修改购物车报价物品的税率并重新计算
-
16-10-2019 - |
题
我有一类产品(合法地)需要在您订购超过一定数量时需要更改其税率。当您在购物车中添加新产品时,我已经扩展了各种税收模型,但是当用户更新购物车中的数量或添加其他产品时,我会遇到问题数量。
问题1:
首先,我不是100%要观察的事件。我尝试了以下内容;
checkout_cart_save_after
(基于此 - > https://stackoverflow.com/questions/14362702/magento-prograginationally-update-cart-cart-via-vent)
checkout_cart_update_items_after
(基于此 - > https://stackoverflow.com/questions/5104482/programmatily-add-product-to-cart-with-with-price-change)
sales_quote_save_before
(基于此 - > https://stackoverflow.com/questions/7638858/magento-recalculate-cart-total-in-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与每个报价项目已经使用的$ 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);
我的更改尚未保存,报价项目的更改已重置,也没有重新计算购物车的总数。开始怀疑是否找到一座高大的建筑物可能是解决方案。
解决方案
我的建议是将观察者放在 sales_quote_collect_totals_before
事件在 Mage_Sales_Model_Quote::collectTotals
在开始总收集过程之前。然后从此观察者方法内部迭代报价项目,然后更改(已经加载的)产品对象上的税类,您可以从报价项目中检索。
在产品对象上设置信息后,无论您做什么,都不要尝试将其保存到数据库中。在内存中的产品对象上设置税务类将足够好,可以在 Mage_Tax_Model_Sales_Total_Quote_Tax
拾取其应根据其计算为基础的税类。保存产品(正如您似乎在上面的代码示例中尝试执行的那样)将引起重大的性能问题,将在计算过程中创建竞赛条件,而不是很好的做法。
您尝试使用的事件之所以使您能够完成您要完成的工作,是因为它们全部是在总计计算之后进行的,该过程仅在保存报价之前只能运行一次。
值得指出的是收集总过程的是,一旦运行,在不做额外的工作的情况下,您不能再次称呼它,以根据对报价项目的更改进行重新计算。查看我从博客系列A的收藏集中汇集的这一领带,在收集总计上进行了汇总:
现在,您了解了总计收集过程中发生的情况,您可能会发现直接称其为直接称呼它。但是,在您开始对自己的目的使用collecttotals感到过于自信,请记住以下规则:
运行收藏量后,无法将产品添加到报价中!
. 。 。 。除非报价地址为清除项目缓存。
几乎每个模型的“收集”方法都依赖于从地址获取报价项目并通过它们循环。 GetalliTems首次在报价地址上运行,该项目集合实际上是用唯一键缓存的,正是此缓存集合在后续呼叫上返回。
如果您确实碰巧有一个意识到,可以真正潜入收集总过程的工作深处,则可以在此处查看Total Collection四部分系列中的第一个,以获取更多的深入阅读: 解开洋红色的收藏:简介
总而言之,您需要捕获一个事件,该事件在收集总计过程(以及在报价地址上调用GetalliTems之前),以便您对项目进行的更改将由总收集者使用。我没有证实建议 sales_quote_collect_totals_before
事件在任何电话之前运行 getAllItems
在报价地址上,但我几乎可以肯定它可以适合您的需求。但是,如果没有,希望我提供了足够的上下文,以找出您需要抓住哪个事件才能使其正常工作。
其他提示
还有另一个事件: sales_quote_item_set_product
在mage_sales_model_quote_item :: setProduct中
Mage::dispatchEvent('sales_quote_item_set_product', array(
'product' => $product,
'quote_item'=>$this
));
您可以使用此事件修改产品税类。使用QuoteItem getQty方法查找添加到购物车中的数量。
也许试图改变税级可能不是最好的方法。为什么不为那些使用较高税类并为该产品的购物车设定最小数量的产品创建类似的产品。然后使用 checkout_cart_update_items_after
根据购物车中的总数量来交换产品?
这绝对不是“最佳实践”,但它可能会帮助您朝另一个方向思考。
或者尝试与 http://www.mageworx.com/multi-fees-magento-extension.html 在哪里增加额外税费的“费用”。这实际上可能是一种更好的方法,但它不会以税收总计出现,而是额外的订单总线。
用这个 <sales_quote_collect_totals_before>
在您的功能中喜欢
public function quoteCollectTotalsBefore(Varien_Event_Observer $observer)
$quote = $observer->getQuote();
foreach ($quote->getAllItems() as $item)
{
$product = $item->getProduct();
$product->setTaxClassId($product_tax_class_id);
}
}
我希望这将一定能起作用