From 849df3cefa39a2b9d0b1970fd67297a583473088 Mon Sep 17 00:00:00 2001 From: Antonio Espinosa Date: Fri, 25 Nov 2016 19:03:11 +0100 Subject: [PATCH] [8.0][FIX][mail_tracking] Use event recipient address to find partners and contacts to bounce (#133) --- mail_tracking/models/mail_tracking_email.py | 22 +++++++++++++------ mail_tracking/models/mail_tracking_event.py | 17 ++++++++++++++ mail_tracking/models/res_partner.py | 2 +- .../models/mail_mass_mailing_contact.py | 5 +++-- .../models/mail_tracking_email.py | 13 +++++++---- 5 files changed, 45 insertions(+), 14 deletions(-) diff --git a/mail_tracking/models/mail_tracking_email.py b/mail_tracking/models/mail_tracking_email.py index c81bdd946a..2dfd2d8da9 100644 --- a/mail_tracking/models/mail_tracking_email.py +++ b/mail_tracking/models/mail_tracking_email.py @@ -195,11 +195,16 @@ def _get_mail_tracking_img(self): }) @api.multi - def _partners_email_bounced_set(self, reason): - for tracking_email in self: + def _partners_email_bounced_set(self, reason, event=None): + recipients = [] + if event and event.recipient_address: + recipients.append(event.recipient_address) + else: + recipients = list(filter(None, self.mapped('recipient_address'))) + for recipient in recipients: self.env['res.partner'].search([ - ('email', '=ilike', tracking_email.recipient_address) - ]).email_bounced_set(tracking_email, reason) + ('email', '=ilike', recipient) + ]).email_bounced_set(self, reason, event=event) @api.multi def smtp_error(self, mail_server, smtp_server, exception): @@ -293,11 +298,14 @@ def event_create(self, event_type, metadata): if not other_ids: vals = tracking_email._event_prepare(event_type, metadata) if vals: - event_ids += event_ids.sudo().create(vals) + events = event_ids.sudo().create(vals) + if event_type in {'hard_bounce', 'spam', 'reject'}: + for event in events: + self.sudo()._partners_email_bounced_set( + event_type, event=event) + event_ids += events else: _logger.debug("Concurrent event '%s' discarded", event_type) - if event_type in {'hard_bounce', 'spam', 'reject'}: - self.sudo()._partners_email_bounced_set(event_type) return event_ids @api.model diff --git a/mail_tracking/models/mail_tracking_event.py b/mail_tracking/models/mail_tracking_event.py index c68d957a19..ac3fab1d29 100644 --- a/mail_tracking/models/mail_tracking_event.py +++ b/mail_tracking/models/mail_tracking_event.py @@ -2,6 +2,7 @@ # © 2016 Antonio Espinosa - # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +import re import time from datetime import datetime @@ -16,6 +17,9 @@ class MailTrackingEvent(models.Model): _description = 'MailTracking event' recipient = fields.Char(string="Recipient", readonly=True) + recipient_address = fields.Char( + string='Recipient email address', readonly=True, store=True, + compute='_compute_recipient_address', index=True) timestamp = fields.Float( string='UTC timestamp', readonly=True, digits=dp.get_precision('MailTracking Timestamp')) @@ -51,6 +55,19 @@ class MailTrackingEvent(models.Model): error_description = fields.Char(string='Error description', readonly=True) error_details = fields.Text(string='Error details', readonly=True) + @api.multi + @api.depends('recipient') + def _compute_recipient_address(self): + for email in self: + if email.recipient: + matches = re.search(r'<(.*@.*)>', email.recipient) + if matches: + email.recipient_address = matches.group(1).lower() + else: + email.recipient_address = email.recipient.lower() + else: + email.recipient_address = False + @api.multi @api.depends('time') def _compute_date(self): diff --git a/mail_tracking/models/res_partner.py b/mail_tracking/models/res_partner.py index faa1db8850..6494b744b9 100644 --- a/mail_tracking/models/res_partner.py +++ b/mail_tracking/models/res_partner.py @@ -36,7 +36,7 @@ def _compute_tracking_emails_count(self): partner.tracking_emails_count = count @api.multi - def email_bounced_set(self, tracking_email, reason): + def email_bounced_set(self, tracking_emails, reason, event=None): """Inherit this method to make any other actions to partners""" partners = self.filtered(lambda r: not r.email_bounced) return partners.write({'email_bounced': True}) diff --git a/mail_tracking_mass_mailing/models/mail_mass_mailing_contact.py b/mail_tracking_mass_mailing/models/mail_mass_mailing_contact.py index 5470d063e7..4edbcf6bb0 100644 --- a/mail_tracking_mass_mailing/models/mail_mass_mailing_contact.py +++ b/mail_tracking_mass_mailing/models/mail_mass_mailing_contact.py @@ -21,8 +21,9 @@ def _compute_email_score(self): email_score_from_email(contact.email) @api.multi - def email_bounced_set(self, tracking_email, reason): - return self.write({'email_bounced': True}) + def email_bounced_set(self, tracking_emails, reason, event=None): + contacts = self.filtered(lambda r: not r.email_bounced) + return contacts.write({'email_bounced': True}) @api.multi def write(self, vals): diff --git a/mail_tracking_mass_mailing/models/mail_tracking_email.py b/mail_tracking_mass_mailing/models/mail_tracking_email.py index c5142c4510..83aca64fcd 100644 --- a/mail_tracking_mass_mailing/models/mail_tracking_email.py +++ b/mail_tracking_mass_mailing/models/mail_tracking_email.py @@ -32,11 +32,16 @@ def create(self, vals): return tracking @api.multi - def _contacts_email_bounced_set(self, reason): - for tracking_email in self: + def _contacts_email_bounced_set(self, reason, event=None): + recipients = [] + if event and event.recipient_address: + recipients.append(event.recipient_address) + else: + recipients = list(filter(None, self.mapped('recipient_address'))) + for recipient in recipients: self.env['mail.mass_mailing.contact'].search([ - ('email', '=ilike', tracking_email.recipient_address) - ]).email_bounced_set(tracking_email, reason) + ('email', '=ilike', recipient) + ]).email_bounced_set(self, reason, event=event) @api.multi def smtp_error(self, mail_server, smtp_server, exception):