Files
Odoo-Modules/fusion_plating/docs/superpowers/specs/2026-06-04-so-job-quality-smart-buttons-design.md
gsinghpal c9eb61ee0c feat(plating): hide quality smart buttons at zero + order-scope NCR/CAPA counts
On the sale.order and fp.job forms, the Holds/Checks/NCRs/CAPAs/RMAs quality
smart buttons (and the SO WO button) now hide when their count is 0, so the row
shows only quality work that exists. NCR and CAPA counts are re-scoped from
customer-wide to order/job via a shared _fp_quality_ncr_ids() helper (NCRs
reached through the order's RMAs + the order/job's holds), so each badge and the
list its button opens always agree. Also aligned the job RMA button's list
domain to its (already SO-scoped) count.

Reverts the Sub-12 Phase D "always-visible (zero is OK)" choice back to the
module's documented hide-at-zero convention.

- fusion_plating_quality 19.0.8.1.0 -> 19.0.8.2.0
- fusion_plating_jobs    19.0.12.4.0 -> 19.0.12.5.0

Deployed + verified on entech (badge == helper across sampled SOs/jobs).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-04 20:36:54 -04:00

4.8 KiB

Sale Order + Job Quality Smart Buttons — hide-at-zero + order-scoped counts

Date: 2026-06-04 Modules: fusion_plating_quality, fusion_plating_jobs Status: approved (brainstorming sign-off)

Problem

The sale.order form shows eight Fusion Plating smart buttons: Receiving, WO, Certificates, Holds, Checks, NCRs, CAPAs, RMAs. On a typical order only three carry data (Receiving / WO / Certificates) yet six of the eight render permanently — five quality buttons (Holds / Checks / NCRs / CAPAs / RMAs) and the WO button all show even at a count of zero. The row reads as noise.

Two of those counts are also wrong on an order:

  • NCRs counts the entire customer's NCR history (customer_partner_id == partner), not this order's. A repeat customer's brand-new order shows "NCRs 5".
  • CAPAs counts the CAPAs under those customer-wide NCRs — same over-count.

This contradicts the module's own documented smart-button convention ("don't add a button that always shows zero… NCRs/RMAs visible only when present"). The Sub-12 Phase D plan that introduced these buttons chose "always visible (zero is OK)"; this spec reverts to the convention.

The identical button row + identical over-count exists on the fp.job form and is fixed in the same change.

Decision

  1. Hide every quality button when its count is 0, on both the sale.order and fp.job forms. Also hide the WO button at 0. (Receiving and Certificates already hide at 0 — untouched.)
  2. Re-scope the NCR and CAPA counts to the order/job, dropping the customer-wide union. Use only the real order-linked paths.

Order-scoped NCR set

There is no direct ncr.sale_order_id or ncr.job_id field. The only honest paths from an order to its NCRs (confirmed by model inspection) are:

  • RMA path: SO → its RMAs (rma.sale_order_id) → NCRs (ncr.rma_id).
  • Hold path: SO → its jobs (fp.job.sale_order_id) → holds (hold.job_id) → the NCR a hold spawned (hold.ncr_id).

NCR set = union of those two. CAPA set = CAPAs whose ncr_id is in that set.

For the fp.job form the same definition applies, narrowed to the one job: the job's SO's RMAs' NCRs, plus this job's holds' NCRs.

Trade-off accepted: an NCR raised with neither an RMA nor a hold link (e.g. a QA team logs one directly against the customer) no longer appears on any order or job. That is correct — such an NCR has no order/job linkage to honestly attach it to, and surfacing it on every one of the customer's orders was the bug.

Changes

fusion_plating_quality

  • models/fp_quality_smart_buttons.py
    • Add sale.order._fp_quality_ncr_ids() and fp.job._fp_quality_ncr_ids() helpers returning the order/job-scoped NCR id list (single source of truth).
    • Rewrite both _compute_* methods to set the NCR count from the helper and the CAPA count from [('ncr_id', 'in', <helper>)]. Holds / Checks / RMAs counts are already correctly scoped — leave them.
    • Point action_view_fp_ncrs, action_view_fp_ncrs_so, and both action_view_fp_capas at the helper-derived ids so each opened list matches its badge.
    • Narrow fp.job.action_view_fp_rmas from SO-OR-partner to SO-only so the RMA list matches its (already SO-scoped) badge count (caught in review — the SO form's RMA button already agreed).
  • views/fp_quality_smart_button_views.xml — add invisible="<count> == 0" to the five SO quality buttons.
  • __manifest__.py — version 19.0.8.1.019.0.8.2.0.

fusion_plating_jobs

  • views/fp_job_quality_buttons.xml — add invisible="<count> == 0" to the five job-form quality buttons.
  • views/sale_order_views.xml — add invisible="x_fc_fp_job_count == 0" to the WO smart button; update the now-stale "always visible" comment.
  • __manifest__.py — version 19.0.12.4.019.0.12.5.0.

Docs

  • fusion_plating/CLAUDE.md — short note in the smart-button section recording that the SO/job quality buttons are hide-at-zero with order-scoped NCR/CAPA counts as of 2026-06-04 (reconciling the Sub-12 "always visible" record).

Out of scope

  • The res.partner "Quality History" button stays as-is. It is customer-wide by design, and the user opted not to touch it.
  • No schema changes, no migration — pure view attributes + non-stored compute logic over existing fields.

Verification

The plating modules cannot be installed on the local Community dev DB (enterprise deps). Verification is:

  1. Static: pyflakes on the edited .py; lxml parse on each edited .xml.
  2. Behavioural (read-only, on an entech clone/shell): for a sample SO and job, confirm the new helper returns only RMA-/hold-linked NCRs and that the counts match, with env.cr.rollback() at the end.
  3. Deploy to entech via the revert-on-failure guard only after the above pass and with the owner's go-ahead (live client box).