diff --git a/mass_mailing_list_dynamic/README.rst b/mass_mailing_list_dynamic/README.rst index a57b65bd..d74187f6 100644 --- a/mass_mailing_list_dynamic/README.rst +++ b/mass_mailing_list_dynamic/README.rst @@ -1,11 +1,30 @@ -.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg - :target: https://www.gnu.org/licenses/agpl - :alt: License: AGPL-3 - ========================== Dynamic Mass Mailing Lists ========================== +.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png + :target: https://odoo-community.org/page/development-status + :alt: Beta +.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 +.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fsocial-lightgray.png?logo=github + :target: https://github.com/OCA/social/tree/12.0/mass_mailing_list_dynamic + :alt: OCA/social +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/social-12-0/social-12-0-mass_mailing_list_dynamic + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png + :target: https://runbot.odoo-community.org/runbot/205/12.0 + :alt: Try me on Runbot + +|badge1| |badge2| |badge3| |badge4| |badge5| + Without this addon you have to choose between providing a dynamic domain and letting your mass mailings reach all partners that match it, or being able to unsubscribe to certain mailing lists while still being subscribed to others. @@ -13,10 +32,15 @@ unsubscribe to certain mailing lists while still being subscribed to others. This addon allows you to create dynamic mailing lists, so you can now benefit from both things. +**Table of contents** + +.. contents:: + :local: + Configuration ============= -To create a dynamic mailing list, you need to: +To configure this module, you need to: #. Go to *Mass Mailing > Mailings > Mailing Lists* and create one. #. Check the *Dynamic* box. @@ -41,6 +65,8 @@ You can also load an existing filter over contacts: Usage ===== +To use this module, you need to: + #. Go to *Mass Mailing > Mailings > Mass Mailings*, and create one. #. Select as recipients a mailing list. #. On "Select mailing lists:", choose one mailing list with dynamic flag @@ -55,54 +81,46 @@ Pay attention to the messages shown to you that tell you about some non-obvious behaviour you could experience if you edit manually contacts from a dynamic list. -.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas - :alt: Try me on Runbot - :target: https://runbot.odoo-community.org/runbot/205/10.0 - -Known issues / Roadmap -====================== - -* Tests affected by https://github.com/odoo/odoo/issues/20603. Do not run them - in stateful databases. - 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 smash it by providing detailed and welcomed feedback. +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 smashing it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. Credits ======= -Images ------- +Authors +~~~~~~~ -* Odoo. -* FontAwesome (http://fontawesome.io). +* Tecnativa Contributors ------------- +~~~~~~~~~~~~ * `Tecnativa `_: * Jairo Llopis * Pedro M. Baeza * David Vidal + * Victor M.M. Torres -Do not contact contributors directly about support or help with technical issues. +Maintainers +~~~~~~~~~~~ -Maintainer ----------- +This module is maintained by the OCA. .. image:: https://odoo-community.org/logo.png :alt: Odoo Community Association :target: https://odoo-community.org -This module is maintained by the OCA. - 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. -To contribute to this module, please visit https://odoo-community.org. +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/mass_mailing_list_dynamic/__init__.py b/mass_mailing_list_dynamic/__init__.py index 2966b917..adc6207f 100644 --- a/mass_mailing_list_dynamic/__init__.py +++ b/mass_mailing_list_dynamic/__init__.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). from . import models diff --git a/mass_mailing_list_dynamic/__manifest__.py b/mass_mailing_list_dynamic/__manifest__.py index 6e0e2439..082f359a 100644 --- a/mass_mailing_list_dynamic/__manifest__.py +++ b/mass_mailing_list_dynamic/__manifest__.py @@ -1,11 +1,11 @@ -# -*- coding: utf-8 -*- # Copyright 2017 Tecnativa - Jairo Llopis # Copyright 2018 Tecnativa - David Vidal +# Copyright 2019 Tecnativa - Victor Martin # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). { "name": "Dynamic Mass Mailing Lists", "summary": "Mass mailing lists that get autopopulated", - "version": "10.0.1.2.0", + "version": "12.0.1.0.0", "category": "Marketing", "website": "https://github.com/OCA/social", "author": "Tecnativa, Odoo Community Association (OCA)", diff --git a/mass_mailing_list_dynamic/models/__init__.py b/mass_mailing_list_dynamic/models/__init__.py index 2e3ac3d4..3bb2fc2b 100644 --- a/mass_mailing_list_dynamic/models/__init__.py +++ b/mass_mailing_list_dynamic/models/__init__.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). from . import mail_mass_mailing diff --git a/mass_mailing_list_dynamic/models/mail_mass_mailing.py b/mass_mailing_list_dynamic/models/mail_mass_mailing.py index 536448bb..7538360f 100644 --- a/mass_mailing_list_dynamic/models/mail_mass_mailing.py +++ b/mass_mailing_list_dynamic/models/mail_mass_mailing.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright 2017 Tecnativa - Jairo Llopis # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). diff --git a/mass_mailing_list_dynamic/models/mail_mass_mailing_contact.py b/mass_mailing_list_dynamic/models/mail_mass_mailing_contact.py index 8dd28174..2a9feedd 100644 --- a/mass_mailing_list_dynamic/models/mail_mass_mailing_contact.py +++ b/mass_mailing_list_dynamic/models/mail_mass_mailing_contact.py @@ -1,5 +1,5 @@ -# -*- coding: utf-8 -*- # Copyright 2017 Tecnativa - Jairo Llopis +# Copyright 2019 Tecnativa - Victor M.M. Torres # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). from odoo import _, api, models @@ -9,13 +9,15 @@ from odoo.exceptions import ValidationError class MassMailingContact(models.Model): _inherit = "mail.mass_mailing.contact" - @api.constrains("partner_id", "list_id", "name", "email") + @api.constrains("partner_id", "list_ids", "name", "email") def _check_no_manual_edits_on_fully_synced_lists(self): if self.env.context.get("syncing"): return - if any((one.list_id.dynamic and - one.list_id.sync_method == "full") for one in self): - raise ValidationError( - _("Cannot edit manually contacts in a fully " - "synchronized list. Change its sync method or execute " - "a manual sync instead.")) + for rec in self: + if rec.list_ids: + if any(rec.list_ids.mapped('dynamic')) and ( + rec.list_ids.mapped('sync_method').count("full") > 0): + raise ValidationError( + _("""Cannot edit manually contacts in a fully synchronized list. + Change its sync method or execute + a manual sync instead.""")) diff --git a/mass_mailing_list_dynamic/models/mail_mass_mailing_list.py b/mass_mailing_list_dynamic/models/mail_mass_mailing_list.py index 47be1b65..621f4c63 100644 --- a/mass_mailing_list_dynamic/models/mail_mass_mailing_list.py +++ b/mass_mailing_list_dynamic/models/mail_mass_mailing_list.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright 2017 Tecnativa - Jairo Llopis # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). @@ -48,17 +47,19 @@ class MassMailingList(models.Model): # Remove undesired contacts when synchronization is full if one.sync_method == "full": Contact.search([ - ("list_id", "=", one.id), + ("list_ids", "in", one.id), ("partner_id", "not in", desired_partners.ids), ]).unlink() - current_contacts = Contact.search([("list_id", "=", one.id)]) + current_contacts = Contact.search([("list_ids", "in", one.id)]) current_partners = current_contacts.mapped("partner_id") # Add new contacts + vals_list = [] for partner in desired_partners - current_partners: - Contact.create({ - "list_id": one.id, + vals_list.append({ + "list_ids": [(4, one.id)], "partner_id": partner.id, }) + Contact.create(vals_list) one.is_synced = True # Invalidate cached contact count self.invalidate_cache(["contact_nbr"], dynamic.ids) diff --git a/mass_mailing_list_dynamic/models/res_partner.py b/mass_mailing_list_dynamic/models/res_partner.py index 465f5304..a58d6e62 100644 --- a/mass_mailing_list_dynamic/models/res_partner.py +++ b/mass_mailing_list_dynamic/models/res_partner.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright 2017 Tecnativa - Pedro M. Baeza # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). diff --git a/mass_mailing_list_dynamic/readme/CONFIGURE.rst b/mass_mailing_list_dynamic/readme/CONFIGURE.rst new file mode 100644 index 00000000..e110755e --- /dev/null +++ b/mass_mailing_list_dynamic/readme/CONFIGURE.rst @@ -0,0 +1,21 @@ +To configure this module, you need to: + +#. Go to *Mass Mailing > Mailings > Mailing Lists* and create one. +#. Check the *Dynamic* box. +#. Choose a *Sync method*: + + - Leave empty to use as a manual mailing list, the normal behavior. + - *Only add new records* to make sure no records disappear from the list + when partners stop matching the *Synchronization critera*. + - *Add and remove records as needed* to make the list be fully synchronized + with the *Synchronization critera*, even if that means removing contacts + from it. +#. Define a *Synchronization criteria* that will be used to match the partners + that should go into the list as contacts. Only partners with emails will + be selected. + +You can also load an existing filter over contacts: + +#. Click on "Load filter" button below criteria. +#. Select one of the existing filters. +#. Click on "Load filter" and you will have that filter as criteria. diff --git a/mass_mailing_list_dynamic/readme/CONTRIBUTORS.rst b/mass_mailing_list_dynamic/readme/CONTRIBUTORS.rst new file mode 100644 index 00000000..e136bc5e --- /dev/null +++ b/mass_mailing_list_dynamic/readme/CONTRIBUTORS.rst @@ -0,0 +1,5 @@ +* `Tecnativa `_: + * Jairo Llopis + * Pedro M. Baeza + * David Vidal + * Victor M.M. Torres diff --git a/mass_mailing_list_dynamic/readme/DESCRIPTION.rst b/mass_mailing_list_dynamic/readme/DESCRIPTION.rst new file mode 100644 index 00000000..12e1d697 --- /dev/null +++ b/mass_mailing_list_dynamic/readme/DESCRIPTION.rst @@ -0,0 +1,6 @@ +Without this addon you have to choose between providing a dynamic domain and +letting your mass mailings reach all partners that match it, or being able to +unsubscribe to certain mailing lists while still being subscribed to others. + +This addon allows you to create dynamic mailing lists, so you can now benefit +from both things. diff --git a/mass_mailing_list_dynamic/readme/USAGE.rst b/mass_mailing_list_dynamic/readme/USAGE.rst new file mode 100644 index 00000000..fd6130c0 --- /dev/null +++ b/mass_mailing_list_dynamic/readme/USAGE.rst @@ -0,0 +1,15 @@ +To use this module, you need to: + +#. Go to *Mass Mailing > Mailings > Mass Mailings*, and create one. +#. Select as recipients a mailing list. +#. On "Select mailing lists:", choose one mailing list with dynamic flag + checked. +#. Before sending the mass mailing, the list will be synced for having latest + changes. + +When you hit the *Sync now* button or send a mass mailing to this list, its +contacts will be automatically updated. + +Pay attention to the messages shown to you that tell you about some non-obvious +behaviour you could experience if you edit manually contacts from a dynamic +list. diff --git a/mass_mailing_list_dynamic/static/description/index.html b/mass_mailing_list_dynamic/static/description/index.html new file mode 100644 index 00000000..a2d0a182 --- /dev/null +++ b/mass_mailing_list_dynamic/static/description/index.html @@ -0,0 +1,472 @@ + + + + + + +Dynamic Mass Mailing Lists + + + +
+

Dynamic Mass Mailing Lists

+ + +

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

+

Without this addon you have to choose between providing a dynamic domain and +letting your mass mailings reach all partners that match it, or being able to +unsubscribe to certain mailing lists while still being subscribed to others.

+

This addon allows you to create dynamic mailing lists, so you can now benefit +from both things.

+

Table of contents

+ +
+

Configuration

+

To configure this module, you need to:

+
    +
  1. Go to Mass Mailing > Mailings > Mailing Lists and create one.
  2. +
  3. Check the Dynamic box.
  4. +
  5. Choose a Sync method:
      +
    • Leave empty to use as a manual mailing list, the normal behavior.
    • +
    • Only add new records to make sure no records disappear from the list +when partners stop matching the Synchronization critera.
    • +
    • Add and remove records as needed to make the list be fully synchronized +with the Synchronization critera, even if that means removing contacts +from it.
    • +
    +
  6. +
  7. Define a Synchronization criteria that will be used to match the partners +that should go into the list as contacts. Only partners with emails will +be selected.
  8. +
+

You can also load an existing filter over contacts:

+
    +
  1. Click on “Load filter” button below criteria.
  2. +
  3. Select one of the existing filters.
  4. +
  5. Click on “Load filter” and you will have that filter as criteria.
  6. +
+
+
+

Usage

+

To use this module, you need to:

+
    +
  1. Go to Mass Mailing > Mailings > Mass Mailings, and create one.
  2. +
  3. Select as recipients a mailing list.
  4. +
  5. On “Select mailing lists:”, choose one mailing list with dynamic flag +checked.
  6. +
  7. Before sending the mass mailing, the list will be synced for having latest +changes.
  8. +
+

When you hit the Sync now button or send a mass mailing to this list, its +contacts will be automatically updated.

+

Pay attention to the messages shown to you that tell you about some non-obvious +behaviour you could experience if you edit manually contacts from a dynamic +list.

+
+
+

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 smashing it by providing a detailed and welcomed +feedback.

+

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

+
+
+

Credits

+
+

Authors

+
    +
  • Tecnativa
  • +
+
+
+

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

+

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

+
+
+
+ + diff --git a/mass_mailing_list_dynamic/tests/__init__.py b/mass_mailing_list_dynamic/tests/__init__.py index 778cd50f..d5210483 100644 --- a/mass_mailing_list_dynamic/tests/__init__.py +++ b/mass_mailing_list_dynamic/tests/__init__.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). from . import test_dynamic_lists diff --git a/mass_mailing_list_dynamic/tests/test_dynamic_lists.py b/mass_mailing_list_dynamic/tests/test_dynamic_lists.py index eb781a59..be6cc111 100644 --- a/mass_mailing_list_dynamic/tests/test_dynamic_lists.py +++ b/mass_mailing_list_dynamic/tests/test_dynamic_lists.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright 2017 Tecnativa - Jairo Llopis # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). @@ -45,7 +44,7 @@ class DynamicListCase(common.SavepointCase): self.list.dynamic = False # Create contact for partner 0 in unsynced list contact0 = Contact.create({ - "list_id": self.list.id, + "list_ids": [(4, self.list.id)], "partner_id": self.partners[0].id, }) self.assertEqual(self.list.contact_nbr, 1) @@ -57,7 +56,7 @@ class DynamicListCase(common.SavepointCase): # Set list as full-synced self.list.sync_method = "full" Contact.search([ - ("list_id", "=", self.list.id), + ("list_ids", "in", self.list.id), ("partner_id", "=", self.partners[2].id), ]).unlink() self.list.action_sync() @@ -66,11 +65,11 @@ class DynamicListCase(common.SavepointCase): # Cannot add or edit contacts in fully synced lists with self.assertRaises(ValidationError): Contact.create({ - "list_id": self.list.id, + "list_ids": [(4, self.list.id)], "partner_id": self.partners[0].id, }) contact1 = Contact.search([ - ("list_id", "=", self.list.id), + ("list_ids", "in", self.list.id), ], limit=1) with self.assertRaises(ValidationError): contact1.name = "other" @@ -82,7 +81,7 @@ class DynamicListCase(common.SavepointCase): self.list.dynamic = False # Now the contact is created without exception Contact.create({ - "list_id": self.list.id, + "list_ids": [(4, self.list.id)], "email": "test@example.com", }) # Contacts can now be changed diff --git a/mass_mailing_list_dynamic/wizards/__init__.py b/mass_mailing_list_dynamic/wizards/__init__.py index da942605..5c4e8060 100644 --- a/mass_mailing_list_dynamic/wizards/__init__.py +++ b/mass_mailing_list_dynamic/wizards/__init__.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). from . import mail_mass_mailing_load_filter diff --git a/mass_mailing_list_dynamic/wizards/mail_mass_mailing_load_filter.py b/mass_mailing_list_dynamic/wizards/mail_mass_mailing_load_filter.py index 89834a2f..3c11b53c 100644 --- a/mass_mailing_list_dynamic/wizards/mail_mass_mailing_load_filter.py +++ b/mass_mailing_list_dynamic/wizards/mail_mass_mailing_load_filter.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright 2017 Tecnativa - Pedro M. Baeza # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).