diff --git a/addons/crm/models/crm_lead.py b/addons/crm/models/crm_lead.py index 8c2371e2c6c..d0365ed2e12 100644 --- a/addons/crm/models/crm_lead.py +++ b/addons/crm/models/crm_lead.py @@ -1193,7 +1193,7 @@ class Lead(models.Model): update_vals[key] = res.group(2).lower() return super(Lead, self).message_update(msg_dict, update_vals=update_vals) - def _message_post_after_hook(self, message, values, notif_layout): + def _message_post_after_hook(self, message, values, notif_layout, notif_values): if self.email_from and not self.partner_id: # we consider that posting a message with a specified recipient (not a follower, a specific one) # on a document without customer means that it was created through the chatter using @@ -1204,7 +1204,7 @@ class Lead(models.Model): ('partner_id', '=', False), ('email_from', '=', new_partner.email), ('stage_id.fold', '=', False)]).write({'partner_id': new_partner.id}) - return super(Lead, self)._message_post_after_hook(message, values, notif_layout) + return super(Lead, self)._message_post_after_hook(message, values, notif_layout, notif_values) @api.multi def message_partner_info_from_emails(self, emails, link_mail=False): diff --git a/addons/event/models/event.py b/addons/event/models/event.py index aab8f6596a6..02b1c1a3489 100644 --- a/addons/event/models/event.py +++ b/addons/event/models/event.py @@ -449,7 +449,7 @@ class EventRegistration(models.Model): pass return recipients - def _message_post_after_hook(self, message, values, notif_layout): + def _message_post_after_hook(self, message, values, notif_layout, notif_values): if self.email and not self.partner_id: # we consider that posting a message with a specified recipient (not a follower, a specific one) # on a document without customer means that it was created through the chatter using @@ -461,7 +461,7 @@ class EventRegistration(models.Model): ('email', '=', new_partner.email), ('state', 'not in', ['cancel']), ]).write({'partner_id': new_partner.id}) - return super(EventRegistration, self)._message_post_after_hook(message, values, notif_layout) + return super(EventRegistration, self)._message_post_after_hook(message, values, notif_layout, notif_values) @api.multi def action_send_badge_email(self): diff --git a/addons/hr_recruitment/models/hr_recruitment.py b/addons/hr_recruitment/models/hr_recruitment.py index d88bc0b9072..17c728b96c7 100644 --- a/addons/hr_recruitment/models/hr_recruitment.py +++ b/addons/hr_recruitment/models/hr_recruitment.py @@ -377,7 +377,7 @@ class Applicant(models.Model): defaults.update(custom_values) return super(Applicant, self).message_new(msg, custom_values=defaults) - def _message_post_after_hook(self, message, values, notif_layout): + def _message_post_after_hook(self, message, values, notif_layout, notif_values): if self.email_from and not self.partner_id: # we consider that posting a message with a specified recipient (not a follower, a specific one) # on a document without customer means that it was created through the chatter using @@ -388,7 +388,7 @@ class Applicant(models.Model): ('partner_id', '=', False), ('email_from', '=', new_partner.email), ('stage_id.fold', '=', False)]).write({'partner_id': new_partner.id}) - return super(Applicant, self)._message_post_after_hook(message, values, notif_layout) + return super(Applicant, self)._message_post_after_hook(message, values, notif_layout, notif_values) @api.multi def create_employee_from_applicant(self): diff --git a/addons/mail/models/mail_message.py b/addons/mail/models/mail_message.py index 724f78ed827..f0872b1b475 100644 --- a/addons/mail/models/mail_message.py +++ b/addons/mail/models/mail_message.py @@ -796,7 +796,7 @@ class Message(models.Model): #------------------------------------------------------ @api.multi - def _notify(self, layout=False, force_send=False, send_after_commit=True, user_signature=True): + def _notify(self, layout=False, force_send=False, send_after_commit=True, values=None): """ 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 """ @@ -847,7 +847,7 @@ class Message(models.Model): ('id', 'in', (partners_sudo - notif_partners).ids), ('channel_ids', 'in', email_channels.ids), ('email', '!=', self_sudo.author_id.email or self_sudo.email_from), - ])._notify(self, layout=layout, force_send=force_send, send_after_commit=send_after_commit, user_signature=user_signature) + ])._notify(self, layout=layout, force_send=force_send, send_after_commit=send_after_commit, values=values) notif_partners._notify_by_chat(self) diff --git a/addons/mail/models/mail_thread.py b/addons/mail/models/mail_thread.py index 955d9ac4479..392106a0547 100644 --- a/addons/mail/models/mail_thread.py +++ b/addons/mail/models/mail_thread.py @@ -67,12 +67,8 @@ class MailThread(models.AbstractModel): creating messages - ``tracking_disable``: at create and write, perform no MailThread features (auto subscription, tracking, post, ...) - - ``mail_auto_delete``: auto delete mail notifications; True by default - (technical hack for templates) - ``mail_notify_force_send``: if less than 50 email notifications to send, send them directly instead of using the queue; True by default - - ``mail_notify_user_signature``: add the current user signature in - email notifications; True by default ''' _name = 'mail.thread' _description = 'Email Thread' @@ -1788,7 +1784,7 @@ class MailThread(models.AbstractModel): def message_post(self, body='', subject=None, message_type='notification', subtype=None, parent_id=False, attachments=None, content_subtype='html', - notif_layout=False, **kwargs): + notif_layout=False, notif_values=None, **kwargs): """ Post a new message in an existing thread, returning the new mail.message ID. :param int thread_id: thread ID to post into, or list with one ID; @@ -1913,10 +1909,10 @@ class MailThread(models.AbstractModel): # Post the message new_message = MailMessage.create(values) - self._message_post_after_hook(new_message, values, notif_layout) + self._message_post_after_hook(new_message, values, notif_layout, notif_values) return new_message - def _message_post_after_hook(self, message, values, notif_layout): + def _message_post_after_hook(self, message, values, notif_layout, notif_values): """ Hook to add custom behavior after having posted the message. Both message and computed value are given, to try to lessen query count by using already-computed values instead of having to rebrowse things. """ @@ -1924,7 +1920,7 @@ class MailThread(models.AbstractModel): message._notify( layout=notif_layout, force_send=self.env.context.get('mail_notify_force_send', True), - user_signature=self.env.context.get('mail_notify_user_signature', True) + values=notif_values, ) # Post-process: subscribe author diff --git a/addons/mail/models/res_partner.py b/addons/mail/models/res_partner.py index 4cee80af16a..19ef96a100c 100644 --- a/addons/mail/models/res_partner.py +++ b/addons/mail/models/res_partner.py @@ -37,13 +37,16 @@ class Partner(models.Model): return dict((res_id, {'partner_ids': [res_id], 'email_to': False, 'email_cc': False}) for res_id in self.ids) @api.model - def _notify_prepare_template_context(self, message): + def _notify_prepare_template_context(self, message, notif_values): # compute signature - signature = "" - if message.author_id and message.author_id.user_ids and message.author_id.user_ids[0].signature: + if not notif_values.pop('add_sign', True): + signature = False + elif message.author_id and message.author_id.user_ids and message.author_id.user_ids[0].signature: signature = message.author_id.user_ids[0].signature elif message.author_id: signature = "

--
%s

" % message.author_id.name + else: + signature = "" # compute Sent by if message.author_id and message.author_id.user_ids: @@ -91,7 +94,7 @@ class Partner(models.Model): } @api.model - def _notify_prepare_email_values(self, message): + def _notify_prepare_email_values(self, message, notif_values): # compute email references references = message.parent_id.message_id if message.parent_id else False @@ -103,7 +106,7 @@ class Partner(models.Model): mail_values = { 'mail_message_id': message.id, 'mail_server_id': message.mail_server_id.id, - 'auto_delete': self._context.get('mail_auto_delete', True), + 'auto_delete': notif_values.pop('mail_auto_delete', True), 'references': references, } mail_values.update(custom_values) @@ -146,16 +149,23 @@ class Partner(models.Model): }) @api.multi - def _notify(self, message, layout=False, force_send=False, send_after_commit=True, user_signature=True): + def _notify(self, message, layout=False, force_send=False, send_after_commit=True, values=None): """ Method to send email linked to notified messages. The recipients are the recordset on which this method is called. :param boolean force_send: send notification emails now instead of letting the scheduler handle the email queue :param boolean send_after_commit: send notification emails after the transaction end instead of durign the transaction; this option is used only if force_send is True - :param user_signature: add current user signature to notification emails """ + :param dict values: values used to compute the notification process, containing + + * add_sign: add user signature to notification email, default is True + * mail_auto_delete: auto delete send emails, default is True + * other values are given to the context used to render the notification template, allowing customization + + """ if not self.ids: return True + values = values if values is not None else {} template_xmlid = layout if layout else 'mail.message_notification_email' try: @@ -164,10 +174,8 @@ class Partner(models.Model): _logger.warning('QWeb template %s not found when sending notification emails. Skipping.' % (template_xmlid)) return False - base_template_ctx = self._notify_prepare_template_context(message) - if not user_signature: - base_template_ctx['signature'] = False - base_mail_values = self._notify_prepare_email_values(message) + base_template_ctx = self._notify_prepare_template_context(message, values) + base_mail_values = self._notify_prepare_email_values(message, values) # classify recipients: actions / no action if message.model and message.res_id and hasattr(self.env[message.model], '_notify_classify_recipients'): @@ -180,7 +188,7 @@ class Partner(models.Model): for email_type, recipient_template_values in recipients.items(): if recipient_template_values['recipients']: # generate notification email content - template_ctx = dict(base_template_ctx, **recipient_template_values) # fixme: set button_unfollow to none + template_ctx = {**base_template_ctx, **recipient_template_values, **values} # fixme: set button_unfollow to none fol_values = { 'subject': message.subject or (message.record_name and 'Re: %s' % message.record_name), 'body': base_template.render(template_ctx, engine='ir.qweb'), diff --git a/addons/mail/wizard/invite.py b/addons/mail/wizard/invite.py index acb89641f75..579c304b191 100644 --- a/addons/mail/wizard/invite.py +++ b/addons/mail/wizard/invite.py @@ -59,6 +59,6 @@ class Invite(models.TransientModel): 'res_id': wizard.res_id, 'no_auto_thread': True, }) - new_partners.with_context(auto_delete=True)._notify(message, force_send=True, send_after_commit=False, user_signature=True) + new_partners.with_context(auto_delete=True)._notify(message, force_send=True, send_after_commit=False, values={'add_sign': True}) message.unlink() return {'type': 'ir.actions.act_window_close'} diff --git a/addons/mail/wizard/mail_compose_message.py b/addons/mail/wizard/mail_compose_message.py index 1aa444cd854..573e54898b4 100644 --- a/addons/mail/wizard/mail_compose_message.py +++ b/addons/mail/wizard/mail_compose_message.py @@ -147,7 +147,7 @@ class MailComposer(models.TransientModel): return super(MailComposer, self).check_access_rule(operation) @api.multi - def _notify(self, force_send=False, user_signature=True): + def _notify(self, layout=False, force_send=False, send_after_commit=True, values=None): """ Override specific notify method of mail.message, because we do not want that feature in the wizard. """ return @@ -217,11 +217,6 @@ class MailComposer(models.TransientModel): Mail = self.env['mail.mail'] ActiveModel = self.env[wizard.model if wizard.model else 'mail.thread'] - if wizard.template_id: - # template user_signature is added when generating body_html - # mass mailing: use template auto_delete value -> note, for emails mass mailing only - Mail = Mail.with_context(mail_notify_user_signature=False) - ActiveModel = ActiveModel.with_context(mail_notify_user_signature=False, mail_auto_delete=wizard.template_id.auto_delete) if not hasattr(ActiveModel, 'message_post'): ActiveModel = self.env['mail.thread'].with_context(thread_model=wizard.model) if wizard.composition_mode == 'mass_post': @@ -257,6 +252,10 @@ class MailComposer(models.TransientModel): message_type=wizard.message_type, subtype_id=subtype_id, notif_layout=notif_layout, + notif_values={ + 'add_sign': not bool(wizard.template_id), + 'mail_auto_delete': wizard.template_id.auto_delete if wizard.template_id else False, + }, **mail_values) if wizard.composition_mode == 'mass_mail': diff --git a/addons/project/models/project.py b/addons/project/models/project.py index 319f50724b6..ff9181938bc 100644 --- a/addons/project/models/project.py +++ b/addons/project/models/project.py @@ -998,7 +998,7 @@ class Task(models.Model): res['headers'] = repr(headers) return res - def _message_post_after_hook(self, message, values, notif_layout): + def _message_post_after_hook(self, message, values, notif_layout, notif_values): if self.email_from and not self.partner_id: # we consider that posting a message with a specified recipient (not a follower, a specific one) # on a document without customer means that it was created through the chatter using @@ -1009,7 +1009,7 @@ class Task(models.Model): ('partner_id', '=', False), ('email_from', '=', new_partner.email), ('stage_id.fold', '=', False)]).write({'partner_id': new_partner.id}) - return super(Task, self)._message_post_after_hook(message, values, notif_layout) + return super(Task, self)._message_post_after_hook(message, values, notif_layout, notif_values) def action_assign_to_me(self): self.write({'user_id': self.env.user.id}) diff --git a/addons/test_mail/tests/test_message_compose.py b/addons/test_mail/tests/test_message_compose.py index e2668cdac45..6fe72d4da6f 100644 --- a/addons/test_mail/tests/test_message_compose.py +++ b/addons/test_mail/tests/test_message_compose.py @@ -63,10 +63,11 @@ class TestMessagePost(BaseFunctionalTest, MockEmails, TestRecipients): def test_post_notifications_keep_emails(self): self.test_record.message_subscribe_users(user_ids=[self.user_admin.id]) - msg = self.test_record.sudo(self.user_employee).with_context(mail_auto_delete=False).message_post( + msg = self.test_record.sudo(self.user_employee).message_post( body='Test', subject='Test', message_type='comment', subtype='mt_comment', - partner_ids=[self.partner_1.id, self.partner_2.id] + partner_ids=[self.partner_1.id, self.partner_2.id], + notif_values={'mail_auto_delete': False} ) # notifications emails should not have been deleted: one for customers, one for user diff --git a/addons/website_event_track/models/event_track.py b/addons/website_event_track/models/event_track.py index 9306cd6a80b..62d1afff823 100644 --- a/addons/website_event_track/models/event_track.py +++ b/addons/website_event_track/models/event_track.py @@ -159,7 +159,7 @@ class Track(models.Model): track._message_add_suggested_recipient(recipients, email=track.partner_email, reason=_('Speaker Email')) return recipients - def _message_post_after_hook(self, message, values, notif_layout): + def _message_post_after_hook(self, message, values, notif_layout, notif_values): if self.partner_email and not self.partner_id: # we consider that posting a message with a specified recipient (not a follower, a specific one) # on a document without customer means that it was created through the chatter using @@ -171,7 +171,7 @@ class Track(models.Model): ('partner_email', '=', new_partner.email), ('stage_id.is_cancel', '=', False), ]).write({'partner_id': new_partner.id}) - return super(Track, self)._message_post_after_hook(message, values, notif_layout) + return super(Track, self)._message_post_after_hook(message, values, notif_layout, notif_values) @api.multi def open_track_speakers_list(self):