From a2f1966f511913bcc1bcdf1ee633ef0830c32299 Mon Sep 17 00:00:00 2001 From: Noah Miller Date: Fri, 5 Aug 2022 14:12:39 -0700 Subject: [PATCH] fix contribution/membership/participant import matching on external id or contact id --- CRM/Contribute/Import/Parser/Contribution.php | 4 +- CRM/Event/Import/Parser/Participant.php | 2 +- CRM/Member/Import/Parser/Membership.php | 2 +- .../Import/Parser/ContributionTest.php | 43 +++++++++++++++++++ .../data/contributions_match_external_id.csv | 3 ++ 5 files changed, 50 insertions(+), 4 deletions(-) create mode 100644 tests/phpunit/CRM/Contribute/Import/Parser/data/contributions_match_external_id.csv diff --git a/CRM/Contribute/Import/Parser/Contribution.php b/CRM/Contribute/Import/Parser/Contribution.php index e244fe0fc36d..9c4a4bbd249d 100644 --- a/CRM/Contribute/Import/Parser/Contribution.php +++ b/CRM/Contribute/Import/Parser/Contribution.php @@ -417,7 +417,7 @@ public function import($values): void { $error = $this->checkContactDuplicate($paramValues); if (CRM_Core_Error::isAPIError($error, CRM_Core_ERROR::DUPLICATE_CONTACT)) { - $matchedIDs = explode(',', $error['error_message']['params'][0]); + $matchedIDs = (array) $error['error_message']['params']; if (count($matchedIDs) > 1) { throw new CRM_Core_Exception('Multiple matching contact records detected for this row. The contribution was not imported', CRM_Import_Parser::ERROR); } @@ -776,7 +776,7 @@ private function deprecatedFormatParams($params, &$values, $create = FALSE) { $error = $this->checkContactDuplicate($params); if (isset($error['error_message']['params'][0])) { - $matchedIDs = explode(',', $error['error_message']['params'][0]); + $matchedIDs = (array) $error['error_message']['params']; // check if only one contact is found if (count($matchedIDs) > 1) { diff --git a/CRM/Event/Import/Parser/Participant.php b/CRM/Event/Import/Parser/Participant.php index 8afe963e82de..de5f53ef5205 100644 --- a/CRM/Event/Import/Parser/Participant.php +++ b/CRM/Event/Import/Parser/Participant.php @@ -236,7 +236,7 @@ public function import(&$values) { $error = $this->checkContactDuplicate($formatValues); if (CRM_Core_Error::isAPIError($error, CRM_Core_ERROR::DUPLICATE_CONTACT)) { - $matchedIDs = explode(',', $error['error_message']['params'][0]); + $matchedIDs = (array) $error['error_message']['params']; if (count($matchedIDs) >= 1) { foreach ($matchedIDs as $contactId) { $formatted['contact_id'] = $contactId; diff --git a/CRM/Member/Import/Parser/Membership.php b/CRM/Member/Import/Parser/Membership.php index 45db615fcdf5..5c6dbc9b22ee 100644 --- a/CRM/Member/Import/Parser/Membership.php +++ b/CRM/Member/Import/Parser/Membership.php @@ -215,7 +215,7 @@ public function import($values) { $error = $this->checkContactDuplicate($formatValues); if (CRM_Core_Error::isAPIError($error, CRM_Core_ERROR::DUPLICATE_CONTACT)) { - $matchedIDs = explode(',', $error['error_message']['params'][0]); + $matchedIDs = (array) $error['error_message']['params']; if (count($matchedIDs) > 1) { throw new CRM_Core_Exception('Multiple matching contact records detected for this row. The membership was not imported', CRM_Import_Parser::ERROR); } diff --git a/tests/phpunit/CRM/Contribute/Import/Parser/ContributionTest.php b/tests/phpunit/CRM/Contribute/Import/Parser/ContributionTest.php index 0a94114c5b40..e1463439fabd 100644 --- a/tests/phpunit/CRM/Contribute/Import/Parser/ContributionTest.php +++ b/tests/phpunit/CRM/Contribute/Import/Parser/ContributionTest.php @@ -277,6 +277,49 @@ public function testImport() :void { $this->assertEquals('No matching Contact found for (mum@example.com )', $row['_status_message']); } + public function testImportWithMatchByExternalIdentifier() :void { + CRM_Core_DAO::executeQuery("ALTER TABLE civicrm_contact AUTO_INCREMENT = 1000000"); + + $contactRubyParams = [ + 'first_name' => 'Ruby', + 'external_identifier' => 'ruby', + 'contact_type' => 'Individual', + ]; + $contactSapphireParams = [ + 'first_name' => 'Sapphire', + 'external_identifier' => 'sapphire', + 'contact_type' => 'Individual', + ]; + $contactRubyId = $this->individualCreate($contactRubyParams); + $contactSapphireId = $this->individualCreate($contactSapphireParams); + + // make sure we're testing dev/core#3784 + self::assertEquals(1, substr($contactRubyId, 0, 1)); + self::assertEquals(1, substr($contactSapphireId, 0, 1)); + + $mapping = [ + ['name' => 'external_identifier'], + ['name' => 'total_amount'], + ['name' => 'receive_date'], + ['name' => 'financial_type_id'], + ]; + $this->importCSV('contributions_match_external_id.csv', $mapping); + + $contributionsOfRuby = Contribution::get() + ->addWhere('contact_id', '=', $contactRubyId)->execute(); + $contributionsOfSapphire = Contribution::get() + ->addWhere('contact_id', '=', $contactSapphireId)->execute(); + + $this->assertCount(1, $contributionsOfRuby, 'Wrong number of contributions imported'); + $this->assertCount(1, $contributionsOfSapphire, 'Wrong number of contributions imported'); + $this->assertEquals(22222, $contributionsOfRuby->first()['total_amount']); + $this->assertEquals(5, $contributionsOfSapphire->first()['total_amount']); + + $dataSource = new CRM_Import_DataSource_CSV($this->userJobID); + $this->assertEquals(0, $dataSource->getRowCount([CRM_Import_Parser::ERROR])); + $this->assertEquals(2, $dataSource->getRowCount([CRM_Import_Parser::VALID])); + } + /** * Run the import parser. * diff --git a/tests/phpunit/CRM/Contribute/Import/Parser/data/contributions_match_external_id.csv b/tests/phpunit/CRM/Contribute/Import/Parser/data/contributions_match_external_id.csv new file mode 100644 index 000000000000..d70db3392532 --- /dev/null +++ b/tests/phpunit/CRM/Contribute/Import/Parser/data/contributions_match_external_id.csv @@ -0,0 +1,3 @@ +External Identifier,Total Amount,Receive Date,Financial Type +sapphire,5,2005-05-05,Donation +ruby,22222,2022-02-22,Donation