【问题标题】:Magento - Dynamically change discount cost in cartMagento - 动态更改购物车中的折扣成本
【发布时间】:2014-06-19 13:43:02
【问题描述】:

在我的 magento 商店中,如何动态更改购物车中的折扣总额?

我可以使用此代码访问并获得当前折扣:

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

我的购物车中有一个按钮,按下该按钮时应在折扣值上增加 5 英镑,同时更新总成本等。

【问题讨论】:

    标签: magento cart discount


    【解决方案1】:

    magento中有一个事件,

    sales_quote_collect_totals_after
    

    每当计算您的总数时就会触发此事件,您可以做的是在会话中设置一个标志,点击按钮以应用折扣,并在上述事件的观察者方法中,检查它是否已设置然后应用折扣。

    在您的 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>
    

    在里面制作一个Observer.php

    Custom
      /Module
        /Model
          /Observer.php
    

    在 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 函数将在报价总额更新时被调用,因此无需显式调用。

    检查它是如何工作的here

    设置magento会话变量,检查here

    希望对你有帮助!

    【讨论】:

    • 抱歉,回复延迟,我已经离开了。哇,非常感谢你。我可以很痛苦,只是问我如何在购物车页面中调用collectTotals 函数?你提到在会话中设置一个标志,但由于我的知识有限,我不知道这一点,并且在网上搜索过没有任何运气
    • 您好,此功能完美运行,但当用户点击提交然后系统向客户收取相同金额(无自定义折扣)时出现问题那时用户可以看到折扣,但是当用户在审核后提交订单时,系统会向用户收取没有折扣的费用。
    • 感谢@huzefam 提供此代码,它可以完美运行,但当客户使用贝宝作为付款方式时会出现问题。在测试时,我发现它没有将运费添加到 BaseGrandTotal 并导致贝宝通过错误 PayPal 网关已拒绝请求。购物车项目总金额与订单金额不匹配(#10413:交易因参数无效而被拒绝。有关详细信息,请参阅其他错误消息)。
    • 您遇到了什么问题,能否详细说明
    • 里面应该有另一个xml节点
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-25
    • 1970-01-01
    • 2020-11-04
    • 1970-01-01
    • 2019-03-06
    相关资源
    最近更新 更多