Merge PR #492 into 16.0

Signed-off-by pedrobaeza
This commit is contained in:
OCA-git-bot 2024-08-05 17:47:14 +00:00
commit 1003af8cf4
22 changed files with 228 additions and 103 deletions

View File

@ -40,14 +40,10 @@ Usage
===== =====
To select the users that have access to a given document page To select the users that have access to a given document page
you need to open a document, go to the 'Security' tab you need to open a document, go to the 'Security' tab and you have 3 options:
and select which groups will have access. - Select a group: Only users with those groups will be able to see the page.
- Select any user: Only the selected users will be able to see the page.
Only users that belong to the 'document_knowledge / Manager' group can - Do not select group or user: All users will be able to see the page.
manage access groups to documents.
If no groups are selected in a document, all users that can access
document pages can access this document.
Bug Tracker Bug Tracker
=========== ===========
@ -73,6 +69,10 @@ Contributors
* Manuel Regidor <manuel.regidor@sygel.es> * Manuel Regidor <manuel.regidor@sygel.es>
* Alberto Martínez <alberto.martinez@sygel.es> * Alberto Martínez <alberto.martinez@sygel.es>
* `Tecnativa <https://www.tecnativa.com>`_:
* Víctor Martínez
Maintainers Maintainers
~~~~~~~~~~~ ~~~~~~~~~~~

View File

@ -4,7 +4,7 @@
{ {
"name": "Document Page Access Group", "name": "Document Page Access Group",
"summary": "Choose groups to access document pages", "summary": "Choose groups to access document pages",
"version": "16.0.1.0.0", "version": "16.0.1.1.0",
"category": "document_knowledge", "category": "document_knowledge",
"website": "https://github.com/OCA/knowledge", "website": "https://github.com/OCA/knowledge",
"author": "Sygel, Odoo Community Association (OCA)", "author": "Sygel, Odoo Community Association (OCA)",

View File

@ -6,6 +6,8 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Odoo Server 16.0\n" "Project-Id-Version: Odoo Server 16.0\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-07-24 07:09+0000\n"
"PO-Revision-Date: 2024-07-24 07:09+0000\n"
"Last-Translator: \n" "Last-Translator: \n"
"Language-Team: \n" "Language-Team: \n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
@ -20,6 +22,7 @@ msgstr ""
#. module: document_page_access_group #. module: document_page_access_group
#: model:ir.model.fields,field_description:document_page_access_group.field_document_page__groups_id #: model:ir.model.fields,field_description:document_page_access_group.field_document_page__groups_id
#: model_terms:ir.ui.view,arch_db:document_page_access_group.document_page_access_group_view_wiki_form
msgid "Groups" msgid "Groups"
msgstr "" msgstr ""
@ -27,3 +30,16 @@ msgstr ""
#: model_terms:ir.ui.view,arch_db:document_page_access_group.document_page_access_group_view_wiki_form #: model_terms:ir.ui.view,arch_db:document_page_access_group.document_page_access_group_view_wiki_form
msgid "Security" msgid "Security"
msgstr "" msgstr ""
#. module: document_page_access_group
#: model:ir.model.fields,field_description:document_page_access_group.field_document_page__user_ids
#: model_terms:ir.ui.view,arch_db:document_page_access_group.document_page_access_group_view_wiki_form
msgid "Users"
msgstr ""
#. module: document_page_access_group
#. odoo-python
#: code:addons/document_page_access_group/models/document_page.py:0
#, python-format
msgid "You cannot set groups and users at the same time."
msgstr ""

View File

@ -6,15 +6,16 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Odoo Server 14.0\n" "Project-Id-Version: Odoo Server 14.0\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2023-06-05 13:08+0000\n" "POT-Creation-Date: 2024-07-24 07:09+0000\n"
"PO-Revision-Date: 2024-07-24 09:10+0200\n"
"Last-Translator: luis-ron <luis.ron@sygel.es>\n" "Last-Translator: luis-ron <luis.ron@sygel.es>\n"
"Language-Team: none\n" "Language-Team: none\n"
"Language: es\n" "Language: es\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n" "Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n" "Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 4.17\n" "X-Generator: Poedit 3.0.1\n"
#. module: document_page_access_group #. module: document_page_access_group
#: model:ir.model,name:document_page_access_group.model_document_page #: model:ir.model,name:document_page_access_group.model_document_page
@ -23,6 +24,7 @@ msgstr "Página de documento"
#. module: document_page_access_group #. module: document_page_access_group
#: model:ir.model.fields,field_description:document_page_access_group.field_document_page__groups_id #: model:ir.model.fields,field_description:document_page_access_group.field_document_page__groups_id
#: model_terms:ir.ui.view,arch_db:document_page_access_group.document_page_access_group_view_wiki_form
msgid "Groups" msgid "Groups"
msgstr "Grupos" msgstr "Grupos"
@ -31,11 +33,15 @@ msgstr "Grupos"
msgid "Security" msgid "Security"
msgstr "Seguridad" msgstr "Seguridad"
#~ msgid "Display Name" #. module: document_page_access_group
#~ msgstr "Nombre mostrado" #: model:ir.model.fields,field_description:document_page_access_group.field_document_page__user_ids
#: model_terms:ir.ui.view,arch_db:document_page_access_group.document_page_access_group_view_wiki_form
msgid "Users"
msgstr "Usuarios"
#~ msgid "ID" #. module: document_page_access_group
#~ msgstr "ID" #. odoo-python
#: code:addons/document_page_access_group/models/document_page.py:0
#~ msgid "Last Modified on" #, python-format
#~ msgstr "Última modificación el" msgid "You cannot set groups and users at the same time."
msgstr "No puedes definir grupos y usuarios al mismo tiempo."

View File

@ -0,0 +1,8 @@
<?xml version='1.0' encoding='utf-8' ?>
<odoo>
<record id="document_page_rule" model="ir.rule">
<field
name="domain_force"
>['|', ('groups_id', 'in', [g.id for g in user.groups_id]), '|', ('user_ids', 'in', [user.id]), '&amp;', ('groups_id', '=', False), ('user_ids', '=', False)]</field>
</record>
</odoo>

View File

@ -0,0 +1,12 @@
# Copyright 2024 Tecnativa - Víctor Martínez
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from openupgradelib import openupgrade
@openupgrade.migrate()
def migrate(env, version):
openupgrade.load_data(
env.cr,
"document_page_access_group",
"migrations/16.0.1.1.0/noupdate_changes.xml",
)

View File

@ -1,10 +1,19 @@
# Copyright 2022 Manuel Regidor <manuel.regidor@sygel.es> # Copyright 2022 Manuel Regidor <manuel.regidor@sygel.es>
# Copyright 2024 Tecnativa - Víctor Martínez
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from odoo import fields, models from odoo import _, api, fields, models
from odoo.exceptions import UserError
class DocumentPage(models.Model): class DocumentPage(models.Model):
_inherit = "document.page" _inherit = "document.page"
groups_id = fields.Many2many(comodel_name="res.groups", string="Groups") groups_id = fields.Many2many(comodel_name="res.groups", string="Groups")
user_ids = fields.Many2many(comodel_name="res.users", string="Users")
@api.constrains("groups_id", "user_ids")
def check_document_page_groups_users(self):
for _item in self.filtered(lambda x: x.groups_id and x.user_ids):
raise UserError(_("You cannot set groups and users at the same time."))
return True

View File

@ -1,2 +1,6 @@
* Manuel Regidor <manuel.regidor@sygel.es> * Manuel Regidor <manuel.regidor@sygel.es>
* Alberto Martínez <alberto.martinez@sygel.es> * Alberto Martínez <alberto.martinez@sygel.es>
* `Tecnativa <https://www.tecnativa.com>`_:
* Víctor Martínez

View File

@ -1,9 +1,5 @@
To select the users that have access to a given document page To select the users that have access to a given document page
you need to open a document, go to the 'Security' tab you need to open a document, go to the 'Security' tab and you have 3 options:
and select which groups will have access. - Select a group: Only users with those groups will be able to see the page.
- Select any user: Only the selected users will be able to see the page.
Only users that belong to the 'document_knowledge / Manager' group can - Do not select group or user: All users will be able to see the page.
manage access groups to documents.
If no groups are selected in a document, all users that can access
document pages can access this document.

View File

@ -12,7 +12,7 @@
/> />
<field <field
name="domain_force" name="domain_force"
>['|', ('groups_id', '=', False), ('groups_id', 'in', [g.id for g in user.groups_id])]</field> >['|', ('groups_id', 'in', [g.id for g in user.groups_id]), '|', ('user_ids', 'in', [user.id]), '&amp;', ('groups_id', '=', False), ('user_ids', '=', False)]</field>
</record> </record>
<record id="document_page_rule_full_access" model="ir.rule"> <record id="document_page_rule_full_access" model="ir.rule">
<field name="name">Document Page Full Access</field> <field name="name">Document Page Full Access</field>

View File

@ -1,4 +1,3 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head> <head>
@ -388,12 +387,10 @@ document pages.</p>
<div class="section" id="usage"> <div class="section" id="usage">
<h1><a class="toc-backref" href="#toc-entry-1">Usage</a></h1> <h1><a class="toc-backref" href="#toc-entry-1">Usage</a></h1>
<p>To select the users that have access to a given document page <p>To select the users that have access to a given document page
you need to open a document, go to the Security tab you need to open a document, go to the Security tab and you have 3 options:
and select which groups will have access.</p> - Select a group: Only users with those groups will be able to see the page.
<p>Only users that belong to the document_knowledge / Manager group can - Select any user: Only the selected users will be able to see the page.
manage access groups to documents.</p> - Do not select group or user: All users will be able to see the page.</p>
<p>If no groups are selected in a document, all users that can access
document pages can access this document.</p>
</div> </div>
<div class="section" id="bug-tracker"> <div class="section" id="bug-tracker">
<h1><a class="toc-backref" href="#toc-entry-2">Bug Tracker</a></h1> <h1><a class="toc-backref" href="#toc-entry-2">Bug Tracker</a></h1>
@ -416,6 +413,10 @@ If you spotted it first, help us to smash it by providing a detailed and welcome
<ul class="simple"> <ul class="simple">
<li>Manuel Regidor &lt;<a class="reference external" href="mailto:manuel.regidor&#64;sygel.es">manuel.regidor&#64;sygel.es</a>&gt;</li> <li>Manuel Regidor &lt;<a class="reference external" href="mailto:manuel.regidor&#64;sygel.es">manuel.regidor&#64;sygel.es</a>&gt;</li>
<li>Alberto Martínez &lt;<a class="reference external" href="mailto:alberto.martinez&#64;sygel.es">alberto.martinez&#64;sygel.es</a>&gt;</li> <li>Alberto Martínez &lt;<a class="reference external" href="mailto:alberto.martinez&#64;sygel.es">alberto.martinez&#64;sygel.es</a>&gt;</li>
<li><a class="reference external" href="https://www.tecnativa.com">Tecnativa</a>:<ul>
<li>Víctor Martínez</li>
</ul>
</li>
</ul> </ul>
</div> </div>
<div class="section" id="maintainers"> <div class="section" id="maintainers">

View File

@ -0,0 +1,37 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo.tests import new_test_user
from odoo.addons.base.tests.common import BaseCommon
class TestDocumentPageAccessGroupBase(BaseCommon):
@classmethod
def setUpClass(cls):
super().setUpClass()
cls.group = cls.env["res.groups"].create({"name": "Test group"})
cls.user = new_test_user(
cls.env, login="test-user", groups="document_knowledge.group_document_user"
)
cls.manager_user = new_test_user(
cls.env,
login="test-manager-user",
groups="document_knowledge.group_document_user",
)
cls.manager_user.write({"groups_id": [(4, cls.group.id)]})
cls.public_page = cls.env["document.page"].create(
{"name": "Public Page", "type": "content"}
)
cls.knowledge_page = cls.env["document.page"].create(
{
"name": "Knowledge Page",
"type": "content",
"groups_id": [(6, 0, [cls.group.id])],
}
)
cls.user_page = cls.env["document.page"].create(
{
"name": "User Page (basic user)",
"type": "content",
"user_ids": [(6, 0, [cls.user.id])],
}
)

View File

@ -1,29 +1,25 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo.exceptions import UserError from odoo.exceptions import UserError
from odoo.tests import common from odoo.tests.common import users
from .common import TestDocumentPageAccessGroupBase
class TestDocumentPageAccessGroup(common.TransactionCase): class TestDocumentPageAccessGroup(TestDocumentPageAccessGroupBase):
def setUp(self): def test_page_access_constrains(self):
super().setUp()
self.document_user_group = self.browse_ref(
"document_knowledge.group_document_user"
).id
self.test_group = self.browse_ref("base.group_erp_manager").id
self.user_id = self.env["res.users"].create(
{
"name": "user",
"login": "user_login",
"email": "user_email",
"groups_id": [(4, self.document_user_group)],
}
)
self.page = self.env["document.page"].create(
{"name": "Page 1", "type": "content"}
)
def test_page_access(self):
self.assertIsNone(self.page.with_user(self.user_id).check_access_rule("read"))
self.page.write({"groups_id": [(4, self.test_group)]})
with self.assertRaises(UserError): with self.assertRaises(UserError):
self.page.with_user(self.user_id).check_access_rule("read") self.knowledge_page.write({"user_ids": [(6, 0, [self.user.id])]})
@users("test-user")
def test_page_access_01(self):
pages = self.env["document.page"].search([])
self.assertIn(self.public_page, pages)
self.assertNotIn(self.knowledge_page, pages)
self.assertIn(self.user_page, pages)
@users("test-manager-user")
def test_page_access_02(self):
pages = self.env["document.page"].search([])
self.assertIn(self.public_page, pages)
self.assertIn(self.knowledge_page, pages)
self.assertNotIn(self.user_page, pages)

View File

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?> <?xml version="1.0" encoding="utf-8" ?>
<!-- Copyright 2022 Manuel Regidor <manuel.regidor@sygel.es> <!-- Copyright 2022 Manuel Regidor <manuel.regidor@sygel.es>
Copyright 2024 Tecnativa - Víctor Martínez
License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). --> License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). -->
<odoo> <odoo>
<record id="document_page_access_group_view_wiki_form" model="ir.ui.view"> <record id="document_page_access_group_view_wiki_form" model="ir.ui.view">
@ -13,7 +14,20 @@
string="Security" string="Security"
groups="document_page.group_document_manager" groups="document_page.group_document_manager"
> >
<field name="groups_id" /> <group
name="groups"
string="Groups"
attrs="{'invisible': [('user_ids','!=',[])]}"
>
<field name="groups_id" nolabel="1" colspan="2" />
</group>
<group
name="users"
string="Users"
attrs="{'invisible': [('groups_id','!=',[])]}"
>
<field name="user_ids" widget="many2many_tags" colspan="2" />
</group>
</page> </page>
</xpath> </xpath>
</field> </field>

View File

@ -42,7 +42,7 @@ Usage
#. Go to `Knowledge / Pages` and create or edit one. #. Go to `Knowledge / Pages` and create or edit one.
#. Set in the "Roles" tab the one we have just created. #. Set in the "Roles" tab the one we have just created.
#. Go back to the role, edit it and add any group(s). #. Go back to the role, edit it and add any group(s).
#. The role groups will have been added in the "Security" tab. #. The role users will have been added in the "Security" tab.
Bug Tracker Bug Tracker
=========== ===========

View File

@ -4,7 +4,7 @@
"name": "Document Page Access Group User Role", "name": "Document Page Access Group User Role",
"author": "Tecnativa, Odoo Community Association (OCA)", "author": "Tecnativa, Odoo Community Association (OCA)",
"website": "https://github.com/OCA/knowledge", "website": "https://github.com/OCA/knowledge",
"version": "16.0.1.0.0", "version": "16.0.1.1.0",
"depends": ["document_page_access_group", "base_user_role"], "depends": ["document_page_access_group", "base_user_role"],
"license": "AGPL-3", "license": "AGPL-3",
"category": "Knowledge", "category": "Knowledge",

View File

@ -0,0 +1,13 @@
# Copyright 2024 Tecnativa - Víctor Martínez
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from openupgradelib import openupgrade
@openupgrade.migrate()
def migrate(env, version):
"""Pages that had roles should now have the correct users."""
pages = env["document.page"].sudo().search([("role_ids", "!=", False)])
for page in pages:
users = page.mapped("role_ids.users")
page.role_ids = False
page.user_ids = users

View File

@ -7,7 +7,7 @@ from odoo import api, fields, models
class DocumentPage(models.Model): class DocumentPage(models.Model):
_inherit = "document.page" _inherit = "document.page"
groups_id = fields.Many2many(compute="_compute_groups_id", store=True) user_ids = fields.Many2many(compute="_compute_user_ids", store=True, readonly=False)
role_ids = fields.Many2many( role_ids = fields.Many2many(
comodel_name="res.users.role", comodel_name="res.users.role",
relation="document_page_user_roles_rel", relation="document_page_user_roles_rel",
@ -16,8 +16,8 @@ class DocumentPage(models.Model):
string="Roles", string="Roles",
) )
@api.depends("role_ids", "role_ids.implied_ids") @api.depends("role_ids", "role_ids.users")
def _compute_groups_id(self): def _compute_user_ids(self):
"""Create a compute to auto-set all the groups of the related roles.""" """Create a compute to auto-set all the users of the related roles."""
for item in self: for item in self:
item.groups_id = item.mapped("role_ids.implied_ids") item.user_ids += item.mapped("role_ids.users")

View File

@ -2,4 +2,4 @@
#. Go to `Knowledge / Pages` and create or edit one. #. Go to `Knowledge / Pages` and create or edit one.
#. Set in the "Roles" tab the one we have just created. #. Set in the "Roles" tab the one we have just created.
#. Go back to the role, edit it and add any group(s). #. Go back to the role, edit it and add any group(s).
#. The role groups will have been added in the "Security" tab. #. The role users will have been added in the "Security" tab.

View File

@ -1,4 +1,3 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head> <head>
@ -391,7 +390,7 @@ ul.auto-toc {
<li>Go to <cite>Knowledge / Pages</cite> and create or edit one.</li> <li>Go to <cite>Knowledge / Pages</cite> and create or edit one.</li>
<li>Set in the “Roles” tab the one we have just created.</li> <li>Set in the “Roles” tab the one we have just created.</li>
<li>Go back to the role, edit it and add any group(s).</li> <li>Go back to the role, edit it and add any group(s).</li>
<li>The role groups will have been added in the “Security” tab.</li> <li>The role users will have been added in the “Security” tab.</li>
</ol> </ol>
</div> </div>
<div class="section" id="bug-tracker"> <div class="section" id="bug-tracker">

View File

@ -1,30 +1,47 @@
# Copyright 2024 Tecnativa - Víctor Martínez # Copyright 2024 Tecnativa - Víctor Martínez
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo.tests.common import users
from odoo.addons.base.tests.common import BaseCommon from odoo.addons.document_page_access_group.tests.common import (
TestDocumentPageAccessGroupBase,
)
class TestDocumentPageAccessGroupUserRole(BaseCommon): class TestDocumentPageAccessGroupUserRole(TestDocumentPageAccessGroupBase):
@classmethod @classmethod
def setUpClass(cls): def setUpClass(cls):
super().setUpClass() super().setUpClass()
cls.page = cls.env["document.page"].create(
{"name": "Page 1", "type": "content"}
)
cls.group_a = cls.env["res.groups"].create({"name": "Test group A"})
cls.group_b = cls.env["res.groups"].create({"name": "Test group B"})
cls.user_role = cls.env["res.users.role"].create( cls.user_role = cls.env["res.users.role"].create(
{"name": "Test role", "implied_ids": [(6, 0, [cls.group_a.id])]} {
"name": "Test role",
"implied_ids": [(6, 0, [cls.group.id])],
"users": [(6, 0, [cls.manager_user.id])],
}
)
cls.role_page = cls.env["document.page"].create(
{
"name": "Role Page (test role)",
"type": "content",
"role_ids": [(6, 0, [cls.user_role.id])],
}
) )
def test_document_page_role(self): def test_document_page_role_misc(self):
self.assertFalse(self.page.groups_id) self.assertFalse(self.role_page.groups_id)
self.page.role_ids = [(4, self.user_role.id)] self.assertTrue(self.role_page.user_ids)
self.assertIn(self.group_a, self.page.groups_id)
self.assertNotIn(self.group_b, self.page.groups_id) @users("test-user")
self.user_role.implied_ids = [(4, self.group_b.id)] def test_document_page_role_access_01(self):
self.assertIn(self.group_a, self.page.groups_id) pages = self.env["document.page"].search([])
self.assertIn(self.group_b, self.page.groups_id) self.assertIn(self.public_page, pages)
self.page.role_ids = [(6, 0, [])] self.assertNotIn(self.knowledge_page, pages)
self.assertNotIn(self.group_a, self.page.groups_id) self.assertIn(self.user_page, pages)
self.assertNotIn(self.group_b, self.page.groups_id) self.assertNotIn(self.role_page, pages)
@users("test-manager-user")
def test_document_page_role_access_02(self):
pages = self.env["document.page"].search([])
self.assertIn(self.public_page, pages)
self.assertIn(self.knowledge_page, pages)
self.assertNotIn(self.user_page, pages)
self.assertIn(self.role_page, pages)

View File

@ -8,24 +8,21 @@
ref="document_page_access_group.document_page_access_group_view_wiki_form" ref="document_page_access_group.document_page_access_group_view_wiki_form"
/> />
<field name="arch" type="xml"> <field name="arch" type="xml">
<page name="security" position="after"> <group name="users" position="before">
<page name="roles" string="Roles" groups="base.group_erp_manager"> <group
<field name="role_ids"> name="roles"
string="Roles"
attrs="{'invisible': [('groups_id','!=',[])]}"
groups="base.group_erp_manager"
>
<field name="role_ids" nolabel="1" colspan="2">
<tree> <tree>
<field name="name" /> <field name="name" />
<field name="comment" /> <field name="comment" />
</tree> </tree>
</field> </field>
</page> </group>
<!-- It is necessary to add the field without groups to be able to apply the readonly after. !--> </group>
<field name="role_ids" invisible="1" groups="!base.group_erp_manager" />
</page>
<!-- Set groups as readonly if there is a defined roles to avoid UX confusion. !-->
<field name="groups_id" position="attributes">
<attribute
name="attrs"
>{'readonly': [('role_ids', '!=', [])]}</attribute>
</field>
</field> </field>
</record> </record>
</odoo> </odoo>