cancel
Showing results for 
Search instead for 
Did you mean: 

Adding 2 configurable products to cart with custom options causes Integrity constraint violtion

Adding 2 configurable products to cart with custom options causes Integrity constraint violtion

I have a controller that receives custom options for a specific configurable product. For each custom option, I must add the product to the cart with such custom additional option. In the end, I want as many cart items as the number of custom options submitted.

 

The problem is, because im adding the same configurable product more than once (although with different custom options) in the same script execution, something is messing up when the cart is saved.

 

At first, I think this is a Magento 2.x bug. I've even opened an issue in Github here: https://github.com/magento/magento2/issues/7488

 

But maybe its just a simple detail I'm missing, thats why I wonder if anybody could help with this.

 

Bellow is a test script to illustrate the problem.

 

$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();

Upon $cart->save() there should be 2 products in the cart, each one with the same configurable attribute options, but with distinct custom additional options (Print style)

 

Instead, when the cart is saved, an exception is thrown regarding the quote_item_option INSERT query.

Notice the insert query for the item option is missing the 'item_id' column

 

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 (?, ?, ?)

 

If you add one product with custom option A in one HTTP request, and then do another HTTP request to add the same product with custom option B, there will be no errors. This only happens when products are added to cart in the same HTTP request.

 

1 REPLY 1

Re: Adding 2 configurable products to cart with custom options causes Integrity constraint violtion

Hi Roman, thanks for the reply!

 

Unfortunately we're building a heavy specific module and we mustn't use other module for this specific task.

Would you be able to shed a light on the issue I've described in the first post?

 

Is there something I'm missing for adding consecutive products 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.