killbill-memoizeit
Changes
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 6371c98..8f21dfa 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
@@ -16,6 +16,10 @@
package com.ning.billing.beatrix.integration;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertTrue;
+
import java.math.BigDecimal;
import java.util.List;
import java.util.UUID;
@@ -41,10 +45,6 @@ import com.ning.billing.entitlement.api.user.SubscriptionData;
import com.ning.billing.invoice.api.Invoice;
import com.ning.billing.invoice.api.InvoiceItemType;
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertNotNull;
-import static org.testng.Assert.assertTrue;
-
@Guice(modules = {BeatrixModule.class})
public class TestIntegration extends TestIntegrationBase {
@@ -116,10 +116,10 @@ public class TestIntegration extends TestIntegrationBase {
//
// MOVE 4 * TIME THE CLOCK
//
- setDateAndCheckForCompletion(new DateTime(2012, 2, 28, 0, 3, 45, 0, testTimeZone));
- setDateAndCheckForCompletion(new DateTime(2012, 2, 29, 0, 3, 45, 0, testTimeZone));
- setDateAndCheckForCompletion(new DateTime(2012, 3, 1, 0, 3, 45, 0, testTimeZone));
- setDateAndCheckForCompletion(new DateTime(2012, 3, 2, 0, 3, 45, 0, testTimeZone), NextEvent.PHASE, NextEvent.INVOICE, NextEvent.PAYMENT);
+ setDateAndCheckForCompletion(new DateTime(2012, 2, 28, 23, 59, 59, 0, testTimeZone));
+ setDateAndCheckForCompletion(new DateTime(2012, 2, 29, 23, 59, 59, 0, testTimeZone));
+ setDateAndCheckForCompletion(new DateTime(2012, 3, 1, 23, 59, 59, 0, testTimeZone));
+ setDateAndCheckForCompletion(new DateTime(2012, 3, 2, 23, 59, 59, 0, testTimeZone), NextEvent.PHASE, NextEvent.INVOICE, NextEvent.PAYMENT);
invoiceChecker.checkInvoice(account.getId(), invoiceItemCount++, callContext, new ExpectedItemCheck(new LocalDate(2012, 3, 2),
new LocalDate(2012, 3, 31), InvoiceItemType.RECURRING, new BigDecimal("561.25")));
invoiceChecker.checkChargedThroughDate(subscription.getId(), new LocalDate(2012, 3, 31), callContext);
@@ -198,10 +198,10 @@ public class TestIntegration extends TestIntegrationBase {
//
// MOVE 4 * TIME THE CLOCK
//
- setDateAndCheckForCompletion(new DateTime(2012, 2, 28, 0, 3, 45, 0, testTimeZone));
- setDateAndCheckForCompletion(new DateTime(2012, 2, 29, 0, 3, 45, 0, testTimeZone));
- setDateAndCheckForCompletion(new DateTime(2012, 3, 1, 0, 3, 45, 0, testTimeZone));
- setDateAndCheckForCompletion(new DateTime(2012, 3, 2, 0, 3, 45, 0, testTimeZone), NextEvent.PHASE, NextEvent.INVOICE, NextEvent.PAYMENT);
+ setDateAndCheckForCompletion(new DateTime(2012, 2, 28, 23, 59, 59, 0, testTimeZone));
+ setDateAndCheckForCompletion(new DateTime(2012, 2, 29, 23, 59, 59, 0, testTimeZone));
+ setDateAndCheckForCompletion(new DateTime(2012, 3, 1, 23, 59, 59, 0, testTimeZone));
+ setDateAndCheckForCompletion(new DateTime(2012, 3, 2, 23, 59, 59, 0, testTimeZone), NextEvent.PHASE, NextEvent.INVOICE, NextEvent.PAYMENT);
invoiceChecker.checkInvoice(account.getId(), invoiceItemCount++, callContext, new ExpectedItemCheck(new LocalDate(2012, 3, 2),
new LocalDate(2012, 4, 2), InvoiceItemType.RECURRING, new BigDecimal("599.95")));
invoiceChecker.checkChargedThroughDate(subscription.getId(), new LocalDate(2012, 4, 2), callContext);
@@ -280,16 +280,16 @@ public class TestIntegration extends TestIntegrationBase {
//
// MOVE 4 * TIME THE CLOCK
//
- setDateAndCheckForCompletion(new DateTime(2012, 2, 28, 0, 3, 45, 0, testTimeZone));
- setDateAndCheckForCompletion(new DateTime(2012, 2, 29, 0, 3, 45, 0, testTimeZone));
- setDateAndCheckForCompletion(new DateTime(2012, 3, 1, 0, 3, 45, 0, testTimeZone));
- setDateAndCheckForCompletion(new DateTime(2012, 3, 2, 0, 3, 45, 0, testTimeZone), NextEvent.PHASE, NextEvent.INVOICE, NextEvent.PAYMENT);
+ setDateAndCheckForCompletion(new DateTime(2012, 2, 28, 23, 59, 59, 0, testTimeZone));
+ setDateAndCheckForCompletion(new DateTime(2012, 2, 29, 23, 59, 59, 0, testTimeZone));
+ setDateAndCheckForCompletion(new DateTime(2012, 3, 1, 23, 59, 59, 0, testTimeZone));
+ setDateAndCheckForCompletion(new DateTime(2012, 3, 2, 23, 59, 59, 0, testTimeZone), NextEvent.PHASE, NextEvent.INVOICE, NextEvent.PAYMENT);
// PRO_RATION
invoiceChecker.checkInvoice(account.getId(), invoiceItemCount++, callContext, new ExpectedItemCheck(new LocalDate(2012, 3, 2),
new LocalDate(2012, 3, 3), InvoiceItemType.RECURRING, new BigDecimal("20.70")));
invoiceChecker.checkChargedThroughDate(subscription.getId(), new LocalDate(2012, 3, 3), callContext);
- setDateAndCheckForCompletion(new DateTime(2012, 3, 3, 0, 3, 45, 0, testTimeZone), NextEvent.INVOICE, NextEvent.PAYMENT);
+ setDateAndCheckForCompletion(new DateTime(2012, 3, 3, 23, 59, 59, 0, testTimeZone), NextEvent.INVOICE, NextEvent.PAYMENT);
invoiceChecker.checkInvoice(account.getId(), invoiceItemCount++, callContext, new ExpectedItemCheck(new LocalDate(2012, 3, 3),
new LocalDate(2012, 4, 3), InvoiceItemType.RECURRING, new BigDecimal("599.95")));
invoiceChecker.checkChargedThroughDate(subscription.getId(), new LocalDate(2012, 4, 3), callContext);
diff --git a/invoice/src/main/java/com/ning/billing/invoice/dao/AuditedInvoiceDao.java b/invoice/src/main/java/com/ning/billing/invoice/dao/AuditedInvoiceDao.java
index 90f071d..ec27c0c 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/dao/AuditedInvoiceDao.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/dao/AuditedInvoiceDao.java
@@ -25,7 +25,6 @@ import java.util.UUID;
import javax.annotation.Nullable;
-import org.joda.time.DateTime;
import org.joda.time.LocalDate;
import org.skife.jdbi.v2.IDBI;
import org.skife.jdbi.v2.Transaction;
@@ -44,7 +43,6 @@ import com.ning.billing.invoice.api.InvoiceItemType;
import com.ning.billing.invoice.api.InvoicePayment;
import com.ning.billing.invoice.api.InvoicePayment.InvoicePaymentType;
import com.ning.billing.invoice.api.user.DefaultInvoiceAdjustmentEvent;
-import com.ning.billing.invoice.generator.InvoiceDateUtils;
import com.ning.billing.invoice.model.CreditAdjInvoiceItem;
import com.ning.billing.invoice.model.CreditBalanceAdjInvoiceItem;
import com.ning.billing.invoice.model.DefaultInvoice;
@@ -206,7 +204,7 @@ public class AuditedInvoiceDao implements InvoiceDao {
audits.addAll(createAudits(TableName.INVOICE_ITEMS, recordIdList));
final List<InvoiceItem> recurringInvoiceItems = invoice.getInvoiceItems(RecurringInvoiceItem.class);
- notifyOfFutureBillingEvents(transactional, invoice.getAccountId(), billCycleDayUTC, recurringInvoiceItems);
+ notifyOfFutureBillingEvents(transactional, invoice.getAccountId(), recurringInvoiceItems);
final List<InvoicePayment> invoicePayments = invoice.getPayments();
final InvoicePaymentSqlDao invoicePaymentSqlDao = transactional.become(InvoicePaymentSqlDao.class);
@@ -948,31 +946,22 @@ public class AuditedInvoiceDao implements InvoiceDao {
invoice.addPayments(invoicePayments);
}
- private void notifyOfFutureBillingEvents(final InvoiceSqlDao dao, final UUID accountId, final int billCycleDayUTC, final List<InvoiceItem> invoiceItems) {
- UUID subscriptionForNextNotification = null;
- boolean shouldBeNotified = false;
+ private void notifyOfFutureBillingEvents(final InvoiceSqlDao dao, final UUID accountId, final List<InvoiceItem> invoiceItems) {
+
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)) {
- subscriptionForNextNotification = recurringInvoiceItem.getSubscriptionId();
- shouldBeNotified = true;
- break;
+ //
+ // We insert a future notification for each recurring subscription at the end of the service period = new CTD of the subscription
+ //
+ nextBillingDatePoster.insertNextBillingNotification(dao, accountId, recurringInvoiceItem.getSubscriptionId(),
+ recurringInvoiceItem.getEndDate().toDateTimeAtCurrentTime());
}
}
}
-
- // We only need to get notified on the BCD. For other invoice events (e.g. phase changes),
- // we'll be notified by entitlement.
- if (shouldBeNotified) {
- // We could be notified at any time during the day at the billCycleDay - use the current time to
- // spread the load.
- final DateTime nextNotificationDateTime = InvoiceDateUtils.calculateBillingCycleDateAfter(clock.getUTCNow(), billCycleDayUTC);
- // NextBillingDatePoster will ignore duplicates
- nextBillingDatePoster.insertNextBillingNotification(dao, accountId, subscriptionForNextNotification, nextNotificationDateTime);
- }
}
private void notifyBusOfInvoiceAdjustment(final Transmogrifier transactional, final UUID invoiceId, final UUID accountId,
diff --git a/invoice/src/main/java/com/ning/billing/invoice/notification/DefaultNextBillingDatePoster.java b/invoice/src/main/java/com/ning/billing/invoice/notification/DefaultNextBillingDatePoster.java
index 5788d4b..54448e3 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/notification/DefaultNextBillingDatePoster.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/notification/DefaultNextBillingDatePoster.java
@@ -17,7 +17,6 @@
package com.ning.billing.invoice.notification;
import java.io.IOException;
-import java.util.List;
import java.util.UUID;
import org.joda.time.DateTime;
@@ -30,7 +29,6 @@ import com.ning.billing.util.callcontext.CallOrigin;
import com.ning.billing.util.callcontext.InternalCallContext;
import com.ning.billing.util.callcontext.InternalCallContextFactory;
import com.ning.billing.util.callcontext.UserType;
-import com.ning.billing.util.notificationq.Notification;
import com.ning.billing.util.notificationq.NotificationQueue;
import com.ning.billing.util.notificationq.NotificationQueueService;
import com.ning.billing.util.notificationq.NotificationQueueService.NoSuchNotificationQueue;
@@ -62,13 +60,6 @@ public class DefaultNextBillingDatePoster implements NextBillingDatePoster {
DefaultNextBillingDateNotifier.NEXT_BILLING_DATE_NOTIFIER_QUEUE);
log.info("Queuing next billing date notification. id: {}, timestamp: {}", subscriptionId.toString(), futureNotificationTime.toString());
- final List<Notification> existingNotifications = nextBillingQueue.getNotificationForAccountAndDate(accountId, futureNotificationTime, context);
- if (existingNotifications.size() > 0) {
- log.info(String.format("%s : notification for account %s and date %s already exist, skip...",
- DefaultNextBillingDateNotifier.NEXT_BILLING_DATE_NOTIFIER_QUEUE, accountId, futureNotificationTime));
- return;
- }
-
nextBillingQueue.recordFutureNotificationFromTransaction(transactionalDao, futureNotificationTime, accountId,
new NextBillingDateNotificationKey(subscriptionId), context);
} catch (NoSuchNotificationQueue e) {