Howto update order item's custom option in Magento?
Asked Answered
C

3

7

Is it possible to update a product custom option value from an order? I know it is possible when items are in cart (before checkout), but I'm not sure if it is possible in a order.

Our app is selling a service and we have a case when a required data is available after checkout only.

Conqueror answered 27/7, 2012 at 12:19 Comment(0)
H
20

It depends on the purpose of your customization. Order Item has custom options stored as serialized array and at any time it is possible for your to modify it.

Unlike quote item, in order item it has different name for retrieving them. The method is called getProductOptions()

Also there is another method that allows you to set them setProductOptions(array $options).

Here is some examples of this method usage in different test cases:

  1. If you need to store it only for internal code usage, you can just add option into array array and set it back:

    $existentOptions = $orderItem->getProductOptions();
    $existentOptions['your_custom_option'] = $yourCustomValue;
    $orderItem->setProductOptions($existentOptions);
    
  2. If you need to show your custom option in the printed document, you need to add your custom option into special option of options, that have structure for showing up its value on the frontend, pdf documents, items list

    $existentOptions = $orderItem->getProductOptions();
    if (!isset($existentOptions['additional_options'])) {
        // If special options of options array is set before, create it.
        $existentOptions['additional_options'] = array(); 
    }
    // Adding visible options value
    $existentOptions['additional_options'][] = array(
        'label' => 'Your Option Label',
        'value' => 'Your Option Value',
        // The last one that is optional (if not set, value is used)
        'print_value' => 'Your Option Value shown in printed documents'
    );
    $orderItem->setProductOptions($existentOptions);
    

Both of these methods even can be combined, if you need one option that is visible to customer and another option that is required for your code.

Also don't forget to save your order/order item after you deed your modifications.

Advice

If you save order and haven't modified the order model itself, you need at least change some data in it, to force order model save all sub entities. For making this possible, you even can just set some non existent attribute.

Case when save operation will not be invoked:

$order->load($id);
$orderItem->getItemById($itemId);
$orderItem->setSomething(111);
$order->save(); // Order Item will not be saved!!

Case when save operation will be invoked:

$order->load($id);
$orderItem->getItemById($itemId);
$orderItem->setSomething(111);
$order->setSomeNonExistentProperty(true); 
$order->save(); // Now it will be saved

Have fun with Magento development

Hogarth answered 27/7, 2012 at 14:8 Comment(2)
Thank you so much. I have spend around one week for this task. Its working well. Thanks againAbsorptivity
@Ivan Chepurnyi: I think you need to save as well from "$orderItem->setProductOptions($existentOptions);" to "$orderItem->setProductOptions($existentOptions)->save();"Chromolithograph
L
0

You can do it on addProduct function, before to order.

    try {
        $cart = Mage::getModel('checkout/cart');
        $previousItemCount = $cart->getQuote()->getItemsCount();

        if ($previousItemCount <= 0) {
            $cart->init();
        }

        $params = $this->getRequest()->getParams();
        $product = Mage::getModel('catalog/product')->load($params['product_id']);

        $date = explode('/', $params['product_dtinvoice']);
        $date = array(
            'month' => $date[0],
            'day' => $date[1],
            'year' => $date[2],
        );

        $cart->addProduct(
            $product,
            new Varien_Object(array(
                'product' => $product->getId(),
                'qty' => 1,
                'options' => array(
                    '4' => array(
                        'month' => $date['month'],
                        'day' => $date['day'],
                        'year' => $date['year']
                    ),
                    '2' => $params['product_ean'],
                    '3' => $params['product_serialnumber'],
                    '1' => $params['product_seller'],
                ),
            ))
        );

        $cart->save();

        if ($previousItemCount < $cart->getQuote()->getItemsCount()) {
            $return = array('result' => true, 'msg' => '');
        } else {
            $return = array('result' => false, 'msg' => 'Did not possible to add this product to cart. Please contact the administrator');
        }

        $this->getResponse()->setBody(Mage::helper('core')->jsonEncode($return));
    } catch(Exception $e) {
        Mage::throwException($e->getMessage());
    }
Like answered 22/3, 2016 at 17:10 Comment(0)
D
0

I answer to an old post. It will maybe help someone.

To improve Ivan's answer, you need to save item after update it. With a $orderItem->save();

Here my code:

$orderId = "your_order_id";
$order = Mage::getModel('sales/order')->load($orderId);
$orderAllItems = $order->getAllItems();
foreach ($orderAllItems as $item) {

    $existentOptions = $item->getProductOptions();
    if (!isset($existentOptions['additional_options'])) {
        $existentOptions['additional_options'] = array(); 
    }

    $existentOptions['additional_options'][] = array(
        'label' => "Group option title",
        'value' => "Select option title + for example price",
    );
    $item->setProductOptions($existentOptions);
    $item->save();

}

Moreover, for your tests, you can clear the options for your test order by running that:

$existentOptions['additional_options'] = array();

Finally, you can find custom options datas in the product ordered to complete your $existentOptions['additional_options'][] :

$orderAllItems = $order->getAllItems();
foreach ($orderAllItems as $item) {

    $product = Mage::getModel('catalog/product')->load($item->getProductId());
    foreach ($product->getOptions() as $o) {
        // ...
    }
}

Axel

Disheveled answered 12/1, 2023 at 15:11 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.