4

We are trying to add custom option or custom value in quote item so that we can also get it in order item.

We are able to add custom value in quote using following code but it is get returning value in order item

  $quote = $this->quoteRepository->getActive($cartId);
    foreach ($quote->getAllItems() as $item) {
            $item->setCustomValue(1);
            $item->save();

     }
  • Did you ever find a solution to this? – jamil Jan 17 '18 at 16:13
3

You can achieve by a plugin in Magento 2.2.*

First of all, we need to create an observer file and one Magento event file to implement this functionality.

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
    <event name="catalog_product_load_after">
        <observer name="set_additional_options" instance="CompanyName\ModuleName\Model\SetAdditionalOptions" />
    </event>    
</config>

Once you have created this file, now you need to Create another file and named as: CompanyName\ModuleName/Model/SetAdditionalOptions.php

<?php
namespace CompanyName\ModuleName\Model;

use Magento\Framework\Event\ObserverInterface;
use Magento\Framework\App\RequestInterface;
use Magento\Framework\App\ObjectManager;
use Magento\Framework\Serialize\Serializer\Json;

class SetAdditionalOptions implements ObserverInterface
{
    protected $_request;    
    public function __construct(RequestInterface $request, Json $serializer = null) 
    {
        $this->_request = $request;
        $this->serializer = $serializer ?: \Magento\Framework\App\ObjectManager::getInstance()
            ->get(\Magento\Framework\Serialize\Serializer\Json::class);
    }

    /**
     * @param \Magento\Framework\Event\Observer $observer
     */
    public function execute(\Magento\Framework\Event\Observer $observer)
    {
        // Check and set information according to your need
        $product = $observer->getProduct();                    
        if ($this->_request->getFullActionName() == 'checkout_cart_add') { //checking when product is adding to cart
            $product = $observer->getProduct();
            $additionalOptions = [];
            $additionalOptions[] = array(
                'label' => "Release Date", //Custom option label
                'value' => $product->getReleaseDate(), //Custom option value
            );                        
            $product->addCustomOption('additional_options', $this->serializer->serialize($additionalOptions));
        }
    }

}

Now, We need to create a plugin for the retrieve custom option from cart to order.

First We need to create di.xml.

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Magento\Quote\Model\Quote\Item\ToOrderItem">
        <plugin name="unique_name" type="CompanyName\ModuleName\Model\Plugin\Quote\ToOrderItem" sortOrder="1" />
    </type>
</config>

Once you have created this file, now you need to Create another file and named as: CompanyName\ModuleName\Model\Plugin\Quote\ToOrderItem.php

<?php
namespace ZCompanyName\ModuleName\Model\Plugin\Quote;

use Magento\Quote\Model\Quote\Item\ToOrderItem as QuoteToOrderItem;
use Magento\Framework\Serialize\Serializer\Json;
class ToOrderItem
{    
    public function __construct(Json $serializer = null) 
    {        
        $this->serializer = $serializer ?: \Magento\Framework\App\ObjectManager::getInstance()
            ->get(\Magento\Framework\Serialize\Serializer\Json::class);
    }

    public function aroundConvert(QuoteToOrderItem $subject,
        \Closure $proceed,
        $item,
        $data = []
    ) {
        // Get Order Item
        $orderItem = $proceed($item, $data);               

        $additionalOptions = $item->getOptionByCode('additional_options');        
        // Check if there is any additional options in Quote Item                    
        if (count($additionalOptions) > 0) {
            // Get Order Item's other options
            $options = $orderItem->getProductOptions();
            // Set additional options to Order Item
            $options['additional_options'] = $this->serializer->unserialize($additionalOptions->getValue());
            $orderItem->setProductOptions($options);
        }

        return $orderItem;
    }
}

  • I have added the di.xml but after that, I could not able to place an order, is throw me the "An error occurred on the server. Please try to place the order again", kindly check and update the answer – senthil May 10 '18 at 11:47
  • Which version are you use? – shah dhairya May 11 '18 at 13:08
  • Thanks for the detailed and under-appreciated answer shah, I needed something similar and slightly modified your code for my use. – jamil Jul 27 '18 at 16:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.