)))
) {
- if ($internalCid = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', $params['external_identifier'], 'id', 'external_identifier', TRUE)) {
+ $extIDResult = civicrm_api3('Contact', 'get', array(
+ 'external_identifier' => $params['external_identifier'],
+ 'showAll' => 'all',
+ 'return' => array('id', 'contact_is_deleted'),
+ ));
+ if (isset($extIDResult['id'])) {
+ // record with matching external identifier does exist.
+ $internalCid = $extIDResult['id'];
if ($internalCid != CRM_Utils_Array::value('id', $params)) {
- $errorMessage = ts('External ID already exists in Database.');
- array_unshift($values, $errorMessage);
- $importRecordParams = array(
- $statusFieldName => 'ERROR',
- "${statusFieldName}Msg" => $errorMessage,
- );
- $this->updateImportRecord($values[count($values) - 1], $importRecordParams);
- return CRM_Import_Parser::DUPLICATE;
+ if ($extIDResult['values'][$internalCid]['contact_is_deleted'] == 1) {
+ // And it is deleted. What to do? If we skip it, they user
+ // will be under the impression that the record exists in
+ // the database, yet they won't be able to find it. If we
+ // don't skip it, the database will try to insert a new record
+ // with an external_identifier that is non-unique. So...
+ // we will update this contact to remove the external_identifier
+ // and let a new record be created.
+ $update_params = array('id' => $internalCid, 'external_identifier' => '');
+ civicrm_api3('Contact', 'create', $update_params);
+ }
+ else {
+ $errorMessage = ts('External ID already exists in Database.');
+ array_unshift($values, $errorMessage);
+ $importRecordParams = array(
+ $statusFieldName => 'ERROR',
+ "${statusFieldName}Msg" => $errorMessage,
+ );
+ $this->updateImportRecord($values[count($values) - 1], $importRecordParams);
+ return CRM_Import_Parser::DUPLICATE;
+ }
}
}
}
$extIDMatch = NULL;
if (!empty($params['external_identifier'])) {
+ // Check for any match on external id, deleted or otherwise.
$extIDContact = civicrm_api3('Contact', 'get', array(
'external_identifier' => $params['external_identifier'],
- 'return' => 'id',
+ 'showAll' => 'all',
+ 'return' => array('id', 'contact_is_deleted'),
));
if (isset($extIDContact['id'])) {
$extIDMatch = $extIDContact['id'];
+
+ if ($extIDContact['values'][$extIDMatch]['contact_is_deleted'] == 1) {
+ // If the contact is deleted, update external identifier to be blank
+ // to avoid key error from MySQL.
+ $params = array('id' => $extIDMatch, 'external_identifier' => '');
+ civicrm_api3('Contact', 'create', $params);
+
+ // And now it is no longer a match.
+ $extIDMatch = NULL;
+ }
}
}
$checkParams = array('check_permissions' => FALSE, 'match' => $params);
parent::setUp();
}
+ /**
+ * Test that import parser will not fail when same external_identifier found of deleted contact.
+ *
+ * @throws \Exception
+ */
+ public function testImportParserWtihDeletedContactExternalIdentifier() {
+ $contactId = $this->individualCreate(array(
+ "external_identifier" => "ext-1",
+ ));
+ CRM_Contact_BAO_Contact::deleteContact($contactId);
+ list($originalValues, $result) = $this->setUpBaseContact(array(
+ 'external_identifier' => 'ext-1',
+ ));
+ $originalValues['nick_name'] = 'Old Bill';
+ $this->runImport($originalValues, CRM_Import_Parser::DUPLICATE_UPDATE, CRM_Import_Parser::VALID);
+ $originalValues['id'] = $result['id'];
+ $this->assertEquals('ext-1', $this->callAPISuccessGetValue('Contact', array('id' => $result['id'], 'return' => 'external_identifier')));
+ $this->callAPISuccessGetSingle('Contact', $originalValues);
+ }
+
/**
* Test import parser will update based on a rule match.
*
$this->callAPISuccessGetSingle('Contact', $contactValues);
}
- /**
- * Test the determination of whether a custom field is valid.
- */
+ /**
+ * Test the determination of whether a custom field is valid.
+ */
public function testCustomFieldValidation() {
$errorMessage = array();
$customGroup = $this->customGroupCreate(array(