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

from __future__ import annotations
from .dto_couponapplicationresponse import (
    DtoCouponApplicationResponse,
    DtoCouponApplicationResponseTypedDict,
)
from .dto_customerresponse import DtoCustomerResponse, DtoCustomerResponseTypedDict
from .dto_invoicelineitemresponse import (
    DtoInvoiceLineItemResponse,
    DtoInvoiceLineItemResponseTypedDict,
)
from .dto_taxappliedresponse import (
    DtoTaxAppliedResponse,
    DtoTaxAppliedResponseTypedDict,
)
from .invoicestatus import InvoiceStatus
from .invoicetype import InvoiceType
from .paymentstatus import PaymentStatus
from .status import Status
from flexprice.types import BaseModel, UNSET_SENTINEL
from pydantic import model_serializer
from typing import Dict, List, Optional, TYPE_CHECKING
from typing_extensions import NotRequired, TypedDict

if TYPE_CHECKING:
    from .dto_subscriptionresponse import (
        DtoSubscriptionResponse,
        DtoSubscriptionResponseTypedDict,
    )


class DtoInvoiceResponseTypedDict(TypedDict):
    adjustment_amount: NotRequired[str]
    r"""adjustment_amount is the total sum of credit notes of type \"adjustment\".
    These are non-cash reductions applied to the invoice (e.g. goodwill credit, billing correction).
    """
    amount_due: NotRequired[str]
    r"""amount_due is the total amount that needs to be paid for this invoice"""
    amount_paid: NotRequired[str]
    r"""amount_paid is the amount that has already been paid towards this invoice"""
    amount_remaining: NotRequired[str]
    r"""amount_remaining is the outstanding amount still owed on this invoice (calculated as amount_due minus amount_paid)"""
    billing_period: NotRequired[str]
    r"""billing_period describes the billing period this invoice covers (e.g., \"January 2024\", \"Q1 2024\")"""
    billing_reason: NotRequired[str]
    r"""billing_reason indicates why this invoice was generated (e.g., \"subscription_billing\", \"manual_charge\")"""
    billing_sequence: NotRequired[int]
    r"""billing_sequence is the sequential number indicating the billing cycle for subscription invoices"""
    coupon_applications: NotRequired[List[DtoCouponApplicationResponseTypedDict]]
    r"""coupon_applications contains the coupon applications associated with this invoice (overrides embedded field)"""
    created_at: NotRequired[str]
    created_by: NotRequired[str]
    currency: NotRequired[str]
    r"""currency is the three-letter ISO currency code (e.g., USD, EUR, GBP) that applies to all monetary amounts on this invoice"""
    customer: NotRequired[DtoCustomerResponseTypedDict]
    r"""Customer response object containing all customer information"""
    customer_id: NotRequired[str]
    r"""customer_id is the ID of the customer who will receive this invoice"""
    description: NotRequired[str]
    r"""description is an optional description or notes about this invoice"""
    due_date: NotRequired[str]
    r"""due_date is the date when payment for this invoice is due"""
    environment_id: NotRequired[str]
    r"""environment_id is the ID of the environment this invoice belongs to (for multi-environment setups)"""
    finalized_at: NotRequired[str]
    r"""finalized_at is the timestamp when this invoice was finalized and made ready for payment"""
    id: NotRequired[str]
    r"""id is the unique identifier for this invoice"""
    idempotency_key: NotRequired[str]
    r"""idempotency_key is a unique key used to prevent duplicate invoice creation when retrying API calls"""
    invoice_number: NotRequired[str]
    r"""invoice_number is the human-readable invoice number displayed to customers (e.g., INV-2024-001)"""
    invoice_pdf_url: NotRequired[str]
    r"""invoice_pdf_url is the URL where customers can download the PDF version of this invoice"""
    invoice_status: NotRequired[InvoiceStatus]
    invoice_type: NotRequired[InvoiceType]
    line_items: NotRequired[List[DtoInvoiceLineItemResponseTypedDict]]
    r"""line_items contains the individual items that make up this invoice (overrides embedded field)"""
    metadata: NotRequired[Dict[str, str]]
    overpaid_amount: NotRequired[str]
    r"""overpaid_amount is the amount overpaid if payment_status is OVERPAID (amount_paid - total)"""
    paid_at: NotRequired[str]
    r"""paid_at is the timestamp when this invoice was fully paid"""
    payment_status: NotRequired[PaymentStatus]
    period_end: NotRequired[str]
    r"""period_end is the end date of the billing period covered by this invoice"""
    period_start: NotRequired[str]
    r"""period_start is the start date of the billing period covered by this invoice"""
    recalculated_invoice_id: NotRequired[str]
    r"""recalculated_invoice_id is the ID of the replacement invoice created when this invoice was voided and recalculated.
    When set, it forms a parent→child link from this (voided) invoice to the new replacement invoice.
    """
    refunded_amount: NotRequired[str]
    r"""refunded_amount is the total sum of credit notes of type \"refund\".
    These are actual refunds issued to the customer.
    """
    status: NotRequired[Status]
    subscription: NotRequired["DtoSubscriptionResponseTypedDict"]
    subscription_id: NotRequired[str]
    r"""subscription_id is the ID of the subscription this invoice is associated with (only present for subscription-based invoices)"""
    subtotal: NotRequired[str]
    r"""subtotal is the sum of all line items before any taxes, discounts, or additional fees"""
    taxes: NotRequired[List[DtoTaxAppliedResponseTypedDict]]
    r"""tax_applied_records contains the tax applied records associated with this invoice"""
    tenant_id: NotRequired[str]
    total: NotRequired[str]
    r"""total is the final amount including taxes, fees, and discounts"""
    total_discount: NotRequired[str]
    r"""total_discount is the sum of all coupon discounts applied to the invoice"""
    total_prepaid_credits_applied: NotRequired[str]
    r"""total_prepaid_credits_applied is the total amount of prepaid credits applied to this invoice."""
    total_tax: NotRequired[str]
    r"""total_tax is the sum of all taxes combined at the invoice level."""
    updated_at: NotRequired[str]
    updated_by: NotRequired[str]
    version: NotRequired[int]
    r"""version is the version number for tracking changes to this invoice"""
    voided_at: NotRequired[str]
    r"""voided_at is the timestamp when this invoice was voided or cancelled"""


class DtoInvoiceResponse(BaseModel):
    adjustment_amount: Optional[str] = None
    r"""adjustment_amount is the total sum of credit notes of type \"adjustment\".
    These are non-cash reductions applied to the invoice (e.g. goodwill credit, billing correction).
    """

    amount_due: Optional[str] = None
    r"""amount_due is the total amount that needs to be paid for this invoice"""

    amount_paid: Optional[str] = None
    r"""amount_paid is the amount that has already been paid towards this invoice"""

    amount_remaining: Optional[str] = None
    r"""amount_remaining is the outstanding amount still owed on this invoice (calculated as amount_due minus amount_paid)"""

    billing_period: Optional[str] = None
    r"""billing_period describes the billing period this invoice covers (e.g., \"January 2024\", \"Q1 2024\")"""

    billing_reason: Optional[str] = None
    r"""billing_reason indicates why this invoice was generated (e.g., \"subscription_billing\", \"manual_charge\")"""

    billing_sequence: Optional[int] = None
    r"""billing_sequence is the sequential number indicating the billing cycle for subscription invoices"""

    coupon_applications: Optional[List[DtoCouponApplicationResponse]] = None
    r"""coupon_applications contains the coupon applications associated with this invoice (overrides embedded field)"""

    created_at: Optional[str] = None

    created_by: Optional[str] = None

    currency: Optional[str] = None
    r"""currency is the three-letter ISO currency code (e.g., USD, EUR, GBP) that applies to all monetary amounts on this invoice"""

    customer: Optional[DtoCustomerResponse] = None
    r"""Customer response object containing all customer information"""

    customer_id: Optional[str] = None
    r"""customer_id is the ID of the customer who will receive this invoice"""

    description: Optional[str] = None
    r"""description is an optional description or notes about this invoice"""

    due_date: Optional[str] = None
    r"""due_date is the date when payment for this invoice is due"""

    environment_id: Optional[str] = None
    r"""environment_id is the ID of the environment this invoice belongs to (for multi-environment setups)"""

    finalized_at: Optional[str] = None
    r"""finalized_at is the timestamp when this invoice was finalized and made ready for payment"""

    id: Optional[str] = None
    r"""id is the unique identifier for this invoice"""

    idempotency_key: Optional[str] = None
    r"""idempotency_key is a unique key used to prevent duplicate invoice creation when retrying API calls"""

    invoice_number: Optional[str] = None
    r"""invoice_number is the human-readable invoice number displayed to customers (e.g., INV-2024-001)"""

    invoice_pdf_url: Optional[str] = None
    r"""invoice_pdf_url is the URL where customers can download the PDF version of this invoice"""

    invoice_status: Optional[InvoiceStatus] = None

    invoice_type: Optional[InvoiceType] = None

    line_items: Optional[List[DtoInvoiceLineItemResponse]] = None
    r"""line_items contains the individual items that make up this invoice (overrides embedded field)"""

    metadata: Optional[Dict[str, str]] = None

    overpaid_amount: Optional[str] = None
    r"""overpaid_amount is the amount overpaid if payment_status is OVERPAID (amount_paid - total)"""

    paid_at: Optional[str] = None
    r"""paid_at is the timestamp when this invoice was fully paid"""

    payment_status: Optional[PaymentStatus] = None

    period_end: Optional[str] = None
    r"""period_end is the end date of the billing period covered by this invoice"""

    period_start: Optional[str] = None
    r"""period_start is the start date of the billing period covered by this invoice"""

    recalculated_invoice_id: Optional[str] = None
    r"""recalculated_invoice_id is the ID of the replacement invoice created when this invoice was voided and recalculated.
    When set, it forms a parent→child link from this (voided) invoice to the new replacement invoice.
    """

    refunded_amount: Optional[str] = None
    r"""refunded_amount is the total sum of credit notes of type \"refund\".
    These are actual refunds issued to the customer.
    """

    status: Optional[Status] = None

    subscription: Optional["DtoSubscriptionResponse"] = None

    subscription_id: Optional[str] = None
    r"""subscription_id is the ID of the subscription this invoice is associated with (only present for subscription-based invoices)"""

    subtotal: Optional[str] = None
    r"""subtotal is the sum of all line items before any taxes, discounts, or additional fees"""

    taxes: Optional[List[DtoTaxAppliedResponse]] = None
    r"""tax_applied_records contains the tax applied records associated with this invoice"""

    tenant_id: Optional[str] = None

    total: Optional[str] = None
    r"""total is the final amount including taxes, fees, and discounts"""

    total_discount: Optional[str] = None
    r"""total_discount is the sum of all coupon discounts applied to the invoice"""

    total_prepaid_credits_applied: Optional[str] = None
    r"""total_prepaid_credits_applied is the total amount of prepaid credits applied to this invoice."""

    total_tax: Optional[str] = None
    r"""total_tax is the sum of all taxes combined at the invoice level."""

    updated_at: Optional[str] = None

    updated_by: Optional[str] = None

    version: Optional[int] = None
    r"""version is the version number for tracking changes to this invoice"""

    voided_at: Optional[str] = None
    r"""voided_at is the timestamp when this invoice was voided or cancelled"""

    @model_serializer(mode="wrap")
    def serialize_model(self, handler):
        optional_fields = set(
            [
                "adjustment_amount",
                "amount_due",
                "amount_paid",
                "amount_remaining",
                "billing_period",
                "billing_reason",
                "billing_sequence",
                "coupon_applications",
                "created_at",
                "created_by",
                "currency",
                "customer",
                "customer_id",
                "description",
                "due_date",
                "environment_id",
                "finalized_at",
                "id",
                "idempotency_key",
                "invoice_number",
                "invoice_pdf_url",
                "invoice_status",
                "invoice_type",
                "line_items",
                "metadata",
                "overpaid_amount",
                "paid_at",
                "payment_status",
                "period_end",
                "period_start",
                "recalculated_invoice_id",
                "refunded_amount",
                "status",
                "subscription",
                "subscription_id",
                "subtotal",
                "taxes",
                "tenant_id",
                "total",
                "total_discount",
                "total_prepaid_credits_applied",
                "total_tax",
                "updated_at",
                "updated_by",
                "version",
                "voided_at",
            ]
        )
        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
