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

/**
 * Catalog
 *
 * Manage products, brands and categories. To learn more about catalog resources see [Catalog Overview](https://developer.bigcommerce.com/api-docs/catalog/products-overview).  - [Authentication](#authentication) - [Differentiating Variants & Modifiers](#variants-and-modifiers) - [Available Endpoints](#available-endpoints) - [Resources](#resources)  ## Authentication Requests can be authenticated by sending an `access_token` via `X-Auth-Token` HTTP header:  ```http GET /stores/store_hash/v3/catalog/summary host: api.bigcommerce.com Accept: application/json X-Auth-Token: {access_token} ```  |Header|Parameter|Description| |-|-|-| |`X-Auth-Token`|`access_token `|Obtained by creating an API account or installing an app in a BigCommerce control panel.|  ### OAuth Scopes | UI Name  | Permission | Parameter                     | |----------|------------|-------------------------------| | Products | modify     | `store_v2_products`           | | Products | read-only  | `store_v2_products_read_only` |  For more information on OAuth Scopes, see: [Authentication](https://developer.bigcommerce.com/api-docs/getting-started/authentication).  For more information on Authenticating BigCommerce APIs, see: [Authentication](https://developer.bigcommerce.com/api-docs/getting-started/authentication).  ## Differentiating Variants and Modifiers [Variants](https://support.bigcommerce.com/s/article/Product-Options-v3#variations) represent a physical product made up of [Product Option](https://support.bigcommerce.com/s/article/Product-Options-v3) choices, i.e. a large blue t-shirt. Each variant can have a unique SKU.  Modifiers represent a choice a customer makes about a product that doesn't represent a physical item, i.e. text to be printed on a t-shirt. Assigning a SKU to a modifier will turn it into a variant.  See [Variant Options](https://developer.bigcommerce.com/api-docs/catalog/products-overview#variant-options) and [Modifier Options](https://developer.bigcommerce.com/api-docs/catalog/products-overview#modifier-options) for more information.  ## Available Endpoints | Resource / Endpoint                     | Description                                                             | |-----------------------------------------|-------------------------------------------------------------------------| | Brand Images                            | Create and manage brand images                                          | | Brand Metafields                        | Create and manage brand metafields                                      | | Brands                                  | Create and manage brands                                                | | Catalog                                 | Create and manage store categories, products, and brands                | | Categories                              | Create and manage categorties                                           | | Category Images                         | Create and manage category images                                       | | Category Metafields                     | Create and manage category metafields                                   | | Product Bulk Pricing Rules              | Create and manage product bulk pricing rules                            | | Product Complex Rules                   | Create and manage product complex rules                                 | | Product Custom Fields                   | Create and manage product custom fields                                 | | Product Images                          | Create and manage product images                                        | | Product Metafields                      | Create and manage product meta fields                                   | | Product Modifier Images                 | Create and manage product modifer images                                | | Product Modifier Values                 | Create and manage product modifier values                               | | Product Modifiers                       | Create and manage product midifiers                                     | | Product Reviews                         | Create and manage product reviews                                       | | Product Variant Option Values           | Create and manage product variant option values                         | | Product Variant Options                 | Create and manage product variant options                               | | Product Variants                        | Create and manage product variants                                      | | Product Videos                          | Create and manage product videos                                        | | Products                                | Create and manage products                                              | | ProductVariant Metafields               | Create and manage product meta flields                                  | | Variants                                | Get and update all variants                                             |  ## Resources  ### Webhooks * [Products](/api-docs/getting-started/webhooks/webhook-events#webhook-events_products) * [Categories](/api-docs/getting-started/webhooks/webhook-events#webhook-events_category) * [SKU](/api-docs/getting-started/webhooks/webhook-events#webhook-events_sku)  ### Related Endpoints * [Catalog API](/api-reference/catalog/catalog-api)
 *
 * The version of the OpenAPI document: 
 * Generated by: https://openapi-generator.tech
 * Generator version: 7.13.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 Bigcommerce\CatalogV3\Model;

use \ArrayAccess;
use \Bigcommerce\CatalogV3\ObjectSerializer;

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

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

    /**
      * Array of property to type mappings. Used for (de)serialization
      *
      * @var string[]
      */
    protected static $openAPITypes = [
        'cost_price' => 'float',
        'price' => 'float',
        'sale_price' => 'float',
        'retail_price' => 'float',
        'weight' => 'float',
        'width' => 'float',
        'height' => 'float',
        'depth' => 'float',
        'is_free_shipping' => 'bool',
        'fixed_cost_shipping_price' => 'float',
        'purchasing_disabled' => 'bool',
        'purchasing_disabled_message' => 'string',
        'upc' => 'string',
        'inventory_level' => 'int',
        'inventory_warning_level' => 'int',
        'bin_picking_number' => 'string',
        'id' => 'int',
        'product_id' => 'int',
        'sku' => 'string',
        'sku_id' => 'int',
        'option_values' => '\Bigcommerce\CatalogV3\Model\ProductVariantOptionValueFull[]',
        'calculated_price' => 'float'
    ];

    /**
      * 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 = [
        'cost_price' => 'double',
        'price' => 'double',
        'sale_price' => 'double',
        'retail_price' => 'double',
        'weight' => 'double',
        'width' => 'double',
        'height' => 'double',
        'depth' => 'double',
        'is_free_shipping' => null,
        'fixed_cost_shipping_price' => 'double',
        'purchasing_disabled' => null,
        'purchasing_disabled_message' => null,
        'upc' => null,
        'inventory_level' => null,
        'inventory_warning_level' => null,
        'bin_picking_number' => null,
        'id' => null,
        'product_id' => null,
        'sku' => null,
        'sku_id' => null,
        'option_values' => null,
        'calculated_price' => 'double'
    ];

    /**
      * Array of nullable properties. Used for (de)serialization
      *
      * @var boolean[]
      */
    protected static array $openAPINullables = [
        'cost_price' => true,
        'price' => true,
        'sale_price' => true,
        'retail_price' => true,
        'weight' => true,
        'width' => true,
        'height' => true,
        'depth' => true,
        'is_free_shipping' => false,
        'fixed_cost_shipping_price' => true,
        'purchasing_disabled' => false,
        'purchasing_disabled_message' => false,
        'upc' => true,
        'inventory_level' => true,
        'inventory_warning_level' => true,
        'bin_picking_number' => true,
        'id' => false,
        'product_id' => false,
        'sku' => false,
        'sku_id' => true,
        'option_values' => false,
        'calculated_price' => 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 = [
        'cost_price' => 'cost_price',
        'price' => 'price',
        'sale_price' => 'sale_price',
        'retail_price' => 'retail_price',
        'weight' => 'weight',
        'width' => 'width',
        'height' => 'height',
        'depth' => 'depth',
        'is_free_shipping' => 'is_free_shipping',
        'fixed_cost_shipping_price' => 'fixed_cost_shipping_price',
        'purchasing_disabled' => 'purchasing_disabled',
        'purchasing_disabled_message' => 'purchasing_disabled_message',
        'upc' => 'upc',
        'inventory_level' => 'inventory_level',
        'inventory_warning_level' => 'inventory_warning_level',
        'bin_picking_number' => 'bin_picking_number',
        'id' => 'id',
        'product_id' => 'product_id',
        'sku' => 'sku',
        'sku_id' => 'sku_id',
        'option_values' => 'option_values',
        'calculated_price' => 'calculated_price'
    ];

    /**
     * Array of attributes to setter functions (for deserialization of responses)
     *
     * @var string[]
     */
    protected static $setters = [
        'cost_price' => 'setCostPrice',
        'price' => 'setPrice',
        'sale_price' => 'setSalePrice',
        'retail_price' => 'setRetailPrice',
        'weight' => 'setWeight',
        'width' => 'setWidth',
        'height' => 'setHeight',
        'depth' => 'setDepth',
        'is_free_shipping' => 'setIsFreeShipping',
        'fixed_cost_shipping_price' => 'setFixedCostShippingPrice',
        'purchasing_disabled' => 'setPurchasingDisabled',
        'purchasing_disabled_message' => 'setPurchasingDisabledMessage',
        'upc' => 'setUpc',
        'inventory_level' => 'setInventoryLevel',
        'inventory_warning_level' => 'setInventoryWarningLevel',
        'bin_picking_number' => 'setBinPickingNumber',
        'id' => 'setId',
        'product_id' => 'setProductId',
        'sku' => 'setSku',
        'sku_id' => 'setSkuId',
        'option_values' => 'setOptionValues',
        'calculated_price' => 'setCalculatedPrice'
    ];

    /**
     * Array of attributes to getter functions (for serialization of requests)
     *
     * @var string[]
     */
    protected static $getters = [
        'cost_price' => 'getCostPrice',
        'price' => 'getPrice',
        'sale_price' => 'getSalePrice',
        'retail_price' => 'getRetailPrice',
        'weight' => 'getWeight',
        'width' => 'getWidth',
        'height' => 'getHeight',
        'depth' => 'getDepth',
        'is_free_shipping' => 'getIsFreeShipping',
        'fixed_cost_shipping_price' => 'getFixedCostShippingPrice',
        'purchasing_disabled' => 'getPurchasingDisabled',
        'purchasing_disabled_message' => 'getPurchasingDisabledMessage',
        'upc' => 'getUpc',
        'inventory_level' => 'getInventoryLevel',
        'inventory_warning_level' => 'getInventoryWarningLevel',
        'bin_picking_number' => 'getBinPickingNumber',
        'id' => 'getId',
        'product_id' => 'getProductId',
        'sku' => 'getSku',
        'sku_id' => 'getSkuId',
        'option_values' => 'getOptionValues',
        'calculated_price' => 'getCalculatedPrice'
    ];

    /**
     * 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('cost_price', $data ?? [], null);
        $this->setIfExists('price', $data ?? [], null);
        $this->setIfExists('sale_price', $data ?? [], null);
        $this->setIfExists('retail_price', $data ?? [], null);
        $this->setIfExists('weight', $data ?? [], null);
        $this->setIfExists('width', $data ?? [], null);
        $this->setIfExists('height', $data ?? [], null);
        $this->setIfExists('depth', $data ?? [], null);
        $this->setIfExists('is_free_shipping', $data ?? [], null);
        $this->setIfExists('fixed_cost_shipping_price', $data ?? [], null);
        $this->setIfExists('purchasing_disabled', $data ?? [], null);
        $this->setIfExists('purchasing_disabled_message', $data ?? [], null);
        $this->setIfExists('upc', $data ?? [], null);
        $this->setIfExists('inventory_level', $data ?? [], null);
        $this->setIfExists('inventory_warning_level', $data ?? [], null);
        $this->setIfExists('bin_picking_number', $data ?? [], null);
        $this->setIfExists('id', $data ?? [], null);
        $this->setIfExists('product_id', $data ?? [], null);
        $this->setIfExists('sku', $data ?? [], null);
        $this->setIfExists('sku_id', $data ?? [], null);
        $this->setIfExists('option_values', $data ?? [], null);
        $this->setIfExists('calculated_price', $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 = [];

        if (!is_null($this->container['cost_price']) && ($this->container['cost_price'] < 0)) {
            $invalidProperties[] = "invalid value for 'cost_price', must be bigger than or equal to 0.";
        }

        if (!is_null($this->container['price']) && ($this->container['price'] < 0)) {
            $invalidProperties[] = "invalid value for 'price', must be bigger than or equal to 0.";
        }

        if (!is_null($this->container['sale_price']) && ($this->container['sale_price'] < 0)) {
            $invalidProperties[] = "invalid value for 'sale_price', must be bigger than or equal to 0.";
        }

        if (!is_null($this->container['retail_price']) && ($this->container['retail_price'] < 0)) {
            $invalidProperties[] = "invalid value for 'retail_price', must be bigger than or equal to 0.";
        }

        if (!is_null($this->container['weight']) && ($this->container['weight'] < 0)) {
            $invalidProperties[] = "invalid value for 'weight', must be bigger than or equal to 0.";
        }

        if (!is_null($this->container['width']) && ($this->container['width'] < 0)) {
            $invalidProperties[] = "invalid value for 'width', must be bigger than or equal to 0.";
        }

        if (!is_null($this->container['height']) && ($this->container['height'] < 0)) {
            $invalidProperties[] = "invalid value for 'height', must be bigger than or equal to 0.";
        }

        if (!is_null($this->container['depth']) && ($this->container['depth'] < 0)) {
            $invalidProperties[] = "invalid value for 'depth', must be bigger than or equal to 0.";
        }

        if (!is_null($this->container['fixed_cost_shipping_price']) && ($this->container['fixed_cost_shipping_price'] < 0)) {
            $invalidProperties[] = "invalid value for 'fixed_cost_shipping_price', must be bigger than or equal to 0.";
        }

        if (!is_null($this->container['purchasing_disabled_message']) && (mb_strlen($this->container['purchasing_disabled_message']) > 255)) {
            $invalidProperties[] = "invalid value for 'purchasing_disabled_message', the character length must be smaller than or equal to 255.";
        }

        if (!is_null($this->container['purchasing_disabled_message']) && (mb_strlen($this->container['purchasing_disabled_message']) < 0)) {
            $invalidProperties[] = "invalid value for 'purchasing_disabled_message', the character length must be bigger than or equal to 0.";
        }

        if (!is_null($this->container['bin_picking_number']) && (mb_strlen($this->container['bin_picking_number']) > 255)) {
            $invalidProperties[] = "invalid value for 'bin_picking_number', the character length must be smaller than or equal to 255.";
        }

        if (!is_null($this->container['bin_picking_number']) && (mb_strlen($this->container['bin_picking_number']) < 0)) {
            $invalidProperties[] = "invalid value for 'bin_picking_number', the character length must be bigger than or equal to 0.";
        }

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

    /**
     * Sets cost_price
     *
     * @param float|null $cost_price The cost price of the variant. Not affected by Price List prices.
     *
     * @return self
     */
    public function setCostPrice($cost_price)
    {
        if (is_null($cost_price)) {
            array_push($this->openAPINullablesSetToNull, 'cost_price');
        } else {
            $nullablesSetToNull = $this->getOpenAPINullablesSetToNull();
            $index = array_search('cost_price', $nullablesSetToNull);
            if ($index !== FALSE) {
                unset($nullablesSetToNull[$index]);
                $this->setOpenAPINullablesSetToNull($nullablesSetToNull);
            }
        }

        if (!is_null($cost_price) && ($cost_price < 0)) {
            throw new \InvalidArgumentException('invalid value for $cost_price when calling ProductVariantFull., must be bigger than or equal to 0.');
        }

        $this->container['cost_price'] = $cost_price;

        return $this;
    }

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

    /**
     * Sets price
     *
     * @param float|null $price This variant's base price on the storefront. If a Price List ID is used, the Price List value will be used. If a Price List ID is not used, and this value is `null`, the product's default price (set in the Product resource's `price` field) will be used as the base price.
     *
     * @return self
     */
    public function setPrice($price)
    {
        if (is_null($price)) {
            array_push($this->openAPINullablesSetToNull, 'price');
        } else {
            $nullablesSetToNull = $this->getOpenAPINullablesSetToNull();
            $index = array_search('price', $nullablesSetToNull);
            if ($index !== FALSE) {
                unset($nullablesSetToNull[$index]);
                $this->setOpenAPINullablesSetToNull($nullablesSetToNull);
            }
        }

        if (!is_null($price) && ($price < 0)) {
            throw new \InvalidArgumentException('invalid value for $price when calling ProductVariantFull., must be bigger than or equal to 0.');
        }

        $this->container['price'] = $price;

        return $this;
    }

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

    /**
     * Sets sale_price
     *
     * @param float|null $sale_price This variant's sale price on the storefront. If a Price List ID is used, the Price List value will be used. If a Price List ID is not used, and this value is null, the product's sale price (set in the Product resource's `price` field) will be used as the sale price.
     *
     * @return self
     */
    public function setSalePrice($sale_price)
    {
        if (is_null($sale_price)) {
            array_push($this->openAPINullablesSetToNull, 'sale_price');
        } else {
            $nullablesSetToNull = $this->getOpenAPINullablesSetToNull();
            $index = array_search('sale_price', $nullablesSetToNull);
            if ($index !== FALSE) {
                unset($nullablesSetToNull[$index]);
                $this->setOpenAPINullablesSetToNull($nullablesSetToNull);
            }
        }

        if (!is_null($sale_price) && ($sale_price < 0)) {
            throw new \InvalidArgumentException('invalid value for $sale_price when calling ProductVariantFull., must be bigger than or equal to 0.');
        }

        $this->container['sale_price'] = $sale_price;

        return $this;
    }

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

    /**
     * Sets retail_price
     *
     * @param float|null $retail_price This variant's retail price on the storefront. If a Price List ID is used, the Price List value will be used. If a Price List ID is not used, and this value is null, the product's retail price (set in the Product resource's `price` field) will be used as the retail price.
     *
     * @return self
     */
    public function setRetailPrice($retail_price)
    {
        if (is_null($retail_price)) {
            array_push($this->openAPINullablesSetToNull, 'retail_price');
        } else {
            $nullablesSetToNull = $this->getOpenAPINullablesSetToNull();
            $index = array_search('retail_price', $nullablesSetToNull);
            if ($index !== FALSE) {
                unset($nullablesSetToNull[$index]);
                $this->setOpenAPINullablesSetToNull($nullablesSetToNull);
            }
        }

        if (!is_null($retail_price) && ($retail_price < 0)) {
            throw new \InvalidArgumentException('invalid value for $retail_price when calling ProductVariantFull., must be bigger than or equal to 0.');
        }

        $this->container['retail_price'] = $retail_price;

        return $this;
    }

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

    /**
     * Sets weight
     *
     * @param float|null $weight This variant's base weight on the storefront. If this value is null, the product's default weight (set in the Product resource's weight field) will be used as the base weight.
     *
     * @return self
     */
    public function setWeight($weight)
    {
        if (is_null($weight)) {
            array_push($this->openAPINullablesSetToNull, 'weight');
        } else {
            $nullablesSetToNull = $this->getOpenAPINullablesSetToNull();
            $index = array_search('weight', $nullablesSetToNull);
            if ($index !== FALSE) {
                unset($nullablesSetToNull[$index]);
                $this->setOpenAPINullablesSetToNull($nullablesSetToNull);
            }
        }

        if (!is_null($weight) && ($weight < 0)) {
            throw new \InvalidArgumentException('invalid value for $weight when calling ProductVariantFull., must be bigger than or equal to 0.');
        }

        $this->container['weight'] = $weight;

        return $this;
    }

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

    /**
     * Sets width
     *
     * @param float|null $width Width of the variant, which can be used when calculating shipping costs. If this value is `null`, the product's default width (set in the Product resource's `width` field) will be used as the base width.
     *
     * @return self
     */
    public function setWidth($width)
    {
        if (is_null($width)) {
            array_push($this->openAPINullablesSetToNull, 'width');
        } else {
            $nullablesSetToNull = $this->getOpenAPINullablesSetToNull();
            $index = array_search('width', $nullablesSetToNull);
            if ($index !== FALSE) {
                unset($nullablesSetToNull[$index]);
                $this->setOpenAPINullablesSetToNull($nullablesSetToNull);
            }
        }

        if (!is_null($width) && ($width < 0)) {
            throw new \InvalidArgumentException('invalid value for $width when calling ProductVariantFull., must be bigger than or equal to 0.');
        }

        $this->container['width'] = $width;

        return $this;
    }

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

    /**
     * Sets height
     *
     * @param float|null $height Height of the variant, which can be used when calculating shipping costs. If this value is `null`, the product's default height (set in the Product resource's `height` field) will be used as the base height.
     *
     * @return self
     */
    public function setHeight($height)
    {
        if (is_null($height)) {
            array_push($this->openAPINullablesSetToNull, 'height');
        } else {
            $nullablesSetToNull = $this->getOpenAPINullablesSetToNull();
            $index = array_search('height', $nullablesSetToNull);
            if ($index !== FALSE) {
                unset($nullablesSetToNull[$index]);
                $this->setOpenAPINullablesSetToNull($nullablesSetToNull);
            }
        }

        if (!is_null($height) && ($height < 0)) {
            throw new \InvalidArgumentException('invalid value for $height when calling ProductVariantFull., must be bigger than or equal to 0.');
        }

        $this->container['height'] = $height;

        return $this;
    }

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

    /**
     * Sets depth
     *
     * @param float|null $depth Depth of the variant, which can be used when calculating shipping costs. If this value is `null`, the product's default depth (set in the Product resource's `depth` field) will be used as the base depth.
     *
     * @return self
     */
    public function setDepth($depth)
    {
        if (is_null($depth)) {
            array_push($this->openAPINullablesSetToNull, 'depth');
        } else {
            $nullablesSetToNull = $this->getOpenAPINullablesSetToNull();
            $index = array_search('depth', $nullablesSetToNull);
            if ($index !== FALSE) {
                unset($nullablesSetToNull[$index]);
                $this->setOpenAPINullablesSetToNull($nullablesSetToNull);
            }
        }

        if (!is_null($depth) && ($depth < 0)) {
            throw new \InvalidArgumentException('invalid value for $depth when calling ProductVariantFull., must be bigger than or equal to 0.');
        }

        $this->container['depth'] = $depth;

        return $this;
    }

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

    /**
     * Sets is_free_shipping
     *
     * @param bool|null $is_free_shipping Flag used to indicate whether the variant has free shipping. If `true`, the shipping cost for the variant will be zero.
     *
     * @return self
     */
    public function setIsFreeShipping($is_free_shipping)
    {
        if (is_null($is_free_shipping)) {
            throw new \InvalidArgumentException('non-nullable is_free_shipping cannot be null');
        }
        $this->container['is_free_shipping'] = $is_free_shipping;

        return $this;
    }

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

    /**
     * Sets fixed_cost_shipping_price
     *
     * @param float|null $fixed_cost_shipping_price A fixed shipping cost for the variant. If defined, this value will be used during checkout instead of normal shipping-cost calculation.
     *
     * @return self
     */
    public function setFixedCostShippingPrice($fixed_cost_shipping_price)
    {
        if (is_null($fixed_cost_shipping_price)) {
            array_push($this->openAPINullablesSetToNull, 'fixed_cost_shipping_price');
        } else {
            $nullablesSetToNull = $this->getOpenAPINullablesSetToNull();
            $index = array_search('fixed_cost_shipping_price', $nullablesSetToNull);
            if ($index !== FALSE) {
                unset($nullablesSetToNull[$index]);
                $this->setOpenAPINullablesSetToNull($nullablesSetToNull);
            }
        }

        if (!is_null($fixed_cost_shipping_price) && ($fixed_cost_shipping_price < 0)) {
            throw new \InvalidArgumentException('invalid value for $fixed_cost_shipping_price when calling ProductVariantFull., must be bigger than or equal to 0.');
        }

        $this->container['fixed_cost_shipping_price'] = $fixed_cost_shipping_price;

        return $this;
    }

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

    /**
     * Sets purchasing_disabled
     *
     * @param bool|null $purchasing_disabled If `true`, this variant will not be purchasable on the storefront.
     *
     * @return self
     */
    public function setPurchasingDisabled($purchasing_disabled)
    {
        if (is_null($purchasing_disabled)) {
            throw new \InvalidArgumentException('non-nullable purchasing_disabled cannot be null');
        }
        $this->container['purchasing_disabled'] = $purchasing_disabled;

        return $this;
    }

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

    /**
     * Sets purchasing_disabled_message
     *
     * @param string|null $purchasing_disabled_message If `purchasing_disabled` is `true`, this message should show on the storefront when the variant is selected.
     *
     * @return self
     */
    public function setPurchasingDisabledMessage($purchasing_disabled_message)
    {
        if (is_null($purchasing_disabled_message)) {
            throw new \InvalidArgumentException('non-nullable purchasing_disabled_message cannot be null');
        }
        if ((mb_strlen($purchasing_disabled_message) > 255)) {
            throw new \InvalidArgumentException('invalid length for $purchasing_disabled_message when calling ProductVariantFull., must be smaller than or equal to 255.');
        }
        if ((mb_strlen($purchasing_disabled_message) < 0)) {
            throw new \InvalidArgumentException('invalid length for $purchasing_disabled_message when calling ProductVariantFull., must be bigger than or equal to 0.');
        }

        $this->container['purchasing_disabled_message'] = $purchasing_disabled_message;

        return $this;
    }

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

    /**
     * Sets upc
     *
     * @param string|null $upc The UPC code used in feeds for shopping comparison sites and external channel integrations.
     *
     * @return self
     */
    public function setUpc($upc)
    {
        if (is_null($upc)) {
            array_push($this->openAPINullablesSetToNull, 'upc');
        } else {
            $nullablesSetToNull = $this->getOpenAPINullablesSetToNull();
            $index = array_search('upc', $nullablesSetToNull);
            if ($index !== FALSE) {
                unset($nullablesSetToNull[$index]);
                $this->setOpenAPINullablesSetToNull($nullablesSetToNull);
            }
        }
        $this->container['upc'] = $upc;

        return $this;
    }

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

    /**
     * Sets inventory_level
     *
     * @param int|null $inventory_level Inventory level for the variant, which is used when the product's inventory_tracking is set to `variant`.
     *
     * @return self
     */
    public function setInventoryLevel($inventory_level)
    {
        if (is_null($inventory_level)) {
            array_push($this->openAPINullablesSetToNull, 'inventory_level');
        } else {
            $nullablesSetToNull = $this->getOpenAPINullablesSetToNull();
            $index = array_search('inventory_level', $nullablesSetToNull);
            if ($index !== FALSE) {
                unset($nullablesSetToNull[$index]);
                $this->setOpenAPINullablesSetToNull($nullablesSetToNull);
            }
        }
        $this->container['inventory_level'] = $inventory_level;

        return $this;
    }

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

    /**
     * Sets inventory_warning_level
     *
     * @param int|null $inventory_warning_level When the variant hits this inventory level, it is considered low stock.
     *
     * @return self
     */
    public function setInventoryWarningLevel($inventory_warning_level)
    {
        if (is_null($inventory_warning_level)) {
            array_push($this->openAPINullablesSetToNull, 'inventory_warning_level');
        } else {
            $nullablesSetToNull = $this->getOpenAPINullablesSetToNull();
            $index = array_search('inventory_warning_level', $nullablesSetToNull);
            if ($index !== FALSE) {
                unset($nullablesSetToNull[$index]);
                $this->setOpenAPINullablesSetToNull($nullablesSetToNull);
            }
        }
        $this->container['inventory_warning_level'] = $inventory_warning_level;

        return $this;
    }

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

    /**
     * Sets bin_picking_number
     *
     * @param string|null $bin_picking_number Identifies where in a warehouse the variant is located.
     *
     * @return self
     */
    public function setBinPickingNumber($bin_picking_number)
    {
        if (is_null($bin_picking_number)) {
            array_push($this->openAPINullablesSetToNull, 'bin_picking_number');
        } else {
            $nullablesSetToNull = $this->getOpenAPINullablesSetToNull();
            $index = array_search('bin_picking_number', $nullablesSetToNull);
            if ($index !== FALSE) {
                unset($nullablesSetToNull[$index]);
                $this->setOpenAPINullablesSetToNull($nullablesSetToNull);
            }
        }
        if (!is_null($bin_picking_number) && (mb_strlen($bin_picking_number) > 255)) {
            throw new \InvalidArgumentException('invalid length for $bin_picking_number when calling ProductVariantFull., must be smaller than or equal to 255.');
        }
        if (!is_null($bin_picking_number) && (mb_strlen($bin_picking_number) < 0)) {
            throw new \InvalidArgumentException('invalid length for $bin_picking_number when calling ProductVariantFull., must be bigger than or equal to 0.');
        }

        $this->container['bin_picking_number'] = $bin_picking_number;

        return $this;
    }

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

    /**
     * Sets id
     *
     * @param int|null $id 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 product_id
     *
     * @return int|null
     */
    public function getProductId()
    {
        return $this->container['product_id'];
    }

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

        return $this;
    }

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

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

        return $this;
    }

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

    /**
     * Sets sku_id
     *
     * @param int|null $sku_id Read-only reference to v2 API's SKU ID. Null if it is a base variant.
     *
     * @return self
     */
    public function setSkuId($sku_id)
    {
        if (is_null($sku_id)) {
            array_push($this->openAPINullablesSetToNull, 'sku_id');
        } else {
            $nullablesSetToNull = $this->getOpenAPINullablesSetToNull();
            $index = array_search('sku_id', $nullablesSetToNull);
            if ($index !== FALSE) {
                unset($nullablesSetToNull[$index]);
                $this->setOpenAPINullablesSetToNull($nullablesSetToNull);
            }
        }
        $this->container['sku_id'] = $sku_id;

        return $this;
    }

    /**
     * Gets option_values
     *
     * @return \Bigcommerce\CatalogV3\Model\ProductVariantOptionValueFull[]|null
     */
    public function getOptionValues()
    {
        return $this->container['option_values'];
    }

    /**
     * Sets option_values
     *
     * @param \Bigcommerce\CatalogV3\Model\ProductVariantOptionValueFull[]|null $option_values Array of option and option values IDs that make up this variant. Will be empty if the variant is the product's base variant.
     *
     * @return self
     */
    public function setOptionValues($option_values)
    {
        if (is_null($option_values)) {
            throw new \InvalidArgumentException('non-nullable option_values cannot be null');
        }
        $this->container['option_values'] = $option_values;

        return $this;
    }

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

    /**
     * Sets calculated_price
     *
     * @param float|null $calculated_price The price of the variant as seen on the storefront. This price takes into account `sale_price` and any price adjustment rules that are applicable to this variant.
     *
     * @return self
     */
    public function setCalculatedPrice($calculated_price)
    {
        if (is_null($calculated_price)) {
            throw new \InvalidArgumentException('non-nullable calculated_price cannot be null');
        }
        $this->container['calculated_price'] = $calculated_price;

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


