Fundamental Fixes for TaxMath Calculations.
authorKarinG <karin@semper-it.com>
Sun, 22 Jan 2017 21:33:28 +0000 (14:33 -0700)
committerKarinG <karin@semper-it.com>
Tue, 24 Jan 2017 01:43:43 +0000 (18:43 -0700)
CRM/Contribute/BAO/Contribution/Utils.php
CRM/Price/BAO/LineItem.php
CRM/Price/BAO/PriceSet.php
templates/CRM/Price/Page/LineItem.tpl

index a5a20458b28d050fcdca7a921a3f619f6e549bf7..59e98fcc58c2fb2ff98e028635146f41f344b635 100644 (file)
@@ -931,7 +931,8 @@ LIMIT 1
    */
   public static function calculateTaxAmount($amount, $taxRate) {
     $taxAmount = array();
-    $taxAmount['tax_amount'] = round(($taxRate / 100) * CRM_Utils_Rule::cleanMoney($amount), 2);
+    // There can not be any rounding at this stage - as this is prior to quantity multiplication
+    $taxAmount['tax_amount'] = ($taxRate / 100) * CRM_Utils_Rule::cleanMoney($amount);
 
     return $taxAmount;
   }
index 290da64d813b41e3c1cd2cf2d7b0b4fb681087d8..04dfc78d2cf13a36c6abd7729d2c3816d20e97d2 100644 (file)
@@ -251,7 +251,15 @@ AND li.entity_id = {$entityId}
         'membership_num_terms' => $dao->membership_num_terms,
         'tax_amount' => $dao->tax_amount,
       );
-      $lineItems[$dao->id]['tax_rate'] = CRM_Price_BAO_LineItem::calculateTaxRate($lineItems[$dao->id]);
+      $taxRates = CRM_Core_PseudoConstant::getTaxRates();
+      if (isset($lineItems[$dao->id]['financial_type_id']) && array_key_exists($lineItems[$dao->id]['financial_type_id'], $taxRates)) {
+        // We are close to output/display here - so apply some rounding at output/display level - to not show Tax Rate in it's full 8 decimals
+        $lineItems[$dao->id]['tax_rate'] = round($taxRates[$lineItems[$dao->id]['financial_type_id']], 3);
+      }
+      else {
+        // There is no Tax Rate associated with this Financial Type
+        $lineItems[$dao->id]['tax_rate'] = FALSE;
+      }
       $lineItems[$dao->id]['subTotal'] = $lineItems[$dao->id]['qty'] * $lineItems[$dao->id]['unit_price'];
       if ($lineItems[$dao->id]['tax_amount'] != '') {
         $getTaxDetails = TRUE;
@@ -537,26 +545,4 @@ AND li.entity_id = {$entityId}
     }
   }
 
-  /**
-   * Calculate tax rate in percentage.
-   *
-   * @param array $lineItemId
-   *   An assoc array of lineItem.
-   *
-   * @return int|void
-   *   tax rate
-   */
-  public static function calculateTaxRate($lineItemId) {
-    if ($lineItemId['unit_price'] == 0) {
-      return FALSE;
-    }
-    if ($lineItemId['html_type'] == 'Text') {
-      $tax = round($lineItemId['tax_amount'] / ($lineItemId['unit_price'] * $lineItemId['qty']) * 100, 2);
-    }
-    else {
-      $tax = round(($lineItemId['tax_amount'] / $lineItemId['unit_price']) * 100, 2);
-    }
-    return $tax;
-  }
-
 }
index 879f34f8ae51a9e76ada2e0e30a60b67f564e005..f401d63eb66c95f129bd3071df0678bd5fd3d3bf 100644 (file)
@@ -1536,11 +1536,12 @@ WHERE       ps.id = %1
    * @return array
    */
   public static function setLineItem($field, $lineItem, $optionValueId) {
+    // Here we round - i.e. after multiplying by quantity
     if ($field['html_type'] == 'Text') {
-      $taxAmount = $field['options'][$optionValueId]['tax_amount'] * $lineItem[$optionValueId]['qty'];
+      $taxAmount = round($field['options'][$optionValueId]['tax_amount'] * $lineItem[$optionValueId]['qty'], 2);
     }
     else {
-      $taxAmount = $field['options'][$optionValueId]['tax_amount'];
+      $taxAmount = round($field['options'][$optionValueId]['tax_amount'], 2);
     }
     $taxRate = $field['options'][$optionValueId]['tax_rate'];
     $lineItem[$optionValueId]['tax_amount'] = $taxAmount;
index 91cd54961930f686692ea6c745eb5b5c84ff7a44..1c7aaa9ce1e5842de2a3e69ac9d566fdf94a57a5 100644 (file)
@@ -72,7 +72,7 @@
     {if $getTaxDetails}
       <td class="right">{$line.line_total|crmMoney}</td>
       {if $line.tax_rate != "" || $line.tax_amount != ""}
-        <td class="right">{$taxTerm} ({$line.tax_rate|string_format:"%.2f"}%)</td>
+        <td class="right">{$taxTerm} ({$line.tax_rate|string_format:"%.3f"}%)</td>
         <td class="right">{$line.tax_amount|crmMoney}</td>
       {else}
         <td></td>