diff options
| author | stephanchrst <stephanchrst@gmail.com> | 2022-05-10 21:51:50 +0700 |
|---|---|---|
| committer | stephanchrst <stephanchrst@gmail.com> | 2022-05-10 21:51:50 +0700 |
| commit | 3751379f1e9a4c215fb6eb898b4ccc67659b9ace (patch) | |
| tree | a44932296ef4a9b71d5f010906253d8c53727726 /addons/mass_mailing/models/utm.py | |
| parent | 0a15094050bfde69a06d6eff798e9a8ddf2b8c21 (diff) | |
initial commit 2
Diffstat (limited to 'addons/mass_mailing/models/utm.py')
| -rw-r--r-- | addons/mass_mailing/models/utm.py | 98 |
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 |
