From 5abe8eaaec5c222e70b1ea1e1979dd4343d515a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Mart=C3=ADnez?= Date: Thu, 16 Jan 2025 16:16:09 +0100 Subject: [PATCH 1/3] [IMP] mail_notification_custom_subject: Do not replace the subject if it is already set If we write something from the mail thread (without subject) it is only when it should replace the subject. TT52259 --- .../models/mail_thread.py | 14 ++++++++------ .../tests/test_mail_notification_custom_subject.py | 4 ++-- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/mail_notification_custom_subject/models/mail_thread.py b/mail_notification_custom_subject/models/mail_thread.py index f9b116fc8..08a26b32d 100644 --- a/mail_notification_custom_subject/models/mail_thread.py +++ b/mail_notification_custom_subject/models/mail_thread.py @@ -35,15 +35,17 @@ class MailThread(models.AbstractModel): if not subtype_id: subtype_id = self.env["ir.model.data"]._xmlid_to_res_id("mail.mt_note") if subtype_id: + domain = [ + ("model_id.model", "=", self._name), + ("subtype_ids", "=", subtype_id), + ] + if subject: + # If it already had a defined subject, we must respect it + domain += [("position", "!=", "replace")] custom_subjects = ( self.env["mail.message.custom.subject"] .sudo() - .search( - [ - ("model_id.model", "=", self._name), - ("subtype_ids", "=", subtype_id), - ] - ) + .search(domain) .sudo(False) ) if not subject: diff --git a/mail_notification_custom_subject/tests/test_mail_notification_custom_subject.py b/mail_notification_custom_subject/tests/test_mail_notification_custom_subject.py index 02bc64a45..08c37249a 100644 --- a/mail_notification_custom_subject/tests/test_mail_notification_custom_subject.py +++ b/mail_notification_custom_subject/tests/test_mail_notification_custom_subject.py @@ -48,12 +48,12 @@ class TestMailNotificationCustomSubject(BaseCommon): # Get message and check subject self.assertEqual(mail_message_2.subject, "Test partner 2 and something more") - # Explicit subject should also be overwritten + # Explicit subject should not also overwritten mail_message_3 = self.partner_2.message_post( body="Test", subtype_xmlid="mail.mt_comment", subject="Test" ) # Get message and check subject - self.assertEqual(mail_message_3.subject, "Test partner 2 and something more") + self.assertEqual(mail_message_3.subject, "Test") def test_email_subject_template_normal(self): with self.with_user("boss"): From 1b770482cfb46b7ab9475f61552afdd4b97c0534 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Mart=C3=ADnez?= Date: Fri, 17 Jan 2025 10:11:25 +0100 Subject: [PATCH 2/3] [IMP] mail_notification_custom_subject: Add a log when there is an Exception to know what has happened TT52259 --- mail_notification_custom_subject/models/mail_thread.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/mail_notification_custom_subject/models/mail_thread.py b/mail_notification_custom_subject/models/mail_thread.py index 08a26b32d..730f2e1cb 100644 --- a/mail_notification_custom_subject/models/mail_thread.py +++ b/mail_notification_custom_subject/models/mail_thread.py @@ -2,9 +2,12 @@ # Copyright 2021 Tecnativa - Pedro M. Baeza # Copyright 2022 Moduon - Eduardo de Miguel # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +import logging from odoo import api, models +_logger = logging.getLogger(__name__) + class MailThread(models.AbstractModel): _inherit = "mail.thread" @@ -69,7 +72,10 @@ class MailThread(models.AbstractModel): elif template.position == "append_after": subject += rendered_subject_template except Exception: - rendered_subject_template = False + _logger.warning( + f"There is an error with {self.display_name} in the mail " + f"message custom subject {template.name}" + ) return super().message_post( body=body, subject=subject, From 6645a95547bf0f328b05b64f2b8989dae5249b4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Mart=C3=ADnez?= Date: Thu, 16 Jan 2025 16:28:52 +0100 Subject: [PATCH 3/3] [IMP] mail_notification_custom_subject: Add inside_replace position Example use Case: Our company is called: MY_COMPANY_NAME but is known as MCN, we want to replace in some places the subject line so that it is sent with MCN TT52259 --- mail_notification_custom_subject/README.rst | 48 ++++++++++--------- .../models/mail_message_custom_subject.py | 9 +++- .../models/mail_thread.py | 15 ++++++ .../readme/CONFIGURE.md | 6 ++- .../static/description/index.html | 21 ++++---- .../test_mail_notification_custom_subject.py | 21 ++++++++ ...mail_notification_custom_subject_views.xml | 5 ++ 7 files changed, 90 insertions(+), 35 deletions(-) diff --git a/mail_notification_custom_subject/README.rst b/mail_notification_custom_subject/README.rst index cf1f0c666..30726f603 100644 --- a/mail_notification_custom_subject/README.rst +++ b/mail_notification_custom_subject/README.rst @@ -39,28 +39,32 @@ the notification emails sent by Odoo Configuration ============= -- Activate access to **Technical Features** (debug mode). +- Activate access to **Technical Features** (debug mode). -- Go to **Settings > Technical > Email > Subject Replacement Templates** +- Go to **Settings > Technical > Email > Subject Replacement + Templates** -- Create a new template. +- Create a new template. - - The field **Model** specifies the model to which the subject - template should apply in the notification emails sent by Odoo. - - The field **Subject Template** accepts - `Jinja `__ - expressions. - - The field **Replace** specifies if the template should replace - existing content or append to it. + - The field **Model** specifies the model to which the subject + template should apply in the notification emails sent by Odoo. + - The field **Subject Template** accepts + `expressions `__. + - The field **Subject to replace** accepts + `expressions `__ + - The field **Replace** specifies if the template should replace + existing content or append to it. + - The field **Partial Replacement** specifies if the template + should parcial replace existing content. Usage ===== To use this module, you need to: -- Open the chatter in Odoo (e.g. Open an Invoice). -- Send a message. -- Observe the rendered Subject template. +- Open the chatter in Odoo (e.g. Open an Invoice). +- Send a message. +- Observe the rendered Subject template. Bug Tracker =========== @@ -83,20 +87,20 @@ Authors Contributors ------------ -- Tecnativa +- Tecnativa - - Pedro M. Baeza - - João Marques - - Carlos Roca - - Víctor Martínez + - Pedro M. Baeza + - João Marques + - Carlos Roca + - Víctor Martínez -- Versada +- Versada - - Naglis Jonaitis + - Naglis Jonaitis -- Moduon +- Moduon - - Eduardo de Miguel + - Eduardo de Miguel Maintainers ----------- diff --git a/mail_notification_custom_subject/models/mail_message_custom_subject.py b/mail_notification_custom_subject/models/mail_message_custom_subject.py index 0340b5630..79bf60fee 100644 --- a/mail_notification_custom_subject/models/mail_message_custom_subject.py +++ b/mail_notification_custom_subject/models/mail_message_custom_subject.py @@ -21,6 +21,10 @@ class MailMessageCustomSubject(models.Model): string="Applied Subtypes", required=True, ) + subject_to_replace = fields.Char( + help="The text that will be replaced. You can use placeholders." + " E.g.: {{ object.company_id.name }}" + ) subject_template = fields.Char( required=True, translate=True, @@ -31,8 +35,9 @@ class MailMessageCustomSubject(models.Model): ("append_before", "Append Before"), ("append_after", "Append After"), ("replace", "Replace"), + ("inside_replace", "Partial Replacement"), ], default="replace", - help="Whether to replace, append at beggining or append at end to other" - " templates that apply to a given context", + help="Whether to replace completely, partially, append at beginning or append" + " at end to other templates that apply to a given context", ) diff --git a/mail_notification_custom_subject/models/mail_thread.py b/mail_notification_custom_subject/models/mail_thread.py index 730f2e1cb..9b15aac91 100644 --- a/mail_notification_custom_subject/models/mail_thread.py +++ b/mail_notification_custom_subject/models/mail_thread.py @@ -1,6 +1,7 @@ # Copyright 2020-2021 Tecnativa - João Marques # Copyright 2021 Tecnativa - Pedro M. Baeza # Copyright 2022 Moduon - Eduardo de Miguel +# Copyright 2025 Tecnativa - Víctor Martínez # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). import logging @@ -71,6 +72,20 @@ class MailThread(models.AbstractModel): subject = rendered_subject_template + subject elif template.position == "append_after": subject += rendered_subject_template + elif template.position == "inside_replace": + rendered_subject_to_replace = self.env[ + "mail.template" + ]._render_template( + template_src=template.subject_to_replace, + model=self._name, + res_ids=[self.id], + )[self.id] + if rendered_subject_to_replace: + # To avoid empty string replacements + subject = subject.replace( + rendered_subject_to_replace, + rendered_subject_template, + ) except Exception: _logger.warning( f"There is an error with {self.display_name} in the mail " diff --git a/mail_notification_custom_subject/readme/CONFIGURE.md b/mail_notification_custom_subject/readme/CONFIGURE.md index 42242f3f1..482a06d0c 100644 --- a/mail_notification_custom_subject/readme/CONFIGURE.md +++ b/mail_notification_custom_subject/readme/CONFIGURE.md @@ -8,6 +8,10 @@ > - The field **Model** specifies the model to which the subject > template should apply in the notification emails sent by Odoo. > - The field **Subject Template** accepts - > [Jinja](https://jinja.palletsprojects.com/en/2.11.x/) expressions. + > [expressions](https://www.odoo.com/documentation/17.0/applications/general/companies/email_template.html#dynamic-placeholders). + > - The field **Subject to replace** accepts + > [expressions](https://www.odoo.com/documentation/17.0/applications/general/companies/email_template.html#dynamic-placeholders) > - The field **Replace** specifies if the template should replace > existing content or append to it. + > - The field **Partial Replacement** specifies if the template should + > parcial replace existing content. diff --git a/mail_notification_custom_subject/static/description/index.html b/mail_notification_custom_subject/static/description/index.html index 9cd819f87..c465a4580 100644 --- a/mail_notification_custom_subject/static/description/index.html +++ b/mail_notification_custom_subject/static/description/index.html @@ -8,11 +8,10 @@ /* :Author: David Goodger (goodger@python.org) -:Id: $Id: html4css1.css 9511 2024-01-13 09:50:07Z milde $ +:Id: $Id: html4css1.css 8954 2022-01-20 10:10:25Z milde $ :Copyright: This stylesheet has been placed in the public domain. Default cascading style sheet for the HTML output of Docutils. -Despite the name, some widely supported CSS2 features are used. See https://docutils.sourceforge.io/docs/howto/html-stylesheets.html for how to customize this style sheet. @@ -275,7 +274,7 @@ pre.literal-block, pre.doctest-block, pre.math, pre.code { margin-left: 2em ; margin-right: 2em } -pre.code .ln { color: gray; } /* line numbers */ +pre.code .ln { color: grey; } /* line numbers */ pre.code, code { background-color: #eeeeee } pre.code .comment, code .comment { color: #5C6576 } pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold } @@ -301,7 +300,7 @@ span.option { span.pre { white-space: pre } -span.problematic, pre.problematic { +span.problematic { color: red } span.section-subtitle { @@ -391,7 +390,8 @@ the notification emails sent by Odoo

  • Activate access to Technical Features (debug mode).

  • -
  • Go to Settings > Technical > Email > Subject Replacement Templates

    +
  • Go to Settings > Technical > Email > Subject Replacement +Templates

  • Create a new template.

    @@ -399,10 +399,13 @@ the notification emails sent by Odoo

  • The field Model specifies the model to which the subject template should apply in the notification emails sent by Odoo.
  • The field Subject Template accepts -Jinja -expressions.
  • +expressions.
  • +
  • The field Subject to replace accepts +expressions
  • The field Replace specifies if the template should replace existing content or append to it.
  • +
  • The field Partial Replacement specifies if the template +should parcial replace existing content.
@@ -461,9 +464,7 @@ If you spotted it first, help us to smash it by providing a detailed and welcome

Maintainers

This module is maintained by the OCA.

- -Odoo Community Association - +Odoo Community Association

OCA, or the Odoo Community Association, is a nonprofit organization whose mission is to support the collaborative development of Odoo features and promote its widespread use.

diff --git a/mail_notification_custom_subject/tests/test_mail_notification_custom_subject.py b/mail_notification_custom_subject/tests/test_mail_notification_custom_subject.py index 08c37249a..a1e2bfe74 100644 --- a/mail_notification_custom_subject/tests/test_mail_notification_custom_subject.py +++ b/mail_notification_custom_subject/tests/test_mail_notification_custom_subject.py @@ -55,6 +55,27 @@ class TestMailNotificationCustomSubject(BaseCommon): # Get message and check subject self.assertEqual(mail_message_3.subject, "Test") + def test_email_subject_template_inside_replace(self): + with self.with_user("boss"): + self.env["mail.message.custom.subject"].create( + { + "name": "Test template", + "model_id": self.env.ref("base.model_res_partner").id, + "subtype_ids": [(6, 0, [self.env.ref("mail.mt_comment").id])], + "subject_to_replace": "{{object.company_id.name}}", + "subject_template": "CLN", + "position": "inside_replace", + } + ) + self.partner_1.company_id = self.env.company + self.partner_1.company_id.name = "COMPANY_LONG_NAME" + mail_message_1 = self.partner_1.message_post( + subject="COMPANY_LONG_NAME: Custom", + body="Test", + subtype_xmlid="mail.mt_comment", + ) + self.assertEqual(mail_message_1.subject, "CLN: Custom") + def test_email_subject_template_normal(self): with self.with_user("boss"): self.env["mail.message.custom.subject"].create( diff --git a/mail_notification_custom_subject/views/mail_notification_custom_subject_views.xml b/mail_notification_custom_subject/views/mail_notification_custom_subject_views.xml index 3267af9fb..ee91309f4 100644 --- a/mail_notification_custom_subject/views/mail_notification_custom_subject_views.xml +++ b/mail_notification_custom_subject/views/mail_notification_custom_subject_views.xml @@ -11,6 +11,11 @@

+