[IMP] mass_mailing: improved statistics + form view + some code cleaning in stat model
bzr revid: tde@openerp.com-20140328135907-nfa9h1zrs4w8la6f
This commit is contained in:
parent
2967919465
commit
083f643618
|
@ -408,12 +408,16 @@ class MassMailing(osv.Model):
|
|||
for mid in ids:
|
||||
results[mid] = {
|
||||
'total': Statistics.search(cr, uid, [('mass_mailing_id', '=', mid)], count=True, context=context),
|
||||
'scheduled': Statistics.search(cr, uid, [('mass_mailing_id', '=', mid), ('scheduled', '!=', False), ('sent', '=', False)], count=True, context=context),
|
||||
'sent': Statistics.search(cr, uid, [('mass_mailing_id', '=', mid), ('sent', '!=', False)], count=True, context=context),
|
||||
'opened': Statistics.search(cr, uid, [('mass_mailing_id', '=', mid), ('opened', '!=', False)], count=True, context=context),
|
||||
'replied': Statistics.search(cr, uid, [('mass_mailing_id', '=', mid), ('replied', '!=', False)], count=True, context=context),
|
||||
'bounced': Statistics.search(cr, uid, [('mass_mailing_id', '=', mid), ('bounced', '!=', False)], count=True, context=context),
|
||||
}
|
||||
results[mid]['delivered'] = results[mid]['sent'] - results[mid]['bounced']
|
||||
results[mid]['received_ratio'] = 100.0 * results[mid]['delivered'] / (results[mid]['sent'] or 1)
|
||||
results[mid]['opened_ratio'] = 100.0 * results[mid]['opened'] / (results[mid]['sent'] or 1)
|
||||
results[mid]['replied_ratio'] = 100.0 * results[mid]['replied'] / (results[mid]['sent'] or 1)
|
||||
return results
|
||||
|
||||
def _get_contact_nbr(self, cr, uid, ids, name, arg, context=None):
|
||||
|
@ -479,12 +483,16 @@ class MassMailing(osv.Model):
|
|||
'Emails Statistics',
|
||||
),
|
||||
'total': fields.function(
|
||||
_get_statistics, string='Total',
|
||||
type='integer', multi='_get_statistics',
|
||||
),
|
||||
'scheduled': fields.function(
|
||||
_get_statistics, string='Scheduled',
|
||||
type='integer', multi='_get_statistics'
|
||||
type='integer', multi='_get_statistics',
|
||||
),
|
||||
'sent': fields.function(
|
||||
_get_statistics, string='Sent',
|
||||
type='integer', multi='_get_statistics'
|
||||
type='integer', multi='_get_statistics',
|
||||
),
|
||||
'delivered': fields.function(
|
||||
_get_statistics, string='Delivered',
|
||||
|
@ -496,13 +504,25 @@ class MassMailing(osv.Model):
|
|||
),
|
||||
'replied': fields.function(
|
||||
_get_statistics, string='Replied',
|
||||
type='integer', multi='_get_statistics'
|
||||
type='integer', multi='_get_statistics',
|
||||
),
|
||||
'bounced': fields.function(
|
||||
_get_statistics, string='Bounced',
|
||||
type='integer', multi='_get_statistics'
|
||||
type='integer', multi='_get_statistics',
|
||||
),
|
||||
# monthly ratio
|
||||
'received_ratio': fields.function(
|
||||
_get_statistics, string='Received Ratio',
|
||||
type='integer', multi='_get_statistics',
|
||||
),
|
||||
'opened_ratio': fields.function(
|
||||
_get_statistics, string='Opened Ratio',
|
||||
type='integer', multi='_get_statistics',
|
||||
),
|
||||
'replied_ratio': fields.function(
|
||||
_get_statistics, string='Replied Ratio',
|
||||
type='integer', multi='_get_statistics',
|
||||
),
|
||||
# dayly ratio
|
||||
'opened_dayly': fields.function(
|
||||
_get_daily_statistics, string='Opened',
|
||||
type='char', multi='_get_daily_statistics',
|
||||
|
@ -602,7 +622,7 @@ class MassMailing(osv.Model):
|
|||
def action_new_list(self, cr, uid, ids, context=None):
|
||||
wizard = self.browse(cr, uid, ids[0], context=context)
|
||||
action_id = self._get_model_to_list_action_id(cr, uid, wizard.mailing_model, context=context)
|
||||
ctx = dict(context, view_manager_highlight=[action_id], default_mass_mailing_id=ids[0], default_model=wizard.mailing_model)
|
||||
ctx = dict(context, search_default_not_opt_out=True, view_manager_highlight=[action_id], default_mass_mailing_id=ids[0], default_model=wizard.mailing_model)
|
||||
return {
|
||||
'name': _('Choose Recipients'),
|
||||
'type': 'ir.actions.act_window',
|
||||
|
@ -644,10 +664,10 @@ class MassMailing(osv.Model):
|
|||
url = urlparse.urljoin(
|
||||
base_url, 'mail/mailing/%(mailing_id)s/unsubscribe?%(params)s' % {
|
||||
'mailing_id': mailing_id,
|
||||
'params': urllib.urlencode({'res_id': res_id, 'email': email})
|
||||
'params': urllib.urlencode({'db': cr.dbname, 'res_id': res_id, 'email': email})
|
||||
}
|
||||
)
|
||||
return '<a href="%s">%s</a>' % (url, msg or 'Click to unsubscribe')
|
||||
return '<small><a href="%s">%s</a></small>' % (url, msg or 'Click to unsubscribe')
|
||||
|
||||
def send_mail(self, cr, uid, ids, context=None):
|
||||
author_id = self.pool['res.users'].browse(cr, uid, uid, context=context).partner_id.id
|
||||
|
@ -680,6 +700,8 @@ class MassMailing(osv.Model):
|
|||
'reply_to': mailing.reply_to,
|
||||
'subject': mailing.name,
|
||||
'record_name': False,
|
||||
'model': mailing.mailing_model,
|
||||
'res_id': res_id,
|
||||
'author_id': author_id,
|
||||
'body_html': body,
|
||||
'auto_delete': True,
|
||||
|
@ -746,15 +768,9 @@ class MailMailStats(osv.Model):
|
|||
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.'
|
||||
),
|
||||
'message_id': fields.char(
|
||||
'Message-ID',
|
||||
),
|
||||
'model': fields.char(
|
||||
'Document model',
|
||||
),
|
||||
'res_id': fields.integer(
|
||||
'Document ID',
|
||||
),
|
||||
'message_id': fields.char('Message-ID'),
|
||||
'model': fields.char('Document model'),
|
||||
'res_id': fields.integer('Document ID'),
|
||||
# campaign / wave data
|
||||
'mass_mailing_id': fields.many2one(
|
||||
'mail.mass_mailing', 'Mass Mailing',
|
||||
|
@ -775,47 +791,39 @@ class MailMailStats(osv.Model):
|
|||
store=True, readonly=True,
|
||||
),
|
||||
# Bounce and tracking
|
||||
'sent': fields.datetime(
|
||||
'Sent',
|
||||
help='Date the related email was sent'),
|
||||
'opened': fields.datetime(
|
||||
'Opened',
|
||||
help='Date when this email has been opened for the first time.'),
|
||||
'replied': fields.datetime(
|
||||
'Replied',
|
||||
help='Date when this email has been replied for the first time.'),
|
||||
'bounced': fields.datetime(
|
||||
'Bounced',
|
||||
help='Date when this email has bounced.'
|
||||
),
|
||||
'scheduled': fields.datetime('Scheduled', help='Date when the email has been created'),
|
||||
'sent': fields.datetime('Sent', help='Date when the email has been sent'),
|
||||
'opened': fields.datetime('Opened', help='Date when the email has been opened the first time'),
|
||||
'replied': fields.datetime('Replied', help='Date when this email has been replied for the first time.'),
|
||||
'bounced': fields.datetime('Bounced', help='Date when this email has bounced.'),
|
||||
}
|
||||
|
||||
def set_opened(self, cr, uid, ids=None, mail_mail_ids=None, mail_message_ids=None, context=None):
|
||||
""" Set as opened """
|
||||
_defaults = {
|
||||
'scheduled': fields.datetime.now,
|
||||
}
|
||||
|
||||
def _get_ids(self, cr, uid, ids=None, mail_mail_ids=None, mail_message_ids=None, domain=None, context=None):
|
||||
if not ids and mail_mail_ids:
|
||||
ids = self.search(cr, uid, [('mail_mail_id', 'in', mail_mail_ids), ('opened', '=', False)], context=context)
|
||||
base_domain = [('mail_mail_id', 'in', mail_mail_ids)]
|
||||
elif not ids and mail_message_ids:
|
||||
ids = self.search(cr, uid, [('message_id', 'in', mail_message_ids), ('opened', '=', False)], context=context)
|
||||
base_domain = [('message_id', 'in', mail_message_ids)]
|
||||
else:
|
||||
ids = self.search(cr, uid, [('id', 'in', ids or []), ('opened', '=', False)], context=context)
|
||||
return self.write(cr, uid, ids, {'opened': fields.datetime.now()}, context=context)
|
||||
base_domain = [('id', 'in', ids or [])]
|
||||
if domain:
|
||||
base_domain = ['&'] + domain + base_domain
|
||||
return self.search(cr, uid, base_domain, context=context)
|
||||
|
||||
def set_opened(self, cr, uid, ids=None, mail_mail_ids=None, mail_message_ids=None, context=None):
|
||||
stat_ids = self._get_ids(cr, uid, ids, mail_mail_ids, mail_message_ids, [('opened', '=', False)], context)
|
||||
self.write(cr, uid, stat_ids, {'opened': fields.datetime.now()}, context=context)
|
||||
return stat_ids
|
||||
|
||||
def set_replied(self, cr, uid, ids=None, mail_mail_ids=None, mail_message_ids=None, context=None):
|
||||
""" Set as replied """
|
||||
if not ids and mail_mail_ids:
|
||||
ids = self.search(cr, uid, [('mail_mail_id', 'in', mail_mail_ids), ('replied', '=', False)], context=context)
|
||||
elif not ids and mail_message_ids:
|
||||
ids = self.search(cr, uid, [('message_id', 'in', mail_message_ids), ('replied', '=', False)], context=context)
|
||||
else:
|
||||
ids = self.search(cr, uid, [('id', 'in', ids or []), ('replied', '=', False)], context=context)
|
||||
return self.write(cr, uid, ids, {'replied': fields.datetime.now()}, context=context)
|
||||
stat_ids = self._get_ids(cr, uid, ids, mail_mail_ids, mail_message_ids, [('replied', '=', False)], context)
|
||||
self.write(cr, uid, stat_ids, {'replied': fields.datetime.now()}, context=context)
|
||||
return stat_ids
|
||||
|
||||
def set_bounced(self, cr, uid, ids=None, mail_mail_ids=None, mail_message_ids=None, context=None):
|
||||
""" Set as bounced """
|
||||
if not ids and mail_mail_ids:
|
||||
ids = self.search(cr, uid, [('mail_mail_id', 'in', mail_mail_ids), ('bounced', '=', False)], context=context)
|
||||
elif not ids and mail_message_ids:
|
||||
ids = self.search(cr, uid, [('message_id', 'in', mail_message_ids), ('bounced', '=', False)], context=context)
|
||||
else:
|
||||
ids = self.search(cr, uid, [('id', 'in', ids or []), ('bounced', '=', False)], context=context)
|
||||
return self.write(cr, uid, ids, {'bounced': fields.datetime.now()}, context=context)
|
||||
stat_ids = self._get_ids(cr, uid, ids, mail_mail_ids, mail_message_ids, [('bounced', '=', False)], context)
|
||||
self.write(cr, uid, stat_ids, {'bounced': fields.datetime.now()}, context=context)
|
||||
return stat_ids
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<menuitem name="Mass Mailing" id="mass_mailing_campaign"
|
||||
parent="base.marketing_menu" sequence="1"/>
|
||||
<!-- Marketing / Mailing Lists -->
|
||||
<menuitem name="Contacts" id="mass_mailing_list"
|
||||
<menuitem name="Contact Lists" id="mass_mailing_list"
|
||||
parent="base.marketing_menu" sequence="2"/>
|
||||
|
||||
<!-- MASS MAILING CONTACT !-->
|
||||
|
@ -208,6 +208,13 @@
|
|||
<field name="state" widget="statusbar" clickable="True"/>
|
||||
</header>
|
||||
<sheet>
|
||||
<div colspan="2" class="oe_form_box_info oe_text_center"
|
||||
attrs="{'invisible': [('scheduled', '=', 0)]}">
|
||||
<p>
|
||||
<strong><field name="scheduled" class="oe_inline"/>emails are in queue
|
||||
and will be sent soon.</strong>
|
||||
</p>
|
||||
</div>
|
||||
<group>
|
||||
<group>
|
||||
<field name="name"/>
|
||||
|
@ -222,20 +229,27 @@
|
|||
type='action' name='%(action_mailing_email_template)d'
|
||||
attrs="{'invisible': [('template_id', '!=', False)]}"
|
||||
context="{'default_mass_mailing_id': active_id}"/>
|
||||
<div style="max-width: 300px !important;">
|
||||
<field name="body_html" class="form_html_preview" nolabel="1"
|
||||
attrs="{'invisible': [('template_id', '=', False)]}"/>
|
||||
<button string='Edit this Email' class='oe_inline oe_link oe_edit_only'
|
||||
type='action' name='%(action_mailing_email_template)d'
|
||||
attrs="{'invisible': [('template_id', '=', False)]}"
|
||||
context="{'default_mass_mailing_id': active_id, 'default_template_id': template_id}"/>
|
||||
<div style="max-width: 300px !important;">
|
||||
<field name="body_html" class="form_html_preview" nolabel="1"
|
||||
attrs="{'invisible': [('template_id', '=', False)]}"/>
|
||||
</div>
|
||||
</div>
|
||||
<field name="email_from"/>
|
||||
<field name="reply_to"/>
|
||||
</group>
|
||||
<group>
|
||||
<p>Here be some graphs</p>
|
||||
<p colspan="2">Here be some pie charts</p>
|
||||
<field name="total"/>
|
||||
<field name="received_ratio" attrs="{'invisible': [('total', '=', 0)]}"/>
|
||||
<field name="opened_ratio" attrs="{'invisible': [('total', '=', 0)]}"/>
|
||||
<field name="replied_ratio" attrs="{'invisible': [('total', '=', 0)]}"/>
|
||||
<p colspan="2">Here be some bar charts</p>
|
||||
<field name="opened_dayly" attrs="{'invisible': [('total', '=', 0)]}"/>
|
||||
<field name="replied_dayly" attrs="{'invisible': [('total', '=', 0)]}"/>
|
||||
</group>
|
||||
</group>
|
||||
<group>
|
||||
|
|
Loading…
Reference in New Issue