Skip to content

Commit

Permalink
Merge pull request #18555 from eileenmcnaughton/del_primary
Browse files Browse the repository at this point in the history
dev/core#2047 Fix merge code so that deleted contacts are not left without a primary address
  • Loading branch information
monishdeb authored Oct 12, 2020
2 parents aadda61 + 2203317 commit 19cd186
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 9 deletions.
73 changes: 73 additions & 0 deletions CRM/Dedupe/MergeHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*
Expand Down
1 change: 1 addition & 0 deletions CRM/Dedupe/Merger.php
Original file line number Diff line number Diff line change
Expand Up @@ -1861,6 +1861,7 @@ public static function mergeLocations($mergeHandler) {
}
$blocksDAO[$name]['update'][$otherBlockDAO->id] = $otherBlockDAO;
}
$blocksDAO[$name]['update'] += $mergeHandler->getBlocksToUpdateForDeletedContact($name);
}
}

Expand Down
9 changes: 0 additions & 9 deletions tests/phpunit/api/v3/JobTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*/
Expand Down

0 comments on commit 19cd186

Please sign in to comment.