CRM-13966 - Refactor out and remove crmasmselect
[civicrm-core.git] / CRM / Case / Form / CaseView.php
1 <?php
2 /*
3 +--------------------------------------------------------------------+
4 | CiviCRM version 4.4 |
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2013 |
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-2013
32 * $Id$
33 *
34 */
35
36 /**
37 * This class generates view mode for CiviCase
38 *
39 */
40 class CRM_Case_Form_CaseView extends CRM_Core_Form {
41 /*
42 * check for merge cases.
43 */
44
45 private $_mergeCases = FALSE;
46
47 /**
48 * Function to set variables up before form is built
49 *
50 * @return void
51 * @access public
52 */
53 public function preProcess() {
54 // js for changing activity status
55 CRM_Core_Resources::singleton()->addScriptFile('civicrm', 'templates/CRM/Case/Form/ActivityChangeStatus.js');
56
57 $this->_showRelatedCases = CRM_Utils_Array::value('relatedCases', $_GET);
58
59 $xmlProcessorProcess = new CRM_Case_XMLProcessor_Process();
60 $isMultiClient = $xmlProcessorProcess->getAllowMultipleCaseClients();
61 $this->assign('multiClient', $isMultiClient);
62
63 //pull the related cases.
64 $this->assign('showRelatedCases', FALSE);
65 if ($this->_showRelatedCases) {
66 $relatedCases = $this->get('relatedCases');
67 if (!isset($relatedCases)) {
68 $cId = CRM_Utils_Request::retrieve('cid', 'Integer', CRM_Core_DAO::$_nullObject);
69 $caseId = CRM_Utils_Request::retrieve('id', 'Integer', CRM_Core_DAO::$_nullObject);
70 $relatedCases = CRM_Case_BAO_Case::getRelatedCases($caseId, $cId);
71 }
72 $this->assign('relatedCases', $relatedCases);
73 $this->assign('showRelatedCases', TRUE);
74 return;
75 }
76
77 //check for civicase access.
78 if (!CRM_Case_BAO_Case::accessCiviCase()) {
79 CRM_Core_Error::fatal(ts('You are not authorized to access this page.'));
80 }
81 $this->_hasAccessToAllCases = CRM_Core_Permission::check('access all cases and activities');
82 $this->assign('hasAccessToAllCases', $this->_hasAccessToAllCases);
83
84 $this->_contactID = $this->get('cid');
85 $this->_caseID = $this->get('id');
86
87 $fulltext = CRM_Utils_Request::retrieve('context', 'String', CRM_Core_DAO::$_nullObject);
88 if ($fulltext == 'fulltext') {
89 $this->assign('fulltext', $fulltext);
90 }
91
92 $this->assign('caseID', $this->_caseID);
93 $this->assign('contactID', $this->_contactID);
94
95 //validate case id.
96 $this->_userCases = array();
97 $session = CRM_Core_Session::singleton();
98 $userID = $session->get('userID');
99 if (!$this->_hasAccessToAllCases) {
100 $this->_userCases = CRM_Case_BAO_Case::getCases(FALSE, $userID, 'any');
101 if (!array_key_exists($this->_caseID, $this->_userCases)) {
102 CRM_Core_Error::fatal(ts('You are not authorized to access this page.'));
103 }
104 }
105 $this->assign('userID', $userID);
106
107 if (CRM_Case_BAO_Case::caseCount($this->_contactID) >= 2) {
108 $this->_mergeCases = TRUE;
109 }
110 $this->assign('mergeCases', $this->_mergeCases);
111
112 //retrieve details about case
113 $params = array('id' => $this->_caseID);
114
115 $returnProperties = array('case_type_id', 'subject', 'status_id', 'start_date');
116 CRM_Core_DAO::commonRetrieve('CRM_Case_BAO_Case', $params, $values, $returnProperties);
117
118 $values['case_type_id'] = trim(CRM_Utils_Array::value('case_type_id', $values),
119 CRM_Core_DAO::VALUE_SEPARATOR
120 );
121 $values['case_type_id'] = explode(CRM_Core_DAO::VALUE_SEPARATOR,
122 CRM_Utils_Array::value('case_type_id', $values)
123 );
124
125 $statuses = CRM_Case_PseudoConstant::caseStatus('label', FALSE);
126 $caseTypeName = CRM_Case_BAO_Case::getCaseType($this->_caseID, 'name');
127 $caseType = CRM_Case_BAO_Case::getCaseType($this->_caseID);
128
129 $this->_caseDetails = array(
130 'case_type' => $caseType,
131 'case_status' => $statuses[$values['case_status_id']],
132 'case_subject' => CRM_Utils_Array::value('subject', $values),
133 'case_start_date' => $values['case_start_date'],
134 );
135 $this->_caseType = $caseTypeName;
136 $this->assign('caseDetails', $this->_caseDetails);
137
138 $newActivityUrl = CRM_Utils_System::url('civicrm/case/activity',
139 "action=add&reset=1&cid={$this->_contactID}&caseid={$this->_caseID}&atype=",
140 FALSE, NULL, FALSE
141 );
142 $this->assign('newActivityUrl', $newActivityUrl);
143
144 // Send Email activity requires a different URL format from all other activities
145 $newActivityEmailUrl = CRM_Utils_System::url('civicrm/activity/email/add',
146 "action=add&context=standalone&reset=1&caseid={$this->_caseID}&atype=",
147 FALSE, NULL, FALSE
148 );
149 $this->assign('newActivityEmailUrl', $newActivityEmailUrl);
150
151 $reportUrl = CRM_Utils_System::url('civicrm/case/report',
152 "reset=1&cid={$this->_contactID}&caseid={$this->_caseID}&asn=",
153 FALSE, NULL, FALSE
154 );
155 $this->assign('reportUrl', $reportUrl);
156
157 // add to recently viewed
158
159 $url = CRM_Utils_System::url('civicrm/contact/view/case',
160 "action=view&reset=1&id={$this->_caseID}&cid={$this->_contactID}&context=home"
161 );
162
163 $displayName = CRM_Contact_BAO_Contact::displayName($this->_contactID);
164 $this->assign('displayName', $displayName);
165
166 CRM_Utils_System::setTitle($displayName . ' - ' . $caseType);
167
168 $recentOther = array();
169 if (CRM_Core_Permission::checkActionPermission('CiviCase', CRM_Core_Action::DELETE)) {
170 $recentOther['deleteUrl'] = CRM_Utils_System::url('civicrm/contact/view/case',
171 "action=delete&reset=1&id={$this->_caseID}&cid={$this->_contactID}&context=home"
172 );
173 }
174
175 // Add the recently viewed case
176 CRM_Utils_Recent::add($displayName . ' - ' . $caseType,
177 $url,
178 $this->_caseID,
179 'Case',
180 $this->_contactID,
181 NULL,
182 $recentOther
183 );
184
185
186 //get the related cases for given case.
187 $relatedCases = $this->get('relatedCases');
188 if (!isset($relatedCases)) {
189 $relatedCases = CRM_Case_BAO_Case::getRelatedCases($this->_caseID, $this->_contactID);
190 $relatedCases = empty($relatedCases) ? FALSE : $relatedCases;
191 $this->set('relatedCases', $relatedCases);
192 }
193 $this->assign('hasRelatedCases', $relatedCases);
194
195 $entitySubType = !empty($values['case_type_id']) ? $values['case_type_id'][0] : NULL;
196 $this->assign('caseTypeID', $entitySubType);
197 $groupTree = &CRM_Core_BAO_CustomGroup::getTree('Case',
198 $this,
199 $this->_caseID,
200 NULL,
201 $entitySubType
202 );
203 CRM_Core_BAO_CustomGroup::buildCustomDataView($this,
204 $groupTree
205 );
206 }
207
208 /**
209 * This function sets the default values for the form. For edit/view mode
210 * the default values are retrieved from the database
211 *
212 * @access public
213 *
214 * @return void
215 */
216 function setDefaultValues() {
217 $defaults = array();
218 return $defaults;
219 }
220
221 /**
222 * Function to build the form
223 *
224 * @return void
225 * @access public
226 */
227 public function buildQuickForm() {
228 //this call is for show related cases.
229 if ($this->_showRelatedCases) {
230 return;
231 }
232
233 $xmlProcessor = new CRM_Case_XMLProcessor_Process();
234 $caseRoles = $xmlProcessor->get($this->_caseType, 'CaseRoles');
235 $reports = $xmlProcessor->get($this->_caseType, 'ActivitySets');
236
237 //adding case manager.CRM-4510.
238 $managerRoleId = $xmlProcessor->getCaseManagerRoleId($this->_caseType);
239 if (!empty($managerRoleId)) {
240 $caseRoles[$managerRoleId] = $caseRoles[$managerRoleId] . '<br />' . '(' . ts('Case Manager') . ')';
241 }
242
243 $aTypes = $xmlProcessor->get($this->_caseType, 'ActivityTypes', TRUE);
244
245 $allActTypes = CRM_Core_PseudoConstant::activityType(TRUE, TRUE, FALSE, 'name');
246
247 // remove Open Case activity type since we're inside an existing case
248 if (($openActTypeId = array_search('Open Case', $allActTypes)) &&
249 array_key_exists($openActTypeId, $aTypes)
250 ) {
251 unset($aTypes[$openActTypeId]);
252 }
253
254 //check for link cases.
255 $unclosedCases = CRM_Case_BAO_Case::getUnclosedCases(NULL, array($this->_caseID));
256 if (empty($unclosedCases) &&
257 ($linkActTypeId = array_search('Link Cases', $allActTypes)) &&
258 array_key_exists($linkActTypeId, $aTypes)
259 ) {
260 unset($aTypes[$linkActTypeId]);
261 }
262
263 if (!$xmlProcessor->getNaturalActivityTypeSort()) {
264 asort($aTypes);
265 }
266
267 $this->add('select', 'activity_type_id', ts('New Activity'), array('' => ts('- select activity type -')) + $aTypes);
268 if ($this->_hasAccessToAllCases) {
269 $this->add('select', 'report_id', ts('Run QA Audit / Redact'),
270 array(
271 '' => ts('- select activity set -')) + $reports
272 );
273 $this->add('select', 'timeline_id', ts('Add Timeline'),
274 array(
275 '' => ts('- select activity set -')) + $reports
276 );
277 }
278 $this->addElement('submit', $this->getButtonName('next'), ts('Go'),
279 array(
280 'class' => 'form-submit-inline',
281 'onclick' => "return checkSelection( this );",
282 )
283 );
284
285 if ($this->_mergeCases) {
286 $allCases = CRM_Case_BAO_Case::getContactCases($this->_contactID);
287 $otherCases = array();
288 foreach ($allCases as $caseId => $details) {
289 //filter current and own cases.
290 if (($caseId == $this->_caseID) ||
291 (!$this->_hasAccessToAllCases &&
292 !array_key_exists($caseId, $this->_userCases)
293 )
294 ) {
295 continue;
296 }
297
298 $otherCases[$caseId] = 'Case ID: ' . $caseId . ' Type: ' . $details['case_type'] . ' Start: ' . $details['case_start_date'];
299 }
300 if (empty($otherCases)) {
301 $this->_mergeCases = FALSE;
302 $this->assign('mergeCases', $this->_mergeCases);
303 }
304 else {
305 $this->add('select', 'merge_case_id',
306 ts('Select Case for Merge'),
307 array(
308 '' => ts('- select case -')) + $otherCases
309 );
310 $this->addElement('submit',
311 $this->getButtonName('next', 'merge_case'),
312 ts('Merge'),
313 array(
314 'class' => 'form-submit-inline',
315 'onclick' => "return checkSelection( this );",
316 )
317 );
318 }
319 }
320
321 $this->add('text', 'change_client_id', ts('Assign to another Client'));
322 $this->add('hidden', 'contact_id', '', array('id' => 'contact_id'));
323 $this->addElement('submit',
324 $this->getButtonName('next', 'edit_client'),
325 ts('Reassign Case'),
326 array(
327 'class' => 'form-submit-inline',
328 'onclick' => "return checkSelection( this );",
329 )
330 );
331
332 $activityStatus = CRM_Core_PseudoConstant::activityStatus();
333 $this->add('select', 'status_id', ts('Status'), array("" => ts(' - any status - ')) + $activityStatus);
334
335 // activity dates
336 $this->addDate('activity_date_low', ts('Activity Dates - From'), FALSE, array('formatType' => 'searchDate'));
337 $this->addDate('activity_date_high', ts('To'), FALSE, array('formatType' => 'searchDate'));
338
339 if (CRM_Core_Permission::check('administer CiviCRM')) {
340 $this->add('checkbox', 'activity_deleted', ts('Deleted Activities'));
341 }
342
343 //get case related relationships (Case Role)
344 $caseRelationships = CRM_Case_BAO_Case::getCaseRoles($this->_contactID, $this->_caseID);
345
346 //save special label because we unset it in the loop
347 $managerLabel = empty($managerRoleId) ? '' : $caseRoles[$managerRoleId];
348
349 //build reporter select
350 $reporters = array("" => ts(' - any reporter - '));
351 foreach ($caseRelationships as $key => & $value) {
352 $reporters[$value['cid']] = $value['name'] . " ( {$value['relation']} )";
353
354 if (!empty($managerRoleId)) {
355 if ($managerRoleId == $value['relation_type']) {
356 $value['relation'] = $managerLabel;
357 }
358 }
359
360 //calculate roles that don't have relationships
361 if (!empty($caseRoles[$value['relation_type']])) {
362 unset($caseRoles[$value['relation_type']]);
363 }
364 }
365
366 // take all case activity types for search filter, CRM-7187
367 $aTypesFilter = array();
368 $allCaseActTypes = CRM_Case_PseudoConstant::caseActivityType();
369 foreach ($allCaseActTypes as $typeDetails) {
370 if (!in_array($typeDetails['name'], array(
371 'Open Case'))) {
372 $aTypesFilter[$typeDetails['id']] = CRM_Utils_Array::value('label', $typeDetails);
373 }
374 }
375 asort($aTypesFilter);
376 $this->add('select', 'activity_type_filter_id', ts('Activity Type'), array('' => ts('- select activity type -')) + $aTypesFilter);
377
378 $this->assign('caseRelationships', $caseRelationships);
379
380 //also add client as role. CRM-4438
381 $caseRoles['client'] = CRM_Case_BAO_Case::getContactNames($this->_caseID);
382
383 $this->assign('caseRoles', $caseRoles);
384
385 $this->add('select', 'reporter_id', ts('Reporter/Role'), $reporters);
386
387 // Retrieve ALL client relationships
388 $relClient = CRM_Contact_BAO_Relationship::getRelationship($this->_contactID,
389 CRM_Contact_BAO_Relationship::CURRENT,
390 0, 0, 0, NULL, NULL, FALSE
391 );
392
393 // Now build 'Other Relationships' array by removing relationships that are already listed under Case Roles
394 // so they don't show up twice.
395 $clientRelationships = array();
396 foreach ($relClient as $r) {
397 if (!array_key_exists($r['id'], $caseRelationships)) {
398 $clientRelationships[] = $r;
399 }
400 }
401 $this->assign('clientRelationships', $clientRelationships);
402
403 // Now global contact list that appears on all cases.
404 $globalGroupInfo = array();
405 $relGlobal = CRM_Case_BAO_Case::getGlobalContacts($globalGroupInfo);
406 $this->assign('globalRelationships', $relGlobal);
407 $this->assign('globalGroupInfo', $globalGroupInfo);
408
409 // List of relationship types
410 $baoRel = new CRM_Contact_BAO_Relationship();
411 $relType = $baoRel->getRelationType('Individual');
412 $roleTypes = array();
413 foreach ($relType as $k => $v) {
414 $roleTypes[substr($k, 0, strpos($k, '_'))] = $v;
415 }
416 $this->add('select', 'role_type', ts('Relationship Type'), array('' => ts('- select type -')) + $roleTypes);
417
418 $hookCaseSummary = CRM_Utils_Hook::caseSummary($this->_caseID);
419 if (is_array($hookCaseSummary)) {
420 $this->assign('hookCaseSummary', $hookCaseSummary);
421 }
422
423
424 $allTags = CRM_Core_BAO_Tag::getTags('civicrm_case');
425
426 if (!empty($allTags)) {
427 $this->add('select', 'case_tag', ts('Tags'), $allTags, FALSE,
428 array('id' => 'tags', 'multiple' => 'multiple', 'class' => 'crm-select2')
429 );
430
431 $tags = CRM_Core_BAO_EntityTag::getTag($this->_caseID, 'civicrm_case');
432
433 $this->setDefaults(array('case_tag' => $tags));
434
435 foreach ($tags as $tid) {
436 if (isset($allTags[$tid])) {
437 $tags[$tid] = $allTags[$tid];
438 }
439 else {
440 unset($tags[$tid]);
441 }
442 }
443
444 $this->assign('tags', implode(', ', array_filter($tags)));
445 $this->assign('showTags', TRUE);
446 }
447 else {
448 $this->assign('showTags', FALSE);
449 }
450
451 // build tagset widget
452
453 // see if we have any tagsets which can be assigned to cases
454 $parentNames = CRM_Core_BAO_Tag::getTagSet('civicrm_case');
455 if ($parentNames) {
456 $this->assign('showTagsets', TRUE);
457 }
458 else {
459 $this->assign('showTagsets', FALSE);
460 }
461 CRM_Core_Form_Tag::buildQuickForm($this, $parentNames, 'civicrm_case', $this->_caseID, TRUE, TRUE);
462
463 $this->addButtons(array(
464 array(
465 'type' => 'cancel',
466 'name' => ts('Done'),
467 'spacing' => '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;',
468 'isDefault' => TRUE,
469 ),
470 )
471 );
472 }
473
474 /**
475 * Process the form
476 *
477 * @return void
478 * @access public
479 */
480 public function postProcess() {
481 $params = $this->controller->exportValues($this->_name);
482 $buttonName = $this->controller->getButtonName();
483
484 // user context
485 $url = CRM_Utils_System::url('civicrm/contact/view/case',
486 "reset=1&action=view&cid={$this->_contactID}&id={$this->_caseID}&show=1"
487 );
488 $session = CRM_Core_Session::singleton();
489 $session->pushUserContext($url);
490
491 if (!empty($params['timeline_id']) && !empty($_POST['_qf_CaseView_next'])) {
492 $session = CRM_Core_Session::singleton();
493 $this->_uid = $session->get('userID');
494 $xmlProcessor = new CRM_Case_XMLProcessor_Process();
495 $xmlProcessorParams = array(
496 'clientID' => $this->_contactID,
497 'creatorID' => $this->_uid,
498 'standardTimeline' => 0,
499 'activity_date_time' => date('YmdHis'),
500 'caseID' => $this->_caseID,
501 'caseType' => $this->_caseType,
502 'activitySetName' => $params['timeline_id'],
503 );
504 $xmlProcessor->run($this->_caseType, $xmlProcessorParams);
505 $reports = $xmlProcessor->get($this->_caseType, 'ActivitySets');
506
507 CRM_Core_Session::setStatus(ts('Activities from the %1 activity set have been added to this case.',
508 array(1 => $reports[$params['timeline_id']])
509 ), ts('Done'), 'success');
510 }
511 elseif ($this->_mergeCases &&
512 $buttonName == '_qf_CaseView_next_merge_case'
513 ) {
514
515 $mainCaseId = $params['merge_case_id'];
516 $otherCaseId = $this->_caseID;
517
518 //merge two cases.
519 CRM_Case_BAO_Case::mergeCases($this->_contactID, $mainCaseId, NULL, $otherCaseId);
520
521 //redirect user to main case view.
522 $url = CRM_Utils_System::url('civicrm/contact/view/case',
523 "reset=1&action=view&cid={$this->_contactID}&id={$mainCaseId}&show=1"
524 );
525 $session = CRM_Core_Session::singleton();
526 $session->pushUserContext($url);
527 }
528 elseif ($buttonName == '_qf_CaseView_next_edit_client') {
529 $mainCaseId = CRM_Case_BAO_Case::mergeCases($params['contact_id'], $this->_caseID, $this->_contactID, NULL, TRUE);
530
531 // user context
532 $url = CRM_Utils_System::url('civicrm/contact/view/case',
533 "reset=1&action=view&cid={$params['contact_id']}&id={$mainCaseId[0]}&show=1"
534 );
535 $session = CRM_Core_Session::singleton();
536 $session->pushUserContext($url);
537 }
538 }
539 }
540