diff options
Diffstat (limited to 'odoo/addons/base/models/res_users.py')
| -rw-r--r-- | odoo/addons/base/models/res_users.py | 38 |
1 files changed, 36 insertions, 2 deletions
diff --git a/odoo/addons/base/models/res_users.py b/odoo/addons/base/models/res_users.py index 204ce97f6fe..2fb44ff6382 100644 --- a/odoo/addons/base/models/res_users.py +++ b/odoo/addons/base/models/res_users.py @@ -405,11 +405,44 @@ class Users(models.Model): @api.multi @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.')) @api.multi + 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 + + @api.multi def toggle_active(self): for user in self: if not user.active and not user.partner_id.active: @@ -951,6 +984,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): |
