Do not display e-notice for zero dollar transactions
authoreileen <emcnaughton@wikimedia.org>
Thu, 11 Oct 2018 14:28:46 +0000 (15:28 +0100)
committereileen <emcnaughton@wikimedia.org>
Thu, 11 Oct 2018 16:51:29 +0000 (17:51 +0100)
CRM/Contribute/BAO/Contribution/Utils.php
CRM/Contribute/Form/Contribution/Confirm.php
tests/phpunit/api/v3/ContributionPageTest.php

index 0b2c99b898e9b99c8c7db1e4ad53c7c29ff85976..d4eed83eb4737a8d8267a01fd3a523c59dfa03bf 100644 (file)
@@ -244,6 +244,7 @@ class CRM_Contribute_BAO_Contribution_Utils {
 
   /**
    * Is a payment being made.
+   *
    * Note that setting is_monetary on the form is somewhat legacy and the behaviour around this setting is confusing. It would be preferable
    * to look for the amount only (assuming this cannot refer to payment in goats or other non-monetary currency
    * @param CRM_Core_Form $form
index 78a08ea421eee0ce2242fc2caed97b816c82f126..123f1198918a69c060aa98d02ab45de33c38a9e9 100644 (file)
@@ -1968,8 +1968,11 @@ class CRM_Contribute_Form_Contribution_Confirm extends CRM_Contribute_Form_Contr
       $capabilities[] = (ucfirst($form->_mode) . 'Mode');
     }
     $form->_paymentProcessors = CRM_Financial_BAO_PaymentProcessor::getPaymentProcessors($capabilities);
-    $form->_params['payment_processor_id'] = !empty($params['payment_processor_id']) ? $params['payment_processor_id'] : 0;
-    $form->_paymentProcessor = $form->_paymentProcessors[$form->_params['payment_processor_id']];
+    $form->_params['payment_processor_id'] = isset($params['payment_processor_id']) ? $params['payment_processor_id'] : 0;
+    if ($form->_params['payment_processor_id'] !== '') {
+      // It can be blank with a $0 transaction - then no processor needs to be selected
+      $form->_paymentProcessor = $form->_paymentProcessors[$form->_params['payment_processor_id']];
+    }
     if (!empty($params['payment_processor_id'])) {
       // The concept of contributeMode is deprecated as is the billing_mode concept.
       if ($form->_paymentProcessor['billing_mode'] == 1) {
@@ -2014,7 +2017,7 @@ class CRM_Contribute_Form_Contribution_Confirm extends CRM_Contribute_Form_Contr
       if (!empty($params['payment_processor_id'])) {
         $params['is_pay_later'] = 0;
       }
-      else {
+      elseif ($params['amount'] !== 0) {
         $params['is_pay_later'] = civicrm_api3('contribution_page', 'getvalue', array(
           'id' => $id,
           'return' => 'is_pay_later',
@@ -2334,7 +2337,7 @@ class CRM_Contribute_Form_Contribution_Confirm extends CRM_Contribute_Form_Contr
         $this->postProcessPremium($premiumParams, $result['contribution']);
       }
       if (!empty($result['contribution'])) {
-        // Not quite sure why it would be empty at this stage but tests show it can be ... at least in tests.
+        // It seems this line is hit when there is a zero dollar transaction & in tests, not sure when else.
         $this->completeTransaction($result, $result['contribution']->id);
       }
       return $result;
@@ -2467,7 +2470,7 @@ class CRM_Contribute_Form_Contribution_Confirm extends CRM_Contribute_Form_Contr
         civicrm_api3('contribution', 'completetransaction', array(
           'id' => $contributionID,
           'trxn_id' => CRM_Utils_Array::value('trxn_id', $result),
-          'payment_processor_id' => $this->_paymentProcessor['id'],
+          'payment_processor_id' => CRM_Utils_Array::value('payment_processor_id', $result, $this->_paymentProcessor['id']),
           'is_transactional' => FALSE,
           'fee_amount' => CRM_Utils_Array::value('fee_amount', $result),
           'receive_date' => CRM_Utils_Array::value('receive_date', $result),
index a9cafed9c7cb9978fcacd3df7ab6fac002eec796..5e7f2479e80e543e6be845d2e1e3daa6b6e4da7a 100644 (file)
@@ -147,6 +147,27 @@ class api_v3_ContributionPageTest extends CiviUnitTestCase {
     $this->assertEquals(5.00, $contribution['non_deductible_amount']);
   }
 
+  /**
+   * Test form submission with basic price set.
+   */
+  public function testSubmitZeroDollar() {
+    $this->setUpContributionPage();
+    $priceFieldID = reset($this->_ids['price_field']);
+    $submitParams = [
+      'price_' . $priceFieldID => $this->_ids['price_field_value']['cheapskate'],
+      'id' => (int) $this->_ids['contribution_page'],
+      'amount' => 0,
+      'priceSetId' => $this->_ids['price_set'][0],
+      'payment_processor_id' => '',
+    ];
+
+    $this->callAPISuccess('contribution_page', 'submit', $submitParams);
+    $contribution = $this->callAPISuccess('contribution', 'getsingle', array('contribution_page_id' => $this->_ids['contribution_page']));
+
+    $this->assertEquals($this->formatMoneyInput(0), $contribution['non_deductible_amount']);
+    $this->assertEquals($this->formatMoneyInput(0), $contribution['total_amount']);
+  }
+
   /**
    * Test form submission with billing first & last name where the contact does NOT
    * otherwise have one.
@@ -1499,6 +1520,16 @@ class api_v3_ContributionPageTest extends CiviUnitTestCase {
         )
       );
       $this->_ids['price_field_value'] = array($priceFieldValue['id']);
+
+      $this->_ids['price_field_value']['cheapskate'] = $this->callAPISuccess('price_field_value', 'create', array(
+          'price_set_id' => $priceSetID,
+          'price_field_id' => $priceField['id'],
+          'label' => 'Stingy Goat',
+          'financial_type_id' => 'Donation',
+          'amount' => 0,
+          'non_deductible_amount' => 0,
+        )
+      )['id'];
     }
     $this->_ids['contribution_page'] = $contributionPageResult['id'];
   }