diff --git a/addons/mass_mailing/models/mail_mail.py b/addons/mass_mailing/models/mail_mail.py index 3d890c95682..d4aa1f36d50 100644 --- a/addons/mass_mailing/models/mail_mail.py +++ b/addons/mass_mailing/models/mail_mail.py @@ -73,4 +73,6 @@ class MailMail(osv.Model): def _postprocess_sent_message(self, cr, uid, mail, context=None, mail_sent=True): if mail_sent is True and mail.statistics_ids: self.pool['mail.mail.statistics'].write(cr, uid, [s.id for s in mail.statistics_ids], {'sent': fields.datetime.now()}, context=context) + elif mail_sent is False and mail.statistics_ids: + self.pool['mail.mail.statistics'].write(cr, uid, [s.id for s in mail.statistics_ids], {'exception': fields.datetime.now()}, context=context) return super(MailMail, self)._postprocess_sent_message(cr, uid, mail, context=context, mail_sent=mail_sent) diff --git a/addons/mass_mailing/models/mass_mailing.py b/addons/mass_mailing/models/mass_mailing.py index 9e8e318699a..375f2e1162d 100644 --- a/addons/mass_mailing/models/mass_mailing.py +++ b/addons/mass_mailing/models/mass_mailing.py @@ -238,13 +238,16 @@ class MassMailingCampaign(osv.Model): Statistics = self.pool['mail.mail.statistics'] results = dict.fromkeys(ids, False) for cid in ids: + stat_ids = Statistics.search(cr, uid, [('mass_mailing_campaign_id', '=', cid)], context=context), + stats = Statistics.browse(cr, uid, stat_ids, context=context) results[cid] = { - 'total': Statistics.search(cr, uid, [('mass_mailing_campaign_id', '=', cid)], count=True, context=context), - 'scheduled': Statistics.search(cr, uid, [('mass_mailing_campaign_id', '=', cid), ('scheduled', '!=', False), ('sent', '=', False)], count=True, context=context), - 'sent': Statistics.search(cr, uid, [('mass_mailing_campaign_id', '=', cid), ('sent', '!=', False)], count=True, context=context), - 'opened': Statistics.search(cr, uid, [('mass_mailing_campaign_id', '=', cid), ('opened', '!=', False)], count=True, context=context), - 'replied': Statistics.search(cr, uid, [('mass_mailing_campaign_id', '=', cid), ('replied', '!=', False)], count=True, context=context), - 'bounced': Statistics.search(cr, uid, [('mass_mailing_campaign_id', '=', cid), ('bounced', '!=', False)], count=True, context=context), + 'total': len(stats), + 'failed': len([s for s in stats if not s.scheduled is False and s.sent is False and not s.exception is False]), + 'scheduled': len([s for s in stats if not s.scheduled is False and s.sent is False]), + 'sent': len([s for s in stats if not s.sent is False]), + 'opened': len([s for s in stats if not s.opened is False]), + 'replied': len([s for s in stats if not s.replied is False]), + 'bounced': len([s for s in stats if not s.bounced is False]), } results[cid]['delivered'] = results[cid]['sent'] - results[cid]['bounced'] results[cid]['received_ratio'] = 100.0 * results[cid]['delivered'] / (results[cid]['sent'] or 1) @@ -278,7 +281,11 @@ class MassMailingCampaign(osv.Model): type='integer', multi='_get_statistics' ), 'scheduled': fields.function( - _get_statistics, string='Total', + _get_statistics, string='Scheduled', + type='integer', multi='_get_statistics' + ), + 'failed': fields.function( + _get_statistics, string='Failed', type='integer', multi='_get_statistics' ), 'sent': fields.function( @@ -419,13 +426,16 @@ class MassMailing(osv.Model): Statistics = self.pool['mail.mail.statistics'] results = dict.fromkeys(ids, False) for mid in ids: + stat_ids = Statistics.search(cr, uid, [('mass_mailing_id', '=', mid)], context=context) + stats = Statistics.browse(cr, uid, stat_ids, context=context) 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), + 'total': len(stats), + 'failed': len([s for s in stats if not s.scheduled is False and s.sent is False and not s.exception is False]), + 'scheduled': len([s for s in stats if not s.scheduled is False and s.sent is False]), + 'sent': len([s for s in stats if not s.sent is False]), + 'opened': len([s for s in stats if not s.opened is False]), + 'replied': len([s for s in stats if not s.replied is False]), + 'bounced': len([s for s in stats if not s.bounced is False]), } results[mid]['delivered'] = results[mid]['sent'] - results[mid]['bounced'] results[mid]['received_ratio'] = 100.0 * results[mid]['delivered'] / (results[mid]['sent'] or 1) @@ -449,7 +459,7 @@ class MassMailing(osv.Model): return res def _get_private_models(self, context=None): - return ['res.partner', 'mail.maass_mailing.contact'] + return ['res.partner', 'mail.mass_mailing.contact'] def _get_auto_reply_to_available(self, cr, uid, ids, name, arg, context=None): res = dict.fromkeys(ids, False) @@ -537,6 +547,10 @@ class MassMailing(osv.Model): _get_statistics, string='Scheduled', type='integer', multi='_get_statistics', ), + 'failed': fields.function( + _get_statistics, string='Failed', + type='integer', multi='_get_statistics', + ), 'sent': fields.function( _get_statistics, string='Sent', type='integer', multi='_get_statistics', @@ -868,6 +882,7 @@ class MailMailStats(osv.Model): # Bounce and tracking 'scheduled': fields.datetime('Scheduled', help='Date when the email has been created'), 'sent': fields.datetime('Sent', help='Date when the email has been sent'), + 'exception': fields.datetime('Exception', help='Date of technical error leading to the email not being 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.'), diff --git a/addons/mass_mailing/static/src/css/email_template.css b/addons/mass_mailing/static/src/css/email_template.css index 823a8d9efc6..495c201a172 100644 --- a/addons/mass_mailing/static/src/css/email_template.css +++ b/addons/mass_mailing/static/src/css/email_template.css @@ -3,19 +3,6 @@ min-height: 270px !important; } -.form_html_preview { - width: 600px; - max-height: 1000px; - -webkit-transform: scale(.50); - -ms-transform: scale(.50); - transform: scale(.50); - -webkit-transform-origin: 0 0; - -ms-transform-origin: 0 0; - transform-origin: 0 0; - margin: 0 0px -300px 0; - overflow: visible !important; -} - .kanban_html_preview { width: 600px; height: 600px; diff --git a/addons/mass_mailing/views/mass_mailing.xml b/addons/mass_mailing/views/mass_mailing.xml index 862b1653a8f..8ef02545a2f 100644 --- a/addons/mass_mailing/views/mass_mailing.xml +++ b/addons/mass_mailing/views/mass_mailing.xml @@ -229,33 +229,43 @@ -
- - - - - - - +
+
+ + +
+
+ + + +
+
+ + +
@@ -265,8 +275,13 @@ Replies go into the original document - (not available for those recipients) + attrs="{'readonly': [('auto_reply_to_available', '=', False)]}"/> + + Replies go into the original document + + + Replies go into the original document (not available for those recipients) +
Use a specific reply-to address @@ -279,16 +294,16 @@ -