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

Odoo16销售订单行product_id字段域修改失效问题求助

Odoo16 销售订单行产品字段域动态限制解决方案

问题分析

你之前的代码无效的核心原因:

  1. 触发时机错误:监听的是product_id字段变化,但需求是当订单的agent_id或agent_product变更时更新可选产品范围,因此不会触发域调整;
  2. 逻辑方向偏差:原有代码是在选完产品后做校验,而非提前限制可选产品的范围,不符合需求预期。

正确实现步骤

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 13:22:54