From cd0331e886d13fa3fbd1f7f6d0934976fd24302c Mon Sep 17 00:00:00 2001 From: Christoph Abenthung Date: Tue, 3 Dec 2024 10:31:37 +0100 Subject: [PATCH] [IMP] mail_quoted_reply: Separate reply body For long replies the message composer gets extremely laggy and slow. To prevent that the reply body is stored in a separate field. --- mail_quoted_reply/README.rst | 24 +++++++---- mail_quoted_reply/__manifest__.py | 4 +- .../models/mail_compose_message.py | 41 +++++++++++++++++-- mail_quoted_reply/readme/DESCRIPTION.md | 4 ++ mail_quoted_reply/readme/USAGE.md | 4 ++ .../static/description/index.html | 8 ++++ mail_quoted_reply/tests/test_reply.py | 29 +++++++++++++ .../views/mail_compose_message_views.xml | 24 +++++++++++ 8 files changed, 126 insertions(+), 12 deletions(-) create mode 100644 mail_quoted_reply/views/mail_compose_message_views.xml diff --git a/mail_quoted_reply/README.rst b/mail_quoted_reply/README.rst index 7d89c7f09..6b3c652d2 100644 --- a/mail_quoted_reply/README.rst +++ b/mail_quoted_reply/README.rst @@ -31,6 +31,10 @@ Mail Message Reply This addon allow to reply on messages from odoo directly. It is useful when replying to a message from a customer. +Additionally, it is possible to separate the reply body from the mail +body. This separation is only for the composer and the sent mail will +contain both parts. + **Table of contents** .. contents:: @@ -42,6 +46,12 @@ Usage On the messages from threads, a reply button is shown. Once it has been pressed, a composer with the reply is shown. +To activate the separation of the reply body add the system parameter +"mail_quoted_reply.separate_reply_body". After opening a composer with +the reply button the reply body will be shown below the mail body as +readonly. To write into the reply body uncheck "Reply Readonly". For +longer replies this can take some time. + Bug Tracker =========== @@ -63,13 +73,13 @@ Authors Contributors ------------ -- Enric Tobella -- Lois Rilo -- Giuseppe Borruso -- Laurence Labusch -- Dani Forga -- Tris Doan -- Akim Juillerat +- Enric Tobella +- Lois Rilo +- Giuseppe Borruso +- Laurence Labusch +- Dani Forga +- Tris Doan +- Akim Juillerat Other credits ------------- diff --git a/mail_quoted_reply/__manifest__.py b/mail_quoted_reply/__manifest__.py index c55c42470..e7fbeb589 100644 --- a/mail_quoted_reply/__manifest__.py +++ b/mail_quoted_reply/__manifest__.py @@ -10,7 +10,9 @@ "author": "Creu Blanca,Odoo Community Association (OCA)", "website": "https://github.com/OCA/social", "depends": ["mail"], - "data": [], + "data": [ + "views/mail_compose_message_views.xml", + ], "assets": { "web.assets_backend": [ "/mail_quoted_reply/static/src/*.js", diff --git a/mail_quoted_reply/models/mail_compose_message.py b/mail_quoted_reply/models/mail_compose_message.py index 3ff708b60..cba214a12 100644 --- a/mail_quoted_reply/models/mail_compose_message.py +++ b/mail_quoted_reply/models/mail_compose_message.py @@ -1,11 +1,15 @@ from markupsafe import Markup -from odoo import api, models, tools +from odoo import api, fields, models, tools class MailComposeMessage(models.TransientModel): _inherit = "mail.compose.message" + is_reply_readonly = fields.Boolean(default=True, string="Reply Readonly") + reply_body = fields.Html(default="", string="Reply body") + is_separate_body = fields.Boolean(compute="_compute_is_separate_body") + @api.depends("composition_mode", "model", "res_domain", "res_ids", "template_id") @api.depends_context("is_quoted_reply") def _compute_body(self): @@ -13,10 +17,13 @@ class MailComposeMessage(models.TransientModel): for composer in self: context = composer._context if context.get("is_quoted_reply"): - if composer.body: - composer.body += Markup(context["quote_body"]) + if self.is_separate_body: + self.reply_body = context["quote_body"] else: - composer.body = Markup(context["quote_body"]) + if self.body: + self.body += Markup(context["quote_body"]) + else: + self.body = Markup(context["quote_body"]) return res @api.depends( @@ -36,3 +43,29 @@ class MailComposeMessage(models.TransientModel): if subj: composer.subject = tools.ustr(subj) return res + + @api.onchange("is_reply_readonly") + def _onchange_is_reply_readonly(self): + if self.reply_body: + self.reply_body = Markup(self.reply_body) + + @api.depends("reply_body") + def _compute_is_separate_body(self): + if self._context.get("is_quoted_reply", False): + parameter_string = ( + self.env["ir.config_parameter"] + .sudo() + .get_param("mail_quoted_reply.separate_reply_body", "") + ) + self.is_separate_body = parameter_string.lower() not in ["", "false", "0"] + else: + self.is_separate_body = False + + def _prepare_mail_values(self, res_ids): + results = super()._prepare_mail_values(res_ids) + if self.is_separate_body and self.reply_body: + for res_id in res_ids: + values = results.get(res_id) + reply_body = Markup(self.reply_body) + values.update({"body": values.get("body") + reply_body}) + return results diff --git a/mail_quoted_reply/readme/DESCRIPTION.md b/mail_quoted_reply/readme/DESCRIPTION.md index 32b30b51d..e959b8590 100644 --- a/mail_quoted_reply/readme/DESCRIPTION.md +++ b/mail_quoted_reply/readme/DESCRIPTION.md @@ -1,2 +1,6 @@ This addon allow to reply on messages from odoo directly. It is useful when replying to a message from a customer. + +Additionally, it is possible to separate the reply body from the mail +body. This separation is only for the composer and the sent mail will +contain both parts. diff --git a/mail_quoted_reply/readme/USAGE.md b/mail_quoted_reply/readme/USAGE.md index e5ce6880c..dfbb67cfa 100644 --- a/mail_quoted_reply/readme/USAGE.md +++ b/mail_quoted_reply/readme/USAGE.md @@ -1,2 +1,6 @@ On the messages from threads, a reply button is shown. Once it has been pressed, a composer with the reply is shown. + +To activate the separation of the reply body add the system parameter "mail_quoted_reply.separate_reply_body". +After opening a composer with the reply button the reply body will be shown below the mail body as readonly. +To write into the reply body uncheck "Reply Readonly". For longer replies this can take some time. diff --git a/mail_quoted_reply/static/description/index.html b/mail_quoted_reply/static/description/index.html index 56a3c4489..a53b66bfd 100644 --- a/mail_quoted_reply/static/description/index.html +++ b/mail_quoted_reply/static/description/index.html @@ -372,6 +372,9 @@ ul.auto-toc {

Beta License: AGPL-3 OCA/social Translate me on Weblate Try me on Runboat

This addon allow to reply on messages from odoo directly. It is useful when replying to a message from a customer.

+

Additionally, it is possible to separate the reply body from the mail +body. This separation is only for the composer and the sent mail will +contain both parts.

Table of contents

    @@ -390,6 +393,11 @@ when replying to a message from a customer.

    Usage

    On the messages from threads, a reply button is shown. Once it has been pressed, a composer with the reply is shown.

    +

    To activate the separation of the reply body add the system parameter +“mail_quoted_reply.separate_reply_body”. After opening a composer with +the reply button the reply body will be shown below the mail body as +readonly. To write into the reply body uncheck “Reply Readonly”. For +longer replies this can take some time.

Bug Tracker

diff --git a/mail_quoted_reply/tests/test_reply.py b/mail_quoted_reply/tests/test_reply.py index ef1f7c220..5c35c8cf0 100644 --- a/mail_quoted_reply/tests/test_reply.py +++ b/mail_quoted_reply/tests/test_reply.py @@ -44,3 +44,32 @@ class TestMessageReply(TransactionCase): ) self.assertTrue(new_message) self.assertEqual(1, len(new_message)) + + def test_reply_separate_body(self): + self.env["ir.config_parameter"].sudo().create( + { + "key": "mail_quoted_reply.separate_reply_body", + "value": "True", + } + ) + partner = self.env["res.partner"].create({"name": "demo partner"}) + message = partner.message_post( + body="demo message", + message_type="email", + partner_ids=self.env.ref("base.partner_demo").ids, + ) + partner.invalidate_recordset() + action = message.reply_message() + wizard = ( + self.env[action["res_model"]].with_context(**action["context"]).create({}) + ) + wizard._compute_body() + self.assertTrue("

demo message

" in wizard.reply_body) + wizard.action_send_mail() + new_message = partner.message_ids.filtered( + lambda r: r.message_type != "notification" and r != message + ) + self.assertTrue(new_message) + self.assertEqual(1, len(new_message)) + new_message = new_message[0] + self.assertTrue("

demo message

" in new_message.body) diff --git a/mail_quoted_reply/views/mail_compose_message_views.xml b/mail_quoted_reply/views/mail_compose_message_views.xml new file mode 100644 index 000000000..4fc6e07d3 --- /dev/null +++ b/mail_quoted_reply/views/mail_compose_message_views.xml @@ -0,0 +1,24 @@ + + + + mail.compose.message + + + + + + + + +