killbill-memoizeit

Remove arbitrary limitation of creating subscriptions in

4/19/2015 1:28:08 AM

Details

diff --git a/entitlement/src/test/java/org/killbill/billing/entitlement/api/TestEntitlementDateHelper.java b/entitlement/src/test/java/org/killbill/billing/entitlement/api/TestEntitlementDateHelper.java
index b1f06b2..9a586a1 100644
--- a/entitlement/src/test/java/org/killbill/billing/entitlement/api/TestEntitlementDateHelper.java
+++ b/entitlement/src/test/java/org/killbill/billing/entitlement/api/TestEntitlementDateHelper.java
@@ -65,6 +65,7 @@ public class TestEntitlementDateHelper extends EntitlementTestSuiteNoDB {
     public void testWithAccountInUtcMinus8() throws EntitlementApiException {
 
         final LocalDate inputDate = new LocalDate(2013, 8, 7);
+        // Current time is in the future so we don't go through logic that will default to a Clock.getUTCNow.
         clock.setDay(inputDate.plusDays(3));
 
         final DateTimeZone timeZoneUtcMinus8 = DateTimeZone.forOffsetHours(-8);
@@ -74,37 +75,18 @@ public class TestEntitlementDateHelper extends EntitlementTestSuiteNoDB {
         final DateTime refererenceDateTime = new DateTime(2013, 1, 1, 1, 28, 10, 0, DateTimeZone.UTC);
         final DateTime targetDate = dateHelper.fromLocalDateAndReferenceTime(inputDate, refererenceDateTime, internalCallContext);
 
-        // And so that datetime in UTC becomes expectedDate below
-        final DateTime expectedDate = new DateTime(2013, 8, 8, 1, 28, 10, 0, DateTimeZone.UTC);
-        Assert.assertEquals(targetDate, expectedDate);
-
-        Assert.assertEquals(targetDate.toDateTime(timeZoneUtcMinus8).toLocalDate(), inputDate);
-    }
-
-
-    @Test(groups = "fast")
-    public void test2WithAccountInUtcMinus8() throws EntitlementApiException {
 
-        final DateTime initialNow = new DateTime(2013, 8, 22,22, 07, 01, 0, DateTimeZone.UTC);
-        clock.setTime(initialNow);
-
-        final LocalDate inputDate = new LocalDate(2013, 8, 22);
+        // Things to verify:
+        // 1. Verify the resulting DateTime brings us back into the correct LocalDate (in the account timezone)
+        Assert.assertEquals(new LocalDate(targetDate, timeZoneUtcMinus8), inputDate);
+        // 2. Verify the resulting DateTime has the same reference time as we indicated (in UTC)
+        Assert.assertEquals(targetDate.toLocalTime(), refererenceDateTime.toLocalTime());
 
-        final DateTimeZone timeZoneUtcMinus8 = DateTimeZone.forOffsetHours(-8);
-        Mockito.when(account.getTimeZone()).thenReturn(timeZoneUtcMinus8);
-
-        // We also use a reference time of 16, 48, 0 -> DateTime in UTC will be (2013, 8, 23, 00, 48, 0) which:
-        // * is greater than now
-        // * with a inputLocalDate in the account timezone which is today
         //
-        // => Code will round to now to not end up in the future
+        // To be more specific, we should find a UTC Date, with the exact specified reference time, and with a LocalDate one day
+        // ahead because of the 8 hours difference.
         //
-        final DateTime refererenceDateTime = new DateTime(2013, 8, 22, 16, 48, 0, DateTimeZone.UTC);
-        final DateTime targetDate = dateHelper.fromLocalDateAndReferenceTime(inputDate, refererenceDateTime, internalCallContext);
-
-        final DateTime now = clock.getUTCNow();
-        Assert.assertTrue(initialNow.compareTo(targetDate) <= 0);
-        Assert.assertTrue(targetDate.compareTo(now) <= 0);
+        Assert.assertEquals(targetDate, new DateTime(2013, 8, 8, 1, 28, 10, 0, DateTimeZone.UTC));
     }
 
 
@@ -122,14 +104,39 @@ public class TestEntitlementDateHelper extends EntitlementTestSuiteNoDB {
         final DateTime refererenceDateTime = new DateTime(2013, 1, 1, 20, 28, 10, 0, DateTimeZone.UTC);
         final DateTime targetDate = dateHelper.fromLocalDateAndReferenceTime(inputDate, refererenceDateTime, internalCallContext);
 
-        // And so that datetime in UTC becomes expectedDate below
-        final DateTime expectedDate = new DateTime(2013, 8, 6, 20, 28, 10, 0, DateTimeZone.UTC);
-        Assert.assertEquals(targetDate, expectedDate);
+        // Things to verify:
+        // 1. Verify the resulting DateTime brings us back into the correct LocalDate (in the account timezone)
+        Assert.assertEquals(new LocalDate(targetDate, timeZoneUtcPlus5), inputDate);
+        // 2. Verify the resulting DateTime has the same reference time as we indicated (in UTC)
+        Assert.assertEquals(targetDate.toLocalTime(), refererenceDateTime.toLocalTime());
 
-        Assert.assertEquals(targetDate.toDateTime(timeZoneUtcPlus5).toLocalDate(), inputDate);
+        //
+        // To be more specific, we should find a UTC Date, with the exact specified reference time, and with a LocalDate one day
+        // ahead because of the 8 hours difference.
+        //
+        Assert.assertEquals(targetDate, new DateTime(2013, 8, 6, 20, 28, 10, 0, DateTimeZone.UTC));
+    }
+
+    @Test(groups = "fast")
+    public void testWhereLocalDateInAccountTimeZoneContainsNow() throws EntitlementApiException {
+
+        final DateTime initialNow = new DateTime(2013, 8, 22,22, 07, 01, 0, DateTimeZone.UTC);
+        clock.setTime(initialNow);
+
+        final LocalDate inputDate = new LocalDate(2013, 8, 22);
+
+        final DateTimeZone timeZoneUtcMinus8 = DateTimeZone.forOffsetHours(-8);
+        Mockito.when(account.getTimeZone()).thenReturn(timeZoneUtcMinus8);
+
+        final DateTime referenceDateTimeThatDoesNotMatter = new DateTime();
+        final DateTime targetDate = dateHelper.fromLocalDateAndReferenceTime(inputDate, referenceDateTimeThatDoesNotMatter, internalCallContext);
 
+        final DateTime now = clock.getUTCNow();
+        Assert.assertTrue(initialNow.compareTo(targetDate) <= 0);
+        Assert.assertTrue(targetDate.compareTo(now) <= 0);
     }
 
+
     @Test(groups = "fast")
     public void testIsBeforeOrEqualsToday() {
 
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/generator/DefaultInvoiceGenerator.java b/invoice/src/main/java/org/killbill/billing/invoice/generator/DefaultInvoiceGenerator.java
index 70a28e7..363f012 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/generator/DefaultInvoiceGenerator.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/generator/DefaultInvoiceGenerator.java
@@ -30,6 +30,7 @@ import javax.annotation.Nullable;
 import org.joda.time.LocalDate;
 import org.joda.time.Months;
 import org.killbill.billing.ErrorCode;
+import org.killbill.billing.account.api.Account;
 import org.killbill.billing.callcontext.InternalCallContext;
 import org.killbill.billing.catalog.api.BillingMode;
 import org.killbill.billing.catalog.api.BillingPeriod;
@@ -87,7 +88,7 @@ public class DefaultInvoiceGenerator implements InvoiceGenerator {
      * adjusts target date to the maximum invoice target date, if future invoices exist
      */
     @Override
-    public Invoice generateInvoice(final UUID accountId, @Nullable final BillingEventSet events,
+    public Invoice generateInvoice(final Account account, @Nullable final BillingEventSet events,
                                    @Nullable final List<Invoice> existingInvoices,
                                    final LocalDate targetDate,
                                    final Currency targetCurrency, final InternalCallContext context) throws InvoiceApiException {
@@ -98,10 +99,10 @@ public class DefaultInvoiceGenerator implements InvoiceGenerator {
         validateTargetDate(targetDate);
         final LocalDate adjustedTargetDate = adjustTargetDate(existingInvoices, targetDate);
 
-        final Invoice invoice = new DefaultInvoice(accountId, clock.getUTCToday(), adjustedTargetDate, targetCurrency);
+        final Invoice invoice = new DefaultInvoice(account.getId(), new LocalDate(clock.getUTCNow(), account.getTimeZone()), adjustedTargetDate, targetCurrency);
         final UUID invoiceId = invoice.getId();
 
-        final List<InvoiceItem> inAdvanceItems = generateInAdvanceInvoiceItems(accountId, invoiceId, events, existingInvoices, adjustedTargetDate, targetCurrency);
+        final List<InvoiceItem> inAdvanceItems = generateInAdvanceInvoiceItems(account.getId(), invoiceId, events, existingInvoices, adjustedTargetDate, targetCurrency);
         invoice.addInvoiceItems(inAdvanceItems);
 
         final List<InvoiceItem> usageItems = generateUsageInvoiceItems(invoiceId, events, existingInvoices, targetDate, context);
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/generator/InvoiceGenerator.java b/invoice/src/main/java/org/killbill/billing/invoice/generator/InvoiceGenerator.java
index e0d6b21..8023ee9 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/generator/InvoiceGenerator.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/generator/InvoiceGenerator.java
@@ -23,6 +23,7 @@ import javax.annotation.Nullable;
 
 import org.joda.time.LocalDate;
 
+import org.killbill.billing.account.api.Account;
 import org.killbill.billing.callcontext.InternalCallContext;
 import org.killbill.billing.catalog.api.Currency;
 import org.killbill.billing.invoice.api.Invoice;
@@ -31,6 +32,6 @@ import org.killbill.billing.junction.BillingEventSet;
 
 public interface InvoiceGenerator {
 
-    public Invoice generateInvoice(UUID accountId, @Nullable BillingEventSet events, @Nullable List<Invoice> existingInvoices,
+    public Invoice generateInvoice(Account account, @Nullable BillingEventSet events, @Nullable List<Invoice> existingInvoices,
                                    LocalDate targetDate, Currency targetCurrency, final InternalCallContext context) throws InvoiceApiException;
 }
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/InvoiceDispatcher.java b/invoice/src/main/java/org/killbill/billing/invoice/InvoiceDispatcher.java
index c5cba2e..1686c1f 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/InvoiceDispatcher.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/InvoiceDispatcher.java
@@ -228,7 +228,7 @@ public class InvoiceDispatcher {
             final Currency targetCurrency = account.getCurrency();
 
             final LocalDate targetDate = dateAndTimeZoneContext != null ? dateAndTimeZoneContext.computeTargetDate(targetDateTime) : null;
-            final Invoice invoice = targetDate != null ? generator.generateInvoice(accountId, billingEvents, invoices, targetDate, targetCurrency, context) : null;
+            final Invoice invoice = targetDate != null ? generator.generateInvoice(account, billingEvents, invoices, targetDate, targetCurrency, context) : null;
             //
             // If invoice comes back null, there is nothing new to generate, we can bail early
             //
diff --git a/invoice/src/test/java/org/killbill/billing/invoice/dao/TestInvoiceDao.java b/invoice/src/test/java/org/killbill/billing/invoice/dao/TestInvoiceDao.java
index 1070c2b..97cd232 100644
--- a/invoice/src/test/java/org/killbill/billing/invoice/dao/TestInvoiceDao.java
+++ b/invoice/src/test/java/org/killbill/billing/invoice/dao/TestInvoiceDao.java
@@ -1109,7 +1109,7 @@ public class TestInvoiceDao extends InvoiceTestSuiteWithEmbeddedDB {
         final BillingEventSet events = new MockBillingEventSet();
         events.add(event1);
 
-        final Invoice invoice1 = generator.generateInvoice(accountId, events, invoiceList, targetDate, Currency.USD, context);
+        final Invoice invoice1 = generator.generateInvoice(account, events, invoiceList, targetDate, Currency.USD, context);
         assertEquals(invoice1.getBalance(), KillBillMoney.of(TEN, invoice1.getCurrency()));
         invoiceList.add(invoice1);
 
@@ -1127,7 +1127,7 @@ public class TestInvoiceDao extends InvoiceTestSuiteWithEmbeddedDB {
 
         // 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, Currency.USD, context);
+        final Invoice invoice2 = generator.generateInvoice(account, events, invoiceList, targetDate, Currency.USD, context);
         assertEquals(invoice2.getBalance(), KillBillMoney.of(FIVE, invoice2.getCurrency()));
         invoiceList.add(invoice2);
 
@@ -1159,7 +1159,7 @@ public class TestInvoiceDao extends InvoiceTestSuiteWithEmbeddedDB {
         events.add(event);
 
         final LocalDate targetDate = invoiceUtil.buildDate(2011, 1, 15);
-        final Invoice invoice = generator.generateInvoice(UUID.randomUUID(), events, null, targetDate, Currency.USD, context);
+        final Invoice invoice = generator.generateInvoice(account, events, null, targetDate, Currency.USD, context);
 
         // expect one pro-ration item and one full-period item
         assertEquals(invoice.getNumberOfItems(), 2);
@@ -1202,7 +1202,7 @@ public class TestInvoiceDao extends InvoiceTestSuiteWithEmbeddedDB {
         events.add(event1);
 
         final UUID accountId = account.getId();
-        final Invoice invoice1 = generator.generateInvoice(accountId, events, null, new LocalDate(effectiveDate1), Currency.USD, context);
+        final Invoice invoice1 = generator.generateInvoice(account, events, null, new LocalDate(effectiveDate1), Currency.USD, context);
         assertNotNull(invoice1);
         assertEquals(invoice1.getNumberOfItems(), 1);
         assertEquals(invoice1.getBalance().compareTo(ZERO), 0);
@@ -1218,7 +1218,7 @@ public class TestInvoiceDao extends InvoiceTestSuiteWithEmbeddedDB {
                                                                        "testEvent2", 2L, SubscriptionBaseTransitionType.PHASE);
         events.add(event2);
 
-        final Invoice invoice2 = generator.generateInvoice(accountId, events, invoiceList, new LocalDate(effectiveDate2), Currency.USD, context);
+        final Invoice invoice2 = generator.generateInvoice(account, events, invoiceList, new LocalDate(effectiveDate2), Currency.USD, context);
         assertNotNull(invoice2);
         assertEquals(invoice2.getNumberOfItems(), 1);
         assertEquals(invoice2.getBalance().compareTo(cheapAmount), 0);
@@ -1228,7 +1228,7 @@ public class TestInvoiceDao extends InvoiceTestSuiteWithEmbeddedDB {
         //invoiceUtil.createInvoice(invoice2, invoice2.getTargetDate().getDayOfMonth(), callcontext);
 
         final DateTime effectiveDate3 = effectiveDate2.plusMonths(1);
-        final Invoice invoice3 = generator.generateInvoice(accountId, events, invoiceList, new LocalDate(effectiveDate3), Currency.USD, context);
+        final Invoice invoice3 = generator.generateInvoice(account, events, invoiceList, new LocalDate(effectiveDate3), Currency.USD, context);
         assertNotNull(invoice3);
         assertEquals(invoice3.getNumberOfItems(), 1);
         assertEquals(invoice3.getBalance().compareTo(cheapAmount), 0);
@@ -1239,7 +1239,7 @@ public class TestInvoiceDao extends InvoiceTestSuiteWithEmbeddedDB {
     @Test(groups = "slow")
     public void testInvoiceForEmptyEventSet() throws InvoiceApiException {
         final BillingEventSet events = new MockBillingEventSet();
-        final Invoice invoice = generator.generateInvoice(UUID.randomUUID(), events, null, new LocalDate(), Currency.USD, context);
+        final Invoice invoice = generator.generateInvoice(account, events, null, new LocalDate(), Currency.USD, context);
         assertNull(invoice);
     }
 
@@ -1273,7 +1273,7 @@ public class TestInvoiceDao extends InvoiceTestSuiteWithEmbeddedDB {
                                                                        "testEvent2", 2L, SubscriptionBaseTransitionType.CHANGE);
         events.add(event2);
 
-        final Invoice invoice = generator.generateInvoice(UUID.randomUUID(), events, null, new LocalDate(effectiveDate2), Currency.USD, context);
+        final Invoice invoice = generator.generateInvoice(account, events, null, new LocalDate(effectiveDate2), Currency.USD, context);
         assertNotNull(invoice);
         assertEquals(invoice.getNumberOfItems(), 2);
         assertEquals(invoice.getBalance().compareTo(cheapAmount), 0);
@@ -1344,7 +1344,7 @@ public class TestInvoiceDao extends InvoiceTestSuiteWithEmbeddedDB {
                                                                        BillingPeriod.MONTHLY, 31, BillingMode.IN_ADVANCE,
                                                                        "new-event", 1L, SubscriptionBaseTransitionType.CREATE);
         events.add(event1);
-        final Invoice newInvoice = generator.generateInvoice(UUID.randomUUID(), events, invoices, targetDate, Currency.USD, context);
+        final Invoice newInvoice = generator.generateInvoice(account, events, invoices, targetDate, Currency.USD, context);
         invoiceUtil.createInvoice(newInvoice, true, context);
 
         // VERIFY THAT WE STILL HAVE ONLY 2 ITEMS, MEANING THERE WERE NO REPAIR AND NO CBA GENERATED
@@ -1379,7 +1379,7 @@ public class TestInvoiceDao extends InvoiceTestSuiteWithEmbeddedDB {
                                                                        "testEvent1", 1L, SubscriptionBaseTransitionType.CHANGE);
         events.add(event1);
 
-        Invoice invoice1 = generator.generateInvoice(UUID.randomUUID(), events, invoices, new LocalDate(targetDate1), Currency.USD, context);
+        Invoice invoice1 = generator.generateInvoice(account, events, invoices, new LocalDate(targetDate1), Currency.USD, context);
         invoices.add(invoice1);
         invoiceUtil.createInvoice(invoice1, true, context);
         invoice1 = new DefaultInvoice(invoiceDao.getById(invoice1.getId(), context));
@@ -1390,7 +1390,7 @@ public class TestInvoiceDao extends InvoiceTestSuiteWithEmbeddedDB {
                                                                        BillingPeriod.MONTHLY, 31, BillingMode.IN_ADVANCE,
                                                                        "testEvent2", 2L, SubscriptionBaseTransitionType.CHANGE);
         events.add(event2);
-        Invoice invoice2 = generator.generateInvoice(UUID.randomUUID(), events, invoices, new LocalDate(targetDate2), Currency.USD, context);
+        Invoice invoice2 = generator.generateInvoice(account, events, invoices, new LocalDate(targetDate2), Currency.USD, context);
         invoiceUtil.createInvoice(invoice2, true, context);
         invoice2 = new DefaultInvoice(invoiceDao.getById(invoice2.getId(), context));
         assertNotNull(invoice2.getInvoiceNumber());
diff --git a/invoice/src/test/java/org/killbill/billing/invoice/generator/TestDefaultInvoiceGenerator.java b/invoice/src/test/java/org/killbill/billing/invoice/generator/TestDefaultInvoiceGenerator.java
index bf63597..b52e885 100644
--- a/invoice/src/test/java/org/killbill/billing/invoice/generator/TestDefaultInvoiceGenerator.java
+++ b/invoice/src/test/java/org/killbill/billing/invoice/generator/TestDefaultInvoiceGenerator.java
@@ -32,6 +32,7 @@ import javax.annotation.Nullable;
 import org.joda.time.DateTime;
 import org.joda.time.DateTimeZone;
 import org.joda.time.LocalDate;
+import org.killbill.billing.account.api.Account;
 import org.killbill.billing.catalog.DefaultPrice;
 import org.killbill.billing.catalog.MockInternationalPrice;
 import org.killbill.billing.catalog.MockPlan;
@@ -58,6 +59,7 @@ import org.killbill.billing.invoice.model.RecurringInvoiceItem;
 import org.killbill.billing.invoice.model.RepairAdjInvoiceItem;
 import org.killbill.billing.junction.BillingEvent;
 import org.killbill.billing.junction.BillingEventSet;
+import org.killbill.billing.mock.MockAccountBuilder;
 import org.killbill.billing.subscription.api.SubscriptionBase;
 import org.killbill.billing.subscription.api.SubscriptionBaseTransitionType;
 import org.killbill.billing.util.config.InvoiceConfig;
@@ -68,6 +70,7 @@ import org.mockito.Mockito;
 import org.skife.config.TimeSpan;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 import static org.killbill.billing.invoice.TestInvoiceHelper.EIGHT;
@@ -93,11 +96,16 @@ import static org.testng.Assert.assertNotNull;
 import static org.testng.Assert.assertNull;
 import static org.testng.Assert.assertTrue;
 
+@SuppressWarnings("UnusedDeclaration")
 public class TestDefaultInvoiceGenerator extends InvoiceTestSuiteNoDB {
 
+    private Account account;
+
     private static final Logger log = LoggerFactory.getLogger(TestDefaultInvoiceGenerator.class);
 
-    public TestDefaultInvoiceGenerator() {
+    @BeforeClass(groups = "fast")
+    protected void beforeClass() throws Exception {
+        super.beforeClass();
         final Clock clock = new DefaultClock();
         final InvoiceConfig invoiceConfig = new InvoiceConfig() {
             @Override
@@ -121,20 +129,31 @@ public class TestDefaultInvoiceGenerator extends InvoiceTestSuiteNoDB {
             }
         };
         this.generator = new DefaultInvoiceGenerator(clock, null, invoiceConfig, internalCallContextFactory);
+        this.account = new MockAccountBuilder().name(UUID.randomUUID().toString().substring(1, 8))
+                                               .firstNameLength(6)
+                                               .email(UUID.randomUUID().toString().substring(1, 8))
+                                               .phone(UUID.randomUUID().toString().substring(1, 8))
+                                               .migrated(false)
+                                               .isNotifiedForInvoices(true)
+                                               .externalKey(UUID.randomUUID().toString().substring(1, 8))
+                                               .billingCycleDayLocal(31)
+                                               .currency(Currency.USD)
+                                               .paymentMethodId(UUID.randomUUID())
+                                               .timeZone(DateTimeZone.UTC)
+                                               .build();
+
     }
 
     @Test(groups = "fast")
     public void testWithNullEventSetAndNullInvoiceSet() throws InvoiceApiException {
-        final UUID accountId = UUID.randomUUID();
-        final Invoice invoice = generator.generateInvoice(accountId, null, null, clock.getUTCToday(), Currency.USD, internalCallContext);
+        final Invoice invoice = generator.generateInvoice(account, null, null, clock.getUTCToday(), Currency.USD, internalCallContext);
         assertNull(invoice);
     }
 
     @Test(groups = "fast")
     public void testWithEmptyEventSet() throws InvoiceApiException {
         final BillingEventSet events = new MockBillingEventSet();
-        final UUID accountId = UUID.randomUUID();
-        final Invoice invoice = generator.generateInvoice(accountId, events, null, clock.getUTCToday(), Currency.USD, internalCallContext);
+        final Invoice invoice = generator.generateInvoice(account, events, null, clock.getUTCToday(), Currency.USD, internalCallContext);
         assertNull(invoice);
     }
 
@@ -153,8 +172,7 @@ public class TestDefaultInvoiceGenerator extends InvoiceTestSuiteNoDB {
         events.add(event);
 
         final LocalDate targetDate = invoiceUtil.buildDate(2011, 10, 3);
-        final UUID accountId = UUID.randomUUID();
-        final Invoice invoice = generator.generateInvoice(accountId, events, null, targetDate, Currency.USD, internalCallContext);
+        final Invoice invoice = generator.generateInvoice(account, events, null, targetDate, Currency.USD, internalCallContext);
 
         assertNotNull(invoice);
         assertEquals(invoice.getNumberOfItems(), 2);
@@ -176,7 +194,6 @@ public class TestDefaultInvoiceGenerator extends InvoiceTestSuiteNoDB {
 
     @Test(groups = "fast")
     public void testSimpleWithTimeZone() throws InvoiceApiException, CatalogApiException {
-        final UUID accountId = UUID.randomUUID();
         final SubscriptionBase sub = createSubscription();
         final Plan plan = new MockPlan();
         final BigDecimal rate = TEN;
@@ -192,7 +209,7 @@ public class TestDefaultInvoiceGenerator extends InvoiceTestSuiteNoDB {
 
         // Target date is the next BCD, in local time
         final LocalDate targetDate = invoiceUtil.buildDate(2012, 8, bcdLocal);
-        final Invoice invoice = generator.generateInvoice(accountId, events, null, targetDate, Currency.USD, internalCallContext);
+        final Invoice invoice = generator.generateInvoice(account, events, null, targetDate, Currency.USD, internalCallContext);
 
         assertNotNull(invoice);
         assertEquals(invoice.getNumberOfItems(), 2);
@@ -216,7 +233,7 @@ public class TestDefaultInvoiceGenerator extends InvoiceTestSuiteNoDB {
 
         // Set a target date of today (start date)
         final LocalDate targetDate = startDate;
-        final Invoice invoice = generator.generateInvoice(accountId, events, null, targetDate, Currency.USD, internalCallContext);
+        final Invoice invoice = generator.generateInvoice(account, events, null, targetDate, Currency.USD, internalCallContext);
 
         assertNotNull(invoice);
         assertEquals(invoice.getNumberOfItems(), 1);
@@ -238,8 +255,7 @@ public class TestDefaultInvoiceGenerator extends InvoiceTestSuiteNoDB {
         events.add(event);
 
         final LocalDate targetDate = invoiceUtil.buildDate(2011, 10, 3);
-        final UUID accountId = UUID.randomUUID();
-        final Invoice invoice = generator.generateInvoice(accountId, events, null, targetDate, Currency.USD, internalCallContext);
+        final Invoice invoice = generator.generateInvoice(account, events, null, targetDate, Currency.USD, internalCallContext);
 
         assertNotNull(invoice);
         assertEquals(invoice.getNumberOfItems(), 2);
@@ -271,8 +287,7 @@ public class TestDefaultInvoiceGenerator extends InvoiceTestSuiteNoDB {
         events.add(event2);
 
         final LocalDate targetDate = invoiceUtil.buildDate(2011, 10, 3);
-        final UUID accountId = UUID.randomUUID();
-        final Invoice invoice = generator.generateInvoice(accountId, events, null, targetDate, Currency.USD, internalCallContext);
+        final Invoice invoice = generator.generateInvoice(account, events, null, targetDate, Currency.USD, internalCallContext);
 
         assertNotNull(invoice);
         assertEquals(invoice.getNumberOfItems(), 2);
@@ -298,7 +313,7 @@ public class TestDefaultInvoiceGenerator extends InvoiceTestSuiteNoDB {
 
         final LocalDate targetDate = invoiceUtil.buildDate(2011, 12, 3);
         final UUID accountId = UUID.randomUUID();
-        final Invoice invoice = generator.generateInvoice(accountId, events, null, targetDate, Currency.USD, internalCallContext);
+        final Invoice invoice = generator.generateInvoice(account, events, null, targetDate, Currency.USD, internalCallContext);
 
         assertNotNull(invoice);
         assertEquals(invoice.getNumberOfItems(), 4);
@@ -339,8 +354,7 @@ public class TestDefaultInvoiceGenerator extends InvoiceTestSuiteNoDB {
         events.add(event3);
 
         final LocalDate targetDate = invoiceUtil.buildDate(2011, 12, 3);
-        final UUID accountId = UUID.randomUUID();
-        final Invoice invoice = generator.generateInvoice(accountId, events, null, targetDate, Currency.USD, internalCallContext);
+        final Invoice invoice = generator.generateInvoice(account, events, null, targetDate, Currency.USD, internalCallContext);
 
         assertNotNull(invoice);
         assertEquals(invoice.getNumberOfItems(), 4);
@@ -362,13 +376,12 @@ public class TestDefaultInvoiceGenerator extends InvoiceTestSuiteNoDB {
         events.add(event1);
 
         LocalDate targetDate = invoiceUtil.buildDate(2011, 12, 1);
-        final UUID accountId = UUID.randomUUID();
-        final Invoice invoice1 = generator.generateInvoice(accountId, events, null, targetDate, Currency.USD, internalCallContext);
+        final Invoice invoice1 = generator.generateInvoice(account, events, null, targetDate, Currency.USD, internalCallContext);
         final List<Invoice> existingInvoices = new ArrayList<Invoice>();
         existingInvoices.add(invoice1);
 
         targetDate = invoiceUtil.buildDate(2011, 12, 3);
-        final Invoice invoice2 = generator.generateInvoice(accountId, events, existingInvoices, targetDate, Currency.USD, internalCallContext);
+        final Invoice invoice2 = generator.generateInvoice(account, events, existingInvoices, targetDate, Currency.USD, internalCallContext);
 
         assertNull(invoice2);
     }
@@ -541,7 +554,7 @@ public class TestDefaultInvoiceGenerator extends InvoiceTestSuiteNoDB {
         final LocalDate targetDate = invoiceUtil.buildDate(2011, 1, 1);
         events.add(createBillingEvent(UUID.randomUUID(), UUID.randomUUID(), targetDate, plan, planPhase, 1));
 
-        final Invoice invoice = generator.generateInvoice(UUID.randomUUID(), events, null, targetDate, Currency.USD, internalCallContext);
+        final Invoice invoice = generator.generateInvoice(account, events, null, targetDate, Currency.USD, internalCallContext);
 
         assertEquals(invoice.getNumberOfItems(), 1);
     }
@@ -556,7 +569,7 @@ public class TestDefaultInvoiceGenerator extends InvoiceTestSuiteNoDB {
 
         events.add(createBillingEvent(UUID.randomUUID(), UUID.randomUUID(), startDate, plan, planPhase, startDate.getDayOfMonth()));
 
-        final Invoice invoice = generator.generateInvoice(UUID.randomUUID(), events, null, targetDate, Currency.USD, internalCallContext);
+        final Invoice invoice = generator.generateInvoice(account, events, null, targetDate, Currency.USD, internalCallContext);
         final RecurringInvoiceItem item = (RecurringInvoiceItem) invoice.getInvoiceItems().get(0);
 
         // end date of the invoice item should be equal to exactly one month later (rounded)
@@ -565,7 +578,6 @@ public class TestDefaultInvoiceGenerator extends InvoiceTestSuiteNoDB {
 
     @Test(groups = "fast")
     public void testFixedPriceLifeCycle() throws InvoiceApiException {
-        final UUID accountId = UUID.randomUUID();
         final SubscriptionBase subscription = createSubscription();
 
         final Plan plan = new MockPlan("plan 1");
@@ -593,13 +605,13 @@ public class TestDefaultInvoiceGenerator extends InvoiceTestSuiteNoDB {
 
         events.add(event2);
         events.add(event1);
-        final Invoice invoice1 = generator.generateInvoice(accountId, events, null, new LocalDate("2012-02-01"), Currency.USD, internalCallContext);
+        final Invoice invoice1 = generator.generateInvoice(account, events, null, new LocalDate("2012-02-01"), Currency.USD, internalCallContext);
         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"), Currency.USD, internalCallContext);
+        final Invoice invoice2 = generator.generateInvoice(account, events, invoiceList, new LocalDate("2012-04-05"), Currency.USD, internalCallContext);
         assertNotNull(invoice2);
         assertEquals(invoice2.getNumberOfItems(), 1);
         final FixedPriceInvoiceItem item = (FixedPriceInvoiceItem) invoice2.getInvoiceItems().get(0);
@@ -617,14 +629,13 @@ public class TestDefaultInvoiceGenerator extends InvoiceTestSuiteNoDB {
         final BillingEventSet events = new MockBillingEventSet();
         final UUID subscriptionId = UUID.randomUUID();
         final UUID bundleId = UUID.randomUUID();
-        final UUID accountId = UUID.randomUUID();
 
         final LocalDate startDate = new LocalDate(2011, 1, 1);
         final BillingEvent event1 = createBillingEvent(subscriptionId, bundleId, startDate, plan1, phase1, 1);
         events.add(event1);
 
         // ensure both components are invoiced
-        final Invoice invoice1 = generator.generateInvoice(accountId, events, null, startDate, Currency.USD, internalCallContext);
+        final Invoice invoice1 = generator.generateInvoice(account, events, null, startDate, Currency.USD, internalCallContext);
         assertNotNull(invoice1);
         assertEquals(invoice1.getNumberOfItems(), 2);
         assertEquals(invoice1.getBalance(), KillBillMoney.of(FIFTEEN, invoice1.getCurrency()));
@@ -636,7 +647,7 @@ public class TestDefaultInvoiceGenerator extends InvoiceTestSuiteNoDB {
         final LocalDate currentDate = startDate.plusMonths(1);
 
         // ensure that only the recurring price is invoiced
-        final Invoice invoice2 = generator.generateInvoice(accountId, events, invoiceList, currentDate, Currency.USD, internalCallContext);
+        final Invoice invoice2 = generator.generateInvoice(account, events, invoiceList, currentDate, Currency.USD, internalCallContext);
         assertNotNull(invoice2);
         assertEquals(invoice2.getNumberOfItems(), 1);
         assertEquals(invoice2.getBalance(), KillBillMoney.of(FIVE, invoice2.getCurrency()));
@@ -661,7 +672,7 @@ public class TestDefaultInvoiceGenerator extends InvoiceTestSuiteNoDB {
         events.add(event1);
 
         // ensure that a single invoice item is generated for the fixed cost
-        final Invoice invoice1 = generator.generateInvoice(accountId, events, null, startDate, Currency.USD, internalCallContext);
+        final Invoice invoice1 = generator.generateInvoice(account, events, null, startDate, Currency.USD, internalCallContext);
         assertNotNull(invoice1);
         assertEquals(invoice1.getNumberOfItems(), 1);
         assertEquals(invoice1.getBalance(), KillBillMoney.of(fixedCost1, invoice1.getCurrency()));
@@ -675,7 +686,7 @@ public class TestDefaultInvoiceGenerator extends InvoiceTestSuiteNoDB {
         events.add(event2);
 
         // ensure that a single invoice item is generated for the fixed cost
-        final Invoice invoice2 = generator.generateInvoice(accountId, events, invoiceList, phaseChangeDate, Currency.USD, internalCallContext);
+        final Invoice invoice2 = generator.generateInvoice(account, events, invoiceList, phaseChangeDate, Currency.USD, internalCallContext);
         assertNotNull(invoice2);
         assertEquals(invoice2.getNumberOfItems(), 1);
         assertEquals(invoice2.getBalance(), KillBillMoney.of(fixedCost2, invoice2.getCurrency()));
@@ -685,7 +696,6 @@ public class TestDefaultInvoiceGenerator extends InvoiceTestSuiteNoDB {
     public void testInvoiceGenerationFailureScenario() throws InvoiceApiException, CatalogApiException {
         final BillingEventSet events = new MockBillingEventSet();
         final UUID subscriptionId = UUID.randomUUID();
-        final UUID accountId = UUID.randomUUID();
         final UUID bundleId = UUID.randomUUID();
         final int BILL_CYCLE_DAY = 15;
 
@@ -708,7 +718,7 @@ public class TestDefaultInvoiceGenerator extends InvoiceTestSuiteNoDB {
         final LocalDate discountPhaseEndDate = trialPhaseEndDate.plusMonths(6);
         events.add(createBillingEvent(subscriptionId, bundleId, discountPhaseEndDate, plan1, phase3, BILL_CYCLE_DAY));
 
-        final Invoice invoice1 = generator.generateInvoice(accountId, events, null, creationDate, Currency.USD, internalCallContext);
+        final Invoice invoice1 = generator.generateInvoice(account, events, null, creationDate, Currency.USD, internalCallContext);
         assertNotNull(invoice1);
         assertEquals(invoice1.getNumberOfItems(), 1);
         assertEquals(invoice1.getBalance().compareTo(ZERO), 0);
@@ -716,7 +726,7 @@ public class TestDefaultInvoiceGenerator extends InvoiceTestSuiteNoDB {
         final List<Invoice> invoiceList = new ArrayList<Invoice>();
         invoiceList.add(invoice1);
 
-        final Invoice invoice2 = generator.generateInvoice(accountId, events, invoiceList, trialPhaseEndDate, Currency.USD, internalCallContext);
+        final Invoice invoice2 = generator.generateInvoice(account, events, invoiceList, trialPhaseEndDate, Currency.USD, internalCallContext);
         assertNotNull(invoice2);
         assertEquals(invoice2.getNumberOfItems(), 1);
         assertEquals(invoice2.getInvoiceItems().get(0).getStartDate(), trialPhaseEndDate);
@@ -724,7 +734,7 @@ public class TestDefaultInvoiceGenerator extends InvoiceTestSuiteNoDB {
 
         invoiceList.add(invoice2);
         LocalDate targetDate = new LocalDate(trialPhaseEndDate.getYear(), trialPhaseEndDate.getMonthOfYear(), BILL_CYCLE_DAY);
-        final Invoice invoice3 = generator.generateInvoice(accountId, events, invoiceList, targetDate, Currency.USD, internalCallContext);
+        final Invoice invoice3 = generator.generateInvoice(account, events, invoiceList, targetDate, Currency.USD, internalCallContext);
         assertNotNull(invoice3);
         assertEquals(invoice3.getNumberOfItems(), 1);
         assertEquals(invoice3.getInvoiceItems().get(0).getStartDate(), targetDate);
@@ -732,7 +742,7 @@ public class TestDefaultInvoiceGenerator extends InvoiceTestSuiteNoDB {
 
         invoiceList.add(invoice3);
         targetDate = targetDate.plusMonths(6);
-        final Invoice invoice4 = generator.generateInvoice(accountId, events, invoiceList, targetDate, Currency.USD, internalCallContext);
+        final Invoice invoice4 = generator.generateInvoice(account, events, invoiceList, targetDate, Currency.USD, internalCallContext);
         assertNotNull(invoice4);
         assertEquals(invoice4.getNumberOfItems(), 7);
     }
@@ -744,7 +754,7 @@ public class TestDefaultInvoiceGenerator extends InvoiceTestSuiteNoDB {
         final Plan plan1 = new MockPlan();
         final PlanPhase phase1 = createMockMonthlyPlanPhase(null, ZERO, PhaseType.TRIAL);
         events.add(createBillingEvent(UUID.randomUUID(), UUID.randomUUID(), clock.getUTCToday(), plan1, phase1, 1));
-        generator.generateInvoice(UUID.randomUUID(), events, null, targetDate, Currency.USD, internalCallContext);
+        generator.generateInvoice(account, events, null, targetDate, Currency.USD, internalCallContext);
     }
 
     private MockPlanPhase createMockMonthlyPlanPhase() {
@@ -791,7 +801,7 @@ public class TestDefaultInvoiceGenerator extends InvoiceTestSuiteNoDB {
                                        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, currency, internalCallContext);
+        final Invoice invoice = generator.generateInvoice(account, events, existingInvoices, targetDate, currency, internalCallContext);
         assertNotNull(invoice);
         assertEquals(invoice.getNumberOfItems(), expectedNumberOfItems);
         existingInvoices.add(invoice);
@@ -805,7 +815,6 @@ public class TestDefaultInvoiceGenerator extends InvoiceTestSuiteNoDB {
         final LocalDate april25 = new LocalDate(2012, 4, 25);
 
         // create a base plan on April 25th
-        final UUID accountId = UUID.randomUUID();
         final SubscriptionBase baseSubscription = createSubscription();
 
         final Plan basePlan = new MockPlan("base Plan");
@@ -818,7 +827,7 @@ public class TestDefaultInvoiceGenerator extends InvoiceTestSuiteNoDB {
         events.add(createBillingEvent(baseSubscription.getId(), baseSubscription.getBundleId(), april25, basePlan, basePlanEvergreen, 25));
 
         // generate invoice
-        final Invoice invoice1 = generator.generateInvoice(accountId, events, null, april25, Currency.USD, internalCallContext);
+        final Invoice invoice1 = generator.generateInvoice(account, events, null, april25, Currency.USD, internalCallContext);
         assertNotNull(invoice1);
         assertEquals(invoice1.getNumberOfItems(), 1);
         assertEquals(invoice1.getBalance().compareTo(TEN), 0);
@@ -839,7 +848,7 @@ public class TestDefaultInvoiceGenerator extends InvoiceTestSuiteNoDB {
         events.add(createBillingEvent(addOnSubscription2.getId(), baseSubscription.getBundleId(), april28, addOn2Plan, addOn2PlanPhaseEvergreen, 25));
 
         // generate invoice
-        final Invoice invoice2 = generator.generateInvoice(accountId, events, invoices, april28, Currency.USD, internalCallContext);
+        final Invoice invoice2 = generator.generateInvoice(account, events, invoices, april28, Currency.USD, internalCallContext);
         invoices.add(invoice2);
         assertNotNull(invoice2);
         assertEquals(invoice2.getNumberOfItems(), 2);
@@ -856,7 +865,7 @@ public class TestDefaultInvoiceGenerator extends InvoiceTestSuiteNoDB {
 
         // generate invoice
         final LocalDate may1 = new LocalDate(2012, 5, 1);
-        final Invoice invoice3 = generator.generateInvoice(accountId, newEvents, invoices, may1, Currency.USD, internalCallContext);
+        final Invoice invoice3 = generator.generateInvoice(account, newEvents, invoices, may1, Currency.USD, internalCallContext);
         assertNotNull(invoice3);
         assertEquals(invoice3.getNumberOfItems(), 3);
         // -4.50 -18 - 10 (to correct the previous 2 invoices) + 4.50 + 13
@@ -869,7 +878,6 @@ public class TestDefaultInvoiceGenerator extends InvoiceTestSuiteNoDB {
         final LocalDate april25 = new LocalDate(2012, 4, 25);
 
         // create a base plan on April 25th
-        final UUID accountId = UUID.randomUUID();
         final SubscriptionBase originalSubscription = createSubscription();
 
         final Plan originalPlan = new MockPlan("original plan");
@@ -879,7 +887,7 @@ public class TestDefaultInvoiceGenerator extends InvoiceTestSuiteNoDB {
         final BillingEventSet events = new MockBillingEventSet();
         events.add(createBillingEvent(originalSubscription.getId(), originalSubscription.getBundleId(), april25, originalPlan, originalPlanEvergreen, 25));
 
-        final Invoice invoice1 = generator.generateInvoice(accountId, events, null, april25, Currency.USD, internalCallContext);
+        final Invoice invoice1 = generator.generateInvoice(account, events, null, april25, Currency.USD, internalCallContext);
 
         printDetailInvoice(invoice1);
 
@@ -901,7 +909,7 @@ public class TestDefaultInvoiceGenerator extends InvoiceTestSuiteNoDB {
         events.add(createBillingEvent(newSubscription.getId(), originalSubscription.getBundleId(), april25, newPlan, newPlanEvergreen, 25));
 
         // generate a new invoice
-        final Invoice invoice2 = generator.generateInvoice(accountId, events, invoices, april25, Currency.USD, internalCallContext);
+        final Invoice invoice2 = generator.generateInvoice(account, events, invoices, april25, Currency.USD, internalCallContext);
 
         printDetailInvoice(invoice2);
         assertEquals(invoice2.getNumberOfItems(), 2);
@@ -965,7 +973,7 @@ public class TestDefaultInvoiceGenerator extends InvoiceTestSuiteNoDB {
 
         // Generate a new invoice
 
-        final Invoice invoice = generator.generateInvoice(accountId, events, existingInvoices, targetDate, currency, internalCallContext);
+        final Invoice invoice = generator.generateInvoice(account, events, existingInvoices, targetDate, currency, internalCallContext);
         assertEquals(invoice.getNumberOfItems(), 7);
         assertEquals(invoice.getInvoiceItems().get(0).getInvoiceItemType(), InvoiceItemType.RECURRING);
         assertEquals(invoice.getInvoiceItems().get(0).getStartDate(), new LocalDate(2013, 6, 15));
@@ -999,7 +1007,7 @@ public class TestDefaultInvoiceGenerator extends InvoiceTestSuiteNoDB {
         existingInvoices.add(invoice);
 
         // Generate next invoice (no-op)
-        final Invoice newInvoice = generator.generateInvoice(accountId, events, existingInvoices, targetDate, currency, internalCallContext);
+        final Invoice newInvoice = generator.generateInvoice(account, events, existingInvoices, targetDate, currency, internalCallContext);
         assertNull(newInvoice);
     }
 
@@ -1046,7 +1054,7 @@ public class TestDefaultInvoiceGenerator extends InvoiceTestSuiteNoDB {
 
         final LocalDate targetDate = invoiceUtil.buildDate(2011, 10, 3);
         final UUID accountId = UUID.randomUUID();
-        final Invoice invoice = generator.generateInvoice(accountId, events, null, targetDate, Currency.USD, internalCallContext);
+        final Invoice invoice = generator.generateInvoice(account, events, null, targetDate, Currency.USD, internalCallContext);
 
         assertNull(invoice);
     }
@@ -1074,7 +1082,7 @@ public class TestDefaultInvoiceGenerator extends InvoiceTestSuiteNoDB {
         eventSet.add(createBillingEvent(subscriptionId2, bundleId, startDate, plan2, plan2phase1, 1));
 
         // generate the first invoice
-        final Invoice invoice1 = generator.generateInvoice(accountId, eventSet, invoices, startDate, currency, internalCallContext);
+        final Invoice invoice1 = generator.generateInvoice(account, eventSet, invoices, startDate, currency, internalCallContext);
         assertNotNull(invoice1);
         assertTrue(invoice1.getBalance().compareTo(FIFTEEN.add(TWELVE)) == 0);
         invoices.add(invoice1);
@@ -1085,7 +1093,7 @@ public class TestDefaultInvoiceGenerator extends InvoiceTestSuiteNoDB {
         eventSet.addSubscriptionWithAutoInvoiceOff(subscriptionId1);
 
         final LocalDate targetDate2 = startDate.plusMonths(1);
-        final Invoice invoice2 = generator.generateInvoice(accountId, eventSet, invoices, targetDate2, currency, internalCallContext);
+        final Invoice invoice2 = generator.generateInvoice(account, eventSet, invoices, targetDate2, currency, internalCallContext);
         assertNotNull(invoice2);
         assertTrue(invoice2.getBalance().compareTo(TWELVE) == 0);
         invoices.add(invoice2);
@@ -1093,7 +1101,7 @@ public class TestDefaultInvoiceGenerator extends InvoiceTestSuiteNoDB {
         final LocalDate targetDate3 = targetDate2.plusMonths(1);
         eventSet.clearSubscriptionsWithAutoInvoiceOff();
         eventSet.add(subscription1creation);
-        final Invoice invoice3 = generator.generateInvoice(accountId, eventSet, invoices, targetDate3, currency, internalCallContext);
+        final Invoice invoice3 = generator.generateInvoice(account, eventSet, invoices, targetDate3, currency, internalCallContext);
         assertNotNull(invoice3);
         assertTrue(invoice3.getBalance().compareTo(FIFTEEN.multiply(TWO).add(TWELVE)) == 0);
     }
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/BundleResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/BundleResource.java
index a0481e4..1b291d4 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/BundleResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/BundleResource.java
@@ -201,7 +201,7 @@ public class BundleResource extends JaxRsResourceBase {
                                 @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                 @HeaderParam(HDR_REASON) final String reason,
                                 @HeaderParam(HDR_COMMENT) final String comment,
-                                @javax.ws.rs.core.Context final HttpServletRequest request) throws SubscriptionApiException, EntitlementApiException {
+                                @javax.ws.rs.core.Context final HttpServletRequest request) throws SubscriptionApiException, EntitlementApiException, AccountApiException {
 
         final CallContext callContext = context.createContext(createdBy, reason, comment, request);
         final UUID bundleId = UUID.fromString(id);
@@ -224,7 +224,7 @@ public class BundleResource extends JaxRsResourceBase {
                                  @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                  @HeaderParam(HDR_REASON) final String reason,
                                  @HeaderParam(HDR_COMMENT) final String comment,
-                                 @javax.ws.rs.core.Context final HttpServletRequest request) throws SubscriptionApiException, EntitlementApiException {
+                                 @javax.ws.rs.core.Context final HttpServletRequest request) throws SubscriptionApiException, EntitlementApiException, AccountApiException {
 
         final CallContext callContext = context.createContext(createdBy, reason, comment, request);
         final UUID bundleId = UUID.fromString(id);
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/JaxRsResourceBase.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/JaxRsResourceBase.java
index fbedb62..e5626b2 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/JaxRsResourceBase.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/JaxRsResourceBase.java
@@ -292,18 +292,12 @@ public abstract class JaxRsResourceBase implements JaxrsResource {
         }
     }
 
-    protected LocalDate toLocalDate(final UUID accountId, final String inputDate, final TenantContext context) {
-
+    protected LocalDate toLocalDate(final UUID accountId, final String inputDate, final TenantContext context) throws AccountApiException {
         final LocalDate maybeResult = extractLocalDate(inputDate);
         if (maybeResult != null) {
             return maybeResult;
         }
-        Account account = null;
-        try {
-            account = accountId != null ? accountUserApi.getAccountById(accountId, context) : null;
-        } catch (final AccountApiException e) {
-            log.info("Failed to retrieve account for id " + accountId);
-        }
+        Account account = accountId != null ? accountUserApi.getAccountById(accountId, context) : null;
         final DateTime inputDateTime = inputDate != null ? DATE_TIME_FORMATTER.parseDateTime(inputDate) : clock.getUTCNow();
         return toLocalDate(account, inputDateTime, context);
     }
diff --git a/jaxrs/src/test/java/org/killbill/billing/jaxrs/TestDateConversion.java b/jaxrs/src/test/java/org/killbill/billing/jaxrs/TestDateConversion.java
index 320ac1c..e568fea 100644
--- a/jaxrs/src/test/java/org/killbill/billing/jaxrs/TestDateConversion.java
+++ b/jaxrs/src/test/java/org/killbill/billing/jaxrs/TestDateConversion.java
@@ -24,6 +24,7 @@ import org.joda.time.LocalDate;
 import org.mockito.Mockito;
 import org.testng.Assert;
 import org.testng.annotations.BeforeClass;
+import org.testng.annotations.BeforeTest;
 import org.testng.annotations.Test;
 
 import org.killbill.billing.account.api.Account;
@@ -34,23 +35,29 @@ import org.killbill.billing.jaxrs.resources.JaxRsResourceBase;
 
 public class TestDateConversion extends JaxRsResourceBase {
 
-    final UUID accountId = UUID.fromString("ffa649da-555e-4c55-bf65-84b06a4b3564");
-    final DateTimeZone dateTimeZone = DateTimeZone.forOffsetHours(-8);
-
     public TestDateConversion() throws AccountApiException {
-        super(null, null, null, null, Mockito.mock(AccountUserApi.class), null, new ClockMock(),  null);
+        super(null, null, null, null, Mockito.mock(AccountUserApi.class), null, new ClockMock(), null);
+    }
+
+    public UUID setupAccount(DateTimeZone accountTimeZone) throws AccountApiException {
+        final UUID accountId = UUID.randomUUID();
         final Account account = Mockito.mock(Account.class);
-        Mockito.when(account.getTimeZone()).thenReturn(dateTimeZone);
+        Mockito.when(account.getTimeZone()).thenReturn(accountTimeZone);
         Mockito.when(accountUserApi.getAccountById(accountId, null)).thenReturn(account);
+        return accountId;
     }
 
-    @BeforeClass
-    public void beforeClass() {
+    @BeforeTest(groups = "fast")
+    public void beforeTest() {
+        ((ClockMock) clock).resetDeltaFromReality();
     }
 
+    //
+    // BASIC Tests to understand how toLocalDate converts different inputs (null, LocalDate, DateTime)
+    //
     @Test(groups = "fast")
-    public void testDateTimeConversion() {
-
+    public void testDateTimeConversion() throws AccountApiException {
+        final UUID accountId = setupAccount(DateTimeZone.forOffsetHours(-8));
         final String input = "2013-08-26T06:50:20Z";
         final LocalDate result = toLocalDate(accountId, input, null);
         Assert.assertTrue(result.compareTo(new LocalDate(2013, 8, 25)) == 0);
@@ -58,7 +65,8 @@ public class TestDateConversion extends JaxRsResourceBase {
 
 
     @Test(groups = "fast")
-    public void testNullConversion() {
+    public void testNullConversion() throws AccountApiException {
+        final UUID accountId = setupAccount(DateTimeZone.forOffsetHours(-8));
         ((ClockMock) clock).setTime(new DateTime("2013-08-26T06:50:20Z"));
         final String input = null;
         final LocalDate result = toLocalDate(accountId, input, null);
@@ -67,9 +75,35 @@ public class TestDateConversion extends JaxRsResourceBase {
     }
 
     @Test(groups = "fast")
-    public void testLocalDateConversion() {
+    public void testLocalDateConversion() throws AccountApiException {
+        final UUID accountId = setupAccount(DateTimeZone.forOffsetHours(-8));
         final String input = "2013-08-25";
         final LocalDate result = toLocalDate(accountId, input, null);
         Assert.assertTrue(result.compareTo(new LocalDate(2013, 8, 25)) == 0);
     }
+
+    //
+    // MOSTLY FOR OUR UNDERSTANDING ON HOW LocalDate and DateTime behave with respect to DateTimeZone
+    //
+
+    // Illustrate that specifying a DateTimeZone in a LocalDate when the input 'instant' is a LocalDate has NO effect.
+    @Test(groups = "fast")
+    public void testTwoLocalDatesWithDifferentTimeZonesAreEquals() throws AccountApiException {
+
+        final String inputDate = "2013-08-25";
+        final LocalDate localDate = LocalDate.parse(inputDate, LOCAL_DATE_FORMATTER);
+        final LocalDate localDateInUTC = new LocalDate(localDate, DateTimeZone.UTC);
+        final LocalDate localDateInAccountTimeZone = new LocalDate(localDate, DateTimeZone.forOffsetHours(-8));
+        Assert.assertEquals(localDateInUTC, localDateInAccountTimeZone);
+    }
+
+    // Illustrate that specifying a DateTimeZone in a LocalDate when the input 'instant' is a DateTime DOES HAVE an effect.
+    @Test(groups = "fast")
+    public void testTwoDateTimesConstructedFromDateTimesWithDifferentTimeZonesAreDifferent() throws AccountApiException {
+
+        final DateTime nowUTC = DATE_TIME_FORMATTER.parseDateTime("2015-04-05T05:27:17.547Z");
+        final LocalDate localDateInUTC = new LocalDate(nowUTC, DateTimeZone.UTC);
+        final LocalDate localDateInAccountTimeZone = new LocalDate(nowUTC, DateTimeZone.forOffsetHours(-8));
+        Assert.assertNotEquals(localDateInUTC, localDateInAccountTimeZone);
+    }
 }
diff --git a/subscription/src/main/java/org/killbill/billing/subscription/api/svcs/DefaultSubscriptionInternalApi.java b/subscription/src/main/java/org/killbill/billing/subscription/api/svcs/DefaultSubscriptionInternalApi.java
index 8650ea8..adfe092 100644
--- a/subscription/src/main/java/org/killbill/billing/subscription/api/svcs/DefaultSubscriptionInternalApi.java
+++ b/subscription/src/main/java/org/killbill/billing/subscription/api/svcs/DefaultSubscriptionInternalApi.java
@@ -108,9 +108,11 @@ public class DefaultSubscriptionInternalApi extends SubscriptionApiBase implemen
             final String realPriceList = (spec.getPriceListName() == null) ? PriceListSet.DEFAULT_PRICELIST_NAME : spec.getPriceListName();
             final DateTime now = clock.getUTCNow();
             final DateTime requestedDate = (requestedDateWithMs != null) ? DefaultClock.truncateMs(requestedDateWithMs) : now;
+            /*
             if (requestedDate.isAfter(now)) {
                 throw new SubscriptionBaseApiException(ErrorCode.SUB_INVALID_REQUESTED_DATE, now.toString(), requestedDate.toString());
             }
+            */
             final DateTime effectiveDate = requestedDate;
 
             final CallContext callContext = internalCallContextFactory.createCallContext(context);
diff --git a/subscription/src/main/java/org/killbill/billing/subscription/api/user/DefaultSubscriptionBase.java b/subscription/src/main/java/org/killbill/billing/subscription/api/user/DefaultSubscriptionBase.java
index f337463..a7ae3e9 100644
--- a/subscription/src/main/java/org/killbill/billing/subscription/api/user/DefaultSubscriptionBase.java
+++ b/subscription/src/main/java/org/killbill/billing/subscription/api/user/DefaultSubscriptionBase.java
@@ -182,7 +182,7 @@ public class DefaultSubscriptionBase extends EntityBase implements SubscriptionB
     @Override
     public DateTime getEndDate() {
         final SubscriptionBaseTransition latestTransition = getPreviousTransition();
-        if (latestTransition.getNextState() == EntitlementState.CANCELLED) {
+        if (latestTransition != null && latestTransition.getNextState() == EntitlementState.CANCELLED) {
             return latestTransition.getEffectiveTransitionTime();
         }
         return null;