From e839009a2abbbe9f18ef409a4b297e2baf1799e2 Mon Sep 17 00:00:00 2001 From: Michiel Gerritsen Date: Thu, 30 Oct 2025 09:56:35 +0100 Subject: [PATCH] Bugfix: Better batch handling for refunds --- Service/Order/ProcessAdjustmentFee.php | 20 ++--- .../Mollie/Order/RefundUsingPaymentFake.php | 42 ++++++++++ .../Order/ProcessAdjustmentFeeTest.php | 83 +++++++++++++++++++ 3 files changed, 134 insertions(+), 11 deletions(-) create mode 100644 Test/Fakes/Service/Mollie/Order/RefundUsingPaymentFake.php create mode 100644 Test/Integration/Service/Order/ProcessAdjustmentFeeTest.php diff --git a/Service/Order/ProcessAdjustmentFee.php b/Service/Order/ProcessAdjustmentFee.php index 43d7f1c63e5..5ddfab25ff2 100644 --- a/Service/Order/ProcessAdjustmentFee.php +++ b/Service/Order/ProcessAdjustmentFee.php @@ -1,20 +1,18 @@ mollieHelper = $mollieHelper; $this->refundUsingPayment = $refundUsingPayment; } public function handle(MollieApiClient $mollieApi, OrderInterface $order, CreditmemoInterface $creditmemo) { + $this->doNotRefundInMollie = false; + if ($creditmemo->getAdjustment() > 0) { $this->positive($mollieApi, $order, $creditmemo); } @@ -44,12 +42,12 @@ public function handle(MollieApiClient $mollieApi, OrderInterface $order, Credit } } - public function doNotRefundInMollie() + public function doNotRefundInMollie(): bool { return $this->doNotRefundInMollie; } - private function positive(MollieApiClient $mollieApi, OrderInterface $order, CreditmemoInterface $creditmemo) + private function positive(MollieApiClient $mollieApi, OrderInterface $order, CreditmemoInterface $creditmemo): void { $this->doNotRefundInMollie = false; @@ -61,7 +59,7 @@ private function positive(MollieApiClient $mollieApi, OrderInterface $order, Cre ); } - private function negative(MollieApiClient $mollieApi, OrderInterface $order, CreditmemoInterface $creditmemo) + private function negative(MollieApiClient $mollieApi, OrderInterface $order, CreditmemoInterface $creditmemo): void { $this->doNotRefundInMollie = true; diff --git a/Test/Fakes/Service/Mollie/Order/RefundUsingPaymentFake.php b/Test/Fakes/Service/Mollie/Order/RefundUsingPaymentFake.php new file mode 100644 index 00000000000..74bb624fe04 --- /dev/null +++ b/Test/Fakes/Service/Mollie/Order/RefundUsingPaymentFake.php @@ -0,0 +1,42 @@ +disableParentCall = true; + } + + public function getCalls(): array + { + return $this->calls; + } + + public function execute(MollieApiClient $mollieApi, $transactionId, $currencyCode, $amount) + { + $this->calls[] = [ + 'transactionId' => $transactionId, + 'currencyCode' => $currencyCode, + 'amount' => $amount, + ]; + + if ($this->disableParentCall) { + return; + } + + parent::execute($mollieApi, $transactionId, $currencyCode, $amount); + } +} diff --git a/Test/Integration/Service/Order/ProcessAdjustmentFeeTest.php b/Test/Integration/Service/Order/ProcessAdjustmentFeeTest.php new file mode 100644 index 00000000000..9c8e3364d7b --- /dev/null +++ b/Test/Integration/Service/Order/ProcessAdjustmentFeeTest.php @@ -0,0 +1,83 @@ +objectManager->create(RefundUsingPaymentFake::class); + $refundUsingPayment->disableParentCall(); + $this->objectManager->addSharedInstance($refundUsingPayment, RefundUsingPayment::class); + + $mollieApiClient = $this->objectManager->create(\Mollie\Api\MollieApiClient::class); + + $instance = $this->objectManager->create(ProcessAdjustmentFee::class); + + $order = $this->objectManager->create(OrderInterface::class); + $creditmemo = $this->objectManager->create(CreditmemoInterface::class); + $creditmemo->setAdjustment(10); + + $instance->handle($mollieApiClient, $order, $creditmemo); + + $this->assertFalse($instance->doNotRefundInMollie()); + $this->assertCount(1, $refundUsingPayment->getCalls()); + } + + public function testRefundsNegative(): void + { + $refundUsingPayment = $this->objectManager->create(RefundUsingPaymentFake::class); + $refundUsingPayment->disableParentCall(); + $this->objectManager->addSharedInstance($refundUsingPayment, RefundUsingPayment::class); + + $mollieApiClient = $this->objectManager->create(\Mollie\Api\MollieApiClient::class); + + $instance = $this->objectManager->create(ProcessAdjustmentFee::class); + + $order = $this->objectManager->create(OrderInterface::class); + $creditmemo = $this->objectManager->create(CreditmemoInterface::class); + $creditmemo->setData('adjustment_negative', 10); + + $instance->handle($mollieApiClient, $order, $creditmemo); + + $this->assertTrue($instance->doNotRefundInMollie()); + $this->assertCount(1, $refundUsingPayment->getCalls()); + } + + public function testResetsTheRefundInMollieFlag(): void + { + // Scenario: Do a negative creditmemo first, then a creditmemo without adjustments. + + $refundUsingPayment = $this->objectManager->create(RefundUsingPaymentFake::class); + $refundUsingPayment->disableParentCall(); + $this->objectManager->addSharedInstance($refundUsingPayment, RefundUsingPayment::class); + + $mollieApiClient = $this->objectManager->create(\Mollie\Api\MollieApiClient::class); + + $instance = $this->objectManager->create(ProcessAdjustmentFee::class); + + $negativeCreditmemo = $this->objectManager->create(CreditmemoInterface::class); + $negativeCreditmemo->setData('adjustment_negative', 10); + + $order = $this->objectManager->create(OrderInterface::class); + + $instance->handle($mollieApiClient, $order, $negativeCreditmemo); + $this->assertTrue($instance->doNotRefundInMollie()); + + $creditmemoWithoutAdjustments = $this->objectManager->create(CreditmemoInterface::class); + + $instance->handle($mollieApiClient, $order, $creditmemoWithoutAdjustments); + $this->assertFalse($instance->doNotRefundInMollie()); + } +}