killbill-memoizeit

Fix entitlement to not return UNCANCEL events to junction (billing

1/30/2013 10:38:21 PM

Changes

Details

diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/api/svcs/DefaultEntitlementInternalApi.java b/entitlement/src/main/java/com/ning/billing/entitlement/api/svcs/DefaultEntitlementInternalApi.java
index e5b3a46..3de50f6 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/api/svcs/DefaultEntitlementInternalApi.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/api/svcs/DefaultEntitlementInternalApi.java
@@ -113,14 +113,12 @@ public class DefaultEntitlementInternalApi extends EntitlementApiBase implements
 
     @Override
     public void setChargedThroughDate(UUID subscriptionId,
-                                      LocalDate localChargedThruDate, InternalCallContext context) {
+                                      DateTime chargedThruDate, InternalCallContext context) {
         final SubscriptionData subscription = (SubscriptionData) dao.getSubscriptionFromId(subscriptionId, context);
-        final DateTime chargedThroughDate = localChargedThruDate.toDateTime(new LocalTime(subscription.getStartDate(), DateTimeZone.UTC), DateTimeZone.UTC);
         final SubscriptionBuilder builder = new SubscriptionBuilder(subscription)
-                .setChargedThroughDate(chargedThroughDate)
+                .setChargedThroughDate(chargedThruDate)
                 .setPaidThroughDate(subscription.getPaidThroughDate());
 
-        log.info("Setting CTD for subscription {} to {} ({} local)", new Object[]{subscriptionId, chargedThroughDate, localChargedThruDate});
         dao.updateChargedThroughDate(new SubscriptionData(builder), context);
     }
 
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionData.java b/entitlement/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionData.java
index 04e70f5..0a39819 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionData.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionData.java
@@ -28,6 +28,7 @@ import org.joda.time.DateTime;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.ning.billing.ErrorCode;
 import com.ning.billing.catalog.api.ActionPolicy;
 import com.ning.billing.catalog.api.BillingPeriod;
 import com.ning.billing.catalog.api.Catalog;
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionTransitionDataIterator.java b/entitlement/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionTransitionDataIterator.java
index bd9ec62..130e50a 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionTransitionDataIterator.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionTransitionDataIterator.java
@@ -81,8 +81,8 @@ public class SubscriptionTransitionDataIterator implements Iterator<Subscription
         if (visibility == Visibility.FROM_DISK_ONLY && !input.isFromDisk()) {
             return true;
         }
-        if ((kind == Kind.ENTITLEMENT && input.getTransitionType() == SubscriptionTransitionType.MIGRATE_BILLING) ||
-                (kind == Kind.BILLING && input.getTransitionType() == SubscriptionTransitionType.MIGRATE_ENTITLEMENT)) {
+        if ((kind == Kind.ENTITLEMENT && shouldSkipForEntitlementEvents(input)) ||
+            (kind == Kind.BILLING && shouldSkipForBillingEvents(input))) {
             return true;
         }
         if ((timeLimit == TimeLimit.FUTURE_ONLY && !input.getEffectiveTransitionTime().isAfter(clock.getUTCNow())) ||
@@ -92,6 +92,19 @@ public class SubscriptionTransitionDataIterator implements Iterator<Subscription
         return false;
     }
 
+    private boolean shouldSkipForEntitlementEvents(final SubscriptionTransitionData input) {
+        // Entitlement system knows about all events except for MIGRATE_BILLING
+        return (input.getTransitionType() == SubscriptionTransitionType.MIGRATE_BILLING);
+    }
+
+    private boolean shouldSkipForBillingEvents(final SubscriptionTransitionData input) {
+        // Junction system knows about all events except for MIGRATE_ENTITLEMENT and UNCANCEL-- which is a NO event as it undo
+        // something that should have happened in the future.
+        return (input.getTransitionType() == SubscriptionTransitionType.MIGRATE_ENTITLEMENT ||
+                input.getTransitionType() == SubscriptionTransitionType.UNCANCEL);
+    }
+
+
     @Override
     public SubscriptionTransitionData next() {
         return next;
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/timeline/TestRepairBP.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/timeline/TestRepairBP.java
index d03ef83..3c9a938 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/timeline/TestRepairBP.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/timeline/TestRepairBP.java
@@ -583,7 +583,7 @@ public class TestRepairBP extends EntitlementTestSuiteWithEmbeddedDB {
 
         // SET CTD to BASE SUBSCRIPTION SP CANCEL OCCURS EOT
         final DateTime newChargedThroughDate = baseSubscription.getStartDate().plusDays(30).plusMonths(1);
-        entitlementInternalApi.setChargedThroughDate(baseSubscription.getId(), newChargedThroughDate.toLocalDate(), internalCallContext);
+        entitlementInternalApi.setChargedThroughDate(baseSubscription.getId(), newChargedThroughDate, internalCallContext);
         baseSubscription = entitlementApi.getSubscriptionFromId(baseSubscription.getId(), callContext);
 
         final DateTime requestedChange = clock.getUTCNow();
@@ -696,7 +696,7 @@ public class TestRepairBP extends EntitlementTestSuiteWithEmbeddedDB {
                 // Move clock at least a sec to make sure the last_sys_update from bundle is different-- and therefore generates a different viewId
                 clock.setDeltaFromReality(1000);
 
-                entitlementInternalApi.setChargedThroughDate(baseSubscription.getId(), newChargedThroughDate.toLocalDate(), internalCallContext);
+                entitlementInternalApi.setChargedThroughDate(baseSubscription.getId(), newChargedThroughDate, internalCallContext);
                 entitlementApi.getSubscriptionFromId(baseSubscription.getId(), callContext);
 
                 repairApi.repairBundle(bRepair, true, callContext);
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/timeline/TestRepairWithAO.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/timeline/TestRepairWithAO.java
index 220cdd0..32c08b7 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/timeline/TestRepairWithAO.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/timeline/TestRepairWithAO.java
@@ -347,7 +347,7 @@ public class TestRepairWithAO extends EntitlementTestSuiteWithEmbeddedDB {
 
         // SET CTD to BASE SUBSCRIPTION SP CANCEL OCCURS EOT
         final DateTime newChargedThroughDate = baseSubscription.getStartDate().plusDays(30).plusMonths(1);
-        entitlementInternalApi.setChargedThroughDate(baseSubscription.getId(), newChargedThroughDate.toLocalDate(), internalCallContext);
+        entitlementInternalApi.setChargedThroughDate(baseSubscription.getId(), newChargedThroughDate, internalCallContext);
         baseSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(baseSubscription.getId(), callContext);
 
         BundleTimeline bundleRepair = repairApi.getBundleTimeline(bundle.getId(), callContext);
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/transfer/TestTransfer.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/transfer/TestTransfer.java
index 11a8dc4..98f2131 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/transfer/TestTransfer.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/transfer/TestTransfer.java
@@ -178,7 +178,7 @@ public class TestTransfer extends EntitlementTestSuiteWithEmbeddedDB {
         final Subscription baseSubscription = testUtil.createSubscription(bundle, baseProduct, baseTerm, basePriceList);
         final DateTime ctd = baseSubscription.getStartDate().plusDays(30);
 
-        entitlementInternalApi.setChargedThroughDate(baseSubscription.getId(), ctd.toLocalDate(), internalCallContext);
+        entitlementInternalApi.setChargedThroughDate(baseSubscription.getId(), ctd, internalCallContext);
 
         final DateTime evergreenPhaseDate = ((SubscriptionData) baseSubscription).getPendingTransition().getEffectiveTransitionTime();
 
@@ -281,7 +281,7 @@ public class TestTransfer extends EntitlementTestSuiteWithEmbeddedDB {
 
         // SET CTD
         final DateTime ctd = baseSubscription.getStartDate().plusDays(30).plusMonths(1);
-        entitlementInternalApi.setChargedThroughDate(baseSubscription.getId(), ctd.toLocalDate(), internalCallContext);
+        entitlementInternalApi.setChargedThroughDate(baseSubscription.getId(), ctd, internalCallContext);
 
 
         final DateTime transferRequestedDate = clock.getUTCNow();
@@ -326,7 +326,7 @@ public class TestTransfer extends EntitlementTestSuiteWithEmbeddedDB {
         clock.addDays(2);
 
         final DateTime newCtd = newBaseSubscription.getStartDate().plusYears(1);
-        entitlementInternalApi.setChargedThroughDate(newBaseSubscription.getId(), newCtd.toLocalDate(), internalCallContext);
+        entitlementInternalApi.setChargedThroughDate(newBaseSubscription.getId(), newCtd, internalCallContext);
         final Subscription newBaseSubscriptionWithCtd = entitlementApi.getSubscriptionFromId(newBaseSubscription.getId(), callContext);
 
         final String newBaseProduct2 = "Pistol";
@@ -377,7 +377,7 @@ public class TestTransfer extends EntitlementTestSuiteWithEmbeddedDB {
 
         // SET CTD TO TRIGGER CANCELLATION EOT
         final DateTime ctd = baseSubscription.getStartDate().plusDays(30).plusMonths(1);
-        entitlementInternalApi.setChargedThroughDate(baseSubscription.getId(), ctd.toLocalDate(), internalCallContext);
+        entitlementInternalApi.setChargedThroughDate(baseSubscription.getId(), ctd, internalCallContext);
 
         final DateTime transferRequestedDate = clock.getUTCNow();
         testListener.pushExpectedEvent(NextEvent.TRANSFER);
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiAddOn.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiAddOn.java
index fad3659..f74c866 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiAddOn.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiAddOn.java
@@ -107,7 +107,7 @@ public class TestUserApiAddOn extends EntitlementTestSuiteWithEmbeddedDB {
             final Duration ctd = testUtil.getDurationMonth(1);
             // Why not just use clock.getUTCNow().plusMonths(1) ?
             final DateTime newChargedThroughDate = DefaultClock.addDuration(now, ctd);
-            entitlementInternalApi.setChargedThroughDate(baseSubscription.getId(), newChargedThroughDate.toLocalDate(), internalCallContext);
+            entitlementInternalApi.setChargedThroughDate(baseSubscription.getId(), newChargedThroughDate, internalCallContext);
             baseSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(baseSubscription.getId(), callContext);
 
             // FUTURE CANCELLATION
@@ -167,7 +167,7 @@ public class TestUserApiAddOn extends EntitlementTestSuiteWithEmbeddedDB {
             final DateTime now = clock.getUTCNow();
             final Duration ctd = testUtil.getDurationMonth(1);
             final DateTime newChargedThroughDate = DefaultClock.addDuration(now, ctd);
-            entitlementInternalApi.setChargedThroughDate(baseSubscription.getId(), newChargedThroughDate.toLocalDate(), internalCallContext);
+            entitlementInternalApi.setChargedThroughDate(baseSubscription.getId(), newChargedThroughDate, internalCallContext);
             baseSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(baseSubscription.getId(), callContext);
 
             // CHANGE IMMEDIATELY WITH TO BP WITH NON INCLUDED ADDON
@@ -230,7 +230,7 @@ public class TestUserApiAddOn extends EntitlementTestSuiteWithEmbeddedDB {
             final DateTime now = clock.getUTCNow();
             final Duration ctd = testUtil.getDurationMonth(1);
             final DateTime newChargedThroughDate = DefaultClock.addDuration(now, ctd);
-            entitlementInternalApi.setChargedThroughDate(baseSubscription.getId(), newChargedThroughDate.toLocalDate(), internalCallContext);
+            entitlementInternalApi.setChargedThroughDate(baseSubscription.getId(), newChargedThroughDate, internalCallContext);
             baseSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(baseSubscription.getId(), callContext);
 
             // CHANGE IMMEDIATELY WITH TO BP WITH NON AVAILABLE ADDON
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCancel.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCancel.java
index 272414d..86cb455 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCancel.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCancel.java
@@ -114,7 +114,7 @@ public class TestUserApiCancel extends EntitlementTestSuiteWithEmbeddedDB {
             // SET CTD + RE READ SUBSCRIPTION + CHANGE PLAN
             final Duration ctd = testUtil.getDurationMonth(1);
             final DateTime newChargedThroughDate = DefaultClock.addDuration(expectedPhaseTrialChange, ctd);
-            entitlementInternalApi.setChargedThroughDate(subscription.getId(), newChargedThroughDate.toLocalDate(), internalCallContext);
+            entitlementInternalApi.setChargedThroughDate(subscription.getId(), newChargedThroughDate, internalCallContext);
             subscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(subscription.getId(), callContext);
 
             assertEquals(subscription.getLastActiveProductName(), prod);
@@ -234,7 +234,7 @@ public class TestUserApiCancel extends EntitlementTestSuiteWithEmbeddedDB {
             // SET CTD + RE READ SUBSCRIPTION + CHANGE PLAN
             final Duration ctd = testUtil.getDurationMonth(1);
             final DateTime newChargedThroughDate = DefaultClock.addDuration(expectedPhaseTrialChange, ctd);
-            entitlementInternalApi.setChargedThroughDate(subscription.getId(), newChargedThroughDate.toLocalDate(), internalCallContext);
+            entitlementInternalApi.setChargedThroughDate(subscription.getId(), newChargedThroughDate, internalCallContext);
             subscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(subscription.getId(), callContext);
 
             // CANCEL EOT
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiChangePlan.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiChangePlan.java
index f8ed15c..151300b 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiChangePlan.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiChangePlan.java
@@ -122,7 +122,7 @@ public class TestUserApiChangePlan extends EntitlementTestSuiteWithEmbeddedDB {
             // SET CTD
             final Duration ctd = testUtil.getDurationMonth(1);
             final DateTime newChargedThroughDate = DefaultClock.addDuration(expectedPhaseTrialChange, ctd);
-            entitlementInternalApi.setChargedThroughDate(subscription.getId(), newChargedThroughDate.toLocalDate(), internalCallContext);
+            entitlementInternalApi.setChargedThroughDate(subscription.getId(), newChargedThroughDate, internalCallContext);
 
             // RE READ SUBSCRIPTION + CHANGE PLAN
             testListener.setNonExpectedMode();
@@ -227,7 +227,7 @@ public class TestUserApiChangePlan extends EntitlementTestSuiteWithEmbeddedDB {
             // SET CTD
             final Duration ctd = testUtil.getDurationMonth(1);
             final DateTime newChargedThroughDate = DefaultClock.addDuration(expectedPhaseTrialChange, ctd);
-            entitlementInternalApi.setChargedThroughDate(subscription.getId(), newChargedThroughDate.toLocalDate(), internalCallContext);
+            entitlementInternalApi.setChargedThroughDate(subscription.getId(), newChargedThroughDate, internalCallContext);
 
             // RE READ SUBSCRIPTION + CHECK CURRENT PHASE
             subscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(subscription.getId(), callContext);
@@ -309,7 +309,7 @@ public class TestUserApiChangePlan extends EntitlementTestSuiteWithEmbeddedDB {
             final DateTime startDiscountPhase = DefaultClock.addDuration(subscription.getStartDate(), durationList);
             final Duration ctd = testUtil.getDurationMonth(1);
             final DateTime newChargedThroughDate = DefaultClock.addDuration(startDiscountPhase, ctd);
-            entitlementInternalApi.setChargedThroughDate(subscription.getId(), newChargedThroughDate.toLocalDate(), internalCallContext);
+            entitlementInternalApi.setChargedThroughDate(subscription.getId(), newChargedThroughDate, internalCallContext);
             subscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(subscription.getId(), callContext);
 
             // CHANGE EOT
@@ -358,7 +358,7 @@ public class TestUserApiChangePlan extends EntitlementTestSuiteWithEmbeddedDB {
             final DateTime startDiscountPhase = DefaultClock.addDuration(subscription.getStartDate(), durationList);
             final Duration ctd = testUtil.getDurationMonth(1);
             final DateTime newChargedThroughDate = DefaultClock.addDuration(startDiscountPhase, ctd);
-            entitlementInternalApi.setChargedThroughDate(subscription.getId(), newChargedThroughDate.toLocalDate(), internalCallContext);
+            entitlementInternalApi.setChargedThroughDate(subscription.getId(), newChargedThroughDate, internalCallContext);
             subscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(subscription.getId(), callContext);
 
             // CHANGE EOT
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiError.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiError.java
index eff68f2..c4c3088 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiError.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiError.java
@@ -192,7 +192,7 @@ public class TestUserApiError extends EntitlementTestSuiteNoDB {
             final DateTime expectedPhaseTrialChange = DefaultClock.addDuration(subscription.getStartDate(), trialPhase.getDuration());
             final Duration ctd = testUtil.getDurationMonth(1);
             final DateTime newChargedThroughDate = DefaultClock.addDuration(expectedPhaseTrialChange, ctd);
-            entitlementInternalApi.setChargedThroughDate(subscription.getId(), newChargedThroughDate.toLocalDate(), internalCallContext);
+            entitlementInternalApi.setChargedThroughDate(subscription.getId(), newChargedThroughDate, internalCallContext);
 
             subscription = entitlementApi.getSubscriptionFromId(subscription.getId(), tenantContext);
 
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 0b6e32e..502e3be 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
@@ -28,7 +28,6 @@ import java.util.UUID;
 
 import javax.annotation.Nullable;
 
-import org.joda.time.DateTimeZone;
 import org.joda.time.LocalDate;
 import org.joda.time.Months;
 import org.slf4j.Logger;
@@ -82,7 +81,7 @@ public class DefaultInvoiceGenerator implements InvoiceGenerator {
     @Override
     public Invoice generateInvoice(final UUID accountId, @Nullable final BillingEventSet events,
                                    @Nullable final List<Invoice> existingInvoices,
-                                   final LocalDate targetDate, final DateTimeZone accountTimeZone,
+                                   final LocalDate targetDate,
                                    final Currency targetCurrency) throws InvoiceApiException {
         if ((events == null) || (events.size() == 0) || events.isAccountAutoInvoiceOff()) {
             return null;
@@ -111,7 +110,7 @@ public class DefaultInvoiceGenerator implements InvoiceGenerator {
 
         final Invoice invoice = new DefaultInvoice(accountId, clock.getUTCToday(), adjustedTargetDate, targetCurrency);
         final UUID invoiceId = invoice.getId();
-        final List<InvoiceItem> proposedItems = generateInvoiceItems(invoiceId, accountId, events, adjustedTargetDate, accountTimeZone, targetCurrency);
+        final List<InvoiceItem> proposedItems = generateInvoiceItems(invoiceId, accountId, events, adjustedTargetDate, targetCurrency);
 
         removeCancellingInvoiceItems(existingItems);
         removeDuplicatedInvoiceItems(proposedItems, existingItems);
@@ -298,7 +297,7 @@ public class DefaultInvoiceGenerator implements InvoiceGenerator {
     }
 
     private List<InvoiceItem> generateInvoiceItems(final UUID invoiceId, final UUID accountId, final BillingEventSet events,
-                                                   final LocalDate targetDate, final DateTimeZone accountTimeZone, final Currency currency) throws InvoiceApiException {
+                                                   final LocalDate targetDate, final Currency currency) throws InvoiceApiException {
         final List<InvoiceItem> items = new ArrayList<InvoiceItem>();
 
         if (events.size() == 0) {
@@ -319,10 +318,10 @@ public class DefaultInvoiceGenerator implements InvoiceGenerator {
             if (!events.getSubscriptionIdsWithAutoInvoiceOff().
                     contains(thisEvent.getSubscription().getId())) { // don't consider events for subscriptions that have auto_invoice_off
                 final BillingEvent adjustedNextEvent = (thisEvent.getSubscription().getId() == nextEvent.getSubscription().getId()) ? nextEvent : null;
-                items.addAll(processEvents(invoiceId, accountId, thisEvent, adjustedNextEvent, targetDate, accountTimeZone, currency, logStringBuilder));
+                items.addAll(processEvents(invoiceId, accountId, thisEvent, adjustedNextEvent, targetDate, currency, logStringBuilder));
             }
         }
-        items.addAll(processEvents(invoiceId, accountId, nextEvent, null, targetDate, accountTimeZone, currency, logStringBuilder));
+        items.addAll(processEvents(invoiceId, accountId, nextEvent, null, targetDate, currency, logStringBuilder));
 
         log.info(logStringBuilder.toString());
 
@@ -331,7 +330,7 @@ public class DefaultInvoiceGenerator implements InvoiceGenerator {
 
     // Turn a set of events into a list of invoice items. Note that the dates on the invoice items will be rounded (granularity of a day)
     private List<InvoiceItem> processEvents(final UUID invoiceId, final UUID accountId, final BillingEvent thisEvent, @Nullable final BillingEvent nextEvent,
-                                            final LocalDate targetDate, final DateTimeZone accountTimeZone, final Currency currency,
+                                            final LocalDate targetDate, final Currency currency,
                                             final StringBuilder logStringBuilder) throws InvoiceApiException {
         final List<InvoiceItem> items = new ArrayList<InvoiceItem>();
 
@@ -354,7 +353,7 @@ public class DefaultInvoiceGenerator implements InvoiceGenerator {
 
                 final List<RecurringInvoiceItemData> itemData;
                 try {
-                    itemData = billingMode.calculateInvoiceItemData(startDate, endDate, targetDate, accountTimeZone, billCycleDayLocal, billingPeriod);
+                    itemData = billingMode.calculateInvoiceItemData(startDate, endDate, targetDate, billCycleDayLocal, 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/generator/InvoiceDateUtils.java b/invoice/src/main/java/com/ning/billing/invoice/generator/InvoiceDateUtils.java
index 0a0aeb9..0719e1a 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/generator/InvoiceDateUtils.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/generator/InvoiceDateUtils.java
@@ -140,6 +140,7 @@ public class InvoiceDateUtils {
         return days.divide(daysInPeriod, 2 * NUMBER_OF_DECIMALS, ROUNDING_METHOD);
     }
 
+ /*
     public static LocalDate calculateBillingCycleDateOnOrAfter(final LocalDate date, final DateTimeZone accountTimeZone,
                                                                final int billingCycleDayLocal) {
         final DateTime tmp = date.toDateTimeAtStartOfDay(accountTimeZone);
@@ -155,30 +156,30 @@ public class InvoiceDateUtils {
 
         return new LocalDate(proposedDateTime, accountTimeZone);
     }
+    */
 
-    private static DateTime calculateBillingCycleDateOnOrAfter(final DateTime date, final int billingCycleDayLocal) {
+    public static LocalDate calculateBillingCycleDateOnOrAfter(final LocalDate date, final int billingCycleDayLocal) {
         final int lastDayOfMonth = date.dayOfMonth().getMaximumValue();
 
-        final MutableDateTime tmp = date.toMutableDateTime();
+        final LocalDate fixedDate;
         if (billingCycleDayLocal > lastDayOfMonth) {
-            tmp.setDayOfMonth(lastDayOfMonth);
+            fixedDate = new LocalDate(date.getYear(), date.getMonthOfYear(), lastDayOfMonth, date.getChronology());
         } else {
-            tmp.setDayOfMonth(billingCycleDayLocal);
+            fixedDate = new LocalDate(date.getYear(), date.getMonthOfYear(), billingCycleDayLocal, date.getChronology());
         }
-        DateTime proposedDate = tmp.toDateTime();
 
+        LocalDate proposedDate = fixedDate;
         while (proposedDate.isBefore(date)) {
             proposedDate = proposedDate.plusMonths(1);
         }
         return proposedDate;
     }
 
-    private static DateTime calculateBillingCycleDateAfter(final DateTime date, final int billingCycleDayLocal) {
-        DateTime proposedDate = calculateBillingCycleDateOnOrAfter(date, billingCycleDayLocal);
+    public static LocalDate calculateBillingCycleDateAfter(final LocalDate date, final int billingCycleDayLocal) {
+        LocalDate proposedDate = calculateBillingCycleDateOnOrAfter(date, billingCycleDayLocal);
         if (date.compareTo(proposedDate) == 0) {
             proposedDate = proposedDate.plusMonths(1);
         }
-
         return proposedDate;
     }
 }
diff --git a/invoice/src/main/java/com/ning/billing/invoice/generator/InvoiceGenerator.java b/invoice/src/main/java/com/ning/billing/invoice/generator/InvoiceGenerator.java
index 3520532..97efc61 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/generator/InvoiceGenerator.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/generator/InvoiceGenerator.java
@@ -32,5 +32,5 @@ import com.ning.billing.util.svcapi.junction.BillingEventSet;
 public interface InvoiceGenerator {
 
     public Invoice generateInvoice(UUID accountId, @Nullable BillingEventSet events, @Nullable List<Invoice> existingInvoices,
-                                   LocalDate targetDate, DateTimeZone accountTimeZone, Currency targetCurrency) throws InvoiceApiException;
+                                   LocalDate targetDate, Currency targetCurrency) throws InvoiceApiException;
 }
diff --git a/invoice/src/main/java/com/ning/billing/invoice/InvoiceDispatcher.java b/invoice/src/main/java/com/ning/billing/invoice/InvoiceDispatcher.java
index e3ff271..ca8d8dd 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/InvoiceDispatcher.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/InvoiceDispatcher.java
@@ -34,7 +34,6 @@ import org.slf4j.LoggerFactory;
 import com.ning.billing.ErrorCode;
 import com.ning.billing.account.api.Account;
 import com.ning.billing.account.api.AccountApiException;
-import com.ning.billing.account.api.BillCycleDay;
 import com.ning.billing.catalog.api.Currency;
 import com.ning.billing.entitlement.api.user.EntitlementUserApiException;
 import com.ning.billing.invoice.api.Invoice;
@@ -49,7 +48,6 @@ import com.ning.billing.invoice.dao.InvoiceDao;
 import com.ning.billing.invoice.dao.InvoiceItemModelDao;
 import com.ning.billing.invoice.dao.InvoiceModelDao;
 import com.ning.billing.invoice.dao.InvoicePaymentModelDao;
-import com.ning.billing.invoice.generator.InvoiceDateUtils;
 import com.ning.billing.invoice.generator.InvoiceGenerator;
 import com.ning.billing.invoice.model.DefaultInvoice;
 import com.ning.billing.invoice.model.FixedPriceInvoiceItem;
@@ -152,14 +150,20 @@ public class InvoiceDispatcher {
         return null;
     }
 
+
     private Invoice processAccountWithLock(final UUID accountId, final DateTime targetDateTime,
                                            final boolean dryRun, final InternalCallContext context) throws InvoiceApiException {
         try {
 
             // Make sure to first set the BCD if needed then get the account object (to have the BCD set)
             final BillingEventSet billingEvents = billingApi.getBillingEventsForAccountAndUpdateAccountBCD(accountId, context);
-
             final Account account = accountApi.getAccountById(accountId, context);
+
+            final DateAndTimeZoneContext dateAndTimeZoneContext = billingEvents.iterator().hasNext() ?
+                                                                  new DateAndTimeZoneContext(billingEvents.iterator().next().getEffectiveDate(), account.getTimeZone(), clock) :
+                                                                  new DateAndTimeZoneContext(null, account.getTimeZone(), clock);
+
+
             List<Invoice> invoices = new ArrayList<Invoice>();
             if (!billingEvents.isAccountAutoInvoiceOff()) {
                 invoices = ImmutableList.<Invoice>copyOf(Collections2.transform(invoiceDao.getInvoicesByAccount(accountId, context),
@@ -173,10 +177,8 @@ public class InvoiceDispatcher {
 
             final Currency targetCurrency = account.getCurrency();
 
-            // All the computations in invoice are performed on days, in the account timezone
-            final LocalDate targetDate = new LocalDate(targetDateTime, account.getTimeZone());
-
-            final Invoice invoice = generator.generateInvoice(accountId, billingEvents, invoices, targetDate, account.getTimeZone(), targetCurrency);
+            final LocalDate targetDate = dateAndTimeZoneContext.computeTargetDate(targetDateTime);
+            final Invoice invoice = generator.generateInvoice(accountId, billingEvents, invoices, targetDate, targetCurrency);
             if (invoice == null) {
                 log.info("Generated null invoice for accountId {} and targetDate {} (targetDateTime {})", new Object[]{accountId, targetDate, targetDateTime});
                 if (!dryRun) {
@@ -186,7 +188,7 @@ public class InvoiceDispatcher {
                 }
             } else {
                 log.info("Generated invoice {} with {} items for accountId {} and targetDate {} (targetDateTime {})", new Object[]{invoice.getId(), invoice.getNumberOfItems(),
-                                                                                                                                   accountId, targetDate, targetDateTime});
+                        accountId, targetDate, targetDateTime});
                 if (!dryRun) {
                     // We need to check whether this is just a 'shell' invoice or a real invoice with items on it
                     final boolean isRealInvoiceWithItems = Collections2.filter(invoice.getInvoiceItems(), new Predicate<InvoiceItem>() {
@@ -213,12 +215,12 @@ public class InvoiceDispatcher {
                                                                                                                                                          }
                                                                                                                                                      }));
 
-                    final Map<UUID, DateTime> callbackDateTimePerSubscriptions = createNextFutureNotificationDate(invoiceItemModelDaos, account.getTimeZone());
+                    final Map<UUID, DateTime> callbackDateTimePerSubscriptions = createNextFutureNotificationDate(invoiceItemModelDaos, dateAndTimeZoneContext);
                     invoiceDao.createInvoice(invoiceModelDao, invoiceItemModelDaos, invoicePaymentModelDaos, isRealInvoiceWithItems, callbackDateTimePerSubscriptions, context);
 
                     final List<InvoiceItem> fixedPriceInvoiceItems = invoice.getInvoiceItems(FixedPriceInvoiceItem.class);
                     final List<InvoiceItem> recurringInvoiceItems = invoice.getInvoiceItems(RecurringInvoiceItem.class);
-                    setChargedThroughDates(account.getBillCycleDay(), account.getTimeZone(), fixedPriceInvoiceItems, recurringInvoiceItems, context);
+                    setChargedThroughDates(dateAndTimeZoneContext, fixedPriceInvoiceItems, recurringInvoiceItems, context);
 
                     final InvoiceCreationInternalEvent event = new DefaultInvoiceCreationEvent(invoice.getId(), invoice.getAccountId(),
                                                                                                invoice.getBalance(), invoice.getCurrency(),
@@ -247,7 +249,7 @@ public class InvoiceDispatcher {
 
 
     @VisibleForTesting
-    Map<UUID, DateTime> createNextFutureNotificationDate(final List<InvoiceItemModelDao> invoiceItems, final DateTimeZone accountTimeZone) {
+    Map<UUID, DateTime> createNextFutureNotificationDate(final List<InvoiceItemModelDao> invoiceItems, final DateAndTimeZoneContext dateAndTimeZoneContext) {
         final Map<UUID, DateTime> result = new HashMap<UUID, DateTime>();
 
         // For each subscription that has a positive (amount) recurring item, create the date
@@ -258,40 +260,24 @@ public class InvoiceDispatcher {
                 if ((item.getEndDate() != null) &&
                     (item.getAmount() == null ||
                      item.getAmount().compareTo(BigDecimal.ZERO) >= 0)) {
-
-                    //
-                    // Since we create the targetDate for next invoice using the date from the notificationQ, we need to make sure
-                    // that this datetime once transformed into a LocalDate points to the correct day.
-                    //
-                    // e.g If accountTimeZone is -8 and we want to invoice on the 16, with a toDateTimeAtCurrentTime = 00:00:23,
-                    // we will generate a datetime that is 16T08:00:23 => LocalDate in that timeZone stays on the 16.
-                    //
-                    // With that approach, the time (part) will vary between each call, but the day will stay correct:
-                    // e.g 00:00:23 -> 08:00:23 -> 16:00:23 -> 00:00:23 (3 different times generated)
-                    //
-                    final int deltaMs = accountTimeZone.getOffset(clock.getUTCNow());
-                    final int negativeDeltaMs = -1 * deltaMs;
-
-                    final LocalTime localTime = clock.getUTCNow().toLocalTime();
-                    result.put(item.getSubscriptionId(), item.getEndDate().toDateTime(localTime, DateTimeZone.UTC).plusMillis(negativeDeltaMs));
+                    result.put(item.getSubscriptionId(), dateAndTimeZoneContext.computeUTCDateTimeFromLocalDate(item.getEndDate()));
                 }
             }
         }
         return result;
     }
 
-    private void setChargedThroughDates(final BillCycleDay billCycleDay,
-                                        final DateTimeZone accountTimeZone,
+    private void setChargedThroughDates(final DateAndTimeZoneContext dateAndTimeZoneContext,
                                         final Collection<InvoiceItem> fixedPriceItems,
                                         final Collection<InvoiceItem> recurringItems,
                                         final InternalCallContext context) {
-        final Map<UUID, LocalDate> chargeThroughDates = new HashMap<UUID, LocalDate>();
-        addInvoiceItemsToChargeThroughDates(billCycleDay, accountTimeZone, chargeThroughDates, fixedPriceItems);
-        addInvoiceItemsToChargeThroughDates(billCycleDay, accountTimeZone, chargeThroughDates, recurringItems);
+        final Map<UUID, DateTime> chargeThroughDates = new HashMap<UUID, DateTime>();
+        addInvoiceItemsToChargeThroughDates(dateAndTimeZoneContext, chargeThroughDates, fixedPriceItems);
+        addInvoiceItemsToChargeThroughDates(dateAndTimeZoneContext, chargeThroughDates, recurringItems);
 
         for (final UUID subscriptionId : chargeThroughDates.keySet()) {
             if (subscriptionId != null) {
-                final LocalDate chargeThroughDate = chargeThroughDates.get(subscriptionId);
+                final DateTime chargeThroughDate = chargeThroughDates.get(subscriptionId);
                 entitlementApi.setChargedThroughDate(subscriptionId, chargeThroughDate, context);
             }
         }
@@ -305,24 +291,58 @@ public class InvoiceDispatcher {
         }
     }
 
-    private void addInvoiceItemsToChargeThroughDates(final BillCycleDay billCycleDay,
-                                                     final DateTimeZone accountTimeZone,
-                                                     final Map<UUID, LocalDate> chargeThroughDates,
+    private void addInvoiceItemsToChargeThroughDates(final DateAndTimeZoneContext dateAndTimeZoneContext,
+                                                     final Map<UUID, DateTime> chargeThroughDates,
                                                      final Collection<InvoiceItem> items) {
 
         for (final InvoiceItem item : items) {
             final UUID subscriptionId = item.getSubscriptionId();
             final LocalDate endDate = (item.getEndDate() != null) ? item.getEndDate() : item.getStartDate();
 
+            final DateTime proposedChargedThroughDate = dateAndTimeZoneContext.computeUTCDateTimeFromLocalDate(endDate);
             if (chargeThroughDates.containsKey(subscriptionId)) {
-                if (chargeThroughDates.get(subscriptionId).isBefore(endDate)) {
-                    // The CTD should always align with the BCD
-                    final LocalDate ctd = InvoiceDateUtils.calculateBillingCycleDateOnOrAfter(endDate, accountTimeZone, billCycleDay.getDayOfMonthLocal());
-                    chargeThroughDates.put(subscriptionId, ctd);
+                if (chargeThroughDates.get(subscriptionId).isBefore(proposedChargedThroughDate)) {
+                    chargeThroughDates.put(subscriptionId, proposedChargedThroughDate);
                 }
             } else {
-                chargeThroughDates.put(subscriptionId, endDate);
+                chargeThroughDates.put(subscriptionId, proposedChargedThroughDate);
             }
         }
     }
+
+    final static class DateAndTimeZoneContext {
+
+        private final LocalTime referenceTime;
+        private final DateTimeZone accountTimeZone;
+        private final Clock clock;
+
+        public DateAndTimeZoneContext(final DateTime effectiveDateTime, final DateTimeZone accountTimeZone, final Clock clock) {
+            this.clock = clock;
+            this.referenceTime = effectiveDateTime != null ? effectiveDateTime.toLocalTime() : null;
+            this.accountTimeZone = accountTimeZone;
+        }
+        public LocalDate computeTargetDate(final DateTime targetDateTime) {
+            return new LocalDate(targetDateTime, accountTimeZone);
+        }
+
+        public DateTime computeUTCDateTimeFromLocalDate(final LocalDate invoiceItemEndDate) {
+            //
+            // Since we create the targetDate for next invoice using the date from the notificationQ, we need to make sure
+            // that this datetime once transformed into a LocalDate points to the correct day.
+            //
+            // e.g If accountTimeZone is -8 and we want to invoice on the 16, with a toDateTimeAtCurrentTime = 00:00:23,
+            // we will generate a datetime that is 16T08:00:23 => LocalDate in that timeZone stays on the 16.
+            //
+            //
+            // We use clock.getUTCNow() to get the offset with account timezone but that may not be correct
+            // when we transition from standard time and daylight saving time. We could end up with a result
+            // that is slightly in advance and therefore results in a null invoice.
+            // We will fix that by re-inserting ourselves in the notificationQ if we detect that there is no invoice
+            // and yet the subscription is recurring and not cancelled.
+            //
+            final int utcOffest = accountTimeZone.getOffset(clock.getUTCNow());
+            final int localToUTCOffest = -1 * utcOffest;
+            return invoiceItemEndDate.toDateTime(referenceTime, DateTimeZone.UTC).plusMillis(localToUTCOffest);
+        }
+    }
 }
diff --git a/invoice/src/main/java/com/ning/billing/invoice/model/BillingMode.java b/invoice/src/main/java/com/ning/billing/invoice/model/BillingMode.java
index 39c5246..457fc96 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/model/BillingMode.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/model/BillingMode.java
@@ -28,5 +28,5 @@ import com.ning.billing.catalog.api.BillingPeriod;
 public interface BillingMode {
 
     List<RecurringInvoiceItemData> calculateInvoiceItemData(LocalDate startDate, @Nullable LocalDate endDate, LocalDate targetDate,
-                                                            DateTimeZone accountTimeZone, int billingCycleDay, BillingPeriod billingPeriod) throws InvalidDateSequenceException;
+                                                            int billingCycleDay, BillingPeriod billingPeriod) throws InvalidDateSequenceException;
 }
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 69193f6..d85ee7e 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
@@ -22,7 +22,6 @@ import java.util.List;
 
 import javax.annotation.Nullable;
 
-import org.joda.time.DateTimeZone;
 import org.joda.time.LocalDate;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -42,7 +41,7 @@ public class InAdvanceBillingMode implements BillingMode {
 
     @Override
     public List<RecurringInvoiceItemData> calculateInvoiceItemData(final LocalDate startDate, @Nullable final LocalDate endDate,
-                                                                   final LocalDate targetDate, final DateTimeZone accountTimeZone,
+                                                                   final LocalDate targetDate,
                                                                    final int billingCycleDayLocal, final BillingPeriod billingPeriod) throws InvalidDateSequenceException {
         if (endDate != null && endDate.isBefore(startDate)) {
             throw new InvalidDateSequenceException();
@@ -53,7 +52,7 @@ public class InAdvanceBillingMode implements BillingMode {
 
         final List<RecurringInvoiceItemData> results = new ArrayList<RecurringInvoiceItemData>();
 
-        final LocalDate firstBillingCycleDate = calculateBillingCycleDateOnOrAfter(startDate, accountTimeZone, billingCycleDayLocal);
+        final LocalDate firstBillingCycleDate = calculateBillingCycleDateOnOrAfter(startDate, billingCycleDayLocal);
 
         // We are not billing for less than a day (we could...)
         if (endDate != null && endDate.equals(startDate)) {
diff --git a/invoice/src/test/java/com/ning/billing/invoice/dao/TestInvoiceDao.java b/invoice/src/test/java/com/ning/billing/invoice/dao/TestInvoiceDao.java
index 736bfe3..b9e6825 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/dao/TestInvoiceDao.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/dao/TestInvoiceDao.java
@@ -25,7 +25,6 @@ import java.util.Map;
 import java.util.UUID;
 
 import org.joda.time.DateTime;
-import org.joda.time.DateTimeZone;
 import org.joda.time.LocalDate;
 import org.mockito.Mockito;
 import org.skife.jdbi.v2.exceptions.TransactionFailedException;
@@ -1031,7 +1030,7 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
         final BillingEventSet events = new MockBillingEventSet();
         events.add(event1);
 
-        final Invoice invoice1 = generator.generateInvoice(accountId, events, invoiceList, targetDate, DateTimeZone.UTC, Currency.USD);
+        final Invoice invoice1 = generator.generateInvoice(accountId, events, invoiceList, targetDate, Currency.USD);
         assertEquals(invoice1.getBalance(), TEN);
         invoiceList.add(invoice1);
 
@@ -1049,7 +1048,7 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
 
         // second invoice should be for one half (14/28 days) the difference between the rate plans
         // this is a temporary state, since it actually contains an adjusting item that properly belong to invoice 1
-        final Invoice invoice2 = generator.generateInvoice(accountId, events, invoiceList, targetDate, DateTimeZone.UTC, Currency.USD);
+        final Invoice invoice2 = generator.generateInvoice(accountId, events, invoiceList, targetDate, Currency.USD);
         assertEquals(invoice2.getBalance(), FIVE);
         invoiceList.add(invoice2);
 
@@ -1081,7 +1080,7 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
         events.add(event);
 
         final LocalDate targetDate = buildDate(2011, 1, 15);
-        final Invoice invoice = generator.generateInvoice(UUID.randomUUID(), events, null, targetDate, DateTimeZone.UTC, Currency.USD);
+        final Invoice invoice = generator.generateInvoice(UUID.randomUUID(), events, null, targetDate, Currency.USD);
 
         // expect one pro-ration item and one full-period item
         assertEquals(invoice.getNumberOfItems(), 2);
@@ -1120,7 +1119,7 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
         events.add(event1);
 
         final UUID accountId = UUID.randomUUID();
-        final Invoice invoice1 = generator.generateInvoice(accountId, events, null, new LocalDate(effectiveDate1), DateTimeZone.UTC, Currency.USD);
+        final Invoice invoice1 = generator.generateInvoice(accountId, events, null, new LocalDate(effectiveDate1), Currency.USD);
         assertNotNull(invoice1);
         assertEquals(invoice1.getNumberOfItems(), 1);
         assertEquals(invoice1.getBalance().compareTo(ZERO), 0);
@@ -1136,7 +1135,7 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
                                                            "testEvent2", 2L, SubscriptionTransitionType.PHASE);
         events.add(event2);
 
-        final Invoice invoice2 = generator.generateInvoice(accountId, events, invoiceList, new LocalDate(effectiveDate2), DateTimeZone.UTC, Currency.USD);
+        final Invoice invoice2 = generator.generateInvoice(accountId, events, invoiceList, new LocalDate(effectiveDate2), Currency.USD);
         assertNotNull(invoice2);
         assertEquals(invoice2.getNumberOfItems(), 1);
         assertEquals(invoice2.getBalance().compareTo(cheapAmount), 0);
@@ -1146,7 +1145,7 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
         //createInvoice(invoice2, invoice2.getTargetDate().getDayOfMonth(), internalCallContext);
 
         final DateTime effectiveDate3 = effectiveDate2.plusMonths(1);
-        final Invoice invoice3 = generator.generateInvoice(accountId, events, invoiceList, new LocalDate(effectiveDate3), DateTimeZone.UTC, Currency.USD);
+        final Invoice invoice3 = generator.generateInvoice(accountId, events, invoiceList, new LocalDate(effectiveDate3), Currency.USD);
         assertNotNull(invoice3);
         assertEquals(invoice3.getNumberOfItems(), 1);
         assertEquals(invoice3.getBalance().compareTo(cheapAmount), 0);
@@ -1157,7 +1156,7 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
     @Test(groups = "slow")
     public void testInvoiceForEmptyEventSet() throws InvoiceApiException {
         final BillingEventSet events = new MockBillingEventSet();
-        final Invoice invoice = generator.generateInvoice(UUID.randomUUID(), events, null, new LocalDate(), DateTimeZone.UTC, Currency.USD);
+        final Invoice invoice = generator.generateInvoice(UUID.randomUUID(), events, null, new LocalDate(), Currency.USD);
         assertNull(invoice);
     }
 
@@ -1191,7 +1190,7 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
                                                            "testEvent2", 2L, SubscriptionTransitionType.CHANGE);
         events.add(event2);
 
-        final Invoice invoice = generator.generateInvoice(UUID.randomUUID(), events, null, new LocalDate(effectiveDate2), DateTimeZone.UTC, Currency.USD);
+        final Invoice invoice = generator.generateInvoice(UUID.randomUUID(), events, null, new LocalDate(effectiveDate2), Currency.USD);
         assertNotNull(invoice);
         assertEquals(invoice.getNumberOfItems(), 2);
         assertEquals(invoice.getBalance().compareTo(cheapAmount), 0);
@@ -1266,7 +1265,7 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
                                                            BillingPeriod.MONTHLY, 1, BillingModeType.IN_ADVANCE,
                                                            "new-event", 1L, SubscriptionTransitionType.CREATE);
         events.add(event1);
-        final Invoice newInvoice = generator.generateInvoice(UUID.randomUUID(), events, invoices, targetDate, DateTimeZone.UTC, Currency.USD);
+        final Invoice newInvoice = generator.generateInvoice(UUID.randomUUID(), events, invoices, targetDate, Currency.USD);
         createInvoice(newInvoice, true, internalCallContext);
 
         // VERIFY THAT WE STILL HAVE ONLY 2 ITEMS, MENAING THERE WERE NO REPAIR AND NO CBA GENERATED
@@ -1301,7 +1300,7 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
                                                            "testEvent1", 1L, SubscriptionTransitionType.CHANGE);
         events.add(event1);
 
-        Invoice invoice1 = generator.generateInvoice(UUID.randomUUID(), events, invoices, new LocalDate(targetDate1), DateTimeZone.UTC, Currency.USD);
+        Invoice invoice1 = generator.generateInvoice(UUID.randomUUID(), events, invoices, new LocalDate(targetDate1), Currency.USD);
         invoices.add(invoice1);
         createInvoice(invoice1, true, internalCallContext);
         invoice1 = new DefaultInvoice(invoiceDao.getById(invoice1.getId(), internalCallContext));
@@ -1312,7 +1311,7 @@ public class TestInvoiceDao extends InvoiceDaoTestBase {
                                                            BillingPeriod.MONTHLY, 31, BillingModeType.IN_ADVANCE,
                                                            "testEvent2", 2L, SubscriptionTransitionType.CHANGE);
         events.add(event2);
-        Invoice invoice2 = generator.generateInvoice(UUID.randomUUID(), events, invoices, new LocalDate(targetDate2), DateTimeZone.UTC, Currency.USD);
+        Invoice invoice2 = generator.generateInvoice(UUID.randomUUID(), events, invoices, new LocalDate(targetDate2), Currency.USD);
         createInvoice(invoice2, true, internalCallContext);
         invoice2 = new DefaultInvoice(invoiceDao.getById(invoice2.getId(), internalCallContext));
         assertNotNull(invoice2.getInvoiceNumber());
diff --git a/invoice/src/test/java/com/ning/billing/invoice/generator/TestDefaultInvoiceGenerator.java b/invoice/src/test/java/com/ning/billing/invoice/generator/TestDefaultInvoiceGenerator.java
index 9c4087a..5514da0 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/generator/TestDefaultInvoiceGenerator.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/generator/TestDefaultInvoiceGenerator.java
@@ -97,7 +97,7 @@ public class TestDefaultInvoiceGenerator extends InvoicingTestBase {
     @Test(groups = "fast")
     public void testWithNullEventSetAndNullInvoiceSet() throws InvoiceApiException {
         final UUID accountId = UUID.randomUUID();
-        final Invoice invoice = generator.generateInvoice(accountId, null, null, clock.getUTCToday(), DateTimeZone.UTC, Currency.USD);
+        final Invoice invoice = generator.generateInvoice(accountId, null, null, clock.getUTCToday(), Currency.USD);
 
         assertNull(invoice);
     }
@@ -107,7 +107,7 @@ public class TestDefaultInvoiceGenerator extends InvoicingTestBase {
         final BillingEventSet events = new MockBillingEventSet();
 
         final UUID accountId = UUID.randomUUID();
-        final Invoice invoice = generator.generateInvoice(accountId, events, null, clock.getUTCToday(), DateTimeZone.UTC, Currency.USD);
+        final Invoice invoice = generator.generateInvoice(accountId, events, null, clock.getUTCToday(), Currency.USD);
 
         assertNull(invoice);
     }
@@ -128,7 +128,7 @@ public class TestDefaultInvoiceGenerator extends InvoicingTestBase {
 
         final LocalDate targetDate = buildDate(2011, 10, 3);
         final UUID accountId = UUID.randomUUID();
-        final Invoice invoice = generator.generateInvoice(accountId, events, null, targetDate, DateTimeZone.UTC, Currency.USD);
+        final Invoice invoice = generator.generateInvoice(accountId, events, null, targetDate, Currency.USD);
 
         assertNotNull(invoice);
         assertEquals(invoice.getNumberOfItems(), 2);
@@ -168,7 +168,7 @@ public class TestDefaultInvoiceGenerator extends InvoicingTestBase {
         // Target date is the next BCD, in local time
         final LocalDate targetDate = buildDate(2012, 8, bcdLocal);
         final DateTimeZone accountTimeZone = DateTimeZone.forID("HST");
-        final Invoice invoice = generator.generateInvoice(accountId, events, null, targetDate, accountTimeZone, Currency.USD);
+        final Invoice invoice = generator.generateInvoice(accountId, events, null, targetDate, Currency.USD);
 
         assertNotNull(invoice);
         assertEquals(invoice.getNumberOfItems(), 2);
@@ -193,7 +193,7 @@ public class TestDefaultInvoiceGenerator extends InvoicingTestBase {
 
         // Set a target date of today (start date)
         final LocalDate targetDate = startDate;
-        final Invoice invoice = generator.generateInvoice(accountId, events, null, targetDate, accountTimeZone, Currency.USD);
+        final Invoice invoice = generator.generateInvoice(accountId, events, null, targetDate, Currency.USD);
 
         assertNotNull(invoice);
         assertEquals(invoice.getNumberOfItems(), 1);
@@ -216,7 +216,7 @@ public class TestDefaultInvoiceGenerator extends InvoicingTestBase {
 
         final LocalDate targetDate = buildDate(2011, 10, 3);
         final UUID accountId = UUID.randomUUID();
-        final Invoice invoice = generator.generateInvoice(accountId, events, null, targetDate, DateTimeZone.UTC, Currency.USD);
+        final Invoice invoice = generator.generateInvoice(accountId, events, null, targetDate, Currency.USD);
 
         assertNotNull(invoice);
         assertEquals(invoice.getNumberOfItems(), 2);
@@ -249,7 +249,7 @@ public class TestDefaultInvoiceGenerator extends InvoicingTestBase {
 
         final LocalDate targetDate = buildDate(2011, 10, 3);
         final UUID accountId = UUID.randomUUID();
-        final Invoice invoice = generator.generateInvoice(accountId, events, null, targetDate, DateTimeZone.UTC, Currency.USD);
+        final Invoice invoice = generator.generateInvoice(accountId, events, null, targetDate, Currency.USD);
 
         assertNotNull(invoice);
         assertEquals(invoice.getNumberOfItems(), 2);
@@ -275,7 +275,7 @@ public class TestDefaultInvoiceGenerator extends InvoicingTestBase {
 
         final LocalDate targetDate = buildDate(2011, 12, 3);
         final UUID accountId = UUID.randomUUID();
-        final Invoice invoice = generator.generateInvoice(accountId, events, null, targetDate, DateTimeZone.UTC, Currency.USD);
+        final Invoice invoice = generator.generateInvoice(accountId, events, null, targetDate, Currency.USD);
 
         assertNotNull(invoice);
         assertEquals(invoice.getNumberOfItems(), 4);
@@ -317,7 +317,7 @@ public class TestDefaultInvoiceGenerator extends InvoicingTestBase {
 
         final LocalDate targetDate = buildDate(2011, 12, 3);
         final UUID accountId = UUID.randomUUID();
-        final Invoice invoice = generator.generateInvoice(accountId, events, null, targetDate, DateTimeZone.UTC, Currency.USD);
+        final Invoice invoice = generator.generateInvoice(accountId, events, null, targetDate, Currency.USD);
 
         assertNotNull(invoice);
         assertEquals(invoice.getNumberOfItems(), 4);
@@ -340,12 +340,12 @@ public class TestDefaultInvoiceGenerator extends InvoicingTestBase {
 
         LocalDate targetDate = buildDate(2011, 12, 1);
         final UUID accountId = UUID.randomUUID();
-        final Invoice invoice1 = generator.generateInvoice(accountId, events, null, targetDate, DateTimeZone.UTC, Currency.USD);
+        final Invoice invoice1 = generator.generateInvoice(accountId, events, null, targetDate, Currency.USD);
         final List<Invoice> existingInvoices = new ArrayList<Invoice>();
         existingInvoices.add(invoice1);
 
         targetDate = buildDate(2011, 12, 3);
-        final Invoice invoice2 = generator.generateInvoice(accountId, events, existingInvoices, targetDate, DateTimeZone.UTC, Currency.USD);
+        final Invoice invoice2 = generator.generateInvoice(accountId, events, existingInvoices, targetDate, Currency.USD);
 
         assertNull(invoice2);
     }
@@ -520,7 +520,7 @@ public class TestDefaultInvoiceGenerator extends InvoicingTestBase {
         final LocalDate targetDate = buildDate(2011, 1, 1);
         events.add(createBillingEvent(UUID.randomUUID(), targetDate, plan, planPhase, 1));
 
-        final Invoice invoice = generator.generateInvoice(UUID.randomUUID(), events, null, targetDate, DateTimeZone.UTC, Currency.USD);
+        final Invoice invoice = generator.generateInvoice(UUID.randomUUID(), events, null, targetDate, Currency.USD);
 
         assertEquals(invoice.getNumberOfItems(), 1);
     }
@@ -535,7 +535,7 @@ public class TestDefaultInvoiceGenerator extends InvoicingTestBase {
 
         events.add(createBillingEvent(UUID.randomUUID(), startDate, plan, planPhase, startDate.getDayOfMonth()));
 
-        final Invoice invoice = generator.generateInvoice(UUID.randomUUID(), events, null, targetDate, DateTimeZone.UTC, Currency.USD);
+        final Invoice invoice = generator.generateInvoice(UUID.randomUUID(), events, null, targetDate, Currency.USD);
         final RecurringInvoiceItem item = (RecurringInvoiceItem) invoice.getInvoiceItems().get(0);
 
         // end date of the invoice item should be equal to exactly one month later (rounded)
@@ -572,13 +572,13 @@ public class TestDefaultInvoiceGenerator extends InvoicingTestBase {
 
         events.add(event2);
         events.add(event1);
-        final Invoice invoice1 = generator.generateInvoice(accountId, events, null, new LocalDate("2012-02-01"), DateTimeZone.UTC, Currency.USD);
+        final Invoice invoice1 = generator.generateInvoice(accountId, events, null, new LocalDate("2012-02-01"), Currency.USD);
         assertNotNull(invoice1);
         assertEquals(invoice1.getNumberOfItems(), 1);
 
         final List<Invoice> invoiceList = new ArrayList<Invoice>();
         invoiceList.add(invoice1);
-        final Invoice invoice2 = generator.generateInvoice(accountId, events, invoiceList, new LocalDate("2012-04-05"), DateTimeZone.UTC, Currency.USD);
+        final Invoice invoice2 = generator.generateInvoice(accountId, events, invoiceList, new LocalDate("2012-04-05"), Currency.USD);
         assertNotNull(invoice2);
         assertEquals(invoice2.getNumberOfItems(), 1);
         final FixedPriceInvoiceItem item = (FixedPriceInvoiceItem) invoice2.getInvoiceItems().get(0);
@@ -602,7 +602,7 @@ public class TestDefaultInvoiceGenerator extends InvoicingTestBase {
         events.add(event1);
 
         // ensure both components are invoiced
-        final Invoice invoice1 = generator.generateInvoice(accountId, events, null, startDate, DateTimeZone.UTC, Currency.USD);
+        final Invoice invoice1 = generator.generateInvoice(accountId, events, null, startDate, Currency.USD);
         assertNotNull(invoice1);
         assertEquals(invoice1.getNumberOfItems(), 2);
         assertEquals(invoice1.getBalance(), FIFTEEN);
@@ -614,7 +614,7 @@ public class TestDefaultInvoiceGenerator extends InvoicingTestBase {
         final LocalDate currentDate = startDate.plusMonths(1);
 
         // ensure that only the recurring price is invoiced
-        final Invoice invoice2 = generator.generateInvoice(accountId, events, invoiceList, currentDate, DateTimeZone.UTC, Currency.USD);
+        final Invoice invoice2 = generator.generateInvoice(accountId, events, invoiceList, currentDate, Currency.USD);
         assertNotNull(invoice2);
         assertEquals(invoice2.getNumberOfItems(), 1);
         assertEquals(invoice2.getBalance(), FIVE);
@@ -638,7 +638,7 @@ public class TestDefaultInvoiceGenerator extends InvoicingTestBase {
         events.add(event1);
 
         // ensure that a single invoice item is generated for the fixed cost
-        final Invoice invoice1 = generator.generateInvoice(accountId, events, null, startDate, DateTimeZone.UTC, Currency.USD);
+        final Invoice invoice1 = generator.generateInvoice(accountId, events, null, startDate, Currency.USD);
         assertNotNull(invoice1);
         assertEquals(invoice1.getNumberOfItems(), 1);
         assertEquals(invoice1.getBalance(), fixedCost1);
@@ -652,7 +652,7 @@ public class TestDefaultInvoiceGenerator extends InvoicingTestBase {
         events.add(event2);
 
         // ensure that a single invoice item is generated for the fixed cost
-        final Invoice invoice2 = generator.generateInvoice(accountId, events, invoiceList, phaseChangeDate, DateTimeZone.UTC, Currency.USD);
+        final Invoice invoice2 = generator.generateInvoice(accountId, events, invoiceList, phaseChangeDate, Currency.USD);
         assertNotNull(invoice2);
         assertEquals(invoice2.getNumberOfItems(), 1);
         assertEquals(invoice2.getBalance(), fixedCost2);
@@ -684,7 +684,7 @@ public class TestDefaultInvoiceGenerator extends InvoicingTestBase {
         final LocalDate discountPhaseEndDate = trialPhaseEndDate.plusMonths(6);
         events.add(createBillingEvent(subscriptionId, discountPhaseEndDate, plan1, phase3, BILL_CYCLE_DAY));
 
-        final Invoice invoice1 = generator.generateInvoice(accountId, events, null, creationDate, DateTimeZone.UTC, Currency.USD);
+        final Invoice invoice1 = generator.generateInvoice(accountId, events, null, creationDate, Currency.USD);
         assertNotNull(invoice1);
         assertEquals(invoice1.getNumberOfItems(), 1);
         assertEquals(invoice1.getBalance().compareTo(ZERO), 0);
@@ -692,7 +692,7 @@ public class TestDefaultInvoiceGenerator extends InvoicingTestBase {
         final List<Invoice> invoiceList = new ArrayList<Invoice>();
         invoiceList.add(invoice1);
 
-        final Invoice invoice2 = generator.generateInvoice(accountId, events, invoiceList, trialPhaseEndDate, DateTimeZone.UTC, Currency.USD);
+        final Invoice invoice2 = generator.generateInvoice(accountId, events, invoiceList, trialPhaseEndDate, Currency.USD);
         assertNotNull(invoice2);
         assertEquals(invoice2.getNumberOfItems(), 1);
         assertEquals(invoice2.getInvoiceItems().get(0).getStartDate(), trialPhaseEndDate);
@@ -700,7 +700,7 @@ public class TestDefaultInvoiceGenerator extends InvoicingTestBase {
 
         invoiceList.add(invoice2);
         LocalDate targetDate = new LocalDate(trialPhaseEndDate.getYear(), trialPhaseEndDate.getMonthOfYear(), BILL_CYCLE_DAY);
-        final Invoice invoice3 = generator.generateInvoice(accountId, events, invoiceList, targetDate, DateTimeZone.UTC, Currency.USD);
+        final Invoice invoice3 = generator.generateInvoice(accountId, events, invoiceList, targetDate, Currency.USD);
         assertNotNull(invoice3);
         assertEquals(invoice3.getNumberOfItems(), 1);
         assertEquals(invoice3.getInvoiceItems().get(0).getStartDate(), targetDate);
@@ -708,7 +708,7 @@ public class TestDefaultInvoiceGenerator extends InvoicingTestBase {
 
         invoiceList.add(invoice3);
         targetDate = targetDate.plusMonths(6);
-        final Invoice invoice4 = generator.generateInvoice(accountId, events, invoiceList, targetDate, DateTimeZone.UTC, Currency.USD);
+        final Invoice invoice4 = generator.generateInvoice(accountId, events, invoiceList, targetDate, Currency.USD);
         assertNotNull(invoice4);
         assertEquals(invoice4.getNumberOfItems(), 7);
     }
@@ -720,7 +720,7 @@ public class TestDefaultInvoiceGenerator extends InvoicingTestBase {
         final Plan plan1 = new MockPlan();
         final PlanPhase phase1 = createMockMonthlyPlanPhase(null, ZERO, PhaseType.TRIAL);
         events.add(createBillingEvent(UUID.randomUUID(), clock.getUTCToday(), plan1, phase1, 1));
-        generator.generateInvoice(UUID.randomUUID(), events, null, targetDate, DateTimeZone.UTC, Currency.USD);
+        generator.generateInvoice(UUID.randomUUID(), events, null, targetDate, Currency.USD);
     }
 
     private MockPlanPhase createMockMonthlyPlanPhase() {
@@ -772,7 +772,7 @@ public class TestDefaultInvoiceGenerator extends InvoicingTestBase {
                                        final LocalDate targetDate, final int expectedNumberOfItems,
                                        final BigDecimal expectedAmount) throws InvoiceApiException {
         final Currency currency = Currency.USD;
-        final Invoice invoice = generator.generateInvoice(accountId, events, existingInvoices, targetDate, DateTimeZone.UTC, currency);
+        final Invoice invoice = generator.generateInvoice(accountId, events, existingInvoices, targetDate, currency);
         assertNotNull(invoice);
         assertEquals(invoice.getNumberOfItems(), expectedNumberOfItems);
         existingInvoices.add(invoice);
@@ -799,7 +799,7 @@ public class TestDefaultInvoiceGenerator extends InvoicingTestBase {
         events.add(createBillingEvent(baseSubscription.getId(), april25, basePlan, basePlanEvergreen, 25));
 
         // generate invoice
-        final Invoice invoice1 = generator.generateInvoice(accountId, events, null, april25, DateTimeZone.UTC, Currency.USD);
+        final Invoice invoice1 = generator.generateInvoice(accountId, events, null, april25, Currency.USD);
         assertNotNull(invoice1);
         assertEquals(invoice1.getNumberOfItems(), 1);
         assertEquals(invoice1.getBalance().compareTo(TEN), 0);
@@ -820,7 +820,7 @@ public class TestDefaultInvoiceGenerator extends InvoicingTestBase {
         events.add(createBillingEvent(addOnSubscription2.getId(), april28, addOn2Plan, addOn2PlanPhaseEvergreen, 25));
 
         // generate invoice
-        final Invoice invoice2 = generator.generateInvoice(accountId, events, invoices, april28, DateTimeZone.UTC, Currency.USD);
+        final Invoice invoice2 = generator.generateInvoice(accountId, events, invoices, april28, Currency.USD);
         invoices.add(invoice2);
         assertNotNull(invoice2);
         assertEquals(invoice2.getNumberOfItems(), 2);
@@ -837,7 +837,7 @@ public class TestDefaultInvoiceGenerator extends InvoicingTestBase {
 
         // generate invoice
         final LocalDate may1 = new LocalDate(2012, 5, 1);
-        final Invoice invoice3 = generator.generateInvoice(accountId, newEvents, invoices, may1, DateTimeZone.UTC, Currency.USD);
+        final Invoice invoice3 = generator.generateInvoice(accountId, newEvents, invoices, may1, Currency.USD);
         assertNotNull(invoice3);
         assertEquals(invoice3.getNumberOfItems(), 5);
         // -4.50 -18 - 10 (to correct the previous 2 invoices) + 4.50 + 13
@@ -860,7 +860,7 @@ public class TestDefaultInvoiceGenerator extends InvoicingTestBase {
         final BillingEventSet events = new MockBillingEventSet();
         events.add(createBillingEvent(originalSubscription.getId(), april25, originalPlan, originalPlanEvergreen, 25));
 
-        final Invoice invoice1 = generator.generateInvoice(accountId, events, null, april25, DateTimeZone.UTC, Currency.USD);
+        final Invoice invoice1 = generator.generateInvoice(accountId, events, null, april25, Currency.USD);
 
         printDetailInvoice(invoice1);
 
@@ -881,7 +881,7 @@ public class TestDefaultInvoiceGenerator extends InvoicingTestBase {
         events.add(createBillingEvent(newSubscription.getId(), april25, newPlan, newPlanEvergreen, 25));
 
         // generate a new invoice
-        final Invoice invoice2 = generator.generateInvoice(accountId, events, invoices, april25, DateTimeZone.UTC, Currency.USD);
+        final Invoice invoice2 = generator.generateInvoice(accountId, events, invoices, april25, Currency.USD);
 
         printDetailInvoice(invoice2);
         assertEquals(invoice2.getNumberOfItems(), 4);
@@ -944,7 +944,7 @@ public class TestDefaultInvoiceGenerator extends InvoicingTestBase {
 
         final LocalDate targetDate = buildDate(2011, 10, 3);
         final UUID accountId = UUID.randomUUID();
-        final Invoice invoice = generator.generateInvoice(accountId, events, null, targetDate, DateTimeZone.UTC, Currency.USD);
+        final Invoice invoice = generator.generateInvoice(accountId, events, null, targetDate, Currency.USD);
 
         assertNull(invoice);
     }
@@ -971,7 +971,7 @@ public class TestDefaultInvoiceGenerator extends InvoicingTestBase {
         eventSet.add(createBillingEvent(subscriptionId2, startDate, plan2, plan2phase1, 1));
 
         // generate the first invoice
-        final Invoice invoice1 = generator.generateInvoice(accountId, eventSet, invoices, startDate, DateTimeZone.UTC, currency);
+        final Invoice invoice1 = generator.generateInvoice(accountId, eventSet, invoices, startDate, currency);
         assertNotNull(invoice1);
         assertTrue(invoice1.getBalance().compareTo(FIFTEEN.add(TWELVE)) == 0);
         invoices.add(invoice1);
@@ -982,7 +982,7 @@ public class TestDefaultInvoiceGenerator extends InvoicingTestBase {
         eventSet.addSubscriptionWithAutoInvoiceOff(subscriptionId1);
 
         final LocalDate targetDate2 = startDate.plusMonths(1);
-        final Invoice invoice2 = generator.generateInvoice(accountId, eventSet, invoices, targetDate2, DateTimeZone.UTC, currency);
+        final Invoice invoice2 = generator.generateInvoice(accountId, eventSet, invoices, targetDate2, currency);
         assertNotNull(invoice2);
         assertTrue(invoice2.getBalance().compareTo(TWELVE) == 0);
         invoices.add(invoice2);
@@ -990,7 +990,7 @@ public class TestDefaultInvoiceGenerator extends InvoicingTestBase {
         final LocalDate targetDate3 = targetDate2.plusMonths(1);
         eventSet.clearSubscriptionsWithAutoInvoiceOff();
         eventSet.add(subscription1creation);
-        final Invoice invoice3 = generator.generateInvoice(accountId, eventSet, invoices, targetDate3, DateTimeZone.UTC, currency);
+        final Invoice invoice3 = generator.generateInvoice(accountId, eventSet, invoices, targetDate3, currency);
         assertNotNull(invoice3);
         assertTrue(invoice3.getBalance().compareTo(FIFTEEN.multiply(TWO).add(TWELVE)) == 0);
     }
@@ -1010,7 +1010,7 @@ public class TestDefaultInvoiceGenerator extends InvoicingTestBase {
 
         final List<Invoice> invoices = new ArrayList<Invoice>();
 
-        final Invoice initialInvoice = generator.generateInvoice(accountId, billingEventSet, null, startDate, DateTimeZone.UTC, Currency.USD);
+        final Invoice initialInvoice = generator.generateInvoice(accountId, billingEventSet, null, startDate, Currency.USD);
         assertNotNull(initialInvoice);
         assertEquals(initialInvoice.getNumberOfItems(), 1);
         assertEquals(initialInvoice.getBalance().compareTo(TEN), 0);
@@ -1028,7 +1028,7 @@ public class TestDefaultInvoiceGenerator extends InvoicingTestBase {
         printDetailInvoice(invoiceWithCredit);
 
         // invoice one month after the initial subscription
-        final Invoice finalInvoice = generator.generateInvoice(accountId, billingEventSet, invoices, startDate.plusMonths(1), DateTimeZone.UTC, Currency.USD);
+        final Invoice finalInvoice = generator.generateInvoice(accountId, billingEventSet, invoices, startDate.plusMonths(1), Currency.USD);
 
         printDetailInvoice(finalInvoice);
 
diff --git a/invoice/src/test/java/com/ning/billing/invoice/generator/TestInvoiceDateUtils.java b/invoice/src/test/java/com/ning/billing/invoice/generator/TestInvoiceDateUtils.java
index 5d419a0..311b0a2 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/generator/TestInvoiceDateUtils.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/generator/TestInvoiceDateUtils.java
@@ -39,7 +39,7 @@ public class TestInvoiceDateUtils {
     @Test(groups = "fast")
     public void testNextBCDShouldNotBeInThePast() throws Exception {
         final LocalDate from = new LocalDate("2012-07-16");
-        final LocalDate to = InvoiceDateUtils.calculateBillingCycleDateOnOrAfter(from, DateTimeZone.forID("Pacific/Pitcairn"), 15);
+        final LocalDate to = InvoiceDateUtils.calculateBillingCycleDateOnOrAfter(from, 15);
         Assert.assertEquals(to, new LocalDate("2012-08-15"));
     }
 
@@ -54,42 +54,42 @@ public class TestInvoiceDateUtils {
     @Test(groups = "fast")
     public void testBeforeBCDWithAfter() throws Exception {
         final LocalDate from = new LocalDate("2012-03-02");
-        final LocalDate to = InvoiceDateUtils.calculateBillingCycleDateAfter(from, DateTimeZone.UTC, 3);
+        final LocalDate to = InvoiceDateUtils.calculateBillingCycleDateAfter(from, 3);
         Assert.assertEquals(to, new LocalDate("2012-03-03"));
     }
 
     @Test(groups = "fast")
     public void testEqualBCDWithAfter() throws Exception {
         final LocalDate from = new LocalDate("2012-03-03");
-        final LocalDate to = InvoiceDateUtils.calculateBillingCycleDateAfter(from, DateTimeZone.UTC, 3);
+        final LocalDate to = InvoiceDateUtils.calculateBillingCycleDateAfter(from, 3);
         Assert.assertEquals(to, new LocalDate("2012-04-03"));
     }
 
     @Test(groups = "fast")
     public void testAfterBCDWithAfter() throws Exception {
         final LocalDate from = new LocalDate("2012-03-04");
-        final LocalDate to = InvoiceDateUtils.calculateBillingCycleDateAfter(from, DateTimeZone.UTC, 3);
+        final LocalDate to = InvoiceDateUtils.calculateBillingCycleDateAfter(from, 3);
         Assert.assertEquals(to, new LocalDate("2012-04-03"));
     }
 
     @Test(groups = "fast")
     public void testBeforeBCDWithOnOrAfter() throws Exception {
         final LocalDate from = new LocalDate("2012-03-02");
-        final LocalDate to = InvoiceDateUtils.calculateBillingCycleDateOnOrAfter(from, DateTimeZone.UTC, 3);
+        final LocalDate to = InvoiceDateUtils.calculateBillingCycleDateOnOrAfter(from, 3);
         Assert.assertEquals(to, new LocalDate("2012-03-03"));
     }
 
     @Test(groups = "fast")
     public void testEqualBCDWithOnOrAfter() throws Exception {
         final LocalDate from = new LocalDate("2012-03-03");
-        final LocalDate to = InvoiceDateUtils.calculateBillingCycleDateOnOrAfter(from, DateTimeZone.UTC, 3);
+        final LocalDate to = InvoiceDateUtils.calculateBillingCycleDateOnOrAfter(from, 3);
         Assert.assertEquals(to, new LocalDate("2012-03-03"));
     }
 
     @Test(groups = "fast")
     public void testAfterBCDWithOnOrAfter() throws Exception {
         final LocalDate from = new LocalDate("2012-03-04");
-        final LocalDate to = InvoiceDateUtils.calculateBillingCycleDateOnOrAfter(from, DateTimeZone.UTC, 3);
+        final LocalDate to = InvoiceDateUtils.calculateBillingCycleDateOnOrAfter(from, 3);
         Assert.assertEquals(to, new LocalDate("2012-04-03"));
     }
 
diff --git a/invoice/src/test/java/com/ning/billing/invoice/model/TestInAdvanceBillingMode.java b/invoice/src/test/java/com/ning/billing/invoice/model/TestInAdvanceBillingMode.java
index c5bc813..3231760 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/model/TestInAdvanceBillingMode.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/model/TestInAdvanceBillingMode.java
@@ -149,7 +149,7 @@ public class TestInAdvanceBillingMode {
                                     final LinkedHashMap<LocalDate, LocalDate> expectedDates) throws InvalidDateSequenceException {
         final InAdvanceBillingMode billingMode = new InAdvanceBillingMode();
 
-        final List<RecurringInvoiceItemData> invoiceItems = billingMode.calculateInvoiceItemData(startDate, endDate, targetDate, dateTimeZone, billingCycleDayLocal, billingPeriod);
+        final List<RecurringInvoiceItemData> invoiceItems = billingMode.calculateInvoiceItemData(startDate, endDate, targetDate, billingCycleDayLocal, billingPeriod);
 
         int i = 0;
         for (final LocalDate periodStartDate : expectedDates.keySet()) {
diff --git a/invoice/src/test/java/com/ning/billing/invoice/TestInvoiceDispatcher.java b/invoice/src/test/java/com/ning/billing/invoice/TestInvoiceDispatcher.java
index 2c8ec5a..c339485 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/TestInvoiceDispatcher.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/TestInvoiceDispatcher.java
@@ -45,6 +45,7 @@ import com.ning.billing.catalog.api.Plan;
 import com.ning.billing.catalog.api.PlanPhase;
 import com.ning.billing.entitlement.api.SubscriptionTransitionType;
 import com.ning.billing.entitlement.api.user.Subscription;
+import com.ning.billing.invoice.InvoiceDispatcher.DateAndTimeZoneContext;
 import com.ning.billing.invoice.api.Invoice;
 import com.ning.billing.invoice.api.InvoiceApiException;
 import com.ning.billing.invoice.api.InvoiceItem;
@@ -267,10 +268,15 @@ public class TestInvoiceDispatcher extends InvoicingTestBase {
     @Test(groups = "slow")
     public void testCreateNextFutureNotificationDate() throws Exception {
 
+
+
         final LocalDate startDate = new LocalDate("2012-10-26");
         final LocalDate endDate = new LocalDate("2012-11-26");
 
         clock.setTime(new DateTime(2012, 10, 26, 1, 12, 23, DateTimeZone.UTC));
+
+        final InvoiceDispatcher.DateAndTimeZoneContext dateAndTimeZoneContext = new DateAndTimeZoneContext(clock.getUTCNow(),DateTimeZone.forID("Pacific/Pitcairn"), clock);
+
         final InvoiceItemModelDao item = new InvoiceItemModelDao(UUID.randomUUID(), clock.getUTCNow(), InvoiceItemType.RECURRING, UUID.randomUUID(), UUID.randomUUID(), UUID.randomUUID(), UUID.randomUUID(),
                                                                  "planName", "phaseName", startDate, endDate, new BigDecimal("23.9"), new BigDecimal("23.9"), Currency.EUR, null);
 
@@ -280,7 +286,7 @@ public class TestInvoiceDispatcher extends InvoicingTestBase {
                                                                    clock);
 
         final DateTime expectedBefore = clock.getUTCNow();
-        final Map<UUID, DateTime> result = dispatcher.createNextFutureNotificationDate(Collections.singletonList(item), DateTimeZone.forID("Pacific/Pitcairn"));
+        final Map<UUID, DateTime> result = dispatcher.createNextFutureNotificationDate(Collections.singletonList(item), dateAndTimeZoneContext);
         final DateTime expectedAfter = clock.getUTCNow();
 
         Assert.assertEquals(result.size(), 1);
diff --git a/invoice/src/test/java/com/ning/billing/invoice/tests/ProRationTestBase.java b/invoice/src/test/java/com/ning/billing/invoice/tests/ProRationTestBase.java
index cacc246..676b612 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/tests/ProRationTestBase.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/tests/ProRationTestBase.java
@@ -19,7 +19,6 @@ package com.ning.billing.invoice.tests;
 import java.math.BigDecimal;
 import java.util.List;
 
-import org.joda.time.DateTimeZone;
 import org.joda.time.LocalDate;
 
 import com.ning.billing.catalog.api.BillingPeriod;
@@ -63,7 +62,7 @@ public abstract class ProRationTestBase extends InvoicingTestBase {
     }
 
     protected BigDecimal calculateNumberOfBillingCycles(final LocalDate startDate, final LocalDate endDate, final LocalDate targetDate, final int billingCycleDay) throws InvalidDateSequenceException {
-        final List<RecurringInvoiceItemData> items = getBillingMode().calculateInvoiceItemData(startDate, endDate, targetDate, DateTimeZone.UTC, billingCycleDay, getBillingPeriod());
+        final List<RecurringInvoiceItemData> items = getBillingMode().calculateInvoiceItemData(startDate, endDate, targetDate, billingCycleDay, getBillingPeriod());
 
         BigDecimal numberOfBillingCycles = ZERO;
         for (final RecurringInvoiceItemData item : items) {
@@ -74,7 +73,7 @@ public abstract class ProRationTestBase extends InvoicingTestBase {
     }
 
     protected BigDecimal calculateNumberOfBillingCycles(final LocalDate startDate, final LocalDate targetDate, final int billingCycleDay) throws InvalidDateSequenceException {
-        final List<RecurringInvoiceItemData> items = getBillingMode().calculateInvoiceItemData(startDate, null, targetDate, DateTimeZone.UTC, billingCycleDay, getBillingPeriod());
+        final List<RecurringInvoiceItemData> items = getBillingMode().calculateInvoiceItemData(startDate, null, targetDate, billingCycleDay, getBillingPeriod());
 
         BigDecimal numberOfBillingCycles = ZERO;
         for (final RecurringInvoiceItemData item : items) {
diff --git a/overdue/src/main/java/com/ning/billing/overdue/applicator/OverdueStateApplicator.java b/overdue/src/main/java/com/ning/billing/overdue/applicator/OverdueStateApplicator.java
index bc2110a..d9ad986 100644
--- a/overdue/src/main/java/com/ning/billing/overdue/applicator/OverdueStateApplicator.java
+++ b/overdue/src/main/java/com/ning/billing/overdue/applicator/OverdueStateApplicator.java
@@ -202,7 +202,7 @@ public class OverdueStateApplicator<T extends Blockable> {
         poster.clearNotificationsFor(blockable, context);
     }
 
-    private void cancelSubscriptionsIfRequired(final T blockable, final OverdueState<T> nextOverdueState, final InternalCallContext context) throws OverdueException {
+    private void  cancelSubscriptionsIfRequired(final T blockable, final OverdueState<T> nextOverdueState, final InternalCallContext context) throws OverdueException {
         if (nextOverdueState.getSubscriptionCancellationPolicy() == OverdueCancellationPolicicy.NONE) {
             return;
         }
diff --git a/util/src/main/java/com/ning/billing/util/svcapi/entitlement/EntitlementInternalApi.java b/util/src/main/java/com/ning/billing/util/svcapi/entitlement/EntitlementInternalApi.java
index 70b8511..b575020 100644
--- a/util/src/main/java/com/ning/billing/util/svcapi/entitlement/EntitlementInternalApi.java
+++ b/util/src/main/java/com/ning/billing/util/svcapi/entitlement/EntitlementInternalApi.java
@@ -18,6 +18,7 @@ package com.ning.billing.util.svcapi.entitlement;
 import java.util.List;
 import java.util.UUID;
 
+import org.joda.time.DateTime;
 import org.joda.time.LocalDate;
 
 import com.ning.billing.entitlement.api.user.EntitlementUserApiException;
@@ -42,7 +43,7 @@ public interface EntitlementInternalApi {
 
     public UUID getAccountIdFromSubscriptionId(final UUID subscriptionId, final InternalTenantContext context) throws EntitlementUserApiException;
 
-    public void setChargedThroughDate(final UUID subscriptionId, final LocalDate localChargedThruDate, final InternalCallContext context);
+    public void setChargedThroughDate(final UUID subscriptionId, final DateTime chargedThruDate, final InternalCallContext context);
 
     public List<EffectiveSubscriptionInternalEvent> getAllTransitions(final Subscription subscription, final InternalTenantContext context);