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.

1 Answer 1

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!

Sign up to request clarification or add additional context in comments.

8 Comments

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
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.
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).
what is the issue you are facing, could you elaborate
there should be another xml node inside <observers>
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.