mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-29 21:08:12 +00:00
Cut off time configuration
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
/**
|
||||
* Resolves the booking/check-in cutoff for one boarding stop: stop-level
|
||||
* `RouteStop.checkinMinutesBefore` override wins, else the route-level default
|
||||
* (`Route.checkinMinutesBefore`), else a bare 30-minute fallback for routes/stops with
|
||||
* neither configured. The basis is the stop's own estimated ARRIVAL time (the train reaching
|
||||
* that stop), not its departure or the schedule's overall origin departure — a downstream
|
||||
* stop's cutoff must be independent of how long ago the train left its origin. The first stop
|
||||
* of a route has no arrival (nothing to arrive at), so it falls back to its own departure.
|
||||
*
|
||||
* Single source of truth for this computation — SeatsService.holdSeats and
|
||||
* SearchService.buildScheduleResult already applied it (search results only ever showed a
|
||||
* segment as bookable if this same cutoff hadn't passed); GuestBookingService.createGuestBooking
|
||||
* used to independently hardcode a flat, non-configurable 30 minutes off the schedule's origin
|
||||
* departure, which could reject a booking the search/hold steps had just accepted under the
|
||||
* route's actual configured cutoff.
|
||||
*/
|
||||
export interface CheckinCutoff {
|
||||
/** The stop's own estimated arrival time (or departure, for the first stop / missing data). */
|
||||
segmentTime: Date;
|
||||
/** Minutes before segmentTime that booking/holding closes. */
|
||||
checkinMinutes: number;
|
||||
/** The moment booking/holding closes for this stop. */
|
||||
cutoffAt: Date;
|
||||
}
|
||||
|
||||
export function resolveCheckinCutoff(
|
||||
schedule: {
|
||||
departureAt: Date;
|
||||
route?: {
|
||||
checkinMinutesBefore?: number | null;
|
||||
stops?: Array<{ stationId: string; checkinMinutesBefore: number | null }>;
|
||||
} | null;
|
||||
},
|
||||
stopTime: { plannedArrivalAt?: Date | null; plannedDepartureAt?: Date | null } | null | undefined,
|
||||
stationId: string | null | undefined,
|
||||
): CheckinCutoff {
|
||||
const segmentTime = stopTime?.plannedArrivalAt ?? stopTime?.plannedDepartureAt ?? schedule.departureAt;
|
||||
const routeStop = stationId ? schedule.route?.stops?.find((s) => s.stationId === stationId) : undefined;
|
||||
const checkinMinutes = routeStop?.checkinMinutesBefore ?? schedule.route?.checkinMinutesBefore ?? 30;
|
||||
return {
|
||||
segmentTime,
|
||||
checkinMinutes,
|
||||
cutoffAt: new Date(segmentTime.getTime() - checkinMinutes * 60_000),
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/**
|
||||
* Resolves a booking's actual boarding/alighting station AND time for one leg from
|
||||
* originStationId/destinationStationId (set when the booking covers only part of a
|
||||
* longer multi-stop schedule, e.g. train runs A→D but the passenger booked B→D), via
|
||||
* the schedule's stopTimes — falling back to the schedule's own full-route
|
||||
* station/time when there's no segment override (older records, or a booking that
|
||||
* covers the whole run).
|
||||
*
|
||||
* Single source of truth for this resolution — station-only lookups used to be
|
||||
* duplicated ad hoc across bookings/tickets/notifications while the departureAt/
|
||||
* arrivalAt kept being read straight off the schedule (the train's full-route span),
|
||||
* which showed the wrong boarding/alighting time for any stop-based booking.
|
||||
*/
|
||||
export interface ResolvedSegment {
|
||||
origin: any;
|
||||
destination: any;
|
||||
departureAt: any;
|
||||
arrivalAt: any;
|
||||
}
|
||||
|
||||
export function resolveBookingSegment(
|
||||
schedule: any,
|
||||
originStationId: string | null | undefined,
|
||||
destinationStationId: string | null | undefined,
|
||||
): ResolvedSegment {
|
||||
const stopTimes: any[] = schedule?.stopTimes ?? [];
|
||||
const findStop = (stationId: string | null | undefined) =>
|
||||
stationId && stopTimes.length > 0 ? stopTimes.find((st: any) => st.stationId === stationId) : undefined;
|
||||
const originStop = findStop(originStationId);
|
||||
const destStop = findStop(destinationStationId);
|
||||
return {
|
||||
origin: originStop?.station ?? schedule?.originStation ?? null,
|
||||
destination: destStop?.station ?? schedule?.destinationStation ?? null,
|
||||
departureAt: originStop?.plannedDepartureAt ?? schedule?.departureAt ?? null,
|
||||
arrivalAt: destStop?.plannedArrivalAt ?? schedule?.arrivalAt ?? null,
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user