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.

Add-to-cart step

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.

Table Field PRO PREMIUM Description
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

Stock quantity updates log.

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.