Merge PR #68 into 12.0

Signed-off-by sebastienbeau
This commit is contained in:
OCA-git-bot
2020-03-09 14:54:34 +00:00
9 changed files with 292 additions and 169 deletions

View File

@@ -13,17 +13,11 @@ User roles
.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png .. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3 :alt: License: AGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fserver--backend-lightgray.png?logo=github .. |badge3| image:: https://img.shields.io/badge/github-oca%2Fserver--backend-lightgray.png?logo=github
:target: https://github.com/OCA/server-backend/tree/12.0/base_user_role :target: https://github.com/oca/server-backend/tree/12.0/base_user_role
:alt: OCA/server-backend :alt: oca/server-backend
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
:target: https://translation.odoo-community.org/projects/server-backend-12-0/server-backend-12-0-base_user_role
:alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png
:target: https://runbot.odoo-community.org/runbot/253/12.0
:alt: Try me on Runbot
|badge1| |badge2| |badge3| |badge4| |badge5| |badge1| |badge2| |badge3|
This module was written to extend the standard functionality regarding users This module was written to extend the standard functionality regarding users
and groups management. and groups management.
@@ -98,10 +92,10 @@ To use this module, you need to:
Bug Tracker Bug Tracker
=========== ===========
Bugs are tracked on `GitHub Issues <https://github.com/OCA/server-backend/issues>`_. Bugs are tracked on `GitHub Issues <https://github.com/oca/server-backend/issues>`_.
In case of trouble, please check there if your issue has already been reported. In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us smashing it by providing a detailed and welcomed If you spotted it first, help us smashing it by providing a detailed and welcomed
`feedback <https://github.com/OCA/server-backend/issues/new?body=module:%20base_user_role%0Aversion:%2012.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_. `feedback <https://github.com/oca/server-backend/issues/new?body=module:%20base_user_role%0Aversion:%2012.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
Do not contact contributors directly about support or help with technical issues. Do not contact contributors directly about support or help with technical issues.
@@ -119,6 +113,8 @@ Contributors
* Sébastien Alix <sebastien.alix@osiell.com> * Sébastien Alix <sebastien.alix@osiell.com>
* Duc, Dao Dong <duc.dd@komit-consulting.com> (https://komit-consulting.com) * Duc, Dao Dong <duc.dd@komit-consulting.com> (https://komit-consulting.com)
* Jean-Charles Drubay <jc@komit-consulting.com> (https://komit-consulting.com) * Jean-Charles Drubay <jc@komit-consulting.com> (https://komit-consulting.com)
* Pierrick Brun <pierrick.brun@akretion.com>
* Kevin Khao <kevin.khao@akretion.com>
Do not contact contributors directly about support or help with technical issues. Do not contact contributors directly about support or help with technical issues.
@@ -133,16 +129,6 @@ Images
Maintainers Maintainers
~~~~~~~~~~~ ~~~~~~~~~~~
This module is maintained by the OCA.
.. image:: https://odoo-community.org/logo.png
:alt: Odoo Community Association
:target: https://odoo-community.org
OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.
.. |maintainer-ABF OSIELL| image:: https://github.com/ABF OSIELL.png?size=40px .. |maintainer-ABF OSIELL| image:: https://github.com/ABF OSIELL.png?size=40px
:target: https://github.com/ABF OSIELL :target: https://github.com/ABF OSIELL
:alt: ABF OSIELL :alt: ABF OSIELL
@@ -150,10 +136,10 @@ promote its widespread use.
:target: https://github.com/jcdrubay :target: https://github.com/jcdrubay
:alt: jcdrubay :alt: jcdrubay
Current `maintainers <https://odoo-community.org/page/maintainer-role>`__: Current maintainers:
|maintainer-ABF OSIELL| |maintainer-jcdrubay| |maintainer-ABF OSIELL| |maintainer-jcdrubay|
This module is part of the `OCA/server-backend <https://github.com/OCA/server-backend/tree/12.0/base_user_role>`_ project on GitHub. This module is part of the `oca/server-backend <https://github.com/oca/server-backend/tree/12.0/base_user_role>`_ project on GitHub.
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. You are welcome to contribute.

View File

@@ -2,22 +2,20 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
{ {
'name': 'User roles', "name": "User roles",
'version': '12.0.1.1.0', "version": "12.0.1.1.1",
'category': 'Tools', "category": "Tools",
'author': 'ABF OSIELL, Odoo Community Association (OCA)', "author": "ABF OSIELL, Odoo Community Association (OCA)",
'license': 'AGPL-3', "license": "AGPL-3",
'maintainers': ['ABF OSIELL', 'jcdrubay'], "maintainers": ["ABF OSIELL", "jcdrubay"],
'website': 'https://github.com/OCA/server-backend', "website": "https://github.com/OCA/server-backend",
'depends': [ "depends": ["base"],
'base', "data": [
"security/ir.model.access.csv",
"data/ir_cron.xml",
"data/ir_module_category.xml",
"views/role.xml",
"views/user.xml",
], ],
'data': [ "installable": True,
'security/ir.model.access.csv',
'data/ir_cron.xml',
'data/ir_module_category.xml',
'views/role.xml',
'views/user.xml',
],
'installable': True,
} }

View File

@@ -10,34 +10,42 @@ _logger = logging.getLogger(__name__)
class ResUsersRole(models.Model): class ResUsersRole(models.Model):
_name = 'res.users.role' _name = "res.users.role"
_inherits = {'res.groups': 'group_id'} _inherits = {"res.groups": "group_id"}
_description = "User role" _description = "User role"
group_id = fields.Many2one( group_id = fields.Many2one(
comodel_name='res.groups', required=True, ondelete='cascade', comodel_name="res.groups",
readonly=True, string="Associated group") required=True,
line_ids = fields.One2many( ondelete="cascade",
comodel_name='res.users.role.line', readonly=True,
inverse_name='role_id', string="Role lines") string="Associated group",
user_ids = fields.One2many(
comodel_name='res.users', string="Users list",
compute='_compute_user_ids')
group_category_id = fields.Many2one(
related='group_id.category_id',
default=lambda cls: cls.env.ref(
'base_user_role.ir_module_category_role').id,
string="Associated category",
help="Associated group's category")
comment = fields.Html(
string="Internal Notes",
) )
line_ids = fields.One2many(
comodel_name="res.users.role.line",
inverse_name="role_id",
string="Role lines",
)
user_ids = fields.One2many(
comodel_name="res.users",
string="Users list",
compute="_compute_user_ids",
)
group_category_id = fields.Many2one(
related="group_id.category_id",
default=lambda cls: cls.env.ref(
"base_user_role.ir_module_category_role"
).id,
string="Associated category",
help="Associated group's category",
)
comment = fields.Html(string="Internal Notes")
@api.multi @api.multi
@api.depends('line_ids.user_id') @api.depends("line_ids.user_id")
def _compute_user_ids(self): def _compute_user_ids(self):
for role in self: for role in self:
role.user_ids = role.line_ids.mapped('user_id') role.user_ids = role.line_ids.mapped("user_id")
@api.model @api.model
def create(self, vals): def create(self, vals):
@@ -53,7 +61,7 @@ class ResUsersRole(models.Model):
@api.multi @api.multi
def unlink(self): def unlink(self):
users = self.mapped('user_ids') users = self.mapped("user_ids")
res = super(ResUsersRole, self).unlink() res = super(ResUsersRole, self).unlink()
users.set_groups_from_roles(force=True) users.set_groups_from_roles(force=True)
return res return res
@@ -61,7 +69,7 @@ class ResUsersRole(models.Model):
@api.multi @api.multi
def update_users(self): def update_users(self):
"""Update all the users concerned by the roles identified by `ids`.""" """Update all the users concerned by the roles identified by `ids`."""
users = self.mapped('user_ids') users = self.mapped("user_ids")
users.set_groups_from_roles() users.set_groups_from_roles()
return True return True
@@ -72,20 +80,22 @@ class ResUsersRole(models.Model):
class ResUsersRoleLine(models.Model): class ResUsersRoleLine(models.Model):
_name = 'res.users.role.line' _name = "res.users.role.line"
_description = 'Users associated to a role' _description = "Users associated to a role"
role_id = fields.Many2one( role_id = fields.Many2one(
comodel_name='res.users.role', string="Role", comodel_name="res.users.role", string="Role", ondelete="cascade"
ondelete='cascade') )
user_id = fields.Many2one( user_id = fields.Many2one(comodel_name="res.users", string="User")
comodel_name='res.users', string="User")
date_from = fields.Date("From") date_from = fields.Date("From")
date_to = fields.Date("To") date_to = fields.Date("To")
is_enabled = fields.Boolean("Enabled", compute='_compute_is_enabled') is_enabled = fields.Boolean("Enabled", compute="_compute_is_enabled")
company_id = fields.Many2one(
"res.company", "Company", default=lambda self: self.env.user.company_id
)
@api.multi @api.multi
@api.depends('date_from', 'date_to') @api.depends("date_from", "date_to")
def _compute_is_enabled(self): def _compute_is_enabled(self):
today = datetime.date.today() today = datetime.date.today()
for role_line in self: for role_line in self:
@@ -101,7 +111,7 @@ class ResUsersRoleLine(models.Model):
@api.multi @api.multi
def unlink(self): def unlink(self):
users = self.mapped('user_id') users = self.mapped("user_id")
res = super(ResUsersRoleLine, self).unlink() res = super(ResUsersRoleLine, self).unlink()
users.set_groups_from_roles(force=True) users.set_groups_from_roles(force=True)
return res return res

View File

@@ -4,38 +4,43 @@ from odoo import api, fields, models
class ResUsers(models.Model): class ResUsers(models.Model):
_inherit = 'res.users' _inherit = "res.users"
role_line_ids = fields.One2many( role_line_ids = fields.One2many(
comodel_name='res.users.role.line', comodel_name="res.users.role.line",
inverse_name='user_id', inverse_name="user_id",
string="Role lines", string="Role lines",
default=lambda self: self._default_role_lines() default=lambda self: self._default_role_lines(),
) )
role_ids = fields.One2many( role_ids = fields.One2many(
comodel_name='res.users.role', string="Roles", comodel_name="res.users.role",
compute='_compute_role_ids') string="Roles",
compute="_compute_role_ids",
)
@api.model @api.model
def _default_role_lines(self): def _default_role_lines(self):
default_user = self.env.ref( default_user = self.env.ref(
'base.default_user', raise_if_not_found=False) "base.default_user", raise_if_not_found=False
)
default_values = [] default_values = []
if default_user: if default_user:
for role_line in default_user.role_line_ids: for role_line in default_user.role_line_ids:
default_values.append({ default_values.append(
'role_id': role_line.role_id.id, {
'date_from': role_line.date_from, "role_id": role_line.role_id.id,
'date_to': role_line.date_to, "date_from": role_line.date_from,
'is_enabled': role_line.is_enabled, "date_to": role_line.date_to,
}) "is_enabled": role_line.is_enabled,
}
)
return default_values return default_values
@api.multi @api.multi
@api.depends('role_line_ids.role_id') @api.depends("role_line_ids.role_id")
def _compute_role_ids(self): def _compute_role_ids(self):
for user in self: for user in self:
user.role_ids = user.role_line_ids.mapped('role_id') user.role_ids = user.role_line_ids.mapped("role_id")
@api.model @api.model
def create(self, vals): def create(self, vals):
@@ -49,6 +54,14 @@ class ResUsers(models.Model):
self.sudo().set_groups_from_roles() self.sudo().set_groups_from_roles()
return res return res
def _get_applicable_roles(self):
return self.role_line_ids.filtered(
lambda rec: rec.is_enabled
and (
not rec.company_id or rec.company_id == rec.user_id.company_id
)
)
@api.multi @api.multi
def set_groups_from_roles(self, force=False): def set_groups_from_roles(self, force=False):
"""Set (replace) the groups following the roles defined on users. """Set (replace) the groups following the roles defined on users.
@@ -58,21 +71,23 @@ class ResUsers(models.Model):
role_groups = {} role_groups = {}
# We obtain all the groups associated to each role first, so that # We obtain all the groups associated to each role first, so that
# it is faster to compare later with each user's groups. # it is faster to compare later with each user's groups.
for role in self.mapped('role_line_ids.role_id'): for role in self.mapped("role_line_ids.role_id"):
role_groups[role] = list(set( role_groups[role] = list(
role.group_id.ids + role.implied_ids.ids + set(
role.trans_implied_ids.ids)) role.group_id.ids
+ role.implied_ids.ids
+ role.trans_implied_ids.ids
)
)
for user in self: for user in self:
if not user.role_line_ids and not force: if not user.role_line_ids and not force:
continue continue
group_ids = [] group_ids = []
role_lines = user.role_line_ids.filtered( for role_line in user._get_applicable_roles():
lambda rec: rec.is_enabled)
for role_line in role_lines:
role = role_line.role_id role = role_line.role_id
if role: if role:
group_ids += role_groups[role] group_ids += role_groups[role]
group_ids = list(set(group_ids)) # Remove duplicates IDs group_ids = list(set(group_ids)) # Remove duplicates IDs
groups_to_add = list(set(group_ids) - set(user.groups_id.ids)) groups_to_add = list(set(group_ids) - set(user.groups_id.ids))
groups_to_remove = list(set(user.groups_id.ids) - set(group_ids)) groups_to_remove = list(set(user.groups_id.ids) - set(group_ids))
to_add = [(4, gr) for gr in groups_to_add] to_add = [(4, gr) for gr in groups_to_add]
@@ -80,7 +95,7 @@ class ResUsers(models.Model):
groups = to_remove + to_add groups = to_remove + to_add
if groups: if groups:
vals = { vals = {
'groups_id': groups, "groups_id": groups,
} }
super(ResUsers, user).write(vals) super(ResUsers, user).write(vals)
return True return True

View File

@@ -1,5 +1,7 @@
* Sébastien Alix <sebastien.alix@osiell.com> * Sébastien Alix <sebastien.alix@osiell.com>
* Duc, Dao Dong <duc.dd@komit-consulting.com> (https://komit-consulting.com) * Duc, Dao Dong <duc.dd@komit-consulting.com> (https://komit-consulting.com)
* Jean-Charles Drubay <jc@komit-consulting.com> (https://komit-consulting.com) * Jean-Charles Drubay <jc@komit-consulting.com> (https://komit-consulting.com)
* Pierrick Brun <pierrick.brun@akretion.com>
* Kevin Khao <kevin.khao@akretion.com>
Do not contact contributors directly about support or help with technical issues. Do not contact contributors directly about support or help with technical issues.

View File

@@ -367,7 +367,7 @@ ul.auto-toc {
!! This file is generated by oca-gen-addon-readme !! !! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !! !! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! --> !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<p><a class="reference external" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/licence-AGPL--3-blue.png" /></a> <a class="reference external" href="https://github.com/OCA/server-backend/tree/12.0/base_user_role"><img alt="OCA/server-backend" src="https://img.shields.io/badge/github-OCA%2Fserver--backend-lightgray.png?logo=github" /></a> <a class="reference external" href="https://translation.odoo-community.org/projects/server-backend-12-0/server-backend-12-0-base_user_role"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external" href="https://runbot.odoo-community.org/runbot/253/12.0"><img alt="Try me on Runbot" src="https://img.shields.io/badge/runbot-Try%20me-875A7B.png" /></a></p> <p><a class="reference external" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/licence-AGPL--3-blue.png" /></a> <a class="reference external" href="https://github.com/oca/server-backend/tree/12.0/base_user_role"><img alt="oca/server-backend" src="https://img.shields.io/badge/github-oca%2Fserver--backend-lightgray.png?logo=github" /></a></p>
<p>This module was written to extend the standard functionality regarding users <p>This module was written to extend the standard functionality regarding users
and groups management. and groups management.
It helps creating well-defined user roles and associating them to users.</p> It helps creating well-defined user roles and associating them to users.</p>
@@ -445,10 +445,10 @@ section). ]</dd>
</div> </div>
<div class="section" id="bug-tracker"> <div class="section" id="bug-tracker">
<h1><a class="toc-backref" href="#id3">Bug Tracker</a></h1> <h1><a class="toc-backref" href="#id3">Bug Tracker</a></h1>
<p>Bugs are tracked on <a class="reference external" href="https://github.com/OCA/server-backend/issues">GitHub Issues</a>. <p>Bugs are tracked on <a class="reference external" href="https://github.com/oca/server-backend/issues">GitHub Issues</a>.
In case of trouble, please check there if your issue has already been reported. In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us smashing it by providing a detailed and welcomed If you spotted it first, help us smashing it by providing a detailed and welcomed
<a class="reference external" href="https://github.com/OCA/server-backend/issues/new?body=module:%20base_user_role%0Aversion:%2012.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**">feedback</a>.</p> <a class="reference external" href="https://github.com/oca/server-backend/issues/new?body=module:%20base_user_role%0Aversion:%2012.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**">feedback</a>.</p>
<p>Do not contact contributors directly about support or help with technical issues.</p> <p>Do not contact contributors directly about support or help with technical issues.</p>
</div> </div>
<div class="section" id="credits"> <div class="section" id="credits">
@@ -465,6 +465,8 @@ If you spotted it first, help us smashing it by providing a detailed and welcome
<li>Sébastien Alix &lt;<a class="reference external" href="mailto:sebastien.alix&#64;osiell.com">sebastien.alix&#64;osiell.com</a>&gt;</li> <li>Sébastien Alix &lt;<a class="reference external" href="mailto:sebastien.alix&#64;osiell.com">sebastien.alix&#64;osiell.com</a>&gt;</li>
<li>Duc, Dao Dong &lt;<a class="reference external" href="mailto:duc.dd&#64;komit-consulting.com">duc.dd&#64;komit-consulting.com</a>&gt; (<a class="reference external" href="https://komit-consulting.com">https://komit-consulting.com</a>)</li> <li>Duc, Dao Dong &lt;<a class="reference external" href="mailto:duc.dd&#64;komit-consulting.com">duc.dd&#64;komit-consulting.com</a>&gt; (<a class="reference external" href="https://komit-consulting.com">https://komit-consulting.com</a>)</li>
<li>Jean-Charles Drubay &lt;<a class="reference external" href="mailto:jc&#64;komit-consulting.com">jc&#64;komit-consulting.com</a>&gt; (<a class="reference external" href="https://komit-consulting.com">https://komit-consulting.com</a>)</li> <li>Jean-Charles Drubay &lt;<a class="reference external" href="mailto:jc&#64;komit-consulting.com">jc&#64;komit-consulting.com</a>&gt; (<a class="reference external" href="https://komit-consulting.com">https://komit-consulting.com</a>)</li>
<li>Pierrick Brun &lt;<a class="reference external" href="mailto:pierrick.brun&#64;akretion.com">pierrick.brun&#64;akretion.com</a>&gt;</li>
<li>Kevin Khao &lt;<a class="reference external" href="mailto:kevin.khao&#64;akretion.com">kevin.khao&#64;akretion.com</a>&gt;</li>
</ul> </ul>
<p>Do not contact contributors directly about support or help with technical issues.</p> <p>Do not contact contributors directly about support or help with technical issues.</p>
</div> </div>
@@ -479,15 +481,10 @@ If you spotted it first, help us smashing it by providing a detailed and welcome
</div> </div>
<div class="section" id="maintainers"> <div class="section" id="maintainers">
<h2><a class="toc-backref" href="#id9">Maintainers</a></h2> <h2><a class="toc-backref" href="#id9">Maintainers</a></h2>
<p>This module is maintained by the OCA.</p> <p>Current maintainers:</p>
<a class="reference external image-reference" href="https://odoo-community.org"><img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" /></a>
<p>OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.</p>
<p>Current <a class="reference external" href="https://odoo-community.org/page/maintainer-role">maintainers</a>:</p>
<p><a class="reference external" href="https://github.com/ABFOSIELL"><img alt="ABF OSIELL" src="https://github.com/ABFOSIELL.png?size=40px" /></a> <a class="reference external" href="https://github.com/jcdrubay"><img alt="jcdrubay" src="https://github.com/jcdrubay.png?size=40px" /></a></p> <p><a class="reference external" href="https://github.com/ABFOSIELL"><img alt="ABF OSIELL" src="https://github.com/ABFOSIELL.png?size=40px" /></a> <a class="reference external" href="https://github.com/jcdrubay"><img alt="jcdrubay" src="https://github.com/jcdrubay.png?size=40px" /></a></p>
<p>This module is part of the <a class="reference external" href="https://github.com/OCA/server-backend/tree/12.0/base_user_role">OCA/server-backend</a> project on GitHub.</p> <p>This module is part of the <a class="reference external" href="https://github.com/oca/server-backend/tree/12.0/base_user_role">oca/server-backend</a> project on GitHub.</p>
<p>You are welcome to contribute. To learn how please visit <a class="reference external" href="https://odoo-community.org/page/Contribute">https://odoo-community.org/page/Contribute</a>.</p> <p>You are welcome to contribute.</p>
</div> </div>
</div> </div>
</div> </div>

View File

@@ -7,23 +7,24 @@ from odoo.tests.common import TransactionCase
class TestUserRole(TransactionCase): class TestUserRole(TransactionCase):
def setUp(self): def setUp(self):
super(TestUserRole, self).setUp() super(TestUserRole, self).setUp()
self.user_model = self.env['res.users'] self.user_model = self.env["res.users"]
self.role_model = self.env['res.users.role'] self.role_model = self.env["res.users.role"]
self.default_user = self.env.ref('base.default_user') self.default_user = self.env.ref("base.default_user")
self.user_id = self.user_model.create( self.user_id = self.user_model.create(
{'name': "USER TEST (ROLES)", 'login': 'user_test_roles'}) {"name": "USER TEST (ROLES)", "login": "user_test_roles"}
)
# ROLE_1 # ROLE_1
self.group_user_id = self.env.ref('base.group_user') self.group_user_id = self.env.ref("base.group_user")
self.group_no_one_id = self.env.ref('base.group_no_one') self.group_no_one_id = self.env.ref("base.group_no_one")
vals = { vals = {
'name': "ROLE_1", "name": "ROLE_1",
'implied_ids': [ "implied_ids": [
(6, 0, [self.group_user_id.id, self.group_no_one_id.id])], (6, 0, [self.group_user_id.id, self.group_no_one_id.id])
],
} }
self.role1_id = self.role_model.create(vals) self.role1_id = self.role_model.create(vals)
@@ -31,22 +32,42 @@ class TestUserRole(TransactionCase):
# Must have group_user in order to have sufficient groups. Check: # Must have group_user in order to have sufficient groups. Check:
# github.com/odoo/odoo/commit/c3717f3018ce0571aa41f70da4262cc946d883b4 # github.com/odoo/odoo/commit/c3717f3018ce0571aa41f70da4262cc946d883b4
self.group_multi_currency_id = self.env.ref( self.group_multi_currency_id = self.env.ref(
'base.group_multi_currency') "base.group_multi_currency"
self.group_settings_id = self.env.ref('base.group_system') )
self.group_settings_id = self.env.ref("base.group_system")
vals = { vals = {
'name': "ROLE_2", "name": "ROLE_2",
'implied_ids': [ "implied_ids": [
(6, 0, [self.group_user_id.id, (
6,
0,
[
self.group_user_id.id,
self.group_multi_currency_id.id, self.group_multi_currency_id.id,
self.group_settings_id.id])], self.group_settings_id.id,
],
)
],
} }
self.role2_id = self.role_model.create(vals) self.role2_id = self.role_model.create(vals)
self.company1 = self.env.ref("base.main_company")
self.company2 = self.env["res.company"].create({"name": "company2"})
self.user_id.write(
{
"company_ids": [
(4, self.company1.id, 0),
(4, self.company2.id, 0),
]
}
)
def test_role_1(self): def test_role_1(self):
self.user_id.write( self.user_id.write(
{'role_line_ids': [(0, 0, {'role_id': self.role1_id.id})]}) {"role_line_ids": [(0, 0, {"role_id": self.role1_id.id})]}
user_group_ids = sorted(set( )
[group.id for group in self.user_id.groups_id])) user_group_ids = sorted(
set([group.id for group in self.user_id.groups_id])
)
role_group_ids = self.role1_id.trans_implied_ids.ids role_group_ids = self.role1_id.trans_implied_ids.ids
role_group_ids.append(self.role1_id.group_id.id) role_group_ids.append(self.role1_id.group_id.id)
role_group_ids = sorted(set(role_group_ids)) role_group_ids = sorted(set(role_group_ids))
@@ -54,9 +75,11 @@ class TestUserRole(TransactionCase):
def test_role_2(self): def test_role_2(self):
self.user_id.write( self.user_id.write(
{'role_line_ids': [(0, 0, {'role_id': self.role2_id.id})]}) {"role_line_ids": [(0, 0, {"role_id": self.role2_id.id})]}
user_group_ids = sorted(set( )
[group.id for group in self.user_id.groups_id])) user_group_ids = sorted(
set([group.id for group in self.user_id.groups_id])
)
role_group_ids = self.role2_id.trans_implied_ids.ids role_group_ids = self.role2_id.trans_implied_ids.ids
role_group_ids.append(self.role2_id.group_id.id) role_group_ids.append(self.role2_id.group_id.id)
role_group_ids = sorted(set(role_group_ids)) role_group_ids = sorted(set(role_group_ids))
@@ -64,12 +87,16 @@ class TestUserRole(TransactionCase):
def test_role_1_2(self): def test_role_1_2(self):
self.user_id.write( self.user_id.write(
{'role_line_ids': [ {
(0, 0, {'role_id': self.role1_id.id}), "role_line_ids": [
(0, 0, {'role_id': self.role2_id.id}), (0, 0, {"role_id": self.role1_id.id}),
]}) (0, 0, {"role_id": self.role2_id.id}),
user_group_ids = sorted(set( ]
[group.id for group in self.user_id.groups_id])) }
)
user_group_ids = sorted(
set([group.id for group in self.user_id.groups_id])
)
role1_group_ids = self.role1_id.trans_implied_ids.ids role1_group_ids = self.role1_id.trans_implied_ids.ids
role1_group_ids.append(self.role1_id.group_id.id) role1_group_ids.append(self.role1_id.group_id.id)
role2_group_ids = self.role2_id.trans_implied_ids.ids role2_group_ids = self.role2_id.trans_implied_ids.ids
@@ -83,15 +110,29 @@ class TestUserRole(TransactionCase):
yesterday = today - datetime.timedelta(days=1) yesterday = today - datetime.timedelta(days=1)
yesterday_str = fields.Date.to_string(yesterday) yesterday_str = fields.Date.to_string(yesterday)
self.user_id.write( self.user_id.write(
{'role_line_ids': [ {
# Role 1 should be enabled "role_line_ids": [
(0, 0, {'role_id': self.role1_id.id, 'date_from': today_str}), # Role 1 should be enabled
# Role 2 should be disabled (
(0, 0, 0,
{'role_id': self.role2_id.id, 'date_to': yesterday_str}), 0,
]}) {"role_id": self.role1_id.id, "date_from": today_str},
user_group_ids = sorted(set( ),
[group.id for group in self.user_id.groups_id])) # Role 2 should be disabled
(
0,
0,
{
"role_id": self.role2_id.id,
"date_to": yesterday_str,
},
),
]
}
)
user_group_ids = sorted(
set([group.id for group in self.user_id.groups_id])
)
role1_group_ids = self.role1_id.trans_implied_ids.ids role1_group_ids = self.role1_id.trans_implied_ids.ids
role1_group_ids.append(self.role1_id.group_id.id) role1_group_ids.append(self.role1_id.group_id.id)
role_group_ids = sorted(set(role1_group_ids)) role_group_ids = sorted(set(role1_group_ids))
@@ -103,10 +144,13 @@ class TestUserRole(TransactionCase):
role2_groups = self.role2_id.implied_ids | self.role2_id.group_id role2_groups = self.role2_id.implied_ids | self.role2_id.group_id
# Configure the user with role1 and role2 # Configure the user with role1 and role2
self.user_id.write( self.user_id.write(
{'role_line_ids': [ {
(0, 0, {'role_id': self.role1_id.id}), "role_line_ids": [
(0, 0, {'role_id': self.role2_id.id}), (0, 0, {"role_id": self.role1_id.id}),
]}) (0, 0, {"role_id": self.role2_id.id}),
]
}
)
# Check user has groups from role1 and role2 # Check user has groups from role1 and role2
self.assertLessEqual(role1_groups, self.user_id.groups_id) self.assertLessEqual(role1_groups, self.user_id.groups_id)
self.assertLessEqual(role2_groups, self.user_id.groups_id) self.assertLessEqual(role2_groups, self.user_id.groups_id)
@@ -127,40 +171,109 @@ class TestUserRole(TransactionCase):
role2_groups = self.role2_id.implied_ids | self.role2_id.group_id role2_groups = self.role2_id.implied_ids | self.role2_id.group_id
# Configure the user with role1 and role2 # Configure the user with role1 and role2
self.user_id.write( self.user_id.write(
{'role_line_ids': [ {
(0, 0, {'role_id': self.role1_id.id}), "role_line_ids": [
(0, 0, {'role_id': self.role2_id.id}), (0, 0, {"role_id": self.role1_id.id}),
]}) (0, 0, {"role_id": self.role2_id.id}),
]
}
)
# Check user has groups from role1 and role2 # Check user has groups from role1 and role2
self.assertLessEqual(role1_groups, self.user_id.groups_id) self.assertLessEqual(role1_groups, self.user_id.groups_id)
self.assertLessEqual(role2_groups, self.user_id.groups_id) self.assertLessEqual(role2_groups, self.user_id.groups_id)
# Remove role2 from the user # Remove role2 from the user
self.user_id.role_line_ids.filtered( self.user_id.role_line_ids.filtered(
lambda l: l.role_id.id == self.role2_id.id).unlink() lambda l: l.role_id.id == self.role2_id.id
).unlink()
# Check user has groups from only role1 # Check user has groups from only role1
self.assertLessEqual(role1_groups, self.user_id.groups_id) self.assertLessEqual(role1_groups, self.user_id.groups_id)
self.assertFalse(role2_groups <= self.user_id.groups_id) self.assertFalse(role2_groups <= self.user_id.groups_id)
# Remove role1 from the user # Remove role1 from the user
self.user_id.role_line_ids.filtered( self.user_id.role_line_ids.filtered(
lambda l: l.role_id.id == self.role1_id.id).unlink() lambda l: l.role_id.id == self.role1_id.id
).unlink()
# Check user has no groups from role1 and role2 # Check user has no groups from role1 and role2
self.assertFalse(role1_groups <= self.user_id.groups_id) self.assertFalse(role1_groups <= self.user_id.groups_id)
self.assertFalse(role2_groups <= self.user_id.groups_id) self.assertFalse(role2_groups <= self.user_id.groups_id)
def test_default_user_roles(self): def test_default_user_roles(self):
self.default_user.write({ self.default_user.write(
'role_line_ids': [ {
(0, 0, { "role_line_ids": [
'role_id': self.role1_id.id, (0, 0, {"role_id": self.role1_id.id}),
}), (0, 0, {"role_id": self.role2_id.id}),
(0, 0, { ]
'role_id': self.role2_id.id, }
}) )
] user = self.user_model.create(
}) {
user = self.user_model.create({ "name": "USER TEST (DEFAULT ROLES)",
'name': "USER TEST (DEFAULT ROLES)", "login": "user_test_default_roles",
'login': 'user_test_default_roles' }
}) )
roles = self.role_model.browse([self.role1_id.id, self.role2_id.id]) roles = self.role_model.browse([self.role1_id.id, self.role2_id.id])
self.assertEqual(user.role_ids, roles) self.assertEqual(user.role_ids, roles)
def test_user_role_different_company(self):
self.user_id.write({"company_id": self.company1.id})
self.user_id.write(
{
"role_line_ids": [
(
0,
0,
{
"role_id": self.role2_id.id,
"company_id": self.company2.id,
},
)
]
}
)
# Check that user does not have any groups
self.assertEquals(
self.user_id.groups_id, self.env["res.groups"].browse()
)
def test_user_role_same_company(self):
self.user_id.write({"company_id": self.company1.id})
self.user_id.write(
{
"role_line_ids": [
(
0,
0,
{
"role_id": self.role1_id.id,
"company_id": self.company1.id,
},
)
]
}
)
user_group_ids = sorted(
set([group.id for group in self.user_id.groups_id])
)
role_group_ids = self.role1_id.trans_implied_ids.ids
role_group_ids.append(self.role1_id.group_id.id)
role_group_ids = sorted(set(role_group_ids))
# Check that user have groups implied by role 1
self.assertEqual(user_group_ids, role_group_ids)
def test_user_role_no_company(self):
self.user_id.write({"company_id": self.company1.id})
self.user_id.write(
{
"role_line_ids": [
(0, 0, {"role_id": self.role2_id.id, "company_id": False})
]
}
)
user_group_ids = sorted(
set([group.id for group in self.user_id.groups_id])
)
role_group_ids = self.role2_id.trans_implied_ids.ids
role_group_ids.append(self.role2_id.group_id.id)
role_group_ids = sorted(set(role_group_ids))
# Check that user have groups implied by role 2
self.assertEqual(user_group_ids, role_group_ids)

View File

@@ -24,6 +24,7 @@
<field name="date_from"/> <field name="date_from"/>
<field name="date_to"/> <field name="date_to"/>
<field name="is_enabled"/> <field name="is_enabled"/>
<field name="company_id" groups="base.group_multi_company"/>
</tree> </tree>
</field> </field>
</page> </page>

View File

@@ -16,6 +16,7 @@
<field name="date_from"/> <field name="date_from"/>
<field name="date_to"/> <field name="date_to"/>
<field name="is_enabled"/> <field name="is_enabled"/>
<field name="company_id" groups="base.group_multi_company"/>
</tree> </tree>
</field> </field>
</page> </page>