[FIX]: mail: storing add_sign on mail message

Only the add_sign from notif_values is usefull for a resend. We can consider
that a mail on resend can be delete in every case, and we can find the
model_description from model since a resend can only be performed on
message linked to a model.

The other notif_values are now parameter in order to ease the understanding
of what can transit through this flow.

Task: #1860054
PR: #25622
This commit is contained in:
XavierDo
2018-07-11 12:25:33 +02:00
parent 62591c58f8
commit c8d283a592
14 changed files with 44 additions and 65 deletions
+2 -2
View File
@@ -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):
+2 -2
View File
@@ -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):
-9
View File
@@ -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()})
+1 -4
View File
@@ -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}
@@ -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):
+3 -5
View File
@@ -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)
+11 -13
View File
@@ -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
+12 -14
View File
@@ -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),
+2 -1
View File
@@ -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'}
+3 -7
View File
@@ -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
+1 -1
View File
@@ -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'}
+2 -2
View File
@@ -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})
@@ -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
@@ -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):