Unshared toxic function getNonDeductibleAmount
authorEileen McNaughton <emcnaughton@wikimedia.org>
Tue, 21 Nov 2023 05:29:07 +0000 (18:29 +1300)
committerEileen McNaughton <emcnaughton@wikimedia.org>
Tue, 21 Nov 2023 05:29:07 +0000 (18:29 +1300)
CRM/Contribute/Form/Contribution.php
CRM/Contribute/Form/Contribution/Confirm.php

index 827f73e3e214959eaf280e42f36d6cc07a4e803c..1f27fb2c5fffc827acfc4389311f0cea613269a4 100644 (file)
@@ -1420,7 +1420,7 @@ class CRM_Contribute_Form_Contribution extends CRM_Contribute_Form_AbstractEditP
         NULL, $receiptDate,
         $recurringContributionID), $contributionParams
       );
-      $contributionParams['non_deductible_amount'] = CRM_Contribute_Form_Contribution_Confirm::getNonDeductibleAmount($params, $financialType, FALSE, $form);
+      $contributionParams['non_deductible_amount'] = $this->getNonDeductibleAmount($params, $financialType, FALSE, $form);
       $contributionParams['skipCleanMoney'] = TRUE;
       // @todo this is the wrong place for this - it should be done as close to form submission
       // as possible
@@ -1468,6 +1468,75 @@ class CRM_Contribute_Form_Contribution extends CRM_Contribute_Form_AbstractEditP
     return $contribution;
   }
 
+  /**
+   * Get non-deductible amount.
+   *
+   * Previously shared function - was quite broken in the other flow.
+   * Maybe here too
+   *
+   * This is a bit too much about wierd form interpretation to be this deep.
+   *
+   * @see https://issues.civicrm.org/jira/browse/CRM-11885
+   *  if non_deductible_amount exists i.e. Additional Details fieldset was opened [and staff typed something] -> keep
+   * it.
+   *
+   * @param array $params
+   * @param CRM_Financial_BAO_FinancialType $financialType
+   * @param bool $online
+   * @param CRM_Contribute_Form_Contribution_Confirm $form
+   *
+   * @return array
+   */
+  private function getNonDeductibleAmount($params, $financialType, $online, $form) {
+    if (isset($params['non_deductible_amount']) && (!empty($params['non_deductible_amount']))) {
+      return $params['non_deductible_amount'];
+    }
+    $priceSetId = $params['priceSetId'] ?? NULL;
+    // return non-deductible amount if it is set at the price field option level
+    if ($priceSetId && !empty($form->_lineItem)) {
+      $nonDeductibleAmount = CRM_Price_BAO_PriceSet::getNonDeductibleAmountFromPriceSet($priceSetId, $form->_lineItem);
+    }
+
+    if (!empty($nonDeductibleAmount)) {
+      return $nonDeductibleAmount;
+    }
+    else {
+      if ($financialType->is_deductible) {
+        if ($online && isset($params['selectProduct'])) {
+          $selectProduct = $params['selectProduct'] ?? NULL;
+        }
+        if (!$online && isset($params['product_name'][0])) {
+          $selectProduct = $params['product_name'][0];
+        }
+        // if there is a product - compare the value to the contribution amount
+        if (isset($selectProduct) &&
+          $selectProduct !== 'no_thanks'
+        ) {
+          $productDAO = new CRM_Contribute_DAO_Product();
+          $productDAO->id = $selectProduct;
+          $productDAO->find(TRUE);
+          // product value exceeds contribution amount
+          if ($params['amount'] < $productDAO->price) {
+            $nonDeductibleAmount = $params['amount'];
+            return $nonDeductibleAmount;
+          }
+          // product value does NOT exceed contribution amount
+          else {
+            return $productDAO->price;
+          }
+        }
+        // contribution is deductible - but there is no product
+        else {
+          return '0.00';
+        }
+      }
+      // contribution is NOT deductible
+      else {
+        return $params['amount'];
+      }
+    }
+  }
+
   /**
    * Create the recurring contribution record.
    *
index c35b1d809b29ad693c796c0a9fd2f537adab7120..e0b340dd6903983b5520591f8d4ca02780dd6947 100644 (file)
@@ -210,7 +210,7 @@ class CRM_Contribute_Form_Contribution_Confirm extends CRM_Contribute_Form_Contr
    *
    * @return array
    */
-  public static function getNonDeductibleAmount($params, $financialType, $online, $form) {
+  private function getNonDeductibleAmount($params, $financialType, $online, $form) {
     if (isset($params['non_deductible_amount']) && (!empty($params['non_deductible_amount']))) {
       return $params['non_deductible_amount'];
     }
@@ -1046,7 +1046,7 @@ class CRM_Contribute_Form_Contribution_Confirm extends CRM_Contribute_Form_Contr
       );
 
       $contributionParams['payment_processor'] = $result ? ($result['payment_processor'] ?? NULL) : NULL;
-      $contributionParams['non_deductible_amount'] = self::getNonDeductibleAmount($params, $financialType, TRUE, $form);
+      $contributionParams['non_deductible_amount'] = $this->getNonDeductibleAmount($params, $financialType, TRUE, $form);
       $contributionParams['skipCleanMoney'] = TRUE;
       // @todo this is the wrong place for this - it should be done as close to form submission
       // as possible