<?php
/**
 * ChannelOrder
 *
 * PHP version 7.4
 *
 * @category Class
 * @package  Linnworks\Orders
 * @author   OpenAPI Generator team
 * @link     https://openapi-generator.tech
 */

/**
 * Orders API
 *
 * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
 *
 * The version of the OpenAPI document: orders
 * Generated by: https://openapi-generator.tech
 * Generator version: 7.11.0
 */

/**
 * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
 * https://openapi-generator.tech
 * Do not edit the class manually.
 */

namespace Linnworks\Orders\Model;

use \ArrayAccess;
use \Linnworks\Orders\ObjectSerializer;

/**
 * ChannelOrder Class Doc Comment
 *
 * @category Class
 * @package  Linnworks\Orders
 * @author   OpenAPI Generator team
 * @link     https://openapi-generator.tech
 * @implements \ArrayAccess<string, mixed>
 */
class ChannelOrder implements ModelInterface, ArrayAccess, \JsonSerializable
{
    public const DISCRIMINATOR = null;

    /**
      * The original name of the model.
      *
      * @var string
      */
    protected static $openAPIModelName = 'ChannelOrder';

    /**
      * Array of property to type mappings. Used for (de)serialization
      *
      * @var string[]
      */
    protected static $openAPITypes = [
        'use_channel_tax' => 'bool',
        'pk_order_id' => 'string',
        'automatically_link_by_sku' => 'bool',
        'automatically_link_by_barcode' => 'bool',
        'automatically_link_by_asin' => 'bool',
        'site' => 'string',
        'match_postal_service_tag' => 'string',
        'postal_service_name' => 'string',
        'save_postal_service_if_not_exist' => 'bool',
        'match_payment_method_tag' => 'string',
        'payment_method_name' => 'string',
        'save_payment_method_if_not_exist' => 'bool',
        'mapping_source' => 'string',
        'order_state' => 'string',
        'order_fulfilment_type' => 'string',
        'order_status_type' => 'string',
        'order_status' => 'string',
        'payment_status' => 'string',
        'order_items' => '\Linnworks\Orders\Model\ChannelOrderItem[]',
        'locations' => '\Linnworks\Orders\Model\ChannelOrderLocation[]',
        'extended_properties' => '\Linnworks\Orders\Model\ChannelOrderExtendedProperty[]',
        'notes' => '\Linnworks\Orders\Model\ChannelOrderNote[]',
        'source' => 'string',
        'sub_source' => 'string',
        'channel_buyer_name' => 'string',
        'reference_number' => 'string',
        'external_reference' => 'string',
        'secondary_reference_number' => 'string',
        'currency' => 'string',
        'conversion_rate' => 'float',
        'received_date' => '\DateTime',
        'updated_date' => '\DateTime',
        'dispatch_by' => '\DateTime',
        'paid_on' => '\DateTime',
        'postal_service_cost' => 'float',
        'postal_service_tax_rate' => 'float',
        'postal_service_discount' => 'float',
        'discount' => 'float',
        'items_refund' => 'float',
        'shipping_refund' => 'float',
        'total_refund' => 'float',
        'line_refund_allocation' => 'string',
        'shipping_refund_allocation' => 'string',
        'buyer_tax_number' => 'string',
        'discount_type' => 'string',
        'discount_tax_type' => 'string',
        'billing_address' => '\Linnworks\Orders\Model\ChannelAddress',
        'delivery_address' => '\Linnworks\Orders\Model\ChannelAddress',
        'delivery_start_date' => '\DateTime',
        'delivery_end_date' => '\DateTime',
        'order_identifier_tags' => 'string[]',
        'force_re_save_fulfilled_order' => 'bool'
    ];

    /**
      * Array of property to format mappings. Used for (de)serialization
      *
      * @var string[]
      * @phpstan-var array<string, string|null>
      * @psalm-var array<string, string|null>
      */
    protected static $openAPIFormats = [
        'use_channel_tax' => null,
        'pk_order_id' => 'uuid',
        'automatically_link_by_sku' => null,
        'automatically_link_by_barcode' => null,
        'automatically_link_by_asin' => null,
        'site' => null,
        'match_postal_service_tag' => null,
        'postal_service_name' => null,
        'save_postal_service_if_not_exist' => null,
        'match_payment_method_tag' => null,
        'payment_method_name' => null,
        'save_payment_method_if_not_exist' => null,
        'mapping_source' => null,
        'order_state' => null,
        'order_fulfilment_type' => null,
        'order_status_type' => null,
        'order_status' => null,
        'payment_status' => null,
        'order_items' => null,
        'locations' => null,
        'extended_properties' => null,
        'notes' => null,
        'source' => null,
        'sub_source' => null,
        'channel_buyer_name' => null,
        'reference_number' => null,
        'external_reference' => null,
        'secondary_reference_number' => null,
        'currency' => null,
        'conversion_rate' => 'double',
        'received_date' => 'date-time',
        'updated_date' => 'date-time',
        'dispatch_by' => 'date-time',
        'paid_on' => 'date-time',
        'postal_service_cost' => 'double',
        'postal_service_tax_rate' => 'double',
        'postal_service_discount' => 'double',
        'discount' => 'double',
        'items_refund' => 'double',
        'shipping_refund' => 'double',
        'total_refund' => 'double',
        'line_refund_allocation' => null,
        'shipping_refund_allocation' => null,
        'buyer_tax_number' => null,
        'discount_type' => null,
        'discount_tax_type' => null,
        'billing_address' => null,
        'delivery_address' => null,
        'delivery_start_date' => 'date-time',
        'delivery_end_date' => 'date-time',
        'order_identifier_tags' => null,
        'force_re_save_fulfilled_order' => null
    ];

    /**
      * Array of nullable properties. Used for (de)serialization
      *
      * @var boolean[]
      */
    protected static array $openAPINullables = [
        'use_channel_tax' => false,
        'pk_order_id' => false,
        'automatically_link_by_sku' => false,
        'automatically_link_by_barcode' => false,
        'automatically_link_by_asin' => false,
        'site' => false,
        'match_postal_service_tag' => false,
        'postal_service_name' => false,
        'save_postal_service_if_not_exist' => false,
        'match_payment_method_tag' => false,
        'payment_method_name' => false,
        'save_payment_method_if_not_exist' => false,
        'mapping_source' => false,
        'order_state' => false,
        'order_fulfilment_type' => false,
        'order_status_type' => false,
        'order_status' => false,
        'payment_status' => false,
        'order_items' => false,
        'locations' => false,
        'extended_properties' => false,
        'notes' => false,
        'source' => false,
        'sub_source' => false,
        'channel_buyer_name' => false,
        'reference_number' => false,
        'external_reference' => false,
        'secondary_reference_number' => false,
        'currency' => false,
        'conversion_rate' => false,
        'received_date' => false,
        'updated_date' => false,
        'dispatch_by' => false,
        'paid_on' => false,
        'postal_service_cost' => false,
        'postal_service_tax_rate' => false,
        'postal_service_discount' => false,
        'discount' => false,
        'items_refund' => false,
        'shipping_refund' => false,
        'total_refund' => false,
        'line_refund_allocation' => false,
        'shipping_refund_allocation' => false,
        'buyer_tax_number' => false,
        'discount_type' => false,
        'discount_tax_type' => false,
        'billing_address' => false,
        'delivery_address' => false,
        'delivery_start_date' => false,
        'delivery_end_date' => false,
        'order_identifier_tags' => false,
        'force_re_save_fulfilled_order' => false
    ];

    /**
      * If a nullable field gets set to null, insert it here
      *
      * @var boolean[]
      */
    protected array $openAPINullablesSetToNull = [];

    /**
     * Array of property to type mappings. Used for (de)serialization
     *
     * @return array
     */
    public static function openAPITypes()
    {
        return self::$openAPITypes;
    }

    /**
     * Array of property to format mappings. Used for (de)serialization
     *
     * @return array
     */
    public static function openAPIFormats()
    {
        return self::$openAPIFormats;
    }

    /**
     * Array of nullable properties
     *
     * @return array
     */
    protected static function openAPINullables(): array
    {
        return self::$openAPINullables;
    }

    /**
     * Array of nullable field names deliberately set to null
     *
     * @return boolean[]
     */
    private function getOpenAPINullablesSetToNull(): array
    {
        return $this->openAPINullablesSetToNull;
    }

    /**
     * Setter - Array of nullable field names deliberately set to null
     *
     * @param boolean[] $openAPINullablesSetToNull
     */
    private function setOpenAPINullablesSetToNull(array $openAPINullablesSetToNull): void
    {
        $this->openAPINullablesSetToNull = $openAPINullablesSetToNull;
    }

    /**
     * Checks if a property is nullable
     *
     * @param string $property
     * @return bool
     */
    public static function isNullable(string $property): bool
    {
        return self::openAPINullables()[$property] ?? false;
    }

    /**
     * Checks if a nullable property is set to null.
     *
     * @param string $property
     * @return bool
     */
    public function isNullableSetToNull(string $property): bool
    {
        return in_array($property, $this->getOpenAPINullablesSetToNull(), true);
    }

    /**
     * Array of attributes where the key is the local name,
     * and the value is the original name
     *
     * @var string[]
     */
    protected static $attributeMap = [
        'use_channel_tax' => 'UseChannelTax',
        'pk_order_id' => 'pkOrderId',
        'automatically_link_by_sku' => 'AutomaticallyLinkBySKU',
        'automatically_link_by_barcode' => 'AutomaticallyLinkByBarcode',
        'automatically_link_by_asin' => 'AutomaticallyLinkByASIN',
        'site' => 'Site',
        'match_postal_service_tag' => 'MatchPostalServiceTag',
        'postal_service_name' => 'PostalServiceName',
        'save_postal_service_if_not_exist' => 'SavePostalServiceIfNotExist',
        'match_payment_method_tag' => 'MatchPaymentMethodTag',
        'payment_method_name' => 'PaymentMethodName',
        'save_payment_method_if_not_exist' => 'SavePaymentMethodIfNotExist',
        'mapping_source' => 'MappingSource',
        'order_state' => 'OrderState',
        'order_fulfilment_type' => 'OrderFulfilmentType',
        'order_status_type' => 'OrderStatusType',
        'order_status' => 'OrderStatus',
        'payment_status' => 'PaymentStatus',
        'order_items' => 'OrderItems',
        'locations' => 'Locations',
        'extended_properties' => 'ExtendedProperties',
        'notes' => 'Notes',
        'source' => 'Source',
        'sub_source' => 'SubSource',
        'channel_buyer_name' => 'ChannelBuyerName',
        'reference_number' => 'ReferenceNumber',
        'external_reference' => 'ExternalReference',
        'secondary_reference_number' => 'SecondaryReferenceNumber',
        'currency' => 'Currency',
        'conversion_rate' => 'ConversionRate',
        'received_date' => 'ReceivedDate',
        'updated_date' => 'UpdatedDate',
        'dispatch_by' => 'DispatchBy',
        'paid_on' => 'PaidOn',
        'postal_service_cost' => 'PostalServiceCost',
        'postal_service_tax_rate' => 'PostalServiceTaxRate',
        'postal_service_discount' => 'PostalServiceDiscount',
        'discount' => 'Discount',
        'items_refund' => 'ItemsRefund',
        'shipping_refund' => 'ShippingRefund',
        'total_refund' => 'TotalRefund',
        'line_refund_allocation' => 'LineRefundAllocation',
        'shipping_refund_allocation' => 'ShippingRefundAllocation',
        'buyer_tax_number' => 'BuyerTaxNumber',
        'discount_type' => 'DiscountType',
        'discount_tax_type' => 'DiscountTaxType',
        'billing_address' => 'BillingAddress',
        'delivery_address' => 'DeliveryAddress',
        'delivery_start_date' => 'DeliveryStartDate',
        'delivery_end_date' => 'DeliveryEndDate',
        'order_identifier_tags' => 'OrderIdentifierTags',
        'force_re_save_fulfilled_order' => 'ForceReSaveFulfilledOrder'
    ];

    /**
     * Array of attributes to setter functions (for deserialization of responses)
     *
     * @var string[]
     */
    protected static $setters = [
        'use_channel_tax' => 'setUseChannelTax',
        'pk_order_id' => 'setPkOrderId',
        'automatically_link_by_sku' => 'setAutomaticallyLinkBySku',
        'automatically_link_by_barcode' => 'setAutomaticallyLinkByBarcode',
        'automatically_link_by_asin' => 'setAutomaticallyLinkByAsin',
        'site' => 'setSite',
        'match_postal_service_tag' => 'setMatchPostalServiceTag',
        'postal_service_name' => 'setPostalServiceName',
        'save_postal_service_if_not_exist' => 'setSavePostalServiceIfNotExist',
        'match_payment_method_tag' => 'setMatchPaymentMethodTag',
        'payment_method_name' => 'setPaymentMethodName',
        'save_payment_method_if_not_exist' => 'setSavePaymentMethodIfNotExist',
        'mapping_source' => 'setMappingSource',
        'order_state' => 'setOrderState',
        'order_fulfilment_type' => 'setOrderFulfilmentType',
        'order_status_type' => 'setOrderStatusType',
        'order_status' => 'setOrderStatus',
        'payment_status' => 'setPaymentStatus',
        'order_items' => 'setOrderItems',
        'locations' => 'setLocations',
        'extended_properties' => 'setExtendedProperties',
        'notes' => 'setNotes',
        'source' => 'setSource',
        'sub_source' => 'setSubSource',
        'channel_buyer_name' => 'setChannelBuyerName',
        'reference_number' => 'setReferenceNumber',
        'external_reference' => 'setExternalReference',
        'secondary_reference_number' => 'setSecondaryReferenceNumber',
        'currency' => 'setCurrency',
        'conversion_rate' => 'setConversionRate',
        'received_date' => 'setReceivedDate',
        'updated_date' => 'setUpdatedDate',
        'dispatch_by' => 'setDispatchBy',
        'paid_on' => 'setPaidOn',
        'postal_service_cost' => 'setPostalServiceCost',
        'postal_service_tax_rate' => 'setPostalServiceTaxRate',
        'postal_service_discount' => 'setPostalServiceDiscount',
        'discount' => 'setDiscount',
        'items_refund' => 'setItemsRefund',
        'shipping_refund' => 'setShippingRefund',
        'total_refund' => 'setTotalRefund',
        'line_refund_allocation' => 'setLineRefundAllocation',
        'shipping_refund_allocation' => 'setShippingRefundAllocation',
        'buyer_tax_number' => 'setBuyerTaxNumber',
        'discount_type' => 'setDiscountType',
        'discount_tax_type' => 'setDiscountTaxType',
        'billing_address' => 'setBillingAddress',
        'delivery_address' => 'setDeliveryAddress',
        'delivery_start_date' => 'setDeliveryStartDate',
        'delivery_end_date' => 'setDeliveryEndDate',
        'order_identifier_tags' => 'setOrderIdentifierTags',
        'force_re_save_fulfilled_order' => 'setForceReSaveFulfilledOrder'
    ];

    /**
     * Array of attributes to getter functions (for serialization of requests)
     *
     * @var string[]
     */
    protected static $getters = [
        'use_channel_tax' => 'getUseChannelTax',
        'pk_order_id' => 'getPkOrderId',
        'automatically_link_by_sku' => 'getAutomaticallyLinkBySku',
        'automatically_link_by_barcode' => 'getAutomaticallyLinkByBarcode',
        'automatically_link_by_asin' => 'getAutomaticallyLinkByAsin',
        'site' => 'getSite',
        'match_postal_service_tag' => 'getMatchPostalServiceTag',
        'postal_service_name' => 'getPostalServiceName',
        'save_postal_service_if_not_exist' => 'getSavePostalServiceIfNotExist',
        'match_payment_method_tag' => 'getMatchPaymentMethodTag',
        'payment_method_name' => 'getPaymentMethodName',
        'save_payment_method_if_not_exist' => 'getSavePaymentMethodIfNotExist',
        'mapping_source' => 'getMappingSource',
        'order_state' => 'getOrderState',
        'order_fulfilment_type' => 'getOrderFulfilmentType',
        'order_status_type' => 'getOrderStatusType',
        'order_status' => 'getOrderStatus',
        'payment_status' => 'getPaymentStatus',
        'order_items' => 'getOrderItems',
        'locations' => 'getLocations',
        'extended_properties' => 'getExtendedProperties',
        'notes' => 'getNotes',
        'source' => 'getSource',
        'sub_source' => 'getSubSource',
        'channel_buyer_name' => 'getChannelBuyerName',
        'reference_number' => 'getReferenceNumber',
        'external_reference' => 'getExternalReference',
        'secondary_reference_number' => 'getSecondaryReferenceNumber',
        'currency' => 'getCurrency',
        'conversion_rate' => 'getConversionRate',
        'received_date' => 'getReceivedDate',
        'updated_date' => 'getUpdatedDate',
        'dispatch_by' => 'getDispatchBy',
        'paid_on' => 'getPaidOn',
        'postal_service_cost' => 'getPostalServiceCost',
        'postal_service_tax_rate' => 'getPostalServiceTaxRate',
        'postal_service_discount' => 'getPostalServiceDiscount',
        'discount' => 'getDiscount',
        'items_refund' => 'getItemsRefund',
        'shipping_refund' => 'getShippingRefund',
        'total_refund' => 'getTotalRefund',
        'line_refund_allocation' => 'getLineRefundAllocation',
        'shipping_refund_allocation' => 'getShippingRefundAllocation',
        'buyer_tax_number' => 'getBuyerTaxNumber',
        'discount_type' => 'getDiscountType',
        'discount_tax_type' => 'getDiscountTaxType',
        'billing_address' => 'getBillingAddress',
        'delivery_address' => 'getDeliveryAddress',
        'delivery_start_date' => 'getDeliveryStartDate',
        'delivery_end_date' => 'getDeliveryEndDate',
        'order_identifier_tags' => 'getOrderIdentifierTags',
        'force_re_save_fulfilled_order' => 'getForceReSaveFulfilledOrder'
    ];

    /**
     * Array of attributes where the key is the local name,
     * and the value is the original name
     *
     * @return array
     */
    public static function attributeMap()
    {
        return self::$attributeMap;
    }

    /**
     * Array of attributes to setter functions (for deserialization of responses)
     *
     * @return array
     */
    public static function setters()
    {
        return self::$setters;
    }

    /**
     * Array of attributes to getter functions (for serialization of requests)
     *
     * @return array
     */
    public static function getters()
    {
        return self::$getters;
    }

    /**
     * The original name of the model.
     *
     * @return string
     */
    public function getModelName()
    {
        return self::$openAPIModelName;
    }

    public const ORDER_STATE_NONE = 'None';
    public const ORDER_STATE_HOLD = 'Hold';
    public const ORDER_STATE_PARK = 'Park';
    public const ORDER_FULFILMENT_TYPE_MANUAL = 'Manual';
    public const ORDER_FULFILMENT_TYPE_POS = 'POS';
    public const ORDER_FULFILMENT_TYPE_DIGITAL_ONLY = 'DigitalOnly';
    public const ORDER_FULFILMENT_TYPE_FULFILMENT_BY_CHANNEL = 'FulfilmentByChannel';
    public const ORDER_STATUS_TYPE_UNKNOWN = 'Unknown';
    public const ORDER_STATUS_TYPE_PENDING = 'Pending';
    public const ORDER_STATUS_TYPE_UNSHIPPED = 'Unshipped';
    public const ORDER_STATUS_TYPE_PARTIALLY_SHIPPED = 'PartiallyShipped';
    public const ORDER_STATUS_TYPE_SHIPPED = 'Shipped';
    public const ORDER_STATUS_TYPE_PARTIALLY_CANCELLED = 'PartiallyCancelled';
    public const ORDER_STATUS_TYPE_CANCELLED = 'Cancelled';
    public const ORDER_STATUS_TYPE_PARTIALLY_REFUNDED = 'PartiallyRefunded';
    public const ORDER_STATUS_TYPE_REFUNDED = 'Refunded';
    public const PAYMENT_STATUS_UNPAID = 'Unpaid';
    public const PAYMENT_STATUS_PAID = 'Paid';
    public const PAYMENT_STATUS_CANCELLED = 'Cancelled';
    public const LINE_REFUND_ALLOCATION_UNKNOWN = 'Unknown';
    public const LINE_REFUND_ALLOCATION_ORDER_LEVEL = 'OrderLevel';
    public const LINE_REFUND_ALLOCATION_LINE_LEVEL = 'LineLevel';
    public const LINE_REFUND_ALLOCATION_BOTH = 'Both';
    public const SHIPPING_REFUND_ALLOCATION_UNKNOWN = 'Unknown';
    public const SHIPPING_REFUND_ALLOCATION_ORDER_LEVEL = 'OrderLevel';
    public const SHIPPING_REFUND_ALLOCATION_LINE_LEVEL = 'LineLevel';
    public const SHIPPING_REFUND_ALLOCATION_BOTH = 'Both';
    public const DISCOUNT_TYPE_ALL_EVENLY = 'AllEvenly';
    public const DISCOUNT_TYPE_ITEMS_THEN_POSTAGE = 'ItemsThenPostage';
    public const DISCOUNT_TYPE_POSTAGE_THEN_ITEMS = 'PostageThenItems';
    public const DISCOUNT_TAX_TYPE_DEDUCT_AFTER_TAX = 'DeductAfterTax';
    public const DISCOUNT_TAX_TYPE_DEDUCT_BEFORE_TAX = 'DeductBeforeTax';

    /**
     * Gets allowable values of the enum
     *
     * @return string[]
     */
    public function getOrderStateAllowableValues()
    {
        return [
            self::ORDER_STATE_NONE,
            self::ORDER_STATE_HOLD,
            self::ORDER_STATE_PARK,
        ];
    }

    /**
     * Gets allowable values of the enum
     *
     * @return string[]
     */
    public function getOrderFulfilmentTypeAllowableValues()
    {
        return [
            self::ORDER_FULFILMENT_TYPE_MANUAL,
            self::ORDER_FULFILMENT_TYPE_POS,
            self::ORDER_FULFILMENT_TYPE_DIGITAL_ONLY,
            self::ORDER_FULFILMENT_TYPE_FULFILMENT_BY_CHANNEL,
        ];
    }

    /**
     * Gets allowable values of the enum
     *
     * @return string[]
     */
    public function getOrderStatusTypeAllowableValues()
    {
        return [
            self::ORDER_STATUS_TYPE_UNKNOWN,
            self::ORDER_STATUS_TYPE_PENDING,
            self::ORDER_STATUS_TYPE_UNSHIPPED,
            self::ORDER_STATUS_TYPE_PARTIALLY_SHIPPED,
            self::ORDER_STATUS_TYPE_SHIPPED,
            self::ORDER_STATUS_TYPE_PARTIALLY_CANCELLED,
            self::ORDER_STATUS_TYPE_CANCELLED,
            self::ORDER_STATUS_TYPE_PARTIALLY_REFUNDED,
            self::ORDER_STATUS_TYPE_REFUNDED,
        ];
    }

    /**
     * Gets allowable values of the enum
     *
     * @return string[]
     */
    public function getPaymentStatusAllowableValues()
    {
        return [
            self::PAYMENT_STATUS_UNPAID,
            self::PAYMENT_STATUS_PAID,
            self::PAYMENT_STATUS_CANCELLED,
        ];
    }

    /**
     * Gets allowable values of the enum
     *
     * @return string[]
     */
    public function getLineRefundAllocationAllowableValues()
    {
        return [
            self::LINE_REFUND_ALLOCATION_UNKNOWN,
            self::LINE_REFUND_ALLOCATION_ORDER_LEVEL,
            self::LINE_REFUND_ALLOCATION_LINE_LEVEL,
            self::LINE_REFUND_ALLOCATION_BOTH,
        ];
    }

    /**
     * Gets allowable values of the enum
     *
     * @return string[]
     */
    public function getShippingRefundAllocationAllowableValues()
    {
        return [
            self::SHIPPING_REFUND_ALLOCATION_UNKNOWN,
            self::SHIPPING_REFUND_ALLOCATION_ORDER_LEVEL,
            self::SHIPPING_REFUND_ALLOCATION_LINE_LEVEL,
            self::SHIPPING_REFUND_ALLOCATION_BOTH,
        ];
    }

    /**
     * Gets allowable values of the enum
     *
     * @return string[]
     */
    public function getDiscountTypeAllowableValues()
    {
        return [
            self::DISCOUNT_TYPE_ALL_EVENLY,
            self::DISCOUNT_TYPE_ITEMS_THEN_POSTAGE,
            self::DISCOUNT_TYPE_POSTAGE_THEN_ITEMS,
        ];
    }

    /**
     * Gets allowable values of the enum
     *
     * @return string[]
     */
    public function getDiscountTaxTypeAllowableValues()
    {
        return [
            self::DISCOUNT_TAX_TYPE_DEDUCT_AFTER_TAX,
            self::DISCOUNT_TAX_TYPE_DEDUCT_BEFORE_TAX,
        ];
    }

    /**
     * Associative array for storing property values
     *
     * @var mixed[]
     */
    protected $container = [];

    /**
     * Constructor
     *
     * @param mixed[]|null $data Associated array of property values
     *                      initializing the model
     */
    public function __construct(?array $data = null)
    {
        $this->setIfExists('use_channel_tax', $data ?? [], null);
        $this->setIfExists('pk_order_id', $data ?? [], null);
        $this->setIfExists('automatically_link_by_sku', $data ?? [], null);
        $this->setIfExists('automatically_link_by_barcode', $data ?? [], null);
        $this->setIfExists('automatically_link_by_asin', $data ?? [], null);
        $this->setIfExists('site', $data ?? [], null);
        $this->setIfExists('match_postal_service_tag', $data ?? [], null);
        $this->setIfExists('postal_service_name', $data ?? [], null);
        $this->setIfExists('save_postal_service_if_not_exist', $data ?? [], null);
        $this->setIfExists('match_payment_method_tag', $data ?? [], null);
        $this->setIfExists('payment_method_name', $data ?? [], null);
        $this->setIfExists('save_payment_method_if_not_exist', $data ?? [], null);
        $this->setIfExists('mapping_source', $data ?? [], null);
        $this->setIfExists('order_state', $data ?? [], null);
        $this->setIfExists('order_fulfilment_type', $data ?? [], null);
        $this->setIfExists('order_status_type', $data ?? [], null);
        $this->setIfExists('order_status', $data ?? [], null);
        $this->setIfExists('payment_status', $data ?? [], null);
        $this->setIfExists('order_items', $data ?? [], null);
        $this->setIfExists('locations', $data ?? [], null);
        $this->setIfExists('extended_properties', $data ?? [], null);
        $this->setIfExists('notes', $data ?? [], null);
        $this->setIfExists('source', $data ?? [], null);
        $this->setIfExists('sub_source', $data ?? [], null);
        $this->setIfExists('channel_buyer_name', $data ?? [], null);
        $this->setIfExists('reference_number', $data ?? [], null);
        $this->setIfExists('external_reference', $data ?? [], null);
        $this->setIfExists('secondary_reference_number', $data ?? [], null);
        $this->setIfExists('currency', $data ?? [], null);
        $this->setIfExists('conversion_rate', $data ?? [], null);
        $this->setIfExists('received_date', $data ?? [], null);
        $this->setIfExists('updated_date', $data ?? [], null);
        $this->setIfExists('dispatch_by', $data ?? [], null);
        $this->setIfExists('paid_on', $data ?? [], null);
        $this->setIfExists('postal_service_cost', $data ?? [], null);
        $this->setIfExists('postal_service_tax_rate', $data ?? [], null);
        $this->setIfExists('postal_service_discount', $data ?? [], null);
        $this->setIfExists('discount', $data ?? [], null);
        $this->setIfExists('items_refund', $data ?? [], null);
        $this->setIfExists('shipping_refund', $data ?? [], null);
        $this->setIfExists('total_refund', $data ?? [], null);
        $this->setIfExists('line_refund_allocation', $data ?? [], null);
        $this->setIfExists('shipping_refund_allocation', $data ?? [], null);
        $this->setIfExists('buyer_tax_number', $data ?? [], null);
        $this->setIfExists('discount_type', $data ?? [], null);
        $this->setIfExists('discount_tax_type', $data ?? [], null);
        $this->setIfExists('billing_address', $data ?? [], null);
        $this->setIfExists('delivery_address', $data ?? [], null);
        $this->setIfExists('delivery_start_date', $data ?? [], null);
        $this->setIfExists('delivery_end_date', $data ?? [], null);
        $this->setIfExists('order_identifier_tags', $data ?? [], null);
        $this->setIfExists('force_re_save_fulfilled_order', $data ?? [], null);
    }

    /**
    * Sets $this->container[$variableName] to the given data or to the given default Value; if $variableName
    * is nullable and its value is set to null in the $fields array, then mark it as "set to null" in the
    * $this->openAPINullablesSetToNull array
    *
    * @param string $variableName
    * @param array  $fields
    * @param mixed  $defaultValue
    */
    private function setIfExists(string $variableName, array $fields, $defaultValue): void
    {
        if (self::isNullable($variableName) && array_key_exists($variableName, $fields) && is_null($fields[$variableName])) {
            $this->openAPINullablesSetToNull[] = $variableName;
        }

        $this->container[$variableName] = $fields[$variableName] ?? $defaultValue;
    }

    /**
     * Show all the invalid properties with reasons.
     *
     * @return array invalid properties with reasons
     */
    public function listInvalidProperties()
    {
        $invalidProperties = [];

        $allowedValues = $this->getOrderStateAllowableValues();
        if (!is_null($this->container['order_state']) && !in_array($this->container['order_state'], $allowedValues, true)) {
            $invalidProperties[] = sprintf(
                "invalid value '%s' for 'order_state', must be one of '%s'",
                $this->container['order_state'],
                implode("', '", $allowedValues)
            );
        }

        $allowedValues = $this->getOrderFulfilmentTypeAllowableValues();
        if (!is_null($this->container['order_fulfilment_type']) && !in_array($this->container['order_fulfilment_type'], $allowedValues, true)) {
            $invalidProperties[] = sprintf(
                "invalid value '%s' for 'order_fulfilment_type', must be one of '%s'",
                $this->container['order_fulfilment_type'],
                implode("', '", $allowedValues)
            );
        }

        $allowedValues = $this->getOrderStatusTypeAllowableValues();
        if (!is_null($this->container['order_status_type']) && !in_array($this->container['order_status_type'], $allowedValues, true)) {
            $invalidProperties[] = sprintf(
                "invalid value '%s' for 'order_status_type', must be one of '%s'",
                $this->container['order_status_type'],
                implode("', '", $allowedValues)
            );
        }

        $allowedValues = $this->getPaymentStatusAllowableValues();
        if (!is_null($this->container['payment_status']) && !in_array($this->container['payment_status'], $allowedValues, true)) {
            $invalidProperties[] = sprintf(
                "invalid value '%s' for 'payment_status', must be one of '%s'",
                $this->container['payment_status'],
                implode("', '", $allowedValues)
            );
        }

        $allowedValues = $this->getLineRefundAllocationAllowableValues();
        if (!is_null($this->container['line_refund_allocation']) && !in_array($this->container['line_refund_allocation'], $allowedValues, true)) {
            $invalidProperties[] = sprintf(
                "invalid value '%s' for 'line_refund_allocation', must be one of '%s'",
                $this->container['line_refund_allocation'],
                implode("', '", $allowedValues)
            );
        }

        $allowedValues = $this->getShippingRefundAllocationAllowableValues();
        if (!is_null($this->container['shipping_refund_allocation']) && !in_array($this->container['shipping_refund_allocation'], $allowedValues, true)) {
            $invalidProperties[] = sprintf(
                "invalid value '%s' for 'shipping_refund_allocation', must be one of '%s'",
                $this->container['shipping_refund_allocation'],
                implode("', '", $allowedValues)
            );
        }

        $allowedValues = $this->getDiscountTypeAllowableValues();
        if (!is_null($this->container['discount_type']) && !in_array($this->container['discount_type'], $allowedValues, true)) {
            $invalidProperties[] = sprintf(
                "invalid value '%s' for 'discount_type', must be one of '%s'",
                $this->container['discount_type'],
                implode("', '", $allowedValues)
            );
        }

        $allowedValues = $this->getDiscountTaxTypeAllowableValues();
        if (!is_null($this->container['discount_tax_type']) && !in_array($this->container['discount_tax_type'], $allowedValues, true)) {
            $invalidProperties[] = sprintf(
                "invalid value '%s' for 'discount_tax_type', must be one of '%s'",
                $this->container['discount_tax_type'],
                implode("', '", $allowedValues)
            );
        }

        return $invalidProperties;
    }

    /**
     * Validate all the properties in the model
     * return true if all passed
     *
     * @return bool True if all properties are valid
     */
    public function valid()
    {
        return count($this->listInvalidProperties()) === 0;
    }


    /**
     * Gets use_channel_tax
     *
     * @return bool|null
     */
    public function getUseChannelTax()
    {
        return $this->container['use_channel_tax'];
    }

    /**
     * Sets use_channel_tax
     *
     * @param bool|null $use_channel_tax Validate if the tax should be overwritten on the order.
     *
     * @return self
     */
    public function setUseChannelTax($use_channel_tax)
    {
        if (is_null($use_channel_tax)) {
            throw new \InvalidArgumentException('non-nullable use_channel_tax cannot be null');
        }
        $this->container['use_channel_tax'] = $use_channel_tax;

        return $this;
    }

    /**
     * Gets pk_order_id
     *
     * @return string|null
     */
    public function getPkOrderId()
    {
        return $this->container['pk_order_id'];
    }

    /**
     * Sets pk_order_id
     *
     * @param string|null $pk_order_id Used when IsNew is false to update the order
     *
     * @return self
     */
    public function setPkOrderId($pk_order_id)
    {
        if (is_null($pk_order_id)) {
            throw new \InvalidArgumentException('non-nullable pk_order_id cannot be null');
        }
        $this->container['pk_order_id'] = $pk_order_id;

        return $this;
    }

    /**
     * Gets automatically_link_by_sku
     *
     * @return bool|null
     */
    public function getAutomaticallyLinkBySku()
    {
        return $this->container['automatically_link_by_sku'];
    }

    /**
     * Sets automatically_link_by_sku
     *
     * @param bool|null $automatically_link_by_sku When the order is saved it will try and link by SKU after trying by channel sku mapping.
     *
     * @return self
     */
    public function setAutomaticallyLinkBySku($automatically_link_by_sku)
    {
        if (is_null($automatically_link_by_sku)) {
            throw new \InvalidArgumentException('non-nullable automatically_link_by_sku cannot be null');
        }
        $this->container['automatically_link_by_sku'] = $automatically_link_by_sku;

        return $this;
    }

    /**
     * Gets automatically_link_by_barcode
     *
     * @return bool|null
     */
    public function getAutomaticallyLinkByBarcode()
    {
        return $this->container['automatically_link_by_barcode'];
    }

    /**
     * Sets automatically_link_by_barcode
     *
     * @param bool|null $automatically_link_by_barcode When the order is saved it will try and link by Barcode after trying by channel sku mapping.
     *
     * @return self
     */
    public function setAutomaticallyLinkByBarcode($automatically_link_by_barcode)
    {
        if (is_null($automatically_link_by_barcode)) {
            throw new \InvalidArgumentException('non-nullable automatically_link_by_barcode cannot be null');
        }
        $this->container['automatically_link_by_barcode'] = $automatically_link_by_barcode;

        return $this;
    }

    /**
     * Gets automatically_link_by_asin
     *
     * @return bool|null
     */
    public function getAutomaticallyLinkByAsin()
    {
        return $this->container['automatically_link_by_asin'];
    }

    /**
     * Sets automatically_link_by_asin
     *
     * @param bool|null $automatically_link_by_asin When the order is saved it will try and link by ASIN after trying by channel sku mapping.
     *
     * @return self
     */
    public function setAutomaticallyLinkByAsin($automatically_link_by_asin)
    {
        if (is_null($automatically_link_by_asin)) {
            throw new \InvalidArgumentException('non-nullable automatically_link_by_asin cannot be null');
        }
        $this->container['automatically_link_by_asin'] = $automatically_link_by_asin;

        return $this;
    }

    /**
     * Gets site
     *
     * @return string|null
     */
    public function getSite()
    {
        return $this->container['site'];
    }

    /**
     * Sets site
     *
     * @param string|null $site Used to determine the site of the order.
     *
     * @return self
     */
    public function setSite($site)
    {
        if (is_null($site)) {
            throw new \InvalidArgumentException('non-nullable site cannot be null');
        }
        $this->container['site'] = $site;

        return $this;
    }

    /**
     * Gets match_postal_service_tag
     *
     * @return string|null
     */
    public function getMatchPostalServiceTag()
    {
        return $this->container['match_postal_service_tag'];
    }

    /**
     * Sets match_postal_service_tag
     *
     * @param string|null $match_postal_service_tag Match postal service method by name
     *
     * @return self
     */
    public function setMatchPostalServiceTag($match_postal_service_tag)
    {
        if (is_null($match_postal_service_tag)) {
            throw new \InvalidArgumentException('non-nullable match_postal_service_tag cannot be null');
        }
        $this->container['match_postal_service_tag'] = $match_postal_service_tag;

        return $this;
    }

    /**
     * Gets postal_service_name
     *
     * @return string|null
     */
    public function getPostalServiceName()
    {
        return $this->container['postal_service_name'];
    }

    /**
     * Sets postal_service_name
     *
     * @param string|null $postal_service_name Postal service name used for saving new postal services
     *
     * @return self
     */
    public function setPostalServiceName($postal_service_name)
    {
        if (is_null($postal_service_name)) {
            throw new \InvalidArgumentException('non-nullable postal_service_name cannot be null');
        }
        $this->container['postal_service_name'] = $postal_service_name;

        return $this;
    }

    /**
     * Gets save_postal_service_if_not_exist
     *
     * @return bool|null
     */
    public function getSavePostalServiceIfNotExist()
    {
        return $this->container['save_postal_service_if_not_exist'];
    }

    /**
     * Sets save_postal_service_if_not_exist
     *
     * @param bool|null $save_postal_service_if_not_exist Determines wither or not to save postal service if it does not exist
     *
     * @return self
     */
    public function setSavePostalServiceIfNotExist($save_postal_service_if_not_exist)
    {
        if (is_null($save_postal_service_if_not_exist)) {
            throw new \InvalidArgumentException('non-nullable save_postal_service_if_not_exist cannot be null');
        }
        $this->container['save_postal_service_if_not_exist'] = $save_postal_service_if_not_exist;

        return $this;
    }

    /**
     * Gets match_payment_method_tag
     *
     * @return string|null
     */
    public function getMatchPaymentMethodTag()
    {
        return $this->container['match_payment_method_tag'];
    }

    /**
     * Sets match_payment_method_tag
     *
     * @param string|null $match_payment_method_tag Match payment method by name
     *
     * @return self
     */
    public function setMatchPaymentMethodTag($match_payment_method_tag)
    {
        if (is_null($match_payment_method_tag)) {
            throw new \InvalidArgumentException('non-nullable match_payment_method_tag cannot be null');
        }
        $this->container['match_payment_method_tag'] = $match_payment_method_tag;

        return $this;
    }

    /**
     * Gets payment_method_name
     *
     * @return string|null
     */
    public function getPaymentMethodName()
    {
        return $this->container['payment_method_name'];
    }

    /**
     * Sets payment_method_name
     *
     * @param string|null $payment_method_name Payment method name used for saving new payment methods
     *
     * @return self
     */
    public function setPaymentMethodName($payment_method_name)
    {
        if (is_null($payment_method_name)) {
            throw new \InvalidArgumentException('non-nullable payment_method_name cannot be null');
        }
        $this->container['payment_method_name'] = $payment_method_name;

        return $this;
    }

    /**
     * Gets save_payment_method_if_not_exist
     *
     * @return bool|null
     */
    public function getSavePaymentMethodIfNotExist()
    {
        return $this->container['save_payment_method_if_not_exist'];
    }

    /**
     * Sets save_payment_method_if_not_exist
     *
     * @param bool|null $save_payment_method_if_not_exist Determines wither or not to save payment methods if it does not exist
     *
     * @return self
     */
    public function setSavePaymentMethodIfNotExist($save_payment_method_if_not_exist)
    {
        if (is_null($save_payment_method_if_not_exist)) {
            throw new \InvalidArgumentException('non-nullable save_payment_method_if_not_exist cannot be null');
        }
        $this->container['save_payment_method_if_not_exist'] = $save_payment_method_if_not_exist;

        return $this;
    }

    /**
     * Gets mapping_source
     *
     * @return string|null
     */
    public function getMappingSource()
    {
        return $this->container['mapping_source'];
    }

    /**
     * Sets mapping_source
     *
     * @param string|null $mapping_source Overrides the mapping source for the channel for example if the Source is 'AMAZON FBA' MappingSource can be used to override to 'AMAZON'
     *
     * @return self
     */
    public function setMappingSource($mapping_source)
    {
        if (is_null($mapping_source)) {
            throw new \InvalidArgumentException('non-nullable mapping_source cannot be null');
        }
        $this->container['mapping_source'] = $mapping_source;

        return $this;
    }

    /**
     * Gets order_state
     *
     * @return string|null
     */
    public function getOrderState()
    {
        return $this->container['order_state'];
    }

    /**
     * Sets order_state
     *
     * @param string|null $order_state State the order should be saved e.g. hold, parked, none
     *
     * @return self
     */
    public function setOrderState($order_state)
    {
        if (is_null($order_state)) {
            throw new \InvalidArgumentException('non-nullable order_state cannot be null');
        }
        $allowedValues = $this->getOrderStateAllowableValues();
        if (!in_array($order_state, $allowedValues, true)) {
            throw new \InvalidArgumentException(
                sprintf(
                    "Invalid value '%s' for 'order_state', must be one of '%s'",
                    $order_state,
                    implode("', '", $allowedValues)
                )
            );
        }
        $this->container['order_state'] = $order_state;

        return $this;
    }

    /**
     * Gets order_fulfilment_type
     *
     * @return string|null
     */
    public function getOrderFulfilmentType()
    {
        return $this->container['order_fulfilment_type'];
    }

    /**
     * Sets order_fulfilment_type
     *
     * @param string|null $order_fulfilment_type Defines type of fulfilment required for order
     *
     * @return self
     */
    public function setOrderFulfilmentType($order_fulfilment_type)
    {
        if (is_null($order_fulfilment_type)) {
            throw new \InvalidArgumentException('non-nullable order_fulfilment_type cannot be null');
        }
        $allowedValues = $this->getOrderFulfilmentTypeAllowableValues();
        if (!in_array($order_fulfilment_type, $allowedValues, true)) {
            throw new \InvalidArgumentException(
                sprintf(
                    "Invalid value '%s' for 'order_fulfilment_type', must be one of '%s'",
                    $order_fulfilment_type,
                    implode("', '", $allowedValues)
                )
            );
        }
        $this->container['order_fulfilment_type'] = $order_fulfilment_type;

        return $this;
    }

    /**
     * Gets order_status_type
     *
     * @return string|null
     */
    public function getOrderStatusType()
    {
        return $this->container['order_status_type'];
    }

    /**
     * Sets order_status_type
     *
     * @param string|null $order_status_type The status of the order on the channel
     *
     * @return self
     */
    public function setOrderStatusType($order_status_type)
    {
        if (is_null($order_status_type)) {
            throw new \InvalidArgumentException('non-nullable order_status_type cannot be null');
        }
        $allowedValues = $this->getOrderStatusTypeAllowableValues();
        if (!in_array($order_status_type, $allowedValues, true)) {
            throw new \InvalidArgumentException(
                sprintf(
                    "Invalid value '%s' for 'order_status_type', must be one of '%s'",
                    $order_status_type,
                    implode("', '", $allowedValues)
                )
            );
        }
        $this->container['order_status_type'] = $order_status_type;

        return $this;
    }

    /**
     * Gets order_status
     *
     * @return string|null
     */
    public function getOrderStatus()
    {
        return $this->container['order_status'];
    }

    /**
     * Sets order_status
     *
     * @param string|null $order_status The raw status text of the order on the channel
     *
     * @return self
     */
    public function setOrderStatus($order_status)
    {
        if (is_null($order_status)) {
            throw new \InvalidArgumentException('non-nullable order_status cannot be null');
        }
        $this->container['order_status'] = $order_status;

        return $this;
    }

    /**
     * Gets payment_status
     *
     * @return string|null
     */
    public function getPaymentStatus()
    {
        return $this->container['payment_status'];
    }

    /**
     * Sets payment_status
     *
     * @param string|null $payment_status Payment status of the order, eg Paid  If Unpaid ChannelOrderAdapter.Save() will ensure order is PARKED
     *
     * @return self
     */
    public function setPaymentStatus($payment_status)
    {
        if (is_null($payment_status)) {
            throw new \InvalidArgumentException('non-nullable payment_status cannot be null');
        }
        $allowedValues = $this->getPaymentStatusAllowableValues();
        if (!in_array($payment_status, $allowedValues, true)) {
            throw new \InvalidArgumentException(
                sprintf(
                    "Invalid value '%s' for 'payment_status', must be one of '%s'",
                    $payment_status,
                    implode("', '", $allowedValues)
                )
            );
        }
        $this->container['payment_status'] = $payment_status;

        return $this;
    }

    /**
     * Gets order_items
     *
     * @return \Linnworks\Orders\Model\ChannelOrderItem[]|null
     */
    public function getOrderItems()
    {
        return $this->container['order_items'];
    }

    /**
     * Sets order_items
     *
     * @param \Linnworks\Orders\Model\ChannelOrderItem[]|null $order_items List of order items
     *
     * @return self
     */
    public function setOrderItems($order_items)
    {
        if (is_null($order_items)) {
            throw new \InvalidArgumentException('non-nullable order_items cannot be null');
        }
        $this->container['order_items'] = $order_items;

        return $this;
    }

    /**
     * Gets locations
     *
     * @return \Linnworks\Orders\Model\ChannelOrderLocation[]|null
     */
    public function getLocations()
    {
        return $this->container['locations'];
    }

    /**
     * Sets locations
     *
     * @param \Linnworks\Orders\Model\ChannelOrderLocation[]|null $locations The order location(s) on the channel
     *
     * @return self
     */
    public function setLocations($locations)
    {
        if (is_null($locations)) {
            throw new \InvalidArgumentException('non-nullable locations cannot be null');
        }
        $this->container['locations'] = $locations;

        return $this;
    }

    /**
     * Gets extended_properties
     *
     * @return \Linnworks\Orders\Model\ChannelOrderExtendedProperty[]|null
     */
    public function getExtendedProperties()
    {
        return $this->container['extended_properties'];
    }

    /**
     * Sets extended_properties
     *
     * @param \Linnworks\Orders\Model\ChannelOrderExtendedProperty[]|null $extended_properties List of extended properties for the order
     *
     * @return self
     */
    public function setExtendedProperties($extended_properties)
    {
        if (is_null($extended_properties)) {
            throw new \InvalidArgumentException('non-nullable extended_properties cannot be null');
        }
        $this->container['extended_properties'] = $extended_properties;

        return $this;
    }

    /**
     * Gets notes
     *
     * @return \Linnworks\Orders\Model\ChannelOrderNote[]|null
     */
    public function getNotes()
    {
        return $this->container['notes'];
    }

    /**
     * Sets notes
     *
     * @param \Linnworks\Orders\Model\ChannelOrderNote[]|null $notes List of notes for the order
     *
     * @return self
     */
    public function setNotes($notes)
    {
        if (is_null($notes)) {
            throw new \InvalidArgumentException('non-nullable notes cannot be null');
        }
        $this->container['notes'] = $notes;

        return $this;
    }

    /**
     * Gets source
     *
     * @return string|null
     */
    public function getSource()
    {
        return $this->container['source'];
    }

    /**
     * Sets source
     *
     * @param string|null $source Source
     *
     * @return self
     */
    public function setSource($source)
    {
        if (is_null($source)) {
            throw new \InvalidArgumentException('non-nullable source cannot be null');
        }
        $this->container['source'] = $source;

        return $this;
    }

    /**
     * Gets sub_source
     *
     * @return string|null
     */
    public function getSubSource()
    {
        return $this->container['sub_source'];
    }

    /**
     * Sets sub_source
     *
     * @param string|null $sub_source SubSource
     *
     * @return self
     */
    public function setSubSource($sub_source)
    {
        if (is_null($sub_source)) {
            throw new \InvalidArgumentException('non-nullable sub_source cannot be null');
        }
        $this->container['sub_source'] = $sub_source;

        return $this;
    }

    /**
     * Gets channel_buyer_name
     *
     * @return string|null
     */
    public function getChannelBuyerName()
    {
        return $this->container['channel_buyer_name'];
    }

    /**
     * Sets channel_buyer_name
     *
     * @param string|null $channel_buyer_name Channel buyer username / name
     *
     * @return self
     */
    public function setChannelBuyerName($channel_buyer_name)
    {
        if (is_null($channel_buyer_name)) {
            throw new \InvalidArgumentException('non-nullable channel_buyer_name cannot be null');
        }
        $this->container['channel_buyer_name'] = $channel_buyer_name;

        return $this;
    }

    /**
     * Gets reference_number
     *
     * @return string|null
     */
    public function getReferenceNumber()
    {
        return $this->container['reference_number'];
    }

    /**
     * Sets reference_number
     *
     * @param string|null $reference_number Reference number, should be the same as the one used for despatches
     *
     * @return self
     */
    public function setReferenceNumber($reference_number)
    {
        if (is_null($reference_number)) {
            throw new \InvalidArgumentException('non-nullable reference_number cannot be null');
        }
        $this->container['reference_number'] = $reference_number;

        return $this;
    }

    /**
     * Gets external_reference
     *
     * @return string|null
     */
    public function getExternalReference()
    {
        return $this->container['external_reference'];
    }

    /**
     * Sets external_reference
     *
     * @param string|null $external_reference External Reference
     *
     * @return self
     */
    public function setExternalReference($external_reference)
    {
        if (is_null($external_reference)) {
            throw new \InvalidArgumentException('non-nullable external_reference cannot be null');
        }
        $this->container['external_reference'] = $external_reference;

        return $this;
    }

    /**
     * Gets secondary_reference_number
     *
     * @return string|null
     */
    public function getSecondaryReferenceNumber()
    {
        return $this->container['secondary_reference_number'];
    }

    /**
     * Sets secondary_reference_number
     *
     * @param string|null $secondary_reference_number Secondary reference number
     *
     * @return self
     */
    public function setSecondaryReferenceNumber($secondary_reference_number)
    {
        if (is_null($secondary_reference_number)) {
            throw new \InvalidArgumentException('non-nullable secondary_reference_number cannot be null');
        }
        $this->container['secondary_reference_number'] = $secondary_reference_number;

        return $this;
    }

    /**
     * Gets currency
     *
     * @return string|null
     */
    public function getCurrency()
    {
        return $this->container['currency'];
    }

    /**
     * Sets currency
     *
     * @param string|null $currency Currency of the order, if value is null, empty or white space it will default to UNK
     *
     * @return self
     */
    public function setCurrency($currency)
    {
        if (is_null($currency)) {
            throw new \InvalidArgumentException('non-nullable currency cannot be null');
        }
        $this->container['currency'] = $currency;

        return $this;
    }

    /**
     * Gets conversion_rate
     *
     * @return float|null
     */
    public function getConversionRate()
    {
        return $this->container['conversion_rate'];
    }

    /**
     * Sets conversion_rate
     *
     * @param float|null $conversion_rate The currency conversion rate Sale/Base
     *
     * @return self
     */
    public function setConversionRate($conversion_rate)
    {
        if (is_null($conversion_rate)) {
            throw new \InvalidArgumentException('non-nullable conversion_rate cannot be null');
        }
        $this->container['conversion_rate'] = $conversion_rate;

        return $this;
    }

    /**
     * Gets received_date
     *
     * @return \DateTime|null
     */
    public function getReceivedDate()
    {
        return $this->container['received_date'];
    }

    /**
     * Sets received_date
     *
     * @param \DateTime|null $received_date UTC received date/time of the order
     *
     * @return self
     */
    public function setReceivedDate($received_date)
    {
        if (is_null($received_date)) {
            throw new \InvalidArgumentException('non-nullable received_date cannot be null');
        }
        $this->container['received_date'] = $received_date;

        return $this;
    }

    /**
     * Gets updated_date
     *
     * @return \DateTime|null
     */
    public function getUpdatedDate()
    {
        return $this->container['updated_date'];
    }

    /**
     * Sets updated_date
     *
     * @param \DateTime|null $updated_date UTC date/time the order was last updated at
     *
     * @return self
     */
    public function setUpdatedDate($updated_date)
    {
        if (is_null($updated_date)) {
            throw new \InvalidArgumentException('non-nullable updated_date cannot be null');
        }
        $this->container['updated_date'] = $updated_date;

        return $this;
    }

    /**
     * Gets dispatch_by
     *
     * @return \DateTime|null
     */
    public function getDispatchBy()
    {
        return $this->container['dispatch_by'];
    }

    /**
     * Sets dispatch_by
     *
     * @param \DateTime|null $dispatch_by UTC date/time the order should be despatched by
     *
     * @return self
     */
    public function setDispatchBy($dispatch_by)
    {
        if (is_null($dispatch_by)) {
            throw new \InvalidArgumentException('non-nullable dispatch_by cannot be null');
        }
        $this->container['dispatch_by'] = $dispatch_by;

        return $this;
    }

    /**
     * Gets paid_on
     *
     * @return \DateTime|null
     */
    public function getPaidOn()
    {
        return $this->container['paid_on'];
    }

    /**
     * Sets paid_on
     *
     * @param \DateTime|null $paid_on Date the order was paid for
     *
     * @return self
     */
    public function setPaidOn($paid_on)
    {
        if (is_null($paid_on)) {
            throw new \InvalidArgumentException('non-nullable paid_on cannot be null');
        }
        $this->container['paid_on'] = $paid_on;

        return $this;
    }

    /**
     * Gets postal_service_cost
     *
     * @return float|null
     */
    public function getPostalServiceCost()
    {
        return $this->container['postal_service_cost'];
    }

    /**
     * Sets postal_service_cost
     *
     * @param float|null $postal_service_cost Postal service cost inclusive of tax after discount
     *
     * @return self
     */
    public function setPostalServiceCost($postal_service_cost)
    {
        if (is_null($postal_service_cost)) {
            throw new \InvalidArgumentException('non-nullable postal_service_cost cannot be null');
        }
        $this->container['postal_service_cost'] = $postal_service_cost;

        return $this;
    }

    /**
     * Gets postal_service_tax_rate
     *
     * @return float|null
     */
    public function getPostalServiceTaxRate()
    {
        return $this->container['postal_service_tax_rate'];
    }

    /**
     * Sets postal_service_tax_rate
     *
     * @param float|null $postal_service_tax_rate Tax percent for the postal service cost, eg 20
     *
     * @return self
     */
    public function setPostalServiceTaxRate($postal_service_tax_rate)
    {
        if (is_null($postal_service_tax_rate)) {
            throw new \InvalidArgumentException('non-nullable postal_service_tax_rate cannot be null');
        }
        $this->container['postal_service_tax_rate'] = $postal_service_tax_rate;

        return $this;
    }

    /**
     * Gets postal_service_discount
     *
     * @return float|null
     */
    public function getPostalServiceDiscount()
    {
        return $this->container['postal_service_discount'];
    }

    /**
     * Sets postal_service_discount
     *
     * @param float|null $postal_service_discount Discount percent for the postal service cost, this will not calculate down the postal service cost
     *
     * @return self
     */
    public function setPostalServiceDiscount($postal_service_discount)
    {
        if (is_null($postal_service_discount)) {
            throw new \InvalidArgumentException('non-nullable postal_service_discount cannot be null');
        }
        $this->container['postal_service_discount'] = $postal_service_discount;

        return $this;
    }

    /**
     * Gets discount
     *
     * @return float|null
     */
    public function getDiscount()
    {
        return $this->container['discount'];
    }

    /**
     * Sets discount
     *
     * @param float|null $discount This represents the final discount applied to the order, as a value (not a percentage), after all item-level discounts are applied. It will be split evenly across all order items
     *
     * @return self
     */
    public function setDiscount($discount)
    {
        if (is_null($discount)) {
            throw new \InvalidArgumentException('non-nullable discount cannot be null');
        }
        $this->container['discount'] = $discount;

        return $this;
    }

    /**
     * Gets items_refund
     *
     * @return float|null
     */
    public function getItemsRefund()
    {
        return $this->container['items_refund'];
    }

    /**
     * Sets items_refund
     *
     * @param float|null $items_refund The refund amount applied across all items
     *
     * @return self
     */
    public function setItemsRefund($items_refund)
    {
        if (is_null($items_refund)) {
            throw new \InvalidArgumentException('non-nullable items_refund cannot be null');
        }
        $this->container['items_refund'] = $items_refund;

        return $this;
    }

    /**
     * Gets shipping_refund
     *
     * @return float|null
     */
    public function getShippingRefund()
    {
        return $this->container['shipping_refund'];
    }

    /**
     * Sets shipping_refund
     *
     * @param float|null $shipping_refund The amount refunded for shipping (if known)
     *
     * @return self
     */
    public function setShippingRefund($shipping_refund)
    {
        if (is_null($shipping_refund)) {
            throw new \InvalidArgumentException('non-nullable shipping_refund cannot be null');
        }
        $this->container['shipping_refund'] = $shipping_refund;

        return $this;
    }

    /**
     * Gets total_refund
     *
     * @return float|null
     */
    public function getTotalRefund()
    {
        return $this->container['total_refund'];
    }

    /**
     * Sets total_refund
     *
     * @param float|null $total_refund The total refund amount applied to the order across all items, services and order-level refunds
     *
     * @return self
     */
    public function setTotalRefund($total_refund)
    {
        if (is_null($total_refund)) {
            throw new \InvalidArgumentException('non-nullable total_refund cannot be null');
        }
        $this->container['total_refund'] = $total_refund;

        return $this;
    }

    /**
     * Gets line_refund_allocation
     *
     * @return string|null
     */
    public function getLineRefundAllocation()
    {
        return $this->container['line_refund_allocation'];
    }

    /**
     * Sets line_refund_allocation
     *
     * @param string|null $line_refund_allocation The known refund allocation for the order lines
     *
     * @return self
     */
    public function setLineRefundAllocation($line_refund_allocation)
    {
        if (is_null($line_refund_allocation)) {
            throw new \InvalidArgumentException('non-nullable line_refund_allocation cannot be null');
        }
        $allowedValues = $this->getLineRefundAllocationAllowableValues();
        if (!in_array($line_refund_allocation, $allowedValues, true)) {
            throw new \InvalidArgumentException(
                sprintf(
                    "Invalid value '%s' for 'line_refund_allocation', must be one of '%s'",
                    $line_refund_allocation,
                    implode("', '", $allowedValues)
                )
            );
        }
        $this->container['line_refund_allocation'] = $line_refund_allocation;

        return $this;
    }

    /**
     * Gets shipping_refund_allocation
     *
     * @return string|null
     */
    public function getShippingRefundAllocation()
    {
        return $this->container['shipping_refund_allocation'];
    }

    /**
     * Sets shipping_refund_allocation
     *
     * @param string|null $shipping_refund_allocation The known refund allocation for the order shipping
     *
     * @return self
     */
    public function setShippingRefundAllocation($shipping_refund_allocation)
    {
        if (is_null($shipping_refund_allocation)) {
            throw new \InvalidArgumentException('non-nullable shipping_refund_allocation cannot be null');
        }
        $allowedValues = $this->getShippingRefundAllocationAllowableValues();
        if (!in_array($shipping_refund_allocation, $allowedValues, true)) {
            throw new \InvalidArgumentException(
                sprintf(
                    "Invalid value '%s' for 'shipping_refund_allocation', must be one of '%s'",
                    $shipping_refund_allocation,
                    implode("', '", $allowedValues)
                )
            );
        }
        $this->container['shipping_refund_allocation'] = $shipping_refund_allocation;

        return $this;
    }

    /**
     * Gets buyer_tax_number
     *
     * @return string|null
     */
    public function getBuyerTaxNumber()
    {
        return $this->container['buyer_tax_number'];
    }

    /**
     * Sets buyer_tax_number
     *
     * @param string|null $buyer_tax_number The tax number of the buyer
     *
     * @return self
     */
    public function setBuyerTaxNumber($buyer_tax_number)
    {
        if (is_null($buyer_tax_number)) {
            throw new \InvalidArgumentException('non-nullable buyer_tax_number cannot be null');
        }
        $this->container['buyer_tax_number'] = $buyer_tax_number;

        return $this;
    }

    /**
     * Gets discount_type
     *
     * @return string|null
     */
    public function getDiscountType()
    {
        return $this->container['discount_type'];
    }

    /**
     * Sets discount_type
     *
     * @param string|null $discount_type This represents how the discount will be split between items and postage. For an expsanation of each opiton, see the enum documentation
     *
     * @return self
     */
    public function setDiscountType($discount_type)
    {
        if (is_null($discount_type)) {
            throw new \InvalidArgumentException('non-nullable discount_type cannot be null');
        }
        $allowedValues = $this->getDiscountTypeAllowableValues();
        if (!in_array($discount_type, $allowedValues, true)) {
            throw new \InvalidArgumentException(
                sprintf(
                    "Invalid value '%s' for 'discount_type', must be one of '%s'",
                    $discount_type,
                    implode("', '", $allowedValues)
                )
            );
        }
        $this->container['discount_type'] = $discount_type;

        return $this;
    }

    /**
     * Gets discount_tax_type
     *
     * @return string|null
     */
    public function getDiscountTaxType()
    {
        return $this->container['discount_tax_type'];
    }

    /**
     * Sets discount_tax_type
     *
     * @param string|null $discount_tax_type This represents if the discount is applied before or after tax
     *
     * @return self
     */
    public function setDiscountTaxType($discount_tax_type)
    {
        if (is_null($discount_tax_type)) {
            throw new \InvalidArgumentException('non-nullable discount_tax_type cannot be null');
        }
        $allowedValues = $this->getDiscountTaxTypeAllowableValues();
        if (!in_array($discount_tax_type, $allowedValues, true)) {
            throw new \InvalidArgumentException(
                sprintf(
                    "Invalid value '%s' for 'discount_tax_type', must be one of '%s'",
                    $discount_tax_type,
                    implode("', '", $allowedValues)
                )
            );
        }
        $this->container['discount_tax_type'] = $discount_tax_type;

        return $this;
    }

    /**
     * Gets billing_address
     *
     * @return \Linnworks\Orders\Model\ChannelAddress|null
     */
    public function getBillingAddress()
    {
        return $this->container['billing_address'];
    }

    /**
     * Sets billing_address
     *
     * @param \Linnworks\Orders\Model\ChannelAddress|null $billing_address billing_address
     *
     * @return self
     */
    public function setBillingAddress($billing_address)
    {
        if (is_null($billing_address)) {
            throw new \InvalidArgumentException('non-nullable billing_address cannot be null');
        }
        $this->container['billing_address'] = $billing_address;

        return $this;
    }

    /**
     * Gets delivery_address
     *
     * @return \Linnworks\Orders\Model\ChannelAddress|null
     */
    public function getDeliveryAddress()
    {
        return $this->container['delivery_address'];
    }

    /**
     * Sets delivery_address
     *
     * @param \Linnworks\Orders\Model\ChannelAddress|null $delivery_address delivery_address
     *
     * @return self
     */
    public function setDeliveryAddress($delivery_address)
    {
        if (is_null($delivery_address)) {
            throw new \InvalidArgumentException('non-nullable delivery_address cannot be null');
        }
        $this->container['delivery_address'] = $delivery_address;

        return $this;
    }

    /**
     * Gets delivery_start_date
     *
     * @return \DateTime|null
     */
    public function getDeliveryStartDate()
    {
        return $this->container['delivery_start_date'];
    }

    /**
     * Sets delivery_start_date
     *
     * @param \DateTime|null $delivery_start_date Channel specified delivery start date (do not set where is not provided)
     *
     * @return self
     */
    public function setDeliveryStartDate($delivery_start_date)
    {
        if (is_null($delivery_start_date)) {
            throw new \InvalidArgumentException('non-nullable delivery_start_date cannot be null');
        }
        $this->container['delivery_start_date'] = $delivery_start_date;

        return $this;
    }

    /**
     * Gets delivery_end_date
     *
     * @return \DateTime|null
     */
    public function getDeliveryEndDate()
    {
        return $this->container['delivery_end_date'];
    }

    /**
     * Sets delivery_end_date
     *
     * @param \DateTime|null $delivery_end_date Channel specified delivery end date (do not set where is not provided)
     *
     * @return self
     */
    public function setDeliveryEndDate($delivery_end_date)
    {
        if (is_null($delivery_end_date)) {
            throw new \InvalidArgumentException('non-nullable delivery_end_date cannot be null');
        }
        $this->container['delivery_end_date'] = $delivery_end_date;

        return $this;
    }

    /**
     * Gets order_identifier_tags
     *
     * @return string[]|null
     */
    public function getOrderIdentifierTags()
    {
        return $this->container['order_identifier_tags'];
    }

    /**
     * Sets order_identifier_tags
     *
     * @param string[]|null $order_identifier_tags Order identifier tags
     *
     * @return self
     */
    public function setOrderIdentifierTags($order_identifier_tags)
    {
        if (is_null($order_identifier_tags)) {
            throw new \InvalidArgumentException('non-nullable order_identifier_tags cannot be null');
        }
        $this->container['order_identifier_tags'] = $order_identifier_tags;

        return $this;
    }

    /**
     * Gets force_re_save_fulfilled_order
     *
     * @return bool|null
     */
    public function getForceReSaveFulfilledOrder()
    {
        return $this->container['force_re_save_fulfilled_order'];
    }

    /**
     * Sets force_re_save_fulfilled_order
     *
     * @param bool|null $force_re_save_fulfilled_order Bool to re-save order
     *
     * @return self
     */
    public function setForceReSaveFulfilledOrder($force_re_save_fulfilled_order)
    {
        if (is_null($force_re_save_fulfilled_order)) {
            throw new \InvalidArgumentException('non-nullable force_re_save_fulfilled_order cannot be null');
        }
        $this->container['force_re_save_fulfilled_order'] = $force_re_save_fulfilled_order;

        return $this;
    }
    /**
     * Returns true if offset exists. False otherwise.
     *
     * @param integer $offset Offset
     *
     * @return boolean
     */
    public function offsetExists($offset): bool
    {
        return isset($this->container[$offset]);
    }

    /**
     * Gets offset.
     *
     * @param integer $offset Offset
     *
     * @return mixed|null
     */
    #[\ReturnTypeWillChange]
    public function offsetGet($offset)
    {
        return $this->container[$offset] ?? null;
    }

    /**
     * Sets value based on offset.
     *
     * @param int|null $offset Offset
     * @param mixed    $value  Value to be set
     *
     * @return void
     */
    public function offsetSet($offset, $value): void
    {
        if (is_null($offset)) {
            $this->container[] = $value;
        } else {
            $this->container[$offset] = $value;
        }
    }

    /**
     * Unsets offset.
     *
     * @param integer $offset Offset
     *
     * @return void
     */
    public function offsetUnset($offset): void
    {
        unset($this->container[$offset]);
    }

    /**
     * Serializes the object to a value that can be serialized natively by json_encode().
     * @link https://www.php.net/manual/en/jsonserializable.jsonserialize.php
     *
     * @return mixed Returns data which can be serialized by json_encode(), which is a value
     * of any type other than a resource.
     */
    #[\ReturnTypeWillChange]
    public function jsonSerialize()
    {
       return ObjectSerializer::sanitizeForSerialization($this);
    }

    /**
     * Gets the string presentation of the object
     *
     * @return string
     */
    public function __toString()
    {
        return json_encode(
            ObjectSerializer::sanitizeForSerialization($this),
            JSON_PRETTY_PRINT
        );
    }

    /**
     * Gets a header-safe presentation of the object
     *
     * @return string
     */
    public function toHeaderValue()
    {
        return json_encode(ObjectSerializer::sanitizeForSerialization($this));
    }
}


