mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-09-08 04:15:43 +00:00
Add tareWeightTons property to CreateWagonTypeDto and update related components
This commit is contained in:
@@ -31,6 +31,7 @@ describe('BookingBatchService — PAID reconcile', () => {
|
||||
createMany: jest.Mock;
|
||||
};
|
||||
let trainSchedulesRepository: {
|
||||
findById: jest.Mock;
|
||||
findByIdWithFullGraph: jest.Mock;
|
||||
findAll: jest.Mock;
|
||||
};
|
||||
@@ -65,6 +66,11 @@ describe('BookingBatchService — PAID reconcile', () => {
|
||||
createMany: jest.fn().mockResolvedValue(undefined),
|
||||
};
|
||||
trainSchedulesRepository = {
|
||||
findById: jest.fn().mockResolvedValue({
|
||||
id: scheduleId,
|
||||
bookingWindowStatus: 'OPEN',
|
||||
windowPhase: null,
|
||||
}),
|
||||
findByIdWithFullGraph: jest.fn().mockResolvedValue({
|
||||
id: scheduleId,
|
||||
maxWagons: 10,
|
||||
@@ -407,6 +413,49 @@ describe('BookingBatchService — PAID reconcile', () => {
|
||||
// Never reserved — waits for its partner in a later cycle.
|
||||
expect(notifier.payNow).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('clears a stale FULL flag and fills a train whose bookings all expired', async () => {
|
||||
// The deadlock: train A filled once, every booking then expired, but
|
||||
// bookingWindowStatus stayed FULL. isFillable() rejects FULL before it ever
|
||||
// reads the budget, so the batch skipped the train forever — it just cycled
|
||||
// PRE_WINDOW→DOC_REVIEW→PAYMENT with an empty consist, and only the odd
|
||||
// already-pinned booking got settled, one per cycle.
|
||||
const staleFull = {
|
||||
id: trainA,
|
||||
maxWagons: 1,
|
||||
bookingWindowStatus: 'FULL',
|
||||
// The batch runs while the customer window is closed.
|
||||
windowPhase: 'PAYMENT',
|
||||
direction: 'IMPORT',
|
||||
trainSetId: `set-${trainA}`,
|
||||
trainSet: { locomotive: smallLoco },
|
||||
scheduleBookings: [],
|
||||
scheduledDepartureDate: new Date('2026-06-20T06:00:00.000Z'),
|
||||
originStationId: originYardId,
|
||||
destinationStationId: destinationYardId,
|
||||
};
|
||||
trainSchedulesRepository.findAll.mockResolvedValue([{ ...staleFull }]);
|
||||
// Live capacity says the train is empty: 1 free wagon, nothing allocated.
|
||||
trainSchedulesRepository.findByIdWithFullGraph.mockResolvedValue(staleFull);
|
||||
// refreshWindowStatus writes CLOSED (mid-PAYMENT, not a customer-open phase);
|
||||
// the re-read reports it, and isFillable() admits CLOSED during PAYMENT.
|
||||
trainSchedulesRepository.findById.mockResolvedValue({
|
||||
id: trainA,
|
||||
bookingWindowStatus: 'CLOSED',
|
||||
windowPhase: 'PAYMENT',
|
||||
});
|
||||
bookingsRepository.findBatchPoolByCorridorDay.mockResolvedValue([
|
||||
commercial('waiting', 30),
|
||||
]);
|
||||
|
||||
const touched = await service.fillRouteDay(originYardId, destinationYardId, day);
|
||||
|
||||
// The train was reopened to the batch and actually filled, not skipped.
|
||||
expect(touched).toEqual([trainA]);
|
||||
expect(notifier.payNow).toHaveBeenCalledTimes(1);
|
||||
expect((notifier.payNow.mock.calls[0][0] as Booking).id).toBe('waiting');
|
||||
expect(notifier.unplaced).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('expireUnacceptedForRouteDay — doc-review sweep', () => {
|
||||
|
||||
Reference in New Issue
Block a user