Search code examples
odooodoo-16

Why m2m field domain not working in odoo orm


Odoo domain filter not working for m2m field for child model. Suppose I have 5 model Budget, BudgetLine, Department, TeamMember and GLCode.

class Budget(models.Model):
    _name = 'mn.budget'

    name = fields.Char(string='Name', required=True, tracking=True)
    budget_line_ids = fields.One2many('mn.budget.line', 'budget_id', string='Budget Lines',)
    department_id = fields.Many2one('mn.department', string='Department',)


class BudgetLine(models.Model):
    _name = 'mn.budget.line'

    budget_id = fields.Many2one('mn.budget', string='Budget')
    gl_code = fields.Many2one('mn.gl_code', string='GL Code',)
    team_members = fields.Many2many(related='gl_code.member_ids', string='Team Members')

class Department(models.Model):
    _name = 'mn.department'
    name = fields.Char(string='Name')
    budget_ids = fields.One2many('mn.budget', 'department_id', string='Budgets')
    team_member_ids = fields.One2many('mn.team_member', 'department_id', string='Team Members')

class GLCode(models.Model):
    _name = 'mn.gl_code'

    code = fields.Char(string='GL Code', required=True)
    budget_line_ids = fields.One2many('mn.budget.line', 'gl_code', string='Budget Lines')
    member_ids = fields.Many2many('mn.team_member', string='Team Members')

class TeamMember(models.Model):
    _name = 'mn.team_member'

    member_id = fields.Many2one(
        'res.users', string='Member',
        # domain user type internal user
        domain=[('groups_id', '=', 1)]
    )
    department_id = fields.Many2one('mn.department', string='Department')
    gl_codes = fields.Many2many('mn.gl_code', string='GL Codes')

BudgetLine could be created from Budget form page. I want to filter gl_code, which parent Budget model department_id is same with member_ids department _id or GL Code ID in Department related TeamMember gl_codes.

I tried following domains in BudgetLine models gl_code field which isn't working

gl_code = fields.Many2one(
        'mn.gl_code', string='GL Code', 
        domain=lambda self: [
            ('id', 'in',  self.budget_id.department_id.team_member_ids.mapped('gl_codes').ids)
        ]
    )

How can I fix this ?


Solution

  • The domain used should be evaluated to an empty list because self.budget_id is an empty recordset instead you can use a computed field

    Example:

    class Budget(models.Model):
        _name = 'mn.budget'
    
        @api.depends('department_id')
        def _compute_gl_code_ids(self):
            if self.department_id:
                self.gl_code_ids = self.department_id.team_member_ids.gl_codes
            else:
                self.gl_code_ids = []
    
        gl_code_ids = fields.Many2many('mn.gl_code', compute='_compute_gl_code_ids')
    

    Add the domain in the view definition:

    <form>
        <field name="gl_code_ids" invisible="0"/>
        <group>
            <field name="name"/>
            <field name="department_id"/>
        </group>
        <field name="budget_line_ids">
            <tree editable="bottom">
                <field name="budget_id"/>
                <field name="gl_code" domain="[('id', 'in', parent.gl_code_ids)]"/>
                <field name="team_members"/>
            </tree>
        </field>
    </form>