Reputation: 233
I want to change the retrieved set of values of a many2many field according to a many2one field onchange function, it worked well with another many2one field, but doesn't seem to filter the outcome on a many2many field my code is as follows
class CustomPurchase(models.Model):
_name = 'custom.purchase'
_description = 'Purchase Record'
supplier_id = fields.Many2one('custom.supplier', string='Supplier', required=True)
product_ids = fields.Many2many('custom.supply.line', string='Purchase Lines', required=True)
@api.onchange('supplier_id')
def onchange_supplier(self):
selected_lines = []
if self.supplier_id:
for rec in self:
selected_lines = rec.env['custom.supply.line'].search([('supplier_id', '=', rec.supplier_id.id)])
domain = {'product_ids': [('id', '=', selected_lines.id)]}
return {'domain': domain, 'value': {'selected_lines': []}}
Expected behavior is to have just the items related to the supplier_id many2one field
Produced behavior is all the items are retrieved
Edit: I've noticed that i when i remove widget="section_and_note_one2many" the domain works perfectly, yet the tree view can't be edited within the same form, even with editable="bottom"
Upvotes: 3
Views: 4718
Reputation: 1314
For more complex cases, to ensure that the domain is correctly set onLoad (even without any onChange event): it's better to use a Field.Binary with a def_compute to get the allowed ids: for instance in the module account: to restrict the domain of tags on countries coming from different models:
In the file account_tax.py:
class AccountTaxRepartitionLine(models.Model):
_name = "account.tax.repartition.line"
tag_ids = fields.Many2many(string="Tax Grids", comodel_name='account.account.tag', domain=[('applicability', '=', 'taxes')], copy=True, ondelete='restrict')
tag_ids_domain = fields.Binary(string="tag domain", help="Dynamic domain used for the tag that can be set on tax", compute="_compute_tag_ids_domain")
@api.depends('company_id.multi_vat_foreign_country_ids', 'company_id.account_fiscal_country_id')
def _compute_tag_ids_domain(self):
for rep_line in self:
allowed_country_ids = (False, rep_line.company_id.account_fiscal_country_id.id, *rep_line.company_id.multi_vat_foreign_country_ids.ids,)
rep_line.tag_ids_domain = [('applicability', '=', 'taxes'), ('country_id', 'in', allowed_country_ids)]
In the file account_tax_views.xml:
<record id="tax_repartition_line_tree" model="ir.ui.view">
<field name="name">account.tax.repartition.line.tree</field>
<field name="model">account.tax.repartition.line</field>
<field name="arch" type="xml">
<tree editable="bottom" create="1" delete="1">
<!-- ... -->
<field name="tag_ids"
widget="many2many_tags"
options="{'no_create': True}"
domain="tag_ids_domain"/>
<field name="tag_ids_domain" invisible="1"/>
</tree>
</field>
</record>
Upvotes: 0
Reputation: 11
You can add check using supplier field directly inside domain.
Code:
@api.onchange('supplier_id')
def onchange_supplier(self):
domain = {'product_ids': []}
for rec in self:
if rec.supplier_id:
domain = {'product_ids': [('supplier_id', '=', rec.supplier_id.id)]}
return {'domain': domain}
UPDATE:
Try to implement this as same as in /addons/mrp/models/mrp_bom.py
on attribute_value_ids
. [Version:12]
Upvotes: 1