6

I want to disable USPS on the frontend if a product's length is over 12" (the max size USPS box we use).

I understand there is an extension, Amasty Shipping Restrictions that gets high praise, but this is much more complex than I require.

Is there a straightforward way to program this into my checkout rules?

5 Answers 5

3

Solution Logic

I set up a solution that iterates through each item in a customer's cart, check's each item's height attribute, then if any item is over a given length, it raises the flag(s) for whatever shipping method can't ship something that length, and hides the shipping method(s) from the customer's view.

I configured this solution to work for USPS (max length 12", limited by the largest box our store offers), UPS (max length 108" per UPS Ground website), and FedEx (max length 165" per FedEx website).

To reiterate, if any one item is over the maximum length, then that shipping method is disabled for the entire cart. I injected this logic check into the "View Cart" and "Onepage Checkout" pages to hide any unavailable shipping methods dynamically.

Files changed

/app/design/frontend/base/default/template/checkout/onepage/shipping_method/available.phtml

/app/design/frontend/rwd/default/template/checkout/cart/shipping.phtml

PHP added

Both Files

<?php 
$cart = Mage::getModel('checkout/cart')->getQuote();
$uspsAllowed = true;        // USPS allowed by default  (unless height attrib greater than 12)
$fedexAllowed = true;       // FedEx allowed by default (unless height attrib greater than 108)
$upsAllowed = true;         // UPS allowed by default   (unless height attrib greater than 165)
foreach ($cart->getAllItems() as $item) {
    $storeId = 1;           // Mbs Standoffs store code
    $attributeId = 'height';// Height attribute code
    $qty += $item->getQty();// Keep track of total item quantity in cart
    $productId = $item->getProduct()->getId();
    $productLength = Mage::getResourceModel('catalog/product')->getAttributeRawValue($productId, $attributeId, $storeId);
    if($productLength > 165) {
        $uspsAllowed = false;
        $fedexAllowed = false;
        $upsAllowed = false;
    } elseif($productLength > 108) {
        $uspsAllowed = false;
        $upsAllowed = false;
    } elseif($productLength > 12) { $uspsAllowed = false; }
} ?>

Shipping.phtml

<?php if($this->escapeHtml($this->getCarrierName($code)) == 'United States Postal Service' && $uspsAllowed == false) { ?>
    <li>This shipping method is currently unavailable. If you would like to ship using this shipping method, please contact us.</li>
<?php } elseif($this->escapeHtml($this->getCarrierName($code)) == 'United Parcel Service' && $upsAllowed == false) { ?>
    <li>One or more of the items in your cart will need to be shipped through UPS Freight. If you would like to ship using this shipping method, please contact us.</li>
<?php } elseif($this->escapeHtml($this->getCarrierName($code)) == 'Federal Express' && $fedexAllowed == false) { ?>
    <li>One or more of the items in your cart will need to be shipped through FedEx Freight. If you would like to ship using this shipping method, please contact us.</li>
<?php } else { ?>
    <?php foreach ($_rates as $_rate): ?>
        <li<?php if ($_rate->getErrorMessage()) echo ' class="error-msg"';?>>
           <?php if ($_rate->getErrorMessage()): ?>
                <?php echo $this->escapeHtml($_rate->getErrorMessage()) ?>
           <?php else: ?>
                <input name="estimate_method" type="radio" value="<?php echo $this->escapeHtml($_rate->getCode()) ?>" id="s_method_<?php echo $_rate->getCode() ?>"<?php if($_rate->getCode()===$this->getAddressShippingMethod()) echo ' checked="checked"' ?> class="radio" />
                <label for="s_method_<?php echo $_rate->getCode() ?>"><?php echo $this->escapeHtml($_rate->getMethodTitle()) ?>
                <?php $_excl = $this->getShippingPrice($_rate->getPrice(), $this->helper('tax')->displayShippingPriceIncludingTax()); ?>
                -
                <?php $_incl = $this->getShippingPrice($_rate->getPrice(), true); ?>
                <?php echo $_excl; ?>
                <?php if ($this->helper('tax')->displayShippingBothPrices() && $_incl != $_excl): ?>
                    (<?php echo $this->__('Incl. Tax'); ?> <?php echo $_incl; ?>)
                <?php endif; ?>
                </label>
           <?php endif ?>
        </li>
    <?php endforeach; ?>
<?php } ?>

Available.phtml

<?php if($this->escapeHtml($this->getCarrierName($code)) == 'USPS' && $uspsAllowed == false) { ?>
    <li>This shipping method is currently unavailable. If you would like to ship using this shipping method, please contact us.</li>

<?php } elseif($this->escapeHtml($this->getCarrierName($code)) == 'UPS' && $upsAllowed == false) { ?>
    <li>One or more of the items in your cart will need to be shipped through UPS Freight. If you would like to ship using this shipping method, please contact us.</li>

<?php } elseif($this->escapeHtml($this->getCarrierName($code)) == 'FedEx' && $fedexAllowed == false) { ?>
    <li>One or more of the items in your cart will need to be shipped through FedEx Freight. If you would like to ship using this shipping method, please contact us.</li>

<?php } else { ?>
    <?php $_sole = $_sole && count($_rates) == 1; foreach ($_rates as $_rate): ?>
    <?php if ($this->escapeHtml($_rate->getMethodTitle()) == 'Priority Mail 1-Day Small Flat Rate Box' || $this->escapeHtml($_rate->getMethodTitle()) == 'Priority Mail 2-Day Small Flat Rate Box' || $this->escapeHtml($_rate->getMethodTitle()) == 'Priority Mail 3-Day Small Flat Rate Box') { 
        // Do nothing. Small Flat Rate not offered on frontend.

    } elseif (($this->escapeHtml($_rate->getMethodTitle()) == 'Priority Mail 1-Day Medium Flat Rate Box' || $this->escapeHtml($_rate->getMethodTitle()) == 'Priority Mail 2-Day Medium Flat Rate Box' || $this->escapeHtml($_rate->getMethodTitle()) == 'Priority Mail 3-Day Medium Flat Rate Box') && $qty >= 50) {

        // Do nothing. Medium Flat Rate not offered on frontend if customer is shipping more than 50 items.
    } elseif (($this->escapeHtml($_rate->getMethodTitle()) == 'Priority Mail 1-Day Large Flat Rate Box' || $this->escapeHtml($_rate->getMethodTitle()) == 'Priority Mail 2-Day Large Flat Rate Box' || $this->escapeHtml($_rate->getMethodTitle()) == 'Priority Mail 3-Day Large Flat Rate Box') && $qty >= 100) {

        // Do nothing. Large Flat Rate not offered on frontend if customer is shipping more than 100 items. ?>
        <li>This shipping method is currently unavailable. If you would like to ship using this shipping method, please contact us.</li>

    <?php } else { ?>
        // Normal code section
    <?php } ?>
4
  • Thanks for sharing this but can u please, let me know which code i have to place in shipping_method.phtml and which code we have i to place in shipping.phtml. If you can help me out. Thanks in Advance
    – LR Soni
    Commented Nov 2, 2015 at 17:11
  • I updated the answer with a more clear breakdown of what code goes where. It is somewhat customized for how our store rules are. It doesn't offer USPS Small Flat Rate ever. It doesn't offer Medium for orders with a total quantity over 50. It doesn't offer Large when quantity over 100. This gives you an idea of how it can be used to modify what your user sees.
    – travisw
    Commented Nov 3, 2015 at 14:00
  • Thanks for your time and thanks for making the changes in the code. Hope may a have a good day Ahead !! :) Cheers :p
    – LR Soni
    Commented Nov 3, 2015 at 14:02
  • I am trying to make this work for our requirement, which is making certain shipping methods unavailable for certain products. I created a new attribute called "no_shipping" for this purpose with options "Yes" and "No". I replaced this with the "length" attribute from your example and works to make the main carrier unavailable. The issue is that we use webshopapps' premium matrix rates for all our shipping methods. Is there a way that I can block one method out of the main carrier, which is premiumrate in our case. Can one restrict based on the shipping methods title instead of carrier code?
    – Sparc
    Commented Jul 20, 2016 at 2:09
1

Take a look at http://projectamplify.com/insight/remove-magento-shipping-methods-if-free-shipping-available/

In

app/ design/ frontend/ default/ YOURTEMPLATE/ template/ checkout/ onepage/ shipping_method/ available.phtml

You could check your quote items to see if any of these products exist, if so remove shipping method (or create an observer for item add/remove and update a custom added field in sales_flat_quote then check the value of this field)

unset($_shippingRateGroups["usps"]);

Also take a look at http://inchoo.net/magento/how-to-hide-shipping-method-on-magento-frontend-but-leave-it-on-in-admin-area/

1

You can try Mconnect Shipping Restriction Magento 2 Module as it allows you to create a variety of shipping rules using various limitation criteria based on customers, shopping cart, and product attributes.

0

Recently I needed to do something similar. In Magento 2 if you extend the shipping class (\Magento\Shipping\Model\Shipping) in an extension, you can access attributes using the method explained in this answer: Magento 2 make product attribute available in QuoteItem

Magento 2.2 docs on building a component for reference: http://devdocs.magento.com/guides/v2.2/extension-dev-guide/build/build.html

0

I have same requirement, Restrict shipping method by product attribute (Sku). I did it with plugin,using below code.

=> app/code/{{vendor}}/{{module}}/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\Quote\Api\ShipmentEstimationInterface">
        <plugin name="shipping_method_restrict" type="{{vendor}}/{{module}}\Plugin\RestrictshippingPlugin" />
    </type>
</config>

=> /app/code/{{vendor}}/{{module}}/Plugin/RestrictshippingPlugin.php

<?php
namespace {{vendor}}\{{module}}\Plugin;
class RestrictshippingPlugin
{
    /**
     * @var \Magento\Checkout\Model\Session
     */
    protected $checkoutSession;

    /**
     * @param \Magento\Checkout\Model\Session $checkoutSession
     */   
    public function __construct(
        \Magento\Checkout\Model\Session $checkoutSession
    ) {
        $this->checkoutSession = $checkoutSession;
    }

    /**
     * Hide specific shipping methods
     *
     */
    public function afterEstimateByExtendedAddress(\Magento\Quote\Api\ShipmentEstimationInterface $subject, $methods) 
    {
        $items = $this->checkoutSession->getQuote()->getAllVisibleItems();
        foreach($methods as $key => &$method) {
            if($method->getMethodCode() == 'testshipping')   /* replace method code here */
            { 
                   if($this->_checkMethodByProduct())
                   { 
                   unset($methods[$key]);                                 
                   }
            }
        }
        return $methods;
    }
    private function _checkMethodByProduct()
    {
        $items = $this->checkoutSession->getQuote()->getAllVisibleItems();
        $renderMethod = false;
        foreach($items as $item)
        {
          if($item->getSku() == "productsku")    // check sku for restrict shipping method
          {
             $renderMethod = true;
             break;
          }
        }
        return $renderMethod; 
    }

}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.