Boarding, ticketing, class fare edit updates

This commit is contained in:
Stephanos A
2026-07-02 16:20:15 +03:00
parent b511da2821
commit 9494d57343
15 changed files with 370 additions and 325 deletions

View File

@@ -159,6 +159,8 @@ export class TicketsService {
} : null,
status: t.status,
validatedAt: t.validatedAt,
boardedAt: t.validatedAt,
qrCode: t.qrPayload ?? null,
createdAt: t.issuedAt,
};
}),
@@ -247,9 +249,12 @@ export class TicketsService {
// Use first seat for primary data
const primarySeat = passengerSeats[0];
// Build passenger QR data with all legs included
const qrData = JSON.stringify({
const barcodePayload = `${booking.bookingRef}${primarySeat.seatId.substring(0, 8).toUpperCase()}`;
// Re-encode QR with ticketNumber included
const qrDataWithTicket = JSON.stringify({
ref: booking.bookingRef,
ticketNumber: barcodePayload,
type: booking.bookingType,
passenger: passengerName,
seats: passengerSeats.map(ps => ({
@@ -259,8 +264,7 @@ export class TicketsService {
scheduleId: ps.scheduleId || booking.scheduleId,
})),
});
const qrPayload = await QRCode.toDataURL(qrData);
const barcodePayload = `${booking.bookingRef}${primarySeat.seatId.substring(0, 8).toUpperCase()}`;
const qrPayloadFinal = await QRCode.toDataURL(qrDataWithTicket);
const ticket = await this.prisma.ticket.create({
data: {
@@ -270,7 +274,7 @@ export class TicketsService {
seatId: primarySeat.seatId,
leg: primarySeat.leg || 1,
scheduleId: primarySeat.scheduleId || booking.scheduleId,
qrPayload,
qrPayload: qrPayloadFinal,
barcodePayload,
} as any,
});
@@ -371,15 +375,13 @@ export class TicketsService {
let bookingRef = qrCodeOrRef;
try {
const qrData = JSON.parse(qrCodeOrRef);
if (qrData.ref) {
bookingRef = qrData.ref;
}
if (qrData.ref) bookingRef = qrData.ref;
} catch {
// Not JSON, treat as booking reference
// Not JSON, treat as booking reference or ticket number
}
// Get booking and ticket info
const booking = await this.prisma.booking.findUnique({
let booking = await this.prisma.booking.findUnique({
where: { bookingRef },
include: {
schedule: { include: { originStation: true, destinationStation: true, train: true } },
@@ -389,6 +391,23 @@ export class TicketsService {
},
});
if (!booking) {
// Input may be a ticket number (barcodePayload) — look it up
const ticket = await this.prisma.ticket.findFirst({ where: { barcodePayload: bookingRef } });
if (ticket) {
booking = await this.prisma.booking.findUnique({
where: { bookingRef: ticket.bookingRef },
include: {
schedule: { include: { originStation: true, destinationStation: true, train: true } },
returnSchedule: { include: { originStation: true, destinationStation: true } },
tickets: true,
seats: { include: { seat: { include: { coach: true } } } },
},
});
if (booking) bookingRef = (booking as any).bookingRef;
}
}
if (!booking) {
throw new NotFoundException('Ticket not found');
}
@@ -443,6 +462,7 @@ export class TicketsService {
message: `Passenger boarded successfully (${result.leg || 'OUTBOUND'} leg)`,
boarding: {
ticketId: ticket.id,
ticketNumber: ticket.barcodePayload,
bookingRef: booking.bookingRef,
passengerName: seatInfo?.passengerName || ticket.passengerName || 'N/A',
route: `${(booking as any).schedule?.originStation?.name || 'N/A'}${(booking as any).schedule?.destinationStation?.name || 'N/A'}`,