Add a cohesive, restrained colour layer using the existing express
tokens (light/dark aware): faint plum gradient washes on the PO card,
legend bar, table header, and Order Summary header; filled accent
gradient pills (EXPRESS / CAD); accent rules on the section title,
summary header, and Grand Total footer. Adds an $xpr-accent-tint token
plus four composed gradient tokens.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The right-aligned value column squeezed the Additional Charge and Tax
dropdowns to a sliver. Move each picker into the (wider) label column,
stacked under its label at full width, so every value cell is now a
single amount that lines up cleanly in the right column under the
vertical divider.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Switch the summary rows from a flex space-between layout to a fixed
two-column grid (label | value) so a vertical divider on the label
cell's right edge lines up across every row. Values are right-aligned
into a clean amount column; the Grand Total footer keeps the divider at
the heavier rule weight.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Restyle the Order Summary card into a clean bordered table — a tinted
"Order Summary" caption bar, a divider line under every row, and an
accent-tinted Grand Total footer with a strong top rule. Uses the
existing light/dark express tokens so it renders correctly in both
colour schemes.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Express order entry now has a single "Lot Order" toggle on the header
instead of a per-line "Lot" checkbox. When on, every line shows Lot
Total and prices as a flat lot (unit price derived = lot total / qty,
qty preserved for production); when off, the Lot Total column is hidden
and lines price per unit as usual. Keeps the order summary clean for the
common per-unit case.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Bite-sized TDD plan: charge-type model + config UI, wizard charge/tax fields,
totals = one tax on (subtotal+charge), per-line lot pricing, SO-create tax on
all lines + typed charge line, and the express summary/line view changes.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Direct/Express order entry: a searchable/creatable fp.additional.charge.type
replaces the fixed Tooling Charge; one order-level account.tax applies to
(subtotal + charge); per-line lot pricing (flat lot total, derived unit price,
qty preserved). Reordered summary. Quotes out of scope.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Grant Odoo Billing (account.group_account_invoice) to group_fp_manager via
implied_ids; Quality Manager + Owner inherit it. Billing only (not Accountant);
the SO-origin workflow gate in fusion_plating_jobs is unchanged, so managers
invoice from the Sale Order's Create Invoice action. Tests assert Manager/Owner
get Billing and Shop Manager does not.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Read-only per-part version history (version#, reference, customer-facing,
order, by/when) below the curated templates list.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Wizard line (direct + express) and SO line now pre-fill BOTH internal +
customer-facing from the part's latest version (fallback to
default_specification_text), without clobbering typed text.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Each part-bearing line writes a deduped version (final order# + date) via
_fp_save_description_version, after the parent-number rename so the title
reflects the confirmed order number.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Bite-sized TDD plan: version model + part load/save helpers, save-on-confirm
hook, wizard + SO-line auto-load, and the part Descriptions-tab history list.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Dedicated fp.part.description.version model: latest auto-loads both internal +
customer-facing into a new order line; on SO confirm, a changed description
saves a new version titled "S#### · date". Browsable per-part history;
default_specification_text kept synced. SO surfaces only (not quotes).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The order-line onchange still auto-ticks "Save as Default" (so a new part's
spec is remembered next time) — only the explanatory popup is removed, per
client request. The ticked checkbox on the line is the cue now.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Carrier/service/weight inputs + Generate Label + Mark Shipped, shown when the
job is awaiting_ship and gated read-only ("Waiting on: WO-xxxx") until every
job on the order is ready. Reuses workspace card tokens; dark-mode accent
override included.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
generate_label (sudo'd FedEx machinery) and mark_shipped (as the technician),
both enforcing the order-level ship-together gate. /load now returns a
shipping block (carrier/service/weight + readiness + any existing label)
when the job is awaiting_ship.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
_fp_order_ship_state + _fp_mark_order_shipped enforce spec D4 ship-together:
the order ships only when every active job on it is awaiting_ship/done.
Shared by the tablet shipping endpoints and /fp/workspace/load.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Spec D5 delivery-completion set. Dispatch records (route/vehicle/pickup)
stay read-only for technicians.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
ACL: grant group_fp_technician write+create on fp.receiving / line / damage.
sudo the internal sale.order x_fc_receiving_status write so a non-privileged
technician isn't blocked inside action_mark_counted / action_close.
Tests deferred to entech (local Docker unavailable this session).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Bite-sized TDD plan across receiving ACL+sudo, delivery ACL, fp.job
ship-readiness helpers, shipping endpoints, and the workspace shipping
panel. Also patches the spec to record the sale.order status-write sudo
fix found during planning.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Design for letting Technicians receive a confirmed order and ship a finished
order from the fp_job_workspace tablet surface. Receiving is ACL-only (the
panel + endpoints already exist); shipping adds a workspace panel + two
sudo-backed endpoints (generate label, mark shipped) gated on all order jobs
being awaiting_ship.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The CoC body now renders English + the French translation together, so the
separate "Certificat de Conformité (Français)" print option was redundant.
- Removed the action_report_coc_fr report action and the now-dead
report_coc_fr template; renamed action_report_coc_en to "Certificate of
Conformance" (print filename "CoC - <name>").
- fp_notification_template: dropped the per-partner-language EN/FR branch —
CoC email attachments always render the single bilingual action_report_coc_en.
- fp_hide_default_reports: dropped the FR sequence record.
- Refreshed the report_coc.xml design note.
- Bump reports 19.0.11.32.0, notifications 19.0.7.1.0.
Deployed on entech (-u removed the orphan FR action + template). Verified the
cert Print menu now lists only "Certificate of Conformance" and it renders
clean. The dead action_report_coc_fr ref in the uninstalled
fusion_plating_bridge_mrp is left as-is (module not loaded).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Changing Settings -> Certificate Owner didn't move existing certs: the signer
was snapshotted from the company owner at cert-creation time, and the CoC
prefers that snapshot over the live owner.
- _fp_create_certificates no longer freezes the company owner into
certified_by_id; it snapshots ONLY a deliberate per-spec signer. Empty
certified_by_id then resolves the LIVE company owner in the CoC report.
- action_issue lazy-fill made robust: resolves the company via the SO /
env.company (fp.certificate has no company_id) so it fills the CURRENT
owner at issue and the "Certified By" gate still passes.
- Settings help text corrected: signature comes from the user's Plating
Signature (Preferences -> My Profile), not "HR Employee".
- Data fix on entech: cleared certified_by_id on 5 stale draft CoCs with no
per-spec signer so they follow the current owner.
Bump certificates 19.0.9.3.0, jobs 19.0.11.4.0. Verified: CoC-30058 resolves
signer = Garry Singh (has Plating Signature), renders clean.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The cert form's x_fc_local_thickness_pdf field only stored the upload; only
the Issue Certs wizard parsed it. Add create/write hooks on the jobs-side
fp.certificate that, when a NON-PDF is written to that field, run the wizard's
parser: readings -> thickness_reading_ids, header metadata -> x_fc_thickness_*,
microscope image (RTF) -> x_fc_thickness_image_id, then relocate the source to
x_fc_local_thickness_evidence_id and clear the PDF field (mirrors the wizard's
non-PDF end state). Real PDFs pass through untouched for the page-2 merge.
Re-entry guarded via the fp_skip_thickness_parse context flag. Bump jobs
19.0.11.3.0.
Deployed + verified on entech: CoC-30065 (.doc) back-filled to 3 readings +
metadata (operator BK) + extracted microscope image, renders inline (242KB);
PDF cert CoC-30040-02 correctly left untouched.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Column titles now render inline "English / French" on one line (was
stacked), cutting header height. First column drops "Line Item": it is
now Part Number / No. de pièce, Description / Description, Serial Number /
Numéro de série with a tight line-height.
- First-column DATA shows three lines — part number, part name, serial
number — via new fp.certificate._fp_resolve_part_identity() (part name
from the job's part catalog, serials from the matching SO line; blanks
fall back to "-"). Bump certificates 19.0.9.2.0, reports 19.0.11.31.0.
Deployed + verified on entech (CoC-30059: ('9876699373',
'VALVE BODY - COMPLETE - ASSY', ''), 243KB render).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Make every CoC classic-body column title bilingual — English (bold) over
the French translation (italic grey), matching Steelhead and the SO
report's stacked-header convention. Cert-info headers (Date of
Certification / Generated By / Work Order #) and line-item headers
(Process / Customer PO / Shipped / NC Qty / Customer Job No.) now show
both languages. First column carries Part Number / Line Item,
Description, and Serial Number, each translated. Bump reports 19.0.11.29.0.
Deployed + render-verified on entech (CoC-30065, 224KB).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
My prior change removed the .cert-statement-box border but the signature +
statement table was never bordered, leaving the whole section borderless.
Add class="bordered" so the two main columns (Certified By | Certification
Statement) get the outer box + divider like the other report tables; the
statement text keeps no separate inner box. Bump reports 19.0.11.28.2.
Deployed on entech (fusion_plating_reports upgrade clean).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The .cert-statement-box border was redundant next to the bordered tables;
render the statement as plain text (padding 0). Bump reports 19.0.11.28.1.
Deployed on entech (fusion_plating_reports upgrade clean).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Customer block: remove the (usually empty) customer-logo third column;
Address | Contact now split 50/50.
- Remove the heavy header bottom border (the Sale Order header has none) and
the hr.heavy rule between the customer block and the cert info table.
- Drop now-dead CSS (.fp-coc h1, hr.heavy, .customer-logo). Bump reports to
19.0.11.28.0.
Deployed + render-verified on entech (CoC-30065, 222KB PDF, no QWeb errors).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Drop the hard spec_reference gate on fp.certificate.action_issue. The
customer-facing description (_fp_resolve_customer_facing_description,
walks job -> SO line, reuses fp_customer_description) now drives the CoC
Process column; spec_reference prints only when an estimator fills it.
- CoC EN/FR reports swap web.external_layout for fp_external_layout_clean +
paperformat_fp_a4_portrait. New shared coc_header (company logo + address
left, Nadcap logo centre, title + Code128 barcode right) mirrors the Sale
Order header. Removed the 3-logo Nadcap/AS9100/CGP accreditation strip and
the body H1s; padding-top 0 on both body wrappers.
- Un-gate the Issue Certs wizard thickness upload (was invisible unless the
customer was thickness-flagged) so a Fischerscope report can be attached to
ANY cert; merge (page 2) + inline readings already render unconditionally.
- Update issue-gate tests, bump versions (certificates 19.0.9.1.0,
reports 19.0.11.27.0, jobs 19.0.11.2.0), record CLAUDE.md rule 14c.
Deployed + render-verified on entech (CoC-30065, 223KB PDF, no QWeb errors).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Adds two Integer fields to res.partner:
- x_fc_default_lead_time_min_days
- x_fc_default_lead_time_max_days
Set once on the customer's Plating Defaults tab (Fulfilment group);
auto-copies onto every new Express Order via the existing
_onchange_partner_id hook. Operator can still override per-order
since the onchange only fills when the wizard field is still blank.
Field declaration lives in fusion_plating_configurator (alongside
the rest of the partner cascade reads). View edit lives in
fusion_plating_invoicing where the Plating Defaults tab already
hosts the other partner-level defaults (invoice strategy, deposit
%, delivery method, deadline-days). Invoicing depends on
configurator, so the fields are registered before the view loads.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Three related fixes on the Express Orders totals card:
1. Totals card now breaks out Subtotal / Tax / Tooling Charge /
Grand Total. Previously the "Subtotal" and "Grand Total" rows
both read from total_amount (same value rendered twice) and no
tax was shown at all. Customers on a fiscal position-mapped
tax rate (Ontario HST, etc.) had their taxes silently dropped
from the preview.
2. tooling_charge now feeds the Grand Total. The total_amount
compute previously summed line subtotals only. Added a real
SO line for the tooling charge in action_create_order so the
eventual sale.order.amount_total matches the preview AND the
invoice carries a "Tooling Charge" line item.
3. tax_ids is now visible as an optional column on the lines
list. Operator can see + override the auto-applied tax per
line. Default still comes from FP-SERVICE product mapped
through partner.property_account_position_id (fiscal position).
New compute fields on fp.direct.order.wizard:
- total_subtotal (sum of line.qty * line.unit_price, pre-tax)
- total_tax (sum of line + tooling taxes via compute_all)
- total_amount (subtotal + tax + tooling — was just subtotal)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
fp.step.template rows already held 'fa-bathtub' (1), 'fa-flag' (2),
and 'fa-undo' (2) — all plating-relevant and presumably valid in an
earlier version of the Selection list. When step_insert snapshot-
copied these into a fresh fusion.plating.process.node via
_copy_snapshot_fields, the ORM rejected them with
ValueError: Wrong value for fusion.plating.process.node.icon
because they weren't in the curated 39-icon list anymore.
Adding 'fa-bathtub' (bathtub / tank / soak), 'fa-flag' (flag /
milestone / gate), and 'fa-undo' (undo / rework / rerun) to the
process.node Selection. Aligns the two lists (template uses
_get_icon_selection -> node._fields['icon'].selection at runtime).
No data migration needed — existing template rows immediately
re-validate against the wider Selection.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
FpExpressActionBtns.onOpen called action_open_part which returned an
ir.actions.act_window dict without a 'views' key. Odoo 19's
_preprocessAction in the web client tries to .map over action.views
and throws TypeError: Cannot read properties of undefined (reading 'map').
Fix: include 'views': [[False, 'form']] alongside view_mode='form' on
both copies of action_open_part (wizard line + sale.order.line).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Three view edits to surface the new cert toggles + workflow nudges:
1. res.partner — Plating Documents tab gains a "Aerospace / Defence"
separator + group with the three new toggles (Nadcap / MTR /
Customer-Specific). All boolean_toggle widget, default OFF.
2. fp.process.node — Recipe form gains a "Certificate Output" group
visible only when node_type == 'recipe'. Five requires_* toggles
+ a blue info banner explaining the suppress-only precedence.
3. fp.certificate — Certificate PDF tab gains a yellow alert banner
when certificate_type is one of the three orphan types AND no
attachment is set. Tells the operator "this type expects a PDF
you upload from disk".
Sub: docs/superpowers/specs/2026-05-27-recipe-cert-toggles-design.md
Task: T6.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Block fp.certificate.action_issue on Nadcap / Mill Test / Customer-
Specific certs when attachment_id is empty. These three cert types
are manual-attach only — operator uploads the supplier doc /
regulator-issued cert / filled customer template PDF before the
cert can be issued. Prevents shipping the customer an empty PDF.
_fp_render_and_attach_pdf gets an early-return guard so an orphan-
type cert never tries to render a CoC QWeb template.
Sub: docs/superpowers/specs/2026-05-27-recipe-cert-toggles-design.md
Task: T5. Makes test_orphan_cert_issue_blocks_without_attachment pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Rewrites fp.job._resolve_required_cert_types as a documented three-step
pipeline:
Step 1 — partner + part flags (extended to read 3 new orphan-type
partner toggles: x_fc_send_nadcap_cert / x_fc_send_mill_test
/ x_fc_send_customer_specific)
Step 2 — recipe-level requires_* Booleans STRIP cert types from
the wanted set (suppress-only — never adds)
Step 3 — CoC + thickness bundling preserved (thickness collapses
into CoC PDF as page 2)
Field-existence guards on partner/recipe attribute reads keep the
resolver robust if the certificates / plating module schemas drift.
Recipe is suppress-only per Q1 locked decision: customer/part is the
ceiling, recipe can only remove. Test 3 (test_recipe_cannot_add_certs_
customer_didnt_want) is the explicit regression guard.
Sub: docs/superpowers/specs/2026-05-27-recipe-cert-toggles-design.md
Task: T4. Makes the 5 resolver tests from T3 pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Six failing tests in test_recipe_cert_suppression.py covering the
full design surface:
1. test_recipe_suppresses_thickness
2. test_recipe_suppresses_nadcap_for_commodity_part
3. test_recipe_cannot_add_certs_customer_didnt_want (suppress-only
regression guard — recipe can never add types customer didn't ask for)
4. test_part_override_coc_recipe_suppresses
5. test_all_orphan_types_propagate (4-element output + bundling)
6. test_orphan_cert_issue_blocks_without_attachment
These will all fail until T4 (resolver) and T5 (orphan-attach gate)
land. RED phase of TDD locked in via commit ordering.
Sub: docs/superpowers/specs/2026-05-27-recipe-cert-toggles-design.md
Task: T3.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds five requires_* Booleans on fusion.plating.process.node
(requires_coc, requires_thickness_report, requires_nadcap_cert,
requires_mill_test, requires_customer_specific), default True.
Recipe is SUPPRESS-ONLY: when False, the recipe never produces that
cert type even if the customer/part requested it. Default True =
existing recipes keep producing the same cert set they produce today.
Surfaced on recipe-level form (node_type == 'recipe'); resolver reads
from job.recipe_id which is always a top-level recipe node.
Post-migrate backfills NULL -> TRUE on existing nodes.
Sub: docs/superpowers/specs/2026-05-27-recipe-cert-toggles-design.md
Task: T2.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds three Boolean fields (x_fc_send_nadcap_cert, x_fc_send_mill_test,
x_fc_send_customer_specific) to res.partner, default False. Wires
aerospace/defence customers into the existing cert resolver so the
three orphan fp.certificate.certificate_type values become reachable.
Post-migrate idempotently backfills NULL -> FALSE on existing rows.
Sub: docs/superpowers/specs/2026-05-27-recipe-cert-toggles-design.md
Task: T1 of the implementation plan.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>