1

I created 4 programmatically custom options. It is successfully display in cart page and also make successful order. I created module for that. Here its code.

path : vendor/addtocart/controller/index/index.php

<?php namespace Vendor\Addtocart\Controller\Index; use Magento\Framework\App\Action\Action; use Magento\Framework\App\Action\Context; use Magento\Framework\Data\Form\FormKey; use Magento\Checkout\Model\Cart; use Magento\Catalog\Model\Product; use Magento\Framework\View\Result\PageFactory; class Index extends \Magento\Framework\App\Action\Action { protected $formKey; protected $cart; protected $product; protected $_pageFactory; protected $_session; protected $serializer; protected $ProductRepository; protected $_responseFactory; public function __construct( \Magento\Framework\App\Action\Context $context, \Magento\Framework\Data\Form\FormKey $formKey, \Magento\Checkout\Model\Cart $cart, \Magento\Catalog\Model\Product $product, \Magento\Catalog\Model\ProductRepository $ProductRepository, \Magento\Customer\Model\Session $session, \Magento\Framework\Serialize\SerializerInterface $serializer, \Magento\Framework\View\Result\PageFactory $PageFactory, \Magento\Framework\App\ResponseFactory $responseFactory, array $data = []) { $this->_responseFactory = $responseFactory; $this->formKey = $formKey; $this->_pageFactory = $PageFactory; $this->cart = $cart; $this->serializer = $serializer; $this->product = $product; $this->ProductRepository = $ProductRepository; $this->_session = $session; parent::__construct($context); } public function execute() { $page = $this->_pageFactory->create(); $productId =1; $id = $this->_session->getId(); $additionalOptions['firstnamesku'] = [ 'label' => 'First Name', 'value' => 'chirag', ]; $additionalOptions['lnamesku'] = [ 'label' => 'Last Name', 'value' => 'parmar', ]; $additionalOptions['emailidsku'] = [ 'label' => 'Email ID', 'value' => '[email protected]', ]; $additionalOptions['phonenosku'] = [ 'label' => 'Phone No', 'value' => '1234567890', ]; if(!$this->_session->isLoggedIn()){ $params = array( 'form_key' => $this->formKey->getFormKey(), 'product' => $productId, //product Id 'qty' =>1 //quantity of product ); }else{ $params = array( 'form_key' => $this->formKey->getFormKey(), 'product' => $productId, //product Id 'qty' =>1, //quantity of product 'customer_id' =>$id ); } //Load the product based on productID $_product = $this->ProductRepository->getById($productId); $_product->addCustomOption('additional_options', $this->serializer->serialize($additionalOptions)); $this->cart->addProduct($_product, $params); $this->cart->save(); //return $page; $message = "Product have been successfully added to your Shopping Cart."; $this->messageManager->addSuccess($message); $accUrl = $this->_url->getUrl('checkout/cart/'); $this->_responseFactory->create()->setRedirect($accUrl)->sendResponse(); $this->setRefererUrl($accUrl); } } 

Now I hit this url : domainname.com/addtocart

Successfully add product to cart and redirect to cart page.

enter image description here

Placed order successsfully. Now also seen this order in admin->sales-> orders.

But the problem is I can not find this custom options in order details.

enter image description here

I also created observer for this. But not getting result as I want.

Vendor\Addtocart\etc\events.xml

<?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\Addtocart\Observer\OrderItemAdditionalOptions" /> </event> </config> 

Vendor\Addtocart\Observer\OrderItemAdditionalOptions.php

<?php namespace Vendor\Addtocart\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'); //print_r($additionalOptions); exit("======="); 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 echo 'Error!!: ' .$e->getMessage(); } } } 

I got error in this code. This code is just for information.

Anyone can help me to figured it out? Thanks in advance..

Edit:-

I saw that in database table "sales_order_item" fieldname "product_options"has this value :

{"info_buyRequest":{"product":1,"qty":1}}

Now I create 2 custom option from adminside and check database for other product. I got following code. If I put this code in that order, than it will give some data which i want :

{"info_buyRequest":{"uenc":"aHR0cDovLzEyNy4wLjAuMS9tMjM0L3N0cml2ZS1zaG91bGRlci1wYWNrLmh0bWw,","product":"2","selected_configurable_option":"","related_product":"","item":"2","options":{"1":"cparmar2","2":"rkhatri2"},"qty":"1"},"options":[{"label":"colorbox","value":"cparmar2","print_value":"cparmar2","option_id":"1","option_type":"field","option_value":"cparmar2","custom_view":false},{"label":"sizebox","value":"rkhatri2","print_value":"rkhatri2","option_id":"2","option_type":"field","option_value":"rkhatri2","custom_view":false}]}

3 Answers 3

1

Please try below code

create Event: Vendor\Addtocart\etc\events.xml

<?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="quote_to_order" instance="Vendor\Addtocart\Observer\OrderItemAdditionalOptions" /> </event> </config> 

and then create observer like this

Vendor\Addtocart\Observer\OrderItemAdditionalOptions.php

<?php namespace Vendor\Addtocart\Observer; use Magento\Framework\Event\ObserverInterface; use \Magento\Framework\Unserialize\Unserialize; use \Magento\Framework\Serialize\Serializer\Json; class OrderItemAdditionalOptions implements ObserverInterface { /** * @param \Magento\Framework\Event\Observer $observer */ protected $Unserialize; protected $Serializer; public function __construct( Unserialize $Unserialize, Json $Json ){ $this->Unserialize = $Unserialize; $this->Serializer = $Json; } 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; //130 } foreach ($order->getAllVisibleItems() as $orderItem) { $quoteItemId = $orderItem->getQuoteItemId(); $quoteItem = $quoteItems[$quoteItemId]; $additionalOptions = $quoteItem->getOptionByCode('additional_options'); // Get Order Item's other options $options = $orderItem->getProductOptions(); // Set additional options to Order Item if($this->isSerialized($additionalOptions->getValue())){ $options['options'] = $this->Unserialize->unserialize($additionalOptions->getValue()); }else{ $options['options'] = $this->Serializer->unserialize($additionalOptions->getValue()); } $orderItem->setProductOptions($options); } } catch (\Exception $e) { // catch error if any $e->getMessage(); } } private function isSerialized($value) { return (boolean) preg_match('/^((s|i|d|b|a|O|C):|N;)/', $value); } } ?> 

Hope this will help you. If it works please accept it.

3
  • Let me check it. @Ronak Commented Mar 18, 2020 at 10:07
  • And also run command bin/magento setup:upgrade and bin/magento setup:static-content:deploy -f Commented Mar 18, 2020 at 10:11
  • 1
    It works perfectly. I checked it. Commented Mar 18, 2020 at 10:29
0

I think you forgot $orderItem->save();

1
  • i tried it but its not working. I think problem is with $additionalOptions = $quoteItem->getOptionByCode('additional_options'); Commented Mar 17, 2020 at 9:40
0

It will append option into the column(product_options) of table (sales_order_item) and it will show in admin,email and pdf.

$orderItems = $order->getAllItems(); $serialNo = 123456; foreach($orderItems as $orderItem){ $orderItemId = $orderItem->getItemId(); $option = $orderItem->getProductOptions(); $serialOptions[] = array('label' => "Serial No.",'value' => $serialNo); $option['options'] = $serialOptions; $orderItem->setProductOptions($option)->save(); } 

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.