3

I tried to override COD payment method.

I had to show COD option only if billing zipcode/postcode is one among the list I have in a table in my DB.

I had to modify the following to accomplish my task.

Mage_Payment_Block_Form_Container --> function getMethods() Mage_Payment_Model_Method_Cashondelivery --> function getCODPincodes()

[getCODPincodes() is a custom method to check that pincode table and form an array to check with billing postcode]

It worked!!!

but when I try to create a module with this.

my config.xml

<?xml version="1.0"?>
<config>
<modules>
    <Royal_Payment>
        <version>1.0.0</version>
    </Royal_Payment>
</modules>
<global>
    <models>
        <payment>
            <rewrite>
                <method_cashondelivery>Royal_Payment_Model_Method_Cashondelivery</method_cashondelivery>
            </rewrite>
        </payment>
    </models>
    <blocks>
        <payment>
            <rewrite>
                <form_container>Royal_Payment_Block_Form_Container</form_container>
            </rewrite>
        </payment>
    </blocks>
</global>

my folder structure

app\code\local\Royal\Payment\Block\Form\Container.php

<?php
class Royal_Payment_Block_Form_Container extends Mage_Payment_Block_Form_Container
{
public function getMethods()
{
    $methods = $this->getData('methods');
    if (is_null($methods)) {
        $quote = $this->getQuote();
        $store = $quote ? $quote->getStoreId() : null;
        $methods = $this->helper('payment')->getStoreMethods($store, $quote);
        $total = $quote->getBaseSubtotal() + $quote->getShippingAddress()->getBaseShippingAmount();
        foreach ($methods as $key => $method) {
            $allowCOD = 1;
            if($method->getCode() == "cashondelivery"){
                $postcodes = Mage::getModel('payment/method_cashondelivery')->getCODPincodes();
                $shippingPincode = $this->getQuote()->getBillingAddress()->getData('postcode');
                if(!in_array($shippingPincode, $postcodes)){
                    $allowCOD = 0;      // don't allow cod method -- it goes to else part in next if... else... block
                }
            }           
            if ($this->_canUseMethod($method)
                && ($total != 0
                    || $method->getCode() == 'free'
                    || ($quote->hasRecurringItems() && $method->canManageRecurringProfiles())) && ($allowCOD == 1)) {
                $this->_assignMethod($method);
            } else {
                unset($methods[$key]);
            }
        }
        $this->setData('methods', $methods);
    }
    return $methods;
}
}

app\code\local\Royal\Payment\Model\Method\Cashondelivery.php

<?php
class Royal_Payment_Model_Method_Cashondelivery extends Mage_Payment_Model_Method_Cashondelivery
{
    public function getCODPincodes(){
    $write = Mage::getSingleton('core/resource')->getConnection('core_read');
    $query = "select pincode from `pincode`";
    $results = $write->fetchAll($query);
    foreach($results as $result){
        $postcodes[] = $result['pincode'];
    }
    return $postcodes;
}
}

My overriden Model is working fine. But block method is not invoked

Where am I going wrong? Can anyone help please?

3
  • cache? compilation? error logs?
    – user487772
    May 17, 2013 at 10:02
  • @Tim: no error logs cleared cache and compiled. Function not invoked
    – Shathish
    May 17, 2013 at 11:14
  • Try rewriting Mage_Checkout_Block_Onepage_Payment_Methods instead
    – mnp
    Jan 18, 2014 at 18:06

2 Answers 2

6

Rather than rewrite the core block you could use the event "payment_method_is_active"

In your config add the following:

<models>
    <royal_payment>
        <class>Royal_Payment_Model</class>
    </royal_payment>
</models>
<events>
    <payment_method_is_active>
        <observers>
            <royal_payment>
                <class>royal_payment/observer</class>
                <method>payment_method_is_active</method>
            </royal_payment>
        </observers>
    </payment_method_is_active>
</events>

Then create your observer class Royal_Payment_Model_Observer with the function payment_method_is_active

public function payment_method_is_active(Varien_Event_Observer $observer) {
    $quote = $observer->getData('quote');
    $method = $observer->getData('result');
    $methodInstance = $observer->getData('method_instance');

    // Here you can do your checking on the quote and if you dont want to show the method
    $method->isAvailable = false;
}

Using the $methodInstance you can validate that you are only checking the COD method.

3
  • I used this answer for a different module. thank you pal! and I started lovin observers
    – Shathish
    May 31, 2013 at 11:51
  • I have mentioned some example using this event on my blog: blog.magepsycho.com/… hope this helps you too.
    – MagePsycho
    Aug 21, 2013 at 13:10
  • There is a type in $oObserver
    – Arvind07
    Nov 21, 2014 at 6:00
2

If you wish to modify the one-page checkout form, you must override the proper block, because the instance of Mage_Payment_Block_Form_Container is not called directly, therefor it wont be overridden from a direct rewrite.

The class that needs to be overridden is Mage_Checkout_Block_Onepage_Payment_Methods since it ultimately extends Mage_Payment_Block_Form_Container and is the class that actually gets invoked. So your rewrite needs to read:

Your config.xml file should contain

<global>
      <blocks>
        <checkout>
         <rewrite>
           <onepage_payment_methods>MyCompany_Checkout_Block_Onepage_Payment_Methods</onepage_payment_methods>
         </rewrite>
        </checkout>
       </blocks>
     </global>

and your class declared as:

class MyCompany_Checkout_Block_Onepage_Payment_Methods extends Mage_Checkout_Block_Onepage_Payment_Methods
{

     //do your stuff here

} 

Let me know if you have any query

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.