Package booking new rules update, cascade delete option updates

This commit is contained in:
Stephanos A
2026-07-06 22:12:04 +03:00
parent f52d7442ac
commit 36055d0d82
31 changed files with 777 additions and 339 deletions

View File

@@ -508,10 +508,11 @@ Returns saved passenger details with generated IDs and confirmation.`,
summary: 'Delete passenger (admin only)',
description: 'Permanently deletes a passenger record and associated data'
})
@ApiQuery({ name: 'cascade', required: false, type: Boolean, description: 'Force delete with all related bookings and data' })
@ApiResponse({ status: 200, description: 'Passenger deleted successfully' })
@ApiResponse({ status: 404, description: 'Passenger not found' })
deletePassenger(@Param('id') id: string) {
return this.service.deletePassenger(id);
deletePassenger(@Param('id') id: string, @Query('cascade') cascade?: string) {
return this.service.deletePassenger(id, cascade === 'true');
}
@Get(':id/usage')

View File

@@ -432,7 +432,7 @@ export class PassengersService {
};
}
async deletePassenger(id: string) {
async deletePassenger(id: string, cascade = false) {
// id may be a TravelerProfile.id (from the list endpoint) or a Passenger.id
let passenger = await this.prisma.passenger.findUnique({
where: { id },
@@ -451,29 +451,67 @@ export class PassengersService {
const passengerId = passenger.id;
// Check usage before allowing deletion
const usage = await this.checkPassengerUsage(passengerId);
if (usage.isInUse && usage.constraints) {
const passengerName = (passenger as any).user?.fullName || `Passenger ${passengerId.slice(-8)}`;
throw new DeleteOperationException('Passenger', passengerName, usage.constraints);
if (!cascade) {
const usage = await this.checkPassengerUsage(passengerId);
if (usage.isInUse && usage.constraints) {
const passengerName = (passenger as any).user?.fullName || `Passenger ${passengerId.slice(-8)}`;
throw new DeleteOperationException('Passenger', passengerName, usage.constraints);
}
}
await this.prisma.$transaction([
this.prisma.loyaltyLedgerEntry.deleteMany({ where: { account: { passengerId } } }),
this.prisma.loyaltyAccount.deleteMany({ where: { passengerId } }),
this.prisma.walletLedgerEntry.deleteMany({ where: { wallet: { passengerId } } }),
this.prisma.walletAccount.deleteMany({ where: { passengerId } }),
this.prisma.notification.deleteMany({ where: { passengerId } }),
this.prisma.travelerProfile.deleteMany({ where: { passengerId } }),
this.prisma.savedRoute.deleteMany({ where: { passengerId } }),
this.prisma.packageBooking.deleteMany({ where: { passengerId } }),
this.prisma.ticket.deleteMany({ where: { booking: { passengerId } } }),
this.prisma.bookingSeat.deleteMany({ where: { booking: { passengerId } } }),
this.prisma.booking.deleteMany({ where: { passengerId } }),
this.prisma.journeySegment.deleteMany({ where: { journey: { passengerId } } }),
this.prisma.journey.deleteMany({ where: { passengerId } }),
this.prisma.passenger.delete({ where: { id: passengerId } }),
]);
// Resolve booking IDs first (needed for multi-step child deletion)
const bookings = await this.prisma.booking.findMany({
where: { passengerId },
select: { id: true },
});
const bookingIds = bookings.map(b => b.id);
if (bookingIds.length > 0) {
const tickets = await this.prisma.ticket.findMany({ where: { bookingId: { in: bookingIds } }, select: { id: true } });
if (tickets.length > 0) {
await this.prisma.gateValidationLog.deleteMany({ where: { ticketId: { in: tickets.map(t => t.id) } } });
}
await this.prisma.ticket.deleteMany({ where: { bookingId: { in: bookingIds } } });
const foodOrders = await this.prisma.foodOrder.findMany({ where: { bookingId: { in: bookingIds } }, select: { id: true } });
if (foodOrders.length > 0) {
await this.prisma.foodOrderItem.deleteMany({ where: { orderId: { in: foodOrders.map(o => o.id) } } });
}
await this.prisma.foodOrder.deleteMany({ where: { bookingId: { in: bookingIds } } });
const paymentIntents = await this.prisma.paymentIntent.findMany({ where: { bookingId: { in: bookingIds } }, select: { id: true } });
if (paymentIntents.length > 0) {
await this.prisma.paymentRefund.deleteMany({ where: { paymentIntentId: { in: paymentIntents.map(p => p.id) } } });
}
await this.prisma.paymentIntent.deleteMany({ where: { bookingId: { in: bookingIds } } });
await this.prisma.bookingSeat.deleteMany({ where: { bookingId: { in: bookingIds } } });
await this.prisma.agentBooking.deleteMany({ where: { bookingId: { in: bookingIds } } });
await this.prisma.bookingModification.deleteMany({ where: { bookingId: { in: bookingIds } } });
await this.prisma.bookingCancellation.deleteMany({ where: { bookingId: { in: bookingIds } } });
await this.prisma.baggageBooking.deleteMany({ where: { bookingId: { in: bookingIds } } });
await this.prisma.excessBaggageCharge.deleteMany({ where: { bookingId: { in: bookingIds } } });
await this.prisma.journey.deleteMany({ where: { bookingId: { in: bookingIds } } });
await this.prisma.booking.deleteMany({ where: { id: { in: bookingIds } } });
}
// Package bookings
const packageBookings = await this.prisma.packageBooking.findMany({ where: { passengerId }, select: { id: true } });
if (packageBookings.length > 0) {
const pbIds = packageBookings.map(pb => pb.id);
await this.prisma.packageBookingPassenger.deleteMany({ where: { bookingId: { in: pbIds } } });
await this.prisma.packagePaymentIntent.deleteMany({ where: { packageBookingId: { in: pbIds } } });
await this.prisma.packageBooking.deleteMany({ where: { id: { in: pbIds } } });
}
await this.prisma.loyaltyLedgerEntry.deleteMany({ where: { account: { passengerId } } });
await this.prisma.loyaltyAccount.deleteMany({ where: { passengerId } });
await this.prisma.walletLedgerEntry.deleteMany({ where: { wallet: { passengerId } } });
await this.prisma.walletAccount.deleteMany({ where: { passengerId } });
await this.prisma.notification.deleteMany({ where: { passengerId } });
await this.prisma.travelerProfile.deleteMany({ where: { passengerId } });
await this.prisma.savedRoute.deleteMany({ where: { passengerId } });
await this.prisma.passenger.delete({ where: { id: passengerId } });
return { deleted: true, passengerId };
}