add status preference dao to ignore list
[civicrm-core.git] / CRM / Campaign / Form / Task / Reserve.php
1 <?php
2 /*
3 +--------------------------------------------------------------------+
4 | CiviCRM version 4.6 |
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2015 |
7 +--------------------------------------------------------------------+
8 | This file is a part of CiviCRM. |
9 | |
10 | CiviCRM is free software; you can copy, modify, and distribute it |
11 | under the terms of the GNU Affero General Public License |
12 | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
13 | |
14 | CiviCRM is distributed in the hope that it will be useful, but |
15 | WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
17 | See the GNU Affero General Public License for more details. |
18 | |
19 | You should have received a copy of the GNU Affero General Public |
20 | License and the CiviCRM Licensing Exception along |
21 | with this program; if not, contact CiviCRM LLC |
22 | at info[AT]civicrm[DOT]org. If you have questions about the |
23 | GNU Affero General Public License or the licensing of CiviCRM, |
24 | see the CiviCRM license FAQ at http://civicrm.org/licensing |
25 +--------------------------------------------------------------------+
26 */
27
28 /**
29 *
30 * @package CRM
31 * @copyright CiviCRM LLC (c) 2004-2015
32 * $Id$
33 *
34 */
35
36 /**
37 * This class provides the functionality to add contacts for
38 * voter reservation.
39 */
40 class CRM_Campaign_Form_Task_Reserve extends CRM_Campaign_Form_Task {
41
42 /**
43 * Survet id`
44 *
45 * @var int
46 */
47 protected $_surveyId;
48
49 /**
50 * Interviewer id
51 *
52 * @var int
53 */
54 protected $_interviewerId;
55
56 /**
57 * Survey details
58 *
59 * @var object
60 */
61 protected $_surveyDetails;
62
63 /**
64 * Number of voters
65 *
66 * @var int
67 */
68 protected $_numVoters;
69
70 /**
71 * Build all the data structures needed to build the form.
72 *
73 * @return void
74 */
75 public function preProcess() {
76 parent::preProcess();
77
78 //get the survey id from user submitted values.
79 $this->_surveyId = $this->get('surveyId');
80 $this->_interviewerId = $this->get('interviewerId');
81 if (!$this->_surveyId) {
82 CRM_Core_Error::statusBounce(ts("Could not find Survey Id."));
83 }
84 if (!$this->_interviewerId) {
85 CRM_Core_Error::statusBounce(ts("Missing Interviewer contact."));
86 }
87 if (!is_array($this->_contactIds) || empty($this->_contactIds)) {
88 CRM_Core_Error::statusBounce(ts("Could not find contacts for reservation."));
89 }
90
91 $params = array('id' => $this->_surveyId);
92 CRM_Campaign_BAO_Survey::retrieve($params, $this->_surveyDetails);
93
94 //get the survey activities.
95 $activityStatus = CRM_Core_PseudoConstant::activityStatus('name');
96 $statusIds = array();
97 foreach (array('Scheduled') as $name) {
98 if ($statusId = array_search($name, $activityStatus)) {
99 $statusIds[] = $statusId;
100 }
101 }
102
103 // these are the activities count that are linked to the current
104 // interviewer and current survey and not the list of ALL survey activities
105 $this->_numVoters = CRM_Campaign_BAO_Survey::getSurveyActivities($this->_surveyId,
106 $this->_interviewerId,
107 $statusIds,
108 NULL,
109 TRUE
110 );
111 //validate the selected survey.
112 $this->validateSurvey();
113 $this->assign('surveyTitle', $this->_surveyDetails['title']);
114 $this->assign('activityType', $this->_surveyDetails['activity_type_id']);
115 $this->assign('surveyId', $this->_surveyId);
116
117 //append breadcrumb to survey dashboard.
118 if (CRM_Campaign_BAO_Campaign::accessCampaign()) {
119 $url = CRM_Utils_System::url('civicrm/campaign', 'reset=1&subPage=survey');
120 CRM_Utils_System::appendBreadCrumb(array(array('title' => ts('Survey(s)'), 'url' => $url)));
121 }
122
123 //set the title.
124 CRM_Utils_System::setTitle(ts('Reserve Respondents'));
125 }
126
127 public function validateSurvey() {
128 $errorMsg = NULL;
129 $maxVoters = CRM_Utils_Array::value('max_number_of_contacts', $this->_surveyDetails);
130 if ($maxVoters) {
131 if ($maxVoters <= $this->_numVoters) {
132 $errorMsg = ts('The maximum number of contacts is already reserved for this interviewer.');
133 }
134 elseif (count($this->_contactIds) > ($maxVoters - $this->_numVoters)) {
135 $errorMsg = ts('You can reserve a maximum of %count contact at a time for this survey.',
136 array(
137 'plural' => 'You can reserve a maximum of %count contacts at a time for this survey.',
138 'count' => $maxVoters - $this->_numVoters,
139 )
140 );
141 }
142 }
143
144 $defaultNum = CRM_Utils_Array::value('default_number_of_contacts', $this->_surveyDetails);
145 if (!$errorMsg && $defaultNum && (count($this->_contactIds) > $defaultNum)) {
146 $errorMsg = ts('You can reserve a maximum of %count contact at a time for this survey.',
147 array(
148 'plural' => 'You can reserve a maximum of %count contacts at a time for this survey.',
149 'count' => $defaultNum,
150 )
151 );
152 }
153
154 if ($errorMsg) {
155 CRM_Core_Error::statusBounce($errorMsg);
156 }
157 }
158
159 /**
160 * Build the form object.
161 *
162 *
163 * @return void
164 */
165 public function buildQuickForm() {
166 // allow to add contact to either new or existing group.
167 $this->addElement('text', 'ActivityType', ts('Activity Type'));
168 $this->addElement('text', 'newGroupName', ts('Name for new group'));
169 $this->addElement('text', 'newGroupDesc', ts('Description of new group'));
170 $groups = CRM_Core_PseudoConstant::nestedGroup();
171 $hasExistingGroups = FALSE;
172 if (is_array($groups) && !empty($groups)) {
173 $hasExistingGroups = TRUE;
174 $this->addElement('select', 'groups', ts('Add respondent(s) to existing group(s)'),
175 $groups, array('multiple' => "multiple", 'class' => 'crm-select2')
176 );
177 }
178 $this->assign('hasExistingGroups', $hasExistingGroups);
179
180 $buttons = array(
181 array(
182 'type' => 'done',
183 'name' => ts('Reserve'),
184 'subName' => 'reserve',
185 'isDefault' => TRUE,
186 ),
187 );
188
189 if (CRM_Core_Permission::check('manage campaign') ||
190 CRM_Core_Permission::check('administer CiviCampaign') ||
191 CRM_Core_Permission::check('interview campaign contacts')
192 ) {
193 $buttons[] = array(
194 'type' => 'next',
195 'name' => ts('Reserve and Interview'),
196 'subName' => 'reserveToInterview',
197 );
198 }
199 $buttons[] = array(
200 'type' => 'back',
201 'name' => ts('Cancel'),
202 );
203
204 $this->addButtons($buttons);
205 $this->addFormRule(array('CRM_Campaign_Form_Task_Reserve', 'formRule'), $this);
206 }
207
208 /**
209 * Global validation rules for the form.
210 *
211 * @param array $fields
212 * Posted values of the form.
213 *
214 * @param $files
215 * @param $self
216 *
217 * @return array
218 * list of errors to be posted back to the form
219 */
220 public static function formRule($fields, $files, $self) {
221 $errors = array();
222 $invalidGroupName = FALSE;
223 if (!empty($fields['newGroupName'])) {
224 $title = trim($fields['newGroupName']);
225 $name = CRM_Utils_String::titleToVar($title);
226 $query = 'select count(*) from civicrm_group where name like %1 OR title like %2';
227 $grpCnt = CRM_Core_DAO::singleValueQuery($query, array(
228 1 => array($name, 'String'),
229 2 => array($title, 'String'),
230 ));
231 if ($grpCnt) {
232 $invalidGroupName = TRUE;
233 $errors['newGroupName'] = ts('Group \'%1\' already exists.', array(1 => $fields['newGroupName']));
234 }
235 }
236 $self->assign('invalidGroupName', $invalidGroupName);
237
238 return empty($errors) ? TRUE : $errors;
239 }
240
241 /**
242 * Process the form after the input has been submitted and validated.
243 *
244 *
245 * @return void
246 */
247 public function postProcess() {
248 //add reservation.
249 $countVoters = 0;
250 $maxVoters = CRM_Utils_Array::value('max_number_of_contacts', $this->_surveyDetails);
251 $activityStatus = CRM_Core_PseudoConstant::activityStatus('name');
252 $statusHeld = array_search('Scheduled', $activityStatus);
253
254 $reservedVoterIds = array();
255 foreach ($this->_contactIds as $cid) {
256 $subject = $this->_surveyDetails['title'] . ' - ' . ts('Respondent Reservation');
257 $session = CRM_Core_Session::singleton();
258 $activityParams = array(
259 'source_contact_id' => $session->get('userID'),
260 'assignee_contact_id' => array($this->_interviewerId),
261 'target_contact_id' => array($cid),
262 'source_record_id' => $this->_surveyId,
263 'activity_type_id' => $this->_surveyDetails['activity_type_id'],
264 'subject' => $subject,
265 'activity_date_time' => date('YmdHis'),
266 'status_id' => $statusHeld,
267 'skipRecentView' => 1,
268 'campaign_id' => CRM_Utils_Array::value('campaign_id', $this->_surveyDetails),
269 );
270 $activity = CRM_Activity_BAO_Activity::create($activityParams);
271 if ($activity->id) {
272 $countVoters++;
273 $reservedVoterIds[$cid] = $cid;
274 }
275 if ($maxVoters && ($maxVoters <= ($this->_numVoters + $countVoters))) {
276 break;
277 }
278 }
279
280 //add reserved voters to groups.
281 $groupAdditions = $this->_addRespondentToGroup($reservedVoterIds);
282
283 // Success message
284 if ($countVoters > 0) {
285 $status = '<p>' . ts("%count contact has been reserved.", array('plural' => '%count contacts have been reserved.', 'count' => $countVoters)) . '</p>';
286 if ($groupAdditions) {
287 $status .= '<p>' . ts('They have been added to %1.',
288 array(1 => implode(' ' . ts('and') . ' ', $groupAdditions))
289 ) . '</p>';
290 }
291 CRM_Core_Session::setStatus($status, ts('Reservation Added'), 'success');
292 }
293 // Error message
294 if (count($this->_contactIds) > $countVoters) {
295 CRM_Core_Session::setStatus(ts('Reservation did not add for %count contact.',
296 array(
297 'plural' => 'Reservation did not add for %count contacts.',
298 'count' => (count($this->_contactIds) - $countVoters),
299 )
300 ), ts('Notice'));
301 }
302
303 //get ready to jump to voter interview form.
304 $buttonName = $this->controller->getButtonName();
305 if (!empty($reservedVoterIds) &&
306 $buttonName == '_qf_Reserve_next_reserveToInterview'
307 ) {
308 $this->controller->set('surveyId', $this->_surveyId);
309 $this->controller->set('contactIds', $reservedVoterIds);
310 $this->controller->set('interviewerId', $this->_interviewerId);
311 $this->controller->set('reserveToInterview', TRUE);
312 }
313 }
314
315 /**
316 * @param $contactIds
317 *
318 * @return array
319 */
320 private function _addRespondentToGroup($contactIds) {
321 $groupAdditions = array();
322 if (empty($contactIds)) {
323 return $groupAdditions;
324 }
325
326 $params = $this->controller->exportValues($this->_name);
327 $groups = CRM_Utils_Array::value('groups', $params, array());
328 $newGroupName = CRM_Utils_Array::value('newGroupName', $params);
329 $newGroupDesc = CRM_Utils_Array::value('newGroupDesc', $params);
330
331 $newGroupId = NULL;
332 //create new group.
333 if ($newGroupName) {
334 $grpParams = array(
335 'title' => $newGroupName,
336 'description' => $newGroupDesc,
337 'is_active' => TRUE,
338 );
339 $group = CRM_Contact_BAO_Group::create($grpParams);
340 $groups[] = $newGroupId = $group->id;
341 }
342
343 //add the respondents to groups.
344 if (is_array($groups)) {
345 $existingGroups = CRM_Core_PseudoConstant::group();
346 foreach ($groups as $groupId) {
347 $addCount = CRM_Contact_BAO_GroupContact::addContactsToGroup($contactIds, $groupId);
348 $totalCount = CRM_Utils_Array::value(1, $addCount);
349 if ($groupId == $newGroupId) {
350 $name = $newGroupName;
351 $new = TRUE;
352 }
353 else {
354 $name = $existingGroups[$groupId];
355 $new = FALSE;
356 }
357 if ($totalCount) {
358 $url = CRM_Utils_System::url('civicrm/group/search',
359 'reset=1&force=1&context=smog&gid=' . $groupId
360 );
361 $groupAdditions[] = '<a href="' . $url . '">' . $name . '</a>';
362 }
363 }
364 }
365
366 return $groupAdditions;
367 }
368
369 }