From 870156d6e2b06283381142c6e61f02e35f8180a4 Mon Sep 17 00:00:00 2001 From: eileen Date: Wed, 4 Nov 2015 21:55:03 -0800 Subject: [PATCH] CRM-17500 fix display name etc not being updated from billing This is tested here in contribution flow --- CRM/Contact/BAO/Contact.php | 32 ++++++- CRM/Contribute/Form/Contribution/Confirm.php | 28 +----- tests/phpunit/api/v3/ContributionPageTest.php | 85 +++++++++++++++++++ 3 files changed, 119 insertions(+), 26 deletions(-) diff --git a/CRM/Contact/BAO/Contact.php b/CRM/Contact/BAO/Contact.php index d3a3d443ae..7bef11045b 100644 --- a/CRM/Contact/BAO/Contact.php +++ b/CRM/Contact/BAO/Contact.php @@ -523,6 +523,35 @@ WHERE civicrm_contact.id = " . CRM_Utils_Type::escape($id, 'Integer'); return NULL; } + /** + * Add billing fields to the params if appropriate. + * + * If we have ANY name fields then we want to ignore all the billing name fields. However, if we + * don't then we should set the name fields to the filling fields AND add the preserveDBName + * parameter (which will tell the BAO only to set those fields if none already exist. + * + * We specifically don't want to set first name from billing and last name form an on-page field. Mixing & + * matching is best done by hipsters. + * + * @param array $params + */ + public static function addBillingNameFieldsIfOtherwiseNotSet(&$params) { + $nameFields = array('first_name', 'middle_name', 'last_name'); + foreach ($nameFields as $field) { + if (!empty($params[$field])) { + return; + } + } + // There are only 3 - we can iterate through them twice :-) + foreach ($nameFields as $field) { + if (!empty($params['billing_' . $field])) { + $params[$field] = $params['billing_' . $field]; + } + $params['preserveDBName'] = TRUE; + } + + } + /** * Create last viewed link to recently updated contact. * @@ -1825,6 +1854,7 @@ ORDER BY civicrm_email.is_primary DESC"; if ($ufGroupId) { $params['uf_group_id'] = $ufGroupId; } + self::addBillingNameFieldsIfOtherwiseNotSet($params); // If a user has logged in, or accessed via a checksum // Then deliberately 'blanking' a value in the profile should remove it from their record @@ -2018,7 +2048,7 @@ ORDER BY civicrm_email.is_primary DESC"; $primaryPhoneLoc = NULL; $session = CRM_Core_Session::singleton(); foreach ($params as $key => $value) { - $fieldName = $locTypeId = $typeId = NULL; + $locTypeId = $typeId = NULL; list($fieldName, $locTypeId, $typeId) = CRM_Utils_System::explode('-', $key, 3); //store original location type id diff --git a/CRM/Contribute/Form/Contribution/Confirm.php b/CRM/Contribute/Form/Contribution/Confirm.php index e0a9f95279..c7d87c83ab 100644 --- a/CRM/Contribute/Form/Contribution/Confirm.php +++ b/CRM/Contribute/Form/Contribution/Confirm.php @@ -1825,6 +1825,9 @@ class CRM_Contribute_Form_Contribution_Confirm extends CRM_Contribute_Form_Contr $params['invoiceID'] = md5(uniqid(rand(), TRUE)); $paramsProcessedForForm = $form->_params = self::getFormParams($params['id'], $params); $form->_amount = $params['amount']; + // hack these in for test support. + $form->_fields['billing_first_name'] = 1; + $form->_fields['billing_last_name'] = 1; $priceSetID = $form->_params['priceSetId'] = $paramsProcessedForForm['price_set_id']; $priceFields = CRM_Price_BAO_PriceSet::getSetDetail($priceSetID); $priceSetFields = reset($priceFields); @@ -1933,31 +1936,6 @@ class CRM_Contribute_Form_Contribution_Confirm extends CRM_Contribute_Form_Contr // billing email address $fields["email-{$this->_bltID}"] = 1; - //unset the billing parameters if it is pay later mode - //to avoid creation of billing location - // @todo - note that elsewhere we don't unset these - we simply make - // a sensible decision about including them when building the form - // and if they are submitted we handle them. Check out abstractEditPaymentForm. - if ($isPayLater && !$this->_isBillingAddressRequiredForPayLater) { - $billingFields = array( - 'billing_first_name', - 'billing_middle_name', - 'billing_last_name', - "billing_street_address-{$this->_bltID}", - "billing_city-{$this->_bltID}", - "billing_state_province-{$this->_bltID}", - "billing_state_province_id-{$this->_bltID}", - "billing_postal_code-{$this->_bltID}", - "billing_country-{$this->_bltID}", - "billing_country_id-{$this->_bltID}", - ); - - foreach ($billingFields as $value) { - unset($params[$value]); - unset($fields[$value]); - } - } - // if onbehalf-of-organization contribution, take out // organization params in a separate variable, to make sure // normal behavior is continued. And use that variable to diff --git a/tests/phpunit/api/v3/ContributionPageTest.php b/tests/phpunit/api/v3/ContributionPageTest.php index 1a46c1f631..de6cb22d06 100644 --- a/tests/phpunit/api/v3/ContributionPageTest.php +++ b/tests/phpunit/api/v3/ContributionPageTest.php @@ -149,6 +149,91 @@ class api_v3_ContributionPageTest extends CiviUnitTestCase { $this->callAPISuccess('contribution', 'getsingle', array('contribution_page_id' => $this->_ids['contribution_page'])); } + /** + * Test form submission with billing first & last name where the contact does NOT + * otherwise have one. + */ + public function testSubmitNewBillingNameData() { + $this->setUpContributionPage(); + $contact = $this->callAPISuccess('Contact', 'create', array('contact_type' => 'Individual', 'email' => 'wonderwoman@amazon.com')); + $priceFieldID = reset($this->_ids['price_field']); + $priceFieldValueID = reset($this->_ids['price_field_value']); + $submitParams = array( + 'price_' . $priceFieldID => $priceFieldValueID, + 'id' => (int) $this->_ids['contribution_page'], + 'amount' => 10, + 'billing_first_name' => 'Wonder', + 'billing_last_name' => 'Woman', + 'contactID' => $contact['id'], + 'email' => 'wonderwoman@amazon.com', + ); + + $this->callAPISuccess('contribution_page', 'submit', $submitParams); + $contact = $this->callAPISuccess('Contact', 'get', array( + 'id' => $contact['id'], + 'return' => array( + 'first_name', + 'last_name', + 'sort_name', + 'display_name', + ), + )); + $this->assertEquals(array( + 'first_name' => 'Wonder', + 'last_name' => 'Woman', + 'display_name' => 'Wonder Woman', + 'sort_name' => 'Woman, Wonder', + 'id' => $contact['id'], + 'contact_id' => $contact['id'], + ), $contact['values'][$contact['id']]); + + } + + /** + * Test form submission with billing first & last name where the contact does + * otherwise have one and should not be overwritten. + */ + public function testSubmitNewBillingNameDoNotOverwrite() { + $this->setUpContributionPage(); + $contact = $this->callAPISuccess('Contact', 'create', array( + 'contact_type' => 'Individual', + 'email' => 'wonderwoman@amazon.com', + 'first_name' => 'Super', + 'last_name' => 'Boy', + )); + $priceFieldID = reset($this->_ids['price_field']); + $priceFieldValueID = reset($this->_ids['price_field_value']); + $submitParams = array( + 'price_' . $priceFieldID => $priceFieldValueID, + 'id' => (int) $this->_ids['contribution_page'], + 'amount' => 10, + 'billing_first_name' => 'Wonder', + 'billing_last_name' => 'Woman', + 'contactID' => $contact['id'], + 'email' => 'wonderwoman@amazon.com', + ); + + $this->callAPISuccess('contribution_page', 'submit', $submitParams); + $contact = $this->callAPISuccess('Contact', 'get', array( + 'id' => $contact['id'], + 'return' => array( + 'first_name', + 'last_name', + 'sort_name', + 'display_name', + ), + )); + $this->assertEquals(array( + 'first_name' => 'Super', + 'last_name' => 'Boy', + 'display_name' => 'Super Boy', + 'sort_name' => 'Boy, Super', + 'id' => $contact['id'], + 'contact_id' => $contact['id'], + ), $contact['values'][$contact['id']]); + + } + /** * Test process with instant payment when more than one configured for the page. * -- 2.25.1