Magento Table rate: How to customise/override?

Posted by Damodar Bashyal on February 27, 2012

 

Our client is using table rate shipping method but he needed slightly modification on the default one. They want to set shipping price on the product level (optionally). So, if shipping is defined for the product then use that to calculate shipping of the order.

If the product is set as 'free' then exclude it's price from shipping. If it's left empty or set as 'default' then just use the rate from table. But if the product has custom shipping price, then add that on the shipping.

This is how I modified the magento's official table rate shipping module/extension.

First of all, go to Magento admin / Catalog / Attributes / Manage Attributes and add new attribute with Attribute code 'tn_table_rate' with input type 'Text Field' and label 'Shipping Cost'. Then add it to your Attribute Set.

app\etc\modules\Technooze_All.xml

<?xml version="1.0"?>
<config>
    <modules>
        <Technooze_Shipping>
            <active>true</active>
            <codePool>community</codePool>
        </Technooze_Shipping>
    </modules>
</config>

app\code\community\Technooze\Shipping\etc\config.xml

<?xml version="1.0"?>
<config>
    <modules>
        <Technooze_Shipping>
            <version>1.0.0</version>
            <depends>
	            <Mage_Shipping />
            </depends>
        </Technooze_Shipping>
    </modules>
    <global>
        <models>
            <class>Technooze_Shipping_Model</class>
            <shipping>
                <rewrite>
	                <carrier_tablerate>Technooze_Shipping_Model_Tablerate</carrier_tablerate>
                </rewrite>
            </shipping>
        </models>
        <helpers>
	        <class>Technooze_Shipping_Helper</class>
        </helpers>
    </global>
</config>

app\code\community\Technooze\Shipping\Helper\Data.php

<?php
/**
  * Data helper
  */
  class Technooze_Shipping_Helper_Data extends Mage_Core_Helper_Abstract{}

app\code\community\Technooze\Shipping\Model\Tablerate.php

<?php
class Technooze_Shipping_Model_Tablerate
	extends Mage_Shipping_Model_Carrier_Tablerate
{
    public function collectRates(Mage_Shipping_Model_Rate_Request $request)
    {
        if (!$this->getConfigFlag('active')) {
            return false;
        }
    
        $customItemPrice = 0;
        $cartHasItems = false;
        if($request->getAllItems())
        {
            foreach ($request->getAllItems() as $item)
            {
                if ($item->getParentItem()) {
                    continue;
                }
                
                $itemPrice = 0;
                $myItemPrice = 0;
                if ($item->getHasChildren() && $item->isShipSeparately())
                {
                    foreach ($item->getChildren() as $child)
                    {
                        if ($child->getProduct()->isVirtual())
                        {
                            $itemPrice = $child->getBaseRowTotal();
                            //$request->setPackageValue($request->getPackageValue() - $child->getBaseRowTotal());
                        } else {
                            $myItemPrice = $child->getBaseRowTotal();
                        }
                    }
                } elseif ($item->getProduct()->isVirtual()) {
                    $itemPrice = $item->getBaseRowTotal();
                    //$request->setPackageValue($request->getPackageValue() - $item->getBaseRowTotal());
                } else {
                    $myItemPrice = $item->getBaseRowTotal();
                }
                
                if($itemPrice > 0 && !$this->getConfigFlag('include_virtual_price'))
                {
                    /*
                     * exclude Virtual products price from Package value if pre-configured
                     **/
                    $request->setPackageValue($request->getPackageValue() - $itemPrice);
                } else {

                    /*
                     * If the item price already not deducted,
                     * look for custom rule, if it has custom price setting.
                     * */
                    $itemPrice = max($itemPrice, $myItemPrice);/*get price whichever is set*/
                    $tnItem = Mage::getModel('catalog/product')->load($item->getData('product_id'));
                    $tnItem = $tnItem->getData('tn_table_rate');
    
                    if(is_string($tnItem))
                    {
                        $tnItem = strtolower($tnItem);
                    }

                    switch($tnItem)
                    {
                        case 'default':
                            break;
                        case 'free':
                            $request->setPackageValue($request->getPackageValue() - $itemPrice);
                            break;
                        default:
                            if($tnItem > 0)
                            {
                                $request->setPackageValue($request->getPackageValue() - $itemPrice);
                                $customItemPrice += $tnItem;
                            }
                    }
                }
            }
            $cartHasItems = true;
        }
        
        // Free shipping by qty
        $freeQty = 0;
        if ($request->getAllItems())
        {
            foreach ($request->getAllItems() as $item)
            {
                if ($item->getProduct()->isVirtual() || $item->getParentItem())
                {
                    continue;
                }
                if ($item->getHasChildren() && $item->isShipSeparately())
                {
                    foreach ($item->getChildren() as $child)
                    {
                        if ($child->getFreeShipping() && !$child->getProduct()->isVirtual())
                        {
                            $freeQty += $item->getQty() * ($child->getQty() - (is_numeric($child->getFreeShipping()) ? $child->getFreeShipping() : 0));
                        }
                    }
                } elseif ($item->getFreeShipping()) {
                    $freeQty += ($item->getQty() - (is_numeric($item->getFreeShipping()) ? $item->getFreeShipping() : 0));
                }
            }
        }

        if (!$request->getConditionName())
        {
        	$request->setConditionName($this->getConfigData('condition_name') ? $this->getConfigData('condition_name') : $this->_default_condition_name);
        }
        
        // Package weight and qty free shipping
        $oldWeight = $request->getPackageWeight();
        $oldQty = $request->getPackageQty();
        $request->setPackageWeight($request->getFreeMethodWeight());
        $request->setPackageQty($oldQty - $freeQty);
        $result = Mage::getModel('shipping/rate_result');
        $rate = $this->getRate($request);
        $request->setPackageWeight($oldWeight);
        $request->setPackageQty($oldQty);

        if ((!empty($rate) && $rate['price'] >= 0) || ($customItemPrice > 0) || ($cartHasItems))
        {
            if(empty($rate['price']))
            {
                $rate['price'] = 0;
            }
            if(empty($rate['cost']))
            {
                $rate['cost'] = 0;
            }
            $method = Mage::getModel('shipping/rate_result_method');
            $method->setCarrier('tablerate');
            $method->setCarrierTitle($this->getConfigData('title'));
            $method->setMethod('bestway');
            $method->setMethodTitle($this->getConfigData('name'));
            if ($request->getFreeShipping() === true || ($request->getPackageQty() == $freeQty))
            {
                $shippingPrice = 0;
            } else {
                $shippingPrice = $this->getFinalPriceWithHandlingFee($rate['price']);
            }
            
            if($customItemPrice > 0)
            {
                $shippingPrice = $shippingPrice + $customItemPrice;
            }
            
            $method->setPrice($shippingPrice);
            $method->setCost($rate['cost']);
            $result->append($method);
        }
        return $result;
    }
}

In this tablerate model we are overriding 'collectRates' method/function.

This is my table rate csv:

Country,Region/State,Zip/Postal Code,Order Subtotal (and above),Shipping
  AUS,*,*,0.01,7.9
  AUS,*,*,30.01,8.9
  AUS,*,*,40.01,9.9
  AUS,*,*,50.01,10.9
AUS,*,*,70.01,11.9

To upload Table rate csv, goto:

e-Commerce Administration / System / Configuration / Shipping Methods / Table Rates / > Here import your CSV and select Price Vs. Destination Condition. NOTE: to see import field you need to select your website under 'Current Configuration Scope' on top right corner. for more information on "How Do I Set Up Table Rate Shipping?" visit this: http://www.magentocommerce.com/knowledge-base/entry/how-do-i-set-up-table-rate-shipping

Jagesh posted on - Wednesday 5th of December 2012 09:47:49 PM

HI,

This information is very useful to me.
Is it possible to integrate UPS ground rates instead of upload table_rate.csv .
Without upload csv file how to override shipping price based on UPS Ground Price.

Alessandro posted on - Friday 19th of April 2013 08:49:04 PM

Hi,
thank you for your code.
I've followed all the steps but it doesn't work on my site.
The shipping cost isn't overrated by what i set into the product page.

Could you please help me?

Thank you,
Alessandro
 
not published on website


QR Code: Magento Table rate: How to customise/override?