summaryrefslogtreecommitdiff
path: root/addons/mass_mailing/models/utm.py
diff options
context:
space:
mode:
authorstephanchrst <stephanchrst@gmail.com>2022-05-10 21:51:50 +0700
committerstephanchrst <stephanchrst@gmail.com>2022-05-10 21:51:50 +0700
commit3751379f1e9a4c215fb6eb898b4ccc67659b9ace (patch)
treea44932296ef4a9b71d5f010906253d8c53727726 /addons/mass_mailing/models/utm.py
parent0a15094050bfde69a06d6eff798e9a8ddf2b8c21 (diff)
initial commit 2
Diffstat (limited to 'addons/mass_mailing/models/utm.py')
-rw-r--r--addons/mass_mailing/models/utm.py98
1 files changed, 98 insertions, 0 deletions
diff --git a/addons/mass_mailing/models/utm.py b/addons/mass_mailing/models/utm.py
new file mode 100644
index 00000000..88c99e0f
--- /dev/null
+++ b/addons/mass_mailing/models/utm.py
@@ -0,0 +1,98 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from odoo import api, fields, models
+
+
+class UtmCampaign(models.Model):
+ _inherit = 'utm.campaign'
+
+ mailing_mail_ids = fields.One2many(
+ 'mailing.mailing', 'campaign_id',
+ domain=[('mailing_type', '=', 'mail')],
+ string='Mass Mailings')
+ mailing_mail_count = fields.Integer('Number of Mass Mailing', compute="_compute_mailing_mail_count")
+ # stat fields
+ received_ratio = fields.Integer(compute="_compute_statistics", string='Received Ratio')
+ opened_ratio = fields.Integer(compute="_compute_statistics", string='Opened Ratio')
+ replied_ratio = fields.Integer(compute="_compute_statistics", string='Replied Ratio')
+ bounced_ratio = fields.Integer(compute="_compute_statistics", string='Bounced Ratio')
+
+ @api.depends('mailing_mail_ids')
+ def _compute_mailing_mail_count(self):
+ if self.ids:
+ mailing_data = self.env['mailing.mailing'].read_group(
+ [('campaign_id', 'in', self.ids)],
+ ['campaign_id'],
+ ['campaign_id']
+ )
+ mapped_data = {m['campaign_id'][0]: m['campaign_id_count'] for m in mailing_data}
+ else:
+ mapped_data = dict()
+ for campaign in self:
+ campaign.mailing_mail_count = mapped_data.get(campaign.id, 0)
+
+ def _compute_statistics(self):
+ """ Compute statistics of the mass mailing campaign """
+ default_vals = {
+ 'received_ratio': 0,
+ 'opened_ratio': 0,
+ 'replied_ratio': 0,
+ 'bounced_ratio': 0
+ }
+ if not self.ids:
+ self.update(default_vals)
+ return
+ self.env.cr.execute("""
+ SELECT
+ c.id as campaign_id,
+ COUNT(s.id) AS expected,
+ COUNT(CASE WHEN s.sent is not null THEN 1 ELSE null END) AS sent,
+ COUNT(CASE WHEN s.scheduled is not null AND s.sent is null AND s.exception is null AND s.ignored is not null THEN 1 ELSE null END) AS ignored,
+ COUNT(CASE WHEN s.id is not null AND s.bounced is null THEN 1 ELSE null END) AS delivered,
+ COUNT(CASE WHEN s.opened is not null THEN 1 ELSE null END) AS opened,
+ 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
+ mailing_trace s
+ RIGHT JOIN
+ utm_campaign c
+ ON (c.id = s.campaign_id)
+ WHERE
+ c.id IN %s
+ GROUP BY
+ c.id
+ """, (tuple(self.ids), ))
+
+ all_stats = self.env.cr.dictfetchall()
+ stats_per_campaign = {
+ stats['campaign_id']: stats
+ for stats in all_stats
+ }
+
+ for campaign in self:
+ stats = stats_per_campaign.get(campaign.id)
+ if not stats:
+ vals = default_vals
+ else:
+ total = (stats['expected'] - stats['ignored']) or 1
+ delivered = stats['sent'] - stats['bounced']
+ vals = {
+ 'received_ratio': 100.0 * delivered / total,
+ 'opened_ratio': 100.0 * stats['opened'] / total,
+ 'replied_ratio': 100.0 * stats['replied'] / total,
+ 'bounced_ratio': 100.0 * stats['bounced'] / total
+ }
+
+ campaign.update(vals)
+
+ def _get_mailing_recipients(self, model=None):
+ """Return the recipients of a mailing campaign. This is based on the statistics
+ build for each mailing. """
+ res = dict.fromkeys(self.ids, {})
+ for campaign in self:
+ domain = [('campaign_id', '=', campaign.id)]
+ if model:
+ domain += [('model', '=', model)]
+ res[campaign.id] = set(self.env['mailing.trace'].search(domain).mapped('res_id'))
+ return res