mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-29 09:30:59 +00:00
booking operations and trains scheduling also allocations
This commit is contained in:
@@ -0,0 +1,91 @@
|
||||
import { compareSchedulingPriority } from "./compareSchedulingPriority";
|
||||
|
||||
export interface ThreeHourSchedulable {
|
||||
id: string;
|
||||
priorityScore?: number;
|
||||
scheduledDate?: string;
|
||||
preferredDepartureDate?: string;
|
||||
isGovernment?: boolean;
|
||||
}
|
||||
|
||||
export interface ThreeHourBookingBucket<T extends ThreeHourSchedulable = ThreeHourSchedulable> {
|
||||
key: string;
|
||||
label: string;
|
||||
start: Date;
|
||||
end: Date;
|
||||
bookings: T[];
|
||||
}
|
||||
|
||||
function bucketStart(date: Date): Date {
|
||||
const start = new Date(date);
|
||||
start.setUTCMinutes(0, 0, 0);
|
||||
const hour = start.getUTCHours();
|
||||
start.setUTCHours(Math.floor(hour / 3) * 3);
|
||||
return start;
|
||||
}
|
||||
|
||||
function formatBucketLabel(start: Date, end: Date): string {
|
||||
const dateFmt = new Intl.DateTimeFormat("en-GB", {
|
||||
day: "2-digit",
|
||||
month: "short",
|
||||
year: "numeric",
|
||||
timeZone: "UTC",
|
||||
});
|
||||
const timeFmt = new Intl.DateTimeFormat("en-GB", {
|
||||
hour: "2-digit",
|
||||
minute: "2-digit",
|
||||
hour12: false,
|
||||
timeZone: "UTC",
|
||||
});
|
||||
return `${dateFmt.format(start)} · ${timeFmt.format(start)} – ${timeFmt.format(end)} UTC`;
|
||||
}
|
||||
|
||||
function getScheduledDate(booking: ThreeHourSchedulable): Date {
|
||||
const raw = booking.scheduledDate ?? booking.preferredDepartureDate;
|
||||
if (!raw) return new Date(0);
|
||||
return new Date(raw);
|
||||
}
|
||||
|
||||
function toPriorityRow(booking: ThreeHourSchedulable) {
|
||||
return {
|
||||
isGovernment: booking.isGovernment,
|
||||
priorityScore: booking.priorityScore,
|
||||
scheduledDate: booking.scheduledDate ?? booking.preferredDepartureDate ?? "",
|
||||
};
|
||||
}
|
||||
|
||||
export function groupBookingsByThreeHourWindow<T extends ThreeHourSchedulable>(
|
||||
bookings: T[],
|
||||
): ThreeHourBookingBucket<T>[] {
|
||||
const map = new Map<string, ThreeHourBookingBucket<T>>();
|
||||
|
||||
for (const booking of bookings) {
|
||||
const scheduled = getScheduledDate(booking);
|
||||
const start = bucketStart(scheduled);
|
||||
const end = new Date(start);
|
||||
end.setUTCHours(end.getUTCHours() + 3);
|
||||
const key = start.toISOString();
|
||||
|
||||
const existing = map.get(key);
|
||||
if (existing) {
|
||||
existing.bookings.push(booking);
|
||||
} else {
|
||||
map.set(key, {
|
||||
key,
|
||||
label: formatBucketLabel(start, end),
|
||||
start,
|
||||
end,
|
||||
bookings: [booking],
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return [...map.values()]
|
||||
.map((bucket) => ({
|
||||
...bucket,
|
||||
bookings: [...bucket.bookings].sort((a, b) =>
|
||||
compareSchedulingPriority(toPriorityRow(a), toPriorityRow(b)),
|
||||
),
|
||||
}))
|
||||
.sort((a, b) => a.start.getTime() - b.start.getTime());
|
||||
}
|
||||
Reference in New Issue
Block a user