diff --git a/CRM/Core/Permission.php b/CRM/Core/Permission.php index 826d70a2847d..e7190cc6ae89 100644 --- a/CRM/Core/Permission.php +++ b/CRM/Core/Permission.php @@ -1016,6 +1016,12 @@ public static function getEntityActionPermissions() { 'access CiviCRM', 'delete in CiviCase', ), + 'restore' => array( + 'administer CiviCase', + ), + 'merge' => array( + 'administer CiviCase', + ), 'default' => array( // At minimum the user needs one of the following. Finer-grained access is controlled by CRM_Case_BAO_Case::addSelectWhereClause array('access my cases and activities', 'access all cases and activities'), diff --git a/api/v3/Case.php b/api/v3/Case.php index ddf3aead95c2..df6332a3eb25 100644 --- a/api/v3/Case.php +++ b/api/v3/Case.php @@ -398,6 +398,42 @@ function _civicrm_api3_case_addtimeline_spec(&$params) { ); } +/** + * Merge 2 cases. + * + * @param array $params + * + * @throws API_Exception + * @return array + */ +function civicrm_api3_case_merge($params) { + $clients1 = CRM_Case_BAO_Case::getCaseClients($params['case_id_1']); + $clients2 = CRM_Case_BAO_Case::getCaseClients($params['case_id_2']); + CRM_Case_BAO_Case::mergeCases($clients1[0], $params['case_id_1'], $clients2[0], $params['case_id_2']); + return civicrm_api3_create_success(); +} + +/** + * Adjust Metadata for merge action. + * + * @param array $params + * Array of parameters determined by getfields. + */ +function _civicrm_api3_case_merge_spec(&$params) { + $params['case_id_1'] = array( + 'title' => 'Case ID 1', + 'description' => 'Id of main case', + 'type' => CRM_Utils_Type::T_INT, + 'api.required' => 1, + ); + $params['case_id_2'] = array( + 'title' => 'Case ID 2', + 'description' => 'Id of second case', + 'type' => CRM_Utils_Type::T_INT, + 'api.required' => 1, + ); +} + /** * Declare deprecated api functions. * @@ -492,8 +528,7 @@ function civicrm_api3_case_update($params) { * @endcode * * @throws API_Exception - * @return bool - * true if success, else false + * @return mixed */ function civicrm_api3_case_delete($params) { //check parameters @@ -507,6 +542,33 @@ function civicrm_api3_case_delete($params) { } } +/** + * Case.restore API specification + * + * @param array $spec description of fields supported by this API call + * @return void + */ +function _civicrm_api3_case_restore_spec(&$spec) { + $result = civicrm_api3('Case', 'getfields', array('api_action' => 'delete')); + $spec = array('id' => $result['values']['id']); +} + +/** + * Restore a specified case from the trash. + * + * @param array $params + * @throws API_Exception + * @return mixed + */ +function civicrm_api3_case_restore($params) { + if (CRM_Case_BAO_Case::restoreCase($params['id'])) { + return civicrm_api3_create_success($params, $params, 'Case', 'restore'); + } + else { + throw new API_Exception('Could not restore case.'); + } +} + /** * Augment case results with extra data. * diff --git a/tests/phpunit/api/v3/CaseTest.php b/tests/phpunit/api/v3/CaseTest.php index be0d687cc1f5..c4ce84537b89 100644 --- a/tests/phpunit/api/v3/CaseTest.php +++ b/tests/phpunit/api/v3/CaseTest.php @@ -177,14 +177,21 @@ public function testCaseDelete() { // Move Case to Trash $id = $result['id']; - $result = $this->callAPISuccess('case', 'delete', array('id' => $id, 'move_to_trash' => 1)); + $this->callAPISuccess('case', 'delete', array('id' => $id, 'move_to_trash' => 1)); // Check result - also check that 'case_id' works as well as 'id' $result = $this->callAPISuccess('case', 'get', array('case_id' => $id)); $this->assertEquals(1, $result['values'][$id]['is_deleted']); - // Delete Case Permanently - also check that 'case_id' works as well as 'id' - $result = $this->callAPISuccess('case', 'delete', array('case_id' => $id)); + // Restore Case from Trash + $this->callAPISuccess('case', 'restore', array('id' => $id)); + + // Check result + $result = $this->callAPISuccess('case', 'get', array('case_id' => $id)); + $this->assertEquals(0, $result['values'][$id]['is_deleted']); + + // Delete Case Permanently + $this->callAPISuccess('case', 'delete', array('case_id' => $id)); // Check result - case should no longer exist $result = $this->callAPISuccess('case', 'get', array('id' => $id)); @@ -697,4 +704,33 @@ public function testCaseAddtimeline() { $this->assertEquals('Follow up', $result['values'][1]['activity_type_id.name']); } + + /** + * Test the case merge function. + * + * 2 cases should be mergeable into 1 + * + * @throws \Exception + */ + public function testCaseMerge() { + $contact1 = $this->individualCreate(array(), 1); + $case1 = $this->callAPISuccess('Case', 'create', array( + 'contact_id' => $contact1, + 'subject' => "Test case 1", + 'case_type_id' => $this->caseTypeId, + )); + $case2 = $this->callAPISuccess('Case', 'create', array( + 'contact_id' => $contact1, + 'subject' => "Test case 2", + 'case_type_id' => $this->caseTypeId, + )); + $result = $this->callAPISuccess('Case', 'getcount', array('contact_id' => $contact1)); + $this->assertEquals(2, $result); + + $this->callAPISuccess('Case', 'merge', array('case_id_1' => $case1['id'], 'case_id_2' => $case2['id'])); + + $result = $this->callAPISuccess('Case', 'getsingle', array('id' => $case2['id'])); + $this->assertEquals(1, $result['is_deleted']); + } + }