From b7d23e981bcd5eb0565e246db8b166ad17bd3ded Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Thu, 19 Jan 2023 16:35:05 +0000 Subject: [PATCH] [FIX] mail: better support using composer on no thread record When using the mail composer in comment mode on models that do not inherit from mail.thread, the post is transformed into notification process. Instead of calling 'message_post' on the records (which would crash) 'message_notify' is called, using MailThread as abstract class (which creates notifications without having to inherit from mail.thread). However some parameters from the composer are not supported when calling 'message_notify'. This commit fixes it and adds tests accordingly. Followup of odoo/odoo#99482 Task-2710804 (Mail: Clean MailThread API) Part-of: odoo/odoo#107356 --- addons/mail/tests/common.py | 2 +- addons/mail/wizard/mail_compose_message.py | 2 + .../tests/test_mail_thread_internals.py | 63 ++++++++++++++++++- 3 files changed, 65 insertions(+), 2 deletions(-) diff --git a/addons/mail/tests/common.py b/addons/mail/tests/common.py index eaa5d21bb26..dca9d428702 100644 --- a/addons/mail/tests/common.py +++ b/addons/mail/tests/common.py @@ -1072,7 +1072,7 @@ class MailCommon(common.TransactionCase, MailCase): return cls.user_portal @classmethod - def _create_records_for_batch(cls, model, count, additional_values=None, prefix=None): + def _create_records_for_batch(cls, model, count, additional_values=None, prefix=''): additional_values = additional_values or {} records = cls.env[model] partners = cls.env['res.partner'] diff --git a/addons/mail/wizard/mail_compose_message.py b/addons/mail/wizard/mail_compose_message.py index b32c39ed554..31532d97386 100644 --- a/addons/mail/wizard/mail_compose_message.py +++ b/addons/mail/wizard/mail_compose_message.py @@ -498,6 +498,8 @@ class MailComposer(models.TransientModel): messages = self.env['mail.message'] for res_id, post_values in post_values_all.items(): if ActiveModel._name == 'mail.thread': + post_values.pop('message_type') # forced to user_notification + post_values.pop('parent_id', False) # not supported in notify if self.model: post_values['model'] = self.model post_values['res_id'] = res_id diff --git a/addons/test_mail/tests/test_mail_thread_internals.py b/addons/test_mail/tests/test_mail_thread_internals.py index 56122681bac..36d254e3868 100644 --- a/addons/test_mail/tests/test_mail_thread_internals.py +++ b/addons/test_mail/tests/test_mail_thread_internals.py @@ -8,7 +8,7 @@ from werkzeug.urls import url_parse, url_decode from odoo import exceptions from odoo.addons.test_mail.models.test_mail_models import MailTestSimple from odoo.addons.test_mail.tests.common import TestMailCommon, TestRecipients -from odoo.tests.common import tagged, HttpCase, users +from odoo.tests.common import tagged, Form, HttpCase, users from odoo.tools import mute_logger @@ -473,6 +473,67 @@ class TestNoThread(TestMailCommon, TestRecipients): subject='Test Notify', ) + @users('employee') + def test_message_notify_composer(self): + """ Test comment mode on composer which triggers a notify when model + does not inherit from mail thread. """ + test_records, _test_partners = self._create_records_for_batch('mail.test.nothread', 2) + + test_reports = self.env['ir.actions.report'].sudo().create([ + { + 'name': 'Test Report on Mail Test Ticket', + 'model': test_records._name, + 'print_report_name': "'TestReport for %s' % object.name", + 'report_type': 'qweb-pdf', + 'report_name': 'test_mail.mail_test_ticket_test_template', + }, { + 'name': 'Test Report 2 on Mail Test Ticket', + 'model': test_records._name, + 'print_report_name': "'TestReport2 for %s' % object.name", + 'report_type': 'qweb-pdf', + 'report_name': 'test_mail.mail_test_ticket_test_template_2', + } + ]) + test_template = self.env['mail.template'].create({ + 'auto_delete': True, + 'body_html': '

TemplateBody

', + 'email_from': '{{ (user.email_formatted) }}', + 'email_to': '', + 'mail_server_id': self.mail_server_domain.id, + 'partner_to': '{{ object.customer_id.id if object.customer_id else "" }}', + 'name': 'TestTemplate', + 'model_id': self.env['ir.model']._get(test_records._name).id, + 'reply_to': '{{ ctx.get("custom_reply_to") or "info@test.example.com" }}', + 'report_template_ids': [(6, 0, test_reports.ids)], + 'scheduled_date': '{{ (object.create_date or datetime.datetime(2022, 12, 26, 18, 0, 0)) + datetime.timedelta(days=2) }}', + 'subject': 'TemplateSubject {{ object.name }}', + }) + attachment_data = self._generate_attachments_data(2, test_template._name, test_template.id) + test_template.write({'attachment_ids': [(0, 0, a) for a in attachment_data]}) + + ctx = { + 'default_composition_mode': 'comment', + 'default_model': test_records._name, + 'default_res_domain': [('id', 'in', test_records.ids)], + 'default_template_id': test_template.id, + } + # open a composer and run it in comment mode + composer_form = Form(self.env['mail.compose.message'].with_context(ctx)) + composer = composer_form.save() + + with self.mock_mail_gateway(mail_unlink_sent=False), self.mock_mail_app(): + _, messages = composer._action_send_mail() + + self.assertEqual(len(messages), 2) + for record, message in zip(test_records, messages): + self.assertEqual( + sorted(message.mapped('attachment_ids.name')), + sorted(['AttFileName_00.txt', 'AttFileName_01.txt', + f'TestReport2 for {record.name}.html', + f'TestReport for {record.name}.html']) + ) + self.assertEqual(len(messages.attachment_ids), 8, 'No attachments should be shared') + @users('employee') def test_message_notify_norecord(self): """ Test notifying on no record, just using the abstract model itself. """