Magento 1.9 – Create an Observer for sales_order_place_after Event

event-observerinvoicemagento-1.9

I'm trying to write an observer <sales_order_place_after> that create invoice automatically when an order is placed. Please tell me how to do it.

Best Answer

A custom Magento module will be required for this task

Let’s name it Karthik_Orderhook

Step 1:- First, create a module initializer in /app/etc/modules/Karthik_Orderhook.xml with the following content:

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

Step 2:- Create a module configuration file config.xml in app/code/local/NAMESPACE/MODULENAME/etc/ (replace NAMESPACE and MODULENAME with your own values). In our case the path will be /app/code/local/Karthik/Orderhook/etc/config.xml with content:

<?xml version="1.0"?>
<config>
    <modules>
        <Karthik_Orderhook>
            <version>1.0</version>
        </Karthik_Orderhook>
    </modules>

    <global>

        <models>            
            <orderhook>
                <class>Karthik_Orderhook</class>
            </orderhook>
        </models>

        <events>
            <sales_order_place_after>
                <observers>
                    <auto_invoice_order>
                        <type>singleton</type>
                        <class>Karthik_Orderhook_Model_Observer</class>
                        <method>implementOrderStatus</method>
                    </auto_invoice_order>
                </observers>
            </sales_order_place_after>
        </events>

    </global>
</config>

I assume you know the working of config.xml and above mentioned tags

Step 3:- Create observer file app/code/community/Karthik/Orderhook/Model/Observer.php with the following content:

   <?php

class Karthik_Orderhook_Model_Observer 
{
    public function implementOrderStatus($event)
    {
        $order = $event->getOrder();

        if ($this->_getPaymentMethod($order) == 'ccsave') {
            if ($order->canInvoice())
                $this->_processOrderStatus($order);
        }
        return $this;
    }

As we have described below – order status will be changed only if “Credit Card Save” payment method has been used with the order. If you don’t need these conditions – just remove the below function _getPaymentMethod.

private function _getPaymentMethod($order)
    {
        return $order->getPayment()->getMethodInstance()->getCode();
    }

    private function _processOrderStatus($order)
    {
        $invoice = $order->prepareInvoice();

        $invoice->register();
        Mage::getModel('core/resource_transaction')
           ->addObject($invoice)
           ->addObject($invoice->getOrder())
           ->save();

        $invoice->sendEmail(true, '');
        $this->_changeOrderStatus($order);
        return true;
    }

    private function _changeOrderStatus($order)
    {
        $statusMessage = '';
        $order->setState(Mage_Sales_Model_Order::STATE_PROCESSING, true); //Setting the status or changing the status of the order placed       
    $order->save();
    }
}

If You want to change status different from above mentioned on then you can replace the code with any of below mentioned

/**
 * change order status to 'Completed'
 */
$order->setState(Mage_Sales_Model_Order::STATE_COMPLETE, true)->save();
Similarly, you can change the order status to pending, processing, canceled, closed, held, etc.

/**
 * change order status to "Pending"
 */
$order->setState(Mage_Sales_Model_Order::STATE_NEW, true)->save();

/**
 * change order status to "Pending Paypal"
 */
$order->setState(Mage_Sales_Model_Order::STATE_PENDING_PAYMENT, true)->save();

/**
 * change order status to "Processing"
 */
$order->setState(Mage_Sales_Model_Order::STATE_PROCESSING, true)->save();

/**
 * change order status to "Completed"
 */
$order->setState(Mage_Sales_Model_Order::STATE_COMPLETE, true)->save();

/**
 * change order status to "Closed"
 */
$order->setState(Mage_Sales_Model_Order::STATE_CLOSED, true)->save();

/**
 * change order status to "Canceled"
 */
$order->setState(Mage_Sales_Model_Order::STATE_CANCELED, true)->save();

/**
 * change order status to "Held"
 */
$order->setState(Mage_Sales_Model_Order::STATE_HOLDED, true)->save();