summaryrefslogtreecommitdiff
path: root/odoo/addons/base/models/res_users.py
diff options
context:
space:
mode:
Diffstat (limited to 'odoo/addons/base/models/res_users.py')
-rw-r--r--odoo/addons/base/models/res_users.py37
1 files changed, 35 insertions, 2 deletions
diff --git a/odoo/addons/base/models/res_users.py b/odoo/addons/base/models/res_users.py
index ea8a05811f3..66b0b2f3e49 100644
--- a/odoo/addons/base/models/res_users.py
+++ b/odoo/addons/base/models/res_users.py
@@ -400,10 +400,42 @@ class Users(models.Model):
@api.constrains('groups_id')
def _check_one_user_type(self):
- for user in self:
- if len(user.groups_id.filtered(lambda x: x.category_id.xml_id == 'base.module_category_user_type')) > 1:
+ """We check that no users are both portal and users (same with public).
+ This could typically happen because of implied groups.
+ """
+ user_types_category = self.env.ref('base.module_category_user_type', raise_if_not_found=False)
+ user_types_groups = self.env['res.groups'].search(
+ [('category_id', '=', user_types_category.id)]) if user_types_category else False
+ if user_types_groups: # needed at install
+ if self._has_multiple_groups(user_types_groups.ids):
raise ValidationError(_('The user cannot have more than one user types.'))
+ def _has_multiple_groups(self, group_ids):
+ """The method is not fast if the list of ids is very long;
+ so we rather check all users than limit to the size of the group
+ :param group_ids: list of group ids
+ :return: boolean: is there at least a user in at least 2 of the provided groups
+ """
+ if group_ids:
+ args = [tuple(group_ids)]
+ if len(self.ids) == 1:
+ where_clause = "AND r.uid = %s"
+ args.append(self.id)
+ else:
+ where_clause = "" # default; we check ALL users (actually pretty efficient)
+ query = """
+ SELECT 1 FROM res_groups_users_rel WHERE EXISTS(
+ SELECT r.uid
+ FROM res_groups_users_rel r
+ WHERE r.gid IN %s""" + where_clause + """
+ GROUP BY r.uid HAVING COUNT(r.gid) > 1
+ )
+ """
+ self.env.cr.execute(query, args)
+ return bool(self.env.cr.fetchall())
+ else:
+ return False
+
def toggle_active(self):
for user in self:
if not user.active and not user.partner_id.active:
@@ -939,6 +971,7 @@ class GroupsImplied(models.Model):
JOIN group_imply i ON (r.gid = i.hid)
WHERE i.gid = %(gid)s
""", dict(gid=group.id))
+ self._check_one_user_type()
return res
class UsersImplied(models.Model):