Ivan Yelizariev
3 years ago
No known key found for this signature in database
GPG Key ID: 5C35763D5E7BFD67
27 changed files with 1189 additions and 14 deletions
-
14mail_multi_website/ ⇐ ⇐ ⇐/README.rst
-
67mail_multi_website/README.rst
-
43mail_multi_website/__init__.py
-
45mail_multi_website/__manifest__.py
-
13mail_multi_website/doc/changelog.rst
-
73mail_multi_website/doc/index.rst
-
36mail_multi_website/doc/src/index.html
-
1mail_multi_website/doc/src/info.yaml
-
123mail_multi_website/i18n/mail_multi_website.pot
-
BINmail_multi_website/images/main.jpg
-
7mail_multi_website/models/__init__.py
-
20mail_multi_website/models/ir_property.py
-
13mail_multi_website/models/mail_message.py
-
185mail_multi_website/models/mail_template.py
-
34mail_multi_website/models/mail_thread.py
-
50mail_multi_website/models/res_users.py
-
12mail_multi_website/models/website.py
-
BINmail_multi_website/static/description/icon.png
-
134mail_multi_website/static/description/index.html
-
4mail_multi_website/tests/__init__.py
-
63mail_multi_website/tests/test_fetch.py
-
11mail_multi_website/tests/test_mail_model.py
-
145mail_multi_website/tests/test_render.py
-
72mail_multi_website/tests/test_send.py
-
14mail_multi_website/views/website_views.xml
-
2mail_multi_website/wizard/__init__.py
-
22mail_multi_website/wizard/mail_compose_message.py
@ -1,14 +0,0 @@ |
|||
===================== |
|||
Multi-Brand Mailing |
|||
===================== |
|||
|
|||
Mail-related stuff for multi-website support |
|||
|
|||
Module is available at Odoo Apps Store: |
|||
https://www.odoo.com/apps/modules/13.0/mail_multi_website/ |
|||
|
|||
We do love FOSS, but sometimes we need to eat ¯\\_(ツ)_/¯ |
|||
|
|||
Please consider buying the module and get karma and support in return |
|||
|
|||
`IT Projects Labs Team <https://itpp.dev/>`__ |
@ -0,0 +1,67 @@ |
|||
.. image:: https://img.shields.io/badge/license-MIT-blue.svg |
|||
:target: https://opensource.org/licenses/MIT |
|||
:alt: License: MIT |
|||
|
|||
===================== |
|||
Multi-Brand Mailing |
|||
===================== |
|||
|
|||
Mail-related stuff for multi-website support |
|||
|
|||
* Makes following field in ``res.users`` website-dependent: |
|||
|
|||
* ``email`` |
|||
* ``signature`` |
|||
|
|||
* Makes following fields in ``mail.template`` website-dependent: |
|||
|
|||
* ``body_html`` |
|||
* ``mail_server_id`` |
|||
* ``report_template`` |
|||
|
|||
* Overrides ``mail.template``'s ``render_template`` method to add ``website`` |
|||
variable. It may cause incompatibility with other modules that redefine that |
|||
method too. |
|||
|
|||
Roadmap |
|||
======= |
|||
|
|||
* ``body_html`` becomes untranslatable after module installation |
|||
|
|||
Credits |
|||
======= |
|||
|
|||
Contributors |
|||
------------ |
|||
* `Ivan Yelizariev <https://it-projects.info/team/yelizariev>`__ |
|||
|
|||
Sponsors |
|||
-------- |
|||
* `e-thos SSII <http://www.e-thos.fr/>`__ |
|||
|
|||
Maintainers |
|||
----------- |
|||
* `IT-Projects LLC <https://it-projects.info>`__ |
|||
|
|||
To get a guaranteed support |
|||
you are kindly requested to purchase the module |
|||
at `odoo apps store <https://apps.odoo.com/apps/modules/13.0/mail_multi_website/>`__. |
|||
|
|||
Thank you for understanding! |
|||
|
|||
`IT-Projects Team <https://www.it-projects.info/team>`__ |
|||
|
|||
Further information |
|||
=================== |
|||
|
|||
Demo: http://runbot.it-projects.info/demo/mail-addons/13.0 |
|||
|
|||
HTML Description: https://apps.odoo.com/apps/modules/13.0/mail_multi_website/ |
|||
|
|||
Usage instructions: `<doc/index.rst>`_ |
|||
|
|||
Changelog: `<doc/changelog.rst>`_ |
|||
|
|||
Notifications on updates: `via Atom <https://github.com/it-projects-llc/mail-addons/commits/13.0/mail_multi_website.atom>`_, `by Email <https://blogtrottr.com/?subscribe=https://github.com/it-projects-llc/mail-addons/commits/13.0/mail_multi_website.atom>`_ |
|||
|
|||
Tested on Odoo 13.0 ca67c83e8d36ececaf97a7579c3ff2529b3e227c |
@ -0,0 +1,43 @@ |
|||
# Copyright 2018 Ivan Yelizariev <https://it-projects.info/team/yelizariev> |
|||
# License MIT (https://opensource.org/licenses/MIT). |
|||
from . import models |
|||
from . import wizard |
|||
from .tests import test_mail_model |
|||
|
|||
|
|||
def post_init_hook(cr, registry): |
|||
from odoo import api, SUPERUSER_ID |
|||
|
|||
env = api.Environment(cr, SUPERUSER_ID, {}) |
|||
|
|||
env.cr.execute("ALTER TABLE res_users ADD COLUMN email VARCHAR") |
|||
|
|||
# fill new email column with values from partner |
|||
for user in env["res.users"].with_context(active_test=False).search([]): |
|||
email = user.partner_id.email |
|||
if email: |
|||
user._force_default("email", email) |
|||
|
|||
|
|||
def uninstall_hook(cr, registry): |
|||
from odoo import api, SUPERUSER_ID |
|||
|
|||
env = api.Environment(cr, SUPERUSER_ID, {}) |
|||
|
|||
# remove properties |
|||
field_ids = [ |
|||
env.ref("base.field_res_users__email").id, |
|||
env.ref("base.field_res_users__signature").id, |
|||
env.ref("mail.field_mail_template__body_html").id, |
|||
env.ref("mail.field_mail_template__mail_server_id").id, |
|||
env.ref("mail.field_mail_template__report_template").id, |
|||
] |
|||
env["ir.property"].search([("fields_id", "in", field_ids)]).unlink() |
|||
|
|||
# copy emails from user to partner |
|||
cr.execute("SELECT partner_id,email FROM res_users") |
|||
for partner_id, default_email in cr.fetchall(): |
|||
env["res.partner"].browse(partner_id).email = default_email |
|||
|
|||
# email field is computed (related) and not needed if mail_multi_website is not installed |
|||
env.cr.execute("ALTER TABLE res_users DROP COLUMN email") |
@ -0,0 +1,45 @@ |
|||
# Copyright 2018,2020 Ivan Yelizariev <https://it-projects.info/team/yelizariev> |
|||
# Copyright 2018 Kolushov Alexandr <https://it-projects.info/team/KolushovAlexandr> |
|||
# License MIT (https://opensource.org/licenses/MIT). |
|||
# License OPL-1 (https://www.odoo.com/documentation/user/13.0/legal/licenses/licenses.html#odoo-apps) for derivative work. |
|||
{ |
|||
"name": """Multi-Brand Mailing""", |
|||
"summary": """Use single Backend to manage several Websites""", |
|||
"category": "Discuss", |
|||
# "live_test_url": "http://apps.it-projects.info/shop/product/website-multi-company?version=11.0", |
|||
"images": ["images/main.jpg"], |
|||
"version": "13.0.2.0.0", |
|||
"application": False, |
|||
"author": "IT-Projects LLC, Ivan Yelizariev", |
|||
"support": "apps@itpp.dev", |
|||
"website": "https://twitter.com/OdooFree", |
|||
"license": "OPL-1", |
|||
"price": 115.00, |
|||
"currency": "EUR", |
|||
"depends": [ |
|||
"ir_config_parameter_multi_company", |
|||
"web_website", |
|||
"mail", |
|||
"test_mail", |
|||
], |
|||
"external_dependencies": {"python": [], "bin": []}, |
|||
"data": ["views/website_views.xml"], |
|||
"demo": [], |
|||
"qweb": [], |
|||
"post_load": None, |
|||
"pre_init_hook": None, |
|||
"post_init_hook": "post_init_hook", |
|||
"uninstall_hook": "uninstall_hook", |
|||
"auto_install": False, |
|||
"installable": True, |
|||
# "demo_title": "Email Addresses per Website", |
|||
# "demo_addons": [ |
|||
# ], |
|||
# "demo_addons_hidden": [ |
|||
# ], |
|||
# "demo_url": "DEMO-URL", |
|||
# "demo_summary": "Use single Backend to manage several Websites", |
|||
# "demo_images": [ |
|||
# "images/MAIN_IMAGE", |
|||
# ] |
|||
} |
@ -0,0 +1,13 @@ |
|||
`2.0.0` |
|||
------- |
|||
- **Improvement:** adapt module to latest version of ``web_website`` module |
|||
|
|||
`1.0.1` |
|||
------- |
|||
|
|||
- **Fix:** Issue with module uninstallation |
|||
|
|||
`1.0.0` |
|||
------- |
|||
|
|||
- **Init version** |
@ -0,0 +1,73 @@ |
|||
===================== |
|||
Multi-Brand Mailing |
|||
===================== |
|||
|
|||
Installation |
|||
============ |
|||
|
|||
* `Install <https://odoo-development.readthedocs.io/en/latest/odoo/usage/install-module.html>`__ this module in a usual way |
|||
|
|||
Configuration |
|||
============= |
|||
|
|||
|
|||
Access to websites |
|||
------------------ |
|||
|
|||
* Go to menu ``[[ Settings ]] >> Users & Companies >> Users`` |
|||
* Select a user |
|||
* Grant access ``[x] Multi Websites for Backend`` |
|||
* Configure **Allowed Websites** |
|||
|
|||
User's email per website |
|||
------------------------ |
|||
|
|||
* Refresh page if you just granted your user access to websites |
|||
* Use top right-hand corner button with current website name to switch between websites |
|||
* Use top right-hand corner button with user name and avatar to open |
|||
Preference popup. When you edit **Email** field, it will be saved as a value |
|||
for current website. |
|||
|
|||
Email template per website |
|||
-------------------------- |
|||
|
|||
* Refresh page if you just granted your user access to websites |
|||
* `Activate Developer Mode <https://odoo-development.readthedocs.io/en/latest/odoo/usage/debug-mode.html>`__ |
|||
* Use top right-hand corner button with current website name to switch between websites |
|||
* Go to menu ``[[ Settings ]] >> Technical >> Email >> Templates`` |
|||
* When you edit template, following fields will be saved as a value for current website: |
|||
|
|||
* **Body** |
|||
* **Outgoing Mail Server** |
|||
* **Optional report to print and attach** |
|||
|
|||
* Additional variable ``website`` is available to configure rest fields (**Subject**, **From**, etc.) |
|||
|
|||
Note. If related record (e.g. ``sale.order``) has field ``company_id`` or ``website_id`` those values will be used instead of currently selected in Website / Company Switchers |
|||
|
|||
Alias domain per website |
|||
------------------------ |
|||
|
|||
Configure ``mail.catchall.domain`` per website. See Documentation of the module `Context-dependent values in System Parameters <https://apps.odoo.com/apps/modules/10.0/ir_config_parameter_multi_company>`__. |
|||
|
|||
Outgoing mails servers per website |
|||
---------------------------------- |
|||
|
|||
If each domain has different Outgoing Mail Server you need following adjustments |
|||
|
|||
* Go to menu ``[[ Website ]] >> Configuration >> Websites`` |
|||
* In each Website specify field **Outgoing Mails** |
|||
|
|||
Properties |
|||
---------- |
|||
|
|||
To review properties by website use menu ``[[ Settings ]] >> Technical >> Parameters >> Company Properties``. See **How it works** in Documentation of module `Website Switcher in Backend <https://apps.odoo.com/apps/modules/10.0/web_website>`__. |
|||
|
|||
Usage |
|||
===== |
|||
|
|||
When you work from backend, Email for current website is used. |
|||
|
|||
When a user do something on website (e.g. purchase products) and some mail is sent, then email address for that website will be used (mostly Administrator's email address). |
|||
|
|||
When email is sent, template's value like body, subject, etc. for current values are used. |
@ -0,0 +1,36 @@ |
|||
|
|||
<section class="oe_container"> |
|||
<div class="oe_row oe_spaced"> |
|||
<div class="oe_span12"> |
|||
|
|||
<div class="alert alert-info oe_mt32" style="padding:0.3em 0.6em; font-size: 150%;"> |
|||
<i class="fa fa-hand-o-right"></i><b> Key features: </b> |
|||
<ul class="list-unstyled"> |
|||
|
|||
<li> |
|||
<i class="fa fa-check-square-o text-primary"></i> |
|||
Separate Mail Templates per Website |
|||
</li> |
|||
|
|||
<li> |
|||
<i class="fa fa-check-square-o text-primary"></i> |
|||
<em>From</em> address in email has address for current Website |
|||
</li> |
|||
|
|||
<li> |
|||
<i class="fa fa-check-square-o text-primary"></i> |
|||
<em>Reply-To</em> address in email has domain of current Website |
|||
</li> |
|||
|
|||
<li> |
|||
<i class="fa fa-check-square-o text-primary"></i> |
|||
User's signature per Website |
|||
</li> |
|||
|
|||
</ul> |
|||
</div> |
|||
|
|||
</div> |
|||
</div> |
|||
</section> |
|||
|
@ -0,0 +1 @@ |
|||
slogan: Use single Backend to manage several Websites |
@ -0,0 +1,123 @@ |
|||
# Translation of Odoo Server. |
|||
# This file contains the translation of the following modules: |
|||
# * mail_multi_website |
|||
# |
|||
msgid "" |
|||
msgstr "" |
|||
"Project-Id-Version: Odoo Server 12.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_multi_website |
|||
#: model:ir.model.fields,field_description:mail_multi_website.field_email_template_preview__body_html |
|||
#: model:ir.model.fields,field_description:mail_multi_website.field_mail_template__body_html |
|||
msgid "Body" |
|||
msgstr "" |
|||
|
|||
#. module: mail_multi_website |
|||
#: model:ir.model.fields,field_description:mail_multi_website.field_mail_test_simple__company_id |
|||
msgid "Company" |
|||
msgstr "" |
|||
|
|||
#. module: mail_multi_website |
|||
#: model:ir.model,name:mail_multi_website.model_ir_property |
|||
msgid "Company Property" |
|||
msgstr "" |
|||
|
|||
#. module: mail_multi_website |
|||
#: model:ir.model.fields,help:mail_multi_website.field_website__mail_server_id |
|||
msgid "Default outgoing mail server" |
|||
msgstr "" |
|||
|
|||
#. module: mail_multi_website |
|||
#: model:ir.model.fields,field_description:mail_multi_website.field_res_users__email_multi_website |
|||
msgid "Email Multi Website" |
|||
msgstr "" |
|||
|
|||
#. module: mail_multi_website |
|||
#: model:ir.model,name:mail_multi_website.model_mail_template |
|||
msgid "Email Templates" |
|||
msgstr "" |
|||
|
|||
#. module: mail_multi_website |
|||
#: model:ir.model,name:mail_multi_website.model_mail_thread |
|||
msgid "Email Thread" |
|||
msgstr "" |
|||
|
|||
#. module: mail_multi_website |
|||
#: model:ir.model,name:mail_multi_website.model_mail_compose_message |
|||
msgid "Email composition wizard" |
|||
msgstr "" |
|||
|
|||
#. module: mail_multi_website |
|||
#: code:addons/mail_multi_website/models/mail_template.py:112 |
|||
#, python-format |
|||
msgid "Failed to render template %r using values %r" |
|||
msgstr "" |
|||
|
|||
#. module: mail_multi_website |
|||
#: model:ir.model,name:mail_multi_website.model_mail_message |
|||
msgid "Message" |
|||
msgstr "" |
|||
|
|||
#. module: mail_multi_website |
|||
#: model:ir.model.fields,field_description:mail_multi_website.field_res_users__email |
|||
msgid "Multi Website Email" |
|||
msgstr "" |
|||
|
|||
#. module: mail_multi_website |
|||
#: model:ir.model.fields,help:mail_multi_website.field_email_template_preview__mail_server_id |
|||
#: model:ir.model.fields,help:mail_multi_website.field_mail_template__mail_server_id |
|||
msgid "Optional preferred server for outgoing mails. If not set, the highest priority one will be used." |
|||
msgstr "" |
|||
|
|||
#. module: mail_multi_website |
|||
#: model:ir.model.fields,field_description:mail_multi_website.field_email_template_preview__report_template |
|||
#: model:ir.model.fields,field_description:mail_multi_website.field_mail_template__report_template |
|||
msgid "Optional report to print and attach (Multi-Website)" |
|||
msgstr "" |
|||
|
|||
#. module: mail_multi_website |
|||
#: model:ir.model.fields,field_description:mail_multi_website.field_email_template_preview__mail_server_id |
|||
#: model:ir.model.fields,field_description:mail_multi_website.field_mail_template__mail_server_id |
|||
msgid "Outgoing Mail Server (Multi-Website)" |
|||
msgstr "" |
|||
|
|||
#. module: mail_multi_website |
|||
#: model:ir.model.fields,field_description:mail_multi_website.field_website__mail_server_id |
|||
msgid "Outgoing Mails" |
|||
msgstr "" |
|||
|
|||
#. module: mail_multi_website |
|||
#: model:ir.model.fields,field_description:mail_multi_website.field_mail_compose_message__mail_server_id |
|||
#: model:ir.model.fields,field_description:mail_multi_website.field_mail_mail__mail_server_id |
|||
#: model:ir.model.fields,field_description:mail_multi_website.field_mail_message__mail_server_id |
|||
msgid "Outgoing mail server" |
|||
msgstr "" |
|||
|
|||
#. module: mail_multi_website |
|||
#: model:ir.model.fields,field_description:mail_multi_website.field_res_users__signature |
|||
msgid "Signature" |
|||
msgstr "" |
|||
|
|||
#. module: mail_multi_website |
|||
#: model:ir.model,name:mail_multi_website.model_mail_test_simple |
|||
msgid "Simple Chatter Model" |
|||
msgstr "" |
|||
|
|||
#. module: mail_multi_website |
|||
#: model:ir.model,name:mail_multi_website.model_res_users |
|||
msgid "Users" |
|||
msgstr "" |
|||
|
|||
#. module: mail_multi_website |
|||
#: model:ir.model,name:mail_multi_website.model_website |
|||
#: model:ir.model.fields,field_description:mail_multi_website.field_mail_test_simple__website_id |
|||
msgid "Website" |
|||
msgstr "" |
|||
|
After Width: 750 | Height: 371 | Size: 285 KiB |
@ -0,0 +1,7 @@ |
|||
# License MIT (https://opensource.org/licenses/MIT). |
|||
from . import res_users |
|||
from . import ir_property |
|||
from . import mail_template |
|||
from . import mail_thread |
|||
from . import mail_message |
|||
from . import website |
@ -0,0 +1,20 @@ |
|||
# Copyright 2018 Ivan Yelizariev <https://it-projects.info/team/yelizariev> |
|||
# Copyright 2018 Kolushov Alexandr <https://it-projects.info/team/KolushovAlexandr> |
|||
# License MIT (https://opensource.org/licenses/MIT). |
|||
from odoo import models |
|||
|
|||
|
|||
class IrProperty(models.Model): |
|||
_inherit = "ir.property" |
|||
|
|||
def write(self, vals): |
|||
res = super(IrProperty, self).write(vals) |
|||
field_object_list = [ |
|||
self.env.ref("base.field_res_users__email"), |
|||
self.env.ref("mail.field_mail_template__body_html"), |
|||
self.env.ref("mail.field_mail_template__mail_server_id"), |
|||
self.env.ref("mail.field_mail_template__report_template"), |
|||
] |
|||
for fobj in field_object_list: |
|||
self._update_db_value_website_dependent(fobj) |
|||
return res |
@ -0,0 +1,13 @@ |
|||
# Copyright 2018,2020 Ivan Yelizariev <https://it-projects.info/team/yelizariev> |
|||
# License MIT (https://opensource.org/licenses/MIT). |
|||
# License OPL-1 (https://www.odoo.com/documentation/user/13.0/legal/licenses/licenses.html#odoo-apps) for derivative work. |
|||
from odoo import fields, models |
|||
|
|||
|
|||
class Message(models.Model): |
|||
_inherit = "mail.message" |
|||
|
|||
def _default_mail_server_id(self): |
|||
return self.env.website.mail_server_id.id |
|||
|
|||
mail_server_id = fields.Many2one(default=_default_mail_server_id) |
@ -0,0 +1,185 @@ |
|||
# Copyright 2018,2020 Ivan Yelizariev <https://it-projects.info/team/yelizariev> |
|||
# License MIT (https://opensource.org/licenses/MIT). |
|||
# License OPL-1 (https://www.odoo.com/documentation/user/13.0/legal/licenses/licenses.html#odoo-apps) for derivative work. |
|||
import logging |
|||
|
|||
from odoo import _, api, fields, models, tools |
|||
from odoo.exceptions import UserError |
|||
|
|||
from odoo.addons.mail.models.mail_template import format_date, format_datetime |
|||
|
|||
_logger = logging.getLogger(__name__) |
|||
FIELDS = ["body_html", "mail_server_id", "report_template"] |
|||
|
|||
try: |
|||
from odoo.addons.mail.models.mail_template import ( |
|||
mako_safe_template_env, |
|||
mako_template_env, |
|||
) |
|||
except ImportError: |
|||
_logger.warning("jinja2 not available, templating features will not work!") |
|||
|
|||
|
|||
class MailTemplate(models.Model): |
|||
|
|||
_inherit = ["mail.template", "website_dependent.mixin"] |
|||
_name = "mail.template" |
|||
|
|||
body_html = fields.Html(company_dependent=True, website_dependent=True) |
|||
mail_server_id = fields.Many2one( |
|||
string="Outgoing Mail Server (Multi-Website)", |
|||
company_dependent=True, |
|||
website_dependent=True, |
|||
) |
|||
report_template = fields.Many2one( |
|||
string="Optional report to print and attach (Multi-Website)", |
|||
company_dependent=True, |
|||
website_dependent=True, |
|||
) |
|||
|
|||
def generate_email(self, res_ids, fields=None): |
|||
"""Remove mail_server_id when not set to recompute in _default_mail_server_id in mail.message""" |
|||
multi_mode = True |
|||
if isinstance(res_ids, int): |
|||
multi_mode = False |
|||
res = super(MailTemplate, self).generate_email(res_ids, fields=fields) |
|||
if not multi_mode: |
|||
list_of_dict = {0: res} |
|||
else: |
|||
list_of_dict = res |
|||
|
|||
for _unused, data in list_of_dict.items(): |
|||
if "mail_server_id" in data and not data.get("mail_server_id"): |
|||
del data["mail_server_id"] |
|||
|
|||
return res |
|||
|
|||
@api.model |
|||
def _render_template(self, template_txt, model, res_ids, post_process=False): |
|||
"""Override to add website to context""" |
|||
multi_mode = True |
|||
if isinstance(res_ids, int): |
|||
multi_mode = False |
|||
res_ids = [res_ids] |
|||
|
|||
results = dict.fromkeys(res_ids, u"") |
|||
|
|||
# try to load the template |
|||
try: |
|||
mako_env = ( |
|||
mako_safe_template_env |
|||
if self.env.context.get("safe") |
|||
else mako_template_env |
|||
) |
|||
template = mako_env.from_string(tools.ustr(template_txt)) |
|||
except Exception: |
|||
_logger.info("Failed to load template %r", template_txt, exc_info=True) |
|||
return multi_mode and results or results[res_ids[0]] |
|||
|
|||
# prepare template variables |
|||
records = self.env[model].browse( |
|||
it for it in res_ids if it |
|||
) # filter to avoid browsing [None] |
|||
res_to_rec = dict.fromkeys(res_ids, None) |
|||
for record in records: |
|||
res_to_rec[record.id] = record |
|||
variables = { |
|||
"format_date": lambda date, date_format=False, lang_code=False: format_date( |
|||
self.env, date, date_format, lang_code |
|||
), |
|||
"format_datetime": lambda dt, tz=False, dt_format=False, lang_code=False: format_datetime( |
|||
self.env, dt, tz, dt_format, lang_code |
|||
), |
|||
"format_amount": lambda amount, currency, lang_code=False: tools.format_amount( |
|||
self.env, amount, currency, lang_code |
|||
), |
|||
"format_duration": lambda value: tools.format_duration(value), |
|||
"user": self.env.user, |
|||
"ctx": self._context, # context kw would clash with mako internals |
|||
} |
|||
|
|||
# [NEW] Check website and company context |
|||
company = self.env["res.company"] # empty value |
|||
|
|||
company_id = self.env.context.get("force_company") |
|||
if company_id: |
|||
company = self.env["res.company"].sudo().browse(company_id) |
|||
|
|||
website = self.env.website |
|||
# [/NEW] |
|||
|
|||
for res_id, record in res_to_rec.items(): |
|||
# [NEW] Check website and company context |
|||
record_company = company |
|||
if not record_company: |
|||
if hasattr(record, "company_id") and record.company_id: |
|||
record_company = record.company_id |
|||
|
|||
record_website = website |
|||
if hasattr(record, "website_id") and record.website_id: |
|||
record_website = record.website_id |
|||
|
|||
if ( |
|||
record_company |
|||
and record_website |
|||
and record_website.company_id != company |
|||
): |
|||
# company and website are incompatible, so keep only company |
|||
record_website = self.env["website"] # empty value |
|||
|
|||
record_context = dict( |
|||
force_company=record_company.id, website_id=record_website.id |
|||
) |
|||
variables["website"] = record_website |
|||
# [/NEW] |
|||
|
|||
variables["object"] = record |
|||
try: |
|||
render_result = template.render(variables) |
|||
except Exception: |
|||
_logger.info( |
|||
"Failed to render template %r using values %r" |
|||
% (template, variables), |
|||
exc_info=True, |
|||
) |
|||
raise UserError( |
|||
_("Failed to render template %r using values %r") |
|||
% (template, variables) |
|||
) |
|||
if render_result == u"False": |
|||
render_result = u"" |
|||
results[res_id] = render_result |
|||
|
|||
if post_process: |
|||
for res_id, result in results.items(): |
|||
results[res_id] = self.with_context( |
|||
**record_context |
|||
).render_post_process(result) |
|||
|
|||
return multi_mode and results or results[res_ids[0]] |
|||
|
|||
@api.model |
|||
def create(self, vals): |
|||
res = super(MailTemplate, self).create(vals) |
|||
# make value company independent |
|||
for f in FIELDS: |
|||
res._force_default(f, vals.get(f)) |
|||
return res |
|||
|
|||
def write(self, vals): |
|||
res = super(MailTemplate, self).write(vals) |
|||
|
|||
# TODO: will it work with OCA's partner_firstname module? |
|||
if "name" in vals: |
|||
fields_to_update = FIELDS |
|||
else: |
|||
fields_to_update = [f for f in FIELDS if f in vals] |
|||
for f in fields_to_update: |
|||
self._update_properties_label(f) |
|||
|
|||
return res |
|||
|
|||
def _auto_init(self): |
|||
for f in FIELDS: |
|||
self._auto_init_website_dependent(f) |
|||
return super(MailTemplate, self)._auto_init() |
@ -0,0 +1,34 @@ |
|||
# Copyright 2018,2020 Ivan Yelizariev <https://it-projects.info/team/yelizariev> |
|||
# License MIT (https://opensource.org/licenses/MIT). |
|||
# License OPL-1 (https://www.odoo.com/documentation/user/13.0/legal/licenses/licenses.html#odoo-apps) for derivative work. |
|||
from odoo import api, models, tools |
|||
|
|||
|
|||
class MailThread(models.AbstractModel): |
|||
_inherit = "mail.thread" |
|||
|
|||
@api.model |
|||
def _message_route_process(self, message, message_dict, routes): |
|||
rcpt_tos = ",".join( |
|||
[ |
|||
tools.decode_message_header(message, "Delivered-To"), |
|||
tools.decode_message_header(message, "To"), |
|||
tools.decode_message_header(message, "Cc"), |
|||
tools.decode_message_header(message, "Resent-To"), |
|||
tools.decode_message_header(message, "Resent-Cc"), |
|||
] |
|||
) |
|||
rcpt_tos_websiteparts = [ |
|||
e.split("@")[1].lower() for e in tools.email_split(rcpt_tos) |
|||
] |
|||
website = ( |
|||
self.env["website"].sudo().search([("domain", "in", rcpt_tos_websiteparts)]) |
|||
) |
|||
company = website.mapped("company_id") |
|||
new_self = self.with_context( |
|||
allowed_website_ids=website.ids, allowed_company_ids=company.ids |
|||
) |
|||
|
|||
return super(MailThread, new_self)._message_route_process( |
|||
message, message_dict, routes |
|||
) |
@ -0,0 +1,50 @@ |
|||
# Copyright 2018 Ivan Yelizariev <https://it-projects.info/team/yelizariev> |
|||
# License MIT (https://opensource.org/licenses/MIT). |
|||
import logging |
|||
|
|||
from odoo import api, fields, models |
|||
|
|||
_logger = logging.getLogger(__name__) |
|||
FIELD_NAME = "email" |
|||
FIELDS = ["signature"] |
|||
ALL_FIELDS = [FIELD_NAME] + FIELDS |
|||
|
|||
|
|||
class User(models.Model): |
|||
|
|||
_inherit = ["res.users", "website_dependent.mixin"] |
|||
_name = "res.users" |
|||
|
|||
signature = fields.Html(company_dependent=True, website_dependent=True) |
|||
|
|||
# extra field to detach email field from res.partner |
|||
email = fields.Char( |
|||
string="Multi Website Email", |
|||
company_dependent=True, |
|||
website_dependent=True, |
|||
inherited=False, |
|||
related=None, |
|||
readonly=False, |
|||
) |
|||
|
|||
@api.model |
|||
def create(self, vals): |
|||
res = super(User, self).create(vals) |
|||
# make value company independent |
|||
res._force_default(FIELD_NAME, vals.get("email")) |
|||
for f in FIELDS: |
|||
res._force_default(f, vals.get(f)) |
|||
return res |
|||
|
|||
def write(self, vals): |
|||
res = super(User, self).write(vals) |
|||
# TODO: will it work with OCA's partner_firstname module? |
|||
if any(k in vals for k in ["name"] + FIELDS): |
|||
for f in ALL_FIELDS: |
|||
self._update_properties_label(f) |
|||
return res |
|||
|
|||
def _auto_init(self): |
|||
for f in FIELDS: |
|||
self._auto_init_website_dependent(f) |
|||
return super(User, self)._auto_init() |
@ -0,0 +1,12 @@ |
|||
# Copyright 2017 Ivan Yelizariev <https://it-projects.info/team/yelizariev> |
|||
# License MIT (https://opensource.org/licenses/MIT). |
|||
|
|||
from odoo import fields, models |
|||
|
|||
|
|||
class Website(models.Model): |
|||
_inherit = "website" |
|||
|
|||
mail_server_id = fields.Many2one( |
|||
"ir.mail_server", "Outgoing Mails", help="Default outgoing mail server" |
|||
) |
After Width: 100 | Height: 100 | Size: 2.1 KiB |
@ -0,0 +1,134 @@ |
|||
|
|||
<section class="container"> |
|||
<div class="row"> |
|||
<div class="col-md-offset-1 col-md-8 mb64 mt64"> |
|||
<div class=""> |
|||
<h2 class="display-3">Multi-Brand Mailing</h2> |
|||
<h4 class="text-default">Use single Backend to manage several Websites</h4> |
|||
<p class="text-default mt16">Version: v<b>13.0</b>.2.0.0</p> |
|||
</div> |
|||
</div> |
|||
<div class="col-md-3 text-right"> |
|||
<p> |
|||
<img src="https://itpp.dev/images/favicon.png"/> |
|||
<br/>Tested and maintained by |
|||
<br/><b>IT Projects Labs</b> |
|||
<br/>Assitance: <a href="mailto:apps@itpp.dev">apps@itpp.dev</a> |
|||
</p> |
|||
</div> |
|||
</div> |
|||
</section> |
|||
|
|||
|
|||
|
|||
<section class="oe_container"> |
|||
<div class="oe_row oe_spaced"> |
|||
<div class="oe_span12"> |
|||
|
|||
<div class="alert alert-info oe_mt32" style="padding:0.3em 0.6em; font-size: 150%;"> |
|||
<i class="fa fa-hand-o-right"></i><b> Key features: </b> |
|||
<ul class="list-unstyled"> |
|||
|
|||
<li> |
|||
<i class="fa fa-check-square-o text-primary"></i> |
|||
Separate Mail Templates per Website |
|||
</li> |
|||
|
|||
<li> |
|||
<i class="fa fa-check-square-o text-primary"></i> |
|||
<em>From</em> address in email has address for current Website |
|||
</li> |
|||
|
|||
<li> |
|||
<i class="fa fa-check-square-o text-primary"></i> |
|||
<em>Reply-To</em> address in email has domain of current Website |
|||
</li> |
|||
|
|||
<li> |
|||
<i class="fa fa-check-square-o text-primary"></i> |
|||
User's signature per Website |
|||
</li> |
|||
|
|||
</ul> |
|||
</div> |
|||
|
|||
</div> |
|||
</div> |
|||
</section> |
|||
|
|||
|
|||
|
|||
|
|||
<section class="container text-center"> |
|||
<div class="mt-4 mb-3"> |
|||
<h2>Let our expertise work for you!</h2> |
|||
<h4 class="d-none d-md-block">(Doors and windows below are clickable)</h4> |
|||
<div class="mb32 d-md-none"> |
|||
<ul class="list-unstyled"> |
|||
<li><a target="_blank" href="https://apps.odoo.com/apps/browse?repo_maintainer_id=59928">All modules</a></li> |
|||
<li><a target="_blank" href="https://apps.odoo.com/apps/browse?price=Free&order=Downloads&repo_maintainer_id=59928">Free Modules</a></li> |
|||
<li><a target="_blank" href="https://apps.odoo.com/apps/modules/category/Point%20of%20Sale/browse?repo_maintainer_id=59928">All POS modules</a></li> |
|||
<li><a target="_blank" href="https://apps.odoo.com/apps/modules/category/Discuss/browse?repo_maintainer_id=59928">All Mail modules</a></li> |
|||
<li><a target="_blank" href="https://apps.odoo.com/apps/modules/category/Website/browse?repo_maintainer_id=59928">All Website modules</a></li> |
|||
<li><a target="_blank" href="https://apps.odoo.com/apps/modules/category/eCommerce/browse?repo_maintainer_id=59928">All eCommerce modules</a></li> |
|||
<li><a target="_blank" href="https://apps.odoo.com/apps/modules/browse?search=sync+studio&repo_maintainer_id=59928">Sync Studio</a></li> |
|||
<li><a target="_blank" href="https://apps.odoo.com/apps/modules/14.0/openapi/">REST API</a></li> |
|||
<li><a target="_blank" href="https://apps.odoo.com/apps/modules/14.0/base_automation_webhook/">Webhooks</a></li> |
|||
<li><a target="_blank" href="https://apps.odoo.com/apps/modules/14.0/pos_product_available/">POS: show product qty</a></li> |
|||
<li><a target="_blank" href="https://apps.odoo.com/apps/modules/14.0/web_login_background/">Web Login Background</a></li> |
|||
</ul> |
|||
</div> |
|||
<div class="mb64 d-none d-xl-block"> |
|||
<img class="img img-responsive" src="https://itpp.dev/images/apps/;-)/itpp-labs-1100.jpg" usemap="#itpp-xl" /> |
|||
<map name="itpp-xl"> |
|||
<area alt="Free Modules" target="_blank" href="https://apps.odoo.com/apps/browse?price=Free&order=Downloads&repo_maintainer_id=59928" shape="rect" class="" coords="900,220,1080,625" /> |
|||
<area alt="Sync Studio" target="_blank" href="https://apps.odoo.com/apps/modules/browse?search=sync+studio&repo_maintainer_id=59928" shape="rect" class="" coords="552,186,721,274" /> |
|||
<area alt="REST API" target="_blank" href="https://apps.odoo.com/apps/modules/14.0/openapi/" shape="rect" class="" coords="646,279,720,365" /> |
|||
<area alt="Webhooks" target="_blank" href="https://apps.odoo.com/apps/modules/14.0/base_automation_webhook/" shape="rect" class="" coords="646,370,720,458" /> |
|||
<area alt="POS: show product qty" target="_blank" href="https://apps.odoo.com/apps/modules/14.0/pos_product_available/" shape="rect" class="" coords="82,373,251,459" /> |
|||
<area alt="All modules" target="_blank" href="https://apps.odoo.com/apps/browse?repo_maintainer_id=59928" shape="rect" class="" coords="326,267,381,456" /> |
|||
<area alt="All POS modules" target="_blank" href="https://apps.odoo.com/apps/modules/category/Point%20of%20Sale/browse?repo_maintainer_id=59928" shape="rect" class="" coords="82,191,154,276" /> |
|||
<area alt="All Mail modules" target="_blank" href="https://apps.odoo.com/apps/modules/category/Discuss/browse?repo_maintainer_id=59928" shape="rect" class="" coords="82,282,155,368" /> |
|||
<area alt="All Website modules" target="_blank" href="https://apps.odoo.com/apps/modules/category/Website/browse?repo_maintainer_id=59928" shape="rect" class="" coords="176,282,250,368" /> |
|||
<area alt="All eCommerce modules" target="_blank" href="https://apps.odoo.com/apps/modules/category/eCommerce/browse?repo_maintainer_id=59928" shape="rect" class="" coords="175,189,250,275" /> |
|||
<area alt="Ivan Yelizariev" target="_blank" href="https://apps.odoo.com/apps/modules/browse?search=Ivan+Yelizariev&repo_maintainer_id=59928" shape="rect" class="" coords="554,280,625,456" /> |
|||
<area alt="Web Login Background" target="_blank" href="https://apps.odoo.com/apps/modules/14.0/web_login_background/" shape="rect" class="" coords="420,267,477,456" /> |
|||
</map> |
|||
</div> |
|||
<div class="mb64 d-none d-lg-block d-xl-none"> |
|||
<img class="img img-responsive" src="https://itpp.dev/images/apps/;-)/itpp-labs-930.jpg" usemap="#itpp-lg" /> |
|||
<map name="itpp-lg"> |
|||
<area alt="Free Modules" target="_blank" href="https://apps.odoo.com/apps/browse?price=Free&order=Downloads&repo_maintainer_id=59928" shape="rect" class="" coords="760,186,913,528" /> |
|||
<area alt="Sync Studio" target="_blank" href="https://apps.odoo.com/apps/modules/browse?search=sync+studio&repo_maintainer_id=59928" shape="rect" class="" coords="466,157,609,231" /> |
|||
<area alt="REST API" target="_blank" href="https://apps.odoo.com/apps/modules/14.0/openapi/" shape="rect" class="" coords="546,235,608,308" /> |
|||
<area alt="Webhooks" target="_blank" href="https://apps.odoo.com/apps/modules/14.0/base_automation_webhook/" shape="rect" class="" coords="546,312,608,387" /> |
|||
<area alt="POS: show product qty" target="_blank" href="https://apps.odoo.com/apps/modules/14.0/pos_product_available/" shape="rect" class="" coords="69,315,212,388" /> |
|||
<area alt="All modules" target="_blank" href="https://apps.odoo.com/apps/browse?repo_maintainer_id=59928" shape="rect" class="" coords="275,225,322,385" /> |
|||
<area alt="All POS modules" target="_blank" href="https://apps.odoo.com/apps/modules/category/Point%20of%20Sale/browse?repo_maintainer_id=59928" shape="rect" class="" coords="69,161,130,233" /> |
|||
<area alt="All Mail modules" target="_blank" href="https://apps.odoo.com/apps/modules/category/Discuss/browse?repo_maintainer_id=59928" shape="rect" class="" coords="69,238,131,311" /> |
|||
<area alt="All Website modules" target="_blank" href="https://apps.odoo.com/apps/modules/category/Website/browse?repo_maintainer_id=59928" shape="rect" class="" coords="148,238,211,311" /> |
|||
<area alt="All eCommerce modules" target="_blank" href="https://apps.odoo.com/apps/modules/category/eCommerce/browse?repo_maintainer_id=59928" shape="rect" class="" coords="147,159,211,232" /> |
|||
<area alt="Ivan Yelizariev" target="_blank" href="https://apps.odoo.com/apps/modules/browse?search=Ivan+Yelizariev&repo_maintainer_id=59928" shape="rect" class="" coords="468,236,528,385" /> |
|||
<area alt="Web Login Background" target="_blank" href="https://apps.odoo.com/apps/modules/14.0/web_login_background/" shape="rect" class="" coords="355,225,403,385" /> |
|||
</map> |
|||
</div> |
|||
<div class="mb64 d-lg-none"> |
|||
<img class="img img-responsive" src="https://itpp.dev/images/apps/;-)/itpp-labs-690.jpg" usemap="#itpp-md" /> |
|||
<map name="itpp-md"> |
|||
<area alt="Free Modules" target="_blank" href="https://apps.odoo.com/apps/browse?price=Free&order=Downloads&repo_maintainer_id=59928" shape="rect" class="" coords="564,138,677,392" /> |
|||
<area alt="Sync Studio" target="_blank" href="https://apps.odoo.com/apps/modules/browse?search=sync+studio&repo_maintainer_id=59928" shape="rect" class="" coords="346,116,452,171" /> |
|||
<area alt="REST API" target="_blank" href="https://apps.odoo.com/apps/modules/14.0/openapi/" shape="rect" class="" coords="405,175,451,228" /> |
|||
<area alt="Webhooks" target="_blank" href="https://apps.odoo.com/apps/modules/14.0/base_automation_webhook/" shape="rect" class="" coords="405,232,451,287" /> |
|||
<area alt="POS: show product qty" target="_blank" href="https://apps.odoo.com/apps/modules/14.0/pos_product_available/" shape="rect" class="" coords="51,233,157,287" /> |
|||
<area alt="All modules" target="_blank" href="https://apps.odoo.com/apps/browse?repo_maintainer_id=59928" shape="rect" class="" coords="204,167,238,286" /> |
|||
<area alt="All POS modules" target="_blank" href="https://apps.odoo.com/apps/modules/category/Point%20of%20Sale/browse?repo_maintainer_id=59928" shape="rect" class="" coords="51,119,96,173" /> |
|||
<area alt="All Mail modules" target="_blank" href="https://apps.odoo.com/apps/modules/category/Discuss/browse?repo_maintainer_id=59928" shape="rect" class="" coords="51,176,97,230" /> |
|||
<area alt="All Website modules" target="_blank" href="https://apps.odoo.com/apps/modules/category/Website/browse?repo_maintainer_id=59928" shape="rect" class="" coords="110,176,156,230" /> |
|||
<area alt="All eCommerce modules" target="_blank" href="https://apps.odoo.com/apps/modules/category/eCommerce/browse?repo_maintainer_id=59928" shape="rect" class="" coords="109,118,156,172" /> |
|||
<area alt="Ivan Yelizariev" target="_blank" href="https://apps.odoo.com/apps/modules/browse?search=Ivan+Yelizariev&repo_maintainer_id=59928" shape="rect" class="" coords="347,175,392,286" /> |
|||
<area alt="Web Login Background" target="_blank" href="https://apps.odoo.com/apps/modules/14.0/web_login_background/" shape="rect" class="" coords="263,167,299,286" /> |
|||
</map> |
|||
</div> |
|||
</div> |
|||
</section> |
|||
|
@ -0,0 +1,4 @@ |
|||
# License MIT (https://opensource.org/licenses/MIT). |
|||
from . import test_send |
|||
from . import test_render |
|||
from . import test_fetch |
@ -0,0 +1,63 @@ |
|||
# Copyright 2018,2020 Ivan Yelizariev <https://it-projects.info/team/yelizariev> |
|||
# Copyright 2018 Kolushov Alexandr <https://it-projects.info/team/KolushovAlexandr> |
|||
# License MIT (https://opensource.org/licenses/MIT). |
|||
# License OPL-1 (https://www.odoo.com/documentation/user/13.0/legal/licenses/licenses.html#odoo-apps) for derivative work. |
|||
from odoo.tools import mute_logger |
|||
|
|||
from odoo.addons.test_mail.data.test_mail_data import MAIL_TEMPLATE |
|||
from odoo.addons.test_mail.tests.test_mail_mail import TestMail |
|||
|
|||
|
|||
# TODO: Shall we use TestMailgateway class instead? |
|||
class TestFetch(TestMail): |
|||
at_install = True |
|||
post_install = True |
|||
|
|||
def setUp(self): |
|||
super(TestFetch, self).setUp() |
|||
self.email_from = '"Sylvie Lelitre" <test.sylvie.lelitre@agrolait.com>' |
|||
self.website = self.env["website"].create( |
|||
{"name": "Test Website", "domain": "example.com"} |
|||
) |
|||
self.company = self.env["res.company"].create({"name": "New Test Website"}) |
|||
self.website.company_id = self.company |
|||
|
|||
# copy-paste from mail.tests.test_mail_gateway |
|||
mail_test_model = self.env["ir.model"]._get("mail.test.simple") |
|||
# groups@.. will cause the creation of new mail.test.simple |
|||
self.alias = self.env["mail.alias"].create( |
|||
{ |
|||
"alias_name": "groups", |
|||
"alias_user_id": False, |
|||
"alias_model_id": mail_test_model.id, |
|||
"alias_contact": "everyone", |
|||
} |
|||
) |
|||
|
|||
@mute_logger("odoo.addons.mail.models.mail_thread", "odoo.models") |
|||
def test_fetch_multi_website(self): |
|||
""" Incoming email on an alias creating a new record + message_new + message details """ |
|||
new_groups = self.format_and_process( |
|||
MAIL_TEMPLATE, |
|||
self.email_from, |
|||
"groups@example.com", |
|||
subject="My Frogs", |
|||
target_model="mail.test.simple", |
|||
) |
|||
|
|||
# Test: one group created by mailgateway administrator |
|||
self.assertEqual( |
|||
len(new_groups), |
|||
1, |
|||
"message_process: a new mail.test should have been created", |
|||
) |
|||
self.assertEqual( |
|||
new_groups.website_id, |
|||
self.website, |
|||
"New record is created with wrong website", |
|||
) |
|||
self.assertEqual( |
|||
new_groups.company_id, |
|||
self.company, |
|||
"New record is created with wrong company", |
|||
) |
@ -0,0 +1,11 @@ |
|||
# Copyright 2018,2020 Ivan Yelizariev <https://it-projects.info/team/yelizariev> |
|||
# License MIT (https://opensource.org/licenses/MIT). |
|||
# License OPL-1 (https://www.odoo.com/documentation/user/13.0/legal/licenses/licenses.html#odoo-apps) for derivative work. |
|||
from odoo import fields, models |
|||
|
|||
|
|||
class MailTest(models.Model): |
|||
_inherit = "mail.test.simple" |
|||
|
|||
company_id = fields.Many2one("res.company", default=lambda self: self.env.company) |
|||
website_id = fields.Many2one("website", default=lambda self: self.env.website) |
@ -0,0 +1,145 @@ |
|||
# Copyright 2018,2020 Ivan Yelizariev <https://it-projects.info/team/yelizariev> |
|||
# Copyright 2018 Kolushov Alexandr <https://it-projects.info/team/KolushovAlexandr> |
|||
# License MIT (https://opensource.org/licenses/MIT). |
|||
# License OPL-1 (https://www.odoo.com/documentation/user/13.0/legal/licenses/licenses.html#odoo-apps) for derivative work. |
|||
import base64 |
|||
|
|||
from odoo.addons.test_mail.tests.test_mail_mail import TestMail |
|||
|
|||
|
|||
class TestRender(TestMail): |
|||
at_install = True |
|||
post_install = True |
|||
|
|||
def setUp(self): |
|||
super(TestRender, self).setUp() |
|||
|
|||
self.original_email = self.env.user.email |
|||
self.original_company = self.env.user.company_id |
|||
self.email = "superadmin@second-website.example" |
|||
self.assertNotEqual(self.original_email, self.email) |
|||
|
|||
self.website = self.env.ref("website.website2") |
|||
self.company = self.env["res.company"].create({"name": "New Test Website"}) |
|||
self.website.company_id = self.company |
|||
self.mail_server_id = self.env["ir.mail_server"].create( |
|||
{"name": "mail server", "smtp_host": "mail.example.com"} |
|||
) |
|||
self.website.mail_server_id = self.mail_server_id |
|||
|
|||
user_admin = self.env.ref("base.user_admin") |
|||
# copy-paste from mail.tests.test_mail_template |
|||
self._attachments = [ |
|||
{ |
|||
"name": "first.txt", |
|||
"datas": base64.b64encode(b"My first attachment"), |
|||
"res_model": "res.partner", |
|||
"res_id": user_admin.partner_id.id, |
|||
}, |
|||
{ |
|||
"name": "second.txt", |
|||
"datas": base64.b64encode(b"My second attachment"), |
|||
"res_model": "res.partner", |
|||
"res_id": user_admin.partner_id.id, |
|||
}, |
|||
] |
|||
|
|||
self.partner_1 = self.env["res.partner"].create({"name": "partner_1"}) |
|||
self.partner_2 = self.env["res.partner"].create({"name": "partner_2"}) |
|||
self.email_1 = "test1@example.com" |
|||
self.email_2 = "test2@example.com" |
|||
self.email_3 = self.partner_1.email |
|||
self.email_template = self.env["mail.template"].create( |
|||
{ |
|||
"model_id": self.env["ir.model"]._get("mail.test").id, |
|||
"name": "Pigs Template", |
|||
"subject": "${website.name}", |
|||
"body_html": "${object.description}", |
|||
"user_signature": False, |
|||
"attachment_ids": [ |
|||
(0, 0, self._attachments[0]), |
|||
(0, 0, self._attachments[1]), |
|||
], |
|||
"partner_to": "%s,%s" |
|||
% (self.partner_2.id, self.user_employee.partner_id.id), |
|||
"email_to": "{}, {}".format(self.email_1, self.email_2), |
|||
"email_cc": "%s" % self.email_3, |
|||
} |
|||
) |
|||
|
|||
def switch_user_website(self): |
|||
# add website to allowed |
|||
self.env.user.write( |
|||
dict( |
|||
backend_website_ids=[(4, self.website.id)], |
|||
backend_website_id=self.website.id, |
|||
company_id=self.company.id, |
|||
company_ids=[(4, self.company.id)], |
|||
) |
|||
) |
|||
|
|||
def test_website_in_render_variables(self): |
|||
"""Mail values are per website""" |
|||
|
|||
self.env.user.backend_website_id = None |
|||
TestModel = self.env["mail.test"].with_context( |
|||
{"mail_create_nolog": True, "mail_create_nosubscribe": True} |
|||
) |
|||
self.test_pigs = TestModel.create( |
|||
{ |
|||
"name": "Pigs", |
|||
"description": "Fans of Pigs, unite !", |
|||
"alias_name": "pigs", |
|||
"alias_contact": "followers", |
|||
} |
|||
) |
|||
|
|||
# sending without website |
|||
mail_id = self.email_template.send_mail(self.test_pigs.id) |
|||
mail = self.env["mail.mail"].browse(mail_id) |
|||
self.assertEqual(mail.subject, "") |
|||
self.assertFalse(mail.mail_server_id) |
|||
|
|||
# sending from frontend |
|||
self.test_pigs.company_id = None |
|||
mail_id = self.email_template.with_context( |
|||
wdb=True, allowed_website_ids=self.website.ids |
|||
).send_mail(self.test_pigs.id) |
|||
mail = self.env["mail.mail"].browse(mail_id) |
|||
self.assertEqual(mail.subject, self.website.name) |
|||
self.assertEqual(mail.mail_server_id, self.mail_server_id) |
|||
|
|||
# copy-pasted tests |
|||
self.assertEqual(mail.email_to, self.email_template.email_to) |
|||
# for some reason self.email_template.email_cc might return u'False' |
|||
self.assertEqual( |
|||
mail.email_cc or "False", self.email_template.email_cc or "False" |
|||
) |
|||
self.assertEqual( |
|||
mail.recipient_ids, self.partner_2 | self.user_employee.partner_id |
|||
) |
|||
|
|||
# sending from frontend |
|||
self.switch_user_website() |
|||
mail_id = self.email_template.send_mail(self.test_pigs.id) |
|||
mail = self.env["mail.mail"].browse(mail_id) |
|||
self.assertEqual(mail.subject, self.website.name) |
|||
|
|||
def _test_message_post_with_template(self): |
|||
# It's deactivated, because workaround is based on checking host value in get_current_website() |
|||
"""Simulate sending email on eCommerce checkout""" |
|||
self.switch_user_website() |
|||
self.env.user.email = self.email |
|||
self.env.user.invalidate_cache() |
|||
self.env.user.invalidate_cache() |
|||
self.assertEqual(self.env.user.email, self.email) |
|||
# switch admin user back |
|||
self.env.user.company_id = self.original_company |
|||
self.env.user.invalidate_cache() |
|||
self.assertEqual(self.env.user.email, self.original_email) |
|||
|
|||
self.test_pigs.with_context( |
|||
allowed_website_ids=self.website.ids |
|||
).message_post_with_template(self.email_template.id) |
|||
message = self.env["mail.message"].search([], order="id desc", limit=1) |
|||
self.assertIn("<%s>" % self.email, message.email_from) |
@ -0,0 +1,72 @@ |
|||
# Copyright 2018 Ivan Yelizariev <https://it-projects.info/team/yelizariev> |
|||
# License MIT (https://opensource.org/licenses/MIT). |
|||
from odoo.tests.common import TransactionCase |
|||
|
|||
|
|||
class TestSendMail(TransactionCase): |
|||
at_install = True |
|||
post_install = True |
|||
|
|||
def setUp(self): |
|||
super(TestSendMail, self).setUp() |
|||
self.website = self.env.ref("website.website2") |
|||
self.company = self.env["res.company"].create({"name": "New Test Website"}) |
|||
self.original_email = self.env.user.email |
|||
self.original_company = self.env.user.company_id |
|||
self.email = "superadmin@second-website.example" |
|||
# Check that current email is set and differs |
|||
self.assertTrue(self.email) |
|||
self.assertNotEqual(self.original_email, self.email) |
|||
self.website.company_id = self.company |
|||
|
|||
def switch_user_website(self): |
|||
# add website to allowed |
|||
self.env.user.write( |
|||
dict( |
|||
backend_website_ids=[(4, self.website.id)], |
|||
backend_website_id=self.website.id, |
|||
company_id=self.company.id, |
|||
company_ids=[(4, self.company.id)], |
|||
) |
|||
) |
|||
|
|||
def test_multi_email(self): |
|||
"""User has email addresses per website""" |
|||
self.switch_user_website() |
|||
# update user's email |
|||
self.env.user.email = self.email |
|||
# Check that writing works |
|||
self.env.user.flush() |
|||
self.env.user.invalidate_cache() |
|||
self.assertEqual( |
|||
self.env.user.email, |
|||
self.email, |
|||
"Write methods doesn't work (Field is not in registry?)", |
|||
) |
|||
|
|||
# changing company will automatically update website value to empty value |
|||
self.env.user.company_id = self.original_company |
|||
self.env.user.invalidate_cache() |
|||
self.assertEqual( |
|||
self.env.user.email, |
|||
self.original_email, |
|||
"Multi-email doesn't work on switching websites", |
|||
) |
|||
|
|||
def test_multi_email_partner(self): |
|||
"""Partner doesn't have email addresses per website""" |
|||
original_email = "original@email1" |
|||
new_email = "new@email2" |
|||
partner = self.env["res.partner"].create( |
|||
{"name": "test", "email": original_email} |
|||
) |
|||
self.switch_user_website() |
|||
# update partner's email |
|||
partner.email = new_email |
|||
self.assertEqual(partner.email, new_email) |
|||
# changing company will automatically update website value to empty value |
|||
self.env.user.company_id = self.original_company |
|||
self.env.user.invalidate_cache() |
|||
self.assertEqual( |
|||
partner.email, new_email, "Partner's email must not be Multi-website" |
|||
) |
@ -0,0 +1,14 @@ |
|||
<?xml version="1.0" encoding="utf-8" ?> |
|||
<!-- Copyright 2018 Ivan Yelizariev <https://it-projects.info/team/yelizariev> |
|||
License MIT (https://opensource.org/licenses/MIT). --> |
|||
<odoo> |
|||
<record id="view_website_multi_mail_form" model="ir.ui.view"> |
|||
<field name="model">website</field> |
|||
<field name="inherit_id" ref="website.view_website_form" /> |
|||
<field name="arch" type="xml"> |
|||
<xpath expr="//field[@name='default_lang_id']" position="after"> |
|||
<field name="mail_server_id" /> |
|||
</xpath> |
|||
</field> |
|||
</record> |
|||
</odoo> |
@ -0,0 +1,2 @@ |
|||
# License MIT (https://opensource.org/licenses/MIT). |
|||
from . import mail_compose_message |
@ -0,0 +1,22 @@ |
|||
# Copyright 2018 Ivan Yelizariev <https://it-projects.info/team/yelizariev> |
|||
# License MIT (https://opensource.org/licenses/MIT). |
|||
from odoo import api, models |
|||
from odoo.http import request |
|||
|
|||
|
|||
class MailComposer(models.TransientModel): |
|||
|
|||
_inherit = "mail.compose.message" |
|||
|
|||
@api.model |
|||
def create(self, vals): |
|||
"""Workaround for https://github.com/odoo/odoo/pull/26589""" |
|||
if "website_id" not in self.env.context: |
|||
website = ( |
|||
request and hasattr(request, "website") and request.website or None |
|||
) |
|||
if not website: |
|||
website = self.env["website"].get_current_website() |
|||
if website: |
|||
self = self.with_context(website_id=website.id) |
|||
return super(MailComposer, self).create(vals) |
Write
Preview
Loading…
Cancel
Save
Reference in new issue