<?php
/**
 * ProductUpdate21RequestCommon
 *
 * 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;

/**
 * ProductUpdate21RequestCommon Class Doc Comment
 *
 * @category Class
 * @description Information to update to the product family. For variants, this will update the fields to all variants in the family.
 * @package  Vend202601
 * @author   OpenAPI Generator team
 * @link     https://openapi-generator.tech
 * @implements \ArrayAccess<string, mixed>
 */
class ProductUpdate21RequestCommon implements ModelInterface, ArrayAccess, \JsonSerializable
{
    public const DISCRIMINATOR = null;

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

    /**
      * Array of property to type mappings. Used for (de)serialization
      *
      * @var string[]
      */
    protected static $openAPITypes = [
        'account_code_purchase' => 'string',
        'account_code_sale' => 'string',
        'brand_id' => 'string',
        'description' => 'string',
        'name' => 'string',
        'product_category_id' => 'string',
        'product_suppliers' => '\Vend202601\Model\ProductUpdate21Supplier[]',
        'tag_ids' => 'string[]',
        'track_inventory' => 'bool',
        'variant_attributes' => '\Vend202601\Model\ProductUpdate21RequestCommonVariantAttributesInner[]'
    ];

    /**
      * 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 = [
        'account_code_purchase' => null,
        'account_code_sale' => null,
        'brand_id' => null,
        'description' => null,
        'name' => null,
        'product_category_id' => null,
        'product_suppliers' => null,
        'tag_ids' => null,
        'track_inventory' => null,
        'variant_attributes' => null
    ];

    /**
      * Array of nullable properties. Used for (de)serialization
      *
      * @var boolean[]
      */
    protected static array $openAPINullables = [
        'account_code_purchase' => false,
        'account_code_sale' => false,
        'brand_id' => false,
        'description' => false,
        'name' => false,
        'product_category_id' => false,
        'product_suppliers' => false,
        'tag_ids' => false,
        'track_inventory' => false,
        'variant_attributes' => 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 = [
        'account_code_purchase' => 'account_code_purchase',
        'account_code_sale' => 'account_code_sale',
        'brand_id' => 'brand_id',
        'description' => 'description',
        'name' => 'name',
        'product_category_id' => 'product_category_id',
        'product_suppliers' => 'product_suppliers',
        'tag_ids' => 'tag_ids',
        'track_inventory' => 'track_inventory',
        'variant_attributes' => 'variant_attributes'
    ];

    /**
     * Array of attributes to setter functions (for deserialization of responses)
     *
     * @var string[]
     */
    protected static $setters = [
        'account_code_purchase' => 'setAccountCodePurchase',
        'account_code_sale' => 'setAccountCodeSale',
        'brand_id' => 'setBrandId',
        'description' => 'setDescription',
        'name' => 'setName',
        'product_category_id' => 'setProductCategoryId',
        'product_suppliers' => 'setProductSuppliers',
        'tag_ids' => 'setTagIds',
        'track_inventory' => 'setTrackInventory',
        'variant_attributes' => 'setVariantAttributes'
    ];

    /**
     * Array of attributes to getter functions (for serialization of requests)
     *
     * @var string[]
     */
    protected static $getters = [
        'account_code_purchase' => 'getAccountCodePurchase',
        'account_code_sale' => 'getAccountCodeSale',
        'brand_id' => 'getBrandId',
        'description' => 'getDescription',
        'name' => 'getName',
        'product_category_id' => 'getProductCategoryId',
        'product_suppliers' => 'getProductSuppliers',
        'tag_ids' => 'getTagIds',
        'track_inventory' => 'getTrackInventory',
        'variant_attributes' => 'getVariantAttributes'
    ];

    /**
     * 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;
    }


    /**
     * 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('account_code_purchase', $data ?? [], null);
        $this->setIfExists('account_code_sale', $data ?? [], null);
        $this->setIfExists('brand_id', $data ?? [], null);
        $this->setIfExists('description', $data ?? [], null);
        $this->setIfExists('name', $data ?? [], null);
        $this->setIfExists('product_category_id', $data ?? [], null);
        $this->setIfExists('product_suppliers', $data ?? [], null);
        $this->setIfExists('tag_ids', $data ?? [], null);
        $this->setIfExists('track_inventory', $data ?? [], null);
        $this->setIfExists('variant_attributes', $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 = [];

        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 account_code_purchase
     *
     * @return string|null
     */
    public function getAccountCodePurchase()
    {
        return $this->container['account_code_purchase'];
    }

    /**
     * Sets account_code_purchase
     *
     * @param string|null $account_code_purchase The code used to attribute the purchase (cost) of the product to a specific account for the Xero integration.
     *
     * @return self
     */
    public function setAccountCodePurchase($account_code_purchase)
    {
        if (is_null($account_code_purchase)) {
            throw new \InvalidArgumentException('non-nullable account_code_purchase cannot be null');
        }
        $this->container['account_code_purchase'] = $account_code_purchase;

        return $this;
    }

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

    /**
     * Sets account_code_sale
     *
     * @param string|null $account_code_sale The code used to attribute the sales of the product to a specific account for the Xero integration.
     *
     * @return self
     */
    public function setAccountCodeSale($account_code_sale)
    {
        if (is_null($account_code_sale)) {
            throw new \InvalidArgumentException('non-nullable account_code_sale cannot be null');
        }
        $this->container['account_code_sale'] = $account_code_sale;

        return $this;
    }

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

    /**
     * Sets brand_id
     *
     * @param string|null $brand_id The brand ID that the product is associated to. To remove the brand from the product, please provide empty value \"\".
     *
     * @return self
     */
    public function setBrandId($brand_id)
    {
        if (is_null($brand_id)) {
            throw new \InvalidArgumentException('non-nullable brand_id cannot be null');
        }
        $this->container['brand_id'] = $brand_id;

        return $this;
    }

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

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

        return $this;
    }

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

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

        return $this;
    }

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

    /**
     * Sets product_category_id
     *
     * @param string|null $product_category_id The product category ID tha the product is associated to. A product can only be associated to the last level (leaf) category. To remove the product category from the product, please provide empty value \"\". Product category was previously known as product types.
     *
     * @return self
     */
    public function setProductCategoryId($product_category_id)
    {
        if (is_null($product_category_id)) {
            throw new \InvalidArgumentException('non-nullable product_category_id cannot be null');
        }
        $this->container['product_category_id'] = $product_category_id;

        return $this;
    }

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

    /**
     * Sets product_suppliers
     *
     * @param \Vend202601\Model\ProductUpdate21Supplier[]|null $product_suppliers A full list of suppliers and its details that are associated to the product family. The order of the supplier listed in this list will reflect the supplier's order in the product. The first supplier is the default supplier. If do not wish to override the code and price that may be custom per variant, just provide the id.
     *
     * @return self
     */
    public function setProductSuppliers($product_suppliers)
    {
        if (is_null($product_suppliers)) {
            throw new \InvalidArgumentException('non-nullable product_suppliers cannot be null');
        }
        $this->container['product_suppliers'] = $product_suppliers;

        return $this;
    }

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

    /**
     * Sets tag_ids
     *
     * @param string[]|null $tag_ids The full list of tag ids that the product is associated to. To remove all tags, please provide empty list.
     *
     * @return self
     */
    public function setTagIds($tag_ids)
    {
        if (is_null($tag_ids)) {
            throw new \InvalidArgumentException('non-nullable tag_ids cannot be null');
        }
        $this->container['tag_ids'] = $tag_ids;

        return $this;
    }

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

    /**
     * Sets track_inventory
     *
     * @param bool|null $track_inventory True to enable inventory tracking for product. This will updating of inventory details such as manual adjustments and reorder details.
     *
     * @return self
     */
    public function setTrackInventory($track_inventory)
    {
        if (is_null($track_inventory)) {
            throw new \InvalidArgumentException('non-nullable track_inventory cannot be null');
        }
        $this->container['track_inventory'] = $track_inventory;

        return $this;
    }

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

    /**
     * Sets variant_attributes
     *
     * @param \Vend202601\Model\ProductUpdate21RequestCommonVariantAttributesInner[]|null $variant_attributes A full list of the variant attributes for the product family. The order of the variant attributes in this list will reflect the order of the attribute on the variant. Maximum three attributes.
     *
     * @return self
     */
    public function setVariantAttributes($variant_attributes)
    {
        if (is_null($variant_attributes)) {
            throw new \InvalidArgumentException('non-nullable variant_attributes cannot be null');
        }
        $this->container['variant_attributes'] = $variant_attributes;

        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));
    }
}


