killbill-memoizeit

Details

diff --git a/api/src/main/java/com/ning/billing/invoice/api/InvoicePaymentApi.java b/api/src/main/java/com/ning/billing/invoice/api/InvoicePaymentApi.java
index bde12a9..8240931 100644
--- a/api/src/main/java/com/ning/billing/invoice/api/InvoicePaymentApi.java
+++ b/api/src/main/java/com/ning/billing/invoice/api/InvoicePaymentApi.java
@@ -24,9 +24,9 @@ import java.util.UUID;
 import org.joda.time.DateTime;
 
 public interface InvoicePaymentApi {
-    public void paymentSuccessful(UUID invoiceId, BigDecimal amount, Currency currency, UUID paymentId, DateTime paymentAttemptDate);
+    public void paymentSuccessful(UUID invoiceId, BigDecimal amount, Currency currency, UUID paymentAttemptId, DateTime paymentAttemptDate);
 
-    public void paymentFailed(UUID invoiceId, UUID paymentId, DateTime paymentAttemptDate);
+    public void paymentFailed(UUID invoiceId, UUID paymentAttemptId, DateTime paymentAttemptDate);
 
     public List<Invoice> getInvoicesByAccount(UUID accountId);
 
diff --git a/api/src/main/java/com/ning/billing/payment/api/PaymentInfo.java b/api/src/main/java/com/ning/billing/payment/api/PaymentInfo.java
index d19afe7..897ba89 100644
--- a/api/src/main/java/com/ning/billing/payment/api/PaymentInfo.java
+++ b/api/src/main/java/com/ning/billing/payment/api/PaymentInfo.java
@@ -26,6 +26,113 @@ import com.google.common.base.Objects;
 import com.ning.billing.util.eventbus.EventBusNotification;
 
 public class PaymentInfo implements EventBusNotification {
+    private final String id;
+    private final BigDecimal amount;
+    private final BigDecimal refundAmount;
+    private final BigDecimal appliedCreditBalanceAmount;
+    private final String paymentNumber;
+    private final String bankIdentificationNumber;
+    private final String status;
+    private final String type;
+    private final String referenceId;
+    private final DateTime effectiveDate;
+    private final DateTime createdDate;
+    private final DateTime updatedDate;
+
+    public PaymentInfo(PaymentInfo src) {
+        this.id = src.id;
+        this.amount = src.amount;
+        this.refundAmount = src.refundAmount;
+        this.appliedCreditBalanceAmount = src.appliedCreditBalanceAmount;
+        this.paymentNumber = src.paymentNumber;
+        this.bankIdentificationNumber = src.bankIdentificationNumber;
+        this.status = src.status;
+        this.type = src.type;
+        this.referenceId = src.referenceId;
+        this.effectiveDate = src.effectiveDate;
+        this.createdDate = src.createdDate;
+        this.updatedDate = src.updatedDate;
+    }
+
+    @JsonCreator
+    public PaymentInfo(@JsonProperty("id") String id,
+                       @JsonProperty("amount") BigDecimal amount,
+                       @JsonProperty("appliedCreditBalanceAmount") BigDecimal appliedCreditBalanceAmount,
+                       @JsonProperty("bankIdentificationNumber") String bankIdentificationNumber,
+                       @JsonProperty("paymentNumber") String paymentNumber,
+                       @JsonProperty("refundAmount") BigDecimal refundAmount,
+                       @JsonProperty("status") String status,
+                       @JsonProperty("type") String type,
+                       @JsonProperty("referenceId") String referenceId,
+                       @JsonProperty("effectiveDate") DateTime effectiveDate,
+                       @JsonProperty("createdDate") DateTime createdDate,
+                       @JsonProperty("updatedDate") DateTime updatedDate) {
+        this.id = id;
+        this.amount = amount;
+        this.appliedCreditBalanceAmount = appliedCreditBalanceAmount;
+        this.bankIdentificationNumber = bankIdentificationNumber;
+        this.createdDate = createdDate;
+        this.effectiveDate = effectiveDate;
+        this.paymentNumber = paymentNumber;
+        this.referenceId = referenceId;
+        this.refundAmount = refundAmount;
+        this.status = status;
+        this.type = type;
+        this.updatedDate = updatedDate;
+    }
+
+    public Builder cloner() {
+        return new Builder(this);
+    }
+
+    public String getId() {
+        return id;
+    }
+
+    public BigDecimal getAmount() {
+        return amount;
+    }
+
+    public BigDecimal getAppliedCreditBalanceAmount() {
+        return appliedCreditBalanceAmount;
+    }
+
+    public String getBankIdentificationNumber() {
+        return bankIdentificationNumber;
+    }
+
+    public DateTime getCreatedDate() {
+        return createdDate;
+    }
+
+    public DateTime getEffectiveDate() {
+        return effectiveDate;
+    }
+
+    public String getPaymentNumber() {
+        return paymentNumber;
+    }
+
+    public String getReferenceId() {
+        return referenceId;
+    }
+
+    public BigDecimal getRefundAmount() {
+        return refundAmount;
+    }
+
+    public String getStatus() {
+        return status;
+    }
+
+    public String getType() {
+        return type;
+    }
+
+    public DateTime getUpdatedDate() {
+        return updatedDate;
+    }
+
     public static class Builder {
         private String id;
         private BigDecimal amount;
@@ -134,113 +241,6 @@ public class PaymentInfo implements EventBusNotification {
         }
     }
 
-    private final String id;
-    private final BigDecimal amount;
-    private final BigDecimal refundAmount;
-    private final BigDecimal appliedCreditBalanceAmount;
-    private final String paymentNumber;
-    private final String bankIdentificationNumber;
-    private final String status;
-    private final String type;
-    private final String referenceId;
-    private final DateTime effectiveDate;
-    private final DateTime createdDate;
-    private final DateTime updatedDate;
-
-    public PaymentInfo(PaymentInfo src) {
-        this.id = src.id;
-        this.amount = src.amount;
-        this.refundAmount = src.refundAmount;
-        this.appliedCreditBalanceAmount = src.appliedCreditBalanceAmount;
-        this.paymentNumber = src.paymentNumber;
-        this.bankIdentificationNumber = src.bankIdentificationNumber;
-        this.status = src.status;
-        this.type = src.type;
-        this.referenceId = src.referenceId;
-        this.effectiveDate = src.effectiveDate;
-        this.createdDate = src.createdDate;
-        this.updatedDate = src.updatedDate;
-    }
-
-    @JsonCreator
-    public PaymentInfo(@JsonProperty("id") String id,
-                       @JsonProperty("amount") BigDecimal amount,
-                       @JsonProperty("appliedCreditBalanceAmount") BigDecimal appliedCreditBalanceAmount,
-                       @JsonProperty("bankIdentificationNumber") String bankIdentificationNumber,
-                       @JsonProperty("paymentNumber") String paymentNumber,
-                       @JsonProperty("refundAmount") BigDecimal refundAmount,
-                       @JsonProperty("status") String status,
-                       @JsonProperty("type") String type,
-                       @JsonProperty("referenceId") String referenceId,
-                       @JsonProperty("effectiveDate") DateTime effectiveDate,
-                       @JsonProperty("createdDate") DateTime createdDate,
-                       @JsonProperty("updatedDate") DateTime updatedDate) {
-        this.id = id;
-        this.amount = amount;
-        this.appliedCreditBalanceAmount = appliedCreditBalanceAmount;
-        this.bankIdentificationNumber = bankIdentificationNumber;
-        this.createdDate = createdDate;
-        this.effectiveDate = effectiveDate;
-        this.paymentNumber = paymentNumber;
-        this.referenceId = referenceId;
-        this.refundAmount = refundAmount;
-        this.status = status;
-        this.type = type;
-        this.updatedDate = updatedDate;
-    }
-
-    public Builder cloner() {
-        return new Builder(this);
-    }
-
-    public String getId() {
-        return id;
-    }
-
-    public BigDecimal getAmount() {
-        return amount;
-    }
-
-    public BigDecimal getAppliedCreditBalanceAmount() {
-        return appliedCreditBalanceAmount;
-    }
-
-    public String getBankIdentificationNumber() {
-        return bankIdentificationNumber;
-    }
-
-    public DateTime getCreatedDate() {
-        return createdDate;
-    }
-
-    public DateTime getEffectiveDate() {
-        return effectiveDate;
-    }
-
-    public String getPaymentNumber() {
-        return paymentNumber;
-    }
-
-    public String getReferenceId() {
-        return referenceId;
-    }
-
-    public BigDecimal getRefundAmount() {
-        return refundAmount;
-    }
-
-    public String getStatus() {
-        return status;
-    }
-
-    public String getType() {
-        return type;
-    }
-
-    public DateTime getUpdatedDate() {
-        return updatedDate;
-    }
-
     @Override
     public int hashCode() {
         return Objects.hashCode(amount,
diff --git a/invoice/src/test/java/com/ning/billing/invoice/api/MockInvoicePaymentApi.java b/invoice/src/test/java/com/ning/billing/invoice/api/MockInvoicePaymentApi.java
index 6f42ec8..3a60656 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/api/MockInvoicePaymentApi.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/api/MockInvoicePaymentApi.java
@@ -29,14 +29,22 @@ import com.ning.billing.catalog.api.Currency;
 public class MockInvoicePaymentApi implements InvoicePaymentApi
 {
     private final CopyOnWriteArrayList<Invoice> invoices = new CopyOnWriteArrayList<Invoice>();
+    private final CopyOnWriteArrayList<InvoicePayment> invoicePayments = new CopyOnWriteArrayList<InvoicePayment>();
 
     public void add(Invoice invoice) {
         invoices.add(invoice);
     }
 
     @Override
-    public void paymentSuccessful(UUID invoiceId, BigDecimal amount, Currency currency, UUID paymentId, DateTime paymentAttemptDate) {
-        throw new UnsupportedOperationException();
+    public void paymentSuccessful(UUID invoiceId, BigDecimal amount, Currency currency, UUID paymentAttemptId, DateTime paymentAttemptDate) {
+        InvoicePayment invoicePayment = new InvoicePayment(invoiceId, amount, currency, paymentAttemptId, paymentAttemptDate);
+
+        for (InvoicePayment existingInvoicePayment : invoicePayments) {
+            if (existingInvoicePayment.getInvoiceId().equals(invoiceId) && existingInvoicePayment.getPaymentAttemptId().equals(paymentAttemptId)) {
+                invoicePayments.remove(existingInvoicePayment);
+            }
+        }
+        invoicePayments.add(invoicePayment);
     }
 
     @Override
@@ -62,7 +70,50 @@ public class MockInvoicePaymentApi implements InvoicePaymentApi
     }
 
     @Override
-    public void paymentFailed(UUID invoiceId, UUID paymentId, DateTime paymentAttemptDate) {
-        throw new UnsupportedOperationException();
+    public void paymentFailed(UUID invoiceId, UUID paymentAttemptId, DateTime paymentAttemptDate) {
+        InvoicePayment invoicePayment = new InvoicePayment(invoiceId, null, null, paymentAttemptId, paymentAttemptDate);
+        for (InvoicePayment existingInvoicePayment : invoicePayments) {
+            if (existingInvoicePayment.getInvoiceId().equals(invoiceId) && existingInvoicePayment.getPaymentAttemptId().equals(paymentAttemptId)) {
+                invoicePayments.remove(invoicePayment);
+            }
+        }
+        invoicePayments.add(invoicePayment);
+    }
+
+    private static class InvoicePayment {
+        private final UUID invoiceId;
+        private final UUID paymentAttemptId;
+        private final DateTime paymentAttemptDate;
+        private final BigDecimal amount;
+        private final Currency currency;
+
+        public InvoicePayment(UUID invoiceId, BigDecimal amount, Currency currency, UUID paymentAttemptId, DateTime paymentAttemptDate) {
+            this.invoiceId = invoiceId;
+            this.paymentAttemptId = paymentAttemptId;
+            this.paymentAttemptDate = paymentAttemptDate;
+            this.amount = amount;
+            this.currency = currency;
+        }
+
+        public UUID getInvoiceId() {
+            return invoiceId;
+        }
+
+        public UUID getPaymentAttemptId() {
+            return paymentAttemptId;
+        }
+
+        public DateTime getPaymentAttemptDate() {
+            return paymentAttemptDate;
+        }
+
+        public BigDecimal getAmount() {
+            return amount;
+        }
+
+        public Currency getCurrency() {
+            return currency;
+        }
+
     }
 }
diff --git a/payment/src/main/java/com/ning/billing/payment/PaymentAttempt.java b/payment/src/main/java/com/ning/billing/payment/PaymentAttempt.java
new file mode 100644
index 0000000..353587d
--- /dev/null
+++ b/payment/src/main/java/com/ning/billing/payment/PaymentAttempt.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2010-2011 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.payment;
+
+import java.math.BigDecimal;
+import java.util.UUID;
+
+import org.joda.time.DateTime;
+import org.joda.time.DateTimeZone;
+
+import com.ning.billing.invoice.api.Invoice;
+
+public class PaymentAttempt {
+    private final UUID paymentAttemptId;
+    private final UUID accountId;
+    private final UUID invoiceId;
+    private final BigDecimal paymentAttemptAmount;
+    private final DateTime paymentAttemptDate;
+
+    public PaymentAttempt(UUID paymentAttemptId, Invoice invoice) {
+        this.paymentAttemptId = paymentAttemptId;
+        this.accountId = invoice.getAccountId();
+        this.invoiceId = invoice.getId();
+        this.paymentAttemptAmount = invoice.getAmountOutstanding();
+        this.paymentAttemptDate = new DateTime(DateTimeZone.UTC);
+    }
+
+    public UUID getPaymentAttemptId() {
+        return paymentAttemptId;
+    }
+
+    public UUID getAccountId() {
+        return accountId;
+    }
+
+    public UUID getInvoiceId() {
+        return invoiceId;
+    }
+
+    public BigDecimal getPaymentAttemptAmount() {
+        return paymentAttemptAmount;
+    }
+
+        public DateTime getPaymentAttemptDate() {
+            return paymentAttemptDate;
+    }
+
+    @Override
+    public String toString() {
+        return "PaymentAttempt [paymentAttemptId=" + paymentAttemptId + ", accountId=" + accountId + ", invoiceId=" + invoiceId + ", paymentAttemptAmount=" + paymentAttemptAmount + "]";
+    }
+
+}
diff --git a/payment/src/main/java/com/ning/billing/payment/RequestProcessor.java b/payment/src/main/java/com/ning/billing/payment/RequestProcessor.java
index 2033d59..db5abcf 100644
--- a/payment/src/main/java/com/ning/billing/payment/RequestProcessor.java
+++ b/payment/src/main/java/com/ning/billing/payment/RequestProcessor.java
@@ -17,6 +17,7 @@
 package com.ning.billing.payment;
 
 import java.math.BigDecimal;
+import java.util.UUID;
 
 import com.google.common.eventbus.Subscribe;
 import com.google.inject.Inject;
@@ -58,21 +59,34 @@ public class RequestProcessor {
             if (invoice == null) {
                 // TODO: log a warning
             }
-            else if (invoice.getAmountOutstanding().compareTo(BigDecimal.ZERO) == 0 ) {
-                // TODO: send a notification that invoice was ignored ?
-            }
             else {
-                final Account account = accountUserApi.getAccountById(event.getAccountId());
-                if (account == null) {
-                    // TODO: log a warning
+                PaymentAttempt paymentAttempt = new PaymentAttempt(UUID.randomUUID(), invoice);
+
+                if (invoice.getAmountOutstanding().compareTo(BigDecimal.ZERO) == 0 ) {
+                // TODO: send a notification that invoice was ignored ?
                 }
                 else {
-                    final String paymentProviderName = account.getPaymentProviderName();
-                    final PaymentProviderPlugin plugin = pluginRegistry.getPlugin(paymentProviderName);
+                    final Account account = accountUserApi.getAccountById(event.getAccountId());
 
-                    Either<PaymentError, PaymentInfo> result = plugin.processInvoice(account, invoice);
+                    if (account == null) {
+                        // TODO: log a warning
+                    }
+                    else {
+                        final BigDecimal paymentAmount = invoice.getAmountOutstanding();
+                        final String paymentProviderName = account.getPaymentProviderName();
+                        final PaymentProviderPlugin plugin = pluginRegistry.getPlugin(paymentProviderName);
 
-                    eventBus.post(result.isLeft() ? result.getLeft() : result.getRight());
+                        Either<PaymentError, PaymentInfo> result = plugin.processInvoice(account, invoice);
+
+                        if (result.isLeft()) {
+                            invoiceApi.paymentFailed(invoice.getId(), paymentAttempt.getPaymentAttemptId(), paymentAttempt.getPaymentAttemptDate());
+                        }
+                        else {
+                            updatePaymentAttemptWithPaymentInfoId(result.getRight().getId(), plugin);
+                            invoiceApi.paymentSuccessful(invoice.getId(), paymentAmount, invoice.getCurrency(), paymentAttempt.getPaymentAttemptId(), paymentAttempt.getPaymentAttemptDate());
+                        }
+                        eventBus.post(result.isLeft() ? result.getLeft() : result.getRight());
+                    }
                 }
             }
         }
@@ -81,6 +95,10 @@ public class RequestProcessor {
         }
     }
 
+    private void updatePaymentAttemptWithPaymentInfoId(String id, PaymentProviderPlugin plugin) {
+        // TODO update PaymentAttempt with paymentId
+    }
+
     @Subscribe
     public void receivePaymentInfoRequest(PaymentInfoRequest paymentInfoRequest) throws EventBusException {
         final Account account = accountUserApi.getAccountById(paymentInfoRequest.getAccountId());