killbill-memoizeit

Merge branch 'bugfixes' of github.com:ning/killbill into

7/7/2012 12:04:51 AM

Details

diff --git a/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestIntegration.java b/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestIntegration.java
index ce54f8c..f169d53 100644
--- a/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestIntegration.java
+++ b/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestIntegration.java
@@ -161,14 +161,9 @@ public class TestIntegration extends TestIntegrationBase {
         busHandler.pushExpectedEvent(NextEvent.INVOICE);
         log.info("Moving clock from" + clock.getUTCNow() + " to " + clock.getUTCNow().plusDays(28));
         clock.addDays(28);// 26 / 5
-
-
-        Thread.sleep(1000000);
-
         assertTrue(busHandler.isCompleted(DELAY));
         assertListenerStatus();
 
-
         busHandler.pushExpectedEvent(NextEvent.PHASE);
         busHandler.pushExpectedEvent(NextEvent.INVOICE);
         busHandler.pushExpectedEvent(NextEvent.PAYMENT);
@@ -177,13 +172,11 @@ public class TestIntegration extends TestIntegrationBase {
         assertTrue(busHandler.isCompleted(DELAY));
         assertListenerStatus();
 
-
         log.info("Moving clock from" + clock.getUTCNow() + " to " + clock.getUTCNow().plusDays(10));
         clock.addDays(10);// 8 / 6
         assertTrue(busHandler.isCompleted(DELAY));
         assertListenerStatus();
 
-
         busHandler.pushExpectedEvent(NextEvent.INVOICE);
         busHandler.pushExpectedEvent(NextEvent.PAYMENT);
         log.info("Moving clock from" + clock.getUTCNow() + " to " + clock.getUTCNow().plusDays(18));
@@ -195,8 +188,6 @@ public class TestIntegration extends TestIntegrationBase {
         clock.addDays(3);
         assertTrue(busHandler.isCompleted(DELAY));
         assertListenerStatus();
-
-
     }
 
 
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 5ec1f68..47f696c 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
@@ -173,7 +173,6 @@ public class DefaultInvoiceDao implements InvoiceDao {
 
                     transactional.insertAuditFromTransaction(audits, context);
                 }
-
                 return null;
             }
         });
@@ -511,15 +510,24 @@ public class DefaultInvoiceDao implements InvoiceDao {
     }
 
     private void notifyOfFutureBillingEvents(final InvoiceSqlDao dao, final List<InvoiceItem> invoiceItems) {
+        DateTime nextBCD = null;
+        UUID subscriptionForNextBCD = null;
         for (final InvoiceItem item : invoiceItems) {
+
             if (item.getInvoiceItemType() == InvoiceItemType.RECURRING) {
                 final RecurringInvoiceItem recurringInvoiceItem = (RecurringInvoiceItem) item;
                 if ((recurringInvoiceItem.getEndDate() != null) &&
                         (recurringInvoiceItem.getAmount() == null ||
                                 recurringInvoiceItem.getAmount().compareTo(BigDecimal.ZERO) >= 0)) {
-                    nextBillingDatePoster.insertNextBillingNotification(dao, item.getSubscriptionId(), recurringInvoiceItem.getEndDate());
+                    if (nextBCD == null || nextBCD.compareTo(recurringInvoiceItem.getEndDate()) > 0) {
+                        nextBCD = recurringInvoiceItem.getEndDate();
+                        subscriptionForNextBCD = recurringInvoiceItem.getSubscriptionId();
+                    }
                 }
             }
         }
+        if (subscriptionForNextBCD != null) {
+            nextBillingDatePoster.insertNextBillingNotification(dao, subscriptionForNextBCD, nextBCD);
+        }
     }
 }
diff --git a/invoice/src/main/java/com/ning/billing/invoice/generator/DefaultInvoiceGenerator.java b/invoice/src/main/java/com/ning/billing/invoice/generator/DefaultInvoiceGenerator.java
index d605e7d..69a8ac4 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/generator/DefaultInvoiceGenerator.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/generator/DefaultInvoiceGenerator.java
@@ -27,6 +27,7 @@ import java.util.Map;
 import java.util.UUID;
 
 import org.joda.time.DateTime;
+import org.joda.time.DateTimeZone;
 import org.joda.time.Months;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -296,6 +297,16 @@ public class DefaultInvoiceGenerator implements InvoiceGenerator {
         return items;
     }
 
+
+    private DateTime roundDateTimeToDate(final DateTime input, final DateTimeZone timeZone) {
+        if (input == null) {
+            return null;
+        }
+        final DateTime tzAdjustedStartDate = input.toDateTime(timeZone);
+        final DateTime roundedStartDate = new DateTime(tzAdjustedStartDate.getYear(), tzAdjustedStartDate.getMonthOfYear(), tzAdjustedStartDate.getDayOfMonth(), 0, 0, timeZone);
+        return roundedStartDate;
+    }
+
     List<InvoiceItem> processEvents(final UUID invoiceId, final UUID accountId, final BillingEvent thisEvent, @Nullable final BillingEvent nextEvent,
             final DateTime targetDate, final Currency currency) throws InvoiceApiException {
         final List<InvoiceItem> items = new ArrayList<InvoiceItem>();
@@ -307,17 +318,21 @@ public class DefaultInvoiceGenerator implements InvoiceGenerator {
         final BillingPeriod billingPeriod = thisEvent.getBillingPeriod();
         if (billingPeriod != BillingPeriod.NO_BILLING_PERIOD) {
             final BillingMode billingMode = instantiateBillingMode(thisEvent.getBillingMode());
+            // Invoice granularity is day; (if not some comparison might fail)
             final DateTime startDate = thisEvent.getEffectiveDate();
-            final DateTime tzAdjustedStartDate = startDate.toDateTime(thisEvent.getTimeZone());
-            final DateTime roundedStartDate = new DateTime(tzAdjustedStartDate.getYear(), tzAdjustedStartDate.getMonthOfYear(), tzAdjustedStartDate.getDayOfMonth(), 0, 0, thisEvent.getTimeZone());
+            final DateTime roundedStartDate = roundDateTimeToDate(startDate, thisEvent.getTimeZone());
+            final DateTime roundedTargetDate = roundDateTimeToDate(targetDate, thisEvent.getTimeZone());
+
             log.info(String.format("start = %s, rounded = %s, target = %s, in = %s", startDate, roundedStartDate, targetDate, (!roundedStartDate.isAfter(targetDate)) ? "in" : "out"));
             if (!roundedStartDate.isAfter(targetDate)) {
                 final DateTime endDate = (nextEvent == null) ? null : nextEvent.getEffectiveDate();
+
+                final DateTime roundedEndDate = roundDateTimeToDate(endDate, thisEvent.getTimeZone());
                 final int billCycleDay = thisEvent.getBillCycleDay();
 
                 final List<RecurringInvoiceItemData> itemData;
                 try {
-                    itemData = billingMode.calculateInvoiceItemData(startDate, endDate, targetDate, billCycleDay, billingPeriod);
+                    itemData = billingMode.calculateInvoiceItemData(roundedStartDate, roundedEndDate, roundedTargetDate, billCycleDay, billingPeriod);
                 } catch (InvalidDateSequenceException e) {
                     throw new InvoiceApiException(ErrorCode.INVOICE_INVALID_DATE_SEQUENCE, startDate, endDate, targetDate);
                 }
diff --git a/invoice/src/main/java/com/ning/billing/invoice/model/InAdvanceBillingMode.java b/invoice/src/main/java/com/ning/billing/invoice/model/InAdvanceBillingMode.java
index e6132d4..117df30 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/model/InAdvanceBillingMode.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/model/InAdvanceBillingMode.java
@@ -77,7 +77,6 @@ public class InAdvanceBillingMode implements BillingMode {
                 results.add(new RecurringInvoiceItemData(lastBillingCycleDate, effectiveEndDate, trailingProRationPeriods));
             }
         }
-
         return results;
     }