Skip to content

Commit 787690b

Browse files
committed
ACP2E-3045: Order closed without fully refunded
1 parent 754fa7a commit 787690b

File tree

2 files changed

+38
-4
lines changed
  • app/code/Magento/Sales

2 files changed

+38
-4
lines changed

app/code/Magento/Sales/Model/ResourceModel/Order/Handler/State.php

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
namespace Magento\Sales\Model\ResourceModel\Order\Handler;
88

99
use Magento\Sales\Model\Order;
10+
use Magento\Sales\Model\Order\Invoice;
1011

1112
/**
1213
* Checking order status and adjusting order status before saving
@@ -30,7 +31,11 @@ public function check(Order $order)
3031
$currentState = Order::STATE_PROCESSING;
3132
}
3233

33-
if (!$order->isCanceled() && !$order->canUnhold() && !$order->canInvoice() && $order->getTotalDue() == 0) {
34+
if (!$order->isCanceled()
35+
&& !$order->canUnhold()
36+
&& !$order->canInvoice()
37+
&& !$this->orderHasOpenInvoices($order)
38+
) {
3439
if (in_array($currentState, [Order::STATE_PROCESSING, Order::STATE_COMPLETE])
3540
&& !$order->canCreditmemo()
3641
&& !$order->canShip()
@@ -67,6 +72,24 @@ public function isPartiallyRefundedOrderShipped(Order $order): bool
6772
return $isPartiallyRefundedOrderShipped;
6873
}
6974

75+
/**
76+
* Check if order has unpaid invoices
77+
*
78+
* @param Order $order
79+
* @return bool
80+
*/
81+
private function orderHasOpenInvoices(Order $order): bool
82+
{
83+
/** @var Invoice $invoice */
84+
foreach ($order->getInvoiceCollection()->getItems() as $invoice) {
85+
if ($invoice->getState() == Invoice::STATE_OPEN) {
86+
return true;
87+
}
88+
}
89+
90+
return false;
91+
}
92+
7093
/**
7194
* Get all refunded items number
7295
*

app/code/Magento/Sales/Test/Unit/Model/ResourceModel/Order/Handler/StateTest.php

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,10 @@
99

1010
use Magento\Sales\Model\Order;
1111
use Magento\Sales\Model\Order\Address;
12+
use Magento\Sales\Model\Order\Invoice;
1213
use Magento\Sales\Model\ResourceModel\Order\Address\Collection;
1314
use Magento\Sales\Model\ResourceModel\Order\Handler\State;
15+
use Magento\Sales\Model\ResourceModel\Order\Invoice\Collection as InvoiceCollection;
1416
use PHPUnit\Framework\MockObject\MockObject;
1517
use PHPUnit\Framework\TestCase;
1618

@@ -46,14 +48,25 @@ protected function setUp(): void
4648
'getIsNotVirtual',
4749
'getStatus',
4850
'getAllItems',
49-
'getTotalDue'
51+
'getInvoiceCollection'
5052
]
5153
)
5254
->disableOriginalConstructor()
5355
->getMock();
5456
$this->orderMock->expects($this->any())
5557
->method('getConfig')
5658
->willReturnSelf();
59+
$invoice = $this->createMock(Invoice::class);
60+
$invoice->expects($this->once())
61+
->method('getState')
62+
->willReturn(Invoice::STATE_PAID);
63+
$invoiceCollection = $this->createMock(InvoiceCollection::class);
64+
$invoiceCollection->expects($this->once())
65+
->method('getItems')
66+
->willReturn([$invoice]);
67+
$this->orderMock->expects($this->once())
68+
->method('getInvoiceCollection')
69+
->willReturn($invoiceCollection);
5770
$this->state = new State();
5871
}
5972

@@ -108,8 +121,6 @@ public function testCheck(
108121
->willReturn($isNotVirtual);
109122
$this->orderMock->method('getAllItems')
110123
->willReturn([]);
111-
$this->orderMock->method('getTotalDue')
112-
->willReturn(0);
113124
if (!$isNotVirtual) {
114125
$this->orderMock->method('getIsVirtual')
115126
->willReturn(!$isNotVirtual);

0 commit comments

Comments
 (0)