mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-29 18:48:11 +00:00
[200~feat: add CustomsPaymentsCard and PaymentsTab components for handling customs payments and payment summaries
This commit is contained in:
@@ -59,6 +59,7 @@ import {
|
||||
import {
|
||||
DEFAULT_CONFIGURATION_SLUG,
|
||||
DEFAULT_RULES_SLUG,
|
||||
ROUTE_SCOPED_TRIGGERS,
|
||||
RULE_ENGINE_CATEGORY_BASE_PATH,
|
||||
RULE_ENGINE_SELECT_NONE,
|
||||
getRuleEngineResource,
|
||||
@@ -120,9 +121,7 @@ const yardOptionsForLegEnd = (
|
||||
// direction + route, so their yard dropdowns narrow exactly like base
|
||||
// freight.
|
||||
(appliesTo === "OTHER" &&
|
||||
["CUSTOMS_CLEARANCE", "WITH_RETURN", "FUEL"].includes(
|
||||
String(values.trigger ?? ""),
|
||||
))
|
||||
ROUTE_SCOPED_TRIGGERS.includes(String(values.trigger ?? "")))
|
||||
) {
|
||||
const direction = String(values.tradeDirection ?? "");
|
||||
// Direction is what decides the countries, so offer nothing until it is set
|
||||
|
||||
@@ -190,6 +190,10 @@ const RATE_TRIGGERS = [
|
||||
{ label: "Cancellation (per wagon, per direction + cargo type)", value: "CANCELLATION" },
|
||||
{ label: "Shipping line extra fee (PIL)", value: "PIL_EXTRA_FEE" },
|
||||
{ label: "Customs clearance service fee (billed with the booking)", value: "CUSTOMS_CLEARANCE" },
|
||||
{
|
||||
label: "Ethiopian customs clearance service fee (Ethiopian-side-only services)",
|
||||
value: "ETHIOPIAN_CUSTOMS_CLEARANCE",
|
||||
},
|
||||
{ label: "Fuel (per lane + cargo type)", value: "FUEL" },
|
||||
];
|
||||
|
||||
@@ -248,8 +252,16 @@ const SHIPPING_LINE_CARGO_KINDS = [
|
||||
const isBaseFreightRate = (values: Record<string, unknown>) =>
|
||||
["BULK", "CONTAINER", "INTERCITY"].includes(String(values.appliesTo ?? ""));
|
||||
|
||||
/** Surcharges sold per origin → destination leg (mirrors RatesService.isRouteScoped). */
|
||||
export const ROUTE_SCOPED_TRIGGERS = [
|
||||
"CUSTOMS_CLEARANCE",
|
||||
"ETHIOPIAN_CUSTOMS_CLEARANCE",
|
||||
"WITH_RETURN",
|
||||
"FUEL",
|
||||
];
|
||||
|
||||
/**
|
||||
* Rates priced per leg: base rail freight, plus the customs clearance fee and
|
||||
* Rates priced per leg: base rail freight, plus the customs clearance fees and
|
||||
* the empty-container return surcharge (sold per route + container type).
|
||||
*/
|
||||
const isRouteScopedRate = (values: Record<string, unknown>) =>
|
||||
@@ -258,19 +270,19 @@ const isRouteScopedRate = (values: Record<string, unknown>) =>
|
||||
(isShippingLineRate(values)
|
||||
? hasShippingLine(values) &&
|
||||
(values.shippingLineRateKind === "BASE" ||
|
||||
["CUSTOMS_CLEARANCE", "WITH_RETURN", "FUEL"].includes(
|
||||
String(values.trigger ?? ""),
|
||||
))
|
||||
ROUTE_SCOPED_TRIGGERS.includes(String(values.trigger ?? "")))
|
||||
: isBaseFreightRate(values)) ||
|
||||
(String(values.appliesTo ?? "") === "OTHER" &&
|
||||
["CUSTOMS_CLEARANCE", "WITH_RETURN", "FUEL"].includes(String(values.trigger ?? "")));
|
||||
ROUTE_SCOPED_TRIGGERS.includes(String(values.trigger ?? "")));
|
||||
|
||||
/**
|
||||
* Surcharges sold per cargo kind: the admin says container or bulk, then names
|
||||
* the container type or bulk commodity the fee covers.
|
||||
*/
|
||||
const isCargoKindTrigger = (values: Record<string, unknown>) =>
|
||||
["CUSTOMS_CLEARANCE", "CANCELLATION"].includes(String(values.trigger ?? ""));
|
||||
["CUSTOMS_CLEARANCE", "ETHIOPIAN_CUSTOMS_CLEARANCE", "CANCELLATION"].includes(
|
||||
String(values.trigger ?? ""),
|
||||
);
|
||||
|
||||
const unitOption = (value: string) => ({ label: value.replace(/_/g, " "), value });
|
||||
|
||||
@@ -314,6 +326,7 @@ const unitsForShape = (
|
||||
// Wagon cancellation fee — scales with the cancelled wagons only.
|
||||
return ["PER_WAGON"];
|
||||
case "CUSTOMS_CLEARANCE":
|
||||
case "ETHIOPIAN_CUSTOMS_CLEARANCE":
|
||||
// Per cargo kind: container fees per box/wagon, bulk per ton/wagon.
|
||||
return cargoKind === "BULK"
|
||||
? ["PER_TON", "PER_WAGON"]
|
||||
@@ -726,6 +739,14 @@ export const RULE_ENGINE_RESOURCES: RuleEngineResourceConfig[] = [
|
||||
{ name: "includesFirstMile", label: "Includes first mile", type: "boolean" },
|
||||
{ name: "includesLastMile", label: "Includes last mile", type: "boolean" },
|
||||
{ name: "includesCustoms", label: "Includes customs", type: "boolean" },
|
||||
{
|
||||
name: "includesEthiopianCustomsOnly",
|
||||
label: "Ethiopian customs only",
|
||||
type: "boolean",
|
||||
description:
|
||||
"EDR clears customs on the Ethiopian side only. Same clearance flow; contracts and bookings price off the Ethiopian customs clearance rate instead of the standard one.",
|
||||
showIf: (v) => v.includesCustoms === true,
|
||||
},
|
||||
{ name: "isActive", label: "Active", type: "boolean" },
|
||||
],
|
||||
},
|
||||
@@ -931,6 +952,11 @@ export const RULE_ENGINE_RESOURCES: RuleEngineResourceConfig[] = [
|
||||
label: "Customs clearance",
|
||||
filters: { trigger: "CUSTOMS_CLEARANCE", isShippingLineRate: "false" },
|
||||
},
|
||||
{
|
||||
key: "ethiopian-customs",
|
||||
label: "Ethiopian customs",
|
||||
filters: { trigger: "ETHIOPIAN_CUSTOMS_CLEARANCE", isShippingLineRate: "false" },
|
||||
},
|
||||
{
|
||||
key: "return",
|
||||
label: "Container return",
|
||||
@@ -1085,6 +1111,7 @@ export const RULE_ENGINE_RESOURCES: RuleEngineResourceConfig[] = [
|
||||
(String(v.appliesTo ?? "") === "OTHER" &&
|
||||
[
|
||||
"CUSTOMS_CLEARANCE",
|
||||
"ETHIOPIAN_CUSTOMS_CLEARANCE",
|
||||
"CANCELLATION",
|
||||
"WITH_RETURN",
|
||||
"LASHING",
|
||||
|
||||
Reference in New Issue
Block a user