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

from __future__ import annotations
from .amountdecimalupdate import AmountDecimalUpdate, AmountDecimalUpdateTypedDict
from .createinvoicelineitemsupdate import (
    CreateInvoiceLineItemsUpdate,
    CreateInvoiceLineItemsUpdateTypedDict,
)
from .invoicestatus import InvoiceStatus
from datetime import datetime
from moovio_sdk.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 UpdateInvoiceTypedDict(TypedDict):
    description: NotRequired[str]
    line_items: NotRequired[CreateInvoiceLineItemsUpdateTypedDict]
    r"""A collection of line items for an invoice."""
    invoice_date: NotRequired[Nullable[datetime]]
    due_date: NotRequired[Nullable[datetime]]
    status: NotRequired[InvoiceStatus]
    r"""The status can be updated to one of the following values under specific conditions:
    - `canceled`: Can only be set if the current status is `draft`, `unpaid`, or `overdue`.
    - `unpaid`: Can only be set if the current status is `draft`. Setting the status to `unpaid` finalizes the invoice and sends an email with a payment link to the customer.
    """
    tax_amount: NotRequired[AmountDecimalUpdateTypedDict]


class UpdateInvoice(BaseModel):
    description: Optional[str] = None

    line_items: Annotated[
        Optional[CreateInvoiceLineItemsUpdate], pydantic.Field(alias="lineItems")
    ] = None
    r"""A collection of line items for an invoice."""

    invoice_date: Annotated[
        OptionalNullable[datetime], pydantic.Field(alias="invoiceDate")
    ] = UNSET

    due_date: Annotated[OptionalNullable[datetime], pydantic.Field(alias="dueDate")] = (
        UNSET
    )

    status: Optional[InvoiceStatus] = None
    r"""The status can be updated to one of the following values under specific conditions:
    - `canceled`: Can only be set if the current status is `draft`, `unpaid`, or `overdue`.
    - `unpaid`: Can only be set if the current status is `draft`. Setting the status to `unpaid` finalizes the invoice and sends an email with a payment link to the customer.
    """

    tax_amount: Annotated[
        Optional[AmountDecimalUpdate], pydantic.Field(alias="taxAmount")
    ] = None

    @model_serializer(mode="wrap")
    def serialize_model(self, handler):
        optional_fields = set(
            [
                "description",
                "lineItems",
                "invoiceDate",
                "dueDate",
                "status",
                "taxAmount",
            ]
        )
        nullable_fields = set(["invoiceDate", "dueDate"])
        serialized = handler(self)
        m = {}

        for n, f in type(self).model_fields.items():
            k = f.alias or n
            val = serialized.get(k)
            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:
    UpdateInvoice.model_rebuild()
except NameError:
    pass
