Commit | Line | Data |
---|---|---|
70980d8e TO |
1 | (function (angular, $, _) { |
2 | ||
360aaa75 | 3 | angular.module('crmMailingAB', ['ngRoute', 'ui.utils', 'ngSanitize', 'crmUi', 'crmAttachment', 'crmMailing', 'crmD3']); |
efd95528 | 4 | angular.module('crmMailingAB').config([ |
70980d8e TO |
5 | '$routeProvider', |
6 | function ($routeProvider) { | |
efd95528 | 7 | $routeProvider.when('/abtest', { |
ef5d18a1 | 8 | templateUrl: '~/crmMailingAB/list.html', |
efd95528 | 9 | controller: 'CrmMailingABListCtrl', |
70980d8e TO |
10 | resolve: { |
11 | mailingABList: function ($route, crmApi) { | |
12 | return crmApi('MailingAB', 'get', {rowCount: 0}); | |
13 | } | |
14 | } | |
15 | }); | |
a12bd71d TO |
16 | $routeProvider.when('/abtest/new', { |
17 | template: '<p>' + ts('Initializing...') + '</p>', | |
18 | controller: 'CrmMailingABNewCtrl', | |
19 | resolve: { | |
20 | abtest: function ($route, CrmMailingAB) { | |
21 | var abtest = new CrmMailingAB(null); | |
22 | return abtest.load().then(function(){ | |
23 | return abtest.save(); | |
24 | }); | |
25 | } | |
26 | } | |
27 | }); | |
efd95528 | 28 | $routeProvider.when('/abtest/:id', { |
ef5d18a1 | 29 | templateUrl: '~/crmMailingAB/edit.html', |
efd95528 | 30 | controller: 'CrmMailingABEditCtrl', |
70980d8e TO |
31 | resolve: { |
32 | abtest: function ($route, CrmMailingAB) { | |
33 | var abtest = new CrmMailingAB($route.current.params.id == 'new' ? null : $route.current.params.id); | |
34 | return abtest.load(); | |
35 | } | |
36 | } | |
37 | }); | |
360aaa75 | 38 | $routeProvider.when('/abtest/:id/report', { |
ef5d18a1 | 39 | templateUrl: '~/crmMailingAB/report.html', |
360aaa75 TO |
40 | controller: 'CrmMailingABReportCtrl', |
41 | resolve: { | |
42 | abtest: function ($route, CrmMailingAB) { | |
43 | var abtest = new CrmMailingAB($route.current.params.id); | |
44 | return abtest.load(); | |
45 | } | |
46 | } | |
47 | }); | |
70980d8e TO |
48 | } |
49 | ]); | |
50 | ||
63430d3c | 51 | angular.module('crmMailingAB').controller('CrmMailingABListCtrl', function ($scope, mailingABList, crmMailingABCriteria, crmMailingABStatus) { |
5d8901af | 52 | var ts = $scope.ts = CRM.ts(null); |
70980d8e | 53 | $scope.mailingABList = mailingABList.values; |
63430d3c TO |
54 | $scope.crmMailingABCriteria = crmMailingABCriteria; |
55 | $scope.crmMailingABStatus = crmMailingABStatus; | |
a7931384 | 56 | }); |
70980d8e | 57 | |
a12bd71d TO |
58 | angular.module('crmMailingAB').controller('CrmMailingABNewCtrl', function ($scope, abtest, $location) { |
59 | // Transition URL "/abtest/new/foo" => "/abtest/123/foo" | |
60 | var parts = $location.path().split('/'); // e.g. "/mailing/new" or "/mailing/123/wizard" | |
61 | parts[2] = abtest.id; | |
62 | $location.path(parts.join('/')); | |
63 | $location.replace(); | |
64 | }); | |
65 | ||
ce245e83 | 66 | angular.module('crmMailingAB').controller('CrmMailingABEditCtrl', function ($scope, abtest, crmMailingABCriteria, crmMailingMgr, crmMailingPreviewMgr, crmStatus, $q, $location, crmBlocker, $interval) { |
70980d8e | 67 | $scope.abtest = abtest; |
5d8901af | 68 | var ts = $scope.ts = CRM.ts(null); |
a12bd71d | 69 | var block = $scope.block = crmBlocker(); |
af6962d8 | 70 | $scope.crmMailingABCriteria = crmMailingABCriteria; |
bcdd7f49 | 71 | $scope.crmMailingConst = CRM.crmMailing; |
af6962d8 | 72 | |
86c3a327 TO |
73 | $scope.isSubmitted = function isSubmitted() { |
74 | return _.size(abtest.mailings.a.jobs) > 0 || _.size(abtest.mailings.b.jobs) > 0; | |
75 | }; | |
c9e9a71e | 76 | |
70980d8e TO |
77 | $scope.sync = function sync() { |
78 | abtest.mailings.a.name = ts('Test A (%1)', {1: abtest.ab.name}); | |
79 | abtest.mailings.b.name = ts('Test B (%1)', {1: abtest.ab.name}); | |
80 | abtest.mailings.c.name = ts('Winner (%1)', {1: abtest.ab.name}); | |
81 | ||
82 | var criteria = crmMailingABCriteria.get(abtest.ab.testing_criteria_id); | |
83 | if (criteria) { | |
d3b6424f | 84 | // TODO review fields exposed in UI and make sure the sync rules match |
70980d8e TO |
85 | switch (criteria.name) { |
86 | case 'Subject lines': | |
c9e9a71e TO |
87 | crmMailingMgr.mergeInto(abtest.mailings.b, abtest.mailings.a, [ |
88 | 'name', | |
9cd4f489 | 89 | 'recipients', |
c9e9a71e TO |
90 | 'subject' |
91 | ]); | |
70980d8e TO |
92 | break; |
93 | case 'From names': | |
c9e9a71e TO |
94 | crmMailingMgr.mergeInto(abtest.mailings.b, abtest.mailings.a, [ |
95 | 'name', | |
9cd4f489 | 96 | 'recipients', |
c9e9a71e TO |
97 | 'from_name', |
98 | 'from_email' | |
99 | ]); | |
70980d8e TO |
100 | break; |
101 | case 'Two different emails': | |
102 | crmMailingMgr.mergeInto(abtest.mailings.b, abtest.mailings.a, [ | |
103 | 'name', | |
9cd4f489 | 104 | 'recipients', |
70980d8e TO |
105 | 'subject', |
106 | 'from_name', | |
107 | 'from_email', | |
495f197a TO |
108 | 'replyto_email', |
109 | 'override_verp', // keep override_verp and replyto_Email linked | |
70980d8e TO |
110 | 'body_html', |
111 | 'body_text' | |
112 | ]); | |
113 | break; | |
114 | default: | |
115 | throw "Unrecognized testing_criteria"; | |
116 | } | |
117 | } | |
118 | crmMailingMgr.mergeInto(abtest.mailings.c, abtest.mailings.a, ['name']); | |
ce245e83 | 119 | return true; |
70980d8e | 120 | }; |
86c3a327 TO |
121 | |
122 | // @return Promise | |
70980d8e | 123 | $scope.save = function save() { |
80e64ffc | 124 | return block(crmStatus({start: ts('Saving...'), success: ts('Saved')}, abtest.save())); |
58dfba8d | 125 | }; |
86c3a327 | 126 | |
58dfba8d TO |
127 | // @return Promise |
128 | $scope.previewMailing = function previewMailing(mailingName, mode) { | |
129 | return crmMailingPreviewMgr.preview(abtest.mailings[mailingName], mode); | |
130 | }; | |
131 | ||
132 | // @return Promise | |
133 | $scope.sendTest = function sendTest(mailingName, recipient) { | |
80e64ffc | 134 | return block(crmStatus({start: ts('Saving...'), success: ''}, abtest.save()) |
58dfba8d TO |
135 | .then(function () { |
136 | crmMailingPreviewMgr.sendTest(abtest.mailings[mailingName], recipient); | |
a12bd71d | 137 | })); |
70980d8e | 138 | }; |
86c3a327 TO |
139 | |
140 | // @return Promise | |
70980d8e | 141 | $scope.delete = function () { |
a12bd71d | 142 | return block(crmStatus({start: ts('Deleting...'), success: ts('Deleted')}, abtest.delete().then($scope.leave))); |
70980d8e | 143 | }; |
86c3a327 TO |
144 | |
145 | // @return Promise | |
146 | $scope.submit = function submit() { | |
ce245e83 | 147 | if (block.check() || $scope.crmMailingAB.$invalid) { |
a12bd71d TO |
148 | return; |
149 | } | |
150 | return block(crmStatus({start: ts('Saving...'), success: ''}, abtest.save()) | |
151 | .then(function() { | |
152 | return crmStatus({start: ts('Submitting...'), success: ts('Submitted')}, abtest.submitTest()); | |
153 | // Note: We're going to leave, so we don't care that submit() modifies several server-side records. | |
154 | // If we stayed on this page, then we'd care about updating and call: abtest.submitTest().then(...abtest.load()...) | |
155 | }) | |
ce245e83 | 156 | ).then($scope.leave); |
22bc3e48 TO |
157 | }; |
158 | ||
a12bd71d | 159 | $scope.leave = function leave() { |
b0797ac3 TO |
160 | $location.path('abtest'); |
161 | $location.replace(); | |
a12bd71d | 162 | }; |
b0797ac3 | 163 | |
22bc3e48 | 164 | function updateCriteriaName() { |
f2bad133 | 165 | var criteria = crmMailingABCriteria.get($scope.abtest.ab.testing_criteria_id); |
bcdd7f49 | 166 | $scope.criteriaName = criteria ? criteria.name : null; |
22bc3e48 | 167 | } |
70980d8e | 168 | |
22bc3e48 TO |
169 | // initialize |
170 | updateCriteriaName(); | |
22bc3e48 | 171 | $scope.$watch('abtest.ab.testing_criteria_id', updateCriteriaName); |
ce245e83 TO |
172 | var syncJob = $interval($scope.sync, 333); |
173 | $scope.$on('$destroy', function(){ | |
174 | $interval.cancel(syncJob); | |
175 | }); | |
70980d8e TO |
176 | }); |
177 | ||
32b8b0bf | 178 | angular.module('crmMailingAB').controller('CrmMailingABReportCtrl', function ($scope, abtest, crmApi, crmMailingPreviewMgr, dialogService) { |
5d8901af | 179 | var ts = $scope.ts = CRM.ts(null); |
360aaa75 TO |
180 | |
181 | $scope.abtest = abtest; | |
182 | ||
183 | $scope.stats = {}; | |
184 | crmApi('Mailing', 'stats', {mailing_id: abtest.ab.mailing_id_a}).then(function(data){ | |
185 | $scope.stats.a = data.values[abtest.ab.mailing_id_a]; | |
186 | }); | |
187 | crmApi('Mailing', 'stats', {mailing_id: abtest.ab.mailing_id_b}).then(function(data){ | |
188 | $scope.stats.b = data.values[abtest.ab.mailing_id_b]; | |
189 | }); | |
32b8b0bf TO |
190 | crmApi('Mailing', 'stats', {mailing_id: abtest.ab.mailing_id_c}).then(function(data){ |
191 | $scope.stats.c = data.values[abtest.ab.mailing_id_c]; | |
192 | }); | |
193 | ||
194 | $scope.previewMailing = function previewMailing(mailingName, mode) { | |
195 | return crmMailingPreviewMgr.preview(abtest.mailings[mailingName], mode); | |
196 | }; | |
197 | $scope.selectWinner = function selectWinner(mailingName) { | |
198 | var model = { | |
199 | abtest: abtest, | |
200 | mailingName: mailingName | |
201 | }; | |
b1fc510d | 202 | var options = CRM.utils.adjustDialogDefaults({ |
32b8b0bf | 203 | autoOpen: false, |
32b8b0bf TO |
204 | title: ts('Select Winner (%1)', { |
205 | 1: mailingName.toUpperCase() | |
206 | }) | |
b1fc510d | 207 | }); |
ef5d18a1 | 208 | return dialogService.open('selectWinnerDialog', '~/crmMailingAB/selectWinner.html', model, options); |
32b8b0bf TO |
209 | }; |
210 | }); | |
211 | ||
212 | ||
213 | angular.module('crmMailingAB').controller('CrmMailingABWinnerDialogCtrl', function ($scope, $timeout, dialogService, crmMailingMgr, crmStatus) { | |
5d8901af | 214 | var ts = $scope.ts = CRM.ts(null); |
32b8b0bf TO |
215 | var abtest = $scope.abtest = $scope.model.abtest; |
216 | var mailingName = $scope.model.mailingName; | |
217 | ||
218 | var titles = {a: ts('Mailing A'), b: ts('Mailing B')}; | |
219 | $scope.mailingTitle = titles[mailingName]; | |
220 | ||
221 | function init() { | |
222 | // When using dialogService with a button bar, the major button actions | |
223 | // need to be registered with the dialog widget (and not embedded in | |
224 | // the body of the dialog). | |
225 | var buttons = {}; | |
226 | buttons[ts('Select Winner')] = function () { | |
227 | crmMailingMgr.mergeInto(abtest.mailings.c, abtest.mailings[mailingName], [ | |
228 | 'name', | |
9cd4f489 | 229 | 'recipients', |
32b8b0bf TO |
230 | 'scheduled_date' |
231 | ]); | |
232 | crmStatus({start: ts('Saving...'), success: ''}, abtest.save()) | |
233 | .then(function () { | |
234 | return crmStatus({start: ts('Submitting...'), success: ts('Submitted')}, | |
235 | abtest.submitFinal().then(function(){ | |
236 | return abtest.load(); | |
237 | })); | |
238 | }) | |
239 | .then(function(){ | |
240 | dialogService.close('selectWinnerDialog', abtest); | |
241 | }); | |
242 | }; | |
243 | buttons[ts('Cancel')] = function () { | |
244 | dialogService.cancel('selectWinnerDialog'); | |
245 | }; | |
246 | dialogService.setButtons('selectWinnerDialog', buttons); | |
247 | } | |
248 | ||
249 | $timeout(init); | |
360aaa75 TO |
250 | }); |
251 | ||
70980d8e | 252 | })(angular, CRM.$, CRM._); |