mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-30 11:08:12 +00:00
Package booking new rules update, cascade delete option updates
This commit is contained in:
@@ -76,10 +76,11 @@ export class FleetController {
|
||||
@Delete('classes/:id')
|
||||
@ApiOperation({ summary: 'Delete a class' })
|
||||
@ApiParam({ name: 'id', description: 'Class UUID' })
|
||||
@ApiQuery({ name: 'cascade', required: false, type: Boolean, description: 'Force delete with all related data' })
|
||||
@ApiResponse({ status: 200, description: 'Class deleted' })
|
||||
@ApiResponse({ status: 404, description: 'Class not found' })
|
||||
deleteClass(@Param('id') id: string) {
|
||||
return this.service.deleteClass(id);
|
||||
deleteClass(@Param('id') id: string, @Query('cascade') cascade?: string) {
|
||||
return this.service.deleteClass(id, cascade === 'true');
|
||||
}
|
||||
|
||||
// Seat Class Endpoints (DEPRECATED - use Classes endpoints instead)
|
||||
@@ -112,10 +113,11 @@ export class FleetController {
|
||||
@Delete('seat-classes/:id')
|
||||
@ApiOperation({ summary: 'Delete a class (DEPRECATED - use /fleet/classes)' })
|
||||
@ApiParam({ name: 'id', description: 'Class UUID' })
|
||||
@ApiQuery({ name: 'cascade', required: false, type: Boolean, description: 'Force delete with all related data' })
|
||||
@ApiResponse({ status: 200, description: 'Class deleted' })
|
||||
@ApiResponse({ status: 404, description: 'Class not found' })
|
||||
deleteSeatClass(@Param('id') id: string) {
|
||||
return this.service.deleteClass(id);
|
||||
deleteSeatClass(@Param('id') id: string, @Query('cascade') cascade?: string) {
|
||||
return this.service.deleteClass(id, cascade === 'true');
|
||||
}
|
||||
|
||||
// Train Endpoints
|
||||
@@ -147,10 +149,11 @@ export class FleetController {
|
||||
@Delete('trains/:id')
|
||||
@ApiOperation({ summary: 'Delete a train service' })
|
||||
@ApiParam({ name: 'id', description: 'Train UUID' })
|
||||
@ApiQuery({ name: 'cascade', required: false, type: Boolean, description: 'Force delete with all related data' })
|
||||
@ApiResponse({ status: 200, description: 'Train deleted' })
|
||||
@ApiResponse({ status: 404, description: 'Train not found' })
|
||||
deleteTrain(@Param('id') id: string) {
|
||||
return this.service.deleteTrain(id);
|
||||
deleteTrain(@Param('id') id: string, @Query('cascade') cascade?: string) {
|
||||
return this.service.deleteTrain(id, cascade === 'true');
|
||||
}
|
||||
|
||||
@Patch('trains/:id/restore')
|
||||
@@ -309,10 +312,11 @@ export class FleetController {
|
||||
@Delete('coaches/:id')
|
||||
@ApiOperation({ summary: 'Delete a coach' })
|
||||
@ApiParam({ name: 'id', description: 'Coach UUID' })
|
||||
@ApiQuery({ name: 'cascade', required: false, type: Boolean, description: 'Force delete with all related data' })
|
||||
@ApiResponse({ status: 200, description: 'Coach deleted successfully' })
|
||||
@ApiResponse({ status: 404, description: 'Coach not found' })
|
||||
deleteCoach(@Param('id') id: string) {
|
||||
return this.service.deleteCoach(id);
|
||||
deleteCoach(@Param('id') id: string, @Query('cascade') cascade?: string) {
|
||||
return this.service.deleteCoach(id, cascade === 'true');
|
||||
}
|
||||
|
||||
@Post('assignments')
|
||||
|
||||
@@ -273,7 +273,7 @@ export class FleetService {
|
||||
});
|
||||
}
|
||||
|
||||
async deleteClass(id: string) {
|
||||
async deleteClass(id: string, cascade = false) {
|
||||
const seatClass = await this.prisma.seatClass.findUnique({
|
||||
where: { id },
|
||||
include: {
|
||||
@@ -284,19 +284,27 @@ export class FleetService {
|
||||
});
|
||||
if (!seatClass) throw new NotFoundException('Seat class not found');
|
||||
|
||||
const totalFareRules = seatClass.fareRules.length + seatClass.routeFareRules.length + seatClass.segmentFares.length;
|
||||
const constraints = [];
|
||||
|
||||
if (totalFareRules > 0) {
|
||||
constraints.push({
|
||||
entityName: 'fare rule',
|
||||
count: totalFareRules,
|
||||
action: 'delete' as const
|
||||
});
|
||||
if (!cascade) {
|
||||
const totalFareRules = seatClass.fareRules.length + seatClass.routeFareRules.length + seatClass.segmentFares.length;
|
||||
const constraints = [];
|
||||
|
||||
if (totalFareRules > 0) {
|
||||
constraints.push({
|
||||
entityName: 'fare rule',
|
||||
count: totalFareRules,
|
||||
action: 'delete' as const
|
||||
});
|
||||
}
|
||||
|
||||
if (constraints.length > 0) {
|
||||
throw new DeleteOperationException('Seat Class', seatClass.name, constraints);
|
||||
}
|
||||
}
|
||||
|
||||
if (constraints.length > 0) {
|
||||
throw new DeleteOperationException('Seat Class', seatClass.name, constraints);
|
||||
|
||||
if (cascade) {
|
||||
await this.prisma.fareRule.deleteMany({ where: { seatClassId: id } });
|
||||
await this.prisma.routeFareRule.deleteMany({ where: { seatClassId: id } });
|
||||
await this.prisma.segmentFareRule.deleteMany({ where: { seatClassId: id } });
|
||||
}
|
||||
|
||||
return this.prisma.seatClass.delete({ where: { id } });
|
||||
@@ -354,24 +362,78 @@ export class FleetService {
|
||||
});
|
||||
}
|
||||
|
||||
async deleteTrain(id: string) {
|
||||
async deleteTrain(id: string, cascade = false) {
|
||||
const train = await this.prisma.train.findUnique({
|
||||
where: { id },
|
||||
include: { schedules: true },
|
||||
});
|
||||
if (!train) throw new NotFoundException('Train not found');
|
||||
|
||||
const constraints = [];
|
||||
if (train.schedules.length > 0) {
|
||||
constraints.push({
|
||||
entityName: 'schedule',
|
||||
count: train.schedules.length,
|
||||
action: 'delete' as const
|
||||
});
|
||||
if (!cascade) {
|
||||
const constraints = [];
|
||||
if (train.schedules.length > 0) {
|
||||
constraints.push({
|
||||
entityName: 'schedule',
|
||||
count: train.schedules.length,
|
||||
action: 'delete' as const
|
||||
});
|
||||
}
|
||||
|
||||
if (constraints.length > 0) {
|
||||
throw new DeleteOperationException('Train', `${train.number} (${train.name})`, constraints);
|
||||
}
|
||||
}
|
||||
|
||||
if (constraints.length > 0) {
|
||||
throw new DeleteOperationException('Train', `${train.number} (${train.name})`, constraints);
|
||||
|
||||
if (cascade && train.schedules.length > 0) {
|
||||
const scheduleIds = train.schedules.map((s: any) => s.id);
|
||||
await this.prisma.tripStopTime.deleteMany({ where: { scheduleId: { in: scheduleIds } } });
|
||||
await this.prisma.coachAssignment.deleteMany({ where: { scheduleId: { in: scheduleIds } } });
|
||||
await this.prisma.tripLiveStatus.deleteMany({ where: { scheduleId: { in: scheduleIds } } });
|
||||
await this.prisma.menuItem.deleteMany({ where: { scheduleId: { in: scheduleIds } } });
|
||||
await this.prisma.journeySegment.deleteMany({ where: { scheduleId: { in: scheduleIds } } });
|
||||
|
||||
const bookings = await this.prisma.booking.findMany({
|
||||
where: { OR: [{ scheduleId: { in: scheduleIds } }, { returnScheduleId: { in: scheduleIds } }] },
|
||||
select: { id: true },
|
||||
});
|
||||
if (bookings.length > 0) {
|
||||
const bookingIds = bookings.map(b => b.id);
|
||||
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 } } });
|
||||
}
|
||||
|
||||
const packages = await this.prisma.travelPackage.findMany({
|
||||
where: { OR: [{ outboundScheduleId: { in: scheduleIds } }, { returnScheduleId: { in: scheduleIds } }] },
|
||||
select: { id: true },
|
||||
});
|
||||
if (packages.length > 0) {
|
||||
const packageIds = packages.map(p => p.id);
|
||||
await this.prisma.packagePriceTier.deleteMany({ where: { packageId: { in: packageIds } } });
|
||||
await this.prisma.travelPackage.deleteMany({ where: { id: { in: packageIds } } });
|
||||
}
|
||||
|
||||
await this.prisma.trainSchedule.deleteMany({ where: { id: { in: scheduleIds } } });
|
||||
}
|
||||
|
||||
return this.prisma.train.delete({ where: { id } });
|
||||
@@ -477,7 +539,7 @@ export class FleetService {
|
||||
});
|
||||
}
|
||||
|
||||
async deleteCoach(id: string) {
|
||||
async deleteCoach(id: string, cascade = false) {
|
||||
const coach = await this.prisma.coach.findUnique({
|
||||
where: { id },
|
||||
include: {
|
||||
@@ -493,47 +555,60 @@ export class FleetService {
|
||||
});
|
||||
if (!coach) throw new NotFoundException('Coach not found');
|
||||
|
||||
const constraints = [];
|
||||
|
||||
if ((coach as any).assignments.length > 0) {
|
||||
constraints.push({
|
||||
entityName: 'schedule assignment',
|
||||
count: (coach as any).assignments.length,
|
||||
action: 'reassign' as const
|
||||
});
|
||||
if (!cascade) {
|
||||
const constraints = [];
|
||||
|
||||
if ((coach as any).assignments.length > 0) {
|
||||
constraints.push({
|
||||
entityName: 'schedule assignment',
|
||||
count: (coach as any).assignments.length,
|
||||
action: 'reassign' as const
|
||||
});
|
||||
}
|
||||
|
||||
const bookedSeats = (coach as any).seats.filter((seat: any) => seat.bookingSeats.length > 0);
|
||||
if (bookedSeats.length > 0) {
|
||||
constraints.push({
|
||||
entityName: 'booked seat',
|
||||
count: bookedSeats.length,
|
||||
action: 'complete' as const
|
||||
});
|
||||
}
|
||||
|
||||
const blockedSeats = (coach as any).seats.filter((seat: any) => seat.blocks.length > 0);
|
||||
if (blockedSeats.length > 0) {
|
||||
constraints.push({
|
||||
entityName: 'blocked seat',
|
||||
count: blockedSeats.length,
|
||||
action: 'delete' as const
|
||||
});
|
||||
}
|
||||
|
||||
const seatsWithTickets = (coach as any).seats.filter((seat: any) => seat.tickets.length > 0);
|
||||
if (seatsWithTickets.length > 0) {
|
||||
constraints.push({
|
||||
entityName: 'seat with issued ticket',
|
||||
count: seatsWithTickets.length,
|
||||
action: 'complete' as const
|
||||
});
|
||||
}
|
||||
|
||||
if (constraints.length > 0) {
|
||||
throw new DeleteOperationException('Coach', coach.number, constraints);
|
||||
}
|
||||
}
|
||||
|
||||
const bookedSeats = (coach as any).seats.filter((seat: any) => seat.bookingSeats.length > 0);
|
||||
if (bookedSeats.length > 0) {
|
||||
constraints.push({
|
||||
entityName: 'booked seat',
|
||||
count: bookedSeats.length,
|
||||
action: 'complete' as const
|
||||
});
|
||||
if (cascade) {
|
||||
const seatIds = (coach as any).seats.map((s: any) => s.id);
|
||||
if (seatIds.length > 0) {
|
||||
await this.prisma.bookingSeat.deleteMany({ where: { seatId: { in: seatIds } } });
|
||||
await this.prisma.seatBlock.deleteMany({ where: { seatId: { in: seatIds } } });
|
||||
await this.prisma.ticket.deleteMany({ where: { seatId: { in: seatIds } } });
|
||||
}
|
||||
await this.prisma.coachAssignment.deleteMany({ where: { coachId: id } });
|
||||
await this.prisma.routeCoachTemplate.deleteMany({ where: { coachId: id } });
|
||||
}
|
||||
|
||||
const blockedSeats = (coach as any).seats.filter((seat: any) => seat.blocks.length > 0);
|
||||
if (blockedSeats.length > 0) {
|
||||
constraints.push({
|
||||
entityName: 'blocked seat',
|
||||
count: blockedSeats.length,
|
||||
action: 'delete' as const
|
||||
});
|
||||
}
|
||||
|
||||
const seatsWithTickets = (coach as any).seats.filter((seat: any) => seat.tickets.length > 0);
|
||||
if (seatsWithTickets.length > 0) {
|
||||
constraints.push({
|
||||
entityName: 'seat with issued ticket',
|
||||
count: seatsWithTickets.length,
|
||||
action: 'complete' as const
|
||||
});
|
||||
}
|
||||
|
||||
if (constraints.length > 0) {
|
||||
throw new DeleteOperationException('Coach', coach.number, constraints);
|
||||
}
|
||||
|
||||
|
||||
await this.prisma.seat.deleteMany({ where: { coachId: id } });
|
||||
|
||||
return this.prisma.coach.delete({ where: { id } });
|
||||
|
||||
Reference in New Issue
Block a user