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

