killbill-aplcache

payment: populate null state machine values in DefaultAdminPaymentApi See

12/2/2016 5:03:38 PM

Details

diff --git a/payment/src/main/java/org/killbill/billing/payment/api/DefaultAdminPaymentApi.java b/payment/src/main/java/org/killbill/billing/payment/api/DefaultAdminPaymentApi.java
index 9058564..18f1feb 100644
--- a/payment/src/main/java/org/killbill/billing/payment/api/DefaultAdminPaymentApi.java
+++ b/payment/src/main/java/org/killbill/billing/payment/api/DefaultAdminPaymentApi.java
@@ -22,6 +22,7 @@ import javax.inject.Inject;
 
 import org.killbill.billing.callcontext.InternalCallContext;
 import org.killbill.billing.payment.core.PaymentTransactionInfoPluginConverter;
+import org.killbill.billing.payment.core.sm.PaymentStateMachineHelper;
 import org.killbill.billing.payment.dao.PaymentDao;
 import org.killbill.billing.util.callcontext.CallContext;
 import org.killbill.billing.util.callcontext.InternalCallContextFactory;
@@ -29,12 +30,17 @@ import org.killbill.billing.util.config.definition.PaymentConfig;
 
 public class DefaultAdminPaymentApi extends DefaultApiBase implements AdminPaymentApi {
 
+    private final PaymentStateMachineHelper paymentSMHelper;
     private final PaymentDao paymentDao;
     private final InternalCallContextFactory internalCallContextFactory;
 
     @Inject
-    public DefaultAdminPaymentApi(final PaymentConfig paymentConfig, final PaymentDao paymentDao, final InternalCallContextFactory internalCallContextFactory) {
+    public DefaultAdminPaymentApi(final PaymentConfig paymentConfig,
+                                  final PaymentStateMachineHelper paymentSMHelper,
+                                  final PaymentDao paymentDao,
+                                  final InternalCallContextFactory internalCallContextFactory) {
         super(paymentConfig, internalCallContextFactory);
+        this.paymentSMHelper = paymentSMHelper;
         this.paymentDao = paymentDao;
         this.internalCallContextFactory = internalCallContextFactory;
     }
@@ -42,19 +48,54 @@ public class DefaultAdminPaymentApi extends DefaultApiBase implements AdminPayme
     @Override
     public void fixPaymentTransactionState(final Payment payment,
                                            final PaymentTransaction paymentTransaction,
-                                           @Nullable final TransactionStatus transactionStatusMaybeNull,
-                                           @Nullable final String lastSuccessPaymentState,
-                                           final String currentPaymentStateName,
+                                           @Nullable final TransactionStatus transactionStatusOrNull,
+                                           @Nullable final String lastSuccessPaymentStateOrNull,
+                                           @Nullable final String currentPaymentStateNameOrNull,
                                            final Iterable<PluginProperty> properties,
                                            final CallContext callContext) throws PaymentApiException {
         final InternalCallContext internalCallContext = internalCallContextFactory.createInternalCallContext(payment.getAccountId(), callContext);
 
-        final TransactionStatus transactionStatus;
-        if (transactionStatusMaybeNull == null) {
+        TransactionStatus transactionStatus = transactionStatusOrNull;
+        if (transactionStatusOrNull == null) {
             checkNotNullParameter(paymentTransaction.getPaymentInfoPlugin(), "PaymentTransactionInfoPlugin");
             transactionStatus = PaymentTransactionInfoPluginConverter.toTransactionStatus(paymentTransaction.getPaymentInfoPlugin());
-        } else {
-            transactionStatus = transactionStatusMaybeNull;
+        }
+
+        String currentPaymentStateName = currentPaymentStateNameOrNull;
+        if (currentPaymentStateName == null) {
+            switch (transactionStatus) {
+                case PENDING:
+                    currentPaymentStateName = paymentSMHelper.getPendingStateForTransaction(paymentTransaction.getTransactionType());
+                    break;
+                case SUCCESS:
+                    currentPaymentStateName = paymentSMHelper.getSuccessfulStateForTransaction(paymentTransaction.getTransactionType());
+                    break;
+                case PAYMENT_FAILURE:
+                    currentPaymentStateName = paymentSMHelper.getFailureStateForTransaction(paymentTransaction.getTransactionType());
+                    break;
+                case PLUGIN_FAILURE:
+                case UNKNOWN:
+                default:
+                    currentPaymentStateName = paymentSMHelper.getErroredStateForTransaction(paymentTransaction.getTransactionType());
+                    break;
+            }
+        }
+
+        String lastSuccessPaymentState = lastSuccessPaymentStateOrNull;
+        if (lastSuccessPaymentState == null &&
+            // Verify we are not updating an older transaction (only the last one has an impact on lastSuccessPaymentState)
+            paymentTransaction.getId().equals(payment.getTransactions().get(payment.getTransactions().size() - 1).getId())) {
+            if (paymentSMHelper.isSuccessState(currentPaymentStateName)) {
+                lastSuccessPaymentState = currentPaymentStateName;
+            } else {
+                for (int i = payment.getTransactions().size() - 2; i >= 0; i--) {
+                    final PaymentTransaction transaction = payment.getTransactions().get(i);
+                    if (TransactionStatus.SUCCESS.equals(transaction.getTransactionStatus())) {
+                        lastSuccessPaymentState = paymentSMHelper.getSuccessfulStateForTransaction(transaction.getTransactionType());
+                        break;
+                    }
+                }
+            }
         }
 
         paymentDao.updatePaymentAndTransactionOnCompletion(payment.getAccountId(),
diff --git a/payment/src/test/java/org/killbill/billing/payment/api/TestDefaultAdminPaymentApi.java b/payment/src/test/java/org/killbill/billing/payment/api/TestDefaultAdminPaymentApi.java
index 03f6d8a..e710d8b 100644
--- a/payment/src/test/java/org/killbill/billing/payment/api/TestDefaultAdminPaymentApi.java
+++ b/payment/src/test/java/org/killbill/billing/payment/api/TestDefaultAdminPaymentApi.java
@@ -206,4 +206,98 @@ public class TestDefaultAdminPaymentApi extends PaymentTestSuiteWithEmbeddedDB {
         Assert.assertEquals(refreshedPaymentTransactionModelDao.getGatewayErrorCode(), "error-code");
         Assert.assertEquals(refreshedPaymentTransactionModelDao.getGatewayErrorMsg(), "error-msg");
     }
+
+    @Test(groups = "slow", description = "https://github.com/killbill/killbill-adyen-plugin/pull/60")
+    public void testFixPaymentTransactionStateRefundSuccessToRefundFailed() throws PaymentApiException {
+        final Payment payment = paymentApi.createPurchase(account,
+                                                          account.getPaymentMethodId(),
+                                                          null,
+                                                          BigDecimal.TEN,
+                                                          Currency.EUR,
+                                                          UUID.randomUUID().toString(),
+                                                          UUID.randomUUID().toString(),
+                                                          ImmutableList.<PluginProperty>of(),
+                                                          callContext);
+
+        final PaymentModelDao paymentModelDao = paymentDao.getPayment(payment.getId(), internalCallContext);
+        final PaymentTransactionModelDao paymentTransactionModelDao = paymentDao.getPaymentTransaction(payment.getTransactions().get(0).getId(), internalCallContext);
+        Assert.assertEquals(paymentModelDao.getStateName(), "PURCHASE_SUCCESS");
+        Assert.assertEquals(paymentModelDao.getLastSuccessStateName(), "PURCHASE_SUCCESS");
+        Assert.assertEquals(paymentTransactionModelDao.getTransactionStatus(), TransactionStatus.SUCCESS);
+
+        final Payment refund = paymentApi.createRefund(account,
+                                                       payment.getId(),
+                                                       payment.getPurchasedAmount(),
+                                                       payment.getCurrency(),
+                                                       UUID.randomUUID().toString(),
+                                                       ImmutableList.<PluginProperty>of(),
+                                                       callContext);
+
+        final PaymentModelDao paymentModelDao2 = paymentDao.getPayment(payment.getId(), internalCallContext);
+        final PaymentTransactionModelDao paymentTransactionModelDao2 = paymentDao.getPaymentTransaction(refund.getTransactions().get(1).getId(), internalCallContext);
+        Assert.assertEquals(paymentModelDao2.getStateName(), "REFUND_SUCCESS");
+        Assert.assertEquals(paymentModelDao2.getLastSuccessStateName(), "REFUND_SUCCESS");
+        Assert.assertEquals(paymentTransactionModelDao2.getTransactionStatus(), TransactionStatus.SUCCESS);
+
+        adminPaymentApi.fixPaymentTransactionState(refund,
+                                                   refund.getTransactions().get(1),
+                                                   TransactionStatus.PAYMENT_FAILURE,
+                                                   null, /* Let Kill Bill figure it out */
+                                                   null, /* Let Kill Bill figure it out */
+                                                   ImmutableList.<PluginProperty>of(),
+                                                   callContext);
+
+        final PaymentModelDao paymentModelDao3 = paymentDao.getPayment(payment.getId(), internalCallContext);
+        final PaymentTransactionModelDao paymentTransactionModelDao3 = paymentDao.getPaymentTransaction(refund.getTransactions().get(1).getId(), internalCallContext);
+        Assert.assertEquals(paymentModelDao3.getStateName(), "REFUND_FAILED");
+        Assert.assertEquals(paymentModelDao3.getLastSuccessStateName(), "PURCHASE_SUCCESS");
+        Assert.assertEquals(paymentTransactionModelDao3.getTransactionStatus(), TransactionStatus.PAYMENT_FAILURE);
+    }
+
+    @Test(groups = "slow", description = "https://github.com/killbill/killbill-adyen-plugin/pull/60")
+    public void testFixPaymentTransactionStateRefundFailedToRefundSuccess() throws PaymentApiException {
+        final Payment payment = paymentApi.createPurchase(account,
+                                                          account.getPaymentMethodId(),
+                                                          null,
+                                                          BigDecimal.TEN,
+                                                          Currency.EUR,
+                                                          UUID.randomUUID().toString(),
+                                                          UUID.randomUUID().toString(),
+                                                          ImmutableList.<PluginProperty>of(),
+                                                          callContext);
+
+        final PaymentModelDao paymentModelDao = paymentDao.getPayment(payment.getId(), internalCallContext);
+        final PaymentTransactionModelDao paymentTransactionModelDao = paymentDao.getPaymentTransaction(payment.getTransactions().get(0).getId(), internalCallContext);
+        Assert.assertEquals(paymentModelDao.getStateName(), "PURCHASE_SUCCESS");
+        Assert.assertEquals(paymentModelDao.getLastSuccessStateName(), "PURCHASE_SUCCESS");
+        Assert.assertEquals(paymentTransactionModelDao.getTransactionStatus(), TransactionStatus.SUCCESS);
+
+        final Payment refund = paymentApi.createRefund(account,
+                                                       payment.getId(),
+                                                       payment.getPurchasedAmount(),
+                                                       payment.getCurrency(),
+                                                       UUID.randomUUID().toString(),
+                                                       ImmutableList.<PluginProperty>of(new PluginProperty(MockPaymentProviderPlugin.PLUGIN_PROPERTY_PAYMENT_PLUGIN_STATUS_OVERRIDE, PaymentPluginStatus.ERROR.toString(), false)),
+                                                       callContext);
+
+        final PaymentModelDao paymentModelDao2 = paymentDao.getPayment(payment.getId(), internalCallContext);
+        final PaymentTransactionModelDao paymentTransactionModelDao2 = paymentDao.getPaymentTransaction(refund.getTransactions().get(1).getId(), internalCallContext);
+        Assert.assertEquals(paymentModelDao2.getStateName(), "REFUND_FAILED");
+        Assert.assertEquals(paymentModelDao2.getLastSuccessStateName(), "PURCHASE_SUCCESS");
+        Assert.assertEquals(paymentTransactionModelDao2.getTransactionStatus(), TransactionStatus.PAYMENT_FAILURE);
+
+        adminPaymentApi.fixPaymentTransactionState(refund,
+                                                   refund.getTransactions().get(1),
+                                                   TransactionStatus.SUCCESS,
+                                                   null, /* Let Kill Bill figure it out */
+                                                   null, /* Let Kill Bill figure it out */
+                                                   ImmutableList.<PluginProperty>of(),
+                                                   callContext);
+
+        final PaymentModelDao paymentModelDao3 = paymentDao.getPayment(payment.getId(), internalCallContext);
+        final PaymentTransactionModelDao paymentTransactionModelDao3 = paymentDao.getPaymentTransaction(refund.getTransactions().get(1).getId(), internalCallContext);
+        Assert.assertEquals(paymentModelDao3.getStateName(), "REFUND_SUCCESS");
+        Assert.assertEquals(paymentModelDao3.getLastSuccessStateName(), "REFUND_SUCCESS");
+        Assert.assertEquals(paymentTransactionModelDao3.getTransactionStatus(), TransactionStatus.SUCCESS);
+    }
 }