[IMP] mail: introduce _message_log as shortcut when logging notifications
This commit introduces _message_log to use when logging notification-based notes on a document. Its main purpose is to provide a shortcut to the complex mechanism of message_post. As it is a lighter code and as it performs less checks and value computation it allows to clearly gain queries when logging notes. It does * skip the notification process completely. Side effect is that followers following note subtype are not notified of document created and pure note tracking. This is considered more as a fix than a feature change. Indeed following notes means that followers want to receive notes logged by other users. The fact that system notifications without a specific subtypes are also notes is a side-effect of the current implementation; * support only notification-based notes and should not be used currently when logging real notes as those could trigger the notification process; * skip access rights checks as it creates the message as superuser. It is therefore defined as a private method and should be called within a method where access rights are already granted; On community runbot installing all 203 modules takes 580K queries instead of 690 at the time of testing. It is a 15% performance increase based on the 'all modules installation' metric. In a distant future message_post and message_log could be merged after some cleaning but it is easier currently to have this shortcut available. Moreover as there are clouds on the mail module some developers prefer to already have some optimization and code cleaning done to avoid loosing all their hair. This commit includes a small test. In a same distant future more tests will probably be added depending on how mail API evolves.
This commit is contained in:
@@ -1954,6 +1954,41 @@ class MailThread(models.AbstractModel):
|
||||
composer.write(update_values)
|
||||
return composer.send_mail()
|
||||
|
||||
def _message_log(self, body='', subject=False, message_type='notification', **kwargs):
|
||||
""" Shortcut allowing to post note on a document. It does not perform
|
||||
any notification and pre-computes some values to have a short code
|
||||
as optimized as possible. This method is private as it does not check
|
||||
access rights and perform the message creation as sudo to speedup
|
||||
the log process. This method should be called within methods where
|
||||
access rights are already granted to avoid privilege escalation. """
|
||||
if len(self.ids) > 1:
|
||||
raise exceptions.Warning(_('Invalid record set: should be called as model (without records) or on single-record recordset'))
|
||||
|
||||
kw_author = kwargs.pop('author_id', False)
|
||||
if kw_author:
|
||||
author = self.env['res.partner'].sudo().browse(kw_author)
|
||||
email_from = formataddr((author.name, author.email))
|
||||
else:
|
||||
author = self.env.user.partner_id
|
||||
email_from = formataddr((author.name, author.email))
|
||||
|
||||
message_values = {
|
||||
'subject': subject,
|
||||
'body': body,
|
||||
'author_id': author.id,
|
||||
'email_from': email_from,
|
||||
'message_type': message_type,
|
||||
'model': kwargs.get('model', self._name),
|
||||
'res_id': self.ids[0] if self.ids else False,
|
||||
'subtype_id': self.env.ref('mail.mt_note').id,
|
||||
'record_name': False,
|
||||
'reply_to': self.env['mail.thread'].sudo()._notify_get_reply_to([0])[0],
|
||||
'message_id': tools.generate_tracking_message_id('message-notify'),
|
||||
}
|
||||
message_values.update(kwargs)
|
||||
message = self.env['mail.message'].sudo().create(message_values)
|
||||
return message
|
||||
|
||||
# ------------------------------------------------------
|
||||
# Followers API
|
||||
# ------------------------------------------------------
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
import base64
|
||||
|
||||
from email.utils import formataddr
|
||||
from unittest.mock import patch
|
||||
|
||||
from odoo.addons.test_mail.tests.common import BaseFunctionalTest, MockEmails, TestRecipients
|
||||
@@ -200,6 +201,17 @@ class TestMessagePost(BaseFunctionalTest, MockEmails, TestRecipients):
|
||||
self.assertEqual(reply.needaction_partner_ids, self.user_employee.partner_id)
|
||||
self.assertEqual(reply.parent_id, msg)
|
||||
|
||||
def test_post_log(self):
|
||||
new_note = self.test_record.sudo(self.user_employee)._message_log(
|
||||
body='<p>Labrador</p>',
|
||||
)
|
||||
|
||||
self.assertEqual(new_note.subtype_id, self.env.ref('mail.mt_note'))
|
||||
self.assertEqual(new_note.body, '<p>Labrador</p>')
|
||||
self.assertEqual(new_note.author_id, self.user_employee.partner_id)
|
||||
self.assertEqual(new_note.email_from, formataddr((self.user_employee.name, self.user_employee.email)))
|
||||
self.assertEqual(new_note.needaction_partner_ids, self.env['res.partner'])
|
||||
|
||||
|
||||
class TestComposer(BaseFunctionalTest, MockEmails, TestRecipients):
|
||||
|
||||
|
||||
Reference in New Issue
Block a user