Overview
Unit of Measure (UOM) conversions enable flexible inventory transactions. You can receive stock in one unit (e.g., boxes), store it in another (e.g., individual units), and sell it in yet another (e.g., grams).Example: Receive salmon in 5kg boxes, store as kg, transfer in grams, and track costing in kg.
UOM Structure
UnitOfMeasure (Base Units)
Base units are the foundation of the conversion system.Unique UOM code (max 20 chars, typically uppercase)Examples:
KG, G, L, ML, UNIT, BOX, PACKFull UOM name (max 100 chars)Examples:
Kilogram, Gram, Liter, Milliliter, Unit, Box, PackDisplay symbol (max 10 chars)Examples:
kg, g, L, mL, u, bx, pkDecimal places for display (0-6)Examples: 0 for whole units, 2 for currency, 4 for scientific
Whether fractional quantities are allowed
true: Can use 1.5 kg, 0.25 Lfalse: Only whole numbers (e.g., 1 unit, 5 boxes)
Active status (inactive UOMs hidden from selection)
UomConversion (Conversion Rules)
Defines directed conversion factors between two UOMs.Source UOM ID
Target UOM ID
Multiplication factor:
target_qty = source_qty × factorExamples:- KG → G: factor = 1000 (1 kg = 1000 g)
- BOX → UNIT: factor = 24 (1 box = 24 units)
- G → KG: factor = 0.001 (1 g = 0.001 kg)
Acceptable variance percentage for physical countsExample: tolerance = 2.0 means ±2% variance is acceptable
Active status (inactive conversions not used)
Common UOM Systems
Weight System
- KG → G: factor = 1000
- G → KG: factor = 0.001
- KG → LB: factor = 2.20462
- LB → KG: factor = 0.453592
- LB → OZ: factor = 16
- OZ → LB: factor = 0.0625
Volume System
- L → ML: factor = 1000
- ML → L: factor = 0.001
- GAL → L: factor = 3.78541
- L → GAL: factor = 0.264172
Count System
- BOX → UNIT: varies (e.g., 24 units per box)
- PACK → UNIT: varies (e.g., 6 units per pack)
- CASE → BOX: varies (e.g., 4 boxes per case)
API Endpoints
Create UOM
Create Conversion
List UOMs
Filter active/inactive UOMs
Filter decimal vs integer UOMs
Search by code or name
List Conversions
Filter by source UOM
Filter by target UOM
Filter active/inactive conversions
Get Conversion Factor
Real-World Examples
Example 1: Rice (Weight-Based)
Item: Arroz Sushi Premium (INSUMO)Base UOM: KG (kilogram) UOM Setup:
- Receive: 50 kg (opening balance)
- Transfer to kitchen: 2000 g (2 kg)
- System stores: 48 kg remaining at warehouse, 2 kg at kitchen
Example 2: Soy Sauce (Volume-Based)
Item: Salsa de Soja Kikkoman (INSUMO)Base UOM: L (liter) UOM Setup:
- Receive: 12 bottles
- System stores: 12 L
- Transfer to bar: 500 mL (0.5 L)
- Remaining: 11.5 L
Example 3: Nori Sheets (Count-Based)
Item: Nori Alga Sheets (INSUMO)Base UOM: SHEET (individual sheet) UOM Setup:
- 1 PACK = 50 SHEET
- 1 BOX = 10 PACK = 500 SHEET
- Receive: 2 boxes
- System stores: 1000 sheets (2 × 500)
- Transfer to kitchen: 5 packs (250 sheets)
- Remaining: 750 sheets
Example 4: Salmon (Weight with Multiple Presentations)
Item: Salmon Atlantic (INSUMO)Base UOM: KG (kilogram) Variants:
SAL-KG- Salmon 1kg (base)SAL-SAKU- Salmon Saku Block 250gSAL-PORTION- Salmon Portion 200g
- Receive: 20 kg bulk salmon
- Cut into: 80 saku blocks (20 kg = 20,000 g = 80 × 250g)
- Transfer to kitchen: 40 saku blocks (10 kg)
- Use for service: 25 portions from 40 saku blocks
Conversion Calculation
Forward Conversion
Convert from source UOM to target UOM:- factor = 1000
- result = 5 × 1000 = 5000 g
Reverse Conversion
Convert back (inverse):- factor = 1000 (kg → g)
- result = 5000 ÷ 1000 = 5 kg
Always create bidirectional conversions for seamless transactions in both directions.
Chained Conversions
For multi-step conversions (e.g., BOX → PACK → UNIT):- BOX → PACK: factor = 10 (1 box = 10 packs)
- PACK → UNIT: factor = 50 (1 pack = 50 units)
- Result: 2 × 10 × 50 = 1000 units
Tolerance in Physical Counts
Thetolerance field defines acceptable variance in physical counts:
| Expected | Actual | Variance | Acceptable? |
|---|---|---|---|
| 100 kg | 102 kg | 2.0% | ✓ Yes |
| 100 kg | 103 kg | 3.0% | ✗ No |
| 50 L | 49.5 L | 1.0% | ✓ Yes |
| 50 L | 48 L | 4.0% | ✗ No |
Tolerance is used during physical inventory counts to flag significant discrepancies that require investigation.
Validation Rules
UOM Creation
- Required Fields
- Optional Fields
- Constraints
code(unique, max 20, uppercase recommended)name(max 100)
Conversion Creation
- Required Fields
- Optional Fields
- Constraints
from_uom_id(must exist)to_uom_id(must exist)factor(> 0)
Business Rules
Bidirectional Setup
Always create both directions (A→B and B→A) for flexibility
Base UOM Per Variant
Each variant has one base UOM; all conversions normalize to it
Active Conversions Only
Inactive conversions are ignored by the system
Item-Specific Packaging
Count conversions (BOX→UNIT) vary per item
Item Type UOM Rules
| Item Type | UOM Conversions | Reasoning |
|---|---|---|
| INSUMO | Multiple allowed | Flexible receiving, storing, and consumption |
| PRODUCTO | Base only (discouraged) | Finished goods typically have fixed packaging |
| ACTIVO | Base only (1:1) | Assets counted as discrete units |
Common Workflows
Workflow 1: Set Up Weight System
Workflow 2: Set Up Item-Specific Packaging
Workflow 3: Handle Multi-UOM Receipt
Database Schema
units_of_measure Table
| Column | Type | Constraints |
|---|---|---|
| id | bigint | PK, auto-increment |
| code | varchar(20) | UNIQUE, NOT NULL |
| name | varchar(100) | NOT NULL |
| symbol | varchar(10) | NULLABLE |
| precision | smallint | DEFAULT 2, CHECK (0-6) |
| is_decimal | boolean | DEFAULT true |
| is_active | boolean | DEFAULT true |
| meta | jsonb | DEFAULT '' |
| created_at | timestamp | |
| updated_at | timestamp |
idx_uom_codeon (code) UNIQUEidx_uom_activeon (is_active)
uom_conversions Table
| Column | Type | Constraints |
|---|---|---|
| id | bigint | PK, auto-increment |
| from_uom_id | bigint | FK → units_of_measure.id, NOT NULL |
| to_uom_id | bigint | FK → units_of_measure.id, NOT NULL |
| factor | decimal(12,6) | NOT NULL, CHECK (> 0) |
| tolerance | decimal(10,4) | DEFAULT 0, CHECK (>= 0) |
| is_active | boolean | DEFAULT true |
| meta | jsonb | DEFAULT '' |
| created_at | timestamp | |
| updated_at | timestamp |
idx_uom_conversion_fromon (from_uom_id)idx_uom_conversion_toon (to_uom_id)idx_uom_conversion_lookupon (from_uom_id, to_uom_id, is_active)
- Unique: (from_uom_id, to_uom_id)
- Check:
from_uom_id != to_uom_id
Best Practices
Name UOMs Clearly
Name UOMs Clearly
Use descriptive names: “Kilogram” not “KG Unit”
Use Standard Symbols
Use Standard Symbols
Follow ISO/industry standards: kg, g, L, mL, lb, oz
Set Appropriate Precision
Set Appropriate Precision
Weight: 4 decimals (0.0001), Count: 0 decimals, Currency: 2 decimals
Create Bidirectional Conversions
Create Bidirectional Conversions
Always add both A→B and B→A for seamless transactions
Use Tolerances for Perishables
Use Tolerances for Perishables
Set 2-5% tolerance for items prone to evaporation/shrinkage
Document Item-Specific Packaging
Document Item-Specific Packaging
Store packaging details in item.meta or variant.meta for reference
Next Steps
Items & Variants
Assign base UOMs to item variants
Stock Movements
Use conversions in multi-UOM transactions
Inventory Locations
Set up locations to hold converted stock