fix(fusion_helpdesk_central): wizard dialog closed on Generate Summary click

Previous fix (return True from action_generate_summary) prevented the
self-id crash but introduced a worse regression: Odoo's web client
auto-closes target='new' modals on any non-action return — the
"wizard done" convention. So Generate Summary updated the field and
then immediately killed the dialog, leaving the user with no chance
to click Send Engagement.

The only Odoo-19 idiom that reliably keeps a wizard dialog open
across a button click is to return an act_window dict that re-opens
the same wizard record (res_id=self.id). That was the original
approach — it crashed because of the active_id self-id collision in
default_get. With the active_model='helpdesk.ticket' guard now in
place (from 0104e877), the re-open is safe.

Belt-and-suspenders: the re-open action passes context={} explicitly,
so even if a future change to default_get drops the active_model
guard, there's no parent-form active_id leaking in to confuse the
ticket lookup. The wizard record is loaded by res_id directly; Odoo
19 doesn't call default_get for record loads, only for new-record
creation.

Centralised the re-open logic in _reopen_action so single + bulk
modes share the same code path.

Bumps fusion_helpdesk_central to 19.0.2.3.4.
This commit is contained in:
gsinghpal
2026-05-27 15:12:33 -04:00
parent f19ca02e05
commit 76866a7c76
2 changed files with 36 additions and 14 deletions

View File

@@ -3,7 +3,7 @@
# License OPL-1
{
'name': 'Fusion Helpdesk Central — Client API Keys',
'version': '19.0.2.3.3',
'version': '19.0.2.3.4',
'category': 'Productivity',
'summary': 'Admin UI on the central Odoo for issuing per-client API '
'keys used by fusion_helpdesk client deployments.',

View File

@@ -331,12 +331,16 @@ class FusionHelpdeskEngagementWizard(models.TransientModel):
# ------------------------------------------------------------------
def action_generate_summary(self):
"""Single mode: fire OpenAI with the current findings, drop the
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 <wizard_id> no longer exists".
result into ai_summary. Returns an act_window dict that re-opens
the SAME wizard record — the only Odoo-19 idiom that reliably
keeps a target='new' wizard dialog open after a button click.
Returning True/None auto-closes the modal (Odoo's "wizard done"
convention).
The previous self-id collision bug (where active_id of the
re-opened action was the wizard's own id, which default_get
mis-read as a ticket id) is now prevented by default_get's
active_model=='helpdesk.ticket' guard.
"""
self.ensure_one()
if self.mode != 'single' or not self.ticket_id:
@@ -349,15 +353,12 @@ class FusionHelpdeskEngagementWizard(models.TransientModel):
)
self.ai_summary = summary
self.ai_unavailable = not bool(summary)
return True
return self._reopen_action()
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.
own findings. Returns an act_window dict to keep the dialog open
(see action_generate_summary for why we can't just return True).
"""
self.ensure_one()
if self.mode != 'bulk' or not self.line_ids:
@@ -373,7 +374,28 @@ 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 True
return self._reopen_action()
def _reopen_action(self):
"""Return the act_window dict that re-opens the same wizard record.
Passes an EXPLICITLY EMPTY context override so the parent ticket
form's active_id / active_model don't leak in and confuse any
future default_get call. The wizard record is loaded directly by
res_id; default_get won't be called for a load (Odoo 19 only
invokes it when creating new records), but the empty context is
belt-and-suspenders against future regressions.
"""
self.ensure_one()
return {
'type': 'ir.actions.act_window',
'name': _('Request Owner Approval'),
'res_model': self._name,
'res_id': self.id,
'view_mode': 'form',
'target': 'new',
'context': {},
}
# ------------------------------------------------------------------
# Send: write engagement state + queue mail