From e3fc56102cef4470105995c673c08eb82e556e4f Mon Sep 17 00:00:00 2001 From: Eileen McNaughton Date: Sun, 19 Jun 2022 11:30:33 +1200 Subject: [PATCH] dev/core#3667 fix failure to match existing contacts in skip mode As reported by Andy C and verified by me 5.48 does create new related contacts in skip mode --- CRM/Contact/Import/Parser/Contact.php | 2 +- .../Form/data/individual_related_create.csv | 3 + .../CRM/Contact/Import/Parser/ContactTest.php | 56 +++++++++++-------- .../phpunit/CRMTraits/Import/ParserTrait.php | 7 +++ 4 files changed, 43 insertions(+), 25 deletions(-) create mode 100644 tests/phpunit/CRM/Contact/Import/Form/data/individual_related_create.csv diff --git a/CRM/Contact/Import/Parser/Contact.php b/CRM/Contact/Import/Parser/Contact.php index 35260a50e9..a64158677a 100644 --- a/CRM/Contact/Import/Parser/Contact.php +++ b/CRM/Contact/Import/Parser/Contact.php @@ -1742,7 +1742,7 @@ class CRM_Contact_Import_Parser_Contact extends CRM_Import_Parser { unset($params['relationship']); } $id = $this->getPossibleContactMatch($params, $extIDMatch, $this->getSubmittedValue('dedupe_rule_id') ?: NULL); - if ($id && $this->isSkipDuplicates()) { + if ($id && $isMainContact && $this->isSkipDuplicates()) { throw new CRM_Core_Exception(ts('Contact matched by dedupe rule already exists in the database.'), CRM_Import_Parser::DUPLICATE); } return $id; diff --git a/tests/phpunit/CRM/Contact/Import/Form/data/individual_related_create.csv b/tests/phpunit/CRM/Contact/Import/Form/data/individual_related_create.csv new file mode 100644 index 0000000000..4ae1fb27dd --- /dev/null +++ b/tests/phpunit/CRM/Contact/Import/Form/data/individual_related_create.csv @@ -0,0 +1,3 @@ +First Name,Last Name,Dad first name,Dad Last name,Dad email +Bob,Smith,William,The Kid,billy-the-kid@example.com +Sarah,Smith,Bill,The Grandkid,Billy-the-grand-kid@example.com diff --git a/tests/phpunit/CRM/Contact/Import/Parser/ContactTest.php b/tests/phpunit/CRM/Contact/Import/Parser/ContactTest.php index 01150919d3..161da0aec7 100644 --- a/tests/phpunit/CRM/Contact/Import/Parser/ContactTest.php +++ b/tests/phpunit/CRM/Contact/Import/Parser/ContactTest.php @@ -24,6 +24,7 @@ use Civi\Api4\IM; use Civi\Api4\LocationType; use Civi\Api4\OpenID; use Civi\Api4\Phone; +use Civi\Api4\Relationship; use Civi\Api4\RelationshipType; use Civi\Api4\UserJob; use Civi\Api4\Website; @@ -36,6 +37,7 @@ use Civi\Api4\Website; */ class CRM_Contact_Import_Parser_ContactTest extends CiviUnitTestCase { use CRMTraits_Custom_CustomDataTrait; + use CRMTraits_Import_ParserTrait; /** * Main entity for the class. @@ -51,13 +53,6 @@ class CRM_Contact_Import_Parser_ContactTest extends CiviUnitTestCase { */ private $relationships = []; - /** - * User Job ID. - * - * @var int - */ - private $userJobID; - /** * Tear down after test. */ @@ -315,6 +310,32 @@ class CRM_Contact_Import_Parser_ContactTest extends CiviUnitTestCase { $this->assertEquals(['Parent'], $contact['contact_sub_type']); } + /** + * Test updating an existing contact with external_identifier match but subtype mismatch. + * + * The subtype is not updated, as there is conflicting contact data. + */ + public function testImportParserUpdateWithExistingRelatedMatch(): void { + $contactID = $this->individualCreate([ + 'external_identifier' => 'billy', + 'first_name' => 'William', + 'last_name' => 'The Kid', + 'email' => 'billy-the-kid@example.com', + 'contact_sub_type' => 'Parent', + ]); + $this->addChild($contactID); + $this->importCSV('individual_related_create.csv', [ + ['first_name'], ['last_name'], [$this->relationships['Dad to'], 'first_name'], [$this->relationships['Dad to'], 'last_name'], [$this->relationships['Dad to'], 'email'], + ], [ + 'onDuplicate' => CRM_Import_Parser::DUPLICATE_SKIP, + ]); + $dataSource = $this->getDataSource(); + $row = $dataSource->getRow(); + $this->assertEquals('IMPORTED', $row['_status']); + $row = $dataSource->getRow(); + $this->assertEquals('IMPORTED', $row['_status']); + } + /** * Test updating an existing contact with external_identifier match but subtype mismatch. * @@ -1219,7 +1240,7 @@ class CRM_Contact_Import_Parser_ContactTest extends CiviUnitTestCase { $this->assertEquals(1640, $contact['address'][0]['state_province_id']); } $this->assertCount(2, $contacts); - $dataSource = new CRM_Import_DataSource_CSV($this->userJobID); + $dataSource = $this->getDataSource(); $dataSource->setOffset(4); $dataSource->setLimit(1); $row = $dataSource->getRow(); @@ -1679,7 +1700,7 @@ class CRM_Contact_Import_Parser_ContactTest extends CiviUnitTestCase { $parser->init(); $result = $parser->import($values); - $dataSource = new CRM_Import_DataSource_CSV($this->userJobID); + $dataSource = $this->getDataSource(); if ($result === FALSE && $expectedResult !== FALSE) { // Import is moving away from returning a status - this is a better way to check $this->assertGreaterThan(0, $dataSource->getRowCount([$expectedResult])); @@ -1721,7 +1742,6 @@ class CRM_Contact_Import_Parser_ContactTest extends CiviUnitTestCase { * @param int $contactID * * @throws \API_Exception - * @throws \Civi\API\Exception\UnauthorizedException */ protected function addChild(int $contactID): void { $relatedContactID = $this->individualCreate(); @@ -1732,11 +1752,12 @@ class CRM_Contact_Import_Parser_ContactTest extends CiviUnitTestCase { 'contact_type_b' => 'Individual', 'contact_sub_type_a' => 'Parent', ])->execute()->first()['id']; - \Civi\Api4\Relationship::create()->setValues([ + Relationship::create()->setValues([ 'relationship_type_id' => $relationshipTypeID, 'contact_id_a' => $contactID, 'contact_id_b' => $relatedContactID, ])->execute(); + $this->relationships['Dad to'] = $relationshipTypeID . '_a_b'; } /** @@ -1826,19 +1847,6 @@ class CRM_Contact_Import_Parser_ContactTest extends CiviUnitTestCase { return $mapper; } - /** - * @param array $fields Array of fields to be imported - * @param array $allfields Array of all fields which can be part of import - */ - private function mapRelationshipFields(&$fields, $allfields) { - foreach ($allfields as $key => $fieldtocheck) { - $elementIndex = array_search($fieldtocheck->_title, $fields); - if ($elementIndex !== FALSE) { - $fields[$elementIndex] = $key; - } - } - } - /** * Test mapping fields within the Parser class. * diff --git a/tests/phpunit/CRMTraits/Import/ParserTrait.php b/tests/phpunit/CRMTraits/Import/ParserTrait.php index 7035b4a62b..722ac2abde 100644 --- a/tests/phpunit/CRMTraits/Import/ParserTrait.php +++ b/tests/phpunit/CRMTraits/Import/ParserTrait.php @@ -94,4 +94,11 @@ trait CRMTraits_Import_ParserTrait { return $mapper; } + /** + * @return \CRM_Import_DataSource + */ + protected function getDataSource(): CRM_Import_DataSource { + return new CRM_Import_DataSource_CSV($this->userJobID); + } + } -- 2.25.1