diff options
| author | Thibault Delavallée <tde@odoo.com> | 2019-07-17 09:26:42 +0000 |
|---|---|---|
| committer | Thibault Delavallée <tde@odoo.com> | 2019-07-17 15:39:06 +0000 |
| commit | 2896aad34e797b6ca65a8efe3c5d71f31500a9a2 (patch) | |
| tree | 81f2298b04182860e84f2ca9815f313cc0c75ffc /addons/mass_mailing/models/mailing_trace.py | |
| parent | 20dfba6e11ac4553509c1a3516c6453b8f8023e7 (diff) | |
[REF] mass_mailing: rename mail.mail.statistics and reporting model
PURPOSE
Mass mailing is currently a bit messy. As SMS will be added as a way to notify
people in mass through SMS let us take this opportunity to somehow clean this
application: organization, light code cleaning, model renaming.
SPECIFICATIONS
Rename mail.mail.statistics to mailing.trace and mail.statistics.report
to mail.trace.report. Rationale :
* mail.mail.statistics is linked to mail.mail model. Soon this model will
hold data related to SMS sending. It makes sense to be broader in the
naming;
* mailing.trace is more inlined with marketing.trace model that is the
marketing automation model using it in marketing automation (enterprise
application);
* mailing.trace is shorter to write;
* mail.statistics.report model should sense to be updated at the same
time;
MIGRATION
mail.mail.statistics model -> mailing.trace
mail_mail_statistics table -> mailing_trace
mail.statistics.report model -> mail.trace.report
fields updated (w column change)
* link.tracker.click: mail_stat_id -> mailing_trace_id
fields updated (no column change)
* mail.mail: statistics_ids -> mailing_trace_ids
* mail.mass_mailing: statistics_ids -> mailing_trace_ids
LINKS
Task ID 2037906
Preparing task ID 1997464 (SMS addition in mass mailing)
PR #34938
Diffstat (limited to 'addons/mass_mailing/models/mailing_trace.py')
| -rw-r--r-- | addons/mass_mailing/models/mailing_trace.py | 117 |
1 files changed, 117 insertions, 0 deletions
diff --git a/addons/mass_mailing/models/mailing_trace.py b/addons/mass_mailing/models/mailing_trace.py new file mode 100644 index 00000000000..9f6556ae3ef --- /dev/null +++ b/addons/mass_mailing/models/mailing_trace.py @@ -0,0 +1,117 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo import api, fields, models + + +class MailingTrace(models.Model): + """ MailingTrace models the statistics collected about emails. Those statistics + are stored in a separated model and table to avoid bloating the mail_mail table + with statistics values. This also allows to delete emails send with mass mailing + without loosing the statistics about them. """ + _name = 'mailing.trace' + _description = 'Mailing Statistics' + _rec_name = 'message_id' + _order = 'message_id' + + # mail data + mail_mail_id = fields.Many2one('mail.mail', string='Mail', index=True) + mail_mail_id_int = fields.Integer( + string='Mail ID (tech)', + help='ID of the related mail_mail. This field is an integer field because ' + 'the related mail_mail can be deleted separately from its statistics. ' + 'However the ID is needed for several action and controllers.', + index=True, + ) + email = fields.Char(string="Recipient email address") + message_id = fields.Char(string='Message-ID') + # document + model = fields.Char(string='Document model') + res_id = fields.Integer(string='Document ID') + # campaign / wave data + mass_mailing_id = fields.Many2one('mail.mass_mailing', string='Mass Mailing', index=True) + mass_mailing_campaign_id = fields.Many2one( + related='mass_mailing_id.mass_mailing_campaign_id', + string='Mass Mailing Campaign', + store=True, readonly=True, index=True) + # Bounce and tracking + ignored = fields.Datetime(help='Date when the email has been invalidated. ' + 'Invalid emails are blacklisted, opted-out or invalid email format') + scheduled = fields.Datetime(help='Date when the email has been created', default=fields.Datetime.now) + sent = fields.Datetime(help='Date when the email has been sent') + exception = fields.Datetime(help='Date of technical error leading to the email not being sent') + opened = fields.Datetime(help='Date when the email has been opened the first time') + replied = fields.Datetime(help='Date when this email has been replied for the first time.') + bounced = fields.Datetime(help='Date when this email has bounced.') + # Link tracking + links_click_ids = fields.One2many('link.tracker.click', 'mailing_trace_id', string='Links click') + clicked = fields.Datetime(help='Date when customer clicked on at least one tracked link') + # Status + state = fields.Selection(compute="_compute_state", + selection=[('outgoing', 'Outgoing'), + ('exception', 'Exception'), + ('sent', 'Sent'), + ('opened', 'Opened'), + ('replied', 'Replied'), + ('bounced', 'Bounced'), + ('ignored', 'Ignored')], store=True) + state_update = fields.Datetime(compute="_compute_state", string='State Update', + help='Last state update of the mail', + store=True) + + @api.depends('sent', 'opened', 'clicked', 'replied', 'bounced', 'exception', 'ignored') + def _compute_state(self): + self.update({'state_update': fields.Datetime.now()}) + for stat in self: + if stat.ignored: + stat.state = 'ignored' + elif stat.exception: + stat.state = 'exception' + elif stat.opened or stat.clicked: + stat.state = 'opened' + elif stat.replied: + stat.state = 'replied' + elif stat.bounced: + stat.state = 'bounced' + elif stat.sent: + stat.state = 'sent' + else: + stat.state = 'outgoing' + + @api.model + def create(self, values): + if 'mail_mail_id' in values: + values['mail_mail_id_int'] = values['mail_mail_id'] + res = super(MailingTrace, self).create(values) + return res + + def _get_records(self, mail_mail_ids=None, mail_message_ids=None, domain=None): + if not self.ids and mail_mail_ids: + base_domain = [('mail_mail_id_int', 'in', mail_mail_ids)] + elif not self.ids and mail_message_ids: + base_domain = [('message_id', 'in', mail_message_ids)] + else: + base_domain = [('id', 'in', self.ids)] + if domain: + base_domain = ['&'] + domain + base_domain + return self.search(base_domain) + + def set_opened(self, mail_mail_ids=None, mail_message_ids=None): + traces = self._get_records(mail_mail_ids, mail_message_ids, [('opened', '=', False)]) + traces.write({'opened': fields.Datetime.now(), 'bounced': False}) + return traces + + def set_clicked(self, mail_mail_ids=None, mail_message_ids=None): + traces = self._get_records(mail_mail_ids, mail_message_ids, [('clicked', '=', False)]) + traces.write({'clicked': fields.Datetime.now()}) + return traces + + def set_replied(self, mail_mail_ids=None, mail_message_ids=None): + traces = self._get_records(mail_mail_ids, mail_message_ids, [('replied', '=', False)]) + traces.write({'replied': fields.Datetime.now()}) + return traces + + def set_bounced(self, mail_mail_ids=None, mail_message_ids=None): + traces = self._get_records(mail_mail_ids, mail_message_ids, [('bounced', '=', False), ('opened', '=', False)]) + traces.write({'bounced': fields.Datetime.now()}) + return traces |
