# coding: utf-8

"""
    FlexPrice API

    FlexPrice API Service

    The version of the OpenAPI document: 1.0
    Generated by OpenAPI Generator (https://openapi-generator.tech)

    Do not edit the class manually.
"""  # noqa: E501


from __future__ import annotations
import pprint
import re  # noqa: F401
import json

from pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictInt, StrictStr
from typing import Any, ClassVar, Dict, List, Optional
from flexprice.models.dto_customer_response import DtoCustomerResponse
from flexprice.models.dto_plan_response import DtoPlanResponse
from flexprice.models.subscription_subscription_line_item import SubscriptionSubscriptionLineItem
from flexprice.models.subscription_subscription_pause import SubscriptionSubscriptionPause
from flexprice.models.types_billing_cadence import TypesBillingCadence
from flexprice.models.types_billing_cycle import TypesBillingCycle
from flexprice.models.types_billing_period import TypesBillingPeriod
from flexprice.models.types_pause_status import TypesPauseStatus
from flexprice.models.types_status import TypesStatus
from flexprice.models.types_subscription_status import TypesSubscriptionStatus
from typing import Optional, Set
from typing_extensions import Self

class DtoSubscriptionResponse(BaseModel):
    """
    DtoSubscriptionResponse
    """ # noqa: E501
    active_pause_id: Optional[StrictStr] = Field(default=None, description="ActivePauseID references the current active pause configuration This will be null if no pause is active or scheduled")
    billing_anchor: Optional[StrictStr] = Field(default=None, description="BillingAnchor is the reference point that aligns future billing cycle dates. It sets the day of week for week intervals, the day of month for month and year intervals, and the month of year for year intervals. The timestamp is in UTC format.")
    billing_cadence: Optional[TypesBillingCadence] = None
    billing_cycle: Optional[TypesBillingCycle] = None
    billing_period: Optional[TypesBillingPeriod] = None
    billing_period_count: Optional[StrictInt] = Field(default=None, description="BillingPeriodCount is the total number units of the billing period.")
    cancel_at: Optional[StrictStr] = Field(default=None, description="CancelAt is the date the subscription will be canceled")
    cancel_at_period_end: Optional[StrictBool] = Field(default=None, description="CancelAtPeriodEnd is whether the subscription was canceled at the end of the current period")
    cancelled_at: Optional[StrictStr] = Field(default=None, description="CanceledAt is the date the subscription was canceled")
    created_at: Optional[StrictStr] = None
    created_by: Optional[StrictStr] = None
    currency: Optional[StrictStr] = Field(default=None, description="Currency is the currency of the subscription in lowercase 3 digit ISO codes")
    current_period_end: Optional[StrictStr] = Field(default=None, description="CurrentPeriodEnd is the end of the current period that the subscription has been invoiced for. At the end of this period, a new invoice will be created.")
    current_period_start: Optional[StrictStr] = Field(default=None, description="CurrentPeriodStart is the end of the current period that the subscription has been invoiced for. At the end of this period, a new invoice will be created.")
    customer: Optional[DtoCustomerResponse] = None
    customer_id: Optional[StrictStr] = Field(default=None, description="CustomerID is the identifier for the customer in our system")
    end_date: Optional[StrictStr] = Field(default=None, description="EndDate is the end date of the subscription")
    environment_id: Optional[StrictStr] = Field(default=None, description="EnvironmentID is the environment identifier for the subscription")
    id: Optional[StrictStr] = Field(default=None, description="ID is the unique identifier for the subscription")
    line_items: Optional[List[SubscriptionSubscriptionLineItem]] = None
    lookup_key: Optional[StrictStr] = Field(default=None, description="LookupKey is the key used to lookup the subscription in our system")
    metadata: Optional[Dict[str, StrictStr]] = None
    pause_status: Optional[TypesPauseStatus] = None
    pauses: Optional[List[SubscriptionSubscriptionPause]] = None
    plan: Optional[DtoPlanResponse] = None
    plan_id: Optional[StrictStr] = Field(default=None, description="PlanID is the identifier for the plan in our system")
    start_date: Optional[StrictStr] = Field(default=None, description="StartDate is the start date of the subscription")
    status: Optional[TypesStatus] = None
    subscription_status: Optional[TypesSubscriptionStatus] = None
    tenant_id: Optional[StrictStr] = None
    trial_end: Optional[StrictStr] = Field(default=None, description="TrialEnd is the end date of the trial period")
    trial_start: Optional[StrictStr] = Field(default=None, description="TrialStart is the start date of the trial period")
    updated_at: Optional[StrictStr] = None
    updated_by: Optional[StrictStr] = None
    version: Optional[StrictInt] = Field(default=None, description="Version is used for optimistic locking")
    __properties: ClassVar[List[str]] = ["active_pause_id", "billing_anchor", "billing_cadence", "billing_cycle", "billing_period", "billing_period_count", "cancel_at", "cancel_at_period_end", "cancelled_at", "created_at", "created_by", "currency", "current_period_end", "current_period_start", "customer", "customer_id", "end_date", "environment_id", "id", "line_items", "lookup_key", "metadata", "pause_status", "pauses", "plan", "plan_id", "start_date", "status", "subscription_status", "tenant_id", "trial_end", "trial_start", "updated_at", "updated_by", "version"]

    model_config = ConfigDict(
        populate_by_name=True,
        validate_assignment=True,
        protected_namespaces=(),
    )


    def to_str(self) -> str:
        """Returns the string representation of the model using alias"""
        return pprint.pformat(self.model_dump(by_alias=True))

    def to_json(self) -> str:
        """Returns the JSON representation of the model using alias"""
        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead
        return json.dumps(self.to_dict())

    @classmethod
    def from_json(cls, json_str: str) -> Optional[Self]:
        """Create an instance of DtoSubscriptionResponse from a JSON string"""
        return cls.from_dict(json.loads(json_str))

    def to_dict(self) -> Dict[str, Any]:
        """Return the dictionary representation of the model using alias.

        This has the following differences from calling pydantic's
        `self.model_dump(by_alias=True)`:

        * `None` is only added to the output dict for nullable fields that
          were set at model initialization. Other fields with value `None`
          are ignored.
        """
        excluded_fields: Set[str] = set([
        ])

        _dict = self.model_dump(
            by_alias=True,
            exclude=excluded_fields,
            exclude_none=True,
        )
        # override the default output from pydantic by calling `to_dict()` of customer
        if self.customer:
            _dict['customer'] = self.customer.to_dict()
        # override the default output from pydantic by calling `to_dict()` of each item in line_items (list)
        _items = []
        if self.line_items:
            for _item_line_items in self.line_items:
                if _item_line_items:
                    _items.append(_item_line_items.to_dict())
            _dict['line_items'] = _items
        # override the default output from pydantic by calling `to_dict()` of each item in pauses (list)
        _items = []
        if self.pauses:
            for _item_pauses in self.pauses:
                if _item_pauses:
                    _items.append(_item_pauses.to_dict())
            _dict['pauses'] = _items
        # override the default output from pydantic by calling `to_dict()` of plan
        if self.plan:
            _dict['plan'] = self.plan.to_dict()
        return _dict

    @classmethod
    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:
        """Create an instance of DtoSubscriptionResponse from a dict"""
        if obj is None:
            return None

        if not isinstance(obj, dict):
            return cls.model_validate(obj)

        _obj = cls.model_validate({
            "active_pause_id": obj.get("active_pause_id"),
            "billing_anchor": obj.get("billing_anchor"),
            "billing_cadence": obj.get("billing_cadence"),
            "billing_cycle": obj.get("billing_cycle"),
            "billing_period": obj.get("billing_period"),
            "billing_period_count": obj.get("billing_period_count"),
            "cancel_at": obj.get("cancel_at"),
            "cancel_at_period_end": obj.get("cancel_at_period_end"),
            "cancelled_at": obj.get("cancelled_at"),
            "created_at": obj.get("created_at"),
            "created_by": obj.get("created_by"),
            "currency": obj.get("currency"),
            "current_period_end": obj.get("current_period_end"),
            "current_period_start": obj.get("current_period_start"),
            "customer": DtoCustomerResponse.from_dict(obj["customer"]) if obj.get("customer") is not None else None,
            "customer_id": obj.get("customer_id"),
            "end_date": obj.get("end_date"),
            "environment_id": obj.get("environment_id"),
            "id": obj.get("id"),
            "line_items": [SubscriptionSubscriptionLineItem.from_dict(_item) for _item in obj["line_items"]] if obj.get("line_items") is not None else None,
            "lookup_key": obj.get("lookup_key"),
            "metadata": obj.get("metadata"),
            "pause_status": obj.get("pause_status"),
            "pauses": [SubscriptionSubscriptionPause.from_dict(_item) for _item in obj["pauses"]] if obj.get("pauses") is not None else None,
            "plan": DtoPlanResponse.from_dict(obj["plan"]) if obj.get("plan") is not None else None,
            "plan_id": obj.get("plan_id"),
            "start_date": obj.get("start_date"),
            "status": obj.get("status"),
            "subscription_status": obj.get("subscription_status"),
            "tenant_id": obj.get("tenant_id"),
            "trial_end": obj.get("trial_end"),
            "trial_start": obj.get("trial_start"),
            "updated_at": obj.get("updated_at"),
            "updated_by": obj.get("updated_by"),
            "version": obj.get("version")
        })
        return _obj


