Magento - Dynamically change discount cost in cart

12,390

There is an event in magento,

sales_quote_collect_totals_after

This is fired whenever your total is calculated, what you can do is set a flag in session on click on the button to apply discount, and in this above event's observer method, check if it is set then apply discount.

In your config.xml

<global>
 <events>
   <sales_quote_collect_totals_after>
     <observers>
       <class>Custom_Module_Model_Observer</class>
       <method>collectTotals</method>
     </observers>
   </sales_quote_collect_totals_after>
 </events>
</global>

Make a Observer.php in

Custom
  /Module
    /Model
      /Observer.php

Make a function in Observer.php

public function collectTotals(Varien_Event_Observer $observer)
{
       $quote=$observer->getEvent()->getQuote();
       $quoteid=$quote->getId();
    //check condition here if need to apply Discount
        if($disocuntApply) $discountAmount =5;

     if($quoteid) {
               if($discountAmount>0) {
           $total=$quote->getBaseSubtotal();
           $quote->setSubtotal(0);
           $quote->setBaseSubtotal(0);

           $quote->setSubtotalWithDiscount(0);
           $quote->setBaseSubtotalWithDiscount(0);

           $quote->setGrandTotal(0);
           $quote->setBaseGrandTotal(0);


           $canAddItems = $quote->isVirtual()? ('billing') : ('shipping'); 
           foreach ($quote->getAllAddresses() as $address) {

                    $address->setSubtotal(0);
                    $address->setBaseSubtotal(0);

                    $address->setGrandTotal(0);
                    $address->setBaseGrandTotal(0);

                    $address->collectTotals();

                    $quote->setSubtotal((float) $quote->getSubtotal() + $address->getSubtotal());
                    $quote->setBaseSubtotal((float) $quote->getBaseSubtotal() + $address->getBaseSubtotal());

                    $quote->setSubtotalWithDiscount(
                        (float) $quote->getSubtotalWithDiscount() + $address->getSubtotalWithDiscount()
                    );
                    $quote->setBaseSubtotalWithDiscount(
                        (float) $quote->getBaseSubtotalWithDiscount() + $address->getBaseSubtotalWithDiscount()
                    );

                    $quote->setGrandTotal((float) $quote->getGrandTotal() + $address->getGrandTotal());
                    $quote->setBaseGrandTotal((float) $quote->getBaseGrandTotal() + $address->getBaseGrandTotal());

           $quote ->save(); 

              $quote->setGrandTotal($quote->getBaseSubtotal()-$discountAmount)
              ->setBaseGrandTotal($quote->getBaseSubtotal()-$discountAmount)
              ->setSubtotalWithDiscount($quote->getBaseSubtotal()-$discountAmount)
              ->setBaseSubtotalWithDiscount($quote->getBaseSubtotal()-$discountAmount)
              ->save(); 


            if($address->getAddressType()==$canAddItems) {

             $address->setSubtotalWithDiscount((float) $address->getSubtotalWithDiscount()-$discountAmount);
             $address->setGrandTotal((float) $address->getGrandTotal()-$discountAmount);
             $address->setBaseSubtotalWithDiscount((float) $address->getBaseSubtotalWithDiscount()-$discountAmount);
             $address->setBaseGrandTotal((float) $address->getBaseGrandTotal()-$discountAmount);
             if($address->getDiscountDescription()){
             $address->setDiscountAmount(-($address->getDiscountAmount()-$discountAmount));
             $address->setDiscountDescription($address->getDiscountDescription().', Amount Waived');
             $address->setBaseDiscountAmount(-($address->getBaseDiscountAmount()-$discountAmount));
             }else {
             $address->setDiscountAmount(-($discountAmount));
             $address->setDiscountDescription('Amount Waived');
             $address->setBaseDiscountAmount(-($discountAmount));
             }
             $address->save();
            }//end: if
           } //end: foreach
           //echo $quote->getGrandTotal();

          foreach($quote->getAllItems() as $item){
                         //We apply discount amount based on the ratio between the GrandTotal and the RowTotal
                         $rat=$item->getPriceInclTax()/$total;
                         $ratdisc=$discountAmount*$rat;
                         $item->setDiscountAmount(($item->getDiscountAmount()+$ratdisc) * $item->getQty());
                         $item->setBaseDiscountAmount(($item->getBaseDiscountAmount()+$ratdisc) * $item->getQty())->save();

                       }


                    }

            }
         }

collectTotals function will be called, whenever the quote totals is updated, so there is no need to call it explicitly.

Check for how it works here.

Setting magento session variables, check here.

hope it helps!

Share:
12,390
odd_duck
Author by

odd_duck

Updated on June 04, 2022

Comments

  • odd_duck
    odd_duck almost 2 years

    In my magento store how can i go about changing the discount total in my shopping cart dynamically?

    I'm able to access and get the current discount with this code:

    <?php
    $quote = Mage::getSingleton('checkout/cart')->getQuote();
    $totals =  $quote->getTotals(); 
    $discount = $totals["discount"]->getValue();
    ?>
    

    I have a button in my shopping cart that when pressed should add an extra £5 onto the discount value, updating the total cost etc at the same time.