[REF] mail: make alias mixin multi-enabled

Purpose of this commit is to allow multi-create in alias mixin by correctly
creating / updating aliases in batch.

Task ID 1919277
Community PR odoo/odoo#41160
Enterprise PR odoo/enterprise#6983
Upgrade PR odoo/upgrade#872

Co-Authored-By: Rémy Voet <ryv@odoo.com>
Co-Authored-By: Thibault Delavallée <tde@odoo.com>
This commit is contained in:
ryv-odoo
2020-04-17 06:52:09 +00:00
committed by Thibault Delavallée
co-authored by Thibault Delavallée
parent 7cfd364db5
commit 186cfb5ebd
8 changed files with 74 additions and 35 deletions
+8 -5
View File
@@ -35,6 +35,9 @@ class AccountJournal(models.Model):
def _get_bank_statements_available_sources(self):
return self.__get_bank_statements_available_sources()
def _default_alias_domain(self):
return self.env["ir.config_parameter"].sudo().get_param("mail.catchall.domain")
name = fields.Char(string='Journal Name', required=True)
code = fields.Char(string='Short Code', size=5, required=True, help="Shorter name used for display. The journal entries of this journal will also be named using this prefix by default.")
active = fields.Boolean(default=True, help="Set active to false to hide the Journal without removing it.")
@@ -140,7 +143,7 @@ class AccountJournal(models.Model):
# alias configuration for journals
alias_id = fields.Many2one('mail.alias', string='Alias', copy=False)
alias_domain = fields.Char('Alias domain', compute='_compute_alias_domain', default=lambda self: self.env["ir.config_parameter"].sudo().get_param("mail.catchall.domain"))
alias_domain = fields.Char('Alias domain', compute='_compute_alias_domain', default=_default_alias_domain, compute_sudo=True)
alias_name = fields.Char('Alias Name', related='alias_id.alias_name', help="It creates draft invoices and bills by sending an email.", readonly=False)
journal_group_ids = fields.Many2many('account.journal.group',
@@ -170,7 +173,7 @@ class AccountJournal(models.Model):
journal.suspense_account_id = False
def _compute_alias_domain(self):
alias_domain = self.env["ir.config_parameter"].sudo().get_param("mail.catchall.domain")
alias_domain = self._default_alias_domain()
for record in self:
record.alias_domain = alias_domain
@@ -306,7 +309,7 @@ class AccountJournal(models.Model):
accounts = self.search([('bank_account_id', '=', bank_account.id)])
if accounts <= self:
bank_accounts += bank_account
self.mapped('alias_id').unlink()
self.mapped('alias_id').sudo().unlink()
ret = super(AccountJournal, self).unlink()
bank_accounts.unlink()
return ret
@@ -323,11 +326,11 @@ class AccountJournal(models.Model):
self.ensure_one()
alias_values = self._get_alias_values(type=vals.get('type') or self.type, alias_name=vals.get('alias_name'))
if self.alias_id:
self.alias_id.write(alias_values)
self.alias_id.sudo().write(alias_values)
else:
alias_values['alias_model_id'] = self.env['ir.model']._get('account.move').id
alias_values['alias_parent_model_id'] = self.env['ir.model']._get('account.journal').id
self.alias_id = self.env['mail.alias'].create(alias_values)
self.alias_id = self.env['mail.alias'].sudo().create(alias_values)
if vals.get('alias_name'):
# remove alias_name to avoid useless write on alias
-3
View File
@@ -99,9 +99,6 @@ class Team(models.Model):
def write(self, vals):
result = super(Team, self).write(vals)
if 'use_leads' in vals or 'alias_defaults' in vals:
for team in self:
team.alias_id.write(team.get_alias_values())
if 'use_leads' in vals or 'use_opportunities' in vals:
self.filtered(lambda team: not team.use_leads and not team.use_opportunities).alias_name = False
return result
+6 -4
View File
@@ -27,6 +27,9 @@ class Alias(models.Model):
_rec_name = 'alias_name'
_order = 'alias_model_id, alias_name'
def _default_alias_domain(self):
return self.env["ir.config_parameter"].sudo().get_param("mail.catchall.domain")
alias_name = fields.Char('Alias Name', copy=False, help="The name of the email alias, e.g. 'jobs' if you want to catch emails for <jobs@example.odoo.com>")
alias_model_id = fields.Many2one('ir.model', 'Aliased Model', required=True, ondelete="cascade",
help="The model (Odoo Document Kind) to which this alias "
@@ -48,8 +51,7 @@ class Alias(models.Model):
'Record Thread ID',
help="Optional ID of a thread (record) to which all incoming messages will be attached, even "
"if they did not reply to it. If set, this will disable the creation of new records completely.")
alias_domain = fields.Char('Alias domain', compute='_get_alias_domain',
default=lambda self: self.env["ir.config_parameter"].sudo().get_param("mail.catchall.domain"))
alias_domain = fields.Char('Alias domain', compute='_compute_alias_domain', default=_default_alias_domain)
alias_parent_model_id = fields.Many2one(
'ir.model', 'Parent Model',
help="Parent model holding the alias. The model holding the alias reference "
@@ -73,8 +75,8 @@ class Alias(models.Model):
('alias_unique', 'UNIQUE(alias_name)', 'Unfortunately this email alias is already used, please choose a unique one')
]
def _get_alias_domain(self):
alias_domain = self.env["ir.config_parameter"].sudo().get_param("mail.catchall.domain")
def _compute_alias_domain(self):
alias_domain = self._default_alias_domain()
for record in self:
record.alias_domain = alias_domain
+40 -13
View File
@@ -16,6 +16,7 @@ class AliasMixin(models.AbstractModel):
_name = 'mail.alias.mixin'
_inherits = {'mail.alias': 'alias_id'}
_description = 'Email Aliases Mixin'
ALIAS_WRITEABLE_FIELDS = ['alias_name', 'alias_contact', 'alias_defaults']
alias_id = fields.Many2one('mail.alias', string='Alias', ondelete="restrict", required=True)
@@ -23,28 +24,54 @@ class AliasMixin(models.AbstractModel):
# CRUD
# --------------------------------------------------
@api.model
def create(self, vals):
""" Create a record with ``vals``, and create a corresponding alias. """
new_alias = not 'alias_id' in vals
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'].create(alias_vals)
record_vals['alias_id'] = alias.id
@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 = []
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
valid_vals_list.append(record_vals)
else:
valid_vals_list.append(vals)
record = super(AliasMixin, self).create(record_vals)
alias.sudo().write(record._alias_get_creation_values())
records = super(AliasMixin, self).create(valid_vals_list)
return record
for record in records:
record.alias_id.sudo().write(record._alias_get_creation_values())
return records
def write(self, vals):
""" Split writable fields of mail.alias and other fields alias fields will
write with sudo and the other normally """
alias_vals, record_vals = self._alias_filter_fields(vals, filters=self.ALIAS_WRITEABLE_FIELDS)
if record_vals:
super(AliasMixin, self).write(record_vals)
if alias_vals and (record_vals or self.check_access_rights('write', raise_exception=False)):
self.mapped('alias_id').sudo().write(alias_vals)
return True
def unlink(self):
""" Delete the given records, and cascade-delete their corresponding alias. """
aliases = self.mapped('alias_id')
res = super(AliasMixin, self).unlink()
aliases.unlink()
aliases.sudo().unlink()
return res
@api.returns(None, lambda value: value[0])
def copy_data(self, default=None):
data = super(AliasMixin, self).copy_data(default)[0]
for fields_not_writable in set(self.env['mail.alias']._fields.keys()) - set(self.ALIAS_WRITEABLE_FIELDS):
if fields_not_writable in data:
del data[fields_not_writable]
return [data]
def _init_column(self, name):
""" Create aliases for existing rows. """
super(AliasMixin, self)._init_column(name)
+1 -1
View File
@@ -19,7 +19,7 @@ access_mail_channel_partner_portal,mail.channel.partner.portal,model_mail_channe
access_mail_channel_partner_user,mail.channel.partner.user,model_mail_channel_partner,base.group_user,1,1,1,1
access_mail_moderation_user,mail.moderation.user,model_mail_moderation,base.group_user,1,1,1,1
access_mail_alias_all,mail.alias.all,model_mail_alias,,1,0,0,0
access_mail_alias_user,mail.alias.user,model_mail_alias,base.group_user,1,1,1,1
access_mail_alias_user,mail.alias.user,model_mail_alias,base.group_user,1,0,0,0
access_mail_alias_system,mail.alias.system,model_mail_alias,base.group_system,1,1,1,1
access_mail_message_subtype_all,mail.message.subtype.all,model_mail_message_subtype,,1,0,0,0
access_mail_message_subtype_user,mail.message.subtype.user,model_mail_message_subtype,base.group_user,1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
19 access_mail_channel_partner_user mail.channel.partner.user model_mail_channel_partner base.group_user 1 1 1 1
20 access_mail_moderation_user mail.moderation.user model_mail_moderation base.group_user 1 1 1 1
21 access_mail_alias_all mail.alias.all model_mail_alias 1 0 0 0
22 access_mail_alias_user mail.alias.user model_mail_alias base.group_user 1 1 0 1 0 1 0
23 access_mail_alias_system mail.alias.system model_mail_alias base.group_system 1 1 1 1
24 access_mail_message_subtype_all mail.message.subtype.all model_mail_message_subtype 1 0 0 0
25 access_mail_message_subtype_user mail.message.subtype.user model_mail_message_subtype base.group_user 1 1 1 1
@@ -18,7 +18,6 @@ access_resource_calendar_leaves_user,resource.calendar.leaves user,resource.mode
access_project_tags_all,project.project_tags_all,model_project_tags,,1,0,0,0
access_project_tags_manager,project.project_tags_manager,model_project_tags,project.group_project_manager,1,1,1,1
access_project_tags_portal,project_tags_portal,project.model_project_tags,base.group_portal,1,0,0,0
access_mail_alias,mail.alias,mail.model_mail_alias,project.group_project_manager,1,1,1,1
access_mail_activity_type_project_manager,mail.activity.type.project.manager,mail.model_mail_activity_type,project.group_project_manager,1,1,1,1
access_account_analytic_account_user,account.analytic.account,analytic.model_account_analytic_account,project.group_project_user,1,0,0,0
access_account_analytic_account_manager,account.analytic.account,analytic.model_account_analytic_account,project.group_project_manager,1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
18 access_project_tags_all project.project_tags_all model_project_tags 1 0 0 0
19 access_project_tags_manager project.project_tags_manager model_project_tags project.group_project_manager 1 1 1 1
20 access_project_tags_portal project_tags_portal project.model_project_tags base.group_portal 1 0 0 0
access_mail_alias mail.alias mail.model_mail_alias project.group_project_manager 1 1 1 1
21 access_mail_activity_type_project_manager mail.activity.type.project.manager mail.model_mail_activity_type project.group_project_manager 1 1 1 1
22 access_account_analytic_account_user account.analytic.account analytic.model_account_analytic_account project.group_project_user 1 0 0 0
23 access_account_analytic_account_manager account.analytic.account analytic.model_account_analytic_account project.group_project_manager 1 1 1 1
+13 -2
View File
@@ -89,12 +89,23 @@ class TestMailAlias(TestMailCommon):
self.assertEqual(record.alias_id.alias_contact, 'followers')
record.write({
'alias_force_thread_id': False,
'alias_name': 'better.alias.test',
'alias_defaults': "{'default_name': 'defaults'}"
})
self.assertFalse(record.alias_id.alias_force_thread_id)
self.assertEqual(record.alias_id.alias_name, 'better.alias.test')
self.assertEqual(record.alias_id.alias_defaults, "{'default_name': 'defaults'}")
with self.assertRaises(exceptions.AccessError):
record.write({
'alias_force_thread_id': 0,
})
with self.assertRaises(exceptions.AccessError):
record.write({
'alias_model_id': self.env['ir.model']._get('mail.test.gateway').id,
})
def test_alias_setup(self):
alias = self.env['mail.alias'].create({
'alias_model_id': self.env['ir.model']._get('mail.test').id,
+6 -6
View File
@@ -556,7 +556,7 @@ specific overrides to work correctly. These overrides will specify the values
of the created alias, like the kind of record it must create and possibly
some default values these records may have depending on the parent object:
.. method:: get_alias_model_name(vals)
.. method:: _get_alias_model_name(vals)
Return the model name for the alias. Incoming emails that are not
replies to existing records will cause the creation of a new record
@@ -568,7 +568,7 @@ some default values these records may have depending on the parent object:
:return: model name
:rtype: str
.. method:: get_alias_values()
.. method:: _get_alias_values()
Return values to create an alias, or to write on the alias after its
creation. While not completely mandatory, it is usually required to make
@@ -579,7 +579,7 @@ some default values these records may have depending on the parent object:
:return: dictionnary of values that will be written to the new alias
:rtype: dict
The ``get_alias_values()`` override is particularly interesting as it allows you
The ``_get_alias_values()`` override is particularly interesting as it allows you
to modify the behaviour of your aliases easily. Among the fields that can be set
on the alias, the following are of particular interest:
@@ -632,13 +632,13 @@ you to make your alias easily configurable from the record's form view.
alias_id = fields.Many2one('mail.alias', string='Alias', ondelete="restrict",
required=True)
def get_alias_model_name(self, vals):
def _get_alias_model_name(self, vals):
""" Specify the model that will get created when the alias receives a message """
return 'business.expense'
def get_alias_values(self):
def _get_alias_values(self):
""" Specify some default values that will be set in the alias at its creation """
values = super(BusinessTrip, self).get_alias_values()
values = super(BusinessTrip, self)._get_alias_values()
# alias_defaults holds a dictionnary that will be written
# to all records created by this alias
#