<?php
/**
 * Sale
 *
 * PHP version 8.1
 *
 * @category Class
 * @package  Vend202601
 * @author   OpenAPI Generator team
 * @link     https://openapi-generator.tech
 */

/**
 * API 2026-01
 *
 * Lightspeed Retail (X-Series) API.
 *
 * The version of the OpenAPI document: 2026-01
 * Contact: x-series.api@lightspeedhq.com
 * Generated by: https://openapi-generator.tech
 * Generator version: 7.20.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 Vend202601\Model;

use \ArrayAccess;
use \Vend202601\ObjectSerializer;

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

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

    /**
      * Array of property to type mappings. Used for (de)serialization
      *
      * @var string[]
      */
    protected static $openAPITypes = [
        'adjustments' => '\Vend202601\Model\Adjustment[]',
        'attributes' => 'string[]',
        'created_at' => 'string',
        'customer_id' => 'string',
        'deleted_at' => 'string',
        'ecom_custom_charges' => '\Vend202601\Model\EcomCustomCharges',
        'id' => 'string',
        'invoice_number' => 'string',
        'invoice_sequence' => 'float',
        'line_items' => '\Vend202601\Model\LineItem[]',
        'note' => 'string',
        'outlet_id' => 'string',
        'payments' => '\Vend202601\Model\Payment[]',
        'register_id' => 'string',
        'return_for' => 'string',
        'sale_date' => 'string',
        'short_code' => 'string',
        'source' => 'string',
        'source_id' => 'string',
        'state' => 'string',
        'status' => 'string',
        'taxes' => '\Vend202601\Model\SaleTax[]',
        'total_loyalty' => 'float',
        'total_price' => 'float',
        'total_tax' => 'float',
        'updated_at' => 'string',
        'user_id' => 'string',
        'version' => 'int'
    ];

    /**
      * 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 = [
        'adjustments' => null,
        'attributes' => null,
        'created_at' => null,
        'customer_id' => null,
        'deleted_at' => null,
        'ecom_custom_charges' => null,
        'id' => 'uuid',
        'invoice_number' => null,
        'invoice_sequence' => 'double',
        'line_items' => null,
        'note' => null,
        'outlet_id' => null,
        'payments' => null,
        'register_id' => null,
        'return_for' => null,
        'sale_date' => null,
        'short_code' => null,
        'source' => null,
        'source_id' => null,
        'state' => null,
        'status' => null,
        'taxes' => null,
        'total_loyalty' => 'double',
        'total_price' => 'double',
        'total_tax' => 'double',
        'updated_at' => null,
        'user_id' => null,
        'version' => 'int64'
    ];

    /**
      * Array of nullable properties. Used for (de)serialization
      *
      * @var boolean[]
      */
    protected static array $openAPINullables = [
        'adjustments' => false,
        'attributes' => false,
        'created_at' => false,
        'customer_id' => false,
        'deleted_at' => true,
        'ecom_custom_charges' => false,
        'id' => false,
        'invoice_number' => false,
        'invoice_sequence' => false,
        'line_items' => false,
        'note' => true,
        'outlet_id' => false,
        'payments' => false,
        'register_id' => false,
        'return_for' => true,
        'sale_date' => false,
        'short_code' => false,
        'source' => false,
        'source_id' => false,
        'state' => false,
        'status' => false,
        'taxes' => false,
        'total_loyalty' => false,
        'total_price' => false,
        'total_tax' => false,
        'updated_at' => false,
        'user_id' => false,
        'version' => 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 = [
        'adjustments' => 'adjustments',
        'attributes' => 'attributes',
        'created_at' => 'created_at',
        'customer_id' => 'customer_id',
        'deleted_at' => 'deleted_at',
        'ecom_custom_charges' => 'ecom_custom_charges',
        'id' => 'id',
        'invoice_number' => 'invoice_number',
        'invoice_sequence' => 'invoice_sequence',
        'line_items' => 'line_items',
        'note' => 'note',
        'outlet_id' => 'outlet_id',
        'payments' => 'payments',
        'register_id' => 'register_id',
        'return_for' => 'return_for',
        'sale_date' => 'sale_date',
        'short_code' => 'short_code',
        'source' => 'source',
        'source_id' => 'source_id',
        'state' => 'state',
        'status' => 'status',
        'taxes' => 'taxes',
        'total_loyalty' => 'total_loyalty',
        'total_price' => 'total_price',
        'total_tax' => 'total_tax',
        'updated_at' => 'updated_at',
        'user_id' => 'user_id',
        'version' => 'version'
    ];

    /**
     * Array of attributes to setter functions (for deserialization of responses)
     *
     * @var string[]
     */
    protected static $setters = [
        'adjustments' => 'setAdjustments',
        'attributes' => 'setAttributes',
        'created_at' => 'setCreatedAt',
        'customer_id' => 'setCustomerId',
        'deleted_at' => 'setDeletedAt',
        'ecom_custom_charges' => 'setEcomCustomCharges',
        'id' => 'setId',
        'invoice_number' => 'setInvoiceNumber',
        'invoice_sequence' => 'setInvoiceSequence',
        'line_items' => 'setLineItems',
        'note' => 'setNote',
        'outlet_id' => 'setOutletId',
        'payments' => 'setPayments',
        'register_id' => 'setRegisterId',
        'return_for' => 'setReturnFor',
        'sale_date' => 'setSaleDate',
        'short_code' => 'setShortCode',
        'source' => 'setSource',
        'source_id' => 'setSourceId',
        'state' => 'setState',
        'status' => 'setStatus',
        'taxes' => 'setTaxes',
        'total_loyalty' => 'setTotalLoyalty',
        'total_price' => 'setTotalPrice',
        'total_tax' => 'setTotalTax',
        'updated_at' => 'setUpdatedAt',
        'user_id' => 'setUserId',
        'version' => 'setVersion'
    ];

    /**
     * Array of attributes to getter functions (for serialization of requests)
     *
     * @var string[]
     */
    protected static $getters = [
        'adjustments' => 'getAdjustments',
        'attributes' => 'getAttributes',
        'created_at' => 'getCreatedAt',
        'customer_id' => 'getCustomerId',
        'deleted_at' => 'getDeletedAt',
        'ecom_custom_charges' => 'getEcomCustomCharges',
        'id' => 'getId',
        'invoice_number' => 'getInvoiceNumber',
        'invoice_sequence' => 'getInvoiceSequence',
        'line_items' => 'getLineItems',
        'note' => 'getNote',
        'outlet_id' => 'getOutletId',
        'payments' => 'getPayments',
        'register_id' => 'getRegisterId',
        'return_for' => 'getReturnFor',
        'sale_date' => 'getSaleDate',
        'short_code' => 'getShortCode',
        'source' => 'getSource',
        'source_id' => 'getSourceId',
        'state' => 'getState',
        'status' => 'getStatus',
        'taxes' => 'getTaxes',
        'total_loyalty' => 'getTotalLoyalty',
        'total_price' => 'getTotalPrice',
        'total_tax' => 'getTotalTax',
        'updated_at' => 'getUpdatedAt',
        'user_id' => 'getUserId',
        'version' => 'getVersion'
    ];

    /**
     * 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 STATE_PARKED = 'parked';
    public const STATE_PENDING = 'pending';
    public const STATE_VOIDED = 'voided';
    public const STATE_CLOSED = 'closed';
    public const STATUS_SAVED = 'SAVED';
    public const STATUS_CLOSED = 'CLOSED';
    public const STATUS_ONACCOUNT = 'ONACCOUNT';
    public const STATUS_LAYBY = 'LAYBY';
    public const STATUS_ONACCOUNT_CLOSED = 'ONACCOUNT_CLOSED';
    public const STATUS_LAYBY_CLOSED = 'LAYBY_CLOSED';
    public const STATUS_AWAITING_DISPATCH = 'AWAITING_DISPATCH';
    public const STATUS_AWAITING_PICKUP = 'AWAITING_PICKUP';
    public const STATUS_DISPATCHED_CLOSED = 'DISPATCHED_CLOSED';
    public const STATUS_PICKED_UP_CLOSED = 'PICKED_UP_CLOSED';
    public const STATUS_VOIDED = 'VOIDED';
    public const STATUS_SERVICE = 'SERVICE';
    public const STATUS_SERVICE_CLOSED = 'SERVICE_CLOSED';

    /**
     * Gets allowable values of the enum
     *
     * @return string[]
     */
    public function getStateAllowableValues()
    {
        return [
            self::STATE_PARKED,
            self::STATE_PENDING,
            self::STATE_VOIDED,
            self::STATE_CLOSED,
        ];
    }

    /**
     * Gets allowable values of the enum
     *
     * @return string[]
     */
    public function getStatusAllowableValues()
    {
        return [
            self::STATUS_SAVED,
            self::STATUS_CLOSED,
            self::STATUS_ONACCOUNT,
            self::STATUS_LAYBY,
            self::STATUS_ONACCOUNT_CLOSED,
            self::STATUS_LAYBY_CLOSED,
            self::STATUS_AWAITING_DISPATCH,
            self::STATUS_AWAITING_PICKUP,
            self::STATUS_DISPATCHED_CLOSED,
            self::STATUS_PICKED_UP_CLOSED,
            self::STATUS_VOIDED,
            self::STATUS_SERVICE,
            self::STATUS_SERVICE_CLOSED,
        ];
    }

    /**
     * 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('adjustments', $data ?? [], null);
        $this->setIfExists('attributes', $data ?? [], null);
        $this->setIfExists('created_at', $data ?? [], null);
        $this->setIfExists('customer_id', $data ?? [], null);
        $this->setIfExists('deleted_at', $data ?? [], null);
        $this->setIfExists('ecom_custom_charges', $data ?? [], null);
        $this->setIfExists('id', $data ?? [], null);
        $this->setIfExists('invoice_number', $data ?? [], null);
        $this->setIfExists('invoice_sequence', $data ?? [], null);
        $this->setIfExists('line_items', $data ?? [], null);
        $this->setIfExists('note', $data ?? [], null);
        $this->setIfExists('outlet_id', $data ?? [], null);
        $this->setIfExists('payments', $data ?? [], null);
        $this->setIfExists('register_id', $data ?? [], null);
        $this->setIfExists('return_for', $data ?? [], null);
        $this->setIfExists('sale_date', $data ?? [], null);
        $this->setIfExists('short_code', $data ?? [], null);
        $this->setIfExists('source', $data ?? [], null);
        $this->setIfExists('source_id', $data ?? [], null);
        $this->setIfExists('state', $data ?? [], null);
        $this->setIfExists('status', $data ?? [], null);
        $this->setIfExists('taxes', $data ?? [], null);
        $this->setIfExists('total_loyalty', $data ?? [], null);
        $this->setIfExists('total_price', $data ?? [], null);
        $this->setIfExists('total_tax', $data ?? [], null);
        $this->setIfExists('updated_at', $data ?? [], null);
        $this->setIfExists('user_id', $data ?? [], null);
        $this->setIfExists('version', $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->getStateAllowableValues();
        if (!is_null($this->container['state']) && !in_array($this->container['state'], $allowedValues, true)) {
            $invalidProperties[] = sprintf(
                "invalid value '%s' for 'state', must be one of '%s'",
                $this->container['state'],
                implode("', '", $allowedValues)
            );
        }

        $allowedValues = $this->getStatusAllowableValues();
        if (!is_null($this->container['status']) && !in_array($this->container['status'], $allowedValues, true)) {
            $invalidProperties[] = sprintf(
                "invalid value '%s' for 'status', must be one of '%s'",
                $this->container['status'],
                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 adjustments
     *
     * @return \Vend202601\Model\Adjustment[]|null
     */
    public function getAdjustments()
    {
        return $this->container['adjustments'];
    }

    /**
     * Sets adjustments
     *
     * @param \Vend202601\Model\Adjustment[]|null $adjustments Collection of aggregated adjustments.
     *
     * @return self
     */
    public function setAdjustments($adjustments)
    {
        if (is_null($adjustments)) {
            throw new \InvalidArgumentException('non-nullable adjustments cannot be null');
        }
        $this->container['adjustments'] = $adjustments;

        return $this;
    }

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

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

        return $this;
    }

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

    /**
     * Sets created_at
     *
     * @param string|null $created_at Creation timestamp in UTC.
     *
     * @return self
     */
    public function setCreatedAt($created_at)
    {
        if (is_null($created_at)) {
            throw new \InvalidArgumentException('non-nullable created_at cannot be null');
        }
        $this->container['created_at'] = $created_at;

        return $this;
    }

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

    /**
     * Sets customer_id
     *
     * @param string|null $customer_id Valid customer ID for the retailer.
     *
     * @return self
     */
    public function setCustomerId($customer_id)
    {
        if (is_null($customer_id)) {
            throw new \InvalidArgumentException('non-nullable customer_id cannot be null');
        }
        $this->container['customer_id'] = $customer_id;

        return $this;
    }

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

    /**
     * Sets deleted_at
     *
     * @param string|null $deleted_at Deletion timestamp in UTC.
     *
     * @return self
     */
    public function setDeletedAt($deleted_at)
    {
        if (is_null($deleted_at)) {
            array_push($this->openAPINullablesSetToNull, 'deleted_at');
        } else {
            $nullablesSetToNull = $this->getOpenAPINullablesSetToNull();
            $index = array_search('deleted_at', $nullablesSetToNull);
            if ($index !== FALSE) {
                unset($nullablesSetToNull[$index]);
                $this->setOpenAPINullablesSetToNull($nullablesSetToNull);
            }
        }
        $this->container['deleted_at'] = $deleted_at;

        return $this;
    }

    /**
     * Gets ecom_custom_charges
     *
     * @return \Vend202601\Model\EcomCustomCharges|null
     */
    public function getEcomCustomCharges()
    {
        return $this->container['ecom_custom_charges'];
    }

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

        return $this;
    }

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

    /**
     * Sets id
     *
     * @param string|null $id Auto-generated object ID.
     *
     * @return self
     */
    public function setId($id)
    {
        if (is_null($id)) {
            throw new \InvalidArgumentException('non-nullable id cannot be null');
        }
        $this->container['id'] = $id;

        return $this;
    }

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

    /**
     * Sets invoice_number
     *
     * @param string|null $invoice_number Invoice number which if provided, should use the prefix and suffix defined for the register.
     *
     * @return self
     */
    public function setInvoiceNumber($invoice_number)
    {
        if (is_null($invoice_number)) {
            throw new \InvalidArgumentException('non-nullable invoice_number cannot be null');
        }
        $this->container['invoice_number'] = $invoice_number;

        return $this;
    }

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

    /**
     * Sets invoice_sequence
     *
     * @param float|null $invoice_sequence Optionally provided value.
     *
     * @return self
     */
    public function setInvoiceSequence($invoice_sequence)
    {
        if (is_null($invoice_sequence)) {
            throw new \InvalidArgumentException('non-nullable invoice_sequence cannot be null');
        }
        $this->container['invoice_sequence'] = $invoice_sequence;

        return $this;
    }

    /**
     * Gets line_items
     *
     * @return \Vend202601\Model\LineItem[]|null
     */
    public function getLineItems()
    {
        return $this->container['line_items'];
    }

    /**
     * Sets line_items
     *
     * @param \Vend202601\Model\LineItem[]|null $line_items Collection of line items.
     *
     * @return self
     */
    public function setLineItems($line_items)
    {
        if (is_null($line_items)) {
            throw new \InvalidArgumentException('non-nullable line_items cannot be null');
        }
        $this->container['line_items'] = $line_items;

        return $this;
    }

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

    /**
     * Sets note
     *
     * @param string|null $note Sale Note.
     *
     * @return self
     */
    public function setNote($note)
    {
        if (is_null($note)) {
            array_push($this->openAPINullablesSetToNull, 'note');
        } else {
            $nullablesSetToNull = $this->getOpenAPINullablesSetToNull();
            $index = array_search('note', $nullablesSetToNull);
            if ($index !== FALSE) {
                unset($nullablesSetToNull[$index]);
                $this->setOpenAPINullablesSetToNull($nullablesSetToNull);
            }
        }
        $this->container['note'] = $note;

        return $this;
    }

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

    /**
     * Sets outlet_id
     *
     * @param string|null $outlet_id Valid outlet ID for the retailer.
     *
     * @return self
     */
    public function setOutletId($outlet_id)
    {
        if (is_null($outlet_id)) {
            throw new \InvalidArgumentException('non-nullable outlet_id cannot be null');
        }
        $this->container['outlet_id'] = $outlet_id;

        return $this;
    }

    /**
     * Gets payments
     *
     * @return \Vend202601\Model\Payment[]|null
     */
    public function getPayments()
    {
        return $this->container['payments'];
    }

    /**
     * Sets payments
     *
     * @param \Vend202601\Model\Payment[]|null $payments Collection of payments.
     *
     * @return self
     */
    public function setPayments($payments)
    {
        if (is_null($payments)) {
            throw new \InvalidArgumentException('non-nullable payments cannot be null');
        }
        $this->container['payments'] = $payments;

        return $this;
    }

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

    /**
     * Sets register_id
     *
     * @param string|null $register_id Valid register ID for the retailer.
     *
     * @return self
     */
    public function setRegisterId($register_id)
    {
        if (is_null($register_id)) {
            throw new \InvalidArgumentException('non-nullable register_id cannot be null');
        }
        $this->container['register_id'] = $register_id;

        return $this;
    }

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

    /**
     * Sets return_for
     *
     * @param string|null $return_for Reference ID to a different sale if this sale was created as a return.
     *
     * @return self
     */
    public function setReturnFor($return_for)
    {
        if (is_null($return_for)) {
            array_push($this->openAPINullablesSetToNull, 'return_for');
        } else {
            $nullablesSetToNull = $this->getOpenAPINullablesSetToNull();
            $index = array_search('return_for', $nullablesSetToNull);
            if ($index !== FALSE) {
                unset($nullablesSetToNull[$index]);
                $this->setOpenAPINullablesSetToNull($nullablesSetToNull);
            }
        }
        $this->container['return_for'] = $return_for;

        return $this;
    }

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

    /**
     * Sets sale_date
     *
     * @param string|null $sale_date Sale timestamp in UTC.
     *
     * @return self
     */
    public function setSaleDate($sale_date)
    {
        if (is_null($sale_date)) {
            throw new \InvalidArgumentException('non-nullable sale_date cannot be null');
        }
        $this->container['sale_date'] = $sale_date;

        return $this;
    }

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

    /**
     * Sets short_code
     *
     * @param string|null $short_code Short, unique code used for loyalty tracking purposes.
     *
     * @return self
     */
    public function setShortCode($short_code)
    {
        if (is_null($short_code)) {
            throw new \InvalidArgumentException('non-nullable short_code cannot be null');
        }
        $this->container['short_code'] = $short_code;

        return $this;
    }

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

    /**
     * Sets source
     *
     * @param string|null $source Origin of the sale. USER for sales created in Lightspeed Retail client apps, SHOPIFY for sales synced from Shopify by the integration, ECOMMERCE for sales coming from Vend Ecommerce, QUOTE for sales converted from quotes in Lightspeed Retail client apps.
     *
     * @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 source_id
     *
     * @return string|null
     */
    public function getSourceId()
    {
        return $this->container['source_id'];
    }

    /**
     * Sets source_id
     *
     * @param string|null $source_id External ID for sales coming from other systems
     *
     * @return self
     */
    public function setSourceId($source_id)
    {
        if (is_null($source_id)) {
            throw new \InvalidArgumentException('non-nullable source_id cannot be null');
        }
        $this->container['source_id'] = $source_id;

        return $this;
    }

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

    /**
     * Sets state
     *
     * @param string|null $state State of the sale.
     *
     * @return self
     */
    public function setState($state)
    {
        if (is_null($state)) {
            throw new \InvalidArgumentException('non-nullable state cannot be null');
        }
        $allowedValues = $this->getStateAllowableValues();
        if (!in_array($state, $allowedValues, true)) {
            throw new \InvalidArgumentException(
                sprintf(
                    "Invalid value '%s' for 'state', must be one of '%s'",
                    $state,
                    implode("', '", $allowedValues)
                )
            );
        }
        $this->container['state'] = $state;

        return $this;
    }

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

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

        return $this;
    }

    /**
     * Gets taxes
     *
     * @return \Vend202601\Model\SaleTax[]|null
     */
    public function getTaxes()
    {
        return $this->container['taxes'];
    }

    /**
     * Sets taxes
     *
     * @param \Vend202601\Model\SaleTax[]|null $taxes Collection of taxes.
     *
     * @return self
     */
    public function setTaxes($taxes)
    {
        if (is_null($taxes)) {
            throw new \InvalidArgumentException('non-nullable taxes cannot be null');
        }
        $this->container['taxes'] = $taxes;

        return $this;
    }

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

    /**
     * Sets total_loyalty
     *
     * @param float|null $total_loyalty Total incurred loyalty.
     *
     * @return self
     */
    public function setTotalLoyalty($total_loyalty)
    {
        if (is_null($total_loyalty)) {
            throw new \InvalidArgumentException('non-nullable total_loyalty cannot be null');
        }
        $this->container['total_loyalty'] = $total_loyalty;

        return $this;
    }

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

    /**
     * Sets total_price
     *
     * @param float|null $total_price Total (tax exclusive) price of the sale
     *
     * @return self
     */
    public function setTotalPrice($total_price)
    {
        if (is_null($total_price)) {
            throw new \InvalidArgumentException('non-nullable total_price cannot be null');
        }
        $this->container['total_price'] = $total_price;

        return $this;
    }

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

    /**
     * Sets total_tax
     *
     * @param float|null $total_tax Total tax of the sale.
     *
     * @return self
     */
    public function setTotalTax($total_tax)
    {
        if (is_null($total_tax)) {
            throw new \InvalidArgumentException('non-nullable total_tax cannot be null');
        }
        $this->container['total_tax'] = $total_tax;

        return $this;
    }

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

    /**
     * Sets updated_at
     *
     * @param string|null $updated_at Last update timestamp in UTC.
     *
     * @return self
     */
    public function setUpdatedAt($updated_at)
    {
        if (is_null($updated_at)) {
            throw new \InvalidArgumentException('non-nullable updated_at cannot be null');
        }
        $this->container['updated_at'] = $updated_at;

        return $this;
    }

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

    /**
     * Sets user_id
     *
     * @param string|null $user_id Valid user ID for the retailer.
     *
     * @return self
     */
    public function setUserId($user_id)
    {
        if (is_null($user_id)) {
            throw new \InvalidArgumentException('non-nullable user_id cannot be null');
        }
        $this->container['user_id'] = $user_id;

        return $this;
    }

    /**
     * Gets version
     *
     * @return int|null
     */
    public function getVersion()
    {
        return $this->container['version'];
    }

    /**
     * Sets version
     *
     * @param int|null $version Auto-incrementing object version number.
     *
     * @return self
     */
    public function setVersion($version)
    {
        if (is_null($version)) {
            throw new \InvalidArgumentException('non-nullable version cannot be null');
        }
        $this->container['version'] = $version;

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

    /**
     * Gets offset.
     *
     * @param integer|string $offset Offset
     *
     * @return mixed|null
     */
    #[\ReturnTypeWillChange]
    public function offsetGet(mixed $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|string $offset Offset
     *
     * @return void
     */
    public function offsetUnset(mixed $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));
    }
}


