Skip to content

Commit 830b844

Browse files
author
Serhii Balko
committed
Merge remote-tracking branch 'origin/MC-39864' into 2.4-develop-pr48
2 parents c65b572 + 08a6b9c commit 830b844

File tree

3 files changed

+232
-79
lines changed

3 files changed

+232
-79
lines changed

app/code/Magento/Sales/Model/Order/Creditmemo/Total/Tax.php

Lines changed: 187 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -5,61 +5,76 @@
55
*/
66
namespace Magento\Sales\Model\Order\Creditmemo\Total;
77

8+
use Magento\Sales\Api\Data\CreditmemoInterface;
9+
use Magento\Sales\Model\Order\Creditmemo;
10+
use Magento\Sales\Model\Order\Invoice;
11+
use Magento\Sales\Model\ResourceModel\Order\Invoice as ResourceInvoice;
12+
813
/**
914
* Collects credit memo taxes.
1015
*/
1116
class Tax extends AbstractTotal
1217
{
1318
/**
14-
* Collects credit memo taxes.
15-
*
16-
* @param \Magento\Sales\Model\Order\Creditmemo $creditmemo
17-
* @return $this
18-
*
19+
* @var ResourceInvoice
20+
*/
21+
private $resourceInvoice;
22+
23+
/**
24+
* @param ResourceInvoice $resourceInvoice
25+
* @param array $data
26+
*/
27+
public function __construct(ResourceInvoice $resourceInvoice, array $data = [])
28+
{
29+
$this->resourceInvoice = $resourceInvoice;
30+
parent::__construct($data);
31+
}
32+
33+
/**
34+
* {@inheritdoc}
1935
* @SuppressWarnings(PHPMD.NPathComplexity)
2036
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
2137
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
2238
*/
23-
public function collect(\Magento\Sales\Model\Order\Creditmemo $creditmemo)
39+
public function collect(Creditmemo $creditmemo)
2440
{
2541
$shippingTaxAmount = 0;
2642
$baseShippingTaxAmount = 0;
2743
$totalTax = 0;
2844
$baseTotalTax = 0;
2945
$totalDiscountTaxCompensation = 0;
3046
$baseTotalDiscountTaxCompensation = 0;
31-
3247
$order = $creditmemo->getOrder();
3348

34-
/** @var $item \Magento\Sales\Model\Order\Creditmemo\Item */
3549
foreach ($creditmemo->getAllItems() as $item) {
3650
$orderItem = $item->getOrderItem();
3751
if ($orderItem->isDummy() || $item->getQty() <= 0) {
3852
continue;
3953
}
54+
4055
$orderItemTax = (double)$orderItem->getTaxInvoiced();
4156
$baseOrderItemTax = (double)$orderItem->getBaseTaxInvoiced();
4257
$orderItemQty = (double)$orderItem->getQtyInvoiced();
4358

4459
if ($orderItemQty) {
45-
/**
46-
* Check item tax amount
47-
*/
48-
60+
/** Check item tax amount */
4961
$tax = $orderItemTax - $orderItem->getTaxRefunded();
5062
$baseTax = $baseOrderItemTax - $orderItem->getBaseTaxRefunded();
51-
$discountTaxCompensation = $orderItem->getDiscountTaxCompensationInvoiced() -
52-
$orderItem->getDiscountTaxCompensationRefunded();
53-
$baseDiscountTaxCompensation = $orderItem->getBaseDiscountTaxCompensationInvoiced() -
54-
$orderItem->getBaseDiscountTaxCompensationRefunded();
63+
$discountTaxCompensation = $orderItem->getDiscountTaxCompensationInvoiced()
64+
- $orderItem->getDiscountTaxCompensationRefunded();
65+
$baseDiscountTaxCompensation = $orderItem->getBaseDiscountTaxCompensationInvoiced()
66+
- $orderItem->getBaseDiscountTaxCompensationRefunded();
5567
if (!$item->isLast()) {
5668
$availableQty = $orderItemQty - $orderItem->getQtyRefunded();
5769
$tax = $creditmemo->roundPrice($tax / $availableQty * $item->getQty());
58-
$baseTax = $creditmemo->roundPrice($baseTax / $availableQty * $item->getQty(), 'base');
59-
$discountTaxCompensation =
60-
$creditmemo->roundPrice($discountTaxCompensation / $availableQty * $item->getQty());
61-
$baseDiscountTaxCompensation =
62-
$creditmemo->roundPrice($baseDiscountTaxCompensation / $availableQty * $item->getQty(), 'base');
70+
$baseTax = $creditmemo->roundPrice(($baseTax / $availableQty * $item->getQty()), 'base');
71+
$discountTaxCompensation = $creditmemo->roundPrice(
72+
$discountTaxCompensation / $availableQty * $item->getQty()
73+
);
74+
$baseDiscountTaxCompensation = $creditmemo->roundPrice(
75+
$baseDiscountTaxCompensation / $availableQty * $item->getQty(),
76+
'base'
77+
);
6378
}
6479

6580
$item->setTaxAmount($tax);
@@ -77,14 +92,14 @@ public function collect(\Magento\Sales\Model\Order\Creditmemo $creditmemo)
7792
$isPartialShippingRefunded = false;
7893
$baseOrderShippingAmount = (float)$order->getBaseShippingAmount();
7994
if ($invoice = $creditmemo->getInvoice()) {
80-
//recalculate tax amounts in case if refund shipping value was changed
95+
// recalculate tax amounts in case if refund shipping value was changed
8196
if ($baseOrderShippingAmount && $creditmemo->getBaseShippingAmount() !== null) {
8297
$taxFactor = $creditmemo->getBaseShippingAmount() / $baseOrderShippingAmount;
8398
$shippingTaxAmount = $invoice->getShippingTaxAmount() * $taxFactor;
8499
$baseShippingTaxAmount = $invoice->getBaseShippingTaxAmount() * $taxFactor;
85100
$totalDiscountTaxCompensation += $invoice->getShippingDiscountTaxCompensationAmount() * $taxFactor;
86-
$baseTotalDiscountTaxCompensation +=
87-
$invoice->getBaseShippingDiscountTaxCompensationAmnt() * $taxFactor;
101+
$baseTotalDiscountTaxCompensation += $invoice->getBaseShippingDiscountTaxCompensationAmnt()
102+
* $taxFactor;
88103
$shippingTaxAmount = $creditmemo->roundPrice($shippingTaxAmount);
89104
$baseShippingTaxAmount = $creditmemo->roundPrice($baseShippingTaxAmount, 'base');
90105
$totalDiscountTaxCompensation = $creditmemo->roundPrice($totalDiscountTaxCompensation);
@@ -97,14 +112,11 @@ public function collect(\Magento\Sales\Model\Order\Creditmemo $creditmemo)
97112
}
98113
} else {
99114
$orderShippingAmount = $order->getShippingAmount();
100-
101115
$baseOrderShippingRefundedAmount = $order->getBaseShippingRefunded();
102-
103116
$shippingTaxAmount = 0;
104117
$baseShippingTaxAmount = 0;
105118
$shippingDiscountTaxCompensationAmount = 0;
106119
$baseShippingDiscountTaxCompensationAmount = 0;
107-
108120
$shippingDelta = $baseOrderShippingAmount - $baseOrderShippingRefundedAmount;
109121

110122
if ($shippingDelta > $creditmemo->getBaseShippingAmount()) {
@@ -113,45 +125,39 @@ public function collect(\Magento\Sales\Model\Order\Creditmemo $creditmemo)
113125
$shippingTaxAmount = $order->getShippingTaxAmount() * $part;
114126
$baseShippingTaxAmount = $order->getBaseShippingTaxAmount() * $basePart;
115127
$shippingDiscountTaxCompensationAmount = $order->getShippingDiscountTaxCompensationAmount() * $part;
116-
$baseShippingDiscountTaxCompensationAmount =
117-
$order->getBaseShippingDiscountTaxCompensationAmnt() * $basePart;
128+
$baseShippingDiscountTaxCompensationAmount = $order->getBaseShippingDiscountTaxCompensationAmnt()
129+
* $basePart;
118130
$shippingTaxAmount = $creditmemo->roundPrice($shippingTaxAmount);
119131
$baseShippingTaxAmount = $creditmemo->roundPrice($baseShippingTaxAmount, 'base');
120-
$shippingDiscountTaxCompensationAmount =
121-
$creditmemo->roundPrice($shippingDiscountTaxCompensationAmount);
122-
$baseShippingDiscountTaxCompensationAmount =
123-
$creditmemo->roundPrice($baseShippingDiscountTaxCompensationAmount, 'base');
132+
$shippingDiscountTaxCompensationAmount = $creditmemo->roundPrice(
133+
$shippingDiscountTaxCompensationAmount
134+
);
135+
$baseShippingDiscountTaxCompensationAmount = $creditmemo->roundPrice(
136+
$baseShippingDiscountTaxCompensationAmount,
137+
'base'
138+
);
124139
if ($part < 1 && $order->getShippingTaxAmount() > 0) {
125140
$isPartialShippingRefunded = true;
126141
}
127142
} elseif ($shippingDelta == $creditmemo->getBaseShippingAmount()) {
128143
$shippingTaxAmount = $order->getShippingTaxAmount() - $order->getShippingTaxRefunded();
129144
$baseShippingTaxAmount = $order->getBaseShippingTaxAmount() - $order->getBaseShippingTaxRefunded();
130-
$shippingDiscountTaxCompensationAmount = $order->getShippingDiscountTaxCompensationAmount() -
131-
$order->getShippingDiscountTaxCompensationRefunded();
132-
$baseShippingDiscountTaxCompensationAmount = $order->getBaseShippingDiscountTaxCompensationAmnt() -
133-
$order->getBaseShippingDiscountTaxCompensationRefunded();
145+
$shippingDiscountTaxCompensationAmount = $order->getShippingDiscountTaxCompensationAmount()
146+
- $order->getShippingDiscountTaxCompensationRefunded();
147+
$baseShippingDiscountTaxCompensationAmount = $order->getBaseShippingDiscountTaxCompensationAmnt()
148+
- $order->getBaseShippingDiscountTaxCompensationRefunded();
134149
}
150+
135151
$totalTax += $shippingTaxAmount;
136152
$baseTotalTax += $baseShippingTaxAmount;
137153
$totalDiscountTaxCompensation += $shippingDiscountTaxCompensationAmount;
138154
$baseTotalDiscountTaxCompensation += $baseShippingDiscountTaxCompensationAmount;
139155
}
140156

141-
$allowedTax = $order->getTaxInvoiced() - $order->getTaxRefunded() - $creditmemo->getTaxAmount();
142-
$allowedBaseTax = $order->getBaseTaxInvoiced() - $order->getBaseTaxRefunded() - $creditmemo->getBaseTaxAmount();
143-
$allowedDiscountTaxCompensation = $order->getDiscountTaxCompensationInvoiced() +
144-
$order->getShippingDiscountTaxCompensationAmount() -
145-
$order->getDiscountTaxCompensationRefunded() -
146-
$order->getShippingDiscountTaxCompensationRefunded() -
147-
$creditmemo->getDiscountTaxCompensationAmount() -
148-
$creditmemo->getShippingDiscountTaxCompensationAmount();
149-
$allowedBaseDiscountTaxCompensation = $order->getBaseDiscountTaxCompensationInvoiced() +
150-
$order->getBaseShippingDiscountTaxCompensationAmnt() -
151-
$order->getBaseDiscountTaxCompensationRefunded() -
152-
$order->getBaseShippingDiscountTaxCompensationRefunded() -
153-
$creditmemo->getBaseShippingDiscountTaxCompensationAmnt() -
154-
$creditmemo->getBaseDiscountTaxCompensationAmount();
157+
$allowedTax = $this->calculateAllowedTax($creditmemo);
158+
$allowedBaseTax = $this->calculateAllowedBaseTax($creditmemo);
159+
$allowedDiscountTaxCompensation = $this->calculateAllowedDiscountTaxCompensation($creditmemo);
160+
$allowedBaseDiscountTaxCompensation = $this->calculateAllowedBaseDiscountTaxCompensation($creditmemo);
155161

156162
if ($creditmemo->isLast() && !$isPartialShippingRefunded) {
157163
$totalTax = $allowedTax;
@@ -161,10 +167,11 @@ public function collect(\Magento\Sales\Model\Order\Creditmemo $creditmemo)
161167
} else {
162168
$totalTax = min($allowedTax, $totalTax);
163169
$baseTotalTax = min($allowedBaseTax, $baseTotalTax);
164-
$totalDiscountTaxCompensation =
165-
min($allowedDiscountTaxCompensation, $totalDiscountTaxCompensation);
166-
$baseTotalDiscountTaxCompensation =
167-
min($allowedBaseDiscountTaxCompensation, $baseTotalDiscountTaxCompensation);
170+
$totalDiscountTaxCompensation = min($allowedDiscountTaxCompensation, $totalDiscountTaxCompensation);
171+
$baseTotalDiscountTaxCompensation = min(
172+
$allowedBaseDiscountTaxCompensation,
173+
$baseTotalDiscountTaxCompensation
174+
);
168175
}
169176

170177
$creditmemo->setTaxAmount($creditmemo->getTaxAmount() + $totalTax);
@@ -177,9 +184,132 @@ public function collect(\Magento\Sales\Model\Order\Creditmemo $creditmemo)
177184

178185
$creditmemo->setGrandTotal($creditmemo->getGrandTotal() + $totalTax + $totalDiscountTaxCompensation);
179186
$creditmemo->setBaseGrandTotal(
180-
$creditmemo->getBaseGrandTotal() +
181-
$baseTotalTax + $baseTotalDiscountTaxCompensation
187+
$creditmemo->getBaseGrandTotal() + $baseTotalTax + $baseTotalDiscountTaxCompensation
182188
);
183189
return $this;
190+
191+
}
192+
193+
/**
194+
* Calculate allowed to Credit Memo tax amount
195+
*
196+
* @param Creditmemo $creditMemo
197+
* @return float
198+
*/
199+
private function calculateAllowedTax(Creditmemo $creditMemo): float
200+
{
201+
$invoice = $creditMemo->getInvoice();
202+
$order = $creditMemo->getOrder();
203+
if ($invoice!== null) {
204+
$amount = $invoice->getTaxAmount()
205+
- $this->calculateInvoiceRefundedAmount($invoice, CreditmemoInterface::TAX_AMOUNT);
206+
} else {
207+
$amount = $order->getTaxInvoiced() - $order->getTaxRefunded();
208+
}
209+
210+
return (float) $amount - $creditMemo->getTaxAmount();
211+
}
212+
213+
/**
214+
* Calculate allowed to Credit Memo tax amount in the base currency
215+
*
216+
* @param Creditmemo $creditMemo
217+
* @return float
218+
*/
219+
private function calculateAllowedBaseTax(Creditmemo $creditMemo): float
220+
{
221+
$invoice = $creditMemo->getInvoice();
222+
$order = $creditMemo->getOrder();
223+
224+
if ($invoice!== null) {
225+
$amount = $invoice->getBaseTaxAmount()
226+
- $this->calculateInvoiceRefundedAmount($invoice, CreditmemoInterface::BASE_TAX_AMOUNT);
227+
} else {
228+
$amount = $order->getBaseTaxInvoiced() - $order->getBaseTaxRefunded();
229+
}
230+
231+
return (float) $amount - $creditMemo->getBaseTaxAmount();
232+
}
233+
234+
/**
235+
* Calculate allowed to Credit Memo discount tax compensation amount
236+
*
237+
* @param Creditmemo $creditMemo
238+
* @return float
239+
*/
240+
private function calculateAllowedDiscountTaxCompensation(Creditmemo $creditMemo): float
241+
{
242+
$invoice = $creditMemo->getInvoice();
243+
$order = $creditMemo->getOrder();
244+
245+
if ($invoice) {
246+
$amount = $invoice->getDiscountTaxCompensationAmount()
247+
+ $invoice->getShippingDiscountTaxCompensationAmount()
248+
- $this->calculateInvoiceRefundedAmount(
249+
$invoice,
250+
CreditmemoInterface::DISCOUNT_TAX_COMPENSATION_AMOUNT
251+
) - $this->calculateInvoiceRefundedAmount(
252+
$invoice,
253+
CreditmemoInterface::SHIPPING_DISCOUNT_TAX_COMPENSATION_AMOUNT
254+
);
255+
} else {
256+
$amount = $order->getDiscountTaxCompensationInvoiced()
257+
+ $order->getShippingDiscountTaxCompensationAmount()
258+
- $order->getDiscountTaxCompensationRefunded()
259+
- $order->getShippingDiscountTaxCompensationRefunded();
260+
}
261+
262+
return (float) $amount
263+
- $creditMemo->getDiscountTaxCompensationAmount()
264+
- $creditMemo->getShippingDiscountTaxCompensationAmount();
265+
}
266+
267+
/**
268+
* Calculate allowed to Credit Memo discount tax compensation amount in the base currency
269+
*
270+
* @param Creditmemo $creditMemo
271+
* @return float
272+
*/
273+
private function calculateAllowedBaseDiscountTaxCompensation(Creditmemo $creditMemo): float
274+
{
275+
$invoice = $creditMemo->getInvoice();
276+
$order = $creditMemo->getOrder();
277+
278+
if ($invoice) {
279+
$amount = $invoice->getBaseDiscountTaxCompensationAmount()
280+
+ $invoice->getBaseShippingDiscountTaxCompensationAmnt()
281+
- $this->calculateInvoiceRefundedAmount(
282+
$invoice,
283+
CreditmemoInterface::BASE_DISCOUNT_TAX_COMPENSATION_AMOUNT
284+
) - $this->calculateInvoiceRefundedAmount(
285+
$invoice,
286+
CreditmemoInterface::BASE_SHIPPING_DISCOUNT_TAX_COMPENSATION_AMNT
287+
);
288+
} else {
289+
$amount = $order->getBaseDiscountTaxCompensationInvoiced()
290+
+ $order->getBaseShippingDiscountTaxCompensationAmnt()
291+
- $order->getBaseDiscountTaxCompensationRefunded()
292+
- $order->getBaseShippingDiscountTaxCompensationRefunded();
293+
}
294+
295+
return (float) $amount
296+
- $creditMemo->getBaseShippingDiscountTaxCompensationAmnt()
297+
- $creditMemo->getBaseDiscountTaxCompensationAmount();
298+
}
299+
300+
/**
301+
* Calculate refunded amount for invoice
302+
*
303+
* @param Invoice $invoice
304+
* @param string $field
305+
* @return float
306+
*/
307+
private function calculateInvoiceRefundedAmount(Invoice $invoice, string $field): float
308+
{
309+
if (empty($invoice->getId())) {
310+
return 0;
311+
}
312+
313+
return $this->resourceInvoice->calculateRefundedAmount((int)$invoice->getId(), $field);
184314
}
185315
}

0 commit comments

Comments
 (0)