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

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

from ..core.api_error import ApiError
from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
from ..core.datetime_utils import serialize_datetime
from ..core.http_response import AsyncHttpResponse, HttpResponse
from ..core.jsonable_encoder import jsonable_encoder
from ..core.pydantic_utilities import parse_obj_as
from ..core.request_options import RequestOptions
from ..core.serialization import convert_and_respect_annotation_metadata
from ..errors.bad_request_error import BadRequestError
from ..errors.conflict_error import ConflictError
from ..errors.forbidden_error import ForbiddenError
from ..errors.internal_server_error import InternalServerError
from ..errors.not_found_error import NotFoundError
from ..errors.unauthorized_error import UnauthorizedError
from ..errors.unprocessable_entity_error import UnprocessableEntityError
from ..types.currency_enum import CurrencyEnum
from ..types.order_enum import OrderEnum
from ..types.purchase_order_cursor_fields import PurchaseOrderCursorFields
from ..types.purchase_order_email_preview_response import PurchaseOrderEmailPreviewResponse
from ..types.purchase_order_email_sent_response import PurchaseOrderEmailSentResponse
from ..types.purchase_order_item import PurchaseOrderItem
from ..types.purchase_order_pagination_response import PurchaseOrderPaginationResponse
from ..types.purchase_order_response_schema import PurchaseOrderResponseSchema
from ..types.purchase_order_status_enum import PurchaseOrderStatusEnum
from ..types.variables_object_list import VariablesObjectList

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


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

    def get(
        self,
        *,
        order: typing.Optional[OrderEnum] = None,
        limit: typing.Optional[int] = None,
        pagination_token: typing.Optional[str] = None,
        sort: typing.Optional[PurchaseOrderCursorFields] = None,
        created_at_gt: typing.Optional[dt.datetime] = None,
        created_at_lt: typing.Optional[dt.datetime] = None,
        created_at_gte: typing.Optional[dt.datetime] = None,
        created_at_lte: typing.Optional[dt.datetime] = None,
        updated_at_gt: typing.Optional[dt.datetime] = None,
        updated_at_lt: typing.Optional[dt.datetime] = None,
        updated_at_gte: typing.Optional[dt.datetime] = None,
        updated_at_lte: typing.Optional[dt.datetime] = None,
        issued_at_gt: typing.Optional[dt.datetime] = None,
        issued_at_lt: typing.Optional[dt.datetime] = None,
        issued_at_gte: typing.Optional[dt.datetime] = None,
        issued_at_lte: typing.Optional[dt.datetime] = None,
        status: typing.Optional[PurchaseOrderStatusEnum] = None,
        document_id: typing.Optional[str] = None,
        document_id_in: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
        created_by: typing.Optional[str] = None,
        counterpart_id: typing.Optional[str] = None,
        counterpart_id_in: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
        counterpart_name: typing.Optional[str] = None,
        currency: typing.Optional[CurrencyEnum] = None,
        currency_in: typing.Optional[typing.Union[CurrencyEnum, typing.Sequence[CurrencyEnum]]] = None,
        project_id: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[PurchaseOrderPaginationResponse]:
        """
        Parameters
        ----------
        order : typing.Optional[OrderEnum]
            Sort order (ascending by default). Typically used together with the `sort` parameter.

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

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

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

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

        created_at_gt : typing.Optional[dt.datetime]

        created_at_lt : typing.Optional[dt.datetime]

        created_at_gte : typing.Optional[dt.datetime]

        created_at_lte : typing.Optional[dt.datetime]

        updated_at_gt : typing.Optional[dt.datetime]

        updated_at_lt : typing.Optional[dt.datetime]

        updated_at_gte : typing.Optional[dt.datetime]

        updated_at_lte : typing.Optional[dt.datetime]

        issued_at_gt : typing.Optional[dt.datetime]

        issued_at_lt : typing.Optional[dt.datetime]

        issued_at_gte : typing.Optional[dt.datetime]

        issued_at_lte : typing.Optional[dt.datetime]

        status : typing.Optional[PurchaseOrderStatusEnum]

        document_id : typing.Optional[str]

        document_id_in : typing.Optional[typing.Union[str, typing.Sequence[str]]]

        created_by : typing.Optional[str]

        counterpart_id : typing.Optional[str]

        counterpart_id_in : typing.Optional[typing.Union[str, typing.Sequence[str]]]

        counterpart_name : typing.Optional[str]

        currency : typing.Optional[CurrencyEnum]

        currency_in : typing.Optional[typing.Union[CurrencyEnum, typing.Sequence[CurrencyEnum]]]

        project_id : typing.Optional[str]

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

        Returns
        -------
        HttpResponse[PurchaseOrderPaginationResponse]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            "payable_purchase_orders",
            method="GET",
            params={
                "order": order,
                "limit": limit,
                "pagination_token": pagination_token,
                "sort": sort,
                "created_at__gt": serialize_datetime(created_at_gt) if created_at_gt is not None else None,
                "created_at__lt": serialize_datetime(created_at_lt) if created_at_lt is not None else None,
                "created_at__gte": serialize_datetime(created_at_gte) if created_at_gte is not None else None,
                "created_at__lte": serialize_datetime(created_at_lte) if created_at_lte is not None else None,
                "updated_at__gt": serialize_datetime(updated_at_gt) if updated_at_gt is not None else None,
                "updated_at__lt": serialize_datetime(updated_at_lt) if updated_at_lt is not None else None,
                "updated_at__gte": serialize_datetime(updated_at_gte) if updated_at_gte is not None else None,
                "updated_at__lte": serialize_datetime(updated_at_lte) if updated_at_lte is not None else None,
                "issued_at__gt": serialize_datetime(issued_at_gt) if issued_at_gt is not None else None,
                "issued_at__lt": serialize_datetime(issued_at_lt) if issued_at_lt is not None else None,
                "issued_at__gte": serialize_datetime(issued_at_gte) if issued_at_gte is not None else None,
                "issued_at__lte": serialize_datetime(issued_at_lte) if issued_at_lte is not None else None,
                "status": status,
                "document_id": document_id,
                "document_id__in": document_id_in,
                "created_by": created_by,
                "counterpart_id": counterpart_id,
                "counterpart_id__in": counterpart_id_in,
                "counterpart.name": counterpart_name,
                "currency": currency,
                "currency__in": currency_in,
                "project_id": project_id,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    PurchaseOrderPaginationResponse,
                    parse_obj_as(
                        type_=PurchaseOrderPaginationResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def create(
        self,
        *,
        counterpart_id: str,
        currency: CurrencyEnum,
        items: typing.Sequence[PurchaseOrderItem],
        message: str,
        valid_for_days: int,
        counterpart_address_id: typing.Optional[str] = OMIT,
        entity_vat_id_id: typing.Optional[str] = OMIT,
        project_id: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[PurchaseOrderResponseSchema]:
        """
        Parameters
        ----------
        counterpart_id : str
            Counterpart unique ID.

        currency : CurrencyEnum
            The currency in which the price of the product is set. (all items need to have the same currency)

        items : typing.Sequence[PurchaseOrderItem]
            List of item to purchase

        message : str
            Msg which will be send to counterpart for who the purchase order is issued.

        valid_for_days : int
            Number of days for which purchase order is valid

        counterpart_address_id : typing.Optional[str]
            The ID of counterpart address object stored in counterparts service. If not provided, counterpart's default address is used.

        entity_vat_id_id : typing.Optional[str]
            Entity VAT ID identifier that applied to purchase order

        project_id : typing.Optional[str]
            Project ID of a purchase order

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

        Returns
        -------
        HttpResponse[PurchaseOrderResponseSchema]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            "payable_purchase_orders",
            method="POST",
            json={
                "counterpart_address_id": counterpart_address_id,
                "counterpart_id": counterpart_id,
                "currency": currency,
                "entity_vat_id_id": entity_vat_id_id,
                "items": convert_and_respect_annotation_metadata(
                    object_=items, annotation=typing.Sequence[PurchaseOrderItem], direction="write"
                ),
                "message": message,
                "project_id": project_id,
                "valid_for_days": valid_for_days,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    PurchaseOrderResponseSchema,
                    parse_obj_as(
                        type_=PurchaseOrderResponseSchema,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

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

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

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

    def get_by_id(
        self, purchase_order_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[PurchaseOrderResponseSchema]:
        """
        Parameters
        ----------
        purchase_order_id : str

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

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

    def delete_by_id(
        self, purchase_order_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[None]:
        """
        Parameters
        ----------
        purchase_order_id : str

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

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

    def update_by_id(
        self,
        purchase_order_id: str,
        *,
        counterpart_address_id: typing.Optional[str] = OMIT,
        counterpart_id: typing.Optional[str] = OMIT,
        entity_vat_id_id: typing.Optional[str] = OMIT,
        items: typing.Optional[typing.Sequence[PurchaseOrderItem]] = OMIT,
        message: typing.Optional[str] = OMIT,
        project_id: typing.Optional[str] = OMIT,
        valid_for_days: typing.Optional[int] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[PurchaseOrderResponseSchema]:
        """
        Parameters
        ----------
        purchase_order_id : str

        counterpart_address_id : typing.Optional[str]
            The ID of counterpart address object stored in counterparts service. If not provided, counterpart's default address is used.

        counterpart_id : typing.Optional[str]
            Counterpart unique ID.

        entity_vat_id_id : typing.Optional[str]
            Entity VAT ID identifier that applied to purchase order

        items : typing.Optional[typing.Sequence[PurchaseOrderItem]]
            List of item to purchase

        message : typing.Optional[str]
            Msg which will be send to counterpart for who the purchase order is issued.

        project_id : typing.Optional[str]
            Project ID of a purchase order

        valid_for_days : typing.Optional[int]
            Number of days for which purchase order is valid

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

        Returns
        -------
        HttpResponse[PurchaseOrderResponseSchema]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            f"payable_purchase_orders/{jsonable_encoder(purchase_order_id)}",
            method="PATCH",
            json={
                "counterpart_address_id": counterpart_address_id,
                "counterpart_id": counterpart_id,
                "entity_vat_id_id": entity_vat_id_id,
                "items": convert_and_respect_annotation_metadata(
                    object_=items, annotation=typing.Sequence[PurchaseOrderItem], direction="write"
                ),
                "message": message,
                "project_id": project_id,
                "valid_for_days": valid_for_days,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    PurchaseOrderResponseSchema,
                    parse_obj_as(
                        type_=PurchaseOrderResponseSchema,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def preview_by_id(
        self,
        purchase_order_id: str,
        *,
        body_text: str,
        subject_text: str,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[PurchaseOrderEmailPreviewResponse]:
        """
        Parameters
        ----------
        purchase_order_id : str

        body_text : str

        subject_text : str

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

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

    def send_by_id(
        self,
        purchase_order_id: str,
        *,
        body_text: str,
        subject_text: str,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[PurchaseOrderEmailSentResponse]:
        """
        Parameters
        ----------
        purchase_order_id : str

        body_text : str

        subject_text : str

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

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


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

    async def get(
        self,
        *,
        order: typing.Optional[OrderEnum] = None,
        limit: typing.Optional[int] = None,
        pagination_token: typing.Optional[str] = None,
        sort: typing.Optional[PurchaseOrderCursorFields] = None,
        created_at_gt: typing.Optional[dt.datetime] = None,
        created_at_lt: typing.Optional[dt.datetime] = None,
        created_at_gte: typing.Optional[dt.datetime] = None,
        created_at_lte: typing.Optional[dt.datetime] = None,
        updated_at_gt: typing.Optional[dt.datetime] = None,
        updated_at_lt: typing.Optional[dt.datetime] = None,
        updated_at_gte: typing.Optional[dt.datetime] = None,
        updated_at_lte: typing.Optional[dt.datetime] = None,
        issued_at_gt: typing.Optional[dt.datetime] = None,
        issued_at_lt: typing.Optional[dt.datetime] = None,
        issued_at_gte: typing.Optional[dt.datetime] = None,
        issued_at_lte: typing.Optional[dt.datetime] = None,
        status: typing.Optional[PurchaseOrderStatusEnum] = None,
        document_id: typing.Optional[str] = None,
        document_id_in: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
        created_by: typing.Optional[str] = None,
        counterpart_id: typing.Optional[str] = None,
        counterpart_id_in: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
        counterpart_name: typing.Optional[str] = None,
        currency: typing.Optional[CurrencyEnum] = None,
        currency_in: typing.Optional[typing.Union[CurrencyEnum, typing.Sequence[CurrencyEnum]]] = None,
        project_id: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[PurchaseOrderPaginationResponse]:
        """
        Parameters
        ----------
        order : typing.Optional[OrderEnum]
            Sort order (ascending by default). Typically used together with the `sort` parameter.

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

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

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

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

        created_at_gt : typing.Optional[dt.datetime]

        created_at_lt : typing.Optional[dt.datetime]

        created_at_gte : typing.Optional[dt.datetime]

        created_at_lte : typing.Optional[dt.datetime]

        updated_at_gt : typing.Optional[dt.datetime]

        updated_at_lt : typing.Optional[dt.datetime]

        updated_at_gte : typing.Optional[dt.datetime]

        updated_at_lte : typing.Optional[dt.datetime]

        issued_at_gt : typing.Optional[dt.datetime]

        issued_at_lt : typing.Optional[dt.datetime]

        issued_at_gte : typing.Optional[dt.datetime]

        issued_at_lte : typing.Optional[dt.datetime]

        status : typing.Optional[PurchaseOrderStatusEnum]

        document_id : typing.Optional[str]

        document_id_in : typing.Optional[typing.Union[str, typing.Sequence[str]]]

        created_by : typing.Optional[str]

        counterpart_id : typing.Optional[str]

        counterpart_id_in : typing.Optional[typing.Union[str, typing.Sequence[str]]]

        counterpart_name : typing.Optional[str]

        currency : typing.Optional[CurrencyEnum]

        currency_in : typing.Optional[typing.Union[CurrencyEnum, typing.Sequence[CurrencyEnum]]]

        project_id : typing.Optional[str]

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

        Returns
        -------
        AsyncHttpResponse[PurchaseOrderPaginationResponse]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            "payable_purchase_orders",
            method="GET",
            params={
                "order": order,
                "limit": limit,
                "pagination_token": pagination_token,
                "sort": sort,
                "created_at__gt": serialize_datetime(created_at_gt) if created_at_gt is not None else None,
                "created_at__lt": serialize_datetime(created_at_lt) if created_at_lt is not None else None,
                "created_at__gte": serialize_datetime(created_at_gte) if created_at_gte is not None else None,
                "created_at__lte": serialize_datetime(created_at_lte) if created_at_lte is not None else None,
                "updated_at__gt": serialize_datetime(updated_at_gt) if updated_at_gt is not None else None,
                "updated_at__lt": serialize_datetime(updated_at_lt) if updated_at_lt is not None else None,
                "updated_at__gte": serialize_datetime(updated_at_gte) if updated_at_gte is not None else None,
                "updated_at__lte": serialize_datetime(updated_at_lte) if updated_at_lte is not None else None,
                "issued_at__gt": serialize_datetime(issued_at_gt) if issued_at_gt is not None else None,
                "issued_at__lt": serialize_datetime(issued_at_lt) if issued_at_lt is not None else None,
                "issued_at__gte": serialize_datetime(issued_at_gte) if issued_at_gte is not None else None,
                "issued_at__lte": serialize_datetime(issued_at_lte) if issued_at_lte is not None else None,
                "status": status,
                "document_id": document_id,
                "document_id__in": document_id_in,
                "created_by": created_by,
                "counterpart_id": counterpart_id,
                "counterpart_id__in": counterpart_id_in,
                "counterpart.name": counterpart_name,
                "currency": currency,
                "currency__in": currency_in,
                "project_id": project_id,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    PurchaseOrderPaginationResponse,
                    parse_obj_as(
                        type_=PurchaseOrderPaginationResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def create(
        self,
        *,
        counterpart_id: str,
        currency: CurrencyEnum,
        items: typing.Sequence[PurchaseOrderItem],
        message: str,
        valid_for_days: int,
        counterpart_address_id: typing.Optional[str] = OMIT,
        entity_vat_id_id: typing.Optional[str] = OMIT,
        project_id: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[PurchaseOrderResponseSchema]:
        """
        Parameters
        ----------
        counterpart_id : str
            Counterpart unique ID.

        currency : CurrencyEnum
            The currency in which the price of the product is set. (all items need to have the same currency)

        items : typing.Sequence[PurchaseOrderItem]
            List of item to purchase

        message : str
            Msg which will be send to counterpart for who the purchase order is issued.

        valid_for_days : int
            Number of days for which purchase order is valid

        counterpart_address_id : typing.Optional[str]
            The ID of counterpart address object stored in counterparts service. If not provided, counterpart's default address is used.

        entity_vat_id_id : typing.Optional[str]
            Entity VAT ID identifier that applied to purchase order

        project_id : typing.Optional[str]
            Project ID of a purchase order

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

        Returns
        -------
        AsyncHttpResponse[PurchaseOrderResponseSchema]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            "payable_purchase_orders",
            method="POST",
            json={
                "counterpart_address_id": counterpart_address_id,
                "counterpart_id": counterpart_id,
                "currency": currency,
                "entity_vat_id_id": entity_vat_id_id,
                "items": convert_and_respect_annotation_metadata(
                    object_=items, annotation=typing.Sequence[PurchaseOrderItem], direction="write"
                ),
                "message": message,
                "project_id": project_id,
                "valid_for_days": valid_for_days,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    PurchaseOrderResponseSchema,
                    parse_obj_as(
                        type_=PurchaseOrderResponseSchema,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

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

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

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

    async def get_by_id(
        self, purchase_order_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[PurchaseOrderResponseSchema]:
        """
        Parameters
        ----------
        purchase_order_id : str

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

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

    async def delete_by_id(
        self, purchase_order_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[None]:
        """
        Parameters
        ----------
        purchase_order_id : str

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

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

    async def update_by_id(
        self,
        purchase_order_id: str,
        *,
        counterpart_address_id: typing.Optional[str] = OMIT,
        counterpart_id: typing.Optional[str] = OMIT,
        entity_vat_id_id: typing.Optional[str] = OMIT,
        items: typing.Optional[typing.Sequence[PurchaseOrderItem]] = OMIT,
        message: typing.Optional[str] = OMIT,
        project_id: typing.Optional[str] = OMIT,
        valid_for_days: typing.Optional[int] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[PurchaseOrderResponseSchema]:
        """
        Parameters
        ----------
        purchase_order_id : str

        counterpart_address_id : typing.Optional[str]
            The ID of counterpart address object stored in counterparts service. If not provided, counterpart's default address is used.

        counterpart_id : typing.Optional[str]
            Counterpart unique ID.

        entity_vat_id_id : typing.Optional[str]
            Entity VAT ID identifier that applied to purchase order

        items : typing.Optional[typing.Sequence[PurchaseOrderItem]]
            List of item to purchase

        message : typing.Optional[str]
            Msg which will be send to counterpart for who the purchase order is issued.

        project_id : typing.Optional[str]
            Project ID of a purchase order

        valid_for_days : typing.Optional[int]
            Number of days for which purchase order is valid

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

        Returns
        -------
        AsyncHttpResponse[PurchaseOrderResponseSchema]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"payable_purchase_orders/{jsonable_encoder(purchase_order_id)}",
            method="PATCH",
            json={
                "counterpart_address_id": counterpart_address_id,
                "counterpart_id": counterpart_id,
                "entity_vat_id_id": entity_vat_id_id,
                "items": convert_and_respect_annotation_metadata(
                    object_=items, annotation=typing.Sequence[PurchaseOrderItem], direction="write"
                ),
                "message": message,
                "project_id": project_id,
                "valid_for_days": valid_for_days,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    PurchaseOrderResponseSchema,
                    parse_obj_as(
                        type_=PurchaseOrderResponseSchema,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def preview_by_id(
        self,
        purchase_order_id: str,
        *,
        body_text: str,
        subject_text: str,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[PurchaseOrderEmailPreviewResponse]:
        """
        Parameters
        ----------
        purchase_order_id : str

        body_text : str

        subject_text : str

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

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

    async def send_by_id(
        self,
        purchase_order_id: str,
        *,
        body_text: str,
        subject_text: str,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[PurchaseOrderEmailSentResponse]:
        """
        Parameters
        ----------
        purchase_order_id : str

        body_text : str

        subject_text : str

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

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