# Fractional product quantity and quantity units

Shop-Script is released with two licenses offering different functionality—PRO and PREMIUM. The support for fractional product quantity and quantity units described in this article are available with PREMIUM license as of Shop-Script version 9.0.0.

## Fractional product quantity

With default settings, product quantities are counted in integer values corresponding to pieces. Instead of integer quantities a user has the option to enable support for fractional quantities in the store settings.

After the common setting is enabled, a user can then enable fractional quantities for selected product types where they are necessary. When fractional quantities are enabled for a product type then they can be turned on or off for individual products of that type.

Availability of fractional product quantities is defined by the add-to-cart step specified in product properties. It is the minimum value by which the product quantity in the shopping cart and and in an order must be dividable without a remainder. The product quantity is rounded up to the nearest value dividable by the add-to-cart step. If a fractional step value is specified then a fractional quantity of that product can be ordered.

For instance, if the add-to-cart step is equal to 0.15 then shoppers can add such quantities as 0.15, 0.3, 0.45, 0.9, 1.5, etc. to their shopping carts and cannot add quantities like 1.01, 2.35 or 9.99 because such quantities are not dividable by the specified step of 0.15.

### Stock quantity precision

In product’s stock quantity, a user can specify any number, which not necessarily needs to be dividable by a the add-to-cart step. The only requirement for that value is that the precision of the stock quantity is not greater than that of the add-to-cart step.

The precision of the add-to-cart step corresponds to the number of decimal digits in the step value. For instance, step value 0.5 has precision 0.1, value 0.015 has precision 0.001, step 10 has precision 1.

If a product’s add-to-cart step is equal to 0.15 then its stock quantity can be set to such values as 0.01, 0.1 or 1 and not to 0.009 or 0.0009 because the latter values have higher precision, i.e. contain a greater number of decimal digits, than the add-to-cart step value.

If the add-to-cart step is expressed by an integer value then its precision is equal to 1. For instance, then precision of step values 1, 2, 5, 20 and 100 is equal to 1, and a user can set only integer stock quantities for such a product.

### Minimum orderable quantity and quantity adjustment value via “+/-” buttons

A user can also change the following settings related to fractional product quantity:

• minimum orderable product quantity,
• quantity adjustment value via “+/-” buttons.

A user can set these values for product types and override them for individual products of those types if necessary.

The values of these two settings can be only dividable by the add-to-cart step. Therefore, if the step value is an integer then the minimum orderable quantity and the quantity adjustment value used in the shopping cart can be integers only, too.

### Database table fields used for fractional product quantity

To support fractional product quantity other field types and additional fields are used in database tables. Both integer and fractional product quantities can be saved to those fields.

`shop_product` `count` `int, NULL` `DECIMAL(15,3), NULL`

Sum of the product variants’ quantities an all stocks.

`shop_product_skus` `count` `int, NULL` `DECIMAL(15,3), NULL`

Sum of a product variant’s stock quantities on all stocks.

`shop_product_stocks` `count` `int, NOT NULL` `DECIMAL(15,3), NOT NULL`

A product variant’s quantity on a certain stock if by-stock quantities are used. An empty value means unlimited quantity on that stock.

`shop_product_stocks_log` `before_count`
`after_count`
`diff_count`
`int, NULL` `DECIMAL(15,3), NULL`

`shop_transfer_products` `count` `int, NOT NULL` `DECIMAL(15,3), NOT NULL`

Stock-to-stock transfer.

`shop_cart_items` `quantity` `int, NOT NULL` `DECIMAL(15,3), NOT NULL`

Product’s quantity in a customer’s shopping cart.

`shop_order_items` `quantity` `int, NOT NULL` `DECIMAL(15,3), NOT NULL`

Certain item’s quantity in an order.

`shop_product` `count_denominator`

-

`int, NOT NULL`

Available precision for stock quantities. Acceptable values: 1 (whole pieces), 10 (precision to tenths), 100 (precision to hundredths), 1000 (precision to thousandths). The minimum available value for the `count` field is the reciprocal of the `count_denominator` field value.

`shop_order_items` `quantity_denominator`

-

`int, NOT NULL`

Available precision of the order item quantity value, which can be saved in the `quantity` field. The list of available values see in the description for the count_denominator field. This field’s value is saved for history purposes to be read in the cases when an ordered product is modified or deleted after the order has been placed.

`shop_product` `order_multiplicity_factor`

-

`DECIMAL(9,3), NOT NULL`

Add-to-cart step. The quantity of products specified in orders which are placed by customers in the storefront is always rounded up so as to be dividable by the step value specified in this field.

`shop_product_skus` `order_count_min*`

-

`DECIMAL(15,3), NULL`

Minimum orderable product quantity. Customers cannot order a product quantity below this field’s value. It must be dividable by the order_multiplicity_factor field value.

`shop_product_skus` `order_count_step*`

-

`DECIMAL(15,3), NULL`

Quantity adjustment value with “+/-” buttons. When the “+/-” buttons are clicked then the value of this field is added to or is subtracted for the corresponding product from the shopping cart. It must be dividable by the order_multiplicity_factor field value.

* The `order_count_min` and `order_count_step` fields are not related to the use of fractional product quantity. They can be changed and used even when support for fractional product quantity is disabled.

In table `shop_type` some additional, paired, fields are used. In each pair, the value in a field with the `_fixed` suffix denotes whether the corresponding value can be set for individual products of the specified type of whether it is equally enabled for all products of that type.

 `order_multiplicity_factor` `order_multiplicity_factor_fixed` See description of the `shop_product.order_multiplicity_factor` field. `count_denominator` `count_denominator_fixed` See description of the `shop_product.count_denominator` field. `order_count_min` `order_count_min_fixed` See description of the `shop_product_skus.order_count_min` field. `order_count_step` `order_count_step_fixed` See description of the `shop_product_skus.order_count_step` field.

The meanings of values in fields with the `_fixed` suffix:

• 0: the value can be set for individual products.
• 1: the value is enabled for all products of this type and cannot be overridden in individual products.
• 2: the value is disabled for all products of this type and cannot be enabled in individual products.

## Product quantity units

Instead of default pieces, an online store can also sell product quantities expressed in feet, liters, pounds, or any other units.

Similar to fractional product quantity, the support for custom quantity units must can be enabled on different levels:

1. For the entire store.
2. For selected product types.
3. For individual products of those types.

Each higher level defines the availability of a lower one.

### Stock & base quantity units

To express product quantities, two kinds of units are used:

• Stock unit is the unit in which a store administrator saves product quantities available on stock. For instance, roll for wallpapers.
• Base unit is an additional unit used for more convenient displaying of product prices in the storefront. For instance, if a shopper wants to compare the prices of different kinds of wallpapers then it would be more convenient to compare the prices for square feet rather than for rolls because the rolls of different wallpaper items may contain different numbers of square feet. In this example the square foot is a base quantity unit.

Both kinds of units can be used shoppers in the storefront:

• to view product prices per each of the unit—on individual product-viewing pages, in various product listing, and on the shopping cart page,
• to filter, sort, or compare products.

How to verify in PHP whether it selection of different stock and base units is allowed in product properties:

```// Base units
wa()->getSetting('base_units_enabled', '', 'shop')

// Stock units
wa()->getSetting('stock_units_enabled', '', 'shop')```

To use different quantity units, a user must select one of available, or add custom units, in the unit list in the store settings.

The information about set up quantity units is stored in the `shop_unit` table.

The `base_unit_id` and `stock_unit_id` fields in tables `shop_product` and `shop_type` are connected to the value of the `id` field in the the `shop_unit` table, except for value 0, which denotes the default quantity unit pieces.

### Database table fields used for quantity units

Table Field Description
`shop_product` `stock_unit_id`

Information about the stock unit set for a product equal to the value of the `id` field of the `shop_unit` table. Value 0 means pieces.

The values of fields used for stock quantities, `shop_product.count`, `shop_product_stocks.count` etc., must be expressed in this unit. Product quantities in shopping carts, in orders, and in printable documents are expressed in this unit.

For instance, if a store sells wallpapers in rolls then stock quantities are expressed in whole rolls and customers can order integer numbers of rolls. A customer cannot order any number of square feet of wallpapers but can order any number of rolls.

`shop_product` `base_unit_id`

Information about the stock unit set for a product equal to the value of the `id` field of the `shop_unit` table. Value 0 means pieces.

These units are convenient to compare products in the storefront. Base units are used only for shoppers’ convenience, they are not saved in shopping carts’ or orders’ properties and are not used in printable documents.

In the example with wallpapers, a base unit can be the square foot. Shoppers may find it more convenient to compare wallpaper prices per square foot than per roll.

`shop_product_skus` `stock_base_ratio`

Conversion ratio between a stock unit and a base unit for a product variant, i.e. how many base units are contained in one stock unit. In the example with wallpapers it is the number of square feet in one roll.

`shop_product` `base_price`

Base price of a product’s main variant expressed in the store’s main currency. It is used for an optimization of product sorting by the base price when there is no `JOIN` with the SKUs table in the query.

`shop_product` `min_base_price`
`max_base_price`

Lower and upper limit of product’s variants expressed in the store’s main currency. They are used for an optimization of product filtering by the base price when there is no `JOIN` with the SKUs table in the query.

`shop_order_items` `stock_unit_id`

Order item’s stock unit, `id` field’s value from the `shop_unit` table. 0 means pieces.

This value is saved for history purposes to be read in the cases when an ordered product is modified or deleted after the order has been placed.

In table `shop_type` some additional, paired, fields are used. In each pair, their is a field with the `_fixed` suffix.

The meanings of values in fields with the `_fixed` suffix:

• 0: the value can be set for individual products.
• 1: the value is enabled for all products of this type and cannot be overridden in individual products.
• 2: the value is disabled for all products of this type and cannot be enabled in individual products.
 `stock_unit_id` `stock_unit_fixed` Stock unit selected for a product type. See the description of the `shop_product.stock_unit_id` field. `base_unit_id` `base_unit_fixed` Base unit selected for a product type. See the description of the `shop_product.base_unit_id` field. `stock_base_ratio` `stock_base_ratio_fixed` quantity units conversion ratio, i.e. how many base units are contained in one stock unit. See the description of the `shop_product_skus.stock_base_ratio` field.