"""cellpointapi.

This file was automatically generated by APIMATIC v3.0 ( https://www.apimatic.io ).
"""

# ruff: noqa: E501
from cellpointapi.api_helper import APIHelper
from cellpointapi.models.links import Links
from cellpointapi.models.non_negative_amount import (
    NonNegativeAmount,
)
from cellpointapi.models.order_status import (
    OrderStatus,
)


class OrderCore(object):
    """Implementation of the 'OrderCore' model.

    Core information about the order.

    Attributes:
        id (str): The model property of type str.
        status (OrderStatus): The model property of type OrderStatus.
        has_accepted_terms_and_conditions (bool): Whether the Terms and Conditions
            have been accepted. Before the order can transition to a PAID state, the
            terms and conditions must be accepted. See the `confirm-payments` and
            `authorize` operations.
        merchant_order_reference (str): Reference for identifying an order.
        order_group_id (str): Unique Identifier to use to create an Order Group.  An
            Order Group will allow for new orders to be linked against this order in
            the future.  Currently, we only support this feature if this id is passed
            at order creation time. Orders created without this cannot have it added
            to them later.  To link another order against this, make a call to
            [Create Connected Order](#tag/Orders/operation/create-connected-order).
            with a new order.  > Note: It is on the callers side to generate the
            unique id for this. It could be a UUID or something that hold business
            significance.   > **Creation of an order will fail, if this field has a
            value, that already exists.**  > **Creation of a connected order will
            fail, if this field is specified, as it should instead be specified as
            part of the URL.**
        created_at (datetime): When the order was created.
        expires_at (datetime): When the order expires for payment.  If no payments
            have been taken by this time, the order will be canceled with the reason
            of `ABANDONED`
        paid_at (datetime): When the order has finished being paid for.  At this
            time, there should be transactions with authorizations to cover the
            complete amount of the order.
        canceled_at (datetime): When the order was canceled.  Cancel reason can be
            found in `status.reason`.
        fulfilled_at (datetime): When the order was fulfilled.
        completed_at (datetime): When the order has been completed and closed.
        total_price (NonNegativeAmount): Total price of order to the buyer. Is the
            same as `priceSummary.totalPrice`
        fulfilled_order_amount (NonNegativeAmount): Total Amount in the order that
            was fulfilled by merchant during their fulfillment process.  Merchant
            sends the `fulfilledOrderAmount` in the [/orders/\<orderId\>/fulfillments
            endpoint](#tag/Orders/operation/fulfill-order).
        processing_fees_amount (NonNegativeAmount): Total amount of processing fees
            added to the order total, which is paid by the buyer.  Applicable only
            when a payment method requires a fee for processing payment.  If the
            `totalPrice` of the order is $1000, but the buyer uses a payment method
            with a $10 fee, then `processingFeesAmount` would be $10 and
            `paymentAmount` will be $1010.
        payment_amount (NonNegativeAmount): Total amount paid by a buyer.  If order
            `status` is `PAID`, it is equal to the sum of `totalPrice` and
            `processingFeesAmount`.  If order `status` is `FULFILLED` or `COMPLETED`,
            it is the sum of `fulfilledOrderAmount` and `processingFeesAmount`.
        links (Links): The model property of type Links.
        additional_properties (Dict[str, Any]): The additional properties for the
            model.

    """

    # Create a mapping from Model property names to API property names
    _names = {
        "merchant_order_reference": "merchantOrderReference",
        "id": "id",
        "status": "status",
        "has_accepted_terms_and_conditions": "hasAcceptedTermsAndConditions",
        "order_group_id": "orderGroupId",
        "created_at": "createdAt",
        "expires_at": "expiresAt",
        "paid_at": "paidAt",
        "canceled_at": "canceledAt",
        "fulfilled_at": "fulfilledAt",
        "completed_at": "completedAt",
        "total_price": "totalPrice",
        "fulfilled_order_amount": "fulfilledOrderAmount",
        "processing_fees_amount": "processingFeesAmount",
        "payment_amount": "paymentAmount",
        "links": "links",
    }

    _optionals = [
        "id",
        "status",
        "has_accepted_terms_and_conditions",
        "order_group_id",
        "created_at",
        "expires_at",
        "paid_at",
        "canceled_at",
        "fulfilled_at",
        "completed_at",
        "total_price",
        "fulfilled_order_amount",
        "processing_fees_amount",
        "payment_amount",
        "links",
    ]

    def __init__(
        self,
        merchant_order_reference=None,
        id=APIHelper.SKIP,
        status=APIHelper.SKIP,
        has_accepted_terms_and_conditions=APIHelper.SKIP,
        order_group_id=APIHelper.SKIP,
        created_at=APIHelper.SKIP,
        expires_at=APIHelper.SKIP,
        paid_at=APIHelper.SKIP,
        canceled_at=APIHelper.SKIP,
        fulfilled_at=APIHelper.SKIP,
        completed_at=APIHelper.SKIP,
        total_price=APIHelper.SKIP,
        fulfilled_order_amount=APIHelper.SKIP,
        processing_fees_amount=APIHelper.SKIP,
        payment_amount=APIHelper.SKIP,
        links=APIHelper.SKIP,
        additional_properties=None):
        """Initialize a OrderCore instance."""
        # Initialize members of the class
        if id is not APIHelper.SKIP:
            self.id = id
        if status is not APIHelper.SKIP:
            self.status = status
        if has_accepted_terms_and_conditions is not APIHelper.SKIP:
            self.has_accepted_terms_and_conditions =\
                 has_accepted_terms_and_conditions
        self.merchant_order_reference = merchant_order_reference
        if order_group_id is not APIHelper.SKIP:
            self.order_group_id = order_group_id
        if created_at is not APIHelper.SKIP:
            self.created_at =\
                 APIHelper.apply_datetime_converter(
                created_at, APIHelper.RFC3339DateTime)\
                 if created_at else None
        if expires_at is not APIHelper.SKIP:
            self.expires_at =\
                 APIHelper.apply_datetime_converter(
                expires_at, APIHelper.RFC3339DateTime)\
                 if expires_at else None
        if paid_at is not APIHelper.SKIP:
            self.paid_at =\
                 APIHelper.apply_datetime_converter(
                paid_at, APIHelper.RFC3339DateTime)\
                 if paid_at else None
        if canceled_at is not APIHelper.SKIP:
            self.canceled_at =\
                 APIHelper.apply_datetime_converter(
                canceled_at, APIHelper.RFC3339DateTime)\
                 if canceled_at else None
        if fulfilled_at is not APIHelper.SKIP:
            self.fulfilled_at =\
                 APIHelper.apply_datetime_converter(
                fulfilled_at, APIHelper.RFC3339DateTime)\
                 if fulfilled_at else None
        if completed_at is not APIHelper.SKIP:
            self.completed_at =\
                 APIHelper.apply_datetime_converter(
                completed_at, APIHelper.RFC3339DateTime)\
                 if completed_at else None
        if total_price is not APIHelper.SKIP:
            self.total_price = total_price
        if fulfilled_order_amount is not APIHelper.SKIP:
            self.fulfilled_order_amount = fulfilled_order_amount
        if processing_fees_amount is not APIHelper.SKIP:
            self.processing_fees_amount = processing_fees_amount
        if payment_amount is not APIHelper.SKIP:
            self.payment_amount = payment_amount
        if links is not APIHelper.SKIP:
            self.links = links

        # Add additional model properties to the instance
        if additional_properties is None:
            additional_properties = {}
        self.additional_properties = additional_properties

    @classmethod
    def from_dictionary(cls,
                        dictionary):
        """Create an instance of this model from a dictionary

        Args:
            dictionary (dictionary): A dictionary representation of the object
            as obtained from the deserialization of the server's response. The
            keys MUST match property names in the API description.

        Returns:
            object: An instance of this structure class.

        """
        if not isinstance(dictionary, dict) or dictionary is None:
            return None

        # Extract variables from the dictionary
        merchant_order_reference =\
            dictionary.get("merchantOrderReference")\
            if dictionary.get("merchantOrderReference")\
                else None
        id =\
            dictionary.get("id")\
            if dictionary.get("id")\
                else APIHelper.SKIP
        status =\
            OrderStatus.from_dictionary(
                dictionary.get("status"))\
                if "status" in dictionary.keys()\
                else APIHelper.SKIP
        has_accepted_terms_and_conditions =\
            dictionary.get("hasAcceptedTermsAndConditions")\
            if "hasAcceptedTermsAndConditions" in dictionary.keys()\
                else APIHelper.SKIP
        order_group_id =\
            dictionary.get("orderGroupId")\
            if dictionary.get("orderGroupId")\
                else APIHelper.SKIP
        created_at = APIHelper.RFC3339DateTime.from_value(
            dictionary.get("createdAt")).datetime\
            if dictionary.get("createdAt") else APIHelper.SKIP
        expires_at = APIHelper.RFC3339DateTime.from_value(
            dictionary.get("expiresAt")).datetime\
            if dictionary.get("expiresAt") else APIHelper.SKIP
        paid_at = APIHelper.RFC3339DateTime.from_value(
            dictionary.get("paidAt")).datetime\
            if dictionary.get("paidAt") else APIHelper.SKIP
        canceled_at = APIHelper.RFC3339DateTime.from_value(
            dictionary.get("canceledAt")).datetime\
            if dictionary.get("canceledAt") else APIHelper.SKIP
        fulfilled_at = APIHelper.RFC3339DateTime.from_value(
            dictionary.get("fulfilledAt")).datetime\
            if dictionary.get("fulfilledAt") else APIHelper.SKIP
        completed_at = APIHelper.RFC3339DateTime.from_value(
            dictionary.get("completedAt")).datetime\
            if dictionary.get("completedAt") else APIHelper.SKIP
        total_price =\
            NonNegativeAmount.from_dictionary(
                dictionary.get("totalPrice"))\
                if "totalPrice" in dictionary.keys()\
                else APIHelper.SKIP
        fulfilled_order_amount =\
            NonNegativeAmount.from_dictionary(
                dictionary.get("fulfilledOrderAmount"))\
                if "fulfilledOrderAmount" in dictionary.keys()\
                else APIHelper.SKIP
        processing_fees_amount =\
            NonNegativeAmount.from_dictionary(
                dictionary.get("processingFeesAmount"))\
                if "processingFeesAmount" in dictionary.keys()\
                else APIHelper.SKIP
        payment_amount =\
            NonNegativeAmount.from_dictionary(
                dictionary.get("paymentAmount"))\
                if "paymentAmount" in dictionary.keys()\
                else APIHelper.SKIP
        links =\
            Links.from_dictionary(
                dictionary.get("links"))\
                if "links" in dictionary.keys()\
                else APIHelper.SKIP

        additional_properties = APIHelper.get_additional_properties(
            dictionary={k: v for k, v in dictionary.items()
                        if k not in cls._names.values()},
            unboxing_function=lambda value: value)

        # Return an object of this model
        return cls(merchant_order_reference,
                   id,
                   status,
                   has_accepted_terms_and_conditions,
                   order_group_id,
                   created_at,
                   expires_at,
                   paid_at,
                   canceled_at,
                   fulfilled_at,
                   completed_at,
                   total_price,
                   fulfilled_order_amount,
                   processing_fees_amount,
                   payment_amount,
                   links,
                   additional_properties)

    @classmethod
    def validate(cls, dictionary):
        """Validate dictionary against class required properties

        Args:
            dictionary (dictionary): A dictionary representation of the object
            as obtained from the deserialization of the server's response. The
            keys MUST match property names in the API description.

        Returns:
            boolean : if dictionary is valid contains required properties.

        """
        if isinstance(dictionary, cls):
            return APIHelper.is_valid_type(
                    value=dictionary.merchant_order_reference,
                    type_callable=lambda value:
                        isinstance(
                        value,
                        str,
                ))

        if not isinstance(dictionary, dict):
            return False

        return APIHelper.is_valid_type(
                value=dictionary.get("merchantOrderReference"),
                type_callable=lambda value:
                    isinstance(
                    value,
                    str,
            ))

    def __repr__(self):
        """Return a unambiguous string representation."""
        _id=(
            self.id
            if hasattr(self, "id")
            else None
        )
        _status=(
            self.status
            if hasattr(self, "status")
            else None
        )
        _has_accepted_terms_and_conditions=(
            self.has_accepted_terms_and_conditions
            if hasattr(self, "has_accepted_terms_and_conditions")
            else None
        )
        _merchant_order_reference=self.merchant_order_reference
        _order_group_id=(
            self.order_group_id
            if hasattr(self, "order_group_id")
            else None
        )
        _created_at=(
            self.created_at
            if hasattr(self, "created_at")
            else None
        )
        _expires_at=(
            self.expires_at
            if hasattr(self, "expires_at")
            else None
        )
        _paid_at=(
            self.paid_at
            if hasattr(self, "paid_at")
            else None
        )
        _canceled_at=(
            self.canceled_at
            if hasattr(self, "canceled_at")
            else None
        )
        _fulfilled_at=(
            self.fulfilled_at
            if hasattr(self, "fulfilled_at")
            else None
        )
        _completed_at=(
            self.completed_at
            if hasattr(self, "completed_at")
            else None
        )
        _total_price=(
            self.total_price
            if hasattr(self, "total_price")
            else None
        )
        _fulfilled_order_amount=(
            self.fulfilled_order_amount
            if hasattr(self, "fulfilled_order_amount")
            else None
        )
        _processing_fees_amount=(
            self.processing_fees_amount
            if hasattr(self, "processing_fees_amount")
            else None
        )
        _payment_amount=(
            self.payment_amount
            if hasattr(self, "payment_amount")
            else None
        )
        _links=(
            self.links
            if hasattr(self, "links")
            else None
        )
        _additional_properties=self.additional_properties
        return (
            f"{self.__class__.__name__}("
            f"id={_id!r}, "
            f"status={_status!r}, "
            f"has_accepted_terms_and_conditions={_has_accepted_terms_and_conditions!r}, "
            f"merchant_order_reference={_merchant_order_reference!r}, "
            f"order_group_id={_order_group_id!r}, "
            f"created_at={_created_at!r}, "
            f"expires_at={_expires_at!r}, "
            f"paid_at={_paid_at!r}, "
            f"canceled_at={_canceled_at!r}, "
            f"fulfilled_at={_fulfilled_at!r}, "
            f"completed_at={_completed_at!r}, "
            f"total_price={_total_price!r}, "
            f"fulfilled_order_amount={_fulfilled_order_amount!r}, "
            f"processing_fees_amount={_processing_fees_amount!r}, "
            f"payment_amount={_payment_amount!r}, "
            f"links={_links!r}, "
            f"additional_properties={_additional_properties!r}, "
            f")"
        )

    def __str__(self):
        """Return a human-readable string representation."""
        _id=(
            self.id
            if hasattr(self, "id")
            else None
        )
        _status=(
            self.status
            if hasattr(self, "status")
            else None
        )
        _has_accepted_terms_and_conditions=(
            self.has_accepted_terms_and_conditions
            if hasattr(self, "has_accepted_terms_and_conditions")
            else None
        )
        _merchant_order_reference=self.merchant_order_reference
        _order_group_id=(
            self.order_group_id
            if hasattr(self, "order_group_id")
            else None
        )
        _created_at=(
            self.created_at
            if hasattr(self, "created_at")
            else None
        )
        _expires_at=(
            self.expires_at
            if hasattr(self, "expires_at")
            else None
        )
        _paid_at=(
            self.paid_at
            if hasattr(self, "paid_at")
            else None
        )
        _canceled_at=(
            self.canceled_at
            if hasattr(self, "canceled_at")
            else None
        )
        _fulfilled_at=(
            self.fulfilled_at
            if hasattr(self, "fulfilled_at")
            else None
        )
        _completed_at=(
            self.completed_at
            if hasattr(self, "completed_at")
            else None
        )
        _total_price=(
            self.total_price
            if hasattr(self, "total_price")
            else None
        )
        _fulfilled_order_amount=(
            self.fulfilled_order_amount
            if hasattr(self, "fulfilled_order_amount")
            else None
        )
        _processing_fees_amount=(
            self.processing_fees_amount
            if hasattr(self, "processing_fees_amount")
            else None
        )
        _payment_amount=(
            self.payment_amount
            if hasattr(self, "payment_amount")
            else None
        )
        _links=(
            self.links
            if hasattr(self, "links")
            else None
        )
        _additional_properties=self.additional_properties
        return (
            f"{self.__class__.__name__}("
            f"id={_id!s}, "
            f"status={_status!s}, "
            f"has_accepted_terms_and_conditions={_has_accepted_terms_and_conditions!s}, "
            f"merchant_order_reference={_merchant_order_reference!s}, "
            f"order_group_id={_order_group_id!s}, "
            f"created_at={_created_at!s}, "
            f"expires_at={_expires_at!s}, "
            f"paid_at={_paid_at!s}, "
            f"canceled_at={_canceled_at!s}, "
            f"fulfilled_at={_fulfilled_at!s}, "
            f"completed_at={_completed_at!s}, "
            f"total_price={_total_price!s}, "
            f"fulfilled_order_amount={_fulfilled_order_amount!s}, "
            f"processing_fees_amount={_processing_fees_amount!s}, "
            f"payment_amount={_payment_amount!s}, "
            f"links={_links!s}, "
            f"additional_properties={_additional_properties!s}, "
            f")"
        )
