OdooRPC创建Manufacturing Order(MO)时如何生成关联库存调拨单
Odoo 15 编程创建生产订单(MO)时自动生成关联库存调拨单的解决方案
问题场景
在Odoo 15中通过代码创建生产订单(Manufacturing Order, MO)时,MO能成功生成,但关联的库存调拨单(stock.pickings) 未按预期创建。手动在前端创建MO时,库存调拨单可正常生成,尝试用onchange方法解决但无效,需找到编程创建MO时自动生成并关联库存调拨单的可行方案。
原代码示例
import odoorpc def create_mo(product_id, product_qty, picking_type_id): # Define the connection parameters db = '' url = '' username = '' password = '' # Initialize the connection odoo = odoorpc.ODOO(url) # Authenticate odoo.login(db, username, password) # Get the picking type record picking_type = odoo.env['stock.picking.type'].browse(picking_type_id) # Access the mrp.bom model mrp_bom_model = odoo.env['mrp.bom'] # Get the product template ID from the product ID product_template_id = odoo.env['product.product'].browse(product_id).product_tmpl_id.id # Define the search domain based on the product template ID search_domain = [('product_tmpl_id', '=', product_template_id)] # Search for the BOM record bom_ids = mrp_bom_model.search(search_domain) # Check if a BOM was found if bom_ids: # Retrieve the BOM record bom_record = mrp_bom_model.browse(bom_ids[0]) # Access the mrp.production model to create the MO mrp_production_model = odoo.env['mrp.production'] # Define the values for the new MO record values = { 'product_id': product_id, 'product_qty': product_qty, 'bom_id': bom_record.id, 'product_uom_id': bom_record.product_uom_id.id, 'picking_type_id': picking_type.id, 'location_src_id': 17, 'location_dest_id': 18, } # Calculate the components from the BOM lines components = [] for line in bom_record.bom_line_ids: components.append({ 'name': line.product_id.name, 'product_id': line.product_id.id, 'product_uom': line.product_uom_id.id, 'product_uom_qty': line.product_qty * product_qty, 'location_id': picking_type.default_location_src_id.id, 'location_dest_id': picking_type.default_location_dest_id.id, }) # Add the components to the MO values values['move_raw_ids'] = [(0, 0, line) for line in components] # Create the MO new_mo_id = mrp_production_model.create(values) # Confirm the MO mrp_production_model.button_plan([new_mo_id]) # Browse the newly created MO new_mo = mrp_production_model.browse(new_mo_id) # Print the ID of the new MO print("New Manufacturing Order created with ID:", new_mo_id) else: print("No BOM found for the specified product.") create_mo(6666,1,8)
问题分析与修正方案
核心问题
手动构建move_raw_ids跳过了Odoo内部的关联逻辑,且方法调用顺序不符合前端创建MO的流程,导致库存调拨单未被触发生成。
修正后的代码
import odoorpc def create_mo(product_id, product_qty, picking_type_id): # 连接参数 db = '' url = '' username = '' password = '' # 初始化连接并认证 odoo = odoorpc.ODOO(url) odoo.login(db, username, password) # 获取领料类型记录 picking_type = odoo.env['stock.picking.type'].browse(picking_type_id) # 查找对应产品的BOM mrp_bom_model = odoo.env['mrp.bom'] product_template_id = odoo.env['product.product'].browse(product_id).product_tmpl_id.id bom_ids = mrp_bom_model.search([('product_tmpl_id', '=', product_template_id)]) if bom_ids: bom_record = mrp_bom_model.browse(bom_ids[0]) mrp_production_model = odoo.env['mrp.production'] # 基础MO参数,不手动添加move_raw_ids values = { 'product_id': product_id, 'product_qty': product_qty, 'bom_id': bom_record.id, 'product_uom_id': bom_record.product_uom_id.id, 'picking_type_id': picking_type.id, # 使用领料类型默认位置,避免硬编码 'location_src_id': picking_type.default_location_src_id.id, 'location_dest_id': picking_type.default_location_dest_id.id, } # 创建MO new_mo_id = mrp_production_model.create(values) new_mo = mrp_production_model.browse(new_mo_id) # 模拟前端onchange_bom_id逻辑,自动生成物料移动记录 new_mo.onchange_bom_id() # 按正确顺序执行确认、计划操作,触发调拨单生成 new_mo.button_confirm() new_mo.button_plan() # 验证调拨单生成情况 picking_ids = new_mo.move_raw_ids.mapped('picking_id') if picking_ids: print(f"生产订单 {new_mo_id} 创建成功,关联库存调拨单ID: {[p.id for p in picking_ids]}") else: print(f"生产订单 {new_mo_id} 创建成功,但未生成库存调拨单,请检查参数配置") else: print("未找到该产品对应的BOM") create_mo(6666, 1, 8)
关键修正点
- 移除手动构建
move_raw_ids:让Odoo通过onchange_bom_id()自动生成物料移动记录,确保携带完整的关联上下文。 - 使用领料类型默认位置:替换硬编码的位置ID,保持与前端创建逻辑一致。
- 调整方法调用顺序:先执行
button_confirm()确认MO,再执行button_plan()计划生产,触发库存调拨单的生成逻辑。 - 添加调拨单验证:生成MO后检查关联的调拨单,确认结果。
额外检查项
- 确认领料类型(
picking_type_id)的默认源位置、目标位置配置正确。 - 检查BOM物料行的库存位置设置是否正常。
- 确保产品具备可库存、可生产的属性配置。
内容的提问来源于stack exchange,提问作者apexprogramming
相关产品推荐
相关产品推荐

