Item / Material Master and Units of Measure
The material master (item master, product master, part master) is the most-referenced object in an ERP. It’s also where developers most often underestimate complexity.
Why it’s not just a “products” table
A material is viewed differently by every department, and each view has its own fields, its own owner, and its own validity:
Material 10023 "Cotton Jersey 180gsm Navy"
│
├── Basic data description, base UoM, weight, dimensions, EAN, material group
├── Purchasing purchasing group, order unit, over/under delivery tolerance, incoterms
├── Sales (per sales org / channel) sales UoM, tax classification, item category group, min order qty
├── MRP (per plant) MRP type, lot size, safety stock, reorder point, planned delivery time
├── Work scheduling production unit, in-house production time, lot size for costing
├── Quality inspection types, certificate requirement
├── Accounting (per valuation area) valuation class, price control (S/V), standard price, moving avg price
├── Costing costing lot size, origin group, overhead group
└── Warehouse storage conditions, hazmat class, shelf life, picking strategy
One material, ~15 views, hundreds of fields, most of them per-org. This is the classic ERP master data shape.
Material types
The material type is the master switch that decides which views exist, how it’s valuated, and whether quantity/value are tracked.
| Type | Quantity tracked | Value tracked | Example |
|---|---|---|---|
| Raw material (ROH) | Yes | Yes | Fabric, steel, resin |
| Semi-finished (HALB) | Yes | Yes | Cut panels, sub-assembly |
| Finished good (FERT) | Yes | Yes | The thing you sell |
| Trading good (HAWA) | Yes | Yes | Bought and resold unchanged |
| Non-stock / consumable (NLAG) | No | No (expensed) | Office supplies, cleaning chemicals |
| Service (DIEN) | No | No | Installation, consulting hours |
| Packaging (VERP) | Yes | Optional | Cartons, pallets |
| Configurable (KMAT) | — | — | Made-to-order variant parent |
| Non-valuated (UNBW) | Yes | No | Customer-owned/consigned tooling |
Choosing the material type wrong at data-load time is a classic disaster — it’s usually not changeable afterwards once transactions exist.
Item identification
| Identifier | Meaning |
|---|---|
| Material number / SKU | Internal primary key. Can be internal-assigned (number range) or external (user-typed) |
| Old material number | Legacy code, kept for search after migration |
| Manufacturer part number (MPN) | The maker’s code |
| Vendor material number | What your supplier calls it, per vendor — needed on POs |
| Customer material number | What your customer calls it, per customer — needed on invoices/EDI |
| GTIN / EAN / UPC | Global trade item number, per packaging level |
| HS code / tariff code | For customs |
| Batch / Lot | Sub-identity of a quantity, see Serial, Lot and Traceability |
| Serial number | Identity of a single unit |
Design note: the mapping tables (vendor material number, customer material number) are essential in real ERPs and always forgotten in homemade ones. EDI is impossible without them.
Variants and configuration
Three different patterns, often confused:
- Distinct SKUs — every size/colour combination is its own material. Simple, explodes SKU count. Standard in apparel and retail.
- Generic + variants — a parent article with a variant matrix (size × colour). Retail ERPs support this natively.
- Configurable material — one material with characteristics chosen at order time (car with options). Requires a variant configurator: characteristics, classes, dependencies, and a BOM/routing selected by the configuration. This is deep, specialised functionality.
Units of Measure (UoM) — the real trap
Every material has:
- Base UoM — the unit stock is stored and valued in. Immutable after transactions exist.
- Order UoM — how you buy it (cartons)
- Sales UoM — how you sell it (pieces)
- Issue UoM — how production consumes it (metres)
- Weight/volume units — for shipping
And a conversion table:
1 PAL (pallet) = 40 CTN
1 CTN (carton) = 24 PC
1 PC = 0.35 KG
UoM rules that will bite you
- Store everything in base UoM internally. Convert at the boundary only.
- Conversions are material-specific, not global. 1 carton of shirts ≠ 1 carton of buttons.
- Rounding is a real accounting problem. If 1 CTN = 3 PC and you order 10 PC, the system must decide: 4 cartons (over-deliver), 3 cartons (under), or error. This is
rounding profile/order unit roundingconfig. - Never store a quantity without its UoM. A bare
quantitycolumn is a bug waiting to happen. - Catch weight — industries like meat, cheese, and metals sell in one unit (pieces) and price in another (kg), with the actual weight only known at picking. If your domain has catch weight and your model doesn’t, you will rebuild it.
- Decimal places — some UoMs allow fractions (KG), some don’t (PC). Enforce this.
Suggested column pattern
quantity NUMERIC(18,6) NOT NULL,
uom_code VARCHAR(6) NOT NULL,
base_quantity NUMERIC(18,6) NOT NULL, -- always populated, always base UoM
base_uom_code VARCHAR(6) NOT NULL
Carry both. Reports use base; documents show the transacted unit.
Valuation-relevant fields
Two fields on the accounting view drive an enormous amount of behaviour:
- Valuation class → determines which GL accounts inventory postings hit
- Price control:
- S = Standard price — inventory valued at a fixed planned price; differences go to variance accounts
- V = Moving average price — inventory value recalculated on each receipt
See Inventory Valuation. Switching price control on a material with stock is a controlled, painful operation.
Lifecycle and status
Materials have statuses that block them per function:
Blocked for procurement— can’t buyBlocked for sales— can’t sellBlocked for production— can’t makeDiscontinuedwith a follow-up material — planning switches to the successor when stock runs outMarked for deletion— flagged; archived later
You never delete a material. Blocking + deletion flag + archiving is the lifecycle.
Extension fields
You will be asked to add custom fields. Rules:
- Check if a standard field already means that. (There are usually 6 unused “material group 1–5” fields.)
- Use the sanctioned extension mechanism, not a bolt-on table with a join, unless it’s genuinely a new entity.
- If the field is per-plant or per-sales-org, it belongs on the view, not the header.
- Add it to the data-migration template, the API contract, and the search help — or it will be empty forever.
Data quality checks worth automating
- Material with no base UoM conversion for its order UoM
- Sales view without a tax classification
- Purchased material with no source of supply / info record
- Material with
price control = Sand standard price 0 - Duplicate materials by (manufacturer part number) or fuzzy description
- Material flagged for deletion with open orders or stock
- Weight/volume missing on anything that ships