diff --git a/mail_company_aware_sender/README.rst b/mail_company_aware_sender/README.rst new file mode 100644 index 0000000000..910b0bf1fa --- /dev/null +++ b/mail_company_aware_sender/README.rst @@ -0,0 +1,113 @@ +========================= +Mail Sender Company Aware +========================= + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:7ee2897c3172b5b4d4927dbf7ec1e94e1c71bc5602f7bdf85b3ac0cae33481d0 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |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/14.0/mail_company_aware_sender + :alt: OCA/social +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/social-14-0/social-14-0-mail_company_aware_sender + :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/social&target_branch=14.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +This module allows to send out mails using a company aware email address. +Suppose we have a user Charles the Magnificent with email address +charlemagne@kingdom.fr. However this user works for two companies, one +for the kingdom of France, with email address info@kingdom.fr, and +one for the Roman Empire with email address chancellery@imperiumromanum.org. + +Now when sending out mail, we want to make clear from what active company the +mail is sent, but also want to keep the name of the active user in the +email from address, so when sending from the kingdom, the email from will +be charlemagne@kingdom.fr, but when sending from the empire, the email will +be charlemagne@imperiumromanum.org. + +Note that after installing this module the system parameter mail.default.from +will no longer be used to set the from address. + +This module can also be used to send company aware emails from templates. +For instance with this formula for the email_from field: +{{ user.get_company_aware_email(object) }} +In this example the company defined in the object will be used instead of the current +company. + +**Table of contents** + +.. contents:: + :local: + +Configuration +============= + +To send out mails with company aware from addresses, three things are needed: + * The company partner needs to have an email address; + * The company must be enabled for it's domain being used in from addresses; + * The company email domain must be defined on a domain whitelist in one + or more of the outgoing mail servers. + +On the company you can also set whether email from should include the name +of the sender or not. This will only affect emails that are modified to use +the company address. + +For particular users/partners there can be an opt-out for using company aware +emails. This can be configured right under the email field in the partner form. + +Bug Tracker +=========== + +Bugs are tracked on `GitHub 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 `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +~~~~~~~ + +* Therp BV + +Contributors +~~~~~~~~~~~~ + +* `Therp BV `_: + + * Ronald Portier (NL66278) + +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/social `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/mail_company_aware_sender/__init__.py b/mail_company_aware_sender/__init__.py new file mode 100644 index 0000000000..83e553ac46 --- /dev/null +++ b/mail_company_aware_sender/__init__.py @@ -0,0 +1,3 @@ +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from . import models diff --git a/mail_company_aware_sender/__manifest__.py b/mail_company_aware_sender/__manifest__.py new file mode 100644 index 0000000000..62880cd88d --- /dev/null +++ b/mail_company_aware_sender/__manifest__.py @@ -0,0 +1,22 @@ +# Copyright 2025 Therp BV . +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +{ + "name": "Mail Sender Company Aware", + "summary": "Send emails with company specific mail domain", + "version": "14.0.1.0.0", + "category": "Social Network", + "website": "https://github.com/OCA/social", + "author": ("Therp BV, " "Odoo Community Association (OCA)"), + "license": "AGPL-3", + "application": False, + "installable": True, + "depends": [ + "mail", + "mail_outbound_static", # Need the domain whitelist on outgoing server. + ], + "data": [ + "views/res_company_view.xml", + "views/res_partner_view.xml", + ], +} diff --git a/mail_company_aware_sender/models/__init__.py b/mail_company_aware_sender/models/__init__.py new file mode 100644 index 0000000000..732f504cd2 --- /dev/null +++ b/mail_company_aware_sender/models/__init__.py @@ -0,0 +1,7 @@ +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from . import ir_mail_server +from . import mail_thread +from . import res_company +from . import res_partner +from . import res_users diff --git a/mail_company_aware_sender/models/ir_mail_server.py b/mail_company_aware_sender/models/ir_mail_server.py new file mode 100644 index 0000000000..3116f91199 --- /dev/null +++ b/mail_company_aware_sender/models/ir_mail_server.py @@ -0,0 +1,50 @@ +# Copyright 2025 Therp BV . +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from odoo import _, api, models +from odoo.exceptions import ValidationError +from odoo.tools import email_domain_extract + + +class IrMailServer(models.Model): + + _inherit = "ir.mail_server" + + @api.model + def _is_domain_whitelisted(self, domain): + """Check whether domain has been whitelisted for sending.""" + whitelist_servers = self.search([]).filtered("domain_whitelist") + for server in whitelist_servers: + if domain in self._get_domain_whitelist(server.domain_whitelist): + return True + return False + + def _get_test_email_addresses(self): + self.ensure_one() + email_to = "noreply@odoo.com" + # if server forces a sender, use it. + if self.smtp_from: + return self.smtp_from, email_to + if not self.env.user.email: + return super()._get_test_email_addresses() + email_from = self.env.user.company_aware_email() + email_domain = email_domain_extract(email_from) + valid_domains = self._get_domain_whitelist(self.domain_whitelist) + if email_domain not in valid_domains: + raise ValidationError( + _("Domain %s not whitelisted on this server") % email_domain + ) + return email_from, email_to + + def build_email(self, *args, **kwargs): + """Provide a valid return address when using company aware From.""" + if self.env.company.use_email_domain and self.env.company.reply_to: + kwargs["reply_to"] = self.env.company.reply_to + return super().build_email(*args, **kwargs) + + @api.model + def _get_default_from_address(self): + """Prevent overwrite of email_from if not desired for company.""" + if self.env.company.use_email_domain: + return None + return super()._get_default_from_address() diff --git a/mail_company_aware_sender/models/mail_thread.py b/mail_company_aware_sender/models/mail_thread.py new file mode 100644 index 0000000000..412a6642a9 --- /dev/null +++ b/mail_company_aware_sender/models/mail_thread.py @@ -0,0 +1,24 @@ +# Copyright 2025 Therp BV . +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +from odoo import models + + +class MailThread(models.AbstractModel): + _inherit = "mail.thread" + + def _message_compute_author(self, author_id, email_from, raise_exception=True): + """Set email from using company email domain. + + We will NOT override an explicitly passed email_from. + + Check for current company to see whether we should try to override + the email_from domain. + """ + email_passed = bool(email_from) + author_id, email_from = super()._message_compute_author( + author_id, email_from, raise_exception=raise_exception + ) + if (not email_passed) and author_id: + author = self.env["res.partner"].browse(author_id) + email_from = author.company_aware_email(default_email=email_from) + return author_id, email_from diff --git a/mail_company_aware_sender/models/res_company.py b/mail_company_aware_sender/models/res_company.py new file mode 100644 index 0000000000..c218fefd8b --- /dev/null +++ b/mail_company_aware_sender/models/res_company.py @@ -0,0 +1,29 @@ +# Copyright 2025 Therp BV . +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from odoo import fields, models +from odoo.tools import email_domain_extract + + +class ResCompany(models.Model): + _inherit = "res.company" + + use_email_domain = fields.Boolean( + help="Use domain part of company for sender email address", + ) + format_email = fields.Boolean( + default=True, # As this is what Odoo standard does. + help='Format email_from with name "John Smith" ' + " or use plain email address", + ) + reply_to = fields.Char( + help="reply_to address to use, if not filled, fallback to mail.default.from", + ) + + def _override_email_domain(self): + """Check whether company email domain can and should be used.""" + self.ensure_one() + if not (self.use_email_domain and self.email): + return False + email_domain = email_domain_extract(self.email) + return self.env["ir.mail_server"].sudo()._is_domain_whitelisted(email_domain) diff --git a/mail_company_aware_sender/models/res_partner.py b/mail_company_aware_sender/models/res_partner.py new file mode 100644 index 0000000000..ab32bbb85a --- /dev/null +++ b/mail_company_aware_sender/models/res_partner.py @@ -0,0 +1,28 @@ +# Copyright 2025 Therp BV . +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from odoo import fields, models +from odoo.tools import formataddr + + +class ResPartner(models.Model): + _inherit = "res.partner" + + fixed_email = fields.Boolean( + help="Email for partner will not be influenced by company", + ) + + def company_aware_email(self, company=None, default_email=None): + """Set email using company email domain if configured.""" + self.ensure_one() + result_email = default_email or self.email + if not self.fixed_email: + company = company or self.env.company + if company._override_email_domain(): + before_at = self.email.split("@")[0] + after_at = company.email.split("@")[1] + result_email = f"{before_at}@{after_at}" + if company.format_email: + # formataddr wants a tuple with name (or False) and email. + result_email = formataddr((self.name, result_email)) + return result_email diff --git a/mail_company_aware_sender/models/res_users.py b/mail_company_aware_sender/models/res_users.py new file mode 100644 index 0000000000..79ca559225 --- /dev/null +++ b/mail_company_aware_sender/models/res_users.py @@ -0,0 +1,28 @@ +# Copyright 2025 Therp BV . +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from odoo import models + + +class ResUsers(models.Model): + _inherit = "res.users" + + def company_aware_email(self, company=None, default_email=None): + """Set email using company email domain if configured.""" + self.ensure_one() + return self.partner_id.company_aware_email( + company=company, default_email=default_email + ) + + def get_company_aware_email(self, record): + """Get company aware email_from related to Odoo record. + + Can be used on email_from field of template like so: + {{ user.get_company_aware_email(object) }} + """ + record.ensure_one() # Must be recordlist with exactly one member. + user = record.user_id if "user_id" in record._fields else self.env.user + company = ( + record.company_id if "company_id" in record._fields else self.env.company + ) + return user.company_aware_email(company=company) diff --git a/mail_company_aware_sender/readme/CONFIGURE.rst b/mail_company_aware_sender/readme/CONFIGURE.rst new file mode 100644 index 0000000000..dbd3243d0c --- /dev/null +++ b/mail_company_aware_sender/readme/CONFIGURE.rst @@ -0,0 +1,12 @@ +To send out mails with company aware from addresses, three things are needed: + * The company partner needs to have an email address; + * The company must be enabled for it's domain being used in from addresses; + * The company email domain must be defined on a domain whitelist in one + or more of the outgoing mail servers. + +On the company you can also set whether email from should include the name +of the sender or not. This will only affect emails that are modified to use +the company address. + +For particular users/partners there can be an opt-out for using company aware +emails. This can be configured right under the email field in the partner form. diff --git a/mail_company_aware_sender/readme/CONTRIBUTORS.rst b/mail_company_aware_sender/readme/CONTRIBUTORS.rst new file mode 100644 index 0000000000..a5e152b71a --- /dev/null +++ b/mail_company_aware_sender/readme/CONTRIBUTORS.rst @@ -0,0 +1,3 @@ +* `Therp BV `_: + + * Ronald Portier (NL66278) diff --git a/mail_company_aware_sender/readme/DESCRIPTION.rst b/mail_company_aware_sender/readme/DESCRIPTION.rst new file mode 100644 index 0000000000..d7067a1348 --- /dev/null +++ b/mail_company_aware_sender/readme/DESCRIPTION.rst @@ -0,0 +1,20 @@ +This module allows to send out mails using a company aware email address. +Suppose we have a user Charles the Magnificent with email address +charlemagne@kingdom.fr. However this user works for two companies, one +for the kingdom of France, with email address info@kingdom.fr, and +one for the Roman Empire with email address chancellery@imperiumromanum.org. + +Now when sending out mail, we want to make clear from what active company the +mail is sent, but also want to keep the name of the active user in the +email from address, so when sending from the kingdom, the email from will +be charlemagne@kingdom.fr, but when sending from the empire, the email will +be charlemagne@imperiumromanum.org. + +Note that after installing this module the system parameter mail.default.from +will no longer be used to set the from address. + +This module can also be used to send company aware emails from templates. +For instance with this formula for the email_from field: +{{ user.get_company_aware_email(object) }} +In this example the company defined in the object will be used instead of the current +company. diff --git a/mail_company_aware_sender/static/description/icon.png b/mail_company_aware_sender/static/description/icon.png new file mode 100644 index 0000000000..c1af495578 Binary files /dev/null and b/mail_company_aware_sender/static/description/icon.png differ diff --git a/mail_company_aware_sender/static/description/index.html b/mail_company_aware_sender/static/description/index.html new file mode 100644 index 0000000000..07139d0bad --- /dev/null +++ b/mail_company_aware_sender/static/description/index.html @@ -0,0 +1,461 @@ + + + + + +Mail Sender Company Aware + + + +
+

Mail Sender Company Aware

+ + +

Beta License: AGPL-3 OCA/social Translate me on Weblate Try me on Runboat

+

This module allows to send out mails using a company aware email address. +Suppose we have a user Charles the Magnificent with email address +charlemagne@kingdom.fr. However this user works for two companies, one +for the kingdom of France, with email address info@kingdom.fr, and +one for the Roman Empire with email address chancellery@imperiumromanum.org.

+

Now when sending out mail, we want to make clear from what active company the +mail is sent, but also want to keep the name of the active user in the +email from address, so when sending from the kingdom, the email from will +be charlemagne@kingdom.fr, but when sending from the empire, the email will +be charlemagne@imperiumromanum.org.

+

Note that after installing this module the system parameter mail.default.from +will no longer be used to set the from address.

+

This module can also be used to send company aware emails from templates. +For instance with this formula for the email_from field: +{{ user.get_company_aware_email(object) }} +In this example the company defined in the object will be used instead of the current +company.

+

Table of contents

+ +
+

Configuration

+
+
To send out mails with company aware from addresses, three things are needed:
+
    +
  • The company partner needs to have an email address;
  • +
  • The company must be enabled for it’s domain being used in from addresses;
  • +
  • The company email domain must be defined on a domain whitelist in one +or more of the outgoing mail servers.
  • +
+
+
+

On the company you can also set whether email from should include the name +of the sender or not. This will only affect emails that are modified to use +the company address.

+

For particular users/partners there can be an opt-out for using company aware +emails. This can be configured right under the email field in the partner form.

+
+
+

Bug Tracker

+

Bugs are tracked on GitHub 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.

+

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

+
+
+

Credits

+
+

Authors

+
    +
  • Therp BV
  • +
+
+
+

Contributors

+
    +
  • Therp BV:
      +
    • Ronald Portier (NL66278)
    • +
    +
  • +
+
+
+

Maintainers

+

This module is maintained by the OCA.

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

+

This module is part of the OCA/social project on GitHub.

+

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

+
+
+
+ + diff --git a/mail_company_aware_sender/tests/__init__.py b/mail_company_aware_sender/tests/__init__.py new file mode 100644 index 0000000000..e64f5c2944 --- /dev/null +++ b/mail_company_aware_sender/tests/__init__.py @@ -0,0 +1,4 @@ +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from . import test_company_aware_sender +from . import test_mail_server diff --git a/mail_company_aware_sender/tests/common.py b/mail_company_aware_sender/tests/common.py new file mode 100644 index 0000000000..1754f4200a --- /dev/null +++ b/mail_company_aware_sender/tests/common.py @@ -0,0 +1,60 @@ +# Copyright 2025 Therp BV . +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +from odoo.tests.common import SavepointCase + + +class CompanyAwareSenderCase(SavepointCase): + @classmethod + def setUpClass(cls): + super().setUpClass() + # Create two companies and a partner/user. + cls.Company = cls.env["res.company"] + cls.Partner = cls.env["res.partner"] + cls.User = cls.env["res.users"] + cls.IrMailServer = cls.env["ir.mail_server"] + cls.mail_server = cls.IrMailServer.create( + { + "name": "localhost", + "smtp_host": "localhost", + "domain_whitelist": "therp.nl", + } + ) + cls.company_kingdom = cls.Company.create( + { + "name": "The kingdom of France", + "email": "info@kingdom.fr", + } + ) + cls.company_imperium = cls.Company.create( + { + "name": "Imperium Romanum", + "email": "chancellery@imperiumromanum.org", + "use_email_domain": True, + "format_email": False, + } + ) + cls.partner_charles = cls.Partner.create( + { + "name": "Charles Le Magne", + "email": "charlemagne@therp.nl", + } + ) + cls.user_charles = cls.User.with_context(no_reset_password=True).create( + { + "partner_id": cls.partner_charles.id, + "login": "charlemagne", + "email": "charlemagne@therp.nl", + "company_id": cls.company_kingdom.id, + "company_ids": [ + (6, 0, [cls.company_kingdom.id, cls.company_imperium.id]), + ], + } + ) + cls.partner_himiltrude = cls.Partner.create( + { + "name": "Himiltrude", + "email": "himiltrude@therp.nl", + "user_id": cls.user_charles.id, + "company_id": cls.company_imperium.id, + } + ) diff --git a/mail_company_aware_sender/tests/test_company_aware_sender.py b/mail_company_aware_sender/tests/test_company_aware_sender.py new file mode 100644 index 0000000000..060982c9b6 --- /dev/null +++ b/mail_company_aware_sender/tests/test_company_aware_sender.py @@ -0,0 +1,72 @@ +# Copyright 2025 Therp BV . +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +from email.utils import parseaddr + +from .common import CompanyAwareSenderCase + + +class TestCompanyAwareSender(CompanyAwareSenderCase): + def _assert_email(self, email_from, expected_email, expected_name=None): + """Assert email_from matches expected parts, tolerant to quoting differences.""" + name, email = parseaddr(email_from or "") + self.assertEqual(email, expected_email) + if expected_name is not None: + self.assertEqual(name, expected_name) + + def test_nothing_changed(self): + # Check with default user and author (current user). + mail_thread = ( + self.env["mail.thread"] + .with_user(self.user_charles) + .with_company(self.company_kingdom) + ) + author_id, email_from = mail_thread._message_compute_author(None, None) + self.assertEqual(author_id, self.partner_charles.id) + self._assert_email(email_from, "charlemagne@therp.nl", "Charles Le Magne") + author_id, email_from = mail_thread._message_compute_author( + None, '"Unknown Person" ' + ) + self.assertEqual(author_id, False) + self._assert_email(email_from, "unknown.person@example.com", "Unknown Person") + + def test_company_overwrite(self): + # Check with default user and author (current user). + mail_thread = ( + self.env["mail.thread"] + .with_user(self.user_charles) + .with_company(self.company_imperium) + ) + # Should not work if domain not whitelisted. + author_id, email_from = mail_thread._message_compute_author(None, None) + self.assertEqual(author_id, self.partner_charles.id) + self._assert_email(email_from, "charlemagne@therp.nl", "Charles Le Magne") + # Whitelist domain. + self.mail_server.write( + {"domain_whitelist": "therp.nl,kingdom.fr,imperiumromanum.org"} + ) + author_id, email_from = mail_thread._message_compute_author(None, None) + self.assertEqual(author_id, self.partner_charles.id) + self._assert_email(email_from, "charlemagne@imperiumromanum.org") + self.company_imperium.write({"format_email": True}) + author_id, email_from = mail_thread._message_compute_author(None, None) + self.assertEqual(author_id, self.partner_charles.id) + self._assert_email( + email_from, "charlemagne@imperiumromanum.org", "Charles Le Magne" + ) + # Now opt out for the override. + self.partner_charles.write({"fixed_email": True}) + author_id, email_from = mail_thread._message_compute_author(None, None) + self.assertEqual(author_id, self.partner_charles.id) + self._assert_email(email_from, "charlemagne@therp.nl", "Charles Le Magne") + + def test_get_sender_from_object(self): + # Whitelist domain. + self.mail_server.write( + {"domain_whitelist": "therp.nl,kingdom.fr,imperiumromanum.org"} + ) + # Check with default user and author (current user). + main_company = self.env.ref("base.main_company") + himiltrude = self.partner_himiltrude.sudo().with_company(main_company) + # Make sure user and company from object used. + email_from = self.env.user.sudo().get_company_aware_email(himiltrude) + self._assert_email(email_from, "charlemagne@imperiumromanum.org") diff --git a/mail_company_aware_sender/tests/test_mail_server.py b/mail_company_aware_sender/tests/test_mail_server.py new file mode 100644 index 0000000000..bfe21d2abd --- /dev/null +++ b/mail_company_aware_sender/tests/test_mail_server.py @@ -0,0 +1,56 @@ +# Copyright 2025 Therp BV . +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +from email.utils import parseaddr + +from odoo.exceptions import ValidationError + +from .common import CompanyAwareSenderCase + + +class TestMailServer(CompanyAwareSenderCase): + def _assert_email(self, email_from, expected_email, expected_name=None): + """Assert email_from matches expected parts, tolerant to quoting differences.""" + name, email = parseaddr(email_from or "") + self.assertEqual(email, expected_email) + if expected_name is not None: + self.assertEqual(name, expected_name) + + def test_test_email_adresses(self): + # Whitelist domain, and enable from address. + self.mail_server.write( + { + "smtp_from": "info@therp.nl", + "domain_whitelist": "therp.nl,kingdom.fr,imperiumromanum.org", + } + ) + email_from, email_to = self.mail_server._get_test_email_addresses() + self.assertEqual(email_from, "info@therp.nl") + self.assertEqual(email_to, "noreply@odoo.com") + # Disable smtp_from and remove therp.nl from whitelist. + self.mail_server.write( + { + "smtp_from": "info@therp.nl", + "domain_whitelist": "kingdom.fr,imperiumromanum.org", + } + ) + self.mail_server.write({"smtp_from": False}) + # Partner charles in imperium should use company aware from. + email_from, email_to = ( + self.mail_server.with_user(self.user_charles) + .with_company(self.company_imperium) + ._get_test_email_addresses() + ) + self._assert_email(email_from, "charlemagne@imperiumromanum.org") + self.assertEqual(email_to, "noreply@odoo.com") + # There should be an exception when using an invalid email domain. + self.company_imperium.write({"email": "court@aachen.de"}) + with self.assertRaises(ValidationError): + self.mail_server.with_user(self.user_charles).with_company( + self.company_imperium + )._get_test_email_addresses() + + def test_disable_encapsulation(self): + email_from = self.mail_server.with_company( + self.company_imperium + )._get_default_from_address() + self.assertEqual(email_from, None) diff --git a/mail_company_aware_sender/views/res_company_view.xml b/mail_company_aware_sender/views/res_company_view.xml new file mode 100644 index 0000000000..2901f8edfd --- /dev/null +++ b/mail_company_aware_sender/views/res_company_view.xml @@ -0,0 +1,26 @@ + + + + + res.company.form - mail_sender_company_aware + res.company + + + + + + + + + + + diff --git a/mail_company_aware_sender/views/res_partner_view.xml b/mail_company_aware_sender/views/res_partner_view.xml new file mode 100644 index 0000000000..5e51a4c776 --- /dev/null +++ b/mail_company_aware_sender/views/res_partner_view.xml @@ -0,0 +1,18 @@ + + + + + res.partner.form - mail_sender_company_aware + res.partner + + + + + + + + + diff --git a/setup/mail_company_aware_sender/odoo/addons/mail_company_aware_sender b/setup/mail_company_aware_sender/odoo/addons/mail_company_aware_sender new file mode 120000 index 0000000000..8d9bd4635a --- /dev/null +++ b/setup/mail_company_aware_sender/odoo/addons/mail_company_aware_sender @@ -0,0 +1 @@ +../../../../mail_company_aware_sender \ No newline at end of file diff --git a/setup/mail_company_aware_sender/setup.py b/setup/mail_company_aware_sender/setup.py new file mode 100644 index 0000000000..28c57bb640 --- /dev/null +++ b/setup/mail_company_aware_sender/setup.py @@ -0,0 +1,6 @@ +import setuptools + +setuptools.setup( + setup_requires=['setuptools-odoo'], + odoo_addon=True, +)