Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[15.0][MIG] mail_layout_force #973

Merged
merged 6 commits into from
Feb 15, 2023
Merged
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
118 changes: 118 additions & 0 deletions mail_layout_force/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
=================
Mail Layout Force
=================

.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
.. |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/licence-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%2Fsocial-lightgray.png?logo=github
:target: https://github.com/OCA/social/tree/15.0/mail_layout_force
:alt: OCA/social
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
:target: https://translation.odoo-community.org/projects/social-15-0/social-15-0-mail_layout_force
:alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png
:target: https://runbot.odoo-community.org/runbot/205/15.0
:alt: Try me on Runbot

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

Odoo will add a default email layout on most commercial communications.

The email layout is a ``QWeb`` view that ends up wrapping the message body
when sending an email. It usually displays the related document reference,
the company logo, and a small footer saying "Powered by Odoo".

There are notably two main layouts used in Odoo, and the user can't control when
they're used, as it's hardcoded into the different applications.

* ``mail.mail_notification_light``
* ``mail.mail_notification_paynow``

This module allows to force a specific layout for a given ``email.template``,
effectively overwritting the one hardcoded by Odoo.

This allows you to fully customize the way Odoo emails are rendered and sent
to your customers.

**Table of contents**

.. contents::
:local:

Configuration
=============

# Go to Configuration > Technical > Emails > Templates
# Open the desired ``email.template`` record.
# In Advanced Parameters tab, find the Force Layout field.

You can leave it empty to use the default email layout (chosen by Odoo).
You can force a custom email layout of your own.
You can use the *Mail: No-Layout notification template* to prevent Odoo
from adding a layout.

To configure a custom layout of your own, some technical knowledge is needed.
You can see how the existing layouts are defined for details or inspiration:

* ``mail.mail_notification_light``
* ``mail.mail_notification_paynow``
* ``mail.mail_notification_borders``

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

Bugs are tracked on `GitHub Issues <https://github.com/OCA/social/issues>`_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us smashing it by providing a detailed and welcomed
`feedback <https://github.com/OCA/social/issues/new?body=module:%20mail_layout_force%0Aversion:%2015.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
~~~~~~~

* Camptocamp

Contributors
~~~~~~~~~~~~

* `Camptocamp <https://www.camptocamp.com>`_

* Iván Todorovich <ivan.todorovich@camptocamp.com>

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.

.. |maintainer-ivantodorovich| image:: https://github.com/ivantodorovich.png?size=40px
:target: https://github.com/ivantodorovich
:alt: ivantodorovich

Current `maintainer <https://odoo-community.org/page/maintainer-role>`__:

|maintainer-ivantodorovich|

This module is part of the `OCA/social <https://github.com/OCA/social/tree/15.0/mail_layout_force>`_ project on GitHub.

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
2 changes: 2 additions & 0 deletions mail_layout_force/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
from . import models
from . import wizards
17 changes: 17 additions & 0 deletions mail_layout_force/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Copyright 2022 Camptocamp SA (https://www.camptocamp.com).
# @author Iván Todorovich <ivan.todorovich@camptocamp.com>
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

{
"name": "Mail Layout Force",
"summary": "Force a mail layout on selected email templates",
"version": "15.0.1.0.0",
"author": "Camptocamp, Odoo Community Association (OCA)",
"maintainers": ["ivantodorovich"],
"website": "https://github.com/OCA/social",
"license": "AGPL-3",
"category": "Marketing",
"depends": ["mail"],
"demo": ["demo/mail_layout.xml"],
"data": ["data/mail_layout.xml", "views/mail_template.xml"],
}
13 changes: 13 additions & 0 deletions mail_layout_force/data/mail_layout.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8" ?>
<!--
Copyright 2022 Camptocamp SA (https://www.camptocamp.com).
@author Iván Todorovich <ivan.todorovich@camptocamp.com>
License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
-->
<odoo>

<template id="mail_layout_noop" name="Mail: No-Layout notification template">
<t t-out="message.body" />
</template>

</odoo>
115 changes: 115 additions & 0 deletions mail_layout_force/demo/mail_layout.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
<?xml version="1.0" encoding="utf-8" ?>
<!--
Copyright 2022 Camptocamp SA (https://www.camptocamp.com).
@author Iván Todorovich <ivan.todorovich@camptocamp.com>
License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
-->
<odoo>

<template id="mail_layout_custom">
<table
border="0"
cellpadding="0"
cellspacing="0"
style="padding-top: 32px; background-color: red; width: 100%; border-collapse:separate;"
>
<tr>
<td align="center">
<table
border="0"
cellpadding="0"
cellspacing="0"
width="590"
style="padding: 24px; background-color: white; border-collapse:separate;"
>
<tbody>
<!-- HEADER -->
<tr>
<td align="center" style="min-width: 590px;">
<table
border="0"
cellpadding="0"
cellspacing="0"
width="100%"
style="background-color: white; padding: 0; border-collapse:separate;"
>
<tr>
<td valign="middle">
<t
t-esc="model_description or 'document'"
/>
<t
t-esc="message.record_name and message.record_name.replace('/','-') or ''"
/>
</td>
<td valign="middle" align="right">
<img
t-att-src="'/logo.png?company=%s' % (company.id or 0)"
style="padding: 0px; margin: 0px; height: 48px;"
t-att-alt="'%s' % company.name"
/>
</td>
</tr>
<tr>
<td colspan="2" style="text-align:center;">
<hr
width="100%"
style="background-color: red; border: medium none; clear: both; display: block; margin:4px 0px 32px 0px;"
/>
</td>
</tr>
</table>
</td>
</tr>
<!-- CONTENT -->
<tr>
<td style="min-width: 590px;">
<t t-out="message.body" />
</td>
</tr>
<!-- FOOTER -->
<tr>
<td
align="center"
style="min-width: 590px; padding: 0 8px 0 8px; font-size:11px;"
>
<hr
width="100%"
style="background-color: red; border: medium none; clear: both; display: block; margin:4px 0px 32px 0px;"
/>
<div style="color: #FF9999;">
<b t-esc="company.name" /><br />
<t t-esc="company.name" />
<t t-if="company.phone">
::
<t t-esc="company.phone" />
</t>
<t t-if="company.email">
::
<a
t-att-href="'mailto:%s' % company.email"
style="text-decoration:none;color:red;"
>
<t t-esc="company.email" />
</a>
</t>
<t t-if="company.website">
::
<a
t-att-href="'%s' % company.website"
style="text-decoration:none;color:red;"
>
<t t-esc="company.website" />
</a>
</t>
</div>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</table>
</template>

</odoo>
60 changes: 60 additions & 0 deletions mail_layout_force/i18n/mail_layout_force.pot
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * mail_layout_force
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 14.0\n"
"Report-Msgid-Bugs-To: \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_layout_force
#: model:ir.model.fields,field_description:mail_layout_force.field_mail_compose_message__display_name
#: model:ir.model.fields,field_description:mail_layout_force.field_mail_template__display_name
#: model:ir.model.fields,field_description:mail_layout_force.field_mail_thread__display_name
msgid "Display Name"
msgstr ""

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

#. module: mail_layout_force
#: model:ir.model,name:mail_layout_force.model_mail_thread
msgid "Email Thread"
msgstr ""

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

#. module: mail_layout_force
#: model:ir.model.fields,field_description:mail_layout_force.field_mail_template__force_email_layout_id
msgid "Force Layout"
msgstr ""

#. module: mail_layout_force
#: model:ir.model.fields,help:mail_layout_force.field_mail_template__force_email_layout_id
msgid "Force a mail layout for this template."
msgstr ""

#. module: mail_layout_force
#: model:ir.model.fields,field_description:mail_layout_force.field_mail_compose_message__id
#: model:ir.model.fields,field_description:mail_layout_force.field_mail_template__id
#: model:ir.model.fields,field_description:mail_layout_force.field_mail_thread__id
msgid "ID"
msgstr ""

#. module: mail_layout_force
#: model:ir.model.fields,field_description:mail_layout_force.field_mail_compose_message____last_update
#: model:ir.model.fields,field_description:mail_layout_force.field_mail_template____last_update
#: model:ir.model.fields,field_description:mail_layout_force.field_mail_thread____last_update
msgid "Last Modified on"
msgstr ""
2 changes: 2 additions & 0 deletions mail_layout_force/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
from . import mail_template
from . import mail_thread
44 changes: 44 additions & 0 deletions mail_layout_force/models/mail_template.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Copyright 2022 Camptocamp SA (https://www.camptocamp.com).
# @author Iván Todorovich <ivan.todorovich@camptocamp.com>
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

from odoo import api, fields, models


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

force_email_layout_id = fields.Many2one(
comodel_name="ir.ui.view",
string="Force Layout",
domain=[("type", "=", "qweb"), ("mode", "=", "primary")],
context={"default_type": "qweb"},
help="Force a mail layout for this template.",
)

def _ensure_force_email_layout_xml_id(self):
missing = self.force_email_layout_id.filtered(lambda rec: not rec.xml_id)
if missing:
vals = [
{
"module": "__export__",
"name": "force_email_layout_%s" % rec.id,
"model": rec._name,
"res_id": rec.id,
}
for rec in missing
]
self.env["ir.model.data"].sudo().create(vals)
self.force_email_layout_id.invalidate_cache(["xml_id"])

@api.model_create_multi
def create(self, vals_list):
records = super().create(vals_list)
records._ensure_force_email_layout_xml_id()
return records

def write(self, vals):
res = super().write(vals)
if "force_email_layout_id" in vals:
self._ensure_force_email_layout_xml_id()
return res
20 changes: 20 additions & 0 deletions mail_layout_force/models/mail_thread.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Copyright 2022 Camptocamp SA (https://www.camptocamp.com).
# @author Iván Todorovich <ivan.todorovich@camptocamp.com>
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

from odoo import models


class MailThread(models.AbstractModel):
_inherit = "mail.thread"

def message_post_with_template(
self, template_id, email_layout_xmlid=None, **kwargs
):
# OVERRIDE to force the email_layout_xmlid defined on the mail.template
template = self.env["mail.template"].sudo().browse(template_id)
if template.force_email_layout_id:
email_layout_xmlid = template.force_email_layout_id.xml_id
return super().message_post_with_template(
template_id, email_layout_xmlid=email_layout_xmlid, **kwargs
)
Loading