3

I am applying custom discount to cart which should be applied if cart validates the shopping cart price rule, working fine discount getting applied.

But I just enabled the currency switcher and tested it on my custom applied discount and its not working with it,

ex : if base currency is dollar and I apply a $5 discount to cart where cart total is $90, so 90 - 5 = $85

works fine.

but when I switch the curreny to Euro cart total changes to €80.66 (standard currecy conversion) same should be done with custom discount but for discount only symbol changes to but value remain 5 and discount becomes €5, so value is 80.66 - 5 = €75.66

this is how I am applying discount to cart, please look at the code & suggest me how to do it correctly

config.xml

<?xml version="1.0"?>
<config>
    <modules>
        <Namespace_Modulename>
            <version>1.0.10</version>
        </Namespace_Modulename>
    </modules>
       <global>
      <events>
            <sales_quote_collect_totals_after>
              <observers>
                  <namespace>
                    <type>singleton</type>
                    <class>Namespace_Modulename_Model_Observer</class>
                    <method>setDiscount</method>
                  </namespace>
              </observers>
           </sales_quote_collect_totals_after>             
      </events>
  </global>

Observer.php

class Namespace_Modulename_Model_Observer
{
   public function setDiscount($observer)
   {
     $quote         =  $observer->getEvent()->getQuote();
     $quoteid       =  $quote->getId();
     $discountAmount=  10;

     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().', Custom Discount');
                $address->setBaseDiscountAmount(-($address->getBaseDiscountAmount()-$discountAmount));
                }else {
                    $address->setDiscountAmount(-($discountAmount));
                    $address->setDiscountDescription('Custom Discount');
                    $address->setBaseDiscountAmount(-($discountAmount));
                }
                $address->save();
           }//end: if
        } //end: foreach

        foreach($quote->getAllItems() as $item){
             $rat=$item->getPriceInclTax()/$total;
             $ratdisc=$discountAmount*$rat;
             $item->setDiscountAmount(($item->getDiscountAmount()+$ratdisc) * $item->getQty());
             $item->setBaseDiscountAmount(($item->getBaseDiscountAmount()+$ratdisc) * $item->getQty())->save();
        }
        }
    }
 }
}
1

Issue solved, magento stores base discount amount & also current discount amount, base discount amount for base currency & current for current selected currency.

So update the code to :

class Namespace_Modulename_Model_Observer
{

  public function setDiscount($observer)
  {
    $quote         =  $observer->getEvent()->getQuote();
    $quoteid       =  $quote->getId();
    $discountAmount=  10;

    if($quoteid) {
        if( $discountAmount > 0 ) {

            $total        = $quote->getBaseSubtotal();
            $currenttotal = $quote->getSubtotal();

            $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) {

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

                    $address    ->setSubtotalWithDiscount(      (float) $address    ->getSubtotalWithDiscount() -       $this->convertCurrency($discountAmount));
                    $address    ->setGrandTotal(                (float) $address    ->getGrandTotal()   -               $this->convertCurrency($discountAmount));
                    $address    ->setBaseSubtotalWithDiscount(  (float) $address    ->getBaseSubtotalWithDiscount() -   $discountAmount);
                    $address    ->setBaseGrandTotal(            (float) $address    ->getBaseGrandTotal()   -           $discountAmount);
                    $address    ->setSubtotalInclTax(           (float) $address    ->getSubtotalInclTax()     -        $this->convertCurrency($discountAmount));
                    $address    ->setBaseSubtotalTotalInclTax(  (float) $address    ->getBaseSubtotalTotalInclTax()   - $discountAmount);


                    if($address->getDiscountDescription()){
                        $address->setDiscountAmount(-($address->getDiscountAmount()-$this->convertCurrency($discountAmount)));
                        $address->setDiscountDescription($address->getDiscountDescription().$this->__(', + Custom Discount'));
                        $address->setBaseDiscountAmount(-($address->getBaseDiscountAmount()-$discountAmount));
                    } else {
                        $address->setDiscountAmount(-($address->getBaseDiscountAmount()-$this->convertCurrency($discountAmount)));
                        //$address->setDiscountDescription($this->__('Custom Discount'));
                        $address->setDiscountDescription($address->getDiscountDescription().$this->__(' + Custom Discount'));
                        $address->setBaseDiscountAmount(-($discountAmount));
                    }
                    $address->save();

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

                    $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() -    $this->convertCurrency($discountAmount))
                            ->setBaseGrandTotal(          $quote->getBaseSubtotal() -    $discountAmount)
                            ->setSubtotalWithDiscount(    $quote->getBaseSubtotal() -    $this->convertCurrency($discountAmount))
                            ->setBaseSubtotalWithDiscount($quote->getBaseSubtotal() -    $discountAmount)
                            ->save();
                }//end: if
            } //end: foreach

            foreach(    $quote->getAllItems() as $item  ){
               //We apply discount amount based on the ratio between the GrandTotal and the RowTotal
               $rat             =   $item   ->getPriceInclTax() /   $total;
               $curRat          =   $item   ->getPriceInclTax() /   $currenttotal;
               $ratdisc         =   $discountAmount   *  $rat;
               $curRatDisc      =   $discountAmount   *  $curRat;

               $item  ->setDiscountAmount(    ($item  ->getDiscountAmount()    +   $ratdisc) * $item  ->getQty());
               $item  ->setBaseDiscountAmount(($item  ->getBaseDiscountAmount()+   $curRatDisc) * $item  ->getQty())->save();
            }
        }
    }
}

public function convertCurrency($amount)
{
    $baseCurrencyCode = Mage::app()->getStore()->getBaseCurrencyCode();
    $currentCurrencyCode = Mage::app()->getStore()->getCurrentCurrencyCode();

    if ($baseCurrencyCode != $currentCurrencyCode) {
        $amount = Mage::helper('directory')->currencyConvert($amount, $baseCurrencyCode, $currentCurrencyCode);    
    }  

    return $amount; 
}
}

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.