mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-27 19:00:55 +00:00
Notify customer on Sign handover, truck assignment, arrival and dispatch of train
This commit is contained in:
@@ -71,6 +71,24 @@ export class BookingNotifierService {
|
||||
});
|
||||
}
|
||||
|
||||
/** Train carrying the booking departed — dispatched origin → destination. */
|
||||
dispatched(b: Booking, origin: string | null, destination: string | null): void {
|
||||
const msg =
|
||||
`Your booking ${b.reference ?? b.id} has been dispatched` +
|
||||
`${origin || destination ? ` from ${origin ?? '?'} to ${destination ?? '?'}` : ''}.`;
|
||||
void this.notifyContact(b, msg, 'DISPATCHED');
|
||||
this.inApp(b, 'Shipment dispatched', msg);
|
||||
}
|
||||
|
||||
/** Train carrying the booking arrived at destination. */
|
||||
arrived(b: Booking, origin: string | null, destination: string | null): void {
|
||||
const msg =
|
||||
`Your booking ${b.reference ?? b.id} has arrived` +
|
||||
`${destination ? ` at ${destination}` : ''}${origin ? ` (from ${origin})` : ''}.`;
|
||||
void this.notifyContact(b, msg, 'ARRIVED');
|
||||
this.inApp(b, 'Shipment arrived', msg);
|
||||
}
|
||||
|
||||
async payNow(b: Booking, deadline: Date): Promise<void> {
|
||||
const payMinutes = Math.max(1, Math.round((deadline.getTime() - Date.now()) / 60_000));
|
||||
const eat = deadline.toLocaleString('en-GB', { timeZone: 'Africa/Addis_Ababa' });
|
||||
|
||||
@@ -158,6 +158,7 @@ describe('TrainSchedulingService', () => {
|
||||
{
|
||||
autoArriveAtFinalYard: jest.fn().mockResolvedValue([]),
|
||||
} as never, // bookingJourneyService
|
||||
{ dispatched: jest.fn(), arrived: jest.fn() } as never, // bookingNotifier
|
||||
);
|
||||
|
||||
const defaultFleetWagons = [
|
||||
|
||||
@@ -72,6 +72,7 @@ import { UpdateScheduleWindowRuleDto } from './dto/update-schedule-window-rule.d
|
||||
import { UpdateScheduleDateDto } from './dto/update-schedule-date.dto';
|
||||
import { type BookingWindowConfig } from './booking-window.config';
|
||||
import { BookingWindowGateway } from './booking-window.gateway';
|
||||
import { BookingNotifierService } from './booking-notifier.service';
|
||||
import {
|
||||
buildCappedWagonPlan,
|
||||
computeFleetAvailability,
|
||||
@@ -281,10 +282,38 @@ export class TrainSchedulingService {
|
||||
private readonly pdfDocuments: WarehouseReleaseDocumentService,
|
||||
private readonly bookingWindowGateway: BookingWindowGateway,
|
||||
private readonly bookingJourneyService: BookingJourneyService,
|
||||
private readonly bookingNotifier: BookingNotifierService,
|
||||
@Optional() private readonly milestoneService?: ClearanceMilestoneService,
|
||||
private readonly configService?: ConfigService,
|
||||
) {}
|
||||
|
||||
/**
|
||||
* Notify each booking's customer that their shipment was dispatched / arrived,
|
||||
* with a deep-link to the booking. Fire-and-forget — never blocks the action.
|
||||
*/
|
||||
private async notifyScheduleBookings(
|
||||
schedule: TrainSchedule,
|
||||
event: 'dispatched' | 'arrived',
|
||||
): Promise<void> {
|
||||
try {
|
||||
const ids = (schedule.scheduleBookings ?? []).map((sb) => sb.bookingId).filter(Boolean);
|
||||
if (!ids.length) return;
|
||||
const origin = schedule.originStation?.label ?? schedule.originStation?.code ?? null;
|
||||
const destination =
|
||||
schedule.destinationStation?.label ?? schedule.destinationStation?.code ?? null;
|
||||
const bookings = await this.dataSource.getRepository(Booking).find({
|
||||
where: { id: In(ids) },
|
||||
relations: { company: true },
|
||||
});
|
||||
for (const b of bookings) {
|
||||
if (event === 'dispatched') this.bookingNotifier.dispatched(b, origin, destination);
|
||||
else this.bookingNotifier.arrived(b, origin, destination);
|
||||
}
|
||||
} catch (err) {
|
||||
this.logger.warn(`Failed to notify schedule bookings (${event}): ${(err as Error).message}`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Complete customer-tracking clearance milestones for every booking on a
|
||||
* schedule when a physical lifecycle event fires (dispatch, arrive, load,
|
||||
@@ -1545,6 +1574,7 @@ export class TrainSchedulingService {
|
||||
{ originYardId: schedule.originStationId },
|
||||
);
|
||||
}
|
||||
void this.notifyScheduleBookings(schedule, 'dispatched');
|
||||
return this.getTrainScheduleById(scheduleId);
|
||||
}
|
||||
|
||||
@@ -2550,6 +2580,7 @@ export class TrainSchedulingService {
|
||||
{ destinationYardId: schedule.destinationStationId },
|
||||
);
|
||||
}
|
||||
void this.notifyScheduleBookings(schedule, 'arrived');
|
||||
|
||||
const detail = await this.getTrainScheduleById(scheduleId);
|
||||
const warehouseAutomation = await this.runWarehouseArrivalAutomation(scheduleId);
|
||||
|
||||
Reference in New Issue
Block a user