killbill-aplcache
Changes
Details
diff --git a/api/src/main/java/com/ning/billing/ErrorCode.java b/api/src/main/java/com/ning/billing/ErrorCode.java
index 39dc17f..bc20699 100644
--- a/api/src/main/java/com/ning/billing/ErrorCode.java
+++ b/api/src/main/java/com/ning/billing/ErrorCode.java
@@ -197,7 +197,7 @@ public enum ErrorCode {
CHARGE_BACK_DOES_NOT_EXIST(4004, "Could not find chargeback for id %s."),
INVOICE_PAYMENT_BY_ATTEMPT_NOT_FOUND(4905, "No invoice payment could be found for paymentAttempt id %s."),
REFUND_AMOUNT_TOO_HIGH(4906, "Tried to refund %s of a %s payment."),
- REFUND_AMOUNT_IS_NEGATIVE(4907, "Refund for negative amounts are not permitted"),
+ REFUND_AMOUNT_IS_POSITIVE(4907, "Refund for positve amounts are not permitted"),
/*
*
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 9bf4cc5..a71783a 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
@@ -42,8 +42,6 @@ public interface InvoicePaymentApi {
public void notifyOfPaymentAttempt(UUID invoiceId, BigDecimal amountOutstanding, Currency currency, UUID paymentAttemptId, DateTime paymentAttemptDate, CallContext context);
- public void notifyOfPaymentAttempt(UUID invoiceId, UUID paymentAttemptId, DateTime paymentAttemptDate, CallContext context);
-
public InvoicePayment createRefund(UUID paymentAttemptId, BigDecimal amount, boolean isInvoiceAdjusted, CallContext context) throws InvoiceApiException;
public InvoicePayment createChargeback(UUID invoicePaymentId, BigDecimal amount, CallContext context) 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 125e195..a73fab7 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
@@ -75,12 +75,6 @@ public class DefaultInvoicePaymentApi implements InvoicePaymentApi {
}
@Override
- public void notifyOfPaymentAttempt(final UUID invoiceId, final UUID paymentAttemptId, final DateTime paymentAttemptDate, final CallContext context) {
- final InvoicePayment invoicePayment = new DefaultInvoicePayment(InvoicePaymentType.ATTEMPT, paymentAttemptId, invoiceId, paymentAttemptDate);
- dao.notifyOfPaymentAttempt(invoicePayment, context);
- }
-
- @Override
public InvoicePayment createChargeback(final UUID invoicePaymentId, final BigDecimal amount, final CallContext context) throws InvoiceApiException {
return dao.postChargeback(invoicePaymentId, amount, context);
}
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 4b10980..2cfec3f 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
@@ -270,7 +270,7 @@ public class DefaultInvoiceDao implements InvoiceDao {
Collection<Invoice> unpaidInvoices = Collections2.filter(invoices, new Predicate<Invoice>() {
@Override
public boolean apply(Invoice in) {
- return (in.getBalance().compareTo(BigDecimal.ZERO) >= 1);
+ return (in.getBalance().compareTo(BigDecimal.ZERO) >= 1) && !in.getTargetDate().isAfter(upToDate);
}
});
return new ArrayList<Invoice>(unpaidInvoices);
@@ -313,29 +313,46 @@ public class DefaultInvoiceDao implements InvoiceDao {
}
final BigDecimal maxRefundAmount = payment.getAmount() == null ? BigDecimal.ZERO : payment.getAmount();
final BigDecimal requestedAmount = amount == null ? maxRefundAmount : amount;
- if (requestedAmount.compareTo(BigDecimal.ZERO) <= 0) {
- throw new InvoiceApiException(ErrorCode.REFUND_AMOUNT_IS_NEGATIVE);
+ if (requestedAmount.compareTo(BigDecimal.ZERO) >= 0) {
+ throw new InvoiceApiException(ErrorCode.REFUND_AMOUNT_IS_POSITIVE);
}
- if (requestedAmount.compareTo(maxRefundAmount) > 0) {
- throw new InvoiceApiException(ErrorCode.REFUND_AMOUNT_TOO_HIGH, requestedAmount, maxRefundAmount);
+
+ // No that we check signs, let's work with positive numbers, this makes things simpler
+ final BigDecimal requestedPositiveAmount = requestedAmount.negate();
+ if (requestedPositiveAmount.compareTo(maxRefundAmount) > 0) {
+ throw new InvoiceApiException(ErrorCode.REFUND_AMOUNT_TOO_HIGH, requestedPositiveAmount, maxRefundAmount);
}
final InvoicePayment refund = new DefaultInvoicePayment(UUID.randomUUID(), InvoicePaymentType.REFUND, paymentAttemptId,
- payment.getInvoiceId(), context.getCreatedDate(), requestedAmount, payment.getCurrency(), payment.getId());
+ payment.getInvoiceId(), context.getCreatedDate(), requestedPositiveAmount.negate(), payment.getCurrency(), payment.getId());
transactional.create(refund, context);
+ // Retrieve invoice after the Refund
+ InvoiceSqlDao transInvoiceDao = transactional.become(InvoiceSqlDao.class);
+ Invoice invoice = transInvoiceDao.getById(payment.getInvoiceId().toString());
+ if (invoice != null) {
+ populateChildren(invoice, transInvoiceDao);
+ }
+
+ final BigDecimal invoiceBalanceAfterRefund = invoice.getBalance();
+ InvoiceItemSqlDao transInvoiceItemDao = transInvoiceDao.become(InvoiceItemSqlDao.class);
+
+ // If we have an existing CBA > 0, we need to adjust it
+ final BigDecimal cbaAmountAfterRefund = invoice.getCBAAmount();
+ BigDecimal cbaAdjAmount = BigDecimal.ZERO;
+ if (cbaAmountAfterRefund.compareTo(BigDecimal.ZERO) > 0) {
+ cbaAdjAmount = (requestedPositiveAmount.compareTo(cbaAmountAfterRefund) > 0) ? cbaAmountAfterRefund.negate() : requestedPositiveAmount.negate();
+ final InvoiceItem cbaAdjItem = new CreditBalanceAdjInvoiceItem(invoice.getId(), invoice.getAccountId(), context.getCreatedDate(), cbaAdjAmount, invoice.getCurrency());
+ transInvoiceItemDao.create(cbaAdjItem, context);
+ }
+ final BigDecimal requestedPositiveAmountAfterCbaAdj = requestedPositiveAmount.subtract(cbaAdjAmount);
+
if (isInvoiceAdjusted) {
- InvoiceSqlDao transInvoiceDao = transactional.become(InvoiceSqlDao.class);
- Invoice invoice = transInvoiceDao.getById(payment.getInvoiceId().toString());
- if (invoice != null) {
- populateChildren(invoice, transInvoiceDao);
- }
- BigDecimal maxBalanceToAdjust = (invoice.getBalance().compareTo(BigDecimal.ZERO) <= 0) ? BigDecimal.ZERO : invoice.getBalance();
- BigDecimal requestedAmountToAdjust = requestedAmount.compareTo(maxBalanceToAdjust) > 0 ? maxBalanceToAdjust : requestedAmount;
- if (requestedAmountToAdjust.compareTo(BigDecimal.ZERO) > 0) {
- final InvoiceItem adjItem = new RefundAdjInvoiceItem(invoice.getId(), invoice.getAccountId(), context.getCreatedDate(), requestedAmountToAdjust, invoice.getCurrency());
- InvoiceItemSqlDao transInvoiceItemDao = transInvoiceDao.become(InvoiceItemSqlDao.class);
+ BigDecimal maxBalanceToAdjust = (invoiceBalanceAfterRefund.compareTo(BigDecimal.ZERO) <= 0) ? BigDecimal.ZERO : invoiceBalanceAfterRefund;
+ BigDecimal requestedPositiveAmountToAdjust = requestedPositiveAmountAfterCbaAdj.compareTo(maxBalanceToAdjust) > 0 ? maxBalanceToAdjust : requestedPositiveAmountAfterCbaAdj;
+ if (requestedPositiveAmountToAdjust.compareTo(BigDecimal.ZERO) > 0) {
+ final InvoiceItem adjItem = new RefundAdjInvoiceItem(invoice.getId(), invoice.getAccountId(), context.getCreatedDate(), requestedPositiveAmountToAdjust.negate(), invoice.getCurrency());
transInvoiceItemDao.create(adjItem, context);
}
}
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 852660d..ed5b2c3 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
@@ -62,7 +62,7 @@ public interface InvoicePaymentSqlDao extends EntitySqlDao<InvoicePayment>, Tran
List<Long> getRecordIds(@Bind("invoiceId") final String invoiceId);
@SqlQuery
- public InvoicePayment getByPaymentAttemptId(@Bind("paymentAttempt") final String paymentAttemptId);
+ public InvoicePayment getByPaymentAttemptId(@Bind("paymentAttemptId") final String paymentAttemptId);
@Override
@SqlQuery
diff --git a/invoice/src/main/java/com/ning/billing/invoice/model/DefaultInvoicePayment.java b/invoice/src/main/java/com/ning/billing/invoice/model/DefaultInvoicePayment.java
index 99e0bde..08371ed 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/model/DefaultInvoicePayment.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/model/DefaultInvoicePayment.java
@@ -22,9 +22,7 @@ import java.util.UUID;
import org.joda.time.DateTime;
-import com.ning.billing.ErrorCode;
import com.ning.billing.catalog.api.Currency;
-import com.ning.billing.invoice.api.InvoiceApiException;
import com.ning.billing.invoice.api.InvoicePayment;
import com.ning.billing.util.entity.EntityBase;
@@ -37,10 +35,6 @@ public class DefaultInvoicePayment extends EntityBase implements InvoicePayment
private final Currency currency;
private final UUID reversedInvoicePaymentId;
- public DefaultInvoicePayment(final InvoicePaymentType type, final UUID paymentAttemptId, final UUID invoiceId, final DateTime paymentDate) {
- this(UUID.randomUUID(), type, paymentAttemptId, invoiceId, paymentDate, null, null, null);
- }
-
public DefaultInvoicePayment(final InvoicePaymentType type, final UUID paymentAttemptId, final UUID invoiceId, final DateTime paymentDate,
final BigDecimal amount, final Currency currency) {
this(UUID.randomUUID(), type, paymentAttemptId, invoiceId, paymentDate, amount, currency, null);
diff --git a/invoice/src/main/resources/com/ning/billing/invoice/dao/InvoiceSqlDao.sql.stg b/invoice/src/main/resources/com/ning/billing/invoice/dao/InvoiceSqlDao.sql.stg
index 90e66bc..416fb5e 100644
--- a/invoice/src/main/resources/com/ning/billing/invoice/dao/InvoiceSqlDao.sql.stg
+++ b/invoice/src/main/resources/com/ning/billing/invoice/dao/InvoiceSqlDao.sql.stg
@@ -20,7 +20,7 @@ get() ::= <<
getInvoicesByAccount() ::= <<
SELECT record_id as invoice_number, <invoiceFields()>
FROM invoices
- WHERE account_id = :accountId AND migrated = 'FALSE'
+ WHERE account_id = :accountId AND migrated = '0'
ORDER BY target_date ASC;
>>
@@ -34,16 +34,15 @@ getAllInvoicesByAccount() ::= <<
getInvoicesByAccountAfterDate() ::= <<
SELECT record_id as invoice_number, <invoiceFields()>
FROM invoices
- WHERE account_id = :accountId AND target_date >= :fromDate AND migrated = 'FALSE'
+ WHERE account_id = :accountId AND target_date >= :fromDate AND migrated = '0'
ORDER BY target_date ASC;
>>
getInvoicesBySubscription() ::= <<
SELECT i.record_id as invoice_number, <invoiceFields("i.")>
FROM invoices i
- LEFT JOIN invoice_items rii ON i.id = rii.invoice_id
- WHERE rii.subscription_id = :subscriptionId AND migrated = 'FALSE'
- GROUP BY i.record_id, <invoiceFields("i.")>
+ JOIN invoice_items ii ON i.id = ii.invoice_id
+ WHERE ii.subscription_id = :subscriptionId AND i.migrated = '0';
>>
getById() ::= <<
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 fa5d431..af2c854 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
@@ -97,12 +97,6 @@ public class MockInvoicePaymentApi implements InvoicePaymentApi {
}
@Override
- public void notifyOfPaymentAttempt(final UUID invoiceId, final UUID paymentAttemptId, final DateTime paymentAttemptDate, final CallContext context) {
- final InvoicePayment invoicePayment = new DefaultInvoicePayment(InvoicePaymentType.ATTEMPT, paymentAttemptId, invoiceId, paymentAttemptDate);
- notifyOfPaymentAttempt(invoicePayment, context);
- }
-
- @Override
public InvoicePayment createChargeback(final UUID invoicePaymentId, final BigDecimal amount, final CallContext context) throws InvoiceApiException {
InvoicePayment existingPayment = null;
for (final InvoicePayment payment : invoicePayments) {
diff --git a/invoice/src/test/java/com/ning/billing/invoice/dao/InvoiceDaoTestBase.java b/invoice/src/test/java/com/ning/billing/invoice/dao/InvoiceDaoTestBase.java
index 304b4e8..6a5631d 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/dao/InvoiceDaoTestBase.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/dao/InvoiceDaoTestBase.java
@@ -98,7 +98,7 @@ public abstract class InvoiceDaoTestBase extends InvoicingTestBase {
}
}
- @BeforeClass(alwaysRun = true)
+ @BeforeClass(groups={"slow"})
protected void setup() throws IOException {
loadSystemPropertiesFromClasspath("/resource.properties");
@@ -109,10 +109,15 @@ public abstract class InvoiceDaoTestBase extends InvoicingTestBase {
final String invoiceDdl = IOUtils.toString(DefaultInvoiceDao.class.getResourceAsStream("/com/ning/billing/invoice/ddl.sql"));
final String utilDdl = IOUtils.toString(DefaultInvoiceDao.class.getResourceAsStream("/com/ning/billing/util/ddl.sql"));
+ clock = new ClockMock();
+
mysqlTestingHelper.startMysql();
mysqlTestingHelper.initDb(invoiceDdl);
mysqlTestingHelper.initDb(utilDdl);
+ bus = new InMemoryBus();
+ bus.start();
+
final NextBillingDatePoster nextBillingDatePoster = new MockNextBillingDatePoster();
final TagDefinitionDao tagDefinitionDao = new MockTagDefinitionDao();
final TagDao tagDao = new AuditedTagDao(dbi, tagEventBuilder, bus);
@@ -123,16 +128,17 @@ public abstract class InvoiceDaoTestBase extends InvoicingTestBase {
invoiceItemSqlDao = dbi.onDemand(InvoiceItemSqlDao.class);
invoicePaymentDao = dbi.onDemand(InvoicePaymentSqlDao.class);
- clock = new ClockMock();
+
+
context = new TestCallContext("Invoice Dao Tests");
generator = new DefaultInvoiceGenerator(clock, invoiceConfig);
- bus = new InMemoryBus();
- bus.start();
+
+
assertTrue(true);
}
- @BeforeMethod(alwaysRun = true)
+ @BeforeMethod(groups={"slow"})
public void cleanupData() {
dbi.inTransaction(new TransactionCallback<Void>() {
@Override
@@ -146,7 +152,7 @@ public abstract class InvoiceDaoTestBase extends InvoicingTestBase {
});
}
- @AfterClass(alwaysRun = true)
+ @AfterClass(groups={"slow"})
protected void tearDown() {
bus.stop();
mysqlTestingHelper.stopMysql();
diff --git a/invoice/src/test/java/com/ning/billing/invoice/dao/InvoiceDaoTests.java b/invoice/src/test/java/com/ning/billing/invoice/dao/InvoiceDaoTests.java
index 098f653..51e9211 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/dao/InvoiceDaoTests.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/dao/InvoiceDaoTests.java
@@ -52,7 +52,6 @@ import com.ning.billing.invoice.model.DefaultInvoice;
import com.ning.billing.invoice.model.DefaultInvoicePayment;
import com.ning.billing.invoice.model.FixedPriceInvoiceItem;
import com.ning.billing.invoice.model.RecurringInvoiceItem;
-import com.ning.billing.invoice.model.RefundAdjInvoiceItem;
import com.ning.billing.invoice.model.RepairAdjInvoiceItem;
import com.ning.billing.junction.api.BillingEventSet;
import com.ning.billing.mock.BrainDeadProxyFactory;
@@ -69,9 +68,9 @@ import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertNull;
import static org.testng.Assert.assertTrue;
-@Test(groups = {"slow", "invoicing", "invoicing-invoiceDao"})
public class InvoiceDaoTests extends InvoiceDaoTestBase {
- @Test
+
+ @Test(groups = {"slow"})
public void testCreationAndRetrievalByAccount() {
final UUID accountId = UUID.randomUUID();
final Invoice invoice = new DefaultInvoice(accountId, clock.getUTCNow(), clock.getUTCNow(), Currency.USD);
@@ -90,7 +89,7 @@ public class InvoiceDaoTests extends InvoiceDaoTestBase {
assertTrue(thisInvoice.getBalance().compareTo(BigDecimal.ZERO) == 0);
}
- @Test
+ @Test(groups = {"slow"})
public void testInvoicePayment() {
final UUID accountId = UUID.randomUUID();
final Invoice invoice = new DefaultInvoice(accountId, clock.getUTCNow(), clock.getUTCNow(), Currency.USD);
@@ -124,13 +123,13 @@ public class InvoiceDaoTests extends InvoiceDaoTestBase {
assertEquals(retrievedInvoice.getPaidAmount().compareTo(new BigDecimal("11.00")), 0);
}
- @Test
+ @Test(groups = {"slow"})
public void testRetrievalForNonExistentInvoiceId() {
final Invoice invoice = invoiceDao.getById(UUID.randomUUID());
assertNull(invoice);
}
- @Test
+ @Test(groups = {"slow"})
public void testAddPayment() {
final UUID accountId = UUID.randomUUID();
final DateTime targetDate = new DateTime(2011, 10, 6, 0, 0, 0, 0);
@@ -149,7 +148,7 @@ public class InvoiceDaoTests extends InvoiceDaoTestBase {
assertEquals(invoice.getNumberOfPayments(), 1);
}
- @Test
+ @Test(groups = {"slow"})
public void testAddPaymentAttempt() {
final UUID accountId = UUID.randomUUID();
final DateTime targetDate = new DateTime(2011, 10, 6, 0, 0, 0, 0);
@@ -158,13 +157,12 @@ public class InvoiceDaoTests extends InvoiceDaoTestBase {
final DateTime paymentAttemptDate = new DateTime(2011, 6, 24, 12, 14, 36, 0);
invoiceDao.create(invoice, context);
- invoiceDao.notifyOfPaymentAttempt(new DefaultInvoicePayment(InvoicePaymentType.ATTEMPT, UUID.randomUUID(), invoice.getId(), paymentAttemptDate), context);
-
+ invoiceDao.notifyOfPaymentAttempt(new DefaultInvoicePayment(InvoicePaymentType.ATTEMPT, UUID.randomUUID(), invoice.getId(), paymentAttemptDate, invoice.getBalance(), Currency.USD), context);
invoice = invoiceDao.getById(invoice.getId());
assertEquals(invoice.getLastPaymentAttempt().compareTo(paymentAttemptDate), 0);
}
- @Test
+ @Test(groups = {"slow"})
public void testGetInvoicesBySubscriptionForRecurringItems() {
final UUID accountId = UUID.randomUUID();
final UUID bundleId = UUID.randomUUID();
@@ -240,7 +238,7 @@ public class InvoiceDaoTests extends InvoiceDaoTestBase {
assertEquals(items4.size(), 1);
}
- @Test
+ @Test(groups = {"slow"})
public void testGetInvoicesBySubscriptionForFixedItems() {
final UUID accountId = UUID.randomUUID();
final UUID bundleId = UUID.randomUUID();
@@ -316,7 +314,7 @@ public class InvoiceDaoTests extends InvoiceDaoTestBase {
assertEquals(items4.size(), 1);
}
- @Test
+ @Test(groups = {"slow"})
public void testGetInvoicesBySubscriptionForRecurringAndFixedItems() {
final UUID accountId = UUID.randomUUID();
final UUID bundleId = UUID.randomUUID();
@@ -419,7 +417,7 @@ public class InvoiceDaoTests extends InvoiceDaoTestBase {
assertEquals(items4.size(), 2);
}
- @Test
+ @Test(groups = {"slow"})
public void testGetInvoicesForAccountAfterDate() {
final UUID accountId = UUID.randomUUID();
final DateTime targetDate1 = new DateTime(2011, 10, 6, 0, 0, 0, 0);
@@ -448,7 +446,7 @@ public class InvoiceDaoTests extends InvoiceDaoTestBase {
assertEquals(invoices.size(), 0);
}
- @Test
+ @Test(groups = {"slow"})
public void testAccountBalance() {
final UUID accountId = UUID.randomUUID();
final UUID bundleId = UUID.randomUUID();
@@ -479,7 +477,7 @@ public class InvoiceDaoTests extends InvoiceDaoTestBase {
}
- @Test
+ @Test(groups = {"slow"})
public void testAccountBalanceWithCredit() {
final UUID accountId = UUID.randomUUID();
final UUID bundleId = UUID.randomUUID();
@@ -504,7 +502,7 @@ public class InvoiceDaoTests extends InvoiceDaoTestBase {
assertEquals(balance.compareTo(BigDecimal.ZERO), 0);
}
- @Test
+ @Test(groups = {"slow"})
public void testAccountBalanceWithNoPayments() {
final UUID accountId = UUID.randomUUID();
final UUID bundleId = UUID.randomUUID();
@@ -530,7 +528,7 @@ public class InvoiceDaoTests extends InvoiceDaoTestBase {
assertEquals(balance.compareTo(rate1.add(rate2)), 0);
}
- @Test
+ @Test(groups = {"slow"})
public void testAccountBalanceWithNoInvoiceItems() {
final UUID accountId = UUID.randomUUID();
final DateTime targetDate1 = new DateTime(2011, 10, 6, 0, 0, 0, 0);
@@ -545,7 +543,153 @@ public class InvoiceDaoTests extends InvoiceDaoTestBase {
assertEquals(balance.compareTo(BigDecimal.ZERO.subtract(payment1)), 0);
}
- @Test
+ @Test(groups = {"slow"})
+ public void testAccountBalanceWithRefundNoAdj() throws InvoiceApiException {
+ testAccountBalanceWithRefundInternal(false);
+ }
+
+ @Test(groups = {"slow"})
+ public void testAccountBalanceWithRefundAndAdj() throws InvoiceApiException {
+ testAccountBalanceWithRefundInternal(true);
+ }
+
+ private void testAccountBalanceWithRefundInternal(boolean withAdjustment) throws InvoiceApiException {
+
+ final UUID accountId = UUID.randomUUID();
+ final UUID bundleId = UUID.randomUUID();
+ final DateTime targetDate1 = new DateTime(2011, 10, 6, 0, 0, 0, 0);
+ final Invoice invoice1 = new DefaultInvoice(accountId, clock.getUTCNow(), targetDate1, Currency.USD);
+ invoiceDao.create(invoice1, context);
+
+ final DateTime startDate = new DateTime(2011, 3, 1, 0, 0, 0, 0);
+ final DateTime endDate = startDate.plusMonths(1);
+
+ final BigDecimal rate1 = new BigDecimal("20.0");
+ final BigDecimal refund1 = new BigDecimal("-7.00");
+ final BigDecimal rate2 = new BigDecimal("10.0");
+
+
+ // Recurring item
+ final RecurringInvoiceItem item2 = new RecurringInvoiceItem(invoice1.getId(), accountId, bundleId, UUID.randomUUID(), "test plan", "test phase B", startDate,
+ endDate, rate1, rate1, Currency.USD);
+ invoiceItemSqlDao.create(item2, context);
+ BigDecimal balance = invoiceDao.getAccountBalance(accountId);
+ assertEquals(balance.compareTo(new BigDecimal("20.00")), 0);
+
+ // Pay the whole thing
+ final UUID paymentAttemptId = UUID.randomUUID();
+ final BigDecimal payment1 = rate1;
+ final InvoicePayment payment = new DefaultInvoicePayment(InvoicePaymentType.ATTEMPT, paymentAttemptId, invoice1.getId(), new DateTime(), payment1, Currency.USD);
+ invoicePaymentDao.create(payment, context);
+ balance = invoiceDao.getAccountBalance(accountId);
+ assertEquals(balance.compareTo(new BigDecimal("0.00")), 0);
+
+ invoiceDao.createRefund(paymentAttemptId, refund1, withAdjustment, context);
+ balance = invoiceDao.getAccountBalance(accountId);
+ if (withAdjustment) {
+ assertEquals(balance.compareTo(BigDecimal.ZERO), 0);
+ } else {
+ assertEquals(balance.compareTo(new BigDecimal("7.00")), 0);
+ }
+ }
+
+ @Test(groups = {"slow"})
+ public void testAccountBalanceWithSmallRefundAndCBANoAdj() throws InvoiceApiException {
+ BigDecimal refundAmount = new BigDecimal("-7.00");
+ BigDecimal expectedBalance = new BigDecimal("-3.00");
+ testAccountBalanceWithRefundAndCBAInternal(false, refundAmount, expectedBalance);
+ }
+
+ @Test(groups = {"slow"})
+ public void testAccountBalanceWithSmallRefundAndCBAWithAdj() throws InvoiceApiException {
+ BigDecimal refundAmount = new BigDecimal("-7.00");
+ BigDecimal expectedBalance = new BigDecimal("-3.00");
+ testAccountBalanceWithRefundAndCBAInternal(true, refundAmount, expectedBalance);
+ }
+
+ @Test(groups = {"slow"})
+ public void testAccountBalanceWithLargeRefundAndCBANoAdj() throws InvoiceApiException {
+ BigDecimal refundAmount = new BigDecimal("-20.00");
+ BigDecimal expectedBalance = new BigDecimal("10.00");
+ testAccountBalanceWithRefundAndCBAInternal(false, refundAmount, expectedBalance);
+ }
+
+ @Test(groups = {"slow"})
+ public void testAccountBalanceWithLargeRefundAndCBAWithAdj() throws InvoiceApiException {
+ BigDecimal refundAmount = new BigDecimal("-20.00");
+ BigDecimal expectedBalance = BigDecimal.ZERO;
+ testAccountBalanceWithRefundAndCBAInternal(true, refundAmount, expectedBalance);
+ }
+
+
+ private void testAccountBalanceWithRefundAndCBAInternal(boolean withAdjustment, final BigDecimal refundAmount, final BigDecimal expectedFinalBalance) throws InvoiceApiException {
+
+ final UUID accountId = UUID.randomUUID();
+ final UUID bundleId = UUID.randomUUID();
+ final DateTime targetDate1 = new DateTime(2011, 10, 6, 0, 0, 0, 0);
+ final Invoice invoice1 = new DefaultInvoice(accountId, clock.getUTCNow(), targetDate1, Currency.USD);
+ invoiceDao.create(invoice1, context);
+
+ final DateTime startDate = new DateTime(2011, 3, 1, 0, 0, 0, 0);
+ final DateTime endDate = startDate.plusMonths(1);
+
+ final BigDecimal amount1 = new BigDecimal("5.0");
+ final BigDecimal rate1 = new BigDecimal("20.0");
+ final BigDecimal rate2 = new BigDecimal("10.0");
+
+ // Fixed Item
+ final FixedPriceInvoiceItem item1 = new FixedPriceInvoiceItem(invoice1.getId(), accountId, bundleId, UUID.randomUUID(), "test plan", "test phase A", startDate,
+ endDate, amount1, Currency.USD);
+ invoiceItemSqlDao.create(item1, context);
+
+ BigDecimal balance = invoiceDao.getAccountBalance(accountId);
+ assertEquals(balance.compareTo(new BigDecimal("5.00")), 0);
+
+ // Recurring item
+ final RecurringInvoiceItem item2 = new RecurringInvoiceItem(invoice1.getId(), accountId, bundleId, UUID.randomUUID(), "test plan", "test phase B", startDate,
+ endDate, rate1, rate1, Currency.USD);
+ invoiceItemSqlDao.create(item2, context);
+ balance = invoiceDao.getAccountBalance(accountId);
+ assertEquals(balance.compareTo(new BigDecimal("25.00")), 0);
+
+ // Pay the whole thing
+ final UUID paymentAttemptId = UUID.randomUUID();
+ final BigDecimal payment1 = amount1.add(rate1);
+ final InvoicePayment payment = new DefaultInvoicePayment(InvoicePaymentType.ATTEMPT, paymentAttemptId, invoice1.getId(), new DateTime(), payment1, Currency.USD);
+ invoicePaymentDao.create(payment, context);
+ balance = invoiceDao.getAccountBalance(accountId);
+ assertEquals(balance.compareTo(new BigDecimal("0.00")), 0);
+
+ // Repair previous item with rate 2
+ final RepairAdjInvoiceItem item2Repair = new RepairAdjInvoiceItem(invoice1.getId(), accountId, startDate, endDate, rate1.negate(), Currency.USD, item2.getId());
+ final RecurringInvoiceItem item2Replace = new RecurringInvoiceItem(invoice1.getId(), accountId, bundleId, UUID.randomUUID(), "test plan", "test phase B", startDate,
+ endDate, rate2, rate2, Currency.USD);
+ invoiceItemSqlDao.create(item2Repair, context);
+ invoiceItemSqlDao.create(item2Replace, context);
+ balance = invoiceDao.getAccountBalance(accountId);
+ assertEquals(balance.compareTo(new BigDecimal("-10.00")), 0);
+
+ // CBA
+ final CreditBalanceAdjInvoiceItem cbaItem = new CreditBalanceAdjInvoiceItem(invoice1.getId(), accountId, new DateTime(), balance.negate(), Currency.USD);
+ invoiceItemSqlDao.create(cbaItem, context);
+ balance = invoiceDao.getAccountBalance(accountId);
+ assertEquals(balance.compareTo(new BigDecimal("-10.00")), 0);
+ BigDecimal cba = invoiceDao.getAccountCBA(accountId);
+ assertEquals(cba.compareTo(new BigDecimal("10.00")), 0);
+
+ // PARTIAL REFUND on the payment
+ invoiceDao.createRefund(paymentAttemptId, refundAmount, withAdjustment, context);
+
+ balance = invoiceDao.getAccountBalance(accountId);
+ assertEquals(balance.compareTo(expectedFinalBalance), 0);
+ cba = invoiceDao.getAccountCBA(accountId);
+
+ final BigDecimal expectedFinalCBA = (expectedFinalBalance.compareTo(BigDecimal.ZERO) < 0) ? expectedFinalBalance.negate() : BigDecimal.ZERO;
+ assertEquals(cba.compareTo(expectedFinalCBA), 0);
+
+ }
+
+ @Test(groups = {"slow"})
public void testAccountBalanceWithAllSortsOfThings() {
final UUID accountId = UUID.randomUUID();
final UUID bundleId = UUID.randomUUID();
@@ -638,7 +782,7 @@ public class InvoiceDaoTests extends InvoiceDaoTestBase {
}
- @Test
+ @Test(groups = {"slow"})
public void testGetUnpaidInvoicesByAccountId() {
final UUID accountId = UUID.randomUUID();
final UUID bundleId = UUID.randomUUID();
@@ -699,7 +843,7 @@ public class InvoiceDaoTests extends InvoiceDaoTestBase {
* this test verifies that immediate changes give the correct results
*
*/
- @Test
+ @Test(groups = {"slow"})
public void testInvoiceGenerationForImmediateChanges() throws InvoiceApiException, CatalogApiException {
final UUID accountId = UUID.randomUUID();
final List<Invoice> invoiceList = new ArrayList<Invoice>();
@@ -754,7 +898,7 @@ public class InvoiceDaoTests extends InvoiceDaoTestBase {
assertEquals(savedInvoice2.getBalance(), FIFTEEN);
}
- @Test
+ @Test(groups = {"slow"})
public void testInvoiceForFreeTrial() throws InvoiceApiException, CatalogApiException {
final Currency currency = Currency.USD;
final DefaultPrice price = new DefaultPrice(BigDecimal.ZERO, Currency.USD);
@@ -786,7 +930,7 @@ public class InvoiceDaoTests extends InvoiceDaoTestBase {
return subscription;
}
- @Test
+ @Test(groups = {"slow"})
public void testInvoiceForFreeTrialWithRecurringDiscount() throws InvoiceApiException, CatalogApiException {
final Currency currency = Currency.USD;
@@ -845,14 +989,14 @@ public class InvoiceDaoTests extends InvoiceDaoTestBase {
//invoiceDao.create(invoice3, context);
}
- @Test
+ @Test(groups = {"slow"})
public void testInvoiceForEmptyEventSet() throws InvoiceApiException {
final BillingEventSet events = new MockBillingEventSet();
final Invoice invoice = generator.generateInvoice(UUID.randomUUID(), events, null, new DateTime(), Currency.USD);
assertNull(invoice);
}
- @Test
+ @Test(groups = {"slow"})
public void testMixedModeInvoicePersistence() throws InvoiceApiException, CatalogApiException {
final Currency currency = Currency.USD;
final DefaultPrice zeroPrice = new DefaultPrice(BigDecimal.ZERO, Currency.USD);
@@ -895,7 +1039,7 @@ public class InvoiceDaoTests extends InvoiceDaoTestBase {
assertEquals(savedInvoice.getBalance().compareTo(cheapAmount), 0);
}
- @Test
+ @Test(groups = {"slow"})
public void testInvoiceNumber() throws InvoiceApiException {
final Currency currency = Currency.USD;
final DateTime targetDate1 = DateTime.now().plusMonths(1);
@@ -938,7 +1082,7 @@ public class InvoiceDaoTests extends InvoiceDaoTestBase {
assertNotNull(invoice2.getInvoiceNumber());
}
- @Test
+ @Test(groups = {"slow"})
public void testAddingWrittenOffTag() throws InvoiceApiException, TagApiException {
final Subscription subscription = getZombieSubscription();
@@ -969,7 +1113,7 @@ public class InvoiceDaoTests extends InvoiceDaoTestBase {
assertTrue(tags.containsKey(ControlTagType.WRITTEN_OFF.toString()));
}
- @Test
+ @Test(groups = {"slow"})
public void testRemoveWrittenOffTag() throws InvoiceApiException, TagApiException {
final Subscription subscription = getZombieSubscription();
diff --git a/payment/src/main/java/com/ning/billing/payment/core/PaymentProcessor.java b/payment/src/main/java/com/ning/billing/payment/core/PaymentProcessor.java
index 20e30b5..03c38ef 100644
--- a/payment/src/main/java/com/ning/billing/payment/core/PaymentProcessor.java
+++ b/payment/src/main/java/com/ning/billing/payment/core/PaymentProcessor.java
@@ -1,4 +1,4 @@
-/*
+/*
* Copyright 2010-2011 Ning, Inc.
*
* Ning licenses this file to you under the Apache License, version 2.0
@@ -303,11 +303,11 @@ public class PaymentProcessor extends ProcessorBase {
payment = paymentDao.getPayment(paymentInput.getId());
invoicePaymentApi.notifyOfPaymentAttempt(invoice.getId(),
- paymentStatus == PaymentStatus.SUCCESS ? payment.getAmount() : null,
- paymentStatus == PaymentStatus.SUCCESS ? payment.getCurrency() : null,
- lastAttempt.getId(),
- lastAttempt.getEffectiveDate(),
- context);
+ payment.getAmount(),
+ paymentStatus == PaymentStatus.SUCCESS ? payment.getCurrency() : null,
+ lastAttempt.getId(),
+ lastAttempt.getEffectiveDate(),
+ context);
// Create Bus event
event = new DefaultPaymentInfoEvent(account.getId(),