fix issue -> consolidation

This commit is contained in:
Marshal
2026-08-24 12:24:23 +00:00
parent 979f024869
commit 2a107e8ba3
20 changed files with 475 additions and 39 deletions

View File

@@ -195,6 +195,20 @@ describe('BookingBatchService — PAID reconcile', () => {
expect(trainSchedulingService.tryAutoWagonAllocation).toHaveBeenCalledTimes(2);
});
it('ensurePaidBookingAllocated never resurrects a CANCELLED booking that is still paymentStatus PAID', async () => {
dataSource.getRepository().findOne.mockResolvedValue({
...paidBooking,
status: 'CANCELLED',
trainScheduleId: null,
} as unknown as Booking);
await service.ensurePaidBookingAllocated(bookingId);
expect(trainScheduleBookingsRepository.createMany).not.toHaveBeenCalled();
expect(trainSchedulingService.tryAutoWagonAllocation).not.toHaveBeenCalled();
expect(dataSource.getRepository().update).not.toHaveBeenCalled();
});
it('ensurePaidBookingAllocated holds a wagon-short booking out of the train', async () => {
trainSchedulingService.previewPaidBookingWagonShortage.mockResolvedValue({
wagonTypeCodes: 'NW6',

View File

@@ -571,6 +571,12 @@ export class BookingBatchService implements OnModuleInit {
relations: { company: true },
});
if (!booking) return;
// A dead booking keeps payment_status = 'PAID' (it was paid before it died),
// so every rescue path below would happily re-place and re-allocate it —
// that is how a cancelled consolidation-lapse booking came back onto its
// train 30s after being cancelled. Never resurrect a dead booking.
if (["CANCELLED", "EXPIRED", "REJECTED", "COMPLETED"].includes(booking.status))
return;
if (!booking.trainScheduleId) {
// A paid booking with no train is money taken and nothing boarding. The
// hold was expired before the payment landed (webhook lag beat the