fix(bridge_mrp): WO recipe generator + demo work-order backfill

bridge_mrp._generate_workorders_from_recipe was writing 'description'
on mrp.workorder, which doesn't exist in Odoo 19 — instead the step
instructions now post to each WO's chatter after bulk create, which
is where the operator sees them anyway.

Demo seeder now creates the full WO chain:
- 9 MRP work centres paired with 9 FP work centres (FP-QUEUE, -RACK,
  -MASK, -EN, -BAKE, -INSP, -DERACK, -DEMASK, -POSTBAKE) with
  costs_hour set so actuals-vs-quoted margin can compute.
- Wires the existing ENP-ALUM-BASIC recipe's 9 operation nodes to
  those FP work centres by matching names.
- Links every coating config to the recipe so the auto-assign hook
  (mrp.production.action_confirm → _auto_assign_recipe_from_so) has
  something to pull.
- Backfills work orders on all existing demo MOs: calls the generator
  once recipe is set. For historical (done) MOs, marks all their WOs
  done with backdated durations (25-90 min). For the Cyclone active
  MO, sets a realistic progression: first WO done, second in progress
  (priority: Hot), rest in 'ready'.

Verified: 90 WOs live, 10 per work centre. One MO shows the full
progression state mix. WO Traveller PDF renders (132KB) — both
portrait + landscape variants still work.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
gsinghpal
2026-04-17 02:18:08 -04:00
parent cb79186325
commit 838b41cb89
2 changed files with 151 additions and 2 deletions

View File

@@ -288,6 +288,7 @@ class MrpProduction(models.Model):
# Walk tree and collect operation WO values
wo_vals_list = []
wo_steps = {} # {sequence: instruction text} — posted to WO chatter after create
seq_counter = [10] # mutable for closure, increments by 10
def _is_node_included(node):
@@ -341,14 +342,19 @@ class MrpProduction(models.Model):
steps.append(line)
step_num += 1
# Odoo 19 mrp.workorder has no 'description' field;
# store step instructions on the operation via the
# existing `operation_id.note` path, or just log them
# to the WO chatter.
wo_vals_list.append({
'production_id': production.id,
'name': node.name,
'workcenter_id': mrp_wc,
'duration_expected': node.estimated_duration or 0,
'sequence': seq_counter[0],
'description': '\n'.join(steps) if steps else '',
})
if steps:
wo_steps[seq_counter[0]] = '\n'.join(steps)
seq_counter[0] += 10
elif node.node_type in ('recipe', 'sub_process'):
@@ -362,7 +368,15 @@ class MrpProduction(models.Model):
# Bulk create work orders
if wo_vals_list:
WorkOrder.create(wo_vals_list)
created_wos = WorkOrder.create(wo_vals_list)
# Post step instructions to each WO's chatter where present
for wo in created_wos:
steps_txt = wo_steps.get(wo.sequence)
if steps_txt:
wo.message_post(
body=_('<b>Recipe steps:</b><br/><pre>%s</pre>') % steps_txt,
subtype_xmlid='mail.mt_note',
)
production.message_post(
body=_('%d work orders generated from recipe "%s".') % (
len(wo_vals_list), production.x_fc_recipe_id.name),