Extend Magento sales order grid using event observer

November 17, 2013  |  3 Comments  |  by Raj (MagePsycho)  |  Magento

You can add new columns to the Sales Order grid easily by extending the block class: Mage_Adminhtml_Block_Sales_Order_Grid
But this is not the preferred way due to conflict issues.

Here I will show you how to extend order grid by using events(core_block_abstract_to_html_before & sales_order_grid_collection_load_before) only.

For example purpose we will be adding Payment Method to sales order grid and MagePsycho_Gridextend will be the skeleton extension.
1. Register the events:

...
<adminhtml>
    <events>
        <core_block_abstract_to_html_before>
            <observers>
                <magepsycho_gridextend_core_block_abstract_to_html_before>
                    <class>magepsycho_gridextend/observer</class>
                    <method>coreBlockAbstractToHtmlBefore</method>
                </magepsycho_gridextend_core_block_abstract_to_html_before>
            </observers>
        </core_block_abstract_to_html_before>
        <sales_order_grid_collection_load_before>
            <observers>
                <magepsycho_gridextend_sales_order_grid_collection_load_before>
                    <class>magepsycho_gridextend/observer</class>
                    <method>salesOrderGridCollectionLoadBefore</method>
                </magepsycho_gridextend_sales_order_grid_collection_load_before>
            </observers>
        </sales_order_grid_collection_load_before>
    </events>
</adminhtml>
...

2. Create the observer model:

<?php
/**
 * @category   MagePsycho
 * @package    MagePsycho_Gridextend
 * @author     magepsycho@gmail.com
 * @license    http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
 */
class MagePsycho_Gridextend_Model_Observer {

    /**
     * Moved to Block class
     * @param Varien_Event_Observer $observer
     */
    public function coreBlockAbstractToHtmlBefore(Varien_Event_Observer $observer)
    {
        /** @var $block Mage_Core_Block_Abstract */
        $block = $observer->getEvent()->getBlock();
        if ($block->getId() == 'sales_order_grid') {
            
            //add new column: payment method
            $paymentArray = Mage::getSingleton('payment/config')->getActiveMethods();
            $paymentMethods = array();
            foreach ($paymentArray as $code => $payment) {
                // not sure why ops_dl was not in the loop so tweaked it
                $paymentTitle = Mage::getStoreConfig('payment/'.$code.'/title');
                $paymentMethods[$code] = $paymentTitle;
            }
            $block->addColumnAfter(
                'payment_method',
                array(
                    'header'   => Mage::helper('sales')->__('Payment Method'),
                    'align'    => 'left',
                    'type'     => 'options',
                    'options'  => $paymentMethods,
                    'index'    => 'payment_method',
                    'filter_index'    => 'payment.method',
                ),
                'shipping_name'
            );
            
            //similary you can addd new columns
            //...

            // Set the new columns order.. otherwise our column would be the last one
            $block->sortColumnsByOrder();
        }
    }

    /**
     * Moved to block class
     * @param Varien_Event_Observer $observer
     */
    public function salesOrderGridCollectionLoadBefore(Varien_Event_Observer $observer)
    {
        $collection = $observer->getOrderGridCollection();
        $select = $collection->getSelect();
        $select->joinLeft(array('payment' => $collection->getTable('sales/order_payment')), 'payment.parent_id=main_table.entity_id',array('payment_method' => 'method'));
    }
}

3. Refresh the Sales > Order page, you will see page similar to:
Sales Order Grid

Similarly, you can extend any admin grid like sales invoice, customer etc.

How to filter payment method in onepage checkout

January 9, 2013  |  10 Comments  |  by Raj (MagePsycho)  |  Latest, Magento

Introduction

Q: How will you filter the payment method in onepage checkout based on some conditions?
A: There are different ways to do so. Some of them are:
#1 By overriding template: app/design/frontend/[interface]/[theme]/template/checkout/onepage/payment/methods.phtml
#2 By overriding method: Mage_Checkout_Block_Onepage_Payment_Methods::_canUseMethod()
#3 By overriding method: Mage_Payment_Model_Method_Abstract::isAvailable()
#4 By overriding method: Mage_Checkout_Block_Onepage_Payment_Methods::getMethods()
#5 By observing event: payment_method_is_active
#6 etc.

Among above methods obviously using event-observer technique is the best way to go (#5).
And here I will be discussing about how to enable the PayPal (Website Standard) method only when current currency is USD.

Steps

Suppose a skeleton module(MagePsycho_Paymentfilter) has already been created.
1> Register the event: ‘payment_method_is_active’ in config.xml.
Add the following xml code in app/code/local/MagePsycho/Paymentfilter/etc/config.xml:

...
<frontend>
	...
	<events>
		<payment_method_is_active>
			<observers>
				<paymentfilter_payment_method_is_active>
					<type>singleton</type>
					<class>paymentfilter/observer</class>
					<method>paymentMethodIsActive</method>
				</paymentfilter_payment_method_is_active>
			</observers>
		</payment_method_is_active>
	</events>
	...
</frontend>
...

2> Implement the observer model
Create observer file: app/code/local/MagePsycho/Paymentfilter/Model/Observer.php and paste the following code:

<?php
/**
 * @category   MagePsycho
 * @package    MagePsycho_Paymentfilter
 * @author     magepsycho@gmail.com
 * @website    http://www.magepsycho.com
 * @license    http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
 	*/
class MagePsycho_Paymentfilter_Model_Observer {

	public function paymentMethodIsActive(Varien_Event_Observer $observer) {
		$event			 = $observer->getEvent();
		$method			 = $event->getMethodInstance();
		$result			 = $event->getResult();
		$currencyCode	 = Mage::app()->getStore()->getCurrentCurrencyCode();
		
		if( $currencyCode == 'USD'){
			if($method->getCode() == 'paypal_standard' ){
				$result->isAvailable = true;
			}else{
				$result->isAvailable = false;
			}
		}
	}

}

3> Go ahead for testing.

Happy E-Commerce!