Milen Petrov
Milen Petrov

Reputation: 273

Magento free shipping shopping cart rule to be applied after discount

I have a problem for which I cannot find a solution. I have a shopping cart rule to give a free shipping for order subtotal > $75. However if a discount code is used this rule is applied again despite the fact that the total amount of the order is less than $75. No taxes and other fees are in place. I want to give a free shipping only if they spend > $75. Any ideas how can I solve this? Thanks in advance

Upvotes: 4

Views: 9077

Answers (3)

Jiří Chmiel
Jiří Chmiel

Reputation: 876

You can try follow class. This must rewrite model "Mage_SalesRule_Model_Rule_Condition_Address". This adds the option "Subtotal with discount" to the condition options in sales rule management in the admin panel.

class YourCompany_SalesRule_Model_Rule_Condition_Address extends Mage_SalesRule_Model_Rule_Condition_Address {

/**
 * (non-PHPdoc)
 * @see Mage_SalesRule_Model_Rule_Condition_Address::loadAttributeOptions()
 */
public function loadAttributeOptions()
{
    parent::loadAttributeOptions();

    $attributes = $this->getAttributeOption();

    $attributes['base_subtotal_with_discount'] = Mage::helper('salesrule')->__('Subtotal with discount');

    $this->setAttributeOption($attributes);

    return $this;
}


/**
 * (non-PHPdoc)
 * @see Mage_SalesRule_Model_Rule_Condition_Address::getInputType()
 */
public function getInputType()
{
    if ($this->getAttribute() == 'base_subtotal_with_discount')
        return 'numeric';

    return parent::getInputType();
}


/**
 * Add field "base_subtotal_with_discount" to address.
 * It is need to validate the "base_subtotal_with_discount" attribute
 * 
 * @see Mage_SalesRule_Model_Rule_Condition_Address::validate()
 */
public function validate(Varien_Object $address)
{
    $address->setBaseSubtotalWithDiscount($address->getBaseSubtotal() + $address->getDiscountAmount());

    return parent::validate($address);
}

}

Upvotes: 2

Vinai
Vinai

Reputation: 14182

You are right, the shopping cart rule only works with the cart subtotal, as does the freeshipping carrier model. Using a small rewrite it is possible to change the behavior of the freeshipping model.

First, deactivate your shopping cart rule that grants free shipping. Then go to System > Configuration > Shipping Methods and activate the free shipping carrier, giving it a "Minimum Order Amount" of 75$.

Next, we need to add the rewrite so the freeshipping model uses the discounted value instead of the subtotal.

Add a module My_Shipping, with the appropriate module registration file. Since you are asking on stackoverflow, I'll assume you are familiar with creating Magento modules. Then add the My/Shipping/etc/config.xml file with the following rewrite declaration:

<?xml version="1.0" encoding="UTF-8"?>
<config>
    <global>
        <models>
            <shipping>
                <rewrite>
                    <carrier_freeshipping>My_Shipping_Model_Freeshipping</carrier_freeshipping>
                </rewrite>
            </shipping>
        </models>
    </global>
</config>

The only thing missing now is the rewritten carrier model. The following code implements the change you require:

class My_Shipping_Model_Freeshipping extends Mage_Shipping_Model_Carrier_Freeshipping
{
    /**
     * Force the original free shipping class to use the discounted package value.
     *
     * The package_value_with_discount value already is in the base currency
     * even if there is no "base" in the property name, no need to convert it.
     *
     * @param Mage_Shipping_Model_Rate_Request $request
     * @return Mage_Shipping_Model_Rate_Result
     */
    public function collectRates(Mage_Shipping_Model_Rate_Request $request)
    {
        $origBaseSubtotal = $request->getBaseSubtotalInclTax();
        $request->setBaseSubtotalInclTax($request->getPackageValueWithDiscount());
        $result = parent::collectRates($request);
        $request->setBaseSubtotalInclTax($origBaseSubtotal);
        return $result;
    }
}

Thats it. Now, if the subtotal including discount is above 75$, the free shipping method is available. Otherwise the customer won't see it.

Upvotes: 6

Fran
Fran

Reputation: 670

It's unfortunately a bug I have noticed. They calculate the subtotal based on the undiscounted value. A way you could go around this would be to set the "Stop processing rules" for your discount code rule.

Upvotes: 1

Related Questions