diff --git a/addons/mass_mailing/__manifest__.py b/addons/mass_mailing/__manifest__.py index fd1e0c8b631..10c3939ea80 100644 --- a/addons/mass_mailing/__manifest__.py +++ b/addons/mass_mailing/__manifest__.py @@ -28,13 +28,13 @@ 'wizard/test_mailing_views.xml', 'wizard/mass_mailing_schedule_date_views.xml', 'views/mass_mailing_views_menus.xml', - 'views/mass_mailing_stats_views.xml', + 'views/mailing_trace_views.xml', 'views/link_tracker_views.xml', 'views/mass_mailing_contact_views.xml', 'views/mass_mailing_list_views.xml', 'views/mass_mailing_views.xml', 'views/res_config_settings_views.xml', - 'report/mass_mailing_stats_report_views.xml', + 'report/mailing_trace_report_views.xml', 'views/assets.xml', 'views/mass_mailing_templates_portal.xml', 'views/themes_templates.xml', diff --git a/addons/mass_mailing/controllers/main.py b/addons/mass_mailing/controllers/main.py index 0d3c563bc6a..4470bb75dfa 100644 --- a/addons/mass_mailing/controllers/main.py +++ b/addons/mass_mailing/controllers/main.py @@ -94,15 +94,15 @@ class MassMailController(http.Controller): @http.route('/mail/track//blank.gif', type='http', auth='public') def track_mail_open(self, mail_id, **post): """ Email tracking. """ - request.env['mail.mail.statistics'].sudo().set_opened(mail_mail_ids=[mail_id]) + request.env['mailing.trace'].sudo().set_opened(mail_mail_ids=[mail_id]) response = werkzeug.wrappers.Response() response.mimetype = 'image/gif' response.data = base64.b64decode(b'R0lGODlhAQABAIAAANvf7wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==') return response - @http.route('/r//m/', type='http', auth="public") - def full_url_redirect(self, code, stat_id, **post): + @http.route('/r//m/', type='http', auth="public") + def full_url_redirect(self, code, mailing_trace_id, **post): # don't assume geoip is set, it is part of the website module # which mass_mailing doesn't depend on country_code = request.session.get('geoip', False) and request.session.geoip.get('country_code', False) @@ -111,7 +111,7 @@ class MassMailController(http.Controller): code, ip=request.httprequest.remote_addr, country_code=country_code, - mail_stat_id=stat_id + mailing_trace_id=mailing_trace_id ) return werkzeug.utils.redirect(request.env['link.tracker'].get_url_from_code(code), 301) diff --git a/addons/mass_mailing/data/mass_mailing_demo.xml b/addons/mass_mailing/data/mass_mailing_demo.xml index b2054c5636d..172d90873bd 100644 --- a/addons/mass_mailing/data/mass_mailing_demo.xml +++ b/addons/mass_mailing/data/mass_mailing_demo.xml @@ -198,7 +198,7 @@ - + 1111000@odoo.com res.partner @@ -207,7 +207,7 @@ - + 1111001@odoo.com res.partner @@ -216,7 +216,7 @@ - + 1111002@odoo.com res.partner @@ -224,7 +224,7 @@ - + 1111003@odoo.com res.partner @@ -232,7 +232,7 @@ - + 1111004@odoo.com res.partner @@ -240,7 +240,7 @@ - + 1111004@odoo.com res.partner @@ -248,7 +248,7 @@ - + 1111004@odoo.com res.partner @@ -264,7 +264,7 @@ use="code"/> 100.01.02.03 BE - + 100.01.02.03 BE - + 100.01.02.04 BE - + 100.01.02.04 BE - + 100.01.02.05 BE - + diff --git a/addons/mass_mailing/models/__init__.py b/addons/mass_mailing/models/__init__.py index afeb0313925..d00a7590cf8 100644 --- a/addons/mass_mailing/models/__init__.py +++ b/addons/mass_mailing/models/__init__.py @@ -5,7 +5,7 @@ from . import link_tracker from . import mass_mailing_contact from . import mass_mailing_list from . import mass_mailing -from . import mass_mailing_stats +from . import mailing_trace from . import mail_mail from . import mail_template from . import mail_thread diff --git a/addons/mass_mailing/models/link_tracker.py b/addons/mass_mailing/models/link_tracker.py index 2b20b007a4b..c33dae7731e 100644 --- a/addons/mass_mailing/models/link_tracker.py +++ b/addons/mass_mailing/models/link_tracker.py @@ -14,22 +14,22 @@ class LinkTracker(models.Model): class LinkTrackerClick(models.Model): _inherit = "link.tracker.click" - mail_stat_id = fields.Many2one('mail.mail.statistics', string='Mail Statistics') + mailing_trace_id = fields.Many2one('mailing.trace', string='Mail Statistics') mass_mailing_id = fields.Many2one('mail.mass_mailing', string='Mass Mailing') mass_mailing_campaign_id = fields.Many2one('mail.mass_mailing.campaign', string='Mass Mailing Campaign') def _prepare_click_values_from_route(self, **route_values): click_values = super(LinkTrackerClick, self)._prepare_click_values_from_route(**route_values) - if click_values.get('mail_stat_id'): - stat_sudo = self.env['mail.mail.statistics'].sudo().browse(route_values['mail_stat_id']).exists() - if not stat_sudo: - click_values['mail_stat_id'] = False + if click_values.get('mailing_trace_id'): + trace_sudo = self.env['mailing.trace'].sudo().browse(route_values['mailing_trace_id']).exists() + if not trace_sudo: + click_values['mailing_trace_id'] = False else: if not click_values.get('mass_mailing_campaign_id'): - click_values['mass_mailing_campaign_id'] = stat_sudo.mass_mailing_campaign_id.id + click_values['mass_mailing_campaign_id'] = trace_sudo.mass_mailing_campaign_id.id if not click_values.get('mass_mailing_id'): - click_values['mass_mailing_id'] = stat_sudo.mass_mailing_id.id + click_values['mass_mailing_id'] = trace_sudo.mass_mailing_id.id return click_values @@ -37,8 +37,8 @@ class LinkTrackerClick(models.Model): def add_click(self, code, **route_values): click = super(LinkTrackerClick, self).add_click(code, **route_values) - if click and click.mail_stat_id: - click.mail_stat_id.set_opened() - click.mail_stat_id.set_clicked() + if click and click.mailing_trace_id: + click.mailing_trace_id.set_opened() + click.mailing_trace_id.set_clicked() return click diff --git a/addons/mass_mailing/models/mail_mail.py b/addons/mass_mailing/models/mail_mail.py index a4de6be6972..1dcb643b1e7 100644 --- a/addons/mass_mailing/models/mail_mail.py +++ b/addons/mass_mailing/models/mail_mail.py @@ -14,16 +14,16 @@ class MailMail(models.Model): _inherit = ['mail.mail'] mailing_id = fields.Many2one('mail.mass_mailing', string='Mass Mailing') - statistics_ids = fields.One2many('mail.mail.statistics', 'mail_mail_id', string='Statistics') + mailing_trace_ids = fields.One2many('mailing.trace', 'mail_mail_id', string='Statistics') @api.model def create(self, values): - """ Override mail_mail creation to create an entry in mail.mail.statistics """ + """ Override mail_mail creation to create an entry in mailing.trace """ # TDE note: should be after 'all values computed', to have values (FIXME after merging other branch holding create refactoring) mail = super(MailMail, self).create(values) - if values.get('statistics_ids'): + if values.get('mailing_trace_ids'): mail_sudo = mail.sudo() - mail_sudo.statistics_ids.write({'message_id': mail_sudo.message_id, 'state': 'outgoing'}) + mail_sudo.mailing_trace_ids.write({'message_id': mail_sudo.message_id, 'state': 'outgoing'}) return mail def _get_tracking_url(self): @@ -54,12 +54,12 @@ class MailMail(models.Model): def _send_prepare_body(self): """ Override to add the tracking URL to the body and to add - Statistic_id in shorted urls """ + trace ID in shortened urls """ # TDE: temporary addition (mail was parameter) due to semi-new-API self.ensure_one() body = super(MailMail, self)._send_prepare_body() - if self.mailing_id and body and self.statistics_ids: + if self.mailing_id and body and self.mailing_trace_ids: for match in re.findall(URL_REGEX, self.body_html): href = match[0] url = match[1] @@ -67,7 +67,7 @@ class MailMail(models.Model): parsed = werkzeug.urls.url_parse(url, scheme='http') if parsed.scheme.startswith('http') and parsed.path.startswith('/r/'): - new_href = href.replace(url, url + '/m/' + str(self.statistics_ids[0].id)) + new_href = href.replace(url, url + '/m/' + str(self.mailing_trace_ids[0].id)) body = body.replace(href, new_href) # generate tracking URL @@ -96,8 +96,8 @@ class MailMail(models.Model): mail_sent = not failure_type # we consider that a recipient error is a failure with mass mailling and show them as failed for mail in self: if mail.mailing_id: - if mail_sent is True and mail.statistics_ids: - mail.statistics_ids.write({'sent': fields.Datetime.now(), 'exception': False}) - elif mail_sent is False and mail.statistics_ids: - mail.statistics_ids.write({'exception': fields.Datetime.now()}) - return super(MailMail, self)._postprocess_sent_message(success_pids, failure_reason=failure_reason, failure_type=failure_type) + if mail_sent is True and mail.mailing_trace_ids: + mail.mailing_trace_ids.write({'sent': fields.Datetime.now(), 'exception': False}) + elif mail_sent is False and mail.mailing_trace_ids: + mail.mailing_trace_ids.write({'exception': fields.Datetime.now()}) + return super(MailMail, self)._postprocess_sent_message(success_pids, failure_reason=failure_reason, failure_type=failure_type) diff --git a/addons/mass_mailing/models/mail_thread.py b/addons/mass_mailing/models/mail_thread.py index 5195672eead..28b02921801 100644 --- a/addons/mass_mailing/models/mail_thread.py +++ b/addons/mass_mailing/models/mail_thread.py @@ -13,12 +13,12 @@ BLACKLIST_MAX_BOUNCED_LIMIT = 5 class MailThread(models.AbstractModel): - """ Update MailThread to add the support of bounce management in mass mailing statistics. """ + """ Update MailThread to add the support of bounce management in mass mailing traces. """ _inherit = 'mail.thread' @api.model def message_route(self, message, message_dict, model=None, thread_id=None, custom_values=None): - """ Override to udpate mass mailing statistics based on bounce emails """ + """ Override to udpate mass mailing traces based on bounce emails """ bounce_alias = self.env['ir.config_parameter'].sudo().get_param("mail.bounce.alias") email_to = decode_message_header(message, 'To') email_to_localpart = (tools.email_split(email_to) or [''])[0].split('@', 1)[0].lower() @@ -28,19 +28,19 @@ class MailThread(models.AbstractModel): bounce_match = bounce_re.search(email_to) if bounce_match: bounced_mail_id = bounce_match.group(1) - self.env['mail.mail.statistics'].set_bounced(mail_mail_ids=[bounced_mail_id]) + self.env['mailing.trace'].set_bounced(mail_mail_ids=[bounced_mail_id]) return super(MailThread, self).message_route(message, message_dict, model, thread_id, custom_values) @api.model def message_route_process(self, message, message_dict, routes): - """ Override to update the parent mail statistics. The parent is found + """ Override to update the parent mailing traces. The parent is found by using the References header of the incoming message and looking for - matching message_id in mail.mail.statistics. """ + matching message_id in mailing.trace. """ if message.get('References') and routes: message_ids = [x.strip() for x in decode_smtp_header(message['References']).split()] - self.env['mail.mail.statistics'].set_opened(mail_message_ids=message_ids) - self.env['mail.mail.statistics'].set_replied(mail_message_ids=message_ids) + self.env['mailing.trace'].set_opened(mail_message_ids=message_ids) + self.env['mailing.trace'].set_replied(mail_message_ids=message_ids) return super(MailThread, self).message_route_process(message, message_dict, routes) def message_post_with_template(self, template_id, **kwargs): @@ -64,11 +64,11 @@ class MailThread(models.AbstractModel): super(MailThread, self)._message_receive_bounce(email, partner, mail_id=None) three_months_ago = fields.Datetime.to_string(datetime.datetime.now() - datetime.timedelta(weeks=13)) - stats = self.env['mail.mail.statistics'] \ + traces = self.env['mailing.trace'] \ .search(['&', ('bounced', '>', three_months_ago), ('email', '=ilike', email)]) \ .mapped('bounced') - if len(stats) >= BLACKLIST_MAX_BOUNCED_LIMIT: - if max(stats) > min(stats) + datetime.timedelta(weeks=1): + if len(traces) >= BLACKLIST_MAX_BOUNCED_LIMIT: + if max(traces) > min(traces) + datetime.timedelta(weeks=1): blacklist_rec = self.env['mail.blacklist'].sudo()._add(email) blacklist_rec._message_log( body='This email has been automatically blacklisted because of too much bounced.') diff --git a/addons/mass_mailing/models/mass_mailing_stats.py b/addons/mass_mailing/models/mailing_trace.py similarity index 81% rename from addons/mass_mailing/models/mass_mailing_stats.py rename to addons/mass_mailing/models/mailing_trace.py index 0710a0e8b1a..9f6556ae3ef 100644 --- a/addons/mass_mailing/models/mass_mailing_stats.py +++ b/addons/mass_mailing/models/mailing_trace.py @@ -4,14 +4,13 @@ from odoo import api, fields, models -class MailMailStats(models.Model): - """ MailMailStats models the statistics collected about emails. Those statistics +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 = 'mail.mail.statistics' - _description = 'Email Statistics' + _name = 'mailing.trace' + _description = 'Mailing Statistics' _rec_name = 'message_id' _order = 'message_id' @@ -45,7 +44,7 @@ class MailMailStats(models.Model): 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', 'mail_stat_id', string='Links click') + 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", @@ -83,7 +82,7 @@ class MailMailStats(models.Model): def create(self, values): if 'mail_mail_id' in values: values['mail_mail_id_int'] = values['mail_mail_id'] - res = super(MailMailStats, self).create(values) + res = super(MailingTrace, self).create(values) return res def _get_records(self, mail_mail_ids=None, mail_message_ids=None, domain=None): @@ -98,22 +97,21 @@ class MailMailStats(models.Model): return self.search(base_domain) def set_opened(self, mail_mail_ids=None, mail_message_ids=None): - statistics = self._get_records(mail_mail_ids, mail_message_ids, [('opened', '=', False)]) - statistics.write({'opened': fields.Datetime.now(), 'bounced': False}) - return statistics + 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): - statistics = self._get_records(mail_mail_ids, mail_message_ids, [('clicked', '=', False)]) - statistics.write({'clicked': fields.Datetime.now()}) - return statistics + 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): - statistics = self._get_records(mail_mail_ids, mail_message_ids, [('replied', '=', False)]) - statistics.write({'replied': fields.Datetime.now()}) - return statistics + 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): - statistics = self._get_records( - mail_mail_ids, mail_message_ids, [('bounced', '=', False), ('opened', '=', False)]) - statistics.write({'bounced': fields.Datetime.now()}) - return statistics + traces = self._get_records(mail_mail_ids, mail_message_ids, [('bounced', '=', False), ('opened', '=', False)]) + traces.write({'bounced': fields.Datetime.now()}) + return traces diff --git a/addons/mass_mailing/models/mass_mailing.py b/addons/mass_mailing/models/mass_mailing.py index 3cc86fbebd4..d0249777baf 100644 --- a/addons/mass_mailing/models/mass_mailing.py +++ b/addons/mass_mailing/models/mass_mailing.py @@ -89,7 +89,7 @@ class MassMailingCampaign(models.Model): 'the effectiveness of the mailings, without causing duplicate messages.') color = fields.Integer(string='Color Index') clicks_ratio = fields.Integer(compute="_compute_clicks_ratio", string="Number of clicks") - # stat fields + # trace statistics fields total = fields.Integer(compute="_compute_statistics") scheduled = fields.Integer(compute="_compute_statistics") failed = fields.Integer(compute="_compute_statistics") @@ -107,9 +107,9 @@ class MassMailingCampaign(models.Model): def _compute_clicks_ratio(self): self.env.cr.execute(""" - SELECT COUNT(DISTINCT(stats.id)) AS nb_mails, COUNT(DISTINCT(clicks.mail_stat_id)) AS nb_clicks, stats.mass_mailing_campaign_id AS id - FROM mail_mail_statistics AS stats - LEFT OUTER JOIN link_tracker_click AS clicks ON clicks.mail_stat_id = stats.id + SELECT COUNT(DISTINCT(stats.id)) AS nb_mails, COUNT(DISTINCT(clicks.mailing_trace_id)) AS nb_clicks, stats.mass_mailing_campaign_id AS id + FROM mailing_trace AS stats + LEFT OUTER JOIN link_tracker_click AS clicks ON clicks.mailing_trace_id = stats.id WHERE stats.mass_mailing_campaign_id IN %s GROUP BY stats.mass_mailing_campaign_id """, (tuple(self.ids), )) @@ -134,7 +134,7 @@ class MassMailingCampaign(models.Model): COUNT(CASE WHEN s.replied is not null THEN 1 ELSE null END) AS replied , COUNT(CASE WHEN s.bounced is not null THEN 1 ELSE null END) AS bounced FROM - mail_mail_statistics s + mailing_trace s RIGHT JOIN mail_mass_mailing_campaign c ON (c.id = s.mass_mailing_campaign_id) @@ -169,7 +169,7 @@ class MassMailingCampaign(models.Model): domain = [('mass_mailing_campaign_id', '=', campaign.id)] if model: domain += [('model', '=', model)] - res[campaign.id] = set(self.env['mail.mail.statistics'].search(domain).mapped('res_id')) + res[campaign.id] = set(self.env['mailing.trace'].search(domain).mapped('res_id')) return res @api.model @@ -253,7 +253,7 @@ class MassMailing(models.Model): contact_ab_pc = fields.Integer(string='A/B Testing percentage', help='Percentage of the contacts that will be mailed. Recipients will be taken randomly.', default=100) # statistics data - statistics_ids = fields.One2many('mail.mail.statistics', 'mass_mailing_id', string='Emails Statistics') + mailing_trace_ids = fields.One2many('mailing.trace', 'mass_mailing_id', string='Emails Statistics') total = fields.Integer(compute="_compute_total") scheduled = fields.Integer(compute="_compute_statistics") expected = fields.Integer(compute="_compute_statistics") @@ -277,9 +277,9 @@ class MassMailing(models.Model): def _compute_clicks_ratio(self): self.env.cr.execute(""" - SELECT COUNT(DISTINCT(stats.id)) AS nb_mails, COUNT(DISTINCT(clicks.mail_stat_id)) AS nb_clicks, stats.mass_mailing_id AS id - FROM mail_mail_statistics AS stats - LEFT OUTER JOIN link_tracker_click AS clicks ON clicks.mail_stat_id = stats.id + SELECT COUNT(DISTINCT(stats.id)) AS nb_mails, COUNT(DISTINCT(clicks.mailing_trace_id)) AS nb_clicks, stats.mass_mailing_id AS id + FROM mailing_trace AS stats + LEFT OUTER JOIN link_tracker_click AS clicks ON clicks.mailing_trace_id = stats.id WHERE stats.mass_mailing_id IN %s GROUP BY stats.mass_mailing_id """, (tuple(self.ids), )) @@ -311,7 +311,7 @@ class MassMailing(models.Model): COUNT(CASE WHEN s.bounced is not null THEN 1 ELSE null END) AS bounced, COUNT(CASE WHEN s.exception is not null THEN 1 ELSE null END) AS failed FROM - mail_mail_statistics s + mailing_trace s RIGHT JOIN mail_mass_mailing m ON (m.id = s.mass_mailing_id) @@ -441,10 +441,10 @@ class MassMailing(models.Model): def retry_failed_mail(self): failed_mails = self.env['mail.mail'].search([('mailing_id', 'in', self.ids), ('state', '=', 'exception')]) - failed_mails.mapped('statistics_ids').unlink() + failed_mails.mapped('mailing_trace_ids').unlink() failed_mails.sudo().unlink() res_ids = self._get_recipients() - except_mailed = self.env['mail.mail.statistics'].search([ + except_mailed = self.env['mailing.trace'].search([ ('model', '=', self.mailing_model_real), ('res_id', 'in', res_ids), ('exception', '!=', False), @@ -471,11 +471,11 @@ class MassMailing(models.Model): def _action_view_documents_filtered(self, view_filter): if view_filter in ('sent', 'opened', 'replied', 'bounced', 'clicked'): - opened_stats = self.statistics_ids.filtered(lambda stat: stat[view_filter]) + opened_stats = self.mailing_trace_ids.filtered(lambda stat: stat[view_filter]) elif view_filter == ('delivered'): - opened_stats = self.statistics_ids.filtered(lambda stat: stat.sent and not stat.bounced) + opened_stats = self.mailing_trace_ids.filtered(lambda stat: stat.sent and not stat.bounced) else: - opened_stats = self.env['mail.mail.statistics'] + opened_stats = self.env['mailing.trace'] res_ids = opened_stats.mapped('res_id') model_name = self.env['ir.model']._get(self.mailing_model_real).display_name return { @@ -551,7 +551,7 @@ class MassMailing(models.Model): # + use a basic heuristic for extracting emails query = """ SELECT lower(substring(t.%(mail_field)s, '([^ ,;<@]+@[^> ,;]+)')) - FROM mail_mail_statistics s + FROM mailing_trace s JOIN %(target)s t ON (s.res_id = t.id) WHERE substring(t.%(mail_field)s, '([^ ,;<@]+@[^> ,;]+)') IS NOT NULL """ @@ -561,7 +561,7 @@ class MassMailing(models.Model): mail_field = 'email' query = """ SELECT lower(substring(p.%(mail_field)s, '([^ ,;<@]+@[^> ,;]+)')) - FROM mail_mail_statistics s + FROM mailing_trace s JOIN %(target)s t ON (s.res_id = t.id) JOIN res_partner p ON (t.partner_id = p.id) WHERE substring(p.%(mail_field)s, '([^ ,;<@]+@[^> ,;]+)') IS NOT NULL @@ -626,7 +626,7 @@ class MassMailing(models.Model): def _get_remaining_recipients(self): res_ids = self._get_recipients() - already_mailed = self.env['mail.mail.statistics'].search_read([ + already_mailed = self.env['mailing.trace'].search_read([ ('model', '=', self.mailing_model_real), ('res_id', 'in', res_ids), ('mass_mailing_id', '=', self.id)], ['res_id']) diff --git a/addons/mass_mailing/report/__init__.py b/addons/mass_mailing/report/__init__.py index 2796202ba19..cd346c5e5ca 100644 --- a/addons/mass_mailing/report/__init__.py +++ b/addons/mass_mailing/report/__init__.py @@ -1,4 +1,4 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. -from . import mass_mailing_stats_report +from . import mailing_trace_report diff --git a/addons/mass_mailing/report/mass_mailing_stats_report.py b/addons/mass_mailing/report/mailing_trace_report.py similarity index 84% rename from addons/mass_mailing/report/mass_mailing_stats_report.py rename to addons/mass_mailing/report/mailing_trace_report.py index 358e90d0dfa..2afa8906097 100644 --- a/addons/mass_mailing/report/mass_mailing_stats_report.py +++ b/addons/mass_mailing/report/mailing_trace_report.py @@ -1,11 +1,11 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. -from odoo import api, fields, models, tools +from odoo import fields, models, tools -class MassMailingReport(models.Model): - _name = 'mail.statistics.report' +class MailingTraceReport(models.Model): + _name = 'mailing.trace.report' _auto = False _description = 'Mass Mailing Statistics' @@ -23,12 +23,12 @@ class MassMailingReport(models.Model): email_from = fields.Char('From', readonly=True) def init(self): - """Mass Mail Statistical Report: based on mail.mail.statistics that models the various + """Mass Mail Statistical Report: based on mailing.trace that models the various statistics collected for each mailing, and mail.mass_mailing model that models the various mailing performed. """ - tools.drop_view_if_exists(self.env.cr, 'mail_statistics_report') + tools.drop_view_if_exists(self.env.cr, 'mailing_trace_report') self.env.cr.execute(""" - CREATE OR REPLACE VIEW mail_statistics_report AS ( + CREATE OR REPLACE VIEW mailing_trace_report AS ( SELECT min(ms.id) as id, ms.scheduled as scheduled_date, @@ -43,7 +43,7 @@ class MassMailingReport(models.Model): mm.state, mm.email_from FROM - mail_mail_statistics as ms + mailing_trace as ms left join mail_mass_mailing as mm ON (ms.mass_mailing_id=mm.id) left join mail_mass_mailing_campaign as mc ON (ms.mass_mailing_campaign_id=mc.id) left join utm_campaign as utm_campaign ON (mc.campaign_id = utm_campaign.id) diff --git a/addons/mass_mailing/report/mass_mailing_stats_report_views.xml b/addons/mass_mailing/report/mailing_trace_report_views.xml similarity index 74% rename from addons/mass_mailing/report/mass_mailing_stats_report_views.xml rename to addons/mass_mailing/report/mailing_trace_report_views.xml index 6924fdc0433..0840fcb2254 100644 --- a/addons/mass_mailing/report/mass_mailing_stats_report_views.xml +++ b/addons/mass_mailing/report/mailing_trace_report_views.xml @@ -1,8 +1,8 @@ - - mail.statistics.report.pivot - mail.statistics.report + + mailing.trace.report.view.pivot + mailing.trace.report @@ -16,9 +16,9 @@ - - mail.statistics.report.graph - mail.statistics.report + + mailing.trace.report.view.graph + mailing.trace.report @@ -27,9 +27,9 @@ - - mail.statistics.report.search - mail.statistics.report + + mailing.trace.report.view.search + mailing.trace.report @@ -51,14 +51,14 @@ - + Mass Mailing Analysis - mail.statistics.report + mailing.trace.report graph,pivot Mass Mailing Statistics allows you to check different mailing related information like number of bounced mails, opened mails, replied mails. You can sort out your analysis by different groups to get accurate grained analysis. + parent="mass_mailing_menu_root" action="mailing_trace_report_action" groups="mass_mailing.group_mass_mailing_user"/> diff --git a/addons/mass_mailing/security/ir.model.access.csv b/addons/mass_mailing/security/ir.model.access.csv index 7e3887ea576..ed137e9ba92 100644 --- a/addons/mass_mailing/security/ir.model.access.csv +++ b/addons/mass_mailing/security/ir.model.access.csv @@ -7,9 +7,9 @@ access_mass_mailing_campaign,mail.mass_mailing.campaign,model_mail_mass_mailing_ access_mass_mailing_campaign_system,mail.mass_mailing.campaign.system,model_mail_mass_mailing_campaign,base.group_system,1,1,1,1 access_mass_mailing,mail.mass_mailing,model_mail_mass_mailing,mass_mailing.group_mass_mailing_user,1,1,1,1 access_mass_mailing_system,mail.mass_mailing.system,model_mail_mass_mailing,base.group_system,1,1,1,1 -access_mail_mail_statistics_user,mail.mail.statistics,model_mail_mail_statistics,base.group_user,1,1,1,1 -access_mail_mail_statistics_mass_mailing_user,mail.mail.statistics,model_mail_mail_statistics,mass_mailing.group_mass_mailing_user,1,1,1,1 -access_mail_statistics_report,mail.statistics.report,model_mail_statistics_report,mass_mailing.group_mass_mailing_user,1,1,1,1 +access_mailing_trace_user,mailing.trace.user,model_mailing_trace,base.group_user,1,1,1,1 +access_mailing_trace_mm_user,access.mailing.trace.mm.user,model_mailing_trace,mass_mailing.group_mass_mailing_user,1,1,1,1 +access_mailing_trace_report_mm_user,access.mailing.trace.report.mm.user,model_mailing_trace_report,mass_mailing.group_mass_mailing_user,1,1,1,1 access_utm_source,access_utm_source,utm.model_utm_source,mass_mailing.group_mass_mailing_user,1,1,1,0 access_ir_mail_server,access_ir_mail_server,base.model_ir_mail_server,mass_mailing.group_mass_mailing_user,1,0,0,0 access_mail_blacklist_mass_mailing_user,access.mail.blacklist.mass_mailing_user,mail.model_mail_blacklist,mass_mailing.group_mass_mailing_user,1,1,1,1 diff --git a/addons/mass_mailing/views/link_tracker_views.xml b/addons/mass_mailing/views/link_tracker_views.xml index b1e4a96a582..450d4e7bd77 100644 --- a/addons/mass_mailing/views/link_tracker_views.xml +++ b/addons/mass_mailing/views/link_tracker_views.xml @@ -80,7 +80,7 @@ - + diff --git a/addons/mass_mailing/views/mass_mailing_stats_views.xml b/addons/mass_mailing/views/mailing_trace_views.xml similarity index 87% rename from addons/mass_mailing/views/mass_mailing_stats_views.xml rename to addons/mass_mailing/views/mailing_trace_views.xml index 57f291ef557..86907f2770f 100644 --- a/addons/mass_mailing/views/mass_mailing_stats_views.xml +++ b/addons/mass_mailing/views/mailing_trace_views.xml @@ -1,9 +1,9 @@ - - - mail.mail.statistics.search - mail.mail.statistics + + + mailing.trace.search + mailing.trace @@ -30,9 +30,9 @@ - - mail.mail.statistics.tree - mail.mail.statistics + + mailing.trace.tree + mailing.trace @@ -49,9 +49,9 @@ - - mail.mail.statistics.form - mail.mail.statistics + + mailing.trace.form + mailing.trace
@@ -88,13 +88,13 @@ Mail Statistics - mail.mail.statistics + mailing.trace tree,form Mail Statistics - mail.mail.statistics + mailing.trace graph,tree,form,pivot [] {'search_default_mass_mailing_id': active_id} @@ -102,7 +102,7 @@ Emails Sent - mail.mail.statistics + mailing.trace tree,graph,form,pivot [] {'search_default_mass_mailing_id': active_id} @@ -110,7 +110,7 @@ Mail Statistics Graph - mail.mail.statistics + mailing.trace diff --git a/addons/mass_mailing/wizard/mail_compose_message.py b/addons/mass_mailing/wizard/mail_compose_message.py index 3f5c0c03e2e..fc75d7e192f 100644 --- a/addons/mass_mailing/wizard/mail_compose_message.py +++ b/addons/mass_mailing/wizard/mail_compose_message.py @@ -16,7 +16,7 @@ class MailComposeMessage(models.TransientModel): def get_mail_values(self, res_ids): """ Override method that generated the mail content by creating the - mail.mail.statistics values in the o2m of mail_mail, when doing pure + mailing.trace values in the o2m of mail_mail, when doing pure email mass mailing. """ self.ensure_one() res = super(MailComposeMessage, self).get_mail_values(res_ids) @@ -71,7 +71,7 @@ class MailComposeMessage(models.TransientModel): mail_values['state'] = 'cancel' elif seen_list is not None: seen_list.add(mail_to) - stat_vals = { + trace_vals = { 'model': self.model, 'res_id': res_id, 'mass_mailing_id': mass_mailing.id, @@ -79,12 +79,12 @@ class MailComposeMessage(models.TransientModel): } if mail_values.get('body_html') and mass_mail_layout: mail_values['body_html'] = mass_mail_layout.render({'body': mail_values['body_html']}, engine='ir.qweb', minimal_qcontext=True) - # propagate ignored state to stat when still-born + # propagate ignored state to trace when still-born if mail_values.get('state') == 'cancel': - stat_vals['ignored'] = fields.Datetime.now() + trace_vals['ignored'] = fields.Datetime.now() mail_values.update({ 'mailing_id': mass_mailing.id, - 'statistics_ids': [(0, 0, stat_vals)], + 'mailing_trace_ids': [(0, 0, trace_vals)], # email-mode: keep original message for routing 'notification': mass_mailing.reply_to_mode == 'thread', 'auto_delete': not mass_mailing.keep_archives, diff --git a/addons/test_mass_mailing/tests/test_link.py b/addons/test_mass_mailing/tests/test_link.py index bbe731413bf..80c73647bf0 100644 --- a/addons/test_mass_mailing/tests/test_link.py +++ b/addons/test_mass_mailing/tests/test_link.py @@ -48,7 +48,7 @@ class TestLinkTracker(common.MassMailingCase): mailing = self.env['mail.mass_mailing'].create({'name': 'Test Mailing', "subject": "Hi!"}) code = self.link.code self.assertEqual(self.link.count, 1) - stat = self.env['mail.mail.statistics'].create({'mass_mailing_id': mailing.id}) + stat = self.env['mailing.trace'].create({'mass_mailing_id': mailing.id}) self.assertFalse(stat.opened) self.assertFalse(stat.clicked) @@ -57,7 +57,7 @@ class TestLinkTracker(common.MassMailingCase): code, ip='100.00.00.01', country_code='BEL', - mail_stat_id=stat.id + mailing_trace_id=stat.id ) self.assertEqual(self.link.count, 2) self.assertEqual(click.mass_mailing_id, mailing) diff --git a/addons/test_mass_mailing/tests/test_mail_auto_blacklist.py b/addons/test_mass_mailing/tests/test_mail_auto_blacklist.py index eee8c7ea964..56db2616fd9 100644 --- a/addons/test_mass_mailing/tests/test_mail_auto_blacklist.py +++ b/addons/test_mass_mailing/tests/test_mail_auto_blacklist.py @@ -9,7 +9,7 @@ class TestAutoBlacklist(common.TransactionCase): mass_mailing_contacts = self.env['mail.mass_mailing.contact'] mass_mailing = self.env['mail.mass_mailing'] mail_blacklist = self.env['mail.blacklist'] - mail_statistics = self.env['mail.mail.statistics'] + mail_statistics = self.env['mailing.trace'] mail_thread = self.env['mail.thread'] # create mailing contact record @@ -45,7 +45,6 @@ class TestAutoBlacklist(common.TransactionCase): }) self.mailing_contact_1._message_receive_bounce(self.mailing_contact_1.email, self.mailing_contact_1) - # create mass mailing record self.mass_mailing = mass_mailing.create({ 'name': 'test',