Skip to content

Commit a7928e2

Browse files
MC-30299: [Magento On-Premise] Incorrect refund when discount applied
1 parent c2e2646 commit a7928e2

File tree

3 files changed

+55
-10
lines changed

3 files changed

+55
-10
lines changed

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

Lines changed: 41 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,38 @@
55
*/
66
namespace Magento\Sales\Model\Order\Creditmemo\Total;
77

8+
use Magento\Tax\Model\Config;
9+
810
/**
911
* Discount total calculator
1012
*/
1113
class Discount extends AbstractTotal
1214
{
15+
/**
16+
* @var Config
17+
*/
18+
private $taxConfig;
19+
20+
/**
21+
* @param Config $taxConfig
22+
* @param array $data
23+
*/
24+
public function __construct(
25+
Config $taxConfig,
26+
array $data = []
27+
) {
28+
$this->taxConfig = $taxConfig;
29+
30+
parent::__construct($data);
31+
}
32+
1333
/**
1434
* Collect discount
1535
*
1636
* @param \Magento\Sales\Model\Order\Creditmemo $creditmemo
1737
* @return $this
1838
* @throws \Magento\Framework\Exception\LocalizedException
39+
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
1940
*/
2041
public function collect(\Magento\Sales\Model\Order\Creditmemo $creditmemo)
2142
{
@@ -31,7 +52,7 @@ public function collect(\Magento\Sales\Model\Order\Creditmemo $creditmemo)
3152
* Calculate how much shipping discount should be applied
3253
* basing on how much shipping should be refunded.
3354
*/
34-
$baseShippingAmount = $this->getBaseShippingAmount($creditmemo);
55+
$baseShippingAmount = $this->getBaseShippingAmount($creditmemo, $order);
3556

3657
/**
3758
* If credit memo's shipping amount is set and Order's shipping amount is 0,
@@ -43,10 +64,14 @@ public function collect(\Magento\Sales\Model\Order\Creditmemo $creditmemo)
4364
);
4465
}
4566
if ($baseShippingAmount) {
67+
$orderBaseShippingAmount = $this->isShippingInclTax((int)$order->getStoreId()) ?
68+
$order->getBaseShippingInclTax() : $order->getBaseShippingAmount();
69+
$orderShippingAmount = $this->isShippingInclTax((int)$order->getStoreId()) ?
70+
$order->getShippingInclTax() : $order->getShippingAmount();
4671
$baseShippingDiscount = $baseShippingAmount *
4772
$order->getBaseShippingDiscountAmount() /
48-
$order->getBaseShippingAmount();
49-
$shippingDiscount = $order->getShippingAmount() * $baseShippingDiscount / $order->getBaseShippingAmount();
73+
$orderBaseShippingAmount;
74+
$shippingDiscount = $orderShippingAmount * $baseShippingDiscount / $orderBaseShippingAmount;
5075
$totalDiscountAmount = $totalDiscountAmount + $shippingDiscount;
5176
$baseTotalDiscountAmount = $baseTotalDiscountAmount + $baseShippingDiscount;
5277
}
@@ -104,8 +129,20 @@ private function getBaseShippingAmount(\Magento\Sales\Model\Order\Creditmemo $cr
104129
if (!$baseShippingAmount) {
105130
$baseShippingInclTax = (float)$creditmemo->getBaseShippingInclTax();
106131
$baseShippingTaxAmount = (float)$creditmemo->getBaseShippingTaxAmount();
107-
$baseShippingAmount = $baseShippingInclTax - $baseShippingTaxAmount;
132+
$baseShippingAmount = $this->isShippingInclTax((int)$creditmemo->getStoreId()) ?
133+
$baseShippingInclTax : $baseShippingInclTax - $baseShippingTaxAmount;
108134
}
109135
return $baseShippingAmount;
110136
}
137+
138+
/**
139+
* Returns whether the user specified a shipping amount that already includes tax
140+
*
141+
* @param int $storeId
142+
* @return bool
143+
*/
144+
private function isShippingInclTax(int $storeId): bool
145+
{
146+
return (bool)$this->taxConfig->displaySalesShippingInclTax($storeId);
147+
}
111148
}

app/code/Magento/Sales/Test/Unit/Model/Order/Creditmemo/Total/DiscountTest.php

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,6 @@
66

77
namespace Magento\Sales\Test\Unit\Model\Order\Creditmemo\Total;
88

9-
/**
10-
* Class DiscountTest
11-
*/
129
class DiscountTest extends \PHPUnit\Framework\TestCase
1310
{
1411
/**
@@ -36,6 +33,11 @@ class DiscountTest extends \PHPUnit\Framework\TestCase
3633
*/
3734
protected $orderItemMock;
3835

36+
/**
37+
* @var \Magento\Tax\Model\Config|\PHPUnit\Framework\MockObject\MockObject
38+
*/
39+
private $taxConfig;
40+
3941
protected function setUp()
4042
{
4143
$this->orderMock = $this->createPartialMock(
@@ -54,7 +56,9 @@ protected function setUp()
5456
'getHasChildren', 'getBaseCost', 'getQty', 'getOrderItem', 'setDiscountAmount',
5557
'setBaseDiscountAmount', 'isLast'
5658
]);
57-
$this->total = new \Magento\Sales\Model\Order\Creditmemo\Total\Discount();
59+
$this->taxConfig = $this->createMock(\Magento\Tax\Model\Config::class);
60+
61+
$this->total = new \Magento\Sales\Model\Order\Creditmemo\Total\Discount($this->taxConfig);
5862
}
5963

6064
public function testCollect()
@@ -74,7 +78,7 @@ public function testCollect()
7478
$this->orderMock->expects($this->once())
7579
->method('getBaseShippingDiscountAmount')
7680
->willReturn(1);
77-
$this->orderMock->expects($this->exactly(3))
81+
$this->orderMock->expects($this->exactly(2))
7882
->method('getBaseShippingAmount')
7983
->willReturn(1);
8084
$this->orderMock->expects($this->once())
@@ -150,7 +154,7 @@ public function testCollectNoBaseShippingAmount()
150154
$this->orderMock->expects($this->once())
151155
->method('getBaseShippingDiscountAmount')
152156
->willReturn(1);
153-
$this->orderMock->expects($this->exactly(3))
157+
$this->orderMock->expects($this->exactly(2))
154158
->method('getBaseShippingAmount')
155159
->willReturn(1);
156160
$this->orderMock->expects($this->once())

app/code/Magento/SalesRule/Model/Quote/Address/Total/ShippingDiscount.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,10 @@ public function collect(Quote $quote, ShippingAssignment $shippingAssignment, To
5353

5454
$address->setShippingDiscountAmount(0);
5555
$address->setBaseShippingDiscountAmount(0);
56+
if ($total->getShippingAmountForDiscount() !== null) {
57+
$address->setShippingAmountForDiscount($total->getShippingAmountForDiscount());
58+
$address->setBaseShippingAmountForDiscount($total->getBaseShippingAmountForDiscount());
59+
}
5660
if ($address->getShippingAmount()) {
5761
$this->calculator->processShippingAmount($address);
5862
$total->addTotalAmount(DiscountCollector::COLLECTOR_TYPE_CODE, -$address->getShippingDiscountAmount());

0 commit comments

Comments
 (0)