[FIX] mass_mailing : restore import mass_mailing.contact into mass_mailing.list

Since the opt out per mailing list, the intermediate model was used
to list all the recipient of a mailing list. The side effect was that
importing new contacts into mailing list was not possible anymore.
Also, creation of a new contact into a mailing list was made indirectly
by creating a new many2many record between contaxct and list, which was
not really user friendly.

This commit restores the mailing contact model as the view of the mailing
list recipients. In other terms, the contact import is restored.
An opt-out computed field as been added to be able to filter on opted out
contact inside the mailing list recipients view.
This opt_out field SHOULD NOT be used in a form view as it need the active
mailing list id in the context in order to be computable and searchable.
This field has no sense without this active mailing list id context.

Task ID 1891228
Linked with blacklist and opt out per mailing task (ID 33224)
Closes PR #27632
This commit is contained in:
David Beguin
2018-11-05 15:15:43 +00:00
parent d226f8b4ff
commit d63e72853b
2 changed files with 45 additions and 4 deletions
@@ -76,6 +76,7 @@ class MassMailingContactListRel(models.Model):
return super(MassMailingContactListRel, self).write(vals)
def action_open_mailing_list_contact(self):
"""TODO DBE : To remove - Deprecated"""
contact_id = self.contact_id
action = {
'name': _(contact_id.name),
@@ -220,12 +221,42 @@ class MassMailingContact(models.Model):
message_bounce = fields.Integer(string='Bounced', help='Counter of the number of bounced emails for this contact.', default=0)
country_id = fields.Many2one('res.country', string='Country')
tag_ids = fields.Many2many('res.partner.category', string='Tags')
opt_out = fields.Boolean('Opt Out', compute='_compute_opt_out', search='_search_opt_out',
help='Opt out flag for a specific mailing list.'
'This field should not be used in a view without a unique and active mailing list context.')
@api.depends('email')
def _compute_is_email_valid(self):
for record in self:
record.is_email_valid = re.match(EMAIL_PATTERN, record.email)
@api.model
def _search_opt_out(self, operator, value):
# Assumes operator is '=' or '!=' and value is True or False
if operator != '=':
if operator == '!=' and isinstance(value, bool):
value = not value
else:
raise NotImplementedError()
if 'default_list_ids' in self._context and isinstance(self._context['default_list_ids'], (list, tuple)) and len(self._context['default_list_ids']) == 1:
[active_list_id] = self._context['default_list_ids']
contacts = self.env['mail.mass_mailing.list_contact_rel'].search([('list_id', '=', active_list_id)])
return [('id', 'in', [record.contact_id.id for record in contacts if record.opt_out == value])]
else:
raise UserError('Search opt out cannot be executed without a unique and valid active mailing list context.')
@api.depends('subscription_list_ids')
def _compute_opt_out(self):
if 'default_list_ids' in self._context and isinstance(self._context['default_list_ids'], (list, tuple)) and len(self._context['default_list_ids']) == 1:
[active_list_id] = self._context['default_list_ids']
for record in self:
active_subscription_list = record.subscription_list_ids.filtered(lambda l: l.list_id.id == active_list_id)
record.opt_out = active_subscription_list.opt_out
else:
for record in self:
record.opt_out = False
def get_name_email(self, name):
name, email = self.env['res.partner']._parse_partner_name(name)
if name and not email:
@@ -11,6 +11,7 @@
<!-- MAILING CONTACT -->
<record model="ir.ui.view" id="mail_mass_mailing_list_contact_rel_view_form">
<!--TODO DBE : To remove - Deprecated -->
<field name="name">mail.mass_mailing.list_contact_rel.view.form</field>
<field name="model">mail.mass_mailing.list_contact_rel</field>
<field name="priority">10</field>
@@ -36,6 +37,7 @@
</record>
<record model="ir.ui.view" id="mail_mass_mailing_list_contact_rel_list_contact_view_tree">
<!--TODO DBE : To remove - Deprecated -->
<field name="name">mail.mass_mailing.list_contact_rel.list_contact.view.tree</field>
<field name="model">mail.mass_mailing.list_contact_rel</field>
<field name="arch" type="xml">
@@ -51,6 +53,7 @@
</record>
<record model="ir.ui.view" id="mail_mass_mailing_list_contact_view_search">
<!--TODO DBE : To remove - Deprecated -->
<field name="name">mail.mass_mailing.list_contact_rel.view.search</field>
<field name="model">mail.mass_mailing.list_contact_rel</field>
<field name="arch" type="xml">
@@ -85,8 +88,14 @@
string="Name / Email"/>
<field name="tag_ids"/>
<field name="list_ids"/>
<separator/>
<filter string="Valid Recipients" name="valid_recipients" domain="[('opt_out', '=', False), ('is_blacklisted', '=', False), ('is_email_valid', '=', True)]"
invisible="'default_list_ids' not in context"/>
<separator/>
<filter string="Exclude Blacklisted" name="not_blacklisted" domain="[('is_blacklisted', '=', False)]"/>
<separator/>
<filter string="Exclude Opt Out" name="not_opt_out" domain="[('opt_out', '=', False)]"
invisible="'default_list_ids' not in context"/>
<separator/>
<separator/>
<filter string="Exclude Bounced" name="not_bounced" domain="[('message_bounce', '&lt;', 3)]"/>
@@ -109,6 +118,7 @@
<field name="company_name"/>
<field name="email"/>
<field name="message_bounce"/>
<field name="opt_out" invisible="'default_list_ids' not in context"/>
<field name="is_blacklisted"/>
</tree>
</field>
@@ -238,7 +248,7 @@
<field name="res_model">mail.mass_mailing.contact</field>
<field name="view_type">form</field>
<field name="view_mode">tree,kanban,form,graph,pivot</field>
<field name="context">{'search_default_not_blacklisted': 1}</field>
<field name="context">{'search_default_valid_recipient': 1}</field>
<field name="help" type="html">
<p class="o_view_nocontent_smiling_face">
Create a contact in your address book
@@ -250,11 +260,11 @@
<record model="ir.actions.act_window" id="action_view_mass_mailing_contacts_from_list">
<field name="name">Recipients</field>
<field name="res_model">mail.mass_mailing.list_contact_rel</field>
<field name="res_model">mail.mass_mailing.contact</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form,graph</field>
<field name="domain">[('list_id', 'in', [active_id])]</field>
<field name="context">{'search_default_valid_recipients': 1, 'default_list_id': active_id}</field>
<field name="domain">[('list_ids', 'in', [active_id])]</field>
<field name="context">{'search_default_valid_recipients': 1, 'default_list_ids': [active_id]}</field>
<field name="help" type="html">
<p class="o_view_nocontent_smiling_face">
Create a new recipient