Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
105 changes: 105 additions & 0 deletions mail_template_domain/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
.. image:: https://odoo-community.org/readme-banner-image
:target: https://odoo-community.org/get-involved?utm_source=readme
:alt: Odoo Community Association

====================
Mail Template Domain
====================

..
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:0ad5a5b12ca98c2057110cf9b2856f809274ebb84075743c3861c6c5710bfd0e
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
:target: https://odoo-community.org/page/development-status
:alt: Beta
.. |badge2| image:: https://img.shields.io/badge/license-AGPL--3-blue.png
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fmail-lightgray.png?logo=github
:target: https://github.com/OCA/mail/tree/17.0/mail_template_domain
:alt: OCA/mail
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
:target: https://translation.odoo-community.org/projects/mail-17-0/mail-17-0-mail_template_domain
:alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png
:target: https://runboat.odoo-community.org/builds?repo=OCA/mail&target_branch=17.0
:alt: Try me on Runboat

|badge1| |badge2| |badge3| |badge4| |badge5|

This module allows setting an application domain on mail templates.

When a domain is configured on a template, that template will only
appear in the email composer when the active record matches the domain.
Templates without a domain continue to appear for all records of the
applicable model.

**Table of contents**

.. contents::
:local:

Usage
=====

To use this module:

1. Go to **Settings > Technical > Email > Templates**.
2. Open or create a mail template.
3. In the **Apply on** field (Settings tab), set the domain that records
must match for this template to appear in the composer (e.g.
``[('is_company', '=', True)]`` to show the template only on contacts
where **Is a Company** is set).
4. Leave **Apply on** empty to keep the template available for all
records of the model (default behaviour).

When a user opens the email composer from a record, only templates whose
**Apply on** domain matches that record will be listed in the *Load
template* dropdown.

Bug Tracker
===========

Bugs are tracked on `GitHub Issues <https://github.com/OCA/mail/issues>`_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us to smash it by providing a detailed and welcomed
`feedback <https://github.com/OCA/mail/issues/new?body=module:%20mail_template_domain%0Aversion:%2017.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.

Do not contact contributors directly about support or help with technical issues.

Credits
=======

Authors
-------

* Tecnativa

Contributors
------------

- `Tecnativa <https://www.tecnativa.com>`__:

- Cristina Hidalgo

Maintainers
-----------

This module is maintained by the OCA.

.. image:: https://odoo-community.org/logo.png
:alt: Odoo Community Association
:target: https://odoo-community.org

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.

This module is part of the `OCA/mail <https://github.com/OCA/mail/tree/17.0/mail_template_domain>`_ project on GitHub.

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
1 change: 1 addition & 0 deletions mail_template_domain/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import models
15 changes: 15 additions & 0 deletions mail_template_domain/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"name": "Mail Template Domain",
"summary": "Filter mail templates by domain on the active record",
"version": "17.0.1.0.0",
"category": "Technical",
"website": "https://github.com/OCA/mail",
"author": "Tecnativa, Odoo Community Association (OCA)",
"license": "AGPL-3",
"installable": True,
"depends": ["mail"],
"data": [
"views/mail_template_views.xml",
"views/mail_compose_message_views.xml",
],
}
56 changes: 56 additions & 0 deletions mail_template_domain/i18n/es.po
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * mail_template_domain
#
# Translators:
# Cristina Hidalgo <cristina.hidalgo@tecnativa.com>, 2024
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 17.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-04-15 09:47+0000\n"
"PO-Revision-Date: 2026-04-15 09:47+0000\n"
"Last-Translator: Cristina Hidalgo <cristina.hidalgo@tecnativa.com>\n"
"Language-Team: none\n"
"Language: es\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"

#. module: mail_template_domain
#: model:ir.model.fields,field_description:mail_template_domain.field_mail_template__filter_domain
#: model_terms:ir.ui.view,arch_db:mail_template_domain.email_template_form_filter_domain
msgid "Apply on"
msgstr "Aplicar en"

#. module: mail_template_domain
#: model:ir.model,name:mail_template_domain.model_mail_compose_message
msgid "Email composition wizard"
msgstr "Asistente de redacción de correo electrónico"

#. module: mail_template_domain
#: model:ir.model,name:mail_template_domain.model_mail_template
msgid "Email Templates"
msgstr "Plantillas de correo electrónico"

#. module: mail_template_domain
#: model:ir.model.fields,help:mail_template_domain.field_mail_template__filter_domain
msgid ""
"If set, this template will only appear in the email composer when the active"
" record matches this domain."
msgstr ""
"Si se establece, esta plantilla solo aparecerá en el compositor de correo "
"cuando el registro activo cumpla este dominio."

#. module: mail_template_domain
#: model:ir.model.fields,field_description:mail_template_domain.field_mail_compose_message__mail_template_res_ids
msgid "Mail Template Res Ids"
msgstr ""

#. module: mail_template_domain
#: model:ir.model.fields,help:mail_template_domain.field_mail_compose_message__mail_template_res_ids
msgid ""
"Technical field: res_ids as JSON used to filter available templates by"
" domain."
msgstr ""
51 changes: 51 additions & 0 deletions mail_template_domain/i18n/mail_template_domain.pot
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * mail_template_domain
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 17.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-04-15 09:47+0000\n"
"PO-Revision-Date: 2026-04-15 09:47+0000\n"
"Last-Translator: \n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"

#. module: mail_template_domain
#: model:ir.model.fields,field_description:mail_template_domain.field_mail_template__filter_domain
#: model_terms:ir.ui.view,arch_db:mail_template_domain.email_template_form_filter_domain
msgid "Apply on"
msgstr ""

#. module: mail_template_domain
#: model:ir.model,name:mail_template_domain.model_mail_compose_message
msgid "Email composition wizard"
msgstr ""

#. module: mail_template_domain
#: model:ir.model,name:mail_template_domain.model_mail_template
msgid "Email Templates"
msgstr ""

#. module: mail_template_domain
#: model:ir.model.fields,help:mail_template_domain.field_mail_template__filter_domain
msgid ""
"If set, this template will only appear in the email composer when the active"
" record matches this domain."
msgstr ""

#. module: mail_template_domain
#: model:ir.model.fields,field_description:mail_template_domain.field_mail_compose_message__mail_template_res_ids
msgid "Mail Template Res Ids"
msgstr ""

#. module: mail_template_domain
#: model:ir.model.fields,help:mail_template_domain.field_mail_compose_message__mail_template_res_ids
msgid ""
"Technical field: res_ids as JSON used to filter available templates by"
" domain."
msgstr ""
2 changes: 2 additions & 0 deletions mail_template_domain/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
from . import mail_compose_message
from . import mail_template
16 changes: 16 additions & 0 deletions mail_template_domain/models/mail_compose_message.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from odoo import api, fields, models


class MailComposeMessage(models.TransientModel):
_inherit = "mail.compose.message"

mail_template_res_ids = fields.Char(
compute="_compute_mail_template_res_ids",
help="Technical field: res_ids as JSON used to filter available"
" templates by domain.",
)

@api.depends("res_ids")
def _compute_mail_template_res_ids(self):
for composer in self:
composer.mail_template_res_ids = composer.res_ids or "[]"
45 changes: 45 additions & 0 deletions mail_template_domain/models/mail_template.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import json

from odoo import api, fields, models
from odoo.tools.safe_eval import safe_eval


class MailTemplate(models.Model):
_inherit = "mail.template"

filter_domain = fields.Char(
string="Apply on",
help="If set, this template will only appear in the email composer "
"when the active record matches this domain.",
)

@api.model
def _name_search(
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why overriding this one instead of search / _search. This one is partial. You should also put a comment as first line explaining why you override the method.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

_name_search is the entry point for Many2one widget lookups. The filter needs Python-side evaluation via filtered_domain() against the actual records, so it can't be pushed down to SQL. Overriding search/_search would apply it to all search paths (list views, programmatic calls), which is not the intended behaviour — fail-open outside the composer context is by design.

self, name="", domain=None, operator="ilike", limit=None, order=None
):
# Override _name_search (Many2one widget lookups) instead of
# search/_search so the filter only applies in the composer dropdown,
# not in list views or programmatic searches (fail-open by design).
ids = super()._name_search(name, domain, operator, limit, order)
res_ids_raw = self._context.get("mail_template_res_ids")
res_model = self._context.get("mail_template_res_model")
if not res_ids_raw or not res_model or res_model not in self.env:
return ids
try:
res_ids = json.loads(res_ids_raw)
except (ValueError, TypeError):
return ids
if not res_ids:
return ids
records = self.env[res_model].browse(res_ids)
if not records.exists():
return ids
return (
self.browse(ids)
.filtered(
lambda t: not t.filter_domain
or len(records.filtered_domain(safe_eval(t.filter_domain)))
== len(records)
)
.ids
)
3 changes: 3 additions & 0 deletions mail_template_domain/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[build-system]
requires = ["whool"]
build-backend = "whool.buildapi"
2 changes: 2 additions & 0 deletions mail_template_domain/readme/CONTRIBUTORS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
- [Tecnativa](https://www.tecnativa.com):
- Cristina Hidalgo
5 changes: 5 additions & 0 deletions mail_template_domain/readme/DESCRIPTION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
This module allows setting an application domain on mail templates.

When a domain is configured on a template, that template will only appear
in the email composer when the active record matches the domain. Templates
without a domain continue to appear for all records of the applicable model.
14 changes: 14 additions & 0 deletions mail_template_domain/readme/USAGE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
To use this module:

1. Go to **Settings > Technical > Email > Templates**.
2. Open or create a mail template.
3. In the **Apply on** field (Settings tab), set the domain that records must
match for this template to appear in the composer
(e.g. `[('is_company', '=', True)]` to show the template only on contacts
where **Is a Company** is set).
4. Leave **Apply on** empty to keep the template available for all records of
the model (default behaviour).

When a user opens the email composer from a record, only templates whose
**Apply on** domain matches that record will be listed in the *Load template*
dropdown.
Loading
Loading