Magento – Magento Bundle ‘As Low As’ Price – I need to add tax

bundled-productmagento-1.9tax

All prices are in the database excluding tax, but are shown including tax. A bundle product detail page shows the price correctly. (lets call it £120). However, the preview of the product you click on to get to the detail page, the price is shown as 'as low as £100' – i.e. it excludes the product tax of 20%.

Can somebody tell me how to correct this, what files to edit and what code?

My Magento website is version 1.9. Confident in and around FTP and the Magento file system, but have been trying forever to get this to work.

Best Answer

It seems Magento left out a swath of code that should be calculating the VAT at that point. I think it was left out because the logic wasn't really straightforward.

The problem is in the structure of the bundle; it has minimum and maximum prices, which also might contain different tax rates. A bundle itself doesn't have a singular tax rate set, since the products contained in the bundle can contain different tax rates.

So we need to look inside the bundle, find the corresponding prices for the individual items, calculate minimum and maximum prices and give these back to the Bundle's price.phtml. Luckily for you, I did just that.

We need to edit two files. Because the code for the taxated bundle products wasn't built in, there was no need to show including/excluding VAT prices in price.phtml since it was always excluding VAT (as you've noticed).

We need to remedy this first to at least be able to show the including VAT price as soon as we have it.

So, replace line 263 of app/design/frontend/base/default/template/bundle/catalog/product/price.phtml, which now reads;

<?php echo $_coreHelper->currency($_minimalPriceTax) ?>

with:

<?php if ($_taxHelper->displayPriceIncludingTax()) : ?>
    <?php echo $_coreHelper->currency($_minimalPriceInclTax) ?>
<?php else: ?>
    <?php echo $_coreHelper->currency($_minimalPriceTax) ?>
<?php endif; ?>

Of course, adhere to Magento best practices by creating a copy of this file within your own template.

Now on to step 2; changing the code to actually retrieve the prices including tax. The class

Mage_Bundle_Model_Product_Price

contains a function called getTotalPrices(). This function retrieves the minimum and maximum prices of a tiered/grouped/bundled product. But it doesn't retrieve the prices including tax for bundled product (which is the premise of your question).

So we are going to replace the lines 196 to 201. They now read;

if ($this->_isPricesCalculatedByIndex) {
    $minimalPrice = $taxHelper->getPrice($product, $product->getData('min_price'), $includeTax,
        null, null, null, null, null, false);
    $maximalPrice = $taxHelper->getPrice($product, $product->getData('max_price'), $includeTax,
        null, null, null, null, null, false);
} else {

Replace those lines with this code;

if ($this->_isPricesCalculatedByIndex) {
    /* Add tax to Bundle product prices because the taxHelper->getPrice() function always returns without tax */
    if($includeTax && $product->getTypeInstance() instanceof Mage_Bundle_Model_Product_Type) {
        $maximalPrice = $minimalPrice = 0;
        $bundleOptions = Mage::getResourceSingleton('bundle/selection')->getChildrenIds($product->getId(), $required=true);

        $childIds = array();
        foreach($bundleOptions as $option) {
            foreach ($option as $childProductId) {
                $childIds[] = $childProductId;
            }
        }
        $childProductObjects = Mage::getResourceModel('catalog/product_collection')
            ->addIdFilter($childIds)
            ->addAttributeToSelect(array('price','tax_class_id'));

        $childPrices = array();
        foreach($childProductObjects as $childProductObject) {
            $childPrices[$childProductObject->getId()] = Mage::helper('tax')->getPrice($childProductObject, $childProductObject->getFinalPrice());
        }

        foreach($bundleOptions as $option) {
            $optionPrices = array();
            foreach($option as $childProductId) {
                $optionPrices[] = $childPrices[$childProductId];
            }
            $_minimalOptionPrice = min($optionPrices);
            $_maximalOptionPrice = max($optionPrices);

            $minimalPrice += $_minimalOptionPrice;
            $maximalPrice += $_maximalOptionPrice;
        }
    } else {
        $minimalPrice = $taxHelper->getPrice($product, $product->getData('min_price'), $includeTax,
            null, null, null, null, null, false);
        $maximalPrice = $taxHelper->getPrice($product, $product->getData('max_price'), $includeTax,
            null, null, null, null, null, false);
    }
} else {

Of course, you should adhere to Magento best practices and rewrite Mage_Bundle_Model_Product_Price by creating your own custom module that extends this class with the new functionality.

That should be it!

Related Topic