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:

  1. Distinct SKUs — every size/colour combination is its own material. Simple, explodes SKU count. Standard in apparel and retail.
  2. Generic + variants — a parent article with a variant matrix (size × colour). Retail ERPs support this natively.
  3. 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

  1. Store everything in base UoM internally. Convert at the boundary only.
  2. Conversions are material-specific, not global. 1 carton of shirts ≠ 1 carton of buttons.
  3. 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 rounding config.
  4. Never store a quantity without its UoM. A bare quantity column is a bug waiting to happen.
  5. 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.
  6. 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 buy
  • Blocked for sales — can’t sell
  • Blocked for production — can’t make
  • Discontinued with a follow-up material — planning switches to the successor when stock runs out
  • Marked 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:

  1. Check if a standard field already means that. (There are usually 6 unused “material group 1–5” fields.)
  2. Use the sanctioned extension mechanism, not a bolt-on table with a join, unless it’s genuinely a new entity.
  3. If the field is per-plant or per-sales-org, it belongs on the view, not the header.
  4. 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 = S and 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

Next