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

from __future__ import annotations
import dataclasses
import dateutil.parser
from ..shared import address as shared_address
from ..shared import amountdiscount as shared_amountdiscount
from ..shared import autocollection as shared_autocollection
from ..shared import creditnotesummary as shared_creditnotesummary
from ..shared import customerbalancetransaction as shared_customerbalancetransaction
from ..shared import customerminified as shared_customerminified
from ..shared import customertaxid as shared_customertaxid
from ..shared import invoicelineitem as shared_invoicelineitem
from ..shared import maximum as shared_maximum
from ..shared import minimum as shared_minimum
from ..shared import percentagediscount as shared_percentagediscount
from ..shared import subscriptionminified as shared_subscriptionminified
from ..shared import trialdiscount as shared_trialdiscount
from ..shared import usagediscount as shared_usagediscount
from dataclasses_json import Undefined, dataclass_json
from datetime import datetime
from enum import Enum
from orb import utils
from typing import Optional, Union



@dataclasses.dataclass
class InvoiceDiscount:
    pass



@dataclasses.dataclass
class InvoiceDiscounts:
    pass



@dataclasses.dataclass
class InvoiceMetadata:
    pass

class InvoiceStatus(str, Enum):
    ISSUED = 'issued'
    PAID = 'paid'
    SYNCED = 'synced'
    VOID = 'void'
    DRAFT = 'draft'


@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."""
    auto_collection: shared_autocollection.AutoCollection = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('auto_collection') }})
    billing_address: Optional[shared_address.Address] = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('billing_address') }})
    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."""
    credit_notes: list[shared_creditnotesummary.CreditNoteSummary] = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('credit_notes') }})
    r"""A list of credit notes associated with the invoice"""
    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') }})
    customer_balance_transactions: list[shared_customerbalancetransaction.CustomerBalanceTransaction] = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('customer_balance_transactions') }})
    customer_tax_id: Optional[shared_customertaxid.CustomerTaxID] = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('customer_tax_id') }})
    discount: Optional[Union[shared_percentagediscount.PercentageDiscount, shared_trialdiscount.TrialDiscount, shared_usagediscount.UsageDiscount, shared_amountdiscount.AmountDiscount]] = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('discount') }})
    discounts: list[Union[shared_percentagediscount.PercentageDiscount, shared_trialdiscount.TrialDiscount, shared_usagediscount.UsageDiscount, shared_amountdiscount.AmountDiscount]] = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('discounts') }})
    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."""
    eligible_to_issue_at: Optional[datetime] = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('eligible_to_issue_at'), 'encoder': utils.datetimeisoformat(False), 'decoder': dateutil.parser.isoparse }})
    r"""If the invoice has a status of `draft`, this will be the time that the invoice will 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(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('hosted_invoice_url') }})
    r"""A URL for the invoice portal."""
    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"""The scheduled 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: Optional[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`."""
    issue_failed_at: Optional[datetime] = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('issue_failed_at'), 'encoder': utils.datetimeisoformat(False), '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(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('issued_at'), 'encoder': utils.datetimeisoformat(False), '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.)"""
    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."""
    maximum: Optional[shared_maximum.Maximum] = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('maximum') }})
    maximum_amount: Optional[str] = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('maximum_amount') }})
    memo: Optional[str] = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('memo') }})
    r"""Free-form text which is available on the invoice PDF and the Orb invoice portal."""
    metadata: InvoiceMetadata = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('metadata') }})
    minimum: Optional[shared_minimum.Minimum] = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('minimum') }})
    minimum_amount: Optional[str] = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('minimum_amount') }})
    paid_at: Optional[datetime] = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('paid_at'), 'encoder': utils.datetimeisoformat(False), '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(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('payment_failed_at'), 'encoder': utils.datetimeisoformat(False), '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(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('payment_started_at'), 'encoder': utils.datetimeisoformat(False), '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(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('scheduled_issue_at'), 'encoder': utils.datetimeisoformat(False), 'decoder': dateutil.parser.isoparse }})
    r"""If the invoice is in draft, this timestamp will reflect when the invoice is scheduled to be issued."""
    shipping_address: Optional[shared_address.Address] = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('shipping_address') }})
    status: InvoiceStatus = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('status') }})
    subscription: Optional[shared_subscriptionminified.SubscriptionMinified] = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('subscription') }})
    subtotal: str = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('subtotal') }})
    r"""The total before any discounts and minimums are applied."""
    sync_failed_at: Optional[datetime] = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('sync_failed_at'), 'encoder': utils.datetimeisoformat(False), '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."""
    total: str = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('total') }})
    r"""The total after any minimums and discounts have been applied."""
    voided_at: Optional[datetime] = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('voided_at'), 'encoder': utils.datetimeisoformat(False), 'decoder': dateutil.parser.isoparse }})
    r"""If the invoice has a status of `void`, this gives a timestamp when the invoice was voided."""
    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 automatically issued in the future, and false otherwise."""
    

