diff --git a/CRM/Case/BAO/Case.php b/CRM/Case/BAO/Case.php index 0d12748dfe33..3a81395d2256 100644 --- a/CRM/Case/BAO/Case.php +++ b/CRM/Case/BAO/Case.php @@ -1141,6 +1141,7 @@ public static function getRelatedContacts($caseID, $includeDetails = TRUE) { } $values = []; + $caseClientCondition = !empty($caseInfo['client_id']) ? "AND cc.id NOT IN (%2)" : ''; $query = << [$caseID, 'Integer'], - 2 => [implode(',', $caseInfo['client_id']), 'String'], ]; + + if ($caseClientCondition) { + $params[2] = [implode(',', $caseInfo['client_id']), 'CommaSeparatedIntegers']; + } $dao = CRM_Core_DAO::executeQuery($query, $params); while ($dao->fetch()) { diff --git a/tests/phpunit/api/v3/CaseTest.php b/tests/phpunit/api/v3/CaseTest.php index 3e3e6fe379e9..470117269217 100644 --- a/tests/phpunit/api/v3/CaseTest.php +++ b/tests/phpunit/api/v3/CaseTest.php @@ -839,6 +839,53 @@ public function testCaseGetOrderByClient() { $this->assertCount(3, $result['values']); } + /** + * Test Case.Get does not return case clients as part of related contacts. + * + * For multi-client cases, case clients should not be returned in duplicates for contacts. + */ + public function testCaseGetDoesNotReturnClientsAsPartOfRelatedContacts() { + $contact1 = $this->individualCreate(['first_name' => 'Aa', 'last_name' => 'Zz']); + $contact2 = $this->individualCreate(['first_name' => 'Bb', 'last_name' => 'Zz']); + $relContact = $this->individualCreate(['first_name' => 'Rel', 'last_name' => 'Contact']); + + $case = $this->callAPISuccess('Case', 'create', [ + 'contact_id' => [$contact1, $contact2], + 'subject' => "Test case 1", + 'case_type_id' => $this->caseTypeId, + ]); + + $relType = $this->relationshipTypeCreate(['name_a_b' => 'Test AB', 'name_b_a' => 'Test BA', 'contact_type_b' => 'Individual']); + $relContact = $this->individualCreate(['first_name' => 'First', 'last_name' => 'Last']); + $_REQUEST = [ + 'rel_type' => "{$relType}_b_a", + 'rel_contact' => $relContact, + 'case_id' => $case['id'], + 'is_unit_test' => TRUE, + ]; + CRM_Contact_Page_AJAX::relationship(); + + $result = $this->callAPISuccess('Case', 'get', [ + 'id' => $case['id'], + 'sequential' => 1, + 'return' => ['id', 'contacts'], + ]); + + $caseContacts = $result['values'][0]['contacts']; + $contactIds = array_column($caseContacts, 'contact_id'); + // We basically need to ensure that the case clients are not returned more than once. + // i.e there should be no duplicates for case clients. + $caseContactInstances = (array_count_values($contactIds)); + $this->assertEquals(1, $caseContactInstances[$contact1]); + $this->assertEquals(1, $caseContactInstances[$contact2]); + + // Verify that the case clients are not part of related contacts. + $relatedContacts = CRM_Case_BAO_Case::getRelatedContacts($case['id']); + $relatedContacts = array_column($relatedContacts, 'contact_id'); + $this->assertNotContains($contact1, $relatedContacts); + $this->assertNotContains($contact2, $relatedContacts); + } + /** * Test the ability to add a timeline to an existing case. *