Adds 8-12 orders that originate from the direct order entry wizard
(used by estimators for bulk entry without quotation flow) instead
of plain sale.order create. Exercises the wizard's
action_create_order() method which builds the SO with all the
x_fc_* header fields, then we confirm to fire _fp_auto_create_job
in one step.
Each wizard creates 1-3 lines with realistic part/coating combos,
treatments, surface area, deadlines, and the wo_group_tag flag
(30% chance) to test multi-line job collapsing. Mixes po_pending
(30%) and PO-doc orders, plus a spread of invoice strategies
(deposit / progress / net_terms / cod_prepay).
Orders distribute across confirmed / in_progress_mid / delivered
/ invoiced / paid states, reusing the state-advancement pattern
from seed_workflow_states.py.
Verified on entech: 10/11 orders created (one invoice failure on a
SO with no invoiceable lines, handled gracefully via savepoint).
22 fp.job records generated across confirmed / in_progress / done.
Part of: native job model migration (spec 2026-04-25)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Builds 7-8 orders in each of 13 workflow states to simulate a
full pipeline:
- Quotation (sale.order draft)
- Quote Sent (sale.order sent)
- Order Confirmed / Job Confirmed
- Job In Progress (Early + Mid)
- Job On Hold (with quality hold)
- Job Done / Delivery Draft
- Delivery Scheduled / En Route / Delivered
- Invoice Draft / Posted / Paid
Each record fills detailed fields: PO numbers, commitment dates,
operator assignments, timelogs, thickness readings on certs,
delivery contacts/vehicles/drivers, payment journals, etc.
Idempotency-ish: each order wrapped in a savepoint so one failure
doesn't crash the whole seed.
Workflow walkthrough findings encoded in script header docstring,
including the gotchas: (1) SO action_confirm creates fp.job in DRAFT
state with 0 steps — must call action_confirm + _generate_steps_from_recipe
explicitly; (2) invoice_payment_term_id is REQUIRED to post invoices;
(3) account.payment.action_validate moves payment to 'paid' but invoice
goes to 'in_payment' (not 'paid' — Odoo 19 design, requires bank
reconciliation for full 'paid' state).
Part of: native job model migration (spec 2026-04-25)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The original cleanup script left behind 33 sale.order, 31 invoice
account.move, 13 payments, 1 picking, 17 quote requests. Extended
to nuke them too — SOs in any state, invoices regardless of
posted/draft (force-cancels via SQL when ORM blocks it), payments
forced to cancel before delete, stock.move + stock.move.line
force-deleted, quote requests unlinked.
Section ordering: payments -> invoices -> pickings/moves -> SOs (FK
direction). Reconciliation links cleared via direct SQL.
Sequences for sale.order and account.move.invoice reset to 1 so
fresh SOs start at S00001.
Re-seeded 31 fp.jobs across all 6 states after running the extended
cleanup.
Part of: native job model migration (spec 2026-04-25)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Two follow-up seed scripts after the main demo reset:
1. seed_work_centres.py: creates one fp.work.centre per existing
fusion.plating.work.center (matched by code), classifying kind
from name/code keywords. Then backfills work_centre_id on every
fp.job.step whose recipe_node has a legacy work_center_id with
a matching native code. Plant Overview kanban now has columns
instead of one big 'Unassigned' bucket.
2. seed_part_coatings.py: assigns existing fp.coating.config rows
(with recipes) to up to 20 bare fp.part.catalog rows
round-robin. Field on the part is x_fc_default_coating_config_id.
Future SO confirms via these parts will naturally generate full
recipe-linked steps via _generate_steps_from_recipe.
Both idempotent — re-running creates nothing new.
Run on entech: 9 native work centres created, all 234 existing
fp.job.step rows bound. Parts with coating: 2 -> 22 (28 -> 8 bare).
Part of: native job model migration (spec 2026-04-25)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
cleanup_demo_data.py: deletes ALL fp.job, fp.job.step, timelogs,
mrp.production, mrp.workorder, and dependent records (deliveries,
certs, holds, portal jobs, racking inspections, uninvoiced SOs).
Resets the fp.job sequence. Preserves masters. Force-cancels MOs/SOs
via SQL UPDATE before unlink to bypass Odoo's _unlink_except_done
and _unlink_except_draft_or_cancel guards.
seed_demo_data.py: creates 31 fp.job rows distributed across all
6 states (draft=5, confirmed=6, in_progress=8, on_hold=3, done=6,
cancelled=3). In_progress jobs have mixed step states with real
timelogs to simulate a live shop floor. Falls back to direct
fp.job creation when a customer's parts have no coating/recipe,
ensuring customer variety even with sparse coating data.
Both scripts: idempotent (safe to re-run), commit at end, walk
dependents bottom-up to avoid FK violations. Used to reset entech
demo data after the migration trial.
Part of: native job model migration (spec 2026-04-25)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Three changes to support live cutover on entech (2026-04-25):
1. Bridge_mrp gate: sale.order.action_confirm in
fusion_plating_bridge_mrp now skips _fp_auto_create_mo when the
x_fc_use_native_jobs config flag is True. Without this, every SO
confirm would create both an mrp.production AND an fp.job
(duplicate work). The gate is the only modification to bridge_mrp
during the migration — the rest stays untouched.
2. Menu nesting: Plating Jobs (Native) now lives INSIDE the existing
Plating app (parent=menu_fp_root) instead of as a separate
top-level app. Two parallel 'Plating' apps was confusing UX. Work
Centres (Native) goes under the existing Configuration sub-menu.
'(Native)' suffix is temporary — drops at full legacy removal.
3. Migration script robustness: per-MO savepoints (so one bad MO
doesn't abort the whole transaction with cascading 'transaction
aborted' errors) + extended partner resolver fallback chain
(warehouse partner → company partner) for orphan demo MOs without
SO link or x_fc_customer_id. Verified: 43 MOs + 297 WOs migrated
on entech with 0 errors after these fixes.
Part of: native job model migration (spec 2026-04-25)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Migration script now sets context fp_jobs_migration=True before
creating fp.job records. action_confirm and button_mark_done check
this flag and skip side-effects (portal job creation, QC check,
racking inspection, delivery, certificate, notification dispatch)
when migrating.
Without this, the migration would double-create portal jobs / QC
checks / racking inspections — once via bridge_mrp's original
create on the source MO, once via jobs module's lifecycle hook on
the new fp.job mirror. With the gate, the migration script
explicitly rebinds the existing dependents via x_fc_job_id.
Manifest 19.0.2.0.0 → 19.0.2.1.0.
Part of: native job model migration (spec 2026-04-25)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds legacy_mrp_production_id (Integer index) on fp.job and
legacy_mrp_workorder_id on fp.job.step. Used as the idempotency
key during cutover migration.
Three scripts under fusion_plating_jobs/scripts/:
- audit_pre_migration.py — counts and data-quality concerns BEFORE
- migrate_to_fp_jobs.py — copies MO->fp.job, WO->fp.job.step, time
logs, rebinds cross-refs (batches,
holds, certs, readings, portals,
inspections, deliveries). Idempotent.
- audit_post_migration.py — counts and verifies AFTER
Migration is run manually from \`odoo shell\` at cutover (not as
auto post-migration hook, for safety). README explains usage.
Tests verify the legacy id fields exist and the migration script
files are well-formed Python.
Manifest 19.0.1.9.0 -> 19.0.2.0.0.
Part of: native job model migration (spec 2026-04-25)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>