diff --git a/invoice/src/main/java/org/killbill/billing/invoice/tree/ItemsNodeInterval.java b/invoice/src/main/java/org/killbill/billing/invoice/tree/ItemsNodeInterval.java
index fbb5ba5..4106f87 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/tree/ItemsNodeInterval.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/tree/ItemsNodeInterval.java
@@ -224,8 +224,10 @@ public class ItemsNodeInterval extends NodeInterval {
/**
* Add the adjustment amount on the item specified by the targetId.
+ *
+ * @return linked item if fully adjusted, null otherwise
*/
- public void addAdjustment(final InvoiceItem item) {
+ public Item addAdjustment(final InvoiceItem item) {
final UUID targetId = item.getLinkedItemId();
// TODO we should really be using findNode(adjustmentDate, callback) instead but wrong dates in test creates panic.
@@ -246,8 +248,10 @@ public class ItemsNodeInterval extends NodeInterval {
if (targetItem.getAmount().compareTo(adjustmentAmount) == 0) {
// Full item adjustment - treat it like a repair
addExistingItem(new ItemsNodeInterval(this, targetInvoiceId, new Item(item, targetItem.getStartDate(), targetItem.getEndDate(), targetInvoiceId, ItemAction.CANCEL)));
+ return targetItem;
} else {
targetItem.incrementAdjustedAmount(adjustmentAmount);
+ return null;
}
}
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/tree/SubscriptionItemTree.java b/invoice/src/main/java/org/killbill/billing/invoice/tree/SubscriptionItemTree.java
index 360216e..de29b6e 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/tree/SubscriptionItemTree.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/tree/SubscriptionItemTree.java
@@ -49,7 +49,7 @@ public class SubscriptionItemTree {
private boolean isBuilt;
private boolean isMerged;
private List<Item> items;
- private List<InvoiceItem> allExistingRecurringItems;
+ private List<Item> existingFullyAdjustedItems;
private List<InvoiceItem> existingFixedItems;
private Map<LocalDate, InvoiceItem> remainingFixedItems;
private List<InvoiceItem> pendingItemAdj;
@@ -79,7 +79,7 @@ public class SubscriptionItemTree {
this.targetInvoiceId = targetInvoiceId;
this.root = new ItemsNodeInterval(targetInvoiceId);
this.items = new LinkedList<Item>();
- this.allExistingRecurringItems = new LinkedList<InvoiceItem>();
+ this.existingFullyAdjustedItems = new LinkedList<Item>();
this.existingFixedItems = new LinkedList<InvoiceItem>();
this.remainingFixedItems = new HashMap<LocalDate, InvoiceItem>();
this.pendingItemAdj = new LinkedList<InvoiceItem>();
@@ -93,7 +93,10 @@ public class SubscriptionItemTree {
Preconditions.checkState(!isBuilt);
for (InvoiceItem item : pendingItemAdj) {
- root.addAdjustment(item);
+ final Item fullyAdjustedItem = root.addAdjustment(item);
+ if (fullyAdjustedItem != null) {
+ existingFullyAdjustedItems.add(fullyAdjustedItem);
+ }
}
pendingItemAdj.clear();
root.buildForExistingItems(items);
@@ -137,7 +140,6 @@ public class SubscriptionItemTree {
Preconditions.checkState(!isBuilt);
switch (invoiceItem.getInvoiceItemType()) {
case RECURRING:
- allExistingRecurringItems.add(invoiceItem);
root.addExistingItem(new ItemsNodeInterval(root, targetInvoiceId, new Item(invoiceItem, targetInvoiceId, ItemAction.ADD)));
break;
@@ -213,10 +215,11 @@ public class SubscriptionItemTree {
// We will ignore any resulting item matching existing items on disk though as these are the result of full item adjustments.
// See https://github.com/killbill/killbill/issues/654
if (isMerged) {
- for (final InvoiceItem existingRecurringItem : allExistingRecurringItems) {
+ for (final Item existingAdjustedItem : existingFullyAdjustedItems) {
// Note: we DO keep the item in case of partial matches, e.g. if the new proposed item end date is before
// the existing (adjusted) item. See TestSubscriptionItemTree#testMaxedOutProRation
- if (resultingCandidate.matches(existingRecurringItem)) {
+ final InvoiceItem fullyAdjustedInvoiceItem = existingAdjustedItem.toInvoiceItem();
+ if (resultingCandidate.matches(fullyAdjustedInvoiceItem)) {
return null;
}
}
diff --git a/invoice/src/test/java/org/killbill/billing/invoice/generator/TestDefaultInvoiceGenerator.java b/invoice/src/test/java/org/killbill/billing/invoice/generator/TestDefaultInvoiceGenerator.java
index 25cdae3..742ab12 100644
--- a/invoice/src/test/java/org/killbill/billing/invoice/generator/TestDefaultInvoiceGenerator.java
+++ b/invoice/src/test/java/org/killbill/billing/invoice/generator/TestDefaultInvoiceGenerator.java
@@ -1070,30 +1070,34 @@ public class TestDefaultInvoiceGenerator extends InvoiceTestSuiteNoDB {
final InvoiceWithMetadata invoiceWithMetadata = generator.generateInvoice(account, events, existingInvoices, targetDate, currency, internalCallContext);
final Invoice invoice = invoiceWithMetadata.getInvoice();
- assertEquals(invoice.getNumberOfItems(), 6);
- assertEquals(invoice.getInvoiceItems().get(0).getInvoiceItemType(), InvoiceItemType.REPAIR_ADJ);
+ assertEquals(invoice.getNumberOfItems(), 7);
+ assertEquals(invoice.getInvoiceItems().get(0).getInvoiceItemType(), InvoiceItemType.RECURRING);
assertEquals(invoice.getInvoiceItems().get(0).getStartDate(), new LocalDate(2013, 6, 15));
- assertEquals(invoice.getInvoiceItems().get(0).getEndDate(), new LocalDate(2013, 6, 21));
+ assertEquals(invoice.getInvoiceItems().get(0).getEndDate(), new LocalDate(2013, 7, 15));
assertEquals(invoice.getInvoiceItems().get(1).getInvoiceItemType(), InvoiceItemType.REPAIR_ADJ);
- assertEquals(invoice.getInvoiceItems().get(1).getStartDate(), new LocalDate(2013, 6, 26));
- assertEquals(invoice.getInvoiceItems().get(1).getEndDate(), new LocalDate(2013, 7, 15));
+ assertEquals(invoice.getInvoiceItems().get(1).getStartDate(), new LocalDate(2013, 6, 15));
+ assertEquals(invoice.getInvoiceItems().get(1).getEndDate(), new LocalDate(2013, 6, 21));
- assertEquals(invoice.getInvoiceItems().get(2).getInvoiceItemType(), InvoiceItemType.RECURRING);
- assertEquals(invoice.getInvoiceItems().get(2).getStartDate(), new LocalDate(2013, 7, 15));
- assertEquals(invoice.getInvoiceItems().get(2).getEndDate(), new LocalDate(2013, 8, 15));
+ assertEquals(invoice.getInvoiceItems().get(2).getInvoiceItemType(), InvoiceItemType.REPAIR_ADJ);
+ assertEquals(invoice.getInvoiceItems().get(2).getStartDate(), new LocalDate(2013, 6, 26));
+ assertEquals(invoice.getInvoiceItems().get(2).getEndDate(), new LocalDate(2013, 7, 15));
assertEquals(invoice.getInvoiceItems().get(3).getInvoiceItemType(), InvoiceItemType.RECURRING);
- assertEquals(invoice.getInvoiceItems().get(3).getStartDate(), new LocalDate(2013, 8, 15));
- assertEquals(invoice.getInvoiceItems().get(3).getEndDate(), new LocalDate(2013, 9, 15));
+ assertEquals(invoice.getInvoiceItems().get(3).getStartDate(), new LocalDate(2013, 7, 15));
+ assertEquals(invoice.getInvoiceItems().get(3).getEndDate(), new LocalDate(2013, 8, 15));
assertEquals(invoice.getInvoiceItems().get(4).getInvoiceItemType(), InvoiceItemType.RECURRING);
- assertEquals(invoice.getInvoiceItems().get(4).getStartDate(), new LocalDate(2013, 9, 15));
- assertEquals(invoice.getInvoiceItems().get(4).getEndDate(), new LocalDate(2013, 10, 15));
+ assertEquals(invoice.getInvoiceItems().get(4).getStartDate(), new LocalDate(2013, 8, 15));
+ assertEquals(invoice.getInvoiceItems().get(4).getEndDate(), new LocalDate(2013, 9, 15));
assertEquals(invoice.getInvoiceItems().get(5).getInvoiceItemType(), InvoiceItemType.RECURRING);
- assertEquals(invoice.getInvoiceItems().get(5).getStartDate(), new LocalDate(2013, 10, 15));
- assertEquals(invoice.getInvoiceItems().get(5).getEndDate(), new LocalDate(2013, 11, 15));
+ assertEquals(invoice.getInvoiceItems().get(5).getStartDate(), new LocalDate(2013, 9, 15));
+ assertEquals(invoice.getInvoiceItems().get(5).getEndDate(), new LocalDate(2013, 10, 15));
+
+ assertEquals(invoice.getInvoiceItems().get(6).getInvoiceItemType(), InvoiceItemType.RECURRING);
+ assertEquals(invoice.getInvoiceItems().get(6).getStartDate(), new LocalDate(2013, 10, 15));
+ assertEquals(invoice.getInvoiceItems().get(6).getEndDate(), new LocalDate(2013, 11, 15));
// Add newly generated invoice to existing invoices
existingInvoices.add(invoice);