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

from __future__ import annotations
from .amount import Amount, AmountTypedDict
from .metadata import Metadata, MetadataTypedDict
from .refund_external_reference_type import RefundExternalReferenceType
from enum import Enum
from mollie.types import BaseModel, Nullable, OptionalNullable, UNSET, UNSET_SENTINEL
import pydantic
from pydantic import model_serializer
from typing import List, Optional
from typing_extensions import Annotated, NotRequired, TypedDict


class RefundRequestExternalReferenceTypedDict(TypedDict):
    type: NotRequired[RefundExternalReferenceType]
    r"""Specifies the reference type"""
    id: NotRequired[str]
    r"""Unique reference from the payment provider"""


class RefundRequestExternalReference(BaseModel):
    type: Optional[RefundExternalReferenceType] = None
    r"""Specifies the reference type"""

    id: Optional[str] = None
    r"""Unique reference from the payment provider"""

    @model_serializer(mode="wrap")
    def serialize_model(self, handler):
        optional_fields = set(["type", "id"])
        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))

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

        return m


class Type(str, Enum):
    r"""The type of source. Currently only the source type `organization` is supported."""

    ORGANIZATION = "organization"


class RefundRequestSourceTypedDict(TypedDict):
    r"""Where the funds will be pulled back from."""

    type: NotRequired[Type]
    organization_id: NotRequired[str]


class RefundRequestSource(BaseModel):
    r"""Where the funds will be pulled back from."""

    type: Optional[Type] = None

    organization_id: Annotated[
        Optional[str], pydantic.Field(alias="organizationId")
    ] = None

    @model_serializer(mode="wrap")
    def serialize_model(self, handler):
        optional_fields = set(["type", "organizationId"])
        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))

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

        return m


class RefundRequestRoutingReversalTypedDict(TypedDict):
    amount: NotRequired[AmountTypedDict]
    r"""In v2 endpoints, monetary amounts are represented as objects with a `currency` and `value` field."""
    source: NotRequired[RefundRequestSourceTypedDict]
    r"""Where the funds will be pulled back from."""


class RefundRequestRoutingReversal(BaseModel):
    amount: Optional[Amount] = None
    r"""In v2 endpoints, monetary amounts are represented as objects with a `currency` and `value` field."""

    source: Optional[RefundRequestSource] = None
    r"""Where the funds will be pulled back from."""

    @model_serializer(mode="wrap")
    def serialize_model(self, handler):
        optional_fields = set(["amount", "source"])
        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))

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

        return m


class RefundRequestTypedDict(TypedDict):
    description: str
    r"""The description of the refund that may be shown to your customer, depending on the payment method used."""
    amount: AmountTypedDict
    r"""In v2 endpoints, monetary amounts are represented as objects with a `currency` and `value` field."""
    metadata: Nullable[MetadataTypedDict]
    r"""Provide any data you like, for example a string or a JSON object. We will save the data alongside the entity. Whenever
    you fetch the entity with our API, we will also include the metadata. You can use up to approximately 1kB.
    """
    external_reference: NotRequired[RefundRequestExternalReferenceTypedDict]
    reverse_routing: NotRequired[Nullable[bool]]
    r"""*This feature is only available to marketplace operators.*

    With Mollie Connect you can charge fees on payments that your app is processing on behalf of other Mollie
    merchants, by providing the `routing` object during [payment creation](create-payment).

    When creating refunds for these *routed* payments, by default the full amount is deducted from your balance.

    If you want to pull back the funds that were routed to the connected merchant(s), you can set this parameter to
    `true` when issuing a full refund.

    For more fine-grained control and for partial refunds, use the `routingReversals` parameter instead.
    """
    routing_reversals: NotRequired[
        Nullable[List[RefundRequestRoutingReversalTypedDict]]
    ]
    r"""*This feature is only available to marketplace operators.*

    When creating refunds for *routed* payments, by default the full amount is deducted from your balance.

    If you want to pull back funds from the connected merchant(s), you can use this parameter to specify what amount
    needs to be reversed from which merchant(s).

    If you simply want to fully reverse the routed funds, you can also use the `reverseRouting` parameter instead.
    """
    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 RefundRequest(BaseModel):
    description: str
    r"""The description of the refund that may be shown to your customer, depending on the payment method used."""

    amount: Amount
    r"""In v2 endpoints, monetary amounts are represented as objects with a `currency` and `value` field."""

    metadata: Nullable[Metadata]
    r"""Provide any data you like, for example a string or a JSON object. We will save the data alongside the entity. Whenever
    you fetch the entity with our API, we will also include the metadata. You can use up to approximately 1kB.
    """

    external_reference: Annotated[
        Optional[RefundRequestExternalReference],
        pydantic.Field(alias="externalReference"),
    ] = None

    reverse_routing: Annotated[
        OptionalNullable[bool], pydantic.Field(alias="reverseRouting")
    ] = UNSET
    r"""*This feature is only available to marketplace operators.*

    With Mollie Connect you can charge fees on payments that your app is processing on behalf of other Mollie
    merchants, by providing the `routing` object during [payment creation](create-payment).

    When creating refunds for these *routed* payments, by default the full amount is deducted from your balance.

    If you want to pull back the funds that were routed to the connected merchant(s), you can set this parameter to
    `true` when issuing a full refund.

    For more fine-grained control and for partial refunds, use the `routingReversals` parameter instead.
    """

    routing_reversals: Annotated[
        OptionalNullable[List[RefundRequestRoutingReversal]],
        pydantic.Field(alias="routingReversals"),
    ] = UNSET
    r"""*This feature is only available to marketplace operators.*

    When creating refunds for *routed* payments, by default the full amount is deducted from your balance.

    If you want to pull back funds from the connected merchant(s), you can use this parameter to specify what amount
    needs to be reversed from which merchant(s).

    If you simply want to fully reverse the routed funds, you can also use the `reverseRouting` parameter instead.
    """

    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(
            ["externalReference", "reverseRouting", "routingReversals", "testmode"]
        )
        nullable_fields = set(
            ["metadata", "reverseRouting", "routingReversals", "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:
    RefundRequestSource.model_rebuild()
except NameError:
    pass
try:
    RefundRequest.model_rebuild()
except NameError:
    pass
