From d8da2e49cb05f4cd982be60f7b779cfbea620ce6 Mon Sep 17 00:00:00 2001 From: Hagernesh Date: Sat, 4 Jul 2026 09:42:09 +0000 Subject: [PATCH] fix --- .../train-scheduling.service.ts | 27 ++++++++++++++++--- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/apps/edr-freight-api/src/modules/train-scheduling/train-scheduling.service.ts b/apps/edr-freight-api/src/modules/train-scheduling/train-scheduling.service.ts index 86e37451e..be6a8ea10 100644 --- a/apps/edr-freight-api/src/modules/train-scheduling/train-scheduling.service.ts +++ b/apps/edr-freight-api/src/modules/train-scheduling/train-scheduling.service.ts @@ -1207,8 +1207,10 @@ export class TrainSchedulingService { const schedule = await this.getImportDjiboutiSchedule(scheduleId); const operation = await this.getOrCreateImportDjiboutiOperation(scheduleId); this.assertImportDjiboutiGatepassGranted(operation); - if (!operation.loadedOnTrainAt) { - throw new BadRequestException('Import train cannot depart Djibouti before loading is confirmed'); + if (!operation.loadedOnTrainAt && !(await this.hasLoadedBooking(schedule.id))) { + throw new BadRequestException( + 'Import train cannot depart Djibouti before at least one booking is loaded', + ); } if (schedule.status === TrainScheduleStatusEnum.Scheduled) { @@ -1586,11 +1588,28 @@ export class TrainSchedulingService { where: { trainScheduleId: schedule.id }, }); this.assertImportDjiboutiGatepassGranted(operation); - if (!operation?.loadedOnTrainAt) { - throw new BadRequestException('Import train cannot depart Djibouti before loading is confirmed'); + // A train dispatches once loading is confirmed at the train level OR at least + // one booking on it is marked LOADED — it never waits for every booking. + if (!operation?.loadedOnTrainAt && !(await this.hasLoadedBooking(schedule.id))) { + throw new BadRequestException( + 'Import train cannot depart Djibouti before at least one booking is loaded', + ); } } + /** True when at least one booking on the schedule is confirmed LOADED. */ + private async hasLoadedBooking(scheduleId: string): Promise { + const [row]: Array<{ loaded: string }> = await this.dataSource.query( + `SELECT COUNT(*) AS loaded + FROM freight.train_schedule_bookings + WHERE train_schedule_id = $1 + AND loading_status = $2 + AND deleted_at IS NULL`, + [scheduleId, LoadingStatus.Loaded], + ); + return Number(row?.loaded ?? 0) > 0; + } + private async getImportDjiboutiSchedule(scheduleId: string): Promise { const schedule = await this.getDjiboutiGatepassSchedule(scheduleId); if (!this.isImportDjiboutiSchedule(schedule)) {