Odoo16销售订单行product_id字段域修改失效问题求助
Odoo16 销售订单行产品字段域动态限制解决方案
问题分析
你之前的代码无效的核心原因:
- 触发时机错误:监听的是
product_id字段变化,但需求是当订单的agent_id或agent_product变更时更新可选产品范围,因此不会触发域调整; - 逻辑方向偏差:原有代码是在选完产品后做校验,而非提前限制可选产品的范围,不符合需求预期。
正确实现步骤
1. 销售订单字段扩展(原有代码这部分无问题,需确保res.partner模型存在agent布尔字段)
from odoo import models, fields, api, _ class SaleOrder(models.Model): _inherit = 'sale.order' agent_id = fields.Many2one('res.partner', string="代理", domain=[('agent', '=', True)]) agent_product = fields.Boolean(string="仅显示代理产品", default=True)
2. 销售订单行字段域动态调整
修改onchange触发条件,监听订单的agent_id和agent_product变化,同时修正库存查询逻辑(覆盖所有子仓库、过滤有可用库存的产品):
class SaleOrderLine(models.Model): _inherit = 'sale.order.line' @api.onchange('order_id.agent_id', 'order_id.agent_product') def _onchange_agent_filter_product(self): # 未勾选"仅显示代理产品"或未选择代理时,使用默认产品域 if not self.order_id.agent_product or not self.order_id.agent_id: return {'domain': {'product_id': []}} agent_location = self.order_id.agent_id.location_id if not agent_location: return {'domain': {'product_id': [('id', '=', False)]}} # 查询代理仓库下所有层级的内部子仓库 location_ids = self.env['stock.location'].search([ ('id', 'child_of', agent_location.id), ('usage', '=', 'internal') ]).ids # 筛选在这些仓库中有可用库存的活跃产品 available_product_ids = self.env['stock.quant'].search([ ('location_id', 'in', location_ids), ('quantity', '>', 0), ('product_id.active', '=', True) ]).mapped('product_id.id') return {'domain': {'product_id': [('id', 'in', available_product_ids)]}} # 可选:保留产品选择后的校验逻辑,防止通过其他渠道添加无库存产品 @api.onchange('product_id') def _onchange_product_check_stock(self): if not self.order_id.agent_product or not self.order_id.agent_id: return agent_location = self.order_id.agent_id.location_id if not agent_location: return location_ids = self.env['stock.location'].search([ ('id', 'child_of', agent_location.id), ('usage', '=', 'internal') ]).ids has_stock = self.env['stock.quant'].search_count([ ('product_id', '=', self.product_id.id), ('location_id', 'in', location_ids), ('quantity', '>', 0) ]) if not has_stock: self.product_id = False return {'warning': { 'title': _('产品无库存'), 'message': _('所选产品在代理的仓库中无可用库存。') }}
3. 关键优化说明
- 触发时机调整:监听订单的
agent_id和agent_product变化,确保域随配置实时更新; - 仓库范围覆盖:使用
child_of查询所有层级子仓库,而非仅直接子级; - 库存有效性过滤:仅保留
quantity > 0的库存记录,避免显示无货产品; - 产品状态过滤:增加
active=True条件,排除已归档产品。
内容的提问来源于stack exchange,提问作者a.hussin
相关产品推荐
相关产品推荐

