Merge PR #1548 into 17.0

Signed-off-by pedrobaeza
pull/1578/head
OCA-git-bot 2025-02-03 10:30:33 +00:00
commit dd801df48e
7 changed files with 107 additions and 44 deletions

View File

@ -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 <https://jinja.palletsprojects.com/en/2.11.x/>`__
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 <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.
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 <https://www.tecnativa.com>
- Tecnativa <https://www.tecnativa.com>
- 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 <https://versada.eu>
- Versada <https://versada.eu>
- Naglis Jonaitis
- Naglis Jonaitis
- Moduon <https://www.moduon.team>
- Moduon <https://www.moduon.team>
- Eduardo de Miguel
- Eduardo de Miguel
Maintainers
-----------

View File

@ -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",
)

View File

@ -1,10 +1,14 @@
# 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
from odoo import api, models
_logger = logging.getLogger(__name__)
class MailThread(models.AbstractModel):
_inherit = "mail.thread"
@ -35,15 +39,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:
@ -66,8 +72,25 @@ 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:
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,

View File

@ -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.

View File

@ -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</p>
<ul>
<li><p class="first">Activate access to <strong>Technical Features</strong> (debug mode).</p>
</li>
<li><p class="first">Go to <strong>Settings &gt; Technical &gt; Email &gt; Subject Replacement Templates</strong></p>
<li><p class="first">Go to <strong>Settings &gt; Technical &gt; Email &gt; Subject Replacement
Templates</strong></p>
</li>
<li><p class="first">Create a new template.</p>
<blockquote>
@ -399,10 +399,13 @@ the notification emails sent by Odoo</p>
<li>The field <strong>Model</strong> specifies the model to which the subject
template should apply in the notification emails sent by Odoo.</li>
<li>The field <strong>Subject Template</strong> accepts
<a class="reference external" href="https://jinja.palletsprojects.com/en/2.11.x/">Jinja</a>
expressions.</li>
<a class="reference external" href="https://www.odoo.com/documentation/17.0/applications/general/companies/email_template.html#dynamic-placeholders">expressions</a>.</li>
<li>The field <strong>Subject to replace</strong> accepts
<a class="reference external" href="https://www.odoo.com/documentation/17.0/applications/general/companies/email_template.html#dynamic-placeholders">expressions</a></li>
<li>The field <strong>Replace</strong> specifies if the template should replace
existing content or append to it.</li>
<li>The field <strong>Partial Replacement</strong> specifies if the template
should parcial replace existing content.</li>
</ul>
</blockquote>
</li>
@ -461,9 +464,7 @@ If you spotted it first, help us to smash it by providing a detailed and welcome
<div class="section" id="maintainers">
<h2><a class="toc-backref" href="#toc-entry-7">Maintainers</a></h2>
<p>This module is maintained by the OCA.</p>
<a class="reference external image-reference" href="https://odoo-community.org">
<img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" />
</a>
<a class="reference external image-reference" href="https://odoo-community.org"><img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" /></a>
<p>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.</p>

View File

@ -48,12 +48,33 @@ 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_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"):

View File

@ -11,6 +11,11 @@
<h1 name="name"><field name="name" /></h1>
</div>
<group>
<field
name="subject_to_replace"
invisible="position!='inside_replace'"
required="position=='inside_replace'"
/>
<field
name="subject_template"
placeholder="Subject (placeholders may be used here)"