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: