Units of Measure (UOM)
The uom submodule of sys is a pure-Java library for parsing, comparing, and converting quantities expressed in SI and imperial units of measure. It supports compound expressions such as kg/m3 and prefixed units such as mm or kPa, and provides domain-specific helpers for the dimensions/mass calculations used by the inventory and trade modules. It owns no database tables, has no Spring services, and depends only on the framework’s HasTrace and BusinessException types.
Concepts
Unit symbolThe textual code that names a unit (e.g.
kg,m,lb,°C). Each unit has one or more accepted aliases — for example liter accepts bothLandl.SI base unitOne of nine "anchors" that every other unit reduces to: pieces, percentage, ampere, candela, kelvin, gram, meter, mole, second. Two units can be converted into one another only when they share a base unit signature.
Unit prefixAn SI multiplier prefix attached to a unit symbol (
p,n,μ/u,m,c,d,da,h,k,M,G,T). Prefixes are recognised on parse and folded into the conversion factor.Single unitA parsed unit symbol that may carry a prefix and an integer exponent (e.g.
m3,kg,m^-1).Compound unitTwo single units multiplied or divided to form a quantity, parsed from a string such as
kg/m3org m^-3. Compound units always have exactly two components in this submodule.QuantityA
(value, unit-code)pair. The pieces variant additionally tracks how many discrete pieces make up the value.Operation typeAdd, subtract, multiply, or divide — used by the calculation utilities when combining two quantities.
Entities
The uom submodule does not persist anything. Its "entities" are immutable in-memory value types and enums used by the rest of the ERP. The diagram below shows how they fit together.
Quantity (SiQuantity)
Immutable record holding a value paired with a unit-of-measure code. Carries assertion helpers (assertHasUomType, assertHasUomTypeAndExponent) so callers can verify that a quantity is in the expected dimension before using it.
| Field | Description |
|---|---|
| Numeric magnitude. |
| Unit code, e.g. |
Pieces Quantity (SiQuantityPcs)
Quantity that additionally tracks a piece count. Used when an item is sold by weight or volume but also exists as discrete units (for example "5 kg comprising 20 pieces"). toSiQuantity() strips the piece count when only the dimensional part is needed.
| Field | Description |
|---|---|
| Numeric magnitude. |
| Unit code. |
| Discrete piece count. |
Compound Unit (SiUomCompound)
A parsed two-component compound unit such as kg/m3 or g m^-3. Instances are cached by uomCode for the lifetime of the JVM since parsing is pure.
| Field | Description |
|---|---|
| The original compound unit string. |
| Two |
Compound Value (SiUomCompoundValue)
A compound unit paired with a numeric value, used as the result of compound conversions.
| Field | Description |
|---|---|
| The compound unit. |
| Numeric magnitude expressed in that compound unit. |
Single Unit (SiUomSingle)
A single parsed unit, optionally prefixed and exponentiated. Cached by uomCode.
| Field | Description |
|---|---|
| The original unit string (e.g. |
| The matching |
| Integer exponent applied to the unit. |
| Optional SI prefix folded into the conversion factor. |
Single Value (SiUomSingleValue)
A single unit paired with a numeric value, used as the result of single-unit conversions.
| Field | Description |
|---|---|
| The single unit. |
| Numeric magnitude expressed in that unit. |
Unit (SiUom)
Enum listing every unit the submodule recognises (PCS, AMPERE, CANDELA, KELVIN, CENTIGRADE, GRAM, TONNE, METER, LITER, MOLE, SECOND, plus imperial: FAHRENHEIT, OUNCE, POUND, STONE, TON, INCH, FOOT, YARD, FURLONG, MILE, FLUID_OUNCE, GALLON). Each value carries its conversion factor to its base unit, its base-unit signature, and the symbols accepted on parse.
Unit Signature (SiUomSignature)
The base-unit fingerprint of a SiUom. Two units are convertible only when their signatures match. A signature is a list of (SiUomBase, exponent) items — typically one item, with two used for compound-derived units.
Base Unit (SiUomBase)
Enum of the nine base units the system reduces everything to. Each base value carries a symbol and the dimensional SiUomType it represents.
| Code | Symbol | Type |
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Dimension (SiUomType)
Enum naming the physical dimension a base unit measures.
| Value | Meaning |
|---|---|
| Discrete count. |
| Dimensionless percentage. |
| Duration. |
| Length, area (exp 2), volume (exp 3). |
| Mass. |
| Electric current. |
| Temperature. |
| Substance amount in moles. |
| Luminous intensity. |
Prefix (SiUomPrefix)
Enum listing the SI prefixes recognised on parse, with their decimal multipliers and symbols.
| Value | Symbol | Multiplier |
|---|---|---|
|
| 1e-12 |
|
| 1e-9 |
|
| 1e-6 |
|
| 1e-6 |
|
| 1e-3 |
|
| 1e-2 |
|
| 1e-1 |
|
| 1e1 |
|
| 1e2 |
|
| 1e3 |
|
| 1e6 |
|
| 1e9 |
|
| 1e12 |
Unit System (UomSystem)
METRIC or IMPERIAL — used by callers that want to pick a unit set for a country or product class.
Operation Type (SiUomOperationType)
ADD, SUBTRACT, MULTIPLY, DIVIDE — selects the arithmetic combination performed by SiUomCalculationUtil.calculateQuantities.
Functionality
Single-unit conversion
SiUomSingleUomUtil converts a SiQuantity (or a raw value/uomCode pair) between two single-unit codes. The conversion goes through the base unit: the source value is reduced to its base via the unit’s factorToBaseUnit and prefix multiplier, then expanded into the target. convertToSiUomIfConvertable returns null instead of raising when the dimensions do not match — useful when callers want to fall through to an alternative.
Compound-unit conversion
SiUomCompoundUtil.convertToSiUomBase parses a compound unit code such as kg/m3 into two SiUomSingle components, requires that the first component has a non-negative exponent and the second a non-positive exponent, and reduces the value to the equivalent base-unit compound (e.g. g/m3). Compound units with shapes other than two components raise a business exception.
Quantity arithmetic
SiUomCalculationUtil.calculateQuantities adds, subtracts, multiplies, or divides two SiQuantity values whose base units agree, returning the result expressed in a caller-supplied target unit. Both quantities are first reduced to their base unit so that, for example, 1 kg + 500 g returns the expected mass. Division by zero raises a business exception.
Domain calculations
The same utility class hosts higher-level helpers used by the trade and inventory flows:
calculateLengthByDimensions(weight, width, thickness, specificWeight)Solves
length [m] = weight / (width × thickness × specificWeight). Asserts that the inputs have the right dimensions before computing.calculateMassByDimensions(length, width, thickness, specificWeight)Solves
mass [g] = length × width × thickness × specificWeight.calculateMassBySquareLength(squareLength, thickness, specificWeight)Solves
mass [g] = squareLength × thickness × specificWeightfor callers that already have an area.calculateSpecificWeight(weight, width, length, thickness, outputUom)Computes specific weight in
g/m3from a mass and a rectangular volume. Currently the onlyoutputUomaccepted isg/m3; other targets raise an internal exception (tracked under REAL-771).
Dimension assertions
SiUomUtil.assertHasUomTypeAndExponent and the matching helpers on SiQuantity raise a business exception when a quantity’s dimension or exponent does not match the expected one. They are used pervasively at the entry of every calculation helper so failures point at the offending input.
Unit parsing
SiUomPreprocessor rewrites convenience forms before parsing: it splits a numerator/denominator compound, expands trailing-digit forms (m2 → m^2, m3 → m^3), and applies a negative exponent sign to the denominator. The parsed forms feed both SiUomSingle.of and SiUomCompound.of, both of which cache their results.
Public API
SYS_UOM_QueryApi and SYS_UOM_CommandApi
The submodule does not provide a query or command API class. Other modules call the static utility classes directly:
| Class | Purpose |
|---|---|
| Convert a |
| Reduce a compound-unit quantity (e.g. |
| Add/subtract/multiply/divide quantities, plus dimension/mass/specific-weight calculations for trade and inventory flows. |
| Immutable value types used as input and output of every utility above. |
| Enum supplied to |
ViewModel actions
The submodule does not expose any UI; it is consumed exclusively from server-side code. There are no view models or actions to document.
Bootstrap
There is no bootstrap class — the recognised units, prefixes, and base units are declared as Java enums and are available from JVM start without any database state.