Magento - Modify Cart Rules Function to apply discounts as a percentage of the original price instead of the product price

I am working on a project where all products in a store have a special price that is different (reduced) from the original price.

I want to be able to use the discounts in the shopping cart as a percentage of the original price, just like in the Discount Rules for the catalog discount.

Right now, if I applied the Percentage of Product Price shopping cart rule, it would apply the discount to the special price instead of the original price.

Where is the function for cart rules? Any details on changing it to apply discounts to the original price will be appreciated.

+3


source to share


1 answer


I recently had to solve the same problem. These two blogging guides were very helpful in developing my final solution.

My custom observer on the event salesrule_validator_process

looks like this:

class My_SalesRule_Model_Observer
{
    // New SalesRule type
    const TO_ORIGINAL_PRICE = 'to_original_price';

    /**
     * Add the new SalesRule type to the admin form.
     * @param Varien_Event_Observer $obs
     */
    public function adminhtmlBlockSalesruleActionsPrepareform($obs)
    {
        $field = $obs->getForm()->getElement('simple_action');
        $options = $field->getValues();
        $options[] = array(
            'value' => self::TO_ORIGINAL_PRICE,
            'label' => Mage::helper('salesrule')->__('Percent of original product price discount')
        );
        $field->setValues($options);
    }

    /**
     * Apply the new SalesRule type to eligible cart items.
     * @param Varien_Event_Observer $obs
     */
    public function salesruleValidatorProcess($obs)
    {
        /* @var Mage_SalesRule_Model_Rule $rule */
        $rule = $obs->getRule();
        if ($rule->getSimpleAction() == self::TO_ORIGINAL_PRICE) {
            /* @var Mage_Sales_Model_Quote_Item $item */
            $item = $obs->getItem();
            // Apply rule qty cap if it exists.
            $qty  = $rule->getDiscountQty()? min($obs->getQty(), $rule->getDiscountQty()) : $obs->getQty();
            // Apply rule stepping if specified.
            $step = $rule->getDiscountStep();
            if ($step) {
                $qty = floor($qty / $step) * $step;
            }

            // Rule discount amount (assumes %).
            $ruleDiscountPercent = $rule->getDiscountAmount();
            /* @see My_Catalog_Model_Product::getDiscountPercent */
            $productDiscountPercent = $item->getProduct()->getDiscountPercent();

            // Ensure that the rule does not clobber a larger discount already present on the $cartItem.
            // Do not apply the rule if the discount would be less than the price they were already quoted
            // from the catalog (i.e. special_price or Catalog Price Rules).
            if ($ruleDiscountPercent > $productDiscountPercent) {
                // Reduce $ruleDiscountPercent to just the gap required to reach target pct of original price.
                // In this way we add the coupon discount to the existing catalog discount (if any).
                $ruleDiscountPercent -= $productDiscountPercent;

                $pct = $ruleDiscountPercent / 100;
                // Apply the discount to the product original price, not the current quote item price.
                $discountAmount = ($item->getProduct()->getPrice() * $pct) * $qty;

                $item->setDiscountPercent($ruleDiscountPercent);
                $obs->getResult()
                    ->setDiscountAmount($discountAmount)
                    ->setBaseDiscountAmount($discountAmount);
            }
        }
    }
}

      



If you've configured your extension correctly, you'll see a new type of rule:

Promotions → Shopping cart rules → Modify "New rule" → Actions → Update prices using the following information: Apply [Percentage of discount price for original products]

Caveats: You've noticed that I've implemented this to work with percentages, including creating a method on the product model to calculate the catalog discount (i.e. special price and other discounts applicable at the catalog level). You will need to implement this if you want to do the same, or update this logic to suit your scenario, perhaps just referencing $item->getProduct()->getPrice()

.

0


source







All Articles