Magento – Free shipping cart rule doesn’t apply if any downloadable or virtual products are added to the cart

magento-1.7shippingshopping-cart-price-rules

I'm managing a store set up with simple, downloadable and virtual products. We have a cart price rule that offers free shipping on orders over £50 being shipped within the UK, which works exactly as it should when there are only simple products in the cart. If, however, the customer then adds a downloadable or virtual product, of any price, the free shipping rule no longer applies. The shipping itself is handled by MatrixRates, but I don't believe this should interact with the free shipping rule. [EDIT: The same issue occurs with both flat rate and vanilla table rates.]

Here are the conditions and action settings for the cart price rule.
enter image description here

Some examples:

  1. Customer adds two basic £20 items, giving a subtotal of £40 and the standard delivery shipping option.
  2. Customer adds a third basic £20 item, giving a subtotal of £60 and the free shipping option is applied.
  3. Customer then adds a downloadable product costing £5, giving a subtotal of £65, however the shipping reverts back to standard delivery only.
  4. Customer removes the downloadable product and the free shipping is reapplied.

  1. Customer adds basic products totalling over £50, free shipping is applied
  2. Customer adds a free virtual or downloadable product to the cart, shipping only allows standard delivery.
  3. Customer removes the downloadable product and the free shipping is reapplied.

I've been playing with this for a while, but haven't found any solutions. I found this Stack Overflow post from earlier this month identifying the same problem, but with no solution. Does anyone have any ideas?

Best Answer

There is the same bug on Magento 1.6. This fix is working and I hope to work on Magento 1.7 too.

Open app/code/core/Mage/SalesRule/Model/Validator.php and add below this:

protected $_baseRoundingDeltas = array();

this code:

protected $_address = null;

also in protected function _getAddress below this:

if ($item instanceof Mage_Sales_Model_Quote_Address_Item) {
    $address = $item->getAddress();

add this:

} elseif ($this->_address) {
    $address = $this->_address;

and finally in public function reset above this:

return $this;

add this:

$this->_address = $address;
Related Topic