Skip to content

Commit

Permalink
Validate subtype change
Browse files Browse the repository at this point in the history
  • Loading branch information
eileenmcnaughton committed May 18, 2022
1 parent adbb007 commit c11e71b
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 15 deletions.
24 changes: 11 additions & 13 deletions CRM/Contact/Import/Parser/Contact.php
Original file line number Diff line number Diff line change
Expand Up @@ -300,28 +300,26 @@ public function import($onDuplicate, &$values) {

$params = $this->getMappedRow($values);
$formatted = [
'contact_type' => $this->_contactType,
'contact_type' => $this->getContactType(),
];

$contactFields = CRM_Contact_DAO_Contact::import();

if (!empty($this->_contactSubType)) {
$params['contact_sub_type'] = $this->_contactSubType;
}
$params['contact_sub_type'] = $this->getContactSubType() ?: ($params['contact_sub_type'] ?? NULL);

if ($subType = CRM_Utils_Array::value('contact_sub_type', $params)) {
if (CRM_Contact_BAO_ContactType::isExtendsContactType($subType, $this->_contactType, FALSE, 'label')) {
$subTypes = CRM_Contact_BAO_ContactType::subTypePairs($this->_contactType, FALSE, NULL);
$params['contact_sub_type'] = array_search($subType, $subTypes);
}
elseif (!CRM_Contact_BAO_ContactType::isExtendsContactType($subType, $this->_contactType)) {
$message = "Mismatched or Invalid Contact Subtype.";
array_unshift($values, $message);
return CRM_Import_Parser::NO_MATCH;
if ($params['contact_sub_type']) {
if (CRM_Contact_BAO_ContactType::isExtendsContactType($params['contact_sub_type'], $this->getContactType(), FALSE, 'label')) {
// I think this bit is switching a passed in label to
// a name.
$subTypes = CRM_Contact_BAO_ContactType::subTypePairs($this->getContactType(), FALSE, NULL);
$params['contact_sub_type'] = array_search($params['contact_sub_type'], $subTypes);
}
}

try {
if ($params['contact_sub_type'] && !CRM_Contact_BAO_ContactType::isExtendsContactType($params['contact_sub_type'], $this->getContactType())) {
throw new CRM_Core_Exception('Mismatched or Invalid Contact Subtype.' . $params['id'], CRM_Import_Parser::NO_MATCH);
}
$params['id'] = $formatted['id'] = $this->lookupContactID($params, ($this->isSkipDuplicates() || $this->isIgnoreDuplicates()));
}
catch (CRM_Core_Exception $e) {
Expand Down
51 changes: 49 additions & 2 deletions tests/phpunit/CRM/Contact/Import/Parser/ContactTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
* File for the CRM_Contact_Imports_Parser_ContactTest class.
*/

use Civi\Api4\RelationshipType;
use Civi\Api4\UserJob;

/**
Expand All @@ -36,7 +37,8 @@ class CRM_Contact_Import_Parser_ContactTest extends CiviUnitTestCase {
* Tear down after test.
*/
public function tearDown(): void {
$this->quickCleanup(['civicrm_address', 'civicrm_phone', 'civicrm_email', 'civicrm_user_job'], TRUE);
$this->quickCleanup(['civicrm_address', 'civicrm_phone', 'civicrm_email', 'civicrm_user_job', 'civicrm_relationship'], TRUE);
RelationshipType::delete()->addWhere('name_a_b', '=', 'Dad to')->execute();
parent::tearDown();
}

Expand Down Expand Up @@ -261,9 +263,11 @@ public function testImportParserWithUpdateWithExternalIdentifier(): void {
/**
* Test updating an existing contact with external_identifier match but subtype mismatch.
*
* The subtype is updated, as there is no conflicting contact data.
*
* @throws \Exception
*/
public function testImportParserWithUpdateWithExternalIdentifierSubtypeMismatch(): void {
public function testImportParserWithUpdateWithExternalIdentifierSubtypeChange(): void {
$contactID = $this->individualCreate(['external_identifier' => 'billy', 'first_name' => 'William', 'contact_sub_type' => 'Parent']);
$this->runImport([
'external_identifier' => 'billy',
Expand All @@ -277,6 +281,27 @@ public function testImportParserWithUpdateWithExternalIdentifierSubtypeMismatch(
$this->assertEquals(['Staff'], $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.
*
* @throws \Exception
*/
public function testImportParserUpdateWithExternalIdentifierSubtypeChangeFail(): void {
$contactID = $this->individualCreate(['external_identifier' => 'billy', 'first_name' => 'William', 'contact_sub_type' => 'Parent']);
$this->addChild($contactID);

$this->runImport([
'external_identifier' => 'billy',
'nick_name' => 'Old Bill',
'contact_sub_type' => 'Staff',
], CRM_Import_Parser::DUPLICATE_UPDATE, CRM_Import_Parser::VALID);
$contact = $this->callAPISuccessGetSingle('Contact', ['id' => $contactID]);
$this->assertEquals('', $contact['nick_name']);
$this->assertEquals(['Parent'], $contact['contact_sub_type']);
}

/**
* Test updating an existing contact with external_identifier match but subtype mismatch.
*
Expand Down Expand Up @@ -1224,6 +1249,28 @@ protected function runImport(array $originalValues, $onDuplicateAction, $expecte
$this->assertEquals($expectedResult, $parser->import($onDuplicateAction, $values), 'Return code from parser import was not as expected');
}

/**
* @param int $contactID
*
* @throws \API_Exception
* @throws \Civi\API\Exception\UnauthorizedException
*/
protected function addChild(int $contactID): void {
$relatedContactID = $this->individualCreate();
$relationshipTypeID = RelationshipType::create()->setValues([
'name_a_b' => 'Dad to',
'name_b_a' => 'Sleep destroyer of',
'contact_type_a' => 'Individual',
'contact_type_b' => 'Individual',
'contact_sub_type_a' => 'Parent',
])->execute()->first()['id'];
\Civi\Api4\Relationship::create()->setValues([
'relationship_type_id' => $relationshipTypeID,
'contact_id_a' => $contactID,
'contact_id_b' => $relatedContactID,
])->execute();
}

/**
* @param array $fields Array of fields to be imported
* @param array $allfields Array of all fields which can be part of import
Expand Down

0 comments on commit c11e71b

Please sign in to comment.