Skip to content

Commit

Permalink
feat(dunning): Add payment requests endpoint (find_all) (#258)
Browse files Browse the repository at this point in the history
* feat(dunning): Add payment requests endpoint (find_all)

* Remove not used import
  • Loading branch information
ancorcruz authored Aug 19, 2024
1 parent 5c37350 commit 2965786
Show file tree
Hide file tree
Showing 5 changed files with 185 additions and 0 deletions.
5 changes: 5 additions & 0 deletions lago_python_client/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from .mrrs.clients import MrrClient
from .organizations.clients import OrganizationClient
from .overdue_balances.clients import OverdueBalanceClient
from .payment_requests.clients import PaymentRequestClient
from .invoice_collections.clients import InvoiceCollectionClient
from .plans.clients import PlanClient
from .subscriptions.clients import SubscriptionClient
Expand Down Expand Up @@ -96,6 +97,10 @@ def organizations(self) -> OrganizationClient:
def overdue_balances(self) -> OverdueBalanceClient:
return OverdueBalanceClient(self.base_api_url, self.api_key)

@callable_cached_property
def payment_requests(self) -> PaymentRequestClient:
return PaymentRequestClient(self.base_api_url, self.api_key)

@callable_cached_property
def invoice_collections(self) -> InvoiceCollectionClient:
return InvoiceCollectionClient(self.base_api_url, self.api_key)
Expand Down
46 changes: 46 additions & 0 deletions lago_python_client/models/payment_request.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
from typing import List, Optional

from ..base_model import BaseModel, BaseResponseModel
from .customer import CustomerResponse

class PaymentRequestInvoiceResponse(BaseResponseModel):
lago_id: str
sequential_id: Optional[int]
number: str
issuing_date: Optional[str]
payment_dispute_lost_at: Optional[str]
payment_due_date: Optional[str]
payment_overdue: bool
net_payment_term: int
invoice_type: str
version_number: int
status: str
payment_status: str
currency: str
fees_amount_cents: int
coupons_amount_cents: int
taxes_amount_cents: int
credit_notes_amount_cents: int
sub_total_excluding_taxes_amount_cents: int
sub_total_including_taxes_amount_cents: int
total_amount_cents: int
prepaid_credit_amount_cents: int
file_url: Optional[str]


class PaymentRequestInvoicesResponse(BaseResponseModel):
__root__: List[PaymentRequestInvoiceResponse]


class PaymentRequestResponse(BaseResponseModel):
lago_id: str
email: str
amount_cents: int
amount_currency: str
created_at: str
customer: Optional[CustomerResponse]
invoices: Optional[PaymentRequestInvoicesResponse]


class PaymentRequestsResponse(BaseResponseModel):
__root__: List[PaymentRequestResponse]
22 changes: 22 additions & 0 deletions lago_python_client/payment_requests/clients.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import sys
from typing import Any, ClassVar, Type, Union

from ..base_client import BaseClient
from ..mixins import FindAllCommandMixin
from ..models.payment_request import PaymentRequestResponse
from ..services.request import make_headers, make_url, send_get_request
from ..services.response import get_response_data, prepare_index_response, Response

if sys.version_info >= (3, 9):
from collections.abc import Mapping
else:
from typing import Mapping


class PaymentRequestClient(
FindAllCommandMixin[PaymentRequestResponse],
BaseClient,
):
API_RESOURCE: ClassVar[str] = 'payment_requests'
RESPONSE_MODEL: ClassVar[Type[PaymentRequestResponse]] = PaymentRequestResponse
ROOT_NAME: ClassVar[str] = 'payment_request'
67 changes: 67 additions & 0 deletions tests/fixtures/payment_request_index.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
{
"payment_requests": [
{
"lago_id": "89b6b61e-4dbc-4307-ac96-4abcfa9e3e2d",
"email": "[email protected]",
"amount_cents": 120,
"amount_currency": "EUR",
"created_at": "2024-06-30T10:59:51Z",
"customer": {
"lago_id": "1a901a90-1a90-1a90-1a90-1a901a901a90",
"external_id": "1a901a90-1a90-1a90-1a90-1a901a901a90",
"address_line1": "5230 Penfield Ave",
"address_line2": null,
"city": "Woodland Hills",
"country": "US",
"created_at": "2022-04-29T08:59:51Z",
"updated_at": "2022-04-29T08:59:51Z",
"email": "[email protected]",
"legal_name": "Coleman-Blair",
"legal_number": "49-008-2965",
"logo_url": "http://hooli.com/logo.png",
"name": "Gavin Belson",
"phone": "1-171-883-3711 x245",
"state": "CA",
"url": "http://hooli.com",
"zipcode": "91364",
"currency": "EUR",
"timezone": "Europe/Paris",
"applicable_timezone": "Europe/Paris",
"billing_configuration": {
"payment_provider": "stripe",
"payment_provider_code": "stripe-eu-1",
"provider_customer_id": "cus_12345"
},
"metadata": []
},
"invoices": [
{
"lago_id": "1a901a90-1a90-1a90-1a90-1a901a901a90",
"sequential_id": 15,
"number": "LAG-1234-001-002",
"issuing_date": "2022-06-02",
"payment_dispute_lost_at": "2022-04-29T08:59:51Z",
"payment_due_date": "2022-06-02",
"payment_overdue": true,
"invoice_type": "one_off",
"version_number": 2,
"status": "finalized",
"payment_status": "pending",
"currency": "EUR",
"net_payment_term": 0,
"fees_amount_cents": 100,
"taxes_amount_cents": 20,
"coupons_amount_cents": 0,
"credit_notes_amount_cents": 0,
"sub_total_excluding_taxes_amount_cents": 100,
"sub_total_including_taxes_amount_cents": 120,
"prepaid_credit_amount_cents": 0,
"total_amount_cents": 120
}
]
}
],
"meta": {
"current_page": 1
}
}
45 changes: 45 additions & 0 deletions tests/test_payment_request_client.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import os

import pytest
from pytest_httpx import HTTPXMock

from lago_python_client.client import Client
from lago_python_client.exceptions import LagoApiError
from lago_python_client.models.payment_request import PaymentRequestResponse


def mock_collection_response():
current_dir = os.path.dirname(os.path.abspath(__file__))
data_path = os.path.join(current_dir, 'fixtures/payment_request_index.json')

with open(data_path, 'rb') as payment_requests_response:
return payment_requests_response.read()


def test_valid_find_all_payment_requests_request(httpx_mock: HTTPXMock):
client = Client(api_key='886fe239-927d-4072-ab72-6dd345e8dd0d')

httpx_mock.add_response(method='GET', url='https://api.getlago.com/api/v1/payment_requests', content=mock_collection_response())
response = client.payment_requests.find_all()

assert response['payment_requests'][0].lago_id == '89b6b61e-4dbc-4307-ac96-4abcfa9e3e2d'
assert response['meta']['current_page'] == 1


def test_valid_find_all_payment_requests_request_with_options(httpx_mock: HTTPXMock):
client = Client(api_key='886fe239-927d-4072-ab72-6dd345e8dd0d')

httpx_mock.add_response(method='GET', url='https://api.getlago.com/api/v1/payment_requests?per_page=2&page=1', content=mock_collection_response())
response = client.payment_requests.find_all({'per_page': 2, 'page': 1})

assert response['payment_requests'][0].lago_id == '89b6b61e-4dbc-4307-ac96-4abcfa9e3e2d'
assert response['meta']['current_page'] == 1


def test_invalid_find_all_payment_requests_request(httpx_mock: HTTPXMock):
client = Client(api_key='invalid')

httpx_mock.add_response(method='GET', url='https://api.getlago.com/api/v1/payment_requests', status_code=404, content=b'')

with pytest.raises(LagoApiError):
client.payment_requests.find_all()

0 comments on commit 2965786

Please sign in to comment.