2011-11-24 52 views
4

好的,我创建了自定义的Total类,用于添加特殊折扣,并且一切看起来都正常,除了由于某种原因我无法找到,我的总计算了两次!这会导致双倍的折扣,并导致总计不正确。现在,这发生在购物车页面和结帐页面上......但是......当我完成订单时总数很好,只计算一次,总计很好。Magento:自定义总数计数两次?

奇怪的是,这就像收集方法被称为购物车页面的两次,但只有一次完成订单,但我可以'追踪所有这些发生的地方,为什么。

要跳过垃圾代码,我就只粘贴重要

 <sales> 
     <quote> 
      <totals> 
       <mydiscount> 
        <class>ucon_mydiscount/total_mydiscount</class> 
        <before>subtotal</before> 
       </mydiscount> 
      </totals> 
     </quote> 
    </sales> 

和收藏家的方法

public function collect(Mage_Sales_Model_Quote_Address $address) 
{ 
    parent::collect($address); 

    $quote = $address->getQuote(); 
    $quoteId = $quote->getEntityId(); 

    $items = $quote->getAllItems(); 
    if (!count($items)) { 
     return $this; 
    }  


    $discount = 0; 
    $productId = 2556; 

    foreach($items as $item) 
    {  
     if($item->getProduct()->getId() == $productId) 
     { 
      $qty = $item->getQty(); 
      $totalPrice = round(($item->getRowTotal()+$item->getTaxAmount()),2); 

      //discount 10%    
      $discount = round($totalPrice * 0.1,2);  

      $discount = 0 - $discount; 
     } 
    } 

    if($discount == 0) 
     return $this; 

    $this->_setAmount($discount); 
    $this->_setBaseAmount($discount); 


    return $this; 
} 

和提取程序

public function fetch(Mage_Sales_Model_Quote_Address $address) 
{ 
    $amount = $address->getMydiscountAmount(); 
    if ($amount != 0) { 
     $title = Mage::helper('ucon_mydiscount')->__('My discount'); 
     $address->addTotal(array(
      'code' => $this->getCode(), 
      'title' => $title, 
      'value' => $amount 
     )); 
    } 
    return $this; 
} 

编辑:还有一两件事,我觉得很奇怪 - 我在我的collect方法中执行setValue,而不是addValue,所以即使方法被调用了t它不应该是双重值,它应该简单地将它设置为正确的值两次。

+0

我用Andrey的评论作为出发点,从[这里](http://stackoverflow.com/questions/4363876/how-to-set-custom-grand-total-before-checkout-process-in-magento ) – Relja

+0

我经历过这一次,但现在不能找到我所做的修复它。我相信我复制了一个Mage类,明确地检查了总数是否已经被使用了。尝试在每个收集和提取函数中添加断点或“Mage :: log(__ METHOD __)”,以查看两次调用的内容 - 这是我上次调试的方式。 – clockworkgeek

回答

15

难道问题是总的对象属于地址对象,而Magento订单通常有两个地址 - 一个用于装运,一个用于结算?

因此将调用您的总计以运行两次 - 一次使用帐单邮寄地址,一次使用邮寄地址,并且金额总计为每个地址。您可以尝试检查您已交出的地址,并且只将值应用于其中之一;

public function collect(Mage_Sales_Model_Quote_Address $address) { 

    $this->_setAddress($address); 
    $this->_setAmount(0); 
    $this->_setBaseAmount(0); 

    if ($address->getAddressType() == 'shipping') { 
    //only apply an actual value to the shipping address 

    //... Do your calculation here as above ... 

    } 

    return $this; 
} 

你也必须做的获取方法,以及类似的东西...

public function fetch(Mage_Sales_Model_Quote_Address $address) { 

    $amount = $address->getMydiscountAmount(); 

    if ($amount != 0 && $address->getAddressType() == 'shipping') { 

    $title = Mage::helper('ucon_mydiscount')->__('My discount'); 

    $address->addTotal(array(
     'code' => $this->getCode(), 
     'title' => $title, 
     'value' => $amount 
    )); 

    } 

    return $this; 
} 

我得承认,collect功能可能是更漂亮,但希望你的想法呢。

试试看看您的总计是否在前端和管理区域正确合计。

+0

不能相信什么****谢谢,不会发现它在一百万年:) – Relja

+0

嗨,我添加了'if($ address-> getAddressType()=='shipping'){',总计在结帐页面中是正确的。但完成订单后错误,看来我的自定义总数不算。任何人都知道什么是错的? – Wakanina

+0

@Wakanina我自己从来没有像前一样将前台总共作为后端,我需要将总数转换为后端的附加产品,我在“checkout_type_onepage_save_order”事件中对观察员进行了收集总量的操作,并将此值的产品添加到订单中。这个博客看起来像是在正确的轨道上:http://www.classyllama.com/blog/unravelling-magentos-collecttotals-orders-and-caveats –

0

是否有可能在购物车块中添加自己的布局xml代码?如果是的话,块被调用两次的机会很大(一个来自基本代码,另一个来自代码 - 即使你只是扩展它),从而重复价格总额。如果是这种情况,您需要删除(破坏性地使用<remove>标签)该块的基本布局xml,然后应该落实到位并开始工作。

+0

不幸的是,事实并非如此。我的布局中有两个购物车块 - 一个用于常规购物车页面,另一个用于购物车/侧边栏。但我试图禁用所有我自己的布局,并使用基本布局,问题仍然存在。 是否有方法可以查看我的收集方法被调用的方法/块? 感谢您的回答。 – Relja

1

周围搜索后,这里是另一种解决方案

public function collect(Mage_Sales_Model_Quote_Address $address) { 
    parent::collect($address); 

    //Pay attention to this code 
    $items = $this->_getAddressItems($address); 
    if (!count($items)) { 
     return $this; //this makes only address type shipping to come through 
    } 

    //Do whatever you want here to add discount or fee... 

    return $this; 
} 

通过这样做,折扣或费用将只增加了送货地址,它会计算一次。所以我们甚至不需要在fetch函数中添加if ($address->getAddressType() == 'shipping') {