$this->buildMergeCaseForm();
//call activity form
- self::activityForm($this, $aTypes);
+ // @todo seems a little odd to call "self" but pass $this in a form function? The only other place this is called from is one place in civihr.
+ self::activityForm($this);
//get case related relationships (Case Role)
$caseRelationships = CRM_Case_BAO_Case::getCaseRoles($this->_contactID, $this->_caseID, NULL, FALSE);
/**
* Build the activity selector/datatable
* @param CRM_Core_Form $form
- * @param array $aTypes
- * To include acivities related to current case id $form->_caseID.
*/
- public static function activityForm($form, $aTypes = []) {
+ public static function activityForm($form) {
$caseRelationships = CRM_Case_BAO_Case::getCaseRoles($form->_contactID, $form->_caseID);
//build reporter select
$reporters = ["" => ts(' - any reporter - ')];
}
$form->add('select', 'reporter_id', ts('Reporter/Role'), $reporters, FALSE, ['id' => 'reporter_id_' . $form->_caseID]);
- // take all case activity types for search filter, CRM-7187
+ // List all the activity types that have been used on this case
$aTypesFilter = [];
- $allCaseActTypes = CRM_Case_PseudoConstant::caseActivityType();
- foreach ($allCaseActTypes as $typeDetails) {
- if (!in_array($typeDetails['name'], ['Open Case'])) {
- $aTypesFilter[$typeDetails['id']] = $typeDetails['label'] ?? NULL;
- }
+ $activity_types_on_case = \Civi\Api4\CaseActivity::get()
+ ->addWhere('case_id', '=', $form->_caseID)
+ // we want to include deleted too since the filter can search for deleted
+ ->addWhere('activity_id.is_deleted', 'IN', [0, 1])
+ // technically correct, but this might end up excluding some deleted ones depending on how they got deleted
+ // ->addWhere('activity_id.is_current_revision', '=', 1)
+ ->addSelect('activity_id.activity_type_id', 'activity_id.activity_type_id:label')
+ ->addGroupBy('activity_id.activity_type_id')
+ // this creates strange SQL - if it is too slow could sort in php instead
+ ->addOrderBy('activity_id.activity_type_id:label', 'ASC')
+ ->execute();
+ foreach ($activity_types_on_case as $typeDetails) {
+ $aTypesFilter[$typeDetails['activity_id.activity_type_id']] = $typeDetails['activity_id.activity_type_id:label'];
}
- $aTypesFilter = $aTypesFilter + $aTypes;
- asort($aTypesFilter);
$form->add('select', 'activity_type_filter_id', ts('Activity Type'), ['' => ts('- select activity type -')] + $aTypesFilter, FALSE, ['id' => 'activity_type_filter_id_' . $form->_caseID]);
$activityStatus = CRM_Core_PseudoConstant::activityStatus();
--- /dev/null
+<?php
+/**
+ * Class CRM_Case_Form_CaseViewTest
+ * @group headless
+ */
+class CRM_Case_Form_CaseViewTest extends CiviCaseTestCase {
+
+ /**
+ * Test that the search filter dropdown includes the desired activity types.
+ */
+ public function testSearchFilterDropdown() {
+ $client_id = $this->individualCreate([], 0, TRUE);
+ $caseObj = $this->createCase($client_id, $this->_loggedInUser);
+
+ $form = $this->getFormObject('CRM_Case_Form_CaseView');
+ $form->set('cid', $client_id);
+ $form->set('id', $caseObj->id);
+ $form->buildForm();
+ $options = $form->getElement('activity_type_filter_id')->_options;
+ // We don't care about the first one, just check it's what we expect
+ $this->assertEquals('- select activity type -', $options[0]['text']);
+ unset($options[0]);
+ $mappedOptions = array_map(function($v) {
+ return [$v['attr']['value'] => $v['text']];
+ }, $options);
+ $this->assertEquals([
+ [14 => 'Follow up'],
+ [60 => 'Income and benefits stabilization'],
+ [58 => 'Long-term housing plan'],
+ [55 => 'Medical evaluation'],
+ [56 => 'Mental health evaluation'],
+ [13 => 'Open Case'],
+ [57 => 'Secure temporary housing'],
+ ], array_values($mappedOptions));
+
+ // Now add some activities where the type might not even be in the config.
+ $this->callAPISuccess('Activity', 'create', [
+ 'case_id' => $caseObj->id,
+ 'subject' => 'aaaa',
+ 'activity_type_id' => 'Inbound Email',
+ ]);
+ $this->callAPISuccess('Activity', 'create', [
+ 'case_id' => $caseObj->id,
+ 'subject' => 'bbbb',
+ 'activity_type_id' => 'Email',
+ ]);
+ $this->callAPISuccess('Activity', 'create', [
+ 'case_id' => $caseObj->id,
+ 'subject' => 'cccc',
+ 'activity_type_id' => 'Meeting',
+ ]);
+
+ // And let's delete one since we still want it to be available as a filter
+ $this->callAPISuccess('Activity', 'create', [
+ 'case_id' => $caseObj->id,
+ 'subject' => 'dddd',
+ 'activity_type_id' => 'Phone Call',
+ 'is_deleted' => 1,
+ ]);
+
+ $form = $this->getFormObject('CRM_Case_Form_CaseView');
+ $form->set('cid', $client_id);
+ $form->set('id', $caseObj->id);
+ $form->buildForm();
+ $options = $form->getElement('activity_type_filter_id')->_options;
+ unset($options[0]);
+ $mappedOptions = array_map(function($v) {
+ return [$v['attr']['value'] => $v['text']];
+ }, $options);
+ $this->assertEquals([
+ [3 => 'Email'],
+ [14 => 'Follow up'],
+ [12 => 'Inbound Email'],
+ [60 => 'Income and benefits stabilization'],
+ [58 => 'Long-term housing plan'],
+ [55 => 'Medical evaluation'],
+ [1 => 'Meeting'],
+ [56 => 'Mental health evaluation'],
+ [13 => 'Open Case'],
+ [2 => 'Phone Call'],
+ [57 => 'Secure temporary housing'],
+ ], array_values($mappedOptions));
+ }
+
+}