Search code examples
pythonodooodoo-9

Dynamic domain for Many2one field based on other model's field


I have a Many2one field inside a model that belongs to a "One2many" relation, and I want that field to only allow entries that satisfy some conditions based on the related model. How should I go about it?

I am using odoo 9, and my problem is as follows:

I have a model that holds two fields:

  1. Many2one : to a product category.

  2. One2many : to a model that represents a product with it's corresponding commission.

The idea behind this is that a partner may have a list of products allowed to be sold, grouped by category. And inside each category you should be able to build a list of products belonging to that category and assign to each product a custom commission value.

I figure I should use domain to filter products that correspond to that category, but I am not able to apply the filter based on the field of the "parent" model.

This is some of the code I have. Please excuse any variable name mismatch, as my code is partially in spanish and I translated it on the go. My solution attempts are not included, so you should be able to work in your helping code as you may see fit.

class allowed_products(models.Model):
  _name = 'products.allowed'

  categ_id = fields.Many2one(comodel_name='product.category', string='Product category', required=True)
  products_and_commissions = fields.One2many(comodel_name='product.commission',
    inverse_name='allowed_list_id', string='Products and their commissions')

  partner_id = fields.Many2one(comodel_name='res.partner')

Below is the class that contains a product with it's corresponding commission (I want to filter its 'product_id' field based on 'categ_id' from the above class)

class product_commission(models.Model):
  _name = 'product.commission'
  
  allowed_list_id = fields.Many2one(comodel_name='products.allowed')

  value = fields.Float('Commission (%)', digits=(16,2), default=30.0, required=True)

#This is the field that should be filtered by corresponding category
  product_id = fields.Many2one('product.product', string='Product', required=True)

For example:

Let's say Partner "A" can sell "Cars" (category). Once I assign category "Cars" to the M2o field, I only want to be able to add "Cars" products with their corresponding commissions to the One2many list of product-commission.

What I get every time is an unfiltered list of every product. I've read several threads but none seem to have worked for me.

Any advise would be greatly appreciated! Thanks <3


Solution

  • I use a technique here to avoid onchange because it will not be triggered in Edit mode:

    Let say that you product allowed view looks like this:

             <field name="categ_id"/>
    
             <field name="products_and_commissions">
                  <tree editable="bottom">
                      <!-- show product that belong to the category if a category is selected
                           else show all product  -->
                       <field name="product_id"  domain="parent.categ_id and [('category_id','child_of', parent.categ_id)] or []" /> 
                      ....
                      ....
                      ....
    

    You may have to use onchange too to clear the field whenever the use changes the category in product allowed model

       @api.model
       def onchange_categ_id(self):
           self.products_and_commissions = False # you can do better here by keeping some product that belong the new category