We have Magento CE 1.9.1.0 installed and we guess that we have a strange problem with the tax calculation. Here is our case study:
In our b2b-shop we want to display all prices without tax. Here are our tax setting in the backend.
The customer tax should applied after discount. The shipping prices are displayed exclusive tax. At the end we want to have a total excl. tax, then the final taxamount and the grandtotal at the end, like you see in the next image of our cart.
We have a taxrate of 19%. Now the problem: When we calculate the grandtotal like this: 126,60 * 1,19 = 150,654 we see that our customer pays 1cent too much. Our dilemma: Statistically, every 10 order occur like this. Why?
What we have done before? The calculation in Magento at the beginning of the development was even worse. So we made a little adjustment in the tax.php at /app/code/local/Mage/Tax/Model/Sales/Total/Quote from line 548 in the method "_calcUnitTaxAmount
" - near "case Mage_Tax_Model_Calculation::CALC_TAX_AFTER_DISCOUNT_ON_INCL:
".
protected function _calcUnitTaxAmount( $item, $rate, &$taxGroups = null, $taxId = null, $recalculateRowTotalInclTax = false ) { $qty = $item->getTotalQty(); $inclTax = $item->getIsPriceInclTax(); $price = $item->getTaxableAmount(); $basePrice = $item->getBaseTaxableAmount(); $rateKey = ($taxId == null) ? (string)$rate : $taxId; $isWeeeEnabled = $this->_weeeHelper->isEnabled(); $isWeeeTaxable = $this->_weeeHelper->isTaxable(); $hiddenTax = null; $baseHiddenTax = null; $weeeTax = null; $baseWeeeTax = null; $unitTaxBeforeDiscount = null; $weeeTaxBeforeDiscount = null; $baseUnitTaxBeforeDiscount = null; $baseWeeeTaxBeforeDiscount = null; switch ($this->_config->getCalculationSequence($this->_store)) { case Mage_Tax_Model_Calculation::CALC_TAX_BEFORE_DISCOUNT_ON_EXCL: case Mage_Tax_Model_Calculation::CALC_TAX_BEFORE_DISCOUNT_ON_INCL: $unitTaxBeforeDiscount = $this->_calculator->calcTaxAmount($price, $rate, $inclTax, false); $baseUnitTaxBeforeDiscount = $this->_calculator->calcTaxAmount($basePrice, $rate, $inclTax, false); if ($isWeeeEnabled && $isWeeeTaxable) { $weeeTaxBeforeDiscount = $this->_calculateWeeeTax(0, $item, $rate, false); $unitTaxBeforeDiscount += $weeeTaxBeforeDiscount; $baseWeeeTaxBeforeDiscount = $this->_calculateWeeeTax(0, $item, $rate); $baseUnitTaxBeforeDiscount += $baseWeeeTaxBeforeDiscount; } $unitTaxBeforeDiscount = $unitTax = $this->_calculator->round($unitTaxBeforeDiscount); $baseUnitTaxBeforeDiscount = $baseUnitTax = $this->_calculator->round($baseUnitTaxBeforeDiscount); break; case Mage_Tax_Model_Calculation::CALC_TAX_AFTER_DISCOUNT_ON_EXCL: case Mage_Tax_Model_Calculation::CALC_TAX_AFTER_DISCOUNT_ON_INCL: // our changes here - formerly: $discountAmount = $item->getDiscountAmount() / $qty; $discountAmount = $item->getDiscountAmount(); $baseDiscountAmount = $item->getBaseDiscountAmount() / $qty; //We want to remove weee if ($isWeeeEnabled) { $discountAmount = $discountAmount - $item->getWeeeDiscount() / $qty; $baseDiscountAmount = $baseDiscountAmount - $item->getBaseWeeeDiscount() / $qty; } $unitTaxBeforeDiscount = $this->_calculator->calcTaxAmount($price, $rate, $inclTax, false); $unitTaxDiscount = $this->_calculator->calcTaxAmount($discountAmount, $rate, $inclTax, false); $unitTax = $this->_calculator->round(max($unitTaxBeforeDiscount - $unitTaxDiscount, 0)); $baseUnitTaxBeforeDiscount = $this->_calculator->calcTaxAmount($basePrice, $rate, $inclTax, false); $baseUnitTaxDiscount = $this->_calculator->calcTaxAmount($baseDiscountAmount, $rate, $inclTax, false); $baseUnitTax = $this->_calculator->round(max($baseUnitTaxBeforeDiscount - $baseUnitTaxDiscount, 0)); if ($isWeeeEnabled && $this->_weeeHelper->isTaxable()) { $weeeTax = $this->_calculateRowWeeeTax($item->getWeeeDiscount(), $item, $rate, false); $weeeTax = $weeeTax / $qty; $unitTax += $weeeTax; $baseWeeeTax = $this->_calculateRowWeeeTax($item->getBaseWeeeDiscount(), $item, $rate); $baseWeeeTax = $baseWeeeTax / $qty; $baseUnitTax += $baseWeeeTax; } $unitTax = $this->_calculator->round($unitTax); $baseUnitTax = $this->_calculator->round($baseUnitTax); //Calculate the weee taxes before discount $weeeTaxBeforeDiscount = 0; $baseWeeeTaxBeforeDiscount = 0; if ($isWeeeTaxable) { $weeeTaxBeforeDiscount = $this->_calculateWeeeTax(0, $item, $rate, false); $unitTaxBeforeDiscount += $weeeTaxBeforeDiscount; $baseWeeeTaxBeforeDiscount = $this->_calculateWeeeTax(0, $item, $rate); $baseUnitTaxBeforeDiscount += $baseWeeeTaxBeforeDiscount; } $unitTaxBeforeDiscount = max(0, $this->_calculator->round($unitTaxBeforeDiscount)); $baseUnitTaxBeforeDiscount = max(0, $this->_calculator->round($baseUnitTaxBeforeDiscount)); if ($inclTax && $discountAmount > 0) { $hiddenTax = $unitTaxBeforeDiscount - $unitTax; $baseHiddenTax = $baseUnitTaxBeforeDiscount - $baseUnitTax; $this->_hiddenTaxes[] = array( 'rate_key' => $rateKey, 'qty' => $qty, 'item' => $item, 'value' => 0, // our changes here - formerly: $hiddenTax 'base_value' => 0, // our changes here - formerly: $baseHiddenTax 'incl_tax' => $inclTax, ); } elseif ($discountAmount > $price) { // case with 100% discount on price incl. tax $hiddenTax = $discountAmount - $price; $baseHiddenTax = $baseDiscountAmount - $basePrice; $this->_hiddenTaxes[] = array( 'rate_key' => $rateKey, 'qty' => $qty, 'item' => $item, 'value' => $hiddenTax, 'base_value' => $baseHiddenTax, 'incl_tax' => $inclTax, ); } // calculate discount compensation // We need the discount compensation when dont calculate the hidden taxes // (when product does not include taxes) if (!$item->getNoDiscount() && $item->getWeeeTaxApplied()) { $item->setDiscountTaxCompensation($item->getDiscountTaxCompensation() + $unitTaxBeforeDiscount * $qty - max(0, $unitTax) * $qty); } break; } /* begin of our addings */ $totalWithoutTax = $item->getRowTotal(); $totalReady = $totalWithoutTax - $discountAmount; $unitTax = $totalReady * ($rateKey / 100); $rowTax = $unitTax; /* end of our addings */ // our changes here - formerly: $rowTax = $this->_store->roundPrice(max(0, $qty * $unitTax)); $baseRowTax = $this->_store->roundPrice(max(0, $qty * $baseUnitTax)); $item->setTaxAmount($item->getTaxAmount() + $rowTax); $item->setBaseTaxAmount($item->getBaseTaxAmount() + $baseRowTax); if (is_array($taxGroups)) { $taxGroups[$rateKey]['tax'] = max(0, $rowTax); $taxGroups[$rateKey]['base_tax'] = max(0, $baseRowTax); } $rowTotalInclTax = $item->getRowTotalInclTax(); if (!isset($rowTotalInclTax) || $recalculateRowTotalInclTax) { if ($this->_config->priceIncludesTax($this->_store)) { $item->setRowTotalInclTax($price * $qty); $item->setBaseRowTotalInclTax($basePrice * $qty); } else { $item->setRowTotalInclTax( $item->getRowTotalInclTax() + ($unitTaxBeforeDiscount - $weeeTaxBeforeDiscount) * $qty); $item->setBaseRowTotalInclTax( $item->getBaseRowTotalInclTax() + ($baseUnitTaxBeforeDiscount - $baseWeeeTaxBeforeDiscount) * $qty); } } return $this; }
The deleted the hiddentax amount and recalculated the rowtax. But this is not working for the 10th order. What we have done wrong? Have we basically did not understand Magento? We are struggeling with this since two weeks :(