diff --git a/mail_parent_recipient/__init__.py b/mail_parent_recipient/__init__.py new file mode 100644 index 0000000..cde864b --- /dev/null +++ b/mail_parent_recipient/__init__.py @@ -0,0 +1,3 @@ +# -*- coding: utf-8 -*- + +from . import models diff --git a/mail_parent_recipient/__manifest__.py b/mail_parent_recipient/__manifest__.py new file mode 100644 index 0000000..a54d14e --- /dev/null +++ b/mail_parent_recipient/__manifest__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2018 Camptocamp +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +{ + "name": "Mail parent recipient", + "description": "Send email to parent partner if partner's email is empty", + "category": "Mail", + "license": "AGPL-3", + "version": "10.0.1.0.0", + "website": "https://github.com/OCA/social", + "author": "Camptocamp, Odoo Community Association (OCA)", + "application": False, + "installable": True, + "depends": [ + 'mail', + ], + "data": ["views/res_config_views.xml"] +} diff --git a/mail_parent_recipient/models/__init__.py b/mail_parent_recipient/models/__init__.py new file mode 100644 index 0000000..caba35a --- /dev/null +++ b/mail_parent_recipient/models/__init__.py @@ -0,0 +1,5 @@ +# -*- coding: utf-8 -*- + +from . import company +from . import mail_template +from . import res_config diff --git a/mail_parent_recipient/models/company.py b/mail_parent_recipient/models/company.py new file mode 100644 index 0000000..bf5beb1 --- /dev/null +++ b/mail_parent_recipient/models/company.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Camptocamp SA +# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). + +from odoo import fields, models + + +class ResCompany(models.Model): + + _inherit = "res.company" + + use_parent_mail_address = fields.Boolean( + string="Use Parent Mail Address", + help="When an email is sent, fallback to partner's parent email if no " + "email is set on the recipient partner." + ) diff --git a/mail_parent_recipient/models/mail_template.py b/mail_parent_recipient/models/mail_template.py new file mode 100644 index 0000000..53f5fbc --- /dev/null +++ b/mail_parent_recipient/models/mail_template.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- +# Copyright 2018 Camptocamp +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +from odoo import models, api + + +class MailTemplate(models.Model): + + _inherit = 'mail.template' + + @api.multi + def generate_recipients(self, results, res_ids): + """Use partner's parent email as recipient. + + Walk up the hierarchy of recipient partners via `parent_id` + and pick the 1st one having an email. + """ + results = super(MailTemplate, self).generate_recipients( + results, + res_ids + ) + disabled = self.env.context.get('no_parent_mail_recipient') + if self.env.user.company_id.use_parent_mail_address and not disabled: + for res_id, values in results.iteritems(): + partner_ids = values.get('partner_ids', []) + partners_with_emails = [] + partners = self.env['res.partner'].sudo().browse(partner_ids) + for partner in partners: + if partner.email: + partners_with_emails.append(partner.id) + elif partner.commercial_partner_id.email: + partners_with_emails.append( + partner.commercial_partner_id.id + ) + # else: + # partner_with_emails.append(partner.id) + results[res_id]['partner_ids'] = partners_with_emails + return results diff --git a/mail_parent_recipient/models/res_config.py b/mail_parent_recipient/models/res_config.py new file mode 100644 index 0000000..2652603 --- /dev/null +++ b/mail_parent_recipient/models/res_config.py @@ -0,0 +1,17 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Camptocamp SA +# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). + +from odoo import fields, models + + +class BaseConfiguration(models.TransientModel): + _inherit = "base.config.settings" + + use_parent_mail_address = fields.Boolean( + related="company_id.use_parent_mail_address", + help=""" + When checked, for partner without eamil the system will try + to use the email address of the partner's parent. + """ + ) diff --git a/mail_parent_recipient/readme/CONTRIBUTORS.rst b/mail_parent_recipient/readme/CONTRIBUTORS.rst new file mode 100644 index 0000000..a7e80e7 --- /dev/null +++ b/mail_parent_recipient/readme/CONTRIBUTORS.rst @@ -0,0 +1,2 @@ +* Thomas Nowicki +* Thierry Ducrest diff --git a/mail_parent_recipient/readme/CREDITS.rst b/mail_parent_recipient/readme/CREDITS.rst new file mode 100644 index 0000000..f5cc070 --- /dev/null +++ b/mail_parent_recipient/readme/CREDITS.rst @@ -0,0 +1,3 @@ +The development of this module has been financially supported by: + +* Camptocamp diff --git a/mail_parent_recipient/readme/DESCRIPTION.rst b/mail_parent_recipient/readme/DESCRIPTION.rst new file mode 100644 index 0000000..27998df --- /dev/null +++ b/mail_parent_recipient/readme/DESCRIPTION.rst @@ -0,0 +1,2 @@ +This module modifies how Odoo get email recipients from partners. +Partner's closest parent email will be used as recipient if partner has no email address. diff --git a/mail_parent_recipient/tests/__init__.py b/mail_parent_recipient/tests/__init__.py new file mode 100644 index 0000000..8b3803c --- /dev/null +++ b/mail_parent_recipient/tests/__init__.py @@ -0,0 +1,3 @@ +# -*- coding: utf-8 -*- + +from . import test_mail_parent_recipient diff --git a/mail_parent_recipient/tests/test_mail_parent_recipient.py b/mail_parent_recipient/tests/test_mail_parent_recipient.py new file mode 100644 index 0000000..c2ea3dd --- /dev/null +++ b/mail_parent_recipient/tests/test_mail_parent_recipient.py @@ -0,0 +1,122 @@ +# -*- coding: utf-8 -*- +# Copyright 2018 Camptocamp +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo.addons.mail.tests.common import TestMail + + +class TestMailTemplate(TestMail): + + @classmethod + def setUpClass(cls): + super(TestMailTemplate, cls).setUpClass() + cls.env = cls.env(context=dict(cls.env.context, tracking_disable=True)) + + cls.Users = cls.env['res.users'] + cls.res_partner = cls.env['res.partner'] + cls.mail_template = cls.env['mail.template'] + cls.mail_comp_msg = cls.env['mail.compose.message'] + + cls.env.user.company_id.use_parent_mail_address = True + # Company + company_vals = { + 'name': 'company_name_test', + 'email': 'company.mail.test@company' + } + + cls.company_test = cls.res_partner.create(company_vals) + + # Partners test 1 without email + partner_no_mail_vals = { + 'name': 'partner_1', + 'parent_id': cls.company_test.id, + } + + # Partners test 2 with email + partner_with_mail_vals = { + 'name': 'partner_2', + 'email': 'partner.2.mail.test@company', + 'parent_id': cls.company_test.id, + } + + cls.partner_no_mail = cls.res_partner.create(partner_no_mail_vals) + cls.partner_with_mail = cls.res_partner.create( + partner_with_mail_vals + ) + + def create_mail_composer(self, partner_to_send_ids): + email_template = self.env[ + 'mail.template' + ].with_context(test_parent_mail_recipient=True).create({ + 'model_id': self.env['ir.model'].search([ + ('model', '=', 'mail.channel') + ], limit=1).id, + 'name': 'Pigs Template', + 'subject': '${object.name}', + 'body_html': '${object.description}', + 'user_signature': False, + 'partner_to': ",".join(partner_to_send_ids), + }) + + composer = self.mail_comp_msg.with_context({ + 'test_parent_mail_recipient': True, + 'default_composition_mode': 'comment', + 'default_model': 'mail.channel', + 'default_use_template': True, + }).create({ + 'subject': 'Forget me subject', + 'body': 'Dummy body', + 'template_id': email_template.id + }) + values = composer.onchange_template_id( + email_template.id, + 'comment', 'mail.channel', self.group_pigs.id + )['value'] + + # use _convert_to_cache to return a browse record list from command + # list or id list for x2many fields + values = composer._convert_to_record( + composer._convert_to_cache(values) + ) + recipients = values['partner_ids'] + + return recipients + + def test_1_mail_send_to_partner_no_mail(self): + """Use company mail if recipient partner has no email.""" + recipients = self.create_mail_composer([str(self.partner_no_mail.id)]) + + self.assertEqual(recipients.email, self.company_test.email) + self.assertNotEqual(recipients.email, self.partner_no_mail.email) + self.assertNotEqual(recipients.email, self.partner_with_mail.email) + + def test_2_mail_send_to_partner_with_mail(self): + """Use partner mail if recipient partner has an email.""" + recipients = self.create_mail_composer( + [str(self.partner_with_mail.id)] + ) + + self.assertNotEqual(recipients.email, self.company_test.email) + self.assertNotEqual(recipients.email, self.partner_no_mail.email) + self.assertEqual(recipients.email, self.partner_with_mail.email) + + def test_3_mail_send_to_company_test(self): + """Use company mail if recipient is the company.""" + recipients = self.create_mail_composer([str(self.company_test.id)]) + + self.assertEqual(recipients.email, self.company_test.email) + self.assertNotEqual(recipients.email, self.partner_no_mail.email) + self.assertNotEqual(recipients.email, self.partner_with_mail.email) + + def test_4_mail_send_to_company_and_partner_no_mail(self): + """ Use only one time company mail if recipient is the company + and partner without mail. + """ + recipients = self.create_mail_composer([ + str(self.partner_no_mail.id), + str(self.company_test.id) + ]) + + self.assertEqual(recipients.email, self.company_test.email) + self.assertNotEqual(recipients.email, self.partner_no_mail.email) + self.assertNotEqual(recipients.email, self.partner_with_mail.email) diff --git a/mail_parent_recipient/views/res_config_views.xml b/mail_parent_recipient/views/res_config_views.xml new file mode 100644 index 0000000..ab683d6 --- /dev/null +++ b/mail_parent_recipient/views/res_config_views.xml @@ -0,0 +1,18 @@ + + + + + mail.parent.recipient.config.settings + base.config.settings + + + +
+ +
+
+
+
+
+
diff --git a/setup/mail_parent_recipient/odoo/__init__.py b/setup/mail_parent_recipient/odoo/__init__.py new file mode 100644 index 0000000..de40ea7 --- /dev/null +++ b/setup/mail_parent_recipient/odoo/__init__.py @@ -0,0 +1 @@ +__import__('pkg_resources').declare_namespace(__name__) diff --git a/setup/mail_parent_recipient/odoo/addons/__init__.py b/setup/mail_parent_recipient/odoo/addons/__init__.py new file mode 100644 index 0000000..de40ea7 --- /dev/null +++ b/setup/mail_parent_recipient/odoo/addons/__init__.py @@ -0,0 +1 @@ +__import__('pkg_resources').declare_namespace(__name__) diff --git a/setup/mail_parent_recipient/odoo/addons/mail_parent_recipient b/setup/mail_parent_recipient/odoo/addons/mail_parent_recipient new file mode 120000 index 0000000..c191ea2 --- /dev/null +++ b/setup/mail_parent_recipient/odoo/addons/mail_parent_recipient @@ -0,0 +1 @@ +../../../../mail_parent_recipient \ No newline at end of file diff --git a/setup/mail_parent_recipient/setup.py b/setup/mail_parent_recipient/setup.py new file mode 100644 index 0000000..28c57bb --- /dev/null +++ b/setup/mail_parent_recipient/setup.py @@ -0,0 +1,6 @@ +import setuptools + +setuptools.setup( + setup_requires=['setuptools-odoo'], + odoo_addon=True, +)