Magento 2 – Fix Cart Items Not Updating Properly

cartmagento2shopping-cart

As per functionality product have different Tier Prices and customers have different Customer Groups. When customer adding product to cart we need to add product of the first Tier Price.

Example:

Product Name: Test Product, SKU: TP.

Tier Prices:

Customer Group: Not Logged, Qty: 1, Price: $2

Customer Group: Retailer, Qty: 10, Price: $18

Customer Group: Retailer, Qty: 30, Price: $15

Customer Group: Wholesale, Qty: 100, Price: $150

Customer Group: Wholesale, Qty: 200, Price: $100

1) If the Not Logged customer adding this product to cart it will add based on customer requested Qty like 1,2,3 etc..

2) If the Retailer Customer is requested 16 Qty, it will add Qty by fallowing logic.

  1. Remainder = Requested Qty/First Tier Price;
  2. MultipleQty = round(Remainder);
  3. FinalQty = First Tier Price * MultipleQty

if customer requested 16 Qty.

  1. Remainder = 16/10; i.e remainder will be = 1.6
  2. MultipleQty = round(1.6); i.e MultipleQty will be = 2;
  3. FinalQty = 2*10; i.e FinalQty = 20;

So here 20 Qty will be added to cart.

Here is the Question. If Retail Customer forgot to login and requested 16 Qty before login it will add as per Not logged customer logic i.e 16 Qty. After Some time Retail Customer Login any where, we need to convert the Shopping cart products as per above ( 2 Point) logic right?. For this I have created Event customer_login to convert Shopping Cart product Qty's as per above logic.

My code is working, When Shopping Cart have only one product.

But my code something went wrong, When Shopping cart have multiple Tier Price products.

For this stuff I have written below code.

<?xml version="1.0"?>

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
    <event name="customer_login">
        <observer name="custom_customer_log_login" instance="ABCSolutions\LimitCartQty\Observer\UpdateCartQtyBasedOnCustomerGroupAtObserver" />
    </event>
</config>

Observer Code

<?php

namespace ABCSolutions\LimitCartQty\Observer;

use \Magento\Framework\Message\ManagerInterface ;

class UpdateCartQtyBasedOnCustomerGroupAtObserver implements \Magento\Framework\Event\ObserverInterface{


    /**
     * @var \Magento\Checkout\Model\Cart
     */
    protected $_customerCartSession;

    /**
     * @var \Magento\Catalog\Model\ProductRepository
     */
    protected $_productRepository;

    /**
     * @var \Magento\Checkout\Model\Session
     */
    protected $_checkoutSession;

    /**
     * @var \Magento\Checkout\Helper\Cart
     */
    protected $_cartHelper;

    /**
     * @var ManagerInterface
     */
    protected $_messageManager;

    public function __construct
    (
        \Magento\Checkout\Model\Cart $cart,
        \Magento\Checkout\Model\Session $checkoutSession,
        \Magento\Catalog\Model\ProductRepository $productRepository,
        ManagerInterface $messageManager
    ){
        $this->_customerCartSession = $cart;
        $this->_productRepository = $productRepository;
        $this->_checkoutSession = $checkoutSession;
        $this->_messageManager = $messageManager;
    }


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

        $customer = $observer->getEvent()->getCustomer();
        $cartItems = $this->_checkoutSession->getQuote()->getAllVisibleItems();

        $objectManager = \Magento\Framework\App\ObjectManager::getInstance();
        $request_qty = 0;
        $tierPriceQty = [];
        $productIDs = [];
        $bcw = 0;

        foreach ($cartItems as $item) {
            $productIDs[] = (int) $item->getProductId();
            $product = $objectManager->create('Magento\Catalog\Model\Product')->load($item->getProductId());
            $tierPrice = $product->getTierPrices();
            $isFirst = false;
            if(count($tierPrice) > 0){
                foreach($tierPrice as $k => $v){
                    if($v->getCustomerGroupID()== $this->_customerCartSession->getCustomerSession()->getCustomerGroupId()){
                        if(!$isFirst){
                            $tierPriceQty[$bcw] = $v->getQty();
                            $isFirst = true;
                            $bcw++;
                        }
                    }
                }
                if(!isset($tierPriceQty[$bcw]) && !($isFirst)){
                    $tierPriceQty[$bcw] = "No Tier Price";
                    $bcw++;
                }

            }else{
                $tierPriceQty[$bcw] = "No";
                $bcw++;
            }
        }

        $i=0;

        foreach($productIDs as $productId){

            unset($params);
            try{

                $productAdded = $this->_productRepository->getById($productId);
                $productSku = $productAdded->getSku();
                $quote = $this->_checkoutSession->getQuote();
                $item= $quote->getItemByProduct($productAdded);
                $itemId= $item->getItemId();
                $cartQty = $item->getQty();
                $isNumber = is_numeric($tierPriceQty[$i]);
                $remainder = 0;

                if($isNumber){
                    $oldQty = $tierPriceQty[$i];

                    $remainder = $cartQty / $oldQty;
                    $multiplyQty = round($remainder);
                    $finalQty = $oldQty * $multiplyQty;
                }else{
                    if($tierPriceQty[$i] == "No"){
                        $finalQty = $cartQty;
                        $oldQty = $finalQty;
                    }elseif($tierPriceQty[$i] == "No Tier Price"){
                        $finalQty = $cartQty;
                        $oldQty = $finalQty;
                    }

                }

                if($finalQty == 0 || $oldQty < $finalQty){
                    $params[$itemId]['qty'] = number_format($oldQty, 0, '.', '');
                }else{
                    $params[$itemId]['qty'] = number_format($finalQty, 0, '.', '');
                }

                $this->_customerCartSession->updateItems($params);
                $this->_customerCartSession->saveQuote();
                $this->_customerCartSession->save();
                $i++;

            }catch (\Magento\Framework\Exception\LocalizedException $e) {
                $this->_messageManager->addError(
                    $objectManager->create('Magento\Framework\Escaper')->escapeHtml($e->getMessage())
                );
                $i++;
                continue;
            } catch (\Exception $e) {
                $this->_messageManager->addException($e, __('We can\'t update the shopping cart.'));
                $objectManager->create('Psr\Log\LoggerInterface')->critical($e);
                $i++;
                continue;
            }
        }

        return true;

    }

}

Any help on this?

Best Answer

Finally I did it.

<?php

namespace ABCSolutions\LimitCartQty\Observer;

use \Magento\Framework\Message\ManagerInterface ;

class UpdateCartQtyBasedOnCustomerGroupAtObserver implements \Magento\Framework\Event\ObserverInterface{


    /**
     * @var \Magento\Checkout\Model\Cart
     */
    protected $_customerCartSession;

    /**
     * @var \Magento\Catalog\Model\ProductRepository
     */
    protected $_productRepository;

    /**
     * @var \Magento\Checkout\Model\Session
     */
    protected $_checkoutSession;

    /**
     * @var \Magento\Checkout\Helper\Cart
     */
    protected $_cartHelper;

    /**
     * @var ManagerInterface
     */
    protected $_messageManager;


    protected $_responseFactory;

    protected $quoteRepository;


    protected $_url;

    public function __construct
    (
        \Magento\Checkout\Model\Cart $cart,
        \Magento\Checkout\Model\Session $checkoutSession,
        \Magento\Catalog\Model\ProductRepository $productRepository,
        ManagerInterface $messageManager,
        \Magento\Framework\App\ResponseFactory $responseFactory,
        \Magento\Framework\UrlInterface $url,
        \Magento\Quote\Api\CartRepositoryInterface $quoteRepository
    ){
        $this->_customerCartSession = $cart;
        $this->_productRepository = $productRepository;
        $this->_checkoutSession = $checkoutSession;
        $this->_messageManager = $messageManager;
        $this->quoteRepository = $quoteRepository;
        $this->_responseFactory = $responseFactory;
        $this->_url = $url;
    }


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

        //$event = $observer->getEvent();
        //$RedirectUrl= $this->_url->getUrl('checkout/cart/updatePost');
        //$this->_responseFactory->create()->setRedirect($RedirectUrl)->sendResponse();

        $customer = $observer->getEvent()->getCustomer();
        //$cartItems = $this->_checkoutSession->getQuote()->getAllVisibleItems();
        $cartItems = $this->_checkoutSession->getQuote()->getAllItems();

        $objectManager = \Magento\Framework\App\ObjectManager::getInstance();
        $request_qty = 0;
        $tierPriceQty = [];
        $productIDs = [];
        $bcw = 0;

        foreach ($cartItems as $item) {
            $productIDs[] = (int) $item->getProductId();
            $product = $objectManager->create('Magento\Catalog\Model\Product')->load($item->getProductId());
            $tierPrice = $product->getTierPrices();
            $isFirst = false;
            if(count($tierPrice) > 0){
                foreach($tierPrice as $k => $v){
                    if($v->getCustomerGroupID()==  $this->_customerCartSession->getCustomerSession()->getCustomerGroupId()){
                        if(!$isFirst){
                            $tierPriceQty[$bcw] = $v->getQty();
                            $isFirst = true;
                            $bcw++;
                        }
                    }
                }
                if(!isset($tierPriceQty[$bcw]) && !($isFirst)){
                    $tierPriceQty[$bcw] = "No Tier Price";
                    $bcw++;
                }

            }else{
                $tierPriceQty[$bcw] = "No";
                $bcw++;
            }
        }

        $this->UpdateShoppingCart($productIDs,$tierPriceQty);

        return true;

    }


    public function UpdateShoppingCart($productIDs = array(), $tierPriceQty = array()){

        $i=0;
        $params = array();
        foreach($productIDs as $productId){

            //unset($params);
            $isTierPrice = false;
            try{

                $productAdded = $this->_productRepository->getById($productId);
                $productSku = $productAdded->getSku();
                $quote = $this->_checkoutSession->getQuote();
                $item= $quote->getItemByProduct($productAdded);
                $itemId= $item->getItemId();
                $cartQty = $item->getQty();
                $isNumber = is_numeric($tierPriceQty[$i]);
                $remainder = 0;

                if($isNumber){
                    $oldQty = $tierPriceQty[$i];

                    $remainder = $cartQty / $oldQty;
                    $multiplyQty = round($remainder);
                    $finalQty = $oldQty * $multiplyQty;
                }else{
                    if($tierPriceQty[$i] == "No"){
                        //$finalQty = $cartQty;
                        //$oldQty = $finalQty;
                        $isTierPrice = true;
                    }elseif($tierPriceQty[$i] == "No Tier Price"){
                        //$finalQty = $cartQty;
                        //$oldQty = $finalQty;
                        $isTierPrice = true;
                    }

                }
                if(!$isTierPrice){
                    if($finalQty <= 0){
                        $params[$itemId]['qty'] = number_format($oldQty, 0, '.', '');
                    }else{
                        $params[$itemId]['qty'] = number_format($finalQty, 0, '.', '');
                    }


                }else{
                    //$isTierPrice = false;
                    $params[$itemId]['qty'] = number_format($cartQty, 0, '.', '');
                }

                $i++;

            }catch (\Magento\Framework\Exception\LocalizedException $e) {
                $this->_messageManager->addError(
                    $objectManager->create('Magento\Framework\Escaper')->escapeHtml($e->getMessage())
                );
                $i++;
                continue;
            } catch (\Exception $e) {
                $this->_messageManager->addException($e, __('We can\'t update the shopping cart.'));
                $objectManager->create('Psr\Log\LoggerInterface')->critical($e);
                $i++;
                continue;
            }
        }

            if(is_array($params)){
                $cartData = $this->_customerCartSession->suggestItemsQty($params);
                $this->_customerCartSession->updateItems($cartData)->save();
                //$this->_customerCartSession->saveQuote();
                //$this->_customerCartSession->save();

                $quote =  $this->_customerCartSession->getQuote();
                $customerId = $this->_customerCartSession->getCustomerSession()->getCustomerId();
                if($customerId == null){
                    $customerId = 0;
                }
                if($quote->getId() != null ){
                    $quote = $this->quoteRepository->get($quote->getId());
                    $quote->setCustomerId($customerId); // Whatever you want to update
                    $this->quoteRepository->save($quote);
                }
            }


    }

}
Related Topic