From 3b1c37fee769397d127804668dd03d03e3e8ce06 Mon Sep 17 00:00:00 2001 From: Coleman Watts Date: Sat, 26 Sep 2015 18:05:41 -0400 Subject: [PATCH] CRM-16980 - Improve case role handing --- CRM/Activity/Page/AJAX.php | 26 ++++++-------- CRM/Case/BAO/Case.php | 58 +++++++++++++++++++++++------- CRM/Case/Form/CaseView.php | 10 ++---- CRM/Case/Page/AJAX.php | 9 ++--- CRM/Contact/Page/AJAX.php | 72 ++++++++++++++------------------------ 5 files changed, 89 insertions(+), 86 deletions(-) diff --git a/CRM/Activity/Page/AJAX.php b/CRM/Activity/Page/AJAX.php index f8ab3517b7..67c5b3442b 100644 --- a/CRM/Activity/Page/AJAX.php +++ b/CRM/Activity/Page/AJAX.php @@ -201,19 +201,10 @@ class CRM_Activity_Page_AJAX { $hasAccessToAllCases = CRM_Core_Permission::check('access all cases and activities'); $managerRoleId = $xmlProcessor->getCaseManagerRoleId($caseTypeName); - if (!empty($managerRoleId)) { - $caseRoles[$managerRoleId] = $caseRoles[$managerRoleId] . '
' . '(' . ts('Case Manager') . ')'; - } - - $relationships = array(); foreach ($caseRelationships as $key => $value) { - //calculate roles that don't have relationships - if (!empty($caseRoles[$value['relation_type']])) { - //keep naming from careRoles array - $caseRelationships[$key]['relation'] = $caseRoles[$value['relation_type']]; - unset($caseRoles[$value['relation_type']]); - } + // This role has been filled + unset($caseRoles[$value['relation_type']]); // mark original case relationships record to use on setting edit links below $caseRelationships[$key]['source'] = 'caseRel'; } @@ -259,8 +250,11 @@ class CRM_Activity_Page_AJAX { // set user name, email and edit columns links foreach ($caseRelationships as $key => &$row) { - // Get rid of the "
(Case Manager)" from label - list($typeLabel) = explode('<', $row['relation']); + $typeLabel = $row['relation']; + // Add "
(Case Manager)" to label + if ($row['relation_type'] == $managerRoleId) { + $row['relation'] .= '
' . '(' . ts('Case Manager') . ')'; + } // view user links if (!empty($row['cid'])) { $row['name'] = ' $typeLabel)) . '" class="crm-hover-button case-miniform" data-contact_type="' . $contactType . '" data-rel_type="' . $row['relation_type'] . '" data-rel_id="' . $row['rel_id'] . '"data-key="' . CRM_Core_Key::get('civicrm/ajax/relation') . '">' . + $row['actions'] = '' . '' . '' . - '' . + '' . '' . ''; break; case 'caseRoles': - $row['actions'] = '' . + $row['actions'] = '' . '' . ''; break; diff --git a/CRM/Case/BAO/Case.php b/CRM/Case/BAO/Case.php index e7de688a63..4d2fb3d429 100644 --- a/CRM/Case/BAO/Case.php +++ b/CRM/Case/BAO/Case.php @@ -968,20 +968,21 @@ SELECT case_status.label AS case_status, status_id, civicrm_case_type.title AS c */ public static function getCaseRoles($contactID, $caseID, $relationshipID = NULL) { $query = ' - SELECT civicrm_relationship.id as civicrm_relationship_id, - civicrm_contact.sort_name as sort_name, + SELECT rel.id as civicrm_relationship_id, + con.sort_name as sort_name, civicrm_email.email as email, civicrm_phone.phone as phone, - civicrm_relationship.contact_id_b as civicrm_contact_id, - civicrm_relationship.contact_id_a as client_id, - civicrm_relationship_type.label_a_b as relation, - civicrm_relationship_type.id as relation_type - FROM civicrm_relationship - INNER JOIN civicrm_relationship_type ON civicrm_relationship.relationship_type_id = civicrm_relationship_type.id - INNER JOIN civicrm_contact ON civicrm_relationship.contact_id_b = civicrm_contact.id - LEFT JOIN civicrm_phone ON (civicrm_phone.contact_id = civicrm_contact.id AND civicrm_phone.is_primary = 1) - LEFT JOIN civicrm_email ON (civicrm_email.contact_id = civicrm_contact.id AND civicrm_email.is_primary = 1) - WHERE civicrm_relationship.contact_id_a = %1 AND civicrm_relationship.case_id = %2'; + con.id as civicrm_contact_id, + IF(rel.contact_id_a = %1, civicrm_relationship_type.label_a_b, civicrm_relationship_type.label_b_a) as relation, + civicrm_relationship_type.id as relation_type, + 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)) + 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 + AND rel.is_active = 1 AND (rel.end_date IS NULL OR rel.end_date > NOW())'; $params = array( 1 => array($contactID, 'Positive'), @@ -1004,7 +1005,8 @@ SELECT case_status.label AS case_status, status_id, civicrm_case_type.title AS c $values[$rid]['phone'] = $dao->phone; $values[$rid]['relation_type'] = $dao->relation_type; $values[$rid]['rel_id'] = $dao->civicrm_relationship_id; - $values[$rid]['client_id'] = $dao->client_id; + $values[$rid]['client_id'] = $contactID; + $values[$rid]['relationship_direction'] = $dao->relationship_direction; } $dao->free(); @@ -3394,6 +3396,36 @@ WHERE id IN (' . implode(',', $copiedActivityIds) . ')'; return $clients; } + /** + * @param int $caseId + * @param string $direction + * @param int $cid + * @param int $relTypeId + * @throws \CRM_Core_Exception + * @throws \CiviCRM_API3_Exception + */ + public static function endCaseRole($caseId, $direction, $cid, $relTypeId) { + // Validate inputs + if ($direction !== 'a' && $direction !== 'b') { + throw new CRM_Core_Exception('Invalid relationship direction'); + } + + // This case might have multiple clients, so we lookup by relationship instead of by id to get them all + $sql = "SELECT id FROM civicrm_relationship WHERE case_id = %1 AND contact_id_{$direction} = %2 AND relationship_type_id = %3"; + $dao = CRM_Core_DAO::executeQuery($sql, array( + 1 => array($caseId, 'Positive'), + 2 => array($cid, 'Positive'), + 3 => array($relTypeId, 'Positive'), + )); + while ($dao->fetch()) { + civicrm_api3('relationship', 'create', array( + 'id' => $dao->id, + 'is_active' => 0, + 'end_date' => 'now', + )); + } + } + /** * Get options for a given case field. * @see CRM_Core_DAO::buildOptions diff --git a/CRM/Case/Form/CaseView.php b/CRM/Case/Form/CaseView.php index 776f2f4c8f..87414e2fb4 100644 --- a/CRM/Case/Form/CaseView.php +++ b/CRM/Case/Form/CaseView.php @@ -369,13 +369,9 @@ class CRM_Case_Form_CaseView extends CRM_Core_Form { CRM_Case_BAO_Case::getGlobalContacts($globalGroupInfo); $this->assign('globalGroupInfo', $globalGroupInfo); - // List of relationship types - $baoRel = new CRM_Contact_BAO_Relationship(); - $relType = $baoRel->getRelationType('Individual'); - $roleTypes = array(); - foreach ($relType as $k => $v) { - $roleTypes[substr($k, 0, strpos($k, '_'))] = $v; - } + + // List relationship types for adding an arbitrary new role to the case + $roleTypes = CRM_Contact_BAO_Relationship::getContactRelationshipType($this->_contactID); $this->add('select', 'role_type', ts('Relationship Type'), array('' => ts('- select type -')) + $roleTypes, FALSE, array('class' => 'crm-select2 twenty')); $hookCaseSummary = CRM_Utils_Hook::caseSummary($this->_caseID); diff --git a/CRM/Case/Page/AJAX.php b/CRM/Case/Page/AJAX.php index f0a9e4667f..c42e9b7496 100644 --- a/CRM/Case/Page/AJAX.php +++ b/CRM/Case/Page/AJAX.php @@ -202,15 +202,16 @@ class CRM_Case_Page_AJAX { */ public static function deleteCaseRoles() { $caseId = CRM_Utils_Type::escape($_POST['case_id'], 'Positive'); - $relType = CRM_Utils_Type::escape($_POST['rel_type'], 'Positive'); + $cid = CRM_Utils_Type::escape($_POST['cid'], 'Positive'); + $relType = CRM_Utils_Request::retrieve('rel_type', 'String', CRM_Core_DAO::$_nullObject, TRUE); - if (!$relType || !CRM_Case_BAO_Case::accessCase($caseId)) { + if (!$cid || !CRM_Case_BAO_Case::accessCase($caseId)) { CRM_Utils_System::permissionDenied(); } - $sql = "DELETE FROM civicrm_relationship WHERE case_id={$caseId} AND relationship_type_id={$relType}"; - CRM_Core_DAO::executeQuery($sql); + list($relTypeId, $a, $b) = explode('_', $relType); + CRM_Case_BAO_Case::endCaseRole($caseId, $b, $cid, $relTypeId); CRM_Utils_System::civiExit(); } diff --git a/CRM/Contact/Page/AJAX.php b/CRM/Contact/Page/AJAX.php index 4fd4fdc2bd..9621dbc329 100644 --- a/CRM/Contact/Page/AJAX.php +++ b/CRM/Contact/Page/AJAX.php @@ -219,62 +219,42 @@ class CRM_Contact_Page_AJAX { CRM_Utils_JSON::output($output); } + /** + * @throws \CiviCRM_API3_Exception + */ public static function relationship() { - $relType = CRM_Utils_Request::retrieve('rel_type', 'Positive', CRM_Core_DAO::$_nullObject, TRUE); + $relType = CRM_Utils_Request::retrieve('rel_type', 'String', CRM_Core_DAO::$_nullObject, TRUE); $relContactID = CRM_Utils_Request::retrieve('rel_contact', 'Positive', CRM_Core_DAO::$_nullObject, TRUE); - $relationshipID = CRM_Utils_Request::retrieve('rel_id', 'Positive', CRM_Core_DAO::$_nullObject); // this used only to determine add or update mode + $originalCid = CRM_Utils_Request::retrieve('cid', 'Positive', CRM_Core_DAO::$_nullObject); + $relationshipID = CRM_Utils_Request::retrieve('rel_id', 'Positive', CRM_Core_DAO::$_nullObject); $caseID = CRM_Utils_Request::retrieve('case_id', 'Positive', CRM_Core_DAO::$_nullObject, TRUE); - // check if there are multiple clients for this case, if so then we need create - // relationship and also activities for each contacts - - // get case client list - $clientList = CRM_Case_BAO_Case::getCaseClients($caseID); + if (!CRM_Case_BAO_Case::accessCase($caseID)) { + CRM_Utils_System::permissionDenied(); + } $ret = array('is_error' => 0); - foreach ($clientList as $sourceContactID) { - $relationParams = array( - 'relationship_type_id' => $relType . '_a_b', - 'contact_check' => array($relContactID => 1), - 'is_active' => 1, - 'case_id' => $caseID, - 'start_date' => date("Ymd"), - ); - - $relationIds = array('contact' => $sourceContactID); - - // check if we are editing/updating existing relationship - if ($relationshipID && $relationshipID != 'null') { - // here we need to retrieve appropriate relationshipID based on client id and relationship type id - $caseRelationships = new CRM_Contact_DAO_Relationship(); - $caseRelationships->case_id = $caseID; - $caseRelationships->relationship_type_id = $relType; - $caseRelationships->contact_id_a = $sourceContactID; - $caseRelationships->find(); + list($relTypeId, $b, $a) = explode('_', $relType); - while ($caseRelationships->fetch()) { - $relationIds['relationship'] = $caseRelationships->id; - $relationIds['contactTarget'] = $relContactID; - } - $caseRelationships->free(); - } - - // create new or update existing relationship - $return = CRM_Contact_BAO_Relationship::legacyCreateMultiple($relationParams, $relationIds); + if ($relationshipID && $originalCid) { + CRM_Case_BAO_Case::endCaseRole($caseID, $a, $originalCid, $relTypeId); + } - if (!empty($return[4][0])) { - $relationshipID = $return[4][0]; + $clientList = CRM_Case_BAO_Case::getCaseClients($caseID); - //create an activity for case role assignment.CRM-4480 - CRM_Case_BAO_Case::createCaseRoleActivity($caseID, $relationshipID, $relContactID); - } - else { - $ret = array( - 'is_error' => 1, - 'error_message' => ts('The relationship type definition for the case role is not valid for the client and / or staff contact types. You can review and edit relationship types at Administer >> Option Lists >> Relationship Types.', - array(1 => CRM_Utils_System::url('civicrm/admin/reltype', 'reset=1'))), - ); + // Loop through multiple case clients + foreach ($clientList as $i => $sourceContactID) { + $result = civicrm_api3('relationship', 'create', array( + 'case_id' => $caseID, + 'relationship_type_id' => $relTypeId, + "contact_id_$a" => $relContactID, + "contact_id_$b" => $sourceContactID, + 'start_date' => 'now', + )); + // Save activity only for the primary (first) client + if ($i == 0 && empty($result['is_error'])) { + CRM_Case_BAO_Case::createCaseRoleActivity($caseID, $result['id'], $relContactID); } } -- 2.25.1