"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""

from __future__ import annotations
from .amount import Amount, AmountTypedDict
from .url import URL, URLTypedDict
from enum import Enum
from mollie import utils
from mollie.types import BaseModel, Nullable, OptionalNullable, UNSET, UNSET_SENTINEL
from mollie.utils import validate_open_enum
import pydantic
from pydantic import model_serializer
from pydantic.functional_validators import PlainValidator
from typing import List, Optional
from typing_extensions import Annotated, NotRequired, TypedDict


class ListEntityInvoiceStatus(str, Enum, metaclass=utils.OpenEnumMeta):
    r"""Status of the invoice."""

    OPEN = "open"
    PAID = "paid"
    OVERDUE = "overdue"


class ListEntityInvoiceNetAmountTypedDict(TypedDict):
    r"""Total amount of the invoice, excluding VAT."""

    currency: str
    r"""A three-character ISO 4217 currency code."""
    value: str
    r"""A string containing an exact monetary amount in the given currency."""


class ListEntityInvoiceNetAmount(BaseModel):
    r"""Total amount of the invoice, excluding VAT."""

    currency: str
    r"""A three-character ISO 4217 currency code."""

    value: str
    r"""A string containing an exact monetary amount in the given currency."""


class ListEntityInvoiceVatAmountTypedDict(TypedDict):
    r"""VAT amount of the invoice. Only applicable to merchants registered in the Netherlands. For EU merchants, VAT will
    be shifted to the recipient (as per article 44 and 196 in the EU VAT Directive 2006/112). For merchants outside
    the EU, no VAT will be charged.
    """

    currency: str
    r"""A three-character ISO 4217 currency code."""
    value: str
    r"""A string containing an exact monetary amount in the given currency."""


class ListEntityInvoiceVatAmount(BaseModel):
    r"""VAT amount of the invoice. Only applicable to merchants registered in the Netherlands. For EU merchants, VAT will
    be shifted to the recipient (as per article 44 and 196 in the EU VAT Directive 2006/112). For merchants outside
    the EU, no VAT will be charged.
    """

    currency: str
    r"""A three-character ISO 4217 currency code."""

    value: str
    r"""A string containing an exact monetary amount in the given currency."""


class ListEntityInvoiceGrossAmountTypedDict(TypedDict):
    r"""Total amount of the invoice, including VAT."""

    currency: str
    r"""A three-character ISO 4217 currency code."""
    value: str
    r"""A string containing an exact monetary amount in the given currency."""


class ListEntityInvoiceGrossAmount(BaseModel):
    r"""Total amount of the invoice, including VAT."""

    currency: str
    r"""A three-character ISO 4217 currency code."""

    value: str
    r"""A string containing an exact monetary amount in the given currency."""


class ListEntityInvoiceLineTypedDict(TypedDict):
    period: str
    r"""The administrative period in `YYYY-MM` on which the line should be booked."""
    description: str
    r"""Description of the product."""
    count: int
    r"""Number of products invoiced. For example, the number of payments."""
    vat_percentage: int
    r"""VAT percentage rate that applies to this product."""
    amount: AmountTypedDict
    r"""In v2 endpoints, monetary amounts are represented as objects with a `currency` and `value` field."""


class ListEntityInvoiceLine(BaseModel):
    period: str
    r"""The administrative period in `YYYY-MM` on which the line should be booked."""

    description: str
    r"""Description of the product."""

    count: int
    r"""Number of products invoiced. For example, the number of payments."""

    vat_percentage: Annotated[int, pydantic.Field(alias="vatPercentage")]
    r"""VAT percentage rate that applies to this product."""

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


class ListEntityInvoiceLinksTypedDict(TypedDict):
    r"""An object with several relevant URLs. Every URL object will contain an `href` and a `type` field."""

    self_: NotRequired[URLTypedDict]
    r"""In v2 endpoints, URLs are commonly represented as objects with an `href` and `type` field."""
    pdf: NotRequired[URLTypedDict]
    r"""In v2 endpoints, URLs are commonly represented as objects with an `href` and `type` field."""


class ListEntityInvoiceLinks(BaseModel):
    r"""An object with several relevant URLs. Every URL object will contain an `href` and a `type` field."""

    self_: Annotated[Optional[URL], pydantic.Field(alias="self")] = None
    r"""In v2 endpoints, URLs are commonly represented as objects with an `href` and `type` field."""

    pdf: Optional[URL] = None
    r"""In v2 endpoints, URLs are commonly represented as objects with an `href` and `type` field."""


class ListEntityInvoiceTypedDict(TypedDict):
    resource: str
    r"""Indicates that the response contains an invoice object.
    Will always contain the string `invoice` for this endpoint.
    """
    id: str
    reference: str
    r"""The reference number of the invoice. An example value would be: `2024.10000`."""
    vat_number: Nullable[str]
    r"""The VAT number to which the invoice was issued to, if applicable."""
    status: ListEntityInvoiceStatus
    net_amount: ListEntityInvoiceNetAmountTypedDict
    r"""Total amount of the invoice, excluding VAT."""
    vat_amount: ListEntityInvoiceVatAmountTypedDict
    r"""VAT amount of the invoice. Only applicable to merchants registered in the Netherlands. For EU merchants, VAT will
    be shifted to the recipient (as per article 44 and 196 in the EU VAT Directive 2006/112). For merchants outside
    the EU, no VAT will be charged.
    """
    gross_amount: ListEntityInvoiceGrossAmountTypedDict
    r"""Total amount of the invoice, including VAT."""
    lines: List[ListEntityInvoiceLineTypedDict]
    r"""The collection of products which make up the invoice."""
    issued_at: str
    r"""The invoice date in `YYYY-MM-DD` format."""
    links: ListEntityInvoiceLinksTypedDict
    r"""An object with several relevant URLs. Every URL object will contain an `href` and a `type` field."""
    paid_at: NotRequired[Nullable[str]]
    r"""The date on which the invoice was paid, if applicable, in `YYYY-MM-DD` format."""
    due_at: NotRequired[Nullable[str]]
    r"""The date on which the invoice is due, if applicable, in `YYYY-MM-DD` format."""


class ListEntityInvoice(BaseModel):
    resource: str
    r"""Indicates that the response contains an invoice object.
    Will always contain the string `invoice` for this endpoint.
    """

    id: str

    reference: str
    r"""The reference number of the invoice. An example value would be: `2024.10000`."""

    vat_number: Annotated[Nullable[str], pydantic.Field(alias="vatNumber")]
    r"""The VAT number to which the invoice was issued to, if applicable."""

    status: Annotated[
        ListEntityInvoiceStatus, PlainValidator(validate_open_enum(False))
    ]

    net_amount: Annotated[ListEntityInvoiceNetAmount, pydantic.Field(alias="netAmount")]
    r"""Total amount of the invoice, excluding VAT."""

    vat_amount: Annotated[ListEntityInvoiceVatAmount, pydantic.Field(alias="vatAmount")]
    r"""VAT amount of the invoice. Only applicable to merchants registered in the Netherlands. For EU merchants, VAT will
    be shifted to the recipient (as per article 44 and 196 in the EU VAT Directive 2006/112). For merchants outside
    the EU, no VAT will be charged.
    """

    gross_amount: Annotated[
        ListEntityInvoiceGrossAmount, pydantic.Field(alias="grossAmount")
    ]
    r"""Total amount of the invoice, including VAT."""

    lines: List[ListEntityInvoiceLine]
    r"""The collection of products which make up the invoice."""

    issued_at: Annotated[str, pydantic.Field(alias="issuedAt")]
    r"""The invoice date in `YYYY-MM-DD` format."""

    links: Annotated[ListEntityInvoiceLinks, pydantic.Field(alias="_links")]
    r"""An object with several relevant URLs. Every URL object will contain an `href` and a `type` field."""

    paid_at: Annotated[OptionalNullable[str], pydantic.Field(alias="paidAt")] = UNSET
    r"""The date on which the invoice was paid, if applicable, in `YYYY-MM-DD` format."""

    due_at: Annotated[OptionalNullable[str], pydantic.Field(alias="dueAt")] = UNSET
    r"""The date on which the invoice is due, if applicable, in `YYYY-MM-DD` format."""

    @model_serializer(mode="wrap")
    def serialize_model(self, handler):
        optional_fields = ["paidAt", "dueAt"]
        nullable_fields = ["vatNumber", "paidAt", "dueAt"]
        null_default_fields = []

        serialized = handler(self)

        m = {}

        for n, f in type(self).model_fields.items():
            k = f.alias or n
            val = serialized.get(k)
            serialized.pop(k, None)

            optional_nullable = k in optional_fields and k in nullable_fields
            is_set = (
                self.__pydantic_fields_set__.intersection({n})
                or k in null_default_fields
            )  # pylint: disable=no-member

            if val is not None and val != UNSET_SENTINEL:
                m[k] = val
            elif val != UNSET_SENTINEL and (
                not k in optional_fields or (optional_nullable and is_set)
            ):
                m[k] = val

        return m
