[FIX] base: user group selection fields

This is a followup on b6c688caa2, which
has introduced a new bug.

Consider two groups A and B in a given category, where B implies A and
also A.id > B.id.  For the sake of simplicity, assume that A.id=2 and
B.id=1.  Following the commit above, the name of the group selection
field will be 'sel_groups_1_2'.

Consider a user in group B.  Because B implies A, this means that the
user now belongs to both A and B.  A call to read() on that user returns
field 'sel_groups_1_2' with value 2, which on the form view appears as
the user belonging to A only.

The error is in read(), which assumes that the group ids in the field
name correspond to the implication order of the groups, which is no
longer the case since b6c688caa2.

closes odoo/odoo#78662

X-original-commit: e73c406671a51e9c1c4872a9e85eebe5656ea38e
Signed-off-by: Raphael Collet (rco) <rco@openerp.com>
This commit is contained in:
Raphael Collet
2021-10-20 06:39:50 +00:00
parent fa106b03bc
commit 143412765f
2 changed files with 48 additions and 1 deletions
+6 -1
View File
@@ -1471,7 +1471,12 @@ class UsersView(models.Model):
if is_boolean_group(f):
values[f] = get_boolean_group(f) in gids
elif is_selection_groups(f):
selected = [gid for gid in get_selection_groups(f) if gid in gids]
# determine selection groups, in order
sel_groups = self.env['res.groups'].sudo().browse(get_selection_groups(f))
sel_order = {g: len(g.trans_implied_ids & sel_groups) for g in sel_groups}
sel_groups = sel_groups.sorted(key=sel_order.get)
# determine which ones are in gids
selected = [gid for gid in sel_groups.ids if gid in gids]
# if 'Internal User' is in the group, this is the "User Type" group
# and we need to show 'Internal User' selected, not Public/Portal.
if self.env.ref('base.group_user').id in selected:
+42
View File
@@ -1,6 +1,7 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo.addons.base.models.res_users import is_selection_groups, get_selection_groups
from odoo.tests.common import TransactionCase, Form, tagged
@@ -129,3 +130,44 @@ class TestUsers2(TransactionCase):
user = f.save()
self.assertIn(self.env.ref('base.group_user'), user.groups_id)
def test_selection_groups(self):
# create 3 groups that should be in a selection
app = self.env['ir.module.category'].create({'name': 'Foo'})
group1, group2, group0 = self.env['res.groups'].create([
{'name': name, 'category_id': app.id}
for name in ('User', 'Manager', 'Visitor')
])
# THIS PART IS NECESSARY TO REPRODUCE AN ISSUE: group1.id < group2.id < group0.id
self.assertLess(group1.id, group2.id)
self.assertLess(group2.id, group0.id)
# implication order is group0 < group1 < group2
group2.implied_ids = group1
group1.implied_ids = group0
groups = group0 + group1 + group2
# determine the name of the field corresponding to groups
fname = next(
name
for name in self.env['res.users'].fields_get()
if is_selection_groups(name) and group0.id in get_selection_groups(name)
)
self.assertCountEqual(get_selection_groups(fname), groups.ids)
# create a user
user = self.env['res.users'].create({'name': 'foo', 'login': 'foo'})
# put user in group0, and check field value
user.write({fname: group0.id})
self.assertEqual(user.groups_id & groups, group0)
self.assertEqual(user.read([fname])[0][fname], group0.id)
# put user in group1, and check field value
user.write({fname: group1.id})
self.assertEqual(user.groups_id & groups, group0 + group1)
self.assertEqual(user.read([fname])[0][fname], group1.id)
# put user in group2, and check field value
user.write({fname: group2.id})
self.assertEqual(user.groups_id & groups, groups)
self.assertEqual(user.read([fname])[0][fname], group2.id)