From 32b8b0bfd3ab71a28baf36490a54ed7dee94de95 Mon Sep 17 00:00:00 2001 From: Tim Otten Date: Sat, 20 Dec 2014 04:50:29 -0800 Subject: [PATCH] crmMailingAB - Report - Add options to view mailing content, select winner, & view winner stats --- js/angular-crmMailingAB.js | 68 +++++++++++++++++++++++-- js/angular-crmMailingAB/services.js | 24 +++++++-- partials/crmMailingAB/report.html | 38 ++++++++++++-- partials/crmMailingAB/selectWinner.html | 19 +++++++ 4 files changed, 139 insertions(+), 10 deletions(-) create mode 100644 partials/crmMailingAB/selectWinner.html diff --git a/js/angular-crmMailingAB.js b/js/angular-crmMailingAB.js index 6dc3d12cd2..6dab3a7d8b 100644 --- a/js/angular-crmMailingAB.js +++ b/js/angular-crmMailingAB.js @@ -138,9 +138,9 @@ $scope.sync(); return crmStatus({start: ts('Saving...'), success: ''}, abtest.save()) .then(function () { - return crmStatus({start: ts('Submitting...'), success: ts('Submitted')}, abtest.submit('Testing')); + return crmStatus({start: ts('Submitting...'), success: ts('Submitted')}, abtest.submitTest()); // Note: We're going to leave, so we don't care that submit() modifies several server-side records. - // If we stayed on this page, then we'd care about updating and call: abtest.submit().then(abtest.load) + // If we stayed on this page, then we'd care about updating and call: abtest.submitTest().then(...abtest.load()...) }) .then(leave); }; @@ -174,7 +174,7 @@ $scope.$watch('abtest.ab.testing_criteria_id', updateCriteriaName); }); - angular.module('crmMailingAB').controller('CrmMailingABReportCtrl', function ($scope, abtest, crmMailingABCriteria, crmApi) { + angular.module('crmMailingAB').controller('CrmMailingABReportCtrl', function ($scope, abtest, crmApi, crmMailingPreviewMgr, dialogService) { var ts = $scope.ts = CRM.ts('CiviMail'); $scope.abtest = abtest; @@ -186,6 +186,68 @@ crmApi('Mailing', 'stats', {mailing_id: abtest.ab.mailing_id_b}).then(function(data){ $scope.stats.b = data.values[abtest.ab.mailing_id_b]; }); + crmApi('Mailing', 'stats', {mailing_id: abtest.ab.mailing_id_c}).then(function(data){ + $scope.stats.c = data.values[abtest.ab.mailing_id_c]; + }); + + $scope.previewMailing = function previewMailing(mailingName, mode) { + return crmMailingPreviewMgr.preview(abtest.mailings[mailingName], mode); + }; + $scope.selectWinner = function selectWinner(mailingName) { + var model = { + abtest: abtest, + mailingName: mailingName + }; + var options = { + autoOpen: false, + modal: true, + title: ts('Select Winner (%1)', { + 1: mailingName.toUpperCase() + }) + }; + return dialogService.open('selectWinnerDialog', partialUrl('selectWinner.html'), model, options); + }; + }); + + + angular.module('crmMailingAB').controller('CrmMailingABWinnerDialogCtrl', function ($scope, $timeout, dialogService, crmMailingMgr, crmStatus) { + var ts = $scope.ts = CRM.ts('CiviMail'); + var abtest = $scope.abtest = $scope.model.abtest; + var mailingName = $scope.model.mailingName; + + var titles = {a: ts('Mailing A'), b: ts('Mailing B')}; + $scope.mailingTitle = titles[mailingName]; + + function init() { + // When using dialogService with a button bar, the major button actions + // need to be registered with the dialog widget (and not embedded in + // the body of the dialog). + var buttons = {}; + buttons[ts('Select Winner')] = function () { + crmMailingMgr.mergeInto(abtest.mailings.c, abtest.mailings[mailingName], [ + 'name', + 'groups', + 'mailings', + 'scheduled_date' + ]); + crmStatus({start: ts('Saving...'), success: ''}, abtest.save()) + .then(function () { + return crmStatus({start: ts('Submitting...'), success: ts('Submitted')}, + abtest.submitFinal().then(function(){ + return abtest.load(); + })); + }) + .then(function(){ + dialogService.close('selectWinnerDialog', abtest); + }); + }; + buttons[ts('Cancel')] = function () { + dialogService.cancel('selectWinnerDialog'); + }; + dialogService.setButtons('selectWinnerDialog', buttons); + } + + $timeout(init); }); })(angular, CRM.$, CRM._); diff --git a/js/angular-crmMailingAB/services.js b/js/angular-crmMailingAB/services.js index c602fda731..e28eac1fd8 100644 --- a/js/angular-crmMailingAB/services.js +++ b/js/angular-crmMailingAB/services.js @@ -102,7 +102,7 @@ .then(function () { return crmApi('MailingAB', 'create', crmMailingAB.ab) .then(function (abResult) { - crmMailingAB.ab.id = abResult.id; + crmMailingAB.id = crmMailingAB.ab.id = abResult.id; }); }) .then(function () { @@ -111,12 +111,12 @@ }, // Schedule the test // @return Promise CrmMailingAB - // Note: Submission may cause the server state to change. Consider abtest.submit().then(abtest.load) - submit: function submit(newStatus) { + // Note: Submission may cause the server state to change. Consider abtest.submit().then(...abtest.load()...) + submitTest: function submitTest() { var crmMailingAB = this; var params = { id: this.ab.id, - status: newStatus, + status: 'Testing', approval_date: crmNow(), scheduled_date: this.mailings.a.scheduled_date ? this.mailings.a.scheduled_date : crmNow() }; @@ -125,6 +125,22 @@ return crmMailingAB; }); }, + // Schedule the final mailing + // @return Promise CrmMailingAB + // Note: Submission may cause the server state to change. Consider abtest.submit().then(...abtest.load()...) + submitFinal: function submitFinal() { + var crmMailingAB = this; + var params = { + id: this.ab.id, + status: 'Final', + approval_date: crmNow(), + scheduled_date: this.mailings.c.scheduled_date ? this.mailings.c.scheduled_date : crmNow() + }; + return crmApi('MailingAB', 'submit', params) + .then(function () { + return crmMailingAB; + }); + }, // @param mailing Object (per APIv3) // @return Promise 'delete': function () { diff --git a/partials/crmMailingAB/report.html b/partials/crmMailingAB/report.html index 0078119653..b9d8ecb643 100644 --- a/partials/crmMailingAB/report.html +++ b/partials/crmMailingAB/report.html @@ -1,38 +1,70 @@ -
+
+
{{abtest.ab|json}}
+
{{abtest.mailings|json}}
+
+
- - + + + + + + + + + + + + + + + + + + + + + + + + + +
{{ts('Details')}}{{ts('Mailing A')}}{{ts('Mailing B')}}{{ts('Mailing A')}}{{ts('Mailing B')}}{{ts('Final')}}
{{ts('HTML')}}{{ts('View')}}{{ts('View')}}{{ts('View')}}
{{ts('Text')}}{{ts('View')}}{{ts('View')}}{{ts('View')}}
{{ts('Delivered')}} {{stats.a.Delivered}} {{stats.b.Delivered}}{{stats.c.Delivered}}
{{ts('Bounces')}} {{stats.a.Bounces}} {{stats.b.Bounces}}{{stats.c.Bounces}}
{{ts('Unsubscribers')}} {{stats.a.Unsubscribers}} {{stats.b.Unsubscribers}}{{stats.c.Unsubscribers}}
{{'Opened'}} {{stats.a.Opened}} {{stats.b.Opened}}{{stats.c.Opened}}
{{ts('Unique Clicks')}} {{stats.a['Unique Clicks']}} {{stats.b['Unique Clicks']}}{{stats.c['Unique Clicks']}}
+ + + +
diff --git a/partials/crmMailingAB/selectWinner.html b/partials/crmMailingAB/selectWinner.html new file mode 100644 index 0000000000..62602248af --- /dev/null +++ b/partials/crmMailingAB/selectWinner.html @@ -0,0 +1,19 @@ +
+
+
+ {{ts('After selecting %1 as the winner, one must schedule the delivery for the final mailing.', {1: mailingTitle})}} +
+ +
+
+ + +
+
+ + + +
+
+
+
-- 2.25.1