Operators can now see and advance a job's parts across multiple stages
at once (e.g. 10 Masking / 20 Plating / 20 Baking on one 50-part job).
Tracking model C (fluid per-stage quantities + existing hold/scrap/
rework records for exceptions); board option 2 (a card per occupied
stage); wait-to-reconverge close. Additive only — no new model, no
migration, no change to the close/cert/ship lifecycle.
Board (fusion_plating_shopfloor/controllers/plant_kanban.py):
- One card PER (job, stage), composite key "{job_id}:{area}". Unsplit
jobs render exactly as before. _job_presences/_render_presence;
primary presence keeps full job card_state, secondary presences
derive state from their focus step.
Card (plant_card.js/.xml/.scss):
- "20 of 50 here" badge; tap opens the workspace focused on that
stage's step (focus_step_id, already accepted by the workspace).
Move + light-up (move_controller.py, fusion_plating_jobs/fp_job_step.py):
- Availability/pre-fill now from qty_at_step (step had no qty_done/
qty_scrapped fields — the old read was always 0, dead path).
- Forward move auto-flips destination pending->ready (no auto-start;
labour timer stays explicit) and auto-finishes a drained source
(best-effort). Predecessor gate is qty-aware: a step with real
arrived parts is startable regardless of upstream completion
(_fp_has_real_incoming, single source of truth for can_start /
blocker / button_start / move blockers).
Operator advance (job_workspace.js):
- "Send -> <next>" action on in_progress/paused steps opens the slimmed
Move dialog (qty steppers, no keyboard; advanced fields collapsed).
Was only wired into the deprecated shopfloor_tablet before.
Close (fp_job.py):
- button_mark_done counts move-based scrap (_fp_scrapped_via_moves) into
qty_scrapped and derives qty_done = qty - scrapped (was blindly
= job.qty, over-counting). Reconciliation gate unchanged.
Static-validated: pyflakes (py), lxml parse (xml), node --check (js).
Dynamic tests + browser check need an installed env (entech/trial) —
plating modules can't install on the local Community DB.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Fusion Plating
Core module of the Fusion Plating product family. A configurable, multi-tenant capable ERP for plating and metal-finishing shops, built for Odoo 19 Community and Enterprise.
Copyright © 2026 Nexa Systems Inc. License: OPL-1 (Odoo Proprietary License v1.0)
What this module is
fusion_plating is the process-agnostic foundation that every plating or
metal-finishing shop needs, regardless of size, jurisdiction, process mix, or
industry. It provides:
- Facility — physical sites with their own tanks, operators, capabilities
- Process Type — extensible taxonomy (filled in by process packs)
- Work Center — lines and stations inside a facility
- Tank — physical vessel with QR code, state, bath history
- Bath — the chemistry currently in a tank, with its own lifecycle
- Bath Parameter — schema for chemistry readings
- Bath Log — daily/per-shift chemistry readings with pass/warn/fail rollup
- Security — Operator / Supervisor / Manager / Administrator roles
- Theme-aware UI — respects Odoo light/dark mode with zero duplication
What this module is not
This core intentionally ships with:
- No process chemistry — install
fusion_plating_process_en,_chrome,_anodize,_black_oxideetc. to get actual process types and their bath parameter schemas. - No regulatory data — install
fusion_plating_compliance_<region>to get jurisdiction-specific limits, forms, and reporting workflows. - No industry specialisations — install
fusion_plating_aerospace,_nuclear,_cgpetc. for industry-specific QMS overlays. - No client-specific strings — everything is data-driven.
Product family
| Module | Purpose | Status |
|---|---|---|
fusion_plating |
Core (this module) | MVP |
fusion_plating_quality |
QMS: NCR, CAPA, doc control, calibration, CoC | planned |
fusion_plating_compliance |
Generic compliance framework | planned |
fusion_plating_compliance_on |
Ontario regulatory pack | planned |
fusion_plating_compliance_tor |
Toronto Ch. 681 municipal pack | planned |
fusion_plating_safety |
SDS, WHMIS/TDG, JHSC, exposure | planned |
fusion_plating_shopfloor |
Tablet operator stations, QR scanning, bake-window enforcer | planned |
fusion_plating_portal |
Customer portal | planned |
fusion_plating_process_en |
Electroless nickel — low/mid/high phos | planned |
fusion_plating_process_chrome |
Chrome coating (hex & trivalent) | planned |
fusion_plating_process_anodize |
Aluminum anodizing (Type II, III) | planned |
fusion_plating_process_black_oxide |
Black oxidizing | planned |
fusion_plating_aerospace |
AS9100 + Nadcap AC7108 | planned |
fusion_plating_nuclear |
CSA N299, CNSC, NQA-1 | planned |
fusion_plating_cgp |
Controlled Goods Program | planned |
fusion_plating_logistics |
Pickup & delivery routing | planned |
fusion_plating_culture |
Values / fundamentals framework | planned |
fusion_plating_bridge_sign |
EE bridge: e-sign CoC acceptance | planned |
fusion_plating_bridge_documents |
EE bridge: Documents workspace | planned |
fusion_plating_bridge_quality |
EE bridge: native quality module |
planned |
Installation
# Development
docker exec odoo-dev-app odoo -d fusion-dev -u fusion_plating --stop-after-init
# Production — after rsync to target server
docker exec <odoo-container> odoo -d <db> -u fusion_plating --stop-after-init
No external Python dependencies. Depends only on standard Odoo 19 Community
base modules (base, mail, contacts, product, stock, sale_management,
purchase, hr, uom).
Design principles
- Works on both Odoo Community and Enterprise. Never depends on
quality,documents,sign,studio, ormrp_plm. EE-specific integrations live in separatefusion_plating_bridge_*modules. - No client-specific strings in core. Configuration, not code.
- Regions are data, not code. Sewer limits, waste classes, reporting forms come from region packs.
- Processes are plug-ins. New process (copper, zinc, tin) = new
fusion_plating_process_*module, core untouched. - Dashboards are configured, not coded. Shops pick their own headline KPIs.
- Theme-aware. Uses Odoo/Bootstrap CSS variables. One source of truth for colours; Odoo's theme engine decides light vs dark.
Security groups
| Group | Intended for |
|---|---|
| Operator | Shop-floor staff. Reads reference data, writes chemistry logs. |
| Supervisor | Line supervisors. Manages baths, schedules jobs, reviews logs. |
| Manager | Quality, EHS, plant manager, engineer. Full CRUD on configuration. |
| Administrator | Owner, system admin. All manager rights + system settings. |
Field naming convention
- New models use
fusion.plating.*namespace. - Fields on our own models use simple names (no prefix).
- Fields added to base Odoo models (
res.company,res.partner,product.template, etc.) use thex_fc_prefix per the repo convention.
Developer notes
- All models inheriting from
mail.threaduse the Odoo 19 chatter pattern. - Security follows the Odoo 19
res.groups.privilegepattern (module category → privilege → groups), not the legacycategory_id-on-group pattern. - Sequence numbers use
ir.sequenceseeded indata/fp_sequence_data.xml. - SCSS uses
color-mix()against CSS custom properties — never hardcodes hex values. Seestatic/src/scss/fusion_plating.scssfor the theming contract. - No
group expand="0"in search views (Odoo 19 incompatibility). - No
category_idorusersfield onres.groups(Odoo 19 incompatibility).