diff --git a/addons/mass_mailing/models/mailing_contact.py b/addons/mass_mailing/models/mailing_contact.py index 1fa42ad9135..567bba5d1b3 100644 --- a/addons/mass_mailing/models/mailing_contact.py +++ b/addons/mass_mailing/models/mailing_contact.py @@ -6,6 +6,46 @@ from odoo.exceptions import UserError from odoo.osv import expression +class MassMailingContactListRel(models.Model): + """ Intermediate model between mass mailing list and mass mailing contact + Indicates if a contact is opted out for a particular list + """ + _name = 'mailing.contact.subscription' + _description = 'Mass Mailing Subscription Information' + _table = 'mailing_contact_list_rel' + _rec_name = 'contact_id' + + contact_id = fields.Many2one('mailing.contact', string='Contact', ondelete='cascade', required=True) + list_id = fields.Many2one('mailing.list', string='Mailing List', ondelete='cascade', required=True) + opt_out = fields.Boolean(string='Opt Out', + help='The contact has chosen not to receive mails anymore from this list', default=False) + unsubscription_date = fields.Datetime(string='Unsubscription Date') + message_bounce = fields.Integer(related='contact_id.message_bounce', store=False, readonly=False) + is_blacklisted = fields.Boolean(related='contact_id.is_blacklisted', store=False, readonly=False) + + _sql_constraints = [ + ('unique_contact_list', 'unique (contact_id, list_id)', + 'A mailing contact cannot subscribe to the same mailing list multiple times.') + ] + + @api.model_create_multi + def create(self, vals_list): + now = fields.Datetime.now() + for vals in vals_list: + if 'opt_out' in vals and not vals.get('unsubscription_date'): + vals['unsubscription_date'] = now if vals['opt_out'] else False + if vals.get('unsubscription_date'): + vals['opt_out'] = True + return super().create(vals_list) + + def write(self, vals): + if 'opt_out' in vals and 'unsubscription_date' not in vals: + vals['unsubscription_date'] = fields.Datetime.now() if vals['opt_out'] else False + if vals.get('unsubscription_date'): + vals['opt_out'] = True + return super(MassMailingContactListRel, self).write(vals) + + class MassMailingContact(models.Model): """Model of a contact. This model is different from the partner model because it holds only some basic information: name, email. The purpose is to diff --git a/addons/mass_mailing/tests/test_mailing_list.py b/addons/mass_mailing/tests/test_mailing_list.py index 9ce0e538853..97dbdd709a9 100644 --- a/addons/mass_mailing/tests/test_mailing_list.py +++ b/addons/mass_mailing/tests/test_mailing_list.py @@ -1,6 +1,9 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. +from datetime import datetime +from freezegun import freeze_time + from odoo import exceptions from odoo.addons.mass_mailing.tests.common import MassMailCommon from odoo.tests.common import Form, users @@ -99,6 +102,19 @@ class TestMailingListMerge(MassMailCommon): new = new.with_context(default_list_ids=[list_id]) self.assertFalse(any(contact.opt_out for contact in new)) + with freeze_time('2022-01-01 12:00'): + contact_form = Form(self.env['mailing.contact']) + contact_form.name = 'Contact_test' + with contact_form.subscription_list_ids.new() as subscription: + subscription.list_id = self.mailing_list_1 + subscription.opt_out = True + with contact_form.subscription_list_ids.new() as subscription: + subscription.list_id = self.mailing_list_2 + subscription.opt_out = False + contact = contact_form.save() + self.assertEqual(contact.subscription_list_ids[0].unsubscription_date, datetime(2022, 1, 1, 12, 0, 0)) + self.assertFalse(contact.subscription_list_ids[1].unsubscription_date) + @users('user_marketing') def test_mailing_list_contact_copy_in_context_of_mailing_list(self): MailingContact = self.env['mailing.contact']