mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-30 02:58:11 +00:00
fix schule issue and contianer type issue
This commit is contained in:
@@ -887,7 +887,7 @@ describe('BookingBatchService — wagonsFor', () => {
|
||||
freightType: 'CONTAINER',
|
||||
cargoTotalWeightVgm: 210,
|
||||
bookingContainers: [
|
||||
{ quantity: 2, wagonsRequired: 2, containerType: { wagonsPerUnit: 1, sizeFt: 40 } },
|
||||
{ quantity: 2, wagonsRequired: 2, containerType: { sizeFt: 40 } },
|
||||
],
|
||||
};
|
||||
expect(service.wagonsFor(booking, dims)).toBe(3);
|
||||
@@ -899,7 +899,7 @@ describe('BookingBatchService — wagonsFor', () => {
|
||||
freightType: 'CONTAINER',
|
||||
cargoTotalWeightVgm: 40,
|
||||
bookingContainers: [
|
||||
{ quantity: 4, wagonsRequired: 2, containerType: { wagonsPerUnit: 0.5, sizeFt: 20 } },
|
||||
{ quantity: 4, wagonsRequired: 2, containerType: { sizeFt: 20 } },
|
||||
],
|
||||
};
|
||||
expect(service.wagonsFor(booking, dims)).toBe(2);
|
||||
@@ -939,7 +939,7 @@ describe('BookingBatchService — wagonsFor', () => {
|
||||
{
|
||||
quantity: 2,
|
||||
wagonsRequired: 2,
|
||||
containerType: { wagonsPerUnit: 1, sizeFt: 40, wagonTypes: [{ id: 'pw2-id' }] },
|
||||
containerType: { sizeFt: 40, wagonTypes: [{ id: 'pw2-id' }] },
|
||||
},
|
||||
],
|
||||
};
|
||||
@@ -950,3 +950,106 @@ describe('BookingBatchService — wagonsFor', () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('BookingBatchService — built-train wagon capacity', () => {
|
||||
// A schedule created from a built train is capped by its PHYSICAL consist:
|
||||
// wagon count only. The locomotive here is deliberately tiny (1T / 1m) — the
|
||||
// old weight/length math would call every one of these trains FULL, so any
|
||||
// assertion below that says "not full" proves those axes are ignored.
|
||||
const scheduleId = 'schedule-built';
|
||||
|
||||
const reservedBooking = (id: string) =>
|
||||
({
|
||||
id,
|
||||
freightType: 'BULK',
|
||||
cargoTotalWeightVgm: 50, // 1 wagon at the 60T default bulk payload
|
||||
bookingContainers: [],
|
||||
originYardId: 'yard-a',
|
||||
destinationYardId: 'yard-b',
|
||||
}) as unknown as Booking;
|
||||
|
||||
const buildService = (opts: {
|
||||
physicalWagons: number;
|
||||
reserved: Booking[];
|
||||
maxWagons?: number;
|
||||
}) => {
|
||||
const schedule = {
|
||||
id: scheduleId,
|
||||
maxWagons: opts.maxWagons ?? 44, // stale locomotive-derived cap on purpose
|
||||
bookingWindowStatus: 'OPEN',
|
||||
originStationId: 'yard-a',
|
||||
destinationStationId: 'yard-b',
|
||||
routeId: null,
|
||||
scheduleBookings: [],
|
||||
trainSet: {
|
||||
locomotive: {
|
||||
maxPullWeightTons: 1,
|
||||
maxTrainLengthMeters: 1,
|
||||
overageToleranceTons: 0,
|
||||
overageToleranceMeters: 0,
|
||||
},
|
||||
train: { id: 'train-built-1' },
|
||||
},
|
||||
};
|
||||
const wagonRepo = { count: jest.fn().mockResolvedValue(opts.physicalWagons) };
|
||||
const genericRepo = {
|
||||
find: jest.fn().mockResolvedValue([]),
|
||||
update: jest.fn().mockResolvedValue(undefined),
|
||||
};
|
||||
const dataSource = {
|
||||
getRepository: jest.fn((entity: { name?: string }) =>
|
||||
entity?.name === 'Wagon' ? wagonRepo : genericRepo,
|
||||
),
|
||||
transaction: jest.fn(),
|
||||
};
|
||||
const service = new BookingBatchService(
|
||||
dataSource as never,
|
||||
{
|
||||
findReservedForSchedule: jest.fn().mockResolvedValue(opts.reserved),
|
||||
} as never,
|
||||
{
|
||||
findByIdWithFullGraph: jest.fn().mockResolvedValue(schedule),
|
||||
findById: jest.fn().mockResolvedValue(schedule),
|
||||
} as never,
|
||||
null as never,
|
||||
null as never,
|
||||
null as never,
|
||||
null as never,
|
||||
null as never,
|
||||
{ emitPhase: jest.fn() } as never,
|
||||
null as never,
|
||||
);
|
||||
return { service, wagonRepo };
|
||||
};
|
||||
|
||||
it('is FULL when bookings hold every physical wagon, even with loco-derived slots free', async () => {
|
||||
const { service } = buildService({
|
||||
physicalWagons: 2,
|
||||
reserved: [reservedBooking('b1'), reservedBooking('b2')],
|
||||
maxWagons: 44, // stale: the old slot cap would say 42 slots remain
|
||||
});
|
||||
await expect(service.isScheduleFull(scheduleId)).resolves.toBe(true);
|
||||
});
|
||||
|
||||
it('is NOT full while physical wagons remain, ignoring weight/length limits', async () => {
|
||||
const { service } = buildService({
|
||||
physicalWagons: 3,
|
||||
reserved: [reservedBooking('b1'), reservedBooking('b2')],
|
||||
});
|
||||
// 1T pull cap would have been exhausted long ago under the old math.
|
||||
await expect(service.isScheduleFull(scheduleId)).resolves.toBe(false);
|
||||
});
|
||||
|
||||
it('reports over-allocation when the consist is trimmed below committed bookings', async () => {
|
||||
const { service } = buildService({
|
||||
physicalWagons: 1,
|
||||
reserved: [reservedBooking('b1'), reservedBooking('b2')],
|
||||
});
|
||||
await expect(service.scheduleWagonUsage(scheduleId)).resolves.toEqual({
|
||||
maxWagons: 1,
|
||||
allocatedWagons: 2,
|
||||
remainingSlots: 0,
|
||||
overAllocatedBy: 1,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user