sales_order_save_commit_after event triggered twice?

All we need is an easy explanation of the problem, so here it is.

I registered an observer for the sales_order_save_commit_after event to be notified when a new order comes in. This works fine but the event is triggered two times in a row with the same order.

My config.xml

        <sales_order_save_commit_after>
            <observers>
                <unique_sales_order_save_commit_after>
                    <type>singleton</type>
                    <class>mymodule/observer</class>
                    <method>export</method>
                </unique_sales_order_save_commit_after>
            </observers>
        </sales_order_save_commit_after>

How can I check if it’s the first time or which other event would be better?

Update

I also tried the sales_order_invoice_pay event (found on SO) but that is not triggered for me.

How to solve :

I know you bored from this bug, So we are here to help you! Take a deep breath and look at the explanation of your problem. We have many solutions to this problem, But we recommend you to use the first method because it is tested & true method that will 100% work for you.

Method 1

Try using sales_order_save_after instead, it’s triggered right after an order is saved in the database and returns the full order object

Why this event is triggered twice, I’m not sure. It’s an an event triggered from Core/Model/Abstract.php method afterCommitCallback, seems that Magento is saving / committing 2 different data sets on the the Order model. Perhaps once the order itself and once the status history.

Is there any difference between the data being parsed on the 2 events that might give a clue to where it’s called from?

Method 2

If anyone is still having problem with this, I found out how magento deals with this.

In the called method you can take the order and set a flag on it.

Ex:

public function export(Varien_Event_Observer $observer) {
    $order = $observer->getEvent()->getOrder();
    if($order->getExportProcessed()){ //check if flag is already set.
        return;
    }

    // your part of code

    //"setExportProcessed" can be called anything you want as it's getting set magically by magento on our $order object.
    $order->setExportProcessed(true); 
}

In app/code/core/Mage/Cataloginventory/Model/Observer.php

function subtractQuoteInventory(Varien_Event_Observer $observer)

is an example of how magento deals with this.

Method 3

I changed the event to sales_order_place_after. This works fine.

Method 4

public function sendEmail(Varien_Event_Observer $observer) {
    if(!Mage::registry('varien_event')){

        //your code here...

        Mage::register('varien_event',true);

    }
}

The Bove code is working for me.

Note: Use and implement method 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply