Fix calculation and assignment of taxAmount on contribution page confirmation
authorMatthew Wire <mjw@mjwconsult.co.uk>
Tue, 3 May 2022 10:35:28 +0000 (11:35 +0100)
committerMatthew Wire <mjw@mjwconsult.co.uk>
Wed, 4 May 2022 10:47:22 +0000 (11:47 +0100)
CRM/Contribute/Form/Contribution/Confirm.php
CRM/Contribute/Form/Contribution/Main.php

index 2ef3a2a863c5bb0d681632adb8d24c169dcc7414..8c44807f269b33f9c9b801934f02d50767ddb700 100644 (file)
@@ -280,7 +280,10 @@ class CRM_Contribute_Form_Contribution_Confirm extends CRM_Contribute_Form_Contr
       $this->setFormAmountFields($this->_params['priceSetId']);
     }
 
-    $this->_params['tax_amount'] = $this->get('tax_amount');
+    if (!empty($this->get('tax_amount'))) {
+      CRM_Core_Error::deprecatedWarning('tax_amount should be not passed in');
+      $this->_params['tax_amount'] = $this->get('tax_amount');
+    }
     $this->_useForMember = $this->get('useForMember');
 
     CRM_Contribute_Form_AbstractEditPayment::formatCreditCardDetails($this->_params);
@@ -492,15 +495,18 @@ class CRM_Contribute_Form_Contribution_Confirm extends CRM_Contribute_Form_Contr
     // Make a copy of line items array to use for display only
     $tplLineItems = $this->_lineItem;
     if (CRM_Invoicing_Utils::isInvoicingEnabled()) {
-      // @todo $params seems like exactly the wrong place to get totalTaxAmount from
-      // this is a calculated variable so we it should be transparent how we
-      // calculated it rather than coming from 'params'
-      $this->assign('totalTaxAmount', $params['tax_amount']);
+      $taxAmount = 0;
+      foreach ($tplLineItems ?? [] as $lineItems) {
+        foreach ($lineItems as $lineItem) {
+          $taxAmount += (float) ($lineItem['tax_amount'] ?? 0);
+        }
+      }
+
+      $this->assign('totalTaxAmount', $taxAmount);
+      $this->assign('taxTerm', CRM_Invoicing_Utils::getTaxTerm());
     }
-    $this->assignLineItemsToTemplate($tplLineItems);
 
     $isDisplayLineItems = $this->_priceSetId && !CRM_Core_DAO::getFieldValue('CRM_Price_DAO_PriceSet', $this->_priceSetId, 'is_quick_config');
-
     $this->assign('isDisplayLineItems', $isDisplayLineItems);
 
     if (!$isDisplayLineItems) {
@@ -509,6 +515,9 @@ class CRM_Contribute_Form_Contribution_Confirm extends CRM_Contribute_Form_Contr
       $this->assign('is_quick_config', 1);
       $this->_params['is_quick_config'] = 1;
     }
+    else {
+      $this->assignLineItemsToTemplate($tplLineItems);
+    }
 
     if (!empty($params['selectProduct']) && $params['selectProduct'] !== 'no_thanks') {
       $option = $params['options_' . $params['selectProduct']] ?? NULL;
@@ -565,8 +574,6 @@ class CRM_Contribute_Form_Contribution_Confirm extends CRM_Contribute_Form_Contr
     $this->assign('priceSetID', $this->_priceSetId);
 
     // The concept of contributeMode is deprecated.
-    // the is_monetary concept probably should be too as it can be calculated from
-    // the existence of 'amount' & seems fragile.
     if ($this->_contributeMode === 'notify' ||
       $this->_amount <= 0.0 || $this->_params['is_pay_later']
     ) {
@@ -1124,6 +1131,7 @@ class CRM_Contribute_Form_Contribution_Confirm extends CRM_Contribute_Form_Contr
       // lets store it in the form variable so postProcess hook can get to this and use it
       $form->_contributionID = $contribution->id;
     }
+    // @fixme: This is assigned to the smarty template for the receipt. It's value should be calculated and not taken from $params.
     $form->assign('totalTaxAmount', $params['tax_amount'] ?? NULL);
 
     // process soft credit / pcp params first
index 3d8c6abafb031245ebe87f10aad58ab3080d6db2..9e82c1f81b03885468fa9dfa3a840c60afe03f81 100644 (file)
@@ -1363,10 +1363,6 @@ class CRM_Contribute_Form_Contribution_Main extends CRM_Contribute_Form_Contribu
         CRM_Price_BAO_PriceSet::processAmount($this->_values['fee'], $params, $lineItem[$priceSetId], $priceSetId);
       }
 
-      if ($params['tax_amount']) {
-        $this->set('tax_amount', $params['tax_amount']);
-      }
-
       if ($proceFieldAmount) {
         $lineItem[$params['priceSetId']][$fieldOption]['unit_price'] = $proceFieldAmount;
         $lineItem[$params['priceSetId']][$fieldOption]['line_total'] = $proceFieldAmount;