|
- export const formatNum = (n: number) =>
- Number.isFinite(n) ? n.toLocaleString(undefined, { maximumFractionDigits: 4 }) : "—";
-
- /** Packaging / compound stock unit (e.g. 1包X25千克) — not a simple unit like 斤 or kg. */
- export const isPackagingUom = (uom?: string | null): boolean => {
- const unit = uom?.trim();
- if (!unit) return false;
- if (/^\d/.test(unit)) return true;
- if (/[xX×]/.test(unit) && /\d/.test(unit)) return true;
- return false;
- };
-
- /** Join qty with UOM; packaging units use parentheses to avoid "6 1包…" ambiguity. */
- export const joinQtyUom = (num: string, unit: string): string =>
- isPackagingUom(unit) ? `${num}(${unit})` : `${num} ${unit}`;
-
- /** Format a quantity with its unit when available. */
- export const formatQty = (qty: number | null | undefined, uom?: string | null): string => {
- if (qty == null || !Number.isFinite(Number(qty))) return "—";
- const num = formatNum(Number(qty));
- const unit = uom?.trim();
- return unit ? joinQtyUom(num, unit) : num;
- };
-
- /** Signed variance for stock adjustments: IN → +qty, OUT → −qty. */
- export const formatSignedQty = (
- qty: number | null | undefined,
- direction: string | null | undefined,
- uom?: string | null,
- ): string => {
- if (qty == null || !Number.isFinite(Number(qty))) return "—";
- const abs = Math.abs(Number(qty));
- const sign = (direction ?? "").trim().toUpperCase() === "OUT" ? "-" : "+";
- const num = formatNum(abs);
- const unit = uom?.trim();
- const signed = `${sign}${num}`;
- return unit ? joinQtyUom(signed, unit) : signed;
- };
|