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

from __future__ import annotations
from .after_balance import AfterBalance, AfterBalanceTypedDict
from .amount import Amount, AmountTypedDict
from .counterparty import Counterparty, CounterpartyTypedDict
from .credit_debit_indicator import CreditDebitIndicator
from .mode import Mode
from .transaction_type import TransactionType
from mollie import models
from mollie.types import BaseModel, Nullable, OptionalNullable, UNSET, UNSET_SENTINEL
import pydantic
from pydantic import field_serializer, model_serializer
from typing import Optional
from typing_extensions import Annotated, NotRequired, TypedDict


class TransactionResponseTypedDict(TypedDict):
    resource: str
    r"""Indicates the response contains a business account transaction object. Will always contain the string
    `business-account-transaction` for this endpoint.
    """
    id: str
    r"""The identifier uniquely referring to this transaction. Mollie assigns this identifier at transaction creation
    time.
    """
    business_account_id: str
    r"""The identifier of the business account this transaction belongs to."""
    credit_debit_indicator: CreditDebitIndicator
    r"""Indicates whether the entry is a credit or debit from the perspective of the account holder."""
    type: TransactionType
    r"""Indicates what kind of transaction this is.

    We may introduce new transaction types as we expand the product. We recommend building your integration
    to handle unexpected values gracefully, so nothing breaks when that happens.
    """
    amount: AmountTypedDict
    r"""In v2 endpoints, monetary amounts are represented as objects with a `currency` and `value` field."""
    mode: Mode
    r"""Whether this entity was created in live mode or in test mode."""
    created_at: str
    r"""The entity's date and time of creation, in [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) format."""
    description: NotRequired[Nullable[str]]
    r"""A short description of the transaction."""
    counterparty: NotRequired[CounterpartyTypedDict]
    r"""The counterparty involved in the transaction, including their name and account identifier."""
    after_balance: NotRequired[AfterBalanceTypedDict]
    r"""The balance of the business account after this transaction was processed."""
    processed_at: NotRequired[Nullable[str]]
    r"""The date and time when the transaction was processed, in ISO 8601 format."""


class TransactionResponse(BaseModel):
    resource: str
    r"""Indicates the response contains a business account transaction object. Will always contain the string
    `business-account-transaction` for this endpoint.
    """

    id: str
    r"""The identifier uniquely referring to this transaction. Mollie assigns this identifier at transaction creation
    time.
    """

    business_account_id: Annotated[str, pydantic.Field(alias="businessAccountId")]
    r"""The identifier of the business account this transaction belongs to."""

    credit_debit_indicator: Annotated[
        CreditDebitIndicator, pydantic.Field(alias="creditDebitIndicator")
    ]
    r"""Indicates whether the entry is a credit or debit from the perspective of the account holder."""

    type: TransactionType
    r"""Indicates what kind of transaction this is.

    We may introduce new transaction types as we expand the product. We recommend building your integration
    to handle unexpected values gracefully, so nothing breaks when that happens.
    """

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

    mode: Mode
    r"""Whether this entity was created in live mode or in test mode."""

    created_at: Annotated[str, pydantic.Field(alias="createdAt")]
    r"""The entity's date and time of creation, in [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) format."""

    description: OptionalNullable[str] = UNSET
    r"""A short description of the transaction."""

    counterparty: Optional[Counterparty] = None
    r"""The counterparty involved in the transaction, including their name and account identifier."""

    after_balance: Annotated[
        Optional[AfterBalance], pydantic.Field(alias="afterBalance")
    ] = None
    r"""The balance of the business account after this transaction was processed."""

    processed_at: Annotated[
        OptionalNullable[str], pydantic.Field(alias="processedAt")
    ] = UNSET
    r"""The date and time when the transaction was processed, in ISO 8601 format."""

    @field_serializer("credit_debit_indicator")
    def serialize_credit_debit_indicator(self, value):
        if isinstance(value, str):
            try:
                return models.CreditDebitIndicator(value)
            except ValueError:
                return value
        return value

    @field_serializer("type")
    def serialize_type(self, value):
        if isinstance(value, str):
            try:
                return models.TransactionType(value)
            except ValueError:
                return value
        return value

    @field_serializer("mode")
    def serialize_mode(self, value):
        if isinstance(value, str):
            try:
                return models.Mode(value)
            except ValueError:
                return value
        return value

    @model_serializer(mode="wrap")
    def serialize_model(self, handler):
        optional_fields = set(
            ["description", "counterparty", "afterBalance", "processedAt"]
        )
        nullable_fields = set(["description", "processedAt"])
        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:
    TransactionResponse.model_rebuild()
except NameError:
    pass
