$storeId = $this->_objectManager->get('Magento\Store\Model\StoreManagerInterface')->getStore()->getId();
$cart = $this->_objectManager->get('\Magento\Checkout\Model\Cart')->getStore()->getId();
$productId = 115; // Configurable Product
$colorAttributeId = 90;
$color = 10; // white
$sizeAttributeId = 135;
$size = 13; // small
$customOptionValues = [
'print_style_1',
'print_style_2',
];
foreach ($customOptionValues as $customOptionValue) {
$product = $this->_objectManager->create('Magento\Catalog\Model\Product')->setStoreId($storeId)->load($productId);
// prepare buyRequest
$buyRequest = new \Magento\Framework\DataObject();
$buyRequest->setData([
'qty' => 1,
'super_attribute' => [
$colorAttributeId => $color,
$sizeAttributeId => $size,
],
]);
$additionalOptions = array();
if ($originalAdditionalOptions = $product->getCustomOption('additional_options'))
{
$additionalOptions = (array) unserialize($originalAdditionalOptions->getValue());
}
$additionalOptions['print_style'] = [
'label' => 'Print Style',
'value' => $customOptionValue,
];
// add the additional options array with the option code additional_options
$product->addCustomOption('additional_options', serialize($additionalOptions));
$cart->addProduct($product, $buyRequest);
}
$cart->save();
$cart->getQuote()->setTotalsCollectedFlag(false)->collectTotals()->save();

SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (`magento`.`quote_item_option`, CONSTRAINT `QUOTE_ITEM_OPTION_ITEM_ID_QUOTE_ITEM_ITEM_ID` FOREIGN KEY (`item_id`) REFERENCES `quote_item` (`item_id`) ON DELETE CASCADE), query was: INSERT INTO `quote_item_option` (`product_id`, `code`, `value`) VALUES (?, ?, ?)
$storeId = $this->_objectManager->get('Magento\Store\Model\StoreManagerInterface')->getStore()->getId();
/* @var \Magento\Checkout\Model\Cart $cart */
$cart = $this->_objectManager->get('\Magento\Checkout\Model\Cart');
$productId = 67; // Configurable Product
$colorAttributeId = 93;
$color = 49; // white
$sizeAttributeId = 141;
$size = 167; // small
$customOptionId = 1;
$customOptionValues = [
'1',
'2',
];
foreach ($customOptionValues as $customOptionValue) {
/* @var \Magento\Catalog\Model\Product $product */
$product = $this->_objectManager->create('Magento\Catalog\Model\Product')->setStoreId($storeId)->load($productId);
// prepare buyRequest
$buyRequest = new \Magento\Framework\DataObject();
$buyRequest->setData([
'qty' => 1,
'super_attribute' => [
$sizeAttributeId => $size,
$colorAttributeId => $color,
],
'options' => [
$customOptionId => $customOptionValue,
]
]);
$cart->addProduct($product, $buyRequest);
}
$cart->save();
$cart->getQuote()->setTotalsCollectedFlag(false)->collectTotals()->save();
Is there a workaroud for this issue in order to add consecutive products (with custom options) to the cart? Maybe some way of reseting the cart before adding the second product?
I'm almost sure the error is due to some mixing/garbage information from the first added product affecting the next one to be added.
This is far from acceptable but since there's no update or aknowledgement of this issue, here is my workaround to insert more than one product with custom options to the cart:
Hi @veloraven
Did you guys have the chance to take a look into this issue? This is still present in 2.1.3
Were you able to reproduce it?
The sample code in the OP uses object manager to make it easier to copy/reproduce. The actual code I'm using uses DI as best practices suggest.
Problem still present in 2.1.4... :-(
I found a quick fix. The problem is the item is not set correctly on item option.
I will try to track this bug deeper, but at least for the moment instead of looping and redirecting in your controller you can create some plugin on :
Magento\Quote\Model\Quote\Item::saveItemOption (around line 732 : magento 2.1.4)
/**
* Save item options
*
* @return $this
*/
public function saveItemOptions()
{
foreach ($this->_options as $index => $option) {
if ($option->isDeleted()) {
$option->delete();
unset($this->_options[$index]);
unset($this->_optionsByCode[$option->getCode()]);
} else {
// Add this code to test if item is set or not
if (!$option->getItem() || !$option->getItem()->getId()) {
$option->setItem($this);
}
$option->save();
}
}
$this->_flagOptionsSaved = true;
// Report to watchers that options were saved
return $this;
}
There must be an issue during the process of addProduct to the quote.
I also faced similar issue with few customized product. In my case the add to cart with custom options work fine. But I get the same exact issue when I reorder the same customized product.
As @eInyzant suggested I can add option to the quote item by using plugin on saveItemOptions(), but it doesn't help in my case as I need to differentiate between the items (customized and non-customized) before Magento adds the product to the quote at the time of reorder. For this I have to use addCustomOption() on the product instead of addOption() on the quote item. But this throws the foreign key constraint error.
Any suggestions on this why it's happening on reorder? We are stuck with the development due to this issue right now. Any fix or suggestion would be a life saver for us now.
Edit
We face this issue on both 2.1.3 and 2.1.5.
This is caused by cache corruption.
Product::_customOptions are overwritten in Quote::addProduct() and on subsequent calls options with quote item set are used.
The easiest fix is to clone a product instance in _prepareProduct() (Magento\ConfigurableProduct\Model\Product\Type\Configurable:958):
if ($subProduct) {
$subProduct = $this->getProductByAttributes($attributes, $product);
}
change to:
if ($subProduct) {
$subProduct = clone $this->getProductByAttributes($attributes, $product);
}
Not sure if there is some better solution for the problem. Let me know if more details are needed.
Any update on this issue? In which version will be resolved?
Also running into this problem. Need to add the product in two separate requests. Above solutions did not fix it.
@pguedesbr, thank you for your report.
We've created internal ticket(s) MAGETWO-84526 to track progress on the issue.
[Magento 2.2.0]
I found a quick fix in Magento\Checkout\Controller\Cart\Add::_initProduct()
Before:
return $this->productRepository->getById($productId, false, $storeId);
After:
return $this->productRepository->getById($productId, false, $storeId, true);
In fact I have a plugin (aroundExecute) on this controller with own _initProduct method. The plugin process each product except the last one (the last one is processed by Magento\Checkout\Controller\Cart\Add). I copied most of logic (remember to do not save a cart in a plugin) from Magento\Checkout\Controller\Cart\Add::execute and before return $proceed(); I set proper request params for last item.
More understanding the custom option issue, I have a problem, the configurable product's custom options are missing when click 'add to cart' button. But only a few products are missing, we need deleted the option and re-created them to resume the function. But we have found the issue still occurs after the day but a different configurable product.
Thanks
Kalun
Have any found the solution i am also facing the same issue ?
thanks
If you debug inside saveItemOptions() you can see that $option has item_id equal to null.
And when you save option, the item_id was missing.
The solution is add a plugin to set item_id equal to current quoteItem
@magento-engcom-team could you please check the status of MAGETWO-84526 ? Thanks
Hi,
we are facing the exact same problem on 2.2.5.
The scenario:
1) add configurable product with custom option value1 into cart
2) add same configuration (same super attributes) with custom option value2 into cart
3) create order -> at this step all is good because we are adding 1 product at a time
now the fun step:
4) go to the order and reorder
inspect the quote table and more specific quote_item_option table and see how for the second simple item there are no options
If anyone has exact code/patch for a workaround would be great.
Hello @pguedesbr @vflirt @elioermini
Thank you for contribution and collaboration!
The initially described issue was fixed in the scope of #13036 PR by @vinayshah
The changes have been delivered into develop branch
Hi!, Some solution? Same problem in magento 2.2.5.
Understanding this issue is closed, however i'd like to comment that the fix for this issue may have introduced a different problem.
I have a very similar scenario where I add a configurable product to the cart via code twice. The same product, but with different lengths. I noticed that when adding the second product, it used the options of the first product. I triple checked my code. It seems like a cache issue with a product instance. Using the above solution - cloning a product instance fixes the problem for me and adding the same product twice to cart shows both products.
Most helpful comment
This is caused by cache corruption.
Product::_customOptions are overwritten in Quote::addProduct() and on subsequent calls options with quote item set are used.
The easiest fix is to clone a product instance in _prepareProduct() (Magento\ConfigurableProduct\Model\Product\Type\Configurable:958):
change to:
Not sure if there is some better solution for the problem. Let me know if more details are needed.