[FW][MERGE] *: improve performance of users and partners creation.

Users (res.users) and Partners (res.partner) are two main models of Odoo.

This PR aims at improving the performance of their creation:
* Records creation in batch
* Code optimizations to reduce number of queries when possible

Task Id - 2229358

closes odoo/odoo#50209

Forward-port-of: odoo/odoo#48912
Signed-off-by: Martin Trigaux (mat) <mat@odoo.com>
Signed-off-by: Victor Feyens (vfe) <vfe@odoo.com>
This commit is contained in:
Odoo's Mergebot
2020-04-27 13:03:23 +02:00
committed by GitHub
5 changed files with 55 additions and 45 deletions
+11 -9
View File
@@ -233,16 +233,18 @@ class ResUsers(models.Model):
inactive_users.with_context(create_user=True).action_reset_password()
return res
@api.model
def create(self, values):
@api.model_create_multi
def create(self, vals_list):
# overridden to automatically invite user to sign up
user = super(ResUsers, self).create(values)
if user.email and not self.env.context.get('no_reset_password'):
try:
user.with_context(create_user=True).action_reset_password()
except MailDeliveryException:
user.partner_id.with_context(create_user=True).signup_cancel()
return user
users = super(ResUsers, self).create(vals_list)
if not self.env.context.get('no_reset_password'):
users_with_email = users.filtered('email')
if users_with_email:
try:
users_with_email.with_context(create_user=True).action_reset_password()
except MailDeliveryException:
users_with_email.partner_id.with_context(create_user=True).signup_cancel()
return users
@api.returns('self', lambda value: value.id)
def copy(self, default=None):
+7 -6
View File
@@ -481,12 +481,13 @@ class ResPartner(models.Model):
vat_number = format_func(vat_number)
return vat_country.upper() + vat_number
@api.model
def create(self, values):
if values.get('vat'):
country_id = values.get('country_id')
values['vat'] = self._fix_vat_number(values['vat'], country_id)
return super(ResPartner, self).create(values)
@api.model_create_multi
def create(self, vals_list):
for values in vals_list:
if values.get('vat'):
country_id = values.get('country_id')
values['vat'] = self._fix_vat_number(values['vat'], country_id)
return super(ResPartner, self).create(vals_list)
def write(self, values):
if values.get('vat') and len(self.mapped('country_id')) == 1:
+6 -6
View File
@@ -6,13 +6,13 @@ from odoo import api, models
class ResUsers(models.Model):
_inherit = "res.users"
@api.model
def create(self, vals):
@api.model_create_multi
def create(self, vals_list):
""" Automatically subscribe employee users to default digest if activated """
user = super(ResUsers, self).create(vals)
users = super(ResUsers, self).create(vals_list)
default_digest_emails = self.env['ir.config_parameter'].sudo().get_param('digest.default_digest_emails')
default_digest_id = self.env['ir.config_parameter'].sudo().get_param('digest.default_digest_id')
if user.has_group('base.group_user') and default_digest_emails and default_digest_id:
if default_digest_emails and default_digest_id:
digest = self.env['digest.digest'].sudo().browse(int(default_digest_id))
digest.user_ids |= user
return user
digest.user_ids |= users.filtered_domain([('share', '=', False)])
return users
+10 -9
View File
@@ -71,17 +71,18 @@ GROUP BY channel_moderator.res_users_id""", [tuple(self.ids)])
type(self).SELF_READABLE_FIELDS.extend(['notification_type'])
return init_res
@api.model
def create(self, values):
if not values.get('login', False):
action = self.env.ref('base.action_res_users')
msg = _("You cannot create a new user from here.\n To create new user please go to configuration panel.")
raise exceptions.RedirectWarning(msg, action.id, _('Go to the configuration panel'))
@api.model_create_multi
def create(self, vals_list):
for values in vals_list:
if not values.get('login', False):
action = self.env.ref('base.action_res_users')
msg = _("You cannot create a new user from here.\n To create new user please go to configuration panel.")
raise exceptions.RedirectWarning(msg, action.id, _('Go to the configuration panel'))
user = super(Users, self).create(values)
users = super(Users, self).create(vals_list)
# Auto-subscribe to channels
self.env['mail.channel'].search([('group_ids', 'in', user.groups_id.ids)])._subscribe_users()
return user
self.env['mail.channel'].search([('group_ids', 'in', users.groups_id.ids)])._subscribe_users()
return users
def write(self, vals):
write_res = super(Users, self).write(vals)
+21 -15
View File
@@ -211,8 +211,8 @@ class Users(models.Model):
SELF_READABLE_FIELDS = ['signature', 'company_id', 'login', 'email', 'name', 'image_1920', 'image_1024', 'image_512', 'image_256', 'image_128', 'lang', 'tz', 'tz_offset', 'groups_id', 'partner_id', '__last_update', 'action_id']
def _default_groups(self):
default_user = self.env.ref('base.default_user', raise_if_not_found=False)
return (default_user or self.env['res.users']).sudo().groups_id
default_user_id = self.env['ir.model.data'].xmlid_to_res_id('base.default_user', raise_if_not_found=False)
return self.env['res.users'].browse(default_user_id).sudo().groups_id if default_user_id else []
@api.model
def _get_default_image(self):
@@ -357,8 +357,10 @@ class Users(models.Model):
@api.depends('groups_id')
def _compute_share(self):
for user in self:
user.share = not user.has_group('base.group_user')
user_group_id = self.env['ir.model.data'].xmlid_to_res_id('base.group_user')
internal_users = self.filtered_domain([('groups_id', 'in', [user_group_id])])
internal_users.share = False
(self - internal_users).share = True
def _compute_companies_count(self):
self.companies_count = self.env['res.company'].sudo().search_count([])
@@ -1250,17 +1252,21 @@ class ModuleCategory(models.Model):
class UsersView(models.Model):
_inherit = 'res.users'
@api.model
def create(self, values):
values = self._remove_reified_groups(values)
user = super(UsersView, self).create(values)
group_multi_company = self.env.ref('base.group_multi_company', False)
if group_multi_company and 'company_ids' in values:
if len(user.company_ids) <= 1 and user.id in group_multi_company.users.ids:
user.write({'groups_id': [(3, group_multi_company.id)]})
elif len(user.company_ids) > 1 and user.id not in group_multi_company.users.ids:
user.write({'groups_id': [(4, group_multi_company.id)]})
return user
@api.model_create_multi
def create(self, vals_list):
new_vals_list = []
for values in vals_list:
new_vals_list.append(self._remove_reified_groups(values))
users = super(UsersView, self).create(new_vals_list)
group_multi_company_id = self.env['ir.model.data'].xmlid_to_res_id(
'base.group_multi_company', raise_if_not_found=False)
if group_multi_company_id:
for user in users:
if len(user.company_ids) <= 1 and group_multi_company_id in user.groups_id.ids:
user.write({'groups_id': [(3, group_multi_company_id)]})
elif len(user.company_ids) > 1 and group_multi_company_id in user.groups_id.ids:
user.write({'groups_id': [(4, group_multi_company_id)]})
return users
def write(self, values):
values = self._remove_reified_groups(values)