Set Additional Option Using Observer
We can use “sales_model_service_quote_submit_before” event to copy additional option from quote item.
First of all we need to define it in events.xml. Write following code in events.xml file.
<?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="sales_model_service_quote_submit_before">
<observer name="unique_name" instance="Vendor\ModuleName\Observer\OrderItemAdditionalOptions" />
</event>
</config>
After this create observer file and write following code in OrderItemAdditionalOptions.php file .
<?php
namespace Vendor\ModuleName\Observer;
use Magento\Framework\Event\ObserverInterface;
class OrderItemAdditionalOptions implements ObserverInterface
{
/**
* @param \Magento\Framework\Event\Observer $observer
*/
public function execute(\Magento\Framework\Event\Observer $observer)
{
try {
$quote = $observer->getQuote();
$order = $observer->getOrder();
$quoteItems = [];
// Map Quote Item with Quote Item Id
foreach ($quote->getAllVisibleItems() as $quoteItem) {
$quoteItems[$quoteItem->getId()] = $quoteItem;
}
foreach ($order->getAllVisibleItems() as $orderItem) {
$quoteItemId = $orderItem->getQuoteItemId();
$quoteItem = $quoteItems[$quoteItemId];
$additionalOptions = $quoteItem->getOptionByCode('additional_options');
if (count($additionalOptions) > 0) {
// Get Order Item's other options
$options = $orderItem->getProductOptions();
// Set additional options to Order Item
$options['additional_options'] = unserialize($additionalOptions->getValue());
$orderItem->setProductOptions($options);
}
}
} catch (\Exception $e) {
// catch error if any
}
}
}
Set Additional Option Using Plugin
We can use plugin for method convert in class Magento\Quote\Model\Quote\Item\ToOrderItem.
This method is executed when a quote item converts into order item.
First of all define plugin in di.xml of module.
<?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="Vendor\ModuleName\Plugin\ToOrderItem" sortOrder="1" />
</type>
</config>
After that create Plugin file and write following code in ToOrderItem.php file.
<?php
namespace Vendor\ModuleName\Plugin;
use Magento\Quote\Model\Quote\Item\ToOrderItem as QuoteToOrderItem;
class ToOrderItem
{
/**
* aroundConvert
*
* @param QuoteToOrderItem $subject
* @param \Closure $proceed
* @param \Magento\Quote\Model\Quote\Item $item
* @param array $data
*
* @return \Magento\Sales\Model\Order\Item
*/
public function aroundConvert(
QuoteToOrderItem $subject,
\Closure $proceed,
$item,
$data = []
) {
// Get Order Item
$orderItem = $proceed($item, $data);
// Get Quote Item's additional Options
$additionalOptions = $item->getOptionByCode('additional_options');
// Check if there is any additional options in Quote Item
if ($additionalOptions) {
// Get Order Item’s other options
$options = $orderItem->getProductOptions();
// Set additional options to Order Item
$options[‘additional_options’] = json_decode($additionalOptions->getValue());
$orderItem->setProductOptions($options);
}
return $orderItem;
}
}