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

import typing

from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
from ..core.request_options import RequestOptions
from ..money_out_types.types.auth_capture_payout_response import AuthCapturePayoutResponse
from ..money_out_types.types.authorize_payment_method import AuthorizePaymentMethod
from ..money_out_types.types.capture_all_out_response import CaptureAllOutResponse
from ..money_out_types.types.operation_result import OperationResult
from ..money_out_types.types.request_out_authorize_invoice_data import RequestOutAuthorizeInvoiceData
from ..money_out_types.types.request_out_authorize_payment_details import RequestOutAuthorizePaymentDetails
from ..money_out_types.types.request_out_authorize_vendor_data import RequestOutAuthorizeVendorData
from ..money_out_types.types.v_card_get_response import VCardGetResponse
from ..types.accountid import Accountid
from ..types.bill_detail_response import BillDetailResponse
from ..types.entrypointfield import Entrypointfield
from ..types.idempotency_key import IdempotencyKey
from ..types.order_id import OrderId
from ..types.orderdescription import Orderdescription
from ..types.payabli_api_response_0000 import PayabliApiResponse0000
from ..types.source import Source
from ..types.subdomain import Subdomain
from ..types.subscriptionid import Subscriptionid
from .raw_client import AsyncRawMoneyOutClient, RawMoneyOutClient

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


class MoneyOutClient:
    def __init__(self, *, client_wrapper: SyncClientWrapper):
        self._raw_client = RawMoneyOutClient(client_wrapper=client_wrapper)

    @property
    def with_raw_response(self) -> RawMoneyOutClient:
        """
        Retrieves a raw implementation of this client that returns raw responses.

        Returns
        -------
        RawMoneyOutClient
        """
        return self._raw_client

    def authorize_out(
        self,
        *,
        entry_point: Entrypointfield,
        payment_method: AuthorizePaymentMethod,
        payment_details: RequestOutAuthorizePaymentDetails,
        vendor_data: RequestOutAuthorizeVendorData,
        invoice_data: typing.Sequence[RequestOutAuthorizeInvoiceData],
        allow_duplicated_bills: typing.Optional[bool] = None,
        do_not_create_bills: typing.Optional[bool] = None,
        force_vendor_creation: typing.Optional[bool] = None,
        idempotency_key: typing.Optional[IdempotencyKey] = None,
        source: typing.Optional[Source] = OMIT,
        order_id: typing.Optional[OrderId] = OMIT,
        order_description: typing.Optional[Orderdescription] = OMIT,
        account_id: typing.Optional[Accountid] = OMIT,
        subdomain: typing.Optional[Subdomain] = OMIT,
        subscription_id: typing.Optional[Subscriptionid] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AuthCapturePayoutResponse:
        """
        Authorizes transaction for payout. Authorized transactions aren't flagged for settlement until captured. Use `referenceId` returned in the response to capture the transaction.

        Parameters
        ----------
        entry_point : Entrypointfield

        payment_method : AuthorizePaymentMethod

        payment_details : RequestOutAuthorizePaymentDetails
            Object containing payment details.

        vendor_data : RequestOutAuthorizeVendorData
            Object containing vendor data.

        invoice_data : typing.Sequence[RequestOutAuthorizeInvoiceData]
            Array of bills associated to the transaction

        allow_duplicated_bills : typing.Optional[bool]
            When `true`, the authorization bypasses the requirement for unique bills, identified by vendor invoice number. This allows you to make more than one payout authorization for a bill, like a split payment.

        do_not_create_bills : typing.Optional[bool]
            When `true`, Payabli won't automatically create a bill for this payout transaction.

        force_vendor_creation : typing.Optional[bool]
            When `true`, the request creates a new vendor record, regardless of whether the vendor already exists.

        idempotency_key : typing.Optional[IdempotencyKey]

        source : typing.Optional[Source]

        order_id : typing.Optional[OrderId]

        order_description : typing.Optional[Orderdescription]

        account_id : typing.Optional[Accountid]

        subdomain : typing.Optional[Subdomain]

        subscription_id : typing.Optional[Subscriptionid]

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

        Returns
        -------
        AuthCapturePayoutResponse
            Success

        Examples
        --------
        from payabli import payabli
        from payabli.money_out_types import (
            AuthorizePaymentMethod,
            RequestOutAuthorizeInvoiceData,
            RequestOutAuthorizePaymentDetails,
            RequestOutAuthorizeVendorData,
        )

        client = payabli(
            api_key="YOUR_API_KEY",
        )
        client.money_out.authorize_out(
            entry_point="48acde49",
            invoice_data=[
                RequestOutAuthorizeInvoiceData(
                    bill_id=54323,
                )
            ],
            order_description="Window Painting",
            payment_details=RequestOutAuthorizePaymentDetails(
                total_amount=47.0,
            ),
            payment_method=AuthorizePaymentMethod(
                method="managed",
            ),
            vendor_data=RequestOutAuthorizeVendorData(
                vendor_number="7895433",
            ),
        )
        """
        _response = self._raw_client.authorize_out(
            entry_point=entry_point,
            payment_method=payment_method,
            payment_details=payment_details,
            vendor_data=vendor_data,
            invoice_data=invoice_data,
            allow_duplicated_bills=allow_duplicated_bills,
            do_not_create_bills=do_not_create_bills,
            force_vendor_creation=force_vendor_creation,
            idempotency_key=idempotency_key,
            source=source,
            order_id=order_id,
            order_description=order_description,
            account_id=account_id,
            subdomain=subdomain,
            subscription_id=subscription_id,
            request_options=request_options,
        )
        return _response.data

    def cancel_all_out(
        self, *, request: typing.Sequence[str], request_options: typing.Optional[RequestOptions] = None
    ) -> CaptureAllOutResponse:
        """
        Cancels an array of payout transactions.

        Parameters
        ----------
        request : typing.Sequence[str]

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

        Returns
        -------
        CaptureAllOutResponse
            Success

        Examples
        --------
        from payabli import payabli

        client = payabli(
            api_key="YOUR_API_KEY",
        )
        client.money_out.cancel_all_out(
            request=["2-29", "2-28", "2-27"],
        )
        """
        _response = self._raw_client.cancel_all_out(request=request, request_options=request_options)
        return _response.data

    def cancel_out(
        self, reference_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> PayabliApiResponse0000:
        """
        Cancel a payout transaction by ID.

        Parameters
        ----------
        reference_id : str
            The ID for the payout transaction.

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

        Returns
        -------
        PayabliApiResponse0000
            Success

        Examples
        --------
        from payabli import payabli

        client = payabli(
            api_key="YOUR_API_KEY",
        )
        client.money_out.cancel_out(
            reference_id="129-219",
        )
        """
        _response = self._raw_client.cancel_out(reference_id, request_options=request_options)
        return _response.data

    def capture_all_out(
        self,
        *,
        request: typing.Sequence[str],
        idempotency_key: typing.Optional[IdempotencyKey] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> CaptureAllOutResponse:
        """
        Captures an array of authorized payout transactions for settlement.

        Parameters
        ----------
        request : typing.Sequence[str]

        idempotency_key : typing.Optional[IdempotencyKey]

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

        Returns
        -------
        CaptureAllOutResponse
            Success

        Examples
        --------
        from payabli import payabli

        client = payabli(
            api_key="YOUR_API_KEY",
        )
        client.money_out.capture_all_out(
            request=["2-29", "2-28", "2-27"],
        )
        """
        _response = self._raw_client.capture_all_out(
            request=request, idempotency_key=idempotency_key, request_options=request_options
        )
        return _response.data

    def capture_out(
        self,
        reference_id: str,
        *,
        idempotency_key: typing.Optional[IdempotencyKey] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AuthCapturePayoutResponse:
        """
        Captures a single authorized payout transaction by ID.

        Parameters
        ----------
        reference_id : str
            The ID for the payout transaction.

        idempotency_key : typing.Optional[IdempotencyKey]

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

        Returns
        -------
        AuthCapturePayoutResponse
            Success

        Examples
        --------
        from payabli import payabli

        client = payabli(
            api_key="YOUR_API_KEY",
        )
        client.money_out.capture_out(
            reference_id="129-219",
        )
        """
        _response = self._raw_client.capture_out(
            reference_id, idempotency_key=idempotency_key, request_options=request_options
        )
        return _response.data

    def payout_details(
        self, trans_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> BillDetailResponse:
        """
        Returns details for a processed money out transaction.

        Parameters
        ----------
        trans_id : str
            ReferenceId for the transaction (PaymentId).

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

        Returns
        -------
        BillDetailResponse
            Success

        Examples
        --------
        from payabli import payabli

        client = payabli(
            api_key="YOUR_API_KEY",
        )
        client.money_out.payout_details(
            trans_id="45-as456777hhhhhhhhhh77777777-324",
        )
        """
        _response = self._raw_client.payout_details(trans_id, request_options=request_options)
        return _response.data

    def v_card_get(
        self, card_token: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> VCardGetResponse:
        """
        Retrieves vCard details for a single card in an entrypoint.

        Parameters
        ----------
        card_token : str
            ID for a virtual card.

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

        Returns
        -------
        VCardGetResponse
            Success

        Examples
        --------
        from payabli import payabli

        client = payabli(
            api_key="YOUR_API_KEY",
        )
        client.money_out.v_card_get(
            card_token="20230403315245421165",
        )
        """
        _response = self._raw_client.v_card_get(card_token, request_options=request_options)
        return _response.data

    def send_v_card_link(
        self, *, trans_id: str, request_options: typing.Optional[RequestOptions] = None
    ) -> OperationResult:
        """
        Sends a virtual card link via email to the vendor associated with the `transId`.

        Parameters
        ----------
        trans_id : str
            The transaction ID of the virtual card payout. The ID is returned as `ReferenceId` in the response when you authorize a payout with POST /MoneyOut/authorize.

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

        Returns
        -------
        OperationResult

        Examples
        --------
        from payabli import payabli

        client = payabli(
            api_key="YOUR_API_KEY",
        )
        client.money_out.send_v_card_link(
            trans_id="01K33Z6YQZ6GD5QVKZ856MJBSC",
        )
        """
        _response = self._raw_client.send_v_card_link(trans_id=trans_id, request_options=request_options)
        return _response.data

    def get_check_image(self, asset_name: str, *, request_options: typing.Optional[RequestOptions] = None) -> str:
        """
        Retrieve the image of a check associated with a processed transaction.
        The check image is returned in the response body as a base64-encoded string.
        The check image is only available for payouts that have been processed.

        Parameters
        ----------
        asset_name : str
            Name of the check asset to retrieve. This is returned as `filename` in the `CheckData` object
            in the response when you make a GET request to `/MoneyOut/details/{transId}`.
            ```
                "CheckData": {
                  "ftype": "PDF",
                  "filename": "check133832686289732320_01JKBNZ5P32JPTZY8XXXX000000.pdf",
                  "furl": "",
                  "fContent": ""
              }
            ```

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

        Returns
        -------
        str
            A base64-encoded string of the check image.

        Examples
        --------
        from payabli import payabli

        client = payabli(
            api_key="YOUR_API_KEY",
        )
        client.money_out.get_check_image(
            asset_name="check133832686289732320_01JKBNZ5P32JPTZY8XXXX000000.pdf",
        )
        """
        _response = self._raw_client.get_check_image(asset_name, request_options=request_options)
        return _response.data


class AsyncMoneyOutClient:
    def __init__(self, *, client_wrapper: AsyncClientWrapper):
        self._raw_client = AsyncRawMoneyOutClient(client_wrapper=client_wrapper)

    @property
    def with_raw_response(self) -> AsyncRawMoneyOutClient:
        """
        Retrieves a raw implementation of this client that returns raw responses.

        Returns
        -------
        AsyncRawMoneyOutClient
        """
        return self._raw_client

    async def authorize_out(
        self,
        *,
        entry_point: Entrypointfield,
        payment_method: AuthorizePaymentMethod,
        payment_details: RequestOutAuthorizePaymentDetails,
        vendor_data: RequestOutAuthorizeVendorData,
        invoice_data: typing.Sequence[RequestOutAuthorizeInvoiceData],
        allow_duplicated_bills: typing.Optional[bool] = None,
        do_not_create_bills: typing.Optional[bool] = None,
        force_vendor_creation: typing.Optional[bool] = None,
        idempotency_key: typing.Optional[IdempotencyKey] = None,
        source: typing.Optional[Source] = OMIT,
        order_id: typing.Optional[OrderId] = OMIT,
        order_description: typing.Optional[Orderdescription] = OMIT,
        account_id: typing.Optional[Accountid] = OMIT,
        subdomain: typing.Optional[Subdomain] = OMIT,
        subscription_id: typing.Optional[Subscriptionid] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AuthCapturePayoutResponse:
        """
        Authorizes transaction for payout. Authorized transactions aren't flagged for settlement until captured. Use `referenceId` returned in the response to capture the transaction.

        Parameters
        ----------
        entry_point : Entrypointfield

        payment_method : AuthorizePaymentMethod

        payment_details : RequestOutAuthorizePaymentDetails
            Object containing payment details.

        vendor_data : RequestOutAuthorizeVendorData
            Object containing vendor data.

        invoice_data : typing.Sequence[RequestOutAuthorizeInvoiceData]
            Array of bills associated to the transaction

        allow_duplicated_bills : typing.Optional[bool]
            When `true`, the authorization bypasses the requirement for unique bills, identified by vendor invoice number. This allows you to make more than one payout authorization for a bill, like a split payment.

        do_not_create_bills : typing.Optional[bool]
            When `true`, Payabli won't automatically create a bill for this payout transaction.

        force_vendor_creation : typing.Optional[bool]
            When `true`, the request creates a new vendor record, regardless of whether the vendor already exists.

        idempotency_key : typing.Optional[IdempotencyKey]

        source : typing.Optional[Source]

        order_id : typing.Optional[OrderId]

        order_description : typing.Optional[Orderdescription]

        account_id : typing.Optional[Accountid]

        subdomain : typing.Optional[Subdomain]

        subscription_id : typing.Optional[Subscriptionid]

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

        Returns
        -------
        AuthCapturePayoutResponse
            Success

        Examples
        --------
        import asyncio

        from payabli import Asyncpayabli
        from payabli.money_out_types import (
            AuthorizePaymentMethod,
            RequestOutAuthorizeInvoiceData,
            RequestOutAuthorizePaymentDetails,
            RequestOutAuthorizeVendorData,
        )

        client = Asyncpayabli(
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            await client.money_out.authorize_out(
                entry_point="48acde49",
                invoice_data=[
                    RequestOutAuthorizeInvoiceData(
                        bill_id=54323,
                    )
                ],
                order_description="Window Painting",
                payment_details=RequestOutAuthorizePaymentDetails(
                    total_amount=47.0,
                ),
                payment_method=AuthorizePaymentMethod(
                    method="managed",
                ),
                vendor_data=RequestOutAuthorizeVendorData(
                    vendor_number="7895433",
                ),
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.authorize_out(
            entry_point=entry_point,
            payment_method=payment_method,
            payment_details=payment_details,
            vendor_data=vendor_data,
            invoice_data=invoice_data,
            allow_duplicated_bills=allow_duplicated_bills,
            do_not_create_bills=do_not_create_bills,
            force_vendor_creation=force_vendor_creation,
            idempotency_key=idempotency_key,
            source=source,
            order_id=order_id,
            order_description=order_description,
            account_id=account_id,
            subdomain=subdomain,
            subscription_id=subscription_id,
            request_options=request_options,
        )
        return _response.data

    async def cancel_all_out(
        self, *, request: typing.Sequence[str], request_options: typing.Optional[RequestOptions] = None
    ) -> CaptureAllOutResponse:
        """
        Cancels an array of payout transactions.

        Parameters
        ----------
        request : typing.Sequence[str]

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

        Returns
        -------
        CaptureAllOutResponse
            Success

        Examples
        --------
        import asyncio

        from payabli import Asyncpayabli

        client = Asyncpayabli(
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            await client.money_out.cancel_all_out(
                request=["2-29", "2-28", "2-27"],
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.cancel_all_out(request=request, request_options=request_options)
        return _response.data

    async def cancel_out(
        self, reference_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> PayabliApiResponse0000:
        """
        Cancel a payout transaction by ID.

        Parameters
        ----------
        reference_id : str
            The ID for the payout transaction.

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

        Returns
        -------
        PayabliApiResponse0000
            Success

        Examples
        --------
        import asyncio

        from payabli import Asyncpayabli

        client = Asyncpayabli(
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            await client.money_out.cancel_out(
                reference_id="129-219",
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.cancel_out(reference_id, request_options=request_options)
        return _response.data

    async def capture_all_out(
        self,
        *,
        request: typing.Sequence[str],
        idempotency_key: typing.Optional[IdempotencyKey] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> CaptureAllOutResponse:
        """
        Captures an array of authorized payout transactions for settlement.

        Parameters
        ----------
        request : typing.Sequence[str]

        idempotency_key : typing.Optional[IdempotencyKey]

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

        Returns
        -------
        CaptureAllOutResponse
            Success

        Examples
        --------
        import asyncio

        from payabli import Asyncpayabli

        client = Asyncpayabli(
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            await client.money_out.capture_all_out(
                request=["2-29", "2-28", "2-27"],
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.capture_all_out(
            request=request, idempotency_key=idempotency_key, request_options=request_options
        )
        return _response.data

    async def capture_out(
        self,
        reference_id: str,
        *,
        idempotency_key: typing.Optional[IdempotencyKey] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AuthCapturePayoutResponse:
        """
        Captures a single authorized payout transaction by ID.

        Parameters
        ----------
        reference_id : str
            The ID for the payout transaction.

        idempotency_key : typing.Optional[IdempotencyKey]

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

        Returns
        -------
        AuthCapturePayoutResponse
            Success

        Examples
        --------
        import asyncio

        from payabli import Asyncpayabli

        client = Asyncpayabli(
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            await client.money_out.capture_out(
                reference_id="129-219",
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.capture_out(
            reference_id, idempotency_key=idempotency_key, request_options=request_options
        )
        return _response.data

    async def payout_details(
        self, trans_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> BillDetailResponse:
        """
        Returns details for a processed money out transaction.

        Parameters
        ----------
        trans_id : str
            ReferenceId for the transaction (PaymentId).

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

        Returns
        -------
        BillDetailResponse
            Success

        Examples
        --------
        import asyncio

        from payabli import Asyncpayabli

        client = Asyncpayabli(
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            await client.money_out.payout_details(
                trans_id="45-as456777hhhhhhhhhh77777777-324",
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.payout_details(trans_id, request_options=request_options)
        return _response.data

    async def v_card_get(
        self, card_token: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> VCardGetResponse:
        """
        Retrieves vCard details for a single card in an entrypoint.

        Parameters
        ----------
        card_token : str
            ID for a virtual card.

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

        Returns
        -------
        VCardGetResponse
            Success

        Examples
        --------
        import asyncio

        from payabli import Asyncpayabli

        client = Asyncpayabli(
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            await client.money_out.v_card_get(
                card_token="20230403315245421165",
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.v_card_get(card_token, request_options=request_options)
        return _response.data

    async def send_v_card_link(
        self, *, trans_id: str, request_options: typing.Optional[RequestOptions] = None
    ) -> OperationResult:
        """
        Sends a virtual card link via email to the vendor associated with the `transId`.

        Parameters
        ----------
        trans_id : str
            The transaction ID of the virtual card payout. The ID is returned as `ReferenceId` in the response when you authorize a payout with POST /MoneyOut/authorize.

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

        Returns
        -------
        OperationResult

        Examples
        --------
        import asyncio

        from payabli import Asyncpayabli

        client = Asyncpayabli(
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            await client.money_out.send_v_card_link(
                trans_id="01K33Z6YQZ6GD5QVKZ856MJBSC",
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.send_v_card_link(trans_id=trans_id, request_options=request_options)
        return _response.data

    async def get_check_image(self, asset_name: str, *, request_options: typing.Optional[RequestOptions] = None) -> str:
        """
        Retrieve the image of a check associated with a processed transaction.
        The check image is returned in the response body as a base64-encoded string.
        The check image is only available for payouts that have been processed.

        Parameters
        ----------
        asset_name : str
            Name of the check asset to retrieve. This is returned as `filename` in the `CheckData` object
            in the response when you make a GET request to `/MoneyOut/details/{transId}`.
            ```
                "CheckData": {
                  "ftype": "PDF",
                  "filename": "check133832686289732320_01JKBNZ5P32JPTZY8XXXX000000.pdf",
                  "furl": "",
                  "fContent": ""
              }
            ```

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

        Returns
        -------
        str
            A base64-encoded string of the check image.

        Examples
        --------
        import asyncio

        from payabli import Asyncpayabli

        client = Asyncpayabli(
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            await client.money_out.get_check_image(
                asset_name="check133832686289732320_01JKBNZ5P32JPTZY8XXXX000000.pdf",
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.get_check_image(asset_name, request_options=request_options)
        return _response.data
