import { Injectable, NotFoundException } from '@nestjs/common'; import { PrismaService } from '../../common/prisma.service'; import { CreateTravelerProfileDto, CreateSavedRouteDto } from './passengers.dto'; @Injectable() export class PassengersService { constructor(private prisma: PrismaService) {} async getProfile(passengerId: string) { const p = await this.prisma.passenger.findUnique({ where: { id: passengerId }, include: { user: { select: { fullName: true, email: true, phone: true } }, bookings: { orderBy: { createdAt: 'desc' }, take: 10, include: { trip: { include: { originStation: true, destinationStation: true, service: true } }, seats: { include: { seat: { include: { coach: true } } } } } }, loyalty: true, wallet: true, travelerProfiles: true, savedRoutes: true, }, }); if (!p) throw new NotFoundException('Passenger not found'); return { id: p.id, fullName: p.user.fullName, email: p.user.email, phone: p.user.phone, createdAt: p.createdAt, bookings: p.bookings.map((b) => ({ id: b.id, bookingRef: b.bookingRef, status: b.status, totalFare: b.totalMinor / 100, createdAt: b.createdAt, trip: { number: b.trip.service.number, origin: { id: b.trip.originStation.id, name: b.trip.originStation.name, code: b.trip.originStation.code, city: b.trip.originStation.city }, destination: { id: b.trip.destinationStation.id, name: b.trip.destinationStation.name, code: b.trip.destinationStation.code, city: b.trip.destinationStation.city }, departureAt: b.trip.departureAt, }, passengers: b.seats.map((bs) => ({ fullName: bs.passengerName, seat: { number: bs.seat.label, coach: bs.seat.coach.label, class: bs.seat.coach.serviceClass } })), })), }; } async getStats(passengerId: string) { const [totalTrips, totalSpendResult, loyalty] = await Promise.all([ this.prisma.booking.count({ where: { passengerId, status: 'COMPLETED' } }), this.prisma.booking.aggregate({ where: { passengerId, status: 'COMPLETED' }, _sum: { totalMinor: true } }), this.prisma.loyaltyAccount.findUnique({ where: { passengerId } }), ]); const totalSpend = (totalSpendResult._sum.totalMinor ?? 0) / 100; return { totalTrips, totalSpend, loyaltyPoints: loyalty?.pointsBalance ?? 0, co2Saved: totalTrips * 6 }; } createTravelerProfile(dto: CreateTravelerProfileDto) { return this.prisma.travelerProfile.create({ data: { ...dto, dateOfBirth: dto.dateOfBirth ? new Date(dto.dateOfBirth) : null } }); } getTravelerProfiles(passengerId: string) { return this.prisma.travelerProfile.findMany({ where: { passengerId } }); } createSavedRoute(dto: CreateSavedRouteDto) { return this.prisma.savedRoute.create({ data: dto }); } getSavedRoutes(passengerId: string) { return this.prisma.savedRoute.findMany({ where: { passengerId }, orderBy: { tripCount: 'desc' } }); } }