killbill-aplcache
Changes
invoice/src/main/java/com/ning/billing/invoice/template/formatters/DefaultInvoiceFormatter.java 9(+7 -2)
Details
diff --git a/api/src/main/java/com/ning/billing/invoice/api/Invoice.java b/api/src/main/java/com/ning/billing/invoice/api/Invoice.java
index 9f21b11..bf7fd7b 100644
--- a/api/src/main/java/com/ning/billing/invoice/api/Invoice.java
+++ b/api/src/main/java/com/ning/billing/invoice/api/Invoice.java
@@ -57,7 +57,9 @@ public interface Invoice extends Entity {
BigDecimal getAmountPaid();
- BigDecimal getTotalAmount();
+ BigDecimal getAmountCharged();
+
+ BigDecimal getAmountCredited();
BigDecimal getBalance();
diff --git a/invoice/src/main/java/com/ning/billing/invoice/model/DefaultInvoice.java b/invoice/src/main/java/com/ning/billing/invoice/model/DefaultInvoice.java
index 0de9aa4..952ff60 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/model/DefaultInvoice.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/model/DefaultInvoice.java
@@ -173,18 +173,24 @@ public class DefaultInvoice extends EntityBase implements Invoice {
}
@Override
- public BigDecimal getTotalAmount() {
- return invoiceItems.getTotalAmount();
+ public BigDecimal getAmountCharged() {
+ return invoiceItems.getAmountCharged();
+ }
+
+ @Override
+ public BigDecimal getAmountCredited() {
+ return invoiceItems.getAmountCredited();
}
@Override
public BigDecimal getBalance() {
- return getTotalAmount().subtract(getAmountPaid());
+ // credits offset payments
+ return getAmountCharged().subtract(getAmountPaid().subtract(getAmountCredited()));
}
@Override
public boolean isDueForPayment(final DateTime targetDate, final int numberOfDays) {
- if (getTotalAmount().compareTo(BigDecimal.ZERO) == 0) {
+ if (getBalance().compareTo(BigDecimal.ZERO) == 0) {
return false;
}
diff --git a/invoice/src/main/java/com/ning/billing/invoice/model/DefaultInvoiceGenerator.java b/invoice/src/main/java/com/ning/billing/invoice/model/DefaultInvoiceGenerator.java
index 8f4554d..08e19c0 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/model/DefaultInvoiceGenerator.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/model/DefaultInvoiceGenerator.java
@@ -97,17 +97,9 @@ public class DefaultInvoiceGenerator implements InvoiceGenerator {
removeCancellingInvoiceItems(existingItems);
removeDuplicatedInvoiceItems(proposedItems, existingItems);
- for (InvoiceItem existingItem : existingItems) {
- if (existingItem instanceof RecurringInvoiceItem) {
- RecurringInvoiceItem recurringItem = (RecurringInvoiceItem) existingItem;
- proposedItems.add(recurringItem.asReversingItem());
- }
- }
-
- BigDecimal creditAmount = calculateCreditAmountToUse(existingItems, proposedItems);
- if (creditAmount.compareTo(BigDecimal.ZERO) > 0) {
- proposedItems.add(new CreditInvoiceItem(invoiceId, accountId, clock.getUTCNow(), creditAmount.negate(), targetCurrency));
- }
+ addReversingItems(existingItems, proposedItems);
+ generateCreditsForPastRepairedInvoices(accountId, existingInvoices, proposedItems, targetCurrency);
+ consumeExistingCredit(invoiceId, accountId, existingItems, proposedItems, targetCurrency);
if (proposedItems == null || proposedItems.size() == 0) {
return null;
@@ -118,54 +110,75 @@ public class DefaultInvoiceGenerator implements InvoiceGenerator {
}
}
- private BigDecimal calculateCreditAmountToUse(List<InvoiceItem> existingItems, List<InvoiceItem> proposedItems) {
- BigDecimal totalUnusedCreditAmount = BigDecimal.ZERO;
- for (InvoiceItem item : existingItems) {
- if (item instanceof CreditInvoiceItem) {
- totalUnusedCreditAmount = totalUnusedCreditAmount.add(item.getAmount());
+ private void generateCreditsForPastRepairedInvoices(UUID accountId, List<Invoice> existingInvoices, List<InvoiceItem> proposedItems, Currency currency) {
+ // determine most accurate invoice balances up to this point
+ Map<UUID, BigDecimal> amountOwedByInvoice = new HashMap<UUID, BigDecimal>();
+
+ if (existingInvoices != null) {
+ for (Invoice invoice : existingInvoices) {
+ amountOwedByInvoice.put(invoice.getId(), invoice.getBalance());
}
}
- BigDecimal totalAmountOwed = BigDecimal.ZERO;
for (InvoiceItem item : proposedItems) {
- // there should be no credit items proposed at this point, but remove them anyhow
- if (!(item instanceof CreditInvoiceItem)) {
- totalAmountOwed = totalAmountOwed.add(item.getAmount());
+ UUID invoiceId = item.getInvoiceId();
+ if (amountOwedByInvoice.containsKey(invoiceId)) {
+ amountOwedByInvoice.put(invoiceId, amountOwedByInvoice.get(invoiceId).add(item.getAmount()));
+ } else {
+ amountOwedByInvoice.put(invoiceId, item.getAmount());
}
}
- if (totalUnusedCreditAmount.compareTo(BigDecimal.ZERO) == 0) {
- return BigDecimal.ZERO;
- } else {
- if (totalAmountOwed.compareTo(totalUnusedCreditAmount) > 0) {
- return totalUnusedCreditAmount;
- } else {
- return totalAmountOwed;
+ for (UUID invoiceId : amountOwedByInvoice.keySet()) {
+ BigDecimal invoiceBalance = amountOwedByInvoice.get(invoiceId);
+ if (invoiceBalance.compareTo(BigDecimal.ZERO) < 0) {
+ proposedItems.add(new CreditInvoiceItem(invoiceId, accountId, clock.getUTCNow(), invoiceBalance.negate(), currency));
}
}
}
- @Override
- public void distributeItems(List<Invoice> invoices) {
- Map<UUID, Invoice> invoiceMap = new HashMap<UUID, Invoice>();
-
- for (Invoice invoice : invoices) {
- invoiceMap.put(invoice.getId(), invoice);
+ private void addReversingItems(List<InvoiceItem> existingItems, List<InvoiceItem> proposedItems) {
+ for (InvoiceItem existingItem : existingItems) {
+ if (existingItem instanceof RecurringInvoiceItem) {
+ RecurringInvoiceItem recurringItem = (RecurringInvoiceItem) existingItem;
+ proposedItems.add(recurringItem.asReversingItem());
+ }
}
+ }
- for (final Invoice invoice: invoices) {
- Iterator<InvoiceItem> itemIterator = invoice.getInvoiceItems().iterator();
- final UUID invoiceId = invoice.getId();
+ private void consumeExistingCredit(UUID invoiceId, UUID accountId, List<InvoiceItem> existingItems,
+ List<InvoiceItem> proposedItems, Currency targetCurrency) {
+ BigDecimal totalUnusedCreditAmount = BigDecimal.ZERO;
+ BigDecimal totalAmountOwed = BigDecimal.ZERO;
- while (itemIterator.hasNext()) {
- InvoiceItem item = itemIterator.next();
+ for (InvoiceItem item : existingItems) {
+ if (item instanceof CreditInvoiceItem) {
+ totalUnusedCreditAmount = totalUnusedCreditAmount.add(item.getAmount());
+ }
+ }
- if (!item.getInvoiceId().equals(invoiceId)) {
- invoiceMap.get(item.getInvoiceId()).addInvoiceItem(item);
- itemIterator.remove();
- }
+ for (InvoiceItem item : proposedItems) {
+ if (item instanceof CreditInvoiceItem) {
+ totalUnusedCreditAmount = totalUnusedCreditAmount.add(item.getAmount());
+ } else {
+ totalAmountOwed = totalAmountOwed.add(item.getAmount());
}
}
+
+ // credits are positive when they reduce the amount owed (since they offset payment)
+ // the credit balance should never be negative
+ BigDecimal creditAmount = BigDecimal.ZERO;
+ if (totalUnusedCreditAmount.compareTo(BigDecimal.ZERO) > 0) {
+ if (totalAmountOwed.abs().compareTo(totalUnusedCreditAmount.abs()) > 0) {
+ creditAmount = totalUnusedCreditAmount.negate();
+ } else {
+ creditAmount = totalAmountOwed;
+ }
+ }
+
+ if (creditAmount.compareTo(BigDecimal.ZERO) < 0) {
+ proposedItems.add(new CreditInvoiceItem(invoiceId, accountId, clock.getUTCNow(), creditAmount, targetCurrency));
+ }
}
private void validateTargetDate(DateTime targetDate) throws InvoiceApiException {
diff --git a/invoice/src/main/java/com/ning/billing/invoice/model/InvoiceGenerator.java b/invoice/src/main/java/com/ning/billing/invoice/model/InvoiceGenerator.java
index e1c7e00..0b47099 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/model/InvoiceGenerator.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/model/InvoiceGenerator.java
@@ -31,6 +31,4 @@ import com.ning.billing.junction.api.BillingEventSet;
public interface InvoiceGenerator {
public Invoice generateInvoice(UUID accountId, @Nullable BillingEventSet events, @Nullable List<Invoice> existingInvoices,
DateTime targetDate, Currency targetCurrency) throws InvoiceApiException;
-
- public void distributeItems(List<Invoice> invoices);
}
diff --git a/invoice/src/main/java/com/ning/billing/invoice/model/InvoiceItemList.java b/invoice/src/main/java/com/ning/billing/invoice/model/InvoiceItemList.java
index 683bbaf..357c7a8 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/model/InvoiceItemList.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/model/InvoiceItemList.java
@@ -34,55 +34,33 @@ public class InvoiceItemList extends ArrayList<InvoiceItem> {
this.addAll(invoiceItems);
}
- public BigDecimal getTotalAmount() {
+ public BigDecimal getAmountCharged() {
// naive implementation, assumes all invoice items share the same currency
BigDecimal total = BigDecimal.ZERO.setScale(NUMBER_OF_DECIMALS, ROUNDING_METHOD);
for (final InvoiceItem item : this) {
- if (item.getAmount() != null) {
- total = total.add(item.getAmount());
+ if (!(item instanceof CreditInvoiceItem)) {
+ if (item.getAmount() != null) {
+ total = total.add(item.getAmount());
+ }
}
}
return total.setScale(NUMBER_OF_DECIMALS, ROUNDING_METHOD);
}
-// public void removeCancellingPairs() {
-// List<InvoiceItem> itemsToRemove = new ArrayList<InvoiceItem>();
-//
-// for (int firstItemIndex = 0; firstItemIndex < this.size(); firstItemIndex++) {
-// for (int secondItemIndex = firstItemIndex + 1; secondItemIndex < this.size(); secondItemIndex++) {
-// InvoiceItem firstItem = this.get(firstItemIndex);
-// InvoiceItem secondItem = this.get(secondItemIndex);
-// if (firstItem.cancels(secondItem)) {
-// itemsToRemove.add(firstItem);
-// itemsToRemove.add(secondItem);
-// }
-// }
-// }
-//
-// this.removeAll(itemsToRemove);
-// }
+ public BigDecimal getAmountCredited() {
+ // naive implementation, assumes all invoice items share the same currency
+ BigDecimal total = BigDecimal.ZERO.setScale(NUMBER_OF_DECIMALS, ROUNDING_METHOD);
+
+ for (final InvoiceItem item : this) {
+ if (item instanceof CreditInvoiceItem) {
+ if (item.getAmount() != null) {
+ total = total.add(item.getAmount());
+ }
+ }
+ }
-// /*
-// * removes recurring items from the list that have a recurring amount of zero, but a recurring rate that is not zero
-// */
-// public void cleanupDuplicatedItems() {
-// Iterator<InvoiceItem> iterator = this.iterator();
-// while (iterator.hasNext()) {
-// InvoiceItem item = iterator.next();
-//
-// if (item instanceof RecurringInvoiceItem) {
-// RecurringInvoiceItem that = (RecurringInvoiceItem) item;
-// boolean recurringRateNull = (that.getRate() == null);
-// boolean recurringAmountZero = (that.getAmount() !=null) && (that.getAmount().compareTo(BigDecimal.ZERO) == 0);
-//
-// if (recurringRateNull || recurringAmountZero) {
-// iterator.remove();
-// } else if (that.getEndDate() != null && that.getStartDate().compareTo(that.getEndDate()) == 0) {
-// iterator.remove();
-// }
-// }
-// }
-// }
+ return total.setScale(NUMBER_OF_DECIMALS, ROUNDING_METHOD);
+ }
}
diff --git a/invoice/src/main/java/com/ning/billing/invoice/template/formatters/DefaultInvoiceFormatter.java b/invoice/src/main/java/com/ning/billing/invoice/template/formatters/DefaultInvoiceFormatter.java
index ed50d2e..1ca7824 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/template/formatters/DefaultInvoiceFormatter.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/template/formatters/DefaultInvoiceFormatter.java
@@ -120,8 +120,13 @@ public class DefaultInvoiceFormatter implements InvoiceFormatter {
}
@Override
- public BigDecimal getTotalAmount() {
- return invoice.getTotalAmount();
+ public BigDecimal getAmountCharged() {
+ return invoice.getAmountCharged();
+ }
+
+ @Override
+ public BigDecimal getAmountCredited() {
+ return invoice.getAmountCredited();
}
@Override
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 e47e152..97d7532 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
@@ -80,7 +80,7 @@ public class InvoiceDaoTests extends InvoiceDaoTestBase {
assertTrue(thisInvoice.getInvoiceDate().compareTo(invoiceDate) == 0);
assertEquals(thisInvoice.getCurrency(), Currency.USD);
assertEquals(thisInvoice.getNumberOfItems(), 0);
- assertTrue(thisInvoice.getTotalAmount().compareTo(BigDecimal.ZERO) == 0);
+ assertTrue(thisInvoice.getBalance().compareTo(BigDecimal.ZERO) == 0);
}
@Test
@@ -100,7 +100,7 @@ public class InvoiceDaoTests extends InvoiceDaoTestBase {
Invoice savedInvoice = invoiceDao.getById(invoiceId);
assertNotNull(savedInvoice);
- assertEquals(savedInvoice.getTotalAmount().compareTo(new BigDecimal("21.00")), 0);
+ assertEquals(savedInvoice.getBalance().compareTo(new BigDecimal("21.00")), 0);
assertEquals(savedInvoice.getBalance().compareTo(new BigDecimal("21.00")), 0);
assertEquals(savedInvoice.getAmountPaid(), BigDecimal.ZERO);
assertEquals(savedInvoice.getInvoiceItems().size(), 1);
@@ -113,7 +113,7 @@ public class InvoiceDaoTests extends InvoiceDaoTestBase {
Invoice retrievedInvoice = invoiceDao.getById(invoiceId);
assertNotNull(retrievedInvoice);
assertEquals(retrievedInvoice.getInvoiceItems().size(), 1);
- assertEquals(retrievedInvoice.getTotalAmount().compareTo(new BigDecimal("21.00")), 0);
+ assertEquals(retrievedInvoice.getAmountCharged().compareTo(new BigDecimal("21.00")), 0);
assertEquals(retrievedInvoice.getBalance().compareTo(new BigDecimal("10.00")), 0);
assertEquals(retrievedInvoice.getAmountPaid().compareTo(new BigDecimal("11.00")), 0);
}
@@ -447,10 +447,10 @@ public class InvoiceDaoTests extends InvoiceDaoTestBase {
invoiceDao.create(invoice2, context);
Invoice savedInvoice1 = invoiceDao.getById(invoice1.getId());
- assertEquals(savedInvoice1.getTotalAmount(), ZERO);
+ assertEquals(savedInvoice1.getBalance(), ZERO);
Invoice savedInvoice2 = invoiceDao.getById(invoice2.getId());
- assertEquals(savedInvoice2.getTotalAmount(), FIFTEEN);
+ assertEquals(savedInvoice2.getBalance(), FIFTEEN);
}
@Test
@@ -475,7 +475,7 @@ public class InvoiceDaoTests extends InvoiceDaoTestBase {
// expect one pro-ration item and one full-period item
assertEquals(invoice.getNumberOfItems(), 2);
- assertEquals(invoice.getTotalAmount().compareTo(ZERO), 0);
+ assertEquals(invoice.getBalance().compareTo(ZERO), 0);
}
private Subscription getZombieSubscription() {
@@ -513,7 +513,7 @@ public class InvoiceDaoTests extends InvoiceDaoTestBase {
Invoice invoice1 = generator.generateInvoice(accountId, events, null, effectiveDate1, Currency.USD);
assertNotNull(invoice1);
assertEquals(invoice1.getNumberOfItems(), 1);
- assertEquals(invoice1.getTotalAmount().compareTo(ZERO), 0);
+ assertEquals(invoice1.getBalance().compareTo(ZERO), 0);
List<Invoice> invoiceList = new ArrayList<Invoice>();
invoiceList.add(invoice1);
@@ -527,7 +527,7 @@ public class InvoiceDaoTests extends InvoiceDaoTestBase {
Invoice invoice2 = generator.generateInvoice(accountId, events, invoiceList, effectiveDate2, Currency.USD);
assertNotNull(invoice2);
assertEquals(invoice2.getNumberOfItems(), 1);
- assertEquals(invoice2.getTotalAmount().compareTo(cheapAmount), 0);
+ assertEquals(invoice2.getBalance().compareTo(cheapAmount), 0);
invoiceList.add(invoice2);
@@ -535,7 +535,7 @@ public class InvoiceDaoTests extends InvoiceDaoTestBase {
Invoice invoice3 = generator.generateInvoice(accountId, events, invoiceList, effectiveDate3, Currency.USD);
assertNotNull(invoice3);
assertEquals(invoice3.getNumberOfItems(), 1);
- assertEquals(invoice3.getTotalAmount().compareTo(cheapAmount), 0);
+ assertEquals(invoice3.getBalance().compareTo(cheapAmount), 0);
}
@Test
@@ -578,14 +578,14 @@ public class InvoiceDaoTests extends InvoiceDaoTestBase {
Invoice invoice = generator.generateInvoice(UUID.randomUUID(), events, null, effectiveDate2, Currency.USD);
assertNotNull(invoice);
assertEquals(invoice.getNumberOfItems(), 2);
- assertEquals(invoice.getTotalAmount().compareTo(cheapAmount), 0);
+ assertEquals(invoice.getBalance().compareTo(cheapAmount), 0);
invoiceDao.create(invoice, context);
Invoice savedInvoice = invoiceDao.getById(invoice.getId());
assertNotNull(savedInvoice);
assertEquals(savedInvoice.getNumberOfItems(), 2);
- assertEquals(savedInvoice.getTotalAmount().compareTo(cheapAmount), 0);
+ assertEquals(savedInvoice.getBalance().compareTo(cheapAmount), 0);
}
@Test
diff --git a/invoice/src/test/java/com/ning/billing/invoice/MockBillingEventSet.java b/invoice/src/test/java/com/ning/billing/invoice/MockBillingEventSet.java
index 3ab1f0d..80db3b8 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/MockBillingEventSet.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/MockBillingEventSet.java
@@ -30,7 +30,11 @@ public class MockBillingEventSet extends TreeSet<BillingEvent> implements Billin
private boolean isAccountInvoiceOff;
private List<UUID> subscriptionIdsWithAutoInvoiceOff = new ArrayList<UUID>();
-
+
+ public void addSubscriptionWithAutoInvoiceOff(UUID subscriptionId) {
+ subscriptionIdsWithAutoInvoiceOff.add(subscriptionId);
+ }
+
@Override
public boolean isLast(BillingEvent event) {
return isAccountInvoiceOff;
@@ -46,4 +50,7 @@ public class MockBillingEventSet extends TreeSet<BillingEvent> implements Billin
return subscriptionIdsWithAutoInvoiceOff;
}
+ public void clearSubscriptionsWithAutoInvoiceOff() {
+ subscriptionIdsWithAutoInvoiceOff.clear();
+ }
}
diff --git a/invoice/src/test/java/com/ning/billing/invoice/tests/DefaultInvoiceGeneratorTests.java b/invoice/src/test/java/com/ning/billing/invoice/tests/DefaultInvoiceGeneratorTests.java
index bf63662..54dae8c 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/tests/DefaultInvoiceGeneratorTests.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/tests/DefaultInvoiceGeneratorTests.java
@@ -19,11 +19,15 @@ package com.ning.billing.invoice.tests;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertNull;
+import static org.testng.Assert.assertTrue;
import static org.testng.Assert.fail;
import java.math.BigDecimal;
import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
import java.util.List;
+import java.util.Map;
import java.util.UUID;
import javax.annotation.Nullable;
@@ -128,7 +132,7 @@ public class DefaultInvoiceGeneratorTests extends InvoicingTestBase {
assertNotNull(invoice);
assertEquals(invoice.getNumberOfItems(), 2);
- assertEquals(invoice.getTotalAmount(), TWENTY);
+ assertEquals(invoice.getBalance(), TWENTY);
assertEquals(invoice.getInvoiceItems().get(0).getSubscriptionId(), sub.getId());
}
@@ -167,7 +171,7 @@ public class DefaultInvoiceGeneratorTests extends InvoicingTestBase {
BigDecimal expectedNumberOfBillingCycles;
expectedNumberOfBillingCycles = ONE.add(FOURTEEN.divide(THIRTY_ONE, 2 * NUMBER_OF_DECIMALS, ROUNDING_METHOD));
BigDecimal expectedAmount = expectedNumberOfBillingCycles.multiply(rate).setScale(NUMBER_OF_DECIMALS, ROUNDING_METHOD);
- assertEquals(invoice.getTotalAmount(), expectedAmount);
+ assertEquals(invoice.getBalance(), expectedAmount);
}
@Test
@@ -196,7 +200,7 @@ public class DefaultInvoiceGeneratorTests extends InvoicingTestBase {
assertNotNull(invoice);
assertEquals(invoice.getNumberOfItems(), 2);
- assertEquals(invoice.getTotalAmount(), rate1.add(rate2).setScale(NUMBER_OF_DECIMALS));
+ assertEquals(invoice.getBalance(), rate1.add(rate2).setScale(NUMBER_OF_DECIMALS));
}
@Test
@@ -233,7 +237,7 @@ public class DefaultInvoiceGeneratorTests extends InvoicingTestBase {
expectedValue = expectedValue.add(numberOfCyclesEvent2.multiply(rate2));
expectedValue = expectedValue.setScale(NUMBER_OF_DECIMALS, ROUNDING_METHOD);
- assertEquals(invoice.getTotalAmount(), expectedValue);
+ assertEquals(invoice.getBalance(), expectedValue);
}
@Test
@@ -264,7 +268,7 @@ public class DefaultInvoiceGeneratorTests extends InvoicingTestBase {
assertNotNull(invoice);
assertEquals(invoice.getNumberOfItems(), 4);
- assertEquals(invoice.getTotalAmount(), rate1.add(rate2).add(TWO.multiply(rate3)).setScale(NUMBER_OF_DECIMALS));
+ assertEquals(invoice.getBalance(), rate1.add(rate2).add(TWO.multiply(rate3)).setScale(NUMBER_OF_DECIMALS));
}
@Test
@@ -293,6 +297,7 @@ public class DefaultInvoiceGeneratorTests extends InvoicingTestBase {
assertNull(invoice2);
}
+ // TODO: modify this test to keep a running total of expected invoice amount over time
@Test
public void testMultiplePlansWithUtterChaos() throws InvoiceApiException, CatalogApiException {
// plan 1: change of phase from trial to discount followed by immediate cancellation; (covers phase change, cancel, pro-ration)
@@ -376,7 +381,8 @@ public class DefaultInvoiceGeneratorTests extends InvoicingTestBase {
// on 4/29/2011, cancel subscription 1
events.add(createBillingEvent(subscriptionId1, plan1CancelDate, plan1, plan1Phase3, 5));
- expectedAmount = TWELVE.multiply(SIX.divide(THIRTY, NUMBER_OF_DECIMALS, ROUNDING_METHOD)).negate().setScale(NUMBER_OF_DECIMALS);
+ // previous invoices are adjusted; this is the pro-ration amount only
+ expectedAmount = TWELVE.multiply(TWENTY_FOUR.divide(THIRTY, NUMBER_OF_DECIMALS, ROUNDING_METHOD)).setScale(NUMBER_OF_DECIMALS);
testInvoiceGeneration(accountId, events, invoices, plan1CancelDate, 2, expectedAmount);
// on 5/10/2011, invoice subscription 2 (trial)
@@ -421,8 +427,7 @@ public class DefaultInvoiceGeneratorTests extends InvoicingTestBase {
// on 7/31/2011, convert subscription 3 to annual
events.add(createBillingEvent(subscriptionId3, plan3UpgradeToAnnualDate, plan3, plan3Phase2, 31));
- expectedAmount = ONE_HUNDRED.subtract(TEN);
- expectedAmount = expectedAmount.add(TEN.multiply(ELEVEN.divide(THIRTY_ONE, 2 * NUMBER_OF_DECIMALS, ROUNDING_METHOD)));
+ expectedAmount = ONE_HUNDRED.add(TEN.multiply(ELEVEN.divide(THIRTY_ONE, 2 * NUMBER_OF_DECIMALS, ROUNDING_METHOD)));
expectedAmount = expectedAmount.setScale(NUMBER_OF_DECIMALS, ROUNDING_METHOD);
testInvoiceGeneration(accountId, events, invoices, plan3UpgradeToAnnualDate, 3, expectedAmount);
@@ -446,7 +451,7 @@ public class DefaultInvoiceGeneratorTests extends InvoicingTestBase {
// on 10/7/2011, invoice subscription 4 (plan 2), cancel subscription 5
events.add(createBillingEvent(subscriptionId5, plan5CancelDate, plan5, plan5Phase2, 10));
- expectedAmount = TWENTY_FOUR.add(TWENTY.multiply(THREE.divide(THIRTY)).negate().setScale(NUMBER_OF_DECIMALS));
+ expectedAmount = TWENTY_FOUR.add(TWENTY.multiply(TWENTY_SEVEN.divide(THIRTY)).setScale(NUMBER_OF_DECIMALS));
testInvoiceGeneration(accountId, events, invoices, plan5CancelDate, 3, expectedAmount);
// on 10/10/2011, invoice plan 2 (evergreen)
@@ -545,7 +550,7 @@ public class DefaultInvoiceGeneratorTests extends InvoicingTestBase {
Invoice invoice1 = generator.generateInvoice(accountId, events, null, startDate, Currency.USD);
assertNotNull(invoice1);
assertEquals(invoice1.getNumberOfItems(), 2);
- assertEquals(invoice1.getTotalAmount(), FIFTEEN);
+ assertEquals(invoice1.getBalance(), FIFTEEN);
List<Invoice> invoiceList = new ArrayList<Invoice>();
invoiceList.add(invoice1);
@@ -557,7 +562,7 @@ public class DefaultInvoiceGeneratorTests extends InvoicingTestBase {
Invoice invoice2 = generator.generateInvoice(accountId, events, invoiceList, currentDate, Currency.USD);
assertNotNull(invoice2);
assertEquals(invoice2.getNumberOfItems(), 1);
- assertEquals(invoice2.getTotalAmount(), FIVE);
+ assertEquals(invoice2.getBalance(), FIVE);
}
@Test
@@ -581,7 +586,7 @@ public class DefaultInvoiceGeneratorTests extends InvoicingTestBase {
Invoice invoice1 = generator.generateInvoice(accountId, events, null, startDate, Currency.USD);
assertNotNull(invoice1);
assertEquals(invoice1.getNumberOfItems(), 1);
- assertEquals(invoice1.getTotalAmount(), fixedCost1);
+ assertEquals(invoice1.getBalance(), fixedCost1);
List<Invoice> invoiceList = new ArrayList<Invoice>();
invoiceList.add(invoice1);
@@ -595,11 +600,11 @@ public class DefaultInvoiceGeneratorTests extends InvoicingTestBase {
Invoice invoice2 = generator.generateInvoice(accountId, events, invoiceList, phaseChangeDate, Currency.USD);
assertNotNull(invoice2);
assertEquals(invoice2.getNumberOfItems(), 1);
- assertEquals(invoice2.getTotalAmount(), fixedCost2);
+ assertEquals(invoice2.getBalance(), fixedCost2);
}
@Test
- public void testNutsFailure() throws InvoiceApiException, CatalogApiException {
+ public void testInvoiceGenerationFailureScenario() throws InvoiceApiException, CatalogApiException {
BillingEventSet events = new MockBillingEventSet();
UUID subscriptionId = UUID.randomUUID();
UUID accountId = UUID.randomUUID();
@@ -627,7 +632,7 @@ public class DefaultInvoiceGeneratorTests extends InvoicingTestBase {
Invoice invoice1 = generator.generateInvoice(accountId, events, null, creationDate, Currency.USD);
assertNotNull(invoice1);
assertEquals(invoice1.getNumberOfItems(), 1);
- assertEquals(invoice1.getTotalAmount().compareTo(ZERO), 0);
+ assertEquals(invoice1.getBalance().compareTo(ZERO), 0);
List<Invoice> invoiceList = new ArrayList<Invoice>();
invoiceList.add(invoice1);
@@ -636,7 +641,7 @@ public class DefaultInvoiceGeneratorTests extends InvoicingTestBase {
assertNotNull(invoice2);
assertEquals(invoice2.getNumberOfItems(), 1);
assertEquals(invoice2.getInvoiceItems().get(0).getStartDate().compareTo(trialPhaseEndDate), 0);
- assertEquals(invoice2.getTotalAmount().compareTo(new BigDecimal("3.21")), 0);
+ assertEquals(invoice2.getBalance().compareTo(new BigDecimal("3.21")), 0);
invoiceList.add(invoice2);
DateTime targetDate = trialPhaseEndDate.toMutableDateTime().dayOfMonth().set(BILL_CYCLE_DAY).toDateTime();
@@ -644,7 +649,7 @@ public class DefaultInvoiceGeneratorTests extends InvoicingTestBase {
assertNotNull(invoice3);
assertEquals(invoice3.getNumberOfItems(), 1);
assertEquals(invoice3.getInvoiceItems().get(0).getStartDate().compareTo(targetDate), 0);
- assertEquals(invoice3.getTotalAmount().compareTo(DISCOUNT_PRICE), 0);
+ assertEquals(invoice3.getBalance().compareTo(DISCOUNT_PRICE), 0);
invoiceList.add(invoice3);
targetDate = targetDate.plusMonths(6);
@@ -710,9 +715,10 @@ public class DefaultInvoiceGeneratorTests extends InvoicingTestBase {
Invoice invoice = generator.generateInvoice(accountId, events, existingInvoices, targetDate, currency);
assertNotNull(invoice);
assertEquals(invoice.getNumberOfItems(), expectedNumberOfItems);
-
existingInvoices.add(invoice);
- assertEquals(invoice.getTotalAmount(), expectedAmount);
+
+ distributeItems(existingInvoices);
+ assertEquals(invoice.getBalance(), expectedAmount);
}
@Test
@@ -736,7 +742,7 @@ public class DefaultInvoiceGeneratorTests extends InvoicingTestBase {
Invoice invoice1 = generator.generateInvoice(accountId, events, null, april25, Currency.USD);
assertNotNull(invoice1);
assertEquals(invoice1.getNumberOfItems(), 1);
- assertEquals(invoice1.getTotalAmount().compareTo(TEN), 0);
+ assertEquals(invoice1.getBalance().compareTo(TEN), 0);
List<Invoice> invoices = new ArrayList<Invoice>();
invoices.add(invoice1);
@@ -758,7 +764,7 @@ public class DefaultInvoiceGeneratorTests extends InvoicingTestBase {
invoices.add(invoice2);
assertNotNull(invoice2);
assertEquals(invoice2.getNumberOfItems(), 2);
- assertEquals(invoice2.getTotalAmount().compareTo(TWENTY_FIVE.multiply(new BigDecimal("0.9")).setScale(NUMBER_OF_DECIMALS, ROUNDING_METHOD)), 0);
+ assertEquals(invoice2.getBalance().compareTo(TWENTY_FIVE.multiply(new BigDecimal("0.9")).setScale(NUMBER_OF_DECIMALS, ROUNDING_METHOD)), 0);
// perform a repair (change base plan; remove one add-on)
// event stream should include just two plans
@@ -775,10 +781,10 @@ public class DefaultInvoiceGeneratorTests extends InvoicingTestBase {
assertNotNull(invoice3);
assertEquals(invoice3.getNumberOfItems(), 5);
// -4.50 -18 - 10 (to correct the previous 2 invoices) + 4.50 + 13
- assertEquals(invoice3.getTotalAmount().compareTo(FIFTEEN.negate()), 0);
+ assertEquals(invoice3.getBalance().compareTo(FIFTEEN.negate()), 0);
}
- @Test(enabled=false)
+ @Test
public void testRepairForPaidInvoice() throws CatalogApiException, InvoiceApiException {
// create an invoice
DateTime april25 = new DateTime(2012, 4, 25, 0, 0, 0, 0);
@@ -795,6 +801,7 @@ public class DefaultInvoiceGeneratorTests extends InvoicingTestBase {
events.add(createBillingEvent(originalSubscription.getId(), april25, originalPlan, originalPlanEvergreen, 25));
Invoice invoice1 = generator.generateInvoice(accountId, events, null, april25, Currency.USD);
+ assertEquals(invoice1.getNumberOfItems(), 1);
List<Invoice> invoices = new ArrayList<Invoice>();
invoices.add(invoice1);
@@ -812,34 +819,94 @@ public class DefaultInvoiceGeneratorTests extends InvoicingTestBase {
// generate a new invoice
Invoice invoice2 = generator.generateInvoice(accountId, events, invoices, april25, Currency.USD);
+ assertEquals(invoice2.getNumberOfItems(), 4);
invoices.add(invoice2);
// move items to the correct invoice (normally, the dao calls will sort that out)
- generator.distributeItems(invoices);
+ distributeItems(invoices);
// ensure that the original invoice balance is zero
-
assertEquals(invoice1.getBalance().compareTo(ZERO), 0);
// ensure that the account balance is correct
- assertEquals(invoice2.getBalance().compareTo(FIVE.negate()), 0);
+ assertEquals(invoice2.getBalance().compareTo(ZERO), 0);
+ // ensure that the account has a credit balance
+ BigDecimal creditBalance = invoice1.getAmountCredited().add(invoice2.getAmountCredited());
+ assertTrue(creditBalance.compareTo(FIVE) == 0);
}
- /*
- test scenario: create invoice, pay invoice, change entitlement (repair)
+ private void distributeItems(List<Invoice> invoices) {
+ Map<UUID, Invoice> invoiceMap = new HashMap<UUID, Invoice>();
+
+ for (Invoice invoice : invoices) {
+ invoiceMap.put(invoice.getId(), invoice);
+ }
+
+ for (final Invoice invoice: invoices) {
+ Iterator<InvoiceItem> itemIterator = invoice.getInvoiceItems().iterator();
+ final UUID invoiceId = invoice.getId();
+
+ while (itemIterator.hasNext()) {
+ InvoiceItem item = itemIterator.next();
+
+ if (!item.getInvoiceId().equals(invoiceId)) {
+ Invoice thisInvoice = invoiceMap.get(item.getInvoiceId());
+ if (thisInvoice == null) {
+ throw new NullPointerException();
+ }
+ thisInvoice.addInvoiceItem(item);
+ itemIterator.remove();
+ }
+ }
+ }
+ }
+
+ @Test
+ public void testAutoInvoiceOff() throws CatalogApiException, InvoiceApiException {
+ Currency currency = Currency.USD;
+ List<Invoice> invoices = new ArrayList<Invoice>();
+ MockBillingEventSet eventSet = new MockBillingEventSet();
+ UUID accountId = UUID.randomUUID();
+
+ DateTime startDate = new DateTime(2012, 1, 1, 0, 12, 34, 0);
- test scenario: two subscriptions, one with auto_invoice_off
+ // add first subscription creation event
+ UUID subscriptionId1 = UUID.randomUUID();
+ Plan plan1 = new MockPlan();
+ PlanPhase plan1phase1 = createMockMonthlyPlanPhase(FIFTEEN, null, PhaseType.DISCOUNT);
+ BillingEvent subscription1creation = createBillingEvent(subscriptionId1, startDate, plan1, plan1phase1, 1);
+ eventSet.add(subscription1creation);
- test scenario: create invoice, pay invoice, change entitlement, generate invoices to use up credits
+ // add second subscription creation event
+ UUID subscriptionId2 = UUID.randomUUID();
+ Plan plan2 = new MockPlan();
+ PlanPhase plan2phase1 = createMockMonthlyPlanPhase(TWELVE, null, PhaseType.EVERGREEN);
+ eventSet.add(createBillingEvent(subscriptionId2, startDate, plan2, plan2phase1, 1));
- test scenario: create invoice, pay invoice, add account-level credit, generate invoice
- */
+ // generate the first invoice
+ Invoice invoice1 = generator.generateInvoice(accountId, eventSet, invoices, startDate, currency);
+ assertNotNull(invoice1);
+ assertTrue(invoice1.getBalance().compareTo(FIFTEEN.add(TWELVE)) == 0);
+ invoices.add(invoice1);
+
+ // set auto invoice off for first subscription (i.e. remove event from BillingEventSet and add subscription id to the list
+ // generate invoice
+ eventSet.remove(subscription1creation);
+ eventSet.addSubscriptionWithAutoInvoiceOff(subscriptionId1);
- @Test(enabled=false)
- public void testAutoInvoiceOff() {
- //BillingEventSet eventSet = new MockBillingEventSet();
- fail();
+ DateTime targetDate2 = startDate.plusMonths(1);
+ Invoice invoice2 = generator.generateInvoice(accountId, eventSet, invoices, targetDate2, currency);
+ assertNotNull(invoice2);
+ assertTrue(invoice2.getBalance().compareTo(TWELVE) == 0);
+ invoices.add(invoice2);
+
+ DateTime targetDate3 = targetDate2.plusMonths(1);
+ eventSet.clearSubscriptionsWithAutoInvoiceOff();
+ eventSet.add(subscription1creation);
+ Invoice invoice3 = generator.generateInvoice(accountId, eventSet, invoices, targetDate3, currency);
+ assertNotNull(invoice3);
+ assertTrue(invoice3.getBalance().compareTo(FIFTEEN.multiply(TWO).add(TWELVE)) == 0);
}
@Test
@@ -860,7 +927,7 @@ public class DefaultInvoiceGeneratorTests extends InvoicingTestBase {
Invoice initialInvoice = generator.generateInvoice(accountId, billingEventSet, null, startDate, Currency.USD);
assertNotNull(initialInvoice);
assertEquals(initialInvoice.getNumberOfItems(), 1);
- assertEquals(initialInvoice.getTotalAmount().compareTo(TEN), 0);
+ assertEquals(initialInvoice.getBalance().compareTo(TEN), 0);
invoices.add(initialInvoice);
// add account-level credit
@@ -872,7 +939,7 @@ public class DefaultInvoiceGeneratorTests extends InvoicingTestBase {
// invoice one month after the initial subscription
Invoice finalInvoice = generator.generateInvoice(accountId, billingEventSet, invoices, startDate.plusMonths(1), Currency.USD);
- assertEquals(finalInvoice.getTotalAmount().compareTo(FIVE), 0);
+ assertEquals(finalInvoice.getBalance().compareTo(FIVE), 0);
assertEquals(finalInvoice.getNumberOfItems(), 2);
}
}
\ No newline at end of file
diff --git a/invoice/src/test/java/com/ning/billing/invoice/tests/InvoicingTestBase.java b/invoice/src/test/java/com/ning/billing/invoice/tests/InvoicingTestBase.java
index 25be5e2..5beea5c 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/tests/InvoicingTestBase.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/tests/InvoicingTestBase.java
@@ -62,6 +62,7 @@ public abstract class InvoicingTestBase {
protected static final BigDecimal TWENTY_FOUR = new BigDecimal("24.0").setScale(NUMBER_OF_DECIMALS);
protected static final BigDecimal TWENTY_FIVE = new BigDecimal("25.0").setScale(NUMBER_OF_DECIMALS);
+ protected static final BigDecimal TWENTY_SEVEN = new BigDecimal("27.0").setScale(NUMBER_OF_DECIMALS);
protected static final BigDecimal TWENTY_EIGHT = new BigDecimal("28.0").setScale(NUMBER_OF_DECIMALS);
protected static final BigDecimal TWENTY_NINE = new BigDecimal("29.0").setScale(NUMBER_OF_DECIMALS);
protected static final BigDecimal THIRTY = new BigDecimal("30.0").setScale(NUMBER_OF_DECIMALS);
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/AccountTimelineJson.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/AccountTimelineJson.java
index c9f627a..204cf6a 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/AccountTimelineJson.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/AccountTimelineJson.java
@@ -96,7 +96,7 @@ public class AccountTimelineJson {
}
this.invoices = new LinkedList<InvoiceJsonWithBundleKeys>();
for (Invoice cur : invoices) {
- this.invoices.add(new InvoiceJsonWithBundleKeys(cur.getTotalAmount(), cur.getId().toString(), cur.getInvoiceDate(), cur.getTargetDate(),
+ this.invoices.add(new InvoiceJsonWithBundleKeys(cur.getAmountCharged(), cur.getAmountCredited(), cur.getId().toString(), cur.getInvoiceDate(), cur.getTargetDate(),
Integer.toString(cur.getInvoiceNumber()), cur.getBalance(),
getBundleExternalKey(cur, bundles)));
}
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/InvoiceJsonSimple.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/InvoiceJsonSimple.java
index e96179e..5680db1 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/InvoiceJsonSimple.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/InvoiceJsonSimple.java
@@ -26,44 +26,35 @@ import org.joda.time.DateTime;
import com.ning.billing.invoice.api.Invoice;
public class InvoiceJsonSimple {
-
- @JsonView(BundleTimelineViews.Base.class)
private final BigDecimal amount;
-
- @JsonView(BundleTimelineViews.Base.class)
+ private final BigDecimal credit;
private final String invoiceId;
-
- @JsonView(BundleTimelineViews.Base.class)
private final DateTime invoiceDate;
-
- @JsonView(BundleTimelineViews.Base.class)
private final DateTime targetDate;
-
- @JsonView(BundleTimelineViews.Base.class)
private final String invoiceNumber;
-
- @JsonView(BundleTimelineViews.Base.class)
private final BigDecimal balance;
-
public InvoiceJsonSimple() {
- this.amount = null;
+ this.amount = BigDecimal.ZERO;
+ this.credit = BigDecimal.ZERO;
this.invoiceId = null;
this.invoiceDate = null;
this.targetDate = null;
this.invoiceNumber = null;
- this.balance = null;
+ this.balance = BigDecimal.ZERO;
}
@JsonCreator
public InvoiceJsonSimple(@JsonProperty("amount") BigDecimal amount,
- @JsonProperty("invoiceId") String invoiceId,
- @JsonProperty("invoiceDate") DateTime invoiceDate,
- @JsonProperty("targetDate") DateTime targetDate,
- @JsonProperty("invoiceNumber") String invoiceNumber,
- @JsonProperty("balance") BigDecimal balance) {
+ @JsonProperty("credit") BigDecimal credit,
+ @JsonProperty("invoiceId") String invoiceId,
+ @JsonProperty("invoiceDate") DateTime invoiceDate,
+ @JsonProperty("targetDate") DateTime targetDate,
+ @JsonProperty("invoiceNumber") String invoiceNumber,
+ @JsonProperty("balance") BigDecimal balance) {
super();
this.amount = amount;
+ this.credit = credit;
this.invoiceId = invoiceId;
this.invoiceDate = invoiceDate;
this.targetDate = targetDate;
@@ -72,7 +63,8 @@ public class InvoiceJsonSimple {
}
public InvoiceJsonSimple(Invoice input) {
- this.amount = input.getTotalAmount();
+ this.amount = input.getAmountCharged();
+ this.credit = input.getAmountCredited();
this.invoiceId = input.getId().toString();
this.invoiceDate = input.getInvoiceDate();
this.targetDate = input.getTargetDate();
@@ -84,6 +76,10 @@ public class InvoiceJsonSimple {
return amount;
}
+ public BigDecimal getCredit() {
+ return credit;
+ }
+
public String getInvoiceId() {
return invoiceId;
}
@@ -110,6 +106,7 @@ public class InvoiceJsonSimple {
int result = 1;
result = prime * result + ((amount == null) ? 0 : amount.hashCode());
result = prime * result + ((balance == null) ? 0 : balance.hashCode());
+ result = prime * result + ((credit == null) ? 0 : credit.hashCode());
result = prime * result
+ ((invoiceDate == null) ? 0 : invoiceDate.hashCode());
result = prime * result
@@ -133,26 +130,37 @@ public class InvoiceJsonSimple {
return false;
} else if (!amount.equals(other.amount))
return false;
+
if (balance == null) {
if (other.balance != null)
return false;
} else if (!balance.equals(other.balance))
return false;
+
+ if (credit == null) {
+ if (other.credit != null)
+ return false;
+ } else if (!credit.equals(other.credit))
+ return false;
+
if (invoiceDate == null) {
if (other.invoiceDate != null)
return false;
} else if (!invoiceDate.equals(other.invoiceDate))
return false;
+
if (invoiceId == null) {
if (other.invoiceId != null)
return false;
} else if (!invoiceId.equals(other.invoiceId))
return false;
+
if (invoiceNumber == null) {
if (other.invoiceNumber != null)
return false;
} else if (!invoiceNumber.equals(other.invoiceNumber))
return false;
+
return true;
}
}
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/InvoiceJsonWithBundleKeys.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/InvoiceJsonWithBundleKeys.java
index 98e2844..f1b0b4a 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/InvoiceJsonWithBundleKeys.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/InvoiceJsonWithBundleKeys.java
@@ -24,11 +24,8 @@ import com.ning.billing.invoice.api.Invoice;
*/
public class InvoiceJsonWithBundleKeys extends InvoiceJsonSimple {
-
-
private final String bundleKeys;
-
public InvoiceJsonWithBundleKeys() {
super();
this.bundleKeys = null;
@@ -36,13 +33,14 @@ public class InvoiceJsonWithBundleKeys extends InvoiceJsonSimple {
@JsonCreator
public InvoiceJsonWithBundleKeys(@JsonProperty("amount") BigDecimal amount,
- @JsonProperty("invoiceId") String invoiceId,
- @JsonProperty("invoiceDate") DateTime invoiceDate,
- @JsonProperty("targetDate") DateTime targetDate,
- @JsonProperty("invoiceNumber") String invoiceNumber,
- @JsonProperty("balance") BigDecimal balance,
- @JsonProperty("externalBundleKeys") String bundleKeys) {
- super(amount, invoiceId, invoiceDate, targetDate, invoiceNumber, balance);
+ @JsonProperty("credit") BigDecimal credit,
+ @JsonProperty("invoiceId") String invoiceId,
+ @JsonProperty("invoiceDate") DateTime invoiceDate,
+ @JsonProperty("targetDate") DateTime targetDate,
+ @JsonProperty("invoiceNumber") String invoiceNumber,
+ @JsonProperty("balance") BigDecimal balance,
+ @JsonProperty("externalBundleKeys") String bundleKeys) {
+ super(amount, credit, invoiceId, invoiceDate, targetDate, invoiceNumber, balance);
this.bundleKeys = bundleKeys;
}
diff --git a/payment/src/test/java/com/ning/billing/payment/MockInvoice.java b/payment/src/test/java/com/ning/billing/payment/MockInvoice.java
index d195b59..802b49a 100644
--- a/payment/src/test/java/com/ning/billing/payment/MockInvoice.java
+++ b/payment/src/test/java/com/ning/billing/payment/MockInvoice.java
@@ -23,6 +23,7 @@ import java.util.UUID;
import javax.annotation.Nullable;
+import com.ning.billing.invoice.api.InvoiceItemType;
import org.joda.time.DateTime;
import com.ning.billing.catalog.api.Currency;
@@ -178,23 +179,37 @@ public class MockInvoice extends EntityBase implements Invoice {
}
@Override
- public BigDecimal getTotalAmount() {
+ public BigDecimal getAmountCharged() {
BigDecimal result = BigDecimal.ZERO;
for(InvoiceItem i : invoiceItems) {
- result = result.add(i.getAmount());
+ if (!i.getInvoiceItemType().equals(InvoiceItemType.CREDIT)) {
+ result = result.add(i.getAmount());
+ }
+ }
+ return result;
+ }
+
+ @Override
+ public BigDecimal getAmountCredited() {
+ BigDecimal result = BigDecimal.ZERO;
+
+ for(InvoiceItem i : invoiceItems) {
+ if (i.getInvoiceItemType().equals(InvoiceItemType.CREDIT)) {
+ result = result.add(i.getAmount());
+ }
}
return result;
}
@Override
public BigDecimal getBalance() {
- return getTotalAmount().subtract(getAmountPaid());
+ return getAmountCharged().subtract(getAmountPaid().subtract(getAmountCredited()));
}
@Override
public boolean isDueForPayment(final DateTime targetDate, final int numberOfDays) {
- if (getTotalAmount().compareTo(BigDecimal.ZERO) == 0) {
+ if (getBalance().compareTo(BigDecimal.ZERO) == 0) {
return false;
}