A wholesaler keeps items in pieces inside the ERP, sells them in cases of twelve, ships them on pallets of four layers and bills cable by the metre. What arrives in the shopping cart is a single number, and if nobody has defined which unit that number carries, the buyer orders ten cases and receives ten pieces. Units of measure are therefore not a side note of master data maintenance but the point where orders, stock levels and invoices drift apart. The international code list for units is maintained continuously and holds roughly 1,800 codes, most of them three characters long (UNECE). This article shows how to separate base, stock, selling and purchase units, why conversion factors belong in the ERP integration rather than in the shop interface, and how a middleware layer carries stock, minimum quantities and unit prices across the system boundary without losing decimals on the way.
Key takeaways
- An item needs four separate unit roles: a base unit for posting, a stock unit for picking, a selling unit for the shop and a purchase unit for the supplier. The catalogue standard common in German B2B separates these levels as ORDER_UNIT, CONTENT_UNIT and NO_CU_PER_OU (BMEcat).
- Conversion factors belong in the leading system. If the same factor is also maintained in the shop, two versions of the truth exist, and the discrepancy typically only surfaces on the invoice.
- For exchange between systems there are three-character unit codes from Recommendation 20 (UNECE). The European standard for electronic invoicing requires exactly this code list for the unit of measure of an invoice line (EN 16931).
- Stock is rounded down into selling units rather than rounded to the nearest value: 1,542 pieces at a factor of 12 become 128 cases, and the remaining 6 pieces stay blocked until they add up to a full pack.
- Quantities and amounts with decimals belong in a decimal type. Binary floating point cannot represent 0.1 exactly (IEEE 754), and the rounding error accumulates across thousands of lines into visible differences.
Why a Base Unit Alone Is Not Enough
Every ERP keeps an item in a base unit. It is the smallest unit that gets posted, and it is deliberately chosen to be neutral: screws in pieces, cable in metres, cleaning agents in litres, bulk goods in kilograms. As long as only the warehouse works with these values, that is coherent. The moment the item appears in the shop, however, several quantity worlds collide. The buyer thinks in cases, the picker in storage locations, the carrier in pallets and loading metres, accounting in invoice lines with a price base quantity. If stock is simply transferred as a base quantity, the shop shows the figure 1,542 without a recognisable unit, and the customer puts ten of them in the cart. Whether that becomes ten pieces, ten cases or 120 pieces is then decided by an assumption nobody wrote down. Exactly that unspoken assumption turns into a complaint later on.
The damage is rarely spectacular but it is persistent. A delivery that is too small triggers a follow-up order, one that is too large triggers a return, and both create documents, queries and correction postings. In consumer commerce roughly 70 percent of started carts are abandoned on average (Baymard Institute); in B2B the typical reaction to an unclear quantity is less often a silent exit than a call to the sales desk, and that call costs processing time at precisely the place the integration was supposed to relieve. The real effort does not arise in the shop but in the interface: if the unit logic is not modelled there, a person has to reconstruct it for every order. Anyone handing items from the ERP to a shop therefore transfers more than a number, namely a pair of quantity and unit, plus the rule for converting that pair into any other unit.
The Four Unit Roles in the Item Master
Things only become clean once four roles are kept separate, even when three of them carry the same value for simple items. The base unit is the posting unit in the ERP and the reference point of every conversion. The stock unit describes the form in which goods sit on the shelf and are picked, for instance as a case rather than a single piece. The selling unit is what the customer sees in the shop and orders in. The purchase unit, finally, is the unit used when reordering from the supplier, often a pallet or a pack. The catalogue standard common in German B2B models this separation explicitly: ORDER_UNIT for the purchase unit, CONTENT_UNIT for the contained unit and NO_CU_PER_OU for the number of content units per order unit (BMEcat). Filling these fields from the start during data mapping between ERP and shop covers the larger part of the work.
Base unit
The smallest postable unit in the ERP. Stock, reservations and stocktaking refer solely to it, and every other quantity is derived from it.
Stock unit
The form in which goods physically sit. It governs picking and broken-pack rules, for example whether a case may be opened at all.
Selling unit
The unit visible in the shop and used for ordering. It may differ per customer group, such as pieces for trade customers and cases for wholesale.
Purchase unit
The unit towards the supplier. The catalogue standard carries it as ORDER_UNIT, complemented by the contained unit CONTENT_UNIT (BMEcat).
Conversion factor
The field NO_CU_PER_OU states how many content units sit inside one order unit (BMEcat). It is the single place where the factor should be maintained.
Unit code
Three-character codes such as KGM for kilogram or MTR for metre make the unit machine-readable and come from Recommendation 20 (UNECE).
Keep Conversion Factors in the ERP, Not in the Shop
The most common shortcut in a project reads: the factor goes into the shop because extending the ERP takes longer and requires more coordination. From that moment on two versions of the truth exist. When the supplier changes the case size from twelve to ten, the factor is updated in the item master but overlooked in the shop. The customer keeps ordering in twelves, the warehouse ships tens, and the difference only shows up on the invoice or during stocktaking. The factor therefore belongs where the item is maintained and travels from there into the shop, not the other way round. The conversion itself happens in the middleware layer: it reads quantity, unit and factor from the ERP, converts in both directions and hands the shop finished values. The shop displays and accepts; it does not calculate.
One factor, one source
read line: qty_sales, unit_sales
fetch factor from the item master (base per selling unit)
qty_base = qty_sales * factor # decimal type, no floating point
if qty_sales < minimum_quantity:
reject and report the minimum back
if qty_sales modulo pack_multiple != 0:
round up to the next multiple and show the notice
reserve qty_base in the ERP
return: qty_sales, unit_sales, qty_base, factorConvert and Round Stock into Selling Units
Stock arrives from the ERP in base units and is displayed in selling units. It is rounded down rather than to the nearest value, because half a case is not a sellable quantity. At a factor of 12, 1,542 pieces become exactly 128 cases; the remaining 6 pieces stay blocked until incoming goods complete a full pack. That remainder should not disappear in the shop but be kept internally as a broken-pack quantity so that stocktaking adds up later. With several warehouses, convert per site first and sum afterwards: two warehouses holding 7 pieces each add up to 14 pieces but still to zero cases, as long as neither site holds a full pack and cross-site picking is not intended. The order of summing and rounding is thus a business decision, one that also shapes inventory synchronisation across multiple warehouses.
- Define the rounding direction: stock is rounded down, order quantities are rounded up to the next pack. Both rules belong in the documentation, because they contradict each other in business terms and both are correct.
- Keep broken-pack quantities visible: the remainder below a full pack stays posted in the ERP and is hidden in the shop rather than lost during synchronisation.
- Convert per warehouse, then sum: conversion per site first, aggregation second. The reverse order produces stock figures that cannot be picked, as regularly shows up in wholesale ERP integration projects.
- Keep safety stock in base units: a buffer of 24 pieces is unambiguous, whereas a buffer of two cases changes its meaning as soon as the factor changes.
- Limit decimal places: for weight and length items the interface defines how many places are used for calculation and how many for display, so that the ERP integration and the shop report the same value.
Minimum Quantities and Pack Multiples in the Cart
In B2B, a freely chosen quantity is the exception. Items carry a minimum order quantity, a step size in multiples of the pack and frequently a different unit per customer group. The catalogue standard provides dedicated fields for this: QUANTITY_MIN for the minimum quantity and QUANTITY_INTERVAL for the permitted step size (BMEcat). Both values belong in the interface, not in a note inside the product description. In the cart the rule should not surface as an error message after submission but as a correction during entry: enter 17 pieces and you see 24 pieces plus a note that the item ships in packs of twelve. Enforcing this in the cart is a recurring element of wholesale system integration because it noticeably reduces queries at the sales desk.
It gets harder when several rules meet. A customer with a framework agreement may call off single pieces, a new customer may not. An item is available by the pallet during a promotion and by the case outside it. Such cases cannot be maintained in the shop backend without reintroducing the second version of the truth; they belong to the customer or customer group as terms data and are transferred together with the item. Anyone running several legal entities or company codes additionally makes sure that units and factors may differ per entity without the assignment slipping in the shop. How that can be organised is described in detail in the article on connecting several ERP entities to a single shop.
| Criterion | Without unit logic | With unit logic |
|---|---|---|
| Quantity field in the shop | A number without a unit | A number with unit and factor |
| Stock display | Base quantity, hard to read | Selling unit, rounded down |
| Minimum quantity | A note in the description text | A rule enforced in the cart |
| Pack multiples | Corrected afterwards by the sales desk | Rounding up visible during entry |
| Invoice line | Unit differs from the order | Unit and price base match |
| Return | Quantity has to be converted by hand | Return posted in the same unit |
Variable Weights and Lengths Without Rounding Losses
With cheese, meat, cable, pipes or fabrics the ordered quantity is not the delivered quantity. The customer orders three wheels of cheese, three pieces weighing 2.340 kg, 2.415 kg and 2.180 kg are shipped, and the actual weight is invoiced. Such items need two quantities per line: the piece count for picking and shipping, and the weight for pricing and invoicing. If only one of the two is transferred, the result is either an invoice based on a theoretical weight or a delivery note without a link to the order line. For trade in prepackaged goods of unequal nominal quantity, German packaging regulation requires the actual fill quantity to be stated (FertigPackV), and the scales used for it are subject to metrology law in commercial trade (MessEG). Reporting the actual weight back is therefore part of the document chain, not an optional extra.
Technically, the data type decides the outcome. Quantities with three decimal places and prices with four or six belong in a decimal type; binary floating point cannot represent even 0.1 exactly (IEEE 754), and the default rounding of that representation rounds to the nearest even value rather than half up. Across a few hundred lines this stays unnoticed; across an annual turnover it accumulates into differences that are tedious to trace during reconciliation. The order of operations matters just as much: multiply first, round afterwards. Rounding unit prices before multiplying them by the quantity produces a different invoice amount for 1,000 metres of cable than the ERP does. How an integration behaves when the leading system stops responding for a while is covered in the article on keeping the shop selling during an ERP outage.
Price Base Quantity and the Unit Price
A price without a base quantity is incomplete. Cable is costed per metre, screws per 100 pieces, cleaning agents per litre, and the ERP holds a dedicated price base quantity for exactly that. The catalogue standard carries it as PRICE_QUANTITY (BMEcat) and thereby separates it cleanly from the order unit. If this field is ignored during import, the classic factor-of-100 error appears: the price for 100 pieces lands in the shop as a unit price. Such errors rarely stand out immediately because they look plausible, and they rarely affect all items, only the product group with a deviating base quantity. How price data and terms are transferred cleanly overall is described in the article on synchronising customer-specific prices.
The unit price as a legal requirement is a separate matter. German price indication rules require sellers to state the price per unit quantity alongside the total price when addressing consumers (PAngV); the unit quantity is 1 kilogram, 1 litre, 1 cubic metre, 1 metre or 1 square metre respectively (PAngV). For goods sold loose, 100 grams or 100 millilitres are also permitted depending on established trade practice (PAngV). The basis for these requirements is the European directive on consumer protection in the indication of prices (Directive 98/6/EC). A pure B2B shop with verified business customer approval is out of scope; as soon as the same shop also serves consumers it is in scope, and the calculation then has to run automatically from net weight and price base quantity rather than sitting in a text field.
A unit is a data field, not a label
Normalising Unit Codes Across System Boundaries
Every system spells units differently. The ERP says ST, the shop says pcs., the supplier catalogue says piece, the EDI message says H87 and an old price list simply says Stk. As long as only humans read it, that works; as soon as two systems reconcile, duplicate items and failed postings appear. The remedy is normalisation onto one code list, and an established one exists: the three-character codes of Recommendation 20 with KGM for kilogram, MTR for metre, LTR for litre and H87 for piece (UNECE). The European standard for electronic invoicing requires exactly this code list for the unit of measure of an invoice line (EN 16931), so normalising pays off anyway once the electronic invoicing mandate comes into play.
In practice the middleware keeps a translation table with three columns: source system, raw value, normalised code. Every unknown raw value lands in a log instead of a silent substitution, because a wrongly guessed unit costs more than a rejected line. In addition, each packaging level deserves its own item number: the allocation rules for article numbers state that every distinguishable trade item receives its own key (GS1), so single piece, case and pallet each get one. Merging those levels loses precisely the information the conversion needs. Such a translation table is a typical building block of interface development and should be versioned like program code.
Returns and Partial Deliveries in Mixed Units
Orders come in cases, deliveries sometimes go out in pieces. If a pack is already broken or the remainder comes from a second warehouse, a partial delivery in a deviating unit appears, and the feedback to the shop has to carry both quantities: the open remainder in the purchase unit and the delivered quantity in the unit actually shipped. The same applies to returns. A customer who ordered 5 cases and sends back 12 single pieces creates a credit note for one case plus a broken pack, and only if the conversion applies at that point as well. The article on the returns process between shop and ERP describes the document chain for this; in drop shipping with supplier integration the supplier maintains its own pack sizes on top, so the conversion happens twice, once towards the supplier and once towards the customer.
Test Cases for Typical Mis-Orders
- An order below the minimum quantity is rejected and names the permitted quantity instead of failing without comment.
- Entering a quantity that breaks the step size rounds it up to the next multiple and the customer sees the correction before submitting.
- Stock of 1,542 base units at a factor of 12 shows 128 selling units, not 128.5 and not 129.
- An item with a price base quantity of 100 produces the same line amount in the shop as in the ERP, verified with a quantity carrying decimals.
- A weight item reports its actual weight back after shipping and the invoice may deviate from the order without the line losing its assignment.
- A change to the conversion factor in the ERP reaches the shop in the next synchronisation run and does not apply retroactively to orders already captured.
- A partial delivery in a deviating unit leaves the remaining quantity expressed in the original purchase unit.
- An unknown unit code from a supplier catalogue is logged and blocks the import of the affected line instead of silently defaulting to pieces.
- Switching the selling unit per customer group shows the same item in pieces or cases without changing the stock figure in the ERP.
A quantity without a unit is not a statement but a guess. Only the factor beside it turns two numbers into an order that survives every system it passes through.
Sources and Studies