Magento 2

Magento2 How to disabled free shipping method at frontend

Magento2 How to disabled free shipping method at frontend.

In this article, I am going to show Magento2 How to disabled free shipping method at frontend.

At magento2, it difficult to disable a shipping method at frontend and Enable at admin area.

At first, I target to override  Free shipping method class  Magento\OfflineShipping\Model\Carrier\Freeshipping ‘s method  collectRates() using Plugin around method

<?php
namespace Devamitbera\CoreRewrite\Plugin;

/**
* Disabled Freeshipping for frontend
*/
class DisabledFreeShippingForFrontPlugin
{
	protected $appState;


 	public function __construct(
	   \Magento\Framework\App\State $appState
	) {
		$this->appState = $appState;
	}

	public function aroundCollectRates(
		\Magento\OfflineShipping\Model\Carrier\Freeshipping $subject ,
		\Closure $proceed ,
		\Magento\Quote\Model\Quote\Address\RateRequest $request
	)
	{
		/* If ares is frontend then return false for disable shipping method at
			frontend */
		if($this->appState->getAreaCode() == 'frontend') 
		{
			return false;
		}

		/*  Else run default  */
		return  $proceed($request);
	}
}

 

And defined under  di.xml  at app/code/Devamitbera/CoreRewrite/etc/  and try disable by using Area code

$this->appState->getAreaCode() == 'frontend'

 

But this is not working at Magento checkout page. I was going strange as the condition as was not working as excepted.

Then, I was started to debug and find that issue is this Magento area.At Checkout page, Magento is estimating Shipping method current quote using of   its Rest API   and that why area code at plugin is webapi_rest.

That why the condition was not working!.

 

So, again trying to find the solution of that issue.

  • Create a new field is_frontent_checkout at Quote table using setup install script InstallData.php  at at app/code/Devamitbera/CoreRewrite/etc/Setup and set it value to 0 or 1  and by default set value 0.
<?php

namespace Devamitbera\CoreRewrite\Setup;

use Magento\Framework\DB\Ddl\Table;
use Magento\Framework\Setup\InstallDataInterface;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\ModuleDataSetupInterface;

/**
 * @codeCoverageIgnore
 */
class InstallData implements InstallDataInterface
{
    /**
     * Quote setup factory
     *
     * @var QuoteSetupFactory
     */
    private $quoteSetupFactory;

    /**
     * Init
     *
     * @param QuoteSetupFactory $setupFactory
     */
    public function __construct(\Magento\Quote\Setup\QuoteSetupFactory $setupFactory)
    {
        $this->quoteSetupFactory = $setupFactory;
    }

    /**
     * {@inheritdoc}
     */
    public function install(ModuleDataSetupInterface $setup, ModuleContextInterface $context)
    {
        /** @var QuoteSetup $quoteSetup */
        $quoteSetup = $this->quoteSetupFactory->create(['setup' => $setup]);

        /**
         * Install eav entity types to the eav/entity_type table
         */
        $attributes = [
                'is_frontent_checkout' => ['type' => Table::TYPE_SMALLINT,'default' => '0']
        ];

        foreach ($attributes as $attributeCode => $attributeParams) {
            $quoteSetup->addAttribute('quote', $attributeCode, $attributeParams);
        }
    }
}
  • As I want to set it to  1 when Customer cart a product frontend that why I had fired an observer on the event   checkout_cart_save_before  and declare events.xml at app/code/Devamitbera/CoreRewrite/etc/frontend.

 

<?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="checkout_cart_save_before">
        <observer name="assign_current_cart_area_frontend"
         instance="Devamitbera\CoreRewrite\Observer\AssignCurrentStoreIsFrontend" />
    </event>
</config>

Observer class  AssignCurrentStoreIsFrontend.php at app/code/Devamitbera/CoreRewrite/Observer

<?php
namespace Devamitbera\CoreRewrite\Observer;

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

class AssignCurrentStoreIsFrontend implements ObserverInterface
{

    public function execute(\Magento\Framework\Event\Observer $observer)
    {
        $cart = $observer->getEvent()->getCart();
        $quote = $cart->getQuote();

        if($quote->getIsFrontentCheckout()!=1){
            $quote->setIsFrontentCheckout(1);
        }

    }

}

 

  • Now disabling the free shipping method when that field value  1.So, I have changed in the Plugin class code.
<?php
namespace Devamitbera\CoreRewrite\Plugin;

/**
* Disabled Freeshipping for frontend
*/
class DisabledFreeShippingForFrontPlugin
{
	protected $_logger;
	protected $quoteFactory;

 	 public function __construct(
        \Psr\Log\LoggerInterface $logger,
        \Magento\Quote\Model\QuoteFactory $quoteFactory

    ) {
		$this->_logger = $logger;
		$this->quoteFactory = $quoteFactory;
   }
	public function aroundCollectRates(
		\Magento\OfflineShipping\Model\Carrier\Freeshipping $subject ,
		\Closure $proceed ,
		\Magento\Quote\Model\Quote\Address\RateRequest $request
	)
	{

		$items = $request->getAllItems();
		$quoteId = false;

		foreach ($items  as $item) 
		{
			$quoteId = $item->getQuoteId();
			break;
		}

		$quote = $this->getCurrentQuote($quoteId);

		if($quote && ($quote->getIsFrontentCheckout() == 1)){
			return false;
		}
		return  $proceed($request);
		
	}
	protected function getCurrentQuote($quoteId){

		return $this->quoteFactory->create()->load($quoteId);
	}
	
}

 

 

In this logic, you can disable any shipping method.

 

Hope, it will help other people.

Related Post:

  1. How to get magento2 base url
  2. Magento2 redirection from Observer
  3. Magento2 get admin url