diff --git a/mass_mailing_unique/README.rst b/mass_mailing_unique/README.rst new file mode 100644 index 00000000..e75c471b --- /dev/null +++ b/mass_mailing_unique/README.rst @@ -0,0 +1,65 @@ +.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 + +=============================== +Unique records for mass mailing +=============================== + +This module extends the functionality of mass mailing lists to disable +duplicate entries in list names and contact emails per list. + +This way you will avoid sending the same message more than once to the same +contact when selecting a mailing list, and you will avoid conflicts when +importing contacts to a list that has a duplicated name. + +Installation +============ + +Before installing this module, you need to: + +* Remove all duplicated list names. +* Remove all duplicated emails in each list. + +Usage +===== + +To use this module, you need to try to create a duplicated mailing list, or a +duplicated email inside one. You will not can. + +.. 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/9.0 + +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. + +Credits +======= + +Contributors +------------ + +* Jairo Llopis +* Vicent Cubells +* Pedro M. Baeza + +Maintainer +---------- + +.. 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. diff --git a/mass_mailing_unique/__init__.py b/mass_mailing_unique/__init__.py new file mode 100644 index 00000000..70227430 --- /dev/null +++ b/mass_mailing_unique/__init__.py @@ -0,0 +1,8 @@ +# -*- coding: utf-8 -*- +# Copyright 2015 Grupo ESOC Ingeniería de Servicios, S.L.U. - Jairo Llopis +# Copyright 2016 Tecnativa - Vicent Cubells +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + + +from . import models +from .hooks import pre_init_hook diff --git a/mass_mailing_unique/__openerp__.py b/mass_mailing_unique/__openerp__.py new file mode 100644 index 00000000..6683eea8 --- /dev/null +++ b/mass_mailing_unique/__openerp__.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- +# Copyright 2015 Grupo ESOC Ingeniería de Servicios, S.L.U. - Jairo Llopis +# Copyright 2016 Tecnativa - Vicent Cubells +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +{ + "name": "Unique records for mass mailing", + "summary": "Avoids duplicate mailing lists and contacts", + "version": "9.0.1.0.0", + "category": "Marketing", + "website": "https://tecnativa.com", + "author": "Grupo ESOC Ingeniería de Servicios," + "Tecnativa, " + "Odoo Community Association (OCA)", + "license": "AGPL-3", + "application": False, + "installable": True, + "pre_init_hook": "pre_init_hook", + "images": [ + "images/error-duplicated-email.png", + "images/error-duplicated-list.png", + ], + "depends": [ + "mass_mailing", + ], +} diff --git a/mass_mailing_unique/hooks.py b/mass_mailing_unique/hooks.py new file mode 100644 index 00000000..1a8961d3 --- /dev/null +++ b/mass_mailing_unique/hooks.py @@ -0,0 +1,45 @@ +# -*- coding: utf-8 -*- +# Copyright 2015 Grupo ESOC Ingeniería de Servicios, S.L.U. - Jairo Llopis +# Copyright 2016 Tecnativa - Vicent Cubells +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + + +from openerp import _ +from openerp.exceptions import ValidationError + + +def pre_init_hook(cr): + """Make sure there are no duplicates before installing the module. + + If you define a unique key in Odoo that cannot be applied, Odoo will log a + warning and install the module without that constraint. Since this module + is useless without those constraints, we check here if all will work before + installing, and provide a user-friendly message in case of failure. + """ + errors = list() + + # Search for duplicates in emails + cr.execute("""SELECT c.email, l.name, COUNT(c.id) + FROM + mail_mass_mailing_contact AS c + INNER JOIN mail_mass_mailing_list AS l ON c.list_id = l.id + GROUP BY l.name, l.id, c.email + HAVING COUNT(c.id) > 1""") + for result in cr.fetchall(): + errors.append( + _("{0} appears {2} times in list {1}.").format(*result)) + + # Search for duplicates in list's name + cr.execute("""SELECT name, COUNT(id) + FROM mail_mass_mailing_list + GROUP BY name + HAVING COUNT(id) > 1""") + for result in cr.fetchall(): + errors.append( + _("There are {1} lists with name {0}.").format(*result)) + + # Abort if duplicates are found + if errors: + raise ValidationError( + _("Fix this before installing:") + + "".join("\n" + e for e in errors)) diff --git a/mass_mailing_unique/i18n/es.po b/mass_mailing_unique/i18n/es.po new file mode 100644 index 00000000..c2447c42 --- /dev/null +++ b/mass_mailing_unique/i18n/es.po @@ -0,0 +1,56 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * mass_mailing_unique +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 8.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-01-29 12:37+0100\n" +"PO-Revision-Date: 2016-01-29 12:38+0100\n" +"Last-Translator: Jairo Llopis \n" +"Language-Team: \n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: \n" +"X-Generator: Poedit 1.8.5\n" + +#. module: mass_mailing_unique +#: sql_constraint:mail.mass_mailing.list:0 +msgid "Cannot have more than one lists with the same name." +msgstr "No se puede tener más de una lista con el mismo nombre." + +#. module: mass_mailing_unique +#: sql_constraint:mail.mass_mailing.contact:0 +msgid "Cannot have the same email more than once in the same list." +msgstr "No se puede tener el mismo email varias veces en la misma lista." + +#. module: mass_mailing_unique +#: code:addons/mass_mailing_unique/hooks.py:42 +#, python-format +msgid "Fix this before installing:" +msgstr "Arregle esto antes de instalar:" + +#. module: mass_mailing_unique +#: model:ir.model,name:mass_mailing_unique.model_mail_mass_mailing_list +msgid "Mailing List" +msgstr "Lista de correo" + +#. module: mass_mailing_unique +#: model:ir.model,name:mass_mailing_unique.model_mail_mass_mailing_contact +msgid "Mass Mailing Contact" +msgstr "Contacto de envío masivo" + +#. module: mass_mailing_unique +#: code:addons/mass_mailing_unique/hooks.py:37 +#, python-format +msgid "There are {1} lists with name {0}." +msgstr "Hay {1} listas con el nombre {0}." + +#. module: mass_mailing_unique +#: code:addons/mass_mailing_unique/hooks.py:28 +#, python-format +msgid "{0} appears {2} times in list {1}." +msgstr "{0} aparece {2} veces en la lista {1}." diff --git a/mass_mailing_unique/i18n/fr.po b/mass_mailing_unique/i18n/fr.po new file mode 100644 index 00000000..9dd927ab --- /dev/null +++ b/mass_mailing_unique/i18n/fr.po @@ -0,0 +1,57 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * mass_mailing_unique +# +# Translators: +# Christophe CHAUVET , 2016 +msgid "" +msgstr "" +"Project-Id-Version: social (8.0)\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-06-30 01:07+0000\n" +"PO-Revision-Date: 2016-06-22 09:25+0000\n" +"Last-Translator: Christophe CHAUVET \n" +"Language-Team: French (http://www.transifex.com/oca/OCA-social-8-0/language/fr/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Language: fr\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" + +#. module: mass_mailing_unique +#: sql_constraint:mail.mass_mailing.list:0 +msgid "Cannot have more than one lists with the same name." +msgstr "Impossible d'avoir plus d'une liste avec le même nom." + +#. module: mass_mailing_unique +#: sql_constraint:mail.mass_mailing.contact:0 +msgid "Cannot have the same email more than once in the same list." +msgstr "Impossible d'avoir le même courriel plus d'une fois dans la même liste" + +#. module: mass_mailing_unique +#: code:addons/mass_mailing_unique/hooks.py:42 +#, python-format +msgid "Fix this before installing:" +msgstr "Fixer avant l'installation:" + +#. module: mass_mailing_unique +#: model:ir.model,name:mass_mailing_unique.model_mail_mass_mailing_list +msgid "Mailing List" +msgstr "Liste de diffusion" + +#. module: mass_mailing_unique +#: model:ir.model,name:mass_mailing_unique.model_mail_mass_mailing_contact +msgid "Mass Mailing Contact" +msgstr "Contact de la liste de diffusion" + +#. module: mass_mailing_unique +#: code:addons/mass_mailing_unique/hooks.py:37 +#, python-format +msgid "There are {1} lists with name {0}." +msgstr "Il y'a {1} listes avec le nom {0}." + +#. module: mass_mailing_unique +#: code:addons/mass_mailing_unique/hooks.py:28 +#, python-format +msgid "{0} appears {2} times in list {1}." +msgstr "{0} Apparaît {2} fois dans la liste {1}." diff --git a/mass_mailing_unique/i18n/it.po b/mass_mailing_unique/i18n/it.po new file mode 100644 index 00000000..73c17649 --- /dev/null +++ b/mass_mailing_unique/i18n/it.po @@ -0,0 +1,57 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * mass_mailing_unique +# +# Translators: +# Paolo Valier, 2016 +msgid "" +msgstr "" +"Project-Id-Version: social (8.0)\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-11-25 18:06+0000\n" +"PO-Revision-Date: 2016-10-24 11:54+0000\n" +"Last-Translator: Paolo Valier\n" +"Language-Team: Italian (http://www.transifex.com/oca/OCA-social-8-0/language/it/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Language: it\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. module: mass_mailing_unique +#: sql_constraint:mail.mass_mailing.list:0 +msgid "Cannot have more than one lists with the same name." +msgstr "Non è possibile avere più di una lista con lo stesso nome." + +#. module: mass_mailing_unique +#: sql_constraint:mail.mass_mailing.contact:0 +msgid "Cannot have the same email more than once in the same list." +msgstr "Non è possibile inserire la stessa email più di una volta nella stessa lista." + +#. module: mass_mailing_unique +#: code:addons/mass_mailing_unique/hooks.py:42 +#, python-format +msgid "Fix this before installing:" +msgstr "Da risolvere prima dell'installazione:" + +#. module: mass_mailing_unique +#: model:ir.model,name:mass_mailing_unique.model_mail_mass_mailing_list +msgid "Mailing List" +msgstr "Mailing List" + +#. module: mass_mailing_unique +#: model:ir.model,name:mass_mailing_unique.model_mail_mass_mailing_contact +msgid "Mass Mailing Contact" +msgstr "Contatto Mass Mailing" + +#. module: mass_mailing_unique +#: code:addons/mass_mailing_unique/hooks.py:37 +#, python-format +msgid "There are {1} lists with name {0}." +msgstr "Ci sono {1} liste con il nome {0}." + +#. module: mass_mailing_unique +#: code:addons/mass_mailing_unique/hooks.py:28 +#, python-format +msgid "{0} appears {2} times in list {1}." +msgstr "{0} appare {2} volte nella lista {1}." diff --git a/mass_mailing_unique/i18n/sl.po b/mass_mailing_unique/i18n/sl.po new file mode 100644 index 00000000..3bd8a808 --- /dev/null +++ b/mass_mailing_unique/i18n/sl.po @@ -0,0 +1,57 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * mass_mailing_unique +# +# Translators: +# Matjaž Mozetič , 2016 +msgid "" +msgstr "" +"Project-Id-Version: social (8.0)\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-02-27 01:40+0000\n" +"PO-Revision-Date: 2016-02-27 16:56+0000\n" +"Last-Translator: Matjaž Mozetič \n" +"Language-Team: Slovenian (http://www.transifex.com/oca/OCA-social-8-0/language/sl/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Language: sl\n" +"Plural-Forms: nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3);\n" + +#. module: mass_mailing_unique +#: sql_constraint:mail.mass_mailing.list:0 +msgid "Cannot have more than one lists with the same name." +msgstr "Imate lahko le en seznam z istim imenom." + +#. module: mass_mailing_unique +#: sql_constraint:mail.mass_mailing.contact:0 +msgid "Cannot have the same email more than once in the same list." +msgstr "Isti e-poštni naslov imate lahko le enkrat v istem seznamu." + +#. module: mass_mailing_unique +#: code:addons/mass_mailing_unique/hooks.py:42 +#, python-format +msgid "Fix this before installing:" +msgstr "Popravite pred namestitvijo:" + +#. module: mass_mailing_unique +#: model:ir.model,name:mass_mailing_unique.model_mail_mass_mailing_list +msgid "Mailing List" +msgstr "Poštni seznam" + +#. module: mass_mailing_unique +#: model:ir.model,name:mass_mailing_unique.model_mail_mass_mailing_contact +msgid "Mass Mailing Contact" +msgstr "Stik masovne pošte" + +#. module: mass_mailing_unique +#: code:addons/mass_mailing_unique/hooks.py:37 +#, python-format +msgid "There are {1} lists with name {0}." +msgstr "{1} seznamov z imenom {0}." + +#. module: mass_mailing_unique +#: code:addons/mass_mailing_unique/hooks.py:28 +#, python-format +msgid "{0} appears {2} times in list {1}." +msgstr "{0} se pojavi {2} krat v seznamu {1}." diff --git a/mass_mailing_unique/images/error-duplicated-email.png b/mass_mailing_unique/images/error-duplicated-email.png new file mode 100644 index 00000000..cb69b830 Binary files /dev/null and b/mass_mailing_unique/images/error-duplicated-email.png differ diff --git a/mass_mailing_unique/images/error-duplicated-list.png b/mass_mailing_unique/images/error-duplicated-list.png new file mode 100644 index 00000000..cb61348c Binary files /dev/null and b/mass_mailing_unique/images/error-duplicated-list.png differ diff --git a/mass_mailing_unique/models/__init__.py b/mass_mailing_unique/models/__init__.py new file mode 100644 index 00000000..f4f8574f --- /dev/null +++ b/mass_mailing_unique/models/__init__.py @@ -0,0 +1,7 @@ +# -*- coding: utf-8 -*- +# Copyright 2015 Grupo ESOC Ingeniería de Servicios, S.L.U. - Jairo Llopis +# Copyright 2016 Tecnativa - Vicent Cubells +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + + +from . import mass_mailing diff --git a/mass_mailing_unique/models/mass_mailing.py b/mass_mailing_unique/models/mass_mailing.py new file mode 100644 index 00000000..97f0b44a --- /dev/null +++ b/mass_mailing_unique/models/mass_mailing.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +# Copyright 2015 Grupo ESOC Ingeniería de Servicios, S.L.U. - Jairo Llopis +# Copyright 2016 Tecnativa - Vicent Cubells +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + + +from openerp import models + + +class MailMassMailingContact(models.Model): + _inherit = "mail.mass_mailing.contact" + _sql_constraints = [ + ("unique_mail_per_list", "UNIQUE(list_id, email)", + "Cannot have the same email more than once in the same list.") + ] + + +class MailMassMailingList(models.Model): + _inherit = "mail.mass_mailing.list" + _sql_constraints = [ + ("unique_name", "UNIQUE(name)", + "Cannot have more than one lists with the same name.") + ] diff --git a/mass_mailing_unique/static/description/icon.png b/mass_mailing_unique/static/description/icon.png new file mode 100644 index 00000000..3a0328b5 Binary files /dev/null and b/mass_mailing_unique/static/description/icon.png differ diff --git a/mass_mailing_unique/tests/__init__.py b/mass_mailing_unique/tests/__init__.py new file mode 100644 index 00000000..e876756a --- /dev/null +++ b/mass_mailing_unique/tests/__init__.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from . import test_mass_mailing_unique diff --git a/mass_mailing_unique/tests/test_mass_mailing_unique.py b/mass_mailing_unique/tests/test_mass_mailing_unique.py new file mode 100644 index 00000000..0e962fd1 --- /dev/null +++ b/mass_mailing_unique/tests/test_mass_mailing_unique.py @@ -0,0 +1,45 @@ +# -*- coding: utf-8 -*- +# Copyright 2016 Tecnativa - Pedro M. Baeza +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from openerp.tests import common +from openerp import exceptions +from ..hooks import pre_init_hook + + +class TestMassMailingUnique(common.SavepointCase): + @classmethod + def setUpClass(cls): + super(TestMassMailingUnique, cls).setUpClass() + cls.list = cls.env['mail.mass_mailing.list'].create({ + 'name': 'Test list', + }) + cls.contact1 = cls.env['mail.mass_mailing.contact'].create({ + 'name': 'Contact 1', + 'email': 'email1@test.com', + }) + + def test_init_hook_list(self): + # Disable temporarily the constraint + self.env.cr.execute(""" + ALTER TABLE mail_mass_mailing_list + DROP CONSTRAINT mail_mass_mailing_list_unique_name + """) + self.env['mail.mass_mailing.list'].create({ + 'name': 'Test list', + }) + with self.assertRaises(exceptions.ValidationError): + pre_init_hook(self.env.cr) + + def test_init_hook_contact(self): + # Disable temporarily the constraint + self.env.cr.execute(""" + ALTER TABLE mail_mass_mailing_contact + DROP CONSTRAINT mail_mass_mailing_contact_unique_mail_per_list + """) + self.env['mail.mass_mailing.contact'].create({ + 'name': 'Contact 2', + 'email': 'email1@test.com', + }) + with self.assertRaises(exceptions.ValidationError): + pre_init_hook(self.env.cr)