CRM-16980 - Improve case role handing
authorColeman Watts <coleman@civicrm.org>
Sat, 26 Sep 2015 22:05:41 +0000 (18:05 -0400)
committerColeman Watts <coleman@civicrm.org>
Sat, 26 Sep 2015 22:05:41 +0000 (18:05 -0400)
CRM/Activity/Page/AJAX.php
CRM/Case/BAO/Case.php
CRM/Case/Form/CaseView.php
CRM/Case/Page/AJAX.php
CRM/Contact/Page/AJAX.php

index f8ab3517b774866a4e315e25303f61b2bffb710b..67c5b3442bd4e89c4855562eee52d1923619efad 100644 (file)
@@ -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] . '<br />' . '(' . 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 "<br />(Case Manager)" from label
-      list($typeLabel) = explode('<', $row['relation']);
+      $typeLabel = $row['relation'];
+      // Add "<br />(Case Manager)" to label
+      if ($row['relation_type'] == $managerRoleId) {
+        $row['relation'] .= '<br />' . '(' . ts('Case Manager') . ')';
+      }
       // view user links
       if (!empty($row['cid'])) {
         $row['name'] = '<a class="view-contact" title="' . ts('View Contact') . '" href=' . CRM_Utils_System::url('civicrm/contact/view',
@@ -277,16 +271,16 @@ class CRM_Activity_Page_AJAX {
         $contactType = $contactType == 'Contact' ? '' : $contactType;
         switch ($row['source']) {
           case 'caseRel':
-            $row['actions'] = '<a href="#editCaseRoleDialog" title="' . ts('Reassign %1', array(1 => $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'] = '<a href="#editCaseRoleDialog" title="' . ts('Reassign %1', array(1 => $typeLabel)) . '" class="crm-hover-button case-miniform" data-contact_type="' . $contactType . '" data-rel_type="' . $row['relation_type'] . '_' . $row['relationship_direction'] . '" data-cid="'  . '" data-rel_id="' . $row['rel_id'] . '"data-key="' . CRM_Core_Key::get('civicrm/ajax/relation') . '">' .
               '<span class="icon ui-icon-pencil"></span>' .
               '</a>' .
-              '<a href="#deleteCaseRoleDialog" title="' . ts('Remove %1', array(1 => $typeLabel)) . '" class="crm-hover-button case-miniform" data-contact_type="' . $contactType . '" data-rel_type="' . $row['relation_type'] . '" data-key="' . CRM_Core_Key::get('civicrm/ajax/delcaserole') . '">' .
+              '<a href="#deleteCaseRoleDialog" title="' . ts('Remove %1', array(1 => $typeLabel)) . '" class="crm-hover-button case-miniform" data-contact_type="' . $contactType . '" data-rel_type="' . $row['relation_type'] . '_' . $row['relationship_direction'] . '" data-cid="' . $row['cid'] . '" data-key="' . CRM_Core_Key::get('civicrm/ajax/delcaserole') . '">' .
               '<span class="icon delete-icon"></span>' .
               '</a>';
             break;
 
           case 'caseRoles':
-            $row['actions'] = '<a href="#editCaseRoleDialog" title="' . ts('Assign %1', array(1 => $typeLabel)) . '" class="crm-hover-button case-miniform" data-contact_type="' . $contactType . '" data-rel_type="' . $row['relation_type'] . '" data-key="' . CRM_Core_Key::get('civicrm/ajax/relation') . '">' .
+            $row['actions'] = '<a href="#editCaseRoleDialog" title="' . ts('Assign %1', array(1 => $typeLabel)) . '" class="crm-hover-button case-miniform" data-contact_type="' . $contactType . '" data-rel_type="' . $row['relation_type'] . '_b_a" data-key="' . CRM_Core_Key::get('civicrm/ajax/relation') . '">' .
               '<span class="icon ui-icon-pencil"></span>' .
               '</a>';
             break;
index e7de688a63fed6aba60ab17ad671da77a0b76c85..4d2fb3d429298d240d299c7f96ddf03e7a36ae4c 100644 (file)
@@ -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
index 776f2f4c8f14c2349c789219d02a15e1af21ea4c..87414e2fb40c4b66213e440a0badd0bef9bfb782 100644 (file)
@@ -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);
index f0a9e4667f781ca8d7b18e9adb088a003082c2bf..c42e9b7496a2e1a31ffed1eab14e4074d47fcdda 100644 (file)
@@ -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();
   }
 
index 4fd4fdc2bd70b2e9dd0dbfbfe8da50149390028f..9621dbc329fa45cb61e4e620b623f5dd6ad40e16 100644 (file)
@@ -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 <a href="%1">Administer >> Option Lists >> Relationship Types</a>.',
-            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);
       }
     }