Skip to content

Commit b3072ac

Browse files
committed
ACP2E-1918: Cannot create more than 1 Credit Memo for $0 Order
1 parent 4c4c0be commit b3072ac

File tree

6 files changed

+48
-23
lines changed

6 files changed

+48
-23
lines changed

app/code/Magento/Checkout/Test/Fixture/SetPaymentMethod.php

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,17 +38,21 @@ public function __construct(
3838

3939
/**
4040
* {@inheritdoc}
41-
* @param array $data Parameters
41+
* @param array $data Parameters. Same format as SetPaymentMethod::DEFAULT_DATA.
4242
* <pre>
4343
* $data = [
4444
* 'cart_id' => (int) Cart ID. Required
4545
* 'method' => (array) Payment method. Optional
4646
* ]
4747
* </pre>
48+
* Fields structure:
49+
* - $data['method']: can be supplied in following formats:
50+
* - array ["method" => "checkmo", "po_number" => null, "additional_data" => null]
51+
* - string "checkmo"
4852
*/
4953
public function apply(array $data = []): ?DataObject
5054
{
51-
$data = array_merge(self::DEFAULT_DATA, $data);
55+
$data = $this->prepareData($data);
5256
$service = $this->serviceFactory->create(PaymentMethodManagementInterface::class, 'set');
5357
$service->execute(
5458
[
@@ -59,4 +63,19 @@ public function apply(array $data = []): ?DataObject
5963

6064
return null;
6165
}
66+
67+
/**
68+
* Prepare payment data
69+
*
70+
* @param array $data
71+
* @return array
72+
*/
73+
private function prepareData(array $data): array
74+
{
75+
if (is_string($data['method'])) {
76+
$data['method'] = ['method' => $data['method']];
77+
}
78+
79+
return array_merge(self::DEFAULT_DATA, $data);
80+
}
6281
}

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

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -769,10 +769,8 @@ private function canCreditmemoForZeroTotalRefunded($totalRefunded)
769769
*/
770770
private function canCreditmemoForZeroTotal($totalRefunded)
771771
{
772-
foreach ($this->getAllItems() as $orderItem) {
773-
if ($this->creditmemoValidator->canRefundItem($orderItem)) {
774-
return true;
775-
}
772+
if ($this->areThereRefundableItems()) {
773+
return true;
776774
}
777775

778776
$totalPaid = $this->getTotalPaid();
@@ -792,6 +790,22 @@ private function canCreditmemoForZeroTotal($totalRefunded)
792790
return true;
793791
}
794792

793+
/**
794+
* Check if there are order items available for refund.
795+
*
796+
* @return bool
797+
*/
798+
private function areThereRefundableItems(): bool
799+
{
800+
foreach ($this->getAllItems() as $orderItem) {
801+
if ($this->creditmemoValidator->canRefundItem($orderItem)) {
802+
return true;
803+
}
804+
}
805+
806+
return false;
807+
}
808+
795809
/**
796810
* Retrieve order hold availability
797811
*

app/code/Magento/Sales/Test/Fixture/Creditmemo.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,10 +62,10 @@ public function __construct(
6262
* @param array $data Parameters. Same format as Creditmemo::DEFAULT_DATA.
6363
* Fields structure fields:
6464
* - $data['items']: can be supplied in following formats:
65-
* - array of arrays [{"sku":"$product1.sku$","qty":1}, {"sku":"$product2.sku$","qty":1}]
66-
* - array of arrays [{"order_item_id":"$oItem1.sku$","qty":1}, {"order_item_id":"$oItem2.sku$","qty":1}]
67-
* - array of arrays [{"product_id":"$product1.id$","qty":1}, {"product_id":"$product2.id$","qty":1}]
68-
* - array of arrays [{"quote_item_id":"$qItem1.id$","qty":1}, {"quote_item_id":"$qItem2.id$","qty":1}]
65+
* - array of arrays [["sku":"$product1.sku$","qty":1], ["sku":"$product2.sku$","qty":1]]
66+
* - array of arrays [["order_item_id":"$oItem1.sku$","qty":1], ["order_item_id":"$oItem2.sku$","qty":1]]
67+
* - array of arrays [["product_id":"$product1.id$","qty":1], ["product_id":"$product2.id$","qty":1]]
68+
* - array of arrays [["quote_item_id":"$qItem1.id$","qty":1], ["quote_item_id":"$qItem2.id$","qty":1]]
6969
* - array of SKUs ["$product1.sku$", "$product2.sku$"]
7070
* - array of order items IDs ["$oItem1.id$", "$oItem2.id$"]
7171
* - array of product instances ["$product1$", "$product2$"]

app/code/Magento/Sales/Test/Unit/Model/OrderTest.php

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
use Magento\Sales\Model\ResourceModel\Order\Collection as OrderCollection;
2929
use Magento\Sales\Model\ResourceModel\Order\CollectionFactory as OrderCollectionFactory;
3030
use Magento\Sales\Model\ResourceModel\Order\Invoice\Collection as OrderInvoiceCollection;
31-
use Magento\Sales\Model\ResourceModel\Order\Item;
31+
use Magento\Sales\Model\Order\Item;
3232
use Magento\Sales\Model\ResourceModel\Order\Item\Collection as OrderItemCollection;
3333
use Magento\Sales\Model\ResourceModel\Order\Item\CollectionFactory as OrderItemCollectionFactory;
3434
use Magento\Sales\Model\ResourceModel\Order\Payment;
@@ -153,16 +153,6 @@ protected function setUp(): void
153153
['create']
154154
);
155155
$this->item = $this->getMockBuilder(Item::class)
156-
->addMethods(
157-
[
158-
'isDeleted',
159-
'getQtyToInvoice',
160-
'getParentItemId',
161-
'getQuoteItemId',
162-
'getLockedDoInvoice',
163-
'getProductId'
164-
]
165-
)
166156
->disableOriginalConstructor()
167157
->getMock();
168158
$this->salesOrderCollectionMock = $this->getMockBuilder(

dev/tests/integration/testsuite/Magento/Sales/Model/OrderTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ protected function setUp(): void
4343
}
4444

4545
/**
46-
* Tests that multiple credit memos can be created for zero total order.
46+
* Tests that multiple credit memos can be created for zero total order if not all items are refunded yet
4747
*/
4848
#[
4949
Config('carriers/freeshipping/active', '1', 'store', 'default'),
@@ -71,7 +71,7 @@ protected function setUp(): void
7171
SetDeliveryMethodFixture::class,
7272
['cart_id' => '$cart.id$', 'carrier_code' => 'freeshipping', 'method_code' => 'freeshipping']
7373
),
74-
DataFixture(SetPaymentMethodFixture::class, ['cart_id' => '$cart.id$', 'method' => ['method' => 'free']]),
74+
DataFixture(SetPaymentMethodFixture::class, ['cart_id' => '$cart.id$', 'method' => 'free']),
7575
DataFixture(PlaceOrderFixture::class, ['cart_id' => '$cart.id$'], 'order'),
7676
DataFixture(InvoiceFixture::class, ['order_id' => '$order.id$'], 'invoice'),
7777
DataFixture(

dev/tests/integration/testsuite/Magento/Sales/_files/creditmemo_with_grouped_product.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
*/
66
declare(strict_types=1);
77

8+
use Magento\Sales\Model\InvoiceOrder;
89
use Magento\Sales\Model\Order;
910
use Magento\Sales\Model\Order\Creditmemo;
1011
use Magento\Sales\Model\Order\Creditmemo\Item;
@@ -20,6 +21,7 @@
2021
/** @var Order $order */
2122
$order = $objectManager->create(Order::class);
2223
$order->loadByIncrementId('100000002');
24+
$objectManager->get(InvoiceOrder::class)->execute($order->getId());
2325
$creditmemo = $creditmemoFactory->createByOrder($order, $order->getData());
2426
$creditmemo->setOrder($order);
2527
$creditmemo->setState(Creditmemo::STATE_OPEN);

0 commit comments

Comments
 (0)