"""Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT."""

from __future__ import annotations
import dataclasses
import dateutil.parser
from ..shared import autocollection as shared_autocollection
from ..shared import creditnotesummary as shared_creditnotesummary
from ..shared import customerminified as shared_customerminified
from ..shared import discounttype as shared_discounttype
from ..shared import invoicelineitem as shared_invoicelineitem
from ..shared import invoicestatus as shared_invoicestatus
from ..shared import subscriptionminified as shared_subscriptionminified
from ..shared import transactions as shared_transactions
from billing import utils
from dataclasses_json import Undefined, dataclass_json
from datetime import datetime
from typing import Optional


@dataclass_json(undefined=Undefined.EXCLUDE)

@dataclasses.dataclass
class InvoiceCustomerTaxID:
    r"""Tax IDs are commonly required to be displayed on customer invoices, which are added to the headers of invoices.


    ### Supported Tax ID Countries and Types


    | Country        | Type         | Description                                 |
    |----------------|--------------|---------------------------------------------|
    | Australia      | `au_abn`     | Australian Business Number (AU ABN)	        |
    | Australia      | `au_arn`     | Australian Taxation Office Reference Number |
    | Austria        | `eu_vat`     | European VAT number                         |
    | Belgium        | `eu_vat`     | European VAT number                         |
    | Brazil         | `br_cnpj`    | Brazilian CNPJ number                       |
    | Brazil         | `br_cpf`     | Brazilian CPF number	                       |
    | Bulgaria       | `bg_uic`     | Bulgaria Unified Identification Code        |
    | Bulgaria       | `eu_vat`     | European VAT number                         |
    | Canada         | `ca_bn`      | Canadian BN                                 |
    | Canada         | `ca_gst_hst` | Canadian GST/HST number                     |
    | Canada         | `ca_pst_bc`  | Canadian PST number (British Columbia)      |
    | Canada         | `ca_pst_mb`  | Canadian PST number (Manitoba)              |
    | Canada         | `ca_pst_sk`  | Canadian PST number (Saskatchewan)          |
    | Canada         | `ca_qst`     | Canadian QST number (Québec)                |
    | Chile          | `cl_tin`     | Chilean TIN                                 |
    | Croatia        | `eu_vat`     | European VAT number                         |
    | Cyprus         | `eu_vat`     | European VAT number                         |
    | Czech Republic | `eu_vat`     | European VAT number                         |
    | Denmark        | `eu_vat`     | European VAT number                         |
    | Egypt          | `eg_tin`     | Egyptian Tax Identification Number	         |
    | Estonia   | `eu_vat`     | European VAT number   |                                                                             
    | EU        | `eu_oss_vat` | European One Stop Shop VAT number for non-Union scheme                                                   |
    | Finland   | `eu_vat`     | European VAT number                                                                                      |
    | France    | `eu_vat`     | European VAT number                                                                                      |
    | Georgia   | `ge_vat`     | Georgian VAT                                                                                             |
    | Germany   | `eu_vat`     | European VAT number                                                                                      |
    | Greece    | `eu_vat`     | European VAT number                                                                                      |
    | Hong Kong | `hk_br`      | Hong Kong BR number                                                                                      |
    | Hungary   | `eu_vat`     | European VAT number                                                                                      |
    | Hungary   | `hu_tin`     | Hungary tax number (adószám)	                                                                            |
    | Iceland   | `is_vat`     | Icelandic VAT                                                                                            |
    | India     | `in_gst`     | Indian GST number                                                                                        |
    | Indonesia | `id_npwp`    | Indonesian NPWP number                                                                                   |
    | Ireland   | `eu_vat`     | European VAT number                                                                                      |
    | Israel    | `il_vat`     | Israel VAT                                                                                               |
    | Italy     | `eu_vat`     | European VAT number                                                                                      |
    | Japan     | `jp_cn`      | Japanese Corporate Number (*Hōjin Bangō*)                                                                |
    | Japan     | `jp_rn`      | Japanese Registered Foreign Businesses' Registration Number (*Tōroku Kokugai Jigyōsha no Tōroku Bangō*)	 |
    | Japan     | `jp_trn`     | Japanese Tax Registration Number (*Tōroku Bangō*)	                                                       |
    | Kenya     | `ke_pin`     | Kenya Revenue Authority Personal Identification Number                                                   |
    | Latvia    | `eu_vat`     | European VAT number                                                                                  |
    | Liechtenstein | `li_uid`  | Liechtensteinian UID number           |
    | Lithuania     | `eu_vat`  | European VAT number	                  |
    | Luxembourg    | `eu_vat`  | European VAT number	                  |
    | Malaysia      | `my_frp`  | Malaysian FRP number                  |
    | Malaysia      | `my_itn`  | Malaysian ITN                         |
    | Malaysia      | `my_sst`  | Malaysian SST number                  |
    | Malta         | `eu_vat ` | European VAT number                   |
    | Mexico        | `mx_rfc`  | Mexican RFC number                    |
    | Netherlands   | `eu_vat`  | European VAT number	                  |
    | New Zealand   | `nz_gst`  | New Zealand GST number	               |
    | Norway        | `no_vat`  | Norwegian VAT number                  |
    | Philippines   | `ph_tin	` | Philippines Tax Identification Number |
    | Poland        | `eu_vat`  | European VAT number                   |
    | Portugal      | `eu_vat`  | European VAT number                   |
    | Romania       | `eu_vat`  | European VAT number                   |
    | Russia        | `ru_inn`  | Russian INN                           |
    | Russia        | `ru_kpp`  | Russian KPP                           |
    | Saudi Arabia  | `sg_gst`  | Singaporean GST                       |
    | Singapore     | `sg_uen`  | Singaporean UEN	                      |
    | Slovakia      | `eu_vat`  | European VAT number                   |
    | Slovenia      | `eu_vat`  | European VAT number                   |
    | Slovenia             | `si_tin` | Slovenia tax number (davčna številka)	             |
    | South Africa	        | `za_vat` | South African VAT number                           |
    | South Korea          | `kr_brn` | Korean BRN                                         |
    | Spain                | `es_cif` | Spanish NIF number (previously Spanish CIF number) |
    | Spain                | `eu_vat` | European VAT number	                               |
    | Sweden               | `eu_vat` | European VAT number                                |
    | Switzerland          | `ch_vat` | Switzerland VAT number	                            |
    | Taiwan               | `tw_vat` | Taiwanese VAT	                                     |
    | Thailand             | `th_vat` | Thai VAT                                           |
    | Turkey               | `tr_tin` | Turkish Tax Identification Number                  |
    | Ukraine              | `ua_vat` | Ukrainian VAT                                      |
    | United Arab Emirates | `ae_trn` | United Arab Emirates TRN	                          |
    | United Kingdom       | `eu_vat` | Northern Ireland VAT number                        |
    | United Kingdom       | `gb_vat` | United Kingdom VAT number                          |
    | United States        | `us_ein` | United States EIN                                  |
    """
    country: str = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('country') }})
    r"""Two-letter ISO code representing the country of the tax ID"""
    type: str = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('type') }})
    r"""One of `ae_trn`, `au_abn`, `au_arn`, `bg_uic`, `br_cn`, `br_cpf`, `ca_bn`, `ca_gst_hst`, `ca_pst_bc`, `ca_pst_mb`, `ca_pst_sk`, `ca_qst`, `ch_vat`, `cl_tin`, `eg_tin`, `es_cif`, `eu_oss_vat`, `eu_vat`, `gb_vat`, `ge_vat`, `hk_br`, `hu_tin`, `id_npwp`, `il_vat`, `in_gst`, `is_vat`, `jp_cn`, `jp_rn`, `jp_trn`, `ke_pin`, `kr_brn`, `li_uid`, `mx_rfc`, `my_frp`, `my_itn`, `my_sst`, `no_vat`, `nz_gst`, `ph_tin`, `ru_inn`, `ru_kpp`, `sa_vat`, `sg_gst`, `sg_uen`, `si_tin`, `th_vat`, `tr_tin`, `tw_vat`, `ua_vat`, `us_ein`, or `za_va`"""
    value: str = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('value') }})
    r"""The value of the ID"""
    



@dataclass_json(undefined=Undefined.EXCLUDE)

@dataclasses.dataclass
class InvoiceDiscount:
    discount_type: shared_discounttype.DiscountType = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('discount_type') }})
    amount_discount: Optional[str] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('amount_discount'), 'exclude': lambda f: f is None }})
    r"""Only available if discount_type is `amount`."""
    applies_to_price_ids: Optional[list[str]] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('applies_to_price_ids'), 'exclude': lambda f: f is None }})
    r"""List of price_ids that this discount applies to. For plan/plan phase discounts, this can be a subset of prices."""
    percentage_discount: Optional[float] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('percentage_discount'), 'exclude': lambda f: f is None }})
    r"""Only available if discount_type is `percentage`.This is a number between 0 and 1."""
    trial_amount_discount: Optional[str] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('trial_amount_discount'), 'exclude': lambda f: f is None }})
    r"""Only available if discount_type is `trial`"""
    usage_discount: Optional[float] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('usage_discount'), 'exclude': lambda f: f is None }})
    r"""Only available if discount_type is `usage`. Number of usage units that this discount is for"""
    



@dataclass_json(undefined=Undefined.EXCLUDE)

@dataclasses.dataclass
class InvoiceMaximumAmount:
    applies_to_price_ids: list[str] = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('applies_to_price_ids') }})
    r"""List of price_ids that this maximum amount applies to. For plan/plan phase maximums, this can be a subset of prices."""
    maximum_amount: str = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('maximum_amount') }})
    r"""Maximum amount applied"""
    



@dataclass_json(undefined=Undefined.EXCLUDE)

@dataclasses.dataclass
class InvoiceMinimumAmount:
    applies_to_price_ids: list[str] = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('applies_to_price_ids') }})
    r"""List of price_ids that this minimum amount applies to. For plan/plan phase minimums, this can be a subset of prices."""
    minimum_amount: str = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('minimum_amount') }})
    r"""Minimum amount applied"""
    



@dataclass_json(undefined=Undefined.EXCLUDE)

@dataclasses.dataclass
class Invoice:
    r"""An [`Invoice`](../guides/concepts#invoice) is a fundamental billing entity, representing the request for payment for a single subscription. This includes a set of line items, which correspond to prices in the subscription's plan and can represent fixed recurring fees or usage-based fees. They are generated at the end of a billing period, or as the result of an action, such as a cancellation."""
    amount_due: str = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('amount_due') }})
    r"""This is the final amount required to be charged to the customer and reflects the application of the customer balance to the `total` of the invoice."""
    created_at: datetime = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('created_at'), 'encoder': utils.datetimeisoformat(False), 'decoder': dateutil.parser.isoparse }})
    r"""The creation time of the resource in Orb."""
    currency: str = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('currency') }})
    r"""An ISO 4217 currency string or `credits`"""
    customer: shared_customerminified.CustomerMinified = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('customer') }})
    r"""The customer receiving this invoice."""
    customer_balance_transactions: shared_transactions.Transactions = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('customer_balance_transactions') }})
    discount: Optional[InvoiceDiscount] = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('discount') }})
    due_date: datetime = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('due_date'), 'encoder': utils.datetimeisoformat(False), 'decoder': dateutil.parser.isoparse }})
    r"""When the invoice payment is due."""
    id: str = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('id') }})
    invoice_date: datetime = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('invoice_date'), 'encoder': utils.datetimeisoformat(False), 'decoder': dateutil.parser.isoparse }})
    r"""Issue date of the invoice"""
    invoice_number: str = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('invoice_number') }})
    r"""Automatically generated invoice number to help track and reconcile invoices. Invoice numbers have a prefix such as `RFOBWG`. These can be sequential per account or customer."""
    invoice_pdf: str = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('invoice_pdf') }})
    r"""The link to download the PDF representation of the `Invoice`."""
    line_items: list[shared_invoicelineitem.InvoiceLineItem] = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('line_items') }})
    r"""The breakdown of prices in this invoice."""
    minimum: Optional[InvoiceMinimumAmount] = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('minimum') }})
    status: shared_invoicestatus.InvoiceStatus = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('status') }})
    r"""The status of this invoice as known to Orb. Invoices start in `\\"draft\\"` state for a given billing period, and are automatically transitioned to `\\"issued\\"` when that billing period ends. Invoices will be marked `\\"paid\\"` upon confirmation of successful automatic payment collection by Orb. Invoices may be manually voided; those will be in the terminal `\\"void\\"` state. Invoices synced to an external billing provider (such as Bill.com, QuickBooks, or Stripe Invoicing) will be marked as `\\"synced\\"`."""
    subscription: shared_subscriptionminified.SubscriptionMinified = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('subscription') }})
    r"""The associated subscription for this invoice."""
    subtotal: str = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('subtotal') }})
    r"""The total before any discounts and minimums are applied."""
    total: str = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('total') }})
    r"""The total after any minimums, discounts, and taxes have been applied."""
    will_auto_issue: bool = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('will_auto_issue') }})
    r"""This is true if the invoice will be automaticaly issued in the future, and false otherwise."""
    auto_collection: Optional[shared_autocollection.AutoCollection] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('auto_collection'), 'exclude': lambda f: f is None }})
    r"""Information about payment auto-collection for this invoice."""
    credit_notes: Optional[list[shared_creditnotesummary.CreditNoteSummary]] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('credit_notes'), 'exclude': lambda f: f is None }})
    r"""A list of credit notes associated with the invoice"""
    customer_tax_id: Optional[InvoiceCustomerTaxID] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('customer_tax_id') }})
    eligible_for_issue_at: Optional[datetime] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('eligible_for_issue_at'), 'encoder': utils.datetimeisoformat(True), 'decoder': dateutil.parser.isoparse }})
    r"""If the invoice has a status of `draft`, this will be the time that the invoice willl be eligible to be issued, otherwise it will be `null`. If `auto-issue` is true, the invoice will automatically begin issuing at this time."""
    hosted_invoice_url: Optional[str] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('hosted_invoice_url'), 'exclude': lambda f: f is None }})
    r"""A URL for the invoice portal."""
    issue_failed_at: Optional[datetime] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('issue_failed_at'), 'encoder': utils.datetimeisoformat(True), 'decoder': dateutil.parser.isoparse }})
    r"""If the invoice failed to issue, this will be the last time it failed to issue (even if it is now in a different state.)"""
    issued_at: Optional[datetime] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('issued_at'), 'encoder': utils.datetimeisoformat(True), 'decoder': dateutil.parser.isoparse }})
    r"""If the invoice has been issued, this will be the time it transitioned to `issued` (even if it is now in a different state.)"""
    maximum: Optional[InvoiceMaximumAmount] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('maximum') }})
    memo: Optional[str] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('memo'), 'exclude': lambda f: f is None }})
    r"""Free-form text which is available on the invoice PDF and the Orb invoice portal."""
    paid_at: Optional[datetime] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('paid_at'), 'encoder': utils.datetimeisoformat(True), 'decoder': dateutil.parser.isoparse }})
    r"""If the invoice has a status of `paid`, this gives a timestamp when the invoice was paid."""
    payment_failed_at: Optional[datetime] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('payment_failed_at'), 'encoder': utils.datetimeisoformat(True), 'decoder': dateutil.parser.isoparse }})
    r"""If payment was attempted on this invoice but failed, this will be the time of the most recent attempt."""
    payment_started_at: Optional[datetime] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('payment_started_at'), 'encoder': utils.datetimeisoformat(True), 'decoder': dateutil.parser.isoparse }})
    r"""If payment was attempted on this invoice, this will be the start time of the most recent attempt. This field is especially useful for delayed-notification payment mechanisms (like bank transfers), where payment can take 3 days or more."""
    scheduled_issue_at: Optional[datetime] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('scheduled_issue_at'), 'encoder': utils.datetimeisoformat(True), 'decoder': dateutil.parser.isoparse }})
    r"""If the invoice is in draft, this timestamp will reflect when the invoice is scheduled to be issued."""
    sync_failed_at: Optional[datetime] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('sync_failed_at'), 'encoder': utils.datetimeisoformat(True), 'decoder': dateutil.parser.isoparse }})
    r"""If the invoice failed to sync, this will be the last time an external invoicing provider sync was attempted. This field will always be `null` for invoices using Orb Invoicing."""
    voided_at: Optional[datetime] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('voided_at'), 'encoder': utils.datetimeisoformat(True), 'decoder': dateutil.parser.isoparse }})
    r"""If the invoice has a status of `void`, this gives a timestamp when the invoice was voided."""
    

