Skip to content

Commit

Permalink
Merge pull request #540 from mollie/release/2.13.0
Browse files Browse the repository at this point in the history
Release/2.13.0
  • Loading branch information
Marvin-Magmodules authored Jun 28, 2022
2 parents e3b8413 + b99ceb9 commit d8e4e9a
Show file tree
Hide file tree
Showing 8 changed files with 210 additions and 8 deletions.
2 changes: 1 addition & 1 deletion Helper/General.php
Original file line number Diff line number Diff line change
Expand Up @@ -605,7 +605,7 @@ public function formatCurrencyValue($value, $currency)
$decimalPrecision = 0;
}

return number_format($value, $decimalPrecision, '.', '');
return number_format($value ?? 0.0, $decimalPrecision, '.', '');
}

/**
Expand Down
6 changes: 4 additions & 2 deletions Model/Client/Payments/Processors/SuccessfulPayment.php
Original file line number Diff line number Diff line change
Expand Up @@ -127,12 +127,14 @@ public function process(
$this->handlePayment($magentoOrder, $molliePayment);
}

/** @var Order\Invoice $invoice */
/** @var Order\Invoice|null $invoice */
$invoice = $payment->getCreatedInvoice();
$sendInvoice = $this->mollieHelper->sendInvoice($magentoOrder->getStoreId());

$this->sendOrderConfirmationEmail($magentoOrder);
$this->sendInvoiceEmail($invoice, $sendInvoice, $magentoOrder);
if ($invoice) {
$this->sendInvoiceEmail($invoice, $sendInvoice, $magentoOrder);
}

return $this->processTransactionResponseFactory->create([
'success' => true,
Expand Down
17 changes: 14 additions & 3 deletions Observer/OrderCancelAfter.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@

use Magento\Framework\Event\ObserverInterface;
use Magento\Framework\Event\Observer;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\Message\ManagerInterface;
use Mollie\Payment\Model\Mollie as MollieModel;
use Mollie\Payment\Helper\General as MollieHelper;

Expand All @@ -28,6 +30,11 @@ class OrderCancelAfter implements ObserverInterface
*/
private $mollieHelper;

/**
* @var ManagerInterface
*/
private $messageManager;

/**
* OrderCancelAfter constructor.
*
Expand All @@ -36,10 +43,12 @@ class OrderCancelAfter implements ObserverInterface
*/
public function __construct(
MollieModel $mollieModel,
MollieHelper $mollieHelper
MollieHelper $mollieHelper,
ManagerInterface $messageManager
) {
$this->mollieModel = $mollieModel;
$this->mollieHelper = $mollieHelper;
$this->messageManager = $messageManager;
}

/**
Expand All @@ -55,12 +64,14 @@ public function execute(Observer $observer)
/**
* When manually marking an order as paid we don't want to communicate to Mollie as it will throw an exception.
*/
if ($order->getReordered()) {
if ($order->getReordered() || !$this->mollieHelper->isPaidUsingMollieOrdersApi($order)) {
return;
}

if ($this->mollieHelper->isPaidUsingMollieOrdersApi($order)) {
try {
$this->mollieModel->cancelOrder($order);
} catch (LocalizedException $localizedException) {
$this->messageManager->addErrorMessage($localizedException->getMessage());
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
<?php

namespace Mollie\Payment\Observer\SalesQuoteItemSetProduct;

use Magento\Catalog\Api\Data\ProductInterface;
use Magento\Catalog\Model\Product\Configuration\Item\Option\OptionInterface;
use Magento\Framework\Event\Observer;
use Magento\Framework\Event\ObserverInterface;
use Magento\Framework\Exception\NotFoundException;
use Magento\Framework\Serialize\SerializerInterface;
use Magento\Quote\Api\Data\CartItemInterface;

class SetSubscriptionDataOnBuyRequest implements ObserverInterface
{
/**
* @var SerializerInterface
*/
private $serializer;

public function __construct(
SerializerInterface $serializer
) {
$this->serializer = $serializer;
}

public function execute(Observer $observer)
{
/** @var ProductInterface $product */
$product = $observer->getData('product');
if (!$product->getData('mollie_subscription_product')) {
return;
}

$table = $product->getData('mollie_subscription_table');
if (!$table) {
return;
}

$buyRequest = $this->getBuyRequest($observer->getData('quote_item'));
$value = $this->serializer->unserialize($buyRequest->getValue());
if (isset($value['mollie_metadata'])) {
return;
}

$data = $this->serializer->unserialize($table);
$default = $this->getDefault($data);

$value['mollie_metadata'] = [
'purchase' => 'subscription',
'recurring_metadata' => [
'option_id' => $default['identifier'],
],
];

$buyRequest->setValue($this->serializer->serialize($value));
}

private function getDefault(array $data): array
{
foreach ($data as $row) {
if (isset($row['isDefault']) && $row['isDefault']) {
return $row;
}
}

return array_shift($data);
}

private function getBuyRequest(CartItemInterface $item): OptionInterface
{
/** @var OptionInterface[] $options */
$options = $item->getOptions();
foreach ($options as $option) {
if ($option->getCode() == 'info_buyRequest') {
return $option;
}
}

throw new NotFoundException(__('No info_buyRequest option found'));
}
}
105 changes: 105 additions & 0 deletions Test/Integration/Observer/TestOrderCancelAfter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
<?php

namespace Mollie\Payment\Observer;

use Magento\Framework\Event;
use Magento\Framework\Event\Observer;
use Magento\Framework\Exception\LocalizedException;
use Magento\Sales\Api\Data\OrderInterface;
use Mollie\Api\Exceptions\ApiException;
use Mollie\Payment\Model\Mollie;
use Mollie\Payment\Test\Integration\IntegrationTestCase;

class TestOrderCancelAfter extends IntegrationTestCase
{
public function testDoesNothingWhenReordered(): void
{
$modelMock = $this->createMock(Mollie::class);
$modelMock->expects($this->never())->method('cancelOrder');

/** @var OrderCancelAfter $instance */
$instance = $this->objectManager->create(OrderCancelAfter::class, [
'mollieModel' => $modelMock,
]);

$order = $this->objectManager->create(OrderInterface::class);
$order->setReordered(true);

$instance->execute($this->makeObserver($order));
}

public function testDoesNothingWhenNotPaidUsingOrdersApi(): void
{
$modelMock = $this->createMock(Mollie::class);
$modelMock->expects($this->never())->method('cancelOrder');

$helperMock = $this->createMock(\Mollie\Payment\Helper\General::class);
$helperMock->method('isPaidUsingMollieOrdersApi')->willReturn(false);

/** @var OrderCancelAfter $instance */
$instance = $this->objectManager->create(OrderCancelAfter::class, [
'mollieHelper' => $helperMock,
'mollieModel' => $modelMock,
]);

$order = $this->objectManager->create(OrderInterface::class);

$instance->execute($this->makeObserver($order));
}

public function testCancelsTheOrder(): void
{
$modelMock = $this->createMock(Mollie::class);
$modelMock->expects($this->once())->method('cancelOrder');

$helperMock = $this->createMock(\Mollie\Payment\Helper\General::class);
$helperMock->method('isPaidUsingMollieOrdersApi')->willReturn(true);

/** @var OrderCancelAfter $instance */
$instance = $this->objectManager->create(OrderCancelAfter::class, [
'mollieHelper' => $helperMock,
'mollieModel' => $modelMock,
]);

$order = $this->objectManager->create(OrderInterface::class);

$instance->execute($this->makeObserver($order));
}

public function testConvertsExceptionToErrorMessage(): void
{
$message = 'Error executing API call (422: Unprocessable Entity): The order cannot be canceled due to an open payment. Please wait until the payment is in a finalized state.. Documentation: https://docs.mollie.com/reference/v2/orders-api/cancel-order';
$exception = new LocalizedException(__($message));
$modelMock = $this->createMock(Mollie::class);
$modelMock->method('cancelOrder')->willThrowException($exception);

$helperMock = $this->createMock(\Mollie\Payment\Helper\General::class);
$helperMock->method('isPaidUsingMollieOrdersApi')->willReturn(true);

/** @var OrderCancelAfter $instance */
$instance = $this->objectManager->create(OrderCancelAfter::class, [
'mollieHelper' => $helperMock,
'mollieModel' => $modelMock,
]);

$order = $this->objectManager->create(OrderInterface::class);

$instance->execute($this->makeObserver($order));

/** @var \\Magento\Framework\Message\ManagerInterface $manager */
$manager = $this->objectManager->get(\Magento\Framework\Message\ManagerInterface::class);

$messages = $manager->getMessages();
$this->assertCount(1, $messages->getErrors());
$this->assertEquals($message, $messages->getErrors()[0]->getText());
}

private function makeObserver(OrderInterface $order): Observer
{
return new Observer([
'event' => new Event([
'order' => $order,
]),
]);
}
}
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "mollie/magento2",
"description": "Mollie Payment Module for Magento 2",
"version": "2.12.0",
"version": "2.13.0",
"keywords": [
"mollie",
"payment",
Expand Down
2 changes: 1 addition & 1 deletion etc/config.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<default>
<payment>
<mollie_general>
<version>v2.12.0</version>
<version>v2.13.0</version>
<active>0</active>
<enabled>0</enabled>
<type>test</type>
Expand Down
3 changes: 3 additions & 0 deletions etc/events.xml
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,7 @@
<event name="checkout_submit_all_after">
<observer name="mollie_startransaction_for_instant_purchase_orders" instance="Mollie\Payment\Observer\CheckoutSubmitAllAfter\StartTransactionForInstantPurchaseOrders" />
</event>
<event name="sales_quote_item_set_product">
<observer name="mollie_add_subscription_product_type_options" instance="Mollie\Payment\Observer\SalesQuoteItemSetProduct\SetSubscriptionDataOnBuyRequest" />
</event>
</config>

0 comments on commit d8e4e9a

Please sign in to comment.