[REF] mail: make alias creation work in batch
In this commit we rewrite part of alias name uniqueness check as well as alias mixin alias creation to enable batch create of * alias records (mail.alias); * records using aliases through mail.alias.mixin; See merge commit for more details. Task ID-2330149 COM PR odoo/odoo#61246 ENT PR odoo/enterprise#14561
This commit is contained in:
committed by
Thibault Delavallée
parent
646457d761
commit
18b49836b7
@@ -11,11 +11,11 @@ class IrConfigParameter(models.Model):
|
||||
def create(self, vals_list):
|
||||
for vals in vals_list:
|
||||
if vals.get('key') in ['mail.bounce.alias', 'mail.catchall.alias']:
|
||||
vals['value'] = self.env['mail.alias']._clean_and_check_unique(vals.get('value'))
|
||||
vals['value'] = self.env['mail.alias']._clean_and_check_unique([vals.get('value')])[0]
|
||||
return super().create(vals_list)
|
||||
|
||||
def write(self, vals):
|
||||
for parameter in self:
|
||||
if 'value' in vals and parameter.key in ['mail.bounce.alias', 'mail.catchall.alias'] and vals['value'] != parameter.value:
|
||||
vals['value'] = self.env['mail.alias']._clean_and_check_unique(vals.get('value'))
|
||||
vals['value'] = self.env['mail.alias']._clean_and_check_unique([vals.get('value')])[0]
|
||||
return super().write(vals)
|
||||
|
||||
@@ -107,22 +107,34 @@ class Alias(models.Model):
|
||||
except Exception:
|
||||
raise ValidationError(_('Invalid expression, it must be a literal python dictionary definition e.g. "{\'field\': \'value\'}"'))
|
||||
|
||||
@api.model
|
||||
def create(self, vals):
|
||||
""" Creates an email.alias record according to the values provided in ``vals``,
|
||||
with 2 alterations: the ``alias_name`` value may be cleaned by replacing
|
||||
certain unsafe characters, and the ``alias_model_id`` value will set to the
|
||||
model ID of the ``model_name`` context value, if provided. Also, it raises
|
||||
UserError if given alias name is already assigned.
|
||||
@api.model_create_multi
|
||||
def create(self, vals_list):
|
||||
""" Creates email.alias records according to the values provided in
|
||||
``vals`` with 1 alteration:
|
||||
|
||||
* ``alias_name`` value may be cleaned by replacing certain unsafe
|
||||
characters;
|
||||
|
||||
:raise UserError: if given alias_name is already assigned or there are
|
||||
duplicates in given vals_list;
|
||||
"""
|
||||
if vals.get('alias_name'):
|
||||
vals['alias_name'] = self._clean_and_check_unique(vals.get('alias_name'))
|
||||
return super(Alias, self).create(vals)
|
||||
alias_names = [vals['alias_name'] for vals in vals_list if vals.get('alias_name')]
|
||||
if alias_names:
|
||||
sanitized_names = self._clean_and_check_unique(alias_names)
|
||||
for vals in vals_list:
|
||||
if vals.get('alias_name'):
|
||||
vals['alias_name'] = sanitized_names[alias_names.index(vals['alias_name'])]
|
||||
return super(Alias, self).create(vals_list)
|
||||
|
||||
def write(self, vals):
|
||||
""""Raises UserError if given alias name is already assigned"""
|
||||
if vals.get('alias_name') and self.ids:
|
||||
vals['alias_name'] = self._clean_and_check_unique(vals.get('alias_name'))
|
||||
if len(self) > 1:
|
||||
raise UserError(_(
|
||||
'Email alias %(alias_name)s cannot be used on %(count)d records at the same time. Please update records one by one.',
|
||||
alias_name=vals['alias_name'], count=len(self)
|
||||
))
|
||||
vals['alias_name'] = self._clean_and_check_unique([vals.get('alias_name')])[0]
|
||||
return super(Alias, self).write(vals)
|
||||
|
||||
def name_get(self):
|
||||
@@ -140,22 +152,25 @@ class Alias(models.Model):
|
||||
res.append((record['id'], _("Inactive Alias")))
|
||||
return res
|
||||
|
||||
def _clean_and_check_unique(self, name):
|
||||
def _clean_and_check_unique(self, names):
|
||||
"""When an alias name appears to already be an email, we keep the local
|
||||
part only. A sanitizing / cleaning is also performed on the name. If
|
||||
name already exists an UserError is raised. """
|
||||
sanitized_name = remove_accents(name).lower().split('@')[0]
|
||||
sanitized_name = re.sub(r'[^\w+.]+', '-', sanitized_name)
|
||||
sanitized_name = sanitized_name.encode('ascii', errors='replace').decode()
|
||||
sanitized_names = []
|
||||
for name in names:
|
||||
sanitized_name = remove_accents(name).lower().split('@')[0]
|
||||
sanitized_name = re.sub(r'[^\w+.]+', '-', sanitized_name)
|
||||
sanitized_name = sanitized_name.encode('ascii', errors='replace').decode()
|
||||
sanitized_names.append(sanitized_name)
|
||||
|
||||
catchall_alias = self.env['ir.config_parameter'].sudo().get_param('mail.catchall.alias')
|
||||
bounce_alias = self.env['ir.config_parameter'].sudo().get_param('mail.bounce.alias')
|
||||
domain = [('alias_name', '=', sanitized_name)]
|
||||
domain = [('alias_name', 'in', sanitized_names)]
|
||||
if self:
|
||||
domain += [('id', 'not in', self.ids)]
|
||||
if sanitized_name in [catchall_alias, bounce_alias] or self.search_count(domain):
|
||||
if any(sanitized_name in [catchall_alias, bounce_alias] for sanitized_name in sanitized_names) or self.search_count(domain):
|
||||
raise UserError(_('The e-mail alias is already used. Please enter another one.'))
|
||||
return sanitized_name
|
||||
return sanitized_names
|
||||
|
||||
def open_document(self):
|
||||
if not self.alias_model_id or not self.alias_force_thread_id:
|
||||
|
||||
@@ -27,14 +27,29 @@ class AliasMixin(models.AbstractModel):
|
||||
@api.model_create_multi
|
||||
def create(self, vals_list):
|
||||
""" Create a record with each ``vals`` or ``vals_list`` and create a corresponding alias. """
|
||||
valid_vals_list = []
|
||||
# prepare all alias values
|
||||
alias_vals_list, record_vals_list = [], []
|
||||
for vals in vals_list:
|
||||
new_alias = not vals.get('alias_id')
|
||||
if new_alias:
|
||||
alias_vals, record_vals = self._alias_filter_fields(vals)
|
||||
alias_vals.update(self._alias_get_creation_values())
|
||||
alias = self.env['mail.alias'].sudo().create(alias_vals)
|
||||
record_vals['alias_id'] = alias.id
|
||||
alias_vals_list.append(alias_vals)
|
||||
record_vals_list.append(record_vals)
|
||||
|
||||
# create all aliases
|
||||
alias_ids = []
|
||||
if alias_vals_list:
|
||||
alias_ids = iter(self.env['mail.alias'].sudo().create(alias_vals_list).ids)
|
||||
|
||||
# update alias values in create vals directly
|
||||
valid_vals_list = []
|
||||
record_vals_iter = iter(record_vals_list)
|
||||
for vals in vals_list:
|
||||
new_alias = not vals.get('alias_id')
|
||||
if new_alias:
|
||||
record_vals = next(record_vals_iter)
|
||||
record_vals['alias_id'] = next(alias_ids)
|
||||
valid_vals_list.append(record_vals)
|
||||
else:
|
||||
valid_vals_list.append(vals)
|
||||
|
||||
Reference in New Issue
Block a user