mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-30 04:08:11 +00:00
Bulk (per ton per km) last-mile rates now carry From/To km bands like
container mode: the Add Rate dialog offers the multi-tier editor in both modes, each tier is created as its own rate row, and overlapping bulk bands are rejected. Pricing picks the tier whose half-open band holds the trip km, falling back to the legacy bandless bulk rate.
This commit is contained in:
@@ -306,34 +306,27 @@ const RuleEngineResourcePage = () => {
|
||||
|
||||
const formFields = useMemo(() => {
|
||||
if (!config) return [];
|
||||
// Last-mile container bands: creating uses the multi-row tier list (one
|
||||
// rate per tier); editing an existing band row keeps the single
|
||||
// From/To/value fields (a rate row IS one band).
|
||||
// Last-mile bands (both modes): creating uses the multi-row tier list (one
|
||||
// rate per tier, each tier carrying its own rate value); editing an
|
||||
// existing band row keeps the single From/To/value fields (a rate row IS
|
||||
// one band).
|
||||
const bandFields = config.formFields.filter((field) => {
|
||||
if (config.slug !== "rates") return true;
|
||||
if (field.type === "tierList") return !editing;
|
||||
if (editing) return true;
|
||||
return field.name !== "minKm" && field.name !== "maxKm";
|
||||
});
|
||||
return bandFields.map((field) => {
|
||||
// On create, the tier rows carry the per-band rate values — the single
|
||||
// last-mile "Rate value" field then only applies to bulk mode.
|
||||
// On create the tier rows carry From/To/value — drop the single fields,
|
||||
// including the last-mile "Rate value" (the non-last-mile one keeps its
|
||||
// own showIf).
|
||||
if (
|
||||
config.slug === "rates" &&
|
||||
!editing &&
|
||||
field.name === "rateValue" &&
|
||||
field.showWhen?.field === "appliesTo" &&
|
||||
field.showWhen.equals.includes("LAST_MILE")
|
||||
) {
|
||||
return {
|
||||
...field,
|
||||
showWhen: undefined,
|
||||
showIf: (values: Record<string, unknown>) =>
|
||||
values.appliesTo === "LAST_MILE" && values.lastMileMode === "BULK",
|
||||
};
|
||||
return false;
|
||||
}
|
||||
return field;
|
||||
}).map((field) => {
|
||||
return field.name !== "minKm" && field.name !== "maxKm";
|
||||
});
|
||||
return bandFields.map((field) => {
|
||||
if (isPriorityRules && field.name === "minWagonCount") {
|
||||
return {
|
||||
...field,
|
||||
@@ -621,19 +614,15 @@ const RuleEngineResourcePage = () => {
|
||||
currency: isLastMile ? (values.currency ?? "ETB") : "USD",
|
||||
trigger: isSurcharge ? values.trigger : "ALWAYS",
|
||||
...(isLastMile
|
||||
? lastMileMode === "BULK"
|
||||
? {
|
||||
rateUnit: "PER_TON_KM",
|
||||
containerTypeId: undefined,
|
||||
minKm: undefined,
|
||||
maxKm: undefined,
|
||||
}
|
||||
: {
|
||||
rateUnit: "PER_KM",
|
||||
// Empty "To km" means an open-ended band — send null so an
|
||||
// edit can clear a previously-set ceiling.
|
||||
maxKm: values.maxKm ?? null,
|
||||
}
|
||||
? {
|
||||
// Empty "To km" means an open-ended band — send null so an
|
||||
// edit can clear a previously-set ceiling. On create the tier
|
||||
// spread below overrides the band fields per tier.
|
||||
maxKm: values.maxKm ?? null,
|
||||
...(lastMileMode === "BULK"
|
||||
? { rateUnit: "PER_TON_KM", containerTypeId: undefined }
|
||||
: { rateUnit: "PER_KM" }),
|
||||
}
|
||||
: {}),
|
||||
};
|
||||
// Editing a LIVE rate files a change request — the rate keeps charging
|
||||
|
||||
@@ -1003,7 +1003,8 @@ export const RULE_ENGINE_RESOURCES: RuleEngineResourceConfig[] = [
|
||||
placeholder: "0",
|
||||
description: "Band start (inclusive). Use 0 for the first band.",
|
||||
showIf: (v) =>
|
||||
v.appliesTo === "LAST_MILE" && v.lastMileMode === "CONTAINER",
|
||||
v.appliesTo === "LAST_MILE" &&
|
||||
(v.lastMileMode === "CONTAINER" || v.lastMileMode === "BULK"),
|
||||
},
|
||||
{
|
||||
name: "maxKm",
|
||||
@@ -1013,7 +1014,8 @@ export const RULE_ENGINE_RESOURCES: RuleEngineResourceConfig[] = [
|
||||
placeholder: "Leave empty for no upper limit",
|
||||
description: "Band end (exclusive) — a 0–30 band covers up to but not including 30 km.",
|
||||
showIf: (v) =>
|
||||
v.appliesTo === "LAST_MILE" && v.lastMileMode === "CONTAINER",
|
||||
v.appliesTo === "LAST_MILE" &&
|
||||
(v.lastMileMode === "CONTAINER" || v.lastMileMode === "BULK"),
|
||||
},
|
||||
{
|
||||
name: "currency",
|
||||
@@ -1035,9 +1037,10 @@ export const RULE_ENGINE_RESOURCES: RuleEngineResourceConfig[] = [
|
||||
type: "tierList",
|
||||
required: true,
|
||||
description:
|
||||
"One rate per distance range. To km is exclusive (0–30 then 30+); leave the last tier's To km empty for no upper limit.",
|
||||
"One rate per distance range — the rate value is per km (container mode) or per ton per km (bulk mode). To km is exclusive (0–30 then 30+); leave the last tier's To km empty for no upper limit.",
|
||||
showIf: (v) =>
|
||||
v.appliesTo === "LAST_MILE" && v.lastMileMode === "CONTAINER",
|
||||
v.appliesTo === "LAST_MILE" &&
|
||||
(v.lastMileMode === "CONTAINER" || v.lastMileMode === "BULK"),
|
||||
},
|
||||
// ── Container type — Container freight, container-kind intercity, and
|
||||
// the empty-container return surcharge (20ft vs 40ft price differently) ─
|
||||
|
||||
Reference in New Issue
Block a user