Domanda

I am facing some problems when trying to add to cart multiple configurable products in 1 single request

We have tuned product list page, to add the required form values for this kind of request (configurable child options, etc...) and this values are sent to a custom controller action

This is the controller code

<?php
namespace Vendor\Module\Controller\Add;

class Cart extends \Magento\Framework\App\Action\Action
{
    protected $_cart;
    protected $productRepository;
    protected $formKeyValidator;

    public function __construct(
        \Magento\Framework\App\Action\Context $context,
        \Magento\Checkout\Model\Cart $cart,
        \Magento\Catalog\Api\ProductRepositoryInterface $productRepository,
        \Magento\Framework\Data\Form\FormKey\Validator $formKeyValidator
    ) {

        $this->_cart = $cart;
        $this->productRepository = $productRepository;
        $this->_formKeyValidator = $formKeyValidator;

        return parent::__construct($context);
    }

    public function execute()
    {
        if (!$this->_formKeyValidator->validate($this->getRequest())) {
            return $this->resultRedirectFactory->create()->setPath('*/*/');
        }

        $qtys       = $this->getRequest()->getParam('qty');
        $childIds   = $this->getRequest()->getParam('child_ids');

        $add = array();
        foreach ($qtys as $parentId => $array) {
            if (is_array($array)) {
                foreach ($array as $attributeId => $child) {
                    foreach ($child as $childId => $value) {
                        if ($value != 0) {
                            $add[$parentId][$attributeId][$childId] = $value;
                        }
                    }
                }
            } else {
                // simple products?
                // @todo
            }
        }

        foreach ($add as $productId => $data) {
            $_product = $this->productRepository->getById($productId);

            foreach ($data as $attributeId => $child) {
                foreach ($child as $childId => $qty) {
                    $options = array(
                        $attributeId => $childId,
                    );

                    $params = array(
                        'form_key' => $this->getRequest()->getParam('form_key'),
                        'product' => $productId,
                        'super_attribute' => $options,
                        'qty' => $qty,
                        'selected_configurable_option' => $childIds[$productId][$attributeId][$childId],
                    );
                    $this->_cart->addProduct($_product, $params);
                }
            }
        }
        $this->_cart->save();
        return $this->resultRedirectFactory->create()->setPath('checkout/cart');
    }
}

This are the results I am getting

  • when adding different children of same configurable product only the first is being added to cart (with qtys of others being added to that first child)
  • when adding different configurable products (with any children) product prices are displayed correctly only in the first configurable product... the others show price 0€

Assuming the data in both $qtys & $childIds arrays are correct (I have validated them against data sent from a configurable product view add to cart request, and they seem ok), can you lead me to the error in the controller code, or any missing code required to be added?

È stato utile?

Soluzione

As reported here https://magento.stackexchange.com/a/110666/3566, problem was we have to create each time new product object

I have tried different ways, trying to avoid using $this->_objectManager

Using \Magento\Catalog\Model\ProductFactory was the only way to make that work

So, apart from adding the new dependency in constructor, with this code changes...

    foreach ($add as $productId => $data) {
        foreach ($data as $attributeId => $child) {
            foreach ($child as $childId => $qty) {
                // @see https://magento.stackexchange.com/a/110666/3566 -> reload product
                $_product = $this->productFactory->create()->setStoreId($storeId)->load($productId);
                $options = array(
                    $attributeId => $childId,
                );

                $params = array(
                    'form_key' => $this->getRequest()->getParam('form_key'),
                    'product' => $productId,
                    'super_attribute' => $options,
                    'qty' => $qty,
                    'selected_configurable_option' => $childIds[$productId][$attributeId][$childId],
                );

                $this->_cart->addProduct($_product, $params);
                $this->_cart->save();
            }
        }
    }

All products are being added to cart correctly, although I have seen some pricing issues (only first configurable product has the right price & the others print 0€), but that's another story

Altri suggerimenti

You need to keep cart save logic outside the foreach loop, So your price issue will be resolved,

    foreach ($add as $productId => $data) {
        foreach ($data as $attributeId => $child) {
            foreach ($child as $childId => $qty) {
                // @see https://magento.stackexchange.com/a/110666/3566 -> reload product
                $_product = $this->productFactory->create()->setStoreId($storeId)->load($productId);
                $options = array(
                    $attributeId => $childId,
                );

                $params = array(
                    'form_key' => $this->getRequest()->getParam('form_key'),
                    'product' => $productId,
                    'super_attribute' => $options,
                    'qty' => $qty,
                    'selected_configurable_option' => $childIds[$productId][$attributeId][$childId],
                );

                $this->_cart->addProduct($_product, $params);
            }
        }
    }
  $this->_cart->save();
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a magento.stackexchange
scroll top