test batch system

This commit is contained in:
Marshal
2026-07-09 17:04:25 +00:00
parent 1690f9e498
commit a7d05fba34
9 changed files with 413 additions and 111 deletions

View File

@@ -752,12 +752,18 @@ describe('BookingBatchService — wagonsFor', () => {
null as never,
) as unknown as {
wagonsFor(booking: unknown, dims: unknown): number;
needFor(booking: unknown, dims: unknown): {
wagons: number;
weightTons: number;
lengthMeters: number;
};
};
// PW2 box wagon: 70T rated payload, 25.2T tare, 17.066m.
const dims = {
container: { lengthMeters: 13.966, tareWeightTons: 22.4, capacityTons: 70 },
bulk: { lengthMeters: 17.066, tareWeightTons: 25.2, capacityTons: 70 },
byWagonTypeId: new Map(),
};
const bulk = (cargoTons: number, over: Record<string, unknown> = {}) => ({
@@ -815,4 +821,49 @@ describe('BookingBatchService — wagonsFor', () => {
};
expect(service.wagonsFor(booking, dims)).toBe(2);
});
describe('per-booking wagon type (cargo/container type FK)', () => {
// The booking's cargo type rides PW2 (25.2T tare / 70T), but the
// representative bulk fallback is a CW3-ish 23.4T tare. Measuring the
// booking on the fallback under-charged its gross (2100 + 30 × 23.4 =
// 2802 instead of 2856), so the fill loop admitted sets that allocation's
// real-consist check later rejected — after the customer had paid.
const dimsWithTypes = {
container: { lengthMeters: 13.966, tareWeightTons: 22.4, capacityTons: 70 },
bulk: { lengthMeters: 17.066, tareWeightTons: 23.4, capacityTons: 70 },
byWagonTypeId: new Map([
['pw2-id', { lengthMeters: 17.066, tareWeightTons: 25.2, capacityTons: 70 }],
]),
};
it('charges a bulk booking the tare of ITS wagon type, not the representative', () => {
const booking = bulk(2100, { cargoType: { wagonTypeId: 'pw2-id' } });
const need = service.needFor(booking, dimsWithTypes);
expect(need.wagons).toBe(30);
expect(need.weightTons).toBe(2856); // 2100 + 30 × 25.2 — matches allocation
});
it('falls back to the representative dims when no wagon type is configured', () => {
const need = service.needFor(bulk(2100), dimsWithTypes);
expect(need.weightTons).toBe(2802); // 2100 + 30 × 23.4 (legacy behavior)
});
it('resolves a container booking through its container type', () => {
const booking = {
freightType: 'CONTAINER',
cargoTotalWeightVgm: 140,
bookingContainers: [
{
quantity: 2,
wagonsRequired: 2,
containerType: { wagonsPerUnit: 1, sizeFt: 40, wagonTypeId: 'pw2-id' },
},
],
};
const need = service.needFor(booking, dimsWithTypes);
expect(need.wagons).toBe(2);
expect(need.weightTons).toBe(190.4); // 140 + 2 × 25.2
expect(need.lengthMeters).toBeCloseTo(34.132, 3); // 2 × 17.066, not NW5's 13.966
});
});
});