Skip to content

Adding 2 configurable products to cart with custom options causes Integrity constraint violation #7488

@pguedesbr

Description

@pguedesbr

Preconditions

  1. Magento 2.1.1
  2. PHP 5.6.25
  3. MySQL 5.6.23

Steps to reproduce

  1. Have a configurable product like a t-shirt with 2 attributes (size/color)
  2. Create a controller to add 2 of the same product to the cart, except each one will have a custom additional option, resulting in 2 different cart items
  3. In the loop to add these products, insert additional options to the product on the fly
	$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();

Expected result

  1. 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)

image

Actual result

  1. Whe cart is saved, an exception is thrown regarding the quote_item_option INSERT query.
  2. 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 (?, ?, ?)

  1. 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.

For 2.1.10 version and later it can be reproduced with the little different scenario:

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    Component: CatalogIssue: Clear DescriptionGate 2 Passed. Manual verification of the issue description passedIssue: ConfirmedGate 3 Passed. Manual verification of the issue completed. Issue is confirmedIssue: Format is validGate 1 Passed. Automatic verification of issue format passedIssue: Ready for WorkGate 4. Acknowledged. Issue is added to backlog and ready for developmentReproduced on 2.1.xThe issue has been reproduced on latest 2.1 releaseReproduced on 2.2.xThe issue has been reproduced on latest 2.2 releaseReproduced on 2.3.xThe issue has been reproduced on latest 2.3 releasebug report

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions