// Document lines carry no UOM of their own: every quantity in the system is a count of the // item's base UOM (FR-MD-02/03). Screens that used to render a per-line UOM picker now show // the unit as a derived, read-only label — the user still needs to know that "12" means // 12 bottles, they just cannot change it. import { ItemListItem, Uom } from "@/types/master-data" /** Minimal shapes so this works with both `Item` and `ItemListItem`. */ type ItemLike = Pick /** * Display name of an item's base UOM, e.g. "BOTTLE". Returns an em dash when no item is * selected yet, and falls back to the raw id if the UOM list has not loaded. */ export function baseUomLabel( items: readonly ItemLike[], uoms: readonly Uom[], itemId: number | null | undefined, ): string { if (!itemId) return "—" const item = items.find((candidate) => candidate.itemId === itemId) if (!item) return "—" return uoms.find((u) => u.uomId === item.baseUomId)?.name ?? `#${item.baseUomId}` } /** * Display name for a UOM id that may be absent — an intermediate production output's WIP * label, which is null on any output that references a real item. */ export function uomLabel(uoms: readonly Uom[], uomId: number | null | undefined): string { if (!uomId) return "—" return uoms.find((u) => u.uomId === uomId)?.name ?? `#${uomId}` } /** * The unit an item's content is measured in — "ml" or "g" — or null when the item has no * content size. Used to label a production input entered in content units. */ export function contentUnitLabel( items: readonly Pick[], itemId: number | null | undefined, ): string | null { if (!itemId) return null const unit = items.find((candidate) => candidate.itemId === itemId)?.contentBaseUnit return unit ? unit.toLowerCase() : null }