Hi all,
Context
- Odoo 19 Enterprise.
- I want a reusable automation that, when a Manufacturing Order (MO) moves from “Confirmed” to “In Progress”, updates the related CRM Lead/Opportunity to a specific stage.
- I may need multiple automations that each move the CRM to different target stages.
Current automated action
- Model: Manufacturing Order (mrp.production)
- Trigger: State set to “In Progress”
- Domain filter: Components Availability = “Available”
- Action: Execute Python code:
for mo in records:
# 1. Find the connected Sales Order (sale.order) by extracting the SO name from the MO's origin.
# The MO dump shows 'origin: OP/00003 - S00038'. We try to extract 'S00038'.
so_name = mo.origin.split(' - ')[-1].strip() if mo.origin else False
if not so_name:
mo.message_post(body="Warning: Could not extract a Sales Order name from the Manufacturing Order's origin.")
continue
SaleOrder = env['sale.order'].search([('name', '=', so_name)], limit=1)
if not SaleOrder:
mo.message_post(body=f"Warning: No Sales Order found with name '{so_name}'. Cannot update CRM stage.")
continue
# 2. Find the connected CRM Lead/Opportunity (crm.lead)
# Assumes 'opportunity_id' is the field linking SO to CRM.
lead = SaleOrder.opportunity_id
if not lead:
mo.message_post(body=f"Warning: Sales Order '{SaleOrder.name}' is not linked to a CRM Opportunity/Lead. Cannot update stage.")
continue
# 3. Find the 'Waiting spare parts delivery' stage in crm.stage
target_stage = env['crm.stage'].search([('name', '=', 'Waiting spare parts delivery')], limit=1)
if not target_stage:
mo.message_post(body="Warning: Target CRM Stage 'Waiting spare parts delivery' not found. Stage update skipped.")
continue
# 4. Update the CRM Lead/Opportunity
# Writing to the lead directly is simpler than browsing by ID.
lead.write({'stage_id': target_stage.id})
# Optional: Log success
# mo.message_post(body=f"Success: Updated CRM Opportunity '{lead.name}' to stage '{target_stage.name}'.")
What I’d like
- Use the same Python once, but pass a different target CRM stage per automation rule. For example when click on "Produced All" (button_mark_done) in MO the CRM status should change to "Finished" stage.
Semi-workaround I have
- Create a separate Server Action and call it from each automation with a context param:
destination_stage = "In service"
stage = env['crm.stage'].search([('name', '=', destination_stage)], limit=1)
if not stage:
raise UserError("CRM Stage '%s' not found." % destination_stage)
env['ir.actions.server'].browse(1124).with_context(
active_model='mrp.production',
active_ids=records.ids,
crm_stage_xmlid=None, # or name
crm_stage_id=stage.id,
).run()
Question
Is there a cleaner or recommended pattern to parameterize the target CRM stage per automation? Examples welcome.
Thanks.