Files
Odoo-Modules/fusion_helpdesk_central/models/helpdesk_ticket.py
gsinghpal d7ec91b0f1 feat(fusion_helpdesk): Critical flag, KPI cards, colored stage pills
Three coordinated changes on top of the section grouping:

1. **Mark as Critical** — a red chip on the New tab sets priority='3'
   when submitted. The central post-create hook auto-applies a "Critical"
   helpdesk.tag (shipped via fusion_helpdesk_central data XML, noupdate=1
   so support can recolor without losing it on upgrade), giving support
   a kanban-groupable signal that doesn't rely on remembering what
   priority='3' means. Scoped to in-app-channel tickets only, so a
   support agent manually setting Urgent on their own ticket isn't
   silently tagged.

2. **KPI cards above the sections** — Total / Open / Closed / Critical
   in a 4-up grid (auto-collapses to 2x2 under 540px). Each card uses
   its own saturated gradient so it reads on both light and dark mode —
   the dialog backdrop is irrelevant because the gradient brings its
   own background. Counts are computed in JS from state.tickets so they
   always match what's rendered below.

3. **Colored stage pills** — red Critical, green Solved, dark-yellow New,
   orange Cancelled, blue for In Progress / Testing / On Hold. Critical
   priority gets a *separate* red pill alongside the stage pill so you
   keep stage info even on escalated tickets. Stage matching is
   substring-based (lowercased) so a renamed "Resolved" or "Done" stage
   on central still maps to the green pill.

Tests cover the new is_critical=True → priority='3' wiring and the
default omission so SLA / stage defaults keep working for normal
tickets. Bumps fusion_helpdesk to 19.0.1.7.0 and
fusion_helpdesk_central to 19.0.1.2.0. End-to-end smoke test verified
live: priority=3 + x_fc_client_label triggers the Critical tag.
2026-05-27 11:21:11 -04:00

84 lines
3.3 KiB
Python

# -*- coding: utf-8 -*-
# Copyright 2026 Nexa Systems Inc.
# License OPL-1
"""Central-side helpdesk.ticket extensions for the customer follow-up flow.
Adds the `x_fc_client_label` deployment tag (set by the in-app reporter so
the embedded inbox can scope per client) and sends a branded acknowledgement
email — carrying the portal magic link — when an in-app ticket is created.
"""
import logging
from odoo import api, fields, models
_logger = logging.getLogger(__name__)
class HelpdeskTicket(models.Model):
_inherit = 'helpdesk.ticket'
x_fc_client_label = fields.Char(
string='Client Deployment', index=True, copy=False,
help='Deployment tag (e.g. ENTECH) set by the fusion_helpdesk in-app '
'reporter. Scopes the embedded "My Tickets" inbox per client and '
'lets support filter tickets by originating deployment.',
)
@api.model_create_multi
def create(self, vals_list):
tickets = super().create(vals_list)
tickets._fc_send_ack_email()
tickets._fc_auto_tag_critical()
return tickets
def _fc_auto_tag_critical(self):
"""Auto-apply the Critical tag on in-app tickets that were filed with
priority='3' (Urgent — the client-side "Mark as Critical" toggle).
Scoped to tickets carrying `x_fc_client_label` so support staff who
manually set priority='3' on their own internal tickets aren't
silently tagged. Best-effort: if the data XML hasn't loaded the tag
yet (e.g. partial install), skip without raising — the ticket is
already filed with priority='3' which is the load-bearing signal."""
critical = self.filtered(
lambda t: t.priority == '3' and t.x_fc_client_label
)
if not critical:
return
tag = self.env.ref(
'fusion_helpdesk_central.tag_critical', raise_if_not_found=False,
)
if not tag:
_logger.warning(
'fusion_helpdesk_central: tag_critical not found, skipping '
'auto-tag on %s critical ticket(s).', len(critical),
)
return
critical.write({'tag_ids': [(4, tag.id)]})
def _fc_send_ack_email(self):
"""Send the branded acknowledgement (with magic link) to the customer.
Only fires for in-app-channel tickets (those tagged with a client
label) that have a customer email — external web-form submissions
rely on the native website confirmation, so this won't double-send.
The whole thing is best-effort: a template/mail failure must never
block ticket creation, so we log and move on.
"""
template = self.env.ref(
'fusion_helpdesk_central.mail_template_ticket_ack',
raise_if_not_found=False,
)
if not template:
return
for ticket in self:
if not (ticket.x_fc_client_label and ticket.partner_email):
continue
try:
template.send_mail(ticket.id, force_send=False)
except Exception: # noqa: BLE001 — ack must never block create
_logger.exception(
'fusion_helpdesk_central: acknowledgement email failed '
'for ticket %s (%s)', ticket.id, ticket.x_fc_client_label,
)