Move the code to add or clear employer from relationship backoffice form to BAO
authorMonish Deb <deb.monish@gmail.com>
Fri, 2 Aug 2019 01:59:12 +0000 (13:59 +1200)
committereileen <emcnaughton@wikimedia.org>
Fri, 2 Aug 2019 03:57:27 +0000 (15:57 +1200)
This is a reduced version of https://github.com/civicrm/civicrm-core/pull/13331 which stalled on the QA over handling of
removed employers - that code is simply excluded. I tested adding & removing & editing relationships with the
current_employer checkbox ticked or unticked & this seems to work fine

CRM/Contact/BAO/Contact/Utils.php
CRM/Contact/BAO/Relationship.php
CRM/Contact/Form/Relationship.php
api/v3/Relationship.php
tests/phpunit/api/v3/RelationshipTest.php

index 8850d9acc50227b806e5711cbe3223976740535c..1d9f166a7131f492c503051b79195ea34ce9c977 100644 (file)
@@ -392,10 +392,7 @@ UNION
       $query = "UPDATE civicrm_contact contact_a,civicrm_contact contact_b
 SET contact_a.employer_id=contact_b.id, contact_a.organization_name=contact_b.organization_name
 WHERE contact_a.id ={$contactId} AND contact_b.id={$orgId}; ";
-
-      //FIXME : currently civicrm mysql_query support only single statement
-      //execution, though mysql 5.0 support multiple statement execution.
-      $dao = CRM_Core_DAO::executeQuery($query);
+      CRM_Core_DAO::executeQuery($query);
     }
   }
 
index d61854ecaef9def9f2283db6a6f87b0d3d2736ab..385ed19e866da2e54acd0a175c48227b76a424ad 100644 (file)
@@ -278,13 +278,15 @@ class CRM_Contact_BAO_Relationship extends CRM_Contact_DAO_Relationship {
    * This is the function that check/add if the relationship created is valid.
    *
    * @param array $params
-   *   (reference ) an assoc array of name/value pairs.
+   *   Array of name/value pairs.
    * @param array $ids
    *   The array that holds all the db ids.
    * @param int $contactId
    *   This is contact id for adding relationship.
    *
    * @return CRM_Contact_BAO_Relationship
+   *
+   * @throws \CiviCRM_API3_Exception
    */
   public static function add($params, $ids = [], $contactId = NULL) {
     $params['id'] = CRM_Utils_Array::value('relationship', $ids, CRM_Utils_Array::value('id', $params));
@@ -311,6 +313,7 @@ class CRM_Contact_BAO_Relationship extends CRM_Contact_DAO_Relationship {
     if (!empty($params['id']) && self::isCurrentEmployerNeedingToBeCleared($params, $params['id'], $type)) {
       CRM_Contact_BAO_Contact_Utils::clearCurrentEmployer($params['contact_id_a']);
     }
+
     $relationship = new CRM_Contact_BAO_Relationship();
     //@todo this code needs to be updated for the possibility that not all fields are set
     // by using $relationship->copyValues($params);
@@ -340,7 +343,18 @@ class CRM_Contact_BAO_Relationship extends CRM_Contact_DAO_Relationship {
     }
 
     $relationship->save();
-
+    // is_current_employer is an optional parameter that triggers updating the employer_id field to reflect
+    // the relationship being updated. As of writing only truthy versions of the parameter are respected.
+    // https://github.com/civicrm/civicrm-core/pull/13331 attempted to cover both but stalled in QA
+    // so currently we have a cut down version.
+    if (!empty($params['is_current_employer'])) {
+      if (!$relationship->relationship_type_id || !$relationship->contact_id_a || !$relationship->contact_id_b) {
+        $relationship->fetch();
+      }
+      if (self::isRelationshipTypeCurrentEmployer($relationship->relationship_type_id)) {
+        CRM_Contact_BAO_Contact_Utils::setCurrentEmployer([$relationship->contact_id_a => $relationship->contact_id_b]);
+      }
+    }
     // add custom field values
     if (!empty($params['custom'])) {
       CRM_Core_BAO_CustomValueTable::store($params['custom'], 'civicrm_relationship', $relationship->id);
@@ -1968,6 +1982,7 @@ AND cc.sort_name LIKE '%$name%'";
    *
    * @return bool
    *   True on success, false if error is encountered.
+   * @throws \CiviCRM_API3_Exception
    */
   public static function disableExpiredRelationships() {
     $query = "SELECT id FROM civicrm_relationship WHERE is_active = 1 AND end_date < CURDATE()";
@@ -2261,13 +2276,13 @@ AND cc.sort_name LIKE '%$name%'";
    *
    * @return bool
    *   TRUE if current employer needs to be cleared.
+   * @throws \CiviCRM_API3_Exception
    */
   public static function isCurrentEmployerNeedingToBeCleared($params, $relationshipId, $updatedRelTypeID = NULL) {
-    $existingTypeID = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Relationship', $relationshipId, 'relationship_type_id');
-    $existingTypeName = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_RelationshipType', $existingTypeID, 'name_b_a');
+    $existingTypeID = (int) CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Relationship', $relationshipId, 'relationship_type_id');
     $updatedRelTypeID = $updatedRelTypeID ? $updatedRelTypeID : $existingTypeID;
 
-    if ($existingTypeName !== 'Employer of') {
+    if (!self::isRelationshipTypeCurrentEmployer($existingTypeID)) {
       return FALSE;
     }
     //Clear employer if relationship is expired.
@@ -2285,4 +2300,18 @@ AND cc.sort_name LIKE '%$name%'";
     return FALSE;
   }
 
+  /**
+   * Is this a current employer relationship type.
+   *
+   * @todo - this could use cached pseudoconstant lookups.
+   *
+   * @param int $existingTypeID
+   *
+   * @return bool
+   */
+  private static function isRelationshipTypeCurrentEmployer(int $existingTypeID): bool {
+    $isCurrentEmployerRelationshipType = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_RelationshipType', $existingTypeID, 'name_b_a') === 'Employer of';
+    return $isCurrentEmployerRelationshipType;
+  }
+
 }
index 1516238bbf77df364107be4a081062e73dfc020a..eca04a56c6d035ec23237d1dded676e1c1f18c8c 100644 (file)
@@ -416,8 +416,6 @@ class CRM_Contact_Form_Relationship extends CRM_Core_Form {
     $note = !empty($params['note']) ? $params['note'] : '';
     $this->saveRelationshipNotes($relationshipIds, $note);
 
-    $this->setEmploymentRelationship($params, $relationshipIds);
-
     // Refresh contact tabs which might have been affected
     $this->ajaxResponse = [
       'reloadBlocks' => ['#crm-contactinfo-content'],
@@ -638,27 +636,4 @@ class CRM_Contact_Form_Relationship extends CRM_Core_Form {
     }
   }
 
-  /**
-   * Sets current employee/employer relationship
-   *
-   * @param $params
-   * @param array $relationshipIds
-   */
-  private function setEmploymentRelationship($params, $relationshipIds) {
-    $employerParams = [];
-    foreach ($relationshipIds as $id) {
-      if (!CRM_Contact_BAO_Relationship::isCurrentEmployerNeedingToBeCleared($params, $id)
-        //don't think this is required to check again.
-        && $this->_allRelationshipNames[$params['relationship_type_id']]["name_a_b"] == 'Employee of') {
-        // Fixme this is dumb why do we have to look this up again?
-        $rel = CRM_Contact_BAO_Relationship::getRelationshipByID($id);
-        $employerParams[$rel->contact_id_a] = $rel->contact_id_b;
-      }
-    }
-    if (!empty($employerParams)) {
-      // @todo this belongs in the BAO.
-      CRM_Contact_BAO_Contact_Utils::setCurrentEmployer($employerParams);
-    }
-  }
-
 }
index d08889cd896b44e5d697b9027052a946a8e1f326..f7023dea4a671d36c526914052633706907e3ca8 100644 (file)
@@ -58,6 +58,11 @@ function _civicrm_api3_relationship_create_spec(&$params) {
   $params['contact_id_b']['api.required'] = 1;
   $params['relationship_type_id']['api.required'] = 1;
   $params['is_active']['api.default'] = 1;
+  $params['is_current_employer'] = [
+    'title' => 'Is Current Employer?',
+    'description' => 'This is a optional parameter used to add employer contact when \'Employee Of\' relationship is created',
+    'type' => CRM_Utils_Type::T_BOOLEAN,
+  ];
 }
 
 /**
index d29fe056debbc70b3b599fd2188b8d369b19081f..a85f738d97d94b89e498c967055167081b7aecb7 100644 (file)
@@ -117,23 +117,24 @@ class api_v3_RelationshipTest extends CiviUnitTestCase {
 
   /**
    * Test Current Employer is correctly set.
+   *
+   * @throws \CRM_Core_Exception
    */
   public function testCurrentEmployerRelationship() {
     $employerRelationshipID = $this->callAPISuccessGetValue('RelationshipType', [
-      'return' => "id",
-      'name_b_a' => "Employer Of",
+      'return' => 'id',
+      'name_b_a' => 'Employer Of',
     ]);
     $employerRelationship = $this->callAPISuccess('Relationship', 'create', [
       'contact_id_a' => $this->_cId_a,
       'contact_id_b' => $this->_cId_b,
       'relationship_type_id' => $employerRelationshipID,
+      'is_current_employer' => 1,
     ]);
-    $params = [$this->_cId_a => $this->_cId_b];
-    CRM_Contact_BAO_Contact_Utils::setCurrentEmployer($params);
 
     //Check if current employer is correctly set.
     $employer = $this->callAPISuccessGetValue('Contact', [
-      'return' => "current_employer",
+      'return' => 'current_employer',
       'id' => $this->_cId_a,
     ]);
     $organisation = $this->callAPISuccessGetValue('Contact', [
@@ -148,7 +149,7 @@ class api_v3_RelationshipTest extends CiviUnitTestCase {
       'relationship_type_id' => $this->_relTypeID,
     ]);
     $employeeContact = $this->callAPISuccessGetSingle('Contact', [
-      'return' => ["current_employer"],
+      'return' => ['current_employer'],
       'id' => $this->_cId_a,
     ]);
     //current employer should be removed.
@@ -1358,4 +1359,48 @@ class api_v3_RelationshipTest extends CiviUnitTestCase {
     $this->callAPISuccessGetCount('membership', ['contact_id' => $this->_cId_a], 0);
   }
 
+  /**
+   * Test api respects is_current_employer.
+   *
+   * @throws \CRM_Core_Exception
+   */
+  public function testRelationshipCreateWithEmployerData() {
+    // CASE A: Create a current employee relationship without setting end date, ensure that employer field is set
+    $params = [
+      'relationship_type_id' => '5_a_b',
+      'related_contact_id' => $this->_cId_b,
+      'start_date' => '2008-12-20',
+      'end_date' => NULL,
+      'is_active' => 1,
+      'is_current_employer' => 1,
+      'is_permission_a_b' => 0,
+      'is_permission_b_a' => 0,
+    ];
+    $reln = new CRM_Contact_Form_Relationship();
+    $reln->_action = CRM_Core_Action::ADD;
+    $reln->_contactId = $this->_cId_a;
+    list ($params, $relationshipIds) = $reln->submit($params);
+    $this->assertEquals(
+      $this->_cId_b,
+      $this->callAPISuccess('Contact', 'getvalue', [
+        'id' => $this->_cId_a,
+        'return' => 'current_employer_id',
+      ]));
+    // CASE B: Create a past employee relationship by setting end date of past, ensure that employer field is cleared
+    $params = [
+      'relationship_type_id' => '5_a_b',
+      'related_contact_id' => $this->_cId_b,
+      // set date to past date
+      'end_date' => '2010-12-20',
+    ];
+    $reln->_action = CRM_Core_Action::UPDATE;
+    $reln->_relationshipId = $relationshipIds[0];
+    list ($params, $relationshipIds) = $reln->submit($params);
+    $this->assertEmpty($this->callAPISuccess('Contact', 'getvalue', [
+      'id' => $this->_cId_a,
+      'return' => 'current_employer_id',
+    ]));
+    $this->callAPISuccess('relationship', 'delete', ['id' => $relationshipIds[0]]);
+  }
+
 }