diff --git a/addons/mail/models/mail_message.py b/addons/mail/models/mail_message.py index bd4face91ce..23e77971004 100644 --- a/addons/mail/models/mail_message.py +++ b/addons/mail/models/mail_message.py @@ -761,18 +761,16 @@ class Message(models.Model): @api.multi def _notify(self, force_send=False, send_after_commit=True, user_signature=True): - """ Add the related record followers to the destination partner_ids if is not a private message. - Call mail_notification.notify to manage the email sending - """ + """ Compute recipients to notify based on specified recipients and document + followers. Delegate notification to partners to send emails and bus notifications + and to channels to broadcast messages on channels """ group_user = self.env.ref('base.group_user') - # have a sudoed copy to manipulate partners (public can go here with - # website modules like forum / blog / ... + # have a sudoed copy to manipulate partners (public can go here with website modules like forum / blog / ... ) self_sudo = self.sudo() - # TDE CHECK: add partners / channels as arguments to be able to notify a message with / without computation ?? - self.ensure_one() # tde: not sure, just for testinh, will see - partners = self.env['res.partner'] | self.partner_ids - channels = self.env['mail.channel'] | self.channel_ids + self.ensure_one() + partners_sudo = self.env['res.partner'].sudo() | self_sudo.partner_ids + channels_sudo = self.env['mail.channel'].sudo() | self_sudo.channel_ids # all followers of the mail.message document have to be added as partners and notified # and filter to employees only if the subtype is internal @@ -783,28 +781,33 @@ class Message(models.Model): ]).filtered(lambda fol: self.subtype_id in fol.subtype_ids) if self_sudo.subtype_id.internal: followers = followers.filtered(lambda fol: fol.channel_id or (fol.partner_id.user_ids and group_user in fol.partner_id.user_ids[0].mapped('groups_id'))) - channels = self_sudo.channel_ids | followers.mapped('channel_id') - partners = self_sudo.partner_ids | followers.mapped('partner_id') - else: - channels = self_sudo.channel_ids - partners = self_sudo.partner_ids + channels_sudo |= followers.mapped('channel_id') + partners_sudo |= followers.mapped('partner_id') # remove author from notified partners if not self._context.get('mail_notify_author', False) and self_sudo.author_id: - partners = partners - self_sudo.author_id + partners_sudo = partners_sudo - self_sudo.author_id # update message, with maybe custom values message_values = { - 'channel_ids': [(6, 0, channels.ids)], - 'needaction_partner_ids': [(6, 0, partners.ids)] + 'channel_ids': [(6, 0, channels_sudo.ids)], + 'needaction_partner_ids': [(6, 0, partners_sudo.ids)] } if self.model and self.res_id and hasattr(self.env[self.model], 'message_get_message_notify_values'): message_values.update(self.env[self.model].browse(self.res_id).message_get_message_notify_values(self, message_values)) self.write(message_values) # notify partners and channels - partners._notify(self, force_send=force_send, send_after_commit=send_after_commit, user_signature=user_signature) - channels._notify(self) + # those methods are called as SUPERUSER because portal users posting messages + # have no access to partner model. Maybe propagating a real uid could be necessary. + email_channels = channels_sudo.filtered(lambda channel: channel.email_send) + partners_sudo.search([ + '|', + ('id', 'in', partners_sudo.ids), + ('channel_ids', 'in', email_channels.ids), + ('email', '!=', self_sudo.author_id and self_sudo.author_id.email or self_sudo.email_from), + ('notify_email', '!=', 'none')])._notify(self, force_send=force_send, send_after_commit=send_after_commit, user_signature=user_signature) + channels_sudo._notify(self) # Discard cache, because child / parent allow reading and therefore # change access rights. diff --git a/addons/mail/models/res_partner.py b/addons/mail/models/res_partner.py index ba927ac16ab..feaa3848a48 100644 --- a/addons/mail/models/res_partner.py +++ b/addons/mail/models/res_partner.py @@ -145,20 +145,6 @@ class Partner(models.Model): @api.multi def _notify(self, message, force_send=False, send_after_commit=True, user_signature=True): - # TDE TODO: model-dependant ? (like customer -> always email ?) - message_sudo = message.sudo() - email_channels = message.channel_ids.filtered(lambda channel: channel.email_send) - self.sudo().search([ - '|', - ('id', 'in', self.ids), - ('channel_ids', 'in', email_channels.ids), - ('email', '!=', message_sudo.author_id and message_sudo.author_id.email or message.email_from), - ('notify_email', '!=', 'none')])._notify_by_email(message, force_send=force_send, send_after_commit=send_after_commit, user_signature=user_signature) - self._notify_by_chat(message) - return True - - @api.multi - def _notify_by_email(self, message, force_send=False, send_after_commit=True, user_signature=True): """ Method to send email linked to notified messages. The recipients are the recordset on which this method is called. diff --git a/addons/mail/tests/test_mail_features.py b/addons/mail/tests/test_mail_features.py index 8f79c9a7a6b..a4309259ae0 100644 --- a/addons/mail/tests/test_mail_features.py +++ b/addons/mail/tests/test_mail_features.py @@ -183,6 +183,18 @@ class TestMessagePost(TestMail): self.assertEqual(new_msg.parent_id.id, parent_msg.id, 'message_post: flatten error') self.assertFalse(new_msg.partner_ids) + def test_post_portal(self): + self.test_pigs.message_subscribe((self.partner_1 | self.user_employee.partner_id).ids) + new_msg = self.test_pigs.sudo(self.user_portal).message_post( + body='
Test
', subject='Subject', + message_type='comment', subtype='mt_comment') + self.assertEqual(new_msg.sudo().needaction_partner_ids, (self.partner_1 | self.user_employee.partner_id)) + + self.assertEqual( + set(m['email_to'][0] for m in self._mails), + set(['%s <%s>' % (self.partner_1.name, self.partner_1.email), + '%s <%s>' % (self.user_employee.name, self.user_employee.email)])) + @mute_logger('odoo.addons.mail.models.mail_mail') def test_post_internal(self): self.test_pigs.message_subscribe_users([self.user_admin.id])