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/core#500 Fix user-specific Case filtering on dashboard and searches to exclude cases from inactive relationships #13134

Merged
merged 6 commits into from
Jan 11, 2019
14 changes: 6 additions & 8 deletions CRM/Case/BAO/Case.php
Original file line number Diff line number Diff line change
Expand Up @@ -528,9 +528,7 @@ public static function getCaseActivityQuery($type = 'upcoming', $userID, $condit
ON t_act.case_id = civicrm_case.id
LEFT JOIN civicrm_phone ON (civicrm_phone.contact_id = civicrm_contact.id AND civicrm_phone.is_primary=1)
LEFT JOIN civicrm_relationship case_relationship
ON ( case_relationship.contact_id_a = civicrm_case_contact.contact_id AND case_relationship.contact_id_b = {$userID}
AND case_relationship.case_id = civicrm_case.id )

ON ( case_relationship.contact_id_a = civicrm_case_contact.contact_id AND case_relationship.contact_id_b = {$userID} AND case_relationship.is_active AND case_relationship.case_id = civicrm_case.id )
LEFT JOIN civicrm_relationship_type case_relation_type
ON ( case_relation_type.id = case_relationship.relationship_type_id
AND case_relation_type.id = case_relationship.relationship_type_id )
Expand Down Expand Up @@ -619,7 +617,7 @@ public static function getCases($allCases = TRUE, $params = array(), $context =
$whereClauses = array('civicrm_case.is_deleted = 0 AND civicrm_contact.is_deleted <> 1');

if (!$allCases) {
$whereClauses[] .= " case_relationship.contact_id_b = {$userID} ";
$whereClauses[] .= " case_relationship.contact_id_b = {$userID} AND case_relationship.is_active ";
}
if (empty($params['status_id']) && ($type == 'upcoming' || $type == 'any')) {
$whereClauses[] = " civicrm_case.status_id != " . CRM_Core_PseudoConstant::getKey('CRM_Case_BAO_Case', 'case_status_id', 'Closed');
Expand Down Expand Up @@ -794,7 +792,7 @@ public static function getCasesSummary($allCases = TRUE) {
else {
$all = 0;
$case_owner = 2;
$myCaseWhereClause = " AND case_relationship.contact_id_b = {$userID}";
$myCaseWhereClause = " AND case_relationship.contact_id_b = {$userID} AND case_relationship.is_active ";
$myGroupByClause = " GROUP BY CONCAT(case_relationship.case_id,'-',case_relationship.contact_id_b)";
}
$myGroupByClause .= ", case_status.label, status_id, case_type_id";
Expand All @@ -810,7 +808,7 @@ public static function getCasesSummary($allCases = TRUE) {
LEFT JOIN civicrm_option_value case_status ON ( civicrm_case.status_id = case_status.value
AND option_group_case_status.id = case_status.option_group_id )
LEFT JOIN civicrm_relationship case_relationship ON ( case_relationship.case_id = civicrm_case.id
AND case_relationship.contact_id_b = {$userID})
AND case_relationship.contact_id_b = {$userID} AND case_relationship.is_active )
WHERE is_deleted = 0 AND cc.contact_id IN (SELECT id FROM civicrm_contact WHERE is_deleted <> 1)
{$myCaseWhereClause} {$myGroupByClause}";

Expand Down Expand Up @@ -859,7 +857,7 @@ public static function getCaseRoles($contactID, $caseID, $relationshipID = NULL,
IF(rel.contact_id_a = %1, "a_b", "b_a") as relationship_direction
FROM civicrm_relationship rel
INNER JOIN civicrm_relationship_type ON rel.relationship_type_id = civicrm_relationship_type.id
INNER JOIN civicrm_contact con ON ((con.id <> %1 AND con.id IN (rel.contact_id_a, rel.contact_id_b)) OR (con.id = %1 AND rel.contact_id_b = rel.contact_id_a AND rel.contact_id_a = %1))
INNER JOIN civicrm_contact con ON ((con.id <> %1 AND con.id IN (rel.contact_id_a, rel.contact_id_b)) OR (con.id = %1 AND rel.contact_id_b = rel.contact_id_a AND rel.contact_id_a = %1 AND rel.is_active))
LEFT JOIN civicrm_phone ON (civicrm_phone.contact_id = con.id AND civicrm_phone.is_primary = 1)
LEFT JOIN civicrm_email ON (civicrm_email.contact_id = con.id AND civicrm_email.is_primary = 1)
WHERE (rel.contact_id_a = %1 OR rel.contact_id_b = %1) AND rel.case_id = %2
Expand Down Expand Up @@ -1918,7 +1916,7 @@ public static function getCaseManagerContact($caseType, $caseId) {
SELECT civicrm_contact.id as casemanager_id,
civicrm_contact.sort_name as casemanager
FROM civicrm_contact
LEFT JOIN civicrm_relationship ON (civicrm_relationship.contact_id_b = civicrm_contact.id AND civicrm_relationship.relationship_type_id = %1)
LEFT JOIN civicrm_relationship ON (civicrm_relationship.contact_id_b = civicrm_contact.id AND civicrm_relationship.relationship_type_id = %1) AND civicrm_relationship.is_active
LEFT JOIN civicrm_case ON civicrm_case.id = civicrm_relationship.case_id
WHERE civicrm_case.id = %2 AND is_active = 1";

Expand Down
2 changes: 1 addition & 1 deletion CRM/Case/BAO/Query.php
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,7 @@ public static function whereClauseSingle(&$values, &$query) {
if ($value == 2) {
$session = CRM_Core_Session::singleton();
$userID = $session->get('userID');
$query->_where[$grouping][] = CRM_Contact_BAO_Query::buildClause("case_relationship.contact_id_b", $op, $userID, 'Int');
$query->_where[$grouping][] = ' ( ' . CRM_Contact_BAO_Query::buildClause("case_relationship.contact_id_b", $op, $userID, 'Int') . ' AND ' . CRM_Contact_BAO_Query::buildClause("case_relationship.is_active", '<>', 0, 'Int') . ' ) ';
$query->_qill[$grouping][] = ts('Case %1 My Cases', array(1 => $op));
$query->_tables['case_relationship'] = $query->_whereTables['case_relationship'] = 1;
}
Expand Down
79 changes: 55 additions & 24 deletions CRM/Case/Form/Case.php
Original file line number Diff line number Diff line change
Expand Up @@ -302,34 +302,30 @@ public static function formRule($values, $files, $form) {
}

/**
* Process the form submission.
* Wrapper for unit testing the post process submit function.
*
* @param $params
* @param $activityTypeFile
* @param $contactId
* @param $context
* @return CRM_Case_BAO_Case
*/
public function postProcess() {
$transaction = new CRM_Core_Transaction();
public function testSubmit($params, $activityTypeFile, $contactId, $context = "case") {
$this->controller = new CRM_Core_Controller();

// check if dedupe button, if so return.
$buttonName = $this->controller->getButtonName();
if (isset($this->_dedupeButtonName) && $buttonName == $this->_dedupeButtonName) {
return;
}
$this->_activityTypeFile = $activityTypeFile;
$this->_currentUserId = $contactId;
$this->_context = $context;

if ($this->_action & CRM_Core_Action::DELETE) {
$caseDelete = CRM_Case_BAO_Case::deleteCase($this->_caseId, TRUE);
if ($caseDelete) {
CRM_Core_Session::setStatus(ts('You can view and / or restore deleted cases by checking the "Deleted Cases" option under Find Cases.'), ts('Case Deleted'), 'success');
}
return;
}
return $this->submit($params);
}

if ($this->_action & CRM_Core_Action::RENEW) {
$caseRestore = CRM_Case_BAO_Case::restoreCase($this->_caseId);
if ($caseRestore) {
CRM_Core_Session::setStatus(ts('The selected case has been restored.'), ts('Restored'), 'success');
}
return;
}
// store the submitted values in an array
$params = $this->controller->exportValues($this->_name);
/**
* Submit the form with given params.
*
* @param $params
*/
public function submit(&$params) {
$params['now'] = date("Ymd");

// 1. call begin post process
Expand Down Expand Up @@ -401,7 +397,42 @@ public function postProcess() {
$className::endPostProcess($this, $params);
}

return $caseObj;
}

/**
* Process the form submission.
*/
public function postProcess() {
$transaction = new CRM_Core_Transaction();

// check if dedupe button, if so return.
$buttonName = $this->controller->getButtonName();
if (isset($this->_dedupeButtonName) && $buttonName == $this->_dedupeButtonName) {
return;
}

if ($this->_action & CRM_Core_Action::DELETE) {
$caseDelete = CRM_Case_BAO_Case::deleteCase($this->_caseId, TRUE);
if ($caseDelete) {
CRM_Core_Session::setStatus(ts('You can view and / or restore deleted cases by checking the "Deleted Cases" option under Find Cases.'), ts('Case Deleted'), 'success');
}
return;
}

if ($this->_action & CRM_Core_Action::RENEW) {
$caseRestore = CRM_Case_BAO_Case::restoreCase($this->_caseId);
if ($caseRestore) {
CRM_Core_Session::setStatus(ts('The selected case has been restored.'), ts('Restored'), 'success');
}
return;
}
// store the submitted values in an array
$params = $this->controller->exportValues($this->_name);
$this->submit($params);

CRM_Core_Session::setStatus($params['statusMsg'], ts('Saved'), 'success');

}

}
86 changes: 86 additions & 0 deletions tests/phpunit/CRM/Case/BAO/CaseTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,92 @@ public function testAddCaseToContact() {
$this->assertEquals('Test Contact - Housing Support', $recent[0]['title']);
}

/**
* Create and return case object of given Client ID.
* @param $clientId
* @return CRM_Case_BAO_Case
*/
private function createCase($clientId) {
$caseParams = array(
'activity_subject' => 'Case Subject',
'client_id' => $clientId,
'case_type_id' => 1,
'status_id' => 1,
'case_type' => 'housing_support',
'subject' => 'Case Subject',
'start_date' => date("Y-m-d"),
'start_date_time' => date("YmdHis"),
'medium_id' => 2,
'activity_details' => '',
);
$form = new CRM_Case_Form_Case();
$caseObj = $form->testSubmit($caseParams, "OpenCase", $clientId, "standalone");
return $caseObj;
}

/**
* Create case role relationship between given contacts for provided case ID.
*
* @param $contactIdA
* @param $contactIdB
* @param $caseId
* @param bool $isActive
*/
private function createCaseRoleRelationship($contactIdA, $contactIdB, $caseId, $isActive = TRUE) {
$relationshipType = $this->relationshipTypeCreate([
'contact_type_b' => 'Individual',
]);

$this->callAPISuccess('Relationship', 'create', array(
'contact_id_a' => $contactIdA,
'contact_id_b' => $contactIdB,
'relationship_type_id' => $relationshipType,
'case_id' => $caseId,
'is_active' => $isActive,
));
}

/**
* Asserts number of cases for given logged in user.
*
* @param $loggedInUser
* @param $caseId
* @param $caseCount
*/
private function assertCasesOfUser($loggedInUser, $caseId, $caseCount) {
$summary = CRM_Case_BAO_Case::getCasesSummary(FALSE);
$upcomingCases = CRM_Case_BAO_Case::getCases(FALSE, array(), 'dashboard', TRUE);
$caseRoles = CRM_Case_BAO_Case::getCaseRoles($loggedInUser, $caseId);

$this->assertEquals($caseCount, $upcomingCases, 'Upcoming case count must be ' . $caseCount);
$this->assertEquals($caseCount, $summary['rows']['Housing Support']['Ongoing']['count'], 'Housing Support Ongoing case summary must be ' . $caseCount);
$this->assertEquals($caseCount, count($caseRoles), 'Total case roles for logged in users must be ' . $caseCount);
}

/**
* Test that Case count is exactly one for logged in user for user's active role.
*/
public function testActiveCaseRole() {
$individual = $this->individualCreate();
$caseObj = $this->createCase($individual);
$caseId = $caseObj->id;
$loggedInUser = $this->createLoggedInUser();
$this->createCaseRoleRelationship($individual, $loggedInUser, $caseId);
$this->assertCasesOfUser($loggedInUser, $caseId, 1);
}

/**
* Test that case count is zero for logged in user for user's inactive role.
*/
public function testInactiveCaseRole() {
$individual = $this->individualCreate();
$caseObj = $this->createCase($individual);
$caseId = $caseObj->id;
$loggedInUser = $this->createLoggedInUser();
$this->createCaseRoleRelationship($individual, $loggedInUser, $caseId, FALSE);
$this->assertCasesOfUser($loggedInUser, $caseId, 0);
}

public function testGetCaseType() {
$caseTypeLabel = CRM_Case_BAO_Case::getCaseType(1);
$this->assertEquals('Housing Support', $caseTypeLabel);
Expand Down