很久以前(一年多,实际上),我在Magento发表了一系列文章’S Cart Totals Collection Process(链接上面),它是如何运作的,以及如何自定义它。该系列提供了一个完全新的总计的指南,但是尝试这个程序的任何牢固开发人员都可能发现了一件缺失的作品:虽然以前的文章提供了将新的总计进入购物车并进入最终订单的一步一步,但是这些总计需要更多的努力来达到订单’申博娱乐和信用备忘录。如果您的订单履行过程发生在Magento中,则花哨的自定义总计在没有支持这些组件的情况下几乎没有任何使用。因此,它’大约是时候探索这些最终碎片。
我们的主要复杂性’在订单仍在购物车/结账阶段,已经看过已经在收集器模型中执行了必要的计算。一旦购物车成为订单,总计只是需要复制到该订单的一系列数字。
人们可能希望这个过程只是那么简单–像复制数字一样简单–创建申博娱乐或信用备忘录时。如果订单仅生产单一申博娱乐,则可能是这种情况。然而,由于只能在订单的一部分申博娱乐或退款的能力,复杂性再次进入。如果我’m目前只有5个项目中只有2个订单,Magento需要知道如何计算每个总数的数量,并且每个总共应该是申博娱乐的一部分。对于本土运输总量,整个金额始终包含在第一个申博娱乐中。但是,对于税收总,该过程更加复杂,需要计算特定的开票项目。
这种复杂程度开始听起来像我们在购物车进程中的面临。并且以一种说话方式’究竟我们又一次– a “cart”建立在创建申博娱乐或信用备忘录而不是订单,可能涉及不同的计算。毕竟,我们’重新认为以前考虑的是先前申博娱乐的金额。那么你’我们可能猜到这一点是我们的’重新处理:专用收集器型号仅为此目的。
幸运的是,在如何引用(即购物车)总数下窥视和管理,我们’装备好理解申博娱乐和信用备忘录总计,因为该过程是相同的。第一步是在配置XML中声明与它们相关联的这些总计和模型。以下是来自核心的示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
. . . . . . 销售量/命令_申博娱乐_全部的_运输 小计,折扣 盛大_全部的,税 . . . . . . 销售量/命令_CreditMemo._全部的_运输 小计,折扣 盛大_全部的,税 . . . . . . |
与报价和订单一样,大多数总数将涉及新的字段,以存储在申博娱乐和信用备忘录表上的适当金额,以及在某些情况下,申博娱乐项目和信用备忘录项目表。作为一个例子,字段“tax_amount” and “base_tax_amount”存在于下表中:
声明的总模型包含一个“collect”方法,就像他们的引用同行一样。这“fetch”然而,引用总计所需的方法是’在这种情况下存在。这是因为申博娱乐和信用备忘录总计的显示过程更接近订单的方式,而不是在购物车中处理的方式。 (一世’很快就达到那样。)
关于定义总计的基本进程的最终说明:我们之前检查了配置节点的使用“fieldsets”从报价转移到订单。 (节点“Global /Fir原套/ sales_convert_quote_address / shipping_amount / to_order”负责报价 ’S Shipping Total将其达到所8次订单。)你赢了’不过,查找订单到申博娱乐或订单到信用备忘录的相同程序。这个流程 将要 工作;定义节点“全局/Fir原套/ sales_convert_order / shipping_amount / to_invoice”将确实会导致订单’S运输金额被复制到从中创建的每份申博娱乐。这是一个’但是,真的是我们想要的。重申,申博娱乐和信用备忘录的总计计算’t只是一个复制数字的问题;如果我从相同的顺序创建三个信用备忘录,我几乎不想要订单’■每次退还全额税金额。 (并且没有收集者模型仍然赢了’T成功地影响了信用备忘录’s grand total, as we’ll see.)
为清楚起见的说明:正如每次在前端查看购物车的情况下运行Collectotals流程一样,重新计算每次更改的所有金额,当创建申博娱乐或信用备忘录时,相同就是如此。正如正在准备和更新的申博娱乐(例如,通过管理用户更改要申博娱乐的数量),收集过程一遍又一遍才能更新我们看到的总计。它’■不是仅在申博娱乐(或信用备忘录)的最终创建时发生的进程。
块类MAGE_SALES_BLOCK_ORDER_TOTALS和其子项MAGE_SALES_BLOCK_ORDER_INVOICE_TOTALS和MAGE_SALES_BLOCK_ORDER_CREDITMEMO_TOTALS负责在订单确认电子邮件和前端中的帐户部分中呈现总计。相关类MAGE_ADMINHTML_BLOCK_SALES_ORDER_TOTALS,MAGE_ADMINHTML_BLOCK_SALES_ORDER_INVOICE_TOTALS,MAGE_ADMINHTML_BLOCK_SALES_ORDER_CREDITMEMO_TOTALS为管理员提供此作业。以下是布局XML文件中的块声明的示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<adminhtml_sales_order_view.> . . . <reference 姓名=“剩下”> <block 类型=“adminhtml / sales_order_view_view_tabs” 姓名=“sales_order_tabs”> <block 类型=“adminhtml / sales_order_view_tab_info” 姓名=“order_tab_info” 模板=“销售/订单/查看/标签/ info.phtml”> . . . <block 类型=“adminhtml / sales_order_totals” 姓名=“ORDER_TOTALS” 模板=“销售/订单/ totals.phtml”> . . . </block> . . . </block> </reference> . . . </ adminhtml_sales_order_view..> |
在上一个条目中“Orders and Caveats”在本系列中,我最初声称,需要在订单阶段成功显示定制总数,因为Vinai Kopp的一些有用建议,只需要备份这些块。由于申博娱乐和信用备忘录总数的显示与订单相同,这为我们提供了一个返回和探索更好的替代方案的绝佳机会。
每个块调用“initTotals”在具有这样的方法的任何子块上。如果我们为自定义总计定义此类子块,则这些类可以依次抓住他们的父级并调用addtotal或addtotalBefore来修改总计阵列,从而消除了对块重写的需求。这里’s在布局XML中为每个父级添加自定义总块的示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
<adminhtml_sales_order_view.> <reference 姓名=“ORDER_TOTALS”> <block 类型=“mymodule / sales_order_totals_mytotal” 姓名=“total_mytotal” /> </reference> </ adminhtml_sales_order_view..> <adminhtml_sales_order_invoice_new. > <reference 姓名=“申博娱乐_totals”> <block 类型=“mymodule / sales_order_totals_mytotal” 姓名=“total_mytotal” /> </reference> </ adminhtml_sales_order_invoice_new. .> <adminhtml_sales_order_creditmemo._new.> <reference 姓名=“creditmemo_totals”> <block 类型=“mymodule / sales_order_totals_mytotal” 姓名=“total_custom_mytotal” /> </reference> </ adminhtml_sales_order_creditmemo._new..> |
和块本身的示例代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
班级 me_mymodule_block_sales_order_totals_mytotal. 延伸 mage_core_block_abstract. { 民众 功能 getSource.() { 返回 $这一点->.;getparentblock.()->.;getSource.(); } / ** *将此总数添加到父级 */ 民众 功能 在ittotals.() { 如果 ((漂浮)$这一点->.;getSource.()->.;getmytotalamount.() ==. 0) { 返回 $这一点; } $总数 = 新的 varien_object.(大批( '代码' =>.; 'mytotal', '场地' =>.; 'mytotal_amount', '价值' =>.; $这一点->.;getSource.()->.;getmytotalamount.(), '标签' =>.; $这一点->.;__('我的总') )); $这一点->.;getparentblock.()->.;addtotalbefore.($总数, '运输'); 返回 $这一点; } } |
唯一繁琐的部分正在确保将此更新应用于所有适当的布局句柄。以下是前端相关布局更新处理的列表:
此处是管理员中的相关手柄:
完全解释定制这些地区的综合示例将包括在结束本系列的综合示例中。
除了申博娱乐和信用备忘录总数的简单宣言之外,重要的问题是他们的计算如何与报价中的计算方式。如果您有一个以建立您自己的纯完整的总数,那就是’你有问题的症结’LL必须为自己决定:您如何在仅开票或退款的一部分订单时如何计算金额?您的自定义全部全部全部全部支付全部在第一申博娱乐上立即应付(如本土运费总额)?如果退还一项项目(并申请退款相应的退款金额),您的定制折扣是否需要重新计算整个订单?
这些是难以完成的棘手的问题,但原始总收集者至少会对您的计算提供一些数据以及如何获得的数据。开始,让’s仅在整个订单上跟踪自定义总数,而不是在单个项目上跟踪,并且我们无需在多个申博娱乐或退款之间将其拆分。本土“collect”Mage_sales_model_order_invoice_total_shipping和mage_sales_model_order_creditmemo_total_shipping为我们提供了一个等价的例子,并演示了一些我们的东西’LL需要处理。
这里’一个令人难以置信的剥离版本的申博娱乐“collect”假设自定义的方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
民众 功能 搜集(mage_sales_model_order_invoice. $申博娱乐) { $申博娱乐->setmytotalamount.(0); $申博娱乐->setbasemytotalamount.(0); Foreach. ($申博娱乐->getOrder..()->GetInvoicCollection.() 作为 $ previnvoice.) { 如果 ($ previnvoice.->getmytotalamount.() && !$ previnvoice.->iscanceled.()) { 返回 $这一点; } } $ mytotalamt. = $申博娱乐->getOrder..()->getmytotalamount.(); $ basemytotalamt. = $申博娱乐->getOrder..()->getbasemytotalamount.(); $申博娱乐->setmytotalamount.($ mytotalamt.); $申博娱乐->setbasemytotalamount.($ basemytotalamt.); $申博娱乐->setgrandtotal.($申博娱乐->getgrandtotal.()+$ mytotalamt.); $申博娱乐->setbasegrandtotal.($申博娱乐->getBaseGrandTotal.()+$ basemytotalamt.); 返回 $这一点; } |
如果需要每件商品跟踪您的自定义总数,或者如果您需要将其划分为多个申博娱乐和贷记备忘录,则可能在您的模型中有一些更复杂的计算。如果我们查看其他一些本机总计逻辑(例如MAGE_SALES_MODEL_ORDER_INVOICE_TOTAL_TAX和MAGE_SALES_MODEL_OLER_CREDITMEMO_TOTAL_TAX),我们可以收集一些额外的有用细节:
笔记: Use the “isLast”谨慎检查,因为在综合产品正在申博娱乐/退款的情况下显然不可靠。在我的测试中,我观察到这一点“isLast”在申博娱乐中存在可配置产品时导致假阴性的方法。“isLast”在申博娱乐或信用备忘录模型上,在相关项目上运行相同的命名方法,该方法将当前数量与留给申博娱乐/退款的数量进行比较。但是,上述了“isDummy”条件是在一个情况下应用而不是另一个情况,导致不准确的比较。幸运的是,这里执行的逻辑并不难以复制,并且您可以在自己的收集逻辑中执行相同的基本检查,并更正了此问题。 (在本系列中寻找最终文章中的示例。)
总之,申博娱乐和信用备忘录的收集过程’T从根本上与报价(至少在技术实施方面)不同。涉及的计算是简单的还是头痛引起的,这里触及的探索应该照亮Magento如何对待订单生命周期的这些组件。
该示例包括本系列中的最后一篇文章(下面链接)已被包含这些长期逾期缺失的碎片更新。
2 Comments
谢谢
非常感谢您的信息,我发现它真的很有用和有趣。肯定会在我未来的项目中使用它。感谢分享这篇文章!