feat: full wagon cancel, leg board, wagon dates

feat(freight): editable train leg times, SL invoice payer
This commit is contained in:
Marshal
2026-08-15 10:12:37 +00:00
parent c9c2d4dcb3
commit dc38e843a6
31 changed files with 1619 additions and 217 deletions

View File

@@ -81,6 +81,8 @@ import type {
LocomotiveRecord,
PinWagonsPayload,
RecordCheckpointPayload,
UpdateCheckpointPayload,
DispatchSchedulePayload,
StaffBookingWindow,
ScheduleMergePreview,
TrainScheduleDetail,
@@ -797,10 +799,13 @@ export const api = {
],
),
dispatchSchedule: endpoint<string, TrainScheduleDetail>(
dispatchSchedule: endpoint<
{ id: string; payload?: DispatchSchedulePayload },
TrainScheduleDetail
>(
"train-scheduling",
"dispatch-schedule",
(id) => trainSchedulingService.dispatchSchedule(id),
({ id, payload }) => trainSchedulingService.dispatchSchedule(id, payload),
undefined,
() => TRAIN_SCHEDULING_INVALIDATIONS,
),
@@ -918,6 +923,18 @@ export const api = {
() => TRAIN_SCHEDULING_INVALIDATIONS,
),
updateCheckpoint: endpoint<
{ id: string; sequenceNo: number; payload: UpdateCheckpointPayload },
TrainTrackResponse
>(
"train-scheduling",
"update-checkpoint",
({ id, sequenceNo, payload }) =>
trainSchedulingService.updateCheckpoint(id, sequenceNo, payload),
undefined,
() => TRAIN_SCHEDULING_INVALIDATIONS,
),
arriveSchedule: endpoint<string, TrainScheduleDetail>(
"train-scheduling",
"arrive-schedule",

View File

@@ -28,6 +28,8 @@ import type {
LocomotiveRecord,
PinWagonsPayload,
RecordCheckpointPayload,
UpdateCheckpointPayload,
DispatchSchedulePayload,
StaffBookingWindow,
ScheduleMergePreview,
TrainScheduleDetail,
@@ -524,10 +526,11 @@ export const trainSchedulingService = {
dispatchSchedule: async (
scheduleId: string,
payload: DispatchSchedulePayload = {},
): Promise<TrainScheduleDetail> => {
const response = await client.post<TrainScheduleDetail>(
URL_CONSTANTS.TRAIN_SCHEDULING.DISPATCH(scheduleId),
{},
payload,
);
return unwrap(response.data);
},
@@ -696,6 +699,18 @@ export const trainSchedulingService = {
return unwrap(response.data);
},
updateCheckpoint: async (
scheduleId: string,
sequenceNo: number,
payload: UpdateCheckpointPayload,
): Promise<TrainTrackResponse> => {
const response = await client.patch<TrainTrackResponse>(
URL_CONSTANTS.TRAIN_SCHEDULING.CHECKPOINT(scheduleId, sequenceNo),
payload,
);
return unwrap(response.data);
},
arriveSchedule: async (scheduleId: string): Promise<TrainScheduleDetail> => {
const response = await client.post<TrainScheduleDetail>(
URL_CONSTANTS.TRAIN_SCHEDULING.ARRIVE(scheduleId),

View File

@@ -26,6 +26,9 @@ export interface Wagon {
lengthMeters?: number;
} | null;
status: Freight.WagonStatus;
/** Latest status-log flip to MAINTENANCE / to AVAILABLE (list endpoint only). */
lastMaintenanceAt?: string | null;
lastAvailableAt?: string | null;
currentYardId: string | null;
currentYard?: { id: string; label?: string; code?: string } | null;
/** Odd EXPORT run (Ethiopia → Djibouti); null when the wagon is not on a run. */