Magento – How to override Mage_Shipping_Model_Carrier_Flatrate

ce-1.7.0.2shipping

I need to override Mage_Shipping_Model_Carrier_Flatrate through my custom module in magento 1.7.

Right now i have done this :

In my app/etc/modules/ i have the file "Namespace_Modulename.xml" with the code:

 <?xml version="1.0"?>
   <config>
      <modules>
        <Namespace_Modulename>
           <active>true</active>
           <codePool>local</codePool>
       </Namespace_Modulename>
     </modules>
   </config> 

In my app/code/local/Namespace/Modulename/etc/ i have file "config.xml" with the code:

 <?xml version="1.0" encoding="utf-8"?>
  <config>
    <modules>
       <Namespace_Modulename>
           <version>0.1.0</version>
       </Namespace_Modulename>
    </modules>
    <global>
     <models>
       <shipping>
         <rewrite>
              <carrier_flatrate>Namespace_Modulename_Model_Flatrate</carrier_flatrate>
         </rewrite>
       </shipping>
     </models>
   </global>
 </config> 

In my app/code/local/Namespace/Modulename/Model i have file "Flatrate.php" with the code:

  class Namespace_Modulename_Model_Flatrate
   extends Mage_Shipping_Model_Carrier_Abstract
   implements Mage_Shipping_Model_Carrier_Interface
   {

   protected $_code = 'flatrate';


    public function collectRates(Mage_Shipping_Model_Rate_Request $request)
    {
    if (!$this->getConfigFlag('active')) {
        return false;
    }

    $freeBoxes = 0;
    if ($request->getAllItems()) {
        foreach ($request->getAllItems() as $item) {
            if ($item->getFreeShipping() && !$item->getProduct()->getTypeInstance()->isVirtual()) {
                $freeBoxes+=$item->getQty();
            }
        }
    }
    $this->setFreeBoxes($freeBoxes);

    $result = Mage::getModel('shipping/rate_result');
    if ($this->getConfigData('type') == 'O') { // per order
        $shippingPrice = $this->getConfigData('price');
    } elseif ($this->getConfigData('type') == 'I') { // per item
        $shippingPrice = '0.00';
        foreach ($request->getAllItems() as $item) {
            if (!$item->getFreeShipping()) {
                $productId = $item->getProduct()->getId();
                $productList = Mage::getModel('catalog/product')->getCollection()
                    ->addAttributeToSelect('ship_price')
                    ->addIdFilter($productId);
                foreach($productList as $product) {
                    $quantity = $item->getQty();
                    if ($product->getShipPrice()) {
                        $shippingPrice+=$product->getShipPrice() * $quantity;
                    } else {
                        $shippingPrice+=$this->getConfigData('price') * $quantity;

                    }
                }
            }

        }
    } else {
        $shippingPrice = false;
    }

    $shippingPrice = $this->getFinalPriceWithHandlingFee($shippingPrice);

    if ($shippingPrice !== false) {
        $method = Mage::getModel('shipping/rate_result_method');

        $method->setCarrier('flatrate');
        $method->setCarrierTitle($this->getConfigData('title'));

        $method->setMethod('flatrate');
        $method->setMethodTitle($this->getConfigData('name'));

        if ($request->getFreeShipping() === true || $request->getPackageQty() == $this->getFreeBoxes()) {
            $shippingPrice = '0.00';
        }


        $method->setPrice($shippingPrice);
        $method->setCost($shippingPrice);

        $result->append($method);
    }

    return $result;
}

public function getAllowedMethods()
{
    return array('flatrate'=>$this->getConfigData('name'));
}

}

But it's not working. May be i am missing something or doing anything wrong.
Please help,

Thanks in advance,
Sarvagya

Best Answer

First, clear cache and disable/refresh compilation. Then, rule out a competing rewrite. Deactivate your module and do the following on a page or with a workbench script:

$className = Mage::getConfig()->getModelClassName('shipping/carrier_flatrate');
echo $className;
$class = new $className;
echo get_class($class);

You should see Mage_Shipping_Model_Carrier_Flatrate two times. Anything other class name and you have a multi-rewrite to chain or otherwise resolve. If you do not see the classname a second time then there is an issue instantiating the class (likely because of autoloading issue). Reactivate your module and test the factory class name resolution as above, and you should see your Flatrate class name.

A final note - if you are rewriting the core Flatrate model, convention indicates that you should extend from it. It's academic in this case given that you are overriding everything in the parent class.