diff --git a/mass_mailing_multi_company/README.rst b/mass_mailing_multi_company/README.rst new file mode 100644 index 00000000000..a8a511a879b --- /dev/null +++ b/mass_mailing_multi_company/README.rst @@ -0,0 +1,87 @@ +.. image:: https://odoo-community.org/readme-banner-image + :target: https://odoo-community.org/get-involved?utm_source=readme + :alt: Odoo Community Association + +========================== +Mass Mailing Multi Company +========================== + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:9d9ebcf1a8ccd3054acfa7495237bcc835a033659e9cd196c37c42ad1b024888 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png + :target: https://odoo-community.org/page/development-status + :alt: Beta +.. |badge2| image:: https://img.shields.io/badge/license-AGPL--3-blue.png + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 +.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fmulti--company-lightgray.png?logo=github + :target: https://github.com/OCA/multi-company/tree/19.0/mass_mailing_multi_company + :alt: OCA/multi-company +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/multi-company-19-0/multi-company-19-0-mass_mailing_multi_company + :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/multi-company&target_branch=19.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +This module adds the company_id field to the models mailing.mailing, +mailing.list, mailing.contact and mailing.contact.subscription. It also +ensures that the lists available for selection in the mailing.mailing +and mailing.contact forms are restricted by the company_id value. For +the mailing.mailing domain, an expression matching only contacts/mailing +contacts with the same company or without company is added when parsing +the domain. + +**Table of contents** + +.. contents:: + :local: + +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 +------- + +* ForgeFlow S.L. + +Contributors +------------ + +- Marina Alapont +- Jasmin Solanki + +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/multi-company `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/mass_mailing_multi_company/__init__.py b/mass_mailing_multi_company/__init__.py new file mode 100644 index 00000000000..0650744f6bc --- /dev/null +++ b/mass_mailing_multi_company/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/mass_mailing_multi_company/__manifest__.py b/mass_mailing_multi_company/__manifest__.py new file mode 100644 index 00000000000..ac911435f13 --- /dev/null +++ b/mass_mailing_multi_company/__manifest__.py @@ -0,0 +1,19 @@ +# Copyright 2024 ForgeFlow S.L. +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +{ + "name": "Mass Mailing Multi Company", + "summary": "Adds the company_id field to the models mailing.mailing," + " mailing.list and mailing.contact", + "version": "19.0.1.0.0", + "license": "AGPL-3", + "author": "ForgeFlow S.L., Odoo Community Association (OCA)", + "website": "https://github.com/OCA/multi-company", + "depends": ["mass_mailing"], + "data": [ + "security/mass_mailing.xml", + "views/mailing_mailing_views.xml", + "views/mailing_list_views.xml", + "views/mailing_contact_views.xml", + ], +} diff --git a/mass_mailing_multi_company/i18n/it.po b/mass_mailing_multi_company/i18n/it.po new file mode 100644 index 00000000000..d7404571665 --- /dev/null +++ b/mass_mailing_multi_company/i18n/it.po @@ -0,0 +1,60 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * mass_mailing_multi_company +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2025-03-20 13:06+0000\n" +"Last-Translator: mymage \n" +"Language-Team: none\n" +"Language: it\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 5.10.2\n" + +#. module: mass_mailing_multi_company +#: model:ir.model.fields,field_description:mass_mailing_multi_company.field_mailing_contact__company_id +#: model:ir.model.fields,field_description:mass_mailing_multi_company.field_mailing_contact_subscription__company_id +#: model:ir.model.fields,field_description:mass_mailing_multi_company.field_mailing_list__company_id +#: model:ir.model.fields,field_description:mass_mailing_multi_company.field_mailing_mailing__company_id +msgid "Company" +msgstr "Azienda" + +#. module: mass_mailing_multi_company +#: model_terms:ir.ui.view,arch_db:mass_mailing_multi_company.view_mail_mass_mailing_form_inherit +msgid "MISC" +msgstr "VARIE" + +#. module: mass_mailing_multi_company +#: model:ir.model,name:mass_mailing_multi_company.model_mailing_contact +msgid "Mailing Contact" +msgstr "Contatto spedizione" + +#. module: mass_mailing_multi_company +#: model:ir.model,name:mass_mailing_multi_company.model_mailing_list +msgid "Mailing List" +msgstr "Mailing list" + +#. module: mass_mailing_multi_company +#: model:ir.model,name:mass_mailing_multi_company.model_mailing_mailing +msgid "Mass Mailing" +msgstr "Spedizione di massa" + +#. module: mass_mailing_multi_company +#: model:ir.model,name:mass_mailing_multi_company.model_mailing_contact_subscription +msgid "Mass Mailing Subscription Information" +msgstr "Informazione iscrizione spedizioni di massa" + +#. module: mass_mailing_multi_company +#: model_terms:ir.ui.view,arch_db:mass_mailing_multi_company.view_mail_mass_mailing_form_inherit +msgid "" +"Since the newsletter company field is specified, an additional filter will " +"be applied to the domain, ensuring records are filtered by the company ID." +msgstr "" +"Poiché è specificato il campo aziendale della newsletter, al dominio verrà " +"applicato un filtro aggiuntivo, assicurando che i record vengano filtrati in " +"base all'ID aziendale." diff --git a/mass_mailing_multi_company/i18n/mass_mailing_multi_company.pot b/mass_mailing_multi_company/i18n/mass_mailing_multi_company.pot new file mode 100644 index 00000000000..e7e10720615 --- /dev/null +++ b/mass_mailing_multi_company/i18n/mass_mailing_multi_company.pot @@ -0,0 +1,54 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * mass_mailing_multi_company +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.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: mass_mailing_multi_company +#: model:ir.model.fields,field_description:mass_mailing_multi_company.field_mailing_contact__company_id +#: model:ir.model.fields,field_description:mass_mailing_multi_company.field_mailing_contact_subscription__company_id +#: model:ir.model.fields,field_description:mass_mailing_multi_company.field_mailing_list__company_id +#: model:ir.model.fields,field_description:mass_mailing_multi_company.field_mailing_mailing__company_id +msgid "Company" +msgstr "" + +#. module: mass_mailing_multi_company +#: model_terms:ir.ui.view,arch_db:mass_mailing_multi_company.view_mail_mass_mailing_form_inherit +msgid "MISC" +msgstr "" + +#. module: mass_mailing_multi_company +#: model:ir.model,name:mass_mailing_multi_company.model_mailing_contact +msgid "Mailing Contact" +msgstr "" + +#. module: mass_mailing_multi_company +#: model:ir.model,name:mass_mailing_multi_company.model_mailing_list +msgid "Mailing List" +msgstr "" + +#. module: mass_mailing_multi_company +#: model:ir.model,name:mass_mailing_multi_company.model_mailing_mailing +msgid "Mass Mailing" +msgstr "" + +#. module: mass_mailing_multi_company +#: model:ir.model,name:mass_mailing_multi_company.model_mailing_contact_subscription +msgid "Mass Mailing Subscription Information" +msgstr "" + +#. module: mass_mailing_multi_company +#: model_terms:ir.ui.view,arch_db:mass_mailing_multi_company.view_mail_mass_mailing_form_inherit +msgid "" +"Since the newsletter company field is specified, an additional filter will " +"be applied to the domain, ensuring records are filtered by the company ID." +msgstr "" diff --git a/mass_mailing_multi_company/models/__init__.py b/mass_mailing_multi_company/models/__init__.py new file mode 100644 index 00000000000..c84a1464a25 --- /dev/null +++ b/mass_mailing_multi_company/models/__init__.py @@ -0,0 +1,4 @@ +from . import mailing_contact +from . import mailing_mailing +from . import mailing_list +from . import mailing_subscription diff --git a/mass_mailing_multi_company/models/mailing_contact.py b/mass_mailing_multi_company/models/mailing_contact.py new file mode 100644 index 00000000000..465ab84a30a --- /dev/null +++ b/mass_mailing_multi_company/models/mailing_contact.py @@ -0,0 +1,11 @@ +# Copyright 2024 ForgeFlow S.L. +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + + +from odoo import fields, models + + +class MassMailingContact(models.Model): + _inherit = "mailing.contact" + + company_id = fields.Many2one("res.company", "Company") diff --git a/mass_mailing_multi_company/models/mailing_list.py b/mass_mailing_multi_company/models/mailing_list.py new file mode 100644 index 00000000000..e529bcd099e --- /dev/null +++ b/mass_mailing_multi_company/models/mailing_list.py @@ -0,0 +1,10 @@ +# Copyright 2024 ForgeFlow S.L. +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import fields, models + + +class MassMailingList(models.Model): + _inherit = "mailing.list" + + company_id = fields.Many2one("res.company", "Company") diff --git a/mass_mailing_multi_company/models/mailing_mailing.py b/mass_mailing_multi_company/models/mailing_mailing.py new file mode 100644 index 00000000000..bb4399f6eaf --- /dev/null +++ b/mass_mailing_multi_company/models/mailing_mailing.py @@ -0,0 +1,40 @@ +# Copyright 2024 ForgeFlow S.L. +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import fields, models +from odoo.fields import Domain + + +class MassMailing(models.Model): + _inherit = "mailing.mailing" + + company_id = fields.Many2one("res.company", "Company") + + def _get_recipients(self): + res_ids = super()._get_recipients() + if self.company_id: + records = self.env[self.mailing_model_real].browse(res_ids) + res_ids = records.filtered( + lambda r: not r.company_id or r.company_id == self.company_id + ).ids + return res_ids + + def _compute_total(self): + res = super()._compute_total() + for mailing in self: + if mailing.company_id: + domain = Domain.AND( + [ + mailing._parse_mailing_domain(), + [ + "|", + ("company_id", "=", mailing.company_id.id), + ("company_id", "=", False), + ], + ] + ) + total = self.env[mailing.mailing_model_real].search_count(domain) + if total and mailing.ab_testing_enabled and mailing.ab_testing_pc < 100: + total = max(int(total / 100.0 * mailing.ab_testing_pc), 1) + mailing.total = total + return res diff --git a/mass_mailing_multi_company/models/mailing_subscription.py b/mass_mailing_multi_company/models/mailing_subscription.py new file mode 100644 index 00000000000..a49598ad9b1 --- /dev/null +++ b/mass_mailing_multi_company/models/mailing_subscription.py @@ -0,0 +1,12 @@ +# Copyright 2024 ForgeFlow S.L. +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import fields, models + + +class MailingSubscription(models.Model): + _inherit = "mailing.subscription" + + company_id = fields.Many2one( + "res.company", "Company", related="contact_id.company_id" + ) diff --git a/mass_mailing_multi_company/pyproject.toml b/mass_mailing_multi_company/pyproject.toml new file mode 100644 index 00000000000..4231d0cccb3 --- /dev/null +++ b/mass_mailing_multi_company/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/mass_mailing_multi_company/readme/CONTRIBUTORS.md b/mass_mailing_multi_company/readme/CONTRIBUTORS.md new file mode 100644 index 00000000000..170cb16f1ec --- /dev/null +++ b/mass_mailing_multi_company/readme/CONTRIBUTORS.md @@ -0,0 +1,2 @@ +- Marina Alapont \ +- Jasmin Solanki \ \ No newline at end of file diff --git a/mass_mailing_multi_company/readme/DESCRIPTION.md b/mass_mailing_multi_company/readme/DESCRIPTION.md new file mode 100644 index 00000000000..a1ed36d8ad9 --- /dev/null +++ b/mass_mailing_multi_company/readme/DESCRIPTION.md @@ -0,0 +1,7 @@ +This module adds the company_id field to the models mailing.mailing, +mailing.list, mailing.contact and mailing.contact.subscription. It also +ensures that the lists available for selection in the mailing.mailing +and mailing.contact forms are restricted by the company_id value. For +the mailing.mailing domain, an expression matching only contacts/mailing +contacts with the same company or without company is added when parsing +the domain. diff --git a/mass_mailing_multi_company/security/mass_mailing.xml b/mass_mailing_multi_company/security/mass_mailing.xml new file mode 100644 index 00000000000..c34f61c030b --- /dev/null +++ b/mass_mailing_multi_company/security/mass_mailing.xml @@ -0,0 +1,27 @@ + + + + + mailing.mailing multi-company + + + ['|',('company_id','=',False),('company_id','in',company_ids)] + + + + + mailing.list multi-company + + + ['|',('company_id','=',False),('company_id','in',company_ids)] + + + + + mailing.contact multi-company + + + ['|',('company_id','=',False),('company_id','in',company_ids)] + + + diff --git a/mass_mailing_multi_company/static/description/icon.png b/mass_mailing_multi_company/static/description/icon.png new file mode 100644 index 00000000000..1dcc49c24f3 Binary files /dev/null and b/mass_mailing_multi_company/static/description/icon.png differ diff --git a/mass_mailing_multi_company/static/description/index.html b/mass_mailing_multi_company/static/description/index.html new file mode 100644 index 00000000000..99857699816 --- /dev/null +++ b/mass_mailing_multi_company/static/description/index.html @@ -0,0 +1,436 @@ + + + + + +README.rst + + + +
+ + + +Odoo Community Association + +
+

Mass Mailing Multi Company

+ +

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

+

This module adds the company_id field to the models mailing.mailing, +mailing.list, mailing.contact and mailing.contact.subscription. It also +ensures that the lists available for selection in the mailing.mailing +and mailing.contact forms are restricted by the company_id value. For +the mailing.mailing domain, an expression matching only contacts/mailing +contacts with the same company or without company is added when parsing +the domain.

+

Table of contents

+ +
+

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

+
    +
  • ForgeFlow S.L.
  • +
+
+
+

Contributors

+ +
+
+

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/multi-company project on GitHub.

+

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

+
+
+
+
+ + diff --git a/mass_mailing_multi_company/tests/__init__.py b/mass_mailing_multi_company/tests/__init__.py new file mode 100644 index 00000000000..54e85a50f2b --- /dev/null +++ b/mass_mailing_multi_company/tests/__init__.py @@ -0,0 +1 @@ +from . import test_mass_mailing_multi_company diff --git a/mass_mailing_multi_company/tests/test_mass_mailing_multi_company.py b/mass_mailing_multi_company/tests/test_mass_mailing_multi_company.py new file mode 100644 index 00000000000..c2dfc939915 --- /dev/null +++ b/mass_mailing_multi_company/tests/test_mass_mailing_multi_company.py @@ -0,0 +1,106 @@ +# Copyright 2024 ForgeFlow S.L. +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo.tests.common import TransactionCase + + +class TestMassMailingMultiCompany(TransactionCase): + @classmethod + def setUpClass(cls): + super().setUpClass() + cls.company_model = cls.env["res.company"] + cls.mailing_model = cls.env["mailing.mailing"] + cls.mailing_list_model = cls.env["mailing.list"] + cls.mailing_contact_model = cls.env["mailing.contact"] + cls.mailing_subscription_model = cls.env["mailing.subscription"] + cls.mailing_contact_model.search([]).unlink() + + # Create test companies + cls.company_1 = cls.company_model.create({"name": "Company 1"}) + cls.company_2 = cls.company_model.create({"name": "Company 2"}) + + # Create test mailing list + cls.mailing_list = cls.mailing_list_model.create( + { + "name": "Test Mailing List", + "company_id": cls.company_1.id, + } + ) + + cls.mailing_contact_1 = cls.mailing_contact_model.create( + { + "name": "Test Contact 1", + "company_id": cls.company_1.id, + } + ) + cls.mailing_contact_2 = cls.mailing_contact_model.create( + { + "name": "Test Contact 2", + "company_id": cls.company_1.id, + } + ) + cls.mailing_contact_3 = cls.mailing_contact_model.create( + { + "name": "Test Contact 3", + "company_id": cls.company_2.id, + } + ) + + # Create test mailing + cls.mailing = cls.mailing_model.create( + { + "name": "Test Mailing", + "subject": "Test", + "mailing_domain": [("is_blacklisted", "=", False)], + "company_id": cls.company_1.id, + "mailing_model_id": cls.env.ref( + "mass_mailing.model_mailing_contact" + ).id, + } + ) + + def test_get_recipients(self): + recipients = self.mailing._get_recipients() + self.assertIn(self.mailing_contact_1.id, recipients) + self.assertIn(self.mailing_contact_2.id, recipients) + self.assertNotIn(self.mailing_contact_3.id, recipients) + + # Without company + self.mailing.company_id = False + recipients = self.mailing._get_recipients() + self.assertIn(self.mailing_contact_1.id, recipients) + self.assertIn(self.mailing_contact_2.id, recipients) + self.assertIn(self.mailing_contact_3.id, recipients) + + def test_compute_total_with_company_id(self): + # With company + self.mailing._compute_total() + self.assertEqual(self.mailing.total, 2) + + # Without company + self.mailing.company_id = False + self.mailing._compute_total() + self.assertEqual(self.mailing.total, 3) + + def test_subscription_multi_company(self): + # Create subscriptions for contacts with company filtering + subscription_1 = self.mailing_subscription_model.create( + { + "contact_id": self.mailing_contact_1.id, + "list_id": self.mailing_list.id, + } + ) + subscription_2 = self.mailing_subscription_model.create( + { + "contact_id": self.mailing_contact_3.id, + "list_id": self.mailing_list.id, + } + ) + + # Verify subscriptions are created + self.assertEqual(subscription_1.contact_id.id, self.mailing_contact_1.id) + self.assertEqual(subscription_2.contact_id.id, self.mailing_contact_3.id) + + # Verify company is properly inherited from contact + self.assertEqual(subscription_1.contact_id.company_id.id, self.company_1.id) + self.assertEqual(subscription_2.contact_id.company_id.id, self.company_2.id) diff --git a/mass_mailing_multi_company/views/mailing_contact_views.xml b/mass_mailing_multi_company/views/mailing_contact_views.xml new file mode 100644 index 00000000000..25c92f5fc9c --- /dev/null +++ b/mass_mailing_multi_company/views/mailing_contact_views.xml @@ -0,0 +1,40 @@ + + + + mailing.contact.view.tree + mailing.contact + + + + + + + + + + mailing.contact.view.form + mailing.contact + + + + + + + + + + + ['|',('company_id', '=', company_id),('company_id', '=', False)] + + + + + diff --git a/mass_mailing_multi_company/views/mailing_list_views.xml b/mass_mailing_multi_company/views/mailing_list_views.xml new file mode 100644 index 00000000000..81ba18218ea --- /dev/null +++ b/mass_mailing_multi_company/views/mailing_list_views.xml @@ -0,0 +1,47 @@ + + + + mailing.list.view.tree + mailing.list + + + + + + + + + + mailing.list.form + mailing.list + + + + + + + + + + mailing.list.form.simplified + mailing.list + + + + + + + + diff --git a/mass_mailing_multi_company/views/mailing_mailing_views.xml b/mass_mailing_multi_company/views/mailing_mailing_views.xml new file mode 100644 index 00000000000..2bf4161cc0e --- /dev/null +++ b/mass_mailing_multi_company/views/mailing_mailing_views.xml @@ -0,0 +1,51 @@ + + + + mailing.mailing.tree + mailing.mailing + + + + + + + + + + mailing.mailing.form + mailing.mailing + + + + + + + + + + + + + + + + ['|',('company_id', '=', company_id),('company_id', '=', False)] + + + + +