Skip to content

Commit 7cdd325

Browse files
committed
Merge branch 'ACP2E-92' of https://github.com/magento-l3/magento2ce into PR-2021-12-21
2 parents 5c36fff + 67b983b commit 7cdd325

File tree

2 files changed

+99
-23
lines changed

2 files changed

+99
-23
lines changed

app/code/Magento/Sales/Model/Order/Creditmemo/Validation/QuantityValidator.php

Lines changed: 63 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
use Magento\Sales\Model\Order\Creditmemo;
1717
use Magento\Sales\Model\Order\Item;
1818
use Magento\Sales\Model\ValidatorInterface;
19+
use Magento\Sales\Api\Data\CreditmemoItemInterface;
20+
use Magento\Framework\Phrase;
1921

2022
/**
2123
* Creditmemo QuantityValidator
@@ -74,23 +76,13 @@ public function validate($entity)
7476

7577
$totalQuantity = 0;
7678
foreach ($entity->getItems() as $item) {
77-
if (!isset($orderItemsById[$item->getOrderItemId()])) {
78-
$messages[] = __(
79-
'The creditmemo contains product SKU "%1" that is not part of the original order.',
80-
$item->getSku()
81-
);
82-
continue;
83-
}
84-
$orderItem = $orderItemsById[$item->getOrderItemId()];
85-
86-
if (!$this->canRefundItem($orderItem, $item->getQty(), $invoiceQtysRefundLimits) ||
87-
!$this->isQtyAvailable($orderItem, $item->getQty())
88-
) {
89-
$messages[] =__(
90-
'The quantity to creditmemo must not be greater than the unrefunded quantity'
91-
. ' for product SKU "%1".',
92-
$orderItem->getSku()
93-
);
79+
$message = $this->validateTotalQuantityRefundable(
80+
$orderItemsById,
81+
$item,
82+
$invoiceQtysRefundLimits
83+
);
84+
if ($message) {
85+
$messages[] = $message;
9486
} else {
9587
$totalQuantity += $item->getQty();
9688
}
@@ -105,6 +97,60 @@ public function validate($entity)
10597
return $messages;
10698
}
10799

100+
/**
101+
* To check the refund qty is decimal if getIsQtyDecimal is unset.
102+
*
103+
* @param mixed $isQtyDecimal
104+
* @param float $itemQty
105+
* @return bool
106+
*/
107+
private function isValidDecimalRefundQty($isQtyDecimal, float $itemQty): bool
108+
{
109+
if (!$isQtyDecimal && (floor($itemQty) !== $itemQty)) {
110+
return false;
111+
}
112+
return true;
113+
}
114+
115+
/**
116+
* Calculate total quantity.
117+
*
118+
* @param array $orderItemsById
119+
* @param CreditmemoItemInterface $item
120+
* @param array $invoiceQtysRefundLimits
121+
* @return Phrase|void
122+
*/
123+
private function validateTotalQuantityRefundable(
124+
array $orderItemsById,
125+
CreditmemoItemInterface $item,
126+
array $invoiceQtysRefundLimits
127+
) {
128+
if (!isset($orderItemsById[$item->getOrderItemId()])) {
129+
return __(
130+
'The creditmemo contains product SKU "%1" that is not part of the original order.',
131+
$item->getSku()
132+
);
133+
}
134+
$orderItem = $orderItemsById[$item->getOrderItemId()];
135+
136+
if (!$this->isValidDecimalRefundQty($orderItem->getIsQtyDecimal(), $item->getQty())) {
137+
return __(
138+
'We found an invalid quantity to refund item "%1".',
139+
$orderItem->getSku()
140+
);
141+
}
142+
143+
if (!$this->canRefundItem($orderItem, $item->getQty(), $invoiceQtysRefundLimits) ||
144+
!$this->isQtyAvailable($orderItem, $item->getQty())
145+
) {
146+
return __(
147+
'The quantity to creditmemo must not be greater than the unrefunded quantity'
148+
. ' for product SKU "%1".',
149+
$orderItem->getSku()
150+
);
151+
}
152+
}
153+
108154
/**
109155
* We can have problem with float in php (on some server $a=762.73;$b=762.73; $a-$b!=0)
110156
* for this we have additional diapason for 0

app/code/Magento/Sales/Test/Unit/Model/Order/Creditmemo/Validation/QuantityValidatorTest.php

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -158,11 +158,21 @@ public function testValidateWithWrongItemId()
158158
* @param int $qtyToRequest
159159
* @param int $qtyToRefund
160160
* @param string $sku
161+
* @param int $total
161162
* @param array $expected
163+
* @param bool $isQtyDecimalAllowed
162164
* @dataProvider dataProviderForValidateQty
163165
*/
164-
public function testValidate($orderId, $orderItemId, $qtyToRequest, $qtyToRefund, $sku, $total, array $expected)
165-
{
166+
public function testValidate(
167+
$orderId,
168+
$orderItemId,
169+
$qtyToRequest,
170+
$qtyToRefund,
171+
$sku,
172+
$total,
173+
array $expected,
174+
bool $isQtyDecimalAllowed
175+
) {
166176
$creditmemoMock = $this->getMockBuilder(CreditmemoInterface::class)
167177
->disableOriginalConstructor()
168178
->getMockForAbstractClass();
@@ -189,7 +199,9 @@ public function testValidate($orderId, $orderItemId, $qtyToRequest, $qtyToRefund
189199
$orderItemMock = $this->getMockBuilder(Item::class)
190200
->disableOriginalConstructor()
191201
->getMock();
192-
$orderItemMock->expects($this->exactly(2))->method('getQtyToRefund')
202+
$orderItemMock->expects($this->any())->method('getIsQtyDecimal')
203+
->willReturn($isQtyDecimalAllowed);
204+
$orderItemMock->expects($this->any())->method('getQtyToRefund')
193205
->willReturn($qtyToRefund);
194206
$creditmemoItemMock->expects($this->any())->method('getQty')
195207
->willReturn($qtyToRequest);
@@ -226,7 +238,8 @@ public function dataProviderForValidateQty()
226238
'qtyToRefund' => 1,
227239
'sku',
228240
'total' => 15,
229-
'expected' => []
241+
'expected' => [],
242+
'isQtyDecimalAllowed' => false
230243
],
231244
[
232245
'orderId' => 1,
@@ -235,7 +248,23 @@ public function dataProviderForValidateQty()
235248
'qtyToRefund' => 0,
236249
'sku',
237250
'total' => 15,
238-
'expected' => []
251+
'expected' => [],
252+
'isQtyDecimalAllowed' => false
253+
],
254+
[
255+
'orderId' => 1,
256+
'orderItemId' => 1,
257+
'qtyToRequest' => 1.5,
258+
'qtyToRefund' => 3,
259+
'sku',
260+
'total' => 5,
261+
'expected' => [
262+
__(
263+
'We found an invalid quantity to refund item "%1".',
264+
$sku
265+
)
266+
],
267+
'isQtyDecimalAllowed' => false
239268
],
240269
[
241270
'orderId' => 1,
@@ -251,7 +280,8 @@ public function dataProviderForValidateQty()
251280
$sku
252281
),
253282
__('The credit memo\'s total must be positive.')
254-
]
283+
],
284+
'isQtyDecimalAllowed' => false
255285
],
256286
];
257287
}

0 commit comments

Comments
 (0)