From 6058b870a17d8f250bb3b5fed3bc25629091d572 Mon Sep 17 00:00:00 2001 From: ghost2023 Date: Sat, 13 Jun 2026 09:29:45 +0300 Subject: [PATCH] feat(train-scheduling): implement API and types for bookable schedules --- .../portal/src/constants/URLS.ts | 4 +++ .../portal/src/services/api.ts | 7 ++++ .../portal/src/services/bookings.service.ts | 10 ++++++ packages/types/src/freight/index.ts | 33 +++++++++++++++++++ 4 files changed, 54 insertions(+) diff --git a/apps/edr-freight-web/portal/src/constants/URLS.ts b/apps/edr-freight-web/portal/src/constants/URLS.ts index 578a1d97d..4e01ba78e 100644 --- a/apps/edr-freight-web/portal/src/constants/URLS.ts +++ b/apps/edr-freight-web/portal/src/constants/URLS.ts @@ -96,4 +96,8 @@ export const URL_CONSTANTS = { CANCEL: (id: string | number) => `/api/bookings/${id}/cancel`, CONFIRM: (id: string | number) => `/api/bookings/${id}/confirm`, }, + + TRAIN_SCHEDULING: { + BOOKABLE_SCHEDULES: "/api/train-scheduling/bookable-schedules", + }, }; diff --git a/apps/edr-freight-web/portal/src/services/api.ts b/apps/edr-freight-web/portal/src/services/api.ts index 645dc7f50..e1bd57729 100644 --- a/apps/edr-freight-web/portal/src/services/api.ts +++ b/apps/edr-freight-web/portal/src/services/api.ts @@ -185,6 +185,13 @@ export const api = { "checkPayment", ({ orderId }) => bookingsService.checkPayment(orderId), ), + + getBookableSchedules: endpoint< + { originYardId?: string; destinationYardId?: string }, + Freight.BookableScheduleItem[] + >("train-scheduling", "bookableSchedules", ({ originYardId, destinationYardId }) => + bookingsService.getBookableSchedules({ originYardId, destinationYardId }), + ), }, consignments: { diff --git a/apps/edr-freight-web/portal/src/services/bookings.service.ts b/apps/edr-freight-web/portal/src/services/bookings.service.ts index a8d36619d..f723e2730 100644 --- a/apps/edr-freight-web/portal/src/services/bookings.service.ts +++ b/apps/edr-freight-web/portal/src/services/bookings.service.ts @@ -151,4 +151,14 @@ export const bookingsService = { const { data } = await client.post(B.CONTRACT_SIGN(id), payload); return data.data ?? data; }, + + getBookableSchedules: async ( + query: Freight.BookableSchedulesQuery = {}, + ): Promise => { + const { data } = await client.get( + URL_CONSTANTS.TRAIN_SCHEDULING.BOOKABLE_SCHEDULES, + { params: query }, + ); + return data.data; + }, }; diff --git a/packages/types/src/freight/index.ts b/packages/types/src/freight/index.ts index e1620b41f..2ba2c9535 100644 --- a/packages/types/src/freight/index.ts +++ b/packages/types/src/freight/index.ts @@ -420,6 +420,39 @@ export interface BookingReferenceData { cargo_type: BookingReferenceCargoTypeGroup[]; } +// ── Train Scheduling (bookable schedules) ────────────────────────────────────── + +export interface BookableSchedulesQuery { + originYardId?: string; + destinationYardId?: string; +} + +export interface BookableScheduleLocomotive { + id: string; + code: string; + name: string | null; + readiness: string | null; +} + +export interface BookableScheduleItem { + id: string; + scheduleDate: string; + trainNumber: string | null; + routeName: string | null; + origin: string | null; + destination: string | null; + locomotive: BookableScheduleLocomotive | null; + wagonCount: number; + totalWeightTons: number; + totalLengthMeters: number; + bookingsCount: number; + freightType: FreightType | "MIXED" | null; + status: TrainScheduleStatus; + bookingWindowStatus: ScheduleBookingWindow; + maxWagons: number; + remainingWagons: number; +} + // ── DTOs ─────────────────────────────────────────────────────────────────────── export interface CreateBookingContainerDto {