Skip to content

Commit 00b7ccf

Browse files
committed
ACP2E-4157: Error when create credit memo for offline refund
1 parent 1d11147 commit 00b7ccf

File tree

2 files changed

+66
-4
lines changed
  • app/code/Magento/Sales
    • Controller/Adminhtml/Order/Creditmemo
    • Test/Unit/Controller/Adminhtml/Order/Creditmemo

2 files changed

+66
-4
lines changed

app/code/Magento/Sales/Controller/Adminhtml/Order/Creditmemo/Save.php

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?php
22
/**
3-
* Copyright © Magento, Inc. All rights reserved.
4-
* See COPYING.txt for license details.
3+
* Copyright 2014 Adobe
4+
* All Rights Reserved.
55
*/
66
namespace Magento\Sales\Controller\Adminhtml\Order\Creditmemo;
77

@@ -10,6 +10,7 @@
1010
use Magento\Sales\Helper\Data as SalesData;
1111
use Magento\Sales\Model\Order\Creditmemo;
1212
use Magento\Sales\Model\Order\Email\Sender\CreditmemoSender;
13+
use Magento\Catalog\Model\Product\Type\AbstractType;
1314

1415
class Save extends \Magento\Backend\App\Action implements HttpPostActionInterface
1516
{
@@ -155,6 +156,13 @@ private function adjustCreditMemoItemQuantities(Creditmemo $creditMemo): void
155156
$parentQuantities = [];
156157
foreach ($items as $item) {
157158
if ($parentId = $item->getOrderItem()->getParentItemId()) {
159+
$parentOrderItem = $item->getOrderItem()->getParentItem();
160+
if ($parentOrderItem && $parentOrderItem->getProductType() === 'bundle' &&
161+
($parentOptions = $parentOrderItem->getProductOptions()) &&
162+
isset($parentOptions['product_calculations']) &&
163+
$parentOptions['product_calculations'] == AbstractType::CALCULATE_PARENT) {
164+
continue;
165+
}
158166
if (empty($parentQuantities[$parentId])) {
159167
$parentQuantities[$parentId] = $item->getQty();
160168
} else {

app/code/Magento/Sales/Test/Unit/Controller/Adminhtml/Order/Creditmemo/SaveTest.php

Lines changed: 56 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?php
22
/**
3-
* Copyright © Magento, Inc. All rights reserved.
4-
* See COPYING.txt for license details.
3+
* Copyright 2014 Adobe
4+
* All Rights Reserved.
55
*/
66
declare(strict_types=1);
77

@@ -29,6 +29,7 @@
2929
use Magento\Sales\Model\Order\Creditmemo;
3030
use Magento\Sales\Model\Order\Creditmemo\Item;
3131
use Magento\Sales\Model\Order\Email\Sender\CreditmemoSender;
32+
use Magento\Catalog\Model\Product\Type\AbstractType;
3233
use PHPUnit\Framework\MockObject\MockObject;
3334
use PHPUnit\Framework\TestCase;
3435

@@ -413,4 +414,57 @@ public function testExecuteEmails(
413414
}
414415
$this->assertEquals($this->resultRedirectMock, $this->_controller->execute());
415416
}
417+
418+
/**
419+
* Test execute method with bundle products
420+
*/
421+
public function testExecuteWithBundleProductCreditMemo()
422+
{
423+
$orderId = 1;
424+
$creditmemoId = 2;
425+
$invoiceId = 3;
426+
$creditmemoData = ['items' => [], 'comment_text' => ''];
427+
$this->_requestMock->expects($this->any())
428+
->method('getParam')
429+
->willReturnMap([
430+
['order_id', null, $orderId],
431+
['creditmemo_id', null, $creditmemoId],
432+
['creditmemo', null, $creditmemoData],
433+
['invoice_id', null, $invoiceId]
434+
]);
435+
436+
$this->_requestMock->expects($this->once())
437+
->method('getPost')
438+
->with('creditmemo')
439+
->willReturn($creditmemoData);
440+
$orderMock = $this->createMock(Order::class);
441+
$parentOrderItemMock = $this->createMock(Order\Item::class);
442+
$parentOrderItemMock->expects($this->any())->method('getProductType')->willReturn('bundle');
443+
$parentOrderItemMock->expects($this->any())
444+
->method('getProductOptions')
445+
->willReturn([
446+
'product_calculations' => AbstractType::CALCULATE_PARENT
447+
]);
448+
$childOrderItemMock = $this->createMock(Order\Item::class);
449+
$childOrderItemMock->expects($this->any())->method('getParentItemId')->willReturn(1);
450+
$childOrderItemMock->expects($this->any())->method('getParentItem')->willReturn($parentOrderItemMock);
451+
$creditMemoItemMock = $this->createMock(Item::class);
452+
$creditMemoItemMock->expects($this->any())->method('getOrderItem')->willReturn($childOrderItemMock);
453+
$creditMemoItemMock->expects($this->never())->method('setQty');
454+
$creditmemoMock = $this->createMock(Creditmemo::class);
455+
$creditmemoMock->expects($this->once())->method('isValidGrandTotal')->willReturn(true);
456+
$creditmemoMock->expects($this->once())->method('getOrder')->willReturn($orderMock);
457+
$creditmemoMock->expects($this->once())->method('getOrderId')->willReturn($orderId);
458+
$creditmemoMock->expects($this->once())->method('getAllItems')->willReturn([$creditMemoItemMock]);
459+
$this->memoLoaderMock->expects($this->once())->method('load')->willReturn($creditmemoMock);
460+
$this->resultRedirectFactoryMock->expects($this->once())
461+
->method('create')
462+
->willReturn($this->resultRedirectMock);
463+
$this->resultRedirectMock->expects($this->once())
464+
->method('setPath')
465+
->with('sales/order/view', ['order_id' => $orderId])
466+
->willReturnSelf();
467+
$result = $this->_controller->execute();
468+
$this->assertEquals($this->resultRedirectMock, $result);
469+
}
416470
}

0 commit comments

Comments
 (0)