CRM-17559 autorenew membership fix - front end form
authoreileen <emcnaughton@wikimedia.org>
Mon, 16 Nov 2015 11:04:45 +0000 (03:04 -0800)
committereileen <emcnaughton@wikimedia.org>
Tue, 24 Nov 2015 05:17:31 +0000 (18:17 +1300)
CRM/Contribute/BAO/Contribution/Utils.php
CRM/Contribute/Form/Contribution.php
CRM/Contribute/Form/Contribution/Confirm.php
CRM/Member/Form/Membership.php
tests/phpunit/api/v3/ContributionPageTest.php

index 2f9a662d339d69ad8cfc6b22d97c3be00b457e5d..5b7595fcc28e30be7744dda28a1670610bd0ef52 100644 (file)
@@ -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;
index 4467a93d76ec79cf70143aebcd7868cc3be276af..ced3745041c12d182281ea9eb1fbcfcc01fef5bc 100644 (file)
@@ -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;
index f79df3b66d298869449a7306589eb2de103e4f2d..9b4b31a9d738073a83a4b8670cbc7f6151b92a41 100644 (file)
@@ -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'])) {
index cd312ff947e561aa8cde30d1ca6e71cf74624e05..825bced3e8d1dab71d0eefe5d0a1940daabd7560 100644 (file)
@@ -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
index de6cb22d06dcb2889f82df9b7c6357cc21dd6445..3e0bdc87b774704c9df923d2e5d084a31fabaded 100644 (file)
@@ -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