# 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.jsonable_encoder import jsonable_encoder
from .....core.pydantic_utilities import pydantic_v1
from .....core.request_options import RequestOptions
from ....commons.errors.entity_not_found_error import EntityNotFoundError
from ....commons.errors.unauthorized_error import UnauthorizedError
from ....commons.errors.unprocessable_entity_error import UnprocessableEntityError
from ....commons.types.claim_id import ClaimId
from ....commons.types.entity_not_found_error_message import EntityNotFoundErrorMessage
from ....commons.types.invoice_id import InvoiceId
from ....commons.types.page_token import PageToken
from ....commons.types.patient_external_id import PatientExternalId
from ....commons.types.provider_id import ProviderId
from ....commons.types.service_line_id import ServiceLineId
from ....commons.types.sort_direction import SortDirection
from ....commons.types.unauthorized_error_message import UnauthorizedErrorMessage
from ....commons.types.unprocessable_entity_error_message import UnprocessableEntityErrorMessage
from ....financials.types.allocation_create import AllocationCreate
from ....financials.types.invoice_update import InvoiceUpdate
from ....financials.types.note_update import NoteUpdate
from ....financials.types.patient_transaction_source import PatientTransactionSource
from .types.patient_payment import PatientPayment
from .types.patient_payment_id import PatientPaymentId
from .types.patient_payment_sort_field import PatientPaymentSortField
from .types.patient_payments_page import PatientPaymentsPage

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


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

    def get_multi(
        self,
        *,
        limit: typing.Optional[int] = None,
        patient_external_id: typing.Optional[PatientExternalId] = None,
        claim_id: typing.Optional[ClaimId] = None,
        service_line_id: typing.Optional[ServiceLineId] = None,
        billing_provider_id: typing.Optional[ProviderId] = None,
        unattributed: typing.Optional[bool] = None,
        invoice_id: typing.Optional[InvoiceId] = None,
        sources: typing.Optional[
            typing.Union[PatientTransactionSource, typing.Sequence[PatientTransactionSource]]
        ] = None,
        sort: typing.Optional[PatientPaymentSortField] = None,
        sort_direction: typing.Optional[SortDirection] = None,
        page_token: typing.Optional[PageToken] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> PatientPaymentsPage:
        """
        Returns all patient payments satisfying the search criteria AND whose organization_id matches
        the current organization_id of the authenticated user.

        Parameters
        ----------
        limit : typing.Optional[int]
            Defaults to 100. The value must be greater than 0 and less than 1000.

        patient_external_id : typing.Optional[PatientExternalId]

        claim_id : typing.Optional[ClaimId]

        service_line_id : typing.Optional[ServiceLineId]

        billing_provider_id : typing.Optional[ProviderId]

        unattributed : typing.Optional[bool]
            returns payments with unattributed allocations if set to true

        invoice_id : typing.Optional[InvoiceId]

        sources : typing.Optional[typing.Union[PatientTransactionSource, typing.Sequence[PatientTransactionSource]]]

        sort : typing.Optional[PatientPaymentSortField]
            Defaults to payment_timestamp

        sort_direction : typing.Optional[SortDirection]
            Sort direction. Defaults to descending order if not provided.

        page_token : typing.Optional[PageToken]

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

        Returns
        -------
        PatientPaymentsPage

        Examples
        --------
        import uuid

        from candid import PatientTransactionSource, SortDirection
        from candid.client import CandidApiClient
        from candid.resources.patient_payments.v_4 import PatientPaymentSortField

        client = CandidApiClient(
            client_id="YOUR_CLIENT_ID",
            client_secret="YOUR_CLIENT_SECRET",
        )
        client.patient_payments.v_4.get_multi(
            limit=1,
            patient_external_id="string",
            claim_id=uuid.UUID(
                "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32",
            ),
            service_line_id=uuid.UUID(
                "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32",
            ),
            billing_provider_id=uuid.UUID(
                "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32",
            ),
            unattributed=True,
            invoice_id=uuid.UUID(
                "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32",
            ),
            sources=PatientTransactionSource.MANUAL_ENTRY,
            sort=PatientPaymentSortField.PAYMENT_SOURCE,
            sort_direction=SortDirection.ASC,
            page_token="eyJ0b2tlbiI6IjEiLCJwYWdlX3Rva2VuIjoiMiJ9",
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            "api/patient-payments/v4",
            method="GET",
            params={
                "limit": limit,
                "patient_external_id": patient_external_id,
                "claim_id": jsonable_encoder(claim_id),
                "service_line_id": jsonable_encoder(service_line_id),
                "billing_provider_id": jsonable_encoder(billing_provider_id),
                "unattributed": unattributed,
                "invoice_id": jsonable_encoder(invoice_id),
                "sources": sources,
                "sort": sort,
                "sort_direction": sort_direction,
                "page_token": page_token,
            },
            request_options=request_options,
        )
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        if 200 <= _response.status_code < 300:
            return pydantic_v1.parse_obj_as(PatientPaymentsPage, _response_json)  # type: ignore
        if "errorName" in _response_json:
            if _response_json["errorName"] == "UnauthorizedError":
                raise UnauthorizedError(
                    pydantic_v1.parse_obj_as(UnauthorizedErrorMessage, _response_json["content"])  # type: ignore
                )
            if _response_json["errorName"] == "UnprocessableEntityError":
                raise UnprocessableEntityError(
                    pydantic_v1.parse_obj_as(UnprocessableEntityErrorMessage, _response_json["content"])  # type: ignore
                )
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def get(
        self, patient_payment_id: PatientPaymentId, *, request_options: typing.Optional[RequestOptions] = None
    ) -> PatientPayment:
        """
        Retrieves a previously created patient payment by its `patient_payment_id`.

        Parameters
        ----------
        patient_payment_id : PatientPaymentId

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

        Returns
        -------
        PatientPayment

        Examples
        --------
        import uuid

        from candid.client import CandidApiClient

        client = CandidApiClient(
            client_id="YOUR_CLIENT_ID",
            client_secret="YOUR_CLIENT_SECRET",
        )
        client.patient_payments.v_4.get(
            patient_payment_id=uuid.UUID(
                "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32",
            ),
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            f"api/patient-payments/v4/{jsonable_encoder(patient_payment_id)}",
            method="GET",
            request_options=request_options,
        )
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        if 200 <= _response.status_code < 300:
            return pydantic_v1.parse_obj_as(PatientPayment, _response_json)  # type: ignore
        if "errorName" in _response_json:
            if _response_json["errorName"] == "EntityNotFoundError":
                raise EntityNotFoundError(
                    pydantic_v1.parse_obj_as(EntityNotFoundErrorMessage, _response_json["content"])  # type: ignore
                )
            if _response_json["errorName"] == "UnauthorizedError":
                raise UnauthorizedError(
                    pydantic_v1.parse_obj_as(UnauthorizedErrorMessage, _response_json["content"])  # type: ignore
                )
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def create(
        self,
        *,
        amount_cents: int,
        patient_external_id: PatientExternalId,
        allocations: typing.Sequence[AllocationCreate],
        payment_timestamp: typing.Optional[dt.datetime] = OMIT,
        payment_note: typing.Optional[str] = OMIT,
        invoice: typing.Optional[InvoiceId] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> PatientPayment:
        """
        Creates a new patient payment record and returns the newly created PatientPayment object.
        The allocations can describe whether the payment is being applied toward a specific service line,
        claim, or billing provider.

        Parameters
        ----------
        amount_cents : int

        patient_external_id : PatientExternalId

        allocations : typing.Sequence[AllocationCreate]

        payment_timestamp : typing.Optional[dt.datetime]

        payment_note : typing.Optional[str]

        invoice : typing.Optional[InvoiceId]

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

        Returns
        -------
        PatientPayment

        Examples
        --------
        import datetime
        import uuid

        from candid import AllocationCreate, AllocationTargetCreate_ServiceLineById
        from candid.client import CandidApiClient

        client = CandidApiClient(
            client_id="YOUR_CLIENT_ID",
            client_secret="YOUR_CLIENT_SECRET",
        )
        client.patient_payments.v_4.create(
            amount_cents=1,
            payment_timestamp=datetime.datetime.fromisoformat(
                "2024-01-15 09:30:00+00:00",
            ),
            payment_note="string",
            patient_external_id="string",
            allocations=[
                AllocationCreate(
                    amount_cents=1,
                    target=AllocationTargetCreate_ServiceLineById(
                        value=uuid.UUID(
                            "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32",
                        )
                    ),
                )
            ],
            invoice=uuid.UUID(
                "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32",
            ),
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            "api/patient-payments/v4",
            method="POST",
            json={
                "amount_cents": amount_cents,
                "payment_timestamp": payment_timestamp,
                "payment_note": payment_note,
                "patient_external_id": patient_external_id,
                "allocations": allocations,
                "invoice": invoice,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        if 200 <= _response.status_code < 300:
            return pydantic_v1.parse_obj_as(PatientPayment, _response_json)  # type: ignore
        if "errorName" in _response_json:
            if _response_json["errorName"] == "EntityNotFoundError":
                raise EntityNotFoundError(
                    pydantic_v1.parse_obj_as(EntityNotFoundErrorMessage, _response_json["content"])  # type: ignore
                )
            if _response_json["errorName"] == "UnauthorizedError":
                raise UnauthorizedError(
                    pydantic_v1.parse_obj_as(UnauthorizedErrorMessage, _response_json["content"])  # type: ignore
                )
            if _response_json["errorName"] == "UnprocessableEntityError":
                raise UnprocessableEntityError(
                    pydantic_v1.parse_obj_as(UnprocessableEntityErrorMessage, _response_json["content"])  # type: ignore
                )
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def update(
        self,
        patient_payment_id: PatientPaymentId,
        *,
        payment_timestamp: typing.Optional[dt.datetime] = OMIT,
        payment_note: typing.Optional[NoteUpdate] = OMIT,
        invoice: typing.Optional[InvoiceUpdate] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> PatientPayment:
        """
        Updates the patient payment record matching the provided patient_payment_id.

        Parameters
        ----------
        patient_payment_id : PatientPaymentId

        payment_timestamp : typing.Optional[dt.datetime]

        payment_note : typing.Optional[NoteUpdate]

        invoice : typing.Optional[InvoiceUpdate]

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

        Returns
        -------
        PatientPayment

        Examples
        --------
        import datetime
        import uuid

        from candid import InvoiceUpdate_Set, NoteUpdate_Set
        from candid.client import CandidApiClient

        client = CandidApiClient(
            client_id="YOUR_CLIENT_ID",
            client_secret="YOUR_CLIENT_SECRET",
        )
        client.patient_payments.v_4.update(
            patient_payment_id=uuid.UUID(
                "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32",
            ),
            payment_timestamp=datetime.datetime.fromisoformat(
                "2024-01-15 09:30:00+00:00",
            ),
            payment_note=NoteUpdate_Set(value="string"),
            invoice=InvoiceUpdate_Set(
                value=uuid.UUID(
                    "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32",
                )
            ),
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            f"api/patient-payments/v4/{jsonable_encoder(patient_payment_id)}",
            method="PATCH",
            json={"payment_timestamp": payment_timestamp, "payment_note": payment_note, "invoice": invoice},
            request_options=request_options,
            omit=OMIT,
        )
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        if 200 <= _response.status_code < 300:
            return pydantic_v1.parse_obj_as(PatientPayment, _response_json)  # type: ignore
        if "errorName" in _response_json:
            if _response_json["errorName"] == "EntityNotFoundError":
                raise EntityNotFoundError(
                    pydantic_v1.parse_obj_as(EntityNotFoundErrorMessage, _response_json["content"])  # type: ignore
                )
            if _response_json["errorName"] == "UnauthorizedError":
                raise UnauthorizedError(
                    pydantic_v1.parse_obj_as(UnauthorizedErrorMessage, _response_json["content"])  # type: ignore
                )
            if _response_json["errorName"] == "UnprocessableEntityError":
                raise UnprocessableEntityError(
                    pydantic_v1.parse_obj_as(UnprocessableEntityErrorMessage, _response_json["content"])  # type: ignore
                )
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def delete(
        self, patient_payment_id: PatientPaymentId, *, request_options: typing.Optional[RequestOptions] = None
    ) -> None:
        """
        Deletes the patient payment record matching the provided patient_payment_id.

        Parameters
        ----------
        patient_payment_id : PatientPaymentId

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

        Returns
        -------
        None

        Examples
        --------
        import uuid

        from candid.client import CandidApiClient

        client = CandidApiClient(
            client_id="YOUR_CLIENT_ID",
            client_secret="YOUR_CLIENT_SECRET",
        )
        client.patient_payments.v_4.delete(
            patient_payment_id=uuid.UUID(
                "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32",
            ),
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            f"api/patient-payments/v4/{jsonable_encoder(patient_payment_id)}",
            method="DELETE",
            request_options=request_options,
        )
        if 200 <= _response.status_code < 300:
            return
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        if "errorName" in _response_json:
            if _response_json["errorName"] == "EntityNotFoundError":
                raise EntityNotFoundError(
                    pydantic_v1.parse_obj_as(EntityNotFoundErrorMessage, _response_json["content"])  # type: ignore
                )
            if _response_json["errorName"] == "UnauthorizedError":
                raise UnauthorizedError(
                    pydantic_v1.parse_obj_as(UnauthorizedErrorMessage, _response_json["content"])  # type: ignore
                )
            if _response_json["errorName"] == "UnprocessableEntityError":
                raise UnprocessableEntityError(
                    pydantic_v1.parse_obj_as(UnprocessableEntityErrorMessage, _response_json["content"])  # type: ignore
                )
        raise ApiError(status_code=_response.status_code, body=_response_json)


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

    async def get_multi(
        self,
        *,
        limit: typing.Optional[int] = None,
        patient_external_id: typing.Optional[PatientExternalId] = None,
        claim_id: typing.Optional[ClaimId] = None,
        service_line_id: typing.Optional[ServiceLineId] = None,
        billing_provider_id: typing.Optional[ProviderId] = None,
        unattributed: typing.Optional[bool] = None,
        invoice_id: typing.Optional[InvoiceId] = None,
        sources: typing.Optional[
            typing.Union[PatientTransactionSource, typing.Sequence[PatientTransactionSource]]
        ] = None,
        sort: typing.Optional[PatientPaymentSortField] = None,
        sort_direction: typing.Optional[SortDirection] = None,
        page_token: typing.Optional[PageToken] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> PatientPaymentsPage:
        """
        Returns all patient payments satisfying the search criteria AND whose organization_id matches
        the current organization_id of the authenticated user.

        Parameters
        ----------
        limit : typing.Optional[int]
            Defaults to 100. The value must be greater than 0 and less than 1000.

        patient_external_id : typing.Optional[PatientExternalId]

        claim_id : typing.Optional[ClaimId]

        service_line_id : typing.Optional[ServiceLineId]

        billing_provider_id : typing.Optional[ProviderId]

        unattributed : typing.Optional[bool]
            returns payments with unattributed allocations if set to true

        invoice_id : typing.Optional[InvoiceId]

        sources : typing.Optional[typing.Union[PatientTransactionSource, typing.Sequence[PatientTransactionSource]]]

        sort : typing.Optional[PatientPaymentSortField]
            Defaults to payment_timestamp

        sort_direction : typing.Optional[SortDirection]
            Sort direction. Defaults to descending order if not provided.

        page_token : typing.Optional[PageToken]

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

        Returns
        -------
        PatientPaymentsPage

        Examples
        --------
        import uuid

        from candid import PatientTransactionSource, SortDirection
        from candid.client import AsyncCandidApiClient
        from candid.resources.patient_payments.v_4 import PatientPaymentSortField

        client = AsyncCandidApiClient(
            client_id="YOUR_CLIENT_ID",
            client_secret="YOUR_CLIENT_SECRET",
        )
        await client.patient_payments.v_4.get_multi(
            limit=1,
            patient_external_id="string",
            claim_id=uuid.UUID(
                "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32",
            ),
            service_line_id=uuid.UUID(
                "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32",
            ),
            billing_provider_id=uuid.UUID(
                "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32",
            ),
            unattributed=True,
            invoice_id=uuid.UUID(
                "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32",
            ),
            sources=PatientTransactionSource.MANUAL_ENTRY,
            sort=PatientPaymentSortField.PAYMENT_SOURCE,
            sort_direction=SortDirection.ASC,
            page_token="eyJ0b2tlbiI6IjEiLCJwYWdlX3Rva2VuIjoiMiJ9",
        )
        """
        _response = await self._client_wrapper.httpx_client.request(
            "api/patient-payments/v4",
            method="GET",
            params={
                "limit": limit,
                "patient_external_id": patient_external_id,
                "claim_id": jsonable_encoder(claim_id),
                "service_line_id": jsonable_encoder(service_line_id),
                "billing_provider_id": jsonable_encoder(billing_provider_id),
                "unattributed": unattributed,
                "invoice_id": jsonable_encoder(invoice_id),
                "sources": sources,
                "sort": sort,
                "sort_direction": sort_direction,
                "page_token": page_token,
            },
            request_options=request_options,
        )
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        if 200 <= _response.status_code < 300:
            return pydantic_v1.parse_obj_as(PatientPaymentsPage, _response_json)  # type: ignore
        if "errorName" in _response_json:
            if _response_json["errorName"] == "UnauthorizedError":
                raise UnauthorizedError(
                    pydantic_v1.parse_obj_as(UnauthorizedErrorMessage, _response_json["content"])  # type: ignore
                )
            if _response_json["errorName"] == "UnprocessableEntityError":
                raise UnprocessableEntityError(
                    pydantic_v1.parse_obj_as(UnprocessableEntityErrorMessage, _response_json["content"])  # type: ignore
                )
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def get(
        self, patient_payment_id: PatientPaymentId, *, request_options: typing.Optional[RequestOptions] = None
    ) -> PatientPayment:
        """
        Retrieves a previously created patient payment by its `patient_payment_id`.

        Parameters
        ----------
        patient_payment_id : PatientPaymentId

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

        Returns
        -------
        PatientPayment

        Examples
        --------
        import uuid

        from candid.client import AsyncCandidApiClient

        client = AsyncCandidApiClient(
            client_id="YOUR_CLIENT_ID",
            client_secret="YOUR_CLIENT_SECRET",
        )
        await client.patient_payments.v_4.get(
            patient_payment_id=uuid.UUID(
                "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32",
            ),
        )
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"api/patient-payments/v4/{jsonable_encoder(patient_payment_id)}",
            method="GET",
            request_options=request_options,
        )
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        if 200 <= _response.status_code < 300:
            return pydantic_v1.parse_obj_as(PatientPayment, _response_json)  # type: ignore
        if "errorName" in _response_json:
            if _response_json["errorName"] == "EntityNotFoundError":
                raise EntityNotFoundError(
                    pydantic_v1.parse_obj_as(EntityNotFoundErrorMessage, _response_json["content"])  # type: ignore
                )
            if _response_json["errorName"] == "UnauthorizedError":
                raise UnauthorizedError(
                    pydantic_v1.parse_obj_as(UnauthorizedErrorMessage, _response_json["content"])  # type: ignore
                )
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def create(
        self,
        *,
        amount_cents: int,
        patient_external_id: PatientExternalId,
        allocations: typing.Sequence[AllocationCreate],
        payment_timestamp: typing.Optional[dt.datetime] = OMIT,
        payment_note: typing.Optional[str] = OMIT,
        invoice: typing.Optional[InvoiceId] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> PatientPayment:
        """
        Creates a new patient payment record and returns the newly created PatientPayment object.
        The allocations can describe whether the payment is being applied toward a specific service line,
        claim, or billing provider.

        Parameters
        ----------
        amount_cents : int

        patient_external_id : PatientExternalId

        allocations : typing.Sequence[AllocationCreate]

        payment_timestamp : typing.Optional[dt.datetime]

        payment_note : typing.Optional[str]

        invoice : typing.Optional[InvoiceId]

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

        Returns
        -------
        PatientPayment

        Examples
        --------
        import datetime
        import uuid

        from candid import AllocationCreate, AllocationTargetCreate_ServiceLineById
        from candid.client import AsyncCandidApiClient

        client = AsyncCandidApiClient(
            client_id="YOUR_CLIENT_ID",
            client_secret="YOUR_CLIENT_SECRET",
        )
        await client.patient_payments.v_4.create(
            amount_cents=1,
            payment_timestamp=datetime.datetime.fromisoformat(
                "2024-01-15 09:30:00+00:00",
            ),
            payment_note="string",
            patient_external_id="string",
            allocations=[
                AllocationCreate(
                    amount_cents=1,
                    target=AllocationTargetCreate_ServiceLineById(
                        value=uuid.UUID(
                            "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32",
                        )
                    ),
                )
            ],
            invoice=uuid.UUID(
                "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32",
            ),
        )
        """
        _response = await self._client_wrapper.httpx_client.request(
            "api/patient-payments/v4",
            method="POST",
            json={
                "amount_cents": amount_cents,
                "payment_timestamp": payment_timestamp,
                "payment_note": payment_note,
                "patient_external_id": patient_external_id,
                "allocations": allocations,
                "invoice": invoice,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        if 200 <= _response.status_code < 300:
            return pydantic_v1.parse_obj_as(PatientPayment, _response_json)  # type: ignore
        if "errorName" in _response_json:
            if _response_json["errorName"] == "EntityNotFoundError":
                raise EntityNotFoundError(
                    pydantic_v1.parse_obj_as(EntityNotFoundErrorMessage, _response_json["content"])  # type: ignore
                )
            if _response_json["errorName"] == "UnauthorizedError":
                raise UnauthorizedError(
                    pydantic_v1.parse_obj_as(UnauthorizedErrorMessage, _response_json["content"])  # type: ignore
                )
            if _response_json["errorName"] == "UnprocessableEntityError":
                raise UnprocessableEntityError(
                    pydantic_v1.parse_obj_as(UnprocessableEntityErrorMessage, _response_json["content"])  # type: ignore
                )
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def update(
        self,
        patient_payment_id: PatientPaymentId,
        *,
        payment_timestamp: typing.Optional[dt.datetime] = OMIT,
        payment_note: typing.Optional[NoteUpdate] = OMIT,
        invoice: typing.Optional[InvoiceUpdate] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> PatientPayment:
        """
        Updates the patient payment record matching the provided patient_payment_id.

        Parameters
        ----------
        patient_payment_id : PatientPaymentId

        payment_timestamp : typing.Optional[dt.datetime]

        payment_note : typing.Optional[NoteUpdate]

        invoice : typing.Optional[InvoiceUpdate]

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

        Returns
        -------
        PatientPayment

        Examples
        --------
        import datetime
        import uuid

        from candid import InvoiceUpdate_Set, NoteUpdate_Set
        from candid.client import AsyncCandidApiClient

        client = AsyncCandidApiClient(
            client_id="YOUR_CLIENT_ID",
            client_secret="YOUR_CLIENT_SECRET",
        )
        await client.patient_payments.v_4.update(
            patient_payment_id=uuid.UUID(
                "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32",
            ),
            payment_timestamp=datetime.datetime.fromisoformat(
                "2024-01-15 09:30:00+00:00",
            ),
            payment_note=NoteUpdate_Set(value="string"),
            invoice=InvoiceUpdate_Set(
                value=uuid.UUID(
                    "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32",
                )
            ),
        )
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"api/patient-payments/v4/{jsonable_encoder(patient_payment_id)}",
            method="PATCH",
            json={"payment_timestamp": payment_timestamp, "payment_note": payment_note, "invoice": invoice},
            request_options=request_options,
            omit=OMIT,
        )
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        if 200 <= _response.status_code < 300:
            return pydantic_v1.parse_obj_as(PatientPayment, _response_json)  # type: ignore
        if "errorName" in _response_json:
            if _response_json["errorName"] == "EntityNotFoundError":
                raise EntityNotFoundError(
                    pydantic_v1.parse_obj_as(EntityNotFoundErrorMessage, _response_json["content"])  # type: ignore
                )
            if _response_json["errorName"] == "UnauthorizedError":
                raise UnauthorizedError(
                    pydantic_v1.parse_obj_as(UnauthorizedErrorMessage, _response_json["content"])  # type: ignore
                )
            if _response_json["errorName"] == "UnprocessableEntityError":
                raise UnprocessableEntityError(
                    pydantic_v1.parse_obj_as(UnprocessableEntityErrorMessage, _response_json["content"])  # type: ignore
                )
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def delete(
        self, patient_payment_id: PatientPaymentId, *, request_options: typing.Optional[RequestOptions] = None
    ) -> None:
        """
        Deletes the patient payment record matching the provided patient_payment_id.

        Parameters
        ----------
        patient_payment_id : PatientPaymentId

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

        Returns
        -------
        None

        Examples
        --------
        import uuid

        from candid.client import AsyncCandidApiClient

        client = AsyncCandidApiClient(
            client_id="YOUR_CLIENT_ID",
            client_secret="YOUR_CLIENT_SECRET",
        )
        await client.patient_payments.v_4.delete(
            patient_payment_id=uuid.UUID(
                "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32",
            ),
        )
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"api/patient-payments/v4/{jsonable_encoder(patient_payment_id)}",
            method="DELETE",
            request_options=request_options,
        )
        if 200 <= _response.status_code < 300:
            return
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        if "errorName" in _response_json:
            if _response_json["errorName"] == "EntityNotFoundError":
                raise EntityNotFoundError(
                    pydantic_v1.parse_obj_as(EntityNotFoundErrorMessage, _response_json["content"])  # type: ignore
                )
            if _response_json["errorName"] == "UnauthorizedError":
                raise UnauthorizedError(
                    pydantic_v1.parse_obj_as(UnauthorizedErrorMessage, _response_json["content"])  # type: ignore
                )
            if _response_json["errorName"] == "UnprocessableEntityError":
                raise UnprocessableEntityError(
                    pydantic_v1.parse_obj_as(UnprocessableEntityErrorMessage, _response_json["content"])  # type: ignore
                )
        raise ApiError(status_code=_response.status_code, body=_response_json)
