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,