Question

I'm using Magento 2.1. Currently, I'm having two shipping methods. One is UPS and another is Flatrate. If my product's attribute returns true, I want to hide Flatrate shipping method from frontend only, for Logged in/Guest User and if the product's attribute returns false I have to hide the UPS shipping method. How can I write the code for the same in my custom module.

Was it helpful?

Solution

Let's say that the attribute code is called attribute_code so the getter name is getAttributeCode().

You need to create an arround plugin on the flatrate carrier model and UPS carrier model where you can check your conditions and return or not the shipping rate result.

You need to create a module and add this in the di.xml file

<type name="Magento\OfflineShipping\Model\Carrier\Flatrate">
    <plugin name="[module]-flatrate" type="[Vendor]\[Module]\Plugin\Flatrate" />
</type>

<type name="Magento\Ups\Model\Carrier">
    <plugin name="[module]-ups" type="[Vendor]\[Module]\Plugin\Ups" />
</type>

Then create the file [Vendor]/[Module]/Plugin/Flatrate.php

<?php 

namespace [Vendor]\[Module]\Plugin;

class Flatrate
{
    public function arroundCollectRates(
        \Magento\OfflineShipping\Model\Carrier\Flatrate $subject,
        \Closure $proceed,
        Magento\Quote\Model\Quote\Address\RateRequest $request
    ) {
        $items = $request->getAllItems();
        foreach ($items as $item) {
            if ($item->getProduct()->getAttributeCode()) {
                 //if your attribute value is true don't show this method
                 return false;
            }
        }
        return $proceed();
    }
}

and this plugin class that handles UPS shipping method [Vendor]/[Module]/Plugin/Ups.php

<?php 

namespace [Vendor]\[Module]\Plugin;

class Ups
{
    public function arroundCollectRates(
        \Magento\OfflineShipping\Model\Carrier\Ups $subject,
        \Closure $proceed,
        Magento\Quote\Model\Quote\Address\RateRequest $request
    ) {
        $items = $request->getAllItems();
        foreach ($items as $item) {
            if ($item->getProduct()->getAttributeCode()) {
                 //if one attribute value is true show the method
                 return $proceed();
            }
        }
        //if all the products had the value false don't show UPS.
        return false;
    }
}

But keep in mind that I didn't test the code so watch out for typos.

Licensed under: CC-BY-SA with attribution
Not affiliated with magento.stackexchange
scroll top