1

I want to make adding to the shopping cart as a separate item on every action of clicking to a button Add to Cart. If the customer clicks Add to Cart a couple of times he/she should see different items in the shopping cart with qty 1.

I know about this question but this is not having an answer.

So is it possible to somehow achieve this?

5
  • Yes this is achievable.. Do you want this for simple product ?
    – aravind
    Oct 29, 2019 at 9:55
  • @aravind I want this for all product types.
    – underser
    Oct 29, 2019 at 9:56
  • I have done this task only for simple products and configurable..
    – aravind
    Oct 29, 2019 at 9:57
  • @aravind, please share your knowledge about simple and configurable, I'll try to adapt it for other products. Thank.
    – underser
    Oct 29, 2019 at 11:11
  • have you created plugin with afterRepresentProduct ? as mentioned in link provided?
    – aravind
    Oct 29, 2019 at 11:31

2 Answers 2

2

Create di.xml in your custom module,

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd" >
    <type name="Magento\Quote\Model\Quote\Item">
        <plugin name="beforeDispatch" type="Vendor\Module\Plugin\Model\Quote\ItemPlugin" sortOrder="1" disabled="false"/>
    </type>
</config>

Create After Method for representProduct,

<?php
namespace Vendor\Module\Plugin\Model\Quote;

class ItemPlugin
{
    public function afterRepresentProduct(\Magento\Quote\Model\Quote\Item $subject, $result)
    {
        $result = false;
        return $result;
    }
}
3
0

Overide form.phtml in vendor/magento/module_catalog/templates/product/view/form.phtml, and change form action to custom controller.

app/design/frontend/Vendor/Module/Magento_Catalog/templates/product/view/form.phtml

<?php $_helper = $this->helper('Magento\Catalog\Helper\Output'); ?>
<?php $_product = $block->getProduct();
    $formSubmitUrl = $this->getUrl('routeId/path/controller');
?>

<div class="product-add-form">
    <form data-product-sku="<?= $block->escapeHtml($_product->getSku()) ?>"
          action="<?= /* @NoEscape */ $formSubmitUrl ?>" method="post"
          id="product_addtocart_form"<?php if ($_product->getOptions()): ?> enctype="multipart/form-data"<?php endif; ?>>
        <input type="hidden" name="product" value="<?= /* @escapeNotVerified */ $_product->getId() ?>" />
        <input type="hidden" name="selected_configurable_option" value="" />
        <input type="hidden" name="related_product" id="related-products-field" value="" />
        <?= $block->getBlockHtml('formkey') ?>
        <?= $block->getChildHtml('form_top') ?>
        <?php if (!$block->hasOptions()):?>
            <?= $block->getChildHtml('product_info_form_content') ?>
        <?php else:?>
            <?php if ($_product->isSaleable() && $block->getOptionsContainer() == 'container1'):?>
                <?= $block->getChildChildHtml('options_container') ?>
            <?php endif;?>
        <?php endif; ?>

        <?php if ($_product->isSaleable() && $block->hasOptions() && $block->getOptionsContainer() == 'container2'):?>
            <?= $block->getChildChildHtml('options_container') ?>
        <?php endif;?>
        <?= $block->getChildHtml('form_bottom') ?>
    </form>
</div>
<script>
    require([
        'jquery',
        'priceBox'
    ], function($){
        var dataPriceBoxSelector = '[data-role=priceBox]',
            dataProductIdSelector = '[data-product-id=<?= $block->escapeHtml($_product->getId()) ?>]',
            priceBoxes = $(dataPriceBoxSelector + dataProductIdSelector);

        priceBoxes = priceBoxes.filter(function(index, elem){
            return !$(elem).find('.price-from').length;
        });

        priceBoxes.priceBox({'priceConfig': <?= /* @escapeNotVerified */ $block->getJsonConfig() ?>});
    });
</script>

Then create app/code/Vendor/Module/etc/frontend/routes.xml for controller in custom module,

<?xml version="1.0" ?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd">
    <router id="standard">
        <route frontName="yourfrontname" id="yourfrontname">
            <module name="Vendor_Module"/>
        </route>
    </router>
</config>

Then in controller add the logic,

<?php

namespace Vendor\Module\Controller\Index;


use Magento\Catalog\Model\ProductRepository;
use Magento\Checkout\Model\Cart as CustomerCart;
use Magento\Framework\Data\Form\FormKey;
use Magento\Catalog\Model\ProductFactory;

class YourController extends \Magento\Checkout\Controller\Cart
{

    /**
 * @param \Magento\Framework\App\Action\Context $context
 */
public function __construct(
    ProductRepository $productRepository,
    FormKey $formKey,
    ProductFactory $product,
    \Magento\Framework\App\Action\Context $context,
    \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
    \Magento\Checkout\Model\Session $checkoutSession,
    \Magento\Store\Model\StoreManagerInterface $storeManager,
    \Magento\Framework\Data\Form\FormKey\Validator $formKeyValidator,
    CustomerCart $cart
) {
    parent::__construct(
        $context,
        $scopeConfig,
        $checkoutSession,
        $storeManager,
        $formKeyValidator,
        $cart
    );
    $this->productRepository = $productRepository;
    $this->formKey = $formKey;
    $this->product = $product;
}


  /**
 * Initialize product instance from request data
 *
 * @return \Magento\Catalog\Model\Product|false
 */
protected function _initProduct()
{
    $productId = (int)$this->getRequest()->getParam('product');
    if ($productId) {
        $storeId = $this->_objectManager->get(
            \Magento\Store\Model\StoreManagerInterface::class
        )->getStore()->getId();
        try {
            return $this->productRepository->getById($productId, false, $storeId);
        } catch (NoSuchEntityException $e) {
            return false;
        }
    }
    return false;
}

/**
 * Add product to shopping cart action
 *
 * @return \Magento\Framework\Controller\Result\Redirect
 * @SuppressWarnings(PHPMD.CyclomaticComplexity)
 */
public function execute()
{
    $postValues = $this->getRequest()->getPostValue();
    $productId = $postValues['product'];
    $formKey = $postValues['form_key'];
    $qty = $postValues['qty'];

    for($qtyVal = 1 ; $qtyVal <= $qty; $qtyVal++) {
        try {
            $params = array(
                'form_key' => $this->formKey->getFormKey(),
                'product' => $productId,
                'qty' => 1
            );
             $_product = $this->product->create()->load($productId);
            $this->cart->addProduct($_product, $params);
              $product = $this->_initProduct();
             /**
             * @todo remove wishlist observer \Magento\Wishlist\Observer\AddToCart
             */
            $this->_eventManager->dispatch(
                'checkout_cart_add_product_complete',
                ['product' => $product, 'request' => $this->getRequest(), 'response' => $this->getResponse()]
            );

            if (!$this->_checkoutSession->getNoCartRedirect(true)) {
                if (!$this->cart->getQuote()->getHasError()) {
                    $message = __(
                        'You added %1 to your shopping cart.',
                        $product->getName()
                    );
                    $this->messageManager->addSuccessMessage($message);
                }
                return $this->goBack(null, $product);
            }
        } catch(\Exception $e) {
            $this->messageManager->addException($e, __('We can\'t add this item to your shopping cart right now.'));
            $this->_objectManager->get(\Psr\Log\LoggerInterface::class)->critical($e);
            return $this->goBack();
        }
    }
    $this->cart->save();
}


/**
 * Resolve response
 *
 * @param string $backUrl
 * @param \Magento\Catalog\Model\Product $product
 * @return $this|\Magento\Framework\Controller\Result\Redirect
 */
protected function goBack($backUrl = null, $product = null)
{
    if (!$this->getRequest()->isAjax()) {
        return parent::_goBack($backUrl);
    }

    $result = [];

    if ($backUrl || $backUrl = $this->getBackUrl()) {
        $result['backUrl'] = $backUrl;
    } else {
        if ($product && !$product->getIsSalable()) {
            $result['product'] = [
                'statusText' => __('Out of stock')
            ];
        }
    }

    $this->getResponse()->representJson(
        $this->_objectManager->get(\Magento\Framework\Json\Helper\Data::class)->jsonEncode($result)
    );
}
}
4
  • do you try this, it works? I see that in $this->cart->addProduct($_product, $params); first argument don't defined
    – underser
    Oct 29, 2019 at 13:02
  • I have updated the answer.. I did few customization, so i edited according to the need..
    – aravind
    Oct 29, 2019 at 13:09
  • What happened does this works?
    – aravind
    Oct 30, 2019 at 4:32
  • doesn't work... Apr 25, 2022 at 13:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.