forvas
forvas

Reputation: 10189

How to fix the dynamic domains issue in Odoo?

I have created a new model named product.service.type. Then, in product.product model, I have also created a Many2many field (named service_type, pointing to product.service.type model).

Now I have the model test, which has product_id and service_type_id fields, both Many2one pointing to product.product and product.service.type respectively.

What I want is that if you select a product, the service type domain changes to show only the service types of the selected product. I managed this through an onchange:

def onchange_product_id(self, cr, uid, ids, product_id, context=None):
    if product_id:
        product = self.pool.get('product.product').browse(
            cr, uid, [product_id], context=context)
        service_type_ids = product.service_type.mapped('id')
        return {
            'domain': {
                'service_type_id': [('id', 'in', service_type_ids)],
            },
        }

This is working great, the problem is when you are editing the record (not creating a new one), because in this case the onchange is not being executed and therefore, the domain shows all service types.

You can see the same problem in partners form, with the field title. Create a new partner which is a company, the domain of title field changes to allow you select only records like Corp., Ltd., etc., but if you set that the partner is a contact, you can select among records like Doctor, Madam, Miss, etc. Now, save the partner with the data you want, and go to other menu of the topbar. Return to partners form and open the created partner to edit it. Check the title field without changing the is_company field. Now you have all titles available, despite your partner belongs to a specific class (company or contact).

How could I fix this problem?

Upvotes: 5

Views: 1262

Answers (2)

afwanwh
afwanwh

Reputation: 176

On your model test, beside your 2 fields, you need one additional many2many that related to field service_type of object product.product. Then give domain to your field service_type_id.

Here is the illustration,

On model product.product you have:

  1. service_type (m2m to product.service.type)

On model test you have:

  1. product_id (m2o to product.product)
  2. service_type_id (m2o to product.service.type)
  3. available_service_type_ids (m2m related/computed to service_type of product.product)
  4. On your xml, service_type_id will have domain [(id , in, available_service_type_ids and available_service_type_ids[0] and available_service_type_ids[0][2] or False)]

Upvotes: 0

Bhavesh Odedra
Bhavesh Odedra

Reputation: 11143

I think, with list of following points. It can be achieve.

  • Update context with product_id in that many2many field, xml side.
  • Override search() method of Product service type model
  • Check if you receive same context and fire your logic otherwise return super() method

For example:

@api.model
def search(self, args, offset=0, limit=None, order=None, count=False):
    context = self._context or {}

    # Display product list which has not included in CofA Template
    if context.get('product_service_id'):
        product = self.env['product.product'].browse(context.get('product_service_id'))
        service_type_ids = product.service_type.mapped('id')
        args += [('service_type_id', 'not in', service_type_ids)]

    return super(ProductServiceType, self).search(args,
                                               offset,
                                               limit,
                                               order,
                                               count=count)

In XML side:

<field name="product_id"/>
<field name="many2many_field" context="{'product_service_id': product_id}">

NOTE: I have tried to answer as per new API and haven't tested it. You need to convert it with old API or as per your requirement.

Upvotes: 0

Related Questions