Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Magento 2 Filter Shipping Methods based on Product Attribute

I am new to Magento 2. Anybody knows of a way to disable a shipping method based on an attribute withing the products in the cart. Let's say we wanna enable store pickup only for certain products. On the onepage checkout these are updated with a post /rest/en/V1/guest-carts/SESSION_ID/estimate-shipping-methods but tried the module-checkout and module-quote and still can't find where this code is so i can extend it. Would be helpful if somebody has been thru this before.

Thanks

like image 820
user1831138 Avatar asked Jun 13 '16 19:06

user1831138


People also ask

How do I restrict shipping in Magento 2?

To restrict shipping by locations in Magento 2, go to Sales > Shipping Restrictions and click Add Rule. Fill in the Restriction name and choose all the shipping methods you want to disable. Then, enter a Restriction message and go to the Conditions section.

How do I get all shipping methods in Magento 2?

First, you need to configure the origin shipping method in Magento 2 to calculate the shipping costs for the shipments from your store and calculate the tax for your products. Go to Stores > Settings > Configuration > Sales > Delivery Methods (formerly Shipping Methods) and specify all the necessary details here.


1 Answers

Probably more than one way to accomplish this, but my method of choice was to create a plugin for \Magento\Shipping\Model\Shipping, specifically the collectRates() function. Granted our requirements were more specific than yours (at bottom).

Basic logic flow is...

collectRates() (Unmodified function in \Magento\Shipping\Model\Shipping, Collects rates for all shipping methods)

afterCollectRates() (plugin)

  • At this point all shipping methods have been called and rates stored in our $request object.
  • You can determine products that are in the cart via $request->getAllItems()
    • NOTE: Child/Parent products are separate items, and depending on your store config, one or the other may not have the custom attribute you want to look at.
  • You can see all shipping methods/rates via $request->getResult()->getAllRates()
  • I did not find a core function to remove a rate, my workaround was to...
    • Unset all data in rate to remove
    • After all rates are modified, use a foreach() loop to store them in a tempArray (with some logic to not add if cost==0, etc.)
    • Now flush and reset all existing rates via $request->getResult()->reset()
    • Finally, add the rates from your tempArray back in


Depending on how you calculate rates, you may also want to extend the various shipping methods so you can bypass them entirely when certain products are in the cart (probably not for your use case, but for anyone trying to disable UPS/FedEx/etc. rates)


As mentioned, our requirements were more extensive and we also had a beforeCollectRates() function which actually created the product array and some other logic (we had to restrict various shipping methods, add handling for specific products, and use dimensional logic to create a list of shipping boxes to send to UPS/FedEx, etc. for the actual CollectRates() part.)

like image 120
mtns_cll Avatar answered Oct 06 '22 17:10

mtns_cll