From 6e975197192bff89b1e9e1a267e89558f55830d9 Mon Sep 17 00:00:00 2001 From: Jamie McClelland Date: Wed, 9 Aug 2017 11:58:39 -0400 Subject: [PATCH] CRM-16964: ensure FILL works on import with custom fields. --- CRM/Contact/Import/Parser/Contact.php | 20 ++- .../CRM/Contact/Import/Parser/ContactTest.php | 116 +++++++++++++++++- 2 files changed, 130 insertions(+), 6 deletions(-) diff --git a/CRM/Contact/Import/Parser/Contact.php b/CRM/Contact/Import/Parser/Contact.php index 064fd3c07b..0a66774c4e 100644 --- a/CRM/Contact/Import/Parser/Contact.php +++ b/CRM/Contact/Import/Parser/Contact.php @@ -1796,12 +1796,17 @@ class CRM_Contact_Import_Parser_Contact extends CRM_Contact_Import_Parser { } unset($params[$key]); } - elseif ($customFieldId = CRM_Core_BAO_CustomField::getKeyID($key)) { - $custom = TRUE; - } else { - $getValue = CRM_Utils_Array::retrieveValueRecursive($contact, $key); - + if ($customFieldId = CRM_Core_BAO_CustomField::getKeyID($key)) { + $custom_params = array('id' => $contact['id'], 'return' => $key); + $getValue = civicrm_api3('Contact', 'getvalue', $custom_params); + if (empty($getValue)) { + unset($getValue); + } + } + else { + $getValue = CRM_Utils_Array::retrieveValueRecursive($contact, $key); + } if ($key == 'contact_source') { $params['source'] = $params[$key]; unset($params[$key]); @@ -1809,6 +1814,11 @@ class CRM_Contact_Import_Parser_Contact extends CRM_Contact_Import_Parser { if ($modeFill && isset($getValue)) { unset($params[$key]); + if ($customFieldId) { + // Extra values must be unset to ensure the values are not + // imported. + unset($params['custom'][$customFieldId]); + } } } } diff --git a/tests/phpunit/CRM/Contact/Import/Parser/ContactTest.php b/tests/phpunit/CRM/Contact/Import/Parser/ContactTest.php index 0aa3ee3196..23f35010a6 100644 --- a/tests/phpunit/CRM/Contact/Import/Parser/ContactTest.php +++ b/tests/phpunit/CRM/Contact/Import/Parser/ContactTest.php @@ -36,7 +36,7 @@ * @package CiviCRM * @group headless */ -class CRM_Contact_Imports_Parser_ContactTest extends CiviUnitTestCase { +class CRM_Contact_Import_Parser_ContactTest extends CiviUnitTestCase { protected $_tablesToTruncate = array(); /** @@ -302,6 +302,120 @@ class CRM_Contact_Imports_Parser_ContactTest extends CiviUnitTestCase { $this->callAPISuccessGetSingle('Contact', $contactValues); } + /** + * Test that setting duplicate action to fill doesn't blow away data + * that exists, but does fill in where it's empty. + * + * @throw \Exception + */ + public function testImportFill() { + // Create a custom field group for testing. + $custom_group_name = 'importFillGroup'; + $results = $this->callAPISuccess('customGroup', 'get', array('title' => $custom_group_name)); + if ($results['count'] == 0) { + $api_params = array( + 'title' => $custom_group_name, + 'extends' => 'Individual', + 'is_active' => TRUE, + ); + $customGroup = $this->callAPISuccess('customGroup', 'create', $api_params); + } + + // Add two custom fields. + $api_params = array( + 'custom_group_id' => $customGroup['id'], + 'label' => 'importFillField1', + 'html_type' => 'Select', + 'data_type' => 'String', + 'option_values' => array( + 'foo' => 'Foo', + 'bar' => 'Bar', + ), + ); + $result = $this->callAPISuccess('custom_field', 'create', $api_params); + $customField1 = $result['id']; + + $api_params = array( + 'custom_group_id' => $customGroup['id'], + 'label' => 'importFillField2', + 'html_type' => 'Select', + 'data_type' => 'String', + 'option_values' => array( + 'baz' => 'Baz', + 'boo' => 'Boo', + ), + ); + $result = $this->callAPISuccess('custom_field', 'create', $api_params); + $customField2 = $result['id']; + + // Now set up values. + $original_gender = 'Male'; + $original_custom1 = 'foo'; + $original_job_title = ''; + $original_custom2 = ''; + $original_email = 'test-import-fill@example.org'; + + $import_gender = 'Female'; + $import_custom1 = 'bar'; + $import_job_title = 'Chief data importer'; + $import_custom2 = 'baz'; + + // Create contact with both one known core field and one custom + // field filled in. + $api_params = array( + 'contact_type' => 'Individual', + 'email' => $original_email, + 'gender' => $original_gender, + 'custom_' . $customField1 => $original_custom1 + ); + $result = $this->callAPISuccess('contact', 'create', $api_params); + $contact_id = $result['id']; + + // Run an import. + $import = array( + 'email' => $original_email, + 'gender_id' => $import_gender, + 'custom_' . $customField1 => $import_custom1, + 'job_title' => $import_job_title, + 'custom_' . $customField2 => $import_custom2 + ); + + $this->runImport($import, CRM_Import_Parser::DUPLICATE_FILL, CRM_Import_Parser::VALID); + + $expected = array( + 'gender' => $original_gender, + 'custom_' . $customField1 => $original_custom1, + 'job_title' => $import_job_title, + 'custom_' . $customField2 => $import_custom2 + ); + + $params = array( + 'id' => $contact_id, + 'return' => array( + 'gender', + 'custom_' . $customField1, + 'job_title', + 'custom_' . $customField2 + ) + ); + $result = civicrm_api3('Contact', 'get', $params); + $values = array_pop($result['values']); + foreach($expected as $field => $expected_value) { + if (!isset($values[$field])) { + $given_value = null; + } + else { + $given_value = $values[$field]; + } + // We expect: + // gender: Male + // job_title: Chief Data Importer + // importFillField1: foo + // importFillField2: baz + $this->assertEquals($expected_value, $given_value, "$field properly handled during Fill import"); + } + } + /** * Run the import parser. * -- 2.25.1