mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-09-08 14:48:18 +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:
@@ -6,6 +6,8 @@ import {
|
||||
listConfigBookingWindows,
|
||||
groupBookingsIntoBoardWindows,
|
||||
computeImportWindowTimes,
|
||||
computeExportWindowTimes,
|
||||
bookingCloseCutoff,
|
||||
type BoardWindowConfig,
|
||||
} from './batch-window.util';
|
||||
|
||||
@@ -360,3 +362,101 @@ describe('computeImportWindowTimes — immediate open inside the window day', ()
|
||||
expect(t.windowOpensAt.getTime()).toBe(now.getTime());
|
||||
});
|
||||
});
|
||||
|
||||
// Booking-close offset: a configured offset pulls the window close earlier than
|
||||
// departure by that many minutes, separately for import and export.
|
||||
describe('bookingCloseCutoff — departure − offset', () => {
|
||||
const departure = new Date('2026-07-10T13:00:00.000Z'); // 16:00 EAT Jul 10
|
||||
|
||||
it('returns departure unchanged when no offset is set', () => {
|
||||
expect(bookingCloseCutoff(departure, 'IMPORT', {}).toISOString()).toBe(
|
||||
departure.toISOString(),
|
||||
);
|
||||
expect(
|
||||
bookingCloseCutoff(departure, 'EXPORT', {
|
||||
importCloseOffsetMinutes: 180,
|
||||
}).toISOString(),
|
||||
).toBe(departure.toISOString());
|
||||
});
|
||||
|
||||
it('a non-positive offset is treated as no offset', () => {
|
||||
expect(
|
||||
bookingCloseCutoff(departure, 'IMPORT', {
|
||||
importCloseOffsetMinutes: 0,
|
||||
}).toISOString(),
|
||||
).toBe(departure.toISOString());
|
||||
expect(
|
||||
bookingCloseCutoff(departure, 'IMPORT', {
|
||||
importCloseOffsetMinutes: -5,
|
||||
}).toISOString(),
|
||||
).toBe(departure.toISOString());
|
||||
});
|
||||
|
||||
it('import 3-hour offset: 16:00 EAT departure → cutoff 13:00 EAT (14:00 → 3h before)', () => {
|
||||
// Departure 16:00 EAT (13:00 UTC), 3h offset → 13:00 EAT = 10:00 UTC.
|
||||
const cutoff = bookingCloseCutoff(departure, 'IMPORT', {
|
||||
importCloseOffsetMinutes: 180,
|
||||
});
|
||||
expect(cutoff.toISOString()).toBe('2026-07-10T10:00:00.000Z');
|
||||
});
|
||||
|
||||
it('export 1-day offset: Jul-10 16:00 EAT departure → cutoff Jul-9 16:00 EAT', () => {
|
||||
const cutoff = bookingCloseCutoff(departure, 'EXPORT', {
|
||||
exportCloseOffsetMinutes: 1440,
|
||||
});
|
||||
// Jul 9 16:00 EAT = Jul 9 13:00 UTC.
|
||||
expect(cutoff.toISOString()).toBe('2026-07-09T13:00:00.000Z');
|
||||
});
|
||||
|
||||
it('import and export offsets are independent', () => {
|
||||
const cfg = {
|
||||
importCloseOffsetMinutes: 180,
|
||||
exportCloseOffsetMinutes: 1440,
|
||||
};
|
||||
expect(bookingCloseCutoff(departure, 'IMPORT', cfg).toISOString()).toBe(
|
||||
'2026-07-10T10:00:00.000Z',
|
||||
);
|
||||
expect(bookingCloseCutoff(departure, 'EXPORT', cfg).toISOString()).toBe(
|
||||
'2026-07-09T13:00:00.000Z',
|
||||
);
|
||||
// DOMESTIC uses the import offset.
|
||||
expect(bookingCloseCutoff(departure, 'DOMESTIC', cfg).toISOString()).toBe(
|
||||
'2026-07-10T10:00:00.000Z',
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('window-time computation honours the close offset', () => {
|
||||
it('export closes at departure − offset, not departure', () => {
|
||||
// Departs Jul 10 16:00 EAT (13:00 UTC), lead 24h, 24-hour desk, 1-day offset.
|
||||
const departure = new Date('2026-07-10T13:00:00.000Z');
|
||||
const { windowClosesAt } = computeExportWindowTimes(departure, {
|
||||
exportBookingLeadHours: 48,
|
||||
windowOpenHour: 8,
|
||||
windowCloseHour: 8, // 24-hour desk
|
||||
exportCloseOffsetMinutes: 1440,
|
||||
});
|
||||
// Jul 9 16:00 EAT = Jul 9 13:00 UTC.
|
||||
expect(windowClosesAt.toISOString()).toBe('2026-07-09T13:00:00.000Z');
|
||||
});
|
||||
|
||||
it('import close is capped at the cutoff (departure − offset)', () => {
|
||||
// Round-the-clock desk, opens 05 Jul 12:00 EAT, 24h duration would run to
|
||||
// 06 Jul 12:00; departure 06 Jul 08:00 EAT (05:00 UTC) with a 2-hour offset →
|
||||
// cutoff 06 Jul 06:00 EAT = 03:00 UTC.
|
||||
const departure = new Date('2026-07-06T05:00:00.000Z');
|
||||
const now = new Date('2026-07-05T09:00:00.000Z');
|
||||
const { windowClosesAt } = computeImportWindowTimes(
|
||||
departure,
|
||||
{
|
||||
importWindowLeadDays: 3,
|
||||
windowOpenHour: 8,
|
||||
windowCloseHour: 8, // 24-hour desk (no office-hour cap)
|
||||
windowDurationHours: 24,
|
||||
importCloseOffsetMinutes: 120,
|
||||
},
|
||||
now,
|
||||
);
|
||||
expect(windowClosesAt.toISOString()).toBe('2026-07-06T03:00:00.000Z');
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user