mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-26 18:42:49 +00:00
feat(operations-reporting): plan station targets per cargo category
The OCC report plans a station lane per cargo type — Nagad–Mojo container and Nagad–Mojo fertilizer are separate numbers — but a target's identity was period + metric + dimension + dimensionKey, so the two collided on one slot. `cargo_category` is now part of the row and of the uniqueness check; it stays null for cargo_category and container_class targets, whose dimensionKey already carries the category. The config grid showed raw codes (VOLUME_TONS, cargo_category, a yard code). The list read now sends readable twins alongside the stored codes, which stay exactly as they are because the reports join on them — the same shape YardDistancesService uses. Labels resolve per dimension rather than from one merged map: CONTAINER_EXPORT exists in both vocabularies and reads differently in each, and merging them gave every cargo-category row the container-class wording.
This commit is contained in:
@@ -671,14 +671,18 @@ export const RULE_ENGINE_RESOURCES: RuleEngineResourceConfig[] = [
|
||||
"Planned TEU, trainsets and tonnage per period — the Plan column in the operations reports",
|
||||
searchPlaceholder: "Search by category, station or note...",
|
||||
supportsSearch: true,
|
||||
cardTitleKey: "dimensionKey",
|
||||
cardTitleKey: "appliesToLabel",
|
||||
cardSubtitleKey: "periodStart",
|
||||
columns: [
|
||||
// The *Label columns are readable twins the API sends alongside the stored
|
||||
// codes (see OperationsTargetsService.toRow) — the codes themselves are
|
||||
// enums the reports join on and stay out of the grid.
|
||||
{ id: "periodStart", header: "Period start", accessorKey: "periodStart", format: "date" },
|
||||
{ id: "periodType", header: "Period", accessorKey: "periodType" },
|
||||
{ id: "metric", header: "Metric", accessorKey: "metric" },
|
||||
{ id: "dimension", header: "Dimension", accessorKey: "dimension" },
|
||||
{ id: "dimensionKey", header: "Applies to", accessorKey: "dimensionKey" },
|
||||
{ id: "periodLabel", header: "Period", accessorKey: "periodLabel" },
|
||||
{ id: "metricLabel", header: "Metric", accessorKey: "metricLabel" },
|
||||
{ id: "dimensionLabel", header: "Plan by", accessorKey: "dimensionLabel" },
|
||||
{ id: "appliesToLabel", header: "Applies to", accessorKey: "appliesToLabel" },
|
||||
{ id: "cargoCategoryLabel", header: "Cargo category", accessorKey: "cargoCategoryLabel" },
|
||||
{ id: "plannedValue", header: "Plan", accessorKey: "plannedValue", format: "number" },
|
||||
],
|
||||
formFields: [
|
||||
@@ -710,12 +714,11 @@ export const RULE_ENGINE_RESOURCES: RuleEngineResourceConfig[] = [
|
||||
label: "Period start",
|
||||
type: "date",
|
||||
required: true,
|
||||
description:
|
||||
"Any date inside the period — it is snapped to the start of the week, month, quarter or year on save.",
|
||||
description: "Any date inside the period — snapped to its start on save.",
|
||||
},
|
||||
{
|
||||
name: "dimension",
|
||||
label: "Applies to",
|
||||
label: "Plan by",
|
||||
type: "select",
|
||||
required: true,
|
||||
options: [
|
||||
@@ -726,22 +729,39 @@ export const RULE_ENGINE_RESOURCES: RuleEngineResourceConfig[] = [
|
||||
},
|
||||
{
|
||||
name: "dimensionKey",
|
||||
label: "Category / station code",
|
||||
label: "Applies to",
|
||||
type: "select",
|
||||
required: true,
|
||||
placeholder: "Select what the target applies to",
|
||||
placeholder: "Select",
|
||||
// The valid keys depend on the chosen dimension, and must match what the
|
||||
// reports emit exactly — a typo here is a target the report never finds.
|
||||
// reports emit exactly — a mismatch here is a target the report never
|
||||
// finds. Station options are the live yard codes, injected by
|
||||
// RuleEngineResourcePage.
|
||||
optionsFromValues: (values) => {
|
||||
const dimension = String(values.dimension ?? "");
|
||||
if (dimension === "container_class") return OPERATIONS_CONTAINER_CLASSES;
|
||||
if (dimension === "station") return [];
|
||||
return OPERATIONS_CARGO_CATEGORIES;
|
||||
},
|
||||
description:
|
||||
"Station targets are keyed on the yard code (KALITY, MOJO, NAGAD…) — type it exactly as it appears on Yards.",
|
||||
},
|
||||
{ name: "plannedValue", label: "Planned value", type: "number", required: true },
|
||||
{
|
||||
name: "cargoCategory",
|
||||
label: "Cargo category",
|
||||
type: "select",
|
||||
required: true,
|
||||
// A station's plan is per station AND per cargo type — the OCC report
|
||||
// plans Nagad-Mojo container and Nagad-Mojo fertilizer separately. The
|
||||
// other two dimensions already carry the category in the key above.
|
||||
showWhen: { field: "dimension", equals: ["station"] },
|
||||
options: OPERATIONS_CARGO_CATEGORIES,
|
||||
},
|
||||
{
|
||||
name: "plannedValue",
|
||||
label: "Planned value",
|
||||
type: "number",
|
||||
required: true,
|
||||
description: "TEU, trainsets or tonnes — whichever the metric above is.",
|
||||
},
|
||||
{ name: "note", label: "Note", type: "text", optional: true },
|
||||
],
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user