"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""

from __future__ import annotations
from .aggregationfunction import AggregationFunction
from .benefitsortproperty import BenefitSortProperty
from .benefittype import BenefitType
from .customersortproperty import CustomerSortProperty
from .eventsortproperty import EventSortProperty
from .eventsource import EventSource
from .listresource_benefit_ import ListResourceBenefit, ListResourceBenefitTypedDict
from .listresource_customer_ import ListResourceCustomer, ListResourceCustomerTypedDict
from .listresource_event_ import ListResourceEvent, ListResourceEventTypedDict
from .listresource_meter_ import ListResourceMeter, ListResourceMeterTypedDict
from .listresource_order_ import ListResourceOrder, ListResourceOrderTypedDict
from .listresource_product_ import ListResourceProduct, ListResourceProductTypedDict
from .listresource_subscription_ import (
    ListResourceSubscription,
    ListResourceSubscriptionTypedDict,
)
from .listresourcewithcursorpagination_event_ import (
    ListResourceWithCursorPaginationEvent,
    ListResourceWithCursorPaginationEventTypedDict,
)
from .metersortproperty import MeterSortProperty
from .ordersortproperty import OrderSortProperty
from .productbillingtype import ProductBillingType
from .productsortproperty import ProductSortProperty
from .productvisibility import ProductVisibility
from .subscriptionsortproperty import SubscriptionSortProperty
from .timeinterval import TimeInterval
from datetime import datetime
from polar_sdk.types import BaseModel, Nullable, OptionalNullable, UNSET, UNSET_SENTINEL
from polar_sdk.utils import FieldMetadata, PathParamMetadata, QueryParamMetadata
import pydantic
from pydantic import model_serializer
from typing import Callable, Dict, List, Optional, Union
from typing_extensions import Annotated, NotRequired, TypeAliasType, TypedDict


OrganizationIDFilterTypedDict = TypeAliasType(
    "OrganizationIDFilterTypedDict", Union[str, List[str]]
)
r"""Filter by organization ID."""


OrganizationIDFilter = TypeAliasType("OrganizationIDFilter", Union[str, List[str]])
r"""Filter by organization ID."""


ProductIDFilterTypedDict = TypeAliasType(
    "ProductIDFilterTypedDict", Union[str, List[str]]
)
r"""Filter by product ID."""


ProductIDFilter = TypeAliasType("ProductIDFilter", Union[str, List[str]])
r"""Filter by product ID."""


CustomerIDFilterTypedDict = TypeAliasType(
    "CustomerIDFilterTypedDict", Union[str, List[str]]
)
r"""Filter by customer ID."""


CustomerIDFilter = TypeAliasType("CustomerIDFilter", Union[str, List[str]])
r"""Filter by customer ID."""


ExternalCustomerIDFilterTypedDict = TypeAliasType(
    "ExternalCustomerIDFilterTypedDict", Union[str, List[str]]
)
r"""Filter by customer external ID."""


ExternalCustomerIDFilter = TypeAliasType(
    "ExternalCustomerIDFilter", Union[str, List[str]]
)
r"""Filter by customer external ID."""


DiscountIDFilterTypedDict = TypeAliasType(
    "DiscountIDFilterTypedDict", Union[str, List[str]]
)
r"""Filter by discount ID."""


DiscountIDFilter = TypeAliasType("DiscountIDFilter", Union[str, List[str]])
r"""Filter by discount ID."""


MetadataQueryTypedDict = TypeAliasType(
    "MetadataQueryTypedDict", Union[str, int, bool, List[str], List[int], List[bool]]
)


MetadataQuery = TypeAliasType(
    "MetadataQuery", Union[str, int, bool, List[str], List[int], List[bool]]
)


class SubscriptionsListRequestTypedDict(TypedDict):
    organization_id: NotRequired[Nullable[OrganizationIDFilterTypedDict]]
    r"""Filter by organization ID."""
    product_id: NotRequired[Nullable[ProductIDFilterTypedDict]]
    r"""Filter by product ID."""
    customer_id: NotRequired[Nullable[CustomerIDFilterTypedDict]]
    r"""Filter by customer ID."""
    external_customer_id: NotRequired[Nullable[ExternalCustomerIDFilterTypedDict]]
    r"""Filter by customer external ID."""
    discount_id: NotRequired[Nullable[DiscountIDFilterTypedDict]]
    r"""Filter by discount ID."""
    active: NotRequired[Nullable[bool]]
    r"""Filter by active or inactive subscription."""
    cancel_at_period_end: NotRequired[Nullable[bool]]
    r"""Filter by subscriptions that are set to cancel at period end."""
    page: NotRequired[int]
    r"""Page number, defaults to 1."""
    limit: NotRequired[int]
    r"""Size of a page, defaults to 10. Maximum is 100."""
    sorting: NotRequired[Nullable[List[SubscriptionSortProperty]]]
    r"""Sorting criterion. Several criteria can be used simultaneously and will be applied in order. Add a minus sign `-` before the criteria name to sort by descending order."""
    metadata: NotRequired[Nullable[Dict[str, MetadataQueryTypedDict]]]
    r"""Filter by metadata key-value pairs. It uses the `deepObject` style, e.g. `?metadata[key]=value`."""


class SubscriptionsListRequest(BaseModel):
    organization_id: Annotated[
        OptionalNullable[OrganizationIDFilter],
        FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
    ] = UNSET
    r"""Filter by organization ID."""

    product_id: Annotated[
        OptionalNullable[ProductIDFilter],
        FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
    ] = UNSET
    r"""Filter by product ID."""

    customer_id: Annotated[
        OptionalNullable[CustomerIDFilter],
        FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
    ] = UNSET
    r"""Filter by customer ID."""

    external_customer_id: Annotated[
        OptionalNullable[ExternalCustomerIDFilter],
        FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
    ] = UNSET
    r"""Filter by customer external ID."""

    discount_id: Annotated[
        OptionalNullable[DiscountIDFilter],
        FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
    ] = UNSET
    r"""Filter by discount ID."""

    active: Annotated[
        OptionalNullable[bool],
        FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
    ] = UNSET
    r"""Filter by active or inactive subscription."""

    cancel_at_period_end: Annotated[
        OptionalNullable[bool],
        FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
    ] = UNSET
    r"""Filter by subscriptions that are set to cancel at period end."""

    page: Annotated[
        Optional[int],
        FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
    ] = 1
    r"""Page number, defaults to 1."""

    limit: Annotated[
        Optional[int],
        FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
    ] = 10
    r"""Size of a page, defaults to 10. Maximum is 100."""

    sorting: Annotated[
        OptionalNullable[List[SubscriptionSortProperty]],
        FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
    ] = UNSET
    r"""Sorting criterion. Several criteria can be used simultaneously and will be applied in order. Add a minus sign `-` before the criteria name to sort by descending order."""

    metadata: Annotated[
        OptionalNullable[Dict[str, MetadataQuery]],
        FieldMetadata(query=QueryParamMetadata(style="deepObject", explode=True)),
    ] = UNSET
    r"""Filter by metadata key-value pairs. It uses the `deepObject` style, e.g. `?metadata[key]=value`."""

    @model_serializer(mode="wrap")
    def serialize_model(self, handler):
        optional_fields = [
            "organization_id",
            "product_id",
            "customer_id",
            "external_customer_id",
            "discount_id",
            "active",
            "cancel_at_period_end",
            "page",
            "limit",
            "sorting",
            "metadata",
        ]
        nullable_fields = [
            "organization_id",
            "product_id",
            "customer_id",
            "external_customer_id",
            "discount_id",
            "active",
            "cancel_at_period_end",
            "sorting",
            "metadata",
        ]
        null_default_fields = []

        serialized = handler(self)

        m = {}

        for n, f in type(self).model_fields.items():
            k = f.alias or n
            val = serialized.get(k)
            serialized.pop(k, None)

            optional_nullable = k in optional_fields and k in nullable_fields
            is_set = (
                self.__pydantic_fields_set__.intersection({n})
                or k in null_default_fields
            )  # pylint: disable=no-member

            if val is not None and val != UNSET_SENTINEL:
                m[k] = val
            elif val != UNSET_SENTINEL and (
                not k in optional_fields or (optional_nullable and is_set)
            ):
                m[k] = val

        return m


class SubscriptionsListResponseTypedDict(TypedDict):
    result: ListResourceSubscriptionTypedDict


class SubscriptionsListResponse(BaseModel):
    next: Callable[[], Optional[SubscriptionsListResponse]]

    result: ListResourceSubscription


QueryParamOrganizationIDFilterTypedDict = TypeAliasType(
    "QueryParamOrganizationIDFilterTypedDict", Union[str, List[str]]
)
r"""Filter by organization ID."""


QueryParamOrganizationIDFilter = TypeAliasType(
    "QueryParamOrganizationIDFilter", Union[str, List[str]]
)
r"""Filter by organization ID."""


BenefitTypeFilterTypedDict = TypeAliasType(
    "BenefitTypeFilterTypedDict", Union[BenefitType, List[BenefitType]]
)
r"""Filter by benefit type."""


BenefitTypeFilter = TypeAliasType(
    "BenefitTypeFilter", Union[BenefitType, List[BenefitType]]
)
r"""Filter by benefit type."""


FilterIDsTypedDict = TypeAliasType("FilterIDsTypedDict", Union[str, List[str]])
r"""Filter by benefit IDs."""


FilterIDs = TypeAliasType("FilterIDs", Union[str, List[str]])
r"""Filter by benefit IDs."""


ExcludeIDsTypedDict = TypeAliasType("ExcludeIDsTypedDict", Union[str, List[str]])
r"""Exclude benefits with these IDs."""


ExcludeIDs = TypeAliasType("ExcludeIDs", Union[str, List[str]])
r"""Exclude benefits with these IDs."""


class BenefitsListRequestTypedDict(TypedDict):
    organization_id: NotRequired[Nullable[QueryParamOrganizationIDFilterTypedDict]]
    r"""Filter by organization ID."""
    type_filter: NotRequired[Nullable[BenefitTypeFilterTypedDict]]
    r"""Filter by benefit type."""
    id: NotRequired[Nullable[FilterIDsTypedDict]]
    r"""Filter by benefit IDs."""
    exclude_id: NotRequired[Nullable[ExcludeIDsTypedDict]]
    r"""Exclude benefits with these IDs."""
    query: NotRequired[Nullable[str]]
    r"""Filter by description."""
    page: NotRequired[int]
    r"""Page number, defaults to 1."""
    limit: NotRequired[int]
    r"""Size of a page, defaults to 10. Maximum is 100."""
    sorting: NotRequired[Nullable[List[BenefitSortProperty]]]
    r"""Sorting criterion. Several criteria can be used simultaneously and will be applied in order. Add a minus sign `-` before the criteria name to sort by descending order."""
    metadata: NotRequired[Nullable[Dict[str, MetadataQueryTypedDict]]]
    r"""Filter by metadata key-value pairs. It uses the `deepObject` style, e.g. `?metadata[key]=value`."""


class BenefitsListRequest(BaseModel):
    organization_id: Annotated[
        OptionalNullable[QueryParamOrganizationIDFilter],
        FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
    ] = UNSET
    r"""Filter by organization ID."""

    type_filter: Annotated[
        OptionalNullable[BenefitTypeFilter],
        pydantic.Field(alias="type"),
        FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
    ] = UNSET
    r"""Filter by benefit type."""

    id: Annotated[
        OptionalNullable[FilterIDs],
        FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
    ] = UNSET
    r"""Filter by benefit IDs."""

    exclude_id: Annotated[
        OptionalNullable[ExcludeIDs],
        FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
    ] = UNSET
    r"""Exclude benefits with these IDs."""

    query: Annotated[
        OptionalNullable[str],
        FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
    ] = UNSET
    r"""Filter by description."""

    page: Annotated[
        Optional[int],
        FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
    ] = 1
    r"""Page number, defaults to 1."""

    limit: Annotated[
        Optional[int],
        FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
    ] = 10
    r"""Size of a page, defaults to 10. Maximum is 100."""

    sorting: Annotated[
        OptionalNullable[List[BenefitSortProperty]],
        FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
    ] = UNSET
    r"""Sorting criterion. Several criteria can be used simultaneously and will be applied in order. Add a minus sign `-` before the criteria name to sort by descending order."""

    metadata: Annotated[
        OptionalNullable[Dict[str, MetadataQuery]],
        FieldMetadata(query=QueryParamMetadata(style="deepObject", explode=True)),
    ] = UNSET
    r"""Filter by metadata key-value pairs. It uses the `deepObject` style, e.g. `?metadata[key]=value`."""

    @model_serializer(mode="wrap")
    def serialize_model(self, handler):
        optional_fields = [
            "organization_id",
            "type_filter",
            "id",
            "exclude_id",
            "query",
            "page",
            "limit",
            "sorting",
            "metadata",
        ]
        nullable_fields = [
            "organization_id",
            "type_filter",
            "id",
            "exclude_id",
            "query",
            "sorting",
            "metadata",
        ]
        null_default_fields = []

        serialized = handler(self)

        m = {}

        for n, f in type(self).model_fields.items():
            k = f.alias or n
            val = serialized.get(k)
            serialized.pop(k, None)

            optional_nullable = k in optional_fields and k in nullable_fields
            is_set = (
                self.__pydantic_fields_set__.intersection({n})
                or k in null_default_fields
            )  # pylint: disable=no-member

            if val is not None and val != UNSET_SENTINEL:
                m[k] = val
            elif val != UNSET_SENTINEL and (
                not k in optional_fields or (optional_nullable and is_set)
            ):
                m[k] = val

        return m


class BenefitsListResponseTypedDict(TypedDict):
    result: ListResourceBenefitTypedDict


class BenefitsListResponse(BaseModel):
    next: Callable[[], Optional[BenefitsListResponse]]

    result: ListResourceBenefit


QueryParamProductIDFilterTypedDict = TypeAliasType(
    "QueryParamProductIDFilterTypedDict", Union[str, List[str]]
)
r"""Filter by product ID."""


QueryParamProductIDFilter = TypeAliasType(
    "QueryParamProductIDFilter", Union[str, List[str]]
)
r"""Filter by product ID."""


ProductsListQueryParamOrganizationIDFilterTypedDict = TypeAliasType(
    "ProductsListQueryParamOrganizationIDFilterTypedDict", Union[str, List[str]]
)
r"""Filter by organization ID."""


ProductsListQueryParamOrganizationIDFilter = TypeAliasType(
    "ProductsListQueryParamOrganizationIDFilter", Union[str, List[str]]
)
r"""Filter by organization ID."""


BenefitIDFilterTypedDict = TypeAliasType(
    "BenefitIDFilterTypedDict", Union[str, List[str]]
)
r"""Filter products granting specific benefit."""


BenefitIDFilter = TypeAliasType("BenefitIDFilter", Union[str, List[str]])
r"""Filter products granting specific benefit."""


class ProductsListRequestTypedDict(TypedDict):
    id: NotRequired[Nullable[QueryParamProductIDFilterTypedDict]]
    r"""Filter by product ID."""
    organization_id: NotRequired[
        Nullable[ProductsListQueryParamOrganizationIDFilterTypedDict]
    ]
    r"""Filter by organization ID."""
    query: NotRequired[Nullable[str]]
    r"""Filter by product name."""
    is_archived: NotRequired[Nullable[bool]]
    r"""Filter on archived products."""
    is_recurring: NotRequired[Nullable[bool]]
    r"""Filter on recurring products. If `true`, only subscriptions tiers are returned. If `false`, only one-time purchase products are returned."""
    benefit_id: NotRequired[Nullable[BenefitIDFilterTypedDict]]
    r"""Filter products granting specific benefit."""
    visibility: NotRequired[Nullable[List[ProductVisibility]]]
    r"""Filter by visibility."""
    page: NotRequired[int]
    r"""Page number, defaults to 1."""
    limit: NotRequired[int]
    r"""Size of a page, defaults to 10. Maximum is 100."""
    sorting: NotRequired[Nullable[List[ProductSortProperty]]]
    r"""Sorting criterion. Several criteria can be used simultaneously and will be applied in order. Add a minus sign `-` before the criteria name to sort by descending order."""
    metadata: NotRequired[Nullable[Dict[str, MetadataQueryTypedDict]]]
    r"""Filter by metadata key-value pairs. It uses the `deepObject` style, e.g. `?metadata[key]=value`."""


class ProductsListRequest(BaseModel):
    id: Annotated[
        OptionalNullable[QueryParamProductIDFilter],
        FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
    ] = UNSET
    r"""Filter by product ID."""

    organization_id: Annotated[
        OptionalNullable[ProductsListQueryParamOrganizationIDFilter],
        FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
    ] = UNSET
    r"""Filter by organization ID."""

    query: Annotated[
        OptionalNullable[str],
        FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
    ] = UNSET
    r"""Filter by product name."""

    is_archived: Annotated[
        OptionalNullable[bool],
        FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
    ] = UNSET
    r"""Filter on archived products."""

    is_recurring: Annotated[
        OptionalNullable[bool],
        FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
    ] = UNSET
    r"""Filter on recurring products. If `true`, only subscriptions tiers are returned. If `false`, only one-time purchase products are returned."""

    benefit_id: Annotated[
        OptionalNullable[BenefitIDFilter],
        FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
    ] = UNSET
    r"""Filter products granting specific benefit."""

    visibility: Annotated[
        OptionalNullable[List[ProductVisibility]],
        FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
    ] = UNSET
    r"""Filter by visibility."""

    page: Annotated[
        Optional[int],
        FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
    ] = 1
    r"""Page number, defaults to 1."""

    limit: Annotated[
        Optional[int],
        FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
    ] = 10
    r"""Size of a page, defaults to 10. Maximum is 100."""

    sorting: Annotated[
        OptionalNullable[List[ProductSortProperty]],
        FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
    ] = UNSET
    r"""Sorting criterion. Several criteria can be used simultaneously and will be applied in order. Add a minus sign `-` before the criteria name to sort by descending order."""

    metadata: Annotated[
        OptionalNullable[Dict[str, MetadataQuery]],
        FieldMetadata(query=QueryParamMetadata(style="deepObject", explode=True)),
    ] = UNSET
    r"""Filter by metadata key-value pairs. It uses the `deepObject` style, e.g. `?metadata[key]=value`."""

    @model_serializer(mode="wrap")
    def serialize_model(self, handler):
        optional_fields = [
            "id",
            "organization_id",
            "query",
            "is_archived",
            "is_recurring",
            "benefit_id",
            "visibility",
            "page",
            "limit",
            "sorting",
            "metadata",
        ]
        nullable_fields = [
            "id",
            "organization_id",
            "query",
            "is_archived",
            "is_recurring",
            "benefit_id",
            "visibility",
            "sorting",
            "metadata",
        ]
        null_default_fields = []

        serialized = handler(self)

        m = {}

        for n, f in type(self).model_fields.items():
            k = f.alias or n
            val = serialized.get(k)
            serialized.pop(k, None)

            optional_nullable = k in optional_fields and k in nullable_fields
            is_set = (
                self.__pydantic_fields_set__.intersection({n})
                or k in null_default_fields
            )  # pylint: disable=no-member

            if val is not None and val != UNSET_SENTINEL:
                m[k] = val
            elif val != UNSET_SENTINEL and (
                not k in optional_fields or (optional_nullable and is_set)
            ):
                m[k] = val

        return m


class ProductsListResponseTypedDict(TypedDict):
    result: ListResourceProductTypedDict


class ProductsListResponse(BaseModel):
    next: Callable[[], Optional[ProductsListResponse]]

    result: ListResourceProduct


OrdersListQueryParamOrganizationIDFilterTypedDict = TypeAliasType(
    "OrdersListQueryParamOrganizationIDFilterTypedDict", Union[str, List[str]]
)
r"""Filter by organization ID."""


OrdersListQueryParamOrganizationIDFilter = TypeAliasType(
    "OrdersListQueryParamOrganizationIDFilter", Union[str, List[str]]
)
r"""Filter by organization ID."""


OrdersListQueryParamProductIDFilterTypedDict = TypeAliasType(
    "OrdersListQueryParamProductIDFilterTypedDict", Union[str, List[str]]
)
r"""Filter by product ID."""


OrdersListQueryParamProductIDFilter = TypeAliasType(
    "OrdersListQueryParamProductIDFilter", Union[str, List[str]]
)
r"""Filter by product ID."""


ProductBillingTypeFilterTypedDict = TypeAliasType(
    "ProductBillingTypeFilterTypedDict",
    Union[ProductBillingType, List[ProductBillingType]],
)
r"""Filter by product billing type. `recurring` will filter data corresponding to subscriptions creations or renewals. `one_time` will filter data corresponding to one-time purchases."""


ProductBillingTypeFilter = TypeAliasType(
    "ProductBillingTypeFilter", Union[ProductBillingType, List[ProductBillingType]]
)
r"""Filter by product billing type. `recurring` will filter data corresponding to subscriptions creations or renewals. `one_time` will filter data corresponding to one-time purchases."""


QueryParamDiscountIDFilterTypedDict = TypeAliasType(
    "QueryParamDiscountIDFilterTypedDict", Union[str, List[str]]
)
r"""Filter by discount ID."""


QueryParamDiscountIDFilter = TypeAliasType(
    "QueryParamDiscountIDFilter", Union[str, List[str]]
)
r"""Filter by discount ID."""


OrdersListQueryParamCustomerIDFilterTypedDict = TypeAliasType(
    "OrdersListQueryParamCustomerIDFilterTypedDict", Union[str, List[str]]
)
r"""Filter by customer ID."""


OrdersListQueryParamCustomerIDFilter = TypeAliasType(
    "OrdersListQueryParamCustomerIDFilter", Union[str, List[str]]
)
r"""Filter by customer ID."""


OrdersListQueryParamExternalCustomerIDFilterTypedDict = TypeAliasType(
    "OrdersListQueryParamExternalCustomerIDFilterTypedDict", Union[str, List[str]]
)
r"""Filter by customer external ID."""


OrdersListQueryParamExternalCustomerIDFilter = TypeAliasType(
    "OrdersListQueryParamExternalCustomerIDFilter", Union[str, List[str]]
)
r"""Filter by customer external ID."""


CheckoutIDFilterTypedDict = TypeAliasType(
    "CheckoutIDFilterTypedDict", Union[str, List[str]]
)
r"""Filter by checkout ID."""


CheckoutIDFilter = TypeAliasType("CheckoutIDFilter", Union[str, List[str]])
r"""Filter by checkout ID."""


class OrdersListRequestTypedDict(TypedDict):
    organization_id: NotRequired[
        Nullable[OrdersListQueryParamOrganizationIDFilterTypedDict]
    ]
    r"""Filter by organization ID."""
    product_id: NotRequired[Nullable[OrdersListQueryParamProductIDFilterTypedDict]]
    r"""Filter by product ID."""
    product_billing_type: NotRequired[Nullable[ProductBillingTypeFilterTypedDict]]
    r"""Filter by product billing type. `recurring` will filter data corresponding to subscriptions creations or renewals. `one_time` will filter data corresponding to one-time purchases."""
    discount_id: NotRequired[Nullable[QueryParamDiscountIDFilterTypedDict]]
    r"""Filter by discount ID."""
    customer_id: NotRequired[Nullable[OrdersListQueryParamCustomerIDFilterTypedDict]]
    r"""Filter by customer ID."""
    external_customer_id: NotRequired[
        Nullable[OrdersListQueryParamExternalCustomerIDFilterTypedDict]
    ]
    r"""Filter by customer external ID."""
    checkout_id: NotRequired[Nullable[CheckoutIDFilterTypedDict]]
    r"""Filter by checkout ID."""
    page: NotRequired[int]
    r"""Page number, defaults to 1."""
    limit: NotRequired[int]
    r"""Size of a page, defaults to 10. Maximum is 100."""
    sorting: NotRequired[Nullable[List[OrderSortProperty]]]
    r"""Sorting criterion. Several criteria can be used simultaneously and will be applied in order. Add a minus sign `-` before the criteria name to sort by descending order."""
    metadata: NotRequired[Nullable[Dict[str, MetadataQueryTypedDict]]]
    r"""Filter by metadata key-value pairs. It uses the `deepObject` style, e.g. `?metadata[key]=value`."""


class OrdersListRequest(BaseModel):
    organization_id: Annotated[
        OptionalNullable[OrdersListQueryParamOrganizationIDFilter],
        FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
    ] = UNSET
    r"""Filter by organization ID."""

    product_id: Annotated[
        OptionalNullable[OrdersListQueryParamProductIDFilter],
        FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
    ] = UNSET
    r"""Filter by product ID."""

    product_billing_type: Annotated[
        OptionalNullable[ProductBillingTypeFilter],
        FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
    ] = UNSET
    r"""Filter by product billing type. `recurring` will filter data corresponding to subscriptions creations or renewals. `one_time` will filter data corresponding to one-time purchases."""

    discount_id: Annotated[
        OptionalNullable[QueryParamDiscountIDFilter],
        FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
    ] = UNSET
    r"""Filter by discount ID."""

    customer_id: Annotated[
        OptionalNullable[OrdersListQueryParamCustomerIDFilter],
        FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
    ] = UNSET
    r"""Filter by customer ID."""

    external_customer_id: Annotated[
        OptionalNullable[OrdersListQueryParamExternalCustomerIDFilter],
        FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
    ] = UNSET
    r"""Filter by customer external ID."""

    checkout_id: Annotated[
        OptionalNullable[CheckoutIDFilter],
        FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
    ] = UNSET
    r"""Filter by checkout ID."""

    page: Annotated[
        Optional[int],
        FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
    ] = 1
    r"""Page number, defaults to 1."""

    limit: Annotated[
        Optional[int],
        FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
    ] = 10
    r"""Size of a page, defaults to 10. Maximum is 100."""

    sorting: Annotated[
        OptionalNullable[List[OrderSortProperty]],
        FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
    ] = UNSET
    r"""Sorting criterion. Several criteria can be used simultaneously and will be applied in order. Add a minus sign `-` before the criteria name to sort by descending order."""

    metadata: Annotated[
        OptionalNullable[Dict[str, MetadataQuery]],
        FieldMetadata(query=QueryParamMetadata(style="deepObject", explode=True)),
    ] = UNSET
    r"""Filter by metadata key-value pairs. It uses the `deepObject` style, e.g. `?metadata[key]=value`."""

    @model_serializer(mode="wrap")
    def serialize_model(self, handler):
        optional_fields = [
            "organization_id",
            "product_id",
            "product_billing_type",
            "discount_id",
            "customer_id",
            "external_customer_id",
            "checkout_id",
            "page",
            "limit",
            "sorting",
            "metadata",
        ]
        nullable_fields = [
            "organization_id",
            "product_id",
            "product_billing_type",
            "discount_id",
            "customer_id",
            "external_customer_id",
            "checkout_id",
            "sorting",
            "metadata",
        ]
        null_default_fields = []

        serialized = handler(self)

        m = {}

        for n, f in type(self).model_fields.items():
            k = f.alias or n
            val = serialized.get(k)
            serialized.pop(k, None)

            optional_nullable = k in optional_fields and k in nullable_fields
            is_set = (
                self.__pydantic_fields_set__.intersection({n})
                or k in null_default_fields
            )  # pylint: disable=no-member

            if val is not None and val != UNSET_SENTINEL:
                m[k] = val
            elif val != UNSET_SENTINEL and (
                not k in optional_fields or (optional_nullable and is_set)
            ):
                m[k] = val

        return m


class OrdersListResponseTypedDict(TypedDict):
    result: ListResourceOrderTypedDict


class OrdersListResponse(BaseModel):
    next: Callable[[], Optional[OrdersListResponse]]

    result: ListResourceOrder


CustomersListQueryParamOrganizationIDFilterTypedDict = TypeAliasType(
    "CustomersListQueryParamOrganizationIDFilterTypedDict", Union[str, List[str]]
)
r"""Filter by organization ID."""


CustomersListQueryParamOrganizationIDFilter = TypeAliasType(
    "CustomersListQueryParamOrganizationIDFilter", Union[str, List[str]]
)
r"""Filter by organization ID."""


class CustomersListRequestTypedDict(TypedDict):
    organization_id: NotRequired[
        Nullable[CustomersListQueryParamOrganizationIDFilterTypedDict]
    ]
    r"""Filter by organization ID."""
    email: NotRequired[Nullable[str]]
    r"""Filter by exact email."""
    query: NotRequired[Nullable[str]]
    r"""Filter by name, email, or external ID."""
    page: NotRequired[int]
    r"""Page number, defaults to 1."""
    limit: NotRequired[int]
    r"""Size of a page, defaults to 10. Maximum is 100."""
    sorting: NotRequired[Nullable[List[CustomerSortProperty]]]
    r"""Sorting criterion. Several criteria can be used simultaneously and will be applied in order. Add a minus sign `-` before the criteria name to sort by descending order."""
    metadata: NotRequired[Nullable[Dict[str, MetadataQueryTypedDict]]]
    r"""Filter by metadata key-value pairs. It uses the `deepObject` style, e.g. `?metadata[key]=value`."""


class CustomersListRequest(BaseModel):
    organization_id: Annotated[
        OptionalNullable[CustomersListQueryParamOrganizationIDFilter],
        FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
    ] = UNSET
    r"""Filter by organization ID."""

    email: Annotated[
        OptionalNullable[str],
        FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
    ] = UNSET
    r"""Filter by exact email."""

    query: Annotated[
        OptionalNullable[str],
        FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
    ] = UNSET
    r"""Filter by name, email, or external ID."""

    page: Annotated[
        Optional[int],
        FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
    ] = 1
    r"""Page number, defaults to 1."""

    limit: Annotated[
        Optional[int],
        FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
    ] = 10
    r"""Size of a page, defaults to 10. Maximum is 100."""

    sorting: Annotated[
        OptionalNullable[List[CustomerSortProperty]],
        FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
    ] = UNSET
    r"""Sorting criterion. Several criteria can be used simultaneously and will be applied in order. Add a minus sign `-` before the criteria name to sort by descending order."""

    metadata: Annotated[
        OptionalNullable[Dict[str, MetadataQuery]],
        FieldMetadata(query=QueryParamMetadata(style="deepObject", explode=True)),
    ] = UNSET
    r"""Filter by metadata key-value pairs. It uses the `deepObject` style, e.g. `?metadata[key]=value`."""

    @model_serializer(mode="wrap")
    def serialize_model(self, handler):
        optional_fields = [
            "organization_id",
            "email",
            "query",
            "page",
            "limit",
            "sorting",
            "metadata",
        ]
        nullable_fields = ["organization_id", "email", "query", "sorting", "metadata"]
        null_default_fields = []

        serialized = handler(self)

        m = {}

        for n, f in type(self).model_fields.items():
            k = f.alias or n
            val = serialized.get(k)
            serialized.pop(k, None)

            optional_nullable = k in optional_fields and k in nullable_fields
            is_set = (
                self.__pydantic_fields_set__.intersection({n})
                or k in null_default_fields
            )  # pylint: disable=no-member

            if val is not None and val != UNSET_SENTINEL:
                m[k] = val
            elif val != UNSET_SENTINEL and (
                not k in optional_fields or (optional_nullable and is_set)
            ):
                m[k] = val

        return m


class CustomersListResponseTypedDict(TypedDict):
    result: ListResourceCustomerTypedDict


class CustomersListResponse(BaseModel):
    next: Callable[[], Optional[CustomersListResponse]]

    result: ListResourceCustomer


EventsListQueryParamOrganizationIDFilterTypedDict = TypeAliasType(
    "EventsListQueryParamOrganizationIDFilterTypedDict", Union[str, List[str]]
)
r"""Filter by organization ID."""


EventsListQueryParamOrganizationIDFilter = TypeAliasType(
    "EventsListQueryParamOrganizationIDFilter", Union[str, List[str]]
)
r"""Filter by organization ID."""


EventsListQueryParamCustomerIDFilterTypedDict = TypeAliasType(
    "EventsListQueryParamCustomerIDFilterTypedDict", Union[str, List[str]]
)
r"""Filter by customer ID."""


EventsListQueryParamCustomerIDFilter = TypeAliasType(
    "EventsListQueryParamCustomerIDFilter", Union[str, List[str]]
)
r"""Filter by customer ID."""


EventsListQueryParamExternalCustomerIDFilterTypedDict = TypeAliasType(
    "EventsListQueryParamExternalCustomerIDFilterTypedDict", Union[str, List[str]]
)
r"""Filter by external customer ID."""


EventsListQueryParamExternalCustomerIDFilter = TypeAliasType(
    "EventsListQueryParamExternalCustomerIDFilter", Union[str, List[str]]
)
r"""Filter by external customer ID."""


NameFilterTypedDict = TypeAliasType("NameFilterTypedDict", Union[str, List[str]])
r"""Filter by event name."""


NameFilter = TypeAliasType("NameFilter", Union[str, List[str]])
r"""Filter by event name."""


SourceFilterTypedDict = TypeAliasType(
    "SourceFilterTypedDict", Union[EventSource, List[EventSource]]
)
r"""Filter by event source."""


SourceFilter = TypeAliasType("SourceFilter", Union[EventSource, List[EventSource]])
r"""Filter by event source."""


class EventsListRequestTypedDict(TypedDict):
    filter_: NotRequired[Nullable[str]]
    r"""Filter events following filter clauses. JSON string following the same schema a meter filter clause."""
    start_timestamp: NotRequired[Nullable[datetime]]
    r"""Filter events after this timestamp."""
    end_timestamp: NotRequired[Nullable[datetime]]
    r"""Filter events before this timestamp."""
    organization_id: NotRequired[
        Nullable[EventsListQueryParamOrganizationIDFilterTypedDict]
    ]
    r"""Filter by organization ID."""
    customer_id: NotRequired[Nullable[EventsListQueryParamCustomerIDFilterTypedDict]]
    r"""Filter by customer ID."""
    external_customer_id: NotRequired[
        Nullable[EventsListQueryParamExternalCustomerIDFilterTypedDict]
    ]
    r"""Filter by external customer ID."""
    meter_id: NotRequired[Nullable[str]]
    r"""Filter by a meter filter clause."""
    name: NotRequired[Nullable[NameFilterTypedDict]]
    r"""Filter by event name."""
    source: NotRequired[Nullable[SourceFilterTypedDict]]
    r"""Filter by event source."""
    query: NotRequired[Nullable[str]]
    r"""Query to filter events."""
    parent_id: NotRequired[Nullable[str]]
    r"""When combined with depth, use this event as the anchor instead of root events."""
    depth: NotRequired[Nullable[int]]
    r"""Fetch descendants up to this depth. When set: 0=root events only, 1=roots+children, etc. Max 5. When not set, returns all events."""
    page: NotRequired[int]
    r"""Page number, defaults to 1."""
    limit: NotRequired[int]
    r"""Size of a page, defaults to 10. Maximum is 100."""
    sorting: NotRequired[Nullable[List[EventSortProperty]]]
    r"""Sorting criterion. Several criteria can be used simultaneously and will be applied in order. Add a minus sign `-` before the criteria name to sort by descending order."""
    metadata: NotRequired[Nullable[Dict[str, MetadataQueryTypedDict]]]
    r"""Filter by metadata key-value pairs. It uses the `deepObject` style, e.g. `?metadata[key]=value`."""


class EventsListRequest(BaseModel):
    filter_: Annotated[
        OptionalNullable[str],
        pydantic.Field(alias="filter"),
        FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
    ] = UNSET
    r"""Filter events following filter clauses. JSON string following the same schema a meter filter clause."""

    start_timestamp: Annotated[
        OptionalNullable[datetime],
        FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
    ] = UNSET
    r"""Filter events after this timestamp."""

    end_timestamp: Annotated[
        OptionalNullable[datetime],
        FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
    ] = UNSET
    r"""Filter events before this timestamp."""

    organization_id: Annotated[
        OptionalNullable[EventsListQueryParamOrganizationIDFilter],
        FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
    ] = UNSET
    r"""Filter by organization ID."""

    customer_id: Annotated[
        OptionalNullable[EventsListQueryParamCustomerIDFilter],
        FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
    ] = UNSET
    r"""Filter by customer ID."""

    external_customer_id: Annotated[
        OptionalNullable[EventsListQueryParamExternalCustomerIDFilter],
        FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
    ] = UNSET
    r"""Filter by external customer ID."""

    meter_id: Annotated[
        OptionalNullable[str],
        FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
    ] = UNSET
    r"""Filter by a meter filter clause."""

    name: Annotated[
        OptionalNullable[NameFilter],
        FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
    ] = UNSET
    r"""Filter by event name."""

    source: Annotated[
        OptionalNullable[SourceFilter],
        FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
    ] = UNSET
    r"""Filter by event source."""

    query: Annotated[
        OptionalNullable[str],
        FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
    ] = UNSET
    r"""Query to filter events."""

    parent_id: Annotated[
        OptionalNullable[str],
        FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
    ] = UNSET
    r"""When combined with depth, use this event as the anchor instead of root events."""

    depth: Annotated[
        OptionalNullable[int],
        FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
    ] = UNSET
    r"""Fetch descendants up to this depth. When set: 0=root events only, 1=roots+children, etc. Max 5. When not set, returns all events."""

    page: Annotated[
        Optional[int],
        FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
    ] = 1
    r"""Page number, defaults to 1."""

    limit: Annotated[
        Optional[int],
        FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
    ] = 10
    r"""Size of a page, defaults to 10. Maximum is 100."""

    sorting: Annotated[
        OptionalNullable[List[EventSortProperty]],
        FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
    ] = UNSET
    r"""Sorting criterion. Several criteria can be used simultaneously and will be applied in order. Add a minus sign `-` before the criteria name to sort by descending order."""

    metadata: Annotated[
        OptionalNullable[Dict[str, MetadataQuery]],
        FieldMetadata(query=QueryParamMetadata(style="deepObject", explode=True)),
    ] = UNSET
    r"""Filter by metadata key-value pairs. It uses the `deepObject` style, e.g. `?metadata[key]=value`."""

    @model_serializer(mode="wrap")
    def serialize_model(self, handler):
        optional_fields = [
            "filter",
            "start_timestamp",
            "end_timestamp",
            "organization_id",
            "customer_id",
            "external_customer_id",
            "meter_id",
            "name",
            "source",
            "query",
            "parent_id",
            "depth",
            "page",
            "limit",
            "sorting",
            "metadata",
        ]
        nullable_fields = [
            "filter",
            "start_timestamp",
            "end_timestamp",
            "organization_id",
            "customer_id",
            "external_customer_id",
            "meter_id",
            "name",
            "source",
            "query",
            "parent_id",
            "depth",
            "sorting",
            "metadata",
        ]
        null_default_fields = []

        serialized = handler(self)

        m = {}

        for n, f in type(self).model_fields.items():
            k = f.alias or n
            val = serialized.get(k)
            serialized.pop(k, None)

            optional_nullable = k in optional_fields and k in nullable_fields
            is_set = (
                self.__pydantic_fields_set__.intersection({n})
                or k in null_default_fields
            )  # pylint: disable=no-member

            if val is not None and val != UNSET_SENTINEL:
                m[k] = val
            elif val != UNSET_SENTINEL and (
                not k in optional_fields or (optional_nullable and is_set)
            ):
                m[k] = val

        return m


EventsListResponseEventsListTypedDict = TypeAliasType(
    "EventsListResponseEventsListTypedDict",
    Union[ListResourceEventTypedDict, ListResourceWithCursorPaginationEventTypedDict],
)
r"""Successful Response"""


EventsListResponseEventsList = TypeAliasType(
    "EventsListResponseEventsList",
    Union[ListResourceEvent, ListResourceWithCursorPaginationEvent],
)
r"""Successful Response"""


MetersListQueryParamOrganizationIDFilterTypedDict = TypeAliasType(
    "MetersListQueryParamOrganizationIDFilterTypedDict", Union[str, List[str]]
)
r"""Filter by organization ID."""


MetersListQueryParamOrganizationIDFilter = TypeAliasType(
    "MetersListQueryParamOrganizationIDFilter", Union[str, List[str]]
)
r"""Filter by organization ID."""


class MetersListRequestTypedDict(TypedDict):
    organization_id: NotRequired[
        Nullable[MetersListQueryParamOrganizationIDFilterTypedDict]
    ]
    r"""Filter by organization ID."""
    query: NotRequired[Nullable[str]]
    r"""Filter by name."""
    is_archived: NotRequired[Nullable[bool]]
    r"""Filter on archived meters."""
    page: NotRequired[int]
    r"""Page number, defaults to 1."""
    limit: NotRequired[int]
    r"""Size of a page, defaults to 10. Maximum is 100."""
    sorting: NotRequired[Nullable[List[MeterSortProperty]]]
    r"""Sorting criterion. Several criteria can be used simultaneously and will be applied in order. Add a minus sign `-` before the criteria name to sort by descending order."""
    metadata: NotRequired[Nullable[Dict[str, MetadataQueryTypedDict]]]
    r"""Filter by metadata key-value pairs. It uses the `deepObject` style, e.g. `?metadata[key]=value`."""


class MetersListRequest(BaseModel):
    organization_id: Annotated[
        OptionalNullable[MetersListQueryParamOrganizationIDFilter],
        FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
    ] = UNSET
    r"""Filter by organization ID."""

    query: Annotated[
        OptionalNullable[str],
        FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
    ] = UNSET
    r"""Filter by name."""

    is_archived: Annotated[
        OptionalNullable[bool],
        FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
    ] = UNSET
    r"""Filter on archived meters."""

    page: Annotated[
        Optional[int],
        FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
    ] = 1
    r"""Page number, defaults to 1."""

    limit: Annotated[
        Optional[int],
        FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
    ] = 10
    r"""Size of a page, defaults to 10. Maximum is 100."""

    sorting: Annotated[
        OptionalNullable[List[MeterSortProperty]],
        FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
    ] = UNSET
    r"""Sorting criterion. Several criteria can be used simultaneously and will be applied in order. Add a minus sign `-` before the criteria name to sort by descending order."""

    metadata: Annotated[
        OptionalNullable[Dict[str, MetadataQuery]],
        FieldMetadata(query=QueryParamMetadata(style="deepObject", explode=True)),
    ] = UNSET
    r"""Filter by metadata key-value pairs. It uses the `deepObject` style, e.g. `?metadata[key]=value`."""

    @model_serializer(mode="wrap")
    def serialize_model(self, handler):
        optional_fields = [
            "organization_id",
            "query",
            "is_archived",
            "page",
            "limit",
            "sorting",
            "metadata",
        ]
        nullable_fields = [
            "organization_id",
            "query",
            "is_archived",
            "sorting",
            "metadata",
        ]
        null_default_fields = []

        serialized = handler(self)

        m = {}

        for n, f in type(self).model_fields.items():
            k = f.alias or n
            val = serialized.get(k)
            serialized.pop(k, None)

            optional_nullable = k in optional_fields and k in nullable_fields
            is_set = (
                self.__pydantic_fields_set__.intersection({n})
                or k in null_default_fields
            )  # pylint: disable=no-member

            if val is not None and val != UNSET_SENTINEL:
                m[k] = val
            elif val != UNSET_SENTINEL and (
                not k in optional_fields or (optional_nullable and is_set)
            ):
                m[k] = val

        return m


class MetersListResponseTypedDict(TypedDict):
    result: ListResourceMeterTypedDict


class MetersListResponse(BaseModel):
    next: Callable[[], Optional[MetersListResponse]]

    result: ListResourceMeter


MetersQuantitiesQueryParamCustomerIDFilterTypedDict = TypeAliasType(
    "MetersQuantitiesQueryParamCustomerIDFilterTypedDict", Union[str, List[str]]
)
r"""Filter by customer ID."""


MetersQuantitiesQueryParamCustomerIDFilter = TypeAliasType(
    "MetersQuantitiesQueryParamCustomerIDFilter", Union[str, List[str]]
)
r"""Filter by customer ID."""


MetersQuantitiesQueryParamExternalCustomerIDFilterTypedDict = TypeAliasType(
    "MetersQuantitiesQueryParamExternalCustomerIDFilterTypedDict", Union[str, List[str]]
)
r"""Filter by external customer ID."""


MetersQuantitiesQueryParamExternalCustomerIDFilter = TypeAliasType(
    "MetersQuantitiesQueryParamExternalCustomerIDFilter", Union[str, List[str]]
)
r"""Filter by external customer ID."""


class MetersQuantitiesRequestTypedDict(TypedDict):
    id: str
    r"""The meter ID."""
    start_timestamp: datetime
    r"""Start timestamp."""
    end_timestamp: datetime
    r"""End timestamp."""
    interval: TimeInterval
    r"""Interval between two timestamps."""
    timezone: NotRequired[str]
    r"""Timezone to use for the timestamps. Default is UTC."""
    customer_id: NotRequired[
        Nullable[MetersQuantitiesQueryParamCustomerIDFilterTypedDict]
    ]
    r"""Filter by customer ID."""
    external_customer_id: NotRequired[
        Nullable[MetersQuantitiesQueryParamExternalCustomerIDFilterTypedDict]
    ]
    r"""Filter by external customer ID."""
    customer_aggregation_function: NotRequired[Nullable[AggregationFunction]]
    r"""If set, will first compute the quantities per customer before aggregating them using the given function. If not set, the quantities will be aggregated across all events."""
    metadata: NotRequired[Nullable[Dict[str, MetadataQueryTypedDict]]]
    r"""Filter by metadata key-value pairs. It uses the `deepObject` style, e.g. `?metadata[key]=value`."""


class MetersQuantitiesRequest(BaseModel):
    id: Annotated[
        str, FieldMetadata(path=PathParamMetadata(style="simple", explode=False))
    ]
    r"""The meter ID."""

    start_timestamp: Annotated[
        datetime, FieldMetadata(query=QueryParamMetadata(style="form", explode=True))
    ]
    r"""Start timestamp."""

    end_timestamp: Annotated[
        datetime, FieldMetadata(query=QueryParamMetadata(style="form", explode=True))
    ]
    r"""End timestamp."""

    interval: Annotated[
        TimeInterval,
        FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
    ]
    r"""Interval between two timestamps."""

    timezone: Annotated[
        Optional[str],
        FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
    ] = "UTC"
    r"""Timezone to use for the timestamps. Default is UTC."""

    customer_id: Annotated[
        OptionalNullable[MetersQuantitiesQueryParamCustomerIDFilter],
        FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
    ] = UNSET
    r"""Filter by customer ID."""

    external_customer_id: Annotated[
        OptionalNullable[MetersQuantitiesQueryParamExternalCustomerIDFilter],
        FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
    ] = UNSET
    r"""Filter by external customer ID."""

    customer_aggregation_function: Annotated[
        OptionalNullable[AggregationFunction],
        FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
    ] = UNSET
    r"""If set, will first compute the quantities per customer before aggregating them using the given function. If not set, the quantities will be aggregated across all events."""

    metadata: Annotated[
        OptionalNullable[Dict[str, MetadataQuery]],
        FieldMetadata(query=QueryParamMetadata(style="deepObject", explode=True)),
    ] = UNSET
    r"""Filter by metadata key-value pairs. It uses the `deepObject` style, e.g. `?metadata[key]=value`."""

    @model_serializer(mode="wrap")
    def serialize_model(self, handler):
        optional_fields = [
            "timezone",
            "customer_id",
            "external_customer_id",
            "customer_aggregation_function",
            "metadata",
        ]
        nullable_fields = [
            "customer_id",
            "external_customer_id",
            "customer_aggregation_function",
            "metadata",
        ]
        null_default_fields = []

        serialized = handler(self)

        m = {}

        for n, f in type(self).model_fields.items():
            k = f.alias or n
            val = serialized.get(k)
            serialized.pop(k, None)

            optional_nullable = k in optional_fields and k in nullable_fields
            is_set = (
                self.__pydantic_fields_set__.intersection({n})
                or k in null_default_fields
            )  # pylint: disable=no-member

            if val is not None and val != UNSET_SENTINEL:
                m[k] = val
            elif val != UNSET_SENTINEL and (
                not k in optional_fields or (optional_nullable and is_set)
            ):
                m[k] = val

        return m
