Replace wagon/locomotive readiness with yard tracking, assign unassigned bookings from origin-yard fleet, standardize rates on USD with CBE ETB conversion, and update fleet/scheduling UI

This commit is contained in:
marshal
2026-06-14 01:32:39 +03:00
parent b73bf2154e
commit 87b0ce6339
45 changed files with 1249 additions and 520 deletions

View File

@@ -1,5 +1,3 @@
import type { Freight } from '@edr/types';
import { api as apiClient } from '../auth/http';
import { URL_CONSTANTS } from '@/constants/URLS';
@@ -13,7 +11,7 @@ export type LocomotiveStatus =
export interface LocomotiveListFilters {
status?: LocomotiveStatus;
readiness?: Freight.WagonReadiness;
currentYardId?: string;
}
export interface Locomotive {
@@ -22,7 +20,8 @@ export interface Locomotive {
name?: string | null;
locomotiveType: LocomotiveType;
status: LocomotiveStatus;
readiness: Freight.WagonReadiness;
currentYardId: string | null;
currentYard?: { id: string; label?: string; code?: string } | null;
maxPullWeightTons: number;
maxTrainLengthMeters: number;
powerKw?: number | null;
@@ -41,7 +40,7 @@ export const locomotivesService = {
getAll: (filters: LocomotiveListFilters = {}) => {
const params = new URLSearchParams();
if (filters.status) params.set('status', filters.status);
if (filters.readiness) params.set('readiness', filters.readiness);
if (filters.currentYardId) params.set('currentYardId', filters.currentYardId);
const qs = params.toString();
return apiClient.get<Locomotive[]>(
`${URL_CONSTANTS.LOCOMOTIVES.BASE}${qs ? `?${qs}` : ''}`,

View File

@@ -8,6 +8,7 @@ import type {
AssignBookingsPayload,
CompositionRemovalEntry,
CompositionUnassignedBooking,
UnassignedBookingsResponse,
CreateTrainSchedulePayload,
EligibleContainerBookingsResponse,
FreightType,
@@ -162,6 +163,17 @@ export const trainSchedulingService = {
return unwrap(response.data);
},
assignUnassignedBooking: async (
scheduleId: string,
bookingId: string,
): Promise<TrainScheduleDetail> => {
const response = await client.post<TrainScheduleDetail>(
URL_CONSTANTS.TRAIN_SCHEDULING.ASSIGN_UNASSIGNED_BOOKING(scheduleId),
{ bookingId },
);
return unwrap(response.data);
},
assignBookings: async (
scheduleId: string,
payload: AssignBookingsPayload,
@@ -374,8 +386,8 @@ export const trainSchedulingService = {
getUnassignedBookings: async (
scheduleId: string,
): Promise<CompositionUnassignedBooking[]> => {
const response = await client.get<CompositionUnassignedBooking[]>(
): Promise<UnassignedBookingsResponse> => {
const response = await client.get<UnassignedBookingsResponse>(
URL_CONSTANTS.TRAIN_SCHEDULING.UNASSIGNED_BOOKINGS(scheduleId),
);
return unwrap(response.data);

View File

@@ -11,14 +11,15 @@ export interface Wagon {
tareWeight: number;
maxPayloadWeight: number;
status: Freight.WagonStatus;
readiness: Freight.WagonReadiness;
currentYardId: string | null;
currentYard?: { id: string; label?: string; code?: string } | null;
notes?: string;
}
export interface WagonListFilters {
search?: string;
status?: Freight.WagonStatus;
readiness?: Freight.WagonReadiness;
currentYardId?: string;
wagonTypeId?: string;
trainId?: string;
}
@@ -28,7 +29,7 @@ export const wagonService = {
const params = new URLSearchParams();
if (filters.search?.trim()) params.set('search', filters.search.trim());
if (filters.status) params.set('status', filters.status);
if (filters.readiness) params.set('readiness', filters.readiness);
if (filters.currentYardId) params.set('currentYardId', filters.currentYardId);
if (filters.wagonTypeId) params.set('wagonTypeId', filters.wagonTypeId);
if (filters.trainId) params.set('trainId', filters.trainId);
const qs = params.toString();