fix issue and add consolidation

This commit is contained in:
Marshal
2026-08-21 23:16:06 +00:00
parent a339ea620e
commit 09deecd04c
21 changed files with 1464 additions and 264 deletions

View File

@@ -14,6 +14,7 @@ import {
sumWagonsRequired,
validate20ftContainerRules,
validateContainerPlacements,
validateWagonCargoExclusivity,
} from './wagon-plan.util';
const nw5: WagonType = {
@@ -222,6 +223,85 @@ describe('wagon-plan.util', () => {
expect(plan[0]?.slotLoadType).toBe('BULK');
expect(buildBulkWagonPlan([bulkBooking], cw3)).toHaveLength(1);
});
it('never pools two bulk bookings on one wagon', () => {
// 5T + 40T both fit a single 60T CW3 by tonnage — but a wagon with bulk
// takes that one load only, so each booking gets its own wagon.
const small = {
id: 'bulk-5',
reference: 'bulk-5',
freightType: 'BULK',
cargoTotalWeightVgm: 5,
bookingContainers: [],
} as unknown as Booking;
const other = {
id: 'bulk-40',
reference: 'bulk-40',
freightType: 'BULK',
cargoTotalWeightVgm: 40,
bookingContainers: [],
} as unknown as Booking;
const plan = buildBulkWagonPlan([small, other], cw3);
expect(plan).toHaveLength(2);
for (const slot of plan) {
expect(slot.allocations).toHaveLength(1);
}
expect(plan[0]?.allocations[0]?.bookingId).toBe('bulk-5');
expect(plan[1]?.allocations[0]?.bookingId).toBe('bulk-40');
expect(validateWagonCargoExclusivity(plan)).toEqual([]);
});
it('a multi-wagon bulk booking still spreads over its own wagons', () => {
const big = {
id: 'bulk-130',
reference: 'bulk-130',
freightType: 'BULK',
cargoTotalWeightVgm: 130,
bookingContainers: [],
} as unknown as Booking;
const plan = buildBulkWagonPlan([big], cw3);
expect(plan).toHaveLength(3);
expect(plan.map((s) => s.allocations[0]?.allocatedWeightTons)).toEqual([60, 60, 10]);
});
it('flags a wagon mixing bulk with anything else', () => {
const bulkAlloc = {
bookingId: 'b',
bookingReference: 'b',
allocatedWeightTons: 5,
loadType: AllocationLoadType.Bulk,
};
const containerAlloc = {
bookingId: 'c',
bookingReference: 'c',
allocatedWeightTons: 25,
loadType: AllocationLoadType.Container,
};
const slot = (allocations: (typeof bulkAlloc)[]) => ({
sequenceNo: 1,
wagonTypeId: cw3.id,
wagonTypeCode: cw3.code,
capacityTons: 60,
lengthMeters: 14,
tareWeightTons: 24,
assignedWeightTons: 0,
allocations,
});
// bulk + container on one wagon
expect(validateWagonCargoExclusivity([slot([bulkAlloc, containerAlloc])]))
.toHaveLength(1);
// bulk + bulk on one wagon
expect(
validateWagonCargoExclusivity([slot([bulkAlloc, { ...bulkAlloc, bookingId: 'b2' }])]),
).toHaveLength(1);
// bulk alone, and containers sharing, are fine
expect(validateWagonCargoExclusivity([slot([bulkAlloc])])).toEqual([]);
expect(
validateWagonCargoExclusivity([
slot([containerAlloc, { ...containerAlloc, bookingId: 'c2' }]),
]),
).toEqual([]);
});
});
describe('containerWagonsForLines — TEU-aware, ceil booking total once', () => {