killbill-memoizeit

entitlement: allow to pass null dates in APIs A null date means

2/11/2016 10:58:10 AM

Details

diff --git a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/overdue/TestOverdueWithSubscriptionCancellation.java b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/overdue/TestOverdueWithSubscriptionCancellation.java
index f3fa2f8..7011c8a 100644
--- a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/overdue/TestOverdueWithSubscriptionCancellation.java
+++ b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/overdue/TestOverdueWithSubscriptionCancellation.java
@@ -30,7 +30,6 @@ import org.killbill.billing.entitlement.api.DefaultEntitlement;
 import org.killbill.billing.entitlement.api.Entitlement.EntitlementState;
 import org.killbill.billing.entitlement.api.SubscriptionBundle;
 import org.killbill.billing.invoice.api.InvoiceItemType;
-import org.killbill.billing.junction.DefaultBlockingState;
 import org.killbill.billing.overdue.wrapper.OverdueWrapper;
 import org.killbill.billing.subscription.api.SubscriptionBase;
 import org.testng.annotations.Test;
@@ -84,7 +83,7 @@ public class TestOverdueWithSubscriptionCancellation extends TestOverdueBase {
 
         // Cancel addOn1 one day after
         clock.addDays(1);
-        cancelEntitlementAndCheckForCompletion(addOn1, clock.getUTCNow(), NextEvent.BLOCK, NextEvent.CANCEL, NextEvent.NULL_INVOICE);
+        cancelEntitlementAndCheckForCompletion(addOn1, NextEvent.BLOCK, NextEvent.CANCEL, NextEvent.NULL_INVOICE);
 
         // DAY 30 have to get out of trial before first payment
         addDaysAndCheckForCompletion(29, NextEvent.PHASE,  NextEvent.PHASE, NextEvent.NULL_INVOICE, NextEvent.INVOICE, NextEvent.PAYMENT_ERROR, NextEvent.INVOICE_PAYMENT_ERROR);
@@ -135,7 +134,7 @@ public class TestOverdueWithSubscriptionCancellation extends TestOverdueBase {
 
         // Cancel bundle 2 one day after (2012-05-02)
         clock.addDays(1);
-        cancelEntitlementAndCheckForCompletion(baseEntitlement2, clock.getUTCNow(), NextEvent.BLOCK, NextEvent.CANCEL, NextEvent.NULL_INVOICE);
+        cancelEntitlementAndCheckForCompletion(baseEntitlement2, NextEvent.BLOCK, NextEvent.CANCEL, NextEvent.NULL_INVOICE);
         final SubscriptionBase cancelledBaseSubscription2 = ((DefaultEntitlement) entitlementApi.getEntitlementForId(baseEntitlement2.getId(), callContext)).getSubscriptionBase();
         assertTrue(cancelledBaseSubscription2.getState() == EntitlementState.CANCELLED);
 
diff --git a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegration.java b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegration.java
index 27642ab..e832853 100644
--- a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegration.java
+++ b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegration.java
@@ -24,7 +24,6 @@ import java.util.List;
 import java.util.UUID;
 
 import org.joda.time.DateTime;
-import org.joda.time.DateTimeZone;
 import org.joda.time.Interval;
 import org.joda.time.LocalDate;
 import org.killbill.billing.ErrorCode;
@@ -33,7 +32,6 @@ import org.killbill.billing.account.api.AccountData;
 import org.killbill.billing.api.TestApiListener.NextEvent;
 import org.killbill.billing.beatrix.util.InvoiceChecker.ExpectedInvoiceItemCheck;
 import org.killbill.billing.beatrix.util.PaymentChecker.ExpectedPaymentCheck;
-import org.killbill.billing.catalog.api.BillingActionPolicy;
 import org.killbill.billing.catalog.api.BillingPeriod;
 import org.killbill.billing.catalog.api.Currency;
 import org.killbill.billing.catalog.api.PriceListSet;
@@ -48,7 +46,6 @@ import org.killbill.billing.invoice.api.DryRunType;
 import org.killbill.billing.invoice.api.Invoice;
 import org.killbill.billing.invoice.api.InvoiceApiException;
 import org.killbill.billing.invoice.api.InvoiceItemType;
-import org.killbill.billing.mock.MockAccountBuilder;
 import org.killbill.billing.payment.api.PluginProperty;
 import org.killbill.billing.payment.api.TransactionStatus;
 import org.killbill.billing.subscription.api.user.DefaultSubscriptionBase;
@@ -121,7 +118,7 @@ public class TestIntegration extends TestIntegrationBase {
         invoiceChecker.checkInvoiceNoAudits(dryRunInvoice, callContext, expectedInvoices);
 
 
-        cancelEntitlementAndCheckForCompletion(bpSubscription, clock.getUTCNow(), NextEvent.BLOCK, NextEvent.BLOCK, NextEvent.CANCEL, NextEvent.CANCEL, NextEvent.INVOICE);
+        cancelEntitlementAndCheckForCompletion(bpSubscription, NextEvent.BLOCK, NextEvent.BLOCK, NextEvent.CANCEL, NextEvent.CANCEL, NextEvent.INVOICE);
 
         invoiceChecker.checkInvoice(account.getId(), 3,
                                     callContext,
@@ -233,7 +230,7 @@ public class TestIntegration extends TestIntegrationBase {
         //
         // FINALLY CANCEL SUBSCRIPTION EOT
         //
-        baseEntitlement = cancelEntitlementAndCheckForCompletion(baseEntitlement, clock.getUTCNow(), NextEvent.BLOCK);
+        baseEntitlement = cancelEntitlementAndCheckForCompletion(baseEntitlement, NextEvent.BLOCK);
 
         // MOVE AFTER CANCEL DATE AND EXPECT EVENT : NextEvent.CANCEL
         addDaysAndCheckForCompletion(31, NextEvent.CANCEL, NextEvent.NULL_INVOICE, NextEvent.NULL_INVOICE);
@@ -324,7 +321,7 @@ public class TestIntegration extends TestIntegrationBase {
         //
         // FINALLY CANCEL SUBSCRIPTION EOT
         //
-        cancelEntitlementAndCheckForCompletion(baseEntitlement, clock.getUTCNow(), NextEvent.BLOCK);
+        cancelEntitlementAndCheckForCompletion(baseEntitlement, NextEvent.BLOCK);
 
         // MOVE AFTER CANCEL DATE
         addDaysAndCheckForCompletion(31, NextEvent.CANCEL, NextEvent.NULL_INVOICE, NextEvent.NULL_INVOICE);
@@ -411,7 +408,7 @@ public class TestIntegration extends TestIntegrationBase {
         //
         // FINALLY CANCEL SUBSCRIPTION EOT
         //
-        baseEntitlement = cancelEntitlementAndCheckForCompletion(baseEntitlement, clock.getUTCNow(), NextEvent.BLOCK);
+        baseEntitlement = cancelEntitlementAndCheckForCompletion(baseEntitlement, NextEvent.BLOCK);
 
         // MOVE AFTER CANCEL DATE AND EXPECT EVENT : NextEvent.CANCEL
         addDaysAndCheckForCompletion(31, NextEvent.CANCEL, NextEvent.NULL_INVOICE, NextEvent.NULL_INVOICE);
diff --git a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationBase.java b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationBase.java
index ef2b22b..14f32de 100644
--- a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationBase.java
+++ b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationBase.java
@@ -582,8 +582,7 @@ public class TestIntegrationBase extends BeatrixTestSuiteWithEmbeddedDB {
             public Entitlement apply(@Nullable final Void dontcare) {
                 try {
                     final PlanPhaseSpecifier spec = new PlanPhaseSpecifier(productName, productCategory, billingPeriod, PriceListSet.DEFAULT_PRICELIST_NAME, null);
-                    final LocalDate effectiveDate = new LocalDate(clock.getUTCNow());
-                    final Entitlement entitlement = entitlementApi.createBaseEntitlement(accountId, spec, bundleExternalKey, overrides, effectiveDate, ImmutableList.<PluginProperty>of(), callContext);
+                    final Entitlement entitlement = entitlementApi.createBaseEntitlement(accountId, spec, bundleExternalKey, overrides, null, ImmutableList.<PluginProperty>of(), callContext);
                     assertNotNull(entitlement);
                     return entitlement;
                 } catch (final EntitlementApiException e) {
@@ -617,8 +616,7 @@ public class TestIntegrationBase extends BeatrixTestSuiteWithEmbeddedDB {
             public Entitlement apply(@Nullable final Void dontcare) {
                 try {
                     final PlanPhaseSpecifier spec = new PlanPhaseSpecifier(productName, productCategory, billingPeriod, PriceListSet.DEFAULT_PRICELIST_NAME, null);
-                    final LocalDate effectiveDate = new LocalDate(clock.getUTCNow());
-                    final Entitlement entitlement = entitlementApi.addEntitlement(bundleId, spec, null, effectiveDate, ImmutableList.<PluginProperty>of(), callContext);
+                    final Entitlement entitlement = entitlementApi.addEntitlement(bundleId, spec, null, null, ImmutableList.<PluginProperty>of(), callContext);
                     assertNotNull(entitlement);
                     return entitlement;
                 } catch (final EntitlementApiException e) {
@@ -644,7 +642,7 @@ public class TestIntegrationBase extends BeatrixTestSuiteWithEmbeddedDB {
                     if (billingPolicy == null) {
                         refreshedEntitlement = refreshedEntitlement.changePlan(productName, billingPeriod, priceList, null, ImmutableList.<PluginProperty>of(), callContext);
                     } else {
-                        refreshedEntitlement = refreshedEntitlement.changePlanOverrideBillingPolicy(productName, billingPeriod, priceList, null, clock.getUTCNow().toLocalDate(), billingPolicy, ImmutableList.<PluginProperty>of(), callContext);
+                        refreshedEntitlement = refreshedEntitlement.changePlanOverrideBillingPolicy(productName, billingPeriod, priceList, null, null, billingPolicy, ImmutableList.<PluginProperty>of(), callContext);
                     }
                     return refreshedEntitlement;
                 } catch (final EntitlementApiException e) {
@@ -664,7 +662,12 @@ public class TestIntegrationBase extends BeatrixTestSuiteWithEmbeddedDB {
     }
 
     protected DefaultEntitlement cancelEntitlementAndCheckForCompletion(final Entitlement entitlement,
-                                                                        final DateTime requestedDate,
+                                                                        final NextEvent... events) {
+        return cancelEntitlementAndCheckForCompletion(entitlement, null, events);
+    }
+
+    protected DefaultEntitlement cancelEntitlementAndCheckForCompletion(final Entitlement entitlement,
+                                                                        final LocalDate requestedDate,
                                                                         final NextEvent... events) {
         return (DefaultEntitlement) doCallAndCheckForCompletion(new Function<Void, Entitlement>() {
             @Override
@@ -672,7 +675,7 @@ public class TestIntegrationBase extends BeatrixTestSuiteWithEmbeddedDB {
                 try {
                     // Need to fetch again to get latest CTD updated from the system
                     Entitlement refreshedEntitlement = entitlementApi.getEntitlementForId(entitlement.getId(), callContext);
-                    refreshedEntitlement = refreshedEntitlement.cancelEntitlementWithDate(requestedDate.toLocalDate(), false, ImmutableList.<PluginProperty>of(), callContext);
+                    refreshedEntitlement = refreshedEntitlement.cancelEntitlementWithDate(requestedDate, false, ImmutableList.<PluginProperty>of(), callContext);
                     return refreshedEntitlement;
                 } catch (final EntitlementApiException e) {
                     fail(e.getMessage());
diff --git a/entitlement/src/main/java/org/killbill/billing/entitlement/api/DefaultEntitlement.java b/entitlement/src/main/java/org/killbill/billing/entitlement/api/DefaultEntitlement.java
index 270db11..a93cdbb 100644
--- a/entitlement/src/main/java/org/killbill/billing/entitlement/api/DefaultEntitlement.java
+++ b/entitlement/src/main/java/org/killbill/billing/entitlement/api/DefaultEntitlement.java
@@ -25,6 +25,8 @@ import java.util.LinkedList;
 import java.util.List;
 import java.util.UUID;
 
+import javax.annotation.Nullable;
+
 import org.joda.time.DateTime;
 import org.joda.time.DateTimeZone;
 import org.joda.time.LocalDate;
@@ -289,7 +291,7 @@ public class DefaultEntitlement extends EntityBase implements Entitlement {
     }
 
     @Override
-    public Entitlement cancelEntitlementWithDate(final LocalDate localCancelDate, final boolean overrideBillingEffectiveDate, final Iterable<PluginProperty> properties, final CallContext callContext) throws EntitlementApiException {
+    public Entitlement cancelEntitlementWithDate(@Nullable final LocalDate localCancelDate, final boolean overrideBillingEffectiveDate, final Iterable<PluginProperty> properties, final CallContext callContext) throws EntitlementApiException {
 
         checkForPermissions(Permission.ENTITLEMENT_CAN_CANCEL, callContext);
 
@@ -399,7 +401,7 @@ public class DefaultEntitlement extends EntityBase implements Entitlement {
 
     // See also EntitlementInternalApi#cancel for the bulk API
     @Override
-    public Entitlement cancelEntitlementWithDateOverrideBillingPolicy(final LocalDate localCancelDate, final BillingActionPolicy billingPolicy, final Iterable<PluginProperty> properties, final CallContext callContext) throws EntitlementApiException {
+    public Entitlement cancelEntitlementWithDateOverrideBillingPolicy(@Nullable final LocalDate localCancelDate, final BillingActionPolicy billingPolicy, final Iterable<PluginProperty> properties, final CallContext callContext) throws EntitlementApiException {
 
         checkForPermissions(Permission.ENTITLEMENT_CAN_CANCEL, callContext);
 
@@ -533,7 +535,7 @@ public class DefaultEntitlement extends EntityBase implements Entitlement {
     }
 
     @Override
-    public Entitlement changePlanWithDate(final String productName, final BillingPeriod billingPeriod, final String priceList, final List<PlanPhasePriceOverride> overrides, final LocalDate localDate, final Iterable<PluginProperty> properties, final CallContext callContext) throws EntitlementApiException {
+    public Entitlement changePlanWithDate(final String productName, final BillingPeriod billingPeriod, final String priceList, final List<PlanPhasePriceOverride> overrides, @Nullable final LocalDate localDate, final Iterable<PluginProperty> properties, final CallContext callContext) throws EntitlementApiException {
 
         checkForPermissions(Permission.ENTITLEMENT_CAN_CHANGE_PLAN, callContext);
 
diff --git a/entitlement/src/main/java/org/killbill/billing/entitlement/api/DefaultEntitlementApi.java b/entitlement/src/main/java/org/killbill/billing/entitlement/api/DefaultEntitlementApi.java
index 1678364..67342e1 100644
--- a/entitlement/src/main/java/org/killbill/billing/entitlement/api/DefaultEntitlementApi.java
+++ b/entitlement/src/main/java/org/killbill/billing/entitlement/api/DefaultEntitlementApi.java
@@ -24,6 +24,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.UUID;
 
+import javax.annotation.Nullable;
 import javax.inject.Inject;
 
 import org.joda.time.DateTime;
@@ -111,11 +112,11 @@ public class DefaultEntitlementApi extends DefaultEntitlementApiBase implements 
         this.entitlementUtils = entitlementUtils;
         this.pluginExecution = pluginExecution;
         this.securityApi = securityApi;
-        this.dateHelper = new EntitlementDateHelper(accountApi, clock);
+        this.dateHelper = new EntitlementDateHelper(clock);
     }
 
     @Override
-    public Entitlement createBaseEntitlement(final UUID accountId, final PlanPhaseSpecifier planPhaseSpecifier, final String externalKey, final List<PlanPhasePriceOverride> overrides, final LocalDate effectiveDate, final Iterable<PluginProperty> properties, final CallContext callContext) throws EntitlementApiException {
+    public Entitlement createBaseEntitlement(final UUID accountId, final PlanPhaseSpecifier planPhaseSpecifier, final String externalKey, final List<PlanPhasePriceOverride> overrides, @Nullable final LocalDate effectiveDate, final Iterable<PluginProperty> properties, final CallContext callContext) throws EntitlementApiException {
 
         final EntitlementSpecifier entitlementSpecifier = new DefaultEntitlementSpecifier(planPhaseSpecifier, overrides);
         final List<EntitlementSpecifier> entitlementSpecifierList = new ArrayList<EntitlementSpecifier>();
@@ -166,7 +167,7 @@ public class DefaultEntitlementApi extends DefaultEntitlementApiBase implements 
 
     @Override
     public Entitlement createBaseEntitlementWithAddOns(final UUID accountId, final String externalKey, final Iterable<EntitlementSpecifier> entitlementSpecifiers,
-                                                       final LocalDate effectiveDate, final Iterable<PluginProperty> properties, final CallContext callContext)
+                                                       @Nullable final LocalDate effectiveDate, final Iterable<PluginProperty> properties, final CallContext callContext)
             throws EntitlementApiException {
 
         final EntitlementSpecifier baseSpecifier = Iterables.tryFind(entitlementSpecifiers, new Predicate<EntitlementSpecifier>() {
@@ -223,7 +224,7 @@ public class DefaultEntitlementApi extends DefaultEntitlementApiBase implements 
     }
 
     @Override
-    public Entitlement addEntitlement(final UUID bundleId, final PlanPhaseSpecifier planPhaseSpecifier, final List<PlanPhasePriceOverride> overrides, final LocalDate effectiveDate, final Iterable<PluginProperty> properties, final CallContext callContext) throws EntitlementApiException {
+    public Entitlement addEntitlement(final UUID bundleId, final PlanPhaseSpecifier planPhaseSpecifier, final List<PlanPhasePriceOverride> overrides, @Nullable final LocalDate effectiveDate, final Iterable<PluginProperty> properties, final CallContext callContext) throws EntitlementApiException {
 
         final EntitlementSpecifier entitlementSpecifier = new DefaultEntitlementSpecifier(planPhaseSpecifier, overrides);
         final List<EntitlementSpecifier> entitlementSpecifierList = new ArrayList<EntitlementSpecifier>();
@@ -272,7 +273,7 @@ public class DefaultEntitlementApi extends DefaultEntitlementApiBase implements 
     }
 
     @Override
-    public List<EntitlementAOStatusDryRun> getDryRunStatusForChange(final UUID bundleId, final String targetProductName, final LocalDate effectiveDate, final TenantContext context) throws EntitlementApiException {
+    public List<EntitlementAOStatusDryRun> getDryRunStatusForChange(final UUID bundleId, final String targetProductName, @Nullable final LocalDate effectiveDate, final TenantContext context) throws EntitlementApiException {
         final InternalTenantContext internalContext = internalCallContextFactory.createInternalTenantContext(bundleId, ObjectType.BUNDLE, context);
         try {
             final SubscriptionBaseBundle bundle = subscriptionBaseInternalApi.getBundleFromId(bundleId, internalContext);
@@ -375,7 +376,7 @@ public class DefaultEntitlementApi extends DefaultEntitlementApiBase implements 
     }
 
     @Override
-    public UUID transferEntitlementsOverrideBillingPolicy(final UUID sourceAccountId, final UUID destAccountId, final String externalKey, final LocalDate effectiveDate, final BillingActionPolicy billingPolicy, final Iterable<PluginProperty> properties, final CallContext context) throws EntitlementApiException {
+    public UUID transferEntitlementsOverrideBillingPolicy(final UUID sourceAccountId, final UUID destAccountId, final String externalKey, @Nullable final LocalDate effectiveDate, final BillingActionPolicy billingPolicy, final Iterable<PluginProperty> properties, final CallContext context) throws EntitlementApiException {
 
         final EntitlementContext pluginContext = new DefaultEntitlementContext(OperationType.TRANSFER_BUNDLE,
                                                                                sourceAccountId,
diff --git a/entitlement/src/main/java/org/killbill/billing/entitlement/api/DefaultEntitlementContext.java b/entitlement/src/main/java/org/killbill/billing/entitlement/api/DefaultEntitlementContext.java
index 79da30c..000c1a0 100644
--- a/entitlement/src/main/java/org/killbill/billing/entitlement/api/DefaultEntitlementContext.java
+++ b/entitlement/src/main/java/org/killbill/billing/entitlement/api/DefaultEntitlementContext.java
@@ -73,7 +73,7 @@ public class DefaultEntitlementContext implements EntitlementContext {
                                      final UUID bundleId,
                                      final String externalKey,
                                      final List<EntitlementSpecifier> entitlementSpecifiers,
-                                     final LocalDate effectiveDate,
+                                     @Nullable final LocalDate effectiveDate,
                                      final Iterable<PluginProperty> pluginProperties,
                                      final CallContext callContext) {
         this(operationType, accountId, destinationAccountId, bundleId, externalKey, entitlementSpecifiers, effectiveDate, pluginProperties,
@@ -88,7 +88,7 @@ public class DefaultEntitlementContext implements EntitlementContext {
                                      final UUID bundleId,
                                      final String externalKey,
                                      final List<EntitlementSpecifier> entitlementSpecifiers,
-                                     final LocalDate effectiveDate,
+                                     @Nullable final LocalDate effectiveDate,
                                      final Iterable<PluginProperty> pluginProperties,
                                      final UUID userToken,
                                      final String userName,
diff --git a/entitlement/src/main/java/org/killbill/billing/entitlement/api/EntitlementDateHelper.java b/entitlement/src/main/java/org/killbill/billing/entitlement/api/EntitlementDateHelper.java
index 7771ea7..9ab7b85 100644
--- a/entitlement/src/main/java/org/killbill/billing/entitlement/api/EntitlementDateHelper.java
+++ b/entitlement/src/main/java/org/killbill/billing/entitlement/api/EntitlementDateHelper.java
@@ -18,42 +18,25 @@
 
 package org.killbill.billing.entitlement.api;
 
+import javax.annotation.Nullable;
+
 import org.joda.time.DateTime;
 import org.joda.time.DateTimeZone;
-import org.joda.time.Interval;
 import org.joda.time.LocalDate;
-import org.killbill.billing.account.api.AccountApiException;
 import org.killbill.billing.account.api.AccountInternalApi;
-import org.killbill.billing.account.api.ImmutableAccountData;
 import org.killbill.billing.callcontext.InternalTenantContext;
 import org.killbill.clock.Clock;
 
 public class EntitlementDateHelper {
 
-    private final AccountInternalApi accountApi;
     private final Clock clock;
 
-    public EntitlementDateHelper(final AccountInternalApi accountApi, final Clock clock) {
-        this.accountApi = accountApi;
+    public EntitlementDateHelper(final Clock clock) {
         this.clock = clock;
     }
 
-    public DateTime fromLocalDateAndReferenceTime(final LocalDate requestedDate, final DateTime referenceDateTime, final InternalTenantContext callContext) throws EntitlementApiException {
-        final ImmutableAccountData account;
-
-        try {
-            account = accountApi.getImmutableAccountDataByRecordId(callContext.getAccountRecordId(), callContext);
-        } catch (final AccountApiException e) {
-            throw new EntitlementApiException(e);
-        }
-
-        // If the input date overlaps with the present, we return NOW.
-        final Interval interval = requestedDate.toInterval(account.getTimeZone());
-        if (interval.contains(clock.getUTCNow())) {
-            return clock.getUTCNow();
-        }
-
-        return callContext.toUTCDateTime(requestedDate, referenceDateTime);
+    public DateTime fromLocalDateAndReferenceTime(@Nullable final LocalDate requestedDate, final DateTime referenceDateTime, final InternalTenantContext callContext) throws EntitlementApiException {
+        return requestedDate == null ? clock.getUTCNow() : callContext.toUTCDateTime(requestedDate, referenceDateTime);
     }
 
     /**
diff --git a/entitlement/src/main/java/org/killbill/billing/entitlement/api/svcs/DefaultEntitlementApiBase.java b/entitlement/src/main/java/org/killbill/billing/entitlement/api/svcs/DefaultEntitlementApiBase.java
index fe2284f..1198f44 100644
--- a/entitlement/src/main/java/org/killbill/billing/entitlement/api/svcs/DefaultEntitlementApiBase.java
+++ b/entitlement/src/main/java/org/killbill/billing/entitlement/api/svcs/DefaultEntitlementApiBase.java
@@ -120,7 +120,7 @@ public class DefaultEntitlementApiBase {
         this.eventsStreamBuilder = eventsStreamBuilder;
         this.entitlementUtils = entitlementUtils;
         this.securityApi = securityApi;
-        this.dateHelper = new EntitlementDateHelper(accountApi, clock);
+        this.dateHelper = new EntitlementDateHelper(clock);
     }
 
     public AccountEntitlements getAllEntitlementsForAccountId(final UUID accountId, final InternalTenantContext tenantContext) throws EntitlementApiException {
@@ -150,7 +150,7 @@ public class DefaultEntitlementApiBase {
                                       entitlementUtils, dateHelper, clock, securityApi, tenantContext, internalCallContextFactory);
     }
 
-    public void pause(final UUID bundleId, final LocalDate localEffectiveDate, final Iterable<PluginProperty> properties, final InternalCallContext internalCallContext) throws EntitlementApiException {
+    public void pause(final UUID bundleId, @Nullable final LocalDate localEffectiveDate, final Iterable<PluginProperty> properties, final InternalCallContext internalCallContext) throws EntitlementApiException {
 
         final EntitlementContext pluginContext = new DefaultEntitlementContext(OperationType.PAUSE_SUBSCRIPTION,
                                                                                null,
@@ -203,7 +203,7 @@ public class DefaultEntitlementApiBase {
         pluginExecution.executeWithPlugin(pauseWithPlugin, pluginContext);
     }
 
-    public void resume(final UUID bundleId, final LocalDate localEffectiveDate, final Iterable<PluginProperty> properties, final InternalCallContext internalCallContext) throws EntitlementApiException {
+    public void resume(final UUID bundleId, @Nullable final LocalDate localEffectiveDate, final Iterable<PluginProperty> properties, final InternalCallContext internalCallContext) throws EntitlementApiException {
 
         final EntitlementContext pluginContext = new DefaultEntitlementContext(OperationType.RESUME_SUBSCRIPTION,
                                                                                null,
@@ -260,7 +260,7 @@ public class DefaultEntitlementApiBase {
         blockUnblockBundle(bundleId, stateName, serviceName, localEffectiveDate, blockBilling, blockEntitlement, blockChange, null, internalCallContext);
     }
 
-    private UUID blockUnblockBundle(final UUID bundleId, final String stateName, final String serviceName, final LocalDate localEffectiveDate, boolean blockBilling, boolean blockEntitlement, boolean blockChange, @Nullable final SubscriptionBase inputBaseSubscription, final InternalCallContext internalCallContext)
+    private UUID blockUnblockBundle(final UUID bundleId, final String stateName, final String serviceName, @Nullable final LocalDate localEffectiveDate, boolean blockBilling, boolean blockEntitlement, boolean blockChange, @Nullable final SubscriptionBase inputBaseSubscription, final InternalCallContext internalCallContext)
             throws EntitlementApiException {
         try {
             final SubscriptionBase baseSubscription = inputBaseSubscription == null ? subscriptionInternalApi.getBaseSubscription(bundleId, internalCallContext) : inputBaseSubscription;
diff --git a/entitlement/src/main/java/org/killbill/billing/entitlement/api/svcs/DefaultEntitlementInternalApi.java b/entitlement/src/main/java/org/killbill/billing/entitlement/api/svcs/DefaultEntitlementInternalApi.java
index fbb664c..8398dc9 100644
--- a/entitlement/src/main/java/org/killbill/billing/entitlement/api/svcs/DefaultEntitlementInternalApi.java
+++ b/entitlement/src/main/java/org/killbill/billing/entitlement/api/svcs/DefaultEntitlementInternalApi.java
@@ -28,6 +28,7 @@ import java.util.Map;
 import java.util.UUID;
 import java.util.concurrent.Callable;
 
+import javax.annotation.Nullable;
 import javax.inject.Inject;
 
 import org.joda.time.DateTime;
@@ -91,7 +92,7 @@ public class DefaultEntitlementInternalApi extends DefaultEntitlementApiBase imp
     }
 
     @Override
-    public void cancel(final Iterable<Entitlement> entitlements, final LocalDate effectiveDate, final BillingActionPolicy billingPolicy, final Iterable<PluginProperty> properties, final InternalCallContext internalCallContext) throws EntitlementApiException {
+    public void cancel(final Iterable<Entitlement> entitlements, @Nullable final LocalDate effectiveDate, final BillingActionPolicy billingPolicy, final Iterable<PluginProperty> properties, final InternalCallContext internalCallContext) throws EntitlementApiException {
         final CallContext callContext = internalCallContextFactory.createCallContext(internalCallContext);
 
         final ImmutableMap.Builder<BlockingState, Optional<UUID>> blockingStates = new ImmutableMap.Builder<BlockingState, Optional<UUID>>();
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 35baa6d..9a22d1d 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
@@ -43,7 +43,7 @@ public class TestEntitlementDateHelper extends EntitlementTestSuiteNoDB {
         account = Mockito.mock(Account.class);
         Mockito.when(accountInternalApi.getAccountByRecordId(Mockito.anyLong(), Mockito.<InternalTenantContext>any())).thenReturn(account);
         Mockito.when(accountInternalApi.getImmutableAccountDataByRecordId(Mockito.anyLong(), Mockito.<InternalTenantContext>any())).thenReturn(account);
-        dateHelper = new EntitlementDateHelper(accountInternalApi, clock);
+        dateHelper = new EntitlementDateHelper(clock);
         clock.resetDeltaFromReality();
     }
 
@@ -117,26 +117,6 @@ public class TestEntitlementDateHelper extends EntitlementTestSuiteNoDB {
     }
 
     @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);
-        internalCallContext.setReferenceDateTimeZone(account.getTimeZone());
-
-        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() {
 
         clock.setTime(new DateTime(2013, 8, 7, 3, 28, 10, 0, DateTimeZone.UTC));
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/SubscriptionResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/SubscriptionResource.java
index 48d2446..3cb4c9e 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/SubscriptionResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/SubscriptionResource.java
@@ -185,7 +185,7 @@ public class SubscriptionResource extends JaxRsResourceBase {
                                                                        ProductCategory.valueOf(entitlement.getProductCategory()),
                                                                        BillingPeriod.valueOf(entitlement.getBillingPeriod()), entitlement.getPriceList(), null);
 
-                final LocalDate inputLocalDate = toLocalDate(account, requestedDate, callContext);
+                final LocalDate inputLocalDate = requestedDate == null ? null : toLocalDate(account, requestedDate, callContext);
                 final PlanSpecifier planSpec = new PlanSpecifier(entitlement.getProductName(),
                                                                  ProductCategory.valueOf(entitlement.getProductCategory()),
                                                                  BillingPeriod.valueOf(entitlement.getBillingPeriod()), entitlement.getPriceList());