Pricing is probably the advantage of Magento and the most interesting part of the system. And for the shop owner - the most important part, because it is connected with money.
Previously, colleagues drew diagrams that barely fit on the Chinese Wall, trying to fit all the stages of calculation.
In this article, I will try to describe only the main stages of the calculation, and an example of rounding off discounts in favor of the store. Fortunately, compared to Magento 1, the innovations have touched the depths, but the approach has remained unchanged.
When the client changes the content of the shopping cart, the calculation starts. The speed of the calculation depends on a number of actions "at depth". Let's start the dive from the most prominent places. We will see the events and dependencies of the types of goods, delivery methods, price rules of the basket, and the catalog.
The article describes the correct approach to pricing intervention for the following modules/integration:
Client's balance - when the money is not returned to the client but remains in the store.
Loyalty program - payment for services to the store.
Certificates - Some balance that can be used by number.
Ratio to quantity - not all ERP systems are able to sell 3 goods for 2 rubles, there is an annoying penny, which the client will demand when returning.
Pricing integration - some retail chains or large companies are responsible for calculating the cost of a specific system, SAP ERP or cloud service (a self-written module for cash registers with an interface).
Let's proceed directly to the calculation, as the formation of the basket when adding products is a separate topic, perhaps in the next articles.
Total, Price, Carrier models will be found in the text, they indicate a certain type, and then it is easier to refer to it.
The journey begins at the tip of the iceberg, and we begin the calculation. We ask TotalsCollector to perform the calculation, this class has been specially separated from the basket to avoid adding more lines to the code.
This is done for the possibility of placing orders to multiple addresses at once, as it is one of the useful functions for B2B stores, which have a centralized purchasing department and orders go "wholesale" but at once to different locations.
Please have the responsible TotalsCollectorList class that returns all the calculation steps to us. All steps are in configuration, ordered. In the end, we will look at our small pricing modifier.
The result of the execution is an array of CollectorInterface classes, in which the logic of cost calculation is implemented.
All stages of calculation are declared for the basic entities that are important in the calculation of the cost: basket, invoice, return. There are always good examples in the system kernel: vendor/magento/module-sales/etc/sales.xml
Below is the addition of the calculation steps for order_invoice and order_creditmemo account(-invoices) and order_creditmemo refunds.
In addition, available_product_type (available types of goods to buy) is added. The modules for specific types of goods declare the types of goods.
Below is the list of names and classes of Total-models for the basket:
1. subtotal => \Magento\Quote\Model\Quote\Address\Total\Subtotal
Calculation of the value of goods before tax discounts and others.
2. tax_subtotal => \Magento\Tax\Model\Sales\Total\Quote\Subtotal
Taxes part of taxation
3. weee => \Magento\Weee\Model\Total\Quote\Weee
Fixed taxes, excise taxes
4. shipping => \Magento\Quote\Model\Quote\Address\Total\Shipping
Calculation of delivery costs, online application to delivery services
5. tax_shipping => \Magento\Tax\Model\Sales\Total\Quote\Shipping
Delivery taxes, shipping may also be taxed and/or required for accounting purposes.
6. discount => \Magento\SalesRule\Model\Quote\Discount
Processing of discount rules, application of coupons, shares, weather discounts
7. tax => \Magento\Tax\Model\Sales\Total\Quote\Tax
Another step in calculating taxes, as the discount under the law, may not reduce the tax base.
8. weee_tax => \Magento\Weee\Model\Total\Quote\WeeeTax
Fixed taxes are another step
9. grand_total => \Magento\Quote\Model\Quote\Address\Total\Grand
The final count is the sum of everything you've counted before.
If we use additional price modifiers and extensions (https://www.mageworx.com/), then we need to worry that all calculations are correct and in the bills and returns, otherwise you will turn into serial programmers who argue with accountants. The most optimal way to modify the discount or basic cost of goods to ensure the integrity of the amounts, even under the conditions of refunds.