Record rules are used as a security measure in odoo. Each rule is applied for a particular model and describes who can access which all records of that model, and what all operations can be done (ie Read, Write, Create, delete).
In this blog, we are going to discuss how we can modify the existing record rules in Odoo.
We can modify the record rules from frontend and also through the backend
1. From the Frontend
We are all familiar with the sale group User: Own Documents Only. Here, I am going to modify a Record Rule Assigned for this Group. I am taking the Record Rule named Personal Orders, which can be accessed in a simple step: Go to Settings under the user & companies menu and select the Groups menu. If the Groups menu is not visible, activate the developer mode.
So a view open and under the Record Rules tab, we can see many rules are added to this group. Here, we can see the record rules have Name, Domain, Model, Read, Write, Create and Delete permission fields.
So currently, the personal Orders rule allows a user to see the sale orders created by only him.
That means, if we assign this group to users, he can see the sales order created by him only.
Here the user Marc Demo has assigned the group user: Own Document Only to sales.
So when he logs in and opens sales he can only see the records created by him.
Let's see what happens if we remove the domain from the Record Rule.
So after removing the domain from the rule, (and if Demo (user) logs in), he is able to see the records created by Mitchell Admin
So in this way, we can make modifications to Record Rules from the Front end.
2. From the Backend
In order to do this in the backend, first, we need to get the XML file of the Record rule. We can get this by simply searching the name of the Record Rule. After that in the new module inside the security folder, create a security .xml and paste the code in that security.xml file. Make sure you have called the security.xml in the manifest file.
The original code will be like
<record id = "sale_order_personal_rule" model = "ir.rule">
<field name = "name"> Personal Orders </field>
<field ref = "model_sale_order" name = "model_id" />
<field name = "domain_force" > ['|', ('user_id', '=', user.id), ('user_id', '=', False)] </field>
<field name = "groups" eval = "[(4, ref ('sales_team.group_sale_salesman'))] "/>
</record>
This is the original code, but before making any changes we have to make the noupdate as false. In order to do that we can use the function tag as
<function name = "write" model = "ir.model.data">
<function name = "search" model = "ir.model.data">
<value eval = "[('module', '=', ' sale '), (' name ',' = ',' sale_order_personal_rule ')] "/>
</function>
<value eval =" {' noupdate ': False} "/>
</function>
Here the first function tag is used to make the noupdate as false and the inner function tag is used to get the rule with the help of module name and rule id.
If we do not change / update the noupdate, the new rule may not be reflected. Sometimes it may be affected when installing the module, but will not affect it when we try to upgrade the module.
Now we need to override / modify the rule, we have to call the record id and model_id with the module name [sale] as
<record id = "sale.sale_order_personal_rule" model = "ir.rule">
<field name = "name"> Personal Orders </field>
<field ref = "sale.model_sale_order" name = "model_id" />
<field name = "domain_force"> ['|', ('user_id', '=', user.id), ('user_id', '=', False)] </field>
<field name = "groups" eval = " [(4, ref ('sales_team.group_sale_salesman'))] "/>
</record>
Now we can modify the Record rule as we want.
<record id = "sale.sale_order_personal_rule" model = "ir.rule">
<field name = "name"> Personal Orders </field>
<field ref = "sale.model_sale_order" name = "model_id" />
<field name = "domain_force"> </field>
<field name = "groups" eval = "[(4, ref ('sales_team.group_sale_salesman'))]" />
</record>
Here, I am removing the value for the domain_force. After this, install the module and check the Record Rule. Here, we can see that the rule has been modified.
To make the noupdate as true after the rule modification, we can update the noupdate as
<function name = "write" model = "ir.model.data">
<function name = "search" model = "ir.model.data">
<value eval = "[('module', '=', ' sale '), (' name ',' = ',' sale_order_personal_rule ')] "/>
</function>
<value eval =" {' noupdate ': True} "/>
</function>
So now onwards on each upgrade of the module the rule will get updated if we had modified the record rule.
Before upgrading the module the Record rule will be like this (see the above image)
So, hereafter installing the module the record rule will be modified.