【问题标题】:odoo / openERP one2many fields dynamic domainodoo / openERP one2many fields 动态域
【发布时间】:2015-12-08 06:53:56
【问题描述】:

我想搜索依赖于其他字段的 one2many 字段的记录。
这是我的代码,

父类:

class SaleOrder(models.Model):
    _inherit = 'sale.order'

    customer_product_ids = fields.One2many('product.product',
                           compute='_get_partner_products')
    order_line = fields.One2many('sale.order.line', 'order_id')

儿童班:

class SaleOrderLine(models.Model):
    _inherit = 'sale.order.line'

    order_id = fields.Many2one('sale.order')
    product_id = fields.Many2one('product.product')

查看

 <record id="view_ata_sale_order_form_inherit" model="ir.ui.view">
        <field name="name">view.ata.sale.order.form.inherit</field>
        <field name="model">sale.order</field>
        <field name="inherit_id" ref="sale.view_order_form"/>
        <field name="arch" type="xml">
            <field name="partner_id" position="after">
                <field name="partner_channel_id" invisible="1"/>
                <field name="customer_product_ids"/>
            </field>
            <xpath expr="//tree/field[@name='product_id']" position="attributes">
                <attribute name="domain">[('id', 'in', [rec.id for rec in parent.customer_product_ids])]</attribute>
            </xpath>
        </field>
    </record>

默认情况下,客户可以看到所有定义的产品。
就我而言,我需要根据选择的客户过滤产品。
每个客户可以有不同的列表产品,或者如果他们没有分类,他们可以看到所有产品

我尝试了上面的代码但出现错误:

Uncaught Error: Expected "]", got "(name)"

我猜错误来自这段代码:

<attribute name="domain">[('id', 'in', [rec.id for rec in parent.partner_product_ids])]</attribute>

我的问题,
是否可以像上面的代码(在视图内)那样做 python 循环理解?

谢谢。

【问题讨论】:

    标签: python openerp openerp-8


    【解决方案1】:

    在您的情况下,您需要使用 onchange 并将动态域返回到您的 one2many 字段

    你应该有这样的东西:

    @api.onchange('partner')
    def onchange_partner(self):
        ids=search for products that have this partner
        then return some thing like this {'domain': {'Many2one or One2many': [('id', 'in', ids)}}
    

    我不会为你写代码,所以你必须搜索onchange并应用它。你可以找到一些信息here

    【讨论】:

    • 你好,Mostafa,是的,我是 odoo 开发的新手,我已经尝试了你的建议,但它没有按预期工作。我已经发布了我的解决方案,它有效。 :)
    【解决方案2】:

    你不能把这样的代码放在那里。我会以不同的方式来做:

    更改产品型号添加其客户

    class Product(models.Model):
        _inherit = 'product.product'
    
        parent_id = fields.Many2one('res.partner')
    

    然后可以更轻松地更改视图:

    <attribute name="domain">[('partner_id', '=', partner_id)]</attribute>
    

    <attribute name="domain">[('partner_id', '=', parent.partner_id)]</attribute>
    

    (取决于您的 product_id 字段在哪里...

    【讨论】:

    • 你好亚历山德罗,谢谢你的建议,我想我找到了另一种方法:)
    【解决方案3】:

    我已经尝试了 Mostafa Mohamed 的解决方案,但它不影响产品列表(他们继续显示所有产品)。
    What should onchange methods do and return?

    这是我的代码,

    @api.multi
    def onchange_partner_id(self, part):
        res = super(SaleOrder, self).onchange_partner_id(part)
        domain = [('active', '=', True), ('sale_ok', '=', True)]
        if part:
            partner = self.env['res.partner'].browse(part)
            if partner and partner.sales_channel_id:
                domain.append(('sales_channel_ids', '=',
                               partner.sales_channel_id.id))
        product_ids = self.env['product.product'].search(domain)
        res.update(domain={
            'order_line.product_id': ['id', 'in', [rec.id for rec in product_ids]]
        })
        return res  
    

    我尝试了另一种解决方案,因此我在 product.product 模型中覆盖了 search_namesearch 方法,它的工作原理。

    这是我的代码,

    1. 继承 sale_view.xml

      <xpath expr="//tree/field[@name='product_id']" position="attributes">
          <attribute name="domain">[
              ('sales_channel_ids', '=', parent.partner_channel_id),
              ('sale_ok', '=', True),
              ('active', '=', True)
          ]</attribute>
          <attribute name="context">{
              'partner_channel_id': parent.partner_channel_id,
              'partner_id': parent.partner_id,
              'quantity': product_uom_qty,
              'pricelist': parent.pricelist_id,
              'uom': product_uom,
              'company_id': parent.company_id
          }</attribute>
       </xpath>   
      

    和覆盖方法
    2) search_name 方法:

    @api.model
    def name_search(self, name, args=None, operator='ilike', limit=100):
        if 'partner_channel_id' in self._context:
            target_domain = findDomain(args, 'sales_channel_ids')
            if len(target_domain) == 1:
                idx = target_domain.keys()[0]
                domain = target_domain.values()[0]
                if False in domain:
                    args.pop(idx)
        return super(ProductProduct, self).name_search(name=name,
                                                   args=args,
                                                   operator=operator,
                                                   limit=limit)   
    
    1. 搜索方法:

      @api.model
      def search(self, args, offset=0, limit=None, order=None, count=False):
          if 'partner_channel_id' in self._context:
              target_domain = findDomain(args, 'sales_channel_ids')
              if len(target_domain) == 1:
                  idx = target_domain.keys()[0]
                  domain = target_domain.values()[0]
                  if False in domain:
                      args.pop(idx)
          return super(ProductProduct, self).search(args=args,
                                                offset=offset,
                                                limit=limit,
                                                order=order,
                                                count=count)
      

    我在这里尝试做的是,当他们在这样的上下文和域中检测到“partner_channel_id”时 ['sales_channel_ids', '=', False],我删除了该域并保留了其余的域(客户没有渠道可以查看所有产品,没有过滤产品)。

    【讨论】:

    • 当然这是一个很好的解决方案,我只是告诉你我的更短更容易:) 此外,我已经在自己的代码中使用了它!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多