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

from __future__ import annotations
import dataclasses
import dateutil.parser
from dataclasses_json import Undefined, dataclass_json
from datetime import datetime
from enum import Enum
from orb import utils
from typing import Optional


@dataclass_json(undefined=Undefined.EXCLUDE)

@dataclasses.dataclass
class CustomerBillingAddress:
    r"""The customer's billing address; all fields in the address are optional. This address appears on customer invoices."""
    city: Optional[str] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('city'), 'exclude': lambda f: f is None }})
    country: Optional[str] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('country'), 'exclude': lambda f: f is None }})
    r"""Two-letter country code (ISO 3166-1 alpha-2)."""
    line1: Optional[str] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('line1'), 'exclude': lambda f: f is None }})
    line2: Optional[str] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('line2'), 'exclude': lambda f: f is None }})
    postal_code: Optional[str] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('postal_code'), 'exclude': lambda f: f is None }})
    r"""ZIP or postal code"""
    state: Optional[str] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('state'), 'exclude': lambda f: f is None }})
    




@dataclasses.dataclass
class CustomerMetadata:
    r"""User specified key-value pairs. If there is no metadata for the customer, this defaults to an empty dictionary."""
    


class CustomerPaymentProvider(str, Enum):
    r"""This is used for creating charges or invoices in an external system via Orb. When not in test mode:
    - the connection must first be configured in the Orb webapp. 
    - if the provider is an invoicing provider (`stripe_invoice`, `quickbooks`, `bill.com`), any product mappings must first be configured with the Orb team.
    """
    QUICKBOOKS = 'quickbooks'
    BILL_COM = 'bill.com'
    STRIPE_CHARGE = 'stripe_charge'
    STRIPE_INVOICE = 'stripe_invoice'
    NULL = 'null'


@dataclass_json(undefined=Undefined.EXCLUDE)

@dataclasses.dataclass
class CustomerShippingAddress:
    r"""The customer's shipping address; all fields in the address are optional. Note that downstream tax calculations are based on the shipping address."""
    city: Optional[str] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('city'), 'exclude': lambda f: f is None }})
    country: Optional[str] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('country'), 'exclude': lambda f: f is None }})
    r"""Two-letter country code (ISO 3166-1 alpha-2)."""
    line1: Optional[str] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('line1'), 'exclude': lambda f: f is None }})
    line2: Optional[str] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('line2'), 'exclude': lambda f: f is None }})
    postal_code: Optional[str] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('postal_code'), 'exclude': lambda f: f is None }})
    r"""ZIP or postal code"""
    state: Optional[str] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('state'), 'exclude': lambda f: f is None }})
    



@dataclass_json(undefined=Undefined.EXCLUDE)

@dataclasses.dataclass
class CustomerCustomerTaxID:
    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 Customer:
    r"""A customer is a buyer of your products, and the other party to the billing relationship.

    In Orb, customers are assigned system generated identifiers automatically, but it's often desirable to have these match existing identifiers in your system. To avoid having to denormalize Orb ID information, you can pass in an `external_customer_id` with your own identifier. See [Customer ID Aliases](../guides/events-and-metrics/customer-aliases) for further information about how these aliases work in Orb.

    In addition to having an identifier in your system, a customer may exist in a payment provider solution like Stripe. Use the `payment_provider_id` and the `payment_provider` enum field to express this mapping.

    A customer also has a timezone (from the standard [IANA timezone database](https://www.iana.org/time-zones)), which defaults to your account's timezone. See [Timezone localization](../guides/product-catalog/timezones.md) for information on what this timezone parameter influences within Orb.
    """
    balance: str = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('balance') }})
    r"""The customer's current balance in their currency."""
    created_at: datetime = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('created_at'), 'encoder': utils.datetimeisoformat(False), 'decoder': dateutil.parser.isoparse }})
    currency: str = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('currency') }})
    r"""An ISO 4217 currency string used for the customer's invoices and balance."""
    email: str = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('email') }})
    r"""A valid customer email, to be used for notifications. When Orb triggers payment through a payment gateway, this email will be used for any automatically issued receipts."""
    id: str = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('id') }})
    r"""The full name of the customer"""
    metadata: CustomerMetadata = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('metadata') }})
    r"""User specified key-value pairs. If there is no metadata for the customer, this defaults to an empty dictionary."""
    name: str = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('name') }})
    payment_provider: CustomerPaymentProvider = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('payment_provider') }})
    r"""This is used for creating charges or invoices in an external system via Orb. When not in test mode:
    - the connection must first be configured in the Orb webapp. 
    - if the provider is an invoicing provider (`stripe_invoice`, `quickbooks`, `bill.com`), any product mappings must first be configured with the Orb team.
    """
    payment_provider_id: str = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('payment_provider_id') }})
    r"""The ID of this customer in an external payments solution, such as Stripe. This is used for creating charges or invoices in the external system via Orb."""
    tax_id: CustomerCustomerTaxID = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('tax_id') }})
    timezone: str = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('timezone') }})
    r"""A timezone identifier from the IANA timezone database, such as \\"America/Los_Angeles\\". This defaults to your account's timezone if not set. This cannot be changed after customer creation."""
    auto_collection: Optional[bool] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('auto_collection'), 'exclude': lambda f: f is None }})
    r"""Determines whether Orb attempts to automatically collect payment for issued invoices from the saved payment method.  Note that if payment provider is set, auto collection will be turned on unless explicitly updated."""
    billing_address: Optional[CustomerBillingAddress] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('billing_address'), 'exclude': lambda f: f is None }})
    email_delivery: Optional[bool] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('email_delivery'), 'exclude': lambda f: f is None }})
    r"""Determines whether Orb will send automated emails to this customer. This setting is superseded by the account-wide email setting for email delivery."""
    external_customer_id: Optional[str] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('external_customer_id'), 'exclude': lambda f: f is None }})
    r"""An optional user-defined ID for this customer resource, used throughout the system as an alias for this Customer. Use this field to identify a customer by an existing identifier in your system."""
    portal_url: Optional[str] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('portal_url'), 'exclude': lambda f: f is None }})
    r"""A link for the customer portal, meant to be sent to your customers. By default, this link does not expire."""
    shipping_address: Optional[CustomerShippingAddress] = dataclasses.field(default=None, metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('shipping_address'), 'exclude': lambda f: f is None }})
    

