add per-container handling options for hazardous, reefer, and return services

- Introduced new boolean fields (isHazardous, isReefer, isReturn) in UnitDraft and related interfaces to allow individual container handling options.
- Updated emptyUnit function to initialize these new fields.
- Modified GlCreateBookingForm to handle and display these options for each container.
- Adjusted calculations for hazardous, reefer, and return quantities based on the new handling options.
- Updated the schema for container units and booking container lines to include handling options.
- Added migration to support the new return flag in the database.
- Enhanced various components to reflect gross weight calculations, ensuring consistency across the application.
This commit is contained in:
Marshal
2026-07-18 19:20:45 +00:00
parent a7041ee70f
commit 0dead281ce
28 changed files with 585 additions and 250 deletions

View File

@@ -0,0 +1,28 @@
import { deriveRateType } from './rate-type.util';
describe('deriveRateType — surcharge triggers', () => {
// Every surcharge trigger must land on its own rateType. A trigger with no
// mapping falls through to the base-freight branch and is silently stored as
// CANCELLATION_FEE, which both mislabels the booking's rate snapshot and
// hides the rate from contract pricing (which looks rateTypes up by name).
it.each([
['HAZARDOUS', 'HAZARD_SURCHARGE'],
['REEFER', 'REEFER_SURCHARGE'],
['WITH_RETURN', 'RETURN_SURCHARGE'],
['OVERWEIGHT', 'OVERWEIGHT_PER_TON'],
['SHIPPING_LINE', 'DOUBLE_HANDLING'],
['CONSOLIDATION', 'LASHING'],
['CANCELLATION', 'CANCELLATION_FEE'],
['DEMURRAGE', 'DEMURRAGE'],
['PIL_EXTRA_FEE', 'PIL_EXTRA_FEE'],
['CUSTOMS_CLEARANCE', 'CUSTOMS_CLEARANCE'],
] as const)('maps trigger %s to %s', (trigger, expected) => {
expect(deriveRateType({ appliesTo: 'OTHER', trigger })).toBe(expected);
});
it('does not fall back to CANCELLATION_FEE for the empty-return service', () => {
expect(deriveRateType({ appliesTo: 'OTHER', trigger: 'WITH_RETURN' })).not.toBe(
'CANCELLATION_FEE',
);
});
});

View File

@@ -25,6 +25,12 @@ export function deriveRateType(input: {
return 'HAZARD_SURCHARGE';
case 'REEFER':
return 'REEFER_SURCHARGE';
// Empty-container return service. Contract pricing looks this rateType up
// by name, so without the mapping a WITH_RETURN rate fell through to the
// base-freight branch and was stored as CANCELLATION_FEE — invisible to
// the contract, and mislabelled on the booking's snapshot.
case 'WITH_RETURN':
return 'RETURN_SURCHARGE';
case 'OVERWEIGHT':
return 'OVERWEIGHT_PER_TON';
case 'SHIPPING_LINE':