一聚教程网:一个值得你收藏的教程网站

热门教程

magento订单总价计算错误原因分析与解决办法

时间:2022-06-25 00:47:31 编辑:袖梨 来源:一聚教程网


原因分析

Magento 的订单价格计算是通过依次执行 config 配置的 global/sales/quote/totals 这个节点下设定的计价模型实现的,而执行顺序则是由各模型的 after 及 before 节点控制。比如,我们可以在原生的 app/code/core/Mage/Tax/etc/config.xml 这个配置文件中看到如下代码:


    ...
   
       
           
               
                    tax/sales_total_quote_subtotal
                    freeshipping
                    tax,discount
               

               
                    tax/sales_total_quote_shipping
                    shipping,tax_subtotal
                    tax,discount
               

               
                    tax/sales_total_quote_tax
                    subtotal,shipping
                    grand_total
                    tax/checkout_tax
                    adminhtml/sales_order_create_totals_tax
               

               
                    tax/checkout_subtotal
                    adminhtml/sales_order_create_totals_subtotal
               

               
                    tax/checkout_shipping
                    adminhtml/sales_order_create_totals_shipping
               

               
                    tax/checkout_discount
                    adminhtml/sales_order_create_totals_discount
               

               
                    tax/checkout_grandtotal
                    adminhtml/sales_order_create_totals_grandtotal
               

           

            ...
       

   

    ...

这里我们可以注意到 tax 这个模型的 before 节点指定了 grand_total,说明 tax 模型应该在 grand_total 模型之前执行。而程序执行的结果是不会骗人的,那么问题就来了,既然会出现开篇中提及的问题,原因是什么呢?

 

我们来看看订单总价计算机制中比较重要的几个环节。其中主要涉及以下几个方法:

购物车总价计算:

Mage_Sales_Model_Quote::collectTotals
通过分别计算购物车各地址总价(分地址计算是为了实现使用多地址运送功能时,不同地址可对应不同价格),再求和:

Mage_Sales_Model_Quote_Address::collectTotals
对每个地址总价的计算时,先通过查找 config 配置 global/sales/quote/totals 这个节点下的所有模型:

Mage_Sales_Model_Quote_Address::getTotalCollector
Mage_Sales_Model_Quote_Address_Total_Collector::getCollectors
再执行各个模型的 collect 方法计算相关价格,并通过父类 Mage_Sales_Model_Quote_Address_Total_Abstract(所有计价模型都继承于这个类)的 _addAmount 及 _addBaseAmount 方法把这个价钱叠加到总价中。

 

而在执行 Mage_Sales_Model_Quote_Address::getTotalCollector 这个方法时会执行 Mage_Sales_Model_Quote_Address_Total_Collector 这个类的构造函数。各计价模块的排序就是在这里进行的,使用的是这个方法:

Mage_Sales_Model_Config_Ordered::_getSortedCollectorCodes
计价顺序错误的问题也正是出现在这里边。关键在于以下这行为数组排序的程序,没有完全按照指定顺序对所有计价模型进行排列:

uasort($configArray, array($this, '_compareTotals'));
 

解决方法

解决方法比较简单,可以通过创建定制组件重写 Mage_Sales_Model_Quote_Address_Total_Collector 这个类(对计价模型排序时实质使用到的类,继承于 Mage_Sales_Model_Config_Ordered)的 _getSortedCollectorCodes 方法,在原来方法的基础上多执行一次或几次上边提到的这行排序代码就可以了。

热门栏目