diff --git a/fusion_helpdesk_central/__manifest__.py b/fusion_helpdesk_central/__manifest__.py index 5ac063e2..f116394a 100644 --- a/fusion_helpdesk_central/__manifest__.py +++ b/fusion_helpdesk_central/__manifest__.py @@ -3,7 +3,7 @@ # License OPL-1 { 'name': 'Fusion Helpdesk Central — Client API Keys', - 'version': '19.0.2.3.2', + 'version': '19.0.2.3.3', 'category': 'Productivity', 'summary': 'Admin UI on the central Odoo for issuing per-client API ' 'keys used by fusion_helpdesk client deployments.', diff --git a/fusion_helpdesk_central/models/engagement_wizard.py b/fusion_helpdesk_central/models/engagement_wizard.py index d6b03d4a..c4e3f6af 100644 --- a/fusion_helpdesk_central/models/engagement_wizard.py +++ b/fusion_helpdesk_central/models/engagement_wizard.py @@ -117,10 +117,23 @@ class FusionHelpdeskEngagementWizard(models.TransientModel): def default_get(self, fields_list): vals = super().default_get(fields_list) ctx = self.env.context or {} - ticket_id = ctx.get('default_ticket_id') or ctx.get('active_id') - ticket_ids = ctx.get('default_ticket_ids') or ctx.get('active_ids') or [] active_model = ctx.get('active_model') + # ONLY trust active_id/active_ids when active_model says they're + # helpdesk tickets. Without this guard, opening the wizard via any + # act_window that left an unrelated active_id in context (e.g. a + # button on the wizard returning a re-open action whose res_id is + # the wizard's OWN id) silently reinterprets that id as a ticket + # — and `_default_get_single` then raises "Ticket N no longer + # exists" against the wizard's own id. The explicit + # `default_ticket_id[s]` context keys are still the strong signal. + ticket_id = ctx.get('default_ticket_id') + if not ticket_id and active_model == 'helpdesk.ticket': + ticket_id = ctx.get('active_id') + ticket_ids = ctx.get('default_ticket_ids') or [] + if not ticket_ids and active_model == 'helpdesk.ticket': + ticket_ids = ctx.get('active_ids') or [] + # Disambiguate single vs bulk by what the caller actually selected. # The list-view server action passes active_ids; the form button # passes a single active_id via a deliberate context key. @@ -318,8 +331,12 @@ class FusionHelpdeskEngagementWizard(models.TransientModel): # ------------------------------------------------------------------ def action_generate_summary(self): """Single mode: fire OpenAI with the current findings, drop the - result into ai_summary. Returns an action to keep the wizard open - (replaces the current view instead of closing it). + result into ai_summary. Returns True (no navigation) so the + wizard stays open and the form view re-renders with the new + summary populated. DO NOT return an `act_window` with + `res_id=self.id` here — that puts the WIZARD's id into the new + action's `active_id`, which then collides with default_get's + ticket lookup and raises "Ticket no longer exists". """ self.ensure_one() if self.mode != 'single' or not self.ticket_id: @@ -332,18 +349,15 @@ class FusionHelpdeskEngagementWizard(models.TransientModel): ) self.ai_summary = summary self.ai_unavailable = not bool(summary) - return { - 'type': 'ir.actions.act_window', - 'res_model': 'fusion.helpdesk.engagement.wizard', - 'res_id': self.id, - 'view_mode': 'form', - 'target': 'new', - } + return True def action_generate_all_summaries(self): """Bulk mode: fire OpenAI per-ticket in parallel using each line's own findings. Lines that already have a non-empty ai_summary get regenerated too (the user clicked the button — they meant it). + + Returns True for the same reason as action_generate_summary: + keep the dialog open; don't re-navigate. """ self.ensure_one() if self.mode != 'bulk' or not self.line_ids: @@ -359,13 +373,7 @@ class FusionHelpdeskEngagementWizard(models.TransientModel): line.ai_summary = results.get(line.ticket_id.id, '') any_ok = any(results.values()) self.ai_unavailable = not any_ok - return { - 'type': 'ir.actions.act_window', - 'res_model': 'fusion.helpdesk.engagement.wizard', - 'res_id': self.id, - 'view_mode': 'form', - 'target': 'new', - } + return True # ------------------------------------------------------------------ # Send: write engagement state + queue mail