diff --git a/addons/mail/models/mail_alias.py b/addons/mail/models/mail_alias.py index ba1afd02d45..72fadd87b1b 100644 --- a/addons/mail/models/mail_alias.py +++ b/addons/mail/models/mail_alias.py @@ -249,3 +249,71 @@ class Alias(models.Model): 'res_id': self.alias_parent_thread_id, 'type': 'ir.actions.act_window', } + + +class AliasMixin(models.AbstractModel): + """ A mixin for models that inherits mail.alias. This mixin initializes the + alias_id column in database, and manages the expected one-to-one + relation between your model and mail aliases. + """ + _name = 'mail.alias.mixin' + _inherits = {'mail.alias': 'alias_id'} + + alias_id = fields.Many2one('mail.alias', string='Alias', ondelete="restrict", required=True) + + def get_alias_model_name(self, 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 + of this alias model. The value may depend on ``vals``, the dict of + values passed to ``create`` when a record of this model is created. + """ + return None + + def get_alias_values(self): + """ Return values to create an alias, or to write on the alias after its + creation. + """ + return {'alias_parent_thread_id': self.id} + + @api.model + def create(self, vals): + """ Create a record with ``vals``, and create a corresponding alias. """ + record = super(AliasMixin, self.with_context( + alias_model_name=self.get_alias_model_name(vals), + alias_parent_model_name=self._name, + )).create(vals) + record.alias_id.sudo().write(record.get_alias_values()) + return record + + @api.multi + 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() + return res + + def _init_column(self, cr, name, context=None): + """ Create aliases for existing rows. """ + super(AliasMixin, self)._init_column(cr, name, context=context) + if name != 'alias_id': + return + + alias_ctx = { + 'alias_model_name': self.get_alias_model_name({}), + 'alias_parent_model_name': self._name, + } + alias_model = self.pool['mail.alias'].browse(cr, SUPERUSER_ID, [], alias_ctx) + + child_ctx = { + 'active_test': False, # retrieve all records + 'prefetch_fields': False, # do not prefetch fields on records + } + child_model = self.browse(cr, SUPERUSER_ID, [], child_ctx) + + for record in child_model.search([('alias_id', '=', False)]): + # create the alias, and link it to the current record + alias = alias_model.create(record.get_alias_values()) + record.with_context({'mail_notrack': True}).alias_id = alias + _logger.info('Mail alias created for %s %s (id %s)', + record._name, record.display_name, record.id) diff --git a/addons/mail/models/res_users.py b/addons/mail/models/res_users.py index 96ede9aa618..d0c16736ef8 100644 --- a/addons/mail/models/res_users.py +++ b/addons/mail/models/res_users.py @@ -14,8 +14,7 @@ class Users(models.Model): group, and the user. This is done by overriding the write method. """ _name = 'res.users' - _inherit = ['res.users'] - _inherits = {'mail.alias': 'alias_id'} + _inherit = ['mail.alias.mixin', 'res.users'] alias_id = fields.Many2one('mail.alias', 'Alias', ondelete="restrict", required=True, help="Email address internally associated with this user. Incoming "\ @@ -35,9 +34,13 @@ class Users(models.Model): self.SELF_READABLE_FIELDS.extend(['notify_email', 'alias_domain', 'alias_name']) return init_res - def _auto_init(self, cr, context=None): - """ Installation hook: aliases """ - return self.pool.get('mail.alias').migrate_to_alias(cr, self._name, self._table, super(Users, self)._auto_init, self._name, self._columns['alias_id'], 'login', alias_force_key='id', context=context) + def get_alias_model_name(self, vals): + return self._name + + def get_alias_values(self): + values = super(Users, self).get_alias_values() + values['alias_force_thread_id'] = self.id + return values @api.model def create(self, values): @@ -46,11 +49,7 @@ class Users(models.Model): msg = _("You cannot create a new user from here.\n To create new user please go to configuration panel.") raise openerp.exceptions.RedirectWarning(msg, action.id, _('Go to the configuration panel')) - user = super(Users, self.with_context( - alias_model_name=self._name, - alias_parent_model_name=self._name - )).create(values) - user.alias_id.sudo().write({"alias_force_thread_id": user.id, "alias_parent_thread_id": user.id}) + user = super(Users, self).create(values) # create a welcome message user._create_welcome_message() @@ -81,14 +80,6 @@ class Users(models.Model): # TODO change SUPERUSER_ID into user.id but catch errors return self.partner_id.sudo().message_post(body=body) - @api.multi - def unlink(self): - # Cascade-delete mail aliases as well, as they should not exist without the user. - aliases = self.mapped('alias_id') - res = super(Users, self).unlink() - aliases.unlink() - return res - def _message_post_get_pid(self): self.ensure_one() if 'thread_model' in self.env.context: