当前位置: 首页>>WEB开发>>正文


修改购物车报价项目的税率并重新计算

webfans WEB开发 , , , 去评论

问题描述

当您订购超过一定数量时,我有一类产品(法律上)需要改变其税率。当您将新产品添加到购物车时,我已经扩展了各种税收模式以使其发挥作用,但是当用户更新购物车中的数量或添加额外的产品时,我遇到了问题,这些产品会将购物车中已有数量超过阈值量。

问题1:

首先,我不是100%观察哪些事件。我已经尝试了以下;

checkout_cart_save_after(基于此 – > https://stackoverflow.com/questions/14362702/magento-programatically-update-cart-via-event)

checkout_cart_update_items_after(基于此 – > https://stackoverflow.com/questions/5104482/programmatically-add-product-to-cart-with-price-change)

sales_quote_save_before(基于此 – > https://stackoverflow.com/questions/7638858/magento-recalculate-cart-total-in-observer)

问题2:

我能够从购物车访问报价商品,有很多方法可以做到这一点。我也可以遍历购物车中的各个物品,更新这些物品的属性,然后保存这些物品(至少暂时)。但是,我不能保存报价并在结帐时重新计算税金。

部分原因是,虽然我可以访问购物车报价,但我不确定使用哪种方法可以写入购物车报价。

我试过的东西:

我在试用购物车内容方面的尝试取决于我观察到的事件,但我尝试了以下所有内容;

1. 
$item = $observer->getQuoteItem;

2.
$cart = Mage::getSingleton('checkout/cart');
$cartItems = $cart->getCart()->getItems(); 

3.
$cart = $observer->getData('cart');
$quote = $cart->getData('quote');
$cartItems = $quote->getAllVisibleItems();

4.
$cartHelper = Mage::helper('checkout/cart');
$cartItems = $cartHelper->getCart()->getItems(); 

5.
$quote = Mage::getModel('checkout/cart');
$cartItems = $quote->getItems(); 

似乎至少允许我访问报价,运行并更新项目的人是

6.
$quote = Mage::getSingleton('checkout/session')->getQuote();
$cartItems = $quote->getAllVisibleItems();

这使我可以在迭代时更新每个报价项目(我相信使用魔法设置器,因为我无法找到任何相应的方法)。我希望能够更新报价项目的税收类别ID,然后重新计算税款。如果我使用以下(其中$ taxClassId与每个报价项目已经使用的不同);

$item->setTaxClassId( $taxClassId );
$item->getProduct()->setIsSuperMode(true);
$item->save;

然后记录结果;

Mage::log($item->debug(), null,'taxobserver.log', true);

它显示我已确实更新了此报价项目并更改了税号。但是,如果我接下来尝试保存修改后的引用;

$quote->setTotalsCollectedFlag(false)->collectTotals();
$quote->save();     

然后再调试一次;

Mage::log($item->debug(), null,'taxobserver.log', true);

我的更改尚未保存,报价项目更改已重置且购物车总计不会重新计算。开始怀疑是否找到一座可以跳楼的高楼可能是解决这个问题的方法。

最佳解决办法

我的建议是让观察员在Mage_Sales_Model_Quote::collectTotals事件中触发sales_quote_collect_totals_before事件,然后开始全部收集过程。然后从这个观察者方法中,迭代报价项目并更改已从报价项目检索的(已加载的)产品对象上的税收类别。

在产品对象上设置信息后,无论您做什么,都不要尝试将其保存到数据库中。根据需要在内存中设置产品对象的税级将足够好,以便在Mage_Tax_Model_Sales_Total_Quote_Tax拾取中找到收集总计逻辑,该计算应基于它计算的税级。保存产品(就像你在上面的代码示例中试图做的那样)将导致重大性能问题,在计算过程中会产生竞争条件,并且不是好的做法。

您尝试使用的事件并不能帮助您完成您想要完成的事情,因为它们都是在总计算之后进行的,这一过程在保存报价前只能运行一次。

值得指出的收集总计过程是,一旦运行,没有做额外的工作,你不能再次调用它使re-calculate根据您对报价项目所做的更改。看到这个tie-bit我从博客系列中摘取了一位最近合并在收集总计过程中的同事:

Now that you understand what occurs during the totals collection process, you may find it convenient or necessary to call it directly yourself. Before you start feeling too confident with using collectTotals for your own purposes, though, keep the following rule in mind:

Products cannot be added to the quote after collectTotals is run!

. . . unless the quote addresses’ item caches are cleared.

Nearly every total model’s “collect” method relies on fetching the quote items from the address and looping through them. The first time getAllItems is run on a quote address, the item collection is actually cached with a unique key, and it’s this cached collection that is returned on subsequent calls.

如果您真的有深入了解汇总过程如何工作的深刻印象,您可以查看关于全部汇总的四部分系列中的第一部分,以获取更多in-depth读数:Unravelling Magento’s collectTotals: Introduction

总而言之,您需要捕获在收集总计过程之前(并且在引用地址上调用getAllItems之前)运行的事件,以便您对这些项目所做的更改将由总收集器使用。我没有证实建议的sales_quote_collect_totals_before事件在引用地址上的任何getAllItems调用之前运行,但我几乎可以肯定它可以满足您的需求。但是,如果没有,希望我已经提供了足够的背景让你弄清楚你需要抓住哪个事件才能使它工作。

次佳解决办法

还有另一个事件:Mage_Sales_Model_Quote_Item :: setProduct中的sales_quote_item_set_product

Mage::dispatchEvent('sales_quote_item_set_product', array(
            'product' => $product,
            'quote_item'=>$this
        ));

您可以使用此事件修改产品税类。使用quoteItem getQty方法来查找添加到购物车的数量。

第三种解决办法

也许试图改变税收可能不是最好的办法。为什么不为那些使用较高税级的产品创建一个类似的产品,并为该产品设置最小数量的购物车。然后使用checkout_cart_update_items_after根据购物车中的总量交换产品?

这绝对不是’best practice’,但它可能有助于您从另一个方向思考。

或者,尝试使用http://www.mageworx.com/multi-fees-magento-extension.html设置某些内容,并在其中添加’fee’以获取额外税款。这实际上可能是一个更好的方法,但它不会出现在税收总额中,更多的是作为额外的订单总额。

参考资料

本文由朵颐IT整理自网络, 文章地址: https://duoyit.com/article/2002.html,转载请务必附带本地址声明。