diff --git a/CRM/Dedupe/MergeHandler.php b/CRM/Dedupe/MergeHandler.php index 654e87c20930..cb0d64ebacdc 100644 --- a/CRM/Dedupe/MergeHandler.php +++ b/CRM/Dedupe/MergeHandler.php @@ -213,6 +213,79 @@ public function copyDataToNewBlockDAO($otherBlockId, $name, $blkCount) { return $otherBlockDAO; } + /** + * Get blocks, if any, to update for the deleted contact. + * + * If the deleted contact no longer has a primary address but still has + * one or more blocks we want to ensure the remaining block is updated + * to have is_primary = 1 in case the contact is ever undeleted. + * + * @param string $entity + * + * @return array + * @throws \CRM_Core_Exception + */ + public function getBlocksToUpdateForDeletedContact($entity) { + $movedBlocks = $this->getLocationBlocksToMerge()[$entity]; + $deletedContactsBlocks = $this->getLocationBlocksForContactToRemove()[$entity]; + $unMovedBlocks = array_values(array_diff_key($deletedContactsBlocks, $movedBlocks)); + if (empty($unMovedBlocks) || empty($movedBlocks)) { + return []; + } + foreach (array_keys($movedBlocks) as $index) { + if ($deletedContactsBlocks[$index]['is_primary']) { + // We have moved the primary - change any other block to be primary. + $newPrimaryBlock = $this->getDAOForLocationEntity($entity); + $newPrimaryBlock->id = $unMovedBlocks[0]['id']; + $newPrimaryBlock->is_primary = 1; + return [$newPrimaryBlock->id => $newPrimaryBlock]; + } + } + return []; + } + + /** + * Get the details of the blocks to be transferred over for the given entity. + * + * @param string $entity + * + * @return array + */ + protected function getLocationBlocksToMoveForEntity($entity) { + $movedBlocks = $this->getLocationBlocksToMerge()[$entity]; + $blockDetails = $this->getLocationBlocksForContactToRemove()[$entity]; + return array_intersect_key($blockDetails, $movedBlocks); + } + + /** + * Does the contact to keep have location blocks for the given entity. + * + * @param string $entity + * + * @return bool + */ + public function contactToKeepHasLocationBlocksForEntity($entity) { + return !empty($this->getLocationBlocksForContactToKeep()[$entity]); + } + + /** + * Get the location blocks for the contact to be kept. + * + * @return array + */ + public function getLocationBlocksForContactToKeep() { + return $this->getMigrationInfo()['main_details']['location_blocks']; + } + + /** + * Get the location blocks for the contact to be deleted. + * + * @return array + */ + public function getLocationBlocksForContactToRemove() { + return $this->getMigrationInfo()['other_details']['location_blocks']; + } + /** * Get the DAO object appropriate to the location entity. * diff --git a/CRM/Dedupe/Merger.php b/CRM/Dedupe/Merger.php index b3898072216a..7fe56cdb923e 100644 --- a/CRM/Dedupe/Merger.php +++ b/CRM/Dedupe/Merger.php @@ -1861,6 +1861,7 @@ public static function mergeLocations($mergeHandler) { } $blocksDAO[$name]['update'][$otherBlockDAO->id] = $otherBlockDAO; } + $blocksDAO[$name]['update'] += $mergeHandler->getBlocksToUpdateForDeletedContact($name); } } diff --git a/tests/phpunit/api/v3/JobTest.php b/tests/phpunit/api/v3/JobTest.php index 492b324c4933..5bc0ccb8fddb 100644 --- a/tests/phpunit/api/v3/JobTest.php +++ b/tests/phpunit/api/v3/JobTest.php @@ -44,15 +44,6 @@ class api_v3_JobTest extends CiviUnitTestCase { */ private $report_instance; - /** - * Should location types be checked to ensure primary addresses are correctly assigned after each test. - * - * We cannot enable this until https://github.com/civicrm/civicrm-core/pull/18555 is merged - * - * @var bool - */ - protected $isLocationTypesOnPostAssert = FALSE; - /** * Set up for tests. */