# This file was auto-generated by Fern from our API Definition.

from ...core.pydantic_utilities import UniversalBaseModel
from .invoice_id import InvoiceId
from .invoice_status import InvoiceStatus
import typing
import pydantic
from ...payment_method_types.types.currency_code import CurrencyCode
import datetime as dt
from ...entity_types.types.entity_id import EntityId
from ...entity_types.types.counterparty_response import CounterpartyResponse
from ...payment_method_types.types.payment_method_response import PaymentMethodResponse
from ...payment_method_types.types.payment_method_id import PaymentMethodId
from .payment_destination_options import PaymentDestinationOptions
from .comment_response import CommentResponse
from .invoice_line_item_response import InvoiceLineItemResponse
from .approval_slot import ApprovalSlot
from ...entity_types.types.approval_policy_response import ApprovalPolicyResponse
from ...entity_types.types.entity_user_response import EntityUserResponse
from .invoice_failure_type import InvoiceFailureType
from .invoice_fees_response import InvoiceFeesResponse
from .payment_schedule import PaymentSchedule
from ...core.pydantic_utilities import IS_PYDANTIC_V2


class InvoiceResponse(UniversalBaseModel):
    """
    Examples
    --------
    import datetime

    from mercoa.commons import Address, PhoneNumber
    from mercoa.entity_types import (
        ApprovalPolicyResponse,
        BusinessProfileResponse,
        CounterpartyCustomizationAccount,
        CounterpartyResponse,
        Ein,
        EntityUserResponse,
        IdentifierList_RolesList,
        ProfileResponse,
        Rule_Approver,
        TaxId,
        Trigger_Amount,
    )
    from mercoa.invoice_types import (
        ApprovalSlot,
        AssociatedApprovalAction,
        CommentResponse,
        InvoiceLineItemResponse,
        InvoiceResponse,
        PaymentDestinationOptions_Check,
    )
    from mercoa.payment_method_types import (
        PaymentMethodResponse_BankAccount,
        PaymentMethodResponse_Check,
    )

    InvoiceResponse(
        id="inv_26e7b5d3-a739-4b23-9ad9-6aaa085f47a9",
        status="PAID",
        amount=100.0,
        currency="USD",
        invoice_date=datetime.datetime.fromisoformat(
            "2021-01-01 00:00:00+00:00",
        ),
        deduction_date=datetime.datetime.fromisoformat(
            "2021-01-01 00:00:00+00:00",
        ),
        settlement_date=datetime.datetime.fromisoformat(
            "2021-01-03 00:00:00+00:00",
        ),
        due_date=datetime.datetime.fromisoformat(
            "2021-01-31 00:00:00+00:00",
        ),
        invoice_number="INV-123",
        note_to_self="For the month of January",
        service_start_date=datetime.datetime.fromisoformat(
            "2021-01-01 00:00:00+00:00",
        ),
        service_end_date=datetime.datetime.fromisoformat(
            "2021-01-31 00:00:00+00:00",
        ),
        payer_id="ent_8545a84e-a45f-41bf-bdf1-33b42a55812c",
        payer=CounterpartyResponse(
            id="ent_8545a84e-a45f-41bf-bdf1-33b42a55812c",
            foreign_id="MY-DB-ID-12345",
            name="Acme Inc.",
            email="customer@acme.com",
            accepted_tos=True,
            status="verified",
            is_customer=True,
            is_payor=True,
            is_payee=False,
            is_network_payor=False,
            is_network_payee=False,
            account_type="business",
            updated_at=datetime.datetime.fromisoformat(
                "2024-01-02 00:00:00+00:00",
            ),
            created_at=datetime.datetime.fromisoformat(
                "2024-01-01 00:00:00+00:00",
            ),
            profile=ProfileResponse(
                business=BusinessProfileResponse(
                    email="customer@acme.com",
                    legal_business_name="Acme Inc.",
                    business_type="llc",
                    phone=PhoneNumber(
                        country_code="1",
                        number="4155551234",
                    ),
                    address=Address(
                        address_line_1="123 Main St",
                        address_line_2="Unit 1",
                        city="San Francisco",
                        state_or_province="CA",
                        postal_code="94105",
                        country="US",
                    ),
                    tax_id_provided=True,
                    tax_id=TaxId(
                        ein=Ein(
                            number="12-3456789",
                        ),
                    ),
                    owners_provided=True,
                ),
            ),
            accounts=[
                CounterpartyCustomizationAccount(
                    account_id="85866843",
                    postal_code="94105",
                    name_on_account="John Doe",
                )
            ],
            payment_methods=[
                PaymentMethodResponse_BankAccount(
                    id="pm_4794d597-70dc-4fec-b6ec-c5988e759769",
                    account_name="My Checking Account",
                    bank_name="Chase",
                    routing_number="12345678",
                    account_number="99988767623",
                    account_type="CHECKING",
                    status="VERIFIED",
                    is_default_source=True,
                    is_default_destination=True,
                    supported_currencies=["USD"],
                    metadata={},
                    frozen=False,
                    created_at=datetime.datetime.fromisoformat(
                        "2021-01-01 00:00:00+00:00",
                    ),
                    updated_at=datetime.datetime.fromisoformat(
                        "2021-01-01 00:00:00+00:00",
                    ),
                )
            ],
            counterparty_type=["ENTITY"],
        ),
        payment_source=PaymentMethodResponse_BankAccount(
            id="pm_4794d597-70dc-4fec-b6ec-c5988e759769",
            account_name="My Checking Account",
            bank_name="Chase",
            routing_number="12345678",
            account_number="99988767623",
            account_type="CHECKING",
            status="VERIFIED",
            is_default_source=True,
            is_default_destination=True,
            supported_currencies=["USD"],
            metadata={},
            frozen=False,
            created_at=datetime.datetime.fromisoformat(
                "2021-01-01 00:00:00+00:00",
            ),
            updated_at=datetime.datetime.fromisoformat(
                "2021-01-01 00:00:00+00:00",
            ),
        ),
        payment_source_id="pm_4794d597-70dc-4fec-b6ec-c5988e759769",
        vendor_id="ent_21661ac1-a2a8-4465-a6c0-64474ba8181d",
        vendor=CounterpartyResponse(
            id="ent_21661ac1-a2a8-4465-a6c0-64474ba8181d",
            foreign_id="MY-DB-ID-90909",
            name="Big Box Store",
            email="vendor@bigboxstore.com",
            accepted_tos=False,
            status="unverified",
            is_customer=False,
            is_payor=False,
            is_payee=True,
            is_network_payor=False,
            is_network_payee=False,
            account_type="business",
            updated_at=datetime.datetime.fromisoformat(
                "2024-01-02 00:00:00+00:00",
            ),
            created_at=datetime.datetime.fromisoformat(
                "2024-01-01 00:00:00+00:00",
            ),
            profile=ProfileResponse(
                business=BusinessProfileResponse(
                    email="vendor@bigboxstore.com",
                    legal_business_name="Big Box Store",
                    business_type="publicCorporation",
                    tax_id_provided=False,
                    owners_provided=False,
                ),
            ),
            payment_methods=[
                PaymentMethodResponse_BankAccount(
                    id="pm_7610541f-4619-4033-8620-cfccfb811293",
                    account_name="Vendor Checking Account",
                    bank_name="Chase",
                    routing_number="66554433",
                    account_number="55934059697648",
                    account_type="CHECKING",
                    status="NEW",
                    is_default_source=True,
                    is_default_destination=True,
                    supported_currencies=["USD"],
                    metadata={},
                    frozen=False,
                    created_at=datetime.datetime.fromisoformat(
                        "2021-01-01 00:00:00+00:00",
                    ),
                    updated_at=datetime.datetime.fromisoformat(
                        "2021-01-01 00:00:00+00:00",
                    ),
                )
            ],
            counterparty_type=["ENTITY"],
        ),
        payment_destination=PaymentMethodResponse_Check(
            id="pm_5fde2f4a-facc-48ef-8f0d-6b7d087c7b18",
            pay_to_the_order_of="John Doe",
            address_line_1="123 Main St",
            address_line_2="Apt 1",
            city="New York",
            state_or_province="NY",
            postal_code="10001",
            country="US",
            is_default_source=False,
            is_default_destination=True,
            supported_currencies=["USD"],
            metadata={},
            frozen=False,
            created_at=datetime.datetime.fromisoformat(
                "2021-01-01 00:00:00+00:00",
            ),
            updated_at=datetime.datetime.fromisoformat(
                "2021-01-01 00:00:00+00:00",
            ),
        ),
        payment_destination_id="pm_5fde2f4a-facc-48ef-8f0d-6b7d087c7b18",
        payment_destination_options=PaymentDestinationOptions_Check(
            delivery="MAIL",
        ),
        payment_destination_confirmed=True,
        has_documents=True,
        has_source_email=True,
        comments=[
            CommentResponse(
                id="ic_b3525b66-da94-4525-9f31-426bcf657128",
                text="This is an approval comment",
                user=EntityUserResponse(
                    id="user_ec3aafc8-ea86-408a-a6c1-545497badbbb",
                    foreign_id="MY-DB-ID-12345",
                    email="john.doe@acme.com",
                    name="John Doe",
                    roles=["admin", "approver"],
                    created_at=datetime.datetime.fromisoformat(
                        "2024-01-01 00:00:00+00:00",
                    ),
                    updated_at=datetime.datetime.fromisoformat(
                        "2024-01-01 00:00:00+00:00",
                    ),
                ),
                associated_approval_action=AssociatedApprovalAction(
                    user_id="user_e24fc81c-c5ee-47e8-af42-4fe29d895506",
                    action="APPROVE",
                ),
                created_at=datetime.datetime.fromisoformat(
                    "2021-01-01 00:00:00+00:00",
                ),
                updated_at=datetime.datetime.fromisoformat(
                    "2021-01-01 00:00:00+00:00",
                ),
            )
        ],
        line_items=[
            InvoiceLineItemResponse(
                id="inli_26672f38-eb9a-48f1-a7a0-f1b855e38cd7",
                amount=100.0,
                currency="USD",
                description="Product A",
                name="Product A",
                quantity=1.0,
                unit_price=100.0,
                category="EXPENSE",
                service_start_date=datetime.datetime.fromisoformat(
                    "2021-01-01 00:00:00+00:00",
                ),
                service_end_date=datetime.datetime.fromisoformat(
                    "2021-01-31 00:00:00+00:00",
                ),
                metadata={"key1": "value1", "key2": "value2"},
                gl_account_id="600394",
                created_at=datetime.datetime.fromisoformat(
                    "2021-01-01 00:00:00+00:00",
                ),
                updated_at=datetime.datetime.fromisoformat(
                    "2021-01-01 00:00:00+00:00",
                ),
            )
        ],
        approvers=[
            ApprovalSlot(
                approval_policy_id="apvl_5ce50275-1789-42ea-bc60-bb7e6d03635c",
                approval_slot_id="inap_9bb311c9-7c15-4c9e-8148-63814e0abec6",
                assigned_user_id="user_e24fc81c-c5ee-47e8-af42-4fe29d895506",
                action="APPROVE",
                eligible_user_ids=["user_e24fc81c-c5ee-47e8-af42-4fe29d895506"],
                eligible_roles=["admin"],
                date=datetime.datetime.fromisoformat(
                    "2021-01-01 00:00:00+00:00",
                ),
            )
        ],
        approval_policy=[
            ApprovalPolicyResponse(
                id="apvl_8545a84e-a45f-41bf-bdf1-33b42a55812c",
                trigger=[
                    Trigger_Amount(
                        amount=100.0,
                        currency="USD",
                    )
                ],
                rule=Rule_Approver(
                    num_approvers=2,
                    identifier_list=IdentifierList_RolesList(
                        value=["Admin", "Controller"]
                    ),
                ),
                upstream_policy_id="root",
                updated_at=datetime.datetime.fromisoformat(
                    "2024-01-02 00:00:00+00:00",
                ),
                created_at=datetime.datetime.fromisoformat(
                    "2024-01-01 00:00:00+00:00",
                ),
            )
        ],
        metadata={"key1": "value1", "key2": "value2"},
        foreign_id="YOUR-DATABASE-ID",
        creator_user=EntityUserResponse(
            id="user_ec3aafc8-ea86-408a-a6c1-545497badbbb",
            foreign_id="MY-DB-ID-12345",
            email="john.doe@acme.com",
            name="John Doe",
            roles=["admin", "approver"],
            created_at=datetime.datetime.fromisoformat(
                "2024-01-01 00:00:00+00:00",
            ),
            updated_at=datetime.datetime.fromisoformat(
                "2024-01-01 00:00:00+00:00",
            ),
        ),
        processed_at=datetime.datetime.fromisoformat(
            "2021-01-01 00:00:00+00:00",
        ),
        created_at=datetime.datetime.fromisoformat(
            "2021-01-01 00:00:00+00:00",
        ),
        updated_at=datetime.datetime.fromisoformat(
            "2021-01-01 00:00:00+00:00",
        ),
    )
    """

    id: InvoiceId
    status: InvoiceStatus
    amount: typing.Optional[float] = pydantic.Field(default=None)
    """
    Total amount of invoice in major units
    """

    currency: typing.Optional[CurrencyCode] = pydantic.Field(default=None)
    """
    Currency code for the amount. Defaults to USD.
    """

    invoice_date: typing.Optional[dt.datetime] = pydantic.Field(alias="invoiceDate", default=None)
    """
    Date the invoice was issued.
    """

    deduction_date: typing.Optional[dt.datetime] = pydantic.Field(alias="deductionDate", default=None)
    """
    Initial date when funds are scheduled to be deducted from payer's account. The actual deduction date may differ from this date, and will be reflected in the processedAt field.
    """

    next_deduction_date: typing.Optional[dt.datetime] = pydantic.Field(alias="nextDeductionDate", default=None)
    """
    If this is a recurring invoice, this will be the next date when funds are scheduled to be deducted from payer's account.
    """

    processed_at: typing.Optional[dt.datetime] = pydantic.Field(alias="processedAt", default=None)
    """
    Date when the invoice payment was processed.
    """

    settlement_date: typing.Optional[dt.datetime] = pydantic.Field(alias="settlementDate", default=None)
    """
    Date of funds settlement.
    """

    due_date: typing.Optional[dt.datetime] = pydantic.Field(alias="dueDate", default=None)
    """
    Due date of invoice.
    """

    invoice_number: typing.Optional[str] = pydantic.Field(alias="invoiceNumber", default=None)
    note_to_self: typing.Optional[str] = pydantic.Field(alias="noteToSelf", default=None)
    service_start_date: typing.Optional[dt.datetime] = pydantic.Field(alias="serviceStartDate", default=None)
    service_end_date: typing.Optional[dt.datetime] = pydantic.Field(alias="serviceEndDate", default=None)
    payer_id: typing.Optional[EntityId] = pydantic.Field(alias="payerId", default=None)
    payer: typing.Optional[CounterpartyResponse] = None
    payment_source: typing.Optional[PaymentMethodResponse] = pydantic.Field(alias="paymentSource", default=None)
    payment_source_id: typing.Optional[PaymentMethodId] = pydantic.Field(alias="paymentSourceId", default=None)
    vendor_id: typing.Optional[EntityId] = pydantic.Field(alias="vendorId", default=None)
    vendor: typing.Optional[CounterpartyResponse] = None
    payment_destination: typing.Optional[PaymentMethodResponse] = pydantic.Field(
        alias="paymentDestination", default=None
    )
    payment_destination_id: typing.Optional[PaymentMethodId] = pydantic.Field(
        alias="paymentDestinationId", default=None
    )
    payment_destination_options: typing.Optional[PaymentDestinationOptions] = pydantic.Field(
        alias="paymentDestinationOptions", default=None
    )
    payment_destination_confirmed: bool = pydantic.Field(alias="paymentDestinationConfirmed")
    """
    True if the payment destination has been confirmed by the vendor. False if the payment destination has been set (for example, a check to an address) but has not been confirmed by the vendor.
    """

    batch_payment: typing.Optional[bool] = pydantic.Field(alias="batchPayment", default=None)
    """
    If true, this invoice will be paid as a batch payment. Batches are automatically determined by Mercoa based on the payment source, destination, and scheduled payment date.
    """

    has_documents: bool = pydantic.Field(alias="hasDocuments")
    """
    True if the invoice has documents attached.
    """

    has_source_email: bool = pydantic.Field(alias="hasSourceEmail")
    """
    True if the invoice was created by an incoming email.
    """

    comments: typing.Optional[typing.List[CommentResponse]] = None
    line_items: typing.Optional[typing.List[InvoiceLineItemResponse]] = pydantic.Field(alias="lineItems", default=None)
    approvers: typing.List[ApprovalSlot]
    approval_policy: typing.List[ApprovalPolicyResponse] = pydantic.Field(alias="approvalPolicy")
    metadata: typing.Dict[str, str] = pydantic.Field()
    """
    Metadata associated with this invoice.
    """

    foreign_id: typing.Optional[str] = pydantic.Field(alias="foreignId", default=None)
    """
    The ID used to identify this invoice in your system. This ID must be unique within each creatorEntity in your system, e.g. two invoices with the same creatorEntity may not have the same foreign ID.
    """

    creator_entity_id: typing.Optional[EntityId] = pydantic.Field(alias="creatorEntityId", default=None)
    """
    The ID of the entity who created this invoice.
    """

    creator_user: typing.Optional[EntityUserResponse] = pydantic.Field(alias="creatorUser", default=None)
    """
    Entity user who created this invoice.
    """

    failure_type: typing.Optional[InvoiceFailureType] = pydantic.Field(alias="failureType", default=None)
    """
    If the invoice failed to be paid, this field will be populated with the type of failure.
    """

    created_at: dt.datetime = pydantic.Field(alias="createdAt")
    updated_at: dt.datetime = pydantic.Field(alias="updatedAt")
    fees: typing.Optional[InvoiceFeesResponse] = pydantic.Field(default=None)
    """
    Fees associated with this invoice.
    """

    payment_schedule: typing.Optional[PaymentSchedule] = pydantic.Field(alias="paymentSchedule", default=None)
    """
    If this is a recurring invoice, this will be the payment schedule for the invoice. If not provided, this will be a one-time invoice.
    """

    if IS_PYDANTIC_V2:
        model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True)  # type: ignore # Pydantic v2
    else:

        class Config:
            frozen = True
            smart_union = True
            extra = pydantic.Extra.allow
