2

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.

odd_duck
  • 3,941
  • 7
  • 43
  • 85

1 Answers1

3

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!

huzefam
  • 1,201
  • 1
  • 12
  • 21
  • Sorry for the delayed response, i've been away. Wow thank you so much for this. Can i be a pain and just ask how i would call the `collectTotals` function in the cart page? You mention setting a flag in session but i am unaware of this with my limited knowledge and have searched online without any luck – odd_duck Jun 30 '14 at 09:53
  • 2
    hi this function works perfect but problem when user click on submit then system charge clients with same amount ( without custom discount ) i am using this i create one button when user click on button i gave then $5 discount and at that time user can see discount but when user submit order after review then system charge user without discount. – Sandeep Singh Mar 12 '15 at 17:10
  • Thankx @huzefam for this code, it works perfectly but have an issue when customer uses paypal as payment method. while testing, i found that it doesn't add shipping amount to BaseGrandTotal and cause paypal to through error PayPal gateway has rejected request. The totals of the cart item amounts do not match order amounts (#10413: Transaction refused because of an invalid argument. See additional error messages for details). – Haris Oct 30 '15 at 13:19
  • what is the issue you are facing, could you elaborate – huzefam Oct 30 '15 at 13:20
  • just to let you know what i did for testing echo $referenceAmount and $sum in which are used for comparison app/code/core/Mage/Paypal/Model/Cart.php – Haris Oct 30 '15 at 13:31
  • @huzefam can you please confirm if the error occurs on your end – Haris Nov 01 '15 at 07:29
  • 1
    there should be another xml node inside – Tahir Yasin Jan 01 '16 at 13:01
  • I am having same issue that @Haris described, Haris did you find the solution or anybody here can help please? – Tahir Yasin Apr 23 '16 at 15:36