Backoffice updates, boarding pass, alternative schedule search and more

This commit is contained in:
Stephanos A
2026-06-23 10:10:55 +03:00
parent b491f39d42
commit 2d51787383
37 changed files with 1267 additions and 1040 deletions

View File

@@ -39,6 +39,23 @@ export class SearchService {
const outbound = [...direct, ...transit];
if (outbound.length === 0) {
const alternativesOutbound = await this.searchAlternatives(
dto.originStationId,
dto.destinationStationId,
dto.date,
dto.adultCount,
dto.childCount,
dto.nationality,
);
return {
journeyType: dto.journeyType === 'ROUND_TRIP' ? 'ROUND_TRIP' : 'ONE_WAY',
outbound: [],
alternativeOutbound: alternativesOutbound,
requestedDate: dto.date,
};
}
if (dto.journeyType === 'ROUND_TRIP') {
const [returnDirect, returnTransit] = await Promise.all([
this.searchSchedules(
@@ -68,12 +85,85 @@ export class SearchService {
new Date(s.departureAt ?? s.leg1?.departureAt).getTime() > latestOutboundArrival
);
if (inbound.length === 0) {
const alternativeInbound = await this.searchAlternatives(
dto.destinationStationId,
dto.originStationId,
dto.returnDate ?? dto.date,
dto.adultCount,
dto.childCount,
dto.nationality,
);
return { journeyType: 'ROUND_TRIP', outbound, inbound: [], alternativeInbound };
}
return { journeyType: 'ROUND_TRIP', outbound, inbound };
}
return { journeyType: 'ONE_WAY', outbound };
}
private async searchAlternatives(
originStationId: string,
destinationStationId: string,
dateStr: string,
adultCount: number,
childCount?: number,
nationality?: string,
) {
const [y, m, d] = dateStr.split('-').map(Number);
const requestedDate = new Date(y, m - 1, d, 0, 0, 0, 0);
const now = new Date();
const daysBefore = Math.min(7, Math.floor(requestedDate.getTime() / 86_400_000));
const daysAfter = 14 - daysBefore;
const windowStart = new Date(requestedDate);
windowStart.setDate(windowStart.getDate() - daysBefore);
if (windowStart < now) windowStart.setTime(now.getTime());
const windowEnd = new Date(requestedDate);
windowEnd.setDate(windowEnd.getDate() + daysAfter + 1); // exclusive upper bound
const totalPassengers = adultCount + (childCount ?? 0);
const requestedNextDay = new Date(y, m - 1, d + 1, 0, 0, 0, 0);
const schedules = await this.prisma.trainSchedule.findMany({
where: {
status: { in: ['SCHEDULED', 'BOARDING'] },
OR: [
{ departureAt: { gte: windowStart, lt: requestedDate } },
{ departureAt: { gte: requestedNextDay < now ? now : requestedNextDay, lt: windowEnd } },
],
stopTimes: { some: { stationId: originStationId } },
},
include: {
train: true,
originStation: true,
destinationStation: true,
stopTimes: { include: { station: true }, orderBy: { sequence: 'asc' } },
coachAssignments: {
include: { coach: { include: { seats: true, coachType: { include: { seatClasses: true } } } } },
},
},
orderBy: { departureAt: 'asc' },
});
const results: any[] = [];
for (const schedule of schedules) {
const result = await this.buildScheduleResult(
schedule,
originStationId,
destinationStationId,
totalPassengers,
nationality,
);
if (result) results.push(result);
}
return results;
}
private async searchSchedules(
originStationId: string,
destinationStationId: string,
@@ -85,12 +175,13 @@ export class SearchService {
const [y, m, d] = dateStr.split('-').map(Number);
const date = new Date(y, m - 1, d, 0, 0, 0, 0);
const nextDay = new Date(y, m - 1, d + 1, 0, 0, 0, 0);
const now = new Date();
const totalPassengers = adultCount + (childCount ?? 0);
const schedules = await this.prisma.trainSchedule.findMany({
where: {
status: { in: ['SCHEDULED', 'BOARDING'] },
departureAt: { gte: date, lt: nextDay },
departureAt: { gte: date < now ? now : date, lt: nextDay },
stopTimes: { some: { stationId: originStationId } },
},
include: {