Skip to content

Commit 08a6b9c

Browse files
author
Serhii Balko
committed
MC-39864: [Magento Cloud] - Tax Miscalculation
1 parent bae3448 commit 08a6b9c

File tree

2 files changed

+92
-12
lines changed

2 files changed

+92
-12
lines changed

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

Lines changed: 63 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,31 @@
55
*/
66
namespace Magento\Sales\Model\Order\Creditmemo\Total;
77

8+
use Magento\Sales\Api\Data\CreditmemoInterface;
89
use Magento\Sales\Model\Order\Creditmemo;
10+
use Magento\Sales\Model\Order\Invoice;
11+
use Magento\Sales\Model\ResourceModel\Order\Invoice as ResourceInvoice;
912

1013
/**
1114
* Collects credit memo taxes.
1215
*/
1316
class Tax extends AbstractTotal
1417
{
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+
1533
/**
1634
* {@inheritdoc}
1735
* @SuppressWarnings(PHPMD.NPathComplexity)
@@ -182,8 +200,12 @@ private function calculateAllowedTax(Creditmemo $creditMemo): float
182200
{
183201
$invoice = $creditMemo->getInvoice();
184202
$order = $creditMemo->getOrder();
185-
$amount = $invoice !== null ? $invoice->getTaxAmount()
186-
: $order->getTaxInvoiced() - $order->getTaxRefunded();
203+
if ($invoice!== null) {
204+
$amount = $invoice->getTaxAmount()
205+
- $this->calculateInvoiceRefundedAmount($invoice, CreditmemoInterface::TAX_AMOUNT);
206+
} else {
207+
$amount = $order->getTaxInvoiced() - $order->getTaxRefunded();
208+
}
187209

188210
return (float) $amount - $creditMemo->getTaxAmount();
189211
}
@@ -198,8 +220,13 @@ private function calculateAllowedBaseTax(Creditmemo $creditMemo): float
198220
{
199221
$invoice = $creditMemo->getInvoice();
200222
$order = $creditMemo->getOrder();
201-
$amount = $invoice !== null ? $invoice->getBaseTaxAmount()
202-
: $order->getBaseTaxInvoiced() - $order->getBaseTaxRefunded();
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+
}
203230

204231
return (float) $amount - $creditMemo->getBaseTaxAmount();
205232
}
@@ -217,7 +244,14 @@ private function calculateAllowedDiscountTaxCompensation(Creditmemo $creditMemo)
217244

218245
if ($invoice) {
219246
$amount = $invoice->getDiscountTaxCompensationAmount()
220-
+ $invoice->getShippingDiscountTaxCompensationAmount();
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+
);
221255
} else {
222256
$amount = $order->getDiscountTaxCompensationInvoiced()
223257
+ $order->getShippingDiscountTaxCompensationAmount()
@@ -243,7 +277,14 @@ private function calculateAllowedBaseDiscountTaxCompensation(Creditmemo $creditM
243277

244278
if ($invoice) {
245279
$amount = $invoice->getBaseDiscountTaxCompensationAmount()
246-
+ $invoice->getBaseShippingDiscountTaxCompensationAmnt();
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+
);
247288
} else {
248289
$amount = $order->getBaseDiscountTaxCompensationInvoiced()
249290
+ $order->getBaseShippingDiscountTaxCompensationAmnt()
@@ -255,4 +296,20 @@ private function calculateAllowedBaseDiscountTaxCompensation(Creditmemo $creditM
255296
- $creditMemo->getBaseShippingDiscountTaxCompensationAmnt()
256297
- $creditMemo->getBaseDiscountTaxCompensationAmount();
257298
}
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);
314+
}
258315
}

app/code/Magento/Sales/Model/ResourceModel/Order/Invoice.php

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,9 @@
55
*/
66
namespace Magento\Sales\Model\ResourceModel\Order;
77

8-
use Magento\Framework\App\ResourceConnection;
9-
use Magento\SalesSequence\Model\Manager;
10-
use Magento\Sales\Model\ResourceModel\Attribute;
8+
use Magento\Framework\DataObject;
9+
use Magento\Framework\Model\AbstractModel;
1110
use Magento\Sales\Model\ResourceModel\EntityAbstract as SalesResource;
12-
use Magento\Framework\Model\ResourceModel\Db\VersionControl\Snapshot;
1311
use Magento\Sales\Model\Spi\InvoiceResourceInterface;
1412

1513
/**
@@ -37,10 +35,10 @@ protected function _construct()
3735
/**
3836
* Perform actions before object save
3937
*
40-
* @param \Magento\Framework\Model\AbstractModel|\Magento\Framework\DataObject $object
38+
* @param AbstractModel|DataObject $object
4139
* @return $this
4240
*/
43-
protected function _beforeSave(\Magento\Framework\Model\AbstractModel $object)
41+
protected function _beforeSave(AbstractModel $object)
4442
{
4543
/** @var \Magento\Sales\Model\Order\Invoice $object */
4644
if (!$object->getOrderId() && $object->getOrder()) {
@@ -50,4 +48,29 @@ protected function _beforeSave(\Magento\Framework\Model\AbstractModel $object)
5048

5149
return parent::_beforeSave($object);
5250
}
51+
52+
/**
53+
* Calculate refunded amount for invoice
54+
*
55+
* @param int $invoiceId
56+
* @param string $filed
57+
* @return float
58+
* @throws \InvalidArgumentException
59+
*/
60+
public function calculateRefundedAmount(int $invoiceId, string $filed): float
61+
{
62+
if (empty($filed)) {
63+
throw new \InvalidArgumentException('The field param must be passed');
64+
}
65+
66+
$select = $this->getConnection()->select();
67+
$select->from(
68+
['credit_memo' => $this->getTable('sales_creditmemo')],
69+
['total' => new \Zend_Db_Expr("SUM(credit_memo.{$filed})")]
70+
)->where(
71+
"credit_memo.invoice_id = ?", $invoiceId
72+
);
73+
74+
return (float) $this->getConnection()->fetchOne($select);
75+
}
5376
}

0 commit comments

Comments
 (0)