diff options
| author | Julien De Coster <jdc@odoo.com> | 2015-02-10 11:56:28 +0100 |
|---|---|---|
| committer | Julien De Coster <jdc@odoo.com> | 2015-02-12 11:58:13 +0100 |
| commit | 8efdedbf1b4da60e58e3d7f4edd50d2c73a13be2 (patch) | |
| tree | 317a0611c383e70ba7ca058eea8c01d567a6ad8a | |
| parent | e2f19f0ed5238f677a9ca8e0f1b628cbaa806e9b (diff) | |
[ADD] Clicks statistics in mass_mailings
| -rw-r--r-- | addons/mass_mailing/models/__init__.py | 2 | ||||
| -rw-r--r-- | addons/mass_mailing/models/mass_mailing.py | 34 | ||||
| -rw-r--r-- | addons/mass_mailing/models/website_links.py (renamed from addons/mass_mailing/models/website_links_click.py) | 7 | ||||
| -rw-r--r-- | addons/mass_mailing/static/src/css/mass_mailing.css | 2 | ||||
| -rw-r--r-- | addons/mass_mailing/views/mass_mailing.xml | 93 | ||||
| -rw-r--r-- | addons/website_links/models/website_links.py | 26 |
6 files changed, 110 insertions, 54 deletions
diff --git a/addons/mass_mailing/models/__init__.py b/addons/mass_mailing/models/__init__.py index 7cc1ba680b4..1e9affea3e7 100644 --- a/addons/mass_mailing/models/__init__.py +++ b/addons/mass_mailing/models/__init__.py @@ -6,4 +6,4 @@ import mail_mail import mail_thread import res_config import mass_mailing_report -import website_links_click +import website_links diff --git a/addons/mass_mailing/models/mass_mailing.py b/addons/mass_mailing/models/mass_mailing.py index 79c12011461..57f8c6059ba 100644 --- a/addons/mass_mailing/models/mass_mailing.py +++ b/addons/mass_mailing/models/mass_mailing.py @@ -493,7 +493,7 @@ class MassMailing(osv.Model): 'email_from': fields.char('From', required=True), 'create_date': fields.datetime('Creation Date'), 'sent_date': fields.datetime('Sent Date', oldname='date', copy=False), - 'schedule_date': fields.datetime('Scheduled Send Date'), + 'schedule_date': fields.datetime('Schedule in the Future'), 'body_html': fields.html('Body'), 'attachment_ids': fields.many2many( 'ir.attachment', 'mass_mailing_ir_attachments_rel', @@ -769,6 +769,10 @@ class MassMailing(osv.Model): comp_ctx = dict(context, active_ids=res_ids) else: comp_ctx = {'active_ids': res_ids} + + # Convert links in absolute URLs before the application of the shortener + self.write(cr, uid, [mailing.id], {'body_html': self.pool['mail.template']._replace_local_links(cr, uid, mailing.body_html, context)}, context=context) + composer_values = { 'author_id': author_id, 'attachment_ids': [(4, attachment.id) for attachment in mailing.attachment_ids], @@ -787,19 +791,32 @@ class MassMailing(osv.Model): composer_id = self.pool['mail.compose.message'].create(cr, uid, composer_values, context=comp_ctx) self.pool['mail.compose.message'].send_mail(cr, uid, [composer_id], auto_commit=True, context=comp_ctx) - self.write(cr, uid, [mailing.id], {'sent_date': fields.datetime.now(), 'state': 'done'}, context=context) + self.write(cr, uid, [mailing.id], {'state': 'done'}, context=context) return True def convert_links(self, cr, uid, ids, context=None): res = {} for mass_mailing in self.browse(cr, uid, ids, context=context): - res[mass_mailing.id] = mass_mailing.body_html if mass_mailing.body_html else '' utm_mixin = mass_mailing.mass_mailing_campaign_id if mass_mailing.mass_mailing_campaign_id else mass_mailing - res[mass_mailing.id] = self.pool['website.links'].convert_links(cr, uid, res[mass_mailing.id], utm_mixin, context=context) + html = mass_mailing.body_html if mass_mailing.body_html else '' + + vals = {'mass_mailing_id': mass_mailing.id} + + if mass_mailing.mass_mailing_campaign_id: + vals['mass_mailing_campaign_id'] = mass_mailing.mass_mailing_campaign_id.id + if utm_mixin.campaign_id: + vals['campaign_id'] = utm_mixin.campaign_id.id + if utm_mixin.source_id: + vals['source_id'] = utm_mixin.source_id.id + if utm_mixin.medium_id: + vals['medium_id'] = utm_mixin.medium_id.id + + res[mass_mailing.id] = self.pool['website.links'].convert_links(cr, uid, html, vals, blacklist=['/unsubscribe_from_list'], context=context) + return res def put_in_queue(self, cr, uid, ids, context=None): - self.write(cr, uid, ids, {'state': 'in_queue'}, context=context) + self.write(cr, uid, ids, {'sent_date': fields.datetime.now(), 'state': 'in_queue'}, context=context) def cancel_mass_mailing(self, cr, uid, ids, context=None): self.write(cr, uid, ids, {'state': 'draft'}, context=context) @@ -830,18 +847,19 @@ class MassMailing(osv.Model): class MailMail(models.Model): _inherit = ['mail.mail'] - links_backlist = ['/unsubscribe_from_list'] - @api.model def send_get_mail_body(self, mail, partner=None): """Override to add Statistic_id in shorted urls """ + + links_blacklist = ['/unsubscribe_from_list'] + if mail.mailing_id and mail.body_html and mail.statistics_ids: for match in re.findall(URL_REGEX, mail.body_html): href = match[0] url = match[1] - if not [s for s in self.links_backlist if s in href]: + if not [s for s in links_blacklist if s in href]: new_href = href.replace(url, url + '/m/' + str(mail.statistics_ids[0].id)) mail.body_html = mail.body_html.replace(href, new_href) diff --git a/addons/mass_mailing/models/website_links_click.py b/addons/mass_mailing/models/website_links.py index 31e93445ef8..f5e10a817d0 100644 --- a/addons/mass_mailing/models/website_links_click.py +++ b/addons/mass_mailing/models/website_links.py @@ -1,10 +1,15 @@ from openerp import fields from openerp import models +class website_links(models.Model): + _inherit = "website.links" + + 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') class website_links_click(models.Model): _inherit = "website.links.click" mail_stat_id = fields.Many2one('mail.mail.statistics', 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') + mass_mailing_campaign_id = fields.Many2one('mail.mass_mailing.campaign', string='Mass Mailing Campaign')
\ No newline at end of file diff --git a/addons/mass_mailing/static/src/css/mass_mailing.css b/addons/mass_mailing/static/src/css/mass_mailing.css index 697afd9231a..bc95533a983 100644 --- a/addons/mass_mailing/static/src/css/mass_mailing.css +++ b/addons/mass_mailing/static/src/css/mass_mailing.css @@ -4,7 +4,7 @@ } .openerp .oe_kanban_view .oe_kanban_mass_mailing { width: 280px; - min-height: 141px; + min-height: 35px; } .openerp .oe_margin_top_8 { margin-top: 8px; diff --git a/addons/mass_mailing/views/mass_mailing.xml b/addons/mass_mailing/views/mass_mailing.xml index 30d713d2365..245a4346dcc 100644 --- a/addons/mass_mailing/views/mass_mailing.xml +++ b/addons/mass_mailing/views/mass_mailing.xml @@ -184,12 +184,6 @@ </field> </record> - <record model="ir.actions.act_window" id="action_view_mass_mailing_statistics"> - <field name="name">Statistics of Clicks</field> - <field name="res_model">website.links.click</field> - <field name="view_mode">graph</field> - </record> - <record model="ir.actions.act_window" id="action_view_mass_mailing_contacts"> <field name="name">Mailing List Subscribers</field> <field name="res_model">mail.mass_mailing.contact</field> @@ -323,6 +317,38 @@ </field> </record> + <record model="ir.ui.view" id="view_mail_mass_mailing_links_tree"> + <field name="name">website.links.tree</field> + <field name="model">website.links</field> + <field name="priority">10</field> + <field name="arch" type="xml"> + <tree string="Mailing Statistics of Clicks"> + <field name="title"/> + <field name="url"/> + <field name="count"/> + </tree> + </field> + </record> + + <record model="ir.ui.view" id="view_mail_mass_mailing_links_search"> + <field name="name">website.links.search</field> + <field name="model">website.links</field> + <field name="inherit_id" ref="website_links.view_website_links_filter"/> + <field name="arch" type="xml"> + <search string="Tracked Link"> + <field name="mass_mailing_id"/> + <field name="mass_mailing_campaign_id"/> + </search> + </field> + </record> + + <record model="ir.actions.act_window" id="action_view_mass_mailing_links_statistics"> + <field name="name">Statistics of Clicks</field> + <field name="res_model">website.links</field> + <field name="view_mode">tree</field> + <field name="context">{'search_default_mass_mailing_id': active_id}</field> + </record> + <record model="ir.ui.view" id="view_mail_mass_mailing_form"> <field name="name">mail.mass_mailing.form</field> <field name="model">mail.mass_mailing</field> @@ -375,9 +401,9 @@ type="action" class="oe_stat_button"> <field name="replied_ratio" string="Replied" widget="percentpie"/> </button> - <button name="mass_mailing_statistics_action" - type="object" class="oe_stat_button"> - <field name="clicks_ratio" string="clicks" widget="percentpie"/> + <button name="%(action_view_mass_mailing_links_statistics)d" + type="action" class="oe_stat_button"> + <field name="clicks_ratio" string="Clicks" widget="percentpie"/> </button> <button name="%(action_view_mail_mail_statistics_mailing)d" type="action" class="oe_stat_button"> @@ -395,6 +421,7 @@ <field name="mailing_domain" widget="char_domain" placeholder="Select recipients" + attrs="{'invisible': [('mailing_model', '=', 'mail.mass_mailing.contact')]}" options="{'model_field': 'mailing_model', 'model_domain': 'mailing_domain'}" context="{'search_default_not_opt_out':1}"/> @@ -423,8 +450,8 @@ attrs="{'required': [('reply_to_mode', '=', 'email')]}"/> </div> <field name="schedule_date" /> - <field name="create_date" readonly="1"/> - <field name="sent_date" readonly="1"/> + <field name="create_date" readonly="1" attrs="{'invisible': [('create_date', '=', False)]}"/> + <field name="sent_date" readonly="1" attrs="{'invisible': [('sent_date', '=', False)]}"/> </group> <group string="Campaign"> <field name="mass_mailing_campaign_id" groups="mass_mailing.group_mass_mailing_campaign" string="Campaign" on_change="onchange_mass_mailing_campaign_id(mass_mailing_campaign_id)"/> @@ -456,6 +483,7 @@ <field name='color'/> <field name='total'/> <field name='failed'/> + <field name='sent_date'/> <templates> <t t-name="kanban-box"> <div t-attf-class="oe_kanban_color_#{kanban_getcolor(record.color.raw_value)} oe_kanban_card oe_kanban_global_click oe_kanban_mass_mailing"> @@ -469,22 +497,26 @@ </div> <div class="oe_kanban_content"> <div> - <h3><field name="name"/> - <!-- <i class="fa fa-exclamation-triangle oe_kanban_mass_mailing_exclamation_sign" attrs="{'invisible': [('failed', '=', 0)]}"></i> --></h3> - <h4 style="display: inline;"><field name="mass_mailing_campaign_id" groups="mass_mailing.group_mass_mailing_campaign"/></h4> - <t t-if="record.mass_mailing_campaign_id.raw_value" groups="mass_mailing.group_mass_mailing_campaign"> - </t><field name="sent_date"/> - </div> - <div> - <div style="display: inline-block"> - <field name="delivered" widget="gauge" style="width:120px; height: 90px;" - options="{'max_field': 'total'}"/> - </div> - <div style="display: inline-block; vertical-align: top;"> - <strong>Opened</strong> <field name="opened_ratio"/> %<br /> - <strong>Replied</strong> <field name="replied_ratio"/> % <br /> - <strong>Clicks</strong> <field name="clicks_ratio"/> % <br /> + <h3><field name="name"/></h3> + + <div attrs="{'invisible': [('sent_date', '=', False)]}"> + <h4 style="display: inline;"><field name="mass_mailing_campaign_id" groups="mass_mailing.group_mass_mailing_campaign"/></h4> + <t t-if="record.mass_mailing_campaign_id.raw_value" groups="mass_mailing.group_mass_mailing_campaign"> - </t><field name="sent_date"/> </div> </div> + <div attrs="{'invisible': [('sent_date', '=', False)]}"> + <t t-if="record.sent_date"> + <div style="display: inline-block"> + <field name="delivered" widget="gauge" style="width:120px; height: 90px;" + options="{'max_field': 'total'}"/> + </div> + <div style="display: inline-block; vertical-align: top;"> + <strong>Opened</strong> <field name="opened_ratio"/> %<br /> + <strong>Replied</strong> <field name="replied_ratio"/> % <br /> + <strong>Clicks</strong> <field name="clicks_ratio"/> % <br /> + </div> + </t> + </div> </div> <div class="oe_clear"></div> </div> @@ -646,6 +678,13 @@ </field> </record> + <record model="ir.actions.act_window" id="dropdb snipp"> + <field name="name">Statistics of Clicks</field> + <field name="res_model">website.links</field> + <field name="view_mode">tree</field> + <field name="context">{'search_default_mass_mailing_campaign_id': active_id}</field> + </record> + <record model="ir.ui.view" id="view_mail_mass_mailing_campaign_form"> <field name="name">mail.mass_mailing.campaign.form</field> <field name="model">mail.mass_mailing.campaign</field> @@ -688,8 +727,8 @@ type="action" class="oe_stat_button oe_inline"> <field name="replied_ratio" widget="percentpie" string="Replied"/> </button> - <button name="mass_mailing_statistics_action" - type="object" class="oe_stat_button"> + <button name="%(dropdb snipp)d" + type="action" class="oe_stat_button"> <field name="clicks_ratio" widget="percentpie" string="Clicks"/> </button> </div> diff --git a/addons/website_links/models/website_links.py b/addons/website_links/models/website_links.py index e254e8fb74c..a174ef29107 100644 --- a/addons/website_links/models/website_links.py +++ b/addons/website_links/models/website_links.py @@ -43,24 +43,15 @@ class website_links(models.Model): short_url_host = fields.Char(string='Host of the short URL', compute='_compute_short_url_host') icon_src = fields.Char(string='Favicon Source', compute='_compute_icon_src') - # List of link's href that will not be converted by the shortener - links_backlist = ['/unsubscribe_from_list'] - @api.model - def convert_links(self, html, utm_mixin): + def convert_links(self, html, vals, blacklist=None): for match in re.findall(URL_REGEX, html): href = match[0] long_url = match[1] - if not [s for s in self.links_backlist if s in long_url]: - vals = {'url': long_url} + vals['url'] = long_url - if utm_mixin.campaign_id: - vals['campaign_id'] = utm_mixin.campaign_id.id - if utm_mixin.source_id: - vals['source_id'] = utm_mixin.source_id.id - if utm_mixin.medium_id: - vals['medium_id'] = utm_mixin.medium_id.id + if not blacklist or blacklist and not [s for s in blacklist if s in long_url]: link = self.create(vals) shorten_url = self.browse(link.id)[0].short_url @@ -68,6 +59,7 @@ class website_links(models.Model): if shorten_url: new_href = href.replace(long_url, shorten_url) html = html.replace(href, new_href) + return html @api.one @@ -159,10 +151,12 @@ class website_links(models.Model): @api.model def create(self, vals): + create_vals = vals.copy() + if 'url' not in vals: raise ValueError('URL field required') else: - vals['url'] = VALIDATE_URL(vals['url']) + create_vals['url'] = VALIDATE_URL(vals['url']) search_domain = [] for fname, value in vals.iteritems(): @@ -174,14 +168,14 @@ class website_links(models.Model): return result if not vals.get('title'): - vals['title'] = self._get_title_from_url(vals['url']) + create_vals['title'] = self._get_title_from_url(vals['url']) # Prevent the UTMs to be set by the values of UTM cookies for (key, fname) in self.env['utm.mixin'].tracking_fields(): if fname not in vals: - vals[fname] = False + create_vals[fname] = False - link = super(website_links, self).create(vals) + link = super(website_links, self).create(create_vals) code = self.env['website.links.code'].get_random_code_string() self.env['website.links.code'].create({'code': code, 'link_id': link.id}) |
