killbill-aplcache

chargeback 1.0 APIs

5/31/2012 6:09:47 PM

Details

diff --git a/api/src/main/java/com/ning/billing/ErrorCode.java b/api/src/main/java/com/ning/billing/ErrorCode.java
index 8cf6f59..3189e64 100644
--- a/api/src/main/java/com/ning/billing/ErrorCode.java
+++ b/api/src/main/java/com/ning/billing/ErrorCode.java
@@ -191,6 +191,7 @@ public enum ErrorCode {
     INVOICE_PAYMENT_NOT_FOUND(4900, "No invoice payment could be found for id %s."),
     CHARGE_BACK_AMOUNT_TOO_HIGH(4901, "Tried to charge back %s of a %s payment."),
     CHARGE_BACK_AMOUNT_IS_NEGATIVE(4902, "Charge backs for negative amounts are not permitted"),
+    CHARGE_BACK_COULD_NOT_FIND_ACCOUNT_ID(4093, "Could not find invoice payment for id %s."),
     /*
      * 
      * Range 5000: Overdue system
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 6f6508b..bd9b94a 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
@@ -44,9 +44,15 @@ public interface InvoicePaymentApi {
     
     public void notifyOfPaymentAttempt(UUID invoiceId, UUID paymentAttemptId, DateTime paymentAttemptDate, CallContext context);
 
-    public void processChargeBack(UUID invoicePaymentId, BigDecimal amount, CallContext context) throws InvoiceApiException;
+    public void processChargeback(UUID invoicePaymentId, BigDecimal amount, CallContext context) throws InvoiceApiException;
 
-    public void processChargeBack(UUID invoicePaymentId, CallContext context) throws InvoiceApiException;
+    public void processChargeback(UUID invoicePaymentId, CallContext context) throws InvoiceApiException;
 
     public BigDecimal getRemainingAmountPaid(UUID invoicePaymentId);
+
+    public List<InvoicePayment> getChargebacksByAccountId(UUID accountId);
+
+    public List<InvoicePayment> getChargebacksByInvoicePaymentId(UUID paymentId);
+
+    UUID getAccountIdFromInvoicePaymentId(UUID uuid) throws InvoiceApiException;
 }
diff --git a/invoice/src/main/java/com/ning/billing/invoice/api/invoice/DefaultInvoicePaymentApi.java b/invoice/src/main/java/com/ning/billing/invoice/api/invoice/DefaultInvoicePaymentApi.java
index c465621..c0f04e3 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/api/invoice/DefaultInvoicePaymentApi.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/api/invoice/DefaultInvoicePaymentApi.java
@@ -80,20 +80,35 @@ public class DefaultInvoicePaymentApi implements InvoicePaymentApi {
     }
 
     @Override
-    public void processChargeBack(UUID invoicePaymentId, BigDecimal amount, CallContext context) throws InvoiceApiException {
-        dao.postChargeBack(invoicePaymentId, amount, context);
+    public void processChargeback(UUID invoicePaymentId, BigDecimal amount, CallContext context) throws InvoiceApiException {
+        dao.postChargeback(invoicePaymentId, amount, context);
     }
 
     @Override
-    public void processChargeBack(UUID invoicePaymentId, CallContext context) throws InvoiceApiException {
+    public void processChargeback(UUID invoicePaymentId, CallContext context) throws InvoiceApiException {
         // use the invoicePaymentId to get the amount remaining on the payment
         // (preventing charge backs totalling more than the payment)
         BigDecimal amount = dao.getRemainingAmountPaid(invoicePaymentId);
-        processChargeBack(invoicePaymentId, amount, context);
+        processChargeback(invoicePaymentId, amount, context);
     }
 
     @Override
     public BigDecimal getRemainingAmountPaid(UUID invoicePaymentId) {
         return dao.getRemainingAmountPaid(invoicePaymentId);
     }
+
+    @Override
+    public List<InvoicePayment> getChargebacksByAccountId(UUID accountId) {
+        return dao.getChargebacksByAccountId(accountId);
+    }
+
+    @Override
+    public List<InvoicePayment> getChargebacksByInvoicePaymentId(UUID paymentId) {
+        return dao.getChargebacksByPaymentId(paymentId);
+    }
+
+    @Override
+    public UUID getAccountIdFromInvoicePaymentId(UUID invoicePaymentId) throws InvoiceApiException {
+        return dao.getAccountIdFromInvoicePaymentId(invoicePaymentId);
+    }
 }
\ No newline at end of file
diff --git a/invoice/src/main/java/com/ning/billing/invoice/dao/DefaultInvoiceDao.java b/invoice/src/main/java/com/ning/billing/invoice/dao/DefaultInvoiceDao.java
index d765db2..ac53c7b 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/dao/DefaultInvoiceDao.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/dao/DefaultInvoiceDao.java
@@ -266,7 +266,7 @@ public class DefaultInvoiceDao implements InvoiceDao {
     }
 
     @Override
-    public void postChargeBack(final UUID invoicePaymentId, final BigDecimal amount, final CallContext context) throws InvoiceApiException {
+    public void postChargeback(final UUID invoicePaymentId, final BigDecimal amount, final CallContext context) throws InvoiceApiException {
         InvoicePayment payment = invoicePaymentSqlDao.getById(invoicePaymentId.toString());
         if (payment == null) {
             throw new InvoiceApiException(ErrorCode.INVOICE_PAYMENT_NOT_FOUND, invoicePaymentId.toString());
@@ -282,7 +282,28 @@ public class DefaultInvoiceDao implements InvoiceDao {
 
     @Override
     public BigDecimal getRemainingAmountPaid(UUID invoicePaymentId) {
-        return invoicePaymentSqlDao.getRemainingAmountPaid(invoicePaymentId.toString());
+        BigDecimal amount = invoicePaymentSqlDao.getRemainingAmountPaid(invoicePaymentId.toString());
+        return amount == null ? BigDecimal.ZERO : amount;
+    }
+
+    @Override
+    public UUID getAccountIdFromInvoicePaymentId(UUID invoicePaymentId) throws InvoiceApiException {
+        UUID accountId = invoicePaymentSqlDao.getAccountIdFromInvoicePaymentId(invoicePaymentId.toString());
+        if (accountId == null) {
+            throw new InvoiceApiException(ErrorCode.CHARGE_BACK_COULD_NOT_FIND_ACCOUNT_ID, invoicePaymentId);
+        } else {
+            return accountId;
+        }
+    }
+
+    @Override
+    public List<InvoicePayment> getChargebacksByAccountId(UUID accountId) {
+        return invoicePaymentSqlDao.getChargeBacksByAccountId(accountId.toString());
+    }
+
+    @Override
+    public List<InvoicePayment> getChargebacksByPaymentId(final UUID paymentId) {
+        return invoicePaymentSqlDao.getChargebacksByPaymentId(paymentId.toString());
     }
 
     @Override
diff --git a/invoice/src/main/java/com/ning/billing/invoice/dao/InvoiceDao.java b/invoice/src/main/java/com/ning/billing/invoice/dao/InvoiceDao.java
index f5aabc8..9a5e58b 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/dao/InvoiceDao.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/dao/InvoiceDao.java
@@ -53,11 +53,17 @@ public interface InvoiceDao {
 
 	List<Invoice> getAllInvoicesByAccount(final UUID accountId);
 
-    void setWrittenOff(UUID invoiceId, CallContext context);
+    void setWrittenOff(final UUID invoiceId, final CallContext context);
 
-    void removeWrittenOff(UUID invoiceId, CallContext context) throws InvoiceApiException;
+    void removeWrittenOff(final UUID invoiceId, final CallContext context) throws InvoiceApiException;
 
-    void postChargeBack(UUID invoicePaymentId, BigDecimal amount, CallContext context) throws InvoiceApiException;
+    void postChargeback(final UUID invoicePaymentId, final BigDecimal amount, final CallContext context) throws InvoiceApiException;
 
-    BigDecimal getRemainingAmountPaid(UUID invoicePaymentId);
+    BigDecimal getRemainingAmountPaid(final UUID invoicePaymentId);
+
+    UUID getAccountIdFromInvoicePaymentId(final UUID invoicePaymentId) throws InvoiceApiException;
+
+    List<InvoicePayment> getChargebacksByAccountId(final UUID accountId);
+
+    List<InvoicePayment> getChargebacksByPaymentId(final UUID paymentId);
 }
diff --git a/invoice/src/main/java/com/ning/billing/invoice/dao/InvoicePaymentSqlDao.java b/invoice/src/main/java/com/ning/billing/invoice/dao/InvoicePaymentSqlDao.java
index cf51d82..9fe5c2b 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/dao/InvoicePaymentSqlDao.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/dao/InvoicePaymentSqlDao.java
@@ -34,6 +34,7 @@ import com.ning.billing.util.callcontext.CallContext;
 import com.ning.billing.util.callcontext.CallContextBinder;
 import com.ning.billing.util.dao.BinderBase;
 import com.ning.billing.util.dao.MapperBase;
+import com.ning.billing.util.dao.UuidMapper;
 import com.ning.billing.util.entity.dao.EntitySqlDao;
 import org.joda.time.DateTime;
 import org.skife.jdbi.v2.SQLStatement;
@@ -86,6 +87,16 @@ public interface InvoicePaymentSqlDao extends EntitySqlDao<InvoicePayment>, Tran
     @SqlQuery
     BigDecimal getRemainingAmountPaid(@Bind("invoicePaymentId") final String invoicePaymentId);
 
+    @SqlQuery
+    @RegisterMapper(UuidMapper.class)
+    UUID getAccountIdFromInvoicePaymentId(@Bind("invoicePaymentId") final String invoicePaymentId);
+
+    @SqlQuery
+    List<InvoicePayment> getChargeBacksByAccountId(@Bind("accountId") final String accountId);
+
+    @SqlQuery
+    List<InvoicePayment> getChargebacksByPaymentId(@Bind("invoicePaymentId") final String paymentId);
+
     public static class InvoicePaymentMapper extends MapperBase implements ResultSetMapper<InvoicePayment> {
         @Override
         public InvoicePayment map(int index, ResultSet result, StatementContext context) throws SQLException {
diff --git a/invoice/src/main/java/com/ning/billing/invoice/dao/InvoiceSqlDao.java b/invoice/src/main/java/com/ning/billing/invoice/dao/InvoiceSqlDao.java
index af611bc..04b3fce 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/dao/InvoiceSqlDao.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/dao/InvoiceSqlDao.java
@@ -83,8 +83,6 @@ public interface InvoiceSqlDao extends EntitySqlDao<Invoice>, AuditSqlDao, Trans
     @SqlQuery
     List<Invoice> getUnpaidInvoicesByAccountId(@Bind("accountId") final String accountId,
                                                @Bind("upToDate") final Date upToDate);
-    
-    
 
     @BindingAnnotation(InvoiceBinder.InvoiceBinderFactory.class)
     @Retention(RetentionPolicy.RUNTIME)
diff --git a/invoice/src/main/resources/com/ning/billing/invoice/dao/InvoicePaymentSqlDao.sql.stg b/invoice/src/main/resources/com/ning/billing/invoice/dao/InvoicePaymentSqlDao.sql.stg
index d201bb9..349d462 100644
--- a/invoice/src/main/resources/com/ning/billing/invoice/dao/InvoicePaymentSqlDao.sql.stg
+++ b/invoice/src/main/resources/com/ning/billing/invoice/dao/InvoicePaymentSqlDao.sql.stg
@@ -97,4 +97,25 @@ getRemainingAmountPaid() ::= <<
     WHERE id = :invoicePaymentId
     OR reversed_invoice_payment_id = :invoicePaymentId;
 >>
+
+getAccountIdFromInvoicePaymentId() ::= <<
+    SELECT account_id
+    FROM invoice_payments ip
+    INNER JOIN invoices i ON i.id = ip.invoice_id
+    WHERE ip.id = :invoicePaymentId;
+>>
+
+getChargeBacksByAccountId() ::= <<
+    SELECT <invoicePaymentFields("ip.")>
+    FROM invoice_payments ip
+    INNER JOIN invoices i ON i.id = ip.invoice_id
+    WHERE i.account_id = :accountId
+    AND reversed_invoice_payment_id IS NOT NULL;
+>>
+
+getChargebacksByPaymentId() ::= <<
+    SELECT <invoicePaymentFields()>
+    FROM invoice_payments
+    WHERE reversed_invoice_payment_id = :invoicePaymentId;
+>>
 ;
\ No newline at end of file
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 2ec4d63..76e1bf3 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
@@ -103,7 +103,7 @@ public class MockInvoicePaymentApi implements InvoicePaymentApi
     }
 
     @Override
-    public void processChargeBack(UUID invoicePaymentId, BigDecimal amount, CallContext context) throws InvoiceApiException {
+    public void processChargeback(UUID invoicePaymentId, BigDecimal amount, CallContext context) throws InvoiceApiException {
         InvoicePayment existingPayment = null;
         for (InvoicePayment payment : invoicePayments) {
             if (payment.getId()  == invoicePaymentId) {
@@ -117,7 +117,7 @@ public class MockInvoicePaymentApi implements InvoicePaymentApi
     }
 
     @Override
-    public void processChargeBack(UUID invoicePaymentId, CallContext context) throws InvoiceApiException {
+    public void processChargeback(UUID invoicePaymentId, CallContext context) throws InvoiceApiException {
         InvoicePayment existingPayment = null;
         for (InvoicePayment payment : invoicePayments) {
             if (payment.getId()  == invoicePaymentId) {
@@ -126,7 +126,7 @@ public class MockInvoicePaymentApi implements InvoicePaymentApi
         }
 
         if (existingPayment != null) {
-            this.processChargeBack(invoicePaymentId, existingPayment.getAmount(), context);
+            this.processChargeback(invoicePaymentId, existingPayment.getAmount(), context);
         }
     }
 
@@ -146,4 +146,18 @@ public class MockInvoicePaymentApi implements InvoicePaymentApi
         return amount;
     }
 
+    @Override
+    public List<InvoicePayment> getChargebacksByAccountId(UUID accountId) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public List<InvoicePayment> getChargebacksByInvoicePaymentId(UUID paymentId) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public UUID getAccountIdFromInvoicePaymentId(UUID uuid) throws InvoiceApiException {
+        throw new UnsupportedOperationException();
+    }
 }
diff --git a/invoice/src/test/java/com/ning/billing/invoice/dao/MockInvoiceDao.java b/invoice/src/test/java/com/ning/billing/invoice/dao/MockInvoiceDao.java
index bb36b40..f6681fb 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/dao/MockInvoiceDao.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/dao/MockInvoiceDao.java
@@ -213,7 +213,7 @@ public class MockInvoiceDao implements InvoiceDao {
     }
 
     @Override
-    public void postChargeBack(UUID invoicePaymentId, BigDecimal amount, CallContext context) throws InvoiceApiException {
+    public void postChargeback(UUID invoicePaymentId, BigDecimal amount, CallContext context) throws InvoiceApiException {
         throw new UnsupportedOperationException();
     }
 
@@ -221,4 +221,19 @@ public class MockInvoiceDao implements InvoiceDao {
     public BigDecimal getRemainingAmountPaid(UUID invoicePaymentId) {
         throw new UnsupportedOperationException();
     }
+
+    @Override
+    public UUID getAccountIdFromInvoicePaymentId(UUID invoicePaymentId) throws InvoiceApiException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public List<InvoicePayment> getChargebacksByAccountId(UUID accountId) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public List<InvoicePayment> getChargebacksByPaymentId(UUID paymentId) {
+        throw new UnsupportedOperationException();
+    }
 }
diff --git a/invoice/src/test/java/com/ning/billing/invoice/tests/ChargeBackTests.java b/invoice/src/test/java/com/ning/billing/invoice/tests/ChargeBackTests.java
index ccd8db6..3b60b5b 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/tests/ChargeBackTests.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/tests/ChargeBackTests.java
@@ -47,6 +47,8 @@ import java.util.ArrayList;
 import java.util.List;
 import java.util.UUID;
 
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
 import static org.testng.Assert.assertTrue;
 import static org.testng.Assert.fail;
 
@@ -82,7 +84,7 @@ public class ChargeBackTests {
         InvoicePayment payment = createAndPersistPayment(invoice.getId(), THIRTY);
 
         // create a full charge back
-        invoicePaymentApi.processChargeBack(payment.getId(), THIRTY, context);
+        invoicePaymentApi.processChargeback(payment.getId(), THIRTY, context);
 
         // check amount owed
         BigDecimal amount = invoicePaymentApi.getRemainingAmountPaid(payment.getId());
@@ -95,7 +97,7 @@ public class ChargeBackTests {
         InvoicePayment payment = createAndPersistPayment(invoice.getId(), THIRTY);
 
         // create a partial charge back
-        invoicePaymentApi.processChargeBack(payment.getId(), FIFTEEN, context);
+        invoicePaymentApi.processChargeback(payment.getId(), FIFTEEN, context);
 
         // check amount owed
         BigDecimal amount = invoicePaymentApi.getRemainingAmountPaid(payment.getId());
@@ -108,7 +110,7 @@ public class ChargeBackTests {
         InvoicePayment payment = createAndPersistPayment(invoice.getId(), THIRTY);
 
         // create a large charge back
-        invoicePaymentApi.processChargeBack(payment.getId(), ONE_MILLION, context);
+        invoicePaymentApi.processChargeback(payment.getId(), ONE_MILLION, context);
     }
 
     @Test(expectedExceptions = InvoiceApiException.class)
@@ -117,7 +119,62 @@ public class ChargeBackTests {
         InvoicePayment payment = createAndPersistPayment(invoice.getId(), THIRTY);
 
         // create a partial charge back
-        invoicePaymentApi.processChargeBack(payment.getId(), BigDecimal.ONE.negate(), context);
+        invoicePaymentApi.processChargeback(payment.getId(), BigDecimal.ONE.negate(), context);
+    }
+
+    @Test
+    public void testGetAccountIdFromPaymentIdHappyPath() throws InvoiceApiException {
+        Invoice invoice = createAndPersistInvoice(THIRTY);
+        InvoicePayment payment = createAndPersistPayment(invoice.getId(), THIRTY);
+        UUID accountId = invoicePaymentApi.getAccountIdFromInvoicePaymentId(payment.getId());
+        assertEquals(accountId, invoice.getAccountId());
+    }
+
+    @Test(expectedExceptions = InvoiceApiException.class)
+    public void testGetAccountIdFromPaymentIdBadPaymentId() throws InvoiceApiException {
+        invoicePaymentApi.getAccountIdFromInvoicePaymentId(UUID.randomUUID());
+    }
+
+    @Test
+    public void testGetChargeBacksByAccountIdWithEmptyReturnSet() throws InvoiceApiException {
+        List<InvoicePayment> chargebacks = invoicePaymentApi.getChargebacksByAccountId(UUID.randomUUID());
+        assertNotNull(chargebacks);
+        assertEquals(chargebacks.size(), 0);
+    }
+
+    @Test
+    public void testGetChargeBacksByAccountIdHappyPath() throws InvoiceApiException {
+        Invoice invoice = createAndPersistInvoice(THIRTY);
+        InvoicePayment payment = createAndPersistPayment(invoice.getId(), THIRTY);
+
+        // create a partial charge back
+        invoicePaymentApi.processChargeback(payment.getId(), FIFTEEN, context);
+
+        List<InvoicePayment> chargebacks = invoicePaymentApi.getChargebacksByAccountId(invoice.getAccountId());
+        assertNotNull(chargebacks);
+        assertEquals(chargebacks.size(), 1);
+        assertEquals(chargebacks.get(0).getReversedInvoicePaymentId(), payment.getId());
+    }
+
+    @Test
+    public void testGetChargeBacksByInvoicePaymentIdWithEmptyReturnSet() throws InvoiceApiException {
+        List<InvoicePayment> chargebacks = invoicePaymentApi.getChargebacksByInvoicePaymentId(UUID.randomUUID());
+        assertNotNull(chargebacks);
+        assertEquals(chargebacks.size(), 0);
+    }
+
+    @Test
+    public void testGetChargeBacksByInvoicePaymentIdHappyPath() throws InvoiceApiException {
+        Invoice invoice = createAndPersistInvoice(THIRTY);
+        InvoicePayment payment = createAndPersistPayment(invoice.getId(), THIRTY);
+
+        // create a partial charge back
+        invoicePaymentApi.processChargeback(payment.getId(), FIFTEEN, context);
+
+        List<InvoicePayment> chargebacks = invoicePaymentApi.getChargebacksByInvoicePaymentId(payment.getId());
+        assertNotNull(chargebacks);
+        assertEquals(chargebacks.size(), 1);
+        assertEquals(chargebacks.get(0).getReversedInvoicePaymentId(), payment.getId());
     }
 
     private Invoice createAndPersistInvoice(BigDecimal amount) {
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/AccountJson.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/AccountJson.java
index 7d3a663..22ae311 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/AccountJson.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/AccountJson.java
@@ -194,7 +194,7 @@ public class AccountJson extends AccountJsonSimple {
     public AccountJson(@JsonProperty("accountId") String accountId,
             @JsonProperty("name") String name,
             @JsonProperty("firstNameLength") Integer length,
-            @JsonProperty("external_key") String externalKey,
+            @JsonProperty("externalKey") String externalKey,
             @JsonProperty("email") String email,
             @JsonProperty("billingDay") Integer billCycleDay,
             @JsonProperty("currency") String currency,