You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Odoo中通过XMLRPC创建带批次的stock.picking验证失败问题

Odoo创建stock.picking验证失败问题解决

错误提示

无法验证库存调拨:未预留或完成任何数量。

问题场景

在Odoo内部通过Python代码创建stock.picking并执行验证操作时触发上述错误,原代码如下:

picking_data = {
            'picking_type_id': 1,  # 替换为实际调拨类型ID
            'location_dest_id': 8,  # 替换为实际目标位置ID
            'location_id': 4,  # 替换为实际源位置ID
            'move_ids': [
                (0, 0, {
                    "name":"Movida1",
                    'location_id': 4,
                    'location_dest_id': 8,
                    'product_id': 376,  # 替换为实际产品ID
                    'product_uom_qty': 10,
                    'product_uom': 1,  # 替换为实际单位ID
                    'move_line_ids': [
                        (0, 0, {
                            'product_id': 376,  # 替换为实际产品ID
                            'lot_id':12,
                            'qty_done':5,
                            'lot_name':'LOT001'
                        }
                        ),
                        (0, 0, 
                        {
                            'product_id': 376,  # 替换为实际产品ID
                            'lot_id':14,
                            'qty_done':5,
                            'lot_name':'LOT003'
                        }
                        ),
                    ],
                }),
            ],
        }
    
picking = self.env['stock.picking'].create(picking_data)
picking.action_confirm()

picking.action_assign()
picking.button_validate()

问题原因

  1. 创建move时直接嵌套move_line_ids的写法存在问题,执行action_assign时Odoo会自动生成预留库存行,覆盖手动设置的qty_done数据
  2. 同时指定lot_id和lot_name会造成数据冲突,lot_id已明确时无需再传lot_name
  3. 验证时系统检测不到有效的已完成数量,因此抛出错误

修正方案

方案一:手动维护库存行(推荐)

创建调拨后先确认动作,再手动生成包含qty_done的库存行,避免自动预留覆盖数据:

picking_data = {
    'picking_type_id': 1,
    'location_dest_id': 8,
    'location_id': 4,
    'move_ids': [
        (0, 0, {
            "name": "Movida1",
            'location_id': 4,
            'location_dest_id': 8,
            'product_id': 376,
            'product_uom_qty': 10,
            'product_uom': 1,
        }),
    ],
}

picking = self.env['stock.picking'].create(picking_data)
picking.action_confirm()

# 遍历所有调拨行,手动创建库存行
for move in picking.move_ids:
    # 清除自动生成的预留库存行
    move.move_line_ids.unlink()
    # 添加自定义库存行,明确设置qty_done
    move.move_line_ids = [
        (0, 0, {
            'product_id': 376,
            'lot_id': 12,
            'qty_done': 5,
            'location_id': move.location_id.id,
            'location_dest_id': move.location_dest_id.id,
            'product_uom_id': move.product_uom.id,
        }),
        (0, 0, {
            'product_id': 376,
            'lot_id': 14,
            'qty_done': 5,
            'location_id': move.location_id.id,
            'location_dest_id': move.location_dest_id.id,
            'product_uom_id': move.product_uom.id,
        }),
    ]

# 执行验证
picking.button_validate()

方案二:强制跳过预留验证

若无需执行库存预留逻辑,可通过上下文参数直接强制验证:

picking_data = {
    # 保持原数据结构,可移除move_line_ids嵌套
    'picking_type_id': 1,
    'location_dest_id': 8,
    'location_id': 4,
    'move_ids': [
        (0, 0, {
            "name": "Movida1",
            'location_id': 4,
            'location_dest_id': 8,
            'product_id': 376,
            'product_uom_qty': 10,
            'product_uom': 1,
        }),
    ],
}

picking = self.env['stock.picking'].create(picking_data)
picking.action_confirm()

# 通过skip_immediate上下文跳过预留,直接验证
picking.with_context(skip_immediate=True).button_validate()

关键注意事项

  • 避免在创建move时直接嵌套move_line_ids,优先在确认调拨后手动维护库存行
  • 已指定lot_id时不要重复设置lot_name,防止数据冲突
  • 验证前必须确保move_line的qty_done总和与move的product_uom_qty匹配

内容的提问来源于stack exchange,提问作者hidura

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 18:01:25