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}]}

asked Mar 17, 2020 at 7:59

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.

answered Mar 18, 2020 at 10:06
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();

answered Mar 17, 2020 at 9:18
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(); 
}
answered Dec 5, 2022 at 10:21

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.