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