Commit Graph

22 Commits

Author SHA1 Message Date
gsinghpal
091f98e1f9 changes 2026-05-18 22:33:23 -04:00
gsinghpal
ab7ff3eea5 fix(portal): /my/orders 500 — QWeb t-value is Python not Jinja, |length is bitwise OR
orders|length in t-value parses as orders | length, not as a Jinja
length filter. orders is a sale.order recordset; the `length`
identifier resolves to None; Python evaluates
recordset | None and raises TypeError. Use len(orders) instead.

Also documents the gotcha in CLAUDE.md (rule 19) so future templates
don't reach for Jinja-style filters in t-value.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-18 00:13:33 -04:00
gsinghpal
f8fc6be370 feat(portal): inject filter+search strip into Odoo /my/orders + docs
- views/fp_sale_order_portal.xml: new template inherit
  portal_my_orders_fp_search on sale.portal_my_orders. Injects the
  fp_portal_list_controls strip before the "no orders" alert. Filter
  pills + sort dropdown are disabled here (we don't own the route,
  Odoo's sortby is preserved separately). The search input is wired
  to .o_portal_my_doc_table tbody (the table class Odoo's
  portal.portal_table emits) so real-time keyword filtering works
  without needing to monkey-patch the stock route or template.

- CLAUDE.md: documents two conventions surfaced by the recent portal
  work:
    Rule 17 — test scaffolding for account.move creation must use
      with_context(fp_from_so_invoice=True) and pass
      invoice_payment_term_id, to satisfy custom gates in
      fusion_plating_jobs and fusion_plating_invoicing.
    Rule 18 — FP portal list pages don't paginate. They load up to
      500 records and rely on fp_portal_list_search.js to filter
      client-side. Hidden <td class="d-none"> cells per row carry
      extra searchable text.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-18 00:06:26 -04:00
gsinghpal
0593b70354 docs(portal): session handoff + sub-A IA spec + plan
Captures everything the next Claude session needs to pick up cold:
  - Live module versions on entech (portal 19.0.3.7.0, jobs/reports
    versions, all 5 tests green)
  - What shipped this session (24+ commits, summarised by area)
  - Sub-A (IA + sidebar) brainstorm decisions locked, spec written,
    plan ready to execute (11 tasks, 4 phases)
  - What's deferred (sub-B multi-user, sub-C search, drafts, real
    statements, RMA portal, top-recurring-parts) and WHY — so next
    session doesn't re-litigate
  - Gotchas hit + fixed this session that aren't obvious from code
  - Deploy recipe (file copy + module upgrade + cache bust) used 20+
    times this session

CLAUDE.md's Recent Session Handoff section now points to the new
handoff doc; the previous handoff is kept as 'superseded but kept
for context' below it.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-17 13:21:21 -04:00
gsinghpal
655b767127 fix(portal): override stock /my/home with FP rich dashboard
The custom dashboard at fusion_plating_portal was rendering a 6-card
view at /my/home, but a method-name mismatch left the parent
portal.CustomerPortal.home() route active instead. Rename the
override to home() so Python MRO does the override naturally, and
add CLAUDE.md Critical Rule 16 documenting the gotcha so future
controller-override work doesn't trip on it.

Version bump: 19.0.2.2.0 -> 19.0.2.3.0.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-17 02:35:52 -04:00
gsinghpal
6b7b44264a changes 2026-05-10 10:25:12 -04:00
gsinghpal
13e300d90e changes 2026-04-28 19:39:37 -04:00
gsinghpal
2d42b33d68 docs(claude.md): log Sub 12a/12b/12c + Phase 1/2/3 menu reorg + ergo fixes
Records full session work for future Claude Code sessions:

Sub 12a — Simple Recipe Editor + Step Library
  3 new models, additive fields on process.node + node.input,
  fp_simple_recipe_editor OWL action with drop-position simulator,
  11 JSONRPC endpoints, snapshot semantics, post_init seeding.

Sub 12b — Move Parts / Move Rack / Rack Parts / Stop Timer dialogs
  fp.rack.tag, fp.job.step.move + .input.value, racking_state on
  fusion.plating.rack (orthogonal to wear state), state machine on
  existing fp.job.step.timelog (no parallel labor model), 12 tablet
  endpoints, 4 OWL dialogs with fp-resolve-rack custom event,
  manager-bypass flags, plant overview Racks pane.

Sub 12c — Reports + Labor History
  Operator Traveller v2 (A4 landscape, paper-style), chronological
  CoC body via fp.certificate.body_style + coc_body_router,
  Labor History views, gap-fix bundle (rack travel ticket PDF,
  per-customer cert statement 3-tier resolution, captured Actual
  values from move.input.value).

Phase 1/2/3 — Menu reorganization
  Top-level: 17 → 6 (operator-visible). Industry verticals nested
  under Compliance hub. Move Log/Labor History/Maintenance under
  Operations. Certificates under Quality.
  Configuration: 36 flat → 7 themed folders + Settings sibling.
  Group-gating: KPIs/Move Log/Replenishment Suggestions →
  supervisor+. Operator now sees ~5 top-levels instead of ~10.

Landing page resolver
  action_fp_resolve_plating_landing server action, user override →
  company default → Sale Orders fallback. x_fc_pickable_landing
  Boolean tag for curated picklist.

Production Line / Routing Station rename
  fusion.plating.work.center → 'Production Line' (shop-layout, owns
  tanks). fp.work.centre → 'Routing Station' (per-step routing,
  cost-per-hour, mrp.workcenter replacement). Model IDs unchanged.

Other ergonomics
  Tank field labels (Code → Tank Number, Tank → Tank Name) +
  state-control header buttons. SO smart-button 'Plating Jobs' → 'WO'.
  Default landing screen = Sale Orders.
  Drop-position simulator in Simple Recipe Editor.

Updated 'Menu Structure' section near top of CLAUDE.md to reflect
new 6-top-level layout + 7-folder Configuration grouping.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 23:06:25 -04:00
gsinghpal
f51976cb08 changes 2026-04-27 08:48:55 -04:00
gsinghpal
2a4909be25 changes 2026-04-27 08:16:20 -04:00
gsinghpal
f08f328688 changes 2026-04-27 00:11:18 -04:00
gsinghpal
d9f58b9851 changes 2026-04-26 15:05:17 -04:00
gsinghpal
2bfabfe135 feat(plating): Sub 8 — split receiving vs inspection + box parity
fp.receiving simplifies to box-count-only (new primary state
machine: draft → counted → staged → closed). Legacy
inspecting/accepted/discrepancy/resolved states stay in the
Selection so existing records load without error but are surfaced
behind a manager-only toggle. New box_count_in field + banner
that tells the receiver "count boxes only — parts are inspected
by the racking crew."

New fp.racking.inspection + fp.racking.inspection.line models —
one record per MO, auto-created by mrp.production.create() with
one line per contributing SO line (qty_expected seeded, qty_found
+ condition filled in by the racking crew when they open the boxes).
State: draft → inspecting → done | discrepancy_flagged (flagged
when any line has a non-ok condition or qty variance). Reopen
restricted to Plating Manager.

WO soft gate: first plating WO button_start raises a UserError
when the MO's racking inspection is still Draft or Inspecting.
Plating Manager bypasses; later WOs are not gated.

fp.delivery gains x_fc_box_count_out. action_mark_delivered calls
_fp_check_box_parity which posts a non-blocking chatter warning
when boxes out ≠ boxes in (resolved via job_ref → MO.origin → SO
→ receiving). Warning only — never blocks shipping.

Menu entry: Plating → Operations → Racking Inspection.

Module version bumps:
  fusion_plating_receiving  → 19.0.3.0.0
  fusion_plating_logistics  → 19.0.3.0.0
  fusion_plating_bridge_mrp → 19.0.12.0.0 (+depends receiving)

Smoke on entech: 12/12 assertions pass (one gate test skipped —
MO had no WOs to test) including box-count state machine, inspection
auto-create, lifecycle, discrepancy flag, and box-parity chatter.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 00:30:36 -04:00
gsinghpal
0342535b9f feat(notifications): Sub 6 — contact profiles + communication routing
Five new boolean flags on res.partner applied to CHILD contacts:
x_fc_receives_certs, _qc, _quotes_so, _invoices, and _is_global_contact.
Single resolver helper res.partner._fp_resolve_notification_recipients
(stream, delivery_location=None) walks location contacts first then
company contacts, returning emails for contacts that opted into the
stream (or flagged themselves global). Falls back to partner.email
when no contact opts in so existing customers keep their exact
pre-Sub-6 routing.

fp.notification.template._dispatch now maps each trigger event to a
stream (so_confirmed→quotes_so, invoice_posted→invoices, shipped→
certs, etc.) and overrides the mail_template's email_to with the
resolved list. fp.delivery passes its delivery_address_id so the
shipped/CoC email routes through location-scoped contacts when they
exist.

Partner form gets a new "Communication Routing" tab on child contact
forms with the 5 flags (hides the per-stream checkboxes when
Global Contact is on, since it overrides them).

fusion_plating_certificates → 19.0.4.0.0 (adds the flag fields)
fusion_plating_notifications → 19.0.5.0.0 (+depends certificates)

Smoke on entech: 11/11 assertions pass including per-stream routing,
delivery-location scoping, zero-flag fallback, email-less skip,
unknown-stream + global behaviour, and case-insensitive dedup.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 00:01:15 -04:00
gsinghpal
a7fd39d6f3 feat(iot): Sub 7 — per-sensor polling interval + rate-limit + entech seed
Per-sensor override on fp.tank.sensor.poll_interval_minutes with a
company-wide default (res.company.x_fc_default_poll_interval_minutes,
default 30) exposed in Settings → Fusion Plating → IoT. Single
lookup helper _fp_effective_poll_interval_minutes keeps downstream
call sites simple. Read-only poll_interval_display Char ("30 min
(default)" / "15 min (override)") keeps units unambiguous per user
request.

Ingest endpoint /fp/iot/ingest drops readings that arrive inside a
sensor's effective interval, returning {accepted, skipped} so the Pi
agent can log it. Pi-side interval stays its own concern.

Post-init hook seeds 5 small tanks + 20 big tanks (10 active, 10
inactive) with 1 temperature + 1 pH sensor each → 25 tanks, 50
sensors. Idempotent (keyed by tank.code, with_context(active_test=
False)). Opt-in via ir.config_parameter
fusion_plating_iot.seed_entech_tanks = '1' so a fresh install
elsewhere doesn't auto-seed. Flag set on entech today; 27 tanks / 52
sensors now live (2 pilot + 25 seeded).

Smoke on entech: 14/14 assertions pass including idempotency and
rate-limit conditions.

fusion_plating_iot → 19.0.2.0.0

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-22 23:29:08 -04:00
gsinghpal
25c3f6f8d1 feat(plating): Sub 5 — order-line fields (serial, job#, thickness, revision)
Four new fields on every sale.order.line, propagated through to MO,
Delivery, and Invoice for end-to-end traceability:

- fp.serial registry (new model in configurator) with smart-button
  traceability to Sale Order, MO, Delivery, Invoice, Part. M2O on SO
  line; optional; user types a customer serial or clicks Generate
  Serial for a sequence-backed one. Reverse O2M links split across
  configurator (invoice) / bridge_mrp (MO) / logistics (delivery) so
  module load order is respected.
- x_fc_job_number on SO line, auto-sequenced FP-JOB-NNNNN on SO
  confirm. Editable — shops can override for customer/legacy schemes.
- fp.coating.thickness (new child of fp.coating.config) with per-
  config discrete thickness options; x_fc_thickness_id on SO line
  domain-filtered to the line's coating. Auto-clears when coating
  changes.
- x_fc_revision_snapshot Char on SO line, frozen from
  x_fc_part_catalog_id.revision at save. Protects historical SOs from
  later catalog edits. Secondary "Revision" picker on the tree view
  lets users switch between prior revisions of the same part number;
  the Part M2O still surfaces only is_latest_revision rows.

Reports (CoC, packing slip, invoice, BoL) pick up all four via the
Sub 2 customer_line_header macro — one macro edit, four reports.

Smoke on entech: 11 assertions pass including revision snapshot,
generate-serial button, typed-serial create-on-fly, coating→thickness
domain reset, SO confirm auto job#, and MO traceability carry.

Module version bumps:
  fusion_plating_configurator  → 19.0.12.0.0
  fusion_plating_bridge_mrp    → 19.0.11.0.0
  fusion_plating_logistics     → 19.0.2.0.0 (+depends configurator)
  fusion_plating_reports       → 19.0.5.1.0

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-22 23:04:44 -04:00
gsinghpal
21da526aa7 feat(plating): Sub 4 — Contract Review (optional, QA-005 1:1 PDF)
Per-part contract review record (fp.contract.review) gated by a
customer-level toggle, signed in two sections (QA Assistant → QA
Manager), settings-based signer rosters (no new res.groups), banner on
the part form that auto-dismisses once the first MO for the part hits
confirmed. QA-005 Rev. 0 paper form reproduced 1:1 in a QWeb PDF.

Never blocks MO/SO/WO — review is purely an audit artefact.

Smoke test run on entech: 12 assertions pass including the 25-cell
risk matrix parity with the paper form and 22 KB PDF render.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-22 21:43:06 -04:00
gsinghpal
d3b4eadbec test(sub3): Sub 3 smoke + verify SQL; mark shipped in CLAUDE.md roadmap
Sub 3 (Default Process + Composer per Part) complete:
 - Phase A: schema additions (part_catalog_id, cloned_from_id,
   treatment_uom on process_node; default_process_id on part_catalog),
   opt_in_out label rename, General Processing seed flipped to
   noupdate=1
 - Phase B: part-scoped Process Composer client action
   (fp_part_process_composer) with 3 RPC endpoints + OWL wrapper +
   Process tab on part form with Compose button
 - Phase C: tree node MO-state palette (green=completed, blue=active,
   red=error-only)

All 8 Sub 3 smoke checks green. Phase 1-3 QC smoke + E2E still green.
Sub 2 features untouched.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-22 09:06:41 -04:00
gsinghpal
733236f987 feat(configurator): Sub 1 — direct-order wizard stops auto-confirm + auto-email
The wizard was calling so.action_confirm() immediately after creating the
sale order, which flipped it from draft to sale state and triggered the
fusion_plating_notifications hook that auto-emails the customer.

Client wants a review step: keep the SO in quotation (draft) so the
user can adjust before the customer sees anything. They manually click
Send (to email the quotation) or Confirm (to convert to sale order,
which intentionally fires the confirmation email).

Changes:
 - Remove so.action_confirm() call in action_create_order
 - Update docstring + inline comment to reflect manual-confirm flow
 - Update the chatter message on the created SO

CLAUDE.md updated to mark Sub 1 + Sub 2 as Shipped.

Verified:
 - Static check: wizard.action_create_order contains no action_confirm
 - Dynamic check: SO created programmatically stays in draft
 - Manual action_confirm() flow still works as designed

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-21 23:43:01 -04:00
gsinghpal
a15b75e38a docs(plating): fine-tuning initiative roadmap + Sub 2 design spec
Captures the current state of the system-wide fine-tuning initiative so a
fresh Claude Code session can resume without context loss.

CLAUDE.md additions (fusion_plating/CLAUDE.md):
* Sub-project roadmap (Sub 1 through 8 + two deferred items)
* Sub 2 locked decisions (Q1–Q6 answers)
* Sub 2 defensive measures that prevent rework when later subs land
* Sub 6 / 7 / 8 previews from the client transcript
* Client-confirmed operational thresholds (tank polling, active tanks)
* How to resume in a fresh session

Sub 2 design spec (docs/superpowers/specs/):
* Part Data Model Overhaul — covers gaps 2b, 2c, 2d, 4
* 12 sections: scope, data model, migration, UI, cert resolution,
  reports, testing, defensive measures, files touched, rollout,
  success criteria, open questions
* All clarifying questions answered; zero placeholders
* Ready for writing-plans skill to generate implementation plan

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-21 19:53:40 -04:00
gsinghpal
192aa60d00 docs(plating): flag fusion_plating_culture as do-not-auto-install
Future sessions shouldn't silently re-install retired modules during
install/upgrade sweeps. Added an explicit "Retired / Do-Not-Install
Modules" section with guardrails:

- Don't include in -i / -u sequences
- Don't add as a depends target
- Don't re-sync to entech /mnt/extra-addons/custom/
- Don't recommend installing without user confirmation

Covers the two modules currently in this state:
- fusion_plating_culture (code in repo, uninstalled on entech)
- fusion_plating_sensors (fully removed, absorbed into fusion_iot)

Also struck-through the "| 80 | Culture | ..." menu row and added a
retired tag to the module-list tree so at-a-glance scans don't
suggest it's a live part of the menu hierarchy.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-20 20:33:23 -04:00
gsinghpal
7c7ef06057 folder rename 2026-04-16 20:53:53 -04:00