3

I have created a custom controller in my module and calling via ajax to add the item to cart.

Below is my controller code.

<?php 

 namespace {Vendor}\{Module}\Controller\Product;                           
 class AddProduct extends \Magento\Framework\App\Action\Action                 
{
 protected $formKey;
 protected $cart;
 protected $product;
 protected $checkoutSession;
 public function __construct(
 \Magento\Framework\App\Action\Context $context,
 \Magento\Framework\Data\Form\FormKey $formKey,
 \Magento\Checkout\Model\Cart $cart,
 \Magento\Catalog\Model\ProductFactory $product,
 \Magento\Checkout\Model\Session $checkoutSession,
 array $data = []) {
  $this->formKey = $formKey;
  $this->cart = $cart;
  $this->product = $product;
  $this->checkoutSession = $checkoutSession;
  parent::__construct($context);
  }
  public function execute()
  {
  $productId = 1;
  $customPrice = 150;
  $params = array(
    'form_key' => $this->formKey->getFormKey(),
    'product_id' => $productId, //product Id
    'qty'   => 1 //quantity of product
  );
  $_product = $this->product->create()->load($productId);
  $this->cart->addProduct($_product, $params);

  $productItem = $this->getProductQuote($_product);
  $productItem->setCustomPrice($customPrice);
  $productItem->setOriginalCustomPrice($customPrice);
  //Enable super mode on the product.
  $productItem->getProduct()->setIsSuperMode(true);
  $this->cart->save();
  echo "success";
 }


 public function getProductQuote($product)
 {
  $quote = $this->checkoutSession->getQuote();
  $cartItems = $quote->getItemByProduct($product);
  return $cartItems;
 } 
}

The above code adds the product of qty 1 to the cart with a custom price whenever it is called.

I want to add only 1 qty of product to the cart. suppose if its called two or three times, only one qty should be present in cart. Need to remove previously added qty from the cart.

Is something can be done programmatically? There is a product setting in backend "Maximum qty allowed in cart", we can set this value but I am looking for the code how it can be done programmatically.

Can anyone look into it and help me, please. Thanks

1

2 Answers 2

1

You can use getItemByProduct

If Item is exist -> use addProduct function -> else -> use updateItem function

$item = $this->cart->getQuote()->getItemByProduct($_product);
if ($item) {
    $this->cart->addProduct($_product, $params);
} else {
    $this->cart->updateItem($item->getId(), 1);
}
7
  • hi, Thank you, but you are doing reversely I think, Mar 12, 2019 at 7:41
  • hi, this code doesn't work for me Mar 12, 2019 at 8:11
  • Does it work for you? Mar 13, 2019 at 7:00
  • Yes, it works. Item qty always = 1 Mar 13, 2019 at 7:02
  • what about custom price? for me it didn't work, Mar 13, 2019 at 7:08
1

Why you do that programmatically ? You can set it by Magento 2 configuration :

Store -> Configuration -> Catalog -> Inventory -> Product Stock Options -> Maximum Qty Allowed in Shopping Cart

Set 1 here. It will working.

EDIT :

events.xml :

<event name="controller_action_predispatch_checkout_cart_add">
  <observer name="vendor_model_cart_add_before" instance="Vendor\Module\Observer\CartAddBefore" />
</event>

CartAddBefore.php :

<?php
namespace Vendor\Module\Observer;

use Magento\Framework\Event\ObserverInterface;
use Magento\Framework\App\Request\DataPersistorInterface;
use Magento\Framework\App\ObjectManager;

class CartAddBefore implements ObserverInterface {

    protected $_cart;
    protected $_messageManager;
    protected $_request;


    public function __construct(
        \Magento\Checkout\Model\Cart $cart,
        \Magento\Framework\Message\ManagerInterface $messageManager,
        \Magento\Framework\App\RequestInterface $request,
    ) {
        $this->_cart = $cart;
        $this->_messageManager = $messageManager;
        $this->_request = $request;        
    }

    public function execute(\Magento\Framework\Event\Observer $observer) {

        $postValues = $this->_request->getPostValue();
        $cartItemsCount = $this->_cart->getQuote()->getItemsCount();

        if($cartItemsCount > 1)
        {
            ...... your logic .......
            $this->_messageManager->addError(__('Sorry, Only 1 product is allowed'));
        }
    }
}
4
  • yes this option is there, but we are not using admin feature as per the requirement, trying to handle programmatically, that's why i mentioned in question Mar 12, 2019 at 11:15
  • so, trying to delete old quote from id and update with new one. If enabled the above setting the error message will be shown to the user, we are avoiding that one Mar 12, 2019 at 11:17
  • Check updated answer. Mar 12, 2019 at 11:24
  • I am calling the controller from ajax request, so can you please help me in giving answer for removing old quote of the product, and add new one, because i don't want to show any error message to the customer, @Rohan, The requirement is like that pls Mar 12, 2019 at 11:27

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.