diff --git a/mail_tracking/models/mail_tracking_email.py b/mail_tracking/models/mail_tracking_email.py index 32b5d7d9..97c926d4 100644 --- a/mail_tracking/models/mail_tracking_email.py +++ b/mail_tracking/models/mail_tracking_email.py @@ -183,12 +183,19 @@ class MailTrackingEmail(models.Model): 'tracking_email_id': self.id, }) - def _partners_email_bounced_set(self, reason): - for tracking_email in self: + @api.multi + 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): self.sudo().write({ 'error_smtp_server': tools.ustr(smtp_server), @@ -199,6 +206,7 @@ class MailTrackingEmail(models.Model): self.sudo()._partners_email_bounced_set('error') return True + @api.multi def tracking_img_add(self, email): self.ensure_one() tracking_url = self._get_mail_tracking_img() @@ -226,6 +234,7 @@ class MailTrackingEmail(models.Model): }) return True + @api.multi def _tracking_sent_prepare(self, mail_server, smtp_server, message, message_id): self.ensure_one() @@ -271,6 +280,7 @@ class MailTrackingEmail(models.Model): concurrent_event_ids = m_event.search(domain) return concurrent_event_ids + @api.multi def event_create(self, event_type, metadata): event_ids = self.env['mail.tracking.event'] for tracking_email in self: @@ -278,11 +288,14 @@ class MailTrackingEmail(models.Model): 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 3bd0fda7..fdcc0086 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,20 @@ 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): for email in self: diff --git a/mail_tracking/models/res_partner.py b/mail_tracking/models/res_partner.py index 8d36c7c4..7360e648 100644 --- a/mail_tracking/models/res_partner.py +++ b/mail_tracking/models/res_partner.py @@ -33,7 +33,7 @@ class ResPartner(models.Model): ]) @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})