mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-29 00:10:57 +00:00
57 lines
1.8 KiB
TypeScript
57 lines
1.8 KiB
TypeScript
/**
|
|
* Client mirror of the backend's contiguous-range rules for priority configs
|
|
* (see PriorityConfigsService.assertNoRangeCollision): ranges per type — per
|
|
* currency for CURRENCY — run from 1 with no gaps and no overlaps, so the next
|
|
* range always starts at the lowest uncovered wagon count. There is no upper
|
|
* ceiling. The backend re-validates on submit AND on approval; this only
|
|
* drives the form prefill.
|
|
*/
|
|
|
|
export type PriorityRuleType = "WAGON" | "CURRENCY" | "CUSTOMS";
|
|
|
|
export interface PriorityRangeRule {
|
|
id?: unknown;
|
|
type?: unknown;
|
|
currency?: unknown;
|
|
minWagonCount?: unknown;
|
|
maxWagonCount?: unknown;
|
|
}
|
|
|
|
const PRIORITY_RULE_TYPES: PriorityRuleType[] = ["WAGON", "CURRENCY", "CUSTOMS"];
|
|
|
|
/**
|
|
* Where the next range for `type` (+`currency`) must start, excluding
|
|
* `excludeId` (the rule being edited). Null only when `type` is not yet a
|
|
* known priority rule type — the chain itself is unbounded, so a next start
|
|
* always exists.
|
|
*/
|
|
export function nextPriorityRangeStart(
|
|
rules: PriorityRangeRule[],
|
|
type: string,
|
|
currency: string | null | undefined,
|
|
excludeId?: string,
|
|
): number | null {
|
|
if (!PRIORITY_RULE_TYPES.includes(type as PriorityRuleType)) return null;
|
|
|
|
const scoped = rules
|
|
.filter(
|
|
(r) =>
|
|
String(r.type ?? "") === type &&
|
|
(excludeId === undefined || String(r.id ?? "") !== excludeId) &&
|
|
(type !== "CURRENCY" ||
|
|
String(r.currency ?? "") === String(currency ?? "")),
|
|
)
|
|
.map((r) => ({
|
|
min: Number(r.minWagonCount ?? 0),
|
|
max: Number(r.maxWagonCount ?? 0),
|
|
}))
|
|
.sort((a, b) => a.min - b.min);
|
|
|
|
let next = 1;
|
|
for (const r of scoped) {
|
|
if (r.min > next) break; // gap before this rule — fill it first
|
|
next = Math.max(next, r.max + 1);
|
|
}
|
|
return next;
|
|
}
|