mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-29 22:18:12 +00:00
add items per wagon map to cargo types and sync bulk rate units
- Implemented in the to manage the physical item capacity for each wagon type. - Added a new migration to create the column in the table. - Introduced method in to update rate units when cargo type unit of measure changes. - Updated booking calculations to consider items per wagon for break-bulk cargo. - Refactored various components to utilize the new items fit logic and ensure consistent date formatting across the application. - Added tests for the new display timezone functionality to ensure consistent date/time representation across different user settings.
This commit is contained in:
@@ -2,6 +2,7 @@ import {
|
||||
bookingCargoTons,
|
||||
bookingGrossWeightTons,
|
||||
bookingTrainLengthMeters,
|
||||
bulkItemWagonsForAllowedTypes,
|
||||
bulkItemWagonsRequired,
|
||||
consistUsage,
|
||||
consistViolations,
|
||||
@@ -76,6 +77,62 @@ describe('train-capacity.util', () => {
|
||||
expect(bulkItemWagonsRequired(breakBulk(0, 800), 69)).toBe(0);
|
||||
expect(bulkItemWagonsRequired(breakBulk(400, 0), 69)).toBe(0);
|
||||
});
|
||||
|
||||
describe('configured items-fit (floor space vs tonnage)', () => {
|
||||
it('weight binds: 50 cars × 20T on a 70T wagon that fits 4 → 3 per wagon → 17', () => {
|
||||
// floor(70/20) = 3 by tonnage < 4 by floor space.
|
||||
expect(bulkItemWagonsRequired(breakBulk(50, 1000), 70, 4)).toBe(17);
|
||||
});
|
||||
|
||||
it('floor space binds: 50 cars × 10T on a 70T wagon that fits 4 → 4 per wagon → 13', () => {
|
||||
// floor(70/10) = 7 by tonnage, but only 4 fit physically.
|
||||
expect(bulkItemWagonsRequired(breakBulk(50, 500), 70, 4)).toBe(13);
|
||||
});
|
||||
|
||||
it('ignores an absent/invalid fit (legacy cargo types): tonnage-only', () => {
|
||||
expect(bulkItemWagonsRequired(breakBulk(50, 1000), 70, null)).toBe(17);
|
||||
expect(bulkItemWagonsRequired(breakBulk(50, 1000), 70, 0)).toBe(17);
|
||||
// floor(70/10) = 7 per wagon → ceil(50/7) = 8 wagons.
|
||||
expect(bulkItemWagonsRequired(breakBulk(50, 500), 70)).toBe(8);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('bulkItemWagonsForAllowedTypes', () => {
|
||||
const breakBulk = (quantity: number, weightTons: number) => ({
|
||||
freightType: 'BULK',
|
||||
cargoTotalWeightVgm: quantity,
|
||||
bulkTotalWeightTons: weightTons,
|
||||
});
|
||||
|
||||
it('picks the fewest-wagon allowed type, each capped by its own fit', () => {
|
||||
const cargoType = {
|
||||
wagonTypes: [
|
||||
{ id: 'nw5', capacityTons: 70 },
|
||||
{ id: 'nw7', capacityTons: 80 },
|
||||
],
|
||||
itemsPerWagonMap: { nw5: 4, nw7: 6 },
|
||||
};
|
||||
// 50 cars × 20T: NW5 → min(4, floor(70/20)=3) = 3/wagon = 17 wagons;
|
||||
// NW7 → min(6, floor(80/20)=4) = 4/wagon = 13 wagons. Best = 13.
|
||||
expect(bulkItemWagonsForAllowedTypes(breakBulk(50, 1000), cargoType, 70)).toBe(13);
|
||||
});
|
||||
|
||||
it('equals the old max-capacity estimate when no fits are configured', () => {
|
||||
const cargoType = {
|
||||
wagonTypes: [
|
||||
{ id: 'a', capacityTons: 50 },
|
||||
{ id: 'b', capacityTons: 70 },
|
||||
],
|
||||
};
|
||||
// Tonnage-only best = biggest wagon: floor(70/20) = 3/wagon → 17.
|
||||
expect(bulkItemWagonsForAllowedTypes(breakBulk(50, 1000), cargoType, 1)).toBe(17);
|
||||
});
|
||||
|
||||
it('falls back to the given capacity when the relation is missing', () => {
|
||||
expect(bulkItemWagonsForAllowedTypes(breakBulk(50, 1000), null, 70)).toBe(17);
|
||||
expect(bulkItemWagonsForAllowedTypes(breakBulk(50, 1000), { wagonTypes: [] }, 70)).toBe(17);
|
||||
});
|
||||
});
|
||||
|
||||
describe('bookingCargoTons (break-bulk weight preference)', () => {
|
||||
|
||||
Reference in New Issue
Block a user