update booking logic for train schedules and customs contracts

This commit is contained in:
Marshal
2026-07-10 12:13:08 +00:00
parent 10111c9e01
commit a58650bdfb
4 changed files with 39 additions and 40 deletions

View File

@@ -2533,21 +2533,17 @@ export class BookingBatchService implements OnModuleInit {
}
/**
* Keep schedule.max_wagons aligned with the train's real boarding limit: the
* locomotive's length-derived slot count, floored by the physical wagons in
* the train set (slots that exist on paper but not in the yard must not be
* sold — see {@link remainingBudget}).
* Keep schedule.max_wagons aligned with the train's boarding limit: the
* locomotive's length-derived slot count. The physical wagons currently in
* the train set do NOT cap this — bookings are admitted on length/weight
* alone and yard staff attach the wagons manually before departure.
*/
private async syncScheduleMaxWagons(
schedule: TrainSchedule,
locomotive: Locomotive,
): Promise<void> {
const limits = await this.capacityLimits(locomotive);
const physicalWagons = schedule.trainSet?.wagons?.length ?? 0;
const maxWagons =
physicalWagons > 0
? Math.min(limits.base.wagons, physicalWagons)
: limits.base.wagons;
const maxWagons = limits.base.wagons;
if ((schedule.maxWagons ?? 0) !== maxWagons) {
await this.dataSource
.getRepository(TrainSchedule)
@@ -2664,11 +2660,10 @@ export class BookingBatchService implements OnModuleInit {
* reserved bookings already use ON THEIR OWN LEGS. A booking riding only
* Dire→Djibouti leaves the Addis→Dire edges untouched.
*
* The wagon axis is additionally capped by the PHYSICAL wagons marshalled in
* the schedule's train set. The length-derived slot count says how many wagons
* the locomotive could pull, not how many exist: a 760m/54-slot train with a
* 50-wagon set once split-offered 4 wagons that were never buildable — the
* customer paid and the wagon planner had nothing to assign.
* The wagon axis is the locomotive's length-derived slot count only — the
* physical wagons currently marshalled in the train set do NOT cap it.
* Bookings are admitted on length/weight capacity and yard staff attach
* the missing wagons manually before wagon assignment.
*/
private async remainingBudget(
schedule: TrainSchedule,
@@ -2676,12 +2671,7 @@ export class BookingBatchService implements OnModuleInit {
wagonDims: WagonDims,
): Promise<CorridorBudget> {
const stops = await this.stopsForSchedule(schedule);
const physicalWagons = schedule.trainSet?.wagons?.length ?? 0;
const base =
physicalWagons > 0
? { ...limits.base, wagons: Math.min(limits.base.wagons, physicalWagons) }
: limits.base;
const budget = new CorridorBudget(stops, base, limits.tolerance);
const budget = new CorridorBudget(stops, limits.base, limits.tolerance);
const allocated = (schedule.scheduleBookings ?? [])
.map((sb) => sb.booking)
.filter((b): b is Booking => Boolean(b));