mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-30 01:48:12 +00:00
implement contract cancellation feature and update contract statuses
- Added functionality to cancel contracts, allowing users to provide a reason for cancellation. - Updated contract statuses to include SUSPENDED and changed CLOSED to COMPLETED. - Enhanced the UI to reflect the new cancellation option and updated messaging for contract statuses. - Refactored contract booking actions to accommodate changes in booking logic for ONE_TIME and GENERAL contracts. - Removed clearance document management from the contract detail page, as it is now handled per booking. - Introduced a SQL script to reset bookings and train schedules for development purposes.
This commit is contained in:
@@ -5,7 +5,7 @@ import {
|
||||
consistViolations,
|
||||
deriveTrainCapacityFromLocomotive,
|
||||
grossWagonWeightTons,
|
||||
minLocomotiveLimits,
|
||||
combinedLocomotiveLimits,
|
||||
sizePartialOfferWagons,
|
||||
trainSetLocomotiveLimits,
|
||||
} from './train-capacity.util';
|
||||
@@ -197,42 +197,75 @@ describe('train-capacity.util', () => {
|
||||
expect(bookingTrainLengthMeters('BULK', 3, { container: 14, bulk: 18 })).toBe(54);
|
||||
});
|
||||
|
||||
it('takes the weakest locomotive across a multi-locomotive set', () => {
|
||||
const limits = minLocomotiveLimits([
|
||||
{ maxPullWeightTons: 3500, maxTrainLengthMeters: 760, overageToleranceTons: 90 },
|
||||
{ maxPullWeightTons: 4000, maxTrainLengthMeters: 760, overageToleranceTons: 20 },
|
||||
it('SUMS pull weight and weight tolerance across a multi-locomotive set', () => {
|
||||
// Two units haul together: 1750 + 1750 = 3500T base, 90 + 90 = 180T overage.
|
||||
const limits = combinedLocomotiveLimits([
|
||||
{ maxPullWeightTons: 1750, maxTrainLengthMeters: 760, overageToleranceTons: 90 },
|
||||
{ maxPullWeightTons: 1750, maxTrainLengthMeters: 760, overageToleranceTons: 90 },
|
||||
]);
|
||||
expect(limits?.maxPullWeightTons).toBe(3500);
|
||||
expect(limits?.overageToleranceTons).toBe(20);
|
||||
expect(limits?.overageToleranceTons).toBe(180);
|
||||
// A single locomotive is just its own limit — no doubling, no halving.
|
||||
expect(
|
||||
combinedLocomotiveLimits([
|
||||
{ maxPullWeightTons: 1750, maxTrainLengthMeters: 760, overageToleranceTons: 90 },
|
||||
])?.maxPullWeightTons,
|
||||
).toBe(1750);
|
||||
});
|
||||
|
||||
it('takes the MINIMUM train length — a second locomotive does not lengthen the siding', () => {
|
||||
const limits = combinedLocomotiveLimits([
|
||||
{ maxPullWeightTons: 1750, maxTrainLengthMeters: 760, overageToleranceMeters: 20 },
|
||||
{ maxPullWeightTons: 1750, maxTrainLengthMeters: 700, overageToleranceMeters: 5 },
|
||||
]);
|
||||
expect(limits?.maxTrainLengthMeters).toBe(700);
|
||||
expect(limits?.overageToleranceMeters).toBe(5);
|
||||
});
|
||||
|
||||
it('ignores unconfigured (null) tolerances instead of zeroing the set (S-2026-00024)', () => {
|
||||
// LOCO-019 had 90T tolerance, LOCO-020 had none configured: the set must
|
||||
// keep the 90, not collapse to 0 and reject 3547.6T on a 3500T train.
|
||||
const limits = minLocomotiveLimits([
|
||||
{ maxPullWeightTons: 3500, maxTrainLengthMeters: 760, overageToleranceTons: 90 },
|
||||
{ maxPullWeightTons: 3500, maxTrainLengthMeters: 760, overageToleranceTons: null },
|
||||
// keep the 90 rather than collapse to 0 — an unset value abstains.
|
||||
const limits = combinedLocomotiveLimits([
|
||||
{ maxPullWeightTons: 1750, maxTrainLengthMeters: 760, overageToleranceTons: 90 },
|
||||
{ maxPullWeightTons: 1750, maxTrainLengthMeters: 760, overageToleranceTons: null },
|
||||
]);
|
||||
expect(limits?.overageToleranceTons).toBe(90);
|
||||
// All unconfigured → no tolerance.
|
||||
const none = minLocomotiveLimits([
|
||||
const none = combinedLocomotiveLimits([
|
||||
{ maxPullWeightTons: 3500, maxTrainLengthMeters: 760 },
|
||||
]);
|
||||
expect(none?.overageToleranceTons).toBe(0);
|
||||
});
|
||||
|
||||
it('reports no pull limit when NO locomotive has one configured', () => {
|
||||
// Summing must not turn "unset" into 0 and strand every booking; an
|
||||
// all-unset set keeps the old "no opinion" behaviour.
|
||||
const limits = combinedLocomotiveLimits([
|
||||
{ maxPullWeightTons: 0, maxTrainLengthMeters: 760 },
|
||||
{ maxPullWeightTons: 0, maxTrainLengthMeters: 760 },
|
||||
]);
|
||||
expect(limits?.maxPullWeightTons).toBe(Infinity);
|
||||
// One configured, one not → only the configured one contributes.
|
||||
expect(
|
||||
combinedLocomotiveLimits([
|
||||
{ maxPullWeightTons: 1750, maxTrainLengthMeters: 760 },
|
||||
{ maxPullWeightTons: 0, maxTrainLengthMeters: 760 },
|
||||
])?.maxPullWeightTons,
|
||||
).toBe(1750);
|
||||
});
|
||||
|
||||
it('trainSetLocomotiveLimits prefers link rows and falls back to the legacy single loco', () => {
|
||||
const l1 = { maxPullWeightTons: 3500, maxTrainLengthMeters: 760, overageToleranceTons: 90 };
|
||||
const l2 = { maxPullWeightTons: 3600, maxTrainLengthMeters: 700, overageToleranceTons: null };
|
||||
const l1 = { maxPullWeightTons: 1750, maxTrainLengthMeters: 760, overageToleranceTons: 90 };
|
||||
const l2 = { maxPullWeightTons: 1800, maxTrainLengthMeters: 700, overageToleranceTons: null };
|
||||
expect(
|
||||
trainSetLocomotiveLimits({ locomotive: null, locomotives: [{ locomotive: l1 }, { locomotive: l2 }] }),
|
||||
).toEqual({
|
||||
maxPullWeightTons: 3500,
|
||||
maxPullWeightTons: 3550,
|
||||
maxTrainLengthMeters: 700,
|
||||
overageToleranceTons: 90,
|
||||
overageToleranceMeters: 0,
|
||||
});
|
||||
expect(trainSetLocomotiveLimits({ locomotive: l1 })?.maxPullWeightTons).toBe(3500);
|
||||
expect(trainSetLocomotiveLimits({ locomotive: l1 })?.maxPullWeightTons).toBe(1750);
|
||||
expect(trainSetLocomotiveLimits(null)).toBeNull();
|
||||
expect(trainSetLocomotiveLimits({ locomotive: null, locomotives: [] })).toBeNull();
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user