From c00831a72a8883f61470c11d2225597ad7901528 Mon Sep 17 00:00:00 2001 From: gsinghpal Date: Mon, 25 May 2026 09:49:10 -0400 Subject: [PATCH] feat(quality_dashboard): sixth 'Certificates' tab (Tasks 14-16) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Counts endpoint: certificates block — open=draft, overdue=draft+>24h. Falls back to {open:0, overdue:0} when fp.certificate isn't installed. JS: TABS array gains the 6th entry. Existing data-driven OWL template auto-renders both the header tile and the body panel. Tab opens the fp.certificate kanban grouped by state, filtered to draft by default. Deep-link: setup() reads action.context.params.tab. The cert_awaiting_issuance notification email links to /odoo/action-fp_quality_dashboard?tab=certificates and lands the QM on the right tab automatically. Template: 'Open across all 5' → 'Open across all ' so it stays correct if more tabs are added later. Manifest: fusion_plating_quality 19.0.6.6.6 → 19.0.7.0.0 (fusion_plating_certificates already in depends — no change needed). Co-Authored-By: Claude Opus 4.7 (1M context) --- .../fusion_plating_quality/__manifest__.py | 2 +- .../controllers/fp_quality_dashboard.py | 10 +++++++++ .../static/src/js/fp_quality_dashboard.js | 21 +++++++++++++------ .../static/src/xml/fp_quality_dashboard.xml | 2 +- 4 files changed, 27 insertions(+), 8 deletions(-) diff --git a/fusion_plating/fusion_plating_quality/__manifest__.py b/fusion_plating/fusion_plating_quality/__manifest__.py index 4e4a0522..81c42446 100644 --- a/fusion_plating/fusion_plating_quality/__manifest__.py +++ b/fusion_plating/fusion_plating_quality/__manifest__.py @@ -5,7 +5,7 @@ { 'name': 'Fusion Plating — Quality (QMS)', - 'version': '19.0.6.6.6', + 'version': '19.0.7.0.0', 'category': 'Manufacturing/Plating', 'summary': 'Native QMS for plating shops: NCR, CAPA, calibration, AVL, FAIR, ' 'internal audits, customer specs, document control. CE + EE compatible.', diff --git a/fusion_plating/fusion_plating_quality/controllers/fp_quality_dashboard.py b/fusion_plating/fusion_plating_quality/controllers/fp_quality_dashboard.py index c0db9af7..1ec09b83 100644 --- a/fusion_plating/fusion_plating_quality/controllers/fp_quality_dashboard.py +++ b/fusion_plating/fusion_plating_quality/controllers/fp_quality_dashboard.py @@ -23,6 +23,7 @@ class FpQualityDashboardController(http.Controller): - CAPA: due_date < today AND state not in (effective, closed) - RMA: state='received' for > 5 days (triage past due) OR state in (authorised, shipped_to_us) for > 14 days + - Certificate: state='draft' for > 1 day (spec 2026-05-25) """ env = request.env today = fields.Date.context_today(env.user) @@ -33,6 +34,7 @@ class FpQualityDashboardController(http.Controller): Ncr = env['fusion.plating.ncr'] Capa = env['fusion.plating.capa'] Rma = env['fusion.plating.rma'] + Cert = env['fp.certificate'] if 'fp.certificate' in env else None d3 = fields.Datetime.subtract(now, days=3) d1 = fields.Datetime.subtract(now, days=1) @@ -87,4 +89,12 @@ class FpQualityDashboardController(http.Controller): ('create_date', '<', d14), ]), }, + # Spec 2026-05-25 — Certificates tab + 'certificates': ({ + 'open': Cert.search_count([('state', '=', 'draft')]), + 'overdue': Cert.search_count([ + ('state', '=', 'draft'), + ('create_date', '<', d1), + ]), + } if Cert is not None else {'open': 0, 'overdue': 0}), } diff --git a/fusion_plating/fusion_plating_quality/static/src/js/fp_quality_dashboard.js b/fusion_plating/fusion_plating_quality/static/src/js/fp_quality_dashboard.js index e2293336..77410153 100644 --- a/fusion_plating/fusion_plating_quality/static/src/js/fp_quality_dashboard.js +++ b/fusion_plating/fusion_plating_quality/static/src/js/fp_quality_dashboard.js @@ -13,11 +13,14 @@ import { useService } from "@web/core/utils/hooks"; import { rpc } from "@web/core/network/rpc"; const TABS = [ - { id: "holds", label: "Holds", model: "fusion.plating.quality.hold", group: "state", domain: [["state", "in", ["on_hold", "under_review"]]] }, - { id: "checks", label: "Checks", model: "fusion.plating.quality.check", group: "state", domain: [] }, - { id: "ncrs", label: "NCRs", model: "fusion.plating.ncr", group: "stage_id", domain: [["state", "!=", "closed"]] }, - { id: "capas", label: "CAPAs", model: "fusion.plating.capa", group: "state", domain: [["state", "not in", ["closed", "effective"]]] }, - { id: "rmas", label: "RMAs", model: "fusion.plating.rma", group: "stage_id", domain: [["state", "not in", ["closed", "cancelled"]]] }, + { id: "holds", label: "Holds", model: "fusion.plating.quality.hold", group: "state", domain: [["state", "in", ["on_hold", "under_review"]]] }, + { id: "checks", label: "Checks", model: "fusion.plating.quality.check", group: "state", domain: [] }, + { id: "ncrs", label: "NCRs", model: "fusion.plating.ncr", group: "stage_id", domain: [["state", "!=", "closed"]] }, + { id: "capas", label: "CAPAs", model: "fusion.plating.capa", group: "state", domain: [["state", "not in", ["closed", "effective"]]] }, + { id: "rmas", label: "RMAs", model: "fusion.plating.rma", group: "stage_id", domain: [["state", "not in", ["closed", "cancelled"]]] }, + // Spec 2026-05-25 — Certificates tab. QM-owned queue of certs + // awaiting issuance; drives the post-shop awaiting_cert workflow. + { id: "certificates", label: "Certificates", model: "fp.certificate", group: "state", domain: [["state", "=", "draft"]] }, ]; export class FpQualityDashboard extends Component { @@ -26,8 +29,14 @@ export class FpQualityDashboard extends Component { setup() { this.action = useService("action"); + // Spec 2026-05-25 — honor ?tab= deep-link from the + // cert_awaiting_issuance notification email so the QM lands + // directly on the Certificates tab. + const tabParam = this.props.action?.context?.params?.tab + || this.props.action?.params?.tab; + const validTab = TABS.find(t => t.id === tabParam); this.state = useState({ - activeTab: "ncrs", + activeTab: validTab ? validTab.id : "ncrs", counts: TABS.reduce((acc, t) => ({ ...acc, [t.id]: { open: 0, overdue: 0 } }), {}), }); diff --git a/fusion_plating/fusion_plating_quality/static/src/xml/fp_quality_dashboard.xml b/fusion_plating/fusion_plating_quality/static/src/xml/fp_quality_dashboard.xml index 39b0f8af..e668a809 100644 --- a/fusion_plating/fusion_plating_quality/static/src/xml/fp_quality_dashboard.xml +++ b/fusion_plating/fusion_plating_quality/static/src/xml/fp_quality_dashboard.xml @@ -8,7 +8,7 @@

Quality Overview

-
Open across all 5
+
Open across all