Assign ir.model.field.access rights according to a domain like for ir.rule

Hi there,

I store confidential data about the employees of my company by overriding the company.employee model in my module.

So, I want the users in “Employee Administration” group see all employees and all information about these (no restrictions), and the users without this group see some employees (that I define thanks to ir.rule.group and ir.rule models by putting domains), certain informations about the others employees but all information about themselves.

My issue takes place on this last point: I can grant access to a field to a group, but i can’t grant access to a field according to a domain like for ir.rule, to tell Tryton “If the employee is the employee linked to the authenticated user, then grants read to all fields.”

Is there a way to do that? Maybe by the a piece of code instead of the XML definition of the access rights ?

Thank for help.

No because views are static.

You must store confidential data in a different model.

So a kind of company.employee.details or company.employee.confidentials model on which I applie a ir.rule to let only the employee himself and Employees Administrators access it… Interesting!

Hi,

I want to share with you how I solved my problem.

Instead of storing confidential data in another table as suggested by @ced, I preferred to make a table_query Model SQL that summarize the base class (in my case company.employee) with only the “public” fields. I called this class company.employee.summary and I allow every users to access data of each records of it.

And so, to allow only users of the “Employee Administration” group to CRUD on all employees and the emloyee itself to read its information, I defined ir.rule[s] directly on company.employee.

In this way, employees see all of themselves and only the summary of the others, and administrators see all of everyone.

Follows a brief example of the technical implementation.

Base class with a confidential field defined :

class Employee(metaclass=PoolMeta):
    __name__ = 'company.employee'

    confidential_field = fields.Char('Confidential field')

Summary class that re-defines “public” fields :

class EmployeeSummary(ModelSQL, ModelView):
    __name__ = 'company.employee.summary'

    first_name = fields.Char('First name')
    last_name = fields.Char('Last name')
    company = fields.Many2One('company.company', 'Company')
    supervisor = fields.Many2One('company.employee.summary', 'Supervisor')

With its table_query method :

    @classmethod
    def table_query(cls):
        pool = Pool()
        employee_table = pool.get('company.employee').__table__()
        party_table = pool.get('party.party').__table__()
        query = employee_table \
            .join(
                party_table,
                condition=(employee_table.party == party_table.id)) \
            .select(
                employee_table.id,
                Coalesce(party_table.common_first_name,
                         party_table.first_name).as_('first_name'),
                Coalesce(party_table.common_last_name,
                         party_table.last_name).as_('last_name'),
                employee_table.company,
                employee_table.supervisor,
                employee_table.create_date,
                employee_table.create_uid,
                employee_table.write_date,
                employee_table.write_uid,
                where=employee_table.active)
        return query

To finish, I created a wizard OpenOwnEmployee to add a menu entry that opens the employee form of the authenticated user.

I would like your advice on this method ! Hope it can help someone else.