feat(api): endpoint de suppression d une reservation non payee
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018BAUeCFpDkRD6tU5wGsc1C
This commit is contained in:
parent
607257f538
commit
efc47aae67
@ -14,6 +14,7 @@ import {
|
||||
BadRequestException,
|
||||
ForbiddenException,
|
||||
ParseIntPipe,
|
||||
ParseUUIDPipe,
|
||||
DefaultValuePipe,
|
||||
Inject,
|
||||
} from '@nestjs/common';
|
||||
@ -591,6 +592,31 @@ export class CsvBookingsController {
|
||||
return await this.csvBookingService.cancelBooking(id, userId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete an unpaid booking
|
||||
*
|
||||
* DELETE /api/v1/csv-bookings/:id
|
||||
*/
|
||||
@Delete(':id')
|
||||
@UseGuards(JwtAuthGuard)
|
||||
@ApiBearerAuth()
|
||||
@ApiOperation({
|
||||
summary: 'Delete an unpaid booking',
|
||||
description:
|
||||
'Permanently deletes a booking whose commission has not been paid. Only accessible by the booking owner. A paid booking has been sent to the carrier and can only be cancelled.',
|
||||
})
|
||||
@ApiParam({ name: 'id', description: 'Booking ID (UUID)' })
|
||||
@ApiResponse({ status: 200, description: 'Booking deleted successfully' })
|
||||
@ApiResponse({ status: 400, description: 'Booking has been paid and cannot be deleted' })
|
||||
@ApiResponse({ status: 404, description: 'Booking not found' })
|
||||
@ApiResponse({ status: 401, description: 'Unauthorized' })
|
||||
async deleteBooking(
|
||||
@Param('id', ParseUUIDPipe) id: string,
|
||||
@Request() req: any
|
||||
): Promise<{ success: boolean; message: string }> {
|
||||
return await this.csvBookingService.deleteBooking(id, req.user.id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update booking cargo details before payment
|
||||
*
|
||||
|
||||
@ -1024,6 +1024,44 @@ export class CsvBookingService {
|
||||
return this.toResponseDto(updatedBooking);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete an unpaid booking (user action).
|
||||
*
|
||||
* Seul le proprietaire peut supprimer, et seulement tant qu'aucun paiement
|
||||
* n'a ete encaisse — voir `CsvBooking.isDeletable()`. Une reservation payee
|
||||
* est partie chez le transporteur : elle s'annule, elle ne s'efface pas.
|
||||
*
|
||||
* Les documents deja televerses restent dans le stockage objet, comme lors de
|
||||
* la suppression d'un document isole : la politique du projet est de les
|
||||
* conserver pour l'audit.
|
||||
*/
|
||||
async deleteBooking(id: string, userId: string): Promise<{ success: boolean; message: string }> {
|
||||
this.logger.log(`Deleting booking ${id} by user ${userId}`);
|
||||
|
||||
const booking = await this.csvBookingRepository.findById(id);
|
||||
|
||||
if (!booking) {
|
||||
throw new NotFoundException('Booking not found');
|
||||
}
|
||||
|
||||
// Meme reponse qu'une reservation inexistante : appartenir a quelqu'un
|
||||
// d'autre ne doit pas etre distinguable de ne pas exister.
|
||||
if (booking.userId !== userId) {
|
||||
throw new NotFoundException('Booking not found');
|
||||
}
|
||||
|
||||
if (!booking.isDeletable()) {
|
||||
throw new BadRequestException(
|
||||
`Cannot delete a booking with status ${booking.status}. Only unpaid bookings can be deleted.`
|
||||
);
|
||||
}
|
||||
|
||||
await this.csvBookingRepository.delete(id);
|
||||
this.logger.log(`Booking ${id} deleted`);
|
||||
|
||||
return { success: true, message: 'Booking deleted successfully' };
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the cargo details of a booking before payment (user action).
|
||||
*
|
||||
|
||||
Loading…
Reference in New Issue
Block a user