Quantities on PhysObj records

The optional wms-quantity Blok adds a quantity field on the Wms.PhysObj model, and brings the corresponding logic.

With the quantity field, PhysObj record represents a certain amount of objects that are otherwise indistinguishable, for all the intents and purposes the WMS is used for.

See also

The original thoughts that led to the separation of the quantity field from wms-core.

Use cases

Goods handled in bulk

The quantity field is necessary for goods handled in bulk, since the quantity in reality is variable.

We don’t use a notion of unit of measure, as we feel it to be too much a source of complication with few benefits. Therefore, the unit of measure is to be thought as part of the PhysObj Type, which will represent for instance “Bulk sand, in metric tons”.

Goods handled as units

For goods that are to be handled as units (e.g, a bottle of milk, a 50kg bag of sand…), the obvious and only benefits of this quantity field are that we can represent many identical such units with a single line in the database.

But these benefits are severely impaired by the need to perform and record many Splits, unless it’s so much common to handle several of them together and not as some kinds of bigger packs, such as pallets or containers, that it counterbalances the overhead of all those Splits.

The database lightening can also be impaired by traceability requirements. For instance, if they induce a great variability in related properties. In the extreme case, if we track serial numbers for all goods, then we’ll end up with each PhysObj record having quantity=1.

Goods with and without quantities

If the application tracks but one bulk Physical Object Type, it becomes necessary to install wms-quantity, however many other Types there are.

This is not an issue, as PhysObj records with quantity=1, when handled through Operations having also quantity=1 will behave as if the quantity field wasn’t there in the first place.

Applicative code written without the quantity field should not require a rewrite, since it defaults to 1, for the PhysObj Model as well as for the splitter operations.

Operations and quantity

The wms-quantity blok introduces the Split and Aggregate Operations, it also makes enhances some Operations with a quantity field and automatic Splits.

Split and Aggregate


This is an overview, see the code documentation for Split and Aggregate for more details.

A Split replaces one record of PhysObj with two identical ones, keeping the overall total quantity.

According to behaviours on the PhysObj Type, they are formal (have no counterpart in reality) or physical. In the latter case, they can be reversible or not, again according to behaviours.

Aggregates are the converse of Splits, and both are always reversible in the sense of History leveraging.

Splitter operations

wms-quantity overrides some Operations by making them inherit from the WmsSplitterOperation Mixin. This enhances them with a quantity field and automatically inserts a Split if and only if that quantity is less than the Goods record’s.

As of this writing, the affected operations are:

Operations defined in downstream libraries or end applications can also inherit the mixin and behave in the same way.


  • More complexity, so wms-quantity shouldn’t be installed if not really needed.
  • PhysObj records with quantities break the intent for them to represent the “physical continuity” of the objects, since Splits create new PhysObj records, even though they haven’t changed in reality.
  • Somewhat related with the previous point is that wms-quantity is at this stage mostly incompatible with wms-reservation, for which it is really convenient to reserve whole lines. The obvious solution to this would be to introduce Splits before reserving, but don’t play well with the efficiency goals of reserver services, and can be a major source of database contention.