mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-29 19:58:11 +00:00
feat: add per-ton cargo loading limits and update related services
This commit is contained in:
@@ -60,12 +60,16 @@ interface CargoNode extends RuleEngineRecord {
|
||||
wagonTypes?: { id: string; code?: string; name?: string }[];
|
||||
/** PER_ITEM only: whole items that physically fit one wagon, keyed by wagon-type id. */
|
||||
itemsPerWagonMap?: Record<string, number> | null;
|
||||
/** PER_TON only: max tons of this cargo per wagon, keyed by wagon-type id. */
|
||||
tonsPerWagonMap?: Record<string, number> | null;
|
||||
isActive?: boolean;
|
||||
displayOrder?: number;
|
||||
}
|
||||
|
||||
/** Form-value prefix for the per-wagon-type items-fit inputs (PER_ITEM cargo). */
|
||||
const ITEMS_FIT_PREFIX = "itemsFit__";
|
||||
/** Form-value prefix for the per-wagon-type tonnage-cap inputs (PER_TON cargo). */
|
||||
const TONS_CAP_PREFIX = "tonsCap__";
|
||||
|
||||
const str = (v: unknown): string => (v == null ? "" : String(v));
|
||||
const orderOf = (n: CargoNode): number => Number(n.displayOrder ?? 0);
|
||||
@@ -159,8 +163,26 @@ const CargoTypesPage = () => {
|
||||
getInitialValue: (record) =>
|
||||
(record as CargoNode).itemsPerWagonMap?.[opt.value],
|
||||
}));
|
||||
// PER_TON cargo: an OPTIONAL "max tons per wagon" per selected wagon type —
|
||||
// how much of this commodity actually rides one wagon, which can be less
|
||||
// than its rating (sugar 50T on a 70T wagon, so 200T takes 4 wagons not 3).
|
||||
// Left blank the wagon's full rated capacity applies, so existing cargo is
|
||||
// unaffected; the API rejects a value above the rating.
|
||||
const tonsCapFields: FormFieldDef[] = (wagonTypeOptions ?? []).map((opt) => ({
|
||||
name: `${TONS_CAP_PREFIX}${opt.value}`,
|
||||
label: `Max tons per ${opt.label} wagon`,
|
||||
type: "number",
|
||||
optional: true,
|
||||
placeholder: "Blank = full wagon capacity",
|
||||
showIf: (values) =>
|
||||
values.unitOfMeasure === "PER_TON" &&
|
||||
Array.isArray(values.wagonTypeIds) &&
|
||||
(values.wagonTypeIds as string[]).includes(opt.value),
|
||||
getInitialValue: (record) =>
|
||||
(record as CargoNode).tonsPerWagonMap?.[opt.value],
|
||||
}));
|
||||
const wagonTypesAt = base.findIndex((field) => field.name === "wagonTypeIds");
|
||||
base.splice(wagonTypesAt + 1, 0, ...fitFields);
|
||||
base.splice(wagonTypesAt + 1, 0, ...fitFields, ...tonsCapFields);
|
||||
return base;
|
||||
}, [wagonTypeOptions]);
|
||||
|
||||
@@ -230,14 +252,22 @@ const CargoTypesPage = () => {
|
||||
// none are visible (not PER_ITEM) so an update clears stale fits.
|
||||
const payload: Record<string, unknown> = {};
|
||||
const itemsPerWagonMap: Record<string, number> = {};
|
||||
const tonsPerWagonMap: Record<string, number> = {};
|
||||
for (const [key, value] of Object.entries(values)) {
|
||||
if (key.startsWith(ITEMS_FIT_PREFIX)) {
|
||||
itemsPerWagonMap[key.slice(ITEMS_FIT_PREFIX.length)] = Number(value);
|
||||
} else if (key.startsWith(TONS_CAP_PREFIX)) {
|
||||
// Blank means "no cap" (use the full rated capacity), so an empty input
|
||||
// must stay OUT of the map — sending 0 would be a zero-ton wagon.
|
||||
if (value !== "" && value !== null && value !== undefined) {
|
||||
tonsPerWagonMap[key.slice(TONS_CAP_PREFIX.length)] = Number(value);
|
||||
}
|
||||
} else {
|
||||
payload[key] = value;
|
||||
}
|
||||
}
|
||||
payload.itemsPerWagonMap = Object.keys(itemsPerWagonMap).length ? itemsPerWagonMap : null;
|
||||
payload.tonsPerWagonMap = Object.keys(tonsPerWagonMap).length ? tonsPerWagonMap : null;
|
||||
// Add always attaches to the page we're on; edit keeps the node's parent.
|
||||
if (formMode?.kind === "create" && current) {
|
||||
payload.parentGroupId = current.id;
|
||||
|
||||
Reference in New Issue
Block a user