killbill-aplcache

Details

diff --git a/invoice/src/main/java/org/killbill/billing/invoice/usage/ContiguousIntervalCapacityUsageInArrear.java b/invoice/src/main/java/org/killbill/billing/invoice/usage/ContiguousIntervalCapacityUsageInArrear.java
index 02c116b..517fcec 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/usage/ContiguousIntervalCapacityUsageInArrear.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/usage/ContiguousIntervalCapacityUsageInArrear.java
@@ -39,8 +39,6 @@ import org.killbill.billing.usage.RawUsage;
 import org.killbill.billing.usage.api.RolledUpUnit;
 import org.killbill.billing.util.config.definition.InvoiceConfig.UsageDetailMode;
 import org.killbill.billing.util.jackson.ObjectMapper;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Joiner;
@@ -51,7 +49,7 @@ import static org.killbill.billing.invoice.usage.UsageUtils.getCapacityInArrearT
 
 public class ContiguousIntervalCapacityUsageInArrear extends ContiguousIntervalUsageInArrear {
 
-    private static final Logger log = LoggerFactory.getLogger(ContiguousIntervalCapacityUsageInArrear.class);
+    private static final Joiner joiner = Joiner.on(", ");
 
     private static final ObjectMapper objectMapper = new ObjectMapper();
 
@@ -130,7 +128,6 @@ public class ContiguousIntervalCapacityUsageInArrear extends ContiguousIntervalU
             }
         }
         // Probably invalid catalog config
-        final Joiner joiner = Joiner.on(", ");
         joiner.join(roUnits);
         Preconditions.checkState(false, "Could not find tier for usage " + usage.getName() + "matching with data = " + joiner.join(roUnits));
         return null;
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 077db78..07675f2 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
@@ -20,7 +20,6 @@ package org.killbill.billing.invoice.usage;
 import java.io.IOException;
 import java.math.BigDecimal;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
@@ -33,21 +32,21 @@ import java.util.concurrent.atomic.AtomicBoolean;
 import javax.annotation.Nullable;
 
 import org.joda.time.LocalDate;
+import org.killbill.billing.ErrorCode;
 import org.killbill.billing.callcontext.InternalTenantContext;
 import org.killbill.billing.catalog.api.BillingMode;
 import org.killbill.billing.catalog.api.CatalogApiException;
 import org.killbill.billing.catalog.api.Currency;
 import org.killbill.billing.catalog.api.Limit;
 import org.killbill.billing.catalog.api.Tier;
-import org.killbill.billing.catalog.api.TieredBlock;
 import org.killbill.billing.catalog.api.Usage;
 import org.killbill.billing.catalog.api.UsageType;
+import org.killbill.billing.invoice.api.InvoiceApiException;
 import org.killbill.billing.invoice.api.InvoiceItem;
 import org.killbill.billing.invoice.api.InvoiceItemType;
 import org.killbill.billing.invoice.generator.BillingIntervalDetail;
 import org.killbill.billing.invoice.model.UsageInvoiceItem;
 import org.killbill.billing.invoice.usage.details.UsageCapacityInArrearDetail;
-import org.killbill.billing.invoice.usage.details.UsageConsumableInArrearDetail;
 import org.killbill.billing.invoice.usage.details.UsageConsumableInArrearTierUnitDetail;
 import org.killbill.billing.invoice.usage.details.UsageInArrearDetail;
 import org.killbill.billing.invoice.usage.details.UsageInArrearTierUnitDetail;
@@ -71,7 +70,6 @@ import com.google.common.collect.Lists;
 
 import static org.killbill.billing.invoice.usage.UsageUtils.getCapacityInArrearTier;
 import static org.killbill.billing.invoice.usage.UsageUtils.getCapacityInArrearUnitTypes;
-import static org.killbill.billing.invoice.usage.UsageUtils.getConsumableInArrearTieredBlocks;
 import static org.killbill.billing.invoice.usage.UsageUtils.getConsumableInArrearUnitTypes;
 
 /**
@@ -172,7 +170,7 @@ public abstract class ContiguousIntervalUsageInArrear {
      * @param existingUsage existing on disk usage items for the subscription
      * @throws CatalogApiException
      */
-    public UsageInArrearItemsAndNextNotificationDate computeMissingItemsAndNextNotificationDate(final List<InvoiceItem> existingUsage) throws CatalogApiException {
+    public UsageInArrearItemsAndNextNotificationDate computeMissingItemsAndNextNotificationDate(final List<InvoiceItem> existingUsage) throws CatalogApiException, InvoiceApiException {
 
         Preconditions.checkState(isBuilt.get());
 
@@ -210,11 +208,21 @@ public abstract class ContiguousIntervalUsageInArrear {
 
             final List<RolledUpUnit> rolledUpUnits = ru.getRolledUpUnits();
 
+
+
             final UsageInArrearDetail toBeBilledUsageDetails = getToBeBilledUsageDetails(rolledUpUnits, billedItems, areAllBilledItemsWithDetails);
             final BigDecimal toBeBilledUsage = toBeBilledUsageDetails.getAmount();
 
-            populateResults(ru.getStart(), ru.getEnd(), billedItems, billedUsage, toBeBilledUsage, toBeBilledUsageDetails, areAllBilledItemsWithDetails, result);
-
+            final int billedUsageDelta = billedUsage.compareTo(toBeBilledUsage);
+            // We built more in the past than what we find now, data usage vanished?
+            if (billedUsageDelta > 0) {
+                throw new InvoiceApiException(ErrorCode.UNEXPECTED_ERROR,
+                                              String.format("ILLEGAL INVOICING STATE: Usage period start='%s', end='%s', previously billed amount='%.2f', new proposed amount='%.2f'",
+                                                            ru.getStart(), ru.getEnd(), billedUsage, toBeBilledUsage));
+            // Something remains to be billed
+            } else if (billedUsageDelta < 0) {
+                populateResults(ru.getStart(), ru.getEnd(), billedItems, billedUsage, toBeBilledUsage, toBeBilledUsageDetails, areAllBilledItemsWithDetails, result);
+            }
         }
         final LocalDate nextNotificationdate = computeNextNotificationDate();
         return new UsageInArrearItemsAndNextNotificationDate(result, nextNotificationdate);
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/usage/SubscriptionUsageInArrear.java b/invoice/src/main/java/org/killbill/billing/invoice/usage/SubscriptionUsageInArrear.java
index f28d4c9..93bbd42 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/usage/SubscriptionUsageInArrear.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/usage/SubscriptionUsageInArrear.java
@@ -33,6 +33,7 @@ import org.killbill.billing.catalog.api.BillingMode;
 import org.killbill.billing.catalog.api.CatalogApiException;
 import org.killbill.billing.catalog.api.Usage;
 import org.killbill.billing.catalog.api.UsageType;
+import org.killbill.billing.invoice.api.InvoiceApiException;
 import org.killbill.billing.invoice.api.InvoiceItem;
 import org.killbill.billing.invoice.generator.InvoiceItemGenerator.InvoiceItemGeneratorLogger;
 import org.killbill.billing.invoice.usage.ContiguousIntervalUsageInArrear.UsageInArrearItemsAndNextNotificationDate;
@@ -113,7 +114,7 @@ public class SubscriptionUsageInArrear {
      * @param existingUsage the existing on disk usage items.
      * @throws CatalogApiException
      */
-    public SubscriptionUsageInArrearItemsAndNextNotificationDate computeMissingUsageInvoiceItems(final List<InvoiceItem> existingUsage, final InvoiceItemGeneratorLogger invoiceItemGeneratorLogger) throws CatalogApiException {
+    public SubscriptionUsageInArrearItemsAndNextNotificationDate computeMissingUsageInvoiceItems(final List<InvoiceItem> existingUsage, final InvoiceItemGeneratorLogger invoiceItemGeneratorLogger) throws CatalogApiException, InvoiceApiException {
         final SubscriptionUsageInArrearItemsAndNextNotificationDate result = new SubscriptionUsageInArrearItemsAndNextNotificationDate();
         final List<ContiguousIntervalUsageInArrear> billingEventTransitionTimePeriods = computeInArrearUsageInterval();
         for (final ContiguousIntervalUsageInArrear usageInterval : billingEventTransitionTimePeriods) {
diff --git a/invoice/src/test/java/org/killbill/billing/invoice/usage/TestContiguousIntervalCapacityInArrear.java b/invoice/src/test/java/org/killbill/billing/invoice/usage/TestContiguousIntervalCapacityInArrear.java
index 9b1fc17..167e2fa 100644
--- a/invoice/src/test/java/org/killbill/billing/invoice/usage/TestContiguousIntervalCapacityInArrear.java
+++ b/invoice/src/test/java/org/killbill/billing/invoice/usage/TestContiguousIntervalCapacityInArrear.java
@@ -33,6 +33,7 @@ import org.killbill.billing.catalog.api.BillingPeriod;
 import org.killbill.billing.catalog.api.CatalogApiException;
 import org.killbill.billing.catalog.api.Currency;
 import org.killbill.billing.catalog.api.Usage;
+import org.killbill.billing.invoice.api.InvoiceApiException;
 import org.killbill.billing.invoice.api.InvoiceItem;
 import org.killbill.billing.invoice.model.FixedPriceInvoiceItem;
 import org.killbill.billing.invoice.model.UsageInvoiceItem;
@@ -175,7 +176,7 @@ public class TestContiguousIntervalCapacityInArrear extends TestUsageInArrearBas
     }
 
     @Test(groups = "fast")
-    public void testComputeMissingItems() throws CatalogApiException {
+    public void testComputeMissingItems() throws CatalogApiException, InvoiceApiException {
 
         final LocalDate startDate = new LocalDate(2014, 03, 20);
         final LocalDate firstBCDDate = new LocalDate(2014, 04, 15);
@@ -257,16 +258,16 @@ public class TestContiguousIntervalCapacityInArrear extends TestUsageInArrearBas
     }
 
     @Test(groups = "fast")
-    public void testMultipleItemsAndTiersAggregateMode() throws CatalogApiException, IOException {
+    public void testMultipleItemsAndTiersAggregateMode() throws CatalogApiException, IOException, InvoiceApiException {
         testMultipleItemsAndTiers(UsageDetailMode.AGGREGATE);
     }
 
     @Test(groups = "fast")
-    public void testMultipleItemsAndTiersDetailMode() throws CatalogApiException, IOException {
+    public void testMultipleItemsAndTiersDetailMode() throws CatalogApiException, IOException, InvoiceApiException {
         testMultipleItemsAndTiers(UsageDetailMode.DETAIL);
     }
 
-    private void testMultipleItemsAndTiers(UsageDetailMode usageDetailMode) throws CatalogApiException, IOException {
+    private void testMultipleItemsAndTiers(UsageDetailMode usageDetailMode) throws CatalogApiException, IOException, InvoiceApiException {
 
         // Case 1
         List<RawUsage> rawUsages = new ArrayList<RawUsage>();
@@ -332,7 +333,7 @@ public class TestContiguousIntervalCapacityInArrear extends TestUsageInArrearBas
     }
 
     @Test(groups = "fast")
-    public void testMultipleItemsAndTiersWithExistingItems() throws CatalogApiException, IOException {
+    public void testMultipleItemsAndTiersWithExistingItems() throws CatalogApiException, IOException, InvoiceApiException {
 
         // let's assume we have some existing usage
         final UsageInArrearTierUnitDetail existingFooUsageTier1 = new UsageConsumableInArrearTierUnitDetail(1, "FOO", BigDecimal.ONE, 1, 9, BigDecimal.TEN);
@@ -367,7 +368,7 @@ public class TestContiguousIntervalCapacityInArrear extends TestUsageInArrearBas
         assertEquals(itemDetails.get(1).getTierPrice().compareTo(new BigDecimal("100.00")), 0);
     }
 
-    private List<InvoiceItem> produceInvoiceItems(List<RawUsage> rawUsages, UsageDetailMode usageDetailMode, List<InvoiceItem> existingItems) throws CatalogApiException {
+    private List<InvoiceItem> produceInvoiceItems(List<RawUsage> rawUsages, UsageDetailMode usageDetailMode, List<InvoiceItem> existingItems) throws CatalogApiException, InvoiceApiException {
 
         final LocalDate startDate = new LocalDate(2014, 03, 20);
         final LocalDate firstBCDDate = new LocalDate(2014, 04, 15);
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 87de942..fff1797 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
@@ -35,6 +35,7 @@ import org.killbill.billing.catalog.api.Currency;
 import org.killbill.billing.catalog.api.TierBlockPolicy;
 import org.killbill.billing.catalog.api.Usage;
 import org.killbill.billing.catalog.api.UsageType;
+import org.killbill.billing.invoice.api.InvoiceApiException;
 import org.killbill.billing.invoice.api.InvoiceItem;
 import org.killbill.billing.invoice.model.FixedPriceInvoiceItem;
 import org.killbill.billing.invoice.model.UsageInvoiceItem;
@@ -264,7 +265,7 @@ public class TestContiguousIntervalConsumableInArrear extends TestUsageInArrearB
 
 
     @Test(groups = "fast")
-    public void testComputeMissingItems() throws CatalogApiException, IOException {
+    public void testComputeMissingItems() throws CatalogApiException, IOException, InvoiceApiException {
 
         final LocalDate startDate = new LocalDate(2014, 03, 20);
         final LocalDate firstBCDDate = new LocalDate(2014, 04, 15);
@@ -461,7 +462,7 @@ public class TestContiguousIntervalConsumableInArrear extends TestUsageInArrearB
     }
 
     @Test(groups = "fast")
-    public void testComputeMissingItemsAggregateModeAllTier() throws CatalogApiException, IOException {
+    public void testComputeMissingItemsAggregateModeAllTier() throws CatalogApiException, IOException, InvoiceApiException {
 
         // Case 1
         List<RawUsage> rawUsages = new ArrayList<RawUsage>();
@@ -558,7 +559,7 @@ public class TestContiguousIntervalConsumableInArrear extends TestUsageInArrearB
     }
 
     @Test(groups = "fast")
-    public void testComputeMissingItemsDetailModeAllTier() throws CatalogApiException, IOException {
+    public void testComputeMissingItemsDetailModeAllTier() throws CatalogApiException, IOException, InvoiceApiException {
 
         // Case 1
         List<RawUsage> rawUsages = new ArrayList<RawUsage>();
@@ -626,7 +627,7 @@ public class TestContiguousIntervalConsumableInArrear extends TestUsageInArrearB
     }
 
     @Test(groups = "fast")
-    public void testComputeMissingItemsAggregateModeTopTier() throws CatalogApiException, IOException {
+    public void testComputeMissingItemsAggregateModeTopTier() throws CatalogApiException, IOException, InvoiceApiException {
 
         // Case 1
         List<RawUsage> rawUsages = new ArrayList<RawUsage>();
@@ -699,7 +700,7 @@ public class TestContiguousIntervalConsumableInArrear extends TestUsageInArrearB
     }
 
     @Test(groups = "fast")
-    public void testComputeMissingItemsDetailModeTopTier() throws CatalogApiException, IOException {
+    public void testComputeMissingItemsDetailModeTopTier() throws CatalogApiException, IOException, InvoiceApiException {
 
         // Case 1
         List<RawUsage> rawUsages = new ArrayList<RawUsage>();
@@ -753,7 +754,7 @@ public class TestContiguousIntervalConsumableInArrear extends TestUsageInArrearB
 
 
     @Test(groups = "fast")
-    public void testMultipleItemsAndTiersWithExistingItemsAllTiers() throws CatalogApiException, IOException {
+    public void testMultipleItemsAndTiersWithExistingItemsAllTiers() throws CatalogApiException, IOException, InvoiceApiException {
 
         //
         // Let's assume we were already billed on the previous period
@@ -819,8 +820,12 @@ public class TestContiguousIntervalConsumableInArrear extends TestUsageInArrearB
     }
 
 
+    @Test(groups = "fast")
+    public void testMultipleItemsAndTiersWithExistingItemsTopTier() throws CatalogApiException, IOException {
+        // TODO + code
+    }
 
-    private List<InvoiceItem> produceInvoiceItems(List<RawUsage> rawUsages, TierBlockPolicy tierBlockPolicy, UsageDetailMode usageDetailMode, final List<InvoiceItem> existingItems) throws CatalogApiException {
+    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);
         final LocalDate firstBCDDate = new LocalDate(2014, 04, 15);