価格設定はおそらくMagentoの美徳であり、システムの最も興味深い部分です。
そして、店主にとって-それはお金に関連しているため、最も重要な部分です。
以前、同僚は、中国の壁にはほとんど収まらない図を描き、計算のすべてすべての段階に合わせようとしました。 この記事では、計算の主要な段階と、店舗に有利な割引を四捨五入する例を説明します。 幸いなことに、Magento 1と比較して、イノベーションは非常に奥深くに触れ、アプローチは変わりませんでした。
氷山の一角
顧客がバスケットの内容を変更すると、計算が開始されます。 計算速度は、「詳細な」多くのアクションに依存します。 著名な場所からダイビングを始めます。 途中で、商品の種類のイベントと依存関係、配送方法、バスケットとカタログの価格ルールが表示されます。
この記事では、次のモジュール/統合に対する正しい価格介入アプローチについて説明します。
- 顧客の残高-お金が顧客に返されず、店舗に残っている場合。
- ロイヤルティプログラム-店頭でのメリットに対する「オウム」による支払い。
- 証明書-番号で使用できる特定の残高。
- 数量に対する多様性-すべてのERPシステムが3品を2ルーブルで販売できるわけではなく、迷惑なペニーが表示されます。
- 価格の統合-一部の小売チェーンまたは大企業では、特定のシステム、SAP ERP、またはクラウドサービス(インターフェイスを備えたレジ用の自己作成モジュール)がコストを計算する責任を負っています。
商品を追加する際のバスケットのラインの形成は、おそらく以下の記事で別のトピックであるため、すぐに計算に進みます。
テキストには合計、価格、運送業者のモデルが含まれ、特定のタイプを示しているため、参照しやすくなっています。
\ Magento \ Quote \ Model \ Quote :: collectTotals
旅は氷山の上で始まり、計算を始めます。
TotalsCollectorに計算を実行するように依頼します。このクラスは、コードに行を追加しないようにバスケットから特別に分離されています。
\ Magento \ Quote \ Model \ Quote \ TotalsCollector :: collect
すべての住所に行き、住所にすべての住所の計算を依頼する場所。
これは、中央集中型の購買部門を持つB2Bストアの便利な機能の1つであり、注文は「別の場所にすぐに」一括送信されるため、さまざまな住所にすぐに注文できるようにするためです。
\ Magento \ Quote \ Model \ Quote \ TotalsCollector :: collectAddressTotals
計算のすべての段階を返す、責任のあるTotalsCollectorListクラスが必要です。 すべてのステージは構成されており、順序付けられています。 最後に、小さな価格調整子を見ていきます。
\ Magento \ Quote \ Model \ Quote \ TotalsCollectorList :: getCollectors
実行の結果は、コスト計算のロジックが実装されるCollectorInterfaceクラスの配列です。
計算のすべての段階は、コストを計算するときに重要な主要エンティティ(バスケット、アカウント、リターン)に対して宣言されます。 システムのコアには常に良い例があります: vendor / magento / module-sales / etc / sales.xml
以下に、order_invoiceおよびorder_creditmemoアカウント(-fact)およびorder_creditmemoの払い戻しの計算ステップの追加について説明します。
さらに、available_product_type(購入可能な商品の種類)が追加されます。 特定の種類の商品のモジュールは、商品の種類を宣言します。
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Sales:etc/sales.xsd"> <section name="order_invoice"> <group name="totals"> <item name="subtotal" instance="Magento\Sales\Model\Order\Invoice\Total\Subtotal" sort_order="50"/> <item name="discount" instance="Magento\Sales\Model\Order\Invoice\Total\Discount" sort_order="100"/> <item name="shipping" instance="Magento\Sales\Model\Order\Invoice\Total\Shipping" sort_order="150"/> <item name="tax" instance="Magento\Sales\Model\Order\Invoice\Total\Tax" sort_order="200"/> <item name="cost_total" instance="Magento\Sales\Model\Order\Invoice\Total\Cost" sort_order="250"/> <item name="grand_total" instance="Magento\Sales\Model\Order\Invoice\Total\Grand" sort_order="350"/> </group> </section> <section name="order_creditmemo"> <group name="totals"> <item name="subtotal" instance="Magento\Sales\Model\Order\Creditmemo\Total\Subtotal" sort_order="50"/> <item name="discount" instance="Magento\Sales\Model\Order\Creditmemo\Total\Discount" sort_order="150"/> <item name="shipping" instance="Magento\Sales\Model\Order\Creditmemo\Total\Shipping" sort_order="200"/> <item name="tax" instance="Magento\Sales\Model\Order\Creditmemo\Total\Tax" sort_order="250"/> <item name="cost_total" instance="Magento\Sales\Model\Order\Creditmemo\Total\Cost" sort_order="300"/> <item name="grand_total" instance="Magento\Sales\Model\Order\Creditmemo\Total\Grand" sort_order="400"/> </group> </section> <order> <available_product_type name="simple"/> <available_product_type name="virtual"/> </order> </config>
以下は、バスケットの合計モデルの名前とクラスのリストです。
1. 小計 => \ Magento \見積り\モデル\見積り\住所\合計\小計
税引き前などの物品のコストの計算。
2. tax_subtotal => \ Magento \ Tax \ Model \ Sales \ Total \ Quote \ Subtotal
課税の一部
3.weee => \ Magento \ Weee \ Model \ Total \ Quote \ Weee、
固定税、物品税
4. 配送 => \ Magento \見積り\モデル\見積り\住所\合計\配送
送料の計算、オンライン決済のための配送サービスへの連絡
5. tax_shipping => \ Magento \ Tax \ Model \ Sales \ Total \ Quote \ Shipping
配送税、配送にも課税される場合があります/および会計のためにこれが必要です。
6. 割引 => \ Magento \ SalesRule \モデル\ Quote \割引、
割引ルールの処理、クーポンの適用、プロモーション、天気割引
7. tax => \ Magento \ Tax \ Model \ Sales \ Total \ Quote \ Tax
法律の割引が課税ベースを減らさないかもしれないので、税計算の別の段階。
8.weee_tax => \ Magento \ Weee \ Model \ Total \ Quote \ WeeeTax、
固定税はもう一つのステップです
9. grand_total => \ Magento \ Quote \ Model \ Quote \ Address \ Total \ Grand
最後の計算では、以前に計算されたすべてを要約します。
水中で
最も興味深いアイテムは、 小計、配送、割引です。
\ Magento \見積り\モデル\見積り\住所\合計\小計
そのため、商品のコストを取得するために、 Subtotalは最終価格を提供するように製品に要求します。
しかし、製品自体は価格を知らず、 価格モデルに移行します。
価格モデルの作業は、「独自のタイプの製品を作成する方法」という別の記事のトピック全体です。
しかし、これはすべての製品の初期価格を再定義するのにすでに十分であり、すべての価格が単純なテーブルに保存され、1日1回ダウンロードされる可能性があるクライアントの個人価格との最も単純な統合の一部になる可能性があります
\ Magento \ SalesRule \ Model \ Quote \割引
割引も、割引を使用できるかどうかについてバスケットをチェックする興味深い場所です。 検証のために特別なルール(たとえば、都市の天気の割引)を追加することは、別の記事に値します。
システムは、現在の日付のすべてのアクティブな割引ルールをチェックします。 多数のルールがある場合、バスケットの再集計が遅くなる可能性があります。 ルールが最大であれば、すべてがうまくいきます
\ Magento \ Quote \ Model \ Quote \ Address \ Total \ Shipping
配送費用の計算は、すべての配送方法をバイパスして呼び出します
\ Magento \ Shipping \ Model \ Carrier \ AbstractCarrierInterface :: collectRates配信計算はデータベースに保存され、指定された配信国でのみ発生します。
デフォルトでは、配送方法と配送国を設定して、製品をバスケットに追加した直後に注文のコストを計算できます。 この方法は、店舗で何らかの方法でIPによって都市または地域に関するデータを取得する場合に使用できます。
あなたの計算は正しいです
モジュール\プロジェクト\統合
同僚は、以前にHabré でモジュールを作成する方法をここで書きました 。
注文明細の割引計算の実装を開始し、割引の計算後にペニーを削除しましょう。
これは、すべての製品にセントなしの価格があり、割引のコペックだけが私たちを悩ませている場合に便利です(VATの計算時)。
Project / Integration / etc / sales.xmlファイルで、Totalモデルを追加するか、古い/不要なウィーを削除できます。
sort_order-実行の順序を提供します; sales.xmlのすべてのTotalモデルに対しても設定されます。
<?xml version="1.0"?> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Sales:etc/sales.xsd"> <section name="quote"> <group name="totals"> <item name="integration_total" instance="Project\Integration\Model\Quote\Address\Total\Custom" sort_order="430"/> <item name="weee" instance="" /> <item name="weee_tax" instance="" /> </group> </section> </config>
sort_order = "430" -税の計算前に割引の計算を宣言します。
これは、割引からペニーを削減するか、バスケット割引システムに要求するのが最善の場所です。
\ Project \ Integration \ Model \ Quote \ Address \ Total \ Customでの計算の実装
<?php namespace Project\Integration\Model\Quote\Address\Total; // class Custom extends \Magento\Quote\Model\Quote\Address\Total\AbstractTotal { // ... public function __construct( // DI ... ) { // ... } public function collect( \Magento\Quote\Model\Quote $quote, \Magento\Quote\Api\Data\ShippingAssignmentInterface $shippingAssignment, \Magento\Quote\Model\Quote\Address\Total $total ) { $address = $shippingAssignment->getShipping()->getAddress(); $quoteItems = $quote->getAllItems(); // , , , - if ($total->getTotalAmount('discount') == 0 || $quote->getItemsCount() == 0 || !$quote->getId() || $address->getAddressType() == 'billing') return $this; // , ... // $totalDiscount = 0; $baseTotalDiscount = 0; foreach ($quoteItems as $item) { // , $newDiscountAmount = (int)$item->getDiscountAmount(); $newBaseDiscountAmount = (int)$item->getBaseDiscountAmount(); // $totalDiscount += $newDiscountAmount; $baseTotalDiscount += $newBaseDiscountAmount; // $rowTotal = $item->getRowTotal() + $item->getDiscountAmount() - $newDiscountAmount; $baseRowTotal = $item->getBaseRowTotal() + $item->getBaseDiscountAmount() - $newBaseDiscountAmount; // $item->setDiscountAmount($newDiscountAmount); $item->setBaseDiscountAmount($newBaseDiscountAmount); // $item->setRowTotal($rowTotal); $item->setBaseRowTotal($baseRowTotal); } // $total->setTotalAmount('discount', $totalDiscount); $total->setBaseTotalAmount('discount', $baseTotalDiscount); $total->setSubtotalWithDiscount($total->getSubtotal() + $total->getDiscountAmount()); $total->setBaseSubtotalWithDiscount($total->getBaseSubtotal() + $total->getBaseDiscountAmount()); return $this; } }
終わる代わりに
ここでペニーを無事捨てました。 セントも問題もありません。
追加の価格修飾子(特別割引または追加料金、Internet Explorerの税金)を使用する場合、すべての計算がアカウントとリターンの両方で正しく機能することを心配する必要があります。そうしないと、会計士を殺すシリアルプログラマーになります。 返品の条件の下でも金額の完全性を確保するために、商品の割引または基準価格を変更することが最も最適です。