fix issue

This commit is contained in:
Marshal
2026-08-22 01:23:50 +00:00
parent b6c1efa043
commit 1ab2cfdb3b
13 changed files with 874 additions and 109 deletions

View File

@@ -86,6 +86,40 @@ describe('BookingBatchService.smartBulkNeed', () => {
expect(call(booking(695), stock, contested)).toBeNull();
});
it('S-2026-00020 shape: 42x40ft eat the NW5, 200T bulk still seats on the 10 coupled PW2', () => {
// The staging complaint: a built train of 42 NW5 + 10 PW2, containers
// hold every NW5, and a bulk booking sits in "Ready for batch" while the
// PW2 ride empty. The chain: committed containers drain NW5 from the
// ledger (their types cannot touch PW2), then the smart gate must seat
// 200T of Perishable on the 10 PW2 at the 20T cap.
const stock = new WagonStockLedger(
new Map([
[nw5.id, 42],
[pw2.id, 10],
]),
2, // DCT -> Dire -> GMP: two edges
);
// Committed container booking rides Dire->GMP (edge 1) on 42 NW5 —
// container-capable types only, exactly how stockLedgerFor debits it.
stock.consume([nw5.id], 42, { fromEdge: 1, toEdge: 2 });
expect(stock.availableFor([nw5.id], { fromEdge: 0, toEdge: 2 })).toBe(0);
expect(stock.availableFor([pw2.id], { fromEdge: 0, toEdge: 2 })).toBe(10);
const smart = (
service as unknown as {
smartBulkNeed: (
b: Booking,
d: unknown,
s: WagonStockLedger,
l: { fromEdge: number; toEdge: number },
r: Map<string, number>,
) => { need: { wagons: number }; perType: Array<{ wagonTypeId: string; wagons: number }> } | null;
}
).smartBulkNeed(booking(200), wagonDims, stock, { fromEdge: 0, toEdge: 2 }, contested);
expect(smart).not.toBeNull();
expect(smart!.perType).toEqual([{ wagonTypeId: pw2.id, wagons: 10 }]);
});
it('uncontested types fall back to biggest per-cargo take (fewest wagons)', () => {
const stock = new WagonStockLedger(
new Map([