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 symbol

The textual code that names a unit (e.g. kg, m, lb, °C). Each unit has one or more accepted aliases — for example liter accepts both L and l.

SI base unit

One 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 prefix

An 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 unit

A parsed unit symbol that may carry a prefix and an integer exponent (e.g. m3, kg, m^-1).

Compound unit

Two single units multiplied or divided to form a quantity, parsed from a string such as kg/m3 or g m^-3. Compound units always have exactly two components in this submodule.

Quantity

A (value, unit-code) pair. The pieces variant additionally tracks how many discrete pieces make up the value.

Operation type

Add, 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.

UOM value types

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.

FieldDescription

value

Numeric magnitude.

uomCode

Unit code, e.g. kg, m, kg/m3.

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.

FieldDescription

value

Numeric magnitude.

uomCode

Unit code.

pieces

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.

FieldDescription

uomCode

The original compound unit string.

siUomSingles

Two SiUomSingle components in the order they appeared.

Compound Value (SiUomCompoundValue)

A compound unit paired with a numeric value, used as the result of compound conversions.

FieldDescription

siUomCompound

The compound unit.

uomValue

Numeric magnitude expressed in that compound unit.

Single Unit (SiUomSingle)

A single parsed unit, optionally prefixed and exponentiated. Cached by uomCode.

FieldDescription

uomCode

The original unit string (e.g. mm, kg, m^3).

siUom

The matching SiUom enum value (e.g. METER, GRAM).

exponent

Integer exponent applied to the unit.

siUomPrefix

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.

FieldDescription

siUomSingle

The single unit.

uomValue

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.

CodeSymbolType

PIECES

pcs

PIECES

PERCENTAGE

%

PERCENTAGE

AMPERE

A

ELECTRIC_CURRENT

CANDELA

cd

LUMINOUS_INTENSITY

KELVIN

K

THERMODYNAMIC_TEMPERATURE

GRAM

g

MASS (note: g is preferred over kg so the kilo prefix can apply)

METER

m

LENGTH

MOLE

mol

AMOUNT_OF_SUBSTANCE

SECOND

s

TIME

Dimension (SiUomType)

Enum naming the physical dimension a base unit measures.

ValueMeaning

PIECES

Discrete count.

PERCENTAGE

Dimensionless percentage.

TIME

Duration.

LENGTH

Length, area (exp 2), volume (exp 3).

MASS

Mass.

ELECTRIC_CURRENT

Electric current.

THERMODYNAMIC_TEMPERATURE

Temperature.

AMOUNT_OF_SUBSTANCE

Substance amount in moles.

LUMINOUS_INTENSITY

Luminous intensity.

Prefix (SiUomPrefix)

Enum listing the SI prefixes recognised on parse, with their decimal multipliers and symbols.

ValueSymbolMultiplier

PICO

p

1e-12

NANO

n

1e-9

MICRO_1

μ

1e-6

MICRO_2

u

1e-6

MILLI

m

1e-3

CENTI

c

1e-2

DECI

d

1e-1

DECA

da

1e1

HECTO

h

1e2

KILO

k

1e3

MEGA

M

1e6

GIGA

G

1e9

TERA

T

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 × specificWeight for callers that already have an area.

calculateSpecificWeight(weight, width, length, thickness, outputUom)

Computes specific weight in g/m3 from a mass and a rectangular volume. Currently the only outputUom accepted is g/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 (m2m^2, m3m^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:

ClassPurpose

SiUomSingleUomUtil

Convert a SiQuantity from one single unit to another, or to its base unit.

SiUomCompoundUtil

Reduce a compound-unit quantity (e.g. kg/m3) to its base form.

SiUomCalculationUtil

Add/subtract/multiply/divide quantities, plus dimension/mass/specific-weight calculations for trade and inventory flows.

SiQuantity / SiQuantityPcs

Immutable value types used as input and output of every utility above.

SiUomOperationType

Enum supplied to calculateQuantities to pick the arithmetic operation.

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.