1

Is there anyway to configure Magento's Price rules so that if Free shipping is given for purchases which in total are equal to or greater than X AND if a coupon reduces X to a lesser value customer pays for shipping?

Thanks

0

override magento core model Mage_Shipping_Model_Carrier_Tablerate

just replace getPackageValue() with getPackageValueWithDiscount() in collectRates(Mage_Shipping_Model_Rate_Request $request)

add below function

public function collectRates(Mage_Shipping_Model_Rate_Request $request)
{
    if (!$this->getConfigFlag('active')) {
        return false;
    }

    // exclude Virtual products price from Package value if pre-configured
    if (!$this->getConfigFlag('include_virtual_price') && $request->getAllItems()) {
        foreach ($request->getAllItems() as $item) {
            if ($item->getParentItem()) {
                continue;
            }
            if ($item->getHasChildren() && $item->isShipSeparately()) {
                foreach ($item->getChildren() as $child) {
                    if ($child->getProduct()->isVirtual()) {
                        $request->setPackageValue($request->getPackageValueWithDiscount() - $child->getBaseRowTotal());
                    }
                }
            } elseif ($item->getProduct()->isVirtual()) {
                $request->setPackageValue($request->getPackageValueWithDiscount() - $item->getBaseRowTotal());
            }
        }
    }

    // Free shipping by qty
    $freeQty = 0;
    if ($request->getAllItems()) {
        $freePackageValue = 0;
        foreach ($request->getAllItems() as $item) {
            if ($item->getProduct()->isVirtual() || $item->getParentItem()) {
                continue;
            }

            if ($item->getHasChildren() && $item->isShipSeparately()) {
                foreach ($item->getChildren() as $child) {
                    if ($child->getFreeShipping() && !$child->getProduct()->isVirtual()) {
                        $freeShipping = is_numeric($child->getFreeShipping()) ? $child->getFreeShipping() : 0;
                        $freeQty += $item->getQty() * ($child->getQty() - $freeShipping);
                    }
                }
            } elseif ($item->getFreeShipping()) {
                $freeShipping = is_numeric($item->getFreeShipping()) ? $item->getFreeShipping() : 0;
                $freeQty += $item->getQty() - $freeShipping;
                $freePackageValue += $item->getBaseRowTotal();
            }
        }
        $oldValue = $request->getPackageValueWithDiscount();
        $request->setPackageValue($oldValue - $freePackageValue);
    }

    if ($freePackageValue) {
        $request->setPackageValue($request->getPackageValueWithDiscount() - $freePackageValue);
    }
    if (!$request->getConditionName()) {
        $conditionName = $this->getConfigData('condition_name');
        $request->setConditionName($conditionName ? $conditionName : $this->_default_condition_name);
    }

    // Package weight and qty free shipping
    $oldWeight = $request->getPackageWeight();
    $oldQty = $request->getPackageQty();

    $request->setPackageWeight($request->getFreeMethodWeight());
    $request->setPackageQty($oldQty - $freeQty);

    $result = $this->_getModel('shipping/rate_result');
    $rate = $this->getRate($request);

    $request->setPackageWeight($oldWeight);
    $request->setPackageQty($oldQty);

    if (!empty($rate) && $rate['price'] >= 0) {
        $method = $this->_getModel('shipping/rate_result_method');

        $method->setCarrier('tablerate');
        $method->setCarrierTitle($this->getConfigData('title'));

        $method->setMethod('bestway');
        $method->setMethodTitle($this->getConfigData('name'));

        if ($request->getFreeShipping() === true || ($request->getPackageQty() == $freeQty)) {
            $shippingPrice = 0;
        } else {
            $shippingPrice = $this->getFinalPriceWithHandlingFee($rate['price']);
        }

        $method->setPrice($shippingPrice);
        $method->setCost($rate['cost']);

        $result->append($method);
    } elseif (empty($rate) && $request->getFreeShipping() === true) {
        /**
         * was applied promotion rule for whole cart
         * other shipping methods could be switched off at all
         * we must show table rate method with 0$ price, if grand_total more, than min table condition_value
         * free setPackageWeight() has already was taken into account
         */
        $request->setPackageValue($freePackageValue);
        $request->setPackageQty($freeQty);
        $rate = $this->getRate($request);
        if (!empty($rate) && $rate['price'] >= 0) {
            $method = $this->_getModel('shipping/rate_result_method');

            $method->setCarrier('tablerate');
            $method->setCarrierTitle($this->getConfigData('title'));

            $method->setMethod('bestway');
            $method->setMethodTitle($this->getConfigData('name'));

            $method->setPrice(0);
            $method->setCost(0);

            $result->append($method);
        }
    } else {
        $error = $this->_getModel('shipping/rate_result_error');
        $error->setCarrier('tablerate');
        $error->setCarrierTitle($this->getConfigData('title'));
        $error->setErrorMessage($this->getConfigData('specificerrmsg'));
        $result->append($error);
    }

    return $result;
}

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.