From 00c49d22538cc08099695b1db93e7ccc8070c9b2 Mon Sep 17 00:00:00 2001 From: Matthew Wire Date: Wed, 22 Feb 2023 20:53:42 +0000 Subject: [PATCH] Allow to disable an invalid relationship (eg. contact subtype was changed so no longer valid) --- CRM/Contact/BAO/Relationship.php | 10 ++-- .../CRM/Contact/BAO/RelationshipTest.php | 54 +++++++++++++++++++ 2 files changed, 60 insertions(+), 4 deletions(-) diff --git a/CRM/Contact/BAO/Relationship.php b/CRM/Contact/BAO/Relationship.php index f4c97866f8..7419108a1e 100644 --- a/CRM/Contact/BAO/Relationship.php +++ b/CRM/Contact/BAO/Relationship.php @@ -49,14 +49,16 @@ class CRM_Contact_BAO_Relationship extends CRM_Contact_DAO_Relationship implemen public static function create(&$params) { $extendedParams = self::loadExistingRelationshipDetails($params); - // When id is specified we always wan't to update, so we don't need to - // check for duplicate relations. + // When id is specified we always want to update, so we don't need to check for duplicate relations. if (!isset($params['id']) && self::checkDuplicateRelationship($extendedParams, (int) $extendedParams['contact_id_a'], (int) $extendedParams['contact_id_b'], CRM_Utils_Array::value('id', $extendedParams, 0))) { throw new CRM_Core_Exception('Duplicate Relationship'); } $params = $extendedParams; - if (!CRM_Contact_BAO_Relationship::checkRelationshipType($params['contact_id_a'], $params['contact_id_b'], - $params['relationship_type_id'])) { + // Check if this is a "simple" disable relationship. If it is don't check the relationshipType + if (!empty($params['id']) && array_key_exists('is_active', $params) && empty($params['is_active'])) { + $disableRelationship = TRUE; + } + if (empty($disableRelationship) && !CRM_Contact_BAO_Relationship::checkRelationshipType($params['contact_id_a'], $params['contact_id_b'], $params['relationship_type_id'])) { throw new CRM_Core_Exception('Invalid Relationship'); } $relationship = self::add($params); diff --git a/tests/phpunit/CRM/Contact/BAO/RelationshipTest.php b/tests/phpunit/CRM/Contact/BAO/RelationshipTest.php index fd8329c4a2..b8b03511f0 100644 --- a/tests/phpunit/CRM/Contact/BAO/RelationshipTest.php +++ b/tests/phpunit/CRM/Contact/BAO/RelationshipTest.php @@ -9,6 +9,8 @@ +--------------------------------------------------------------------+ */ +use Civi\Api4\Relationship; + /** * Test class for CRM_Contact_BAO_Relationship * @@ -320,4 +322,56 @@ class CRM_Contact_BAO_RelationshipTest extends CiviUnitTestCase { $this->assertEquals($relationshipObj->end_date, $today); } + /** + * This tests that you can disable an invalid relationship. + * It is quite easy to end up with invalid relationships if you change contact subtypes. + * + * @return void + * @throws \CRM_Core_Exception + */ + public function testDisableInvalidRelationship() { + $individualStaff = civicrm_api3('Contact', 'create', [ + 'display_name' => 'Individual A', + 'contact_type' => 'Individual', + 'contact_sub_type' => 'Staff', + ]); + $individualStudent = civicrm_api3('Contact', 'create', [ + 'display_name' => 'Individual B', + 'contact_type' => 'Individual', + 'contact_sub_type' => 'Student', + ]); + + $personToOrgType = 'A_B_relationship'; + $orgToPersonType = 'B_A_relationship'; + + $relationshipTypeID = civicrm_api3('RelationshipType', 'create', [ + 'name_a_b' => $personToOrgType, + 'name_b_a' => $orgToPersonType, + 'contact_type_a' => 'Individual', + 'contact_type_b' => 'Individual', + 'contact_sub_type_a' => 'Staff', + 'contact_sub_type_b' => 'Student', + ])['id']; + + // Create a relationship between the two individuals with sub types + $relationship = Relationship::create(FALSE) + ->addValue('contact_id_a', $individualStaff['id']) + ->addValue('contact_id_b', $individualStudent['id']) + ->addValue('relationship_type_id', $relationshipTypeID) + ->execute() + ->first(); + + // This makes the relationship invalid because one contact sub type is no longer matching the required one + civicrm_api3('Contact', 'create', [ + 'id' => $individualStaff['id'], + 'contact_sub_type' => 'Parent', + ]); + + // Check that we can disable the invalid relationship + Relationship::update(FALSE) + ->addValue('is_active', FALSE) + ->addWhere('id', '=', $relationship['id']) + ->execute(); + } + } -- 2.25.1