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

如何基于sale.order所选价格表对sale.order.line的product_id应用域筛选?

嘿,我来帮你搞定这个基于订单价格表筛选订单行产品的需求!你现在的代码已经有了基础框架,但还需要关联到订单的价格表来动态生成产品筛选域,我给你完善一下实现:

首先,修改你的sale_order_line类里的_get_product_ids方法,让它能获取当前订单行所属订单的价格表,然后筛选出该价格表里的产品,同时保留你原来的可售性条件:

class sale_order_line(osv.osv):
    _inherit = 'sale.order.line'
    
    def _get_product_ids(self, cr, uid, ids, context=None):
        # 先初始化基础的产品筛选条件:可售且状态符合要求
        domain = [('sale_ok', '=', True), ('state', 'in', ['sellable', 'custom'])]
        
        # 获取当前操作的订单行记录
        order_lines = self.browse(cr, uid, ids, context=context)
        for line in order_lines:
            # 拿到订单行关联的父订单
            parent_order = line.order_id
            if parent_order.pricelist_id:
                # 查询该价格表下所有的价格条目
                pricelist_item_obj = self.pool.get('product.pricelist.item')
                item_ids = pricelist_item_obj.search(cr, uid, 
                    [('pricelist_id', '=', parent_order.pricelist_id.id)]
                )
                pricelist_items = pricelist_item_obj.browse(cr, uid, item_ids, context=context)
                
                # 收集价格条目中明确指定的产品ID(排除那些按分类/规则定义的条目)
                valid_product_ids = [item.product_id.id for item in pricelist_items if item.product_id]
                
                if valid_product_ids:
                    # 把价格表里的产品ID加入筛选域
                    domain.append(('id', 'in', valid_product_ids))
                # 所有订单行都属于同一个订单,循环一次就够了
                break
        
        return domain
    
    _columns = {
        'product_id': fields.many2one('product.product', 'Product', domain=_get_product_ids, change_default=True),
    }

代码说明:

  1. 基础域保留:保留了你原来要求的sale_ok=True和产品状态筛选,确保只有可售产品能被选择;
  2. 关联订单价格表:通过订单行的order_id拿到父订单的价格表,这是最可靠的方式,不需要依赖上下文传递;
  3. 筛选价格表产品:查询该价格表下的所有product.pricelist.item记录,提取其中明确指定了product_id的条目,把这些产品ID加入筛选条件;
  4. 边界处理:如果订单还没设置价格表,或者价格表里没有指定具体产品,会自动 fallback 到基础的可售产品筛选。

额外优化建议:

如果你希望在新建订单行还没关联订单的时候,就能通过上下文提前获取订单的价格表,可以修改视图里的context,在sale.order的表单视图中,给订单行的字段/列表添加parent_pricelist_id的上下文:

<field name="order_line" context="{'partner_id': parent.partner_id, 'parent_pricelist_id': parent.pricelist_id}">
    <!-- 订单行的子视图内容 -->
</field>

然后在_get_product_ids方法开头添加一段逻辑,优先从上下文获取价格表:

def _get_product_ids(self, cr, uid, ids, context=None):
    context = context or {}
    domain = [('sale_ok', '=', True), ('state', 'in', ['sellable', 'custom'])]
    
    # 优先从上下文获取订单价格表(新建订单行时用)
    pricelist_id = context.get('parent_pricelist_id')
    if pricelist_id:
        pricelist_item_obj = self.pool.get('product.pricelist.item')
        item_ids = pricelist_item_obj.search(cr, uid, [('pricelist_id', '=', pricelist_id)])
        pricelist_items = pricelist_item_obj.browse(cr, uid, item_ids, context=context)
        valid_product_ids = [item.product_id.id for item in pricelist_items if item.product_id]
        if valid_product_ids:
            domain.append(('id', 'in', valid_product_ids))
        return domain
    
    # 下面是原来的从订单行获取订单的逻辑
    order_lines = self.browse(cr, uid, ids, context=context)
    # ... 后续代码不变

这样不管是编辑已有订单行还是新建订单行,都能正确根据订单的价格表筛选产品啦!

内容的提问来源于stack exchange,提问作者Raviprasad M R

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 11:28:15