diff --git a/addons/crm/models/crm_lead.py b/addons/crm/models/crm_lead.py index 5945470f51c..49b0cab9b4b 100644 --- a/addons/crm/models/crm_lead.py +++ b/addons/crm/models/crm_lead.py @@ -1186,7 +1186,7 @@ class Lead(models.Model): defaults.update(custom_values) return super(Lead, self).message_new(msg_dict, custom_values=defaults) - def _message_post_after_hook(self, message, values, notif_layout, notif_values): + def _message_post_after_hook(self, message, *args, **kwargs): 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 @@ -1197,7 +1197,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, notif_values) + return super(Lead, self)._message_post_after_hook(message, *args, **kwargs) @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 1c2189a2d12..8cf1304a110 100644 --- a/addons/event/models/event.py +++ b/addons/event/models/event.py @@ -459,7 +459,7 @@ class EventRegistration(models.Model): pass return recipients - def _message_post_after_hook(self, message, values, notif_layout, notif_values): + def _message_post_after_hook(self, message, *args, **kwargs): 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 @@ -471,7 +471,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, notif_values) + return super(EventRegistration, self)._message_post_after_hook(message, *args, **kwargs) @api.multi def action_send_badge_email(self): diff --git a/addons/gamification/models/challenge.py b/addons/gamification/models/challenge.py index ac5286813c3..845e1ade290 100644 --- a/addons/gamification/models/challenge.py +++ b/addons/gamification/models/challenge.py @@ -553,9 +553,6 @@ class Challenge(models.Model): partner_ids=challenge.mapped('user_ids.partner_id.id'), subtype='mail.mt_comment', notif_layout='mail.mail_notification_light', - notif_values={ - 'model_description': challenge._description.lower(), - } ) if challenge.report_message_group_id: challenge.report_message_group_id.message_post( @@ -580,18 +577,12 @@ class Challenge(models.Model): partner_ids=[(4, user.partner_id.id)], subtype='mail.mt_comment', notif_layout='mail.mail_notification_light', - notif_values={ - 'model_description': self._description.lower(), - } ) if challenge.report_message_group_id: challenge.report_message_group_id.message_post( body=body_html, subtype='mail.mt_comment', notif_layout='mail.mail_notification_light', - notif_values={ - 'model_description': self._description.lower(), - } ) return challenge.write({'last_report_date': fields.Date.today()}) diff --git a/addons/gamification/models/goal.py b/addons/gamification/models/goal.py index 77966b00c77..1d11c0f8016 100644 --- a/addons/gamification/models/goal.py +++ b/addons/gamification/models/goal.py @@ -224,12 +224,9 @@ class Goal(models.Model): .render_template(template.body_html, 'gamification.goal', self.id) self.env['mail.thread'].message_post( body=body_html, - partner_ids=[ self.user_id.partner_id.id], + partner_ids=[self.user_id.partner_id.id], subtype='mail.mt_comment', notif_layout='mail.mail_notification_light', - notif_values={ - 'model_description': self._description.lower(), - } ) return {'to_update': True} diff --git a/addons/hr_recruitment/models/hr_recruitment.py b/addons/hr_recruitment/models/hr_recruitment.py index 9bc544bab1e..898a5234939 100644 --- a/addons/hr_recruitment/models/hr_recruitment.py +++ b/addons/hr_recruitment/models/hr_recruitment.py @@ -397,7 +397,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, notif_values): + def _message_post_after_hook(self, message, *args, **kwargs): 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 @@ -408,7 +408,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, notif_values) + return super(Applicant, self)._message_post_after_hook(message, *args, **kwargs) @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 a32ccfa9b54..220010076d1 100644 --- a/addons/mail/models/mail_message.py +++ b/addons/mail/models/mail_message.py @@ -122,7 +122,7 @@ class Message(models.Model): need_moderation = fields.Boolean('Need moderation', compute='_compute_need_moderation', search='_search_need_moderation') #keep notification layout informations to be able to generate mail again layout = fields.Char('Layout', copy=False) # xml id of layout - layout_values = fields.Char('Notification values', copy=False) + add_sign = fields.Boolean(default=True) @api.multi def _get_needaction(self): @@ -971,7 +971,7 @@ class Message(models.Model): #------------------------------------------------------ @api.multi - def _notify(self, layout=False, force_send=False, send_after_commit=True, values=None): + def _notify(self, force_send=False, send_after_commit=True, model_description=False, mail_auto_delete=True): """ 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 """ @@ -1007,8 +1007,6 @@ class Message(models.Model): #update message, with maybe custom values message_values = {} - if email_partner: - message_values = {'layout': layout, 'layout_values': repr(values)} if channels_sudo: message_values['channel_ids'] = [(6, 0, channels_sudo.ids)] if partners_sudo: @@ -1027,7 +1025,7 @@ class Message(models.Model): ('id', 'in', (email_partner).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, values=values) + ])._notify(self, force_send=force_send, send_after_commit=send_after_commit, model_description=model_description, mail_auto_delete=mail_auto_delete) notif_partners._notify_by_chat(self) channels_sudo._notify(self) diff --git a/addons/mail/models/mail_thread.py b/addons/mail/models/mail_thread.py index d6b696c8124..e33588f24a6 100644 --- a/addons/mail/models/mail_thread.py +++ b/addons/mail/models/mail_thread.py @@ -1899,7 +1899,8 @@ class MailThread(models.AbstractModel): def message_post(self, body='', subject=None, message_type='notification', subtype=None, parent_id=False, attachments=None, - notif_layout=False, notif_values=None, **kwargs): + notif_layout=False, add_sign=False, model_description=False, + mail_auto_delete=True, **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; @@ -1933,7 +1934,8 @@ class MailThread(models.AbstractModel): return self.env[model].browse(self.ids).message_post( body=body, subject=subject, message_type=message_type, subtype=subtype, parent_id=parent_id, attachments=attachments, - notif_layout=notif_layout, notif_values=notif_values, **kwargs) + notif_layout=notif_layout, add_sign=add_sign, + mail_auto_delete=mail_auto_delete, model_description=model_description, **kwargs) # 0: Find the message's author, because we need it for private discussion author_id = kwargs.get('author_id') @@ -2004,7 +2006,10 @@ class MailThread(models.AbstractModel): 'parent_id': parent_id, 'subtype_id': subtype_id, 'partner_ids': [(4, pid) for pid in partner_ids], + 'add_sign': add_sign }) + if notif_layout: + values['layout'] = notif_layout # 3. Attachments # - HACK TDE FIXME: Chatter: attachments linked to the document (not done JS-side), load the message @@ -2017,21 +2022,16 @@ class MailThread(models.AbstractModel): # Post the message new_message = MailMessage.create(values) - self._message_post_after_hook(new_message, values, notif_layout, notif_values) + self._message_post_after_hook(new_message, values, model_description=model_description, mail_auto_delete=mail_auto_delete) return new_message - def _message_post_after_hook(self, message, values, notif_layout, notif_values): + def _message_post_after_hook(self, message, values, model_description=False, mail_auto_delete=True): """ 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. """ # Notify recipients of the newly-created message (Inbox / Email + channels) if values.get('moderation_status') != 'pending_moderation': - message._notify( - layout=notif_layout, - force_send=self.env.context.get('mail_notify_force_send', True), - values=notif_values, - ) - + message._notify(force_send=self.env.context.get('mail_notify_force_send', True), model_description=model_description, mail_auto_delete=mail_auto_delete) # Post-process: subscribe author if values['author_id'] and values['model'] and self.ids and values['message_type'] != 'notification' and not self._context.get('mail_create_nosubscribe'): self._message_subscribe([values['author_id']]) @@ -2304,9 +2304,7 @@ class MailThread(models.AbstractModel): partner_ids=[(4, pid) for pid in partner_ids], record_name=record.display_name, notif_layout='mail.mail_notification_light', - notif_values={ - 'model_description': record._description.lower(), - } + model_description=record._description.lower() ) @api.multi diff --git a/addons/mail/models/res_partner.py b/addons/mail/models/res_partner.py index d9fb69cecb2..74f59d7d80e 100644 --- a/addons/mail/models/res_partner.py +++ b/addons/mail/models/res_partner.py @@ -37,9 +37,9 @@ 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, notif_values): + def _notify_prepare_template_context(self, message, model_description=False, mail_auto_delete=True): # compute signature - if not notif_values.pop('add_sign', True): + if not message.add_sign: 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 @@ -58,9 +58,8 @@ class Partner(models.Model): else: website_url = False - model_name = False - if message.model: - model_name = self.env['ir.model']._get(message.model).display_name + if not model_description and message.model: + model_description = self.env['ir.model']._get(message.model).display_name record_name = message.record_name @@ -85,7 +84,7 @@ class Partner(models.Model): 'signature': signature, 'website_url': website_url, 'company': company, - 'model_description': model_name, + 'model_description': model_description, 'record': record, 'record_name': record_name, 'tracking_values': tracking, @@ -94,7 +93,7 @@ class Partner(models.Model): } @api.model - def _notify_prepare_email_values(self, message, notif_values): + def _notify_prepare_email_values(self, message, mail_auto_delete=True): # compute email references references = message.parent_id.message_id if message.parent_id else False @@ -106,7 +105,7 @@ class Partner(models.Model): mail_values = { 'mail_message_id': message.id, 'mail_server_id': message.mail_server_id.id, - 'auto_delete': notif_values.pop('mail_auto_delete', True), + 'auto_delete': mail_auto_delete, 'references': references, } mail_values.update(custom_values) @@ -147,7 +146,7 @@ class Partner(models.Model): }) @api.multi - def _notify(self, message, layout=False, force_send=False, send_after_commit=True, values=None): + def _notify(self, message, force_send=False, send_after_commit=True, model_description=False, mail_auto_delete=True): """ Method to send email linked to notified messages. The recipients are the recordset on which this method is called. @@ -163,17 +162,16 @@ class Partner(models.Model): """ if not self.ids: return True - values = values if values is not None else {} - template_xmlid = layout if layout else 'mail.message_notification_email' + template_xmlid = message.layout if message.layout else 'mail.message_notification_email' try: base_template = self.env.ref(template_xmlid, raise_if_not_found=True) except ValueError: _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, values) - base_mail_values = self._notify_prepare_email_values(message, values) + base_template_ctx = self._notify_prepare_template_context(message, model_description=model_description) + base_mail_values = self._notify_prepare_email_values(message, mail_auto_delete=mail_auto_delete) # classify recipients: actions / no action tig = self.env[message.model].browse(message.res_id) if message.model and message.res_id else False @@ -184,7 +182,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 = {**base_template_ctx, **recipient_template_values, **values} # fixme: set button_unfollow to none + template_ctx = {**base_template_ctx, **recipient_template_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', minimal_qcontext=True), diff --git a/addons/mail/wizard/invite.py b/addons/mail/wizard/invite.py index 579c304b191..6aa42e05f3f 100644 --- a/addons/mail/wizard/invite.py +++ b/addons/mail/wizard/invite.py @@ -58,7 +58,8 @@ class Invite(models.TransientModel): 'model': wizard.res_model, 'res_id': wizard.res_id, 'no_auto_thread': True, + 'add_sign': True, }) - new_partners.with_context(auto_delete=True)._notify(message, force_send=True, send_after_commit=False, values={'add_sign': True}) + new_partners.with_context(auto_delete=True)._notify(message, force_send=True, send_after_commit=False) 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 905c7194083..afccac5318a 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, layout=False, force_send=False, send_after_commit=True, values=None): + def _notify(self, **kwargs): """ Override specific notify method of mail.message, because we do not want that feature in the wizard. """ return @@ -198,7 +198,6 @@ class MailComposer(models.TransientModel): """ Process the wizard content and proceed with sending the related email(s), rendering any template patterns on the fly if needed. """ notif_layout = self._context.get('custom_layout') - ctx_notif_values = self._context.get('notif_values', {}) for wizard in self: # Duplicate attachments linked to the email.template. # Indeed, basic mail.compose.message wizard duplicates attachments in mass @@ -247,15 +246,12 @@ class MailComposer(models.TransientModel): if wizard.composition_mode == 'mass_mail': batch_mails |= Mail.create(mail_values) else: - notif_values = dict( - add_sign=not bool(wizard.template_id), - mail_auto_delete=wizard.template_id.auto_delete if wizard.template_id else False, - **ctx_notif_values) post_params = dict( message_type=wizard.message_type, subtype_id=subtype_id, notif_layout=notif_layout, - notif_values=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 ActiveModel._name == 'mail.thread' and wizard.model: post_params['model'] = wizard.model diff --git a/addons/mail/wizard/mail_resend_message.py b/addons/mail/wizard/mail_resend_message.py index f637b0ca737..38815c1a64d 100644 --- a/addons/mail/wizard/mail_resend_message.py +++ b/addons/mail/wizard/mail_resend_message.py @@ -57,7 +57,7 @@ class MailResendMessage(models.TransientModel): to_send = wizard.partner_ids.filtered(lambda p: p.resend).mapped("partner_id") notif_to_cancel = wizard.notification_ids.filtered(lambda notif: notif.res_partner_id in to_cancel and notif.email_status in ('exception', 'bounce')) notif_to_cancel.sudo().write({'email_status': 'canceled'}) - to_send.sudo()._notify(self.mail_message_id, self.mail_message_id.layout, force_send=True, send_after_commit=False, values=literal_eval(self.mail_message_id.layout_values)) + to_send.sudo()._notify(self.mail_message_id, force_send=True, send_after_commit=False) self.mail_message_id._notify_failure_update() return {'type': 'ir.actions.act_window_close'} diff --git a/addons/project/models/project.py b/addons/project/models/project.py index 2de6c14f47d..08a473a4c5e 100644 --- a/addons/project/models/project.py +++ b/addons/project/models/project.py @@ -959,7 +959,7 @@ class Task(models.Model): res['headers'] = repr(headers) return res - def _message_post_after_hook(self, message, values, notif_layout, notif_values): + def _message_post_after_hook(self, message, *args, **kwargs): 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 @@ -970,7 +970,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, notif_values) + return super(Task, self)._message_post_after_hook(message, *args, **kwargs) 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 517f0faeb1c..7620f6fa4a4 100644 --- a/addons/test_mail/tests/test_message_compose.py +++ b/addons/test_mail/tests/test_message_compose.py @@ -67,7 +67,7 @@ class TestMessagePost(BaseFunctionalTest, MockEmails, TestRecipients): body='Test', subject='Test', message_type='comment', subtype='mt_comment', partner_ids=[self.partner_1.id, self.partner_2.id], - notif_values={'mail_auto_delete': False} + 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 e6185595a1a..9929f6e5519 100644 --- a/addons/website_event_track/models/event_track.py +++ b/addons/website_event_track/models/event_track.py @@ -164,7 +164,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, notif_values): + def _message_post_after_hook(self, message, *args, **kwargs): 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 @@ -176,7 +176,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, notif_values) + return super(Track, self)._message_post_after_hook(message, *args, **kwargs) @api.multi def open_track_speakers_list(self):