};
});
+ angular.module('crmMailing').factory('crmMailingStats', function (crmApi, crmLegacy) {
+ var statTypes = [
+ // {name: 'Recipients', title: ts('Intended Recipients'), searchFilter: '', eventsFilter: '&event=queue'},
+ {name: 'Delivered', title: ts('Successful Deliveries'), searchFilter: '&mailing_delivery_status=Y', eventsFilter: '&event=delivered'},
+ {name: 'Opened', title: ts('Tracked Opens'), searchFilter: '&mailing_open_status=Y', eventsFilter: '&event=opened'},
+ {name: 'Unique Clicks', title: ts('Click-throughs'), searchFilter: '&mailing_click_status=Y', eventsFilter: '&event=click&distinct=1'},
+ // {name: 'Forward', title: ts('Forwards'), searchFilter: '&mailing_forward=1', eventsFilter: '&event=forward'},
+ // {name: 'Replies', title: ts('Replies'), searchFilter: '&mailing_reply_status=Y', eventsFilter: '&event=reply'},
+ {name: 'Bounces', title: ts('Bounces'), searchFilter: '&mailing_delivery_status=N', eventsFilter: '&event=bounce'},
+ {name: 'Unsubscribers', title: ts('Unsubscribes'), searchFilter: '&mailing_unsubscribe=1', eventsFilter: '&event=unsubscribe'}
+ // {name: 'OptOuts', title: ts('Opt-Outs'), searchFilter: '&mailing_optout=1', eventsFilter: '&event=optout'}
+ ];
+
+ return {
+ getStatTypes: function() {
+ return statTypes;
+ },
+
+ /**
+ * @param mailingIds object
+ * List of mailing IDs ({a: 123, b: 456})
+ * @return Promise
+ * List of stats for each mailing
+ * ({a: ...object..., b: ...object...})
+ */
+ getStats: function(mailingIds) {
+ var params = {};
+ angular.forEach(mailingIds, function(mailingId, name) {
+ params[name] = ['Mailing', 'stats', {mailing_id: mailingId}];
+ });
+ return crmApi(params).then(function(result) {
+ var stats = {};
+ angular.forEach(mailingIds, function(mailingId, name) {
+ stats[name] = result[name].values[mailingId];
+ });
+ return stats;
+ });
+ },
+
+ /**
+ * Determine the legacy URL for a report about a given mailing and stat.
+ *
+ * @param mailing object
+ * @param statType object (see statTypes above)
+ * @param view string ('search', 'event', 'report')
+ * @return string|null
+ */
+ getUrl: function getUrl(mailing, statType, view) {
+ switch (view) {
+ case 'events':
+ return crmLegacy.url('civicrm/mailing/report/event',
+ 'reset=1&mid=' + mailing.id + statType.eventsFilter);
+
+ case 'search':
+ return crmLegacy.url('civicrm/contact/search/advanced',
+ 'force=1&mailing_id=' + mailing.id + statType.searchFilter);
+
+ // TODO: case 'report':
+ default:
+ return null;
+ }
+ }
+ };
+ });
+
})(angular, CRM.$, CRM._);
$scope.$on('$destroy', myAutosave.stop);
});
- angular.module('crmMailingAB').controller('CrmMailingABReportCtrl', function ($scope, crmApi, crmMailingStats, crmLegacy) {
+ angular.module('crmMailingAB').controller('CrmMailingABReportCtrl', function ($scope, crmApi, crmMailingStats) {
var ts = $scope.ts = CRM.ts(null);
- $scope.stats = {};
- crmApi('Mailing', 'stats', {mailing_id: $scope.abtest.ab.mailing_id_a}).then(function(data){
- $scope.stats.a = data.values[$scope.abtest.ab.mailing_id_a];
- });
- crmApi('Mailing', 'stats', {mailing_id: $scope.abtest.ab.mailing_id_b}).then(function(data){
- $scope.stats.b = data.values[$scope.abtest.ab.mailing_id_b];
- });
- crmApi('Mailing', 'stats', {mailing_id: $scope.abtest.ab.mailing_id_c}).then(function(data){
- $scope.stats.c = data.values[$scope.abtest.ab.mailing_id_c];
+ crmMailingStats.getStats({
+ a: $scope.abtest.ab.mailing_id_a,
+ b: $scope.abtest.ab.mailing_id_b,
+ c: $scope.abtest.ab.mailing_id_c
+ }).then(function(stats) {
+ $scope.stats = stats;
});
+
+ $scope.statTypes = crmMailingStats.getStatTypes();
+ $scope.statUrl = function statUrl(mailing, statType, view) {
+ return crmMailingStats.getUrl(mailing, statType, view);
+ };
});
angular.module('crmMailingAB').controller('CrmMailingABWinnerDialogCtrl', function ($scope, $timeout, dialogService, crmMailingMgr, crmStatus) {
<td><a ng-click="previewMailing('b','text')" ng-show="abtest.mailings.b.body_text">{{ts('View')}}</a></td>
<td><a ng-click="previewMailing('c','text')" ng-show="abtest.mailings.c.body_text && abtest.ab.status == 'Final'">{{ts('View')}}</a></td>
</tr>
- <tr>
- <td>{{ts('Deliveries')}}</td>
- <td>{{stats.a.Delivered}}</td>
- <td>{{stats.b.Delivered}}</td>
- <td ng-show="abtest.ab.status == 'Final'">{{stats.c.Delivered}}</td>
- </tr>
- <tr>
- <td>{{ts('Opens')}}</td>
- <td>{{stats.a.Opened}}</td>
- <td>{{stats.b.Opened}}</td>
- <td ng-show="abtest.ab.status == 'Final'">{{stats.c.Opened}}</td>
- </tr>
- <tr>
- <td>{{ts('Unique Clicks')}}</td>
- <td>{{stats.a['Unique Clicks']}}</td>
- <td>{{stats.b['Unique Clicks']}}</td>
- <td ng-show="abtest.ab.status == 'Final'">{{stats.c['Unique Clicks']}}</td>
- </tr>
- <tr>
- <td>{{ts('Bounces')}}</td>
- <td>{{stats.a.Bounces}}</td>
- <td>{{stats.b.Bounces}}</td>
- <td ng-show="abtest.ab.status == 'Final'">{{stats.c.Bounces}}</td>
- </tr>
- <tr>
- <td>{{ts('Unsubscribes')}}</td>
- <td>{{stats.a.Unsubscribers}}</td>
- <td>{{stats.b.Unsubscribers}}</td>
- <td ng-show="abtest.ab.status == 'Final'">{{stats.c.Unsubscribers}}</td>
+ <tr ng-repeat="statType in statTypes">
+ <td>{{statType.title}}</td>
+ <td>
+ <a class="crm-hover-button" ng-href="{{statUrl(abtest.mailings.a, statType, 'events')}}" title="{{statType.title}}">{{stats.a[statType.name] || ts('n/a')}}</a>
+ <a class="crm-hover-button" ng-href="{{statUrl(abtest.mailings.a, statType, 'search')}}" title="{{ts('Search for contacts')}}" crm-icon="search"></a>
+ </td>
+ <td>
+ <a class="crm-hover-button" ng-href="{{statUrl(abtest.mailings.b, statType, 'events')}}" title="{{statType.title}}">{{stats.b[statType.name] || ts('n/a')}}</a>
+ <a class="crm-hover-button" ng-href="{{statUrl(abtest.mailings.b, statType, 'search')}}" title="{{ts('Search for contacts')}}" crm-icon="search"></a>
+ </td>
+ <td ng-show="abtest.ab.status == 'Final'">
+ <a class="crm-hover-button" ng-href="{{statUrl(abtest.mailings.c, statType, 'events')}}" title="{{statType.title}}">{{stats.a[statType.name] || ts('n/a')}}</a>
+ <a class="crm-hover-button" ng-href="{{statUrl(abtest.mailings.c, statType, 'search')}}" title="{{ts('Search for contacts')}}" crm-icon="search"></a>
+ </td>
</tr>
<tr ng-show="abtest.ab.status == 'Testing'">
<td></td>