# generated by datamodel-codegen:
#   filename:  openapi.yaml
#   timestamp: 2023-01-11T09:37:01+00:00

from __future__ import annotations

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

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: str
    original_plans: List[str]


class BacktestSubstitutionMultiRequest(BaseModel):
    new_plan: constr(min_length=1)
    original_plans: List[constr(min_length=1)]


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: Optional[constr(regex=r'^[-a-zA-Z0-9_]+$', max_length=100)] = None


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


class CategoricalFilter(BaseModel):
    property_name: str
    operator: Operator
    comparison_value: List[str]


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: 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: 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: Optional[int] = 30
    customer_id: Optional[constr(min_length=1)] = None


class PaymentProviderEnum(Enum):
    stripe = 'stripe'


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


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


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


class CustomerBalanceAdjustmentCreateRequest(BaseModel):
    adjustment_id: Optional[
        constr(regex=r'^[-a-zA-Z0-9_]+$', min_length=1, max_length=100)
    ] = None
    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)
    pricing_unit_code: constr(min_length=1)
    pricing_unit: Optional[int] = None
    description: Optional[str] = None
    effective_at: Optional[datetime] = None
    expires_at: Optional[datetime] = None
    status: Optional[Status5] = None
    amount_paid: Optional[confloat(lt=10000000000.0, gt=-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 Success(Enum):
    none = 'none'


class CustomerBatchCreateFailure(BaseModel):
    success: Success
    failed_customers: Dict[str, Any]


class BehaviorOnExisting(Enum):
    merge = 'merge'
    ignore = 'ignore'
    overwrite = 'overwrite'


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


class CustomerBatchCreateSuccess(BaseModel):
    success: Success1
    failed_customers: Optional[Dict[str, Any]] = 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: constr(min_length=1)
    source: Source1
    external_plan_id: constr(min_length=1, max_length=100)


class Feature(BaseModel):
    feature_name: constr(max_length=50)
    feature_description: str


class FeatureRequest(BaseModel):
    feature_name: constr(min_length=1, max_length=50)
    feature_description: str


class Status6(Enum):
    error = 'error'


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


class Status7(Enum):
    success = 'success'


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


class Source2(Enum):
    stripe = 'stripe'


class ImportCustomersRequestRequest(BaseModel):
    source: Source2


class Status8(Enum):
    error = 'error'


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


class Status9(Enum):
    success = 'success'


class ImportPaymentObjectSuccess(BaseModel):
    status: Status9
    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 FlatFeeBillingType(Enum):
    in_arrears = 'in_arrears'
    in_advance = 'in_advance'


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


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


class InviteRequestRequest(BaseModel):
    email: EmailStr


class InviteResponse(BaseModel):
    email: EmailStr


class PaymentStatus(Enum):
    draft = 'draft'
    voided = 'voided'
    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 PaymentStatus1(Enum):
    paid = 'paid'
    unpaid = 'unpaid'


class InvoiceUpdate(BaseModel):
    payment_status: PaymentStatus1


class LightweightCustomer(BaseModel):
    customer_name: str = Field(..., description='The display name of the customer')
    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',
    )
    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: str = Field(..., description='The display name of the customer')
    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',
    )
    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 ExternalPaymentObjType1Enum(Enum):
    stripe = 'stripe'


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


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


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


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


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


class LightweightOrganization(BaseModel):
    organization_id: Optional[constr(regex=r'^[-a-zA-Z0-9_]+$', max_length=100)] = None
    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 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 UsageAggregationType(Enum):
    count = 'count'
    sum = 'sum'
    max = 'max'
    unique = 'unique'
    latest = 'latest'
    average = 'average'


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 MetricCreateRequest(BaseModel):
    event_name: constr(min_length=1, max_length=50) = Field(
        ..., description='Name of the event that this metric is tracking.'
    )
    property_name: Optional[constr(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: Optional[bool] = Field(
        None,
        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.',
    )


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


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


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


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


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


class PaymentPlan(Enum):
    self_hosted_free = 'self_hosted_free'
    cloud = 'cloud'
    self_hosted_enterprise = 'self_hosted_enterprise'


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: Optional[OrganizationType1] = 'development'


class OrganizationSetting(BaseModel):
    setting_id: constr(regex=r'^[-a-zA-Z0-9_]+$', max_length=100)
    setting_name: constr(max_length=100)
    setting_values: Dict[str, Any]
    setting_group: constr(max_length=100)


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


class Status11(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: Optional[Status11] = '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 Status12(Enum):
    active = 'active'
    archived = 'archived'


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


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


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


class Status14(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[Status14] = None
    make_active_type: Optional[MakeActiveType] = None
    replace_immediately_type: Optional[ReplaceImmediatelyType] = None
    transition_to_plan_id: Optional[constr(min_length=1)] = None


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


class PatchedWebhookEndpointRequest(BaseModel):
    name: Optional[constr(max_length=100)] = None
    webhook_url: Optional[constr(min_length=1, max_length=100)] = None
    triggers_in: Optional[List[TriggersInEnum]] = 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]
    total_usage: confloat(lt=10000000000.0, gt=-10000000000.0)


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 Status15(Enum):
    active = 'active'
    archived = 'archived'
    experimental = 'experimental'


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


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


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


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


class PlanNameAndID(BaseModel):
    plan_name: constr(max_length=100) = Field(..., description='Name of the plan')
    plan_id: constr(regex=r'^[-a-zA-Z0-9_]+$', max_length=100)


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


class Status18(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 Status19(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'
    _ = ''


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 Status20(Enum):
    active = 'active'
    retiring = 'retiring'
    grandfathered = 'grandfathered'
    archived = 'archived'
    inactive = 'inactive'


class Status21(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[Status21] = None
    make_active_type: Optional[MakeActiveType2] = None
    replace_immediately_type: Optional[ReplaceImmediatelyType2] = None


class Status22(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: str
    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: Optional[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 BatchRoundingTypeEnum(Enum):
    round_up = 'round_up'
    round_down = 'round_down'
    round_nearest = 'round_nearest'
    no_rounding = 'no_rounding'


class BatchRoundingType(BaseModel):
    __root__: Optional[BatchRoundingTypeEnum] = None


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


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 Status23(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: Status23


class Status24(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: Status24


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 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: Optional[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: Optional[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: Optional[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: constr(min_length=1) = 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[constr(min_length=1)] = Field(
        None, description='The plan to replace the current plan with'
    )
    invoicing_behavior: Optional[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: Optional[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 Success2(Enum):
    none = 'none'


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


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


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


class Status25(Enum):
    error = 'error'


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


class Source6(Enum):
    stripe = 'stripe'


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


class Status26(Enum):
    success = 'success'


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


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


class UsageAlertCreateRequest(BaseModel):
    metric_id: constr(min_length=1)
    plan_version_id: constr(min_length=1)
    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 TriggersInEnum1(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[TriggersInEnum1]


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):
    adjustment_id: Optional[constr(regex=r'^[-a-zA-Z0-9_]+$', max_length=100)] = None
    customer: LightweightCustomer
    amount: confloat(lt=10000000000.0, gt=-10000000000.0)
    pricing_unit: PricingUnit
    description: Optional[str] = None
    effective_at: Optional[datetime] = None
    expires_at: Optional[datetime] = None
    status: Optional[Status4] = None
    parent_adjustment_id: str
    amount_paid: Optional[confloat(lt=10000000000.0, gt=-10000000000.0)] = None
    amount_paid_currency: PricingUnit


class CustomerBatchCreateRequestRequest(BaseModel):
    customers: List[CustomerCreateRequest]
    behavior_on_existing: BehaviorOnExisting


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: confloat(ge=0.0, lt=10000000000.0)
    subtotal: confloat(lt=10000000000.0, gt=-10000000000.0)
    billing_type: BillingType
    metadata: Dict[str, Any]
    plan: LightweightPlanVersion
    subscription_filters: List[SubscriptionCategoricalFilter]


class LightweightInvoice(BaseModel):
    currency: PricingUnit
    external_payment_obj_type: ExternalPaymentObjType1
    cost_due: confloat(ge=0.0, lt=10000000000.0)
    issue_date: datetime
    start_date: date
    seller: Seller
    invoice_number: constr(max_length=13)
    end_date: date
    due_date: datetime
    external_payment_obj_id: constr(max_length=100)
    payment_status: PaymentStatus2


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


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


class Metric(BaseModel):
    metric_id: constr(regex=r'^[-a-zA-Z0-9_]+$')
    event_name: str = Field(
        ..., description='Name of the event that this metric is tracking.'
    )
    property_name: 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: Granularity = Field(
        ...,
        description="The granularity of the metric. Only applies to metrics of type 'gauge' or 'rate'.",
    )
    event_type: 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: 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(
        None,
        description="The proration of the metric. Only applies to metrics of type 'gauge'.",
    )


class Organization(BaseModel):
    organization_id: Optional[constr(regex=r'^[-a-zA-Z0-9_]+$', max_length=100)] = None
    organization_name: constr(max_length=100)
    payment_plan: Optional[PaymentPlan] = None
    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%'
    )
    invoice_grace_period: conint(ge=0, le=365)
    linked_organizations: List[LightweightOrganization]
    current_user: LightweightUser
    address: Address
    team_name: str


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%'
    )
    invoice_grace_period: Optional[conint(ge=0, le=365)] = None
    plan_tags: Optional[List[TagRequest]] = None


class PatchedPlanUpdateRequest(BaseModel):
    plan_name: Optional[constr(min_length=1, max_length=100)] = Field(
        None, description='Name of the plan'
    )
    status: Optional[Status13] = 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 PlanComponentRequest(BaseModel):
    tiers: Optional[List[PriceTierCreateRequest]] = None
    metric_id: constr(min_length=1)


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


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


class PlanVersionCreateRequest(BaseModel):
    description: Optional[str] = None
    plan_id: Optional[constr(min_length=1)] = None
    flat_fee_billing_type: FlatFeeBillingType2
    flat_rate: Optional[confloat(ge=0.0, lt=10000000000.0)] = None
    components: Optional[List[PlanComponentRequest]] = 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[constr(min_length=1)] = None
    currency_code: Optional[constr(min_length=1)] = None


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


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: Optional[constr(regex=r'^[-a-zA-Z0-9_]+$', max_length=50)] = None
    metric: Metric
    plan_version: LightweightPlanVersion
    threshold: confloat(lt=10000000000.0, gt=-10000000000.0)


class WebhookEndpoint(BaseModel):
    webhook_endpoint_id: constr(regex=r'^[-a-zA-Z0-9_]+$')
    name: Optional[constr(max_length=100)] = None
    webhook_url: constr(max_length=100)
    webhook_secret: constr(regex=r'^[-a-zA-Z0-9_]+$')
    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: PaymentProvider
    has_payment_method: bool
    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 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):
    price_adjustment: Optional[PriceAdjustmentRequest] = None
    flat_fee_billing_type: FlatFeeBillingType
    currency_code: Optional[constr(min_length=1)] = None
    components: Optional[List[PlanComponentRequest]] = None
    day_anchor: Optional[conint(ge=1, le=31)] = None
    features: Optional[List[FeatureRequest]] = None
    flat_rate: Optional[confloat(ge=0.0, lt=10000000000.0)] = None
    description: Optional[str] = None
    usage_billing_frequency: Optional[UsageBillingFrequency] = None
    transition_to_plan_id: Optional[constr(min_length=1)] = None
    month_anchor: Optional[conint(ge=1, le=12)] = None


class Invoice(BaseModel):
    invoice_number: constr(max_length=13)
    cost_due: confloat(ge=0.0, lt=10000000000.0)
    currency: PricingUnit
    issue_date: datetime
    payment_status: PaymentStatus
    external_payment_obj_id: constr(max_length=100)
    external_payment_obj_type: ExternalPaymentObjType
    line_items: List[InvoiceLineItem]
    customer: LightweightCustomerSerializerForInvoice
    due_date: datetime
    start_date: date
    end_date: date
    seller: Seller
    invoice_pdf: AnyUrl


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: Status15
    external_links: List[InitialExternalPlanLink] = Field(
        ..., description='The external links that this plan has.'
    )
    plan_id: constr(regex=r'^[-a-zA-Z0-9_]+$', max_length=100)
    parent_plan: PlanNameAndID
    target_customer: LightweightCustomer
    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')
    plan_id: Optional[
        constr(regex=r'^[-a-zA-Z0-9_]+$', min_length=1, max_length=100)
    ] = None
    status: Optional[Status16] = None
    initial_external_links: Optional[List[InitialExternalPlanLinkRequest]] = None
    initial_version: InitialPlanVersionRequest
    parent_plan_id: Optional[constr(min_length=1)] = 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: str
    flat_fee_billing_type: FlatFeeBillingType3
    flat_rate: confloat(lt=10000000000.0, gt=-10000000000.0)
    components: List[PlanComponent]
    features: List[Feature]
    price_adjustment: PriceAdjustment
    usage_billing_frequency: UsageBillingFrequency3
    version: int
    status: Status20
    plan_name: str
    currency: PricingUnit
    version_id: Optional[constr(regex=r'^[-a-zA-Z0-9_]+$', max_length=250)] = None
    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: float
    results: SingleSubstitutionResults


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
    line_items: List[GroupedLineItem]
    cost_due: confloat(ge=0.0, lt=10000000000.0)
    issue_date: datetime
    start_date: date
    end_date: date
    due_date: datetime


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: Status17
    external_links: List[InitialExternalPlanLink] = Field(
        ..., description='The external links that this plan has.'
    )
    plan_id: constr(regex=r'^[-a-zA-Z0-9_]+$', max_length=100)
    parent_plan: PlanNameAndID
    target_customer: LightweightCustomer
    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)
    start_date: date
    end_date: date
    time_created: Optional[datetime] = None
    kpis: Optional[Dict[str, Any]] = None
    status: Optional[Status] = None
    backtest_id: Optional[constr(regex=r'^[-a-zA-Z0-9_]+$', max_length=100)] = None
    backtest_substitutions: List[BacktestSubstitution]
    backtest_results: AllSubstitutionResults
