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

import typing
from ..core.client_wrapper import SyncClientWrapper
from .notification_configuration.client import NotificationConfigurationClient
from ..core.request_options import RequestOptions
from ..organization_types.types.organization_response import OrganizationResponse
from json.decoder import JSONDecodeError
from ..core.api_error import ApiError
from ..core.pydantic_utilities import parse_obj_as
from ..commons.errors.bad_request import BadRequest
from ..commons.errors.unauthorized import Unauthorized
from ..commons.errors.forbidden import Forbidden
from ..commons.errors.not_found import NotFound
from ..commons.errors.conflict import Conflict
from ..commons.errors.internal_server_error import InternalServerError
from ..commons.errors.unimplemented import Unimplemented
from ..organization_types.types.organization_request import OrganizationRequest
import datetime as dt
from ..email_log_types.types.email_log_response import EmailLogResponse
from ..core.datetime_utils import serialize_datetime
from ..core.client_wrapper import AsyncClientWrapper
from .notification_configuration.client import AsyncNotificationConfigurationClient

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


class OrganizationClient:
    def __init__(self, *, client_wrapper: SyncClientWrapper):
        self._client_wrapper = client_wrapper
        self.notification_configuration = NotificationConfigurationClient(client_wrapper=self._client_wrapper)

    def get(
        self,
        *,
        payment_methods: typing.Optional[bool] = None,
        email_provider: typing.Optional[bool] = None,
        external_accounting_system_provider: typing.Optional[bool] = None,
        color_scheme: typing.Optional[bool] = None,
        payee_onboarding_options: typing.Optional[bool] = None,
        payor_onboarding_options: typing.Optional[bool] = None,
        metadata_schema: typing.Optional[bool] = None,
        notification_email_template: typing.Optional[bool] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> OrganizationResponse:
        """
        Get current organization information

        Parameters
        ----------
        payment_methods : typing.Optional[bool]
            include supported payment methods in response

        email_provider : typing.Optional[bool]
            include email provider info in response

        external_accounting_system_provider : typing.Optional[bool]
            include external accounting system provider info in response

        color_scheme : typing.Optional[bool]
            include color scheme info in response

        payee_onboarding_options : typing.Optional[bool]
            include payee onboarding options in response

        payor_onboarding_options : typing.Optional[bool]
            include payor onboarding options in response

        metadata_schema : typing.Optional[bool]
            include metadata schema in response

        notification_email_template : typing.Optional[bool]
            include notification-email-template in response

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

        Returns
        -------
        OrganizationResponse

        Examples
        --------
        from mercoa import Mercoa

        client = Mercoa(
            token="YOUR_TOKEN",
        )
        client.organization.get(
            payment_methods=True,
            email_provider=True,
            external_accounting_system_provider=True,
            color_scheme=True,
            payee_onboarding_options=True,
            payor_onboarding_options=True,
            metadata_schema=True,
            notification_email_template=True,
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            "organization",
            method="GET",
            params={
                "paymentMethods": payment_methods,
                "emailProvider": email_provider,
                "externalAccountingSystemProvider": external_accounting_system_provider,
                "colorScheme": color_scheme,
                "payeeOnboardingOptions": payee_onboarding_options,
                "payorOnboardingOptions": payor_onboarding_options,
                "metadataSchema": metadata_schema,
                "notificationEmailTemplate": notification_email_template,
            },
            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 typing.cast(
                OrganizationResponse,
                parse_obj_as(
                    type_=OrganizationResponse,  # type: ignore
                    object_=_response_json,
                ),
            )
        if "errorName" in _response_json:
            if _response_json["errorName"] == "BadRequest":
                raise BadRequest(
                    typing.cast(
                        str,
                        parse_obj_as(
                            type_=str,  # type: ignore
                            object_=_response_json["content"],
                        ),
                    )
                )
            if _response_json["errorName"] == "Unauthorized":
                raise Unauthorized(
                    typing.cast(
                        str,
                        parse_obj_as(
                            type_=str,  # type: ignore
                            object_=_response_json["content"],
                        ),
                    )
                )
            if _response_json["errorName"] == "Forbidden":
                raise Forbidden(
                    typing.cast(
                        str,
                        parse_obj_as(
                            type_=str,  # type: ignore
                            object_=_response_json["content"],
                        ),
                    )
                )
            if _response_json["errorName"] == "NotFound":
                raise NotFound(
                    typing.cast(
                        str,
                        parse_obj_as(
                            type_=str,  # type: ignore
                            object_=_response_json["content"],
                        ),
                    )
                )
            if _response_json["errorName"] == "Conflict":
                raise Conflict(
                    typing.cast(
                        str,
                        parse_obj_as(
                            type_=str,  # type: ignore
                            object_=_response_json["content"],
                        ),
                    )
                )
            if _response_json["errorName"] == "InternalServerError":
                raise InternalServerError(
                    typing.cast(
                        str,
                        parse_obj_as(
                            type_=str,  # type: ignore
                            object_=_response_json["content"],
                        ),
                    )
                )
            if _response_json["errorName"] == "Unimplemented":
                raise Unimplemented(
                    typing.cast(
                        str,
                        parse_obj_as(
                            type_=str,  # type: ignore
                            object_=_response_json["content"],
                        ),
                    )
                )
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def update(
        self, *, request: OrganizationRequest, request_options: typing.Optional[RequestOptions] = None
    ) -> OrganizationResponse:
        """
        Update current organization

        Parameters
        ----------
        request : OrganizationRequest

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

        Returns
        -------
        OrganizationResponse

        Examples
        --------
        from mercoa import Mercoa
        from mercoa.organization_types import (
            BusinessOnboardingOptions,
            ColorSchemeRequest,
            EmailProviderRequest,
            EmailSenderRequest,
            ExternalAccountingSystemProviderRequest_None,
            IndividualOnboardingOptions,
            MetadataSchema,
            NotificationEmailTemplateRequest,
            OnboardingOption,
            OnboardingOptionsRequest,
            OrganizationRequest,
            PaymentMethodsRequest,
            PaymentRailRequest,
        )

        client = Mercoa(
            token="YOUR_TOKEN",
        )
        client.organization.update(
            request=OrganizationRequest(
                name="string",
                logo="string",
                website_url="string",
                support_email="string",
                payment_methods=PaymentMethodsRequest(
                    payer_payments=[
                        PaymentRailRequest(
                            type="custom",
                            active=True,
                        )
                    ],
                    backup_disbursements=[
                        PaymentRailRequest(
                            type="custom",
                            active=True,
                        )
                    ],
                    vendor_disbursements=[
                        PaymentRailRequest(
                            type="custom",
                            active=True,
                        )
                    ],
                ),
                email_provider=EmailProviderRequest(
                    sender=EmailSenderRequest(
                        provider="none",
                        from_email="string",
                        from_name="string",
                        api_key="string",
                    ),
                    inbox_domain="string",
                    alternative_inbox_domains=[],
                ),
                external_accounting_system_provider=ExternalAccountingSystemProviderRequest_None(),
                color_scheme=ColorSchemeRequest(
                    primary_color="string",
                    secondary_color="string",
                    logo_background_color="string",
                    rounded_corners=1,
                ),
                payee_onboarding_options=OnboardingOptionsRequest(
                    enable_business=True,
                    enable_individual=True,
                    payment_method=True,
                    business=BusinessOnboardingOptions(
                        type=OnboardingOption(
                            show=True,
                            edit=True,
                            required=True,
                        ),
                        doing_business_as=OnboardingOption(
                            show=True,
                            edit=True,
                            required=True,
                        ),
                        ein=OnboardingOption(
                            show=True,
                            edit=True,
                            required=True,
                        ),
                        mcc=OnboardingOption(
                            show=True,
                            edit=True,
                            required=True,
                        ),
                        formation_date=OnboardingOption(
                            show=True,
                            edit=True,
                            required=True,
                        ),
                        website=OnboardingOption(
                            show=True,
                            edit=True,
                            required=True,
                        ),
                        description=OnboardingOption(
                            show=True,
                            edit=True,
                            required=True,
                        ),
                        representatives=OnboardingOption(
                            show=True,
                            edit=True,
                            required=True,
                        ),
                        logo=OnboardingOption(
                            show=True,
                            edit=True,
                            required=True,
                        ),
                        average_transaction_size=OnboardingOption(
                            show=True,
                            edit=True,
                            required=True,
                        ),
                        average_monthly_transaction_volume=OnboardingOption(
                            show=True,
                            edit=True,
                            required=True,
                        ),
                        max_transaction_size=OnboardingOption(
                            show=True,
                            edit=True,
                            required=True,
                        ),
                        terms_of_service=OnboardingOption(
                            show=True,
                            edit=True,
                            required=True,
                        ),
                        email=OnboardingOption(
                            show=True,
                            edit=True,
                            required=True,
                        ),
                        name=OnboardingOption(
                            show=True,
                            edit=True,
                            required=True,
                        ),
                        address=OnboardingOption(
                            show=True,
                            edit=True,
                            required=True,
                        ),
                        phone=OnboardingOption(
                            show=True,
                            edit=True,
                            required=True,
                        ),
                        ten_ninety_nine=OnboardingOption(
                            show=True,
                            edit=True,
                            required=True,
                        ),
                        w_9=OnboardingOption(
                            show=True,
                            edit=True,
                            required=True,
                        ),
                    ),
                    individual=IndividualOnboardingOptions(
                        date_of_birth=OnboardingOption(
                            show=True,
                            edit=True,
                            required=True,
                        ),
                        ssn=OnboardingOption(
                            show=True,
                            edit=True,
                            required=True,
                        ),
                        terms_of_service=OnboardingOption(
                            show=True,
                            edit=True,
                            required=True,
                        ),
                        email=OnboardingOption(
                            show=True,
                            edit=True,
                            required=True,
                        ),
                        name=OnboardingOption(
                            show=True,
                            edit=True,
                            required=True,
                        ),
                        address=OnboardingOption(
                            show=True,
                            edit=True,
                            required=True,
                        ),
                        phone=OnboardingOption(
                            show=True,
                            edit=True,
                            required=True,
                        ),
                        ten_ninety_nine=OnboardingOption(
                            show=True,
                            edit=True,
                            required=True,
                        ),
                        w_9=OnboardingOption(
                            show=True,
                            edit=True,
                            required=True,
                        ),
                    ),
                ),
                payor_onboarding_options=OnboardingOptionsRequest(
                    enable_business=True,
                    enable_individual=True,
                    payment_method=True,
                    business=BusinessOnboardingOptions(
                        type=OnboardingOption(
                            show=True,
                            edit=True,
                            required=True,
                        ),
                        doing_business_as=OnboardingOption(
                            show=True,
                            edit=True,
                            required=True,
                        ),
                        ein=OnboardingOption(
                            show=True,
                            edit=True,
                            required=True,
                        ),
                        mcc=OnboardingOption(
                            show=True,
                            edit=True,
                            required=True,
                        ),
                        formation_date=OnboardingOption(
                            show=True,
                            edit=True,
                            required=True,
                        ),
                        website=OnboardingOption(
                            show=True,
                            edit=True,
                            required=True,
                        ),
                        description=OnboardingOption(
                            show=True,
                            edit=True,
                            required=True,
                        ),
                        representatives=OnboardingOption(
                            show=True,
                            edit=True,
                            required=True,
                        ),
                        logo=OnboardingOption(
                            show=True,
                            edit=True,
                            required=True,
                        ),
                        average_transaction_size=OnboardingOption(
                            show=True,
                            edit=True,
                            required=True,
                        ),
                        average_monthly_transaction_volume=OnboardingOption(
                            show=True,
                            edit=True,
                            required=True,
                        ),
                        max_transaction_size=OnboardingOption(
                            show=True,
                            edit=True,
                            required=True,
                        ),
                        terms_of_service=OnboardingOption(
                            show=True,
                            edit=True,
                            required=True,
                        ),
                        email=OnboardingOption(
                            show=True,
                            edit=True,
                            required=True,
                        ),
                        name=OnboardingOption(
                            show=True,
                            edit=True,
                            required=True,
                        ),
                        address=OnboardingOption(
                            show=True,
                            edit=True,
                            required=True,
                        ),
                        phone=OnboardingOption(
                            show=True,
                            edit=True,
                            required=True,
                        ),
                        ten_ninety_nine=OnboardingOption(
                            show=True,
                            edit=True,
                            required=True,
                        ),
                        w_9=OnboardingOption(
                            show=True,
                            edit=True,
                            required=True,
                        ),
                    ),
                    individual=IndividualOnboardingOptions(
                        date_of_birth=OnboardingOption(
                            show=True,
                            edit=True,
                            required=True,
                        ),
                        ssn=OnboardingOption(
                            show=True,
                            edit=True,
                            required=True,
                        ),
                        terms_of_service=OnboardingOption(
                            show=True,
                            edit=True,
                            required=True,
                        ),
                        email=OnboardingOption(
                            show=True,
                            edit=True,
                            required=True,
                        ),
                        name=OnboardingOption(
                            show=True,
                            edit=True,
                            required=True,
                        ),
                        address=OnboardingOption(
                            show=True,
                            edit=True,
                            required=True,
                        ),
                        phone=OnboardingOption(
                            show=True,
                            edit=True,
                            required=True,
                        ),
                        ten_ninety_nine=OnboardingOption(
                            show=True,
                            edit=True,
                            required=True,
                        ),
                        w_9=OnboardingOption(
                            show=True,
                            edit=True,
                            required=True,
                        ),
                    ),
                ),
                metadata_schema=[
                    MetadataSchema(
                        key="string",
                        display_name="string",
                        type="STRING",
                    )
                ],
                notification_email_template=NotificationEmailTemplateRequest(
                    background_style="string",
                    header="string",
                    body="string",
                    signature="string",
                    footer="string",
                    button="string",
                ),
            ),
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            "organization",
            method="POST",
            json=request,
            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 typing.cast(
                OrganizationResponse,
                parse_obj_as(
                    type_=OrganizationResponse,  # type: ignore
                    object_=_response_json,
                ),
            )
        if "errorName" in _response_json:
            if _response_json["errorName"] == "BadRequest":
                raise BadRequest(
                    typing.cast(
                        str,
                        parse_obj_as(
                            type_=str,  # type: ignore
                            object_=_response_json["content"],
                        ),
                    )
                )
            if _response_json["errorName"] == "Unauthorized":
                raise Unauthorized(
                    typing.cast(
                        str,
                        parse_obj_as(
                            type_=str,  # type: ignore
                            object_=_response_json["content"],
                        ),
                    )
                )
            if _response_json["errorName"] == "Forbidden":
                raise Forbidden(
                    typing.cast(
                        str,
                        parse_obj_as(
                            type_=str,  # type: ignore
                            object_=_response_json["content"],
                        ),
                    )
                )
            if _response_json["errorName"] == "NotFound":
                raise NotFound(
                    typing.cast(
                        str,
                        parse_obj_as(
                            type_=str,  # type: ignore
                            object_=_response_json["content"],
                        ),
                    )
                )
            if _response_json["errorName"] == "Conflict":
                raise Conflict(
                    typing.cast(
                        str,
                        parse_obj_as(
                            type_=str,  # type: ignore
                            object_=_response_json["content"],
                        ),
                    )
                )
            if _response_json["errorName"] == "InternalServerError":
                raise InternalServerError(
                    typing.cast(
                        str,
                        parse_obj_as(
                            type_=str,  # type: ignore
                            object_=_response_json["content"],
                        ),
                    )
                )
            if _response_json["errorName"] == "Unimplemented":
                raise Unimplemented(
                    typing.cast(
                        str,
                        parse_obj_as(
                            type_=str,  # type: ignore
                            object_=_response_json["content"],
                        ),
                    )
                )
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def email_log(
        self,
        *,
        start_date: typing.Optional[dt.datetime] = None,
        end_date: typing.Optional[dt.datetime] = None,
        limit: typing.Optional[int] = None,
        starting_after: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> EmailLogResponse:
        """
        Get log of all emails sent to this organization. Content format subject to change.

        Parameters
        ----------
        start_date : typing.Optional[dt.datetime]

        end_date : typing.Optional[dt.datetime]

        limit : typing.Optional[int]
            Number of logs to return. Limit can range between 1 and 100, and the default is 10.

        starting_after : typing.Optional[str]
            The ID of the log to start after. If not provided, the first page of logs will be returned.

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

        Returns
        -------
        EmailLogResponse

        Examples
        --------
        import datetime

        from mercoa import Mercoa

        client = Mercoa(
            token="YOUR_TOKEN",
        )
        client.organization.email_log(
            start_date=datetime.datetime.fromisoformat(
                "2024-01-15 09:30:00+00:00",
            ),
            end_date=datetime.datetime.fromisoformat(
                "2024-01-15 09:30:00+00:00",
            ),
            limit=1,
            starting_after="string",
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            "organization/emailLog",
            method="GET",
            params={
                "startDate": serialize_datetime(start_date) if start_date is not None else None,
                "endDate": serialize_datetime(end_date) if end_date is not None else None,
                "limit": limit,
                "startingAfter": starting_after,
            },
            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 typing.cast(
                EmailLogResponse,
                parse_obj_as(
                    type_=EmailLogResponse,  # type: ignore
                    object_=_response_json,
                ),
            )
        if "errorName" in _response_json:
            if _response_json["errorName"] == "BadRequest":
                raise BadRequest(
                    typing.cast(
                        str,
                        parse_obj_as(
                            type_=str,  # type: ignore
                            object_=_response_json["content"],
                        ),
                    )
                )
            if _response_json["errorName"] == "Unauthorized":
                raise Unauthorized(
                    typing.cast(
                        str,
                        parse_obj_as(
                            type_=str,  # type: ignore
                            object_=_response_json["content"],
                        ),
                    )
                )
            if _response_json["errorName"] == "Forbidden":
                raise Forbidden(
                    typing.cast(
                        str,
                        parse_obj_as(
                            type_=str,  # type: ignore
                            object_=_response_json["content"],
                        ),
                    )
                )
            if _response_json["errorName"] == "NotFound":
                raise NotFound(
                    typing.cast(
                        str,
                        parse_obj_as(
                            type_=str,  # type: ignore
                            object_=_response_json["content"],
                        ),
                    )
                )
            if _response_json["errorName"] == "Conflict":
                raise Conflict(
                    typing.cast(
                        str,
                        parse_obj_as(
                            type_=str,  # type: ignore
                            object_=_response_json["content"],
                        ),
                    )
                )
            if _response_json["errorName"] == "InternalServerError":
                raise InternalServerError(
                    typing.cast(
                        str,
                        parse_obj_as(
                            type_=str,  # type: ignore
                            object_=_response_json["content"],
                        ),
                    )
                )
            if _response_json["errorName"] == "Unimplemented":
                raise Unimplemented(
                    typing.cast(
                        str,
                        parse_obj_as(
                            type_=str,  # type: ignore
                            object_=_response_json["content"],
                        ),
                    )
                )
        raise ApiError(status_code=_response.status_code, body=_response_json)


class AsyncOrganizationClient:
    def __init__(self, *, client_wrapper: AsyncClientWrapper):
        self._client_wrapper = client_wrapper
        self.notification_configuration = AsyncNotificationConfigurationClient(client_wrapper=self._client_wrapper)

    async def get(
        self,
        *,
        payment_methods: typing.Optional[bool] = None,
        email_provider: typing.Optional[bool] = None,
        external_accounting_system_provider: typing.Optional[bool] = None,
        color_scheme: typing.Optional[bool] = None,
        payee_onboarding_options: typing.Optional[bool] = None,
        payor_onboarding_options: typing.Optional[bool] = None,
        metadata_schema: typing.Optional[bool] = None,
        notification_email_template: typing.Optional[bool] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> OrganizationResponse:
        """
        Get current organization information

        Parameters
        ----------
        payment_methods : typing.Optional[bool]
            include supported payment methods in response

        email_provider : typing.Optional[bool]
            include email provider info in response

        external_accounting_system_provider : typing.Optional[bool]
            include external accounting system provider info in response

        color_scheme : typing.Optional[bool]
            include color scheme info in response

        payee_onboarding_options : typing.Optional[bool]
            include payee onboarding options in response

        payor_onboarding_options : typing.Optional[bool]
            include payor onboarding options in response

        metadata_schema : typing.Optional[bool]
            include metadata schema in response

        notification_email_template : typing.Optional[bool]
            include notification-email-template in response

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

        Returns
        -------
        OrganizationResponse

        Examples
        --------
        import asyncio

        from mercoa import AsyncMercoa

        client = AsyncMercoa(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.organization.get(
                payment_methods=True,
                email_provider=True,
                external_accounting_system_provider=True,
                color_scheme=True,
                payee_onboarding_options=True,
                payor_onboarding_options=True,
                metadata_schema=True,
                notification_email_template=True,
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            "organization",
            method="GET",
            params={
                "paymentMethods": payment_methods,
                "emailProvider": email_provider,
                "externalAccountingSystemProvider": external_accounting_system_provider,
                "colorScheme": color_scheme,
                "payeeOnboardingOptions": payee_onboarding_options,
                "payorOnboardingOptions": payor_onboarding_options,
                "metadataSchema": metadata_schema,
                "notificationEmailTemplate": notification_email_template,
            },
            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 typing.cast(
                OrganizationResponse,
                parse_obj_as(
                    type_=OrganizationResponse,  # type: ignore
                    object_=_response_json,
                ),
            )
        if "errorName" in _response_json:
            if _response_json["errorName"] == "BadRequest":
                raise BadRequest(
                    typing.cast(
                        str,
                        parse_obj_as(
                            type_=str,  # type: ignore
                            object_=_response_json["content"],
                        ),
                    )
                )
            if _response_json["errorName"] == "Unauthorized":
                raise Unauthorized(
                    typing.cast(
                        str,
                        parse_obj_as(
                            type_=str,  # type: ignore
                            object_=_response_json["content"],
                        ),
                    )
                )
            if _response_json["errorName"] == "Forbidden":
                raise Forbidden(
                    typing.cast(
                        str,
                        parse_obj_as(
                            type_=str,  # type: ignore
                            object_=_response_json["content"],
                        ),
                    )
                )
            if _response_json["errorName"] == "NotFound":
                raise NotFound(
                    typing.cast(
                        str,
                        parse_obj_as(
                            type_=str,  # type: ignore
                            object_=_response_json["content"],
                        ),
                    )
                )
            if _response_json["errorName"] == "Conflict":
                raise Conflict(
                    typing.cast(
                        str,
                        parse_obj_as(
                            type_=str,  # type: ignore
                            object_=_response_json["content"],
                        ),
                    )
                )
            if _response_json["errorName"] == "InternalServerError":
                raise InternalServerError(
                    typing.cast(
                        str,
                        parse_obj_as(
                            type_=str,  # type: ignore
                            object_=_response_json["content"],
                        ),
                    )
                )
            if _response_json["errorName"] == "Unimplemented":
                raise Unimplemented(
                    typing.cast(
                        str,
                        parse_obj_as(
                            type_=str,  # type: ignore
                            object_=_response_json["content"],
                        ),
                    )
                )
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def update(
        self, *, request: OrganizationRequest, request_options: typing.Optional[RequestOptions] = None
    ) -> OrganizationResponse:
        """
        Update current organization

        Parameters
        ----------
        request : OrganizationRequest

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

        Returns
        -------
        OrganizationResponse

        Examples
        --------
        import asyncio

        from mercoa import AsyncMercoa
        from mercoa.organization_types import (
            BusinessOnboardingOptions,
            ColorSchemeRequest,
            EmailProviderRequest,
            EmailSenderRequest,
            ExternalAccountingSystemProviderRequest_None,
            IndividualOnboardingOptions,
            MetadataSchema,
            NotificationEmailTemplateRequest,
            OnboardingOption,
            OnboardingOptionsRequest,
            OrganizationRequest,
            PaymentMethodsRequest,
            PaymentRailRequest,
        )

        client = AsyncMercoa(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.organization.update(
                request=OrganizationRequest(
                    name="string",
                    logo="string",
                    website_url="string",
                    support_email="string",
                    payment_methods=PaymentMethodsRequest(
                        payer_payments=[
                            PaymentRailRequest(
                                type="custom",
                                active=True,
                            )
                        ],
                        backup_disbursements=[
                            PaymentRailRequest(
                                type="custom",
                                active=True,
                            )
                        ],
                        vendor_disbursements=[
                            PaymentRailRequest(
                                type="custom",
                                active=True,
                            )
                        ],
                    ),
                    email_provider=EmailProviderRequest(
                        sender=EmailSenderRequest(
                            provider="none",
                            from_email="string",
                            from_name="string",
                            api_key="string",
                        ),
                        inbox_domain="string",
                        alternative_inbox_domains=[],
                    ),
                    external_accounting_system_provider=ExternalAccountingSystemProviderRequest_None(),
                    color_scheme=ColorSchemeRequest(
                        primary_color="string",
                        secondary_color="string",
                        logo_background_color="string",
                        rounded_corners=1,
                    ),
                    payee_onboarding_options=OnboardingOptionsRequest(
                        enable_business=True,
                        enable_individual=True,
                        payment_method=True,
                        business=BusinessOnboardingOptions(
                            type=OnboardingOption(
                                show=True,
                                edit=True,
                                required=True,
                            ),
                            doing_business_as=OnboardingOption(
                                show=True,
                                edit=True,
                                required=True,
                            ),
                            ein=OnboardingOption(
                                show=True,
                                edit=True,
                                required=True,
                            ),
                            mcc=OnboardingOption(
                                show=True,
                                edit=True,
                                required=True,
                            ),
                            formation_date=OnboardingOption(
                                show=True,
                                edit=True,
                                required=True,
                            ),
                            website=OnboardingOption(
                                show=True,
                                edit=True,
                                required=True,
                            ),
                            description=OnboardingOption(
                                show=True,
                                edit=True,
                                required=True,
                            ),
                            representatives=OnboardingOption(
                                show=True,
                                edit=True,
                                required=True,
                            ),
                            logo=OnboardingOption(
                                show=True,
                                edit=True,
                                required=True,
                            ),
                            average_transaction_size=OnboardingOption(
                                show=True,
                                edit=True,
                                required=True,
                            ),
                            average_monthly_transaction_volume=OnboardingOption(
                                show=True,
                                edit=True,
                                required=True,
                            ),
                            max_transaction_size=OnboardingOption(
                                show=True,
                                edit=True,
                                required=True,
                            ),
                            terms_of_service=OnboardingOption(
                                show=True,
                                edit=True,
                                required=True,
                            ),
                            email=OnboardingOption(
                                show=True,
                                edit=True,
                                required=True,
                            ),
                            name=OnboardingOption(
                                show=True,
                                edit=True,
                                required=True,
                            ),
                            address=OnboardingOption(
                                show=True,
                                edit=True,
                                required=True,
                            ),
                            phone=OnboardingOption(
                                show=True,
                                edit=True,
                                required=True,
                            ),
                            ten_ninety_nine=OnboardingOption(
                                show=True,
                                edit=True,
                                required=True,
                            ),
                            w_9=OnboardingOption(
                                show=True,
                                edit=True,
                                required=True,
                            ),
                        ),
                        individual=IndividualOnboardingOptions(
                            date_of_birth=OnboardingOption(
                                show=True,
                                edit=True,
                                required=True,
                            ),
                            ssn=OnboardingOption(
                                show=True,
                                edit=True,
                                required=True,
                            ),
                            terms_of_service=OnboardingOption(
                                show=True,
                                edit=True,
                                required=True,
                            ),
                            email=OnboardingOption(
                                show=True,
                                edit=True,
                                required=True,
                            ),
                            name=OnboardingOption(
                                show=True,
                                edit=True,
                                required=True,
                            ),
                            address=OnboardingOption(
                                show=True,
                                edit=True,
                                required=True,
                            ),
                            phone=OnboardingOption(
                                show=True,
                                edit=True,
                                required=True,
                            ),
                            ten_ninety_nine=OnboardingOption(
                                show=True,
                                edit=True,
                                required=True,
                            ),
                            w_9=OnboardingOption(
                                show=True,
                                edit=True,
                                required=True,
                            ),
                        ),
                    ),
                    payor_onboarding_options=OnboardingOptionsRequest(
                        enable_business=True,
                        enable_individual=True,
                        payment_method=True,
                        business=BusinessOnboardingOptions(
                            type=OnboardingOption(
                                show=True,
                                edit=True,
                                required=True,
                            ),
                            doing_business_as=OnboardingOption(
                                show=True,
                                edit=True,
                                required=True,
                            ),
                            ein=OnboardingOption(
                                show=True,
                                edit=True,
                                required=True,
                            ),
                            mcc=OnboardingOption(
                                show=True,
                                edit=True,
                                required=True,
                            ),
                            formation_date=OnboardingOption(
                                show=True,
                                edit=True,
                                required=True,
                            ),
                            website=OnboardingOption(
                                show=True,
                                edit=True,
                                required=True,
                            ),
                            description=OnboardingOption(
                                show=True,
                                edit=True,
                                required=True,
                            ),
                            representatives=OnboardingOption(
                                show=True,
                                edit=True,
                                required=True,
                            ),
                            logo=OnboardingOption(
                                show=True,
                                edit=True,
                                required=True,
                            ),
                            average_transaction_size=OnboardingOption(
                                show=True,
                                edit=True,
                                required=True,
                            ),
                            average_monthly_transaction_volume=OnboardingOption(
                                show=True,
                                edit=True,
                                required=True,
                            ),
                            max_transaction_size=OnboardingOption(
                                show=True,
                                edit=True,
                                required=True,
                            ),
                            terms_of_service=OnboardingOption(
                                show=True,
                                edit=True,
                                required=True,
                            ),
                            email=OnboardingOption(
                                show=True,
                                edit=True,
                                required=True,
                            ),
                            name=OnboardingOption(
                                show=True,
                                edit=True,
                                required=True,
                            ),
                            address=OnboardingOption(
                                show=True,
                                edit=True,
                                required=True,
                            ),
                            phone=OnboardingOption(
                                show=True,
                                edit=True,
                                required=True,
                            ),
                            ten_ninety_nine=OnboardingOption(
                                show=True,
                                edit=True,
                                required=True,
                            ),
                            w_9=OnboardingOption(
                                show=True,
                                edit=True,
                                required=True,
                            ),
                        ),
                        individual=IndividualOnboardingOptions(
                            date_of_birth=OnboardingOption(
                                show=True,
                                edit=True,
                                required=True,
                            ),
                            ssn=OnboardingOption(
                                show=True,
                                edit=True,
                                required=True,
                            ),
                            terms_of_service=OnboardingOption(
                                show=True,
                                edit=True,
                                required=True,
                            ),
                            email=OnboardingOption(
                                show=True,
                                edit=True,
                                required=True,
                            ),
                            name=OnboardingOption(
                                show=True,
                                edit=True,
                                required=True,
                            ),
                            address=OnboardingOption(
                                show=True,
                                edit=True,
                                required=True,
                            ),
                            phone=OnboardingOption(
                                show=True,
                                edit=True,
                                required=True,
                            ),
                            ten_ninety_nine=OnboardingOption(
                                show=True,
                                edit=True,
                                required=True,
                            ),
                            w_9=OnboardingOption(
                                show=True,
                                edit=True,
                                required=True,
                            ),
                        ),
                    ),
                    metadata_schema=[
                        MetadataSchema(
                            key="string",
                            display_name="string",
                            type="STRING",
                        )
                    ],
                    notification_email_template=NotificationEmailTemplateRequest(
                        background_style="string",
                        header="string",
                        body="string",
                        signature="string",
                        footer="string",
                        button="string",
                    ),
                ),
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            "organization",
            method="POST",
            json=request,
            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 typing.cast(
                OrganizationResponse,
                parse_obj_as(
                    type_=OrganizationResponse,  # type: ignore
                    object_=_response_json,
                ),
            )
        if "errorName" in _response_json:
            if _response_json["errorName"] == "BadRequest":
                raise BadRequest(
                    typing.cast(
                        str,
                        parse_obj_as(
                            type_=str,  # type: ignore
                            object_=_response_json["content"],
                        ),
                    )
                )
            if _response_json["errorName"] == "Unauthorized":
                raise Unauthorized(
                    typing.cast(
                        str,
                        parse_obj_as(
                            type_=str,  # type: ignore
                            object_=_response_json["content"],
                        ),
                    )
                )
            if _response_json["errorName"] == "Forbidden":
                raise Forbidden(
                    typing.cast(
                        str,
                        parse_obj_as(
                            type_=str,  # type: ignore
                            object_=_response_json["content"],
                        ),
                    )
                )
            if _response_json["errorName"] == "NotFound":
                raise NotFound(
                    typing.cast(
                        str,
                        parse_obj_as(
                            type_=str,  # type: ignore
                            object_=_response_json["content"],
                        ),
                    )
                )
            if _response_json["errorName"] == "Conflict":
                raise Conflict(
                    typing.cast(
                        str,
                        parse_obj_as(
                            type_=str,  # type: ignore
                            object_=_response_json["content"],
                        ),
                    )
                )
            if _response_json["errorName"] == "InternalServerError":
                raise InternalServerError(
                    typing.cast(
                        str,
                        parse_obj_as(
                            type_=str,  # type: ignore
                            object_=_response_json["content"],
                        ),
                    )
                )
            if _response_json["errorName"] == "Unimplemented":
                raise Unimplemented(
                    typing.cast(
                        str,
                        parse_obj_as(
                            type_=str,  # type: ignore
                            object_=_response_json["content"],
                        ),
                    )
                )
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def email_log(
        self,
        *,
        start_date: typing.Optional[dt.datetime] = None,
        end_date: typing.Optional[dt.datetime] = None,
        limit: typing.Optional[int] = None,
        starting_after: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> EmailLogResponse:
        """
        Get log of all emails sent to this organization. Content format subject to change.

        Parameters
        ----------
        start_date : typing.Optional[dt.datetime]

        end_date : typing.Optional[dt.datetime]

        limit : typing.Optional[int]
            Number of logs to return. Limit can range between 1 and 100, and the default is 10.

        starting_after : typing.Optional[str]
            The ID of the log to start after. If not provided, the first page of logs will be returned.

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

        Returns
        -------
        EmailLogResponse

        Examples
        --------
        import asyncio
        import datetime

        from mercoa import AsyncMercoa

        client = AsyncMercoa(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.organization.email_log(
                start_date=datetime.datetime.fromisoformat(
                    "2024-01-15 09:30:00+00:00",
                ),
                end_date=datetime.datetime.fromisoformat(
                    "2024-01-15 09:30:00+00:00",
                ),
                limit=1,
                starting_after="string",
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            "organization/emailLog",
            method="GET",
            params={
                "startDate": serialize_datetime(start_date) if start_date is not None else None,
                "endDate": serialize_datetime(end_date) if end_date is not None else None,
                "limit": limit,
                "startingAfter": starting_after,
            },
            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 typing.cast(
                EmailLogResponse,
                parse_obj_as(
                    type_=EmailLogResponse,  # type: ignore
                    object_=_response_json,
                ),
            )
        if "errorName" in _response_json:
            if _response_json["errorName"] == "BadRequest":
                raise BadRequest(
                    typing.cast(
                        str,
                        parse_obj_as(
                            type_=str,  # type: ignore
                            object_=_response_json["content"],
                        ),
                    )
                )
            if _response_json["errorName"] == "Unauthorized":
                raise Unauthorized(
                    typing.cast(
                        str,
                        parse_obj_as(
                            type_=str,  # type: ignore
                            object_=_response_json["content"],
                        ),
                    )
                )
            if _response_json["errorName"] == "Forbidden":
                raise Forbidden(
                    typing.cast(
                        str,
                        parse_obj_as(
                            type_=str,  # type: ignore
                            object_=_response_json["content"],
                        ),
                    )
                )
            if _response_json["errorName"] == "NotFound":
                raise NotFound(
                    typing.cast(
                        str,
                        parse_obj_as(
                            type_=str,  # type: ignore
                            object_=_response_json["content"],
                        ),
                    )
                )
            if _response_json["errorName"] == "Conflict":
                raise Conflict(
                    typing.cast(
                        str,
                        parse_obj_as(
                            type_=str,  # type: ignore
                            object_=_response_json["content"],
                        ),
                    )
                )
            if _response_json["errorName"] == "InternalServerError":
                raise InternalServerError(
                    typing.cast(
                        str,
                        parse_obj_as(
                            type_=str,  # type: ignore
                            object_=_response_json["content"],
                        ),
                    )
                )
            if _response_json["errorName"] == "Unimplemented":
                raise Unimplemented(
                    typing.cast(
                        str,
                        parse_obj_as(
                            type_=str,  # type: ignore
                            object_=_response_json["content"],
                        ),
                    )
                )
        raise ApiError(status_code=_response.status_code, body=_response_json)
