Files
Odoo-Modules/fusion-plating/CLAUDE.md
gsinghpal 2b84c31a12 CLAUDE.md: comprehensive workflow status — 12/15 stages built, 3 gaps remain
Full ASCII diagram of the end-to-end lifecycle with [DONE] / [NOT BUILT]
tags. Key models quick reference table. 3 remaining gaps: Recipe→WO
generation, account hold check, auto-email package. Architectural
decisions documented for next session.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 16:05:08 -04:00

277 lines
17 KiB
Markdown

# Fusion Plating — Claude Code Instructions
## Project
Fusion Plating is a multi-module Odoo 19 ERP for electroless nickel plating and metal finishing shops. Built by Nexa Systems for EN Technologies (the client). Replaces Steelhead Software.
## Module Structure
```
fusion_plating/ — Core: facilities, process types, tanks, baths, chemistry, recipes
fusion_plating_shopfloor/ — Tablet UI, plant overview kanban, process tree visualization
fusion_plating_portal/ — Customer portal
fusion_plating_reports/ — PDF reports (WO margin, discharge sample, etc.)
fusion_plating_compliance/ — Compliance framework, jurisdictions
fusion_plating_aerospace/ — AS9100 / Nadcap
fusion_plating_nuclear/ — CSA N299 / CNSC
fusion_plating_cgp/ — Controlled Goods Program
fusion_plating_safety/ — SDS, WHMIS, JHSC
fusion_plating_quality/ — QMS (NCR, CAPA, calibration)
fusion_plating_logistics/ — Pickup & delivery
fusion_plating_culture/ — Values / fundamentals
fusion_plating_bridge_mrp/ — MRP integration (extends mrp.workorder)
fusion_plating_bridge_sign/ — Digital signatures
fusion_plating_bridge_quality/ — Quality bridge
fusion_plating_process_en/ — Electroless nickel process pack
fusion_plating_process_chrome/ — Chrome process pack
fusion_plating_process_anodize/ — Anodizing process pack
fusion_plating_process_black_oxide/ — Black oxide process pack
```
## Critical Rules — Odoo 19
1. **NEVER code from memory** — Read reference files from the server first.
2. **Backend OWL**: `static template`, `static props = ["*"]`, standalone `rpc()` from `@web/core/network/rpc`. NOT `useService("rpc")`.
3. **HTTP routes**: `type="jsonrpc"` — NOT `type="json"` (deprecated in Odoo 19).
4. **Search views**: NO `group expand="0"`, NO `string` attribute on `<search>`, NO `<group string="...">` wrapper for group-by filters.
5. **res.config.settings**: Only boolean/integer/float/char/selection/many2one/datetime. NO Date fields.
6. **Field params**: `parent_path` does NOT accept `unaccent` parameter in Odoo 19.
7. **SCSS borders**: Use `$border-color` (SCSS variable) for card borders, NOT `color-mix()` in border shorthand — the SCSS compiler drops it. `color-mix()` works fine in `background-color`, `box-shadow`, etc.
8. **Theme awareness**: All colours must use CSS custom properties (`var(--bs-body-bg)`, `var(--bs-body-color)`, `var(--bs-border-color)`, `var(--bs-secondary-color)`, `var(--o-action)`). NO hardcoded hex. See `fusion_plating_shopfloor.scss` as the gold standard.
## Naming
- New fields on **custom models**: standard names (no prefix needed)
- New fields on **standard Odoo models**: `x_fc_*` prefix
- Legacy fields: `x_studio_*`
- Canadian English for all user-facing text
- SCSS class prefix: `o_fp_*` (shopfloor: `o_fp_po_*`, `o_fp_pt_*`; recipes: `o_fp_recipe_*`)
## Process Recipe System (NEW — v19.0.2.x)
**Model**: `fusion.plating.process.node` (in `fusion_plating` core)
- Hierarchical tree with `_parent_store = True`
- Node types: `recipe`, `sub_process`, `operation`, `step`
- Companion model: `fusion.plating.process.node.input` (operator inputs)
- `icon` is a Selection field (24 curated plating icons), NOT a Char
- Auto-icon: JS `guessIcon(name)` maps keywords → icons when adding nodes
- OWL tree editor: registered as `fp_recipe_tree_editor` client action
- Controller: `fusion_plating/controllers/recipe_controller.py` (7 endpoints)
- SCSS: `fusion_plating/static/src/scss/recipe_tree_editor.scss`
### Recipe Endpoints
```
POST /fp/recipe/tree — full nested tree for OWL editor
POST /fp/recipe/node/create — add child node
POST /fp/recipe/node/write — update fields
POST /fp/recipe/node/unlink — delete + cascade
POST /fp/recipe/node/reorder — bulk sequence update
POST /fp/recipe/node/move — change parent_id
POST /fp/recipe/duplicate — deep-copy recipe
```
### Steelhead Features Status
| Feature | Status |
|---------|--------|
| Hierarchical process tree | Done |
| Node types (recipe/sub/op/step) | Done |
| Auto-complete flag | Done |
| Customer visible flag | Done |
| Manual/automated flag | Done |
| Requires sign-off | Done |
| Opt In/Out (disabled/opt-in/opt-out) | Done |
| Icon picker | Done |
| Time tracking (created/updated with seconds) | Done |
| Operator inputs | Done |
| Description (rich text) | Done |
| File attachments (via mail.thread) | Done |
| OWL tree editor with drag-drop | Done |
| Tags | Not yet |
| Dashboard Transitions | Not yet |
| Treatment Groups / Choices | Not yet |
| Go To Node Options | Not yet |
| Spec Fields | Not yet |
### Client Recipes Created
- `ENP-ALUM-BASIC` — Electroless Nickel Plating Aluminium Basic (9 operations, 15 steps). Data file: `fusion_plating/data/fp_recipe_enp_alum_basic.xml`
## Plant Overview Dashboard
- OWL client action: `fp_plant_overview` in `fusion_plating_shopfloor`
- Kanban columns = work centres, cards = active `mrp.workorder` records
- Drag & drop between columns (writes `workcenter_id` on the work order)
- Endpoint: `POST /fp/shopfloor/plant_overview`
- Move endpoint: `POST /fp/shopfloor/plant_overview/move_card`
- Auto-refreshes every 30s
## Deployment
### odoo-entech (LXC 111 on pve-worker5)
- **Type**: Native Odoo (apt package, NOT Docker)
- **IP**: 10.200.1.26
- **DB**: `admin` (PostgreSQL local, user `odoo`)
- **Config**: `/etc/odoo/odoo.conf`
- **Addons**: `/mnt/extra-addons/custom/` (fusion_plating modules live here)
- **Service**: `systemctl {start|stop|restart} odoo`
- **Update command**:
```bash
ssh pve-worker5 "pct exec 111 -- bash -c 'systemctl stop odoo && su - odoo -s /bin/bash -c \"/usr/bin/odoo -c /etc/odoo/odoo.conf -d admin -u MODULE_NAME --stop-after-init\" && systemctl start odoo'"
```
- **Copy files**: `cat LOCAL_FILE | ssh pve-worker5 "pct exec 111 -- bash -c 'cat > /mnt/extra-addons/custom/REMOTE_PATH'"`
- **IMPORTANT**: Must pass `-c /etc/odoo/odoo.conf` or Odoo won't find the repackaged enterprise addons
### odoo-trial (VM 316 on pve-worker1)
- **Type**: Docker (container `odoo-trial-app`, db `odoo-trial-db`)
- **DB**: `trial` (user `odoo`)
- **Host addons path**: `/opt/odoo/custom-addons/` → mounts as `/mnt/extra-addons/` in Docker
- **Docker network**: `odoo_odoo-network`
- **Copy files** (base64 pipe through qm guest exec):
```bash
B64=$(base64 -w0 "LOCAL_FILE")
ssh pve-worker1 "qm guest exec 316 -- bash -c 'echo $B64 | base64 -d > /opt/odoo/custom-addons/REMOTE_PATH'"
```
- **Clear asset cache** (required after SCSS/JS changes):
```bash
ssh pve-worker1 "qm guest exec 316 -- bash -c \"docker exec odoo-trial-db psql -U odoo -d trial -c \\\"DELETE FROM ir_attachment WHERE url LIKE '%/web/assets/%';\\\"\""
```
- **Update command**:
```bash
ssh pve-worker1 "qm guest exec 316 -- bash -c 'docker stop odoo-trial-app && docker run --rm --network odoo_odoo-network -v odoo_odoo-data:/var/lib/odoo -v /opt/odoo/custom-addons:/mnt/extra-addons -v /opt/odoo/enterprise-addons:/mnt/enterprise-addons -v /opt/odoo/odoo.conf:/etc/odoo/odoo.conf odoo:19 odoo -d trial -u MODULE_NAME --stop-after-init && docker start odoo-trial-app'"
```
### Git Push
```bash
cd K:/Github/Odoo-Modules/fusion-plating && git push origin main
```
Pushes to both GitHub and Gitea (nexasystems.ca) via multiple remotes.
## Supabase Knowledge Base
Project: `nexasystems` (id: `ikvdlqkbqsitabxidvnq`)
- `fusionapps.decisions` — past architecture decisions
- `fusionapps.issues` — known issues and fixes
- `fusionapps.code_snippets` — reference code
- `fusionapps.quick_commands` — deployment and admin commands
- `fusionapps.vm_registry` — VM inventory
- `fusionapps.proxmox_nodes` — cluster node specs
## End-to-End Business Workflow
### Full Lifecycle (What Exists Today)
```
┌─ QUOTATION ──────────────────────────────────────────────────────┐
│ 1. Customer submits RFQ on portal [DONE] │
│ → FpQuoteRequest (state: new → under_review → quoted) │
│ → Model: fusion_plating_portal/models/fp_quote_request.py │
│ │
│ 2. Customer accepts → "Create Sale Order" button [DONE] │
│ → action_create_sale_order() creates SO with lines │
│ → Links SO origin back to RFQ ref │
│ │
│ 3. SO confirmed → MRP creates Manufacturing Order [DONE] │
│ → Standard Odoo sale_mrp flow │
└──────────────────────────────────────────────────────────────────┘
┌─ MANUFACTURING ──────────────────────────────────────────────────┐
│ 4. MO confirmed → Portal Job auto-created [DONE] │
│ → MrpProduction.action_confirm() override │
│ → Creates FpPortalJob (state: in_progress) │
│ → Links via x_fc_portal_job_id │
│ │
│ 5. Planner assigns recipe + configures steps [DONE] │
│ → x_fc_recipe_id set on MO │
│ → Opens fp.recipe.config.wizard for opt-in/out │
│ → Creates fusion.plating.job.node.override records │
│ │
│ 6. Work orders generated from recipe [NOT BUILT] │
│ → Convert recipe operation nodes → mrp.workorder │
│ → Respect opt-in/out overrides │
│ → Map work_center_id, estimated_duration, etc. │
│ │
│ 7. Operators execute WOs on shopfloor [DONE] │
│ → Plant Overview kanban (drag between work centres) │
│ → Batch chemistry tracking (FpBatch + FpBatchChemistry) │
│ → Quality holds (FpQualityHold → FpNcr → FpCapa) │
│ │
│ 8. MO marked done → Portal job ready_to_ship [DONE] │
│ → MrpProduction.button_mark_done() override │
│ → Auto-creates FpDelivery (draft) │
└──────────────────────────────────────────────────────────────────┘
┌─ SHIPPING & INVOICING ───────────────────────────────────────────┐
│ 9. CoC report generated [DONE] │
│ → report_coc.xml (PDF with job info, certification, sig) │
│ → Attached to delivery + portal job │
│ │
│ 10. Delivery scheduled & executed [DONE] │
│ → FpDelivery: draft → scheduled → en_route → delivered │
│ → Chain of custody auto-logged (FpChainOfCustody) │
│ → Proof of delivery captured (FpProofOfDelivery) │
│ → Routes with stops (FpRoute + FpRouteStop) │
│ │
│ 11. Delivery marked → Portal job shipped [DONE] │
│ → FpDelivery.action_mark_delivered() override │
│ → Sets actual_ship_date + tracking_ref on portal job │
│ │
│ 12. Account hold check before invoicing [NOT BUILT] │
│ → Flag on res.partner blocking invoice creation │
│ → Prevents shipping to customers with overdue balances │
│ │
│ 13. Invoice posted → Portal job complete [DONE] │
│ → AccountMove.action_post() override │
│ → Sets invoice_ref on portal job, state → complete │
│ │
│ 14. Auto-email with CoC + Invoice + Tracking [NOT BUILT] │
│ → mail.template triggered on delivery/invoice │
│ → Attaches: CoC PDF, Invoice PDF, tracking info │
└──────────────────────────────────────────────────────────────────┘
┌─ CUSTOMER PORTAL ────────────────────────────────────────────────┐
│ 15. Customer sees on portal [DONE] │
│ → Job progress bar (received → complete) │
│ → CoC download, invoice access, tracking ref │
│ → Quote request history │
└──────────────────────────────────────────────────────────────────┘
```
### Per-Job Recipe Overrides (v19.0.2.0.0 bridge_mrp)
- `x_fc_recipe_id` on `mrp.production` → links MO to recipe
- `fusion.plating.job.node.override` → per-job opt-in/out decisions
- `fp.recipe.config.wizard` → checklist wizard for planner
- "Overrides" stat button on MO form
- Located in `fusion_plating_bridge_mrp`
### 3 Remaining Gaps
| Gap | Description | Module |
|-----|-------------|--------|
| **Recipe → Work Orders** | Convert recipe operation nodes into mrp.workorder records, respecting opt-in/out overrides. Map work_center_id, estimated_duration. | `fusion_plating_bridge_mrp` |
| **Account Hold Check** | Flag on res.partner that blocks invoice creation / shipping for customers with overdue balances. | `fusion_plating_bridge_mrp` or new module |
| **Auto-Email Package** | On delivery marked shipped (or invoice posted), auto-send email to customer with CoC PDF + Invoice PDF + tracking info. | `fusion_plating_bridge_mrp` |
### Key Architectural Decisions Needed
1. **Recipe → WO mapping**: One WO per `operation` node? Or one per `step`? (Recommend: one per `operation`, steps become WO instructions)
2. **Account hold**: Flag on `res.partner`? Or computed from `account.move` aging? (Check Steelhead)
3. **Email trigger**: On delivery completion? On invoice posting? Both? (Check with client)
4. **Product Configurator**: Extend standard Odoo or build custom? (Need to see Steelhead's quote flow)
### Key Models Quick Reference
| Model | Module | Purpose |
|-------|--------|---------|
| `fusion.plating.process.node` | `fusion_plating` | Recipe tree (template) |
| `fusion.plating.process.node.input` | `fusion_plating` | Operator input definitions |
| `fusion.plating.job.node.override` | `fusion_plating_bridge_mrp` | Per-job opt-in/out |
| `fp.quote.request` | `fusion_plating_portal` | Customer RFQ |
| `fusion.plating.portal.job` | `fusion_plating_portal` | Portal-facing job tracker |
| `fusion.plating.customer.spec` | `fusion_plating_quality` | Spec library |
| `fusion.plating.quality.hold` | `fusion_plating_quality` | Parts on hold |
| `fusion.plating.ncr` | `fusion_plating_quality` | Non-conformance reports |
| `fusion.plating.capa` | `fusion_plating_quality` | Corrective actions |
| `fusion.plating.batch` | `fusion_plating_batch` | Rack/barrel batch tracking |
| `fusion.plating.delivery` | `fusion_plating_logistics` | Delivery with chain of custody |
| `fusion.plating.pickup.request` | `fusion_plating_logistics` | Customer pickup requests |
| `fusion.plating.route` | `fusion_plating_logistics` | Driver routes with stops |
## Repackaged Enterprise Modules
See `K:\Github\RePackaged-Odoo\CLAUDE.md` for full details. Key points:
- Odoo 19 enterprise modules repackaged for community edition
- All OEEL-1 licenses changed to LGPL-3
- Phone-home/telemetry gutted
- `web_enterprise` and `mail_enterprise` are installed on odoo-entech
- Addons path includes: `_dependencies`, `accounting`, `inventory_manufacturing`, `hr`, `sales`, `ai`, `fusion_backend`, `custom`, `website`