This commit is contained in:
Marshal
2026-07-07 12:28:47 +00:00
parent 1c18fdbd52
commit f300600bfa
63 changed files with 2587 additions and 428 deletions

View File

@@ -21,6 +21,7 @@ describe('BookingBatchService — PAID reconcile', () => {
findPaidUnlinkedForSchedule: jest.Mock;
findBatchPool: jest.Mock;
findBatchPoolByRouteDay: jest.Mock;
findBatchPoolByCorridorDay: jest.Mock;
findReservedForSchedule: jest.Mock;
update: jest.Mock;
};
@@ -53,6 +54,7 @@ describe('BookingBatchService — PAID reconcile', () => {
findPaidUnlinkedForSchedule: jest.fn().mockResolvedValue([]),
findBatchPool: jest.fn().mockResolvedValue([]),
findBatchPoolByRouteDay: jest.fn().mockResolvedValue([]),
findBatchPoolByCorridorDay: jest.fn().mockResolvedValue([]),
findReservedForSchedule: jest.fn().mockResolvedValue([]),
update: jest.fn().mockResolvedValue(undefined),
};
@@ -196,6 +198,8 @@ describe('BookingBatchService — PAID reconcile', () => {
cargoTotalWeightVgm: 10,
freightType: 'CONTAINER',
bookingContainers: [],
originYardId,
destinationYardId,
}) as unknown as Booking;
beforeEach(() => {
@@ -227,13 +231,15 @@ describe('BookingBatchService — PAID reconcile', () => {
trainSetId: `set-${id}`,
trainSet: { locomotive: smallLoco },
scheduleBookings: [],
originStationId: originYardId,
destinationStationId: destinationYardId,
}),
);
});
it('spills overflow to the next train by priority, then reports unplaced', async () => {
// 3 commercial bookings, descending priority; only 1 fits per train (2 total).
bookingsRepository.findBatchPoolByRouteDay.mockResolvedValue([
bookingsRepository.findBatchPoolByCorridorDay.mockResolvedValue([
commercial('hi', 30),
commercial('mid', 20),
commercial('lo', 10),
@@ -241,9 +247,8 @@ describe('BookingBatchService — PAID reconcile', () => {
const touched = await service.fillRouteDay(originYardId, destinationYardId, day);
expect(bookingsRepository.findBatchPoolByRouteDay).toHaveBeenCalledWith(
originYardId,
destinationYardId,
expect(bookingsRepository.findBatchPoolByCorridorDay).toHaveBeenCalledWith(
[originYardId, destinationYardId],
day,
);
// Both trains were processed.
@@ -258,7 +263,7 @@ describe('BookingBatchService — PAID reconcile', () => {
});
it('reserves the chosen train id on each commercial booking', async () => {
bookingsRepository.findBatchPoolByRouteDay.mockResolvedValue([commercial('hi', 30)]);
bookingsRepository.findBatchPoolByCorridorDay.mockResolvedValue([commercial('hi', 30)]);
await service.fillRouteDay(originYardId, destinationYardId, day);
@@ -286,9 +291,11 @@ describe('BookingBatchService — PAID reconcile', () => {
freightType: 'CONTAINER',
consolidationPartnerId: partnerId,
bookingContainers: [{ quantity: 1 }],
originYardId,
destinationYardId,
}) as unknown as Booking;
bookingsRepository.findBatchPoolByRouteDay.mockResolvedValue([
bookingsRepository.findBatchPoolByCorridorDay.mockResolvedValue([
consol('a', 'b', 30),
consol('b', 'a', 20),
]);
@@ -313,9 +320,11 @@ describe('BookingBatchService — PAID reconcile', () => {
freightType: 'CONTAINER',
consolidationPartnerId: 'missing-partner',
bookingContainers: [{ quantity: 1 }],
originYardId,
destinationYardId,
} as unknown as Booking;
bookingsRepository.findBatchPoolByRouteDay.mockResolvedValue([lonely]);
bookingsRepository.findBatchPoolByCorridorDay.mockResolvedValue([lonely]);
await service.fillRouteDay(originYardId, destinationYardId, day);