0

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?

  • Yes this is achievable.. Do you want this for simple product ? – aravind Oct 29 '19 at 9:55
  • @aravind I want this for all product types. – underser Oct 29 '19 at 9:56
  • I have done this task only for simple products and configurable.. – aravind Oct 29 '19 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 '19 at 11:11
  • have you created plugin with afterRepresentProduct ? as mentioned in link provided? – aravind Oct 29 '19 at 11:31
0

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;
    }
}
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)
    );
}
}
  • do you try this, it works? I see that in $this->cart->addProduct($_product, $params); first argument don't defined – underser Oct 29 '19 at 13:02
  • I have updated the answer.. I did few customization, so i edited according to the need.. – aravind Oct 29 '19 at 13:09
  • What happened does this works? – aravind Oct 30 '19 at 4:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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