"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""

from .basesdk import BaseSDK
from apideck_unify import models, utils
from apideck_unify._hooks import HookContext
from apideck_unify.types import OptionalNullable, UNSET
from apideck_unify.utils import get_security_from_env
from datetime import date
from jsonpath import JSONPath
from typing import Any, Dict, List, Mapping, Optional, Union


class Bills(BaseSDK):
    def list(
        self,
        *,
        raw: Optional[bool] = False,
        service_id: Optional[str] = None,
        cursor: OptionalNullable[str] = UNSET,
        limit: Optional[int] = 20,
        filter_: Optional[
            Union[models.BillsFilter, models.BillsFilterTypedDict]
        ] = None,
        sort: Optional[Union[models.BillsSort, models.BillsSortTypedDict]] = None,
        pass_through: Optional[Dict[str, Any]] = None,
        fields: OptionalNullable[str] = UNSET,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> Optional[models.AccountingBillsAllResponse]:
        r"""List Bills

        List Bills

        :param raw: Include raw response. Mostly used for debugging purposes
        :param service_id: Provide the service id you want to call (e.g., pipedrive). Only needed when a consumer has activated multiple integrations for a Unified API.
        :param cursor: Cursor to start from. You can find cursors for next/previous pages in the meta.cursors property of the response.
        :param limit: Number of results to return. Minimum 1, Maximum 200, Default 20
        :param filter_: Apply filters
        :param sort: Apply sorting
        :param pass_through: Optional unmapped key/values that will be passed through to downstream as query parameters. Ie: ?pass_through[search]=leads becomes ?search=leads
        :param fields: The 'fields' parameter allows API users to specify the fields they want to include in the API response. If this parameter is not present, the API will return all available fields. If this parameter is present, only the fields specified in the comma-separated string will be included in the response. Nested properties can also be requested by using a dot notation. <br /><br />Example: `fields=name,email,addresses.city`<br /><br />In the example above, the response will only include the fields \"name\", \"email\" and \"addresses.city\". If any other fields are available, they will be excluded.
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

        if server_url is not None:
            base_url = server_url

        request = models.AccountingBillsAllRequest(
            raw=raw,
            service_id=service_id,
            cursor=cursor,
            limit=limit,
            filter_=utils.get_pydantic_model(filter_, Optional[models.BillsFilter]),
            sort=utils.get_pydantic_model(sort, Optional[models.BillsSort]),
            pass_through=pass_through,
            fields=fields,
        )

        req = self._build_request(
            method="GET",
            path="/accounting/bills",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=False,
            request_has_path_params=False,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            _globals=models.AccountingBillsAllGlobals(
                consumer_id=self.sdk_configuration.globals.consumer_id,
                app_id=self.sdk_configuration.globals.app_id,
            ),
            security=self.sdk_configuration.security,
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config
            else:
                retries = utils.RetryConfig(
                    "backoff", utils.BackoffStrategy(500, 60000, 1.5, 3600000), True
                )

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["5XX"])

        http_res = self.do_request(
            hook_ctx=HookContext(
                operation_id="accounting.billsAll",
                oauth2_scopes=[],
                security_source=get_security_from_env(
                    self.sdk_configuration.security, models.Security
                ),
            ),
            request=req,
            error_status_codes=["400", "401", "402", "404", "422", "4XX", "5XX"],
            retry_config=retry_config,
        )

        def next_func() -> Optional[models.AccountingBillsAllResponse]:
            body = utils.unmarshal_json(http_res.text, Dict[Any, Any])
            next_cursor = JSONPath("$.meta.cursors.next").parse(body)

            if len(next_cursor) == 0:
                return None
            next_cursor = next_cursor[0]

            return self.list(
                raw=raw,
                service_id=service_id,
                cursor=next_cursor,
                limit=limit,
                filter_=filter_,
                sort=sort,
                pass_through=pass_through,
                fields=fields,
                retries=retries,
            )

        data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return models.AccountingBillsAllResponse(
                get_bills_response=utils.unmarshal_json(
                    http_res.text, Optional[models.GetBillsResponse]
                ),
                http_meta=models.HTTPMetadata(request=req, response=http_res),
                next=next_func,
            )
        if utils.match_response(http_res, "400", "application/json"):
            data = utils.unmarshal_json(http_res.text, models.BadRequestResponseData)
            raise models.BadRequestResponse(data=data)
        if utils.match_response(http_res, "401", "application/json"):
            data = utils.unmarshal_json(http_res.text, models.UnauthorizedResponseData)
            raise models.UnauthorizedResponse(data=data)
        if utils.match_response(http_res, "402", "application/json"):
            data = utils.unmarshal_json(
                http_res.text, models.PaymentRequiredResponseData
            )
            raise models.PaymentRequiredResponse(data=data)
        if utils.match_response(http_res, "404", "application/json"):
            data = utils.unmarshal_json(http_res.text, models.NotFoundResponseData)
            raise models.NotFoundResponse(data=data)
        if utils.match_response(http_res, "422", "application/json"):
            data = utils.unmarshal_json(http_res.text, models.UnprocessableResponseData)
            raise models.UnprocessableResponse(data=data)
        if utils.match_response(http_res, ["4XX", "5XX"], "*"):
            http_res_text = utils.stream_to_text(http_res)
            raise models.APIError(
                "API error occurred", http_res.status_code, http_res_text, http_res
            )
        if utils.match_response(http_res, "default", "application/json"):
            return models.AccountingBillsAllResponse(
                unexpected_error_response=utils.unmarshal_json(
                    http_res.text, Optional[models.UnexpectedErrorResponse]
                ),
                http_meta=models.HTTPMetadata(request=req, response=http_res),
                next=next_func,
            )

        content_type = http_res.headers.get("Content-Type")
        http_res_text = utils.stream_to_text(http_res)
        raise models.APIError(
            f"Unexpected response received (code: {http_res.status_code}, type: {content_type})",
            http_res.status_code,
            http_res_text,
            http_res,
        )

    async def list_async(
        self,
        *,
        raw: Optional[bool] = False,
        service_id: Optional[str] = None,
        cursor: OptionalNullable[str] = UNSET,
        limit: Optional[int] = 20,
        filter_: Optional[
            Union[models.BillsFilter, models.BillsFilterTypedDict]
        ] = None,
        sort: Optional[Union[models.BillsSort, models.BillsSortTypedDict]] = None,
        pass_through: Optional[Dict[str, Any]] = None,
        fields: OptionalNullable[str] = UNSET,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> Optional[models.AccountingBillsAllResponse]:
        r"""List Bills

        List Bills

        :param raw: Include raw response. Mostly used for debugging purposes
        :param service_id: Provide the service id you want to call (e.g., pipedrive). Only needed when a consumer has activated multiple integrations for a Unified API.
        :param cursor: Cursor to start from. You can find cursors for next/previous pages in the meta.cursors property of the response.
        :param limit: Number of results to return. Minimum 1, Maximum 200, Default 20
        :param filter_: Apply filters
        :param sort: Apply sorting
        :param pass_through: Optional unmapped key/values that will be passed through to downstream as query parameters. Ie: ?pass_through[search]=leads becomes ?search=leads
        :param fields: The 'fields' parameter allows API users to specify the fields they want to include in the API response. If this parameter is not present, the API will return all available fields. If this parameter is present, only the fields specified in the comma-separated string will be included in the response. Nested properties can also be requested by using a dot notation. <br /><br />Example: `fields=name,email,addresses.city`<br /><br />In the example above, the response will only include the fields \"name\", \"email\" and \"addresses.city\". If any other fields are available, they will be excluded.
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

        if server_url is not None:
            base_url = server_url

        request = models.AccountingBillsAllRequest(
            raw=raw,
            service_id=service_id,
            cursor=cursor,
            limit=limit,
            filter_=utils.get_pydantic_model(filter_, Optional[models.BillsFilter]),
            sort=utils.get_pydantic_model(sort, Optional[models.BillsSort]),
            pass_through=pass_through,
            fields=fields,
        )

        req = self._build_request_async(
            method="GET",
            path="/accounting/bills",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=False,
            request_has_path_params=False,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            _globals=models.AccountingBillsAllGlobals(
                consumer_id=self.sdk_configuration.globals.consumer_id,
                app_id=self.sdk_configuration.globals.app_id,
            ),
            security=self.sdk_configuration.security,
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config
            else:
                retries = utils.RetryConfig(
                    "backoff", utils.BackoffStrategy(500, 60000, 1.5, 3600000), True
                )

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["5XX"])

        http_res = await self.do_request_async(
            hook_ctx=HookContext(
                operation_id="accounting.billsAll",
                oauth2_scopes=[],
                security_source=get_security_from_env(
                    self.sdk_configuration.security, models.Security
                ),
            ),
            request=req,
            error_status_codes=["400", "401", "402", "404", "422", "4XX", "5XX"],
            retry_config=retry_config,
        )

        def next_func() -> Optional[models.AccountingBillsAllResponse]:
            body = utils.unmarshal_json(http_res.text, Dict[Any, Any])
            next_cursor = JSONPath("$.meta.cursors.next").parse(body)

            if len(next_cursor) == 0:
                return None
            next_cursor = next_cursor[0]

            return self.list(
                raw=raw,
                service_id=service_id,
                cursor=next_cursor,
                limit=limit,
                filter_=filter_,
                sort=sort,
                pass_through=pass_through,
                fields=fields,
                retries=retries,
            )

        data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return models.AccountingBillsAllResponse(
                get_bills_response=utils.unmarshal_json(
                    http_res.text, Optional[models.GetBillsResponse]
                ),
                http_meta=models.HTTPMetadata(request=req, response=http_res),
                next=next_func,
            )
        if utils.match_response(http_res, "400", "application/json"):
            data = utils.unmarshal_json(http_res.text, models.BadRequestResponseData)
            raise models.BadRequestResponse(data=data)
        if utils.match_response(http_res, "401", "application/json"):
            data = utils.unmarshal_json(http_res.text, models.UnauthorizedResponseData)
            raise models.UnauthorizedResponse(data=data)
        if utils.match_response(http_res, "402", "application/json"):
            data = utils.unmarshal_json(
                http_res.text, models.PaymentRequiredResponseData
            )
            raise models.PaymentRequiredResponse(data=data)
        if utils.match_response(http_res, "404", "application/json"):
            data = utils.unmarshal_json(http_res.text, models.NotFoundResponseData)
            raise models.NotFoundResponse(data=data)
        if utils.match_response(http_res, "422", "application/json"):
            data = utils.unmarshal_json(http_res.text, models.UnprocessableResponseData)
            raise models.UnprocessableResponse(data=data)
        if utils.match_response(http_res, ["4XX", "5XX"], "*"):
            http_res_text = await utils.stream_to_text_async(http_res)
            raise models.APIError(
                "API error occurred", http_res.status_code, http_res_text, http_res
            )
        if utils.match_response(http_res, "default", "application/json"):
            return models.AccountingBillsAllResponse(
                unexpected_error_response=utils.unmarshal_json(
                    http_res.text, Optional[models.UnexpectedErrorResponse]
                ),
                http_meta=models.HTTPMetadata(request=req, response=http_res),
                next=next_func,
            )

        content_type = http_res.headers.get("Content-Type")
        http_res_text = await utils.stream_to_text_async(http_res)
        raise models.APIError(
            f"Unexpected response received (code: {http_res.status_code}, type: {content_type})",
            http_res.status_code,
            http_res_text,
            http_res,
        )

    def create(
        self,
        *,
        raw: Optional[bool] = False,
        service_id: Optional[str] = None,
        bill_number: OptionalNullable[str] = UNSET,
        supplier: OptionalNullable[
            Union[models.LinkedSupplierInput, models.LinkedSupplierInputTypedDict]
        ] = UNSET,
        company_id: OptionalNullable[str] = UNSET,
        currency: OptionalNullable[models.Currency] = UNSET,
        currency_rate: OptionalNullable[float] = UNSET,
        tax_inclusive: OptionalNullable[bool] = UNSET,
        bill_date: OptionalNullable[date] = UNSET,
        due_date: OptionalNullable[date] = UNSET,
        paid_date: OptionalNullable[date] = UNSET,
        po_number: OptionalNullable[str] = UNSET,
        reference: OptionalNullable[str] = UNSET,
        line_items: Optional[
            Union[
                List[models.BillLineItemInput], List[models.BillLineItemInputTypedDict]
            ]
        ] = None,
        terms: OptionalNullable[str] = UNSET,
        balance: OptionalNullable[float] = UNSET,
        deposit: OptionalNullable[float] = UNSET,
        sub_total: OptionalNullable[float] = UNSET,
        total_tax: OptionalNullable[float] = UNSET,
        total: OptionalNullable[float] = UNSET,
        tax_code: OptionalNullable[str] = UNSET,
        notes: OptionalNullable[str] = UNSET,
        status: OptionalNullable[models.BillStatus] = UNSET,
        ledger_account: OptionalNullable[
            Union[
                models.LinkedLedgerAccountInput,
                models.LinkedLedgerAccountInputTypedDict,
            ]
        ] = UNSET,
        payment_method: OptionalNullable[str] = UNSET,
        channel: OptionalNullable[str] = UNSET,
        language: OptionalNullable[str] = UNSET,
        accounting_by_row: OptionalNullable[bool] = UNSET,
        bank_account: Optional[
            Union[models.BankAccount, models.BankAccountTypedDict]
        ] = None,
        discount_percentage: OptionalNullable[float] = UNSET,
        tracking_categories: OptionalNullable[
            Union[
                List[models.LinkedTrackingCategory],
                List[models.LinkedTrackingCategoryTypedDict],
            ]
        ] = UNSET,
        row_version: OptionalNullable[str] = UNSET,
        custom_fields: Optional[
            Union[List[models.CustomField], List[models.CustomFieldTypedDict]]
        ] = None,
        pass_through: Optional[
            Union[List[models.PassThroughBody], List[models.PassThroughBodyTypedDict]]
        ] = None,
        accounting_period: OptionalNullable[str] = UNSET,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.AccountingBillsAddResponse:
        r"""Create Bill

        Create Bill

        :param raw: Include raw response. Mostly used for debugging purposes
        :param service_id: Provide the service id you want to call (e.g., pipedrive). Only needed when a consumer has activated multiple integrations for a Unified API.
        :param bill_number: Reference to supplier bill number
        :param supplier: The supplier this entity is linked to.
        :param company_id: The company or subsidiary id the transaction belongs to
        :param currency: Indicates the associated currency for an amount of money. Values correspond to [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217).
        :param currency_rate: Currency Exchange Rate at the time entity was recorded/generated.
        :param tax_inclusive: Amounts are including tax
        :param bill_date: Date bill was issued - YYYY-MM-DD.
        :param due_date: The due date is the date on which a payment is scheduled to be received - YYYY-MM-DD.
        :param paid_date: The paid date is the date on which a payment was sent to the supplier - YYYY-MM-DD.
        :param po_number: A PO Number uniquely identifies a purchase order and is generally defined by the buyer. The buyer will match the PO number in the invoice to the Purchase Order.
        :param reference: Optional bill reference.
        :param line_items:
        :param terms: Terms of payment.
        :param balance: Balance of bill due.
        :param deposit: Amount of deposit made to this bill.
        :param sub_total: Sub-total amount, normally before tax.
        :param total_tax: Total tax amount applied to this bill.
        :param total: Total amount of bill, including tax.
        :param tax_code: Applicable tax id/code override if tax is not supplied on a line item basis.
        :param notes:
        :param status: Invoice status
        :param ledger_account:
        :param payment_method: Payment method used for the transaction, such as cash, credit card, bank transfer, or check
        :param channel: The channel through which the transaction is processed.
        :param language: language code according to ISO 639-1. For the United States - EN
        :param accounting_by_row: Indicates if accounting by row is used (true) or not (false). Accounting by row means that a separate ledger transaction is created for each row.
        :param bank_account:
        :param discount_percentage: Discount percentage applied to this transaction.
        :param tracking_categories: A list of linked tracking categories.
        :param row_version: A binary value used to detect updates to a object and prevent data conflicts. It is incremented each time an update is made to the object.
        :param custom_fields:
        :param pass_through: The pass_through property allows passing service-specific, custom data or structured modifications in request body when creating or updating resources.
        :param accounting_period: Accounting period
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

        if server_url is not None:
            base_url = server_url

        request = models.AccountingBillsAddRequest(
            raw=raw,
            service_id=service_id,
            bill=models.BillInput(
                bill_number=bill_number,
                supplier=utils.get_pydantic_model(
                    supplier, OptionalNullable[models.LinkedSupplierInput]
                ),
                company_id=company_id,
                currency=currency,
                currency_rate=currency_rate,
                tax_inclusive=tax_inclusive,
                bill_date=bill_date,
                due_date=due_date,
                paid_date=paid_date,
                po_number=po_number,
                reference=reference,
                line_items=utils.get_pydantic_model(
                    line_items, Optional[List[models.BillLineItemInput]]
                ),
                terms=terms,
                balance=balance,
                deposit=deposit,
                sub_total=sub_total,
                total_tax=total_tax,
                total=total,
                tax_code=tax_code,
                notes=notes,
                status=status,
                ledger_account=utils.get_pydantic_model(
                    ledger_account, OptionalNullable[models.LinkedLedgerAccountInput]
                ),
                payment_method=payment_method,
                channel=channel,
                language=language,
                accounting_by_row=accounting_by_row,
                bank_account=utils.get_pydantic_model(
                    bank_account, Optional[models.BankAccount]
                ),
                discount_percentage=discount_percentage,
                tracking_categories=utils.get_pydantic_model(
                    tracking_categories,
                    OptionalNullable[List[models.LinkedTrackingCategory]],
                ),
                row_version=row_version,
                custom_fields=utils.get_pydantic_model(
                    custom_fields, Optional[List[models.CustomField]]
                ),
                pass_through=utils.get_pydantic_model(
                    pass_through, Optional[List[models.PassThroughBody]]
                ),
                accounting_period=accounting_period,
            ),
        )

        req = self._build_request(
            method="POST",
            path="/accounting/bills",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=True,
            request_has_path_params=False,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            _globals=models.AccountingBillsAddGlobals(
                consumer_id=self.sdk_configuration.globals.consumer_id,
                app_id=self.sdk_configuration.globals.app_id,
            ),
            security=self.sdk_configuration.security,
            get_serialized_body=lambda: utils.serialize_request_body(
                request.bill, False, False, "json", models.BillInput
            ),
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config
            else:
                retries = utils.RetryConfig(
                    "backoff", utils.BackoffStrategy(500, 60000, 1.5, 3600000), True
                )

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["5XX"])

        http_res = self.do_request(
            hook_ctx=HookContext(
                operation_id="accounting.billsAdd",
                oauth2_scopes=[],
                security_source=get_security_from_env(
                    self.sdk_configuration.security, models.Security
                ),
            ),
            request=req,
            error_status_codes=["400", "401", "402", "404", "422", "4XX", "5XX"],
            retry_config=retry_config,
        )

        data: Any = None
        if utils.match_response(http_res, "201", "application/json"):
            return models.AccountingBillsAddResponse(
                create_bill_response=utils.unmarshal_json(
                    http_res.text, Optional[models.CreateBillResponse]
                ),
                http_meta=models.HTTPMetadata(request=req, response=http_res),
            )
        if utils.match_response(http_res, "400", "application/json"):
            data = utils.unmarshal_json(http_res.text, models.BadRequestResponseData)
            raise models.BadRequestResponse(data=data)
        if utils.match_response(http_res, "401", "application/json"):
            data = utils.unmarshal_json(http_res.text, models.UnauthorizedResponseData)
            raise models.UnauthorizedResponse(data=data)
        if utils.match_response(http_res, "402", "application/json"):
            data = utils.unmarshal_json(
                http_res.text, models.PaymentRequiredResponseData
            )
            raise models.PaymentRequiredResponse(data=data)
        if utils.match_response(http_res, "404", "application/json"):
            data = utils.unmarshal_json(http_res.text, models.NotFoundResponseData)
            raise models.NotFoundResponse(data=data)
        if utils.match_response(http_res, "422", "application/json"):
            data = utils.unmarshal_json(http_res.text, models.UnprocessableResponseData)
            raise models.UnprocessableResponse(data=data)
        if utils.match_response(http_res, ["4XX", "5XX"], "*"):
            http_res_text = utils.stream_to_text(http_res)
            raise models.APIError(
                "API error occurred", http_res.status_code, http_res_text, http_res
            )
        if utils.match_response(http_res, "default", "application/json"):
            return models.AccountingBillsAddResponse(
                unexpected_error_response=utils.unmarshal_json(
                    http_res.text, Optional[models.UnexpectedErrorResponse]
                ),
                http_meta=models.HTTPMetadata(request=req, response=http_res),
            )

        content_type = http_res.headers.get("Content-Type")
        http_res_text = utils.stream_to_text(http_res)
        raise models.APIError(
            f"Unexpected response received (code: {http_res.status_code}, type: {content_type})",
            http_res.status_code,
            http_res_text,
            http_res,
        )

    async def create_async(
        self,
        *,
        raw: Optional[bool] = False,
        service_id: Optional[str] = None,
        bill_number: OptionalNullable[str] = UNSET,
        supplier: OptionalNullable[
            Union[models.LinkedSupplierInput, models.LinkedSupplierInputTypedDict]
        ] = UNSET,
        company_id: OptionalNullable[str] = UNSET,
        currency: OptionalNullable[models.Currency] = UNSET,
        currency_rate: OptionalNullable[float] = UNSET,
        tax_inclusive: OptionalNullable[bool] = UNSET,
        bill_date: OptionalNullable[date] = UNSET,
        due_date: OptionalNullable[date] = UNSET,
        paid_date: OptionalNullable[date] = UNSET,
        po_number: OptionalNullable[str] = UNSET,
        reference: OptionalNullable[str] = UNSET,
        line_items: Optional[
            Union[
                List[models.BillLineItemInput], List[models.BillLineItemInputTypedDict]
            ]
        ] = None,
        terms: OptionalNullable[str] = UNSET,
        balance: OptionalNullable[float] = UNSET,
        deposit: OptionalNullable[float] = UNSET,
        sub_total: OptionalNullable[float] = UNSET,
        total_tax: OptionalNullable[float] = UNSET,
        total: OptionalNullable[float] = UNSET,
        tax_code: OptionalNullable[str] = UNSET,
        notes: OptionalNullable[str] = UNSET,
        status: OptionalNullable[models.BillStatus] = UNSET,
        ledger_account: OptionalNullable[
            Union[
                models.LinkedLedgerAccountInput,
                models.LinkedLedgerAccountInputTypedDict,
            ]
        ] = UNSET,
        payment_method: OptionalNullable[str] = UNSET,
        channel: OptionalNullable[str] = UNSET,
        language: OptionalNullable[str] = UNSET,
        accounting_by_row: OptionalNullable[bool] = UNSET,
        bank_account: Optional[
            Union[models.BankAccount, models.BankAccountTypedDict]
        ] = None,
        discount_percentage: OptionalNullable[float] = UNSET,
        tracking_categories: OptionalNullable[
            Union[
                List[models.LinkedTrackingCategory],
                List[models.LinkedTrackingCategoryTypedDict],
            ]
        ] = UNSET,
        row_version: OptionalNullable[str] = UNSET,
        custom_fields: Optional[
            Union[List[models.CustomField], List[models.CustomFieldTypedDict]]
        ] = None,
        pass_through: Optional[
            Union[List[models.PassThroughBody], List[models.PassThroughBodyTypedDict]]
        ] = None,
        accounting_period: OptionalNullable[str] = UNSET,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.AccountingBillsAddResponse:
        r"""Create Bill

        Create Bill

        :param raw: Include raw response. Mostly used for debugging purposes
        :param service_id: Provide the service id you want to call (e.g., pipedrive). Only needed when a consumer has activated multiple integrations for a Unified API.
        :param bill_number: Reference to supplier bill number
        :param supplier: The supplier this entity is linked to.
        :param company_id: The company or subsidiary id the transaction belongs to
        :param currency: Indicates the associated currency for an amount of money. Values correspond to [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217).
        :param currency_rate: Currency Exchange Rate at the time entity was recorded/generated.
        :param tax_inclusive: Amounts are including tax
        :param bill_date: Date bill was issued - YYYY-MM-DD.
        :param due_date: The due date is the date on which a payment is scheduled to be received - YYYY-MM-DD.
        :param paid_date: The paid date is the date on which a payment was sent to the supplier - YYYY-MM-DD.
        :param po_number: A PO Number uniquely identifies a purchase order and is generally defined by the buyer. The buyer will match the PO number in the invoice to the Purchase Order.
        :param reference: Optional bill reference.
        :param line_items:
        :param terms: Terms of payment.
        :param balance: Balance of bill due.
        :param deposit: Amount of deposit made to this bill.
        :param sub_total: Sub-total amount, normally before tax.
        :param total_tax: Total tax amount applied to this bill.
        :param total: Total amount of bill, including tax.
        :param tax_code: Applicable tax id/code override if tax is not supplied on a line item basis.
        :param notes:
        :param status: Invoice status
        :param ledger_account:
        :param payment_method: Payment method used for the transaction, such as cash, credit card, bank transfer, or check
        :param channel: The channel through which the transaction is processed.
        :param language: language code according to ISO 639-1. For the United States - EN
        :param accounting_by_row: Indicates if accounting by row is used (true) or not (false). Accounting by row means that a separate ledger transaction is created for each row.
        :param bank_account:
        :param discount_percentage: Discount percentage applied to this transaction.
        :param tracking_categories: A list of linked tracking categories.
        :param row_version: A binary value used to detect updates to a object and prevent data conflicts. It is incremented each time an update is made to the object.
        :param custom_fields:
        :param pass_through: The pass_through property allows passing service-specific, custom data or structured modifications in request body when creating or updating resources.
        :param accounting_period: Accounting period
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

        if server_url is not None:
            base_url = server_url

        request = models.AccountingBillsAddRequest(
            raw=raw,
            service_id=service_id,
            bill=models.BillInput(
                bill_number=bill_number,
                supplier=utils.get_pydantic_model(
                    supplier, OptionalNullable[models.LinkedSupplierInput]
                ),
                company_id=company_id,
                currency=currency,
                currency_rate=currency_rate,
                tax_inclusive=tax_inclusive,
                bill_date=bill_date,
                due_date=due_date,
                paid_date=paid_date,
                po_number=po_number,
                reference=reference,
                line_items=utils.get_pydantic_model(
                    line_items, Optional[List[models.BillLineItemInput]]
                ),
                terms=terms,
                balance=balance,
                deposit=deposit,
                sub_total=sub_total,
                total_tax=total_tax,
                total=total,
                tax_code=tax_code,
                notes=notes,
                status=status,
                ledger_account=utils.get_pydantic_model(
                    ledger_account, OptionalNullable[models.LinkedLedgerAccountInput]
                ),
                payment_method=payment_method,
                channel=channel,
                language=language,
                accounting_by_row=accounting_by_row,
                bank_account=utils.get_pydantic_model(
                    bank_account, Optional[models.BankAccount]
                ),
                discount_percentage=discount_percentage,
                tracking_categories=utils.get_pydantic_model(
                    tracking_categories,
                    OptionalNullable[List[models.LinkedTrackingCategory]],
                ),
                row_version=row_version,
                custom_fields=utils.get_pydantic_model(
                    custom_fields, Optional[List[models.CustomField]]
                ),
                pass_through=utils.get_pydantic_model(
                    pass_through, Optional[List[models.PassThroughBody]]
                ),
                accounting_period=accounting_period,
            ),
        )

        req = self._build_request_async(
            method="POST",
            path="/accounting/bills",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=True,
            request_has_path_params=False,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            _globals=models.AccountingBillsAddGlobals(
                consumer_id=self.sdk_configuration.globals.consumer_id,
                app_id=self.sdk_configuration.globals.app_id,
            ),
            security=self.sdk_configuration.security,
            get_serialized_body=lambda: utils.serialize_request_body(
                request.bill, False, False, "json", models.BillInput
            ),
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config
            else:
                retries = utils.RetryConfig(
                    "backoff", utils.BackoffStrategy(500, 60000, 1.5, 3600000), True
                )

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["5XX"])

        http_res = await self.do_request_async(
            hook_ctx=HookContext(
                operation_id="accounting.billsAdd",
                oauth2_scopes=[],
                security_source=get_security_from_env(
                    self.sdk_configuration.security, models.Security
                ),
            ),
            request=req,
            error_status_codes=["400", "401", "402", "404", "422", "4XX", "5XX"],
            retry_config=retry_config,
        )

        data: Any = None
        if utils.match_response(http_res, "201", "application/json"):
            return models.AccountingBillsAddResponse(
                create_bill_response=utils.unmarshal_json(
                    http_res.text, Optional[models.CreateBillResponse]
                ),
                http_meta=models.HTTPMetadata(request=req, response=http_res),
            )
        if utils.match_response(http_res, "400", "application/json"):
            data = utils.unmarshal_json(http_res.text, models.BadRequestResponseData)
            raise models.BadRequestResponse(data=data)
        if utils.match_response(http_res, "401", "application/json"):
            data = utils.unmarshal_json(http_res.text, models.UnauthorizedResponseData)
            raise models.UnauthorizedResponse(data=data)
        if utils.match_response(http_res, "402", "application/json"):
            data = utils.unmarshal_json(
                http_res.text, models.PaymentRequiredResponseData
            )
            raise models.PaymentRequiredResponse(data=data)
        if utils.match_response(http_res, "404", "application/json"):
            data = utils.unmarshal_json(http_res.text, models.NotFoundResponseData)
            raise models.NotFoundResponse(data=data)
        if utils.match_response(http_res, "422", "application/json"):
            data = utils.unmarshal_json(http_res.text, models.UnprocessableResponseData)
            raise models.UnprocessableResponse(data=data)
        if utils.match_response(http_res, ["4XX", "5XX"], "*"):
            http_res_text = await utils.stream_to_text_async(http_res)
            raise models.APIError(
                "API error occurred", http_res.status_code, http_res_text, http_res
            )
        if utils.match_response(http_res, "default", "application/json"):
            return models.AccountingBillsAddResponse(
                unexpected_error_response=utils.unmarshal_json(
                    http_res.text, Optional[models.UnexpectedErrorResponse]
                ),
                http_meta=models.HTTPMetadata(request=req, response=http_res),
            )

        content_type = http_res.headers.get("Content-Type")
        http_res_text = await utils.stream_to_text_async(http_res)
        raise models.APIError(
            f"Unexpected response received (code: {http_res.status_code}, type: {content_type})",
            http_res.status_code,
            http_res_text,
            http_res,
        )

    def get(
        self,
        *,
        id: str,
        service_id: Optional[str] = None,
        raw: Optional[bool] = False,
        fields: OptionalNullable[str] = UNSET,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.AccountingBillsOneResponse:
        r"""Get Bill

        Get Bill

        :param id: ID of the record you are acting upon.
        :param service_id: Provide the service id you want to call (e.g., pipedrive). Only needed when a consumer has activated multiple integrations for a Unified API.
        :param raw: Include raw response. Mostly used for debugging purposes
        :param fields: The 'fields' parameter allows API users to specify the fields they want to include in the API response. If this parameter is not present, the API will return all available fields. If this parameter is present, only the fields specified in the comma-separated string will be included in the response. Nested properties can also be requested by using a dot notation. <br /><br />Example: `fields=name,email,addresses.city`<br /><br />In the example above, the response will only include the fields \"name\", \"email\" and \"addresses.city\". If any other fields are available, they will be excluded.
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

        if server_url is not None:
            base_url = server_url

        request = models.AccountingBillsOneRequest(
            id=id,
            service_id=service_id,
            raw=raw,
            fields=fields,
        )

        req = self._build_request(
            method="GET",
            path="/accounting/bills/{id}",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=False,
            request_has_path_params=True,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            _globals=models.AccountingBillsOneGlobals(
                consumer_id=self.sdk_configuration.globals.consumer_id,
                app_id=self.sdk_configuration.globals.app_id,
            ),
            security=self.sdk_configuration.security,
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config
            else:
                retries = utils.RetryConfig(
                    "backoff", utils.BackoffStrategy(500, 60000, 1.5, 3600000), True
                )

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["5XX"])

        http_res = self.do_request(
            hook_ctx=HookContext(
                operation_id="accounting.billsOne",
                oauth2_scopes=[],
                security_source=get_security_from_env(
                    self.sdk_configuration.security, models.Security
                ),
            ),
            request=req,
            error_status_codes=["400", "401", "402", "404", "422", "4XX", "5XX"],
            retry_config=retry_config,
        )

        data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return models.AccountingBillsOneResponse(
                get_bill_response=utils.unmarshal_json(
                    http_res.text, Optional[models.GetBillResponse]
                ),
                http_meta=models.HTTPMetadata(request=req, response=http_res),
            )
        if utils.match_response(http_res, "400", "application/json"):
            data = utils.unmarshal_json(http_res.text, models.BadRequestResponseData)
            raise models.BadRequestResponse(data=data)
        if utils.match_response(http_res, "401", "application/json"):
            data = utils.unmarshal_json(http_res.text, models.UnauthorizedResponseData)
            raise models.UnauthorizedResponse(data=data)
        if utils.match_response(http_res, "402", "application/json"):
            data = utils.unmarshal_json(
                http_res.text, models.PaymentRequiredResponseData
            )
            raise models.PaymentRequiredResponse(data=data)
        if utils.match_response(http_res, "404", "application/json"):
            data = utils.unmarshal_json(http_res.text, models.NotFoundResponseData)
            raise models.NotFoundResponse(data=data)
        if utils.match_response(http_res, "422", "application/json"):
            data = utils.unmarshal_json(http_res.text, models.UnprocessableResponseData)
            raise models.UnprocessableResponse(data=data)
        if utils.match_response(http_res, ["4XX", "5XX"], "*"):
            http_res_text = utils.stream_to_text(http_res)
            raise models.APIError(
                "API error occurred", http_res.status_code, http_res_text, http_res
            )
        if utils.match_response(http_res, "default", "application/json"):
            return models.AccountingBillsOneResponse(
                unexpected_error_response=utils.unmarshal_json(
                    http_res.text, Optional[models.UnexpectedErrorResponse]
                ),
                http_meta=models.HTTPMetadata(request=req, response=http_res),
            )

        content_type = http_res.headers.get("Content-Type")
        http_res_text = utils.stream_to_text(http_res)
        raise models.APIError(
            f"Unexpected response received (code: {http_res.status_code}, type: {content_type})",
            http_res.status_code,
            http_res_text,
            http_res,
        )

    async def get_async(
        self,
        *,
        id: str,
        service_id: Optional[str] = None,
        raw: Optional[bool] = False,
        fields: OptionalNullable[str] = UNSET,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.AccountingBillsOneResponse:
        r"""Get Bill

        Get Bill

        :param id: ID of the record you are acting upon.
        :param service_id: Provide the service id you want to call (e.g., pipedrive). Only needed when a consumer has activated multiple integrations for a Unified API.
        :param raw: Include raw response. Mostly used for debugging purposes
        :param fields: The 'fields' parameter allows API users to specify the fields they want to include in the API response. If this parameter is not present, the API will return all available fields. If this parameter is present, only the fields specified in the comma-separated string will be included in the response. Nested properties can also be requested by using a dot notation. <br /><br />Example: `fields=name,email,addresses.city`<br /><br />In the example above, the response will only include the fields \"name\", \"email\" and \"addresses.city\". If any other fields are available, they will be excluded.
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

        if server_url is not None:
            base_url = server_url

        request = models.AccountingBillsOneRequest(
            id=id,
            service_id=service_id,
            raw=raw,
            fields=fields,
        )

        req = self._build_request_async(
            method="GET",
            path="/accounting/bills/{id}",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=False,
            request_has_path_params=True,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            _globals=models.AccountingBillsOneGlobals(
                consumer_id=self.sdk_configuration.globals.consumer_id,
                app_id=self.sdk_configuration.globals.app_id,
            ),
            security=self.sdk_configuration.security,
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config
            else:
                retries = utils.RetryConfig(
                    "backoff", utils.BackoffStrategy(500, 60000, 1.5, 3600000), True
                )

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["5XX"])

        http_res = await self.do_request_async(
            hook_ctx=HookContext(
                operation_id="accounting.billsOne",
                oauth2_scopes=[],
                security_source=get_security_from_env(
                    self.sdk_configuration.security, models.Security
                ),
            ),
            request=req,
            error_status_codes=["400", "401", "402", "404", "422", "4XX", "5XX"],
            retry_config=retry_config,
        )

        data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return models.AccountingBillsOneResponse(
                get_bill_response=utils.unmarshal_json(
                    http_res.text, Optional[models.GetBillResponse]
                ),
                http_meta=models.HTTPMetadata(request=req, response=http_res),
            )
        if utils.match_response(http_res, "400", "application/json"):
            data = utils.unmarshal_json(http_res.text, models.BadRequestResponseData)
            raise models.BadRequestResponse(data=data)
        if utils.match_response(http_res, "401", "application/json"):
            data = utils.unmarshal_json(http_res.text, models.UnauthorizedResponseData)
            raise models.UnauthorizedResponse(data=data)
        if utils.match_response(http_res, "402", "application/json"):
            data = utils.unmarshal_json(
                http_res.text, models.PaymentRequiredResponseData
            )
            raise models.PaymentRequiredResponse(data=data)
        if utils.match_response(http_res, "404", "application/json"):
            data = utils.unmarshal_json(http_res.text, models.NotFoundResponseData)
            raise models.NotFoundResponse(data=data)
        if utils.match_response(http_res, "422", "application/json"):
            data = utils.unmarshal_json(http_res.text, models.UnprocessableResponseData)
            raise models.UnprocessableResponse(data=data)
        if utils.match_response(http_res, ["4XX", "5XX"], "*"):
            http_res_text = await utils.stream_to_text_async(http_res)
            raise models.APIError(
                "API error occurred", http_res.status_code, http_res_text, http_res
            )
        if utils.match_response(http_res, "default", "application/json"):
            return models.AccountingBillsOneResponse(
                unexpected_error_response=utils.unmarshal_json(
                    http_res.text, Optional[models.UnexpectedErrorResponse]
                ),
                http_meta=models.HTTPMetadata(request=req, response=http_res),
            )

        content_type = http_res.headers.get("Content-Type")
        http_res_text = await utils.stream_to_text_async(http_res)
        raise models.APIError(
            f"Unexpected response received (code: {http_res.status_code}, type: {content_type})",
            http_res.status_code,
            http_res_text,
            http_res,
        )

    def update(
        self,
        *,
        id: str,
        service_id: Optional[str] = None,
        raw: Optional[bool] = False,
        bill_number: OptionalNullable[str] = UNSET,
        supplier: OptionalNullable[
            Union[models.LinkedSupplierInput, models.LinkedSupplierInputTypedDict]
        ] = UNSET,
        company_id: OptionalNullable[str] = UNSET,
        currency: OptionalNullable[models.Currency] = UNSET,
        currency_rate: OptionalNullable[float] = UNSET,
        tax_inclusive: OptionalNullable[bool] = UNSET,
        bill_date: OptionalNullable[date] = UNSET,
        due_date: OptionalNullable[date] = UNSET,
        paid_date: OptionalNullable[date] = UNSET,
        po_number: OptionalNullable[str] = UNSET,
        reference: OptionalNullable[str] = UNSET,
        line_items: Optional[
            Union[
                List[models.BillLineItemInput], List[models.BillLineItemInputTypedDict]
            ]
        ] = None,
        terms: OptionalNullable[str] = UNSET,
        balance: OptionalNullable[float] = UNSET,
        deposit: OptionalNullable[float] = UNSET,
        sub_total: OptionalNullable[float] = UNSET,
        total_tax: OptionalNullable[float] = UNSET,
        total: OptionalNullable[float] = UNSET,
        tax_code: OptionalNullable[str] = UNSET,
        notes: OptionalNullable[str] = UNSET,
        status: OptionalNullable[models.BillStatus] = UNSET,
        ledger_account: OptionalNullable[
            Union[
                models.LinkedLedgerAccountInput,
                models.LinkedLedgerAccountInputTypedDict,
            ]
        ] = UNSET,
        payment_method: OptionalNullable[str] = UNSET,
        channel: OptionalNullable[str] = UNSET,
        language: OptionalNullable[str] = UNSET,
        accounting_by_row: OptionalNullable[bool] = UNSET,
        bank_account: Optional[
            Union[models.BankAccount, models.BankAccountTypedDict]
        ] = None,
        discount_percentage: OptionalNullable[float] = UNSET,
        tracking_categories: OptionalNullable[
            Union[
                List[models.LinkedTrackingCategory],
                List[models.LinkedTrackingCategoryTypedDict],
            ]
        ] = UNSET,
        row_version: OptionalNullable[str] = UNSET,
        custom_fields: Optional[
            Union[List[models.CustomField], List[models.CustomFieldTypedDict]]
        ] = None,
        pass_through: Optional[
            Union[List[models.PassThroughBody], List[models.PassThroughBodyTypedDict]]
        ] = None,
        accounting_period: OptionalNullable[str] = UNSET,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.AccountingBillsUpdateResponse:
        r"""Update Bill

        Update Bill

        :param id: ID of the record you are acting upon.
        :param service_id: Provide the service id you want to call (e.g., pipedrive). Only needed when a consumer has activated multiple integrations for a Unified API.
        :param raw: Include raw response. Mostly used for debugging purposes
        :param bill_number: Reference to supplier bill number
        :param supplier: The supplier this entity is linked to.
        :param company_id: The company or subsidiary id the transaction belongs to
        :param currency: Indicates the associated currency for an amount of money. Values correspond to [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217).
        :param currency_rate: Currency Exchange Rate at the time entity was recorded/generated.
        :param tax_inclusive: Amounts are including tax
        :param bill_date: Date bill was issued - YYYY-MM-DD.
        :param due_date: The due date is the date on which a payment is scheduled to be received - YYYY-MM-DD.
        :param paid_date: The paid date is the date on which a payment was sent to the supplier - YYYY-MM-DD.
        :param po_number: A PO Number uniquely identifies a purchase order and is generally defined by the buyer. The buyer will match the PO number in the invoice to the Purchase Order.
        :param reference: Optional bill reference.
        :param line_items:
        :param terms: Terms of payment.
        :param balance: Balance of bill due.
        :param deposit: Amount of deposit made to this bill.
        :param sub_total: Sub-total amount, normally before tax.
        :param total_tax: Total tax amount applied to this bill.
        :param total: Total amount of bill, including tax.
        :param tax_code: Applicable tax id/code override if tax is not supplied on a line item basis.
        :param notes:
        :param status: Invoice status
        :param ledger_account:
        :param payment_method: Payment method used for the transaction, such as cash, credit card, bank transfer, or check
        :param channel: The channel through which the transaction is processed.
        :param language: language code according to ISO 639-1. For the United States - EN
        :param accounting_by_row: Indicates if accounting by row is used (true) or not (false). Accounting by row means that a separate ledger transaction is created for each row.
        :param bank_account:
        :param discount_percentage: Discount percentage applied to this transaction.
        :param tracking_categories: A list of linked tracking categories.
        :param row_version: A binary value used to detect updates to a object and prevent data conflicts. It is incremented each time an update is made to the object.
        :param custom_fields:
        :param pass_through: The pass_through property allows passing service-specific, custom data or structured modifications in request body when creating or updating resources.
        :param accounting_period: Accounting period
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

        if server_url is not None:
            base_url = server_url

        request = models.AccountingBillsUpdateRequest(
            id=id,
            service_id=service_id,
            raw=raw,
            bill=models.BillInput(
                bill_number=bill_number,
                supplier=utils.get_pydantic_model(
                    supplier, OptionalNullable[models.LinkedSupplierInput]
                ),
                company_id=company_id,
                currency=currency,
                currency_rate=currency_rate,
                tax_inclusive=tax_inclusive,
                bill_date=bill_date,
                due_date=due_date,
                paid_date=paid_date,
                po_number=po_number,
                reference=reference,
                line_items=utils.get_pydantic_model(
                    line_items, Optional[List[models.BillLineItemInput]]
                ),
                terms=terms,
                balance=balance,
                deposit=deposit,
                sub_total=sub_total,
                total_tax=total_tax,
                total=total,
                tax_code=tax_code,
                notes=notes,
                status=status,
                ledger_account=utils.get_pydantic_model(
                    ledger_account, OptionalNullable[models.LinkedLedgerAccountInput]
                ),
                payment_method=payment_method,
                channel=channel,
                language=language,
                accounting_by_row=accounting_by_row,
                bank_account=utils.get_pydantic_model(
                    bank_account, Optional[models.BankAccount]
                ),
                discount_percentage=discount_percentage,
                tracking_categories=utils.get_pydantic_model(
                    tracking_categories,
                    OptionalNullable[List[models.LinkedTrackingCategory]],
                ),
                row_version=row_version,
                custom_fields=utils.get_pydantic_model(
                    custom_fields, Optional[List[models.CustomField]]
                ),
                pass_through=utils.get_pydantic_model(
                    pass_through, Optional[List[models.PassThroughBody]]
                ),
                accounting_period=accounting_period,
            ),
        )

        req = self._build_request(
            method="PATCH",
            path="/accounting/bills/{id}",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=True,
            request_has_path_params=True,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            _globals=models.AccountingBillsUpdateGlobals(
                consumer_id=self.sdk_configuration.globals.consumer_id,
                app_id=self.sdk_configuration.globals.app_id,
            ),
            security=self.sdk_configuration.security,
            get_serialized_body=lambda: utils.serialize_request_body(
                request.bill, False, False, "json", models.BillInput
            ),
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config
            else:
                retries = utils.RetryConfig(
                    "backoff", utils.BackoffStrategy(500, 60000, 1.5, 3600000), True
                )

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["5XX"])

        http_res = self.do_request(
            hook_ctx=HookContext(
                operation_id="accounting.billsUpdate",
                oauth2_scopes=[],
                security_source=get_security_from_env(
                    self.sdk_configuration.security, models.Security
                ),
            ),
            request=req,
            error_status_codes=["400", "401", "402", "404", "422", "4XX", "5XX"],
            retry_config=retry_config,
        )

        data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return models.AccountingBillsUpdateResponse(
                update_bill_response=utils.unmarshal_json(
                    http_res.text, Optional[models.UpdateBillResponse]
                ),
                http_meta=models.HTTPMetadata(request=req, response=http_res),
            )
        if utils.match_response(http_res, "400", "application/json"):
            data = utils.unmarshal_json(http_res.text, models.BadRequestResponseData)
            raise models.BadRequestResponse(data=data)
        if utils.match_response(http_res, "401", "application/json"):
            data = utils.unmarshal_json(http_res.text, models.UnauthorizedResponseData)
            raise models.UnauthorizedResponse(data=data)
        if utils.match_response(http_res, "402", "application/json"):
            data = utils.unmarshal_json(
                http_res.text, models.PaymentRequiredResponseData
            )
            raise models.PaymentRequiredResponse(data=data)
        if utils.match_response(http_res, "404", "application/json"):
            data = utils.unmarshal_json(http_res.text, models.NotFoundResponseData)
            raise models.NotFoundResponse(data=data)
        if utils.match_response(http_res, "422", "application/json"):
            data = utils.unmarshal_json(http_res.text, models.UnprocessableResponseData)
            raise models.UnprocessableResponse(data=data)
        if utils.match_response(http_res, ["4XX", "5XX"], "*"):
            http_res_text = utils.stream_to_text(http_res)
            raise models.APIError(
                "API error occurred", http_res.status_code, http_res_text, http_res
            )
        if utils.match_response(http_res, "default", "application/json"):
            return models.AccountingBillsUpdateResponse(
                unexpected_error_response=utils.unmarshal_json(
                    http_res.text, Optional[models.UnexpectedErrorResponse]
                ),
                http_meta=models.HTTPMetadata(request=req, response=http_res),
            )

        content_type = http_res.headers.get("Content-Type")
        http_res_text = utils.stream_to_text(http_res)
        raise models.APIError(
            f"Unexpected response received (code: {http_res.status_code}, type: {content_type})",
            http_res.status_code,
            http_res_text,
            http_res,
        )

    async def update_async(
        self,
        *,
        id: str,
        service_id: Optional[str] = None,
        raw: Optional[bool] = False,
        bill_number: OptionalNullable[str] = UNSET,
        supplier: OptionalNullable[
            Union[models.LinkedSupplierInput, models.LinkedSupplierInputTypedDict]
        ] = UNSET,
        company_id: OptionalNullable[str] = UNSET,
        currency: OptionalNullable[models.Currency] = UNSET,
        currency_rate: OptionalNullable[float] = UNSET,
        tax_inclusive: OptionalNullable[bool] = UNSET,
        bill_date: OptionalNullable[date] = UNSET,
        due_date: OptionalNullable[date] = UNSET,
        paid_date: OptionalNullable[date] = UNSET,
        po_number: OptionalNullable[str] = UNSET,
        reference: OptionalNullable[str] = UNSET,
        line_items: Optional[
            Union[
                List[models.BillLineItemInput], List[models.BillLineItemInputTypedDict]
            ]
        ] = None,
        terms: OptionalNullable[str] = UNSET,
        balance: OptionalNullable[float] = UNSET,
        deposit: OptionalNullable[float] = UNSET,
        sub_total: OptionalNullable[float] = UNSET,
        total_tax: OptionalNullable[float] = UNSET,
        total: OptionalNullable[float] = UNSET,
        tax_code: OptionalNullable[str] = UNSET,
        notes: OptionalNullable[str] = UNSET,
        status: OptionalNullable[models.BillStatus] = UNSET,
        ledger_account: OptionalNullable[
            Union[
                models.LinkedLedgerAccountInput,
                models.LinkedLedgerAccountInputTypedDict,
            ]
        ] = UNSET,
        payment_method: OptionalNullable[str] = UNSET,
        channel: OptionalNullable[str] = UNSET,
        language: OptionalNullable[str] = UNSET,
        accounting_by_row: OptionalNullable[bool] = UNSET,
        bank_account: Optional[
            Union[models.BankAccount, models.BankAccountTypedDict]
        ] = None,
        discount_percentage: OptionalNullable[float] = UNSET,
        tracking_categories: OptionalNullable[
            Union[
                List[models.LinkedTrackingCategory],
                List[models.LinkedTrackingCategoryTypedDict],
            ]
        ] = UNSET,
        row_version: OptionalNullable[str] = UNSET,
        custom_fields: Optional[
            Union[List[models.CustomField], List[models.CustomFieldTypedDict]]
        ] = None,
        pass_through: Optional[
            Union[List[models.PassThroughBody], List[models.PassThroughBodyTypedDict]]
        ] = None,
        accounting_period: OptionalNullable[str] = UNSET,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.AccountingBillsUpdateResponse:
        r"""Update Bill

        Update Bill

        :param id: ID of the record you are acting upon.
        :param service_id: Provide the service id you want to call (e.g., pipedrive). Only needed when a consumer has activated multiple integrations for a Unified API.
        :param raw: Include raw response. Mostly used for debugging purposes
        :param bill_number: Reference to supplier bill number
        :param supplier: The supplier this entity is linked to.
        :param company_id: The company or subsidiary id the transaction belongs to
        :param currency: Indicates the associated currency for an amount of money. Values correspond to [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217).
        :param currency_rate: Currency Exchange Rate at the time entity was recorded/generated.
        :param tax_inclusive: Amounts are including tax
        :param bill_date: Date bill was issued - YYYY-MM-DD.
        :param due_date: The due date is the date on which a payment is scheduled to be received - YYYY-MM-DD.
        :param paid_date: The paid date is the date on which a payment was sent to the supplier - YYYY-MM-DD.
        :param po_number: A PO Number uniquely identifies a purchase order and is generally defined by the buyer. The buyer will match the PO number in the invoice to the Purchase Order.
        :param reference: Optional bill reference.
        :param line_items:
        :param terms: Terms of payment.
        :param balance: Balance of bill due.
        :param deposit: Amount of deposit made to this bill.
        :param sub_total: Sub-total amount, normally before tax.
        :param total_tax: Total tax amount applied to this bill.
        :param total: Total amount of bill, including tax.
        :param tax_code: Applicable tax id/code override if tax is not supplied on a line item basis.
        :param notes:
        :param status: Invoice status
        :param ledger_account:
        :param payment_method: Payment method used for the transaction, such as cash, credit card, bank transfer, or check
        :param channel: The channel through which the transaction is processed.
        :param language: language code according to ISO 639-1. For the United States - EN
        :param accounting_by_row: Indicates if accounting by row is used (true) or not (false). Accounting by row means that a separate ledger transaction is created for each row.
        :param bank_account:
        :param discount_percentage: Discount percentage applied to this transaction.
        :param tracking_categories: A list of linked tracking categories.
        :param row_version: A binary value used to detect updates to a object and prevent data conflicts. It is incremented each time an update is made to the object.
        :param custom_fields:
        :param pass_through: The pass_through property allows passing service-specific, custom data or structured modifications in request body when creating or updating resources.
        :param accounting_period: Accounting period
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

        if server_url is not None:
            base_url = server_url

        request = models.AccountingBillsUpdateRequest(
            id=id,
            service_id=service_id,
            raw=raw,
            bill=models.BillInput(
                bill_number=bill_number,
                supplier=utils.get_pydantic_model(
                    supplier, OptionalNullable[models.LinkedSupplierInput]
                ),
                company_id=company_id,
                currency=currency,
                currency_rate=currency_rate,
                tax_inclusive=tax_inclusive,
                bill_date=bill_date,
                due_date=due_date,
                paid_date=paid_date,
                po_number=po_number,
                reference=reference,
                line_items=utils.get_pydantic_model(
                    line_items, Optional[List[models.BillLineItemInput]]
                ),
                terms=terms,
                balance=balance,
                deposit=deposit,
                sub_total=sub_total,
                total_tax=total_tax,
                total=total,
                tax_code=tax_code,
                notes=notes,
                status=status,
                ledger_account=utils.get_pydantic_model(
                    ledger_account, OptionalNullable[models.LinkedLedgerAccountInput]
                ),
                payment_method=payment_method,
                channel=channel,
                language=language,
                accounting_by_row=accounting_by_row,
                bank_account=utils.get_pydantic_model(
                    bank_account, Optional[models.BankAccount]
                ),
                discount_percentage=discount_percentage,
                tracking_categories=utils.get_pydantic_model(
                    tracking_categories,
                    OptionalNullable[List[models.LinkedTrackingCategory]],
                ),
                row_version=row_version,
                custom_fields=utils.get_pydantic_model(
                    custom_fields, Optional[List[models.CustomField]]
                ),
                pass_through=utils.get_pydantic_model(
                    pass_through, Optional[List[models.PassThroughBody]]
                ),
                accounting_period=accounting_period,
            ),
        )

        req = self._build_request_async(
            method="PATCH",
            path="/accounting/bills/{id}",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=True,
            request_has_path_params=True,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            _globals=models.AccountingBillsUpdateGlobals(
                consumer_id=self.sdk_configuration.globals.consumer_id,
                app_id=self.sdk_configuration.globals.app_id,
            ),
            security=self.sdk_configuration.security,
            get_serialized_body=lambda: utils.serialize_request_body(
                request.bill, False, False, "json", models.BillInput
            ),
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config
            else:
                retries = utils.RetryConfig(
                    "backoff", utils.BackoffStrategy(500, 60000, 1.5, 3600000), True
                )

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["5XX"])

        http_res = await self.do_request_async(
            hook_ctx=HookContext(
                operation_id="accounting.billsUpdate",
                oauth2_scopes=[],
                security_source=get_security_from_env(
                    self.sdk_configuration.security, models.Security
                ),
            ),
            request=req,
            error_status_codes=["400", "401", "402", "404", "422", "4XX", "5XX"],
            retry_config=retry_config,
        )

        data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return models.AccountingBillsUpdateResponse(
                update_bill_response=utils.unmarshal_json(
                    http_res.text, Optional[models.UpdateBillResponse]
                ),
                http_meta=models.HTTPMetadata(request=req, response=http_res),
            )
        if utils.match_response(http_res, "400", "application/json"):
            data = utils.unmarshal_json(http_res.text, models.BadRequestResponseData)
            raise models.BadRequestResponse(data=data)
        if utils.match_response(http_res, "401", "application/json"):
            data = utils.unmarshal_json(http_res.text, models.UnauthorizedResponseData)
            raise models.UnauthorizedResponse(data=data)
        if utils.match_response(http_res, "402", "application/json"):
            data = utils.unmarshal_json(
                http_res.text, models.PaymentRequiredResponseData
            )
            raise models.PaymentRequiredResponse(data=data)
        if utils.match_response(http_res, "404", "application/json"):
            data = utils.unmarshal_json(http_res.text, models.NotFoundResponseData)
            raise models.NotFoundResponse(data=data)
        if utils.match_response(http_res, "422", "application/json"):
            data = utils.unmarshal_json(http_res.text, models.UnprocessableResponseData)
            raise models.UnprocessableResponse(data=data)
        if utils.match_response(http_res, ["4XX", "5XX"], "*"):
            http_res_text = await utils.stream_to_text_async(http_res)
            raise models.APIError(
                "API error occurred", http_res.status_code, http_res_text, http_res
            )
        if utils.match_response(http_res, "default", "application/json"):
            return models.AccountingBillsUpdateResponse(
                unexpected_error_response=utils.unmarshal_json(
                    http_res.text, Optional[models.UnexpectedErrorResponse]
                ),
                http_meta=models.HTTPMetadata(request=req, response=http_res),
            )

        content_type = http_res.headers.get("Content-Type")
        http_res_text = await utils.stream_to_text_async(http_res)
        raise models.APIError(
            f"Unexpected response received (code: {http_res.status_code}, type: {content_type})",
            http_res.status_code,
            http_res_text,
            http_res,
        )

    def delete(
        self,
        *,
        id: str,
        service_id: Optional[str] = None,
        raw: Optional[bool] = False,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.AccountingBillsDeleteResponse:
        r"""Delete Bill

        Delete Bill

        :param id: ID of the record you are acting upon.
        :param service_id: Provide the service id you want to call (e.g., pipedrive). Only needed when a consumer has activated multiple integrations for a Unified API.
        :param raw: Include raw response. Mostly used for debugging purposes
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

        if server_url is not None:
            base_url = server_url

        request = models.AccountingBillsDeleteRequest(
            id=id,
            service_id=service_id,
            raw=raw,
        )

        req = self._build_request(
            method="DELETE",
            path="/accounting/bills/{id}",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=False,
            request_has_path_params=True,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            _globals=models.AccountingBillsDeleteGlobals(
                consumer_id=self.sdk_configuration.globals.consumer_id,
                app_id=self.sdk_configuration.globals.app_id,
            ),
            security=self.sdk_configuration.security,
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config
            else:
                retries = utils.RetryConfig(
                    "backoff", utils.BackoffStrategy(500, 60000, 1.5, 3600000), True
                )

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["5XX"])

        http_res = self.do_request(
            hook_ctx=HookContext(
                operation_id="accounting.billsDelete",
                oauth2_scopes=[],
                security_source=get_security_from_env(
                    self.sdk_configuration.security, models.Security
                ),
            ),
            request=req,
            error_status_codes=["400", "401", "402", "404", "422", "4XX", "5XX"],
            retry_config=retry_config,
        )

        data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return models.AccountingBillsDeleteResponse(
                delete_bill_response=utils.unmarshal_json(
                    http_res.text, Optional[models.DeleteBillResponse]
                ),
                http_meta=models.HTTPMetadata(request=req, response=http_res),
            )
        if utils.match_response(http_res, "400", "application/json"):
            data = utils.unmarshal_json(http_res.text, models.BadRequestResponseData)
            raise models.BadRequestResponse(data=data)
        if utils.match_response(http_res, "401", "application/json"):
            data = utils.unmarshal_json(http_res.text, models.UnauthorizedResponseData)
            raise models.UnauthorizedResponse(data=data)
        if utils.match_response(http_res, "402", "application/json"):
            data = utils.unmarshal_json(
                http_res.text, models.PaymentRequiredResponseData
            )
            raise models.PaymentRequiredResponse(data=data)
        if utils.match_response(http_res, "404", "application/json"):
            data = utils.unmarshal_json(http_res.text, models.NotFoundResponseData)
            raise models.NotFoundResponse(data=data)
        if utils.match_response(http_res, "422", "application/json"):
            data = utils.unmarshal_json(http_res.text, models.UnprocessableResponseData)
            raise models.UnprocessableResponse(data=data)
        if utils.match_response(http_res, ["4XX", "5XX"], "*"):
            http_res_text = utils.stream_to_text(http_res)
            raise models.APIError(
                "API error occurred", http_res.status_code, http_res_text, http_res
            )
        if utils.match_response(http_res, "default", "application/json"):
            return models.AccountingBillsDeleteResponse(
                unexpected_error_response=utils.unmarshal_json(
                    http_res.text, Optional[models.UnexpectedErrorResponse]
                ),
                http_meta=models.HTTPMetadata(request=req, response=http_res),
            )

        content_type = http_res.headers.get("Content-Type")
        http_res_text = utils.stream_to_text(http_res)
        raise models.APIError(
            f"Unexpected response received (code: {http_res.status_code}, type: {content_type})",
            http_res.status_code,
            http_res_text,
            http_res,
        )

    async def delete_async(
        self,
        *,
        id: str,
        service_id: Optional[str] = None,
        raw: Optional[bool] = False,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.AccountingBillsDeleteResponse:
        r"""Delete Bill

        Delete Bill

        :param id: ID of the record you are acting upon.
        :param service_id: Provide the service id you want to call (e.g., pipedrive). Only needed when a consumer has activated multiple integrations for a Unified API.
        :param raw: Include raw response. Mostly used for debugging purposes
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

        if server_url is not None:
            base_url = server_url

        request = models.AccountingBillsDeleteRequest(
            id=id,
            service_id=service_id,
            raw=raw,
        )

        req = self._build_request_async(
            method="DELETE",
            path="/accounting/bills/{id}",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=False,
            request_has_path_params=True,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            _globals=models.AccountingBillsDeleteGlobals(
                consumer_id=self.sdk_configuration.globals.consumer_id,
                app_id=self.sdk_configuration.globals.app_id,
            ),
            security=self.sdk_configuration.security,
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config
            else:
                retries = utils.RetryConfig(
                    "backoff", utils.BackoffStrategy(500, 60000, 1.5, 3600000), True
                )

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["5XX"])

        http_res = await self.do_request_async(
            hook_ctx=HookContext(
                operation_id="accounting.billsDelete",
                oauth2_scopes=[],
                security_source=get_security_from_env(
                    self.sdk_configuration.security, models.Security
                ),
            ),
            request=req,
            error_status_codes=["400", "401", "402", "404", "422", "4XX", "5XX"],
            retry_config=retry_config,
        )

        data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return models.AccountingBillsDeleteResponse(
                delete_bill_response=utils.unmarshal_json(
                    http_res.text, Optional[models.DeleteBillResponse]
                ),
                http_meta=models.HTTPMetadata(request=req, response=http_res),
            )
        if utils.match_response(http_res, "400", "application/json"):
            data = utils.unmarshal_json(http_res.text, models.BadRequestResponseData)
            raise models.BadRequestResponse(data=data)
        if utils.match_response(http_res, "401", "application/json"):
            data = utils.unmarshal_json(http_res.text, models.UnauthorizedResponseData)
            raise models.UnauthorizedResponse(data=data)
        if utils.match_response(http_res, "402", "application/json"):
            data = utils.unmarshal_json(
                http_res.text, models.PaymentRequiredResponseData
            )
            raise models.PaymentRequiredResponse(data=data)
        if utils.match_response(http_res, "404", "application/json"):
            data = utils.unmarshal_json(http_res.text, models.NotFoundResponseData)
            raise models.NotFoundResponse(data=data)
        if utils.match_response(http_res, "422", "application/json"):
            data = utils.unmarshal_json(http_res.text, models.UnprocessableResponseData)
            raise models.UnprocessableResponse(data=data)
        if utils.match_response(http_res, ["4XX", "5XX"], "*"):
            http_res_text = await utils.stream_to_text_async(http_res)
            raise models.APIError(
                "API error occurred", http_res.status_code, http_res_text, http_res
            )
        if utils.match_response(http_res, "default", "application/json"):
            return models.AccountingBillsDeleteResponse(
                unexpected_error_response=utils.unmarshal_json(
                    http_res.text, Optional[models.UnexpectedErrorResponse]
                ),
                http_meta=models.HTTPMetadata(request=req, response=http_res),
            )

        content_type = http_res.headers.get("Content-Type")
        http_res_text = await utils.stream_to_text_async(http_res)
        raise models.APIError(
            f"Unexpected response received (code: {http_res.status_code}, type: {content_type})",
            http_res.status_code,
            http_res_text,
            http_res,
        )
