Odoo Community Association

Stock Secondary Unit

Production/Stable License: AGPL-3 OCA/stock-logistics-warehouse Translate me on Weblate Try me on Runboat

This module lets a product be tracked, throughout the whole stock flow, in a secondary unit of measure alongside its normal one - typically a count (pieces, boxes) next to a product that is actually measured by weight or volume. A classic case: fish sold by weight, but an order is placed for “40 pieces” because each of a fixed number of guests gets exactly one - the real weight per piece varies, but the piece count must travel through the whole warehouse route exactly as ordered.

It builds on product_secondary_unit’s per-product configuration (the conversion factor, and the dependency_type that decides how the two quantities relate to each other) and extends it to stock.move and stock.move.line, so a secondary quantity can be demanded on a transfer, counted on its operations, and shown on delivery documents - not just converted once on the product form.

Two independent secondary-unit settings live on the product:

Why ``dependency_type`` matters here in particular: a stock move’s product_uom_qty (demand) and a move line’s quantity (what was actually done) are two different fields with different needs:

For independent and secondary_priority (together, the “count-preserving” types), the module makes sure the secondary quantity survives every stock operation exactly, instead of being silently re-derived from the primary quantity and losing precision or meaning:

Table of contents

Usage

Displaying stock on hand in a secondary unit

  1. On a product, go to Inventory tab > Secondary unit and choose which of the product’s configured secondary units should be used for the on-hand display (“Second unit for inventory”).
  2. A “Secondary Unit” smart button appears on the product form (next to “On Hand”), showing the current stock quantity converted into that unit. This is purely informational: it does not affect any transfer.

Demanding and counting a secondary quantity on a transfer

  1. On a transfer’s operations (the move lines list, or a move’s own detail form when Detailed Operations is enabled), the Secondary Qty and its unit are editable columns/fields (needs the “Units of Measure” feature enabled, uom.group_uom).
  2. What happens when the secondary quantity is entered depends on the product’s secondary unit dependency_type:
    • dependent: entering either quantity recomputes the other through the conversion factor.
    • independent / secondary_priority: the secondary quantity is entered on its own; for secondary_priority the primary quantity is estimated from it, but never the other way round once a secondary quantity has actually been set.

Validating a transfer that doesn’t match the secondary demand exactly

For a count-preserving secondary unit (independent or secondary_priority), if what was actually counted is less than demanded and a backorder gets created:

  • The backorder is created for exactly what’s left of the secondary demand (e.g. 40 pieces demanded, 30 counted -> the backorder demands exactly 10 pieces) - never a proportional estimate derived from whatever the primary quantity (e.g. weight) happened to be.
  • The original, now-done transfer keeps its secondary quantity in sync with what was actually counted, not the original demand.

If instead more was counted than demanded, the move’s own demand is left untouched by this module alone; reconciling that difference is out of scope for this module.

Decreasing the demand of a confirmed transfer

When the quantity of a confirmed sale order line is decreased, core creates a move with a negative quantity and merges it into the pending one. For a count-preserving secondary unit, the surviving move’s secondary quantity reflects the net effect of the decrease, not just whatever it already had before. If the decrease is bigger than the pending demand, the remaining quantity becomes a return whose secondary quantity is positive too.

Chained transfers (multi-step routes, make-to-order replenishment)

When a transfer is part of a pull chain (e.g. the “Input -> Stock” leg of a 2-step reception, or an internal make-to-order move), whatever secondary unit and quantity is set on it is carried forward into the next transfer created for that chain - the destination move doesn’t start without one.

Delivery documents

The delivery slip report shows the secondary quantity and unit next to the primary one for every line, both for a picking still being processed and once it is done.

Bug Tracker

Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us to smash it by providing a detailed and welcomed feedback.

Do not contact contributors directly about support or help with technical issues.

Credits

Authors

  • Tecnativa

Contributors

Maintainers

This module is maintained by the OCA.

Odoo Community Association

OCA, or the Odoo Community Association, is a nonprofit organization whose mission is to support the collaborative development of Odoo features and promote its widespread use.

This module is part of the OCA/stock-logistics-warehouse project on GitHub.

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.