From 449f4c901f8d9674bf3d9f4cc3029b3b98cdcb0c Mon Sep 17 00:00:00 2001 From: eileen Date: Mon, 16 Nov 2015 03:04:45 -0800 Subject: [PATCH] CRM-17559 autorenew membership fix - front end form --- CRM/Contribute/BAO/Contribution/Utils.php | 28 +++-------- CRM/Contribute/Form/Contribution.php | 3 +- CRM/Contribute/Form/Contribution/Confirm.php | 42 +++++++++-------- CRM/Member/Form/Membership.php | 3 +- tests/phpunit/api/v3/ContributionPageTest.php | 47 +++++++++++++++++++ 5 files changed, 79 insertions(+), 44 deletions(-) diff --git a/CRM/Contribute/BAO/Contribution/Utils.php b/CRM/Contribute/BAO/Contribution/Utils.php index 2f9a662d33..5b7595fcc2 100644 --- a/CRM/Contribute/BAO/Contribution/Utils.php +++ b/CRM/Contribute/BAO/Contribution/Utils.php @@ -45,7 +45,8 @@ class CRM_Contribute_BAO_Contribution_Utils { * @param int $contributionTypeId * Financial type id. * @param int|string $component component id - * @param $isTest + * @param bool $isTest + * @param bool $isRecur * * @throws CRM_Core_Exception * @throws Exception @@ -59,7 +60,8 @@ class CRM_Contribute_BAO_Contribution_Utils { $contactID, $contributionTypeId, $component = 'contribution', - $isTest + $isTest, + $isRecur ) { CRM_Core_Payment_Form::mapParams($form->_bltID, $form->_params, $paymentParams, TRUE); $lineItems = $form->_lineItem; @@ -88,19 +90,6 @@ class CRM_Contribute_BAO_Contribution_Utils { CRM_Utils_Date::mysqlToIso($form->_params['receive_date']) ); if ($isPaymentTransaction) { - // Fix for CRM-14354. If the membership is recurring, don't create a - // civicrm_contribution_recur record for the additional contribution - // (i.e., the amount NOT associated with the membership). Temporarily - // cache the is_recur values so we can process the additional gift as a - // one-off payment. - if (!empty($form->_values['is_recur'])) { - if ($form->_membershipBlock['is_separate_payment'] && !empty($form->_params['auto_renew'])) { - $cachedFormValue = CRM_Utils_Array::value('is_recur', $form->_values); - $cachedParamValue = CRM_Utils_Array::value('is_recur', $paymentParams); - unset($form->_values['is_recur']); - unset($paymentParams['is_recur']); - } - } $contributionParams = array( 'contact_id' => $contactID, @@ -124,7 +113,8 @@ class CRM_Contribute_BAO_Contribution_Utils { $contributionParams, $financialType, TRUE, - $form->_bltID + $form->_bltID, + $isRecur ); $paymentParams['contributionTypeID'] = $contributionTypeId; @@ -140,12 +130,6 @@ class CRM_Contribute_BAO_Contribution_Utils { return array('contribution' => $contribution); } - // restore cached values (part of fix for CRM-14354) - if (!empty($cachedFormValue)) { - $form->_values['is_recur'] = $cachedFormValue; - $paymentParams['is_recur'] = $cachedParamValue; - } - $paymentParams['contributionID'] = $contribution->id; //CRM-15297 deprecate contributionTypeID $paymentParams['financialTypeID'] = $paymentParams['contributionTypeID'] = $contribution->financial_type_id; diff --git a/CRM/Contribute/Form/Contribution.php b/CRM/Contribute/Form/Contribution.php index 4467a93d76..ced3745041 100644 --- a/CRM/Contribute/Form/Contribution.php +++ b/CRM/Contribute/Form/Contribution.php @@ -1193,7 +1193,8 @@ class CRM_Contribute_Form_Contribution extends CRM_Contribute_Form_AbstractEditP $contributionParams, $financialType, FALSE, - $this->_bltID + $this->_bltID, + CRM_Utils_Array::value('is_recur', $this->_params) ); $paymentParams['contributionID'] = $contribution->id; diff --git a/CRM/Contribute/Form/Contribution/Confirm.php b/CRM/Contribute/Form/Contribution/Confirm.php index f79df3b66d..9b4b31a9d7 100644 --- a/CRM/Contribute/Form/Contribution/Confirm.php +++ b/CRM/Contribute/Form/Contribution/Confirm.php @@ -807,7 +807,8 @@ class CRM_Contribute_Form_Contribution_Confirm extends CRM_Contribute_Form_Contr $contributionParams, $financialType, $online, - $billingLocationID + $billingLocationID, + $isRecur ) { $transaction = new CRM_Core_Transaction(); $contactID = $contributionParams['contact_id']; @@ -837,7 +838,8 @@ class CRM_Contribute_Form_Contribution_Confirm extends CRM_Contribute_Form_Contr if (!isset($params['is_email_receipt']) && $isEmailReceipt) { $params['is_email_receipt'] = $isEmailReceipt; } - $recurringContributionID = self::processRecurringContribution($form, $params, $contactID, $financialType, $online); + $params['is_recur'] = $isRecur; + $recurringContributionID = self::processRecurringContribution($form, $params, $contactID, $financialType); $nonDeductibleAmount = self::getNonDeductibleAmount($params, $financialType, $online); $now = date('YmdHis'); @@ -1045,16 +1047,12 @@ class CRM_Contribute_Form_Contribution_Confirm extends CRM_Contribute_Form_Contr * @param array $params * @param int $contactID * @param string $contributionType - * @param bool $online * - * @return mixed + * @return int|null */ - public static function processRecurringContribution(&$form, &$params, $contactID, $contributionType, $online = TRUE) { - // return if this page is not set for recurring - // or the user has not chosen the recurring option + public static function processRecurringContribution(&$form, &$params, $contactID, $contributionType) { - //this is online case validation. - if ((empty($form->_values['is_recur']) && $online) || empty($params['is_recur'])) { + if (empty($params['is_recur'])) { return NULL; } @@ -1100,16 +1098,11 @@ class CRM_Contribute_Form_Contribution_Confirm extends CRM_Contribute_Form_Contr $recurParams['trxn_id'] = CRM_Utils_Array::value('trxn_id', $params, $params['invoiceID']); $recurParams['financial_type_id'] = $contributionType->id; - if (!$online || $form->_values['is_monetary']) { + if ($form->_values['is_monetary']) { $recurParams['payment_instrument_id'] = 1; } - $campaignId = CRM_Utils_Array::value('campaign_id', $params); - if ($online) { - if (!array_key_exists('campaign_id', $params)) { - $campaignId = CRM_Utils_Array::value('campaign_id', $form->_values); - } - } + $campaignId = CRM_Utils_Array::value('campaign_id', $params, CRM_Utils_Array::value('campaign_id', $form->_values)); $recurParams['campaign_id'] = $campaignId; $recurring = CRM_Contribute_BAO_ContributionRecur::add($recurParams); @@ -1427,17 +1420,23 @@ class CRM_Contribute_Form_Contribution_Confirm extends CRM_Contribute_Form_Contr $isTest = CRM_Utils_Array::value('is_test', $membershipParams, FALSE); $errors = $createdMemberships = $paymentResults = array(); + $isRecurForFirstTransaction = CRM_Utils_Array::value('is_recur', $form->_values, CRM_Utils_Array::value('is_recur', $membershipParams)); + if ($isPaidMembership) { if ($isProcessSeparateMembershipTransaction) { // If we have 2 transactions only one can use the invoice id. $membershipParams['invoiceID'] .= '-2'; + if (!empty($membershipParams['auto_renew'])) { + $isRecurForFirstTransaction = FALSE; + } } $paymentResult = CRM_Contribute_BAO_Contribution_Utils::processConfirm($form, $membershipParams, $contactID, $financialTypeID, 'membership', - $isTest + $isTest, + $isRecurForFirstTransaction ); if (!empty($paymentResult['contribution'])) { @@ -1649,6 +1648,7 @@ class CRM_Contribute_Form_Contribution_Confirm extends CRM_Contribute_Form_Contr $financialType->find(TRUE); $tempParams['amount'] = $minimumFee; $tempParams['invoiceID'] = md5(uniqid(rand(), TRUE)); + $isRecur = CRM_Utils_Array::value('is_recur', $tempParams); //assign receive date when separate membership payment //and contribution amount not selected. @@ -1693,7 +1693,8 @@ class CRM_Contribute_Form_Contribution_Confirm extends CRM_Contribute_Form_Contr $contributionParams, $financialType, TRUE, - $form->_bltID + $form->_bltID, + $isRecur ); $result = array(); @@ -2157,12 +2158,13 @@ class CRM_Contribute_Form_Contribution_Confirm extends CRM_Contribute_Form_Contr } } } - + $isRecur = CRM_Utils_Array::value('is_recur', $this->_values, CRM_Utils_Array::value('is_recur', $paymentParams)); $result = CRM_Contribute_BAO_Contribution_Utils::processConfirm($this, $paymentParams, $contactID, $this->wrangleFinancialTypeID($this->_values['financial_type_id']), 'contribution', - ($this->_mode == 'test') ? 1 : 0 + ($this->_mode == 'test') ? 1 : 0, + $isRecur ); if (empty($result['is_payment_failure'])) { diff --git a/CRM/Member/Form/Membership.php b/CRM/Member/Form/Membership.php index cd312ff947..825bced3e8 100644 --- a/CRM/Member/Form/Membership.php +++ b/CRM/Member/Form/Membership.php @@ -1428,7 +1428,8 @@ class CRM_Member_Form_Membership extends CRM_Member_Form { ), $financialType, FALSE, - $this->_bltID + $this->_bltID, + TRUE ); //create new soft-credit record, CRM-13981 diff --git a/tests/phpunit/api/v3/ContributionPageTest.php b/tests/phpunit/api/v3/ContributionPageTest.php index de6cb22d06..3e0bdc87b7 100644 --- a/tests/phpunit/api/v3/ContributionPageTest.php +++ b/tests/phpunit/api/v3/ContributionPageTest.php @@ -494,6 +494,53 @@ class api_v3_ContributionPageTest extends CiviUnitTestCase { $this->assertEquals(2, $recurringContribution['contribution_status_id']); } + /** + * Test submit recurring membership with immediate confirmation (IATS style). + * + * - we process 2 membership transactions against with a recurring contribution against a contribution page with an immediate + * processor (IATS style - denoted by returning trxn_id) + * - the first creates a new membership, completed contribution, in progress recurring. Check these + * - create another - end date should be extended + */ + public function testSubmitMembershipPriceSetPaymentPaymentProcessorSeparatePaymentRecurInstantPayment() { + + $this->setUpMembershipContributionPage(TRUE); + $dummyPP = Civi\Payment\System::singleton()->getByProcessor($this->_paymentProcessor); + $dummyPP->setDoDirectPaymentResult(array('payment_status_id' => 1, 'trxn_id' => 'create_first_success')); + + $submitParams = array( + 'price_' . $this->_ids['price_field'][0] => reset($this->_ids['price_field_value']), + 'id' => (int) $this->_ids['contribution_page'], + 'amount' => 10, + 'billing_first_name' => 'Billy', + 'billing_middle_name' => 'Goat', + 'billing_last_name' => 'Gruff', + 'email' => 'billy@goat.gruff', + 'selectMembership' => $this->_ids['membership_type'], + 'payment_processor_id' => 1, + 'credit_card_number' => '4111111111111111', + 'credit_card_type' => 'Visa', + 'credit_card_exp_date' => array('M' => 9, 'Y' => 2040), + 'cvv2' => 123, + 'is_recur' => 1, + 'auto_renew' => TRUE, + 'frequency_interval' => 1, + 'frequency_unit' => 'month', + ); + + $this->callAPIAndDocument('contribution_page', 'submit', $submitParams, __FUNCTION__, __FILE__, 'submit contribution page', NULL); + $contribution = $this->callAPISuccess('contribution', 'get', array( + 'contribution_page_id' => $this->_ids['contribution_page'], + 'contribution_status_id' => 1, + )); + + $this->assertEquals(2, $contribution['count']); + $membershipPayment = $this->callAPISuccess('membership_payment', 'getsingle', array()); + $this->callAPISuccessGetSingle('membership', array('id' => $membershipPayment['membership_id'])); + $this->assertNotEmpty($contribution['values'][$membershipPayment['contribution_id']]['contribution_recur_id']); + $this->callAPISuccess('contribution_recur', 'getsingle', array()); + } + /** * Test submit recurring membership with delayed confirmation (Authorize.net style) * - we process 2 membership transactions against with a recurring contribution against a contribution page with a delayed -- 2.25.1