killbill-aplcache

#69 - Changed type and name of the new attribute to accept a List

6/30/2016 4:34:20 PM

Details

diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/InvoicePaymentJson.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/InvoicePaymentJson.java
index a30a99e..90d44b6 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/InvoicePaymentJson.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/InvoicePaymentJson.java
@@ -52,9 +52,9 @@ public class InvoicePaymentJson extends PaymentJson {
                               @JsonProperty("currency") final String currency,
                               @JsonProperty("paymentMethodId") final String paymentMethodId,
                               @JsonProperty("transactions") final List<? extends PaymentTransactionJson> transactions,
-                              @JsonProperty("nextScheduledPaymentAttempt") final PaymentAttempt nextScheduledPaymentAttempt,
+                              @JsonProperty("paymentAttempts") final List<PaymentAttempt> paymentAttempts,
                               @JsonProperty("auditLogs") @Nullable final List<AuditLogJson> auditLogs) {
-        super(accountId, paymentId, paymentNumber, paymentExternalKey, authAmount, capturedAmount, purchasedAmount, refundedAmount, creditedAmount, currency, paymentMethodId, transactions, nextScheduledPaymentAttempt, auditLogs);
+        super(accountId, paymentId, paymentNumber, paymentExternalKey, authAmount, capturedAmount, purchasedAmount, refundedAmount, creditedAmount, currency, paymentMethodId, transactions, paymentAttempts, auditLogs);
         this.targetInvoiceId = targetInvoiceId;
     }
 
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/PaymentJson.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/PaymentJson.java
index 0a416e9..66b3e32 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/PaymentJson.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/PaymentJson.java
@@ -51,7 +51,7 @@ public class PaymentJson extends JsonBase {
     @ApiModelProperty(dataType = "java.util.UUID")
     private final String paymentMethodId;
     private final List<? extends PaymentTransactionJson> transactions;
-    private final PaymentAttempt nextScheduledPaymentAttempt;
+    private final List<PaymentAttempt> paymentAttempts;
 
     @JsonCreator
     public PaymentJson(@JsonProperty("accountId") final String accountId,
@@ -66,7 +66,7 @@ public class PaymentJson extends JsonBase {
                        @JsonProperty("currency") final String currency,
                        @JsonProperty("paymentMethodId") final String paymentMethodId,
                        @JsonProperty("transactions") final List<? extends PaymentTransactionJson> transactions,
-                       @JsonProperty("nextScheduledPaymentAttempt") final PaymentAttempt nextScheduledPaymentAttempt,
+                       @JsonProperty("paymentAttempts") final List<PaymentAttempt> paymentAttempts,
                        @JsonProperty("auditLogs") @Nullable final List<AuditLogJson> auditLogs) {
         super(auditLogs);
         this.accountId = accountId;
@@ -81,7 +81,7 @@ public class PaymentJson extends JsonBase {
         this.currency = currency;
         this.paymentMethodId = paymentMethodId;
         this.transactions = transactions;
-        this.nextScheduledPaymentAttempt = nextScheduledPaymentAttempt;
+        this.paymentAttempts = paymentAttempts;
     }
 
     public PaymentJson(final Payment dp, @Nullable final AccountAuditLogs accountAuditLogs) {
@@ -97,7 +97,7 @@ public class PaymentJson extends JsonBase {
              dp.getCurrency() != null ? dp.getCurrency().toString() : null,
              dp.getPaymentMethodId() != null ? dp.getPaymentMethodId().toString() : null,
              getTransactions(dp.getTransactions(), dp.getExternalKey(), accountAuditLogs),
-             dp.getNextScheduledPaymentAttempt(),
+             dp.getPaymentAttempts(),
              toAuditLogJson(accountAuditLogs == null ? null : accountAuditLogs.getAuditLogsForPayment(dp.getId())));
     }
 
@@ -161,7 +161,7 @@ public class PaymentJson extends JsonBase {
         return transactions;
     }
 
-    public PaymentAttempt getNextScheduledPaymentAttempt() { return nextScheduledPaymentAttempt; }
+    public List<PaymentAttempt> getPaymentAttempts() { return paymentAttempts; }
 
     @Override
     public String toString() {
@@ -178,7 +178,7 @@ public class PaymentJson extends JsonBase {
         sb.append(", currency='").append(currency).append('\'');
         sb.append(", paymentMethodId='").append(paymentMethodId).append('\'');
         sb.append(", transactions=").append(transactions);
-        sb.append(", nextScheduledPaymentAttempt=").append(nextScheduledPaymentAttempt);
+        sb.append(", paymentAttempts=").append(paymentAttempts);
         sb.append('}');
         return sb.toString();
     }
@@ -230,7 +230,7 @@ public class PaymentJson extends JsonBase {
         if (transactions != null ? !transactions.equals(that.transactions) : that.transactions != null) {
             return false;
         }
-        if (nextScheduledPaymentAttempt != null ? !nextScheduledPaymentAttempt.equals(that.nextScheduledPaymentAttempt) : that.nextScheduledPaymentAttempt!= null) {
+        if (paymentAttempts != null ? !paymentAttempts.equals(that.paymentAttempts) : that.paymentAttempts!= null) {
             return false;
         }
 
@@ -251,7 +251,7 @@ public class PaymentJson extends JsonBase {
         result = 31 * result + (currency != null ? currency.hashCode() : 0);
         result = 31 * result + (paymentMethodId != null ? paymentMethodId.hashCode() : 0);
         result = 31 * result + (transactions != null ? transactions.hashCode() : 0);
-        result = 31 * result + (nextScheduledPaymentAttempt != null ? nextScheduledPaymentAttempt.hashCode() : 0);
+        result = 31 * result + (paymentAttempts != null ? paymentAttempts.hashCode() : 0);
         return result;
     }
 }
diff --git a/payment/src/main/java/org/killbill/billing/payment/api/DefaultPayment.java b/payment/src/main/java/org/killbill/billing/payment/api/DefaultPayment.java
index f2b9168..0751cc9 100644
--- a/payment/src/main/java/org/killbill/billing/payment/api/DefaultPayment.java
+++ b/payment/src/main/java/org/killbill/billing/payment/api/DefaultPayment.java
@@ -52,21 +52,21 @@ public class DefaultPayment extends EntityBase implements Payment {
 
     private final Currency currency;
     private final List<PaymentTransaction> transactions;
-    private final PaymentAttempt nextScheduledPaymentAttempt;
+    private final List<PaymentAttempt> paymentAttempts;
 
     public DefaultPayment(final UUID id, @Nullable final DateTime createdDate, @Nullable final DateTime updatedDate, final UUID accountId,
                           final UUID paymentMethodId,
                           final Integer paymentNumber,
                           final String externalKey,
                           final List<PaymentTransaction> transactions,
-                          @Nullable final PaymentAttempt nextScheduledPaymentAttempt) {
+                          final List<PaymentAttempt> paymentAttempts) {
         super(id, createdDate, updatedDate);
         this.accountId = accountId;
         this.paymentMethodId = paymentMethodId;
         this.paymentNumber = paymentNumber;
         this.externalKey = externalKey;
         this.transactions = transactions;
-        this.nextScheduledPaymentAttempt = nextScheduledPaymentAttempt;
+        this.paymentAttempts = paymentAttempts;
 
         final Collection<PaymentTransaction> voidedTransactions = new LinkedList<PaymentTransaction>();
         final Collection<PaymentTransaction> nonVoidedTransactions = new LinkedList<PaymentTransaction>();
@@ -348,7 +348,7 @@ public class DefaultPayment extends EntityBase implements Payment {
     }
 
     @Override
-    public PaymentAttempt getNextScheduledPaymentAttempt() { return nextScheduledPaymentAttempt; }
+    public List<PaymentAttempt> getPaymentAttempts() { return paymentAttempts; }
 
     @Override
     public String toString() {
@@ -363,7 +363,7 @@ public class DefaultPayment extends EntityBase implements Payment {
         sb.append(", refundAmount=").append(refundAmount);
         sb.append(", currency=").append(currency);
         sb.append(", transactions=").append(transactions);
-        sb.append(", nextScheduledPaymentAttempt=").append(nextScheduledPaymentAttempt);
+        sb.append(", paymentAttempts=").append(paymentAttempts);
         sb.append('}');
         return sb.toString();
     }
@@ -412,7 +412,7 @@ public class DefaultPayment extends EntityBase implements Payment {
         if (transactions != null ? !transactions.equals(that.transactions) : that.transactions != null) {
             return false;
         }
-        if (nextScheduledPaymentAttempt != null ? !nextScheduledPaymentAttempt.equals(that.nextScheduledPaymentAttempt) : that.nextScheduledPaymentAttempt!= null) {
+        if (paymentAttempts != null ? !paymentAttempts.equals(that.paymentAttempts) : that.paymentAttempts != null) {
             return false;
         }
 
@@ -432,7 +432,7 @@ public class DefaultPayment extends EntityBase implements Payment {
         result = 31 * result + (refundAmount != null ? refundAmount.hashCode() : 0);
         result = 31 * result + (currency != null ? currency.hashCode() : 0);
         result = 31 * result + (transactions != null ? transactions.hashCode() : 0);
-        result = 31 * result + (nextScheduledPaymentAttempt != null ? nextScheduledPaymentAttempt.hashCode() : 0);
+        result = 31 * result + (paymentAttempts != null ? paymentAttempts.hashCode() : 0);
         return result;
     }
 }
diff --git a/payment/src/main/java/org/killbill/billing/payment/api/DefaultPaymentAttempt.java b/payment/src/main/java/org/killbill/billing/payment/api/DefaultPaymentAttempt.java
index efdc63b..03c5fa1 100644
--- a/payment/src/main/java/org/killbill/billing/payment/api/DefaultPaymentAttempt.java
+++ b/payment/src/main/java/org/killbill/billing/payment/api/DefaultPaymentAttempt.java
@@ -17,46 +17,91 @@
 package org.killbill.billing.payment.api;
 
 import java.math.BigDecimal;
+import java.util.Arrays;
 import java.util.UUID;
 
 import org.joda.time.DateTime;
 import org.killbill.billing.catalog.api.Currency;
 import org.killbill.billing.entity.EntityBase;
+import org.killbill.billing.payment.dao.PaymentAttemptModelDao;
 
 public class DefaultPaymentAttempt extends EntityBase implements PaymentAttempt {
 
-    private final UUID paymentId;
+    private final UUID accountId;
+    private final UUID paymentMethodId;
+    private final String paymentExternalKey;
+    private final UUID transactionId;
+    private final String transactionExternalKey;
     private final TransactionType transactionType;
-    private final DateTime effectiveDate;
-    private final TransactionStatus status;
+    private final String stateName;
     private final BigDecimal amount;
     private final Currency currency;
-
-    public DefaultPaymentAttempt(final UUID id, final UUID paymentId,
-                                 final TransactionType transactionType, final DateTime effectiveDate,
-                                 final TransactionStatus status, final BigDecimal amount, final Currency currency) {
-        super(id);
-        this.paymentId = paymentId;
+    private final String pluginName;
+    private final byte[] pluginProperties;
+
+    public DefaultPaymentAttempt(final UUID accountId, final UUID paymentMethodId, final UUID id, final DateTime createdDate, final DateTime updatedDate,
+                                 final String paymentExternalKey, final UUID transactionId, final String transactionExternalKey, final TransactionType transactionType,
+                                 final String stateName, final BigDecimal amount, final Currency currency, final String pluginName, final byte[] pluginProperties) {
+        super(id, createdDate, updatedDate);
+        this.accountId = accountId;
+        this.paymentMethodId = paymentMethodId;
+        this.paymentExternalKey = paymentExternalKey;
+        this.transactionId = transactionId;
+        this.transactionExternalKey = transactionExternalKey;
         this.transactionType = transactionType;
-        this.effectiveDate = effectiveDate;
-        this.status = status;
+        this.stateName = stateName;
         this.amount = amount;
         this.currency = currency;
+        this.pluginName = pluginName;
+        this.pluginProperties = pluginProperties;
+    }
+
+    public DefaultPaymentAttempt(final PaymentAttemptModelDao paymentAttemptModelDao) {
+        this(paymentAttemptModelDao.getAccountId(),
+            paymentAttemptModelDao.getPaymentMethodId(),
+            paymentAttemptModelDao.getId(),
+            paymentAttemptModelDao.getCreatedDate(),
+            paymentAttemptModelDao.getUpdatedDate(),
+            paymentAttemptModelDao.getPaymentExternalKey(),
+            paymentAttemptModelDao.getTransactionId(),
+            paymentAttemptModelDao.getTransactionExternalKey(),
+            paymentAttemptModelDao.getTransactionType(),
+            paymentAttemptModelDao.getStateName(),
+            paymentAttemptModelDao.getAmount(),
+            paymentAttemptModelDao.getCurrency(),
+            paymentAttemptModelDao.getPluginName(),
+            paymentAttemptModelDao.getPluginProperties()
+        );
     }
 
     @Override
-    public UUID getPaymentId() {
-        return paymentId;
+    public UUID getAccountId() {
+        return accountId;
     }
 
     @Override
-    public TransactionType getTransactionType() {
-        return transactionType;
+    public UUID getPaymentMethodId() {
+        return paymentMethodId;
+    }
+
+    @Override
+    public String getPaymentExternalKey() {
+        return paymentExternalKey;
     }
 
     @Override
-    public DateTime getEffectiveDate() {
-        return effectiveDate;
+    public UUID getTransactionId() {
+        return transactionId;
+    }
+
+    @Override
+    public String getTransactionExternalKey() {
+        return transactionExternalKey;
+    }
+
+    @Override
+    public TransactionType getTransactionType() {
+        return transactionType;
     }
 
     @Override
@@ -70,21 +115,35 @@ public class DefaultPaymentAttempt extends EntityBase implements PaymentAttempt 
     }
 
     @Override
-    public TransactionStatus getTransactionStatus() {
-        return status;
+    public String getPluginName() {
+        return pluginName;
+    }
+
+    @Override
+    public byte[] getPluginProperties() {
+        return pluginProperties;
+    }
+
+    @Override
+    public String getStateName() {
+        return stateName;
     }
 
     @Override
     public String toString() {
-        final StringBuilder sb = new StringBuilder("DefaultPaymentTransaction{");
-        sb.append("paymentId=").append(paymentId);
-        sb.append(", transactionType=").append(transactionType);
-        sb.append(", effectiveDate=").append(effectiveDate);
-        sb.append(", status=").append(status);
-        sb.append(", amount=").append(amount);
-        sb.append(", currency=").append(currency);
-        sb.append('}');
-        return sb.toString();
+        return "DefaultPaymentAttempt{" +
+               "accountId=" + accountId +
+               ", paymentMethodId=" + paymentMethodId +
+               ", paymentExternalKey='" + paymentExternalKey + '\'' +
+               ", transactionId=" + transactionId +
+               ", transactionExternalKey='" + transactionExternalKey + '\'' +
+               ", transactionType=" + transactionType +
+               ", stateName=" + stateName +
+               ", amount=" + amount +
+               ", currency=" + currency +
+               ", pluginName='" + pluginName + '\'' +
+               ", pluginProperties=" + Arrays.toString(pluginProperties) +
+               '}';
     }
 
     @Override
@@ -101,37 +160,54 @@ public class DefaultPaymentAttempt extends EntityBase implements PaymentAttempt 
 
         final DefaultPaymentAttempt that = (DefaultPaymentAttempt) o;
 
-        if (amount != null ? amount.compareTo(that.amount) != 0 : that.amount != null) {
+        if (accountId != null ? !accountId.equals(that.accountId) : that.accountId != null) {
             return false;
         }
-        if (currency != that.currency) {
+        if (paymentMethodId != null ? !paymentMethodId.equals(that.paymentMethodId) : that.paymentMethodId != null) {
             return false;
         }
-        if (paymentId != null ? !paymentId.equals(that.paymentId) : that.paymentId != null) {
+        if (paymentExternalKey != null ? !paymentExternalKey.equals(that.paymentExternalKey) : that.paymentExternalKey != null) {
             return false;
         }
-        if (effectiveDate != null ? effectiveDate.compareTo(that.effectiveDate) != 0 : that.effectiveDate != null) {
+        if (transactionId != null ? !transactionId.equals(that.transactionId) : that.transactionId != null) {
             return false;
         }
-        if (status != that.status) {
+        if (transactionExternalKey != null ? !transactionExternalKey.equals(that.transactionExternalKey) : that.transactionExternalKey != null) {
             return false;
         }
         if (transactionType != that.transactionType) {
             return false;
         }
+        if (stateName != that.stateName) {
+            return false;
+        }
+        if (amount != null ? !amount.equals(that.amount) : that.amount != null) {
+            return false;
+        }
+        if (currency != that.currency) {
+            return false;
+        }
+        if (pluginName != null ? !pluginName.equals(that.pluginName) : that.pluginName != null) {
+            return false;
+        }
+        return Arrays.equals(pluginProperties, that.pluginProperties);
 
-        return true;
     }
 
     @Override
     public int hashCode() {
         int result = super.hashCode();
-        result = 31 * result + (paymentId != null ? paymentId.hashCode() : 0);
+        result = 31 * result + (accountId != null ? accountId.hashCode() : 0);
+        result = 31 * result + (paymentMethodId != null ? paymentMethodId.hashCode() : 0);
+        result = 31 * result + (paymentExternalKey != null ? paymentExternalKey.hashCode() : 0);
+        result = 31 * result + (transactionId != null ? transactionId.hashCode() : 0);
+        result = 31 * result + (transactionExternalKey != null ? transactionExternalKey.hashCode() : 0);
         result = 31 * result + (transactionType != null ? transactionType.hashCode() : 0);
-        result = 31 * result + (effectiveDate != null ? effectiveDate.hashCode() : 0);
-        result = 31 * result + (status != null ? status.hashCode() : 0);
+        result = 31 * result + (stateName != null ? stateName.hashCode() : 0);
         result = 31 * result + (amount != null ? amount.hashCode() : 0);
         result = 31 * result + (currency != null ? currency.hashCode() : 0);
+        result = 31 * result + (pluginName != null ? pluginName.hashCode() : 0);
+        result = 31 * result + Arrays.hashCode(pluginProperties);
         return result;
     }
 }
diff --git a/payment/src/main/java/org/killbill/billing/payment/core/PaymentProcessor.java b/payment/src/main/java/org/killbill/billing/payment/core/PaymentProcessor.java
index 812fa29..6ad704f 100644
--- a/payment/src/main/java/org/killbill/billing/payment/core/PaymentProcessor.java
+++ b/payment/src/main/java/org/killbill/billing/payment/core/PaymentProcessor.java
@@ -19,6 +19,7 @@
 package org.killbill.billing.payment.core;
 
 import java.math.BigDecimal;
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Comparator;
 import java.util.HashMap;
@@ -31,7 +32,6 @@ import java.util.UUID;
 import javax.annotation.Nullable;
 import javax.inject.Inject;
 
-import org.joda.time.DateTime;
 import org.killbill.automaton.OperationResult;
 import org.killbill.billing.ErrorCode;
 import org.killbill.billing.account.api.Account;
@@ -53,12 +53,15 @@ import org.killbill.billing.payment.api.TransactionStatus;
 import org.killbill.billing.payment.api.TransactionType;
 import org.killbill.billing.payment.core.janitor.IncompletePaymentTransactionTask;
 import org.killbill.billing.payment.core.sm.PaymentAutomatonRunner;
+import org.killbill.billing.payment.dao.PaymentAttemptModelDao;
 import org.killbill.billing.payment.dao.PaymentDao;
 import org.killbill.billing.payment.dao.PaymentModelDao;
 import org.killbill.billing.payment.dao.PaymentTransactionModelDao;
+import org.killbill.billing.payment.glue.DefaultPaymentService;
 import org.killbill.billing.payment.plugin.api.PaymentPluginApi;
 import org.killbill.billing.payment.plugin.api.PaymentPluginApiException;
 import org.killbill.billing.payment.plugin.api.PaymentTransactionInfoPlugin;
+import org.killbill.billing.payment.retry.PaymentRetryNotificationKey;
 import org.killbill.billing.tag.TagInternalApi;
 import org.killbill.billing.util.callcontext.CallContext;
 import org.killbill.billing.util.callcontext.InternalCallContextFactory;
@@ -70,6 +73,11 @@ import org.killbill.billing.util.entity.dao.DefaultPaginationHelper.EntityPagina
 import org.killbill.billing.util.entity.dao.DefaultPaginationHelper.SourcePaginationBuilder;
 import org.killbill.clock.Clock;
 import org.killbill.commons.locker.GlobalLocker;
+import org.killbill.notificationq.api.NotificationEvent;
+import org.killbill.notificationq.api.NotificationEventWithMetadata;
+import org.killbill.notificationq.api.NotificationQueue;
+import org.killbill.notificationq.api.NotificationQueueService;
+import org.killbill.notificationq.api.NotificationQueueService.NoSuchNotificationQueue;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -92,6 +100,7 @@ public class PaymentProcessor extends ProcessorBase {
     private final PaymentAutomatonRunner paymentAutomatonRunner;
     private final IncompletePaymentTransactionTask incompletePaymentTransactionTask;
     private final PaymentConfig paymentConfig;
+    private final NotificationQueueService notificationQueueService;
 
     private static final Logger log = LoggerFactory.getLogger(PaymentProcessor.class);
 
@@ -106,11 +115,13 @@ public class PaymentProcessor extends ProcessorBase {
                             final PaymentAutomatonRunner paymentAutomatonRunner,
                             final IncompletePaymentTransactionTask incompletePaymentTransactionTask,
                             final PaymentConfig paymentConfig,
+                            final NotificationQueueService notificationQueueService,
                             final Clock clock) {
         super(pluginRegistry, accountUserApi, paymentDao, tagUserApi, locker, internalCallContextFactory, invoiceApi, clock);
         this.paymentAutomatonRunner = paymentAutomatonRunner;
         this.incompletePaymentTransactionTask = incompletePaymentTransactionTask;
         this.paymentConfig = paymentConfig;
+        this.notificationQueueService = notificationQueueService;
     }
 
     public Payment createAuthorization(final boolean isApiPayment, @Nullable final UUID attemptId, final Account account, @Nullable final UUID paymentMethodId, @Nullable final UUID paymentId, final BigDecimal amount, final Currency currency,
@@ -472,53 +483,53 @@ public class PaymentProcessor extends ProcessorBase {
                                   curPaymentModelDao.getPaymentNumber(),
                                   curPaymentModelDao.getExternalKey(),
                                   sortedTransactions,
-                                  (withAttempts && !sortedTransactions.isEmpty()) ? getNextRetryDateForFailedPayment(sortedTransactions) : null
+                                  (withAttempts && !sortedTransactions.isEmpty()) ?
+                                  getPaymentAttempts(sortedTransactions,
+                                                     paymentDao.getPaymentAttempts(curPaymentModelDao.getExternalKey(), internalTenantContext),
+                                                     internalTenantContext) : null
                                   );
     }
 
-    private PaymentAttempt getNextRetryDateForFailedPayment(final List<PaymentTransaction> purchasedTransactions) {
-        DateTime nextDateTime = null;
-        final List<Integer> retryDays = paymentConfig.getPaymentFailureRetryDays();
-        final int attemptsInState = getNumberAttemptsInState(purchasedTransactions, TransactionStatus.PAYMENT_FAILURE);
-        final int retryCount = (attemptsInState - 1) >= 0 ? (attemptsInState - 1) : 0;
-        if (retryCount < retryDays.size()) {
-            final int retryInDays;
-            final DateTime nextRetryDate = clock.getUTCNow();
-            try {
-                retryInDays = retryDays.get(retryCount);
-                nextDateTime = nextRetryDate.plusDays(retryInDays);
-                log.debug("Next retryDate={}, retryInDays={}, retryCount={}, now={}", nextDateTime, retryInDays, retryCount, clock.getUTCNow());
-            } catch (final NumberFormatException ex) {
-                log.error("Could not get retry day for retry count {}", retryCount);
-            }
-        }
-        PaymentTransaction lastAttempt = purchasedTransactions.get(purchasedTransactions.size() - 1);
-        return new DefaultPaymentAttempt(
-                UUID.randomUUID(),
-                lastAttempt.getPaymentId(),
-                lastAttempt.getTransactionType(),
-                nextDateTime,
-                TransactionStatus.SCHEDULED,
-                lastAttempt.getAmount(),
-                lastAttempt.getCurrency()
-        );
-    }
+    private List<PaymentAttempt> getPaymentAttempts(final List<PaymentTransaction> purchasedTransactions,
+                                                    final List<PaymentAttemptModelDao> paymentAttempts,
+                                                    final InternalTenantContext internalTenantContext) {
+
+        List<PaymentAttempt> result = new ArrayList<PaymentAttempt>();
 
-    private int getNumberAttemptsInState(final Collection<PaymentTransaction> allTransactions, final TransactionStatus... statuses) {
-        if (allTransactions == null || allTransactions.size() == 0) {
-            return 0;
+        // Add Past Payment Attempts
+        for (PaymentAttemptModelDao pastPaymentAttempt : paymentAttempts) {
+            DefaultPaymentAttempt paymentAttempt = new DefaultPaymentAttempt(pastPaymentAttempt);
+            result.add(paymentAttempt);
         }
-        return Collections2.filter(allTransactions, new Predicate<PaymentTransaction>() {
-            @Override
-            public boolean apply(final PaymentTransaction input) {
-                for (final TransactionStatus cur : statuses) {
-                    if (input.getTransactionStatus() == cur) {
-                        return true;
-                    }
-                }
-                return false;
+
+        // Get Future Payment Attempts from Notification Queue and add them to the list
+        try {
+            final NotificationQueue retryQueue = notificationQueueService.getNotificationQueue(DefaultPaymentService.SERVICE_NAME, "retry");
+            final List<NotificationEventWithMetadata<NotificationEvent>> notificationEventWithMetadatas =
+                    retryQueue.getFutureNotificationForSearchKeys(internalTenantContext.getAccountRecordId(), internalTenantContext.getTenantRecordId());
+
+            for (NotificationEventWithMetadata<NotificationEvent> notificationEvent : notificationEventWithMetadatas) {
+                DefaultPaymentAttempt futurePaymentAttempt = new DefaultPaymentAttempt(
+                        null, //accountId,
+                        null, //paymentMethodId,
+                        ((PaymentRetryNotificationKey) notificationEvent.getEvent()).getAttemptId(), //id,
+                        notificationEvent.getEffectiveDate(), //createdDate,
+                        notificationEvent.getEffectiveDate(), //updatedDate,
+                        null, //paymentExternalKey,
+                        null, //transactionId,
+                        null, //transactionExternalKey,
+                        null, //transactionType,
+                        "SCHEDULED", //stateName,
+                        null, //amount,
+                        null, //currency,
+                        ((PaymentRetryNotificationKey) notificationEvent.getEvent()).getPaymentControlPluginNames().get(0), //pluginName,
+                        null);//pluginProperties
+                result.add(futurePaymentAttempt);
             }
-        }).size();
+        } catch (NoSuchNotificationQueue noSuchNotificationQueue) {
+            log.error("ERROR Loading Notification Queue - " + noSuchNotificationQueue.getMessage());
+        }
+        return result;
     }
 
     private PaymentTransactionInfoPlugin findPaymentTransactionInfoPlugin(final PaymentTransactionModelDao paymentTransactionModelDao, @Nullable final Iterable<PaymentTransactionInfoPlugin> pluginTransactions) {