mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-29 23:28:11 +00:00
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:
@@ -3607,11 +3607,19 @@ export class BookingBatchService implements OnModuleInit {
|
||||
|
||||
/** See {@link isScheduleFull} — same check for callers that already hold the full graph. */
|
||||
private async isTrainFull(schedule: TrainSchedule): Promise<boolean> {
|
||||
// Built train: the physical consist is the only capacity axis, and a wagon
|
||||
// is committed to its booking for the WHOLE trip — wagon allocation has no
|
||||
// leg concept, so a wagon hauling Negad→Mojo cargo can never be re-sold for
|
||||
// the Doraleh→Negad edge it merely passes through. Count commitments
|
||||
// train-wide, not per corridor edge: the per-edge budget read "free slots"
|
||||
// on pass-through legs of a sold-out consist, so the window of a full train
|
||||
// cycled OPEN forever instead of concluding DONE (and the day pool's
|
||||
// leftover bookings were never expired).
|
||||
const physicalWagons = await this.builtTrainWagonCount(schedule);
|
||||
if (physicalWagons != null) {
|
||||
return (await this.committedWagons(schedule)) >= physicalWagons;
|
||||
}
|
||||
if ((await this.remainingWagons(schedule)) <= 0) return true;
|
||||
// Built train: the physical consist is the only capacity axis. Weight and
|
||||
// length were enforced when the consist was assembled (builder /
|
||||
// adjust-consist), so a free wagon slot means the train genuinely has room.
|
||||
if ((await this.builtTrainWagonCount(schedule)) != null) return false;
|
||||
const locomotive = schedule.trainSet?.locomotive;
|
||||
if (!locomotive) return false; // no weight/length limits to bind against
|
||||
const wagonDims = await this.loadWagonDims();
|
||||
@@ -3620,6 +3628,29 @@ export class BookingBatchService implements OnModuleInit {
|
||||
return budget.isExhausted(this.minPerWagonNeed(wagonDims));
|
||||
}
|
||||
|
||||
/**
|
||||
* Wagons the schedule's allocated + reserved bookings occupy train-wide,
|
||||
* regardless of which corridor leg each rides. Deduped by booking id — a
|
||||
* booking mid-settle can momentarily be both linked and reserved.
|
||||
*/
|
||||
private async committedWagons(schedule: TrainSchedule): Promise<number> {
|
||||
const wagonDims = await this.loadWagonDims();
|
||||
const allocated = (schedule.scheduleBookings ?? [])
|
||||
.map((sb) => sb.booking)
|
||||
.filter((b): b is Booking => Boolean(b));
|
||||
const reserved = await this.bookingsRepository.findReservedForSchedule(
|
||||
schedule.id,
|
||||
);
|
||||
const byId = new Map(
|
||||
[...allocated, ...reserved].map((b) => [b.id, b] as const),
|
||||
);
|
||||
let total = 0;
|
||||
for (const booking of byId.values()) {
|
||||
total += this.wagonsFor(booking, wagonDims);
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
/**
|
||||
* Smallest gross weight / shortest length one more wagon could add: the
|
||||
* lightest wagon type at its rated payload. Feeds CorridorBudget.isExhausted,
|
||||
|
||||
Reference in New Issue
Block a user