# generated by datamodel-codegen:
#   filename:  https://raw.githubusercontent.com/uselotus/lotus/main/docs/openapi.yaml
#   timestamp: 2023-01-20T06:15:06+00:00

from __future__ import annotations

from datetime import date, datetime
from enum import Enum
from typing import Any, Dict, List, Optional
from uuid import UUID

from pydantic import AnyUrl, BaseModel, EmailStr, Field, confloat, conint, constr


class APIToken(BaseModel):
    name: Optional[constr(max_length=50)] = Field(
        None,
        description='A free-form name for the API key. Need not be unique. 50 characters max.',
    )
    prefix: str
    expiry_date: Optional[datetime] = Field(
        None,
        description='Once API key expires, clients cannot use it anymore.',
        title='Expires',
    )
    created: datetime


class APITokenCreateResponse(BaseModel):
    api_key: APIToken
    key: str


class APITokenRequest(BaseModel):
    name: Optional[constr(min_length=1, max_length=50)] = Field(
        None,
        description='A free-form name for the API key. Need not be unique. 50 characters max.',
    )
    expiry_date: Optional[datetime] = Field(
        None,
        description='Once API key expires, clients cannot use it anymore.',
        title='Expires',
    )


class APITokenRollResponse(BaseModel):
    api_key: APIToken
    key: str


class Action(BaseModel):
    id: int
    actor: str
    verb: constr(max_length=255)
    action_object: str
    target: str
    public: Optional[bool] = None
    description: Optional[str] = None
    timestamp: Optional[datetime] = None


class Address(BaseModel):
    city: str = Field(..., description='City, district, suburb, town, or village')
    country: constr(min_length=2, max_length=2) = Field(
        ..., description='ISO 3166-1 alpha-2 country code'
    )
    line1: str = Field(
        ..., description='Address line 1 (e.g., street, PO Box, or company name)'
    )
    line2: Optional[str] = Field(
        None, description='Address line 2 (e.g., apartment, suite, unit, or building)'
    )
    postal_code: str = Field(..., description='ZIP or postal code')
    state: str = Field(..., description='State, county, province, or region')


class AddressRequest(BaseModel):
    city: constr(min_length=1) = Field(
        ..., description='City, district, suburb, town, or village'
    )
    country: constr(min_length=2, max_length=2) = Field(
        ..., description='ISO 3166-1 alpha-2 country code'
    )
    line1: constr(min_length=1) = Field(
        ..., description='Address line 1 (e.g., street, PO Box, or company name)'
    )
    line2: Optional[str] = Field(
        None, description='Address line 2 (e.g., apartment, suite, unit, or building)'
    )
    postal_code: constr(min_length=1) = Field(..., description='ZIP or postal code')
    state: constr(min_length=1) = Field(
        ..., description='State, county, province, or region'
    )


class Kpi(Enum):
    total_revenue = 'total_revenue'


class BacktestCreate(BaseModel):
    start_date: date
    end_date: date
    kpis: List[Kpi]
    backtest_name: constr(max_length=100)


class Kpi1(Enum):
    total_revenue = 'total_revenue'


class Status(Enum):
    running = 'running'
    completed = 'completed'
    failed = 'failed'


class BacktestSubstitutionMulti(BaseModel):
    new_plan: UUID
    original_plans: List[UUID]


class BacktestSubstitutionMultiRequest(BaseModel):
    new_plan: UUID
    original_plans: List[UUID]


class Status1(Enum):
    running = 'running'
    completed = 'completed'
    failed = 'failed'


class BacktestSummary(BaseModel):
    backtest_name: constr(max_length=100)
    start_date: date
    end_date: date
    time_created: Optional[datetime] = None
    kpis: Optional[Dict[str, Any]] = None
    status: Optional[Status1] = None
    backtest_id: str


class Operator(Enum):
    isin = 'isin'
    isnotin = 'isnotin'


class CategoricalFilter(BaseModel):
    property_name: constr(max_length=100)
    operator: Operator
    comparison_value: List[str]


class Operator1(Enum):
    isin = 'isin'
    isnotin = 'isnotin'


class CategoricalFilterRequest(BaseModel):
    property_name: constr(min_length=1, max_length=100)
    operator: Operator1
    comparison_value: List[constr(min_length=1)]


class ChangeUserOrganizationRequestRequest(BaseModel):
    transfer_to_organization_id: constr(min_length=1) = Field(
        ..., description='The organization ID to transfer to'
    )


class ComponentUsage(BaseModel):
    event_name: str = Field(
        ..., description='The name of the event you are checking access for.'
    )
    metric_name: str = Field(..., description='The name of the metric.')
    metric_id: str = Field(
        ...,
        description="The metric_id of the metric. This metric_id can be found in the Lotus frontend if you haven't seen it before.",
    )
    metric_usage: float = Field(
        ...,
        description='The current usage of the metric. Keep in mind the current usage of the metric can be different from the billable usage of the metric.',
    )
    metric_free_limit: Optional[float] = Field(
        ...,
        description='If you specified a free tier of usage for this metric, this is the amount of usage that is free. Will be null if you did not specify a free tier for this metric.',
    )
    metric_total_limit: Optional[float] = Field(
        ...,
        description='The total limit of the metric. Will be null if you did not specify a limit for this metric.',
    )


class Status2(Enum):
    success = 'success'


class ConfirmIdemsReceived(BaseModel):
    status: Status2
    ids_not_found: List[str]


class Status3(Enum):
    failure = 'failure'


class ConfirmIdemsReceivedFailure(BaseModel):
    status: Status3
    error: str


class ConfirmIdemsReceivedRequestRequest(BaseModel):
    idempotency_ids: List[constr(min_length=1)]
    number_days_lookback: int = 30
    customer_id: Optional[constr(min_length=1)] = None


class CreditDrawdown(BaseModel):
    credit_id: str
    amount: confloat(le=0.0, gt=-10000000000.0)
    description: Optional[str] = None
    applied_at: datetime


class PaymentProviderEnum(Enum):
    stripe = 'stripe'


class PaymentProvider(BaseModel):
    __root__: Optional[PaymentProviderEnum] = None


class Status4(Enum):
    active = 'active'
    inactive = 'inactive'


class CustomerBalanceAdjustmentCreateRequest(BaseModel):
    customer_id: constr(min_length=1) = Field(
        ...,
        description='The id provided when creating the customer, we suggest matching with your internal customer id in your backend',
    )
    amount: confloat(lt=10000000000.0, gt=-10000000000.0)
    currency_code: constr(min_length=1)
    description: Optional[str] = None
    effective_at: Optional[datetime] = None
    expires_at: Optional[datetime] = None
    amount_paid: Optional[confloat(ge=0.0, lt=10000000000.0)] = None
    amount_paid_currency_code: Optional[constr(min_length=1)] = None


class CustomerBalanceAdjustmentUpdateRequest(BaseModel):
    description: Optional[str] = None
    expires_at: Optional[datetime] = None


class PaymentProvider1(Enum):
    stripe = 'stripe'


class CustomerCreateRequest(BaseModel):
    customer_name: Optional[constr(max_length=100)] = Field(
        None, description='The display name of the customer'
    )
    customer_id: constr(regex=r'^[-a-zA-Z0-9_]+$', min_length=1, max_length=50) = Field(
        ...,
        description='The id provided when creating the customer, we suggest matching with your internal customer id in your backend',
    )
    email: EmailStr = Field(
        ...,
        description='The primary email address of the customer, must be the same as the email address used to create the customer in the payment provider',
    )
    payment_provider: Optional[PaymentProvider1] = Field(
        None,
        description='The payment provider this customer is associated with. Currently, only Stripe is supported.',
    )
    payment_provider_id: Optional[constr(min_length=1)] = Field(
        None,
        description="The customer's ID in the specified payment provider. Please note that payment_provider and payment_provider_id are mutually necessary.",
    )
    properties: Optional[Dict[str, Any]] = Field(
        None, description='Extra metadata for the customer'
    )
    default_currency_code: Optional[constr(min_length=1)] = Field(
        None,
        description="The currency code this customer will be invoiced in. Codes are 3 letters, e.g. 'USD'.",
    )
    address: Optional[AddressRequest] = None
    tax_rate: Optional[confloat(ge=0.0, le=999.9999)] = Field(
        None, description='Tax rate as percentage. For example, 10.5 for 10.5%'
    )


class CustomerStripeIntegration(BaseModel):
    stripe_id: str
    has_payment_method: bool


class CustomerUpdate(BaseModel):
    default_currency_code: str
    address: Optional[Address] = None
    tax_rate: Optional[confloat(ge=0.0, le=999.9999)] = Field(
        None, description='Tax rate as percentage. For example, 10.5 for 10.5%'
    )


class CustomerWithRevenue(BaseModel):
    customer_id: Optional[constr(regex=r'^[-a-zA-Z0-9_]+$', max_length=50)] = Field(
        None,
        description='The id provided when creating the customer, we suggest matching with your internal customer id in your backend',
    )
    total_amount_due: float


class DayMetricUsage(BaseModel):
    date: date
    customer_usages: Dict[str, confloat(lt=10000000000.0, gt=-10000000000.0)]


class DemoRegistrationDetailRequest(BaseModel):
    email: constr(min_length=1)
    password: constr(min_length=1)
    username: constr(min_length=1)


class DemoRegistrationFailure(BaseModel):
    detail: str


class DemoRegistrationRequest(BaseModel):
    register_: DemoRegistrationDetailRequest = Field(..., alias='register')


class EmailRequest(BaseModel):
    email: EmailStr


class Event(BaseModel):
    event_name: constr(max_length=100) = Field(
        ...,
        description='String name of the event, corresponds to definition in metrics',
    )
    properties: Optional[Dict[str, Any]] = Field(
        None,
        description='Extra metadata on the event that can be filtered and queried on in the metrics. All key value pairs should have string keys and values can be either strings or numbers. Place subscription filters in this object to specify which subscription the event should be tracked under',
    )
    time_created: datetime = Field(
        ...,
        description='The time that the event occured, represented as a datetime in ISO 8601 in the UTC timezome.',
    )
    idempotency_id: str = Field(
        ...,
        description='A unique identifier for the specific event being passed in. Passing in a unique id allows Lotus to make sure no double counting occurs. We recommend using a UUID4. You can use the same idempotency_id again after 7 days',
    )
    customer_id: str = Field(
        ...,
        description='The id of the customer that this event is associated with, usually the customer id in your backend',
    )


class EventRequest(BaseModel):
    event_name: constr(min_length=1, max_length=100) = Field(
        ...,
        description='String name of the event, corresponds to definition in metrics',
    )
    properties: Optional[Dict[str, Any]] = Field(
        None,
        description='Extra metadata on the event that can be filtered and queried on in the metrics. All key value pairs should have string keys and values can be either strings or numbers. Place subscription filters in this object to specify which subscription the event should be tracked under',
    )
    time_created: datetime = Field(
        ...,
        description='The time that the event occured, represented as a datetime in ISO 8601 in the UTC timezome.',
    )
    idempotency_id: constr(min_length=1) = Field(
        ...,
        description='A unique identifier for the specific event being passed in. Passing in a unique id allows Lotus to make sure no double counting occurs. We recommend using a UUID4. You can use the same idempotency_id again after 7 days',
    )
    customer_id: constr(min_length=1) = Field(
        ...,
        description='The id of the customer that this event is associated with, usually the customer id in your backend',
    )


class Source(Enum):
    stripe = 'stripe'


class ExternalPlanLink(BaseModel):
    source: Source
    external_plan_id: constr(max_length=100)


class Source1(Enum):
    stripe = 'stripe'


class ExternalPlanLinkRequest(BaseModel):
    plan_id: UUID
    source: Source1
    external_plan_id: constr(min_length=1, max_length=100)


class Feature(BaseModel):
    feature_name: constr(max_length=50)
    feature_description: Optional[str] = Field(...)


class FeatureRequest(BaseModel):
    feature_name: constr(min_length=1, max_length=50)
    feature_description: Optional[str] = Field(...)


class Status5(Enum):
    error = 'error'


class ImportCustomerFailure(BaseModel):
    status: Status5
    detail: str


class Status6(Enum):
    success = 'success'


class ImportCustomerSuccess(BaseModel):
    status: Status6
    detail: str


class Source2(Enum):
    stripe = 'stripe'


class ImportCustomersRequestRequest(BaseModel):
    source: Source2


class Status7(Enum):
    error = 'error'


class ImportPaymentObjectFailure(BaseModel):
    status: Status7
    detail: str


class Status8(Enum):
    success = 'success'


class ImportPaymentObjectSuccess(BaseModel):
    status: Status8
    detail: str


class Source3(Enum):
    stripe = 'stripe'


class ImportPaymentObjectsRequestRequest(BaseModel):
    source: Source3


class InitResetPasswordSuccess(BaseModel):
    email: str


class Source4(Enum):
    stripe = 'stripe'


class InitialExternalPlanLink(BaseModel):
    source: Source4
    external_plan_id: constr(max_length=100)


class Source5(Enum):
    stripe = 'stripe'


class InitialExternalPlanLinkRequest(BaseModel):
    source: Source5
    external_plan_id: constr(min_length=1, max_length=100)


class UsageBillingFrequencyEnum(Enum):
    monthly = 'monthly'
    quarterly = 'quarterly'
    end_of_period = 'end_of_period'
    field_ = ''


class UsageBillingFrequency(BaseModel):
    __root__: Optional[UsageBillingFrequencyEnum] = None


class FlatFeeBillingType(Enum):
    in_arrears = 'in_arrears'
    in_advance = 'in_advance'


class InviteRequestRequest(BaseModel):
    email: EmailStr


class InviteResponse(BaseModel):
    email: EmailStr


class PaymentStatus(Enum):
    paid = 'paid'
    unpaid = 'unpaid'


class ExternalPaymentObjTypeEnum(Enum):
    stripe = 'stripe'


class ExternalPaymentObjType(BaseModel):
    __root__: Optional[ExternalPaymentObjTypeEnum] = None


class BillingTypeEnum(Enum):
    in_arrears = 'in_arrears'
    in_advance = 'in_advance'


class BillingType(BaseModel):
    __root__: Optional[BillingTypeEnum] = None


class BillingType1Enum(Enum):
    in_arrears = 'in_arrears'
    in_advance = 'in_advance'


class BillingType1(BaseModel):
    __root__: Optional[BillingType1Enum] = None


class InvoiceLineItemRequest(BaseModel):
    name: constr(min_length=1, max_length=100)
    start_date: datetime
    end_date: datetime
    quantity: Optional[confloat(ge=0.0, lt=10000000000.0)] = Field(...)
    subtotal: confloat(lt=10000000000.0, gt=-10000000000.0)
    billing_type: Optional[BillingType1] = Field(...)
    metadata: Optional[Dict[str, Any]] = Field(...)


class ExternalPaymentObjType1Enum(Enum):
    stripe = 'stripe'


class ExternalPaymentObjType1(BaseModel):
    __root__: Optional[ExternalPaymentObjType1Enum] = None


class PaymentStatus1(Enum):
    paid = 'paid'
    unpaid = 'unpaid'


class InvoiceUpdate(BaseModel):
    payment_status: PaymentStatus1


class LightweightCustomer(BaseModel):
    customer_name: Optional[str] = Field(
        ..., description='The display name of the customer'
    )
    email: Optional[EmailStr] = Field(
        ...,
        description='The primary email address of the customer, must be the same as the email address used to create the customer in the payment provider',
    )
    customer_id: constr(regex=r'^[-a-zA-Z0-9_]+$') = Field(
        ...,
        description='The id provided when creating the customer, we suggest matching with your internal customer id in your backend',
    )


class LightweightCustomerSerializerForInvoice(BaseModel):
    customer_name: Optional[str] = Field(
        ..., description='The display name of the customer'
    )
    email: Optional[EmailStr] = Field(
        ...,
        description='The primary email address of the customer, must be the same as the email address used to create the customer in the payment provider',
    )
    customer_id: constr(regex=r'^[-a-zA-Z0-9_]+$') = Field(
        ...,
        description='The id provided when creating the customer, we suggest matching with your internal customer id in your backend',
    )
    address: Optional[Address] = None


class PaymentStatus2(Enum):
    paid = 'paid'
    unpaid = 'unpaid'


class ExternalPaymentObjType2Enum(Enum):
    stripe = 'stripe'


class ExternalPaymentObjType2(BaseModel):
    __root__: Optional[ExternalPaymentObjType2Enum] = None


class BillingType2Enum(Enum):
    in_arrears = 'in_arrears'
    in_advance = 'in_advance'


class BillingType2(BaseModel):
    __root__: Optional[BillingType2Enum] = None


class OrganizationType(Enum):
    Production = 'Production'
    Development = 'Development'
    Demo = 'Demo'
    Internal_Demo = 'Internal Demo'


class LightweightOrganization(BaseModel):
    organization_id: str
    organization_name: constr(max_length=100)
    organization_type: OrganizationType
    current: bool


class LightweightPlanVersion(BaseModel):
    plan_name: str
    plan_id: str
    version: int


class LightweightPlanVersionRequest(BaseModel):
    plan_name: constr(min_length=1)
    plan_id: constr(min_length=1)


class LightweightSubscriptionRecordRequest(BaseModel):
    is_new: bool = Field(
        ...,
        description='Whether this subscription came from a renewal or from a first-time. Defaults to true on creation.',
    )
    start_date: datetime = Field(
        ...,
        description='The time the subscription starts. This will be a string in yyyy-mm-dd HH:mm:ss format in UTC time.',
    )
    fully_billed: bool = Field(
        ..., description='Whether the subscription has been fully billed and finalized.'
    )
    auto_renew: bool = Field(
        ...,
        description='Whether the subscription automatically renews. Defaults to true.',
    )
    billing_plan: LightweightPlanVersionRequest
    end_date: datetime = Field(
        ...,
        description='The time the subscription starts. This will be a string in yyyy-mm-dd HH:mm:ss format in UTC time.',
    )


class LightweightUser(BaseModel):
    username: constr(regex=r'^[\w.@+-]+$', max_length=150) = Field(
        ...,
        description='Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.',
    )
    email: EmailStr


class LoginFailure(BaseModel):
    detail: str


class LoginRequestRequest(BaseModel):
    username: constr(min_length=1)
    password: constr(min_length=1)


class LogoutFailure(BaseModel):
    detail: str


class LogoutSuccess(BaseModel):
    detail: str


class GranularityEnum(Enum):
    seconds = 'seconds'
    minutes = 'minutes'
    hours = 'hours'
    days = 'days'
    months = 'months'
    quarters = 'quarters'
    years = 'years'
    total = 'total'


class Granularity(BaseModel):
    __root__: Optional[GranularityEnum] = Field(
        None,
        description="The granularity of the metric. Only applies to metrics of type 'gauge' or 'rate'.",
    )


class EventTypeEnum(Enum):
    delta = 'delta'
    total = 'total'


class EventType(BaseModel):
    __root__: Optional[EventTypeEnum] = Field(
        None,
        description="Used only for metrics of type 'gauge'. Please refer to our documentation for an explanation of the different types.",
    )


class MetricType(Enum):
    counter = 'counter'
    rate = 'rate'
    custom = 'custom'
    gauge = 'gauge'


class ProrationEnum(Enum):
    seconds = 'seconds'
    minutes = 'minutes'
    hours = 'hours'
    days = 'days'
    months = 'months'
    quarters = 'quarters'
    years = 'years'
    total = 'total'


class Proration(BaseModel):
    __root__: Optional[ProrationEnum] = Field(
        None,
        description="The proration of the metric. Only applies to metrics of type 'gauge'.",
    )


class UsageAggregationTypeEnum(Enum):
    count = 'count'
    sum = 'sum'
    max = 'max'
    unique = 'unique'
    latest = 'latest'
    average = 'average'


class UsageAggregationType(BaseModel):
    __root__: Optional[UsageAggregationTypeEnum] = Field(
        None,
        description='The type of aggregation that should be used for this metric. Please refer to our documentation for an explanation of the different types.',
    )


class BillableAggregationTypeEnum(Enum):
    count = 'count'
    sum = 'sum'
    max = 'max'
    unique = 'unique'
    latest = 'latest'
    average = 'average'


class BillableAggregationType(BaseModel):
    __root__: Optional[BillableAggregationTypeEnum] = None


class Granularity1Enum(Enum):
    seconds = 'seconds'
    minutes = 'minutes'
    hours = 'hours'
    days = 'days'
    months = 'months'
    quarters = 'quarters'
    years = 'years'
    total = 'total'


class Granularity1(BaseModel):
    __root__: Optional[Granularity1Enum] = Field(
        None,
        description="The granularity of the metric. Only applies to metrics of type 'gauge' or 'rate'.",
    )


class EventType1Enum(Enum):
    delta = 'delta'
    total = 'total'


class EventType1(BaseModel):
    __root__: Optional[EventType1Enum] = Field(
        None,
        description="Used only for metrics of type 'gauge'. Please refer to our documentation for an explanation of the different types.",
    )


class MetricType1(Enum):
    counter = 'counter'
    rate = 'rate'
    custom = 'custom'
    gauge = 'gauge'


class Proration1Enum(Enum):
    seconds = 'seconds'
    minutes = 'minutes'
    hours = 'hours'
    days = 'days'
    months = 'months'
    quarters = 'quarters'
    years = 'years'
    total = 'total'


class Proration1(BaseModel):
    __root__: Optional[Proration1Enum] = Field(
        None,
        description="The proration of the metric. Only applies to metrics of type 'gauge'.",
    )


class MetricRevenue(BaseModel):
    metric_name: str
    original_plan_revenue: float
    new_plan_revenue: float


class Status9(Enum):
    active = 'active'
    archived = 'archived'


class MetricUpdate(BaseModel):
    billable_metric_name: Optional[constr(max_length=50)] = None
    status: Optional[Status9] = None


class Operator2(Enum):
    gte = 'gte'
    gt = 'gt'
    eq = 'eq'
    lt = 'lt'
    lte = 'lte'


class NumericFilter(BaseModel):
    property_name: constr(max_length=100)
    operator: Operator2
    comparison_value: float


class Operator3(Enum):
    gte = 'gte'
    gt = 'gt'
    eq = 'eq'
    lt = 'lt'
    lte = 'lte'


class NumericFilterRequest(BaseModel):
    property_name: constr(min_length=1, max_length=100)
    operator: Operator3
    comparison_value: float


class OrganizationType1(Enum):
    development = 'development'
    production = 'production'


class OrganizationCreateRequest(BaseModel):
    organization_name: constr(min_length=1, max_length=100)
    default_currency_code: Optional[constr(min_length=1)] = None
    organization_type: OrganizationType1 = 'development'


class SettingName(Enum):
    generate_customer_after_creating_in_lotus = (
        'generate_customer_after_creating_in_lotus'
    )
    subscription_filter_keys = 'subscription_filter_keys'
    payment_grace_period = 'payment_grace_period'


class SettingGroup(Enum):
    stripe = 'stripe'
    billing = 'billing'


class OrganizationSetting(BaseModel):
    setting_id: str
    setting_name: SettingName
    setting_values: Dict[str, Any]
    setting_group: Optional[SettingGroup] = None


class OrganizationSettingUpdate(BaseModel):
    setting_values: Optional[Dict[str, Any]] = None


class Status10(Enum):
    Active = 'Active'
    Invited = 'Invited'


class OrganizationUser(BaseModel):
    username: constr(regex=r'^[\w.@+-]+$', max_length=150) = Field(
        ...,
        description='Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.',
    )
    email: EmailStr
    role: str
    status: Status10 = 'Active'


class PaginatedActionList(BaseModel):
    next: Optional[str] = None
    previous: Optional[str] = None
    results: Optional[List[Action]] = None


class PaginatedEventList(BaseModel):
    next: Optional[str] = None
    previous: Optional[str] = None
    results: Optional[List[Event]] = None


class PatchedCustomerUpdateRequest(BaseModel):
    default_currency_code: Optional[constr(min_length=1)] = None
    address: Optional[AddressRequest] = None
    tax_rate: Optional[confloat(ge=0.0, le=999.9999)] = Field(
        None, description='Tax rate as percentage. For example, 10.5 for 10.5%'
    )


class PaymentStatus3(Enum):
    paid = 'paid'
    unpaid = 'unpaid'


class PatchedInvoiceUpdateRequest(BaseModel):
    payment_status: Optional[PaymentStatus3] = None


class Status11(Enum):
    active = 'active'
    archived = 'archived'


class PatchedMetricUpdateRequest(BaseModel):
    billable_metric_name: Optional[constr(max_length=50)] = None
    status: Optional[Status11] = None


class PatchedOrganizationSettingUpdateRequest(BaseModel):
    setting_values: Optional[Dict[str, Any]] = None


class Status12(Enum):
    active = 'active'
    archived = 'archived'


class Status13(Enum):
    active = 'active'
    archived = 'archived'


class MakeActiveType(Enum):
    replace_immediately = 'replace_immediately'
    replace_on_active_version_renewal = 'replace_on_active_version_renewal'
    grandfather_active = 'grandfather_active'


class ReplaceImmediatelyType(Enum):
    end_current_subscription_and_bill = 'end_current_subscription_and_bill'
    end_current_subscription_dont_bill = 'end_current_subscription_dont_bill'
    change_subscription_plan = 'change_subscription_plan'


class PatchedPlanVersionUpdateRequest(BaseModel):
    description: Optional[str] = None
    status: Optional[Status13] = None
    make_active_type: Optional[MakeActiveType] = None
    replace_immediately_type: Optional[ReplaceImmediatelyType] = None
    transition_to_plan_id: Optional[UUID] = None


class PaymentProcessor(Enum):
    stripe = 'stripe'


class PaymentProviderPostDataRequest(BaseModel):
    payment_processor: PaymentProcessor
    data: Dict[str, Any]


class PaymentProviderPostRequestRequest(BaseModel):
    pp_info: PaymentProviderPostDataRequest


class PaymentProcessor1(Enum):
    stripe = 'stripe'


class PaymentProviderPostResponse(BaseModel):
    payment_processor: PaymentProcessor1
    success: bool
    details: str


class PeriodMetricRevenueResponse(BaseModel):
    total_revenue_period_1: confloat(lt=10000000000.0, gt=-10000000000.0)
    total_revenue_period_2: confloat(lt=10000000000.0, gt=-10000000000.0)
    earned_revenue_period_1: confloat(lt=10000000000.0, gt=-10000000000.0)
    earned_revenue_period_2: confloat(lt=10000000000.0, gt=-10000000000.0)


class PeriodSingleMetricUsage(BaseModel):
    data: List[DayMetricUsage]


class PeriodSubscriptionsResponse(BaseModel):
    period_1_total_subscriptions: int
    period_1_new_subscriptions: int
    period_2_total_subscriptions: int
    period_2_new_subscriptions: int


class PlanDuration(Enum):
    monthly = 'monthly'
    quarterly = 'quarterly'
    yearly = 'yearly'


class Status14(Enum):
    active = 'active'
    archived = 'archived'
    experimental = 'experimental'


class PlanDuration1(Enum):
    monthly = 'monthly'
    quarterly = 'quarterly'
    yearly = 'yearly'


class Status15(Enum):
    active = 'active'
    archived = 'archived'
    experimental = 'experimental'


class PlanDuration2(Enum):
    monthly = 'monthly'
    quarterly = 'quarterly'
    yearly = 'yearly'


class Status16(Enum):
    active = 'active'
    archived = 'archived'
    experimental = 'experimental'


class PlanNameAndID(BaseModel):
    plan_name: constr(max_length=100) = Field(..., description='Name of the plan')
    plan_id: str


class PlanRepresentation(BaseModel):
    plan_name: str
    plan_id: str
    plan_revenue: float


class Status17(Enum):
    active = 'active'
    archived = 'archived'


class FlatFeeBillingType1(Enum):
    in_arrears = 'in_arrears'
    in_advance = 'in_advance'


class UsageBillingFrequency1Enum(Enum):
    monthly = 'monthly'
    quarterly = 'quarterly'
    end_of_period = 'end_of_period'


class UsageBillingFrequency1(BaseModel):
    __root__: Optional[UsageBillingFrequency1Enum] = None


class Status18(Enum):
    active = 'active'
    retiring = 'retiring'
    grandfathered = 'grandfathered'
    archived = 'archived'
    inactive = 'inactive'


class FlatFeeBillingType2(Enum):
    in_arrears = 'in_arrears'
    in_advance = 'in_advance'


class UsageBillingFrequency2Enum(Enum):
    monthly = 'monthly'
    quarterly = 'quarterly'
    end_of_period = 'end_of_period'
    field_ = ''


class UsageBillingFrequency2(BaseModel):
    __root__: Optional[UsageBillingFrequency2Enum] = None


class MakeActiveType1(Enum):
    replace_immediately = 'replace_immediately'
    replace_on_active_version_renewal = 'replace_on_active_version_renewal'
    grandfather_active = 'grandfather_active'


class ReplaceImmediatelyType1(Enum):
    end_current_subscription_and_bill = 'end_current_subscription_and_bill'
    end_current_subscription_dont_bill = 'end_current_subscription_dont_bill'
    change_subscription_plan = 'change_subscription_plan'


class FlatFeeBillingType3(Enum):
    in_arrears = 'in_arrears'
    in_advance = 'in_advance'


class UsageBillingFrequency3Enum(Enum):
    monthly = 'monthly'
    quarterly = 'quarterly'
    end_of_period = 'end_of_period'


class UsageBillingFrequency3(BaseModel):
    __root__: Optional[UsageBillingFrequency3Enum] = None


class Status19(Enum):
    active = 'active'
    retiring = 'retiring'
    grandfathered = 'grandfathered'
    archived = 'archived'
    inactive = 'inactive'


class Status20(Enum):
    active = 'active'
    archived = 'archived'


class MakeActiveType2(Enum):
    replace_immediately = 'replace_immediately'
    replace_on_active_version_renewal = 'replace_on_active_version_renewal'
    grandfather_active = 'grandfather_active'


class ReplaceImmediatelyType2(Enum):
    end_current_subscription_and_bill = 'end_current_subscription_and_bill'
    end_current_subscription_dont_bill = 'end_current_subscription_dont_bill'
    change_subscription_plan = 'change_subscription_plan'


class PlanVersionUpdate(BaseModel):
    description: Optional[str] = None
    status: Optional[Status20] = None
    make_active_type: Optional[MakeActiveType2] = None
    replace_immediately_type: Optional[ReplaceImmediatelyType2] = None


class Status21(Enum):
    success = 'success'


class PriceAdjustmentType(Enum):
    percentage = 'percentage'
    fixed = 'fixed'
    price_override = 'price_override'


class PriceAdjustment(BaseModel):
    price_adjustment_name: constr(max_length=100)
    price_adjustment_description: Optional[str] = Field(...)
    price_adjustment_type: PriceAdjustmentType
    price_adjustment_amount: confloat(lt=10000000000.0, gt=-10000000000.0)


class PriceAdjustmentType1(Enum):
    percentage = 'percentage'
    fixed = 'fixed'
    price_override = 'price_override'


class PriceAdjustmentRequest(BaseModel):
    price_adjustment_name: constr(min_length=1) = ''
    price_adjustment_description: Optional[str] = None
    price_adjustment_type: PriceAdjustmentType1
    price_adjustment_amount: confloat(lt=10000000000.0, gt=-10000000000.0)


class Type(Enum):
    flat = 'flat'
    per_unit = 'per_unit'
    free = 'free'


class BatchRoundingType(Enum):
    round_up = 'round_up'
    round_down = 'round_down'
    round_nearest = 'round_nearest'
    no_rounding = 'no_rounding'


class PriceTier(BaseModel):
    type: Type
    range_start: confloat(lt=10000000000.0, gt=-10000000000.0)
    range_end: Optional[confloat(lt=10000000000.0, gt=-10000000000.0)] = Field(...)
    cost_per_batch: Optional[confloat(lt=10000000000.0, gt=-10000000000.0)] = Field(...)
    metric_units_per_batch: Optional[
        confloat(lt=10000000000.0, gt=-10000000000.0)
    ] = Field(...)
    batch_rounding_type: Optional[BatchRoundingType] = Field(...)


class Type1(Enum):
    flat = 'flat'
    per_unit = 'per_unit'
    free = 'free'


class BatchRoundingType1Enum(Enum):
    round_up = 'round_up'
    round_down = 'round_down'
    round_nearest = 'round_nearest'
    no_rounding = 'no_rounding'


class BatchRoundingType1(BaseModel):
    __root__: Optional[BatchRoundingType1Enum] = None


class PriceTierCreateRequest(BaseModel):
    type: Type1
    range_start: confloat(ge=0.0, lt=10000000000.0)
    range_end: Optional[confloat(ge=0.0, lt=10000000000.0)] = None
    cost_per_batch: Optional[confloat(ge=0.0, lt=10000000000.0)] = None
    metric_units_per_batch: Optional[confloat(ge=0.0, lt=10000000000.0)] = None
    batch_rounding_type: Optional[BatchRoundingType1] = None


class PricingUnit(BaseModel):
    code: constr(max_length=10)
    name: constr(max_length=100)
    symbol: constr(max_length=10)


class PricingUnitRequest(BaseModel):
    code: constr(min_length=1, max_length=10)
    name: constr(min_length=1, max_length=100)
    symbol: constr(min_length=1, max_length=10)


class Status22(Enum):
    active = 'active'
    archived = 'archived'


class Product(BaseModel):
    name: constr(max_length=100)
    description: Optional[str] = None
    product_id: Optional[constr(regex=r'^[-a-zA-Z0-9_]+$', max_length=100)] = None
    status: Status22


class Status23(Enum):
    active = 'active'
    archived = 'archived'


class ProductRequest(BaseModel):
    name: constr(min_length=1, max_length=100)
    description: Optional[str] = None
    product_id: Optional[
        constr(regex=r'^[-a-zA-Z0-9_]+$', min_length=1, max_length=100)
    ] = None
    status: Status23


class RegistrationDetailRequest(BaseModel):
    organization_name: str
    industry: str
    email: constr(min_length=1)
    password: constr(min_length=1)
    username: constr(min_length=1)


class RegistrationFailure(BaseModel):
    detail: str


class RegistrationRequest(BaseModel):
    register_: RegistrationDetailRequest = Field(..., alias='register')


class ResetPasswordRequestRequest(BaseModel):
    userId: constr(min_length=1)
    password: constr(min_length=1)
    token: constr(min_length=1)


class ResetPasswordSuccess(BaseModel):
    detail: str
    token: str


class RevenueDate(BaseModel):
    date: date
    original_plan_revenue: float
    new_plan_revenue: float


class Seller(BaseModel):
    name: str
    address: Optional[Address] = None
    phone: Optional[constr(max_length=20)] = None
    email: Optional[EmailStr] = None


class SellerRequest(BaseModel):
    name: constr(min_length=1)
    phone: Optional[constr(max_length=20)] = None
    email: Optional[EmailStr] = None


class SessionSuccess(BaseModel):
    isAuthenticated: bool


class SingleCustomerValue(BaseModel):
    customer_id: str
    customer_name: str
    value: float


class SinglePaymentProvider(BaseModel):
    payment_provider_name: str
    connected: bool
    redirect_url: AnyUrl


class SinglePlanNumCustomers(BaseModel):
    plan_name: str
    num_customers: int
    percent_total: float


class SubscriptionCategoricalFilter(BaseModel):
    value: str
    property_name: str = Field(
        ...,
        description="The string name of the property to filter on. Example: 'product_id'",
    )


class SubscriptionCategoricalFilterRequest(BaseModel):
    value: constr(min_length=1)
    property_name: constr(min_length=1) = Field(
        ...,
        description="The string name of the property to filter on. Example: 'product_id'",
    )


class SubscriptionCustomerSummary(BaseModel):
    billing_plan_name: str
    plan_version: str
    end_date: datetime = Field(
        ...,
        description='The time the subscription starts. This will be a string in yyyy-mm-dd HH:mm:ss format in UTC time.',
    )
    auto_renew: Optional[bool] = Field(
        None,
        description='Whether the subscription automatically renews. Defaults to true.',
    )


class SubscriptionRecord(BaseModel):
    start_date: datetime = Field(
        ...,
        description='The time the subscription starts. This will be a string in yyyy-mm-dd HH:mm:ss format in UTC time.',
    )
    end_date: datetime = Field(
        ...,
        description='The time the subscription starts. This will be a string in yyyy-mm-dd HH:mm:ss format in UTC time.',
    )
    auto_renew: bool = Field(
        ...,
        description='Whether the subscription automatically renews. Defaults to true.',
    )
    is_new: bool = Field(
        ...,
        description='Whether this subscription came from a renewal or from a first-time. Defaults to true on creation.',
    )
    subscription_filters: List[SubscriptionCategoricalFilter]
    customer: LightweightCustomer
    billing_plan: LightweightPlanVersion
    fully_billed: bool = Field(
        ..., description='Whether the subscription has been fully billed and finalized.'
    )


class FlatFeeBehavior(Enum):
    refund = 'refund'
    prorate = 'prorate'
    charge_full = 'charge_full'


class UsageBehavior(Enum):
    bill_full = 'bill_full'
    bill_none = 'bill_none'


class InvoicingBehavior(Enum):
    add_to_next_invoice = 'add_to_next_invoice'
    invoice_now = 'invoice_now'


class SubscriptionRecordCancelRequest(BaseModel):
    flat_fee_behavior: FlatFeeBehavior = Field(
        'charge_full',
        description='Can either charge the full amount of the flat fee, regardless of how long the customer has been on the plan, prorate the fflat fee, or charge nothing for the flat fee. If the flat fee has already been invoiced (e.g. in advance payment on last subscription), and the reuslting charge is less than the amount already invoiced, the difference will be refunded as a credit. Defaults to charge full amount.',
    )
    usage_behavior: UsageBehavior = Field(
        'bill_full',
        description='If bill_full, current usage will be billed on the invoice. If bill_none, current unbilled usage will be dropped from the invoice. Defaults to bill_full.',
    )
    invoicing_behavior: InvoicingBehavior = Field(
        'invoice_now',
        description='Whether to invoice now or invoice at the end of the billing period. Defaults to invoice now.',
    )


class SubscriptionRecordCreateRequest(BaseModel):
    start_date: datetime = Field(
        ...,
        description='The date the subscription starts. This should be a string in YYYY-MM-DD format of the date in UTC time.',
    )
    end_date: Optional[datetime] = Field(
        None,
        description='The date the subscription ends. This should be a string in YYYY-MM-DD format of the date in UTC time. If you don’t set it (recommended), we will use the information in the billing plan to automatically calculate this.',
    )
    auto_renew: Optional[bool] = Field(
        None,
        description='Whether the subscription automatically renews. Defaults to true.',
    )
    is_new: Optional[bool] = None
    subscription_filters: Optional[List[SubscriptionCategoricalFilterRequest]] = Field(
        None,
        description='Add filter key, value pairs that define which events will be applied to this plan subscription.',
    )
    customer_id: constr(min_length=1) = Field(
        ..., description='The id provided when creating the customer'
    )
    plan_id: UUID = Field(
        ..., description='The Lotus plan_id, found in the billing plan object'
    )


class SubscriptionRecordRequest(BaseModel):
    start_date: datetime = Field(
        ...,
        description='The time the subscription starts. This will be a string in yyyy-mm-dd HH:mm:ss format in UTC time.',
    )
    end_date: datetime = Field(
        ...,
        description='The time the subscription starts. This will be a string in yyyy-mm-dd HH:mm:ss format in UTC time.',
    )
    auto_renew: bool = Field(
        ...,
        description='Whether the subscription automatically renews. Defaults to true.',
    )
    is_new: bool = Field(
        ...,
        description='Whether this subscription came from a renewal or from a first-time. Defaults to true on creation.',
    )
    subscription_filters: List[SubscriptionCategoricalFilterRequest]
    billing_plan: LightweightPlanVersionRequest
    fully_billed: bool = Field(
        ..., description='Whether the subscription has been fully billed and finalized.'
    )


class InvoicingBehavior1(Enum):
    add_to_next_invoice = 'add_to_next_invoice'
    invoice_now = 'invoice_now'


class UsageBehavior1(Enum):
    transfer_to_new_subscription = 'transfer_to_new_subscription'
    keep_separate = 'keep_separate'


class SubscriptionRecordUpdateRequest(BaseModel):
    replace_plan_id: Optional[UUID] = Field(
        None, description='The plan to replace the current plan with'
    )
    invoicing_behavior: InvoicingBehavior1 = Field(
        'invoice_now',
        description='The invoicing behavior to use when replacing the plan. Invoice now will invoice the customer for the prorated difference of the old plan and the new plan, whereas add_to_next_invoice will wait until the end of the subscription to do the calculation.',
    )
    usage_behavior: UsageBehavior1 = Field(
        'transfer_to_new_subscription',
        description='The usage behavior to use when replacing the plan. Transfer to new subscription will transfer the usage from the old subscription to the new subscription, whereas reset_usage will reset the usage to 0 for the new subscription, while keeping the old usage on the old subscription and charging for that appropriately at the end of the month.',
    )
    turn_off_auto_renew: Optional[bool] = Field(
        None, description='Turn off auto renew for the subscription'
    )
    end_date: Optional[datetime] = Field(
        None, description='Change the end date for the subscription.'
    )


class Tag(BaseModel):
    tag_name: constr(max_length=50)
    tag_hex: Optional[constr(max_length=7)] = None
    tag_color: Optional[constr(max_length=20)] = None


class TagRequest(BaseModel):
    tag_name: constr(min_length=1, max_length=50)
    tag_hex: Optional[constr(min_length=1, max_length=7)] = None
    tag_color: Optional[constr(min_length=1, max_length=20)] = None


class TopCustomers(BaseModel):
    original_plan_revenue: List[SingleCustomerValue]
    new_plan_revenue: List[SingleCustomerValue]
    biggest_pct_increase: List[SingleCustomerValue]
    biggest_pct_decrease: List[SingleCustomerValue]


class Success(Enum):
    none = 'none'


class TrackEventFailure(BaseModel):
    success: Success
    failed_events: Dict[str, Any]


class Success1(Enum):
    all = 'all'
    some = 'some'


class TrackEventSuccess(BaseModel):
    success: Success1
    failed_events: Dict[str, Any]


class Status24(Enum):
    error = 'error'


class TransferSubscriptionsFailure(BaseModel):
    status: Status24
    detail: str


class Source6(Enum):
    stripe = 'stripe'


class TransferSubscriptionsRequestRequest(BaseModel):
    source: Source6
    end_now: bool


class Status25(Enum):
    success = 'success'


class TransferSubscriptionsSuccess(BaseModel):
    status: Status25
    detail: str


class UsageAlertCreate(BaseModel):
    metric_id: UUID
    plan_version_id: UUID
    threshold: confloat(lt=10000000000.0, gt=-10000000000.0)


class UsageAlertCreateRequest(BaseModel):
    metric_id: UUID
    plan_version_id: UUID
    threshold: confloat(lt=10000000000.0, gt=-10000000000.0)


class User(BaseModel):
    username: constr(regex=r'^[\w.@+-]+$', max_length=150) = Field(
        ...,
        description='Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.',
    )
    email: EmailStr
    organization_name: str
    organization_id: str


class UserRequest(BaseModel):
    username: constr(regex=r'^[\w.@+-]+$', min_length=1, max_length=150) = Field(
        ...,
        description='Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.',
    )
    email: EmailStr
    organization_name: constr(min_length=1)
    organization_id: constr(min_length=1)


class TriggersInEnum(Enum):
    invoice_created = 'invoice.created'
    invoice_paid = 'invoice.paid'
    usage_alert_triggered = 'usage_alert.triggered'


class WebhookEndpointRequest(BaseModel):
    name: Optional[constr(max_length=100)] = None
    webhook_url: constr(min_length=1, max_length=100)
    triggers_in: List[TriggersInEnum]


class TriggerName(Enum):
    invoice_created = 'invoice.created'
    invoice_paid = 'invoice.paid'
    usage_alert_triggered = 'usage_alert.triggered'


class WebhookTrigger(BaseModel):
    trigger_name: TriggerName


class TriggerName1(Enum):
    invoice_created = 'invoice.created'
    invoice_paid = 'invoice.paid'
    usage_alert_triggered = 'usage_alert.triggered'


class WebhookTriggerRequest(BaseModel):
    trigger_name: TriggerName1


class BacktestCreateRequest(BaseModel):
    start_date: date
    end_date: date
    substitutions: List[BacktestSubstitutionMultiRequest]
    kpis: List[Kpi1]
    backtest_name: constr(min_length=1, max_length=100)


class BatchEventRequest(BaseModel):
    batch: List[EventRequest]


class CustomerBalanceAdjustment(BaseModel):
    credit_id: str
    customer: LightweightCustomer
    amount: confloat(ge=0.0, lt=10000000000.0)
    amount_remaining: confloat(ge=0.0, lt=10000000000.0)
    currency: PricingUnit
    description: Optional[str] = Field(...)
    effective_at: datetime
    expires_at: Optional[datetime] = Field(...)
    status: Status4
    amount_paid: confloat(lt=10000000000.0, gt=-10000000000.0)
    amount_paid_currency: Optional[PricingUnit] = Field(...)
    drawdowns: List[CreditDrawdown]


class CustomerIntegrations(BaseModel):
    stripe: Optional[CustomerStripeIntegration] = None


class CustomerSummary(BaseModel):
    customer_name: Optional[constr(max_length=100)] = Field(
        None, description='The display name of the customer'
    )
    customer_id: Optional[constr(regex=r'^[-a-zA-Z0-9_]+$', max_length=50)] = Field(
        None,
        description='The id provided when creating the customer, we suggest matching with your internal customer id in your backend',
    )
    subscriptions: List[SubscriptionCustomerSummary]


class DemoRegistrationSuccess(BaseModel):
    detail: str
    token: str
    user: User


class GetEventAccess(BaseModel):
    plan_id: str = Field(
        ...,
        description='The plan_id of the plan we are checking that has access to this feature.',
    )
    subscription_filters: List[SubscriptionCategoricalFilter] = Field(
        ...,
        description="The subscription filters that are applied to this plan's relationship with the customer. If your billing model does not have the ability multiple plans or subscriptions per customer, this is likely not relevant for you.",
    )
    usage_per_component: List[ComponentUsage] = Field(
        ...,
        description="The usage of each component of the plan the customer is on. Only components that match the request will be included: If metric_id is provided, this will be a list of length 1. If event_name is provided, this will be a list of length 1 or more depending on how many components of the customer's plan use this event.",
    )


class GetFeatureAccess(BaseModel):
    feature_name: str = Field(
        ..., description='Name of the feature to check access for.'
    )
    plan_id: str = Field(
        ...,
        description='The plan_id of the plan we are checking that has access to this feature.',
    )
    subscription_filters: List[SubscriptionCategoricalFilter] = Field(
        ...,
        description="The subscription filters that are applied to this plan's relationship with the customer. If your billing model does not have the ability multiple plans or subscriptions per customer, this is likely not relevant for you.",
    )
    access: bool = Field(
        ...,
        description="Whether or not the plan has access to this feature. If your customer can have multiple plans or subscriptions, then you must check the 'access' across all returned plans to determine if the customer can access this feature.",
    )


class InvoiceLineItem(BaseModel):
    name: constr(max_length=100)
    start_date: datetime
    end_date: datetime
    quantity: Optional[confloat(ge=0.0, lt=10000000000.0)] = Field(...)
    subtotal: confloat(lt=10000000000.0, gt=-10000000000.0)
    billing_type: Optional[BillingType] = Field(...)
    metadata: Optional[Dict[str, Any]] = Field(...)
    plan: Optional[LightweightPlanVersion] = Field(...)
    subscription_filters: Optional[List[SubscriptionCategoricalFilter]] = Field(...)


class InvoiceRequest(BaseModel):
    invoice_id: constr(min_length=1)
    currency: PricingUnitRequest
    external_payment_obj_type: Optional[ExternalPaymentObjType1] = Field(...)
    line_items: List[InvoiceLineItemRequest]
    seller: SellerRequest


class LightweightInvoice(BaseModel):
    seller: Seller
    currency: PricingUnit
    due_date: Optional[datetime] = Field(...)
    start_date: date
    invoice_number: str
    end_date: date
    payment_status: PaymentStatus2
    external_payment_obj_id: Optional[str] = Field(...)
    issue_date: datetime
    invoice_id: str
    external_payment_obj_type: Optional[ExternalPaymentObjType2] = Field(...)
    cost_due: confloat(lt=10000000000.0, gt=-10000000000.0)


class LightweightInvoiceLineItem(BaseModel):
    billing_type: Optional[BillingType2] = Field(...)
    name: constr(max_length=100)
    start_date: datetime
    end_date: datetime
    quantity: Optional[confloat(ge=0.0, lt=10000000000.0)] = Field(...)
    plan: Optional[LightweightPlanVersion] = Field(...)
    subscription_filters: Optional[List[SubscriptionCategoricalFilter]] = Field(...)
    subtotal: confloat(lt=10000000000.0, gt=-10000000000.0)


class LoginSuccess(BaseModel):
    detail: str
    token: str
    user: User


class Metric(BaseModel):
    metric_id: str
    event_name: str = Field(
        ..., description='Name of the event that this metric is tracking.'
    )
    property_name: Optional[str] = Field(
        ...,
        description="The name of the property of the event that should be used for this metric. Doesn't apply if the metric is of type 'counter' with an aggregation of count.",
    )
    aggregation_type: str
    granularity: Optional[Granularity] = Field(
        ...,
        description="The granularity of the metric. Only applies to metrics of type 'gauge' or 'rate'.",
    )
    event_type: Optional[EventType] = Field(
        ...,
        description="Used only for metrics of type 'gauge'. Please refer to our documentation for an explanation of the different types.",
    )
    metric_type: MetricType = Field(
        ...,
        description='The type of metric that this is. Please refer to our documentation for an explanation of the different types.',
    )
    metric_name: str
    numeric_filters: List[NumericFilter]
    categorical_filters: List[CategoricalFilter]
    is_cost_metric: bool = Field(
        ...,
        description='Whether or not this metric is a cost metric (used to track costs to your business).',
    )
    custom_sql: Optional[str] = Field(
        ...,
        description='A custom SQL query that can be used to define the metric. Please refer to our documentation for more information.',
    )
    proration: Optional[Proration] = Field(
        ...,
        description="The proration of the metric. Only applies to metrics of type 'gauge'.",
    )


class MetricCreateRequest(BaseModel):
    event_name: Optional[constr(min_length=1, max_length=50)] = Field(
        None, description='Name of the event that this metric is tracking.'
    )
    property_name: Optional[constr(min_length=1, max_length=50)] = Field(
        None,
        description="The name of the property of the event that should be used for this metric. Doesn't apply if the metric is of type 'counter' with an aggregation of count.",
    )
    usage_aggregation_type: Optional[UsageAggregationType] = Field(
        None,
        description='The type of aggregation that should be used for this metric. Please refer to our documentation for an explanation of the different types.',
    )
    billable_aggregation_type: Optional[BillableAggregationType] = None
    granularity: Optional[Granularity1] = Field(
        None,
        description="The granularity of the metric. Only applies to metrics of type 'gauge' or 'rate'.",
    )
    event_type: Optional[EventType1] = Field(
        None,
        description="Used only for metrics of type 'gauge'. Please refer to our documentation for an explanation of the different types.",
    )
    metric_type: MetricType1 = Field(
        ...,
        description='The type of metric that this is. Please refer to our documentation for an explanation of the different types.',
    )
    metric_name: constr(min_length=1)
    proration: Optional[Proration1] = Field(
        None,
        description="The proration of the metric. Only applies to metrics of type 'gauge'.",
    )
    properties: Optional[Dict[str, Any]] = None
    is_cost_metric: bool = Field(
        False,
        description='Whether or not this metric is a cost metric (used to track costs to your business).',
    )
    custom_sql: Optional[str] = Field(
        None,
        description='A custom SQL query that can be used to define the metric. Please refer to our documentation for more information.',
    )
    categorical_filters: Optional[List[CategoricalFilterRequest]] = None
    numeric_filters: Optional[List[NumericFilterRequest]] = None


class MetricRequest(BaseModel):
    metric_id: constr(min_length=1)
    aggregation_type: constr(min_length=1)
    metric_name: constr(min_length=1)
    numeric_filters: List[NumericFilterRequest]
    categorical_filters: List[CategoricalFilterRequest]


class Organization(BaseModel):
    organization_id: str
    organization_name: constr(max_length=100)
    payment_provider_ids: Optional[Dict[str, Any]] = None
    users: List[OrganizationUser]
    default_currency: PricingUnit
    available_currencies: List[PricingUnit]
    plan_tags: List[Tag]
    tax_rate: Optional[confloat(ge=0.0, le=999.9999)] = Field(
        None, description='Tax rate as percentage. For example, 10.5 for 10.5%'
    )
    payment_grace_period: Optional[conint(ge=0, le=365)] = Field(...)
    linked_organizations: List[LightweightOrganization]
    current_user: LightweightUser
    address: Optional[Address] = Field(...)
    team_name: str
    subscription_filter_keys: List[str]


class PatchedCustomerBalanceAdjustmentRequest(BaseModel):
    credit_id: Optional[constr(min_length=1)] = None
    amount: Optional[confloat(ge=0.0, lt=10000000000.0)] = None
    currency: Optional[PricingUnitRequest] = None
    amount_paid_currency: Optional[PricingUnitRequest] = None


class PatchedOrganizationUpdateRequest(BaseModel):
    default_currency_code: Optional[constr(min_length=1)] = None
    address: Optional[AddressRequest] = None
    tax_rate: Optional[confloat(ge=0.0, le=999.9999)] = Field(
        None, description='Tax rate as percentage. For example, 10.5 for 10.5%'
    )
    payment_grace_period: Optional[conint(ge=0, le=365)] = None
    plan_tags: Optional[List[TagRequest]] = None
    subscription_filter_keys: Optional[List[constr(min_length=1)]] = None


class PatchedPlanUpdateRequest(BaseModel):
    plan_name: Optional[constr(min_length=1, max_length=100)] = Field(
        None, description='Name of the plan'
    )
    status: Optional[Status12] = None
    tags: Optional[List[TagRequest]] = None


class PeriodMetricUsageResponse(BaseModel):
    metrics: Dict[str, PeriodSingleMetricUsage]


class PlanComponent(BaseModel):
    billable_metric: Metric
    tiers: List[PriceTier]
    pricing_unit: PricingUnit


class PlanComponentCreateRequest(BaseModel):
    metric_id: UUID
    tiers: Optional[List[PriceTierCreateRequest]] = None


class PlanUpdate(BaseModel):
    plan_name: Optional[constr(max_length=100)] = Field(
        None, description='Name of the plan'
    )
    status: Optional[Status17] = None
    tags: Optional[List[Tag]] = None


class PlanVersion(BaseModel):
    description: Optional[str] = Field(...)
    flat_fee_billing_type: FlatFeeBillingType1
    flat_rate: confloat(lt=10000000000.0, gt=-10000000000.0)
    components: List[PlanComponent]
    features: List[Feature]
    price_adjustment: Optional[PriceAdjustment] = Field(...)
    usage_billing_frequency: Optional[UsageBillingFrequency1] = Field(...)
    version: int
    status: Status18
    plan_name: str
    currency: PricingUnit


class PlanVersionCreateRequest(BaseModel):
    description: Optional[str] = None
    plan_id: Optional[UUID] = None
    flat_fee_billing_type: FlatFeeBillingType2
    flat_rate: Optional[confloat(ge=0.0, lt=10000000000.0)] = None
    components: Optional[List[PlanComponentCreateRequest]] = None
    features: Optional[List[FeatureRequest]] = None
    price_adjustment: Optional[PriceAdjustmentRequest] = None
    usage_billing_frequency: Optional[UsageBillingFrequency2] = None
    day_anchor: Optional[conint(ge=1, le=31)] = None
    month_anchor: Optional[conint(ge=1, le=12)] = None
    make_active: bool
    make_active_type: Optional[MakeActiveType1] = None
    replace_immediately_type: Optional[ReplaceImmediatelyType1] = None
    transition_to_plan_id: Optional[UUID] = None
    currency_code: Optional[constr(min_length=1)] = None


class PlansByNumCustomers(BaseModel):
    results: List[SinglePlanNumCustomers]
    status: Status21


class RegistrationSuccess(BaseModel):
    detail: str
    token: str
    user: User


class SingleMetricCost(BaseModel):
    metric: Metric
    cost: confloat(lt=10000000000.0, gt=-10000000000.0)


class SingleSubstitutionResults(BaseModel):
    cumulative_revenue: List[RevenueDate]
    revenue_by_metric: List[MetricRevenue]
    top_customers: TopCustomers


class UsageAlert(BaseModel):
    usage_alert_id: str
    metric: Metric
    plan_version: LightweightPlanVersion
    threshold: confloat(lt=10000000000.0, gt=-10000000000.0)


class UsageAlertRequest(BaseModel):
    metric: MetricRequest
    plan_version: LightweightPlanVersionRequest
    threshold: confloat(lt=10000000000.0, gt=-10000000000.0)


class WebhookEndpoint(BaseModel):
    webhook_endpoint_id: str
    name: Optional[constr(max_length=100)] = None
    webhook_url: constr(max_length=100)
    webhook_secret: str
    triggers: List[WebhookTrigger]


class Customer(BaseModel):
    customer_id: str
    email: EmailStr
    customer_name: str
    invoices: List[LightweightInvoice]
    total_amount_due: float
    subscriptions: List[SubscriptionRecord]
    integrations: CustomerIntegrations = Field(
        ...,
        description="A dictionary containing the customer's integrations. Keys are the integration type, and the value is a dictionary containing the integration's properties, which can vary by integration.",
    )
    default_currency: PricingUnit
    payment_provider: Optional[PaymentProvider] = Field(...)
    has_payment_method: bool
    address: Optional[Address] = None
    tax_rate: Optional[confloat(lt=1000.0, gt=-1000.0)] = Field(
        ..., description='Tax rate as percentage. For example, 10.5 for 10.5%'
    )


class GroupedLineItem(BaseModel):
    plan_name: str
    subscription_filters: List[SubscriptionCategoricalFilter]
    subtotal: confloat(lt=100000000.0, gt=-100000000.0)
    start_date: datetime
    end_date: datetime
    sub_items: List[LightweightInvoiceLineItem]


class InitialPlanVersionRequest(BaseModel):
    transition_to_plan_id: Optional[UUID] = None
    month_anchor: Optional[conint(ge=1, le=12)] = None
    day_anchor: Optional[conint(ge=1, le=31)] = None
    description: Optional[str] = None
    usage_billing_frequency: Optional[UsageBillingFrequency] = None
    currency_code: Optional[constr(min_length=1)] = None
    components: Optional[List[PlanComponentCreateRequest]] = None
    flat_fee_billing_type: FlatFeeBillingType
    price_adjustment: Optional[PriceAdjustmentRequest] = None
    flat_rate: Optional[confloat(ge=0.0, lt=10000000000.0)] = None
    features: Optional[List[FeatureRequest]] = None


class Invoice(BaseModel):
    invoice_id: str
    invoice_number: str
    cost_due: confloat(lt=10000000000.0, gt=-10000000000.0)
    currency: PricingUnit
    issue_date: datetime
    payment_status: PaymentStatus
    external_payment_obj_id: Optional[str] = Field(...)
    external_payment_obj_type: Optional[ExternalPaymentObjType] = Field(...)
    line_items: List[InvoiceLineItem]
    customer: LightweightCustomerSerializerForInvoice
    due_date: Optional[datetime] = Field(...)
    start_date: date
    end_date: date
    seller: Seller
    invoice_pdf: Optional[AnyUrl] = Field(...)


class InvoiceCreatedRequest(BaseModel):
    payload: InvoiceRequest


class InvoicePaidRequest(BaseModel):
    payload: InvoiceRequest


class Plan(BaseModel):
    plan_name: constr(max_length=100) = Field(..., description='Name of the plan')
    plan_duration: PlanDuration = Field(..., description='Duration of the plan')
    status: Status14
    external_links: List[InitialExternalPlanLink] = Field(
        ..., description='The external links that this plan has.'
    )
    plan_id: str
    parent_plan: Optional[PlanNameAndID] = Field(...)
    target_customer: Optional[LightweightCustomer] = Field(...)
    display_version: PlanVersion
    num_versions: int = Field(
        ..., description='The number of versions that this plan has.'
    )
    active_subscriptions: int = Field(
        ...,
        description='The number of active subscriptions that this plan has across all versions.',
    )
    tags: List[Tag] = Field(..., description='The tags that this plan has.')


class PlanCreateRequest(BaseModel):
    plan_name: constr(min_length=1, max_length=100) = Field(
        ..., description='Name of the plan'
    )
    plan_duration: PlanDuration1 = Field(..., description='Duration of the plan')
    status: Optional[Status15] = None
    initial_external_links: Optional[List[InitialExternalPlanLinkRequest]] = None
    initial_version: InitialPlanVersionRequest
    parent_plan_id: Optional[UUID] = None
    target_customer_id: Optional[constr(min_length=1)] = Field(
        None,
        description='The id provided when creating the customer, we suggest matching with your internal customer id in your backend',
    )
    tags: Optional[List[TagRequest]] = None


class PlanVersionDetail(BaseModel):
    description: Optional[str] = Field(...)
    flat_fee_billing_type: FlatFeeBillingType3
    flat_rate: confloat(lt=10000000000.0, gt=-10000000000.0)
    components: List[PlanComponent]
    features: List[Feature]
    price_adjustment: Optional[PriceAdjustment] = Field(...)
    usage_billing_frequency: Optional[UsageBillingFrequency3] = Field(...)
    version: int
    status: Status19
    plan_name: str
    currency: PricingUnit
    version_id: str
    plan_id: str
    alerts: List[UsageAlert]


class SingleDayCostAnalysis(BaseModel):
    date: date
    cost_data: List[SingleMetricCost]
    revenue: confloat(lt=10000000000.0, gt=-10000000000.0)


class SingleSubstitution(BaseModel):
    substitution_name: str
    original_plan: PlanRepresentation
    new_plan: PlanRepresentation
    pct_revenue_change: Optional[float] = Field(...)
    results: SingleSubstitutionResults


class UsageAlertPayloadRequest(BaseModel):
    subscription: LightweightSubscriptionRecordRequest
    usage_alert: UsageAlertRequest
    usage: confloat(lt=10000000000.0, gt=-10000000000.0)
    time_triggered: datetime


class UsageAlertTriggeredRequest(BaseModel):
    payload: UsageAlertPayloadRequest


class AllSubstitutionResults(BaseModel):
    substitution_results: Optional[List[SingleSubstitution]] = None
    original_plans_revenue: Optional[float] = None
    new_plans_revenue: Optional[float] = None
    pct_revenue_change: Optional[float] = None


class BacktestSubstitution(BaseModel):
    new_plan: PlanVersionDetail
    original_plan: PlanVersionDetail


class CostAnalysis(BaseModel):
    per_day: List[SingleDayCostAnalysis]
    total_cost: confloat(lt=10000000000.0, gt=-10000000000.0)
    total_revenue: confloat(lt=10000000000.0, gt=-10000000000.0)
    margin: confloat(lt=10000000000.0, gt=-10000000000.0)


class DraftInvoice(BaseModel):
    currency: PricingUnit
    due_date: Optional[datetime] = Field(...)
    start_date: date
    end_date: date
    line_items: List[GroupedLineItem]
    issue_date: datetime
    invoice_id: str
    cost_due: confloat(lt=10000000000.0, gt=-10000000000.0)


class DraftInvoiceResponse(BaseModel):
    invoice: Optional[List[DraftInvoice]] = None


class PlanDetail(BaseModel):
    plan_name: constr(max_length=100) = Field(..., description='Name of the plan')
    plan_duration: PlanDuration2 = Field(..., description='Duration of the plan')
    status: Status16
    external_links: List[InitialExternalPlanLink] = Field(
        ..., description='The external links that this plan has.'
    )
    plan_id: str
    parent_plan: Optional[PlanNameAndID] = Field(...)
    target_customer: Optional[LightweightCustomer] = Field(...)
    display_version: PlanVersionDetail
    num_versions: int = Field(
        ..., description='The number of versions that this plan has.'
    )
    active_subscriptions: int = Field(
        ...,
        description='The number of active subscriptions that this plan has across all versions.',
    )
    tags: List[Tag] = Field(..., description='The tags that this plan has.')
    versions: List[PlanVersionDetail]


class BacktestDetail(BaseModel):
    backtest_name: constr(max_length=100)
    backtest_results: AllSubstitutionResults
    status: Optional[Status] = None
    start_date: date
    backtest_substitutions: List[BacktestSubstitution]
    backtest_id: str
    end_date: date
    kpis: Optional[Dict[str, Any]] = None
    time_created: Optional[datetime] = None
