feat(domain): une reservation non payee peut etre supprimee

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018BAUeCFpDkRD6tU5wGsc1C
This commit is contained in:
David 2026-09-07 21:40:53 +02:00
parent 8e393b611a
commit 607257f538
2 changed files with 59 additions and 0 deletions

View File

@ -315,6 +315,41 @@ describe('CsvBooking Entity', () => {
}); });
}); });
describe('isDeletable', () => {
it('allows deleting a booking whose commission is still unpaid', () => {
const booking = createValidBooking();
booking.status = CsvBookingStatus.PENDING_PAYMENT;
expect(booking.isDeletable()).toBe(true);
});
it.each([
// Paye : la reservation est partie chez le transporteur.
CsvBookingStatus.PENDING,
CsvBookingStatus.ACCEPTED,
CsvBookingStatus.REJECTED,
CsvBookingStatus.CANCELLED,
// Virement declare : il peut etre en cours d'acheminement.
CsvBookingStatus.PENDING_BANK_TRANSFER,
])('refuses to delete a %s booking', status => {
const booking = createValidBooking();
booking.status = status;
expect(booking.isDeletable()).toBe(false);
});
it('stops being deletable once the payment is completed', () => {
const booking = createValidBooking();
booking.status = CsvBookingStatus.PENDING_PAYMENT;
expect(booking.isDeletable()).toBe(true);
booking.markPaymentCompleted();
expect(booking.status).toBe(CsvBookingStatus.PENDING);
expect(booking.isDeletable()).toBe(false);
});
});
describe('Expiration Logic', () => { describe('Expiration Logic', () => {
it('should not be expired for recent bookings', () => { it('should not be expired for recent bookings', () => {
const booking = createValidBooking(); const booking = createValidBooking();

View File

@ -14,6 +14,12 @@ export enum CsvBookingStatus {
CANCELLED = 'CANCELLED', // User cancelled the booking CANCELLED = 'CANCELLED', // User cancelled the booking
} }
/**
* Statuts dans lesquels aucun paiement n'a ete encaisse : la reservation peut
* alors etre supprimee. Voir `CsvBooking.isDeletable()`.
*/
export const DELETABLE_STATUSES: readonly CsvBookingStatus[] = [CsvBookingStatus.PENDING_PAYMENT];
/** /**
* Document Interface * Document Interface
* *
@ -276,6 +282,24 @@ export class CsvBooking {
} }
} }
/**
* Can this booking be deleted outright?
*
* Une reservation impayee n'engage personne : elle n'est pas partie chez le
* transporteur et ne porte aucune trace comptable. La supprimer est donc sans
* consequence, la ou une reservation payee doit rester tracable et ne peut
* qu'etre annulee.
*
* `PENDING_BANK_TRANSFER` est volontairement exclu : le virement declare peut
* etre en cours d'acheminement, et supprimer la reservation priverait
* l'administration de ce qu'elle doit rapprocher a sa reception. Etendre la
* regle a ce statut est une decision comptable, pas technique : il suffirait
* de l'ajouter a `DELETABLE_STATUSES`.
*/
isDeletable(): boolean {
return DELETABLE_STATUSES.includes(this.status);
}
/** /**
* Cancel the booking (by user) * Cancel the booking (by user)
* *