Units of Measure — how every quantity is measured and converted¶
What this covers. A food business names the same physical amount a dozen different ways: flour arrives in a "case of six 2 kg bags," a recipe asks for "300 g," a count sheet reads "4.5 kg on hand," and a price list quotes "€/case." This chapter explains how all of those become one honest number the books can add up. It covers the single unit model gated by physical dimension (mass, volume, or count); the rule that you can only convert within a dimension (the system never guesses density); the company-shared set of standard units plus the operator-added custom units and per-item units; the bundle you buy in — a 25 kg sack, a case of 6 × 2 kg — which is just a per-item unit that also carries a barcode; the moment of truth where every quantity is converted to a base amount as it is posted; and why an item's base unit is frozen once it has any history. A unit is a measure — how much of something there is — and how a vendor prices an item in one is a separate layer (the supplier article), taught in Procurement; this chapter touches it only where price meets measurement.
1. Why a units model exists at all¶
Start with the problem it solves. Every document in a restaurant talks about quantities, and almost none of them agree on the unit:
- A supplier price list quotes a case.
- A goods receipt — the record that stock physically arrived — might be in cases, or in bags.
- A recipe asks for grams.
- A count sheet reads kilograms.
- The books need a single running number for "how much flour is on hand."
If each of those stored its own number in its own unit, every downstream calculation would have to translate on the fly, at the exact moment it did the math. On-hand, cost, recipe explosion, month-end variance — each would have to know how to turn a case into a gram before it could add anything up. That is precisely where inventory systems silently go wrong: a kilogram gets added to a gram, or a price-per-case gets averaged against a price-per-bag, and the error is invisible until the count doesn't reconcile.
The domain avoids this with one rule the whole stock side leans on:
Every quantity the books store is already in the item's base unit. The conversion happens once — at the edge, the moment a document is posted — and never again.
This is the convert-to-base-at-the-posting-edge rule. Everything downstream — the running stock balance, weighted-average cost, theoretical-vs-actual variance — works only on base-unit numbers and never re-converts. ("Weighted-average cost," or WAC, is the running cost-per-unit of a pool of identical stock; we'll lean on it below.) Someone auditing on-hand never has to ask "what unit is this number in?" — it is always grams, or milliliters, or pieces.
The units model is simply the machinery that turns a quantity in any operator-facing unit — an ounce, a kilogram, or a bundle like a case of six — into that one base number.
2. One model, gated by physical dimension¶
Every measure a company uses — a gram, a "2 kg bag," a supplier's "case of six" — lives in one shared unit model. What keeps grams from being averaged against milliliters is a single property on every unit: its dimension, the kind of physical quantity it measures. There are exactly three, and every unit belongs to one:
| Dimension | Canonical base | Example units in this dimension |
|---|---|---|
| Mass | gram (g) | g, kg, oz, lb, "2 kg bag," "case of 6 × 2 kg" |
| Volume | milliliter (ml) | ml, L, fl oz, qt, gal, "1.5 L bottle" |
| Count | piece (pcs) | pcs, "tray of 30 eggs," "10-can case" |
The single hard rule that follows:
Two units can convert into each other only when they share a dimension.
This is structural, not a matter of discipline. A unit is allowed on an item only when its dimension matches the item's. Picking an ounce-based unit (Mass) for a milliliter item (Volume) is rejected before any number is computed — there is no later stage at which an incompatible unit could slip through and corrupt a total.
Why three dimensions and not, say, one big list of units. Mass, volume, and count are the three physically incommensurable ways a food operation measures things. Within a dimension, conversion is pure arithmetic that is always true everywhere — 1 kg is 1000 g for flour, for sugar, for anything. Across dimensions it is never universally true: turning milliliters into grams needs a density that depends on the specific substance (see §6). The dimension boundary is the line between "always safe to convert" and "only safe with extra, item-specific knowledge," drawn once so no calculation downstream has to redraw it.
The conversion factor — every unit points at its base¶
Each unit carries one number: how much of its dimension's canonical base one of this unit equals. We'll call that number its conversion factor to base. The canonical base of each dimension is the unit whose factor is 1 — the gram, the milliliter, the piece.
| Unit | Dimension | Factor to base | Read as |
|---|---|---|---|
| gram | Mass | 1 | 1 g = 1 g (canonical) |
| kilogram | Mass | 1000 | 1 kg = 1000 g |
| ounce | Mass | 28.3495 | 1 oz = 28.3495 g |
| pound | Mass | 453.592 | 1 lb = 453.592 g |
| milliliter | Volume | 1 | 1 ml = 1 ml (canonical) |
| liter | Volume | 1000 | 1 L = 1000 ml |
| fluid ounce | Volume | 29.5735 | 1 fl oz = 29.5735 ml |
| quart | Volume | 946.353 | 1 qt = 946.353 ml |
| gallon | Volume | 3785.41 | 1 gal = 3785.41 ml |
| piece | Count | 1 | 1 pcs = 1 pcs (canonical) |
With every unit pointing straight at its base, converting to base is the simplest possible arithmetic — a single multiply:
base amount = quantity × the unit's factor to base
That one line is the entire conversion engine.
Why "factor to base" beats unit-to-unit tables. Because every unit reduces to the same base independently, there is never a chain to walk and never a question like "what's the path from kilograms to ounces?" — both resolve to grams on their own, and you compare the two grams. Adding a new unit ("case of 6 × 2 kg") is a single new number (12000 g), not a fresh row in a conversion table against every other unit you'd have to keep consistent forever. This is the textbook one canonical base per dimension design, and it is what lets the conversion stay a single multiply no matter how many exotic units a company invents.
3. The dimension an item lives in vs. the units it can use¶
Two things in this domain wear the word "base," and it is worth keeping them apart from the start.
The first is an item's base unit — chosen once, when the inventory item is first created, and limited to exactly the three canonical choices: grams, milliliters, or pieces. This choice does one job: it declares which dimension the item lives in, and therefore which canonical base every number the books keep about that item is denominated in. Flour is a Mass item, so its base unit is the gram; its on-hand, its cost-per-unit, its recipe draws — all in grams. Notice an item can't be anchored on "kg" or "oz": those aren't dimensions, they're just other Mass units you can convert from. The base unit names the dimension, not a display preference.
The second is the canonical base unit itself — the gram row, the milliliter row, the piece row — which is a real, shared measure with a factor of 1. An item with a gram base unit resolves, at read time, to the company's one shared gram. The item doesn't own a private base unit; it points at the company-shared canonical base for its dimension.
Why this separation matters. The item only ever needs to know its dimension. All the conversion machinery hangs off the shared canonical base for that dimension — which means every item in the Mass dimension reduces to the same gram, every Volume item to the same milliliter. There is one denominator per dimension per company, not one per item, so two flours, or flour and sugar, are directly comparable without any extra bridging.
4. Units, and the bundle you buy in¶
A unit is a measure — how much of something there is — and the same model holds a few roles a unit can play. They differ only in scope (who can use it) and in whether an operator may edit them:
- a standard unit — a generic, company-shared, immutable measure (gram, kilogram, liter);
- a custom unit — a company-shared measure the operator defines (a house scoop, a tray of 30);
- a per-item unit — a factor true only for one item. This covers two shapes: a density-like measure ("a cup of this flour = 120 g") and the bundle that item is bought in (a 25 kg sack, a case of 6 × 2 kg).
The key simplification: a bundle is not a separate kind of thing — it is just a per-item unit. It converts to base exactly like any other unit, one ratio and one multiply; the only extra it carries is what lets a buyer recognize the physical package — the manufacturer's barcode and an optional photo. Nothing about who sells it or at what price lives on the unit; that is a further layer again (the supplier article), and it lives in Procurement. This chapter teaches the bundle only as far as the measurement goes.
(a) Standard units — the immutable company-shared dictionary¶
These are the small, fixed vocabulary of generic measures every item can reach for. There are exactly ten, and they are the same in every company:
| Standard unit | Dimension | Factor to base | Canonical? |
|---|---|---|---|
| gram (g) | Mass | 1 | ✓ |
| kilogram (kg) | Mass | 1000 | |
| ounce (oz) | Mass | 28.3495 | |
| pound (lb) | Mass | 453.592 | |
| milliliter (ml) | Volume | 1 | ✓ |
| liter (L) | Volume | 1000 | |
| fluid ounce (fl oz) | Volume | 29.5735 | |
| quart (qt) | Volume | 946.353 | |
| gallon (gal) | Volume | 3785.41 | |
| piece (pcs) | Count | 1 | ✓ |
These belong to no single item — they are shared across the whole company — and they are immutable: an operator cannot edit a standard unit's factor. Every one of them is a universal physical constant, so the set is server-protected (see the immutability note below) and is seeded for every new company (§7).
A company can hide the standards it doesn't use. A Portuguese restaurant has no use for ounces and gallons; a US one rarely wants both metric and customary in every pick-list. Hiding a standard unit removes it from the unit selects for new entries — nothing more: anything that already references it keeps converting exactly as recorded, and the unit can be unhidden at any time. The three canonical bases (g, ml, pcs) can never be hidden — they are the anchors every conversion resolves against.
(b) Custom units — operator-owned measures in the shared dictionary¶
Not every measure a company wants has a universal definition. A bakery might keep a house "baker's dozen" (13 pcs); an egg supplier thinks in a tray of 30; an operation might standardize on a house scoop (60 g as this business packs it). These are company-shared like a standard unit — every item in the matching dimension can reach for them — but they are operator-owned, not server-protected. An operator adds a custom unit by giving it a dimension, a name, and one factor to base:
| Custom unit (examples) | Dimension | Factor to base |
|---|---|---|
| baker's dozen | Count | 13 |
| tray of 30 | Count | 30 |
| house scoop | Mass | 60 |
They are dimension-pure exactly like every other unit — one factor to base, no density, no cross-dimension conversion — so a custom Mass unit converts to grams with the same single multiply as a kilogram does. The one difference from a standard unit is editability: a custom unit can be renamed, have its factor adjusted, or be retired, right up until the first document references it. After that the same reproducibility rule that freezes a bundle unit's ratio (§4c, below) applies — a referenced unit must keep meaning what history recorded it to mean. (That lock-on-first-reference is the intended guardrail; it is not yet enforced in the system.)
Why lb/qt/gal are standard, not custom. The US-customary trio is defined by universal physical constants — a pound is 453.592 g everywhere, for everyone, forever. A custom unit's factor is an operator-asserted fact, editable until first use; putting a physical constant behind an editable factor invites a typo that silently corrupts every quantity entered through it. Constants belong in the immutable seeded set; custom units carry the vocabulary only the company itself can define.
Why standard units can't be edited. Every unit's ratio and every cost-per-unit in the company is ultimately expressed against grams, milliliters, or pieces. If someone could change what a gram is worth — say, edit its factor from 1 to something else — every historical and future quantity in that dimension would shift underneath the books at once. The immutability protects the denominator the entire stock ledger is built on.
Because they are the same ten in every company, they are laid down for a new company the moment it is created — see §7 — so the very first item an operator adds already has a full set of standard units to pick from.
(c) Per-item units — a factor, or a bundle, true for one item¶
Sometimes the factor an operator needs is true only for one item. The headline case is a density-like fact: "a cup of this flour = 120 g." A cup is a volume and flour is a mass item, so there is no generic conversion — but for this flour, as this operation scoops it, the operator can assert one. They add a per-item measure on the flour: a mass measure named cup with a factor of 120. It converts like any other measure (a single multiply to grams), it can be referenced by recipes and counts and chosen as the item's stock or pricing measure, and it never pretends to be a general rule — a cup on flour is 120 g, a cup on grated cheese might be 90 g, and neither says anything about a cup of milk. A density-like per-item measure is still a measure — nothing is bought "in cups"; it is the deliberate, operator-owned escape hatch §6 returns to.
The other per-item shape is the bundle the item arrives in — "I receive flour in a 2 kg bag," or "this comes as a case of 6 × 2 kg." A bundle is not a separate kind of thing: it is a per-item unit like any other, with one ratio to base, plus two extras that describe the physical package — the manufacturer's barcode (the global code printed on it) and an optional photo. It carries no price and no supplier; those live on a supplier article (below).
Bundle ratios flatten to one number. There is no nesting.
A "case of 6 × 2 kg" is not stored as a tree of "6 ×" wrapping "2 kg" wrapping
"1000 g." It is stored as one ratio: 6 × 2 × 1000 = 12000 grams. The operator (or
the form they use) does the multiplication once, and the model keeps the product.
There is nothing recursive to traverse, and the conversion stays the same single
multiply as for any unit.
Bundle units are operator-managed — they can be created and retired — but with one firm guardrail: a unit's ratio cannot be changed once a document references it. To "resize" a bundle you create a new unit and stop using the old. The reason is reproducibility: a goods receipt posted last month referenced a unit by its ratio, and re-deriving that posting must always give the same base amount. If the ratio could be edited in place, history would silently change meaning.
(d) The price layer — a supplier article prices an item in a unit¶
A unit is supplier-free on purpose: the same 25 kg sack is the same sack no matter who sells it, and two vendors can offer it without anyone duplicating the bundle. The commercial facts — who sells this item, in which unit, at what price, with what minimum order and lead time, under what code on their invoice — hang off a separate record, a supplier article: one per supplier that prices the item in that unit, taught in full in Procurement. The piece that touches measurement is the figure an article unlocks, price per base measure, which lets a buyer compare vendors honestly no matter which unit each one prices in:
price per base measure = the article's price ÷ the priced unit's ratio to base
Worked example — comparing two flour vendors. Vendor A sells flour at €18.00 per case of 6 × 2 kg (a unit that flattens to 12 000 g):
18.00 ÷ 12 000 = €0.0015 per gram. Vendor B sells it at €2.40 per 2 kg bag (2 000 g):2.40 ÷ 2 000 = €0.0012 per gram. Side by side, Vendor B is cheaper per gram — even though its sticker price looks smaller only because its unit is smaller. The supplier articles are what make the two prices comparable at all.
5. The moment of truth: convert once, at the posting edge¶
Everything above exists to serve one event. A posting document — a goods receipt (goods arriving), a stock count (a physical count of what is actually on hand), a transfer (stock moving between your own warehouses), a wastage write-off, or the consumption a sale triggers — records the operator's quantity in whatever unit they chose, together with which unit that was. Then, at the instant it writes a stock movement (one line in the books recording stock moving from one place to another), it converts: it checks the unit shares the item's dimension and multiplies by that unit's factor to base. The base amount is what lands in the books.
Which unit the operator keys is itself a per-item courtesy. An item may name a stock unit — the measure a human naturally counts, issues, and reads it in: kilograms for flour the kitchen weighs by the sack, pieces for buns. When set, it pre-fills the unit on a stock count, a write-off, or a production output, so the operator types "12", not "12 000"; left unset, entry falls back to the base unit. It is a preference, not an accounting fact — the base unit is the machine's denominator (§3) and freezes once history exists (§8), while the stock unit is the human's pen: it can change freely without rescaling a single stored number, precisely because whatever unit was keyed converts to base right here at the edge.
From that point on, on-hand, cost-per-unit, and variance never see the original unit again. They work only on base-unit numbers.
This is the whole reason the downstream math can stay simple. On-hand for an item at a warehouse is a plain sum of its movements (all in the same base unit). The warehouse cost-per-unit is one weighted average over base-unit quantities and values. Month-end variance subtracts one base number from another. None of them carry a units table, because the units layer already did the one conversion at the door. The units model's entire job is to guarantee that common denominator at the edge so nothing after it ever has to.
6. No cross-dimension (density) conversion — on purpose¶
The system will not convert grams to milliliters, or pieces to grams, or any pairing across the three dimensions. There is no density factor anywhere in the model, and a unit from the wrong dimension is refused outright.
This is a deliberate refusal, not a gap waiting to be filled:
- Density is item-specific and unstable. 100 ml of olive oil, of honey, and of water weigh three different amounts. The same flour packs to a different volume loose than compressed. A single stored "density" per item would be a guess that silently distorts every costed quantity that relied on it.
- The operator already knows the right unit. If flour is bought, counted, and used in recipes by weight, then every flour unit is a Mass unit and nothing ever needs a volume. The dimension is chosen once, when the item is created, and the whole item lives inside it.
- It keeps the engine a single multiply. Allowing density would force a per-item lookup and a branch on dimension at every posting — exactly the "translate at the moment of use" complexity the whole base-unit design exists to eliminate.
There is, however, a blessed escape hatch — and it is per-item, deliberate, and owned by the operator. US recipe authoring hits the wall on day one: American recipes say cups, and a cup is a volume, while flour is a Mass item. The answer is not a density engine; it is an ordinary per-item measure (§4c). Create a Mass measure on the flour item, name it cup, and give it a factor of 120 — because for this flour, as this operation scoops it, one cup weighs 120 g. It converts like any other measure — a single multiply to grams — and it never pretends to be a general volume-to-mass rule: the cup on flour is 120 g, a cup on grated cheese might be 90 g, and neither says anything about a cup of milk. The factor is a per-item fact the operator asserted, not a conversion the system guessed. The dimension wall stands; the measure is simply a named amount of this one item. Note this is a density measure, not a bundle — a cup of flour is something you portion, not a unit you buy in — which is exactly why it stays usable in recipes and counts.
If a business genuinely buys something one way and uses it another — buys oil by the liter but recipes it by the gram — the same answer applies: an item-scoped measure carrying a deliberate, per-item factor. What never exists is an implicit auto-conversion buried in the unit layer, guessing on the operator's behalf.
A related point: recipes and dish serving sizes are authored in a dish-facing vocabulary that includes friendly conveniences like oz, lb, fl oz, qt, kg, and L. Those reduce to the same canonical base — grams, milliliters, pieces — using the same factors. So when a sale explodes a recipe into the raw ingredients that left stock (the bill-of-materials explosion taught in the recipes chapter), every ingredient quantity lands in the identical base denominator the books already use. The recipe layer and the stock layer stay dimensionally consistent without sharing the same units — they share the same three bases.
7. Where the standard measures come from¶
A company doesn't share one global dictionary of units with every other company — each company has its own copy, because units are company-scoped. So there is no single set of standard measures to lay down once for everyone. Instead, the ten standard units are created per company, the moment that company is registered, with their dimensions, factors, and canonical flags set correctly, and they are marked as the immutable standard set.
Why this matters operationally. A brand-new company with no standard dictionary would show empty unit pick-lists and — worse — would have no canonical base for a new item's dimension to resolve against, so every conversion would fail. Laying down the ten units at registration is what makes the units model usable from the very first item created. The creation step is idempotent: running it again only fills in any unit that's missing, never duplicates one.
Owning a per-company copy is also what makes the dictionary tailorable: each company hides the standards it doesn't use (§4a) and adds custom units (§4b) for its own vocabulary — same company-shared scope, but operator-owned and editable until first referenced, rather than part of the server-protected seed.
8. An item's base unit freezes once it has history¶
An item's base unit can be chosen freely while the item is new — but once the item has any stock history, its base unit is locked for good. It cannot be re-anchored to a different dimension, and it cannot be swapped even within its dimension.
The reason is the same denominator argument, taken to its limit. The base unit is the denominator of every quantity the books store about the item and every cost-per-unit for it. Once a single movement has posted — say, "1500 g received at €0.0012 per gram" — re-reading the item as a Count item, or even just re-anchoring it within Mass, would make every historical quantity and every historical cost meaningless. There is no valid way to retroactively re-convert a denominator that history was already recorded against; the old numbers simply stop meaning what they meant. So the only safe rule is: choose the base unit once, and freeze it the instant the item starts accumulating a past.
This mirrors a discipline that runs throughout the stock domain — lock the accounting policy once transaction history exists — and it is the same reason a unit's ratio can't be edited once a document references it (§4). The difference is one of scope: a bundle unit's ratio governs one bundle size, while the base unit governs the item's entire denominator. Both freeze for the same reason; the base unit just protects far more.
9. End to end — "case of 6 × 2 kg" all the way to base¶
Flour, modeled as a Mass item, so its base unit is the gram. The operator buys it from one vendor as a case of 6 × 2 kg bags at €18.00 per case, and a recipe uses 300 g per batch.
The units in play:
| Unit | Kind | Scope | Dimension | Ratio to base |
|---|---|---|---|---|
| gram | measure | company-shared | Mass | 1 (canonical base, immutable) |
| kilogram | measure | company-shared | Mass | 1000 (standard measure, immutable) |
| "Case 6 × 2 kg" | bundle | this flour only | Mass | 12000 |
The case ratio is the flattened product: 6 × 2 kg × 1000 g/kg = 12000 g. Nothing
nested is stored — just the single number 12000. The case is a bundle unit; its
€18.00 price isn't on the unit itself but on the supplier article that records
how Baker's Supply sells it.
1. Comparable purchase price (before anything is posted).
price per base measure = 18.00 ÷ 12000 = €0.0015 per gram — the article's price over
the unit's ratio; the figure used to rank this vendor against any other flour vendor,
whatever unit they price in.
2. Receiving (a goods receipt posts a stock movement).
The operator receives 3 cases. Convert at the edge:
base amount = 3 × 12000 = 36000 g. The movement from supplier into the warehouse
carries 36000 grams. "3 cases" was the operator's input; the books only ever
see 36000.
3. On-hand. After this one receipt, on-hand for flour at this warehouse is the sum of its movements: 36000 g (which is 36 kg, which is 3 cases — but what's stored is grams).
4. Cost-per-unit (weighted-average).
The capitalized value 3 × 18.00 = €54.00 over 36000 g gives a weighted-average
cost of €0.0015 per gram.
5. Recipe consumption (a sale explodes the recipe, posting a consumption move).
The recipe asks for 300 g per batch. Selling one batch posts a consumption
movement of 300 g — already in base, because the recipe's portion unit reduces
straight to grams. Cost of that consumption: 300 × 0.0015 = €0.45. On-hand drops
to 36000 − 300 = 35700 g.
Every number that touched the books — 36000, 35700, 300 — is grams. The "case," the "6 × 2 kg," the "€18," and the "€0.0015/g" all lived only at the edge or in the vendor-comparison layer. That is the units model doing its single job: one honest denominator, fixed once at the door.
See also¶
- Item model & policies — where an item's base unit (its dimension anchor) is chosen, and the broader "lock the policy once history exists" discipline this chapter's base-unit freeze is one instance of.
- Recipes & production — how a recipe's dish-facing quantities reduce to the same three bases, and how a sale's bill-of-materials explosion lands in the identical base denominator.
- Costing & valuation — the weighted-average cost that consumes these base-unit quantities, and price-per-base-measure as the honest vendor comparison.
- Procurement — the supplier article in use: the pricing, minimum order quantities, and lead times it carries for an item in a chosen unit.
- Stock ledger — the movement journal every converted quantity lands in, always in base units.
- Glossary — concise definitions of unit (measure), base unit, the bundle you buy in, supplier article, and the per-company standard-measure set.