mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-09-07 17:45:42 +00:00
fix(freight): gate loading on booking paymentStatus only; default schedule voyage no. to train's voyage number
This commit is contained in:
@@ -504,9 +504,10 @@ export default function TrainScheduleV2DetailPage() {
|
||||
b.originYardId === originYardId &&
|
||||
!b.loadedAt &&
|
||||
(b.loadingStatus ?? "UNLOADED") !== "LOADED" &&
|
||||
// Paid is read from the PAYMENT status only, never booking.status.
|
||||
(b.isGovernment
|
||||
? b.status === "APPROVED" || b.status === "PAID"
|
||||
: b.status === "PAID" ||
|
||||
? b.status === "APPROVED" || b.paymentStatus === "PAID"
|
||||
: b.paymentStatus === "PAID" ||
|
||||
// Shipping-line bookings ride from accept on the credit ledger.
|
||||
(Boolean(b.shippingLineCompanyId) && b.status === "FULLY_EXECUTED")),
|
||||
);
|
||||
|
||||
@@ -158,6 +158,11 @@ export default function TrainScheduleV2ListPage() {
|
||||
const [routeId, setRouteId] = useState("");
|
||||
const [scheduleDate, setScheduleDate] = useState("");
|
||||
const [trainId, setTrainId] = useState("");
|
||||
// Voyage number for this departure — required. Auto-filled from the selected
|
||||
// train's own voyage number (typed in the Train Builder) when a train is
|
||||
// picked; legacy trains without one fall back to the direction-matched run
|
||||
// number. Staff may edit.
|
||||
const [voyageNumber, setVoyageNumber] = useState("");
|
||||
const [reverseWagonOrder, setReverseWagonOrder] = useState(false);
|
||||
// "" = a normal customer train; an id dedicates the departure to that
|
||||
// shipping line and hides it from every customer-facing view.
|
||||
@@ -461,6 +466,13 @@ export default function TrainScheduleV2ListPage() {
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (!voyageNumber.trim()) {
|
||||
toast({
|
||||
title: "Voyage number is required",
|
||||
variant: "destructive",
|
||||
});
|
||||
return;
|
||||
}
|
||||
// Only build the window override when the toggle is on — off means "inherit
|
||||
// the global rules", which the API expresses as an absent windowRule.
|
||||
let windowRule: CreateScheduleWindowRulePayload | undefined;
|
||||
@@ -483,6 +495,7 @@ export default function TrainScheduleV2ListPage() {
|
||||
routeId,
|
||||
scheduleDate: new Date(scheduleDate).toISOString(),
|
||||
trainId,
|
||||
voyageNumber: voyageNumber.trim(),
|
||||
reverseWagonOrder,
|
||||
...(shippingLineCompanyId ? { shippingLineCompanyId } : {}),
|
||||
...(windowRule ? { windowRule } : {}),
|
||||
@@ -490,6 +503,7 @@ export default function TrainScheduleV2ListPage() {
|
||||
});
|
||||
toast({ title: "Train schedule created" });
|
||||
showScheduleWarnings(created.warnings);
|
||||
setVoyageNumber("");
|
||||
setReverseWagonOrder(false);
|
||||
setShippingLineCompanyId("");
|
||||
setConfigureWindow(false);
|
||||
@@ -689,7 +703,20 @@ export default function TrainScheduleV2ListPage() {
|
||||
};
|
||||
})}
|
||||
value={trainId || null}
|
||||
onChange={(v) => setTrainId(v ?? "")}
|
||||
onChange={(v) => {
|
||||
setTrainId(v ?? "");
|
||||
// Default the voyage number to the picked train's own voyage
|
||||
// number (the Train Builder stores it as `trainName`). The run
|
||||
// number is a train number, not a voyage — only fall back to it
|
||||
// for legacy trains that have no voyage number yet; staff can
|
||||
// still override.
|
||||
const picked = (trainsQuery.data ?? []).find((t) => t.id === v);
|
||||
const runNumber =
|
||||
selectedRoute?.direction === "IMPORT"
|
||||
? picked?.importTrainNumber
|
||||
: picked?.exportTrainNumber;
|
||||
setVoyageNumber(picked?.trainName?.trim() || runNumber || "");
|
||||
}}
|
||||
searchable
|
||||
disabled={!routeId}
|
||||
nothingFoundMessage={
|
||||
@@ -698,6 +725,15 @@ export default function TrainScheduleV2ListPage() {
|
||||
: "Select a route first"
|
||||
}
|
||||
/>
|
||||
<TextInput
|
||||
label="Voyage number"
|
||||
description="Sailing/run number for this departure that yards and customs quote. Defaults to the selected train's voyage number — edit if needed."
|
||||
placeholder={trainId ? "e.g. V-2026-0620" : "Select a train first"}
|
||||
required
|
||||
maxLength={20}
|
||||
value={voyageNumber}
|
||||
onChange={(e) => setVoyageNumber(e.currentTarget.value)}
|
||||
/>
|
||||
<Select
|
||||
label="Shipping line (optional)"
|
||||
description="Dedicate this departure to one shipping line. The train is then hidden from customers and shown only in that line's portal."
|
||||
@@ -930,7 +966,12 @@ function TrainIdentityCell({ schedule }: { schedule: TrainScheduleListItem }) {
|
||||
let subtitle = "";
|
||||
if (schedule.train) {
|
||||
title = schedule.trainNumber ?? schedule.train.code;
|
||||
subtitle = [schedule.trainNumber ? schedule.train.code : null, schedule.train.trainName]
|
||||
// Show THIS departure's voyage number (the schedule's own), not the train's
|
||||
// voyage/name — one train serves many departures, each with its own voyage.
|
||||
subtitle = [
|
||||
schedule.trainNumber ? schedule.train.code : null,
|
||||
schedule.voyageNumber ? `Voyage ${schedule.voyageNumber}` : null,
|
||||
]
|
||||
.filter(Boolean)
|
||||
.join(" · ");
|
||||
} else if (locos.length) {
|
||||
|
||||
Reference in New Issue
Block a user