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

import datetime as dt
import typing

import pydantic
from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
from .counterpart_raw_data import CounterpartRawData
from .currency_enum import CurrencyEnum
from .currency_exchange_schema2 import CurrencyExchangeSchema2
from .file_schema import FileSchema
from .ocr_status_enum import OcrStatusEnum
from .payable_credit_note_data import PayableCreditNoteData
from .payable_origin_enum import PayableOriginEnum
from .payable_payment_terms_create_payload import PayablePaymentTermsCreatePayload
from .payable_response_schema_other_extracted_data import PayableResponseSchemaOtherExtractedData
from .payable_state_enum import PayableStateEnum
from .source_of_payable_data_enum import SourceOfPayableDataEnum
from .suggested_payment_term import SuggestedPaymentTerm
from .tag_read_schema import TagReadSchema


class PayableResponseSchema(UniversalBaseModel):
    """
    Represents an Accounts Payable document received from a vendor or supplier.
    """

    id: str = pydantic.Field()
    """
    A unique ID assigned to this payable.
    """

    created_at: dt.datetime = pydantic.Field()
    """
    UTC date and time when this payable was created. Timestamps follow the [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) format.
    """

    updated_at: dt.datetime = pydantic.Field()
    """
    UTC date and time when this payable was last updated. Timestamps follow the [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) format.
    """

    amount_due: typing.Optional[int] = pydantic.Field(default=None)
    """
    How much is left to be paid on the invoice (in minor units).
    """

    amount_paid: typing.Optional[int] = pydantic.Field(default=None)
    """
    How much was paid on the invoice (in minor units).
    """

    amount_to_pay: typing.Optional[int] = pydantic.Field(default=None)
    """
    How much is left to be paid on the invoice (in minor units) with discounts from payment terms.
    """

    approval_policy_id: typing.Optional[str] = pydantic.Field(default=None)
    """
    Id of existing approval policy that applies to this payable, if any. A policy is applied if the payable matches the policy trigger conditions.
    """

    counterpart: typing.Optional[CounterpartRawData] = pydantic.Field(default=None)
    """
    Object representing de-normalized counterpart data. Filled at the moment of invoice submitting for approval or payment.
    """

    counterpart_address_id: typing.Optional[str] = pydantic.Field(default=None)
    """
    The ID of counterpart address object stored in counterparts service
    """

    counterpart_bank_account_id: typing.Optional[str] = pydantic.Field(default=None)
    """
    The ID of counterpart bank account object stored in counterparts service
    """

    counterpart_id: typing.Optional[str] = pydantic.Field(default=None)
    """
    The ID of the counterpart object that represents the vendor or supplier.
    """

    counterpart_raw_data: typing.Optional[CounterpartRawData] = pydantic.Field(default=None)
    """
    Object representing counterpart data which was extracted by OCR. Used for informational purposes.
    """

    counterpart_vat_id_id: typing.Optional[str] = pydantic.Field(default=None)
    """
    The ID of counterpart VAT ID object stored in counterparts service
    """

    created_by_role_id: typing.Optional[str] = pydantic.Field(default=None)
    """
    The ID of the role that the entity user who created this payable had at that time. If the payable was created using a partner access token, the value is `null`.
    """

    credit_notes: typing.List[PayableCreditNoteData] = pydantic.Field()
    """
    The list of linked credit notes of the payable.
    """

    currency: typing.Optional[CurrencyEnum] = pydantic.Field(default=None)
    """
    The [currency code](https://docs.monite.com/references/currencies) of the currency used in the payable.
    """

    currency_exchange: typing.Optional[CurrencyExchangeSchema2] = None
    description: typing.Optional[str] = pydantic.Field(default=None)
    """
    An arbitrary description of this payable.
    """

    discount: typing.Optional[int] = pydantic.Field(default=None)
    """
    The value of the additional discount that will be applied to the total amount. in [minor units](https://docs.monite.com/references/currencies#minor-units). For example, $12.50 is represented as 1250.
    """

    document_id: typing.Optional[str] = pydantic.Field(default=None)
    """
    A unique invoice number assigned by the invoice issuer for payment tracking purposes. This is different from `id` which is an internal ID created automatically by Monite.
    """

    due_date: typing.Optional[str] = pydantic.Field(default=None)
    """
    The date by which the payable must be paid, in the YYYY-MM-DD format. If the payable specifies payment terms with early payment discounts, this is the final payment date.
    """

    entity_id: str = pydantic.Field()
    """
    The ID of the entity to which the payable was issued.
    """

    file: typing.Optional[FileSchema] = pydantic.Field(default=None)
    """
    The original file from which this payable was created.
    """

    file_id: typing.Optional[str] = pydantic.Field(default=None)
    """
    File id to retrieve file info from file saver.
    """

    issued_at: typing.Optional[str] = pydantic.Field(default=None)
    """
    The date when the payable was issued, in the YYYY-MM-DD format.
    """

    marked_as_paid_by_entity_user_id: typing.Optional[str] = pydantic.Field(default=None)
    """
    The ID of the entity user who marked this document as paid.
    """

    marked_as_paid_with_comment: typing.Optional[str] = pydantic.Field(default=None)
    """
    An arbitrary comment that describes how and when this payable was paid.
    """

    ocr_request_id: typing.Optional[str] = pydantic.Field(default=None)
    """
    Id of OCR request to match asynchronous result of processing payable.
    """

    ocr_status: typing.Optional[OcrStatusEnum] = pydantic.Field(default=None)
    """
    The status of the data recognition process using OCR. The 'processing' status means that the data recognition is in progress and the user needs to wait for the data enrichment. The 'error' status indicates that some error occurred on the OCR side and the user can fill in the data manually. The 'success' status means the data recognition has been successfully completed, after which the user can check the data if desired and enrich or correct it.
    """

    other_extracted_data: typing.Optional[PayableResponseSchemaOtherExtractedData] = pydantic.Field(default=None)
    """
    Data extracted from the uploaded payable by OCR.
    """

    paid_at: typing.Optional[dt.datetime] = pydantic.Field(default=None)
    """
    The date by which the payable was paid
    """

    partner_metadata: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = pydantic.Field(default=None)
    """
    Metadata for partner needs
    """

    payable_origin: PayableOriginEnum = pydantic.Field()
    """
    Specifies how this payable was created in Monite: `upload` - created via an API call, `email` - sent via email to the entity's mailbox.
    """

    payment_terms: typing.Optional[PayablePaymentTermsCreatePayload] = pydantic.Field(default=None)
    """
    The number of days to pay with potential discount for options shorter than due_date
    """

    project_id: typing.Optional[str] = pydantic.Field(default=None)
    """
    Project ID of a payable.
    """

    purchase_order_id: typing.Optional[str] = pydantic.Field(default=None)
    """
    The identifier of the purchase order to which this payable belongs.
    """

    sender: typing.Optional[str] = pydantic.Field(default=None)
    """
    The email address from which the invoice was sent to the entity.
    """

    source_of_payable_data: SourceOfPayableDataEnum = pydantic.Field()
    """
    Specifies how the property values of this payable were provided: `ocr` - Monite OCR service extracted the values from the provided PDF or image file, `user_specified` - values were added or updated via an API call.
    """

    status: PayableStateEnum = pydantic.Field()
    """
    The [status](https://docs.monite.com/accounts-payable/payables/index) of the payable.
    """

    subtotal: typing.Optional[int] = pydantic.Field(default=None)
    """
    The subtotal amount to be paid, in [minor units](https://docs.monite.com/references/currencies#minor-units). For example, $12.50 is represented as 1250.
    """

    suggested_payment_term: typing.Optional[SuggestedPaymentTerm] = pydantic.Field(default=None)
    """
    The suggested date and corresponding discount in which payable could be paid. The date is in the YYYY-MM-DD format. The discount is calculated as X * (10^-4) - for example, 100 is 1%, 25 is 0,25%, 10000 is 100 %. Date varies depending on the payment terms and may even be equal to the due date with discount 0.
    """

    tags: typing.Optional[typing.List[TagReadSchema]] = pydantic.Field(default=None)
    """
    A list of user-defined tags (labels) assigned to this payable. Tags can be used to trigger a specific approval policy for this payable.
    """

    tax: typing.Optional[int] = pydantic.Field(default=None)
    """
    Registered tax percentage applied for a service price in minor units, e.g. 200 means 2%, 1050 means 10.5%.
    """

    tax_amount: typing.Optional[int] = pydantic.Field(default=None)
    """
    Tax amount in [minor units](https://docs.monite.com/references/currencies#minor-units). For example, $12.50 is represented as 1250.
    """

    total_amount: typing.Optional[int] = pydantic.Field(default=None)
    """
    The total amount to be paid, in [minor units](https://docs.monite.com/references/currencies#minor-units). For example, $12.50 is represented as 1250.
    """

    total_amount_with_credit_notes: typing.Optional[int] = pydantic.Field(default=None)
    """
    The total price of the payable in [minor units](https://docs.monite.com/references/currencies#minor-units), excluding all issued credit notes.
    """

    was_created_by_user_id: typing.Optional[str] = None

    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
