From 161700cfe8b0c6684ee02b6d6bbf3994a6942108 Mon Sep 17 00:00:00 2001 From: fern-api <115122769+fern-api[bot]@users.noreply.github.com> Date: Wed, 24 May 2023 21:49:49 +0000 Subject: [PATCH] Release v0.0.10 --- pyproject.toml | 4 +- src/mercoa/__init__.py | 2 + src/mercoa/resources/__init__.py | 2 + src/mercoa/resources/entity/__init__.py | 2 + src/mercoa/resources/entity/client.py | 36 ++++++++++++++++ src/mercoa/resources/entity/types/__init__.py | 2 + .../entity/types/entity_add_payees_request.py | 25 +++++++++++ .../invoice/types/comment_request.py | 3 ++ .../invoice/types/comment_response.py | 2 + .../invoice/types/invoice_request.py | 7 +++ .../invoice/types/invoice_response.py | 20 +++++++-- src/mercoa/resources/payment_method/client.py | 43 +++++++++++++++++++ 12 files changed, 143 insertions(+), 5 deletions(-) create mode 100644 src/mercoa/resources/entity/types/entity_add_payees_request.py diff --git a/pyproject.toml b/pyproject.toml index 2048985..cba7650 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,7 @@ [tool.poetry] name = "mercoa" -version = "v0.0.9" +version = "v0.0.10" description = "" authors = [] packages = [ @@ -12,8 +12,8 @@ packages = [ python = "^3.7" httpx = "0.23.3" pydantic = "^1.9.2" -backports-cached_property = "1.0.2" types-backports = "0.1.3" +backports-cached_property = "1.0.2" [tool.poetry.dev-dependencies] mypy = "0.971" diff --git a/src/mercoa/__init__.py b/src/mercoa/__init__.py index c274b0f..a424266 100644 --- a/src/mercoa/__init__.py +++ b/src/mercoa/__init__.py @@ -46,6 +46,7 @@ EmailSenderProvider, EmailSenderRequest, EmailSenderResponse, + EntityAddPayeesRequest, EntityId, EntityRequest, EntityResponse, @@ -158,6 +159,7 @@ "EmailSenderProvider", "EmailSenderRequest", "EmailSenderResponse", + "EntityAddPayeesRequest", "EntityId", "EntityRequest", "EntityResponse", diff --git a/src/mercoa/resources/__init__.py b/src/mercoa/resources/__init__.py index 8fb0a21..42f34e3 100644 --- a/src/mercoa/resources/__init__.py +++ b/src/mercoa/resources/__init__.py @@ -24,6 +24,7 @@ BusinessProfileResponse, BusinessType, Ein, + EntityAddPayeesRequest, EntityId, EntityRequest, EntityResponse, @@ -147,6 +148,7 @@ "EmailSenderProvider", "EmailSenderRequest", "EmailSenderResponse", + "EntityAddPayeesRequest", "EntityId", "EntityRequest", "EntityResponse", diff --git a/src/mercoa/resources/entity/__init__.py b/src/mercoa/resources/entity/__init__.py index b4be636..fe8b9e9 100644 --- a/src/mercoa/resources/entity/__init__.py +++ b/src/mercoa/resources/entity/__init__.py @@ -6,6 +6,7 @@ BusinessProfileResponse, BusinessType, Ein, + EntityAddPayeesRequest, EntityId, EntityRequest, EntityResponse, @@ -25,6 +26,7 @@ "BusinessProfileResponse", "BusinessType", "Ein", + "EntityAddPayeesRequest", "EntityId", "EntityRequest", "EntityResponse", diff --git a/src/mercoa/resources/entity/client.py b/src/mercoa/resources/entity/client.py index 14e0b5f..1e23c5f 100644 --- a/src/mercoa/resources/entity/client.py +++ b/src/mercoa/resources/entity/client.py @@ -16,6 +16,7 @@ from ..invoice.types.currency_code import CurrencyCode from ..invoice.types.invoice_response import InvoiceResponse from ..invoice.types.invoice_status import InvoiceStatus +from .types.entity_add_payees_request import EntityAddPayeesRequest from .types.entity_id import EntityId from .types.entity_request import EntityRequest from .types.entity_response import EntityResponse @@ -233,6 +234,23 @@ def plaid_link_token(self, entity_id: EntityId) -> str: return pydantic.parse_obj_as(str, _response_json) # type: ignore raise ApiError(status_code=_response.status_code, body=_response_json) + def add_payees(self, entity_id: EntityId, *, request: EntityAddPayeesRequest) -> None: + _response = httpx.request( + "POST", + urllib.parse.urljoin(f"{self._environment.value}/", f"entity/{entity_id}/addPayees"), + json=jsonable_encoder(request), + headers=remove_none_from_headers( + {"Authorization": f"Bearer {self._token}" if self._token is not None else None} + ), + ) + if 200 <= _response.status_code < 300: + return + try: + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json) + class AsyncEntityClient: def __init__( @@ -455,3 +473,21 @@ async def plaid_link_token(self, entity_id: EntityId) -> str: if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(str, _response_json) # type: ignore raise ApiError(status_code=_response.status_code, body=_response_json) + + async def add_payees(self, entity_id: EntityId, *, request: EntityAddPayeesRequest) -> None: + async with httpx.AsyncClient() as _client: + _response = await _client.request( + "POST", + urllib.parse.urljoin(f"{self._environment.value}/", f"entity/{entity_id}/addPayees"), + json=jsonable_encoder(request), + headers=remove_none_from_headers( + {"Authorization": f"Bearer {self._token}" if self._token is not None else None} + ), + ) + if 200 <= _response.status_code < 300: + return + try: + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json) diff --git a/src/mercoa/resources/entity/types/__init__.py b/src/mercoa/resources/entity/types/__init__.py index 48072a4..0b67377 100644 --- a/src/mercoa/resources/entity/types/__init__.py +++ b/src/mercoa/resources/entity/types/__init__.py @@ -5,6 +5,7 @@ from .business_profile_response import BusinessProfileResponse from .business_type import BusinessType from .ein import Ein +from .entity_add_payees_request import EntityAddPayeesRequest from .entity_id import EntityId from .entity_request import EntityRequest from .entity_response import EntityResponse @@ -23,6 +24,7 @@ "BusinessProfileResponse", "BusinessType", "Ein", + "EntityAddPayeesRequest", "EntityId", "EntityRequest", "EntityResponse", diff --git a/src/mercoa/resources/entity/types/entity_add_payees_request.py b/src/mercoa/resources/entity/types/entity_add_payees_request.py new file mode 100644 index 0000000..c28e854 --- /dev/null +++ b/src/mercoa/resources/entity/types/entity_add_payees_request.py @@ -0,0 +1,25 @@ +# This file was auto-generated by Fern from our API Definition. + +import datetime as dt +import typing + +import pydantic + +from ....core.datetime_utils import serialize_datetime +from .entity_id import EntityId + + +class EntityAddPayeesRequest(pydantic.BaseModel): + payees: typing.List[EntityId] + + def json(self, **kwargs: typing.Any) -> str: + kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} + return super().json(**kwargs_with_defaults) + + def dict(self, **kwargs: typing.Any) -> typing.Dict[str, typing.Any]: + kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} + return super().dict(**kwargs_with_defaults) + + class Config: + frozen = True + json_encoders = {dt.datetime: serialize_datetime} diff --git a/src/mercoa/resources/invoice/types/comment_request.py b/src/mercoa/resources/invoice/types/comment_request.py index 1ed6458..06fe3ae 100644 --- a/src/mercoa/resources/invoice/types/comment_request.py +++ b/src/mercoa/resources/invoice/types/comment_request.py @@ -6,10 +6,12 @@ import pydantic from ....core.datetime_utils import serialize_datetime +from ...entity_users.types.entity_user_id import EntityUserId class CommentRequest(pydantic.BaseModel): text: str + user_id: typing.Optional[EntityUserId] = pydantic.Field(alias="userId") def json(self, **kwargs: typing.Any) -> str: kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} @@ -21,4 +23,5 @@ def dict(self, **kwargs: typing.Any) -> typing.Dict[str, typing.Any]: class Config: frozen = True + allow_population_by_field_name = True json_encoders = {dt.datetime: serialize_datetime} diff --git a/src/mercoa/resources/invoice/types/comment_response.py b/src/mercoa/resources/invoice/types/comment_response.py index ef04898..4f4a72b 100644 --- a/src/mercoa/resources/invoice/types/comment_response.py +++ b/src/mercoa/resources/invoice/types/comment_response.py @@ -6,11 +6,13 @@ import pydantic from ....core.datetime_utils import serialize_datetime +from ...entity_users.types.entity_user_response import EntityUserResponse class CommentResponse(pydantic.BaseModel): id: str text: str + user: typing.Optional[EntityUserResponse] created_at: dt.datetime = pydantic.Field(alias="createdAt") updated_at: dt.datetime = pydantic.Field(alias="updatedAt") diff --git a/src/mercoa/resources/invoice/types/invoice_request.py b/src/mercoa/resources/invoice/types/invoice_request.py index 68de427..06d914d 100644 --- a/src/mercoa/resources/invoice/types/invoice_request.py +++ b/src/mercoa/resources/invoice/types/invoice_request.py @@ -7,6 +7,7 @@ from ....core.datetime_utils import serialize_datetime from ...entity.types.entity_id import EntityId +from ...entity_users.types.entity_user_id import EntityUserId from ...payment_method.types.payment_method_id import PaymentMethodId from .create_vendor_request import CreateVendorRequest from .currency_code import CurrencyCode @@ -18,6 +19,9 @@ class InvoiceRequest(pydantic.BaseModel): status: typing.Optional[InvoiceStatus] amount: typing.Optional[float] currency: typing.Optional[CurrencyCode] + invoice_date: typing.Optional[dt.datetime] = pydantic.Field( + alias="invoiceDate", description=("Date the invoice was created.\n") + ) deduction_date: typing.Optional[dt.datetime] = pydantic.Field( alias="deductionDate", description=("Date when funds will be deducted from payer's account.\n") ) @@ -50,6 +54,9 @@ class InvoiceRequest(pydantic.BaseModel): alias="uploadedImage", description=("Base64 encoded image or PDF of invoice. PNG, JPG, and PDF are supported. 10MB max.\n"), ) + created_by_id: typing.Optional[EntityUserId] = pydantic.Field( + alias="createdById", description=("ID of entity user who created this invoice.\n") + ) def json(self, **kwargs: typing.Any) -> str: kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} diff --git a/src/mercoa/resources/invoice/types/invoice_response.py b/src/mercoa/resources/invoice/types/invoice_response.py index 4e2ac43..8a3fe7a 100644 --- a/src/mercoa/resources/invoice/types/invoice_response.py +++ b/src/mercoa/resources/invoice/types/invoice_response.py @@ -8,9 +8,11 @@ from ....core.datetime_utils import serialize_datetime from ...entity.types.entity_id import EntityId from ...entity.types.entity_response import EntityResponse +from ...entity_users.types.entity_user_response import EntityUserResponse from ...payment_method.types.payment_method_id import PaymentMethodId from ...payment_method.types.payment_method_response import PaymentMethodResponse from ...transaction.types.transaction_response import TransactionResponse +from .comment_response import CommentResponse from .currency_code import CurrencyCode from .invoice_id import InvoiceId from .invoice_line_item_response import InvoiceLineItemResponse @@ -22,9 +24,16 @@ class InvoiceResponse(pydantic.BaseModel): status: InvoiceStatus amount: typing.Optional[float] currency: typing.Optional[CurrencyCode] - deduction_date: typing.Optional[dt.datetime] = pydantic.Field(alias="deductionDate") - funded_date: typing.Optional[dt.datetime] = pydantic.Field(alias="fundedDate") - due_date: typing.Optional[dt.datetime] = pydantic.Field(alias="dueDate") + invoice_date: typing.Optional[dt.datetime] = pydantic.Field( + alias="invoiceDate", description=("Date the invoice was created.\n") + ) + deduction_date: typing.Optional[dt.datetime] = pydantic.Field( + alias="deductionDate", description=("Date when funds will be deducted from payer's account.\n") + ) + funded_date: typing.Optional[dt.datetime] = pydantic.Field( + alias="fundedDate", description=("Date of funds settlement.\n") + ) + due_date: typing.Optional[dt.datetime] = pydantic.Field(alias="dueDate", description=("Due date of invoice.\n")) invoice_number: typing.Optional[str] = pydantic.Field(alias="invoiceNumber") note_to_self: typing.Optional[str] = pydantic.Field(alias="noteToSelf") service_start_date: typing.Optional[dt.datetime] = pydantic.Field(alias="serviceStartDate") @@ -38,8 +47,13 @@ class InvoiceResponse(pydantic.BaseModel): payment_destination: typing.Optional[PaymentMethodResponse] = pydantic.Field(alias="paymentDestination") payment_destination_id: typing.Optional[PaymentMethodId] = pydantic.Field(alias="paymentDestinationId") payment_destination_confirmed: bool = pydantic.Field(alias="paymentDestinationConfirmed") + has_documents: bool = pydantic.Field(alias="hasDocuments") + comments: typing.Optional[typing.List[CommentResponse]] transactions: typing.Optional[typing.List[TransactionResponse]] line_items: typing.Optional[typing.List[InvoiceLineItemResponse]] = pydantic.Field(alias="lineItems") + created_by: typing.Optional[EntityUserResponse] = pydantic.Field( + alias="createdBy", description=("Entity user who created this invoice.\n") + ) processed_at: typing.Optional[dt.datetime] = pydantic.Field(alias="processedAt") created_at: dt.datetime = pydantic.Field(alias="createdAt") updated_at: dt.datetime = pydantic.Field(alias="updatedAt") diff --git a/src/mercoa/resources/payment_method/client.py b/src/mercoa/resources/payment_method/client.py index 4f582a8..2a5a016 100644 --- a/src/mercoa/resources/payment_method/client.py +++ b/src/mercoa/resources/payment_method/client.py @@ -82,6 +82,27 @@ def get(self, entity_id: EntityId, payment_method_id: PaymentMethodId) -> Paymen return pydantic.parse_obj_as(PaymentMethodResponse, _response_json) # type: ignore raise ApiError(status_code=_response.status_code, body=_response_json) + def update( + self, entity_id: EntityId, payment_method_id: PaymentMethodId, *, request: PaymentMethodRequest + ) -> PaymentMethodResponse: + _response = httpx.request( + "PUT", + urllib.parse.urljoin( + f"{self._environment.value}/", f"entity/{entity_id}/paymentMethod/{payment_method_id}" + ), + json=jsonable_encoder(request), + headers=remove_none_from_headers( + {"Authorization": f"Bearer {self._token}" if self._token is not None else None} + ), + ) + try: + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + if 200 <= _response.status_code < 300: + return pydantic.parse_obj_as(PaymentMethodResponse, _response_json) # type: ignore + raise ApiError(status_code=_response.status_code, body=_response_json) + def delete(self, entity_id: EntityId, payment_method_id: PaymentMethodId) -> None: _response = httpx.request( "DELETE", @@ -207,6 +228,28 @@ async def get(self, entity_id: EntityId, payment_method_id: PaymentMethodId) -> return pydantic.parse_obj_as(PaymentMethodResponse, _response_json) # type: ignore raise ApiError(status_code=_response.status_code, body=_response_json) + async def update( + self, entity_id: EntityId, payment_method_id: PaymentMethodId, *, request: PaymentMethodRequest + ) -> PaymentMethodResponse: + async with httpx.AsyncClient() as _client: + _response = await _client.request( + "PUT", + urllib.parse.urljoin( + f"{self._environment.value}/", f"entity/{entity_id}/paymentMethod/{payment_method_id}" + ), + json=jsonable_encoder(request), + headers=remove_none_from_headers( + {"Authorization": f"Bearer {self._token}" if self._token is not None else None} + ), + ) + try: + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + if 200 <= _response.status_code < 300: + return pydantic.parse_obj_as(PaymentMethodResponse, _response_json) # type: ignore + raise ApiError(status_code=_response.status_code, body=_response_json) + async def delete(self, entity_id: EntityId, payment_method_id: PaymentMethodId) -> None: async with httpx.AsyncClient() as _client: _response = await _client.request(