diff --git a/mail_quoted_reply/README.rst b/mail_quoted_reply/README.rst index 3d8a04f67b..a0e41df34c 100644 --- a/mail_quoted_reply/README.rst +++ b/mail_quoted_reply/README.rst @@ -31,6 +31,9 @@ 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 +45,10 @@ 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/__manifest__.py b/mail_quoted_reply/__manifest__.py index d4c898e560..29d055135e 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/models/*.js", diff --git a/mail_quoted_reply/models/mail_compose_message.py b/mail_quoted_reply/models/mail_compose_message.py index af50226357..c672c7343c 100644 --- a/mail_quoted_reply/models/mail_compose_message.py +++ b/mail_quoted_reply/models/mail_compose_message.py @@ -1,19 +1,52 @@ 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.onchange("template_id") def _onchange_template_id_wrapper(self): super()._onchange_template_id_wrapper() context = self._context if "is_quoted_reply" in context.keys() and context["is_quoted_reply"]: - self.body += Markup(context["quote_body"]) + if self.is_separate_body: + self.reply_body = context["quote_body"] + else: + self.body += Markup(context["quote_body"]) return + @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 get_mail_values(self, res_ids): + results = super(MailComposeMessage, self).get_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 + @api.model def get_record_data(self, values): result = super().get_record_data(values) diff --git a/mail_quoted_reply/readme/DESCRIPTION.rst b/mail_quoted_reply/readme/DESCRIPTION.rst index fbaa89bdca..aa6cdc676d 100644 --- a/mail_quoted_reply/readme/DESCRIPTION.rst +++ b/mail_quoted_reply/readme/DESCRIPTION.rst @@ -1,2 +1,5 @@ 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.rst b/mail_quoted_reply/readme/USAGE.rst index 2a57635f4b..6cf62aefc0 100644 --- a/mail_quoted_reply/readme/USAGE.rst +++ b/mail_quoted_reply/readme/USAGE.rst @@ -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 bc0dd8776b..eb51dc4914 100644 --- a/mail_quoted_reply/static/description/index.html +++ b/mail_quoted_reply/static/description/index.html @@ -371,6 +371,8 @@ <h1 class="title">Mail Message Reply</h1> <p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external image-reference" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/licence-AGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/OCA/social/tree/16.0/mail_quoted_reply"><img alt="OCA/social" src="https://img.shields.io/badge/github-OCA%2Fsocial-lightgray.png?logo=github" /></a> <a class="reference external image-reference" href="https://translation.odoo-community.org/projects/social-16-0/social-16-0-mail_quoted_reply"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external image-reference" href="https://runboat.odoo-community.org/builds?repo=OCA/social&target_branch=16.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p> <p>This addon allow to reply on messages from odoo directly. It is useful when replying to a message from a customer.</p> +<p>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.</p> <p><strong>Table of contents</strong></p> <div class="contents local topic" id="contents"> <ul class="simple"> @@ -388,6 +390,9 @@ <h1 class="title">Mail Message Reply</h1> <h1><a class="toc-backref" href="#toc-entry-1">Usage</a></h1> <p>On the messages from threads, a reply button is shown. Once it has been pressed, a composer with the reply is shown.</p> +<p>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.</p> </div> <div class="section" id="bug-tracker"> <h1><a class="toc-backref" href="#toc-entry-2">Bug Tracker</a></h1> diff --git a/mail_quoted_reply/tests/test_reply.py b/mail_quoted_reply/tests/test_reply.py index ef1f7c220f..1183cbe5b0 100644 --- a/mail_quoted_reply/tests/test_reply.py +++ b/mail_quoted_reply/tests/test_reply.py @@ -44,3 +44,32 @@ def test_reply(self): ) 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._onchange_template_id_wrapper() + self.assertTrue("<p>demo message</p>" 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("<p>demo message</p>" 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 0000000000..2acc8f7b05 --- /dev/null +++ b/mail_quoted_reply/views/mail_compose_message_views.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="utf-8" ?> +<odoo> + <record id="mail_quoted_reply_composer_view_form" model="ir.ui.view"> + <field name="model">mail.compose.message</field> + <field name="inherit_id" ref="mail.email_compose_message_wizard_form" /> + <field name="arch" type="xml"> + <xpath expr="//field[@name='body']" position="after"> + <field name="is_separate_body" invisible="1" /> + <field + name="reply_body" + attrs="{'readonly': [('is_reply_readonly', '=', True)], 'invisible': [('is_separate_body', '=', False)]}" + force_save="1" + /> + <label + for="is_reply_readonly" + attrs="{'invisible': [('is_separate_body', '=', False)]}" + /> + <field + name="is_reply_readonly" + widget="boolean_toggle" + attrs="{'invisible': [('is_separate_body', '=', False)]}" + /> + </xpath> + </field> + </record> +</odoo>