Commit | Line | Data |
---|---|---|
70980d8e TO |
1 | (function (angular, $, _) { |
2 | ||
882e1558 | 3 | angular.module('crmMailingAB', ['ngRoute', 'ui.utils', '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}); | |
5ad42de8 TO |
13 | }, |
14 | fields: function(crmMetadata){ | |
15 | return crmMetadata.getFields('MailingAB'); | |
70980d8e TO |
16 | } |
17 | } | |
18 | }); | |
a12bd71d TO |
19 | $routeProvider.when('/abtest/new', { |
20 | template: '<p>' + ts('Initializing...') + '</p>', | |
21 | controller: 'CrmMailingABNewCtrl', | |
22 | resolve: { | |
23 | abtest: function ($route, CrmMailingAB) { | |
24 | var abtest = new CrmMailingAB(null); | |
25 | return abtest.load().then(function(){ | |
26 | return abtest.save(); | |
27 | }); | |
28 | } | |
29 | } | |
30 | }); | |
efd95528 | 31 | $routeProvider.when('/abtest/:id', { |
3ad2ea69 | 32 | templateUrl: '~/crmMailingAB/main.html', |
efd95528 | 33 | controller: 'CrmMailingABEditCtrl', |
70980d8e TO |
34 | resolve: { |
35 | abtest: function ($route, CrmMailingAB) { | |
36 | var abtest = new CrmMailingAB($route.current.params.id == 'new' ? null : $route.current.params.id); | |
37 | return abtest.load(); | |
38 | } | |
39 | } | |
40 | }); | |
41 | } | |
42 | ]); | |
43 | ||
5ad42de8 | 44 | angular.module('crmMailingAB').controller('CrmMailingABListCtrl', function($scope, mailingABList, crmMailingABCriteria, crmMailingABStatus, fields) { |
5d8901af | 45 | var ts = $scope.ts = CRM.ts(null); |
5ad42de8 | 46 | $scope.mailingABList = _.values(mailingABList.values); |
63430d3c TO |
47 | $scope.crmMailingABCriteria = crmMailingABCriteria; |
48 | $scope.crmMailingABStatus = crmMailingABStatus; | |
5ad42de8 TO |
49 | $scope.fields = fields; |
50 | $scope.filter = {}; | |
a7931384 | 51 | }); |
70980d8e | 52 | |
a12bd71d TO |
53 | angular.module('crmMailingAB').controller('CrmMailingABNewCtrl', function ($scope, abtest, $location) { |
54 | // Transition URL "/abtest/new/foo" => "/abtest/123/foo" | |
55 | var parts = $location.path().split('/'); // e.g. "/mailing/new" or "/mailing/123/wizard" | |
56 | parts[2] = abtest.id; | |
57 | $location.path(parts.join('/')); | |
58 | $location.replace(); | |
59 | }); | |
60 | ||
6877567a | 61 | angular.module('crmMailingAB').controller('CrmMailingABEditCtrl', function ($scope, abtest, crmMailingABCriteria, crmMailingMgr, crmMailingPreviewMgr, crmStatus, $q, $location, crmBlocker, $interval, $timeout, CrmAutosaveCtrl, dialogService) { |
70980d8e | 62 | $scope.abtest = abtest; |
5d8901af | 63 | var ts = $scope.ts = CRM.ts(null); |
a12bd71d | 64 | var block = $scope.block = crmBlocker(); |
6877567a TO |
65 | $scope.crmUrl = CRM.url; |
66 | var myAutosave = null; | |
af6962d8 | 67 | $scope.crmMailingABCriteria = crmMailingABCriteria; |
bcdd7f49 | 68 | $scope.crmMailingConst = CRM.crmMailing; |
0fc156d9 | 69 | $scope.checkPerm = CRM.checkPerm; |
af6962d8 | 70 | |
86c3a327 TO |
71 | $scope.isSubmitted = function isSubmitted() { |
72 | return _.size(abtest.mailings.a.jobs) > 0 || _.size(abtest.mailings.b.jobs) > 0; | |
73 | }; | |
c9e9a71e | 74 | |
70980d8e TO |
75 | $scope.sync = function sync() { |
76 | abtest.mailings.a.name = ts('Test A (%1)', {1: abtest.ab.name}); | |
77 | abtest.mailings.b.name = ts('Test B (%1)', {1: abtest.ab.name}); | |
c65ef09e | 78 | abtest.mailings.c.name = ts('Final (%1)', {1: abtest.ab.name}); |
70980d8e | 79 | |
05aaa6ae | 80 | if (abtest.ab.testing_criteria) { |
d3b6424f | 81 | // TODO review fields exposed in UI and make sure the sync rules match |
05aaa6ae TO |
82 | switch (abtest.ab.testing_criteria) { |
83 | case 'subject': | |
c9e9a71e TO |
84 | crmMailingMgr.mergeInto(abtest.mailings.b, abtest.mailings.a, [ |
85 | 'name', | |
9cd4f489 | 86 | 'recipients', |
c9e9a71e TO |
87 | 'subject' |
88 | ]); | |
70980d8e | 89 | break; |
05aaa6ae | 90 | case 'from': |
c9e9a71e TO |
91 | crmMailingMgr.mergeInto(abtest.mailings.b, abtest.mailings.a, [ |
92 | 'name', | |
9cd4f489 | 93 | 'recipients', |
c9e9a71e TO |
94 | 'from_name', |
95 | 'from_email' | |
96 | ]); | |
70980d8e | 97 | break; |
05aaa6ae | 98 | case 'full_email': |
70980d8e TO |
99 | crmMailingMgr.mergeInto(abtest.mailings.b, abtest.mailings.a, [ |
100 | 'name', | |
9cd4f489 | 101 | 'recipients', |
70980d8e TO |
102 | 'subject', |
103 | 'from_name', | |
104 | 'from_email', | |
495f197a TO |
105 | 'replyto_email', |
106 | 'override_verp', // keep override_verp and replyto_Email linked | |
70980d8e TO |
107 | 'body_html', |
108 | 'body_text' | |
109 | ]); | |
110 | break; | |
111 | default: | |
112 | throw "Unrecognized testing_criteria"; | |
113 | } | |
114 | } | |
115 | crmMailingMgr.mergeInto(abtest.mailings.c, abtest.mailings.a, ['name']); | |
ce245e83 | 116 | return true; |
70980d8e | 117 | }; |
86c3a327 TO |
118 | |
119 | // @return Promise | |
70980d8e | 120 | $scope.save = function save() { |
80e64ffc | 121 | return block(crmStatus({start: ts('Saving...'), success: ts('Saved')}, abtest.save())); |
58dfba8d | 122 | }; |
86c3a327 | 123 | |
58dfba8d TO |
124 | // @return Promise |
125 | $scope.previewMailing = function previewMailing(mailingName, mode) { | |
126 | return crmMailingPreviewMgr.preview(abtest.mailings[mailingName], mode); | |
127 | }; | |
128 | ||
129 | // @return Promise | |
130 | $scope.sendTest = function sendTest(mailingName, recipient) { | |
80e64ffc | 131 | return block(crmStatus({start: ts('Saving...'), success: ''}, abtest.save()) |
58dfba8d TO |
132 | .then(function () { |
133 | crmMailingPreviewMgr.sendTest(abtest.mailings[mailingName], recipient); | |
a12bd71d | 134 | })); |
70980d8e | 135 | }; |
86c3a327 TO |
136 | |
137 | // @return Promise | |
70980d8e | 138 | $scope.delete = function () { |
a12bd71d | 139 | return block(crmStatus({start: ts('Deleting...'), success: ts('Deleted')}, abtest.delete().then($scope.leave))); |
70980d8e | 140 | }; |
86c3a327 TO |
141 | |
142 | // @return Promise | |
143 | $scope.submit = function submit() { | |
ce245e83 | 144 | if (block.check() || $scope.crmMailingAB.$invalid) { |
a12bd71d TO |
145 | return; |
146 | } | |
147 | return block(crmStatus({start: ts('Saving...'), success: ''}, abtest.save()) | |
148 | .then(function() { | |
6877567a | 149 | return crmStatus({start: ts('Submitting...'), success: ts('Submitted')}, myAutosave.suspend(abtest.submitTest())); |
a12bd71d TO |
150 | // Note: We're going to leave, so we don't care that submit() modifies several server-side records. |
151 | // If we stayed on this page, then we'd care about updating and call: abtest.submitTest().then(...abtest.load()...) | |
152 | }) | |
43c27a4c | 153 | ); |
22bc3e48 TO |
154 | }; |
155 | ||
a12bd71d | 156 | $scope.leave = function leave() { |
b0797ac3 TO |
157 | $location.path('abtest'); |
158 | $location.replace(); | |
a12bd71d | 159 | }; |
b0797ac3 | 160 | |
6877567a TO |
161 | $scope.selectWinner = function selectWinner(mailingName) { |
162 | var model = { | |
163 | abtest: $scope.abtest, | |
164 | mailingName: mailingName | |
165 | }; | |
166 | var options = CRM.utils.adjustDialogDefaults({ | |
167 | autoOpen: false, | |
b315fbbc CW |
168 | height: 'auto', |
169 | width: '40%', | |
c65ef09e | 170 | title: ts('Select Final Mailing (Test %1)', { |
6877567a TO |
171 | 1: mailingName.toUpperCase() |
172 | }) | |
173 | }); | |
174 | return myAutosave.suspend(dialogService.open('selectWinnerDialog', '~/crmMailingAB/selectWinner.html', model, options)); | |
175 | }; | |
176 | ||
22bc3e48 | 177 | // initialize |
ce245e83 TO |
178 | var syncJob = $interval($scope.sync, 333); |
179 | $scope.$on('$destroy', function(){ | |
180 | $interval.cancel(syncJob); | |
181 | }); | |
e08a61f9 | 182 | |
6877567a | 183 | myAutosave = new CrmAutosaveCtrl({ |
e08a61f9 | 184 | save: $scope.save, |
6877567a TO |
185 | saveIf: function(){ |
186 | return abtest.ab.status == 'Draft' && $scope.sync(); | |
187 | }, | |
e08a61f9 TO |
188 | model: function(){ |
189 | return abtest.getAutosaveSignature(); | |
190 | }, | |
191 | form: function() { | |
192 | return $scope.crmMailingAB; | |
193 | } | |
194 | }); | |
195 | $timeout(myAutosave.start); | |
196 | $scope.$on('$destroy', myAutosave.stop); | |
70980d8e TO |
197 | }); |
198 | ||
7173e315 | 199 | angular.module('crmMailingAB').controller('CrmMailingABReportCtrl', function ($scope, crmApi, crmMailingStats) { |
5d8901af | 200 | var ts = $scope.ts = CRM.ts(null); |
360aaa75 | 201 | |
00d99fa7 | 202 | var CrmMailingABReportCnt = 1, activeMailings = null; |
e038321f | 203 | $scope.getActiveMailings = function() { |
00d99fa7 TO |
204 | if ($scope.abtest.$CrmMailingABReportCnt != CrmMailingABReportCnt) { |
205 | $scope.abtest.$CrmMailingABReportCnt = ++CrmMailingABReportCnt; | |
e038321f | 206 | activeMailings = [ |
deea897f TO |
207 | {name: 'a', title: ts('Mailing A'), mailing: $scope.abtest.mailings.a, attachments: $scope.abtest.attachments.a}, |
208 | {name: 'b', title: ts('Mailing B'), mailing: $scope.abtest.mailings.b, attachments: $scope.abtest.attachments.b} | |
e038321f TO |
209 | ]; |
210 | if ($scope.abtest.ab.status == 'Final') { | |
deea897f | 211 | activeMailings.push({name: 'c', title: ts('Final'), mailing: $scope.abtest.mailings.c, attachments: $scope.abtest.attachments.c}); |
e038321f TO |
212 | } |
213 | } | |
214 | return activeMailings; | |
215 | }; | |
216 | ||
7173e315 TO |
217 | crmMailingStats.getStats({ |
218 | a: $scope.abtest.ab.mailing_id_a, | |
219 | b: $scope.abtest.ab.mailing_id_b, | |
220 | c: $scope.abtest.ab.mailing_id_c | |
221 | }).then(function(stats) { | |
222 | $scope.stats = stats; | |
32b8b0bf | 223 | }); |
7173e315 TO |
224 | |
225 | $scope.statTypes = crmMailingStats.getStatTypes(); | |
226 | $scope.statUrl = function statUrl(mailing, statType, view) { | |
05381a97 | 227 | return crmMailingStats.getUrl(mailing, statType, view, 'abtest/' + $scope.abtest.ab.id); |
7173e315 | 228 | }; |
8f685a33 TO |
229 | |
230 | $scope.checkPerm = CRM.checkPerm; | |
32b8b0bf TO |
231 | }); |
232 | ||
32b8b0bf | 233 | angular.module('crmMailingAB').controller('CrmMailingABWinnerDialogCtrl', function ($scope, $timeout, dialogService, crmMailingMgr, crmStatus) { |
5d8901af | 234 | var ts = $scope.ts = CRM.ts(null); |
32b8b0bf TO |
235 | var abtest = $scope.abtest = $scope.model.abtest; |
236 | var mailingName = $scope.model.mailingName; | |
237 | ||
238 | var titles = {a: ts('Mailing A'), b: ts('Mailing B')}; | |
239 | $scope.mailingTitle = titles[mailingName]; | |
240 | ||
241 | function init() { | |
242 | // When using dialogService with a button bar, the major button actions | |
243 | // need to be registered with the dialog widget (and not embedded in | |
244 | // the body of the dialog). | |
b315fbbc CW |
245 | var buttons = [ |
246 | { | |
247 | text: ts('Submit final mailing'), | |
248 | icons: {primary: 'ui-icon-check'}, | |
249 | click: function () { | |
250 | crmMailingMgr.mergeInto(abtest.mailings.c, abtest.mailings[mailingName], [ | |
251 | 'name', | |
252 | 'recipients', | |
253 | 'scheduled_date' | |
254 | ]); | |
255 | crmStatus({start: ts('Saving...'), success: ''}, abtest.save()) | |
256 | .then(function () { | |
257 | return crmStatus({start: ts('Submitting...'), success: ts('Submitted')}, | |
258 | abtest.submitFinal().then(function(r){ | |
259 | delete abtest.$CrmMailingABReportCnt; | |
260 | return r; | |
261 | })); | |
262 | }) | |
263 | .then(function(){ | |
264 | dialogService.close('selectWinnerDialog', abtest); | |
265 | }); | |
266 | } | |
267 | }, | |
268 | { | |
269 | text: ts('Cancel'), | |
270 | icons: {primary: 'ui-icon-close'}, | |
271 | click: function () { | |
272 | dialogService.cancel('selectWinnerDialog'); | |
273 | } | |
274 | } | |
275 | ]; | |
32b8b0bf TO |
276 | dialogService.setButtons('selectWinnerDialog', buttons); |
277 | } | |
278 | ||
279 | $timeout(init); | |
360aaa75 TO |
280 | }); |
281 | ||
70980d8e | 282 | })(angular, CRM.$, CRM._); |