killbill-aplcache

Details

diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md
index 20451a4..f0692f6 100644
--- a/.github/CONTRIBUTING.md
+++ b/.github/CONTRIBUTING.md
@@ -7,13 +7,13 @@
 In your [Mailing-List](https://groups.google.com/forum/#!forum/killbilling-users) post, specify:
 
 * Step by step description on how to reproduce the issue
-* [Account data and system dump](https://github.com/killbill/killbill/wiki/Production-troubleshooting#debugging-issues) of an affected account
+* [Account data and system dump](http://docs.killbill.io/0.19/debugging.html#_seeking_help) via KPM of an affected account
 
 #### **Do you intend to add a new feature or change an existing one?**
 
 Do not open an issue or pull request on GitHub until you have collected positive feedback about the change on the [Mailing-List](https://groups.google.com/forum/#!forum/killbilling-users).
 
-When submitting code, make sure to add [new tests](https://github.com/killbill/killbill/wiki/Navigating-the-Kill-Bill-codebase).
+When submitting code, make sure to add [new tests](http://docs.killbill.io/0.19/development.html#_navigating_the_kill_bill_codebase).
 
 #### **Do you want to contribute to the Kill Bill documentation?**
 
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/usage/ContiguousIntervalUsageInArrear.java b/invoice/src/main/java/org/killbill/billing/invoice/usage/ContiguousIntervalUsageInArrear.java
index bcc13cb..98def8c 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/usage/ContiguousIntervalUsageInArrear.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/usage/ContiguousIntervalUsageInArrear.java
@@ -232,6 +232,7 @@ public abstract class ContiguousIntervalUsageInArrear {
         return result;
     }
 
+
     @VisibleForTesting
     List<RolledUpUsage> getRolledUpUsage() {
 
@@ -239,15 +240,7 @@ public abstract class ContiguousIntervalUsageInArrear {
 
         final Iterator<RawUsage> rawUsageIterator = rawSubscriptionUsage.iterator();
         if (!rawUsageIterator.hasNext()) {
-            final LocalDate startDate = transitionTimes.get(transitionTimes.size() - 2);
-            final LocalDate endDate = transitionTimes.get(transitionTimes.size() - 1);
-            for (String unitType : unitTypes) {
-                final List<RolledUpUnit> emptyRolledUptUnits = new ArrayList<RolledUpUnit>();
-                emptyRolledUptUnits.add(new DefaultRolledUpUnit(unitType, 0L));
-                final DefaultRolledUpUsage defaultForUnit = new DefaultRolledUpUsage(getSubscriptionId(), startDate, endDate, emptyRolledUptUnits);
-                result.add(defaultForUnit);
-            }
-            return result;
+            return getEmptyRolledUpUsage();
         }
 
 
@@ -265,8 +258,8 @@ public abstract class ContiguousIntervalUsageInArrear {
         }
 
         // Optimize path where all raw usage items are outside or our transitionTimes range
-        if (prevRawUsage.getDate().compareTo(transitionTimes.get(transitionTimes.size() - 1)) >= 0) {
-            return ImmutableList.of();
+        if (prevRawUsage == null || prevRawUsage.getDate().compareTo(transitionTimes.get(transitionTimes.size() - 1)) >= 0) {
+            return getEmptyRolledUpUsage();
         }
 
         //
@@ -329,6 +322,19 @@ public abstract class ContiguousIntervalUsageInArrear {
         return result;
     }
 
+    private List<RolledUpUsage> getEmptyRolledUpUsage() {
+        final List<RolledUpUsage> result = new ArrayList<RolledUpUsage>();
+        final LocalDate startDate = transitionTimes.get(transitionTimes.size() - 2);
+        final LocalDate endDate = transitionTimes.get(transitionTimes.size() - 1);
+        for (String unitType : unitTypes) {
+            final List<RolledUpUnit> emptyRolledUptUnits = new ArrayList<RolledUpUnit>();
+            emptyRolledUptUnits.add(new DefaultRolledUpUnit(unitType, 0L));
+            final DefaultRolledUpUsage defaultForUnit = new DefaultRolledUpUsage(getSubscriptionId(), startDate, endDate, emptyRolledUptUnits);
+            result.add(defaultForUnit);
+        }
+        return result;
+    }
+
     /**
      * Based on usage type compute new amount
      *
diff --git a/invoice/src/test/java/org/killbill/billing/invoice/usage/TestContiguousIntervalConsumableInArrear.java b/invoice/src/test/java/org/killbill/billing/invoice/usage/TestContiguousIntervalConsumableInArrear.java
index 476c420..cb532bd 100644
--- a/invoice/src/test/java/org/killbill/billing/invoice/usage/TestContiguousIntervalConsumableInArrear.java
+++ b/invoice/src/test/java/org/killbill/billing/invoice/usage/TestContiguousIntervalConsumableInArrear.java
@@ -1002,6 +1002,42 @@ public class TestContiguousIntervalConsumableInArrear extends TestUsageInArrearB
         // TODO + code
     }
 
+    @Test(groups = "fast")
+    public void testGetRolledUpUsageOnlyUsageBeforeTransitionTime() {
+
+        final DefaultTieredBlock tieredBlock1 = createDefaultTieredBlock("unit", 100, 1000, BigDecimal.ONE);
+        final DefaultTieredBlock tieredBlock2 = createDefaultTieredBlock("unit2", 10, 1000, BigDecimal.ONE);
+        final DefaultTier tier = createDefaultTierWithBlocks(tieredBlock1, tieredBlock2);
+
+        final DefaultUsage usage = createConsumableInArrearUsage(usageName, BillingPeriod.MONTHLY, TierBlockPolicy.ALL_TIERS, tier);
+
+
+        final LocalDate t0 = new LocalDate(2015, 03, BCD);
+        final BillingEvent eventT0 = createMockBillingEvent(t0.toDateTimeAtStartOfDay(DateTimeZone.UTC), BillingPeriod.MONTHLY, Collections.<Usage>emptyList());
+
+        final LocalDate t1 = new LocalDate(2015, 04, BCD);
+        final BillingEvent eventT1 = createMockBillingEvent(t1.toDateTimeAtStartOfDay(DateTimeZone.UTC), BillingPeriod.MONTHLY, Collections.<Usage>emptyList());
+
+        final LocalDate targetDate = t1;
+
+
+        // Prev t0
+        final RawUsage raw1 = new DefaultRawUsage(subscriptionId, new LocalDate(2015, 03, 01), "unit", 12L);
+
+        final List<RawUsage> rawUsage = ImmutableList.of(raw1);
+
+        final ContiguousIntervalUsageInArrear intervalConsumableInArrear = createContiguousIntervalConsumableInArrear(usage, rawUsage, targetDate, true, eventT0, eventT1);
+
+
+        final List<RolledUpUsage> unsortedRolledUpUsage =  intervalConsumableInArrear.getRolledUpUsage();
+        assertEquals(unsortedRolledUpUsage.size(), 2);
+        assertEquals(unsortedRolledUpUsage.get(0).getRolledUpUnits().size(), 1);
+        assertEquals(unsortedRolledUpUsage.get(0).getRolledUpUnits().get(0).getAmount().longValue(), 0L);
+        assertEquals(unsortedRolledUpUsage.get(1).getRolledUpUnits().size(), 1);
+        assertEquals(unsortedRolledUpUsage.get(1).getRolledUpUnits().get(0).getAmount().longValue(), 0L);
+
+    }
+
     private List<InvoiceItem> produceInvoiceItems(List<RawUsage> rawUsages, TierBlockPolicy tierBlockPolicy, UsageDetailMode usageDetailMode, final List<InvoiceItem> existingItems) throws CatalogApiException, InvoiceApiException {
 
         final LocalDate startDate = new LocalDate(2014, 03, 20);
@@ -1051,4 +1087,5 @@ public class TestContiguousIntervalConsumableInArrear extends TestUsageInArrearB
 
         return result;
     }
+
 }

NEWS 6(+6 -0)

diff --git a/NEWS b/NEWS
index 32f0f09..8b9d282 100644
--- a/NEWS
+++ b/NEWS
@@ -56,6 +56,12 @@
     Fix missing Invoice Notification when we have future billing events (#846)
     Reduce log level of InvoiceItemGeneratorLogger (#851)
 
+0.18.21
+    Fix for NPE if the only available usage is before the first transition date
+
+0.18.20
+    Fix issue when changing a Plan defined in a subsequent catalog version
+
 0.18.18
     See https://github.com/killbill/killbill/releases/tag/killbill-0.18.18