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

from __future__ import annotations
import dataclasses
import dateutil.parser
from ..shared import amountdiscountinterval as shared_amountdiscountinterval
from ..shared import couponredemption as shared_couponredemption
from ..shared import customer as shared_customer
from ..shared import fixedfeequantityscheduleentry as shared_fixedfeequantityscheduleentry
from ..shared import maximuminterval as shared_maximuminterval
from ..shared import minimuminterval as shared_minimuminterval
from ..shared import percentagediscountinterval as shared_percentagediscountinterval
from ..shared import plan as shared_plan
from ..shared import priceinterval as shared_priceinterval
from ..shared import subscriptiontrialinfo as shared_subscriptiontrialinfo
from ..shared import usagediscountinterval as shared_usagediscountinterval
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 SubscriptionDiscountIntervals:
    pass



@dataclasses.dataclass
class SubscriptionMetadata:
    r"""User specified key-value pairs. If no metadata was specified at subscription creation time, this defaults to an empty dictionary."""
    


class SubscriptionStatus(str, Enum):
    ACTIVE = 'active'
    ENDED = 'ended'
    UPCOMING = 'upcoming'


@dataclass_json(undefined=Undefined.EXCLUDE)

@dataclasses.dataclass
class Subscription:
    r"""A [subscription](../guides/core-concepts.mdx#subscription) represents the purchase of a plan by a customer.

    By default, subscriptions begin on the day that they're created and renew automatically for each billing cycle at
    the cadence that's configured in the plan definition.

    Subscriptions also default to **beginning of month alignment**, which means the first invoice issued for the
    subscription will have pro-rated charges between the `start_date` and the first of the following month. Subsequent
    billing periods will always start and end on a month boundary (e.g. subsequent month starts for monthly billing).

    Depending on the plan configuration, any _flat_ recurring fees will be billed either at the beginning (in-advance)
    or end (in-arrears) of each billing cycle. Plans default to **in-advance billing**. Usage-based fees are billed in
    arrears as usage is accumulated. In the normal course of events, you can expect an invoice to contain usage-based
    charges for the previous period, and a recurring fee for the following period.
    """
    active_plan_phase_order: Optional[int] = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('active_plan_phase_order') }})
    r"""The current plan phase that is active, only if the subscription's plan has phases."""
    auto_collection: Optional[bool] = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('auto_collection') }})
    r"""Determines whether issued invoices for this subscription will automatically be charged with the saved payment method on the due date. This property defaults to the plan's behavior."""
    billing_cycle_day: int = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('billing_cycle_day') }})
    r"""The day of the month on which the billing cycle is anchored. If the maximum number of days in a month is greater than this value, the last day of the month is the billing cycle day (e.g. billing_cycle_day=31 for April means the billing period begins on the 30th."""
    created_at: datetime = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('created_at'), 'encoder': utils.datetimeisoformat(False), 'decoder': dateutil.parser.isoparse }})
    current_billing_period_end_date: Optional[datetime] = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('current_billing_period_end_date'), 'encoder': utils.datetimeisoformat(False), 'decoder': dateutil.parser.isoparse }})
    r"""The end of the current billing period. This is an exclusive timestamp, such that the instant returned is not part of the billing period. Set to null for subscriptions that are not currently active."""
    current_billing_period_start_date: Optional[datetime] = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('current_billing_period_start_date'), 'encoder': utils.datetimeisoformat(False), 'decoder': dateutil.parser.isoparse }})
    r"""The start date of the current billing period. This is an inclusive timestamp; the instant returned is exactly the beginning of the billing period. Set to null if the subscription is not currently active."""
    customer: shared_customer.Customer = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('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.
    """
    default_invoice_memo: Optional[str] = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('default_invoice_memo') }})
    r"""Determines the default memo on this subscriptions' invoices. Note that if this is not provided, it is determined by the plan configuration."""
    discount_intervals: list[Union[shared_amountdiscountinterval.AmountDiscountInterval, shared_percentagediscountinterval.PercentageDiscountInterval, shared_usagediscountinterval.UsageDiscountInterval]] = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('discount_intervals') }})
    r"""The discount intervals for this subscription."""
    end_date: Optional[datetime] = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('end_date'), 'encoder': utils.datetimeisoformat(False), 'decoder': dateutil.parser.isoparse }})
    r"""The date Orb stops billing for this subscription."""
    fixed_fee_quantity_schedule: list[shared_fixedfeequantityscheduleentry.FixedFeeQuantityScheduleEntry] = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('fixed_fee_quantity_schedule') }})
    id: str = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('id') }})
    invoicing_threshold: Optional[str] = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('invoicing_threshold') }})
    maximum_intervals: list[shared_maximuminterval.MaximumInterval] = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('maximum_intervals') }})
    r"""The maximum intervals for this subscription."""
    metadata: SubscriptionMetadata = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('metadata') }})
    r"""User specified key-value pairs. If no metadata was specified at subscription creation time, this defaults to an empty dictionary."""
    minimum_intervals: list[shared_minimuminterval.MinimumInterval] = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('minimum_intervals') }})
    r"""The minimum intervals for this subscription."""
    net_terms: int = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('net_terms') }})
    r"""Determines the difference between the invoice issue date for subscription invoices as the date that they are due. A value of `0` here represents that the invoice is due on issue, whereas a value of `30` represents that the customer has a month to pay the invoice."""
    plan: shared_plan.Plan = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('plan') }})
    r"""The [Plan](../guides/core-concepts.mdx#plan-and-price) resource represents a plan that can be subscribed to by a
    customer. Plans define the billing behavior of the subscription. You can see more about how to configure prices
    in the [Price resource](/reference/price).
    """
    price_intervals: list[shared_priceinterval.PriceInterval] = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('price_intervals') }})
    r"""The price intervals for this subscription."""
    redeemed_coupon: Optional[shared_couponredemption.CouponRedemption] = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('redeemed_coupon') }})
    start_date: datetime = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('start_date'), 'encoder': utils.datetimeisoformat(False), 'decoder': dateutil.parser.isoparse }})
    r"""The date Orb starts billing for this subscription."""
    status: SubscriptionStatus = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('status') }})
    trial_info: shared_subscriptiontrialinfo.SubscriptionTrialInfo = dataclasses.field(metadata={'dataclasses_json': { 'letter_case': utils.get_field_name('trial_info') }})
    

