# coding: utf-8

"""
    Voucherify API

    Voucherify promotion engine REST API. Please see https://docs.voucherify.io/docs for more details.

    The version of the OpenAPI document: v2018-08-01
    Contact: support@voucherify.io
    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 datetime import datetime
from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr
from typing import Any, ClassVar, Dict, List, Optional
from voucherify.models.custom_event import CustomEvent
from voucherify.models.earning_rule import EarningRule
from voucherify.models.list_publications_item_valid_single_voucher import ListPublicationsItemValidSingleVoucher
from voucherify.models.loyalty_pending_points import LoyaltyPendingPoints
from voucherify.models.loyalty_points_bucket import LoyaltyPointsBucket
from voucherify.models.loyalty_tier import LoyaltyTier
from voucherify.models.member_activity_data_balance import MemberActivityDataBalance
from voucherify.models.member_activity_data_customer_event import MemberActivityDataCustomerEvent
from voucherify.models.member_activity_data_order import MemberActivityDataOrder
from voucherify.models.member_activity_data_redemption import MemberActivityDataRedemption
from voucherify.models.member_activity_data_transaction import MemberActivityDataTransaction
from voucherify.models.reward_assignment import RewardAssignment
from voucherify.models.simple_campaign import SimpleCampaign
from voucherify.models.simple_customer import SimpleCustomer
from voucherify.models.simple_event import SimpleEvent
from voucherify.models.simple_promotion_stack import SimplePromotionStack
from voucherify.models.simple_promotion_tier import SimplePromotionTier
from voucherify.models.simple_redemption import SimpleRedemption
from voucherify.models.simple_redemption_reward_result import SimpleRedemptionRewardResult
from voucherify.models.simple_referral_tier import SimpleReferralTier
from voucherify.models.simple_voucher import SimpleVoucher
from voucherify.models.voucher_balance import VoucherBalance
from typing import Optional, Set
from typing_extensions import Self

class MemberActivityData(BaseModel):
    """
    MemberActivityData
    """ # noqa: E501
    customer: Optional[SimpleCustomer] = None
    campaign: Optional[SimpleCampaign] = None
    loyalty_tier_from: Optional[LoyaltyTier] = None
    loyalty_tier_to: Optional[LoyaltyTier] = None
    created_at: Optional[datetime] = None
    loyalty_tier: Optional[LoyaltyTier] = None
    expiration_date: Optional[datetime] = None
    publication: Optional[ListPublicationsItemValidSingleVoucher] = None
    order: Optional[MemberActivityDataOrder] = None
    voucher: Optional[SimpleVoucher] = None
    holder: Optional[SimpleCustomer] = None
    promotion_tier: Optional[SimplePromotionTier] = None
    promotion_stack: Optional[SimplePromotionStack] = None
    redemption: Optional[MemberActivityDataRedemption] = None
    redemption_rollback: Optional[SimpleRedemption] = None
    reward: Optional[SimpleRedemptionRewardResult] = None
    referral_tier: Optional[SimpleReferralTier] = None
    balance: Optional[MemberActivityDataBalance] = None
    custom_event: Optional[CustomEvent] = None
    customer_event: Optional[MemberActivityDataCustomerEvent] = None
    earning_rule: Optional[EarningRule] = None
    event: Optional[SimpleEvent] = None
    reward_redemption: Optional[Dict[str, Any]] = None
    reward_assignment: Optional[RewardAssignment] = None
    source: Optional[StrictStr] = None
    transaction: Optional[MemberActivityDataTransaction] = None
    pending_points: Optional[LoyaltyPendingPoints] = None
    voucher_pending_points_balance: Optional[VoucherBalance] = None
    source_voucher: Optional[SimpleVoucher] = None
    destination_voucher: Optional[SimpleVoucher] = None
    points: Optional[StrictInt] = Field(default=None, description="The number of expired points.")
    buckets: Optional[List[LoyaltyPointsBucket]] = None
    __properties: ClassVar[List[str]] = ["customer", "campaign", "loyalty_tier_from", "loyalty_tier_to", "created_at", "loyalty_tier", "expiration_date", "publication", "order", "voucher", "holder", "promotion_tier", "promotion_stack", "redemption", "redemption_rollback", "reward", "referral_tier", "balance", "custom_event", "customer_event", "earning_rule", "event", "reward_redemption", "reward_assignment", "source", "transaction", "pending_points", "voucher_pending_points_balance", "source_voucher", "destination_voucher", "points", "buckets"]

    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 MemberActivityData 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 campaign
        if self.campaign:
            _dict['campaign'] = self.campaign.to_dict()
        # override the default output from pydantic by calling `to_dict()` of loyalty_tier_from
        if self.loyalty_tier_from:
            _dict['loyalty_tier_from'] = self.loyalty_tier_from.to_dict()
        # override the default output from pydantic by calling `to_dict()` of loyalty_tier_to
        if self.loyalty_tier_to:
            _dict['loyalty_tier_to'] = self.loyalty_tier_to.to_dict()
        # override the default output from pydantic by calling `to_dict()` of loyalty_tier
        if self.loyalty_tier:
            _dict['loyalty_tier'] = self.loyalty_tier.to_dict()
        # override the default output from pydantic by calling `to_dict()` of publication
        if self.publication:
            _dict['publication'] = self.publication.to_dict()
        # override the default output from pydantic by calling `to_dict()` of order
        if self.order:
            _dict['order'] = self.order.to_dict()
        # override the default output from pydantic by calling `to_dict()` of voucher
        if self.voucher:
            _dict['voucher'] = self.voucher.to_dict()
        # override the default output from pydantic by calling `to_dict()` of holder
        if self.holder:
            _dict['holder'] = self.holder.to_dict()
        # override the default output from pydantic by calling `to_dict()` of promotion_tier
        if self.promotion_tier:
            _dict['promotion_tier'] = self.promotion_tier.to_dict()
        # override the default output from pydantic by calling `to_dict()` of promotion_stack
        if self.promotion_stack:
            _dict['promotion_stack'] = self.promotion_stack.to_dict()
        # override the default output from pydantic by calling `to_dict()` of redemption
        if self.redemption:
            _dict['redemption'] = self.redemption.to_dict()
        # override the default output from pydantic by calling `to_dict()` of redemption_rollback
        if self.redemption_rollback:
            _dict['redemption_rollback'] = self.redemption_rollback.to_dict()
        # override the default output from pydantic by calling `to_dict()` of reward
        if self.reward:
            _dict['reward'] = self.reward.to_dict()
        # override the default output from pydantic by calling `to_dict()` of referral_tier
        if self.referral_tier:
            _dict['referral_tier'] = self.referral_tier.to_dict()
        # override the default output from pydantic by calling `to_dict()` of balance
        if self.balance:
            _dict['balance'] = self.balance.to_dict()
        # override the default output from pydantic by calling `to_dict()` of custom_event
        if self.custom_event:
            _dict['custom_event'] = self.custom_event.to_dict()
        # override the default output from pydantic by calling `to_dict()` of customer_event
        if self.customer_event:
            _dict['customer_event'] = self.customer_event.to_dict()
        # override the default output from pydantic by calling `to_dict()` of earning_rule
        if self.earning_rule:
            _dict['earning_rule'] = self.earning_rule.to_dict()
        # override the default output from pydantic by calling `to_dict()` of event
        if self.event:
            _dict['event'] = self.event.to_dict()
        # override the default output from pydantic by calling `to_dict()` of reward_assignment
        if self.reward_assignment:
            _dict['reward_assignment'] = self.reward_assignment.to_dict()
        # override the default output from pydantic by calling `to_dict()` of transaction
        if self.transaction:
            _dict['transaction'] = self.transaction.to_dict()
        # override the default output from pydantic by calling `to_dict()` of pending_points
        if self.pending_points:
            _dict['pending_points'] = self.pending_points.to_dict()
        # override the default output from pydantic by calling `to_dict()` of voucher_pending_points_balance
        if self.voucher_pending_points_balance:
            _dict['voucher_pending_points_balance'] = self.voucher_pending_points_balance.to_dict()
        # override the default output from pydantic by calling `to_dict()` of source_voucher
        if self.source_voucher:
            _dict['source_voucher'] = self.source_voucher.to_dict()
        # override the default output from pydantic by calling `to_dict()` of destination_voucher
        if self.destination_voucher:
            _dict['destination_voucher'] = self.destination_voucher.to_dict()
        # override the default output from pydantic by calling `to_dict()` of each item in buckets (list)
        _items = []
        if self.buckets:
            for _item_buckets in self.buckets:
                if _item_buckets:
                    _items.append(_item_buckets.to_dict())
            _dict['buckets'] = _items
        # set to None if created_at (nullable) is None
        # and model_fields_set contains the field
        if self.created_at is None and "created_at" in self.model_fields_set:
            _dict['created_at'] = None

        # set to None if expiration_date (nullable) is None
        # and model_fields_set contains the field
        if self.expiration_date is None and "expiration_date" in self.model_fields_set:
            _dict['expiration_date'] = None

        # set to None if order (nullable) is None
        # and model_fields_set contains the field
        if self.order is None and "order" in self.model_fields_set:
            _dict['order'] = None

        # set to None if redemption (nullable) is None
        # and model_fields_set contains the field
        if self.redemption is None and "redemption" in self.model_fields_set:
            _dict['redemption'] = None

        # set to None if balance (nullable) is None
        # and model_fields_set contains the field
        if self.balance is None and "balance" in self.model_fields_set:
            _dict['balance'] = None

        # set to None if customer_event (nullable) is None
        # and model_fields_set contains the field
        if self.customer_event is None and "customer_event" in self.model_fields_set:
            _dict['customer_event'] = None

        # set to None if reward_redemption (nullable) is None
        # and model_fields_set contains the field
        if self.reward_redemption is None and "reward_redemption" in self.model_fields_set:
            _dict['reward_redemption'] = None

        # set to None if source (nullable) is None
        # and model_fields_set contains the field
        if self.source is None and "source" in self.model_fields_set:
            _dict['source'] = None

        # set to None if transaction (nullable) is None
        # and model_fields_set contains the field
        if self.transaction is None and "transaction" in self.model_fields_set:
            _dict['transaction'] = None

        # set to None if points (nullable) is None
        # and model_fields_set contains the field
        if self.points is None and "points" in self.model_fields_set:
            _dict['points'] = None

        # set to None if buckets (nullable) is None
        # and model_fields_set contains the field
        if self.buckets is None and "buckets" in self.model_fields_set:
            _dict['buckets'] = None

        return _dict

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

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

        _obj = cls.model_validate({
            "customer": SimpleCustomer.from_dict(obj["customer"]) if obj.get("customer") is not None else None,
            "campaign": SimpleCampaign.from_dict(obj["campaign"]) if obj.get("campaign") is not None else None,
            "loyalty_tier_from": LoyaltyTier.from_dict(obj["loyalty_tier_from"]) if obj.get("loyalty_tier_from") is not None else None,
            "loyalty_tier_to": LoyaltyTier.from_dict(obj["loyalty_tier_to"]) if obj.get("loyalty_tier_to") is not None else None,
            "created_at": obj.get("created_at"),
            "loyalty_tier": LoyaltyTier.from_dict(obj["loyalty_tier"]) if obj.get("loyalty_tier") is not None else None,
            "expiration_date": obj.get("expiration_date"),
            "publication": ListPublicationsItemValidSingleVoucher.from_dict(obj["publication"]) if obj.get("publication") is not None else None,
            "order": MemberActivityDataOrder.from_dict(obj["order"]) if obj.get("order") is not None else None,
            "voucher": SimpleVoucher.from_dict(obj["voucher"]) if obj.get("voucher") is not None else None,
            "holder": SimpleCustomer.from_dict(obj["holder"]) if obj.get("holder") is not None else None,
            "promotion_tier": SimplePromotionTier.from_dict(obj["promotion_tier"]) if obj.get("promotion_tier") is not None else None,
            "promotion_stack": SimplePromotionStack.from_dict(obj["promotion_stack"]) if obj.get("promotion_stack") is not None else None,
            "redemption": MemberActivityDataRedemption.from_dict(obj["redemption"]) if obj.get("redemption") is not None else None,
            "redemption_rollback": SimpleRedemption.from_dict(obj["redemption_rollback"]) if obj.get("redemption_rollback") is not None else None,
            "reward": SimpleRedemptionRewardResult.from_dict(obj["reward"]) if obj.get("reward") is not None else None,
            "referral_tier": SimpleReferralTier.from_dict(obj["referral_tier"]) if obj.get("referral_tier") is not None else None,
            "balance": MemberActivityDataBalance.from_dict(obj["balance"]) if obj.get("balance") is not None else None,
            "custom_event": CustomEvent.from_dict(obj["custom_event"]) if obj.get("custom_event") is not None else None,
            "customer_event": MemberActivityDataCustomerEvent.from_dict(obj["customer_event"]) if obj.get("customer_event") is not None else None,
            "earning_rule": EarningRule.from_dict(obj["earning_rule"]) if obj.get("earning_rule") is not None else None,
            "event": SimpleEvent.from_dict(obj["event"]) if obj.get("event") is not None else None,
            "reward_redemption": obj.get("reward_redemption"),
            "reward_assignment": RewardAssignment.from_dict(obj["reward_assignment"]) if obj.get("reward_assignment") is not None else None,
            "source": obj.get("source"),
            "transaction": MemberActivityDataTransaction.from_dict(obj["transaction"]) if obj.get("transaction") is not None else None,
            "pending_points": LoyaltyPendingPoints.from_dict(obj["pending_points"]) if obj.get("pending_points") is not None else None,
            "voucher_pending_points_balance": VoucherBalance.from_dict(obj["voucher_pending_points_balance"]) if obj.get("voucher_pending_points_balance") is not None else None,
            "source_voucher": SimpleVoucher.from_dict(obj["source_voucher"]) if obj.get("source_voucher") is not None else None,
            "destination_voucher": SimpleVoucher.from_dict(obj["destination_voucher"]) if obj.get("destination_voucher") is not None else None,
            "points": obj.get("points"),
            "buckets": [LoyaltyPointsBucket.from_dict(_item) for _item in obj["buckets"]] if obj.get("buckets") is not None else None
        })
        return _obj


