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