EST_BATCH_TIME = 5;
this.$onInit = function() {
+ if (ctrl.action === 'create') {
+ ctrl.ids = [0];
+ }
totalBatches = Math.ceil(ctrl.ids.length / BATCH_SIZE);
runBatch();
};
records.push(record);
});
});
- } else {
+ } else if (ctrl.action !== 'create') {
// For other batch actions (update, delete), add supplied ids to the where clause
params.where = params.where || [];
params.where.push([ctrl.idField || 'id', 'IN', ctrl.ids.slice(ctrl.first, ctrl.last)]);
stopIncrementer();
ctrl.progress = Math.floor(100 * ++currentBatch / totalBatches);
if (ctrl.last >= ctrl.ids.length) {
- $timeout(ctrl.success, 500);
+ $timeout(function() {
+ ctrl.success({result: result});
+ }, 500);
} else {
runBatch();
}
--- /dev/null
+(function(angular, $, _) {
+ "use strict";
+
+ angular.module('crmSearchTasks').controller('crmSearchTaskMailing', function($scope, crmApi4, searchTaskBaseTrait) {
+ var ts = $scope.ts = CRM.ts('org.civicrm.search_kit'),
+ // Combine this controller with model properties (ids, entity, entityInfo) and searchTaskBaseTrait
+ ctrl = angular.extend(this, $scope.model, searchTaskBaseTrait),
+ templateTypes;
+
+ this.entityTitle = this.getEntityTitle();
+
+ // This option is needed to determine whether the mailing will be handled by CiviMail or Mosaico
+ crmApi4({
+ templateTypes: ['Mailing', 'getFields', {
+ loadOptions: ['id'],
+ where: [['name', '=', 'template_type']]
+ }, ['options']],
+ recipientCount: ['Contact', 'get', {
+ select: ['row_count'],
+ join: [['Email AS email', 'INNER', ['id', '=', 'email.contact_id']]],
+ where: [['id', 'IN', ctrl.ids], ['do_not_email', '!=', true], ['is_opt_out', '!=', true], ['email.on_hold', '=', 0]],
+ groupBy: ['id']
+ }]
+ }).then(function(results) {
+ templateTypes = results.templateTypes[0];
+ ctrl.recipientCount = results.recipientCount.count;
+ });
+
+ this.submit = function() {
+ var contacts = _.transform(ctrl.ids, function(records, cid) {
+ records.push({contact_id: cid});
+ });
+ ctrl.start({
+ values: {
+ title: 'Hidden Group ' + Date.now(),
+ is_hidden: true,
+ 'group_type:name': ['Mailing List'],
+ },
+ chain: {
+ contacts: ['GroupContact', 'save', {
+ defaults: {group_id: '$id'},
+ records: contacts
+ }],
+ mailing: ['Mailing', 'create', {
+ values: {
+ name: ctrl.name,
+ template_type: templateTypes[0].id
+ }
+ }, 0],
+ mailingGroup: ['MailingGroup', 'create', {
+ values: {
+ group_type: 'Include',
+ 'entity_table:name': 'Group',
+ entity_id: '$id',
+ mailing_id: '$mailing.id'
+ },
+ }, 0]
+ }
+ });
+ };
+
+
+ this.onSuccess = function(result) {
+ window.location = CRM.url('civicrm/a#/mailing/' + result[0].mailing.id);
+ };
+
+ this.onError = function() {
+ CRM.alert(ts('An error occurred while attempting to create mailing.'), ts('Error'), 'error');
+ this.cancel();
+ };
+
+ });
+})(angular, CRM.$, CRM._);
--- /dev/null
+<div id="bootstrap-theme" crm-dialog="crmSearchTask">
+ <form name="crmSearchTaskMailingForm" ng-controller="crmSearchTaskMailing as $ctrl">
+ <div class="alert alert-info">
+ <p>{{:: ts('Compose and send a mass-mailing to the %1 selected contacts (you will be able to add or exclude additional groups of contacts in the next step).', {1: $ctrl.ids.length}) }}</p>
+ </div>
+ <label for="crm-search-task-mailing-name">{{:: ts('Mailing Name') }} <span class="crm-marker">*</span></label>
+ <input required class="form-control" id="crm-search-task-mailing-name" ng-model="$ctrl.name">
+ <br>
+ <div ng-if="!$ctrl.run" class="alert" ng-class="{'alert-success': $ctrl.recipientCount === $ctrl.ids.length, 'alert-danger': $ctrl.recipientCount === 0, 'alert-warning': $ctrl.recipientCount !== 0 && $ctrl.recipientCount < $ctrl.ids.length}">
+ <div ng-if="!$ctrl.recipientCount && $ctrl.recipientCount !== 0">
+ <i class="crm-i fa-spinner fa-spin"></i>
+ {{:: ts('Checking recipients...') }}
+ </div>
+ <div ng-if="$ctrl.recipientCount === 0">
+ <i class="crm-i fa-exclamation-triangle"></i>
+ {{:: ts('None of the selected contacts are eligible to receive mailings (due to lack of email address or unsubscribe status).') }}
+ </div>
+ <div ng-if="$ctrl.recipientCount && $ctrl.recipientCount < $ctrl.ids.length">
+ <i class="crm-i fa-exclamation-triangle"></i>
+ {{:: ts('%1 of the selected contacts cannot receive mailings (due to lack of email address or unsubscribe status).', {1: $ctrl.ids.length - $ctrl.recipientCount}) }}
+ </div>
+ <div ng-if="$ctrl.recipientCount === $ctrl.ids.length">
+ <i class="crm-i fa-check-circle"></i>
+ {{:: ts('All of the selected contacts have active email addresses.') }}
+ </div>
+ </div>
+ <div ng-if="$ctrl.run" class="crm-search-task-progress">
+ <h5>{{:: ts('Creating mailing...') }}</h5>
+ <crm-search-batch-runner entity="'Group'" action="create" params="$ctrl.run" success="$ctrl.onSuccess(result)" error="$ctrl.onError()" ></crm-search-batch-runner>
+ </div>
+ <crm-dialog-button text="ts('Cancel')" icons="{primary: 'fa-times'}" on-click="$ctrl.cancel()" disabled="$ctrl.run" />
+ <crm-dialog-button text="ts('Create Mailing')" icons="{primary: 'fa-paper-plane'}" on-click="$ctrl.submit()" disabled="!$ctrl.recipientCount || $ctrl.run || !crmSearchTaskMailingForm.$valid" />
+ </form>
+</div>