From 02c7627a3ef1c1799cb7dd66a74235ade215a879 Mon Sep 17 00:00:00 2001 From: DarioLodeiros Date: Sun, 24 May 2026 09:50:00 +0200 Subject: [PATCH] [FIX] pms: skip cancel-by-modification reservations on confirm_all_reservations pms.folio.action_confirm() called with confirm_all_reservations=True in the context unconditionally re-confirms every reservation of the folio, including those previously cancelled. This is problematic for reservations cancelled because of a modification chain (state='cancel', cancelled_reason='modified'): re-confirming them re-occupies the room of a superseded version of the same booking and triggers a ValidationError from _compute_avail_id ("There is no availability for the room type X on YYYY-MM-DD") even though the booking itself is consistent. Skip those historical artefacts. Other cancelled reservations (cancelled_reason in late/intime/noshow, or empty) keep being re-confirmed: those represent cases where an external system cancels and later re-confirms the same booking, and the caller of confirm_all_reservations=True expects them to come back to life. Today this flag is set only by an external channel-manager connector import path, so the blast radius of the change is contained. --- pms/models/pms_folio.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/pms/models/pms_folio.py b/pms/models/pms_folio.py index 0a06b9f81b..9c521b5fcc 100644 --- a/pms/models/pms_folio.py +++ b/pms/models/pms_folio.py @@ -1673,7 +1673,12 @@ def action_confirm(self): ) if self.env.context.get("confirm_all_reservations"): - self.reservation_ids.action_confirm() + # Skip reservations cancelled because of a modification: re-confirming + # them would re-occupy the room of a superseded version of the same + # booking and trigger spurious availability errors. + self.reservation_ids.filtered( + lambda r: not (r.state == "cancel" and r.cancelled_reason == "modified") + ).action_confirm() return True