diff --git a/mass_mailing_partner/README.rst b/mass_mailing_partner/README.rst new file mode 100644 index 00000000..09bf2dd3 --- /dev/null +++ b/mass_mailing_partner/README.rst @@ -0,0 +1,88 @@ +.. 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 + +=============================== +Link partners with mass-mailing +=============================== + +This module links mass-mailing contacts with partners. + +Features +-------- +* When creating or saving a mass-mailing contact, partners are matched through + email, linking matched partner, or creating a new one if no match and the + maling list partner mandatory field is checked. +* Mailing contacts smart button in partner form. + + +Configuration +============= + +At first install, all existing mass mailing contacts are matched against +partners. + + +Usage +===== + +In partner view, there is a new action called "Add to mailing list". This +action open a pop-up to select a mailing list. Selected partners will be added +as mailing list contacts. + +.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas + :alt: Try me on Runbot + :target: https://runbot.odoo-community.org/runbot/111/8.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 +`here `_. + + +License +======= + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published +by the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . + + +Credits +======= + +Contributors +------------ + +* Pedro M. Baeza +* Rafael Blasco +* Antonio Espinosa +* Javier Iniesta + +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 http://odoo-community.org. \ No newline at end of file diff --git a/mass_mailing_partner/__init__.py b/mass_mailing_partner/__init__.py new file mode 100644 index 00000000..9250d91b --- /dev/null +++ b/mass_mailing_partner/__init__.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# See README.rst file on addon root folder for license details + +from . import models +from . import wizard +from openerp import api, SUPERUSER_ID + + +def _match_existing_contacts(cr, registry): + with api.Environment.manage(): + env = api.Environment(cr, SUPERUSER_ID, {}) + contact_model = env['mail.mass_mailing.contact'] + partner_model = env['res.partner'] + contacts = contact_model.search([('email', '!=', False)]) + for contact in contacts: + if contact.email: + partners = partner_model.search([('email', '=ilike', + contact.email)]) + if partners: + contact.write({'partner_id': partners[0].id}) diff --git a/mass_mailing_partner/__openerp__.py b/mass_mailing_partner/__openerp__.py new file mode 100644 index 00000000..684b39cd --- /dev/null +++ b/mass_mailing_partner/__openerp__.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +# See README.rst file on addon root folder for license details + +{ + "name": "Link partners with mass-mailing", + "version": "8.0.1.0.0", + "author": "Antiun Ingeniería S.L., " + "Serv. Tecnol. Avanzados - Pedro M. Baeza, " + "Odoo Community Association (OCA)", + "license": "AGPL-3", + "category": "Marketing", + "depends": [ + 'mass_mailing', + ], + "post_init_hook": "_match_existing_contacts", + 'data': [ + 'views/mail_mass_mailing_contact_view.xml', + 'views/mail_mass_mailing_view.xml', + 'views/res_partner_view.xml', + 'wizard/partner_mail_list_wizard.xml' + ], + "installable": True, +} diff --git a/mass_mailing_partner/i18n/es.po b/mass_mailing_partner/i18n/es.po new file mode 100644 index 00000000..3da5e0ad --- /dev/null +++ b/mass_mailing_partner/i18n/es.po @@ -0,0 +1,140 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * mass_mailing_partner +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 8.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-11-03 14:42+0000\n" +"PO-Revision-Date: 2015-11-03 14:42+0000\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_partner +#: view:partner.mail.list.wizard:mass_mailing_partner.partner_mail_list_wizard_form +msgid "Add contacts to mailing list" +msgstr "Añadir contactos a la lista de correo" + +#. module: mass_mailing_partner +#: model:ir.actions.act_window,name:mass_mailing_partner.action_partner_mail_list +msgid "Add to mailing list" +msgstr "Añadir a lista de correo" + +#. module: mass_mailing_partner +#: view:partner.mail.list.wizard:mass_mailing_partner.partner_mail_list_wizard_form +msgid "Cancel" +msgstr "Cancelar" + +#. module: mass_mailing_partner +#: model:ir.model,name:mass_mailing_partner.model_partner_mail_list_wizard +#: view:partner.mail.list.wizard:mass_mailing_partner.partner_mail_list_wizard_form +msgid "Create contact mailing list" +msgstr "Crear lista de correo de contactos" + +#. module: mass_mailing_partner +#: field:partner.mail.list.wizard,create_uid:0 +msgid "Created by" +msgstr "Creado por" + +#. module: mass_mailing_partner +#: field:partner.mail.list.wizard,create_date:0 +msgid "Created on" +msgstr "Creado en" + +#. module: mass_mailing_partner +#: field:partner.mail.list.wizard,id:0 +msgid "ID" +msgstr "ID" + +#. module: mass_mailing_partner +#: field:partner.mail.list.wizard,write_uid:0 +msgid "Last Updated by" +msgstr "Última actualización por" + +#. module: mass_mailing_partner +#: field:partner.mail.list.wizard,write_date:0 +msgid "Last Updated on" +msgstr "Última actualización en" + +#. module: mass_mailing_partner +#: model:ir.model,name:mass_mailing_partner.model_mail_mass_mailing_list +#: field:partner.mail.list.wizard,mail_list_id:0 +#: view:res.partner:mass_mailing_partner.view_res_partner_filter +msgid "Mailing List" +msgstr "Lista de correo" + +#. module: mass_mailing_partner +#: field:res.partner,mass_mailing_contacts_count:0 +msgid "Mailing list number" +msgstr "Nº Listas de correo" + +#. module: mass_mailing_partner +#: view:res.partner:mass_mailing_partner.view_partner_form +msgid "Mailing lists" +msgstr "Listas de correo" + +#. module: mass_mailing_partner +#: field:mail.mass_mailing.list,partner_mandatory:0 +msgid "Mandatory Partner" +msgstr "Empresa obligatoria" + +#. module: mass_mailing_partner +#: model:ir.model,name:mass_mailing_partner.model_mail_mass_mailing_contact +msgid "Mass Mailing Contact" +msgstr "Contacto de lista de correo" + +#. module: mass_mailing_partner +#: field:res.partner,mass_mailing_contacts:0 +msgid "Mass mailing contacts" +msgstr "Contactos de lista de correo" + +#. module: mass_mailing_partner +#: model:ir.model,name:mass_mailing_partner.model_res_partner +#: view:mail.mass_mailing.contact:mass_mailing_partner.view_mail_mass_mailing_contact_search +#: field:mail.mass_mailing.contact,partner_id:0 +msgid "Partner" +msgstr "Empresa" + +#. module: mass_mailing_partner +#: code:addons/mass_mailing_partner/wizard/partner_mail_list_wizard.py:24 +#, python-format +msgid "Partner '%s' has no email." +msgstr "La empresa '%s' no tiene email." + +#. module: mass_mailing_partner +#: field:mail.mass_mailing.list,partner_category:0 +msgid "Partner Tag" +msgstr "Etiqueta de empresa" + +#. module: mass_mailing_partner +#: code:addons/mass_mailing_partner/models/mail_mass_mailing_contact.py:15 +#: sql_constraint:mail.mass_mailing.contact:0 +#, python-format +msgid "Partner already exists in this mailing list." +msgstr "La empresa ya existe en esta lista de correo" + +#. module: mass_mailing_partner +#: field:partner.mail.list.wizard,partner_ids:0 +msgid "Partner ids" +msgstr "IDS de empresas" + +#. module: mass_mailing_partner +#: code:addons/mass_mailing_partner/models/res_partner.py:23 +#, python-format +msgid "This partner '%s' is subscribed to one or more mailing lists. Email must be assigned." +msgstr "Esta empresa '%s' está suscrita a una o más listas de correo. El email debe estar asignado." + +#. module: mass_mailing_partner +#: view:partner.mail.list.wizard:mass_mailing_partner.partner_mail_list_wizard_form +msgid "or" +msgstr "o" + +#. module: mass_mailing_partner +#: view:mail.mass_mailing.contact:mass_mailing_partner.view_mail_mass_mailing_contact_tree +msgid "{'readonly': [('partner_id', '!=', False)]}" +msgstr "" diff --git a/mass_mailing_partner/i18n/mass_mailing_partner.pot b/mass_mailing_partner/i18n/mass_mailing_partner.pot new file mode 100644 index 00000000..e09d240b --- /dev/null +++ b/mass_mailing_partner/i18n/mass_mailing_partner.pot @@ -0,0 +1,140 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * mass_mailing_partner +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 8.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-11-03 14:42+0000\n" +"PO-Revision-Date: 2015-11-03 14:42+0000\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_partner +#: view:partner.mail.list.wizard:mass_mailing_partner.partner_mail_list_wizard_form +msgid "Add contacts to mailing list" +msgstr "" + +#. module: mass_mailing_partner +#: model:ir.actions.act_window,name:mass_mailing_partner.action_partner_mail_list +msgid "Add to mailing list" +msgstr "" + +#. module: mass_mailing_partner +#: view:partner.mail.list.wizard:mass_mailing_partner.partner_mail_list_wizard_form +msgid "Cancel" +msgstr "" + +#. module: mass_mailing_partner +#: model:ir.model,name:mass_mailing_partner.model_partner_mail_list_wizard +#: view:partner.mail.list.wizard:mass_mailing_partner.partner_mail_list_wizard_form +msgid "Create contact mailing list" +msgstr "" + +#. module: mass_mailing_partner +#: field:partner.mail.list.wizard,create_uid:0 +msgid "Created by" +msgstr "" + +#. module: mass_mailing_partner +#: field:partner.mail.list.wizard,create_date:0 +msgid "Created on" +msgstr "" + +#. module: mass_mailing_partner +#: field:partner.mail.list.wizard,id:0 +msgid "ID" +msgstr "" + +#. module: mass_mailing_partner +#: field:partner.mail.list.wizard,write_uid:0 +msgid "Last Updated by" +msgstr "" + +#. module: mass_mailing_partner +#: field:partner.mail.list.wizard,write_date:0 +msgid "Last Updated on" +msgstr "" + +#. module: mass_mailing_partner +#: model:ir.model,name:mass_mailing_partner.model_mail_mass_mailing_list +#: field:partner.mail.list.wizard,mail_list_id:0 +#: view:res.partner:mass_mailing_partner.view_res_partner_filter +msgid "Mailing List" +msgstr "" + +#. module: mass_mailing_partner +#: field:res.partner,mass_mailing_contacts_count:0 +msgid "Mailing list number" +msgstr "" + +#. module: mass_mailing_partner +#: view:res.partner:mass_mailing_partner.view_partner_form +msgid "Mailing lists" +msgstr "" + +#. module: mass_mailing_partner +#: field:mail.mass_mailing.list,partner_mandatory:0 +msgid "Mandatory Partner" +msgstr "" + +#. module: mass_mailing_partner +#: model:ir.model,name:mass_mailing_partner.model_mail_mass_mailing_contact +msgid "Mass Mailing Contact" +msgstr "" + +#. module: mass_mailing_partner +#: field:res.partner,mass_mailing_contacts:0 +msgid "Mass mailing contacts" +msgstr "" + +#. module: mass_mailing_partner +#: model:ir.model,name:mass_mailing_partner.model_res_partner +#: view:mail.mass_mailing.contact:mass_mailing_partner.view_mail_mass_mailing_contact_search +#: field:mail.mass_mailing.contact,partner_id:0 +msgid "Partner" +msgstr "" + +#. module: mass_mailing_partner +#: code:addons/mass_mailing_partner/wizard/partner_mail_list_wizard.py:24 +#, python-format +msgid "Partner '%s' has no email." +msgstr "" + +#. module: mass_mailing_partner +#: field:mail.mass_mailing.list,partner_category:0 +msgid "Partner Tag" +msgstr "" + +#. module: mass_mailing_partner +#: code:addons/mass_mailing_partner/models/mail_mass_mailing_contact.py:15 +#: sql_constraint:mail.mass_mailing.contact:0 +#, python-format +msgid "Partner already exists in this mailing list." +msgstr "" + +#. module: mass_mailing_partner +#: field:partner.mail.list.wizard,partner_ids:0 +msgid "Partner ids" +msgstr "" + +#. module: mass_mailing_partner +#: code:addons/mass_mailing_partner/models/res_partner.py:23 +#, python-format +msgid "This partner '%s' is subscribed to one or more mailing lists. Email must be assigned." +msgstr "" + +#. module: mass_mailing_partner +#: view:partner.mail.list.wizard:mass_mailing_partner.partner_mail_list_wizard_form +msgid "or" +msgstr "" + +#. module: mass_mailing_partner +#: view:mail.mass_mailing.contact:mass_mailing_partner.view_mail_mass_mailing_contact_tree +msgid "{'readonly': [('partner_id', '!=', False)]}" +msgstr "" diff --git a/mass_mailing_partner/models/__init__.py b/mass_mailing_partner/models/__init__.py new file mode 100644 index 00000000..744629bd --- /dev/null +++ b/mass_mailing_partner/models/__init__.py @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- +# See README.rst file on addon root folder for license details + +from . import mail_mass_mailing_contact +from . import res_partner +from . import mail_mass_mailing diff --git a/mass_mailing_partner/models/mail_mass_mailing.py b/mass_mailing_partner/models/mail_mass_mailing.py new file mode 100644 index 00000000..95d062a5 --- /dev/null +++ b/mass_mailing_partner/models/mail_mass_mailing.py @@ -0,0 +1,13 @@ +# -*- coding: utf-8 -*- +# See README.rst file on addon root folder for license details + +from openerp import models, fields + + +class MailMassMailingList(models.Model): + _inherit = 'mail.mass_mailing.list' + + partner_mandatory = fields.Boolean(string="Mandatory Partner", + default=False) + partner_category = fields.Many2one(comodel_name='res.partner.category', + string="Partner Tag") diff --git a/mass_mailing_partner/models/mail_mass_mailing_contact.py b/mass_mailing_partner/models/mail_mass_mailing_contact.py new file mode 100644 index 00000000..04692763 --- /dev/null +++ b/mass_mailing_partner/models/mail_mass_mailing_contact.py @@ -0,0 +1,78 @@ +# -*- coding: utf-8 -*- +# See README.rst file on addon root folder for license details + +from openerp import models, fields, api, _ + + +class MailMassMailingContact(models.Model): + _inherit = 'mail.mass_mailing.contact' + + partner_id = fields.Many2one(comodel_name='res.partner', string="Partner", + domain=[('email', '!=', False)]) + + _sql_constraints = [ + ('partner_list_uniq', 'unique(partner_id, list_id)', + _('Partner already exists in this mailing list.')) + ] + + @api.one + @api.onchange('partner_id') + def _onchange_partner(self): + if self.partner_id: + self.name = self.partner_id.name + self.email = self.partner_id.email + + @api.model + @api.returns('self', lambda x: x.id) + def create(self, vals): + if not vals.get('partner_id'): + vals = self._set_partner(vals) + vals = self._set_name_email(vals) + return super(MailMassMailingContact, self).create(vals) + + @api.one + def write(self, vals): + if vals.get('partner_id', None) is False: + # If removing partner, search again by email + vals = self._set_partner(vals) + vals = self._set_name_email(vals) + return super(MailMassMailingContact, self).write(vals) + + def _prepare_partner(self, vals, mailing_list): + vals = { + 'name': vals.get('name') or vals.get('email'), + 'email': vals.get('email', False), + } + if mailing_list.partner_category: + vals['category_id'] = [(4, mailing_list.partner_category.id, 0)] + return vals + + def _set_partner(self, vals): + email = vals.get('email', self.email) + if not email: + return vals + m_mailing = self.env['mail.mass_mailing.list'] + m_partner = self.env['res.partner'] + list_id = vals.get('list_id', self.list_id.id) + mailing_list = m_mailing.browse(list_id) + # Look for a partner with that email + email = email.strip() + partners = m_partner.search([('email', '=ilike', email)], limit=1) + if partners: + # Partner found + vals['partner_id'] = partners[0].id + elif mailing_list.partner_mandatory: + # Create partner + partner = m_partner.sudo().create( + self._prepare_partner(vals, mailing_list)) + vals['partner_id'] = partner.id + return vals + + def _set_name_email(self, vals): + partner_id = vals.get('partner_id', self.partner_id.id) + if not partner_id: + return vals + partner = self.env['res.partner'].browse(partner_id) + vals['email'] = partner.email + vals['name'] = partner.name + return vals diff --git a/mass_mailing_partner/models/res_partner.py b/mass_mailing_partner/models/res_partner.py new file mode 100644 index 00000000..82d7b4e2 --- /dev/null +++ b/mass_mailing_partner/models/res_partner.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +# See README.rst file on addon root folder for license details + +from openerp import models, fields, api, _ +from openerp.exceptions import ValidationError + + +class ResPartner(models.Model): + _inherit = 'res.partner' + + mass_mailing_contacts = fields.One2many( + comodel_name='mail.mass_mailing.contact', inverse_name='partner_id') + + mass_mailing_contacts_count = fields.Integer( + string='Mailing list number', compute='_count_mass_mailing_contacts', + store=True) + + @api.one + @api.constrains('email') + def _check_email_mass_mailing_contacts(self): + if self.mass_mailing_contacts and not self.email: + raise ValidationError( + _("This partner '%s' is subscribed to one or more " + "mailing lists. Email must be assigned." % self.name)) + + @api.one + @api.depends('mass_mailing_contacts') + def _count_mass_mailing_contacts(self): + self.mass_mailing_contacts_count = len(self.mass_mailing_contacts) + + @api.multi + def write(self, vals): + res = super(ResPartner, self).write(vals) + if vals.get('name') or vals.get('email'): + mm_vals = {} + if vals.get('name'): + mm_vals['name'] = vals['name'] + if vals.get('email'): + mm_vals['name'] = vals['email'] + self.mapped('mass_mailing_contacts').write(mm_vals) + return res diff --git a/mass_mailing_partner/static/description/icon.png b/mass_mailing_partner/static/description/icon.png new file mode 100644 index 00000000..b18b21a1 Binary files /dev/null and b/mass_mailing_partner/static/description/icon.png differ diff --git a/mass_mailing_partner/tests/__init__.py b/mass_mailing_partner/tests/__init__.py new file mode 100644 index 00000000..163ae133 --- /dev/null +++ b/mass_mailing_partner/tests/__init__.py @@ -0,0 +1,5 @@ +# -*- coding: utf-8 -*- +# See README.rst file on addon root folder for license details + +from . import test_mail_mass_mailing_contact, test_res_partner +from . import test_partner_mail_list_wizard diff --git a/mass_mailing_partner/tests/base.py b/mass_mailing_partner/tests/base.py new file mode 100644 index 00000000..af32621f --- /dev/null +++ b/mass_mailing_partner/tests/base.py @@ -0,0 +1,35 @@ +# -*- coding: utf-8 -*- +# See README.rst file on addon root folder for license details + +from openerp.tests.common import TransactionCase + + +class BaseCase(TransactionCase): + def setUp(self): + super(BaseCase, self).setUp() + m_partner_category = self.env['res.partner.category'] + m_mailing_list = self.env['mail.mass_mailing.list'] + self.company_id = self.env.ref('base.main_company') + self.company = self.env['res.company'].browse(self.company_id) + self.partner = self.create_partner({'name': 'Partner test', + 'email': 'partner@test.com'}) + partner_category = m_partner_category.create({'name': 'Category Test'}) + self.mailing_list = m_mailing_list.create({'name': 'List test'}) + self.mailing_list2 = m_mailing_list.create( + {'name': 'List test 2', 'partner_mandatory': True, + 'partner_category': partner_category.id}) + + def create_partner(self, vals): + m_partner = self.env['res.partner'] + return m_partner.create(vals) + + def create_mailing_contact(self, vals): + m_mailing_contact = self.env['mail.mass_mailing.contact'] + return m_mailing_contact.create(vals) + + def check_mailing_contact_partner(self, mailing_contact): + if mailing_contact.partner_id: + self.assertEqual(mailing_contact.partner_id.email, + mailing_contact.email) + self.assertEqual(mailing_contact.partner_id.name, + mailing_contact.name) diff --git a/mass_mailing_partner/tests/test_mail_mass_mailing_contact.py b/mass_mailing_partner/tests/test_mail_mass_mailing_contact.py new file mode 100644 index 00000000..05d73092 --- /dev/null +++ b/mass_mailing_partner/tests/test_mail_mass_mailing_contact.py @@ -0,0 +1,35 @@ +# -*- coding: utf-8 -*- +# See README.rst file on addon root folder for license details + +from . import base +from .. import _match_existing_contacts +from psycopg2 import IntegrityError + + +class MailMassMailingContactCase(base.BaseCase): + + def test_match_existing_contacts(self): + contact = self.create_mailing_contact( + {'email': 'partner@test.com', 'list_id': self.mailing_list.id}) + _match_existing_contacts(self.cr, self.registry) + self.assertEqual(contact.partner_id.id, self.partner.id) + + def test_create_mass_mailing_contact(self): + contact = self.create_mailing_contact( + {'email': 'partner2@test.com', 'name': 'Partner test 2', + 'list_id': self.mailing_list2.id}) + self.check_mailing_contact_partner(contact) + with self.assertRaises(IntegrityError): + self.create_mailing_contact({'email': 'partner2@test.com', + 'list_id': self.mailing_list2.id}) + + def test_write_mass_mailing_contact(self): + contact = self.create_mailing_contact( + {'email': 'partner@test.com', 'list_id': self.mailing_list.id}) + contact.write({'partner_id': False}) + self.check_mailing_contact_partner(contact) + contact2 = self.create_mailing_contact( + {'email': 'partner2@test.com', 'name': 'Partner test 2', + 'list_id': self.mailing_list.id}) + contact.write({'partner_id': False}) + self.assertFalse(contact2.partner_id) diff --git a/mass_mailing_partner/tests/test_partner_mail_list_wizard.py b/mass_mailing_partner/tests/test_partner_mail_list_wizard.py new file mode 100644 index 00000000..c50d2640 --- /dev/null +++ b/mass_mailing_partner/tests/test_partner_mail_list_wizard.py @@ -0,0 +1,24 @@ +# -*- coding: utf-8 -*- +# See README.rst file on addon root folder for license details + +from . import base +from openerp.exceptions import Warning as UserError + + +class PartnerMailListWizardCase(base.BaseCase): + + def test_add_to_mail_list(self): + wizard = self.env['partner.mail.list.wizard'].create( + {'mail_list_id': self.mailing_list.id}) + wizard.partner_ids = [self.partner.id] + wizard.add_to_mail_list() + contact = self.env['mail.mass_mailing.contact'].search([ + ('partner_id', '=', self.partner.id), + ('list_id', '=', self.mailing_list.id)]) + self.check_mailing_contact_partner(contact) + # This line does not create a new contact + wizard.add_to_mail_list() + partner = self.env['res.partner'].create({'name': 'No email partner'}) + wizard.partner_ids = [partner.id] + with self.assertRaises(UserError): + wizard.add_to_mail_list() diff --git a/mass_mailing_partner/tests/test_res_partner.py b/mass_mailing_partner/tests/test_res_partner.py new file mode 100644 index 00000000..a8fb2183 --- /dev/null +++ b/mass_mailing_partner/tests/test_res_partner.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- +# See README.rst file on addon root folder for license details + +from . import base +from openerp.exceptions import ValidationError + + +class ResPartnerCase(base.BaseCase): + + def test_count_mass_mailing_contacts(self): + self.create_mailing_contact({'email': 'partner@test.com', + 'list_id': self.mailing_list.id}) + self.create_mailing_contact({'email': 'partner@test.com', + 'list_id': self.mailing_list2.id}) + self.partner._count_mass_mailing_contacts() + self.assertEqual(self.partner.mass_mailing_contacts_count, 2) + + def test_write_res_partner(self): + contact = self.create_mailing_contact( + {'email': 'partner@test.com', 'list_id': self.mailing_list.id}) + self.partner.write({'name': 'Changed', 'email': 'partner@changed.com'}) + self.assertEqual(contact.name, self.partner.name) + self.assertEqual(contact.email, self.partner.email) + with self.assertRaises(ValidationError): + self.partner.write({'email': False}) diff --git a/mass_mailing_partner/views/mail_mass_mailing_contact_view.xml b/mass_mailing_partner/views/mail_mass_mailing_contact_view.xml new file mode 100644 index 00000000..37c4ccbc --- /dev/null +++ b/mass_mailing_partner/views/mail_mass_mailing_contact_view.xml @@ -0,0 +1,39 @@ + + + + + + mail.mass_mailing.contact.tree.partner + mail.mass_mailing.contact + + + + + + + {'readonly': [('partner_id', '!=', False)]} + + + {'readonly': [('partner_id', '!=', False)]} + + + + + + mail.mass_mailing.contact.search.partner + mail.mass_mailing.contact + + + + + + + + + + + + + diff --git a/mass_mailing_partner/views/mail_mass_mailing_view.xml b/mass_mailing_partner/views/mail_mass_mailing_view.xml new file mode 100644 index 00000000..fff295c4 --- /dev/null +++ b/mass_mailing_partner/views/mail_mass_mailing_view.xml @@ -0,0 +1,22 @@ + + + + + + mail.mass_mailing.list.form + mail.mass_mailing.list + + + + + + + + + + + + + + + diff --git a/mass_mailing_partner/views/res_partner_view.xml b/mass_mailing_partner/views/res_partner_view.xml new file mode 100644 index 00000000..da04ad92 --- /dev/null +++ b/mass_mailing_partner/views/res_partner_view.xml @@ -0,0 +1,39 @@ + + + + + + Partner Form with mailing contacts + res.partner + + +
+ +
+
+
+ + + Partner Search with mailing contacts + res.partner + + 20 + + + + + + + +
+
diff --git a/mass_mailing_partner/wizard/__init__.py b/mass_mailing_partner/wizard/__init__.py new file mode 100644 index 00000000..d9b71887 --- /dev/null +++ b/mass_mailing_partner/wizard/__init__.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- +# See README.rst file on addon root folder for license details + +from . import partner_mail_list_wizard diff --git a/mass_mailing_partner/wizard/partner_mail_list_wizard.py b/mass_mailing_partner/wizard/partner_mail_list_wizard.py new file mode 100644 index 00000000..0e6d67d0 --- /dev/null +++ b/mass_mailing_partner/wizard/partner_mail_list_wizard.py @@ -0,0 +1,34 @@ +# -*- coding: utf-8 -*- +# See README.rst file on addon root folder for license details + +from openerp import models, api, fields, _ +from openerp.exceptions import Warning as UserError + + +class PartnerMailListWizard(models.TransientModel): + _name = "partner.mail.list.wizard" + _description = "Create contact mailing list" + + mail_list_id = fields.Many2one(comodel_name="mail.mass_mailing.list", + string="Mailing List") + partner_ids = fields.Many2many( + comodel_name="res.partner", relation="mail_list_wizard_partner", + default=lambda self: self.env.context.get("active_ids")) + + @api.multi + def add_to_mail_list(self): + contact_obj = self.env['mail.mass_mailing.contact'] + for partner in self.partner_ids: + if not partner.email: + raise UserError(_("Partner '%s' has no email.") % partner.name) + criteria = [('email', '=', partner.email), + ('list_id', '=', self.mail_list_id.id)] + contact_test = contact_obj.search(criteria) + if contact_test: + continue + contact_vals = { + 'email': partner.email, + 'name': partner.name, + 'list_id': self.mail_list_id.id + } + contact_obj.create(contact_vals) diff --git a/mass_mailing_partner/wizard/partner_mail_list_wizard.xml b/mass_mailing_partner/wizard/partner_mail_list_wizard.xml new file mode 100644 index 00000000..28125056 --- /dev/null +++ b/mass_mailing_partner/wizard/partner_mail_list_wizard.xml @@ -0,0 +1,32 @@ + + + + + + + + partner.mail.list.form + partner.mail.list.wizard + +
+ + + + +
+
+
+ +
+