"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
# @generated-id: 7ca74b3f7b91

from __future__ import annotations
from .mandate_method import MandateMethod
from mollie.types import BaseModel, Nullable, OptionalNullable, UNSET, UNSET_SENTINEL
import pydantic
from pydantic import model_serializer
from typing import Optional
from typing_extensions import Annotated, NotRequired, TypedDict


class MandateRequestTypedDict(TypedDict):
    method: MandateMethod
    r"""Payment method of the mandate.

    SEPA Direct Debit and PayPal mandates can be created directly.
    """
    consumer_name: str
    r"""The customer's name."""
    id: NotRequired[str]
    r"""The identifier uniquely referring to this mandate. Example: `mdt_pWUnw6pkBN`."""
    consumer_account: NotRequired[Nullable[str]]
    r"""The customer's IBAN. Required for SEPA Direct Debit mandates."""
    consumer_bic: NotRequired[Nullable[str]]
    r"""The BIC of the customer's bank."""
    consumer_email: NotRequired[Nullable[str]]
    r"""The customer's email address. Required for PayPal mandates."""
    signature_date: NotRequired[Nullable[str]]
    r"""The date when the mandate was signed in `YYYY-MM-DD` format."""
    mandate_reference: NotRequired[Nullable[str]]
    r"""A custom mandate reference. For SEPA Direct Debit, it is vital to provide a unique reference. Some banks will
    decline Direct Debit payments if the mandate reference is not unique.
    """
    paypal_billing_agreement_id: NotRequired[Nullable[str]]
    r"""The billing agreement ID given by PayPal. For example: `B-12A34567B8901234CD`. Required for PayPal mandates.
    Must provide either this field or `payPalVaultId`, but not both.
    """
    pay_pal_vault_id: NotRequired[Nullable[str]]
    r"""The Vault ID given by PayPal. For example: `8kk8451t`. Required for PayPal mandates.
    Must provide either this field or `paypalBillingAgreementId`, but not both.
    """
    testmode: NotRequired[Nullable[bool]]
    r"""Whether to create the entity in test mode or live mode.

    Most API credentials are specifically created for either live mode or test mode, in which case this parameter must
    not be sent. For organization-level credentials such as OAuth access tokens, you can enable test mode by setting
    `testmode` to `true`.
    """


class MandateRequest(BaseModel):
    method: MandateMethod
    r"""Payment method of the mandate.

    SEPA Direct Debit and PayPal mandates can be created directly.
    """

    consumer_name: Annotated[str, pydantic.Field(alias="consumerName")]
    r"""The customer's name."""

    id: Optional[str] = None
    r"""The identifier uniquely referring to this mandate. Example: `mdt_pWUnw6pkBN`."""

    consumer_account: Annotated[
        OptionalNullable[str], pydantic.Field(alias="consumerAccount")
    ] = UNSET
    r"""The customer's IBAN. Required for SEPA Direct Debit mandates."""

    consumer_bic: Annotated[
        OptionalNullable[str], pydantic.Field(alias="consumerBic")
    ] = UNSET
    r"""The BIC of the customer's bank."""

    consumer_email: Annotated[
        OptionalNullable[str], pydantic.Field(alias="consumerEmail")
    ] = UNSET
    r"""The customer's email address. Required for PayPal mandates."""

    signature_date: Annotated[
        OptionalNullable[str], pydantic.Field(alias="signatureDate")
    ] = UNSET
    r"""The date when the mandate was signed in `YYYY-MM-DD` format."""

    mandate_reference: Annotated[
        OptionalNullable[str], pydantic.Field(alias="mandateReference")
    ] = UNSET
    r"""A custom mandate reference. For SEPA Direct Debit, it is vital to provide a unique reference. Some banks will
    decline Direct Debit payments if the mandate reference is not unique.
    """

    paypal_billing_agreement_id: Annotated[
        OptionalNullable[str], pydantic.Field(alias="paypalBillingAgreementId")
    ] = UNSET
    r"""The billing agreement ID given by PayPal. For example: `B-12A34567B8901234CD`. Required for PayPal mandates.
    Must provide either this field or `payPalVaultId`, but not both.
    """

    pay_pal_vault_id: Annotated[
        OptionalNullable[str], pydantic.Field(alias="payPalVaultId")
    ] = UNSET
    r"""The Vault ID given by PayPal. For example: `8kk8451t`. Required for PayPal mandates.
    Must provide either this field or `paypalBillingAgreementId`, but not both.
    """

    testmode: OptionalNullable[bool] = UNSET
    r"""Whether to create the entity in test mode or live mode.

    Most API credentials are specifically created for either live mode or test mode, in which case this parameter must
    not be sent. For organization-level credentials such as OAuth access tokens, you can enable test mode by setting
    `testmode` to `true`.
    """

    @model_serializer(mode="wrap")
    def serialize_model(self, handler):
        optional_fields = set(
            [
                "id",
                "consumerAccount",
                "consumerBic",
                "consumerEmail",
                "signatureDate",
                "mandateReference",
                "paypalBillingAgreementId",
                "payPalVaultId",
                "testmode",
            ]
        )
        nullable_fields = set(
            [
                "consumerAccount",
                "consumerBic",
                "consumerEmail",
                "signatureDate",
                "mandateReference",
                "paypalBillingAgreementId",
                "payPalVaultId",
                "testmode",
            ]
        )
        serialized = handler(self)
        m = {}

        for n, f in type(self).model_fields.items():
            k = f.alias or n
            val = serialized.get(k, serialized.get(n))
            is_nullable_and_explicitly_set = (
                k in nullable_fields
                and (self.__pydantic_fields_set__.intersection({n}))  # pylint: disable=no-member
            )

            if val != UNSET_SENTINEL:
                if (
                    val is not None
                    or k not in optional_fields
                    or is_nullable_and_explicitly_set
                ):
                    m[k] = val

        return m


try:
    MandateRequest.model_rebuild()
except NameError:
    pass
