Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

dev/report#53: search on relationship and case (2) #20002

Merged
merged 5 commits into from
Apr 19, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions CRM/Contact/BAO/Query.php
Original file line number Diff line number Diff line change
Expand Up @@ -5792,7 +5792,7 @@ public function filterRelatedContacts(&$from, &$where, &$having) {
INNER JOIN $tableName transform_temp ON ( transform_temp.contact_id = displayRelType.contact_id_a OR transform_temp.contact_id = displayRelType.contact_id_b )
";
$qcache['where'] = "
WHERE displayRelType.relationship_type_id = {$this->_displayRelationshipType}
AND displayRelType.relationship_type_id = {$this->_displayRelationshipType}
AND displayRelType.is_active = 1
";
}
Expand All @@ -5813,7 +5813,7 @@ public function filterRelatedContacts(&$from, &$where, &$having) {
";
}
$qcache['where'] = "
WHERE displayRelType.relationship_type_id = $relType
AND displayRelType.relationship_type_id = $relType
AND displayRelType.is_active = 1
";
}
Expand All @@ -5837,10 +5837,14 @@ public function filterRelatedContacts(&$from, &$where, &$having) {
else {
$from .= $qcache['from'];
}
$where = $qcache['where'];
if (!strlen($where)) {
$where = " WHERE 1 ";
}
$where .= $qcache['where'];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I kind of remember this code area from the earlier PR but I don't remember if there was ever a time when $where was passed in to the function and is blank or didn't have "WHERE" in it already. I wonder if it's worth adding a guard against that, e.g. if $where does not contain "WHERE", then $where = "WHERE (1) " . $qcache['where']. Or something like that - just an example.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have added a check whether $where is empty.

if (!empty($this->_tables['civicrm_case'])) {
// Change the join on CiviCRM case so that it joins on the right contac from the relationship.
$from = str_replace("ON civicrm_case_contact.contact_id = contact_a.id", "ON civicrm_case_contact.contact_id = transform_temp.contact_id", $from);
$where = str_replace("AND civicrm_case_contact.contact_id = contact_a.id", "AND civicrm_case_contact.contact_id = transform_temp.contact_id", $where);
$where .= " AND displayRelType.case_id = civicrm_case_contact.case_id ";
}
if (!empty($this->_permissionFromClause) && !stripos($from, 'aclContactCache')) {
Expand Down
11 changes: 10 additions & 1 deletion tests/fixtures/case_types.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,15 @@
"is_active": 1,
"is_reserved": 0,
"weight": 1
}
},
{
"id": 2,
"name": "adult_day_care_referral",
"title": "Adult Day Care Referral",
"description": "Arranging adult day care for senior individuals",
"is_active": 1,
"is_reserved": 0,
"weight": 1
}
]
}
58 changes: 58 additions & 0 deletions tests/phpunit/CRM/Case/BAO/QueryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -116,4 +116,62 @@ public function testFindCasesQuery() {
);
}

/**
* Tests the advanced search query by searching on related contacts and case type at the same time.
*
* Preparation:
* Create a contact Contact A
* Create another contact Contact B
* Create a third contact Contact C
* Create a case of type Housing Support for Contact A
* On the case assign the role Benefit specialist is to Contact B
* Create a second case of type Adult day care referral
* On the case assign the role Benefit specialist is to Contact C
*
* Searching:
* Go to advanced search
* Click on View contact as related contact
* Select Benefit Specialist as relationship type
* Go to tab cases and select Housing Support as case type
*
* Expected results
* We expect to find contact B and not C.
*
* @throws \Exception
*/
public function testAdvancedSearchWithDisplayRelationshipsAndCaseType() {
// Preperation
$benefitRelationshipTypeId = civicrm_api3('RelationshipType', 'getvalue', ['return' => 'id', 'name_a_b' => 'Benefits Specialist is']);
$clientContactID = $this->individualCreate(['first_name' => 'John', 'last_name' => 'Smith']);
$benefitSpecialist1 = $this->individualCreate(['Individual', 'first_name' => 'Alexa', 'last_name' => 'Clarke']);
$benefitSpecialist2 = $this->individualCreate(['Individual', 'first_name' => 'Sandra', 'last_name' => 'Johnson']);
$housingSupportCase = $this->createCase($clientContactID, NULL, ['case_type' => 'housing_support', 'case_type_id' => 1]);
$adultDayCareReferralCase = $this->createCase($clientContactID, NULL, ['case_type' => 'adult_day_care_referral', 'case_type_id' => 2]);
civicrm_api3('Relationship', 'create', ['contact_id_a' => $clientContactID, 'contact_id_b' => $benefitSpecialist1, 'relationship_type_id' => $benefitRelationshipTypeId, 'case_id' => $housingSupportCase->id]);
civicrm_api3('Relationship', 'create', ['contact_id_a' => $clientContactID, 'contact_id_b' => $benefitSpecialist2, 'relationship_type_id' => $benefitRelationshipTypeId, 'case_id' => $adultDayCareReferralCase->id]);

// Search setup
$formValues = ['display_relationship_type' => $benefitRelationshipTypeId . '_b_a', 'case_type_id' => 1];
$params = CRM_Contact_BAO_Query::convertFormValues($formValues, 0, FALSE, NULL, []);
$isDeleted = in_array(['deleted_contacts', '=', 1, 0, 0], $params);
$selector = new CRM_Contact_Selector(
'CRM_Contact_Selector',
$formValues,
$params,
NULL,
CRM_Core_Action::NONE,
NULL,
FALSE,
'advanced'
);
$queryObject = $selector->getQueryObject();
$sql = $queryObject->query(FALSE, FALSE, FALSE, $isDeleted);
// Run the search
$rows = CRM_Core_DAO::executeQuery(implode(' ', $sql))->fetchAll();
// Check expected results.
$this->assertCount(1, $rows);
$this->assertEquals('Alexa', $rows[0]['first_name']);
$this->assertEquals('Clarke', $rows[0]['last_name']);
}

}
2 changes: 1 addition & 1 deletion tests/phpunit/CRM/Contact/SelectorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -441,7 +441,7 @@ public function querySets() {
'searchDescendentGroups' => FALSE,
'expected_query' => [
0 => 'SELECT contact_a.id as contact_id, contact_a.contact_type as `contact_type`, contact_a.contact_sub_type as `contact_sub_type`, contact_a.sort_name as `sort_name`, contact_a.display_name as `display_name`, contact_a.do_not_email as `do_not_email`, contact_a.do_not_phone as `do_not_phone`, contact_a.do_not_mail as `do_not_mail`, contact_a.do_not_sms as `do_not_sms`, contact_a.do_not_trade as `do_not_trade`, contact_a.is_opt_out as `is_opt_out`, contact_a.legal_identifier as `legal_identifier`, contact_a.external_identifier as `external_identifier`, contact_a.nick_name as `nick_name`, contact_a.legal_name as `legal_name`, contact_a.image_URL as `image_URL`, contact_a.preferred_communication_method as `preferred_communication_method`, contact_a.preferred_language as `preferred_language`, contact_a.preferred_mail_format as `preferred_mail_format`, contact_a.first_name as `first_name`, contact_a.middle_name as `middle_name`, contact_a.last_name as `last_name`, contact_a.prefix_id as `prefix_id`, contact_a.suffix_id as `suffix_id`, contact_a.formal_title as `formal_title`, contact_a.communication_style_id as `communication_style_id`, contact_a.job_title as `job_title`, contact_a.gender_id as `gender_id`, contact_a.birth_date as `birth_date`, contact_a.is_deceased as `is_deceased`, contact_a.deceased_date as `deceased_date`, contact_a.household_name as `household_name`, IF ( contact_a.contact_type = \'Individual\', NULL, contact_a.organization_name ) as organization_name, contact_a.sic_code as `sic_code`, contact_a.is_deleted as `contact_is_deleted`, IF ( contact_a.contact_type = \'Individual\', contact_a.organization_name, NULL ) as current_employer, civicrm_address.id as address_id, civicrm_address.street_address as `street_address`, civicrm_address.supplemental_address_1 as `supplemental_address_1`, civicrm_address.supplemental_address_2 as `supplemental_address_2`, civicrm_address.supplemental_address_3 as `supplemental_address_3`, civicrm_address.city as `city`, civicrm_address.postal_code_suffix as `postal_code_suffix`, civicrm_address.postal_code as `postal_code`, civicrm_address.geo_code_1 as `geo_code_1`, civicrm_address.geo_code_2 as `geo_code_2`, civicrm_address.state_province_id as state_province_id, civicrm_address.country_id as country_id, civicrm_phone.id as phone_id, civicrm_phone.phone_type_id as phone_type_id, civicrm_phone.phone as `phone`, civicrm_email.id as email_id, civicrm_email.email as `email`, civicrm_email.on_hold as `on_hold`, civicrm_im.id as im_id, civicrm_im.provider_id as provider_id, civicrm_im.name as `im`, civicrm_worldregion.id as worldregion_id, civicrm_worldregion.name as `world_region`',
2 => 'WHERE displayRelType.relationship_type_id = 1
2 => 'WHERE 1 AND displayRelType.relationship_type_id = 1
AND displayRelType.is_active = 1
AND ( 1 ) AND (contact_a.is_deleted = 0)',
],
Expand Down