Magento 2 Documentation  2.3
Documentation for Magento 2 CMS v2.3 (December 2018)
AbstractAggregateCalculator.php
Go to the documentation of this file.
1 <?php
7 
9 
11 {
15  protected function calculateWithTaxInPrice(QuoteDetailsItemInterface $item, $quantity, $round = true)
16  {
17  $taxRateRequest = $this->getAddressRateRequest()->setProductClassId(
18  $this->taxClassManagement->getTaxClassId($item->getTaxClassKey())
19  );
20  $rate = $this->calculationTool->getRate($taxRateRequest);
21  $storeRate = $storeRate = $this->calculationTool->getStoreRate($taxRateRequest, $this->storeId);
22 
23  $discountTaxCompensationAmount = 0;
24  $applyTaxAfterDiscount = $this->config->applyTaxAfterDiscount($this->storeId);
25  $discountAmount = $item->getDiscountAmount();
26 
27  // Calculate $rowTotalInclTax
28  $priceInclTax = $this->calculationTool->round($item->getUnitPrice());
29  $rowTotalInclTax = $priceInclTax * $quantity;
30  if (!$this->isSameRateAsStore($rate, $storeRate)) {
31  $priceInclTax = $this->calculatePriceInclTax($priceInclTax, $storeRate, $rate, $round);
32  $rowTotalInclTax = $priceInclTax * $quantity;
33  }
34  $rowTaxExact = $this->calculationTool->calcTaxAmount($rowTotalInclTax, $rate, true, false);
35  $deltaRoundingType = self::KEY_REGULAR_DELTA_ROUNDING;
36  if ($applyTaxAfterDiscount) {
38  }
39  $rowTax = $this->roundAmount($rowTaxExact, $rate, true, $deltaRoundingType, $round, $item);
40  $rowTotal = $rowTotalInclTax - $rowTax;
41  $price = $rowTotal / $quantity;
42  if ($round) {
43  $price = $this->calculationTool->round($price);
44  }
45 
46  //Handle discount
47  if ($applyTaxAfterDiscount) {
48  //TODO: handle originalDiscountAmount
49  $taxableAmount = max($rowTotalInclTax - $discountAmount, 0);
50  $rowTaxAfterDiscount = $this->calculationTool->calcTaxAmount(
51  $taxableAmount,
52  $rate,
53  true,
54  false
55  );
56  $rowTaxAfterDiscount = $this->roundAmount(
57  $rowTaxAfterDiscount,
58  $rate,
59  true,
60  self::KEY_REGULAR_DELTA_ROUNDING,
61  $round,
62  $item
63  );
64  // Set discount tax compensation
65  $discountTaxCompensationAmount = $rowTax - $rowTaxAfterDiscount;
66  $rowTax = $rowTaxAfterDiscount;
67  }
68 
69  // Calculate applied taxes
71  $appliedRates = $this->calculationTool->getAppliedRates($taxRateRequest);
72  $appliedTaxes = $this->getAppliedTaxes($rowTax, $rate, $appliedRates);
73 
74  return $this->taxDetailsItemDataObjectFactory->create()
75  ->setCode($item->getCode())
76  ->setType($item->getType())
77  ->setRowTax($rowTax)
78  ->setPrice($price)
79  ->setPriceInclTax($priceInclTax)
80  ->setRowTotal($rowTotal)
81  ->setRowTotalInclTax($rowTotalInclTax)
82  ->setDiscountTaxCompensationAmount($discountTaxCompensationAmount)
83  ->setAssociatedItemCode($item->getAssociatedItemCode())
84  ->setTaxPercent($rate)
85  ->setAppliedTaxes($appliedTaxes);
86  }
87 
91  protected function calculateWithTaxNotInPrice(QuoteDetailsItemInterface $item, $quantity, $round = true)
92  {
93  $taxRateRequest = $this->getAddressRateRequest()->setProductClassId(
94  $this->taxClassManagement->getTaxClassId($item->getTaxClassKey())
95  );
96  $rate = $this->calculationTool->getRate($taxRateRequest);
97  $appliedRates = $this->calculationTool->getAppliedRates($taxRateRequest);
98 
99  $applyTaxAfterDiscount = $this->config->applyTaxAfterDiscount($this->storeId);
100  $discountAmount = $item->getDiscountAmount();
101  $discountTaxCompensationAmount = 0;
102 
103  // Calculate $rowTotal
104  $price = $this->calculationTool->round($item->getUnitPrice());
105  $rowTotal = $price * $quantity;
106  $rowTaxes = [];
107  $rowTaxesBeforeDiscount = [];
108  $appliedTaxes = [];
109  //Apply each tax rate separately
110  foreach ($appliedRates as $appliedRate) {
111  $taxId = $appliedRate['id'];
112  $taxRate = $appliedRate['percent'];
113  $rowTaxPerRate = $this->calculationTool->calcTaxAmount($rowTotal, $taxRate, false, false);
114  $deltaRoundingType = self::KEY_REGULAR_DELTA_ROUNDING;
115  if ($applyTaxAfterDiscount) {
117  }
118  $rowTaxPerRate = $this->roundAmount($rowTaxPerRate, $taxId, false, $deltaRoundingType, $round, $item);
119  $rowTaxAfterDiscount = $rowTaxPerRate;
120 
121  //Handle discount
122  if ($applyTaxAfterDiscount) {
123  //TODO: handle originalDiscountAmount
124  $taxableAmount = max($rowTotal - $discountAmount, 0);
125  $rowTaxAfterDiscount = $this->calculationTool->calcTaxAmount(
126  $taxableAmount,
127  $taxRate,
128  false,
129  false
130  );
131  $rowTaxAfterDiscount = $this->roundAmount(
132  $rowTaxAfterDiscount,
133  $taxId,
134  false,
135  self::KEY_REGULAR_DELTA_ROUNDING,
136  $round,
137  $item
138  );
139  }
140  $appliedTaxes[$taxId] = $this->getAppliedTax(
141  $rowTaxAfterDiscount,
142  $appliedRate
143  );
144 
145  $rowTaxes[] = $rowTaxAfterDiscount;
146  $rowTaxesBeforeDiscount[] = $rowTaxPerRate;
147  }
148  $rowTax = array_sum($rowTaxes);
149  $rowTaxBeforeDiscount = array_sum($rowTaxesBeforeDiscount);
150  $rowTotalInclTax = $rowTotal + $rowTaxBeforeDiscount;
151  $priceInclTax = $rowTotalInclTax / $quantity;
152 
153  if ($round) {
154  $priceInclTax = $this->calculationTool->round($priceInclTax);
155  }
156 
157  return $this->taxDetailsItemDataObjectFactory->create()
158  ->setCode($item->getCode())
159  ->setType($item->getType())
160  ->setRowTax($rowTax)
161  ->setPrice($price)
162  ->setPriceInclTax($priceInclTax)
163  ->setRowTotal($rowTotal)
164  ->setRowTotalInclTax($rowTotalInclTax)
165  ->setDiscountTaxCompensationAmount($discountTaxCompensationAmount)
166  ->setAssociatedItemCode($item->getAssociatedItemCode())
167  ->setTaxPercent($rate)
168  ->setAppliedTaxes($appliedTaxes);
169  }
170 
182  abstract protected function roundAmount(
183  $amount,
184  $rate = null,
185  $direction = null,
186  $type = self::KEY_REGULAR_DELTA_ROUNDING,
187  $round = true,
188  $item = null
189  );
190 }
calculateWithTaxInPrice(QuoteDetailsItemInterface $item, $quantity, $round=true)
calculateWithTaxNotInPrice(QuoteDetailsItemInterface $item, $quantity, $round=true)
$price
roundAmount( $amount, $rate=null, $direction=null, $type=self::KEY_REGULAR_DELTA_ROUNDING, $round=true, $item=null)
$amount
Definition: order.php:14
$type
Definition: item.phtml:13
calculatePriceInclTax($storePriceInclTax, $storeRate, $customerRate, $round=true)
$taxRate
Definition: tax_rule.php:12