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:
@@ -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),
|
||||
|
||||
Reference in New Issue
Block a user