Domain in XML to only show records an employee is involved with

I have a situation where employees can see the whole list of records. But to make it a bit more friendly I have also added a ‘My Orders’ menu item. When an employee opens that menu, a (filtered) list of orders should appear where the employee is involved with. Multiple employees can be involved with an order.

To make it work I was thinking of adding a Many2Many field to the order where employees can be added (automatically). So for each order I have a list of employees which I can use to filter out the records. My intention was to do that in the ir.action.act_window record of the XML file, but that doesn’t work :cry:

The field:

employees = fields.Many2Many('order.order-company.employee',
                'order', 'employee', 'Employees')

The XML:

<record model="ir.action.act_window" id="act_my_order_form">
    <field name="name">My Orders</field>
    <field name="res_model">order.order</field>
    <field name="domain" eval="[
        (Eval('context', {}).get('employee', None), 'in', 'employees')
        ]" pyson="1"/>
</record>

I also tried

<record model="ir.action.act_window" id="act_my_order_form">
    <field name="name">My Orders</field>
    <field name="res_model">order.order</field>
    <field name="domain" eval="[
        (Eval('_user.employee'), 'in', 'employees')
        ]" pyson="1"/>
</record>

And both the other way around (Eval at the end).
Is this possible or do I have to add a Function field and based on that filter the records?

In short, the employees are allowed to see all the orders, but the extra menu entry ‘My Orders’ only shows the order the employee is involved with. I am on 5.4 will 5.8 (or 6.0) any difference?

Your domain is wrong. The first argument is the name of the field, second the operation and third the value to filter. So instead of using:

[(Eval('context', {}).get('employee', None), 'in', 'employees')]"

You should use the employees field as first argument:

[('employees', 'in', Eval('context', {}).get('employee', None))]"

Like I said, I have done that. but that didn’t work either. I get a traceback:

Traceback (most recent call last):
  File "/trytond/wsgi.py", line 109, in dispatch_request
    return endpoint(request, **request.view_args)
  File "/trytond/protocols/dispatcher.py", line 48, in rpc
    request, database_name, *request.rpc_params)
  File "/trytond/wsgi.py", line 76, in auth_required
    return wrapped(*args, **kwargs)
  File "/trytond/protocols/wrappers.py", line 131, in wrapper
    return func(request, pool, *args, **kwargs)
  File "/trytond/protocols/dispatcher.py", line 186, in _dispatch
    result = rpc.result(meth(*c_args, **c_kwargs))
  File "/trytond/model/modelsql.py", line 1247, in search
    tables, expression = cls.search_domain(domain)
  File "/trytond/model/modelsql.py", line 1431, in search_domain
    expression = convert(domain)
  File "/trytond/model/modelsql.py", line 1429, in convert
    domain[1:] if domain[0] == 'AND' else domain)))
  File "/trytond/model/modelsql.py", line 1428, in <genexpr>
    return And((convert(d) for d in (
  File "/trytond/model/modelsql.py", line 1419, in convert
    expression = field.convert_domain(domain, tables, cls)
  File "/trytond/model/fields/many2many.py", line 440, in convert_domain
    relation_domain, tables=relation_tables)
  File "/trytond/model/modelsql.py", line 1431, in search_domain
    expression = convert(domain)
  File "/trytond/model/modelsql.py", line 1429, in convert
    domain[1:] if domain[0] == 'AND' else domain)))
  File "/trytond/model/modelsql.py", line 1428, in <genexpr>
    return And((convert(d) for d in (
  File "/trytond/model/modelsql.py", line 1419, in convert
    expression = field.convert_domain(domain, tables, cls)
  File "/trytond/model/fields/field.py", line 193, in wrapper
    return func(*args, **kwargs)
  File "/trytond/model/fields/many2one.py", line 238, in convert_domain
    target_domain, tables=target_tables)
  File "/trytond/model/modelsql.py", line 1431, in search_domain
    expression = convert(domain)
  File "/trytond/model/modelsql.py", line 1429, in convert
    domain[1:] if domain[0] == 'AND' else domain)))
  File "/trytond/model/modelsql.py", line 1428, in <genexpr>
    return And((convert(d) for d in (
  File "/trytond/model/modelsql.py", line 1419, in convert
    expression = field.convert_domain(domain, tables, cls)
  File "/trytond/model/fields/field.py", line 398, in convert_domain
    expression = Operator(column, self._domain_value(operator, value))
  File "/trytond/model/fields/field.py", line 373, in _domain_value
    return [self.sql_format(v) for v in value if v is not None]
TypeError: 'int' object is not iterable

Fault: 'int' object is not iterable

It also seems a bit weird to me because

[('employees', 'in', Eval('context', {}).get('employee', None))]

kind of says:

[('Many2Many', 'in', 'Many2One')]

So I made a very slight change, wrap the Many2One into a [] to make it a list:

[('employees', 'in', [Eval('context', {}).get('employee', None))]]

And it worked! :partying_face: which is strange because I have done that before but then it didn’t work. Maybe I forgot to update or whatever. It works now.

Thanks for pushing me to do it again.