| 1 | (function(angular, $, _) { |
| 2 | |
| 3 | angular.module('crmMailingAB').controller('CrmMailingABEditCtrl', function($scope, abtest, crmMailingABCriteria, crmMailingMgr, crmMailingPreviewMgr, crmStatus, $q, $location, crmBlocker, $interval, $timeout, CrmAutosaveCtrl, dialogService, mailingFields) { |
| 4 | $scope.abtest = abtest; |
| 5 | var ts = $scope.ts = CRM.ts(null); |
| 6 | var block = $scope.block = crmBlocker(); |
| 7 | $scope.crmUrl = CRM.url; |
| 8 | var myAutosave = null; |
| 9 | $scope.crmMailingABCriteria = crmMailingABCriteria; |
| 10 | $scope.crmMailingConst = CRM.crmMailing; |
| 11 | $scope.checkPerm = CRM.checkPerm; |
| 12 | $scope.mailingFields = mailingFields; |
| 13 | |
| 14 | $scope.isSubmitted = function isSubmitted() { |
| 15 | return _.size(abtest.mailings.a.jobs) > 0 || _.size(abtest.mailings.b.jobs) > 0; |
| 16 | }; |
| 17 | |
| 18 | $scope.sync = function sync() { |
| 19 | abtest.mailings.a.name = ts('Test A (%1)', {1: abtest.ab.name}); |
| 20 | abtest.mailings.b.name = ts('Test B (%1)', {1: abtest.ab.name}); |
| 21 | abtest.mailings.c.name = ts('Final (%1)', {1: abtest.ab.name}); |
| 22 | |
| 23 | if (abtest.ab.testing_criteria) { |
| 24 | // TODO review fields exposed in UI and make sure the sync rules match |
| 25 | switch (abtest.ab.testing_criteria) { |
| 26 | case 'subject': |
| 27 | var exclude_subject = [ |
| 28 | 'name', |
| 29 | 'recipients', |
| 30 | 'subject' |
| 31 | ]; |
| 32 | crmMailingMgr.mergeInto(abtest.mailings.b, abtest.mailings.a, exclude_subject); |
| 33 | crmMailingMgr.mergeInto(abtest.mailings.c, abtest.mailings.a, exclude_subject); |
| 34 | break; |
| 35 | case 'from': |
| 36 | var exclude_from = [ |
| 37 | 'name', |
| 38 | 'recipients', |
| 39 | 'from_name', |
| 40 | 'from_email' |
| 41 | ]; |
| 42 | crmMailingMgr.mergeInto(abtest.mailings.b, abtest.mailings.a, exclude_from); |
| 43 | crmMailingMgr.mergeInto(abtest.mailings.c, abtest.mailings.a, exclude_from); |
| 44 | break; |
| 45 | case 'full_email': |
| 46 | var exclude_full_email = [ |
| 47 | 'name', |
| 48 | 'recipients', |
| 49 | 'subject', |
| 50 | 'from_name', |
| 51 | 'from_email', |
| 52 | 'replyto_email', |
| 53 | 'override_verp', // keep override_verp and replyto_Email linked |
| 54 | 'body_html', |
| 55 | 'body_text' |
| 56 | ]; |
| 57 | crmMailingMgr.mergeInto(abtest.mailings.b, abtest.mailings.a, exclude_full_email); |
| 58 | crmMailingMgr.mergeInto(abtest.mailings.c, abtest.mailings.a, exclude_full_email); |
| 59 | break; |
| 60 | default: |
| 61 | throw "Unrecognized testing_criteria"; |
| 62 | } |
| 63 | } |
| 64 | return true; |
| 65 | }; |
| 66 | |
| 67 | // @return Promise |
| 68 | $scope.save = function save() { |
| 69 | return block(crmStatus({start: ts('Saving...'), success: ts('Saved')}, abtest.save())); |
| 70 | }; |
| 71 | |
| 72 | // @return Promise |
| 73 | $scope.previewMailing = function previewMailing(mailingName, mode) { |
| 74 | return crmMailingPreviewMgr.preview(abtest.mailings[mailingName], mode); |
| 75 | }; |
| 76 | |
| 77 | // @return Promise |
| 78 | $scope.sendTest = function sendTest(mailingName, recipient) { |
| 79 | return block(crmStatus({start: ts('Saving...'), success: ''}, abtest.save()) |
| 80 | .then(function() { |
| 81 | crmMailingPreviewMgr.sendTest(abtest.mailings[mailingName], recipient); |
| 82 | })); |
| 83 | }; |
| 84 | |
| 85 | // @return Promise |
| 86 | $scope.delete = function() { |
| 87 | return block(crmStatus({start: ts('Deleting...'), success: ts('Deleted')}, abtest.delete().then($scope.leave))); |
| 88 | }; |
| 89 | |
| 90 | // @return Promise |
| 91 | $scope.submit = function submit() { |
| 92 | if (block.check() || $scope.crmMailingAB.$invalid) { |
| 93 | return; |
| 94 | } |
| 95 | return block(crmStatus({start: ts('Saving...'), success: ''}, abtest.save()) |
| 96 | .then(function() { |
| 97 | return crmStatus({ |
| 98 | start: ts('Submitting...'), |
| 99 | success: ts('Submitted') |
| 100 | }, myAutosave.suspend(abtest.submitTest())); |
| 101 | // Note: We're going to leave, so we don't care that submit() modifies several server-side records. |
| 102 | // If we stayed on this page, then we'd care about updating and call: abtest.submitTest().then(...abtest.load()...) |
| 103 | }) |
| 104 | ); |
| 105 | }; |
| 106 | |
| 107 | $scope.leave = function leave() { |
| 108 | $location.path('abtest'); |
| 109 | $location.replace(); |
| 110 | }; |
| 111 | |
| 112 | $scope.selectWinner = function selectWinner(mailingName) { |
| 113 | var model = { |
| 114 | abtest: $scope.abtest, |
| 115 | mailingName: mailingName |
| 116 | }; |
| 117 | var options = CRM.utils.adjustDialogDefaults({ |
| 118 | autoOpen: false, |
| 119 | height: 'auto', |
| 120 | width: '40%', |
| 121 | title: ts('Select Final Mailing (Test %1)', { |
| 122 | 1: mailingName.toUpperCase() |
| 123 | }) |
| 124 | }); |
| 125 | return myAutosave.suspend(dialogService.open('selectWinnerDialog', '~/crmMailingAB/WinnerDialogCtrl.html', model, options)); |
| 126 | }; |
| 127 | |
| 128 | // initialize |
| 129 | var syncJob = $interval($scope.sync, 333); |
| 130 | $scope.$on('$destroy', function() { |
| 131 | $interval.cancel(syncJob); |
| 132 | }); |
| 133 | |
| 134 | myAutosave = new CrmAutosaveCtrl({ |
| 135 | save: $scope.save, |
| 136 | saveIf: function() { |
| 137 | return abtest.ab.status == 'Draft' && $scope.sync(); |
| 138 | }, |
| 139 | model: function() { |
| 140 | return abtest.getAutosaveSignature(); |
| 141 | }, |
| 142 | form: function() { |
| 143 | return $scope.crmMailingAB; |
| 144 | } |
| 145 | }); |
| 146 | $timeout(myAutosave.start); |
| 147 | $scope.$on('$destroy', myAutosave.stop); |
| 148 | }); |
| 149 | |
| 150 | })(angular, CRM.$, CRM._); |