5

We are using Magento 2.2.2, We have more then 5 shipping methods enabled in our site.

We needs to remove other shipping methods and enable only free shipping if the cost of their order totals to more then 100.

And if it totals less then 100 then all other shipping methods will enabled.

6 Answers 6

0

To remove Flat Rate when subtotal is more than 100, you can add below code.

vendor/magento/module-offline-shipping/Model/Carrier/Flatrate.php

public function collectRates(RateRequest $request){
    ....

    // Add this code
    if($request->getSubtotalIncludingTax() > 100){
         return false;
    }
    // Code End

    ...
}


Also set subtotal including tax value in request of below function

vendor/magento/module-quote/Model/Quote/Address.php

public function requestShippingRates(\Magento\Quote\Model\Quote\Item\AbstractItem $item = null)
{
    ...

    $validateFreeShippingTotal = $this->getBaseSubtotalWithDiscount() + $this->getBaseTaxAmount();
    $request->setSubtotalIncludingTax($validateFreeShippingTotal);

    ...
}
1
  • never edit VENDOR files!!! Jan 27 at 17:20
5

You can do that by overriding the

\Magento\Quote\Model\ShippingMethodManagement::getShippingMethods function.

private function getShippingMethods(Quote $quote, $address)
{
    $output = [];
    $shippingAddress = $quote->getShippingAddress();
    $shippingAddress->addData($this->extractAddressData($address));
    $shippingAddress->setCollectShippingRates(true);

    $this->totalsCollector->collectAddressTotals($quote, $shippingAddress);
    $shippingRates = $shippingAddress->getGroupedAllShippingRates();
    foreach ($shippingRates as $carrierRates) {
        foreach ($carrierRates as $rate) {
            $output[] = $this->converter->modelToDataObject($rate, $quote->getQuoteCurrencyCode());
        }
    }
    return $output;
}

This method is responsible for providing all the available shipping methods. So all you have to do is, check the grand total of the quote and enable the respective methods.

Below are the modified lines to display only free shipping when order amount goes above 100.

foreach ($shippingRates as $carrierRates) {
    foreach ($carrierRates as $rate) {
        if ($quote->getGrandTotal() <= 100) {
            $output[] = $this->converter->modelToDataObject($rate, $quote->getQuoteCurrencyCode());
        } else {
            if ($rate->getMethod() == "freeshipping") {
                $output[] = $this->converter->modelToDataObject($rate, $quote->getQuoteCurrencyCode());
                break;
            }
        }

    }
}

Since this method is a private function, you can't use plugins. You can go with preference to achieve that.

3
  • How can I get the customer?
    – k33n
    Apr 24, 2018 at 12:36
  • 1
    @Mike We can't overridden getShippingMethods as it's private function Jun 5, 2018 at 14:14
  • @MahendraJella you are right. i am not able to override this method. can you tell me how to fix this?
    – Ajay Patel
    Nov 5, 2018 at 9:37
3

The answer of @Ravindrasinh is half the answer: it explains how you can show a shipping method from a given amount. Your question is also about the inverse of this: hide certain shipping methods from a given amount.

What you need to do is write plugins after the collectRates()-methods of the given shipping methods so you can manipulate the outcome according to your own quote.

2

Now check screen short for apply free shipping and other shipping method Flat rate , table rate option in No then all are disable only free shipping enable Yes

Store -> Configuration -> Sales -> Shipping Method -> Free Shipping

enter image description here

Free shipping cart image

enter image description here

7
  • I don't understand what your are saying, can you please explain me in detail ? please check my updated question for more information Feb 6, 2018 at 11:32
  • In your screenshot there is only freeshipping method Feb 6, 2018 at 11:33
  • yes only free shipping enable and other shipping method disable Feb 6, 2018 at 11:37
  • which type of issue are face Feb 6, 2018 at 11:40
  • but in my case more then 5 shipping methods are enabled Feb 6, 2018 at 11:44
0

To remove Flat Rate when subtotal is more than 1000, you can add below code.

****vendor/magento/module-offline-shipping/Model/Carrier/Flatrate.php****

$request->getBaseSubtotalInclTax() <= 1000

0

Write a plugin to disable flat rate shipping method when free shipping is actually enabled based on cart sub total.

1-> Create custom module Hello_World

2-> Create plugin and configure in di.xml file, app/code/Hello/World/etc/di.xml

<?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\OfflineShipping\Model\Carrier\Flatrate">
        <plugin name="disable-flatrate" type="Hello\World\Model\Carrier\Flatrate" sortOrder="1" />
    </type>
</config>

Write a Model class to process sub total validation.

3-> Create model file app/code/Hello/World/Model/Carrier/Flatrate.php

<?php
namespace Hello\World\Model\Carrier;

class Flatrate
{

    const XML_PATH_FREE_SHIPPING_SUBTOTAL = "carriers/freeshipping/free_shipping_subtotal";

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

    /**
     * @var \Magento\Framework\App\Config\ScopeConfigInterface
     */
    protected $_scopeConfig;

    public function __construct(
        \Magento\Checkout\Model\Session $checkoutSession,
        \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
        \Magento\Store\Model\StoreManagerInterface $storeManager
    ) {
        $this->_storeManager = $storeManager;
        $this->_checkoutSession = $checkoutSession;
        $this->_scopeConfig = $scopeConfig;
    }

    public function afterCollectRates(\Magento\OfflineShipping\Model\Carrier\Flatrate $flatRate, $result)
    {
        $scopeId = $this->_storeManager->getStore()->getId();

        $storeScope = \Magento\Store\Model\ScopeInterface::SCOPE_STORES;

        // Get MOA value from system configuration.
        $freeShippingSubTotal = $this->_scopeConfig->getValue(self::XML_PATH_FREE_SHIPPING_SUBTOTAL, $storeScope, $scopeId);

        // Get cart subtotal from checkout session.
        $baseSubTotal = $this->_checkoutSession->getQuote()->getBaseSubtotal();

        // Validate subtoal should be empty or Zero.
        if(!empty($baseSubTotal) && !empty($freeShippingSubTotal)) {

            if($baseSubTotal >= $freeShippingSubTotal) {
                return false;
            }
        }

        return $result;
    }
}

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.