Skip to content

Commit 289859d

Browse files
Merge pull request #144 from mollie/5.5.1
5.5.1
2 parents 9b6a200 + 62b873a commit 289859d

File tree

14 files changed

+598
-85
lines changed

14 files changed

+598
-85
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<?php
2+
3+
class Mollie_Mpm_Exceptions_KlarnaException extends Exception
4+
{
5+
6+
}

app/code/community/Mollie/Mpm/Helper/Data.php

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
11
<?php
2+
3+
use Mollie\Api\Resources\Order as MollieOrder;
4+
use Mollie_Mpm_Model_Adminhtml_System_Config_Source_InvoiceMoment as InvoiceMoment;
5+
26
/**
37
* Copyright (c) 2012-2019, Mollie B.V.
48
* All rights reserved.
@@ -55,6 +59,7 @@ class Mollie_Mpm_Helper_Data extends Mage_Core_Helper_Abstract
5559
const XPATH_PAYMENTLINK_MESSAGE = 'payment/mollie_paymentlink/message';
5660
const XPATH_API_METHOD = 'payment/%method%/method';
5761
const XPATH_PAYMENT_DESCRIPTION = 'payment/%method%/payment_description';
62+
const XPATH_INVOICE_MOMENT = 'payment/%method%/invoice_moment';
5863

5964
/**
6065
* @var null
@@ -912,4 +917,61 @@ public function getPaymentDescription($method, Mage_Sales_Model_Order $order, $s
912917
$description
913918
);
914919
}
920+
921+
/**
922+
* If one of the payments has the status 'paid', return that status. Otherwise return the last status.
923+
*
924+
* @param MollieOrder $order
925+
* @return string|null
926+
*/
927+
public function getLastRelevantStatus(MollieOrder $order)
928+
{
929+
if (!isset($order->_embedded->payments)) {
930+
return null;
931+
}
932+
933+
$payments = $order->_embedded->payments;
934+
foreach ($payments as $payment) {
935+
if ($payment->status == 'paid') {
936+
return 'paid';
937+
}
938+
}
939+
940+
return end($payments)->status;
941+
}
942+
943+
public function getInvoiceMoment(Mage_Sales_Model_Order $order)
944+
{
945+
$method = $this->getMethodCode($order);
946+
947+
if (!in_array($method, array('klarnasliceit', 'klarnapaylater'))) {
948+
return InvoiceMoment::ON_AUTHORIZE_PAID_AFTER_SHIPMENT;
949+
}
950+
951+
$path = str_replace('%method%', 'mollie_' . $method, static::XPATH_INVOICE_MOMENT);
952+
return $this->getStoreConfig($path, $order->getStoreId());
953+
}
954+
955+
public function isInvoiceMomentOnAuthorize(Mage_Sales_Model_Order $order)
956+
{
957+
$moment = $this->getInvoiceMoment($order);
958+
959+
return $moment == InvoiceMoment::ON_AUTHORIZE_PAID_AFTER_SHIPMENT ||
960+
$moment == InvoiceMoment::ON_AUTHORIZE_PAID_BEFORE_SHIPMENT;
961+
}
962+
963+
public function getInvoiceMomentPaidStatus(Mage_Sales_Model_Order $order)
964+
{
965+
$moment = $this->getInvoiceMoment($order);
966+
967+
if ($moment == InvoiceMoment::ON_AUTHORIZE_PAID_AFTER_SHIPMENT) {
968+
return Mage_Sales_Model_Order_Invoice::STATE_OPEN;
969+
}
970+
971+
if ($moment == InvoiceMoment::ON_AUTHORIZE_PAID_BEFORE_SHIPMENT) {
972+
return Mage_Sales_Model_Order_Invoice::STATE_PAID;
973+
}
974+
975+
throw new \Exception('Invoice moment not supported: ' . $moment);
976+
}
915977
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?php
2+
3+
class Mollie_Mpm_Model_Adminhtml_System_Config_Source_InvoiceMoment
4+
{
5+
const ON_SHIPMENT = 'shipment';
6+
const ON_AUTHORIZE_PAID_BEFORE_SHIPMENT = 'authorize_paid_before_shipment';
7+
const ON_AUTHORIZE_PAID_AFTER_SHIPMENT = 'authorize_paid_after_shipment';
8+
9+
public function toOptionArray()
10+
{
11+
return array(
12+
array(
13+
'value' => static::ON_AUTHORIZE_PAID_BEFORE_SHIPMENT,
14+
'label' => __('On Authorize and set status Paid before shipment'),
15+
),
16+
array(
17+
'value' => static::ON_AUTHORIZE_PAID_AFTER_SHIPMENT,
18+
'label' => __('On Authorize and set status Paid after shipment'),
19+
),
20+
array(
21+
'value' => static::ON_SHIPMENT,
22+
'label' => __('On Shipment'),
23+
)
24+
);
25+
}
26+
}

app/code/community/Mollie/Mpm/Model/Client/Orders.php

Lines changed: 103 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
<?php
22

33
use Mollie\Api\Resources\Payment;
4+
use Mollie_Mpm_Model_Adminhtml_System_Config_Source_InvoiceMoment as InvoiceMoment;
45

56
/**
67
* Copyright (c) 2012-2019, Mollie B.V.
@@ -200,13 +201,18 @@ public function processTransaction(Mage_Sales_Model_Order $order, $type = 'webho
200201
/**
201202
* Check if last payment was canceled, failed or expired and redirect customer to cart for retry.
202203
*/
203-
$lastPayment = isset($mollieOrder->_embedded->payments) ? end($mollieOrder->_embedded->payments) : null;
204-
$lastPaymentStatus = isset($lastPayment) ? $lastPayment->status : null;
204+
$lastPaymentStatus = $this->mollieHelper->getLastRelevantStatus($mollieOrder);
205205
if ($lastPaymentStatus == 'canceled' || $lastPaymentStatus == 'failed' || $lastPaymentStatus == 'expired') {
206206
$order->getPayment()->setAdditionalInformation('payment_status', $lastPaymentStatus)->save();
207207
$this->mollieHelper->registerCancellation($order, $status);
208208
$msg = array('success' => false, 'status' => $lastPaymentStatus, 'order_id' => $orderId, 'type' => $type);
209209
$this->mollieHelper->addTolog('success', $msg);
210+
211+
$methodCode = $this->mollieHelper->getMethodCode($order);
212+
if ($lastPaymentStatus != 'canceled' && ($methodCode == 'klarnapaylater' || $methodCode == 'klarnasliceit')) {
213+
throw new Mollie_Mpm_Exceptions_KlarnaException;
214+
}
215+
210216
return $msg;
211217
}
212218

@@ -246,16 +252,20 @@ public function processTransaction(Mage_Sales_Model_Order $order, $type = 'webho
246252
/**
247253
* Create pending invoice, as order has not been paid.
248254
*/
249-
/** @var Mage_Sales_Model_Service_Order $service */
250-
$invoice = $order->prepareInvoice();
251-
$invoice->setRequestedCaptureCase(Mage_Sales_Model_Order_Invoice::NOT_CAPTURE);
252-
$invoice->setTransactionId($transactionId);
253-
$invoice->register();
254-
255-
Mage::getModel('core/resource_transaction')
256-
->addObject($invoice)
257-
->addObject($invoice->getOrder())
258-
->save();
255+
if ($this->mollieHelper->isInvoiceMomentOnAuthorize($order)) {
256+
/** @var Mage_Sales_Model_Service_Order $service */
257+
$invoice = $order->prepareInvoice();
258+
$invoice->setRequestedCaptureCase(Mage_Sales_Model_Order_Invoice::CAPTURE_ONLINE);
259+
$invoice->setTransactionId($transactionId);
260+
$invoice->register();
261+
262+
$invoice->setState($this->mollieHelper->getInvoiceMomentPaidStatus($order));
263+
264+
Mage::getModel('core/resource_transaction')
265+
->addObject($invoice)
266+
->addObject($invoice->getOrder())
267+
->save();
268+
}
259269
}
260270

261271
$order->setState(Mage_Sales_Model_Order::STATE_PROCESSING)->save();
@@ -273,8 +283,9 @@ public function processTransaction(Mage_Sales_Model_Order $order, $type = 'webho
273283
}
274284

275285
/** @var Mage_Sales_Model_Order_Invoice $invoice */
276-
$invoice = $payment->getCreatedInvoice();
277-
$sendInvoice = $this->mollieHelper->sendInvoice($storeId);
286+
$invoice = isset($invoice) ? $invoice : $payment->getCreatedInvoice();
287+
$sendInvoice = $this->mollieHelper->sendInvoice($storeId) &&
288+
$this->mollieHelper->getInvoiceMoment($order) == \Mollie_Mpm_Model_Adminhtml_System_Config_Source_InvoiceMoment::ON_AUTHORIZE_PAID_BEFORE_SHIPMENT;
278289

279290
if (!$order->getEmailSent()) {
280291
try {
@@ -432,7 +443,6 @@ public function cancelOrder(Mage_Sales_Model_Order $order)
432443
public function createShipment(Mage_Sales_Model_Order_Shipment $shipment, Mage_Sales_Model_Order $order)
433444
{
434445
$shipAll = false;
435-
$orderId = $order->getId();
436446

437447
$transactionId = $order->getMollieTransactionId();
438448
if (empty($transactionId)) {
@@ -496,16 +506,32 @@ public function createShipment(Mage_Sales_Model_Order_Shipment $shipment, Mage_S
496506
* Check if Transactions needs to be captures (eg. Klarna methods)
497507
*/
498508
$payment = $order->getPayment();
509+
499510
/** @var Mage_Sales_Model_Order_Invoice $invoice */
500-
$invoice = $order->getInvoiceCollection()->getLastItem();
501-
if ($invoice && $invoice->getState() == 1) {
502-
$payment->registerCaptureNotification($order->getBaseGrandTotal(), true);
511+
$invoice = $this->createPartialInvoice($shipment, $transactionId);
512+
513+
/**
514+
* If there is no invoice created try to receive the last invoice.
515+
*/
516+
if (!$invoice) {
517+
$invoice = $order->getInvoiceCollection()->getLastItem();
518+
}
519+
520+
if ($invoice && $invoice->getState() == Mage_Sales_Model_Order_Invoice::STATE_OPEN) {
521+
$captureAmount = $this->getCaptureAmount($order, $invoice);
522+
$payment->setTransactionId($transactionId);
523+
$payment->registerCaptureNotification($captureAmount, true);
524+
503525
$order->save();
504526
$sendInvoice = $this->mollieHelper->sendInvoice($order->getStoreId());
505527
if ($invoice && !$invoice->getEmailSent() && $sendInvoice) {
506528
$invoice->setEmailSent(true)->sendEmail()->save();
507529
}
508530
}
531+
532+
if ($shipAll) {
533+
$this->markOrderAsCompleted($order);
534+
}
509535
} catch (\Exception $e) {
510536
$this->mollieHelper->addTolog('error', $e->getMessage());
511537
Mage::throwException($this->mollieHelper->__('Mollie API: %s', $e->getMessage()));
@@ -782,4 +808,63 @@ private function itemsAreShippable(\Mollie\Api\Resources\Order $mollieOrder, $or
782808
}
783809
return true;
784810
}
811+
812+
private function createPartialInvoice(Mage_Sales_Model_Order_Shipment $shipment, $transactionId)
813+
{
814+
$order = $shipment->getOrder();
815+
$payment = $order->getPayment();
816+
817+
if (
818+
!in_array($payment->getMethod(), array('mollie_klarnapaylater', 'mollie_klarnasliceit')) ||
819+
$this->mollieHelper->getInvoiceMoment($order) != 'shipment'
820+
) {
821+
return null;
822+
}
823+
824+
$quantities = [];
825+
/** @var Mage_Sales_Model_Order_Shipment_Item $item */
826+
foreach ($shipment->getAllItems() as $item) {
827+
$quantities[$item->getOrderItemId()] = $item->getQty();
828+
}
829+
830+
$invoice = $order->prepareInvoice($quantities);
831+
$invoice->setRequestedCaptureCase(Mage_Sales_Model_Order_Invoice::CAPTURE_ONLINE);
832+
$invoice->setTransactionId($transactionId);
833+
$invoice->register();
834+
835+
$invoice->setState(Mage_Sales_Model_Order_Invoice::STATE_PAID);
836+
$invoice->save();
837+
838+
$sendInvoice = $this->mollieHelper->sendInvoice($order->getStoreId());
839+
if ($invoice && !$invoice->getEmailSent() && $sendInvoice) {
840+
$invoice->setEmailSent(true)->sendEmail()->save();
841+
}
842+
843+
return $invoice;
844+
}
845+
846+
private function getCaptureAmount(Mage_Sales_Model_Order $order, Mage_Sales_Model_Order_Invoice $invoice = null)
847+
{
848+
if ($invoice) {
849+
return $invoice->getBaseGrandTotal();
850+
}
851+
852+
$payment = $order->getPayment();
853+
if ($invoice = $payment->getCreatedInvoice()) {
854+
return $invoice->getBaseGrandTotal();
855+
}
856+
857+
return $order->getBaseGrandTotal();
858+
}
859+
860+
private function markOrderAsCompleted(Mage_Sales_Model_Order $order)
861+
{
862+
$methodCode = $this->mollieHelper->getMethodCode($order);
863+
if ($methodCode != 'klarnapaylater' && $methodCode != 'klarnasliceit') {
864+
return;
865+
}
866+
867+
$order->addStatusToHistory(Mage_Sales_Model_Order::STATE_COMPLETE);
868+
$order->save();
869+
}
785870
}

app/code/community/Mollie/Mpm/Model/Method/Deprecated/Abstract.php

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,63 @@ class Mollie_Mpm_Model_Method_Deprecated_Abstract extends Mage_Payment_Model_Met
4040
protected $_canUseInternal = false;
4141
protected $_canUseCheckout = false;
4242
protected $_canUseForMultishipping = false;
43+
protected $_canRefund = true;
44+
protected $_canRefundInvoicePartial = true;
45+
46+
/**
47+
* Refund Pre-v5.x Orders.
48+
*
49+
* This function is restored to create online refunds for old orders.
50+
* See Mollie_Mpm_Model_Mollie for current implemenation.
51+
*
52+
* @param Varien_Object $payment
53+
* @param float $amount
54+
*
55+
* @return $this
56+
* @throws Mage_Core_Exception
57+
*/
58+
public function refund(Varien_Object $payment, $amount)
59+
{
60+
/** @var Mollie_Mpm_Model_Payments $payments */
61+
$payments = Mage::getModel('mpm/payments');
62+
63+
/** @var Mollie_Mpm_Helper_Data $helper */
64+
$helper = Mage::helper('mpm');
65+
66+
/** @var Mage_Sales_Model_Order $order */
67+
$order = $payment->getOrder();
68+
69+
$transactionId = $payments->getTransactionIdByOrderId($order->getId());
70+
71+
if (empty($transactionId)) {
72+
$msg = array('error' => true, 'msg' => $helper->__('Transaction ID not found'));
73+
$helper->addTolog('error', $msg);
74+
return $this;
75+
}
76+
77+
$apiKey = $helper->getApiKey($order->getStoreId());
78+
if (empty($apiKey)) {
79+
$msg = array('error' => true, 'msg' => $helper->__('Api key not found'));
80+
$helper->addTolog('error', $msg);
81+
return $this;
82+
}
83+
84+
try {
85+
$mollieApi = $helper->getMollieAPI($apiKey);
86+
$payment = $mollieApi->payments->get($transactionId);
87+
$payment->refund(
88+
array(
89+
"amount" => array(
90+
"currency" => $order->getOrderCurrencyCode(),
91+
"value" => $helper->formatCurrencyValue($amount, $order->getOrderCurrencyCode())
92+
)
93+
)
94+
);
95+
} catch (\Exception $e) {
96+
$helper->addTolog('error', $e->getMessage());
97+
Mage::throwException($helper->__('Error: not possible to create an online refund: %s', $e->getMessage()));
98+
}
99+
100+
return $this;
101+
}
43102
}

app/code/community/Mollie/Mpm/Model/Mollie.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,8 @@ public function startTransaction(Mage_Sales_Model_Order $order)
110110
if (self::RETRY_FLAG && $methodCode != 'klarnapaylater' && $methodCode != 'klarnasliceit') {
111111
$this->mollieHelper->addTolog('error', $e->getMessage());
112112
$transactionResult = $this->paymentsApi->startTransaction($order);
113+
} elseif ($methodCode == 'klarnapaylater' || $methodCode == 'klarnasliceit') {
114+
throw new Mollie_Mpm_Exceptions_KlarnaException($e->getMessage());
113115
} else {
114116
Mage::throwException($e->getMessage());
115117
}

0 commit comments

Comments
 (0)