dev/core#4156 Fix failure to update organization_name on employees during merge
authorEileen McNaughton <emcnaughton@wikimedia.org>
Fri, 10 Mar 2023 00:13:01 +0000 (13:13 +1300)
committerEileen McNaughton <emcnaughton@wikimedia.org>
Fri, 10 Mar 2023 01:37:12 +0000 (14:37 +1300)
CRM/Dedupe/Merger.php
tests/phpunit/CRM/Dedupe/MergerTest.php

index 7fdb55f5850588f46625410fb085895933b2fda0..b09c0c1bad5bb00db3bf2bdea8cb50d6d74a6912 100644 (file)
@@ -9,6 +9,7 @@
  +--------------------------------------------------------------------+
  */
 
+use Civi\Api4\Contact;
 use Civi\Api4\CustomGroup;
 
 /**
@@ -685,7 +686,18 @@ INNER JOIN  civicrm_membership membership2 ON membership1.membership_type_id = m
     // This parameter causes blank fields to be be emptied out.
     // We can probably remove.
     $params['updateBlankLocInfo'] = TRUE;
+    if (empty($params['contact_type']) || ($params['contact_type'] === 'Organization' && empty($params['organization_name']))) {
+      // Ensuring this is set addresses https://lab.civicrm.org/dev/core/-/issues/4156
+      // but not that RM_Dedupe_MergerTest::testMergeWithEmployer covers this scenario
+      // so refactoring of this is safe.
+      $contact = Contact::get(FALSE)->addWhere('id', '=', $contactID)->addSelect('organization_name', 'contact_type')->execute()->first();
+      $params['contact_type'] = $contact['contact_type'];
+      if (empty($params['organization_name']) && $params['contact_type'] === 'Organization') {
+        $params['organization_name'] = $contact['organization_name'];
+      }
+    }
     $data = self::formatProfileContactParams($params, $contactID);
+
     CRM_Contact_BAO_Contact::create($data);
   }
 
@@ -707,13 +719,12 @@ INNER JOIN  civicrm_membership membership2 ON membership1.membership_type_id = m
     int $contactID
   ) {
 
-    $data = $contactDetails = [];
+    $data = ['contact_type' => $params['contact_type']];
 
     // get the contact details (hier)
     $details = CRM_Contact_BAO_Contact::getHierContactDetails($contactID, []);
 
     $contactDetails = $details[$contactID];
-    $data['contact_type'] = $contactDetails['contact_type'] ?? NULL;
     $data['contact_sub_type'] = $contactDetails['contact_sub_type'] ?? NULL;
 
     //fix contact sub type CRM-5125
@@ -993,10 +1004,6 @@ INNER JOIN  civicrm_membership membership2 ON membership1.membership_type_id = m
       }
     }
 
-    if (!isset($data['contact_type'])) {
-      $data['contact_type'] = 'Individual';
-    }
-
     return $data;
   }
 
index 9aad35e896b897aa1ca40f76a8d0ccc7637713b7..c821f75d183d362136efc3750f5a82645a3ae4b8 100644 (file)
@@ -1,5 +1,7 @@
 <?php
 
+use Civi\Api4\Contact;
+
 /**
  * Class CRM_Dedupe_DedupeMergerTest
  *
@@ -812,7 +814,7 @@ class CRM_Dedupe_MergerTest extends CiviUnitTestCase {
     // update the text custom field for duplicate contact 1 with value 'def'
     $this->callAPISuccess('Contact', 'create', [
       'id' => $duplicateContactID1,
-      "{$customFieldName}" => 'def',
+      $customFieldName => 'def',
     ]);
     $this->assertCustomFieldValue($duplicateContactID1, 'def', $customFieldName);
 
@@ -1453,7 +1455,28 @@ WHERE
     CRM_Core_DAO_AllCoreTables::flush();
     $contact1 = $this->individualCreate();
     $contact2 = $this->individualCreate(['api.Im.create' => ['name' => 'chat_handle']]);
-    $this->callAPISuccess('Contact', 'merge', ['to_keep_id' => $contact1, 'to_remove_id' => $contact2]);
+    $this->callAPISuccess('Contact', 'merge', [
+      'to_keep_id' => $contact1,
+      'to_remove_id' => $contact2,
+    ]);
+  }
+
+  /**
+   * Test that organization name is updated for employees of merged organizations..
+   *
+   * @throws \CRM_Core_Exception
+   */
+  public function testMergeWithEmployer(): void {
+    $organizationToRemoveID = $this->organizationCreate(['organization_name' => 'remove']);
+    $organizationToKeepID = $this->organizationCreate(['organization_name' => 'keep']);
+    $individualID = $this->createContactWithEmployerRelationship([
+      'contact_id_b' => $organizationToRemoveID,
+    ]);
+    $employerName = Contact::get()->addSelect('organization_name')->addWhere('id', '=', $individualID)->execute()->first()['organization_name'];
+    $this->assertEquals('remove', $employerName);
+    $this->callAPISuccess('Contact', 'merge', ['to_keep_id' => $organizationToKeepID, 'to_remove_id' => $organizationToRemoveID, 'mode' => 'aggressive']);
+    $employerName = Contact::get()->addSelect('organization_name')->addWhere('id', '=', $individualID)->execute()->first()['organization_name'];
+    $this->assertEquals('keep', $employerName);
   }
 
   /**