# coding: utf-8

"""
Copyright 2017 Square, Inc.

    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at

        http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.
"""


from pprint import pformat
from six import iteritems
import re


class Order(object):
    """
    NOTE: This class is auto generated by the swagger code generator program.
    Do not edit the class manually.
    """
    def __init__(self, id=None, location_id=None, reference_id=None, source=None, customer_id=None, line_items=None, taxes=None, discounts=None, service_charges=None, fulfillments=None, returns=None, return_amounts=None, net_amounts=None, rounding_adjustment=None, tenders=None, refunds=None, created_at=None, updated_at=None, closed_at=None, state=None, total_money=None, total_tax_money=None, total_discount_money=None, total_service_charge_money=None):
        """
        Order - a model defined in Swagger

        :param dict swaggerTypes: The key is attribute name
                                  and the value is attribute type.
        :param dict attributeMap: The key is attribute name
                                  and the value is json key in definition.
        """
        self.swagger_types = {
            'id': 'str',
            'location_id': 'str',
            'reference_id': 'str',
            'source': 'OrderSource',
            'customer_id': 'str',
            'line_items': 'list[OrderLineItem]',
            'taxes': 'list[OrderLineItemTax]',
            'discounts': 'list[OrderLineItemDiscount]',
            'service_charges': 'list[OrderServiceCharge]',
            'fulfillments': 'list[OrderFulfillment]',
            'returns': 'list[OrderReturn]',
            'return_amounts': 'OrderMoneyAmounts',
            'net_amounts': 'OrderMoneyAmounts',
            'rounding_adjustment': 'OrderRoundingAdjustment',
            'tenders': 'list[Tender]',
            'refunds': 'list[Refund]',
            'created_at': 'str',
            'updated_at': 'str',
            'closed_at': 'str',
            'state': 'str',
            'total_money': 'Money',
            'total_tax_money': 'Money',
            'total_discount_money': 'Money',
            'total_service_charge_money': 'Money'
        }

        self.attribute_map = {
            'id': 'id',
            'location_id': 'location_id',
            'reference_id': 'reference_id',
            'source': 'source',
            'customer_id': 'customer_id',
            'line_items': 'line_items',
            'taxes': 'taxes',
            'discounts': 'discounts',
            'service_charges': 'service_charges',
            'fulfillments': 'fulfillments',
            'returns': 'returns',
            'return_amounts': 'return_amounts',
            'net_amounts': 'net_amounts',
            'rounding_adjustment': 'rounding_adjustment',
            'tenders': 'tenders',
            'refunds': 'refunds',
            'created_at': 'created_at',
            'updated_at': 'updated_at',
            'closed_at': 'closed_at',
            'state': 'state',
            'total_money': 'total_money',
            'total_tax_money': 'total_tax_money',
            'total_discount_money': 'total_discount_money',
            'total_service_charge_money': 'total_service_charge_money'
        }

        self._id = id
        self._location_id = location_id
        self._reference_id = reference_id
        self._source = source
        self._customer_id = customer_id
        self._line_items = line_items
        self._taxes = taxes
        self._discounts = discounts
        self._service_charges = service_charges
        self._fulfillments = fulfillments
        self._returns = returns
        self._return_amounts = return_amounts
        self._net_amounts = net_amounts
        self._rounding_adjustment = rounding_adjustment
        self._tenders = tenders
        self._refunds = refunds
        self._created_at = created_at
        self._updated_at = updated_at
        self._closed_at = closed_at
        self._state = state
        self._total_money = total_money
        self._total_tax_money = total_tax_money
        self._total_discount_money = total_discount_money
        self._total_service_charge_money = total_service_charge_money

    @property
    def id(self):
        """
        Gets the id of this Order.
        The order's unique ID.  This field is read-only.

        :return: The id of this Order.
        :rtype: str
        """
        return self._id

    @id.setter
    def id(self, id):
        """
        Sets the id of this Order.
        The order's unique ID.  This field is read-only.

        :param id: The id of this Order.
        :type: str
        """

        self._id = id

    @property
    def location_id(self):
        """
        Gets the location_id of this Order.
        The ID of the merchant location this order is associated with.

        :return: The location_id of this Order.
        :rtype: str
        """
        return self._location_id

    @location_id.setter
    def location_id(self, location_id):
        """
        Sets the location_id of this Order.
        The ID of the merchant location this order is associated with.

        :param location_id: The location_id of this Order.
        :type: str
        """

        if location_id is None:
            raise ValueError("Invalid value for `location_id`, must not be `None`")
        if len(location_id) < 1:
            raise ValueError("Invalid value for `location_id`, length must be greater than or equal to `1`")

        self._location_id = location_id

    @property
    def reference_id(self):
        """
        Gets the reference_id of this Order.
        A client specified identifier to associate an entity in another system with this order.

        :return: The reference_id of this Order.
        :rtype: str
        """
        return self._reference_id

    @reference_id.setter
    def reference_id(self, reference_id):
        """
        Sets the reference_id of this Order.
        A client specified identifier to associate an entity in another system with this order.

        :param reference_id: The reference_id of this Order.
        :type: str
        """

        if reference_id is None:
            raise ValueError("Invalid value for `reference_id`, must not be `None`")
        if len(reference_id) > 40:
            raise ValueError("Invalid value for `reference_id`, length must be less than `40`")

        self._reference_id = reference_id

    @property
    def source(self):
        """
        Gets the source of this Order.
        The origination details of the order.

        :return: The source of this Order.
        :rtype: OrderSource
        """
        return self._source

    @source.setter
    def source(self, source):
        """
        Sets the source of this Order.
        The origination details of the order.

        :param source: The source of this Order.
        :type: OrderSource
        """

        self._source = source

    @property
    def customer_id(self):
        """
        Gets the customer_id of this Order.
        The [Customer](#type-customer) ID of the customer associated with the order.

        :return: The customer_id of this Order.
        :rtype: str
        """
        return self._customer_id

    @customer_id.setter
    def customer_id(self, customer_id):
        """
        Sets the customer_id of this Order.
        The [Customer](#type-customer) ID of the customer associated with the order.

        :param customer_id: The customer_id of this Order.
        :type: str
        """

        self._customer_id = customer_id

    @property
    def line_items(self):
        """
        Gets the line_items of this Order.
        The line items included in the order.

        :return: The line_items of this Order.
        :rtype: list[OrderLineItem]
        """
        return self._line_items

    @line_items.setter
    def line_items(self, line_items):
        """
        Sets the line_items of this Order.
        The line items included in the order.

        :param line_items: The line_items of this Order.
        :type: list[OrderLineItem]
        """

        self._line_items = line_items

    @property
    def taxes(self):
        """
        Gets the taxes of this Order.
        A list of taxes applied to this order. On read or retrieve, this list includes both order-level and item-level taxes. When creating an Order, set your order-level taxes in this list.

        :return: The taxes of this Order.
        :rtype: list[OrderLineItemTax]
        """
        return self._taxes

    @taxes.setter
    def taxes(self, taxes):
        """
        Sets the taxes of this Order.
        A list of taxes applied to this order. On read or retrieve, this list includes both order-level and item-level taxes. When creating an Order, set your order-level taxes in this list.

        :param taxes: The taxes of this Order.
        :type: list[OrderLineItemTax]
        """

        self._taxes = taxes

    @property
    def discounts(self):
        """
        Gets the discounts of this Order.
        A list of discounts applied to this order. On read or retrieve, this list includes both order-level and item-level discounts. When creating an Order, set your order-level discounts in this list.

        :return: The discounts of this Order.
        :rtype: list[OrderLineItemDiscount]
        """
        return self._discounts

    @discounts.setter
    def discounts(self, discounts):
        """
        Sets the discounts of this Order.
        A list of discounts applied to this order. On read or retrieve, this list includes both order-level and item-level discounts. When creating an Order, set your order-level discounts in this list.

        :param discounts: The discounts of this Order.
        :type: list[OrderLineItemDiscount]
        """

        self._discounts = discounts

    @property
    def service_charges(self):
        """
        Gets the service_charges of this Order.
        A list of service charges applied to the order.

        :return: The service_charges of this Order.
        :rtype: list[OrderServiceCharge]
        """
        return self._service_charges

    @service_charges.setter
    def service_charges(self, service_charges):
        """
        Sets the service_charges of this Order.
        A list of service charges applied to the order.

        :param service_charges: The service_charges of this Order.
        :type: list[OrderServiceCharge]
        """

        self._service_charges = service_charges

    @property
    def fulfillments(self):
        """
        Gets the fulfillments of this Order.
        Details on order fulfillment.  Orders can only be created with at most one fulfillment. However, orders returned by the API may contain multiple fulfillments.

        :return: The fulfillments of this Order.
        :rtype: list[OrderFulfillment]
        """
        return self._fulfillments

    @fulfillments.setter
    def fulfillments(self, fulfillments):
        """
        Sets the fulfillments of this Order.
        Details on order fulfillment.  Orders can only be created with at most one fulfillment. However, orders returned by the API may contain multiple fulfillments.

        :param fulfillments: The fulfillments of this Order.
        :type: list[OrderFulfillment]
        """

        self._fulfillments = fulfillments

    @property
    def returns(self):
        """
        Gets the returns of this Order.
        Collection of items from sale Orders being returned in this one. Normally part of an Itemized Return or Exchange.  There will be exactly one `Return` object per sale Order being referenced.  This field is read-only.

        :return: The returns of this Order.
        :rtype: list[OrderReturn]
        """
        return self._returns

    @returns.setter
    def returns(self, returns):
        """
        Sets the returns of this Order.
        Collection of items from sale Orders being returned in this one. Normally part of an Itemized Return or Exchange.  There will be exactly one `Return` object per sale Order being referenced.  This field is read-only.

        :param returns: The returns of this Order.
        :type: list[OrderReturn]
        """

        self._returns = returns

    @property
    def return_amounts(self):
        """
        Gets the return_amounts of this Order.
        Rollup of returned money amounts.  This field is read-only.

        :return: The return_amounts of this Order.
        :rtype: OrderMoneyAmounts
        """
        return self._return_amounts

    @return_amounts.setter
    def return_amounts(self, return_amounts):
        """
        Sets the return_amounts of this Order.
        Rollup of returned money amounts.  This field is read-only.

        :param return_amounts: The return_amounts of this Order.
        :type: OrderMoneyAmounts
        """

        self._return_amounts = return_amounts

    @property
    def net_amounts(self):
        """
        Gets the net_amounts of this Order.
        Net money amounts (sale money - return money).  This field is read-only.

        :return: The net_amounts of this Order.
        :rtype: OrderMoneyAmounts
        """
        return self._net_amounts

    @net_amounts.setter
    def net_amounts(self, net_amounts):
        """
        Sets the net_amounts of this Order.
        Net money amounts (sale money - return money).  This field is read-only.

        :param net_amounts: The net_amounts of this Order.
        :type: OrderMoneyAmounts
        """

        self._net_amounts = net_amounts

    @property
    def rounding_adjustment(self):
        """
        Gets the rounding_adjustment of this Order.
        A positive or negative rounding adjustment to the total of the order, commonly used to apply Cash Rounding when the minimum unit of account is smaller than the lowest physical denomination of currency.  This field is read-only.

        :return: The rounding_adjustment of this Order.
        :rtype: OrderRoundingAdjustment
        """
        return self._rounding_adjustment

    @rounding_adjustment.setter
    def rounding_adjustment(self, rounding_adjustment):
        """
        Sets the rounding_adjustment of this Order.
        A positive or negative rounding adjustment to the total of the order, commonly used to apply Cash Rounding when the minimum unit of account is smaller than the lowest physical denomination of currency.  This field is read-only.

        :param rounding_adjustment: The rounding_adjustment of this Order.
        :type: OrderRoundingAdjustment
        """

        self._rounding_adjustment = rounding_adjustment

    @property
    def tenders(self):
        """
        Gets the tenders of this Order.
        The Tenders which were used to pay for the Order. This field is read-only.

        :return: The tenders of this Order.
        :rtype: list[Tender]
        """
        return self._tenders

    @tenders.setter
    def tenders(self, tenders):
        """
        Sets the tenders of this Order.
        The Tenders which were used to pay for the Order. This field is read-only.

        :param tenders: The tenders of this Order.
        :type: list[Tender]
        """

        self._tenders = tenders

    @property
    def refunds(self):
        """
        Gets the refunds of this Order.
        The Refunds that are part of this Order. This field is read-only.

        :return: The refunds of this Order.
        :rtype: list[Refund]
        """
        return self._refunds

    @refunds.setter
    def refunds(self, refunds):
        """
        Sets the refunds of this Order.
        The Refunds that are part of this Order. This field is read-only.

        :param refunds: The refunds of this Order.
        :type: list[Refund]
        """

        self._refunds = refunds

    @property
    def created_at(self):
        """
        Gets the created_at of this Order.
        Timestamp for when the order was created. In RFC 3339 format, e.g., \"2016-09-04T23:59:33.123Z\".  This field is read-only.

        :return: The created_at of this Order.
        :rtype: str
        """
        return self._created_at

    @created_at.setter
    def created_at(self, created_at):
        """
        Sets the created_at of this Order.
        Timestamp for when the order was created. In RFC 3339 format, e.g., \"2016-09-04T23:59:33.123Z\".  This field is read-only.

        :param created_at: The created_at of this Order.
        :type: str
        """

        self._created_at = created_at

    @property
    def updated_at(self):
        """
        Gets the updated_at of this Order.
        Timestamp for when the order was last updated. In RFC 3339 format, e.g., \"2016-09-04T23:59:33.123Z\".  This field is read-only.

        :return: The updated_at of this Order.
        :rtype: str
        """
        return self._updated_at

    @updated_at.setter
    def updated_at(self, updated_at):
        """
        Sets the updated_at of this Order.
        Timestamp for when the order was last updated. In RFC 3339 format, e.g., \"2016-09-04T23:59:33.123Z\".  This field is read-only.

        :param updated_at: The updated_at of this Order.
        :type: str
        """

        self._updated_at = updated_at

    @property
    def closed_at(self):
        """
        Gets the closed_at of this Order.
        Timestamp for when the order was closed. In RFC 3339 format, e.g., \"2016-09-04T23:59:33.123Z\".  This field is read-only.

        :return: The closed_at of this Order.
        :rtype: str
        """
        return self._closed_at

    @closed_at.setter
    def closed_at(self, closed_at):
        """
        Sets the closed_at of this Order.
        Timestamp for when the order was closed. In RFC 3339 format, e.g., \"2016-09-04T23:59:33.123Z\".  This field is read-only.

        :param closed_at: The closed_at of this Order.
        :type: str
        """

        self._closed_at = closed_at

    @property
    def state(self):
        """
        Gets the state of this Order.
        The current state of the order. `OPEN`,`COMPLETED`,`CANCELED` See [OrderState](#type-orderstate) for possible values

        :return: The state of this Order.
        :rtype: str
        """
        return self._state

    @state.setter
    def state(self, state):
        """
        Sets the state of this Order.
        The current state of the order. `OPEN`,`COMPLETED`,`CANCELED` See [OrderState](#type-orderstate) for possible values

        :param state: The state of this Order.
        :type: str
        """

        self._state = state

    @property
    def total_money(self):
        """
        Gets the total_money of this Order.
        The total amount of money to collect for the order.  This field is read-only.

        :return: The total_money of this Order.
        :rtype: Money
        """
        return self._total_money

    @total_money.setter
    def total_money(self, total_money):
        """
        Sets the total_money of this Order.
        The total amount of money to collect for the order.  This field is read-only.

        :param total_money: The total_money of this Order.
        :type: Money
        """

        self._total_money = total_money

    @property
    def total_tax_money(self):
        """
        Gets the total_tax_money of this Order.
        The total tax amount of money to collect for the order.  This field is read-only.

        :return: The total_tax_money of this Order.
        :rtype: Money
        """
        return self._total_tax_money

    @total_tax_money.setter
    def total_tax_money(self, total_tax_money):
        """
        Sets the total_tax_money of this Order.
        The total tax amount of money to collect for the order.  This field is read-only.

        :param total_tax_money: The total_tax_money of this Order.
        :type: Money
        """

        self._total_tax_money = total_tax_money

    @property
    def total_discount_money(self):
        """
        Gets the total_discount_money of this Order.
        The total discount amount of money to collect for the order.  This field is read-only.

        :return: The total_discount_money of this Order.
        :rtype: Money
        """
        return self._total_discount_money

    @total_discount_money.setter
    def total_discount_money(self, total_discount_money):
        """
        Sets the total_discount_money of this Order.
        The total discount amount of money to collect for the order.  This field is read-only.

        :param total_discount_money: The total_discount_money of this Order.
        :type: Money
        """

        self._total_discount_money = total_discount_money

    @property
    def total_service_charge_money(self):
        """
        Gets the total_service_charge_money of this Order.
        The total amount of money collected in service charges for the order.  Note: `total_service_charge_money` is the sum of `applied_money` fields for each individual service charge. Therefore, `total_service_charge_money` will only include inclusive tax amounts, not additive tax amounts.  This field is read-only.

        :return: The total_service_charge_money of this Order.
        :rtype: Money
        """
        return self._total_service_charge_money

    @total_service_charge_money.setter
    def total_service_charge_money(self, total_service_charge_money):
        """
        Sets the total_service_charge_money of this Order.
        The total amount of money collected in service charges for the order.  Note: `total_service_charge_money` is the sum of `applied_money` fields for each individual service charge. Therefore, `total_service_charge_money` will only include inclusive tax amounts, not additive tax amounts.  This field is read-only.

        :param total_service_charge_money: The total_service_charge_money of this Order.
        :type: Money
        """

        self._total_service_charge_money = total_service_charge_money

    def to_dict(self):
        """
        Returns the model properties as a dict
        """
        result = {}

        for attr, _ in iteritems(self.swagger_types):
            value = getattr(self, attr)
            if isinstance(value, list):
                result[attr] = list(map(
                    lambda x: x.to_dict() if hasattr(x, "to_dict") else x,
                    value
                ))
            elif hasattr(value, "to_dict"):
                result[attr] = value.to_dict()
            elif isinstance(value, dict):
                result[attr] = dict(map(
                    lambda item: (item[0], item[1].to_dict())
                    if hasattr(item[1], "to_dict") else item,
                    value.items()
                ))
            else:
                result[attr] = value

        return result

    def to_str(self):
        """
        Returns the string representation of the model
        """
        return pformat(self.to_dict())

    def __repr__(self):
        """
        For `print` and `pprint`
        """
        return self.to_str()

    def __eq__(self, other):
        """
        Returns true if both objects are equal
        """
        return self.__dict__ == other.__dict__

    def __ne__(self, other):
        """
        Returns true if both objects are not equal
        """
        return not self == other
