2

Could it be possible to remove all the shipping methods except the one having shipping amount 0?

There may be a promotion rule which will return the amount 0 for shipping, so it must not be removed.

conditional free shipping

6

Here is a quick(ish) and dirty way of doing it.
You have to modify the shipping methods template in the checkout process. (checkout/onepage/shipping_method/available.phtml and checkout/multishipping/shipping.phtml).

The idea is that before printing the available shipping methods you can loop through them and see if there is one with the price 0.

So add this piece of code right before <dl class="sp-methods">.

<?php 
$hasZeroRate = false;
$groupsToShow = array();
foreach ($_shippingRateGroups as $code => $_rates) : 
    foreach ($_rates as $_rate) : 
        if ($_rate->getPrice() == 0) : 
             $hasZeroRate = true;//found a zero rate
             $groupsToShow[] = $code; //remember to show only this group
        endif;
    endforeach;
endforeach;
?>

Now you need to edit the listing of the shipping rates.

So below this line:

<?php $_sole = count($_shippingRateGroups) == 1; foreach ($_shippingRateGroups as $code => $_rates): ?> 

add

<?php if ($hasZeroRate && !in_array($code, $groupsToShow)) : //if there is a rate with the price 0 and not in this group then skip the group. ?>
    <?php continue;?>
<?php endif;?>

The under

<?php $_sole = $_sole && count($_rates) == 1; foreach ($_rates as $_rate): ?> 

add this:

 <?php if ($hasZeroRate && $_rate->getPrice() != 0) : //if there is a zero rate but the price for the current rate is not 0 skip it.?>
    <?php continue;?>
 <?php endif;?>
  • the same way you can have the clean solution too. – Mohammad Faisal Apr 4 '14 at 12:47
2

Display only shipping methods with price 0 (zero) if any

I'd solved this problem by creating a custom module while the other answer by Marius is also working if you do not want to create a module.

In my module I'd overridden the Mage_Checkout_Block_Onepage_Shipping_Method_Available block as:

config.xml

<global>
    <blocks>
        <checkout>
            <rewrite>
                <onepage_shipping_method_available>Excellence_Subscription_Block_Checkout_Onepage_Shipping_Method_Available</onepage_shipping_method_available>
            </rewrite>
        </checkout>
    </blocks>
</global>

Excellence_Subscription_Block_Checkout_Onepage_Shipping_Method_Available

<?php

class Excellence_Subscription_Block_Checkout_Onepage_Shipping_Method_Available extends Mage_Checkout_Block_Onepage_Shipping_Method_Available {

    public function getShippingRates() {
        $groups = parent::getShippingRates();
        $free = array();
        foreach ($groups as $code => $_rates) {
            foreach ($_rates as $_rate) {
                if (!$_rate->getPrice() > 0) {
                    $free[$code] = $_rates;
                }
            }
        }
        if (!empty($free)) {
            return $this->_rates = $free;
        }
        return $groups;
    }

}
  • i am used one custom shipping method like free shipping but i have follow your instruction but not any shipping method display in checkout section. – Bhavesh Godhani Jan 8 '15 at 12:17
  • @BhaveshGodhani: please check if that module in not already rewriting the block(onepage_shipping_method_available). Also check if it is setting the shipping price to 0. – Mohammad Faisal Jan 8 '15 at 13:27
1

Normally I would suggest using the event $this->_eventPrefix.'_load_after to perform some changes to a collection after it has been loaded but in the case of the collection attached to sales/quote_address_rate it does not have an eventPrefix that I can see :(

What you could do is listen to the event core_collection_abstract_load_after and check the collection instance.

public function salesRateAfter($observer) {
    $collection = $observer->getCollection();
    if ($collection instanceof Mage_Sales_Model_Resource_Quote_Address_Rate_Collection) {
        // Check for the entry you want and remove all others
    }
}

Since as behind all the shipping rates code it appears to simply load the collection based on an address filter.

public function getShippingRatesCollection()
{
    if (is_null($this->_rates)) {
        $this->_rates = Mage::getModel('sales/quote_address_rate')->getCollection()
            ->setAddressFilter($this->getId());
        if ($this->getQuote()->hasNominalItems(false)) {
            $this->_rates->setFixedOnlyFilter(true);
        }
        if ($this->getId()) {
            foreach ($this->_rates as $rate) {
                $rate->setAddress($this);
            }
        }
    }
    return $this->_rates;
}

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.