2

I tried to change the attribute value of Product's attribute [cart_status] once we click on Place Order button and make the payment.

Means Only if order is successfull. I guess this is correct event : <sales_order_payment_capture> as i saw here

config.xml :

<sales_order_payment_capture>
    <observers>
        <example_place_order>
            <class>Amasty_Example_Model_Observer</class>
            <method>PlaceOrder</method>
        </example_place_order>
    </observers>
</sales_order_payment_capture>

app/code/local/Amasty/Example/Model - Observer.php

public function PlaceOrder($observer)
{ 
    $product = $observer->getEvent()->getProduct(); 
    Mage::getSingleton('catalog/product_action')->updateAttributes(
    array(
        $product->getId()),
        array('cart_status' => 0),
        $storeId = 0
    );
}

Result :

Fatal error : Call to a member function getId() on a non-object in array($product->getId()),

2 Answers 2

2

Try to use checkout_onepage_controller_success_action observer

<checkout_onepage_controller_success_action>
    <observers>
        <update_product_attribute>
            <class>YourPackageName_YourModuleName_Model_Observer</class>
            <method>updateProductAttribute</method>
        </update_product_attribute>
    </observers>
</checkout_onepage_controller_success_action>

Observer:

<?php
    public function updateProductAttribute($observer){
        $orderIds = $observer->getEvent()->getOrderIds();
        if (empty($orderIds) || !is_array($orderIds)) {
            return;
        }
        foreach ($orderIds as $orderId) {
            $order = Mage::getModel('sales/order')->load($orderId);
            $items = $order->getAllVisibleItems();
            foreach($items as $i){
                $product = $i->getProduct();
                $product->setCartStatus(0);
                $product->save();
            }
        }
    }
?>
1

Just as improvement for answer above ... for better performance please avoid calling save, load or delete inside a loop.

In this case you can just collect product IDs and useMage::getSingleton('catalog/product_action')->updateAttributes() as written in your question.

public function updateProductAttribute($observer)
{
    $orderIds = $observer->getEvent()->getOrderIds();
    if (empty($orderIds) || !is_array($orderIds)) {
        return;
    }

    $productIds = array();

    foreach ($orderIds as $orderId) {
        $order = Mage::getModel('sales/order')->load($orderId);
        $items = $order->getAllVisibleItems();
        foreach ($items as $i) {
            $productIds[] = $i->getProduct()->getId();
        }
    }

    Mage::getSingleton('catalog/product_action')->updateAttributes(
        $productIds,
        array('cart_status' => 0),
        $storeId = 0
    );
}

Maybe to save you some time ... you're dealing with a lot of events/observer at the moment, what is the prefered way instead of rewriting classes. So this may help you ...

1.) find available events (just do it on test environment!)

Open app/Mage.php and add one line to dispatchEvent() method

public static function dispatchEvent($name, array $data = array())
{
    Mage::log($name, null, $name . '.log', true);
    ...
}

To get the data from this event you can also do this here:

public static function dispatchEvent($name, array $data = array())
{
    if ($name == 'event_you_want_to_log') {
        Mage::log(array($name, $data), null, $name . '.log', true);
    }
    ...
}

Now, do the action you want to observe and comment Mage::log again.

2.) get data from observer

In this case you'll get something like this:

2017-06-15T07:34:22+00:00 DEBUG (7): Varien_Event_Observer Object
(
    [_data:protected] => Array
        (
            [event] => Varien_Event Object
                (
                    ...

                    [_data:protected] => Array
                        (
                            [order_ids] => Array
                                (
                                    [0] => 15
                                )

                            [name] => checkout_onepage_controller_success_action
                        )
                    ...
                )

            [order_ids] => Array
                (
                    [0] => 15
                )
        )
    ...
)

You can access data with either $observer->getEvent()->getOrderIds() or $observer->getOrderIds().

6
  • Thanks for helping me to make things better, i updated your code, now i can able to place an order successfully, but attribute value is not changing.... when you get free time, please check once.....
    – user52996
    Jun 15, 2017 at 9:31
  • Just was a typo - missing ) ... please check again.
    – sv3n
    Jun 15, 2017 at 9:39
  • yes buddy , i tried that before , still i faced same...... we faced similar issue last time here : magento.stackexchange.com/questions/178802/…
    – user52996
    Jun 15, 2017 at 9:41
  • Another "typo" ... please compare code from your question ... one array to much ;)
    – sv3n
    Jun 15, 2017 at 10:09
  • 1
    Its OK, other answer is correct ... was just to improve ;)
    – sv3n
    Jun 15, 2017 at 10:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.