# This file was auto-generated by Fern from our API Definition.

import datetime as dt
import typing
from json.decoder import JSONDecodeError

from .. import core
from ..core.api_error import ApiError
from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
from ..core.datetime_utils import serialize_datetime
from ..core.http_response import AsyncHttpResponse, HttpResponse
from ..core.jsonable_encoder import jsonable_encoder
from ..core.pydantic_utilities import parse_obj_as
from ..core.request_options import RequestOptions
from ..core.serialization import convert_and_respect_annotation_metadata
from ..errors.bad_request_error import BadRequestError
from ..errors.conflict_error import ConflictError
from ..errors.forbidden_error import ForbiddenError
from ..errors.internal_server_error import InternalServerError
from ..errors.not_acceptable_error import NotAcceptableError
from ..errors.not_found_error import NotFoundError
from ..errors.unauthorized_error import UnauthorizedError
from ..errors.unprocessable_entity_error import UnprocessableEntityError
from ..types.counterpart_raw_data_update_request import CounterpartRawDataUpdateRequest
from ..types.currency_enum import CurrencyEnum
from ..types.ocr_status_enum import OcrStatusEnum
from ..types.order_enum import OrderEnum
from ..types.payable_aggregated_data_response import PayableAggregatedDataResponse
from ..types.payable_cursor_fields import PayableCursorFields
from ..types.payable_origin_enum import PayableOriginEnum
from ..types.payable_pagination_response import PayablePaginationResponse
from ..types.payable_payment_terms_create_payload import PayablePaymentTermsCreatePayload
from ..types.payable_response_schema import PayableResponseSchema
from ..types.payable_state_enum import PayableStateEnum
from ..types.payable_templates_variables_object_list import PayableTemplatesVariablesObjectList
from ..types.payable_validation_response import PayableValidationResponse
from ..types.payable_validations_resource import PayableValidationsResource
from ..types.payables_fields_allowed_for_validate import PayablesFieldsAllowedForValidate
from ..types.source_of_payable_data_enum import SourceOfPayableDataEnum
from ..types.suggested_payment_term import SuggestedPaymentTerm

# this is used as the default value for optional parameters
OMIT = typing.cast(typing.Any, ...)


class RawPayablesClient:
    def __init__(self, *, client_wrapper: SyncClientWrapper):
        self._client_wrapper = client_wrapper

    def get(
        self,
        *,
        order: typing.Optional[OrderEnum] = None,
        limit: typing.Optional[int] = None,
        pagination_token: typing.Optional[str] = None,
        sort: typing.Optional[PayableCursorFields] = None,
        created_at_gt: typing.Optional[dt.datetime] = None,
        created_at_lt: typing.Optional[dt.datetime] = None,
        created_at_gte: typing.Optional[dt.datetime] = None,
        created_at_lte: typing.Optional[dt.datetime] = None,
        status: typing.Optional[PayableStateEnum] = None,
        status_in: typing.Optional[typing.Union[PayableStateEnum, typing.Sequence[PayableStateEnum]]] = None,
        id_in: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
        total_amount: typing.Optional[int] = None,
        total_amount_gt: typing.Optional[int] = None,
        total_amount_lt: typing.Optional[int] = None,
        total_amount_gte: typing.Optional[int] = None,
        total_amount_lte: typing.Optional[int] = None,
        amount: typing.Optional[int] = None,
        amount_gt: typing.Optional[int] = None,
        amount_lt: typing.Optional[int] = None,
        amount_gte: typing.Optional[int] = None,
        amount_lte: typing.Optional[int] = None,
        currency: typing.Optional[CurrencyEnum] = None,
        counterpart_name: typing.Optional[str] = None,
        counterpart_name_contains: typing.Optional[str] = None,
        counterpart_name_icontains: typing.Optional[str] = None,
        search_text: typing.Optional[str] = None,
        due_date: typing.Optional[str] = None,
        due_date_gt: typing.Optional[str] = None,
        due_date_lt: typing.Optional[str] = None,
        due_date_gte: typing.Optional[str] = None,
        due_date_lte: typing.Optional[str] = None,
        issued_at: typing.Optional[str] = None,
        issued_at_gt: typing.Optional[str] = None,
        issued_at_lt: typing.Optional[str] = None,
        issued_at_gte: typing.Optional[str] = None,
        issued_at_lte: typing.Optional[str] = None,
        document_id: typing.Optional[str] = None,
        document_id_contains: typing.Optional[str] = None,
        document_id_icontains: typing.Optional[str] = None,
        was_created_by_user_id: typing.Optional[str] = None,
        counterpart_id: typing.Optional[str] = None,
        source_of_payable_data: typing.Optional[SourceOfPayableDataEnum] = None,
        ocr_status: typing.Optional[OcrStatusEnum] = None,
        line_item_id: typing.Optional[str] = None,
        purchase_order_id: typing.Optional[str] = None,
        project_id: typing.Optional[str] = None,
        project_id_in: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
        tag_ids: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
        tag_ids_not_in: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
        origin: typing.Optional[PayableOriginEnum] = None,
        has_file: typing.Optional[bool] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[PayablePaginationResponse]:
        """
        Lists all payables from the connected entity.

        If you already have the data of the payable (amount in [minor units](
        https://docs.monite.com/references/currencies#minor-units), currency, vendor information, and other details)
        stored somewhere as individual attributes, you can create a payable with these attributes by calling [POST
        /payables](https://docs.monite.com/api/payables/post-payables) and providing the [base64-encoded](
        https://en.wikipedia.org/wiki/Base64) contents of the original invoice file in the field `base64_encoded_file`.

        A payable is a financial document given by an entity`s supplier itemizing the purchase of a good or a service and
        demanding payment.

        The `file_name` field is optional. If omitted, it defaults to “default_file_name”. If the settings are configured
        to automatically set `suggested_payment_term`, this object can be omitted from the request body.

        The `id` generated for this payable can be used in other API calls to update the data of this payable or trigger [
        status transitions](https://docs.monite.com/accounts-payable/approvals/manual-transition), for example. essential data
        fields to move from `draft` to `new`

        Related guide: [Create a payable from data](https://docs.monite.com/accounts-payable/payables/collect#create-a-payable-from-data)

        See also:


        [Automatic calculation of due date](https://docs.monite.com/accounts-payable/payables/collect#automatic-calculation-of-due-date)

        [Suggested payment date](https://docs.monite.com/accounts-payable/payables/collect#suggested-payment-date)

        [Attach file](https://docs.monite.com/accounts-payable/payables/collect#attach-file)

        [Collect payables by email](https://docs.monite.com/accounts-payable/payables/collect#send-payables-by-email)

        [Manage line items](https://docs.monite.com/accounts-payable/payables/line-items)

        Parameters
        ----------
        order : typing.Optional[OrderEnum]
            Sort order (ascending by default). Typically used together with the `sort` parameter.

        limit : typing.Optional[int]
            The number of items (0 .. 100) to return in a single page of the response. The response may contain fewer items if it is the last or only page.

        pagination_token : typing.Optional[str]
            A pagination token obtained from a previous call to this endpoint. Use it to get the next or previous page of results for your initial query. If `pagination_token` is specified, all other query parameters are ignored and inferred from the initial query.

            If not specified, the first page of results will be returned.

        sort : typing.Optional[PayableCursorFields]
            The field to sort the results by. Typically used together with the `order` parameter.

        created_at_gt : typing.Optional[dt.datetime]
            Return only payables created in Monite after the specified date and time. The value must be in the ISO 8601 format YYYY-MM-DDThh:mm[:ss[.ffffff]][Z|±hh:mm].

        created_at_lt : typing.Optional[dt.datetime]
            Return only payables created in Monite before the specified date and time.

        created_at_gte : typing.Optional[dt.datetime]
            Return only payables created in Monite on or after the specified date and time.

        created_at_lte : typing.Optional[dt.datetime]
            Return only payables created in Monite before or on the specified date and time.

        status : typing.Optional[PayableStateEnum]
            Return only payables that have the specified [status](https://docs.monite.com/accounts-payable/payables/index).

            To query multiple statuses at once, use the `status__in` parameter instead.

        status_in : typing.Optional[typing.Union[PayableStateEnum, typing.Sequence[PayableStateEnum]]]
            Return only payables that have the specified [statuses](https://docs.monite.com/accounts-payable/payables/index).

            To specify multiple statuses, repeat this parameter for each value: `status__in=draft&status__in=new`

        id_in : typing.Optional[typing.Union[str, typing.Sequence[str]]]
            Return only payables with specified IDs. Valid but nonexistent IDs do not raise errors but produce no results.

            To specify multiple IDs, repeat this parameter for each value: `id__in=<id1>&id__in=<id2>`

        total_amount : typing.Optional[int]
            Return only payables with the exact specified total amount. The amount must be specified in the minor units of currency. For example, $12.5 is represented as 1250.

        total_amount_gt : typing.Optional[int]
            Return only payables whose total amount (in minor units) exceeds the specified value.

        total_amount_lt : typing.Optional[int]
            Return only payables whose total amount (in minor units) is less than the specified value.

        total_amount_gte : typing.Optional[int]
            Return only payables whose total amount (in minor units) is greater than or equal to the specified value.

        total_amount_lte : typing.Optional[int]
            Return only payables whose total amount (in minor units) is less than or equal to the specified value.

        amount : typing.Optional[int]
            Return only payables with the specified amount.

        amount_gt : typing.Optional[int]
            Return only payables whose amount (in minor units) exceeds the specified value.

        amount_lt : typing.Optional[int]
            Return only payables whose amount (in minor units) is less than the specified value.

        amount_gte : typing.Optional[int]
            Return only payables whose amount (in minor units) is greater than or equal to the specified value.

        amount_lte : typing.Optional[int]
            Return only payables whose amount (in minor units) is less than or equal to the specified value.

        currency : typing.Optional[CurrencyEnum]
            Return only payables that use the specified currency.

        counterpart_name : typing.Optional[str]
            Return only payables received from counterparts with the specified name (exact match, case-sensitive).

            For counterparts of `type = individual`, the full name is formatted as `first_name last_name`.

        counterpart_name_contains : typing.Optional[str]
            Return only payables received from counterparts whose name contains the specified string (case-sensitive).

        counterpart_name_icontains : typing.Optional[str]
            Return only payables received from counterparts whose name contains the specified string (case-insensitive).

        search_text : typing.Optional[str]
            Apply the `icontains` condition to search for the specified text in the `document_id` and `counterpart_name` fields in the payables.

        due_date : typing.Optional[str]
            Return payables that are due on the specified date (YYYY-MM-DD)

        due_date_gt : typing.Optional[str]
            Return payables that are due after the specified date (exclusive, YYYY-MM-DD).

        due_date_lt : typing.Optional[str]
            Return payables that are due before the specified date (exclusive, YYYY-MM-DD).

        due_date_gte : typing.Optional[str]
            Return payables that are due on or after the specified date (YYYY-MM-DD).

        due_date_lte : typing.Optional[str]
            Return payables that are due before or on the specified date (YYYY-MM-DD).

        issued_at : typing.Optional[str]
            Return payables that are issued at the specified date (YYYY-MM-DD)

        issued_at_gt : typing.Optional[str]
            Return payables that are issued after the specified date (exclusive, YYYY-MM-DD).

        issued_at_lt : typing.Optional[str]
            Return payables that are issued before the specified date (exclusive, YYYY-MM-DD).

        issued_at_gte : typing.Optional[str]
            Return payables that are issued on or after the specified date (YYYY-MM-DD).

        issued_at_lte : typing.Optional[str]
            Return payables that are issued before or on the specified date (YYYY-MM-DD).

        document_id : typing.Optional[str]
            Return a payable with the exact specified document number (case-sensitive).

            The `document_id` is the user-facing document number such as INV-00042, not to be confused with Monite resource IDs (`id`).

        document_id_contains : typing.Optional[str]
            Return only payables whose document number (`document_id`) contains the specified string (case-sensitive).

        document_id_icontains : typing.Optional[str]
            Return only payables whose document number (`document_id`) contains the specified string (case-insensitive).

        was_created_by_user_id : typing.Optional[str]
            Return only payables created in Monite by the entity user with the specified ID.

        counterpart_id : typing.Optional[str]
            Return only payables received from the counterpart with the specified ID.

            Counterparts that have been deleted but have associated payables will still return results here because the payables contain a frozen copy of the counterpart data.

            If the specified counterpart ID does not exist and never existed, no results are returned.

        source_of_payable_data : typing.Optional[SourceOfPayableDataEnum]
            Return only payables coming from the specified source.

        ocr_status : typing.Optional[OcrStatusEnum]
            Return only payables with specific OCR statuses.

        line_item_id : typing.Optional[str]
            Search for a payable by the identifier of the line item associated with it.

        purchase_order_id : typing.Optional[str]
            Search for a payable by the identifier of the purchase order associated with it.

        project_id : typing.Optional[str]
            Return only payables assigned to the project with the specified ID.

            Valid but nonexistent project IDs do not raise errors but return no results.

        project_id_in : typing.Optional[typing.Union[str, typing.Sequence[str]]]
            Return only payables whose `project_id` include at least one of the project_id with the specified IDs. Valid but nonexistent project IDs do not raise errors but produce no results.

        tag_ids : typing.Optional[typing.Union[str, typing.Sequence[str]]]
            Return only payables whose `tags` include at least one of the tags with the specified IDs. Valid but nonexistent tag IDs do not raise errors but produce no results.

        tag_ids_not_in : typing.Optional[typing.Union[str, typing.Sequence[str]]]
            Return only payables whose `tags` do not include any of the tags with the specified IDs. Valid but nonexistent tag IDs do not raise errors but produce the results.

        origin : typing.Optional[PayableOriginEnum]
            Return only payables from a given origin ['einvoice', 'upload', 'email']

        has_file : typing.Optional[bool]
            Return only payables with or without attachments (files)

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[PayablePaginationResponse]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            "payables",
            method="GET",
            params={
                "order": order,
                "limit": limit,
                "pagination_token": pagination_token,
                "sort": sort,
                "created_at__gt": serialize_datetime(created_at_gt) if created_at_gt is not None else None,
                "created_at__lt": serialize_datetime(created_at_lt) if created_at_lt is not None else None,
                "created_at__gte": serialize_datetime(created_at_gte) if created_at_gte is not None else None,
                "created_at__lte": serialize_datetime(created_at_lte) if created_at_lte is not None else None,
                "status": status,
                "status__in": status_in,
                "id__in": id_in,
                "total_amount": total_amount,
                "total_amount__gt": total_amount_gt,
                "total_amount__lt": total_amount_lt,
                "total_amount__gte": total_amount_gte,
                "total_amount__lte": total_amount_lte,
                "amount": amount,
                "amount__gt": amount_gt,
                "amount__lt": amount_lt,
                "amount__gte": amount_gte,
                "amount__lte": amount_lte,
                "currency": currency,
                "counterpart_name": counterpart_name,
                "counterpart_name__contains": counterpart_name_contains,
                "counterpart_name__icontains": counterpart_name_icontains,
                "search_text": search_text,
                "due_date": due_date,
                "due_date__gt": due_date_gt,
                "due_date__lt": due_date_lt,
                "due_date__gte": due_date_gte,
                "due_date__lte": due_date_lte,
                "issued_at": issued_at,
                "issued_at__gt": issued_at_gt,
                "issued_at__lt": issued_at_lt,
                "issued_at__gte": issued_at_gte,
                "issued_at__lte": issued_at_lte,
                "document_id": document_id,
                "document_id__contains": document_id_contains,
                "document_id__icontains": document_id_icontains,
                "was_created_by_user_id": was_created_by_user_id,
                "counterpart_id": counterpart_id,
                "source_of_payable_data": source_of_payable_data,
                "ocr_status": ocr_status,
                "line_item_id": line_item_id,
                "purchase_order_id": purchase_order_id,
                "project_id": project_id,
                "project_id__in": project_id_in,
                "tag_ids": tag_ids,
                "tag_ids__not_in": tag_ids_not_in,
                "origin": origin,
                "has_file": has_file,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    PayablePaginationResponse,
                    parse_obj_as(
                        type_=PayablePaginationResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 406:
                raise NotAcceptableError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def create(
        self,
        *,
        base64encoded_file: typing.Optional[str] = OMIT,
        counterpart_address_id: typing.Optional[str] = OMIT,
        counterpart_bank_account_id: typing.Optional[str] = OMIT,
        counterpart_id: typing.Optional[str] = OMIT,
        counterpart_vat_id_id: typing.Optional[str] = OMIT,
        currency: typing.Optional[CurrencyEnum] = OMIT,
        description: typing.Optional[str] = OMIT,
        discount: typing.Optional[int] = OMIT,
        document_id: typing.Optional[str] = OMIT,
        due_date: typing.Optional[str] = OMIT,
        file_name: typing.Optional[str] = OMIT,
        issued_at: typing.Optional[str] = OMIT,
        partner_metadata: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = OMIT,
        payment_terms: typing.Optional[PayablePaymentTermsCreatePayload] = OMIT,
        project_id: typing.Optional[str] = OMIT,
        purchase_order_id: typing.Optional[str] = OMIT,
        sender: typing.Optional[str] = OMIT,
        subtotal: typing.Optional[int] = OMIT,
        suggested_payment_term: typing.Optional[SuggestedPaymentTerm] = OMIT,
        tag_ids: typing.Optional[typing.Sequence[str]] = OMIT,
        tax: typing.Optional[int] = OMIT,
        tax_amount: typing.Optional[int] = OMIT,
        total_amount: typing.Optional[int] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[PayableResponseSchema]:
        """
        Add a new payable by providing the amount, currency, vendor name, and other details.
        You can provide the base64_encoded contents of the original invoice file in the field `base64_encoded_file`.

        You can use this endpoint to bypass the Monite OCR service and provide the data directly
        (for example, if you already have the data in place).

        A newly created payable has the the `draft` [status](https://docs.monite.com/accounts-payable/payables/index).

        Parameters
        ----------
        base64encoded_file : typing.Optional[str]
            Base64-encoded contents of the original issued payable. The file is provided for reference purposes as the original source of the data.

             Any file formats are allowed. The most common formats are PDF, PNG, JPEG, TIFF.

        counterpart_address_id : typing.Optional[str]
            The ID of counterpart address object stored in counterparts service

        counterpart_bank_account_id : typing.Optional[str]
            The ID of counterpart bank account object stored in counterparts service

        counterpart_id : typing.Optional[str]
            The ID of the counterpart object that represents the vendor or supplier.

        counterpart_vat_id_id : typing.Optional[str]
            The ID of counterpart VAT ID object stored in counterparts service

        currency : typing.Optional[CurrencyEnum]
            The [currency code](https://docs.monite.com/references/currencies) of the currency used in the payable.

        description : typing.Optional[str]
            An arbitrary description of this payable.

        discount : typing.Optional[int]
            The value of the additional discount that will be applied to the total amount. in [minor units](https://docs.monite.com/references/currencies#minor-units). For example, $12.50 is represented as 1250.

        document_id : typing.Optional[str]
            A unique invoice number assigned by the invoice issuer for payment tracking purposes.

        due_date : typing.Optional[str]
            The date by which the payable must be paid, in the YYYY-MM-DD format. If the payable specifies payment terms with early payment discounts, this is the final payment date.

        file_name : typing.Optional[str]
            The original file name.

        issued_at : typing.Optional[str]
            The date when the payable was issued, in the YYYY-MM-DD format.

        partner_metadata : typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]]
            Metadata for partner needs

        payment_terms : typing.Optional[PayablePaymentTermsCreatePayload]
            The number of days to pay with potential discount for options shorter than due_date

        project_id : typing.Optional[str]
            The ID of a project

        purchase_order_id : typing.Optional[str]
            The identifier of the purchase order to which this payable belongs.

        sender : typing.Optional[str]
            The email address from which the invoice was sent to the entity.

        subtotal : typing.Optional[int]
            The subtotal amount to be paid, in [minor units](https://docs.monite.com/references/currencies#minor-units). For example, $12.50 is represented as 1250.

        suggested_payment_term : typing.Optional[SuggestedPaymentTerm]
            The suggested date and corresponding discount in which payable could be paid. The date is in the YYYY-MM-DD format. The discount is calculated as X * (10^-4) - for example, 100 is 1%, 25 is 0,25%, 10000 is 100 %. Date varies depending on the payment terms and may even be equal to the due date with discount 0.

        tag_ids : typing.Optional[typing.Sequence[str]]
            A list of IDs of user-defined tags (labels) assigned to this payable. Tags can be used to trigger a specific approval policy for this payable.

        tax : typing.Optional[int]
            Registered tax percentage applied for a service price in minor units, e.g. 200 means 2%. 1050 means 10.5%.

        tax_amount : typing.Optional[int]
            Tax amount in [minor units](https://docs.monite.com/references/currencies#minor-units). For example, $12.50 is represented as 1250.

        total_amount : typing.Optional[int]
            The total amount to be paid, in [minor units](https://docs.monite.com/references/currencies#minor-units). For example, $12.50 is represented as 1250.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[PayableResponseSchema]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            "payables",
            method="POST",
            json={
                "base64_encoded_file": base64encoded_file,
                "counterpart_address_id": counterpart_address_id,
                "counterpart_bank_account_id": counterpart_bank_account_id,
                "counterpart_id": counterpart_id,
                "counterpart_vat_id_id": counterpart_vat_id_id,
                "currency": currency,
                "description": description,
                "discount": discount,
                "document_id": document_id,
                "due_date": due_date,
                "file_name": file_name,
                "issued_at": issued_at,
                "partner_metadata": partner_metadata,
                "payment_terms": convert_and_respect_annotation_metadata(
                    object_=payment_terms, annotation=PayablePaymentTermsCreatePayload, direction="write"
                ),
                "project_id": project_id,
                "purchase_order_id": purchase_order_id,
                "sender": sender,
                "subtotal": subtotal,
                "suggested_payment_term": convert_and_respect_annotation_metadata(
                    object_=suggested_payment_term, annotation=SuggestedPaymentTerm, direction="write"
                ),
                "tag_ids": tag_ids,
                "tax": tax,
                "tax_amount": tax_amount,
                "total_amount": total_amount,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    PayableResponseSchema,
                    parse_obj_as(
                        type_=PayableResponseSchema,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def get_analytics(
        self,
        *,
        created_at_gt: typing.Optional[dt.datetime] = None,
        created_at_lt: typing.Optional[dt.datetime] = None,
        created_at_gte: typing.Optional[dt.datetime] = None,
        created_at_lte: typing.Optional[dt.datetime] = None,
        status: typing.Optional[PayableStateEnum] = None,
        status_in: typing.Optional[typing.Union[PayableStateEnum, typing.Sequence[PayableStateEnum]]] = None,
        id_in: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
        total_amount: typing.Optional[int] = None,
        total_amount_gt: typing.Optional[int] = None,
        total_amount_lt: typing.Optional[int] = None,
        total_amount_gte: typing.Optional[int] = None,
        total_amount_lte: typing.Optional[int] = None,
        amount: typing.Optional[int] = None,
        amount_gt: typing.Optional[int] = None,
        amount_lt: typing.Optional[int] = None,
        amount_gte: typing.Optional[int] = None,
        amount_lte: typing.Optional[int] = None,
        currency: typing.Optional[CurrencyEnum] = None,
        counterpart_name: typing.Optional[str] = None,
        counterpart_name_contains: typing.Optional[str] = None,
        counterpart_name_icontains: typing.Optional[str] = None,
        search_text: typing.Optional[str] = None,
        due_date: typing.Optional[str] = None,
        due_date_gt: typing.Optional[str] = None,
        due_date_lt: typing.Optional[str] = None,
        due_date_gte: typing.Optional[str] = None,
        due_date_lte: typing.Optional[str] = None,
        issued_at: typing.Optional[str] = None,
        issued_at_gt: typing.Optional[str] = None,
        issued_at_lt: typing.Optional[str] = None,
        issued_at_gte: typing.Optional[str] = None,
        issued_at_lte: typing.Optional[str] = None,
        document_id: typing.Optional[str] = None,
        document_id_contains: typing.Optional[str] = None,
        document_id_icontains: typing.Optional[str] = None,
        was_created_by_user_id: typing.Optional[str] = None,
        counterpart_id: typing.Optional[str] = None,
        source_of_payable_data: typing.Optional[SourceOfPayableDataEnum] = None,
        ocr_status: typing.Optional[OcrStatusEnum] = None,
        line_item_id: typing.Optional[str] = None,
        purchase_order_id: typing.Optional[str] = None,
        project_id: typing.Optional[str] = None,
        project_id_in: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
        tag_ids: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
        tag_ids_not_in: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
        origin: typing.Optional[PayableOriginEnum] = None,
        has_file: typing.Optional[bool] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[PayableAggregatedDataResponse]:
        """
        Retrieve aggregated statistics for payables, including total amount and count, both overall and by status.

        For more flexible configuration and retrieval of other data types, use `GET /analytics/payables`.

        Parameters
        ----------
        created_at_gt : typing.Optional[dt.datetime]
            Return only payables created in Monite after the specified date and time. The value must be in the ISO 8601 format YYYY-MM-DDThh:mm[:ss[.ffffff]][Z|±hh:mm].

        created_at_lt : typing.Optional[dt.datetime]
            Return only payables created in Monite before the specified date and time.

        created_at_gte : typing.Optional[dt.datetime]
            Return only payables created in Monite on or after the specified date and time.

        created_at_lte : typing.Optional[dt.datetime]
            Return only payables created in Monite before or on the specified date and time.

        status : typing.Optional[PayableStateEnum]
            Return only payables that have the specified [status](https://docs.monite.com/accounts-payable/payables/index).

            To query multiple statuses at once, use the `status__in` parameter instead.

        status_in : typing.Optional[typing.Union[PayableStateEnum, typing.Sequence[PayableStateEnum]]]
            Return only payables that have the specified [statuses](https://docs.monite.com/accounts-payable/payables/index).

            To specify multiple statuses, repeat this parameter for each value: `status__in=draft&status__in=new`

        id_in : typing.Optional[typing.Union[str, typing.Sequence[str]]]
            Return only payables with specified IDs. Valid but nonexistent IDs do not raise errors but produce no results.

            To specify multiple IDs, repeat this parameter for each value: `id__in=<id1>&id__in=<id2>`

        total_amount : typing.Optional[int]
            Return only payables with the exact specified total amount. The amount must be specified in the minor units of currency. For example, $12.5 is represented as 1250.

        total_amount_gt : typing.Optional[int]
            Return only payables whose total amount (in minor units) exceeds the specified value.

        total_amount_lt : typing.Optional[int]
            Return only payables whose total amount (in minor units) is less than the specified value.

        total_amount_gte : typing.Optional[int]
            Return only payables whose total amount (in minor units) is greater than or equal to the specified value.

        total_amount_lte : typing.Optional[int]
            Return only payables whose total amount (in minor units) is less than or equal to the specified value.

        amount : typing.Optional[int]
            Return only payables with the specified amount.

        amount_gt : typing.Optional[int]
            Return only payables whose amount (in minor units) exceeds the specified value.

        amount_lt : typing.Optional[int]
            Return only payables whose amount (in minor units) is less than the specified value.

        amount_gte : typing.Optional[int]
            Return only payables whose amount (in minor units) is greater than or equal to the specified value.

        amount_lte : typing.Optional[int]
            Return only payables whose amount (in minor units) is less than or equal to the specified value.

        currency : typing.Optional[CurrencyEnum]
            Return only payables that use the specified currency.

        counterpart_name : typing.Optional[str]
            Return only payables received from counterparts with the specified name (exact match, case-sensitive).

            For counterparts of `type = individual`, the full name is formatted as `first_name last_name`.

        counterpart_name_contains : typing.Optional[str]
            Return only payables received from counterparts whose name contains the specified string (case-sensitive).

        counterpart_name_icontains : typing.Optional[str]
            Return only payables received from counterparts whose name contains the specified string (case-insensitive).

        search_text : typing.Optional[str]
            Apply the `icontains` condition to search for the specified text in the `document_id` and `counterpart_name` fields in the payables.

        due_date : typing.Optional[str]
            Return payables that are due on the specified date (YYYY-MM-DD)

        due_date_gt : typing.Optional[str]
            Return payables that are due after the specified date (exclusive, YYYY-MM-DD).

        due_date_lt : typing.Optional[str]
            Return payables that are due before the specified date (exclusive, YYYY-MM-DD).

        due_date_gte : typing.Optional[str]
            Return payables that are due on or after the specified date (YYYY-MM-DD).

        due_date_lte : typing.Optional[str]
            Return payables that are due before or on the specified date (YYYY-MM-DD).

        issued_at : typing.Optional[str]
            Return payables that are issued at the specified date (YYYY-MM-DD)

        issued_at_gt : typing.Optional[str]
            Return payables that are issued after the specified date (exclusive, YYYY-MM-DD).

        issued_at_lt : typing.Optional[str]
            Return payables that are issued before the specified date (exclusive, YYYY-MM-DD).

        issued_at_gte : typing.Optional[str]
            Return payables that are issued on or after the specified date (YYYY-MM-DD).

        issued_at_lte : typing.Optional[str]
            Return payables that are issued before or on the specified date (YYYY-MM-DD).

        document_id : typing.Optional[str]
            Return a payable with the exact specified document number (case-sensitive).

            The `document_id` is the user-facing document number such as INV-00042, not to be confused with Monite resource IDs (`id`).

        document_id_contains : typing.Optional[str]
            Return only payables whose document number (`document_id`) contains the specified string (case-sensitive).

        document_id_icontains : typing.Optional[str]
            Return only payables whose document number (`document_id`) contains the specified string (case-insensitive).

        was_created_by_user_id : typing.Optional[str]
            Return only payables created in Monite by the entity user with the specified ID.

        counterpart_id : typing.Optional[str]
            Return only payables received from the counterpart with the specified ID.

            Counterparts that have been deleted but have associated payables will still return results here because the payables contain a frozen copy of the counterpart data.

            If the specified counterpart ID does not exist and never existed, no results are returned.

        source_of_payable_data : typing.Optional[SourceOfPayableDataEnum]
            Return only payables coming from the specified source.

        ocr_status : typing.Optional[OcrStatusEnum]
            Return only payables with specific OCR statuses.

        line_item_id : typing.Optional[str]
            Search for a payable by the identifier of the line item associated with it.

        purchase_order_id : typing.Optional[str]
            Search for a payable by the identifier of the purchase order associated with it.

        project_id : typing.Optional[str]
            Return only payables assigned to the project with the specified ID.

            Valid but nonexistent project IDs do not raise errors but return no results.

        project_id_in : typing.Optional[typing.Union[str, typing.Sequence[str]]]
            Return only payables whose `project_id` include at least one of the project_id with the specified IDs. Valid but nonexistent project IDs do not raise errors but produce no results.

        tag_ids : typing.Optional[typing.Union[str, typing.Sequence[str]]]
            Return only payables whose `tags` include at least one of the tags with the specified IDs. Valid but nonexistent tag IDs do not raise errors but produce no results.

        tag_ids_not_in : typing.Optional[typing.Union[str, typing.Sequence[str]]]
            Return only payables whose `tags` do not include any of the tags with the specified IDs. Valid but nonexistent tag IDs do not raise errors but produce the results.

        origin : typing.Optional[PayableOriginEnum]
            Return only payables from a given origin ['einvoice', 'upload', 'email']

        has_file : typing.Optional[bool]
            Return only payables with or without attachments (files)

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[PayableAggregatedDataResponse]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            "payables/analytics",
            method="GET",
            params={
                "created_at__gt": serialize_datetime(created_at_gt) if created_at_gt is not None else None,
                "created_at__lt": serialize_datetime(created_at_lt) if created_at_lt is not None else None,
                "created_at__gte": serialize_datetime(created_at_gte) if created_at_gte is not None else None,
                "created_at__lte": serialize_datetime(created_at_lte) if created_at_lte is not None else None,
                "status": status,
                "status__in": status_in,
                "id__in": id_in,
                "total_amount": total_amount,
                "total_amount__gt": total_amount_gt,
                "total_amount__lt": total_amount_lt,
                "total_amount__gte": total_amount_gte,
                "total_amount__lte": total_amount_lte,
                "amount": amount,
                "amount__gt": amount_gt,
                "amount__lt": amount_lt,
                "amount__gte": amount_gte,
                "amount__lte": amount_lte,
                "currency": currency,
                "counterpart_name": counterpart_name,
                "counterpart_name__contains": counterpart_name_contains,
                "counterpart_name__icontains": counterpart_name_icontains,
                "search_text": search_text,
                "due_date": due_date,
                "due_date__gt": due_date_gt,
                "due_date__lt": due_date_lt,
                "due_date__gte": due_date_gte,
                "due_date__lte": due_date_lte,
                "issued_at": issued_at,
                "issued_at__gt": issued_at_gt,
                "issued_at__lt": issued_at_lt,
                "issued_at__gte": issued_at_gte,
                "issued_at__lte": issued_at_lte,
                "document_id": document_id,
                "document_id__contains": document_id_contains,
                "document_id__icontains": document_id_icontains,
                "was_created_by_user_id": was_created_by_user_id,
                "counterpart_id": counterpart_id,
                "source_of_payable_data": source_of_payable_data,
                "ocr_status": ocr_status,
                "line_item_id": line_item_id,
                "purchase_order_id": purchase_order_id,
                "project_id": project_id,
                "project_id__in": project_id_in,
                "tag_ids": tag_ids,
                "tag_ids__not_in": tag_ids_not_in,
                "origin": origin,
                "has_file": has_file,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    PayableAggregatedDataResponse,
                    parse_obj_as(
                        type_=PayableAggregatedDataResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def upload_from_file(
        self, *, file: core.File, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[PayableResponseSchema]:
        """
        Upload an incoming invoice (payable) in PDF, PNG, JPEG, or TIFF format and scan its contents. The maximum file size is 10MB.

        Parameters
        ----------
        file : core.File
            See core.File for more documentation

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[PayableResponseSchema]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            "payables/upload_from_file",
            method="POST",
            data={},
            files={
                "file": file,
            },
            headers={
                "content-type": "multipart/form-data",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    PayableResponseSchema,
                    parse_obj_as(
                        type_=PayableResponseSchema,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 409:
                raise ConflictError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def get_validations(
        self, *, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[PayableValidationsResource]:
        """
        Get payable validations.

        Parameters
        ----------
        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[PayableValidationsResource]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            "payables/validations",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    PayableValidationsResource,
                    parse_obj_as(
                        type_=PayableValidationsResource,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def update_validations(
        self,
        *,
        required_fields: typing.Sequence[PayablesFieldsAllowedForValidate],
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[PayableValidationsResource]:
        """
        Update payable validations.

        Parameters
        ----------
        required_fields : typing.Sequence[PayablesFieldsAllowedForValidate]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[PayableValidationsResource]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            "payables/validations",
            method="PUT",
            json={
                "required_fields": required_fields,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    PayableValidationsResource,
                    parse_obj_as(
                        type_=PayableValidationsResource,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def reset_validations(
        self, *, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[PayableValidationsResource]:
        """
        Reset payable validations to default ones.

        Parameters
        ----------
        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[PayableValidationsResource]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            "payables/validations/reset",
            method="POST",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    PayableValidationsResource,
                    parse_obj_as(
                        type_=PayableValidationsResource,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def get_variables(
        self, *, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[PayableTemplatesVariablesObjectList]:
        """
        Get a list of placeholders allowed to insert into an email template for customization

        Parameters
        ----------
        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[PayableTemplatesVariablesObjectList]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            "payables/variables",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    PayableTemplatesVariablesObjectList,
                    parse_obj_as(
                        type_=PayableTemplatesVariablesObjectList,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def get_by_id(
        self, payable_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[PayableResponseSchema]:
        """
        Retrieves information about a specific payable with the given ID.

        Parameters
        ----------
        payable_id : str

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[PayableResponseSchema]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            f"payables/{jsonable_encoder(payable_id)}",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    PayableResponseSchema,
                    parse_obj_as(
                        type_=PayableResponseSchema,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 409:
                raise ConflictError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def delete_by_id(
        self, payable_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[None]:
        """
        Deletes a specific payable.

        Parameters
        ----------
        payable_id : str

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[None]
        """
        _response = self._client_wrapper.httpx_client.request(
            f"payables/{jsonable_encoder(payable_id)}",
            method="DELETE",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return HttpResponse(response=_response, data=None)
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 409:
                raise ConflictError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def update_by_id(
        self,
        payable_id: str,
        *,
        counterpart_address_id: typing.Optional[str] = OMIT,
        counterpart_bank_account_id: typing.Optional[str] = OMIT,
        counterpart_id: typing.Optional[str] = OMIT,
        counterpart_raw_data: typing.Optional[CounterpartRawDataUpdateRequest] = OMIT,
        counterpart_vat_id_id: typing.Optional[str] = OMIT,
        currency: typing.Optional[CurrencyEnum] = OMIT,
        description: typing.Optional[str] = OMIT,
        discount: typing.Optional[int] = OMIT,
        document_id: typing.Optional[str] = OMIT,
        due_date: typing.Optional[str] = OMIT,
        issued_at: typing.Optional[str] = OMIT,
        partner_metadata: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = OMIT,
        payment_terms: typing.Optional[PayablePaymentTermsCreatePayload] = OMIT,
        project_id: typing.Optional[str] = OMIT,
        purchase_order_id: typing.Optional[str] = OMIT,
        sender: typing.Optional[str] = OMIT,
        subtotal: typing.Optional[int] = OMIT,
        suggested_payment_term: typing.Optional[SuggestedPaymentTerm] = OMIT,
        tag_ids: typing.Optional[typing.Sequence[str]] = OMIT,
        tax: typing.Optional[int] = OMIT,
        tax_amount: typing.Optional[int] = OMIT,
        total_amount: typing.Optional[int] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[PayableResponseSchema]:
        """
        Updates the information about a specific payable.

        Parameters
        ----------
        payable_id : str

        counterpart_address_id : typing.Optional[str]
            The ID of counterpart address object stored in counterparts service

        counterpart_bank_account_id : typing.Optional[str]
            The ID of counterpart bank account object stored in counterparts service

        counterpart_id : typing.Optional[str]
            The ID of the counterpart object that represents the vendor or supplier.

        counterpart_raw_data : typing.Optional[CounterpartRawDataUpdateRequest]
            Allows to fix some data in counterpart recognised fields to correct them in order to make autolinking happen.

        counterpart_vat_id_id : typing.Optional[str]
            The ID of counterpart VAT ID object stored in counterparts service

        currency : typing.Optional[CurrencyEnum]
            The [currency code](https://docs.monite.com/references/currencies) of the currency used in the payable.

        description : typing.Optional[str]
            An arbitrary description of this payable.

        discount : typing.Optional[int]
            The value of the additional discount that will be applied to the total amount. in [minor units](https://docs.monite.com/references/currencies#minor-units). For example, $12.50 is represented as 1250.

        document_id : typing.Optional[str]
            A unique invoice number assigned by the invoice issuer for payment tracking purposes.

        due_date : typing.Optional[str]
            The date by which the payable must be paid, in the YYYY-MM-DD format. If the payable specifies payment terms with early payment discounts, this is the final payment date.

        issued_at : typing.Optional[str]
            The date when the payable was issued, in the YYYY-MM-DD format.

        partner_metadata : typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]]
            Metadata for partner needs

        payment_terms : typing.Optional[PayablePaymentTermsCreatePayload]
            The number of days to pay with potential discount for options shorter than due_date

        project_id : typing.Optional[str]
            The project ID of the payable.

        purchase_order_id : typing.Optional[str]
            The identifier of the purchase order to which this payable belongs.

        sender : typing.Optional[str]
            The email address from which the invoice was sent to the entity.

        subtotal : typing.Optional[int]
            The subtotal amount to be paid, in [minor units](https://docs.monite.com/references/currencies#minor-units). For example, $12.50 is represented as 1250.

        suggested_payment_term : typing.Optional[SuggestedPaymentTerm]
            The suggested date and corresponding discount in which payable could be paid. The date is in the YYYY-MM-DD format. The discount is calculated as X * (10^-4) - for example, 100 is 1%, 25 is 0,25%, 10000 is 100 %. Date varies depending on the payment terms and may even be equal to the due date with discount 0.

        tag_ids : typing.Optional[typing.Sequence[str]]
            A list of IDs of user-defined tags (labels) assigned to this payable. Tags can be used to trigger a specific approval policy for this payable.

        tax : typing.Optional[int]
            Registered tax percentage applied for a service price in minor units, e.g. 200 means 2%, 1050 means 10.5%.

        tax_amount : typing.Optional[int]
            Tax amount in [minor units](https://docs.monite.com/references/currencies#minor-units). For example, $12.50 is represented as 1250.

        total_amount : typing.Optional[int]
            The total amount to be paid, in [minor units](https://docs.monite.com/references/currencies#minor-units). For example, $12.50 is represented as 1250.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[PayableResponseSchema]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            f"payables/{jsonable_encoder(payable_id)}",
            method="PATCH",
            json={
                "counterpart_address_id": counterpart_address_id,
                "counterpart_bank_account_id": counterpart_bank_account_id,
                "counterpart_id": counterpart_id,
                "counterpart_raw_data": convert_and_respect_annotation_metadata(
                    object_=counterpart_raw_data, annotation=CounterpartRawDataUpdateRequest, direction="write"
                ),
                "counterpart_vat_id_id": counterpart_vat_id_id,
                "currency": currency,
                "description": description,
                "discount": discount,
                "document_id": document_id,
                "due_date": due_date,
                "issued_at": issued_at,
                "partner_metadata": partner_metadata,
                "payment_terms": convert_and_respect_annotation_metadata(
                    object_=payment_terms, annotation=PayablePaymentTermsCreatePayload, direction="write"
                ),
                "project_id": project_id,
                "purchase_order_id": purchase_order_id,
                "sender": sender,
                "subtotal": subtotal,
                "suggested_payment_term": convert_and_respect_annotation_metadata(
                    object_=suggested_payment_term, annotation=SuggestedPaymentTerm, direction="write"
                ),
                "tag_ids": tag_ids,
                "tax": tax,
                "tax_amount": tax_amount,
                "total_amount": total_amount,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    PayableResponseSchema,
                    parse_obj_as(
                        type_=PayableResponseSchema,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 409:
                raise ConflictError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def approve_payment_by_id(
        self, payable_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[PayableResponseSchema]:
        """
        Confirms that the payable is ready to be paid.

        Parameters
        ----------
        payable_id : str

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[PayableResponseSchema]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            f"payables/{jsonable_encoder(payable_id)}/approve_payment_operation",
            method="POST",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    PayableResponseSchema,
                    parse_obj_as(
                        type_=PayableResponseSchema,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 409:
                raise ConflictError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def attach_file_by_id(
        self, payable_id: str, *, file: core.File, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[PayableResponseSchema]:
        """
        Attach file to payable without existing attachment.

        Parameters
        ----------
        payable_id : str

        file : core.File
            See core.File for more documentation

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[PayableResponseSchema]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            f"payables/{jsonable_encoder(payable_id)}/attach_file",
            method="POST",
            data={},
            files={
                "file": file,
            },
            headers={
                "content-type": "multipart/form-data",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    PayableResponseSchema,
                    parse_obj_as(
                        type_=PayableResponseSchema,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 409:
                raise ConflictError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def cancel_by_id(
        self, payable_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[PayableResponseSchema]:
        """
        Cancels the payable that was not confirmed during the review.

        Parameters
        ----------
        payable_id : str

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[PayableResponseSchema]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            f"payables/{jsonable_encoder(payable_id)}/cancel",
            method="POST",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    PayableResponseSchema,
                    parse_obj_as(
                        type_=PayableResponseSchema,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 409:
                raise ConflictError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def post_payables_id_cancel_ocr(
        self, payable_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[PayableResponseSchema]:
        """
        Request to cancel the OCR processing of the specified payable.

        Parameters
        ----------
        payable_id : str

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[PayableResponseSchema]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            f"payables/{jsonable_encoder(payable_id)}/cancel_ocr",
            method="POST",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    PayableResponseSchema,
                    parse_obj_as(
                        type_=PayableResponseSchema,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 409:
                raise ConflictError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def mark_as_paid_by_id(
        self,
        payable_id: str,
        *,
        comment: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[PayableResponseSchema]:
        """
        Mark a payable as paid.

        Payables can be paid using the payment channels offered by Monite or through external payment channels. In the latter
         case, the invoice is not automatically marked as paid in the system and needs to be converted to the paid status
         manually.

        Optionally, it is possible to pass the `comment` field in the request body, to describe how and when the invoice was
        paid.

        Notes:
        - To use this endpoint with an entity user token, this entity user must have a role that includes the `pay` permission
        for payables.
        - The `amount_to_pay` field is automatically calculated based on the `amount_due` less the percentage described
        in the `payment_terms.discount` value.

        Related guide: [Mark a payable as paid](https://docs.monite.com/accounts-payable/approvals/manual-transition#mark-as-paid)

        See also:

        [Payables lifecycle](https://docs.monite.com/accounts-payable/payables/index)

        [Payables status transitions](https://docs.monite.com/accounts-payable/payables/collect#suggested-payment-date)

        Parameters
        ----------
        payable_id : str

        comment : typing.Optional[str]
            An arbitrary comment that describes how and when this payable was paid.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[PayableResponseSchema]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            f"payables/{jsonable_encoder(payable_id)}/mark_as_paid",
            method="POST",
            json={
                "comment": comment,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    PayableResponseSchema,
                    parse_obj_as(
                        type_=PayableResponseSchema,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 409:
                raise ConflictError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def mark_as_partially_paid_by_id(
        self, payable_id: str, *, amount_paid: int, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[PayableResponseSchema]:
        """
        Mark a payable as partially paid.

        If the payable is partially paid, its status is moved to `partially_paid`. The value of the `amount_paid` field must be
         the sum of all payments made, not only the last one.

        Notes:
        - This endpoint can be used for payables in the `waiting_to_be_paid` status.
        - The `amount_paid` must be greater than 0 and less than the total payable amount specified by the `amount` field.
        - You can use this endpoint multiple times for the same payable to reflect multiple partial payments, always setting the
         sum of all payments made.
        - To use this endpoint with an entity user token, this entity user must have a role that includes the `pay`
        permission for payables.
        - The `amount_to_pay` field is automatically calculated based on the `amount_due` less the percentage described
        in the `payment_terms.discount` value.

        Related guide: [Mark a payable as partially paid](https://docs.monite.com/accounts-payable/approvals/manual-transition#mark-as-partially-paid)

        See also:

        [Payables lifecycle](https://docs.monite.com/accounts-payable/payables/index)

        [Payables status transitions](https://docs.monite.com/accounts-payable/payables/collect#suggested-payment-date)

        [Mark a payable as paid](https://docs.monite.com/accounts-payable/approvals/manual-transition#mark-as-paid)

        Parameters
        ----------
        payable_id : str

        amount_paid : int
            How much was paid on the invoice (in minor units).

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[PayableResponseSchema]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            f"payables/{jsonable_encoder(payable_id)}/mark_as_partially_paid",
            method="POST",
            json={
                "amount_paid": amount_paid,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    PayableResponseSchema,
                    parse_obj_as(
                        type_=PayableResponseSchema,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 409:
                raise ConflictError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def reject_by_id(
        self, payable_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[PayableResponseSchema]:
        """
        Declines the payable when an approver finds any mismatch or discrepancies.

        Parameters
        ----------
        payable_id : str

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[PayableResponseSchema]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            f"payables/{jsonable_encoder(payable_id)}/reject",
            method="POST",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    PayableResponseSchema,
                    parse_obj_as(
                        type_=PayableResponseSchema,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 409:
                raise ConflictError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def reopen_by_id(
        self, payable_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[PayableResponseSchema]:
        """
        Reset payable state from rejected to new.

        Parameters
        ----------
        payable_id : str

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[PayableResponseSchema]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            f"payables/{jsonable_encoder(payable_id)}/reopen",
            method="POST",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    PayableResponseSchema,
                    parse_obj_as(
                        type_=PayableResponseSchema,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 409:
                raise ConflictError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def submit_for_approval_by_id(
        self, payable_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[PayableResponseSchema]:
        """
        Starts the approval process once the uploaded payable is validated.

        Parameters
        ----------
        payable_id : str

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[PayableResponseSchema]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            f"payables/{jsonable_encoder(payable_id)}/submit_for_approval",
            method="POST",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    PayableResponseSchema,
                    parse_obj_as(
                        type_=PayableResponseSchema,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 409:
                raise ConflictError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def validate_by_id(
        self, payable_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[PayableValidationResponse]:
        """
        Check the invoice for compliance with the requirements for movement from draft to new status.

        Parameters
        ----------
        payable_id : str

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[PayableValidationResponse]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            f"payables/{jsonable_encoder(payable_id)}/validate",
            method="POST",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    PayableValidationResponse,
                    parse_obj_as(
                        type_=PayableValidationResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 409:
                raise ConflictError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)


class AsyncRawPayablesClient:
    def __init__(self, *, client_wrapper: AsyncClientWrapper):
        self._client_wrapper = client_wrapper

    async def get(
        self,
        *,
        order: typing.Optional[OrderEnum] = None,
        limit: typing.Optional[int] = None,
        pagination_token: typing.Optional[str] = None,
        sort: typing.Optional[PayableCursorFields] = None,
        created_at_gt: typing.Optional[dt.datetime] = None,
        created_at_lt: typing.Optional[dt.datetime] = None,
        created_at_gte: typing.Optional[dt.datetime] = None,
        created_at_lte: typing.Optional[dt.datetime] = None,
        status: typing.Optional[PayableStateEnum] = None,
        status_in: typing.Optional[typing.Union[PayableStateEnum, typing.Sequence[PayableStateEnum]]] = None,
        id_in: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
        total_amount: typing.Optional[int] = None,
        total_amount_gt: typing.Optional[int] = None,
        total_amount_lt: typing.Optional[int] = None,
        total_amount_gte: typing.Optional[int] = None,
        total_amount_lte: typing.Optional[int] = None,
        amount: typing.Optional[int] = None,
        amount_gt: typing.Optional[int] = None,
        amount_lt: typing.Optional[int] = None,
        amount_gte: typing.Optional[int] = None,
        amount_lte: typing.Optional[int] = None,
        currency: typing.Optional[CurrencyEnum] = None,
        counterpart_name: typing.Optional[str] = None,
        counterpart_name_contains: typing.Optional[str] = None,
        counterpart_name_icontains: typing.Optional[str] = None,
        search_text: typing.Optional[str] = None,
        due_date: typing.Optional[str] = None,
        due_date_gt: typing.Optional[str] = None,
        due_date_lt: typing.Optional[str] = None,
        due_date_gte: typing.Optional[str] = None,
        due_date_lte: typing.Optional[str] = None,
        issued_at: typing.Optional[str] = None,
        issued_at_gt: typing.Optional[str] = None,
        issued_at_lt: typing.Optional[str] = None,
        issued_at_gte: typing.Optional[str] = None,
        issued_at_lte: typing.Optional[str] = None,
        document_id: typing.Optional[str] = None,
        document_id_contains: typing.Optional[str] = None,
        document_id_icontains: typing.Optional[str] = None,
        was_created_by_user_id: typing.Optional[str] = None,
        counterpart_id: typing.Optional[str] = None,
        source_of_payable_data: typing.Optional[SourceOfPayableDataEnum] = None,
        ocr_status: typing.Optional[OcrStatusEnum] = None,
        line_item_id: typing.Optional[str] = None,
        purchase_order_id: typing.Optional[str] = None,
        project_id: typing.Optional[str] = None,
        project_id_in: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
        tag_ids: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
        tag_ids_not_in: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
        origin: typing.Optional[PayableOriginEnum] = None,
        has_file: typing.Optional[bool] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[PayablePaginationResponse]:
        """
        Lists all payables from the connected entity.

        If you already have the data of the payable (amount in [minor units](
        https://docs.monite.com/references/currencies#minor-units), currency, vendor information, and other details)
        stored somewhere as individual attributes, you can create a payable with these attributes by calling [POST
        /payables](https://docs.monite.com/api/payables/post-payables) and providing the [base64-encoded](
        https://en.wikipedia.org/wiki/Base64) contents of the original invoice file in the field `base64_encoded_file`.

        A payable is a financial document given by an entity`s supplier itemizing the purchase of a good or a service and
        demanding payment.

        The `file_name` field is optional. If omitted, it defaults to “default_file_name”. If the settings are configured
        to automatically set `suggested_payment_term`, this object can be omitted from the request body.

        The `id` generated for this payable can be used in other API calls to update the data of this payable or trigger [
        status transitions](https://docs.monite.com/accounts-payable/approvals/manual-transition), for example. essential data
        fields to move from `draft` to `new`

        Related guide: [Create a payable from data](https://docs.monite.com/accounts-payable/payables/collect#create-a-payable-from-data)

        See also:


        [Automatic calculation of due date](https://docs.monite.com/accounts-payable/payables/collect#automatic-calculation-of-due-date)

        [Suggested payment date](https://docs.monite.com/accounts-payable/payables/collect#suggested-payment-date)

        [Attach file](https://docs.monite.com/accounts-payable/payables/collect#attach-file)

        [Collect payables by email](https://docs.monite.com/accounts-payable/payables/collect#send-payables-by-email)

        [Manage line items](https://docs.monite.com/accounts-payable/payables/line-items)

        Parameters
        ----------
        order : typing.Optional[OrderEnum]
            Sort order (ascending by default). Typically used together with the `sort` parameter.

        limit : typing.Optional[int]
            The number of items (0 .. 100) to return in a single page of the response. The response may contain fewer items if it is the last or only page.

        pagination_token : typing.Optional[str]
            A pagination token obtained from a previous call to this endpoint. Use it to get the next or previous page of results for your initial query. If `pagination_token` is specified, all other query parameters are ignored and inferred from the initial query.

            If not specified, the first page of results will be returned.

        sort : typing.Optional[PayableCursorFields]
            The field to sort the results by. Typically used together with the `order` parameter.

        created_at_gt : typing.Optional[dt.datetime]
            Return only payables created in Monite after the specified date and time. The value must be in the ISO 8601 format YYYY-MM-DDThh:mm[:ss[.ffffff]][Z|±hh:mm].

        created_at_lt : typing.Optional[dt.datetime]
            Return only payables created in Monite before the specified date and time.

        created_at_gte : typing.Optional[dt.datetime]
            Return only payables created in Monite on or after the specified date and time.

        created_at_lte : typing.Optional[dt.datetime]
            Return only payables created in Monite before or on the specified date and time.

        status : typing.Optional[PayableStateEnum]
            Return only payables that have the specified [status](https://docs.monite.com/accounts-payable/payables/index).

            To query multiple statuses at once, use the `status__in` parameter instead.

        status_in : typing.Optional[typing.Union[PayableStateEnum, typing.Sequence[PayableStateEnum]]]
            Return only payables that have the specified [statuses](https://docs.monite.com/accounts-payable/payables/index).

            To specify multiple statuses, repeat this parameter for each value: `status__in=draft&status__in=new`

        id_in : typing.Optional[typing.Union[str, typing.Sequence[str]]]
            Return only payables with specified IDs. Valid but nonexistent IDs do not raise errors but produce no results.

            To specify multiple IDs, repeat this parameter for each value: `id__in=<id1>&id__in=<id2>`

        total_amount : typing.Optional[int]
            Return only payables with the exact specified total amount. The amount must be specified in the minor units of currency. For example, $12.5 is represented as 1250.

        total_amount_gt : typing.Optional[int]
            Return only payables whose total amount (in minor units) exceeds the specified value.

        total_amount_lt : typing.Optional[int]
            Return only payables whose total amount (in minor units) is less than the specified value.

        total_amount_gte : typing.Optional[int]
            Return only payables whose total amount (in minor units) is greater than or equal to the specified value.

        total_amount_lte : typing.Optional[int]
            Return only payables whose total amount (in minor units) is less than or equal to the specified value.

        amount : typing.Optional[int]
            Return only payables with the specified amount.

        amount_gt : typing.Optional[int]
            Return only payables whose amount (in minor units) exceeds the specified value.

        amount_lt : typing.Optional[int]
            Return only payables whose amount (in minor units) is less than the specified value.

        amount_gte : typing.Optional[int]
            Return only payables whose amount (in minor units) is greater than or equal to the specified value.

        amount_lte : typing.Optional[int]
            Return only payables whose amount (in minor units) is less than or equal to the specified value.

        currency : typing.Optional[CurrencyEnum]
            Return only payables that use the specified currency.

        counterpart_name : typing.Optional[str]
            Return only payables received from counterparts with the specified name (exact match, case-sensitive).

            For counterparts of `type = individual`, the full name is formatted as `first_name last_name`.

        counterpart_name_contains : typing.Optional[str]
            Return only payables received from counterparts whose name contains the specified string (case-sensitive).

        counterpart_name_icontains : typing.Optional[str]
            Return only payables received from counterparts whose name contains the specified string (case-insensitive).

        search_text : typing.Optional[str]
            Apply the `icontains` condition to search for the specified text in the `document_id` and `counterpart_name` fields in the payables.

        due_date : typing.Optional[str]
            Return payables that are due on the specified date (YYYY-MM-DD)

        due_date_gt : typing.Optional[str]
            Return payables that are due after the specified date (exclusive, YYYY-MM-DD).

        due_date_lt : typing.Optional[str]
            Return payables that are due before the specified date (exclusive, YYYY-MM-DD).

        due_date_gte : typing.Optional[str]
            Return payables that are due on or after the specified date (YYYY-MM-DD).

        due_date_lte : typing.Optional[str]
            Return payables that are due before or on the specified date (YYYY-MM-DD).

        issued_at : typing.Optional[str]
            Return payables that are issued at the specified date (YYYY-MM-DD)

        issued_at_gt : typing.Optional[str]
            Return payables that are issued after the specified date (exclusive, YYYY-MM-DD).

        issued_at_lt : typing.Optional[str]
            Return payables that are issued before the specified date (exclusive, YYYY-MM-DD).

        issued_at_gte : typing.Optional[str]
            Return payables that are issued on or after the specified date (YYYY-MM-DD).

        issued_at_lte : typing.Optional[str]
            Return payables that are issued before or on the specified date (YYYY-MM-DD).

        document_id : typing.Optional[str]
            Return a payable with the exact specified document number (case-sensitive).

            The `document_id` is the user-facing document number such as INV-00042, not to be confused with Monite resource IDs (`id`).

        document_id_contains : typing.Optional[str]
            Return only payables whose document number (`document_id`) contains the specified string (case-sensitive).

        document_id_icontains : typing.Optional[str]
            Return only payables whose document number (`document_id`) contains the specified string (case-insensitive).

        was_created_by_user_id : typing.Optional[str]
            Return only payables created in Monite by the entity user with the specified ID.

        counterpart_id : typing.Optional[str]
            Return only payables received from the counterpart with the specified ID.

            Counterparts that have been deleted but have associated payables will still return results here because the payables contain a frozen copy of the counterpart data.

            If the specified counterpart ID does not exist and never existed, no results are returned.

        source_of_payable_data : typing.Optional[SourceOfPayableDataEnum]
            Return only payables coming from the specified source.

        ocr_status : typing.Optional[OcrStatusEnum]
            Return only payables with specific OCR statuses.

        line_item_id : typing.Optional[str]
            Search for a payable by the identifier of the line item associated with it.

        purchase_order_id : typing.Optional[str]
            Search for a payable by the identifier of the purchase order associated with it.

        project_id : typing.Optional[str]
            Return only payables assigned to the project with the specified ID.

            Valid but nonexistent project IDs do not raise errors but return no results.

        project_id_in : typing.Optional[typing.Union[str, typing.Sequence[str]]]
            Return only payables whose `project_id` include at least one of the project_id with the specified IDs. Valid but nonexistent project IDs do not raise errors but produce no results.

        tag_ids : typing.Optional[typing.Union[str, typing.Sequence[str]]]
            Return only payables whose `tags` include at least one of the tags with the specified IDs. Valid but nonexistent tag IDs do not raise errors but produce no results.

        tag_ids_not_in : typing.Optional[typing.Union[str, typing.Sequence[str]]]
            Return only payables whose `tags` do not include any of the tags with the specified IDs. Valid but nonexistent tag IDs do not raise errors but produce the results.

        origin : typing.Optional[PayableOriginEnum]
            Return only payables from a given origin ['einvoice', 'upload', 'email']

        has_file : typing.Optional[bool]
            Return only payables with or without attachments (files)

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[PayablePaginationResponse]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            "payables",
            method="GET",
            params={
                "order": order,
                "limit": limit,
                "pagination_token": pagination_token,
                "sort": sort,
                "created_at__gt": serialize_datetime(created_at_gt) if created_at_gt is not None else None,
                "created_at__lt": serialize_datetime(created_at_lt) if created_at_lt is not None else None,
                "created_at__gte": serialize_datetime(created_at_gte) if created_at_gte is not None else None,
                "created_at__lte": serialize_datetime(created_at_lte) if created_at_lte is not None else None,
                "status": status,
                "status__in": status_in,
                "id__in": id_in,
                "total_amount": total_amount,
                "total_amount__gt": total_amount_gt,
                "total_amount__lt": total_amount_lt,
                "total_amount__gte": total_amount_gte,
                "total_amount__lte": total_amount_lte,
                "amount": amount,
                "amount__gt": amount_gt,
                "amount__lt": amount_lt,
                "amount__gte": amount_gte,
                "amount__lte": amount_lte,
                "currency": currency,
                "counterpart_name": counterpart_name,
                "counterpart_name__contains": counterpart_name_contains,
                "counterpart_name__icontains": counterpart_name_icontains,
                "search_text": search_text,
                "due_date": due_date,
                "due_date__gt": due_date_gt,
                "due_date__lt": due_date_lt,
                "due_date__gte": due_date_gte,
                "due_date__lte": due_date_lte,
                "issued_at": issued_at,
                "issued_at__gt": issued_at_gt,
                "issued_at__lt": issued_at_lt,
                "issued_at__gte": issued_at_gte,
                "issued_at__lte": issued_at_lte,
                "document_id": document_id,
                "document_id__contains": document_id_contains,
                "document_id__icontains": document_id_icontains,
                "was_created_by_user_id": was_created_by_user_id,
                "counterpart_id": counterpart_id,
                "source_of_payable_data": source_of_payable_data,
                "ocr_status": ocr_status,
                "line_item_id": line_item_id,
                "purchase_order_id": purchase_order_id,
                "project_id": project_id,
                "project_id__in": project_id_in,
                "tag_ids": tag_ids,
                "tag_ids__not_in": tag_ids_not_in,
                "origin": origin,
                "has_file": has_file,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    PayablePaginationResponse,
                    parse_obj_as(
                        type_=PayablePaginationResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 406:
                raise NotAcceptableError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def create(
        self,
        *,
        base64encoded_file: typing.Optional[str] = OMIT,
        counterpart_address_id: typing.Optional[str] = OMIT,
        counterpart_bank_account_id: typing.Optional[str] = OMIT,
        counterpart_id: typing.Optional[str] = OMIT,
        counterpart_vat_id_id: typing.Optional[str] = OMIT,
        currency: typing.Optional[CurrencyEnum] = OMIT,
        description: typing.Optional[str] = OMIT,
        discount: typing.Optional[int] = OMIT,
        document_id: typing.Optional[str] = OMIT,
        due_date: typing.Optional[str] = OMIT,
        file_name: typing.Optional[str] = OMIT,
        issued_at: typing.Optional[str] = OMIT,
        partner_metadata: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = OMIT,
        payment_terms: typing.Optional[PayablePaymentTermsCreatePayload] = OMIT,
        project_id: typing.Optional[str] = OMIT,
        purchase_order_id: typing.Optional[str] = OMIT,
        sender: typing.Optional[str] = OMIT,
        subtotal: typing.Optional[int] = OMIT,
        suggested_payment_term: typing.Optional[SuggestedPaymentTerm] = OMIT,
        tag_ids: typing.Optional[typing.Sequence[str]] = OMIT,
        tax: typing.Optional[int] = OMIT,
        tax_amount: typing.Optional[int] = OMIT,
        total_amount: typing.Optional[int] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[PayableResponseSchema]:
        """
        Add a new payable by providing the amount, currency, vendor name, and other details.
        You can provide the base64_encoded contents of the original invoice file in the field `base64_encoded_file`.

        You can use this endpoint to bypass the Monite OCR service and provide the data directly
        (for example, if you already have the data in place).

        A newly created payable has the the `draft` [status](https://docs.monite.com/accounts-payable/payables/index).

        Parameters
        ----------
        base64encoded_file : typing.Optional[str]
            Base64-encoded contents of the original issued payable. The file is provided for reference purposes as the original source of the data.

             Any file formats are allowed. The most common formats are PDF, PNG, JPEG, TIFF.

        counterpart_address_id : typing.Optional[str]
            The ID of counterpart address object stored in counterparts service

        counterpart_bank_account_id : typing.Optional[str]
            The ID of counterpart bank account object stored in counterparts service

        counterpart_id : typing.Optional[str]
            The ID of the counterpart object that represents the vendor or supplier.

        counterpart_vat_id_id : typing.Optional[str]
            The ID of counterpart VAT ID object stored in counterparts service

        currency : typing.Optional[CurrencyEnum]
            The [currency code](https://docs.monite.com/references/currencies) of the currency used in the payable.

        description : typing.Optional[str]
            An arbitrary description of this payable.

        discount : typing.Optional[int]
            The value of the additional discount that will be applied to the total amount. in [minor units](https://docs.monite.com/references/currencies#minor-units). For example, $12.50 is represented as 1250.

        document_id : typing.Optional[str]
            A unique invoice number assigned by the invoice issuer for payment tracking purposes.

        due_date : typing.Optional[str]
            The date by which the payable must be paid, in the YYYY-MM-DD format. If the payable specifies payment terms with early payment discounts, this is the final payment date.

        file_name : typing.Optional[str]
            The original file name.

        issued_at : typing.Optional[str]
            The date when the payable was issued, in the YYYY-MM-DD format.

        partner_metadata : typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]]
            Metadata for partner needs

        payment_terms : typing.Optional[PayablePaymentTermsCreatePayload]
            The number of days to pay with potential discount for options shorter than due_date

        project_id : typing.Optional[str]
            The ID of a project

        purchase_order_id : typing.Optional[str]
            The identifier of the purchase order to which this payable belongs.

        sender : typing.Optional[str]
            The email address from which the invoice was sent to the entity.

        subtotal : typing.Optional[int]
            The subtotal amount to be paid, in [minor units](https://docs.monite.com/references/currencies#minor-units). For example, $12.50 is represented as 1250.

        suggested_payment_term : typing.Optional[SuggestedPaymentTerm]
            The suggested date and corresponding discount in which payable could be paid. The date is in the YYYY-MM-DD format. The discount is calculated as X * (10^-4) - for example, 100 is 1%, 25 is 0,25%, 10000 is 100 %. Date varies depending on the payment terms and may even be equal to the due date with discount 0.

        tag_ids : typing.Optional[typing.Sequence[str]]
            A list of IDs of user-defined tags (labels) assigned to this payable. Tags can be used to trigger a specific approval policy for this payable.

        tax : typing.Optional[int]
            Registered tax percentage applied for a service price in minor units, e.g. 200 means 2%. 1050 means 10.5%.

        tax_amount : typing.Optional[int]
            Tax amount in [minor units](https://docs.monite.com/references/currencies#minor-units). For example, $12.50 is represented as 1250.

        total_amount : typing.Optional[int]
            The total amount to be paid, in [minor units](https://docs.monite.com/references/currencies#minor-units). For example, $12.50 is represented as 1250.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[PayableResponseSchema]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            "payables",
            method="POST",
            json={
                "base64_encoded_file": base64encoded_file,
                "counterpart_address_id": counterpart_address_id,
                "counterpart_bank_account_id": counterpart_bank_account_id,
                "counterpart_id": counterpart_id,
                "counterpart_vat_id_id": counterpart_vat_id_id,
                "currency": currency,
                "description": description,
                "discount": discount,
                "document_id": document_id,
                "due_date": due_date,
                "file_name": file_name,
                "issued_at": issued_at,
                "partner_metadata": partner_metadata,
                "payment_terms": convert_and_respect_annotation_metadata(
                    object_=payment_terms, annotation=PayablePaymentTermsCreatePayload, direction="write"
                ),
                "project_id": project_id,
                "purchase_order_id": purchase_order_id,
                "sender": sender,
                "subtotal": subtotal,
                "suggested_payment_term": convert_and_respect_annotation_metadata(
                    object_=suggested_payment_term, annotation=SuggestedPaymentTerm, direction="write"
                ),
                "tag_ids": tag_ids,
                "tax": tax,
                "tax_amount": tax_amount,
                "total_amount": total_amount,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    PayableResponseSchema,
                    parse_obj_as(
                        type_=PayableResponseSchema,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def get_analytics(
        self,
        *,
        created_at_gt: typing.Optional[dt.datetime] = None,
        created_at_lt: typing.Optional[dt.datetime] = None,
        created_at_gte: typing.Optional[dt.datetime] = None,
        created_at_lte: typing.Optional[dt.datetime] = None,
        status: typing.Optional[PayableStateEnum] = None,
        status_in: typing.Optional[typing.Union[PayableStateEnum, typing.Sequence[PayableStateEnum]]] = None,
        id_in: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
        total_amount: typing.Optional[int] = None,
        total_amount_gt: typing.Optional[int] = None,
        total_amount_lt: typing.Optional[int] = None,
        total_amount_gte: typing.Optional[int] = None,
        total_amount_lte: typing.Optional[int] = None,
        amount: typing.Optional[int] = None,
        amount_gt: typing.Optional[int] = None,
        amount_lt: typing.Optional[int] = None,
        amount_gte: typing.Optional[int] = None,
        amount_lte: typing.Optional[int] = None,
        currency: typing.Optional[CurrencyEnum] = None,
        counterpart_name: typing.Optional[str] = None,
        counterpart_name_contains: typing.Optional[str] = None,
        counterpart_name_icontains: typing.Optional[str] = None,
        search_text: typing.Optional[str] = None,
        due_date: typing.Optional[str] = None,
        due_date_gt: typing.Optional[str] = None,
        due_date_lt: typing.Optional[str] = None,
        due_date_gte: typing.Optional[str] = None,
        due_date_lte: typing.Optional[str] = None,
        issued_at: typing.Optional[str] = None,
        issued_at_gt: typing.Optional[str] = None,
        issued_at_lt: typing.Optional[str] = None,
        issued_at_gte: typing.Optional[str] = None,
        issued_at_lte: typing.Optional[str] = None,
        document_id: typing.Optional[str] = None,
        document_id_contains: typing.Optional[str] = None,
        document_id_icontains: typing.Optional[str] = None,
        was_created_by_user_id: typing.Optional[str] = None,
        counterpart_id: typing.Optional[str] = None,
        source_of_payable_data: typing.Optional[SourceOfPayableDataEnum] = None,
        ocr_status: typing.Optional[OcrStatusEnum] = None,
        line_item_id: typing.Optional[str] = None,
        purchase_order_id: typing.Optional[str] = None,
        project_id: typing.Optional[str] = None,
        project_id_in: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
        tag_ids: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
        tag_ids_not_in: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
        origin: typing.Optional[PayableOriginEnum] = None,
        has_file: typing.Optional[bool] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[PayableAggregatedDataResponse]:
        """
        Retrieve aggregated statistics for payables, including total amount and count, both overall and by status.

        For more flexible configuration and retrieval of other data types, use `GET /analytics/payables`.

        Parameters
        ----------
        created_at_gt : typing.Optional[dt.datetime]
            Return only payables created in Monite after the specified date and time. The value must be in the ISO 8601 format YYYY-MM-DDThh:mm[:ss[.ffffff]][Z|±hh:mm].

        created_at_lt : typing.Optional[dt.datetime]
            Return only payables created in Monite before the specified date and time.

        created_at_gte : typing.Optional[dt.datetime]
            Return only payables created in Monite on or after the specified date and time.

        created_at_lte : typing.Optional[dt.datetime]
            Return only payables created in Monite before or on the specified date and time.

        status : typing.Optional[PayableStateEnum]
            Return only payables that have the specified [status](https://docs.monite.com/accounts-payable/payables/index).

            To query multiple statuses at once, use the `status__in` parameter instead.

        status_in : typing.Optional[typing.Union[PayableStateEnum, typing.Sequence[PayableStateEnum]]]
            Return only payables that have the specified [statuses](https://docs.monite.com/accounts-payable/payables/index).

            To specify multiple statuses, repeat this parameter for each value: `status__in=draft&status__in=new`

        id_in : typing.Optional[typing.Union[str, typing.Sequence[str]]]
            Return only payables with specified IDs. Valid but nonexistent IDs do not raise errors but produce no results.

            To specify multiple IDs, repeat this parameter for each value: `id__in=<id1>&id__in=<id2>`

        total_amount : typing.Optional[int]
            Return only payables with the exact specified total amount. The amount must be specified in the minor units of currency. For example, $12.5 is represented as 1250.

        total_amount_gt : typing.Optional[int]
            Return only payables whose total amount (in minor units) exceeds the specified value.

        total_amount_lt : typing.Optional[int]
            Return only payables whose total amount (in minor units) is less than the specified value.

        total_amount_gte : typing.Optional[int]
            Return only payables whose total amount (in minor units) is greater than or equal to the specified value.

        total_amount_lte : typing.Optional[int]
            Return only payables whose total amount (in minor units) is less than or equal to the specified value.

        amount : typing.Optional[int]
            Return only payables with the specified amount.

        amount_gt : typing.Optional[int]
            Return only payables whose amount (in minor units) exceeds the specified value.

        amount_lt : typing.Optional[int]
            Return only payables whose amount (in minor units) is less than the specified value.

        amount_gte : typing.Optional[int]
            Return only payables whose amount (in minor units) is greater than or equal to the specified value.

        amount_lte : typing.Optional[int]
            Return only payables whose amount (in minor units) is less than or equal to the specified value.

        currency : typing.Optional[CurrencyEnum]
            Return only payables that use the specified currency.

        counterpart_name : typing.Optional[str]
            Return only payables received from counterparts with the specified name (exact match, case-sensitive).

            For counterparts of `type = individual`, the full name is formatted as `first_name last_name`.

        counterpart_name_contains : typing.Optional[str]
            Return only payables received from counterparts whose name contains the specified string (case-sensitive).

        counterpart_name_icontains : typing.Optional[str]
            Return only payables received from counterparts whose name contains the specified string (case-insensitive).

        search_text : typing.Optional[str]
            Apply the `icontains` condition to search for the specified text in the `document_id` and `counterpart_name` fields in the payables.

        due_date : typing.Optional[str]
            Return payables that are due on the specified date (YYYY-MM-DD)

        due_date_gt : typing.Optional[str]
            Return payables that are due after the specified date (exclusive, YYYY-MM-DD).

        due_date_lt : typing.Optional[str]
            Return payables that are due before the specified date (exclusive, YYYY-MM-DD).

        due_date_gte : typing.Optional[str]
            Return payables that are due on or after the specified date (YYYY-MM-DD).

        due_date_lte : typing.Optional[str]
            Return payables that are due before or on the specified date (YYYY-MM-DD).

        issued_at : typing.Optional[str]
            Return payables that are issued at the specified date (YYYY-MM-DD)

        issued_at_gt : typing.Optional[str]
            Return payables that are issued after the specified date (exclusive, YYYY-MM-DD).

        issued_at_lt : typing.Optional[str]
            Return payables that are issued before the specified date (exclusive, YYYY-MM-DD).

        issued_at_gte : typing.Optional[str]
            Return payables that are issued on or after the specified date (YYYY-MM-DD).

        issued_at_lte : typing.Optional[str]
            Return payables that are issued before or on the specified date (YYYY-MM-DD).

        document_id : typing.Optional[str]
            Return a payable with the exact specified document number (case-sensitive).

            The `document_id` is the user-facing document number such as INV-00042, not to be confused with Monite resource IDs (`id`).

        document_id_contains : typing.Optional[str]
            Return only payables whose document number (`document_id`) contains the specified string (case-sensitive).

        document_id_icontains : typing.Optional[str]
            Return only payables whose document number (`document_id`) contains the specified string (case-insensitive).

        was_created_by_user_id : typing.Optional[str]
            Return only payables created in Monite by the entity user with the specified ID.

        counterpart_id : typing.Optional[str]
            Return only payables received from the counterpart with the specified ID.

            Counterparts that have been deleted but have associated payables will still return results here because the payables contain a frozen copy of the counterpart data.

            If the specified counterpart ID does not exist and never existed, no results are returned.

        source_of_payable_data : typing.Optional[SourceOfPayableDataEnum]
            Return only payables coming from the specified source.

        ocr_status : typing.Optional[OcrStatusEnum]
            Return only payables with specific OCR statuses.

        line_item_id : typing.Optional[str]
            Search for a payable by the identifier of the line item associated with it.

        purchase_order_id : typing.Optional[str]
            Search for a payable by the identifier of the purchase order associated with it.

        project_id : typing.Optional[str]
            Return only payables assigned to the project with the specified ID.

            Valid but nonexistent project IDs do not raise errors but return no results.

        project_id_in : typing.Optional[typing.Union[str, typing.Sequence[str]]]
            Return only payables whose `project_id` include at least one of the project_id with the specified IDs. Valid but nonexistent project IDs do not raise errors but produce no results.

        tag_ids : typing.Optional[typing.Union[str, typing.Sequence[str]]]
            Return only payables whose `tags` include at least one of the tags with the specified IDs. Valid but nonexistent tag IDs do not raise errors but produce no results.

        tag_ids_not_in : typing.Optional[typing.Union[str, typing.Sequence[str]]]
            Return only payables whose `tags` do not include any of the tags with the specified IDs. Valid but nonexistent tag IDs do not raise errors but produce the results.

        origin : typing.Optional[PayableOriginEnum]
            Return only payables from a given origin ['einvoice', 'upload', 'email']

        has_file : typing.Optional[bool]
            Return only payables with or without attachments (files)

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[PayableAggregatedDataResponse]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            "payables/analytics",
            method="GET",
            params={
                "created_at__gt": serialize_datetime(created_at_gt) if created_at_gt is not None else None,
                "created_at__lt": serialize_datetime(created_at_lt) if created_at_lt is not None else None,
                "created_at__gte": serialize_datetime(created_at_gte) if created_at_gte is not None else None,
                "created_at__lte": serialize_datetime(created_at_lte) if created_at_lte is not None else None,
                "status": status,
                "status__in": status_in,
                "id__in": id_in,
                "total_amount": total_amount,
                "total_amount__gt": total_amount_gt,
                "total_amount__lt": total_amount_lt,
                "total_amount__gte": total_amount_gte,
                "total_amount__lte": total_amount_lte,
                "amount": amount,
                "amount__gt": amount_gt,
                "amount__lt": amount_lt,
                "amount__gte": amount_gte,
                "amount__lte": amount_lte,
                "currency": currency,
                "counterpart_name": counterpart_name,
                "counterpart_name__contains": counterpart_name_contains,
                "counterpart_name__icontains": counterpart_name_icontains,
                "search_text": search_text,
                "due_date": due_date,
                "due_date__gt": due_date_gt,
                "due_date__lt": due_date_lt,
                "due_date__gte": due_date_gte,
                "due_date__lte": due_date_lte,
                "issued_at": issued_at,
                "issued_at__gt": issued_at_gt,
                "issued_at__lt": issued_at_lt,
                "issued_at__gte": issued_at_gte,
                "issued_at__lte": issued_at_lte,
                "document_id": document_id,
                "document_id__contains": document_id_contains,
                "document_id__icontains": document_id_icontains,
                "was_created_by_user_id": was_created_by_user_id,
                "counterpart_id": counterpart_id,
                "source_of_payable_data": source_of_payable_data,
                "ocr_status": ocr_status,
                "line_item_id": line_item_id,
                "purchase_order_id": purchase_order_id,
                "project_id": project_id,
                "project_id__in": project_id_in,
                "tag_ids": tag_ids,
                "tag_ids__not_in": tag_ids_not_in,
                "origin": origin,
                "has_file": has_file,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    PayableAggregatedDataResponse,
                    parse_obj_as(
                        type_=PayableAggregatedDataResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def upload_from_file(
        self, *, file: core.File, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[PayableResponseSchema]:
        """
        Upload an incoming invoice (payable) in PDF, PNG, JPEG, or TIFF format and scan its contents. The maximum file size is 10MB.

        Parameters
        ----------
        file : core.File
            See core.File for more documentation

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[PayableResponseSchema]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            "payables/upload_from_file",
            method="POST",
            data={},
            files={
                "file": file,
            },
            headers={
                "content-type": "multipart/form-data",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    PayableResponseSchema,
                    parse_obj_as(
                        type_=PayableResponseSchema,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 409:
                raise ConflictError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def get_validations(
        self, *, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[PayableValidationsResource]:
        """
        Get payable validations.

        Parameters
        ----------
        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[PayableValidationsResource]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            "payables/validations",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    PayableValidationsResource,
                    parse_obj_as(
                        type_=PayableValidationsResource,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def update_validations(
        self,
        *,
        required_fields: typing.Sequence[PayablesFieldsAllowedForValidate],
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[PayableValidationsResource]:
        """
        Update payable validations.

        Parameters
        ----------
        required_fields : typing.Sequence[PayablesFieldsAllowedForValidate]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[PayableValidationsResource]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            "payables/validations",
            method="PUT",
            json={
                "required_fields": required_fields,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    PayableValidationsResource,
                    parse_obj_as(
                        type_=PayableValidationsResource,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def reset_validations(
        self, *, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[PayableValidationsResource]:
        """
        Reset payable validations to default ones.

        Parameters
        ----------
        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[PayableValidationsResource]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            "payables/validations/reset",
            method="POST",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    PayableValidationsResource,
                    parse_obj_as(
                        type_=PayableValidationsResource,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def get_variables(
        self, *, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[PayableTemplatesVariablesObjectList]:
        """
        Get a list of placeholders allowed to insert into an email template for customization

        Parameters
        ----------
        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[PayableTemplatesVariablesObjectList]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            "payables/variables",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    PayableTemplatesVariablesObjectList,
                    parse_obj_as(
                        type_=PayableTemplatesVariablesObjectList,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def get_by_id(
        self, payable_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[PayableResponseSchema]:
        """
        Retrieves information about a specific payable with the given ID.

        Parameters
        ----------
        payable_id : str

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[PayableResponseSchema]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"payables/{jsonable_encoder(payable_id)}",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    PayableResponseSchema,
                    parse_obj_as(
                        type_=PayableResponseSchema,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 409:
                raise ConflictError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def delete_by_id(
        self, payable_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[None]:
        """
        Deletes a specific payable.

        Parameters
        ----------
        payable_id : str

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[None]
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"payables/{jsonable_encoder(payable_id)}",
            method="DELETE",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return AsyncHttpResponse(response=_response, data=None)
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 409:
                raise ConflictError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def update_by_id(
        self,
        payable_id: str,
        *,
        counterpart_address_id: typing.Optional[str] = OMIT,
        counterpart_bank_account_id: typing.Optional[str] = OMIT,
        counterpart_id: typing.Optional[str] = OMIT,
        counterpart_raw_data: typing.Optional[CounterpartRawDataUpdateRequest] = OMIT,
        counterpart_vat_id_id: typing.Optional[str] = OMIT,
        currency: typing.Optional[CurrencyEnum] = OMIT,
        description: typing.Optional[str] = OMIT,
        discount: typing.Optional[int] = OMIT,
        document_id: typing.Optional[str] = OMIT,
        due_date: typing.Optional[str] = OMIT,
        issued_at: typing.Optional[str] = OMIT,
        partner_metadata: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = OMIT,
        payment_terms: typing.Optional[PayablePaymentTermsCreatePayload] = OMIT,
        project_id: typing.Optional[str] = OMIT,
        purchase_order_id: typing.Optional[str] = OMIT,
        sender: typing.Optional[str] = OMIT,
        subtotal: typing.Optional[int] = OMIT,
        suggested_payment_term: typing.Optional[SuggestedPaymentTerm] = OMIT,
        tag_ids: typing.Optional[typing.Sequence[str]] = OMIT,
        tax: typing.Optional[int] = OMIT,
        tax_amount: typing.Optional[int] = OMIT,
        total_amount: typing.Optional[int] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[PayableResponseSchema]:
        """
        Updates the information about a specific payable.

        Parameters
        ----------
        payable_id : str

        counterpart_address_id : typing.Optional[str]
            The ID of counterpart address object stored in counterparts service

        counterpart_bank_account_id : typing.Optional[str]
            The ID of counterpart bank account object stored in counterparts service

        counterpart_id : typing.Optional[str]
            The ID of the counterpart object that represents the vendor or supplier.

        counterpart_raw_data : typing.Optional[CounterpartRawDataUpdateRequest]
            Allows to fix some data in counterpart recognised fields to correct them in order to make autolinking happen.

        counterpart_vat_id_id : typing.Optional[str]
            The ID of counterpart VAT ID object stored in counterparts service

        currency : typing.Optional[CurrencyEnum]
            The [currency code](https://docs.monite.com/references/currencies) of the currency used in the payable.

        description : typing.Optional[str]
            An arbitrary description of this payable.

        discount : typing.Optional[int]
            The value of the additional discount that will be applied to the total amount. in [minor units](https://docs.monite.com/references/currencies#minor-units). For example, $12.50 is represented as 1250.

        document_id : typing.Optional[str]
            A unique invoice number assigned by the invoice issuer for payment tracking purposes.

        due_date : typing.Optional[str]
            The date by which the payable must be paid, in the YYYY-MM-DD format. If the payable specifies payment terms with early payment discounts, this is the final payment date.

        issued_at : typing.Optional[str]
            The date when the payable was issued, in the YYYY-MM-DD format.

        partner_metadata : typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]]
            Metadata for partner needs

        payment_terms : typing.Optional[PayablePaymentTermsCreatePayload]
            The number of days to pay with potential discount for options shorter than due_date

        project_id : typing.Optional[str]
            The project ID of the payable.

        purchase_order_id : typing.Optional[str]
            The identifier of the purchase order to which this payable belongs.

        sender : typing.Optional[str]
            The email address from which the invoice was sent to the entity.

        subtotal : typing.Optional[int]
            The subtotal amount to be paid, in [minor units](https://docs.monite.com/references/currencies#minor-units). For example, $12.50 is represented as 1250.

        suggested_payment_term : typing.Optional[SuggestedPaymentTerm]
            The suggested date and corresponding discount in which payable could be paid. The date is in the YYYY-MM-DD format. The discount is calculated as X * (10^-4) - for example, 100 is 1%, 25 is 0,25%, 10000 is 100 %. Date varies depending on the payment terms and may even be equal to the due date with discount 0.

        tag_ids : typing.Optional[typing.Sequence[str]]
            A list of IDs of user-defined tags (labels) assigned to this payable. Tags can be used to trigger a specific approval policy for this payable.

        tax : typing.Optional[int]
            Registered tax percentage applied for a service price in minor units, e.g. 200 means 2%, 1050 means 10.5%.

        tax_amount : typing.Optional[int]
            Tax amount in [minor units](https://docs.monite.com/references/currencies#minor-units). For example, $12.50 is represented as 1250.

        total_amount : typing.Optional[int]
            The total amount to be paid, in [minor units](https://docs.monite.com/references/currencies#minor-units). For example, $12.50 is represented as 1250.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[PayableResponseSchema]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"payables/{jsonable_encoder(payable_id)}",
            method="PATCH",
            json={
                "counterpart_address_id": counterpart_address_id,
                "counterpart_bank_account_id": counterpart_bank_account_id,
                "counterpart_id": counterpart_id,
                "counterpart_raw_data": convert_and_respect_annotation_metadata(
                    object_=counterpart_raw_data, annotation=CounterpartRawDataUpdateRequest, direction="write"
                ),
                "counterpart_vat_id_id": counterpart_vat_id_id,
                "currency": currency,
                "description": description,
                "discount": discount,
                "document_id": document_id,
                "due_date": due_date,
                "issued_at": issued_at,
                "partner_metadata": partner_metadata,
                "payment_terms": convert_and_respect_annotation_metadata(
                    object_=payment_terms, annotation=PayablePaymentTermsCreatePayload, direction="write"
                ),
                "project_id": project_id,
                "purchase_order_id": purchase_order_id,
                "sender": sender,
                "subtotal": subtotal,
                "suggested_payment_term": convert_and_respect_annotation_metadata(
                    object_=suggested_payment_term, annotation=SuggestedPaymentTerm, direction="write"
                ),
                "tag_ids": tag_ids,
                "tax": tax,
                "tax_amount": tax_amount,
                "total_amount": total_amount,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    PayableResponseSchema,
                    parse_obj_as(
                        type_=PayableResponseSchema,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 409:
                raise ConflictError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def approve_payment_by_id(
        self, payable_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[PayableResponseSchema]:
        """
        Confirms that the payable is ready to be paid.

        Parameters
        ----------
        payable_id : str

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[PayableResponseSchema]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"payables/{jsonable_encoder(payable_id)}/approve_payment_operation",
            method="POST",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    PayableResponseSchema,
                    parse_obj_as(
                        type_=PayableResponseSchema,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 409:
                raise ConflictError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def attach_file_by_id(
        self, payable_id: str, *, file: core.File, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[PayableResponseSchema]:
        """
        Attach file to payable without existing attachment.

        Parameters
        ----------
        payable_id : str

        file : core.File
            See core.File for more documentation

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[PayableResponseSchema]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"payables/{jsonable_encoder(payable_id)}/attach_file",
            method="POST",
            data={},
            files={
                "file": file,
            },
            headers={
                "content-type": "multipart/form-data",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    PayableResponseSchema,
                    parse_obj_as(
                        type_=PayableResponseSchema,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 409:
                raise ConflictError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def cancel_by_id(
        self, payable_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[PayableResponseSchema]:
        """
        Cancels the payable that was not confirmed during the review.

        Parameters
        ----------
        payable_id : str

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[PayableResponseSchema]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"payables/{jsonable_encoder(payable_id)}/cancel",
            method="POST",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    PayableResponseSchema,
                    parse_obj_as(
                        type_=PayableResponseSchema,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 409:
                raise ConflictError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def post_payables_id_cancel_ocr(
        self, payable_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[PayableResponseSchema]:
        """
        Request to cancel the OCR processing of the specified payable.

        Parameters
        ----------
        payable_id : str

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[PayableResponseSchema]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"payables/{jsonable_encoder(payable_id)}/cancel_ocr",
            method="POST",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    PayableResponseSchema,
                    parse_obj_as(
                        type_=PayableResponseSchema,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 409:
                raise ConflictError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def mark_as_paid_by_id(
        self,
        payable_id: str,
        *,
        comment: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[PayableResponseSchema]:
        """
        Mark a payable as paid.

        Payables can be paid using the payment channels offered by Monite or through external payment channels. In the latter
         case, the invoice is not automatically marked as paid in the system and needs to be converted to the paid status
         manually.

        Optionally, it is possible to pass the `comment` field in the request body, to describe how and when the invoice was
        paid.

        Notes:
        - To use this endpoint with an entity user token, this entity user must have a role that includes the `pay` permission
        for payables.
        - The `amount_to_pay` field is automatically calculated based on the `amount_due` less the percentage described
        in the `payment_terms.discount` value.

        Related guide: [Mark a payable as paid](https://docs.monite.com/accounts-payable/approvals/manual-transition#mark-as-paid)

        See also:

        [Payables lifecycle](https://docs.monite.com/accounts-payable/payables/index)

        [Payables status transitions](https://docs.monite.com/accounts-payable/payables/collect#suggested-payment-date)

        Parameters
        ----------
        payable_id : str

        comment : typing.Optional[str]
            An arbitrary comment that describes how and when this payable was paid.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[PayableResponseSchema]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"payables/{jsonable_encoder(payable_id)}/mark_as_paid",
            method="POST",
            json={
                "comment": comment,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    PayableResponseSchema,
                    parse_obj_as(
                        type_=PayableResponseSchema,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 409:
                raise ConflictError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def mark_as_partially_paid_by_id(
        self, payable_id: str, *, amount_paid: int, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[PayableResponseSchema]:
        """
        Mark a payable as partially paid.

        If the payable is partially paid, its status is moved to `partially_paid`. The value of the `amount_paid` field must be
         the sum of all payments made, not only the last one.

        Notes:
        - This endpoint can be used for payables in the `waiting_to_be_paid` status.
        - The `amount_paid` must be greater than 0 and less than the total payable amount specified by the `amount` field.
        - You can use this endpoint multiple times for the same payable to reflect multiple partial payments, always setting the
         sum of all payments made.
        - To use this endpoint with an entity user token, this entity user must have a role that includes the `pay`
        permission for payables.
        - The `amount_to_pay` field is automatically calculated based on the `amount_due` less the percentage described
        in the `payment_terms.discount` value.

        Related guide: [Mark a payable as partially paid](https://docs.monite.com/accounts-payable/approvals/manual-transition#mark-as-partially-paid)

        See also:

        [Payables lifecycle](https://docs.monite.com/accounts-payable/payables/index)

        [Payables status transitions](https://docs.monite.com/accounts-payable/payables/collect#suggested-payment-date)

        [Mark a payable as paid](https://docs.monite.com/accounts-payable/approvals/manual-transition#mark-as-paid)

        Parameters
        ----------
        payable_id : str

        amount_paid : int
            How much was paid on the invoice (in minor units).

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[PayableResponseSchema]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"payables/{jsonable_encoder(payable_id)}/mark_as_partially_paid",
            method="POST",
            json={
                "amount_paid": amount_paid,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    PayableResponseSchema,
                    parse_obj_as(
                        type_=PayableResponseSchema,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 409:
                raise ConflictError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def reject_by_id(
        self, payable_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[PayableResponseSchema]:
        """
        Declines the payable when an approver finds any mismatch or discrepancies.

        Parameters
        ----------
        payable_id : str

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[PayableResponseSchema]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"payables/{jsonable_encoder(payable_id)}/reject",
            method="POST",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    PayableResponseSchema,
                    parse_obj_as(
                        type_=PayableResponseSchema,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 409:
                raise ConflictError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def reopen_by_id(
        self, payable_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[PayableResponseSchema]:
        """
        Reset payable state from rejected to new.

        Parameters
        ----------
        payable_id : str

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[PayableResponseSchema]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"payables/{jsonable_encoder(payable_id)}/reopen",
            method="POST",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    PayableResponseSchema,
                    parse_obj_as(
                        type_=PayableResponseSchema,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 409:
                raise ConflictError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def submit_for_approval_by_id(
        self, payable_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[PayableResponseSchema]:
        """
        Starts the approval process once the uploaded payable is validated.

        Parameters
        ----------
        payable_id : str

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[PayableResponseSchema]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"payables/{jsonable_encoder(payable_id)}/submit_for_approval",
            method="POST",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    PayableResponseSchema,
                    parse_obj_as(
                        type_=PayableResponseSchema,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 409:
                raise ConflictError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def validate_by_id(
        self, payable_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[PayableValidationResponse]:
        """
        Check the invoice for compliance with the requirements for movement from draft to new status.

        Parameters
        ----------
        payable_id : str

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[PayableValidationResponse]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"payables/{jsonable_encoder(payable_id)}/validate",
            method="POST",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    PayableValidationResponse,
                    parse_obj_as(
                        type_=PayableValidationResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 409:
                raise ConflictError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
