From 0c578c022f237e3904062d3f95d579bd809a286d Mon Sep 17 00:00:00 2001 From: Monish Deb Date: Fri, 2 Aug 2019 14:43:53 +1200 Subject: [PATCH] dev/core#470: Current employer disapears when disabling expired relationships MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Overview ---------------------------------------- Steps to replicate: 1. Create a current relationship (set empty end-date) on individual A as organization A and mark as current employer 2. Create a past relationship on individual A as organization B without marking as current employer 3. Run Disable expired relationships cron job Before ---------------------------------------- Result: Clear the employer field of Contact A After ---------------------------------------- Result: Does not clear the employer field of Contact A Technical Details ---------------------------------------- This PR replaces https://github.com/civicrm/civicrm-core/pull/13334 --- CRM/Contact/BAO/Relationship.php | 14 ++++- tests/phpunit/api/v3/RelationshipTest.php | 72 +++++++++++++++++++++++ 2 files changed, 84 insertions(+), 2 deletions(-) diff --git a/CRM/Contact/BAO/Relationship.php b/CRM/Contact/BAO/Relationship.php index 385ed19e86..5d55ef141a 100644 --- a/CRM/Contact/BAO/Relationship.php +++ b/CRM/Contact/BAO/Relationship.php @@ -2281,8 +2281,9 @@ AND cc.sort_name LIKE '%$name%'"; public static function isCurrentEmployerNeedingToBeCleared($params, $relationshipId, $updatedRelTypeID = NULL) { $existingTypeID = (int) CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Relationship', $relationshipId, 'relationship_type_id'); $updatedRelTypeID = $updatedRelTypeID ? $updatedRelTypeID : $existingTypeID; + $currentEmployerID = (int) civicrm_api3('Contact', 'getvalue', ['return' => 'current_employer_id', 'id' => $params['contact_id_a']]); - if (!self::isRelationshipTypeCurrentEmployer($existingTypeID)) { + if ($currentEmployerID !== (int) $params['contact_id_b'] || !self::isRelationshipTypeCurrentEmployer($existingTypeID)) { return FALSE; } //Clear employer if relationship is expired. @@ -2294,7 +2295,16 @@ AND cc.sort_name LIKE '%$name%'"; if ((isset($params['is_current_employer']) && empty($params['is_current_employer'])) || ((isset($params['is_active']) && empty($params['is_active']))) || $existingTypeID != $updatedRelTypeID) { - return TRUE; + // If there are no other active employer relationships between the same 2 contacts... + if (!civicrm_api3('Relationship', 'getcount', [ + 'is_active' => 1, + 'relationship_type_id' => $existingTypeID, + 'id' => ['<>' => $params['id']], + 'contact_id_a' => $params['contact_id_a'], + 'contact_id_b' => $params['contact_id_b'], + ])) { + return TRUE; + } } return FALSE; diff --git a/tests/phpunit/api/v3/RelationshipTest.php b/tests/phpunit/api/v3/RelationshipTest.php index a85f738d97..b8c23988a5 100644 --- a/tests/phpunit/api/v3/RelationshipTest.php +++ b/tests/phpunit/api/v3/RelationshipTest.php @@ -1403,4 +1403,76 @@ class api_v3_RelationshipTest extends CiviUnitTestCase { $this->callAPISuccess('relationship', 'delete', ['id' => $relationshipIds[0]]); } + /** + * Test disabling an expired relationship does not incorrectly clear employer_id. + * + * See https://lab.civicrm.org/dev/core/issues/470 + * + * @throws \CRM_Core_Exception + * @throws \CiviCRM_API3_Exception + */ + public function testDisableExpiredRelationships() { + // Step 1: Create a current employer relationship with Org A + $params = [ + 'relationship_type_id' => '5', + 'contact_id_a' => $this->_cId_a, + 'contact_id_b' => $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, + ]; + $this->callAPISuccess('Relationship', 'create', $params); + + // ensure that the employer_id field is sucessfully set + $this->assertEquals( + $this->_cId_b, + $this->callAPISuccess('Contact', 'getvalue', [ + 'id' => $this->_cId_a, + 'return' => 'current_employer_id', + ])); + // Step 2: Create a PAST employer relationship with Org B, and setting is_current_employer = FALSE + $orgID2 = $this->organizationCreate(); + $params = [ + 'relationship_type_id' => '5', + 'contact_id_a' => $this->_cId_a, + 'contact_id_b' => $orgID2, + 'start_date' => '2008-12-20', + 'end_date' => '2008-12-22', + 'is_active' => 1, + 'is_current_employer' => 0, + 'is_permission_a_b' => 0, + 'is_permission_b_a' => 0, + ]; + + $relationshipB = $this->callAPISuccess('Relationship', 'create', $params); + // ensure that the employer_id field is still set to contact b + $this->assertEquals( + $this->_cId_b, + $this->callAPISuccess('Contact', 'getvalue', [ + 'id' => $this->_cId_a, + 'return' => 'current_employer_id', + ])); + + // Step 3: Call schedule job disable_expired_relationships + CRM_Contact_BAO_Relationship::disableExpiredRelationships(); + + // Result A: Ensure that employer field is not cleared + $this->assertEquals( + $this->_cId_b, + $this->callAPISuccess('Contact', 'getvalue', [ + 'id' => $this->_cId_a, + 'return' => 'current_employer_id', + ])); + // Result B: Ensure that the previous employer relationship with Org B is successfully disabled + $this->assertEquals( + FALSE, + (bool) $this->callAPISuccess('Relationship', 'getvalue', [ + 'id' => $relationshipB['id'], + 'return' => 'is_active', + ])); + } + } -- 2.25.1