mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-29 15:18:11 +00:00
add lashing surcharge for cargo types with hasLashing flag
add lashing surcharge for cargo types with hasLashing flag
This commit is contained in:
@@ -137,4 +137,109 @@ describe('BookingBatchService — exportSpaceReport (whole-booking, single train
|
||||
'No export train is accepting bookings for this day',
|
||||
);
|
||||
});
|
||||
|
||||
describe('dayImportAvailability (advisory, summed across the day)', () => {
|
||||
const DAY_STR = '2026-07-20';
|
||||
|
||||
const importSchedule = (id: string, over: Record<string, unknown> = {}) => ({
|
||||
id,
|
||||
status: 'SCHEDULED',
|
||||
direction: 'IMPORT',
|
||||
scheduledDepartureDate: DAY,
|
||||
bookingWindowStatus: 'OPEN',
|
||||
windowPhase: 'OPEN', // still OPEN — the advisory ignores the fill phase
|
||||
...over,
|
||||
});
|
||||
|
||||
// A bulk booking small enough to fit; freeWagons is what matters, not `fits`.
|
||||
const importBooking = (cargoTons: number) =>
|
||||
({
|
||||
id: 'bk-imp',
|
||||
freightType: 'BULK',
|
||||
tradeDirection: 'IMPORT',
|
||||
originYardId: 'yard-a',
|
||||
destinationYardId: 'yard-b',
|
||||
cargoTotalWeightVgm: cargoTons,
|
||||
bookingContainers: [],
|
||||
}) as unknown as Booking;
|
||||
|
||||
it('sums free wagons across every import train on the day', async () => {
|
||||
trainSchedulesRepository.findAll.mockResolvedValue([
|
||||
importSchedule('train-1'),
|
||||
importSchedule('train-2'),
|
||||
]);
|
||||
|
||||
const one = await service.dayImportAvailability(
|
||||
importBooking(60),
|
||||
DAY_STR,
|
||||
);
|
||||
// Re-run with a single train to prove two trains sum to double one train.
|
||||
trainSchedulesRepository.findAll.mockResolvedValue([
|
||||
importSchedule('train-1'),
|
||||
]);
|
||||
const solo = await service.dayImportAvailability(
|
||||
importBooking(60),
|
||||
DAY_STR,
|
||||
);
|
||||
|
||||
expect(solo.freeWagons).toBeGreaterThan(0);
|
||||
expect(one.freeWagons).toBe(solo.freeWagons * 2);
|
||||
expect(one.trainsForDay).toBe(true);
|
||||
});
|
||||
|
||||
it('ignores EXPORT trains — they are not part of the import pool', async () => {
|
||||
trainSchedulesRepository.findAll.mockResolvedValue([
|
||||
importSchedule('train-1'),
|
||||
{ ...importSchedule('train-2'), direction: 'EXPORT' },
|
||||
]);
|
||||
|
||||
const both = await service.dayImportAvailability(
|
||||
importBooking(60),
|
||||
DAY_STR,
|
||||
);
|
||||
trainSchedulesRepository.findAll.mockResolvedValue([
|
||||
importSchedule('train-1'),
|
||||
]);
|
||||
const solo = await service.dayImportAvailability(
|
||||
importBooking(60),
|
||||
DAY_STR,
|
||||
);
|
||||
|
||||
expect(both.freeWagons).toBe(solo.freeWagons);
|
||||
});
|
||||
|
||||
it('ignores FULL trains', async () => {
|
||||
trainSchedulesRepository.findAll.mockResolvedValue([
|
||||
importSchedule('train-1', { bookingWindowStatus: 'FULL' }),
|
||||
]);
|
||||
|
||||
const report = await service.dayImportAvailability(
|
||||
importBooking(60),
|
||||
DAY_STR,
|
||||
);
|
||||
|
||||
expect(report.freeWagons).toBe(0);
|
||||
expect(report.trainsForDay).toBe(false);
|
||||
});
|
||||
|
||||
it('nets out capacity already held by reserved bookings', async () => {
|
||||
trainSchedulesRepository.findAll.mockResolvedValue([
|
||||
importSchedule('train-1'),
|
||||
]);
|
||||
const empty = await service.dayImportAvailability(
|
||||
importBooking(60),
|
||||
DAY_STR,
|
||||
);
|
||||
|
||||
bookingsRepository.findReservedForSchedule.mockResolvedValue([
|
||||
heavyReserved,
|
||||
]);
|
||||
const withHold = await service.dayImportAvailability(
|
||||
importBooking(60),
|
||||
DAY_STR,
|
||||
);
|
||||
|
||||
expect(withHold.freeWagons).toBeLessThan(empty.freeWagons);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user