killbill-memoizeit
Changes
account/src/main/java/org/killbill/billing/account/api/svcs/DefaultAccountInternalApi.java 11(+7 -4)
api/src/main/java/org/killbill/billing/subscription/api/user/SubscriptionBaseApiException.java 7(+4 -3)
entitlement/src/main/java/org/killbill/billing/entitlement/api/svcs/DefaultEntitlementInternalApi.java 21(+3 -18)
entitlement/src/main/java/org/killbill/billing/entitlement/engine/core/DefaultEventsStream.java 7(+3 -4)
entitlement/src/main/java/org/killbill/billing/entitlement/engine/core/EventsStreamBuilder.java 22(+13 -9)
junction/src/main/java/org/killbill/billing/junction/plumbing/billing/DefaultInternalBillingApi.java 30(+24 -6)
junction/src/test/java/org/killbill/billing/junction/plumbing/billing/TestDefaultInternalBillingApi.java 15(+6 -9)
subscription/src/main/java/org/killbill/billing/subscription/api/SubscriptionBaseApiService.java 6(+2 -4)
subscription/src/main/java/org/killbill/billing/subscription/api/svcs/DefaultSubscriptionInternalApi.java 17(+1 -16)
subscription/src/main/java/org/killbill/billing/subscription/api/user/DefaultSubscriptionBase.java 5(+2 -3)
subscription/src/main/java/org/killbill/billing/subscription/api/user/DefaultSubscriptionBaseApiService.java 23(+17 -6)
subscription/src/test/java/org/killbill/billing/subscription/api/user/TestUserApiCancel.java 6(+3 -3)
Details
diff --git a/account/src/main/java/org/killbill/billing/account/api/svcs/DefaultAccountInternalApi.java b/account/src/main/java/org/killbill/billing/account/api/svcs/DefaultAccountInternalApi.java
index ba32fd5..44e8b4d 100644
--- a/account/src/main/java/org/killbill/billing/account/api/svcs/DefaultAccountInternalApi.java
+++ b/account/src/main/java/org/killbill/billing/account/api/svcs/DefaultAccountInternalApi.java
@@ -1,7 +1,7 @@
/*
* Copyright 2010-2013 Ning, Inc.
- * Copyright 2014-2017 Groupon, Inc
- * Copyright 2014-2017 The Billing Project, LLC
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 The Billing Project, LLC
*
* The Billing Project licenses this file to you under the Apache License, version 2.0
* (the "License"); you may not use this file except in compliance with the
@@ -49,6 +49,7 @@ import org.killbill.billing.util.cache.CacheLoaderArgument;
import org.killbill.billing.util.dao.NonEntityDao;
import com.google.common.base.Function;
+import com.google.common.base.Preconditions;
import com.google.common.collect.Collections2;
import com.google.common.collect.ImmutableList;
@@ -104,9 +105,11 @@ public class DefaultAccountInternalApi extends DefaultAccountApiBase implements
}
@Override
- public int getBCD(final UUID accountId, final InternalTenantContext context) throws AccountApiException {
+ public int getBCD(final InternalTenantContext context) throws AccountApiException {
final CacheLoaderArgument arg = createBCDCacheLoaderArgument(context);
- final Integer result = bcdCacheController.get(accountId, arg);
+ Preconditions.checkNotNull(context.getAccountRecordId(), "Context missing accountRecordId");
+ final ImmutableAccountData account = immutableAccountInternalApi.getImmutableAccountDataByRecordId(context.getAccountRecordId(), context);
+ final Integer result = bcdCacheController.get(account.getId(), arg);
return result != null ? result : DefaultMutableAccountData.DEFAULT_BILLING_CYCLE_DAY_LOCAL;
}
diff --git a/api/src/main/java/org/killbill/billing/account/api/AccountInternalApi.java b/api/src/main/java/org/killbill/billing/account/api/AccountInternalApi.java
index f935ae7..6907d07 100644
--- a/api/src/main/java/org/killbill/billing/account/api/AccountInternalApi.java
+++ b/api/src/main/java/org/killbill/billing/account/api/AccountInternalApi.java
@@ -1,7 +1,7 @@
/*
* Copyright 2010-2013 Ning, Inc.
- * Copyright 2014-2016 Groupon, Inc
- * Copyright 2014-2016 The Billing Project, LLC
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 The Billing Project, LLC
*
* The Billing Project licenses this file to you under the Apache License, version 2.0
* (the "License"); you may not use this file except in compliance with the
@@ -34,7 +34,7 @@ public interface AccountInternalApi extends ImmutableAccountInternalApi {
void updateBCD(String key, int bcd, InternalCallContext context) throws AccountApiException;
- int getBCD(UUID accountId, InternalTenantContext context) throws AccountApiException;
+ int getBCD(InternalTenantContext context) throws AccountApiException;
List<AccountEmail> getEmails(UUID accountId, InternalTenantContext context);
diff --git a/api/src/main/java/org/killbill/billing/entitlement/EventsStream.java b/api/src/main/java/org/killbill/billing/entitlement/EventsStream.java
index a62fc85..5305ac8 100644
--- a/api/src/main/java/org/killbill/billing/entitlement/EventsStream.java
+++ b/api/src/main/java/org/killbill/billing/entitlement/EventsStream.java
@@ -66,7 +66,7 @@ public interface EventsStream {
boolean isBlockEntitlement(final DateTime effectiveDate);
- int getDefaultBillCycleDayLocal();
+ Integer getDefaultBillCycleDayLocal();
Collection<BlockingState> getPendingEntitlementCancellationEvents();
diff --git a/api/src/main/java/org/killbill/billing/subscription/api/SubscriptionBase.java b/api/src/main/java/org/killbill/billing/subscription/api/SubscriptionBase.java
index a9f6125..a94da73 100644
--- a/api/src/main/java/org/killbill/billing/subscription/api/SubscriptionBase.java
+++ b/api/src/main/java/org/killbill/billing/subscription/api/SubscriptionBase.java
@@ -46,7 +46,7 @@ public interface SubscriptionBase extends Entity, Blockable {
public boolean cancelWithDate(final DateTime requestedDate, final CallContext context)
throws SubscriptionBaseApiException;
- public boolean cancelWithPolicy(final BillingActionPolicy policy, int accountBillCycleDayLocal, final CallContext context)
+ public boolean cancelWithPolicy(final BillingActionPolicy policy, final CallContext context)
throws SubscriptionBaseApiException;
public boolean uncancel(final CallContext context)
diff --git a/api/src/main/java/org/killbill/billing/subscription/api/SubscriptionBaseInternalApi.java b/api/src/main/java/org/killbill/billing/subscription/api/SubscriptionBaseInternalApi.java
index 4d8b6b9..562aa85 100644
--- a/api/src/main/java/org/killbill/billing/subscription/api/SubscriptionBaseInternalApi.java
+++ b/api/src/main/java/org/killbill/billing/subscription/api/SubscriptionBaseInternalApi.java
@@ -47,7 +47,7 @@ public interface SubscriptionBaseInternalApi {
boolean renameCancelledBundleIfExist,
InternalCallContext contextWithValidAccountRecordId) throws SubscriptionBaseApiException;
- public void cancelBaseSubscriptions(Iterable<SubscriptionBase> subscriptions, BillingActionPolicy policy, int accountBillCycleDayLocal, InternalCallContext context) throws SubscriptionBaseApiException;
+ public void cancelBaseSubscriptions(Iterable<SubscriptionBase> subscriptions, BillingActionPolicy policy, InternalCallContext context) throws SubscriptionBaseApiException;
//@VisibleForTesting
SubscriptionBaseBundle createBundleForAccount(UUID accountId, String bundleName, boolean renameCancelledBundleIfExist, InternalCallContext context)
@@ -94,8 +94,6 @@ public interface SubscriptionBaseInternalApi {
public void updateBCD(final UUID subscriptionId, final int bcd, @Nullable final LocalDate effectiveFromDate, final InternalCallContext internalCallContext) throws SubscriptionBaseApiException;
- public int getDefaultBillCycleDayLocal(final Map<UUID, Integer> bcdCache, final SubscriptionBase subscription, final SubscriptionBase baseSubscription, final PlanPhaseSpecifier planPhaseSpecifier, final int accountBillCycleDayLocal, final Catalog catalog, final InternalTenantContext context) throws SubscriptionBaseApiException;
-
public UUID getAccountIdFromBundleId(UUID bundleId, InternalTenantContext context) throws SubscriptionBaseApiException;
public UUID getBundleIdFromSubscriptionId(UUID entitlementId, InternalTenantContext context) throws SubscriptionBaseApiException;
diff --git a/api/src/main/java/org/killbill/billing/subscription/api/user/SubscriptionBaseApiException.java b/api/src/main/java/org/killbill/billing/subscription/api/user/SubscriptionBaseApiException.java
index 99e98b9..3f2126e 100644
--- a/api/src/main/java/org/killbill/billing/subscription/api/user/SubscriptionBaseApiException.java
+++ b/api/src/main/java/org/killbill/billing/subscription/api/user/SubscriptionBaseApiException.java
@@ -1,7 +1,9 @@
/*
* Copyright 2010-2013 Ning, Inc.
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 The Billing Project, LLC
*
- * Ning licenses this file to you under the Apache License, version 2.0
+ * The Billing Project licenses this file to you under the Apache License, version 2.0
* (the "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
*
@@ -18,13 +20,12 @@ package org.killbill.billing.subscription.api.user;
import org.killbill.billing.BillingExceptionBase;
import org.killbill.billing.ErrorCode;
-import org.killbill.billing.catalog.api.CatalogApiException;
public class SubscriptionBaseApiException extends BillingExceptionBase {
private static final long serialVersionUID = 19083233L;
- public SubscriptionBaseApiException(final CatalogApiException e) {
+ public SubscriptionBaseApiException(final BillingExceptionBase e) {
super(e, e.getCode(), 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 172c7cf..4e3200b 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
@@ -1,7 +1,7 @@
/*
* Copyright 2010-2013 Ning, Inc.
- * Copyright 2014-2017 Groupon, Inc
- * Copyright 2014-2017 The Billing Project, LLC
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 The Billing Project, LLC
*
* The Billing Project licenses this file to you under the Apache License, version 2.0
* (the "License"); you may not use this file except in compliance with the
@@ -36,14 +36,10 @@ import org.killbill.billing.catalog.api.BillingActionPolicy;
import org.killbill.billing.catalog.api.CatalogApiException;
import org.killbill.billing.catalog.api.Plan;
import org.killbill.billing.catalog.api.PlanPhase;
-import org.killbill.billing.catalog.api.PlanPhasePriceOverride;
-import org.killbill.billing.catalog.api.PlanPhaseSpecifier;
-import org.killbill.billing.catalog.api.PlanSpecifier;
import org.killbill.billing.catalog.api.PriceList;
import org.killbill.billing.catalog.api.Product;
import org.killbill.billing.catalog.api.ProductCategory;
import org.killbill.billing.entitlement.DefaultEntitlementService;
-import org.killbill.billing.entitlement.EntitlementService;
import org.killbill.billing.entitlement.EventsStream;
import org.killbill.billing.entitlement.api.EntitlementPluginExecution.WithEntitlementPlugin;
import org.killbill.billing.entitlement.block.BlockingChecker;
@@ -52,7 +48,6 @@ import org.killbill.billing.entitlement.engine.core.EntitlementNotificationKey;
import org.killbill.billing.entitlement.engine.core.EntitlementNotificationKeyAction;
import org.killbill.billing.entitlement.engine.core.EntitlementUtils;
import org.killbill.billing.entitlement.engine.core.EventsStreamBuilder;
-import org.killbill.billing.entitlement.logging.EntitlementLoggingHelper;
import org.killbill.billing.entitlement.plugin.api.EntitlementContext;
import org.killbill.billing.entitlement.plugin.api.OperationType;
import org.killbill.billing.entity.EntityBase;
@@ -498,7 +493,7 @@ public class DefaultEntitlement extends EntityBase implements Entitlement {
try {
// Cancel subscription base first, to correctly compute the add-ons entitlements we need to cancel (see below)
- getSubscriptionBase().cancelWithPolicy(billingPolicy, eventsStream.getDefaultBillCycleDayLocal(), callContext);
+ getSubscriptionBase().cancelWithPolicy(billingPolicy, callContext);
} catch (final SubscriptionBaseApiException e) {
throw new EntitlementApiException(e);
}
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 cf0128a..d5c9e39 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
@@ -1,7 +1,7 @@
/*
* Copyright 2010-2013 Ning, Inc.
- * Copyright 2014-2017 Groupon, Inc
- * Copyright 2014-2017 The Billing Project, LLC
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 The Billing Project, LLC
*
* The Billing Project licenses this file to you under the Apache License, version 2.0
* (the "License"); you may not use this file except in compliance with the
@@ -33,13 +33,11 @@ import javax.inject.Inject;
import org.joda.time.DateTime;
import org.joda.time.LocalDate;
-import org.killbill.billing.account.api.AccountApiException;
import org.killbill.billing.account.api.AccountInternalApi;
import org.killbill.billing.callcontext.InternalCallContext;
import org.killbill.billing.catalog.api.BillingActionPolicy;
import org.killbill.billing.entitlement.DefaultEntitlementService;
import org.killbill.billing.entitlement.EntitlementInternalApi;
-import org.killbill.billing.entitlement.EntitlementService;
import org.killbill.billing.entitlement.api.BaseEntitlementWithAddOnsSpecifier;
import org.killbill.billing.entitlement.api.BlockingState;
import org.killbill.billing.entitlement.api.BlockingStateType;
@@ -76,7 +74,6 @@ import org.killbill.notificationq.api.NotificationQueueService;
import org.killbill.notificationq.api.NotificationQueueService.NoSuchNotificationQueue;
import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableMap;
public class DefaultEntitlementInternalApi extends DefaultEntitlementApiBase implements EntitlementInternalApi {
@@ -102,14 +99,6 @@ public class DefaultEntitlementInternalApi extends DefaultEntitlementApiBase imp
return;
}
- int bcd;
- try {
- bcd = accountApi.getBCD(entitlements.iterator().next().getAccountId(), internalCallContext);
- } catch (final AccountApiException e) {
- throw new EntitlementApiException(e);
- }
- Preconditions.checkState(bcd > 0, "Unexpected condition where account info could not be retrieved");
-
final CallContext callContext = internalCallContextFactory.createCallContext(internalCallContext);
final ImmutableMap.Builder<BlockingState, Optional<UUID>> blockingStates = new ImmutableMap.Builder<BlockingState, Optional<UUID>>();
@@ -155,7 +144,6 @@ public class DefaultEntitlementInternalApi extends DefaultEntitlementApiBase imp
final Callable<Void> preCallbacksCallback = new BulkSubscriptionBaseCancellation(subscriptions,
billingPolicy,
- bcd,
internalCallContext);
pluginExecution.executeWithPlugin(preCallbacksCallback, callbacks, pluginContexts);
@@ -187,23 +175,20 @@ public class DefaultEntitlementInternalApi extends DefaultEntitlementApiBase imp
private final Iterable<SubscriptionBase> subscriptions;
private final BillingActionPolicy billingPolicy;
- private final int accountBillCycleDayLocal;
private final InternalCallContext callContext;
public BulkSubscriptionBaseCancellation(final Iterable<SubscriptionBase> subscriptions,
final BillingActionPolicy billingPolicy,
- final int accountBillCycleDayLocal,
final InternalCallContext callContext) {
this.subscriptions = subscriptions;
this.billingPolicy = billingPolicy;
- this.accountBillCycleDayLocal = accountBillCycleDayLocal;
this.callContext = callContext;
}
@Override
public Void call() throws Exception {
try {
- subscriptionInternalApi.cancelBaseSubscriptions(subscriptions, billingPolicy, accountBillCycleDayLocal, callContext);
+ subscriptionInternalApi.cancelBaseSubscriptions(subscriptions, billingPolicy, callContext);
} catch (final SubscriptionBaseApiException e) {
throw new EntitlementApiException(e);
}
diff --git a/entitlement/src/main/java/org/killbill/billing/entitlement/engine/core/DefaultEventsStream.java b/entitlement/src/main/java/org/killbill/billing/entitlement/engine/core/DefaultEventsStream.java
index daf7ff6..1caed00 100644
--- a/entitlement/src/main/java/org/killbill/billing/entitlement/engine/core/DefaultEventsStream.java
+++ b/entitlement/src/main/java/org/killbill/billing/entitlement/engine/core/DefaultEventsStream.java
@@ -33,7 +33,6 @@ import org.killbill.billing.callcontext.InternalTenantContext;
import org.killbill.billing.catalog.api.Plan;
import org.killbill.billing.catalog.api.Product;
import org.killbill.billing.catalog.api.ProductCategory;
-import org.killbill.billing.entitlement.EntitlementService;
import org.killbill.billing.entitlement.EventsStream;
import org.killbill.billing.entitlement.api.BlockingState;
import org.killbill.billing.entitlement.api.BlockingStateType;
@@ -72,7 +71,7 @@ public class DefaultEventsStream implements EventsStream {
private final InternalTenantContext internalTenantContext;
private final DateTime utcNow;
private final LocalDate utcToday;
- private final int defaultBillCycleDayLocal;
+ private final Integer defaultBillCycleDayLocal;
private BlockingAggregator currentStateBlockingAggregator;
private List<BlockingState> subscriptionEntitlementStates;
@@ -93,7 +92,7 @@ public class DefaultEventsStream implements EventsStream {
@Nullable final SubscriptionBase baseSubscription,
final SubscriptionBase subscription,
final Collection<SubscriptionBase> allSubscriptionsForBundle,
- final int defaultBillCycleDayLocal,
+ @Nullable final Integer defaultBillCycleDayLocal,
final InternalTenantContext contextWithValidAccountRecordId, final DateTime utcNow) {
sanityChecks(account, bundle, baseSubscription, subscription);
this.account = account;
@@ -234,7 +233,7 @@ public class DefaultEventsStream implements EventsStream {
}
@Override
- public int getDefaultBillCycleDayLocal() {
+ public Integer getDefaultBillCycleDayLocal() {
return defaultBillCycleDayLocal;
}
diff --git a/entitlement/src/main/java/org/killbill/billing/entitlement/engine/core/EventsStreamBuilder.java b/entitlement/src/main/java/org/killbill/billing/entitlement/engine/core/EventsStreamBuilder.java
index 6b1991b..9f72b61 100644
--- a/entitlement/src/main/java/org/killbill/billing/entitlement/engine/core/EventsStreamBuilder.java
+++ b/entitlement/src/main/java/org/killbill/billing/entitlement/engine/core/EventsStreamBuilder.java
@@ -36,6 +36,7 @@ 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.billing.catalog.api.BillingAlignment;
import org.killbill.billing.catalog.api.Catalog;
import org.killbill.billing.catalog.api.CatalogApiException;
import org.killbill.billing.catalog.api.CatalogInternalApi;
@@ -58,6 +59,7 @@ import org.killbill.billing.subscription.api.SubscriptionBaseInternalApi;
import org.killbill.billing.subscription.api.user.SubscriptionBaseApiException;
import org.killbill.billing.subscription.api.user.SubscriptionBaseBundle;
import org.killbill.billing.subscription.api.user.SubscriptionBaseTransition;
+import org.killbill.billing.util.bcd.BillCycleDayCalculator;
import org.killbill.billing.util.cache.CacheControllerDispatcher;
import org.killbill.billing.util.callcontext.InternalCallContextFactory;
import org.killbill.billing.util.callcontext.TenantContext;
@@ -149,7 +151,7 @@ public class EventsStreamBuilder {
final int accountBCD;
try {
account = accountInternalApi.getImmutableAccountDataByRecordId(internalTenantContext.getAccountRecordId(), internalTenantContext);
- accountBCD = accountInternalApi.getBCD(account.getId(), internalTenantContext);
+ accountBCD = accountInternalApi.getBCD(internalTenantContext);
} catch (final AccountApiException e) {
throw new EntitlementApiException(e);
}
@@ -276,7 +278,7 @@ public class EventsStreamBuilder {
final InternalTenantContext internalTenantContext) throws EntitlementApiException {
final int accountBCD;
try {
- accountBCD = accountInternalApi.getBCD(bundle.getAccountId(), internalTenantContext);
+ accountBCD = accountInternalApi.getBCD(internalTenantContext);
} catch (final AccountApiException e) {
throw new EntitlementApiException(e);
}
@@ -397,13 +399,15 @@ public class EventsStreamBuilder {
final InternalTenantContext internalTenantContext) throws EntitlementApiException {
try {
- final int defaultAlignmentDay = subscriptionInternalApi.getDefaultBillCycleDayLocal(bcdCache,
- subscription,
- baseSubscription,
- createPlanPhaseSpecifier(subscription),
- accountBCD,
- catalog,
- internalTenantContext);
+ Integer defaultAlignmentDay = null;
+ try {
+ final BillingAlignment alignment = catalog.billingAlignment(createPlanPhaseSpecifier(subscription), clock.getUTCNow(), subscription.getStartDate());
+ if (alignment != BillingAlignment.ACCOUNT || accountBCD != 0) {
+ defaultAlignmentDay = BillCycleDayCalculator.calculateBcdForAlignment(bcdCache, subscription, baseSubscription, alignment, internalTenantContext, accountBCD);
+ }
+ } catch (final CatalogApiException e) {
+ throw new SubscriptionBaseApiException(e);
+ }
return new DefaultEventsStream(account,
bundle,
blockingStates,
diff --git a/junction/src/main/java/org/killbill/billing/junction/plumbing/billing/DefaultInternalBillingApi.java b/junction/src/main/java/org/killbill/billing/junction/plumbing/billing/DefaultInternalBillingApi.java
index 5e5d811..42a2890 100644
--- a/junction/src/main/java/org/killbill/billing/junction/plumbing/billing/DefaultInternalBillingApi.java
+++ b/junction/src/main/java/org/killbill/billing/junction/plumbing/billing/DefaultInternalBillingApi.java
@@ -1,7 +1,7 @@
/*
* Copyright 2010-2013 Ning, Inc.
- * Copyright 2014-2016 Groupon, Inc
- * Copyright 2014-2016 The Billing Project, LLC
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 The Billing Project, LLC
*
* The Billing Project licenses this file to you under the Apache License, version 2.0
* (the "License"); you may not use this file except in compliance with the
@@ -29,7 +29,6 @@ import java.util.UUID;
import javax.annotation.Nullable;
-import org.joda.time.DateTime;
import org.killbill.billing.ObjectType;
import org.killbill.billing.account.api.AccountApiException;
import org.killbill.billing.account.api.AccountInternalApi;
@@ -143,7 +142,7 @@ public class DefaultInternalBillingApi implements BillingInternalApi {
final DefaultBillingEventSet result, final Set<UUID> skipSubscriptionsSet, final Catalog catalog, final List<Tag> tagsForAccount) throws AccountApiException, CatalogApiException, SubscriptionBaseApiException {
final boolean dryRunMode = dryRunArguments != null;
- final int currentAccountBCD = accountApi.getBCD(account.getId(), context);
+ final int currentAccountBCD = accountApi.getBCD(context);
// In dryRun mode, when we care about invoice generated for new BASE subscription, no such bundle exists yet; we still
// want to tap into subscriptionBase logic, so we make up a bundleId
@@ -189,7 +188,18 @@ public class DefaultInternalBillingApi implements BillingInternalApi {
BillingEvent oldestBillingEvent = null;
for (final BillingEvent event : result) {
- if (oldestBillingEvent == null || event.getEffectiveDate().compareTo(oldestBillingEvent.getEffectiveDate()) < 0) {
+ final BigDecimal recurringPrice = event.getRecurringPrice(event.getEffectiveDate());
+ final boolean hasRecurringPrice = recurringPrice != null; // Note: could be zero (BCD would still be set, by convention)
+ final boolean hasUsage = event.getUsages() != null && !event.getUsages().isEmpty();
+ if (!hasRecurringPrice &&
+ !hasUsage) {
+ // Nothing to bill, ignored for the purpose of BCD calculation
+ continue;
+ }
+
+ if (oldestBillingEvent == null ||
+ event.getEffectiveDate().compareTo(oldestBillingEvent.getEffectiveDate()) < 0 ||
+ (event.getEffectiveDate().compareTo(oldestBillingEvent.getEffectiveDate()) == 0 && event.getTotalOrdering().compareTo(oldestBillingEvent.getTotalOrdering()) < 0)) {
oldestBillingEvent = event;
}
}
@@ -203,6 +213,11 @@ public class DefaultInternalBillingApi implements BillingInternalApi {
if (accountBCDCandidate != 0) {
log.info("Setting account BCD='{}', accountId='{}'", accountBCDCandidate, account.getId());
accountApi.updateBCD(account.getExternalKey(), accountBCDCandidate, context);
+
+ // Because we now have computed the real BCD, we need to re-compute the BillingEvents BCD for ACCOUNT alignments (see BillCycleDayCalculator#calculateBcdForAlignment).
+ // The code could maybe be optimized (no need to re-run the full function?), but since it's run once per account, it's probably not worth it.
+ result.clear();
+ addBillingEventsForBundles(bundles, account, dryRunArguments, context, result, skipSubscriptionsSet, catalog, tagsForAccount);
}
}
}
@@ -248,7 +263,10 @@ public class DefaultInternalBillingApi implements BillingInternalApi {
private int calculateBcdForTransition(final Catalog catalog, final Map<UUID, Integer> bcdCache, final SubscriptionBase baseSubscription, final SubscriptionBase subscription, final int accountBillCycleDayLocal, final EffectiveSubscriptionInternalEvent transition, final InternalTenantContext internalTenantContext)
throws CatalogApiException {
- final BillingAlignment alignment = catalog.billingAlignment(getPlanPhaseSpecifierFromTransition(catalog, transition), transition.getEffectiveTransitionTime(), subscription.getStartDate());
+ BillingAlignment alignment = catalog.billingAlignment(getPlanPhaseSpecifierFromTransition(catalog, transition), transition.getEffectiveTransitionTime(), subscription.getStartDate());
+ if (alignment == BillingAlignment.ACCOUNT && accountBillCycleDayLocal == 0) {
+ alignment = BillingAlignment.SUBSCRIPTION;
+ }
return BillCycleDayCalculator.calculateBcdForAlignment(bcdCache, subscription, baseSubscription, alignment, internalTenantContext, accountBillCycleDayLocal);
}
diff --git a/junction/src/test/java/org/killbill/billing/junction/plumbing/billing/TestBillingApi.java b/junction/src/test/java/org/killbill/billing/junction/plumbing/billing/TestBillingApi.java
index f65d823..e6e6daf 100644
--- a/junction/src/test/java/org/killbill/billing/junction/plumbing/billing/TestBillingApi.java
+++ b/junction/src/test/java/org/killbill/billing/junction/plumbing/billing/TestBillingApi.java
@@ -40,7 +40,6 @@ import org.killbill.billing.catalog.api.InternationalPrice;
import org.killbill.billing.catalog.api.Plan;
import org.killbill.billing.catalog.api.PlanPhase;
import org.killbill.billing.catalog.api.PriceList;
-import org.killbill.billing.catalog.api.PriceListSet;
import org.killbill.billing.entitlement.api.BlockingState;
import org.killbill.billing.entitlement.api.BlockingStateType;
import org.killbill.billing.entitlement.api.Entitlement.EntitlementState;
@@ -285,7 +284,7 @@ public class TestBillingApi extends JunctionTestSuiteNoDB {
Mockito.when(account.getTimeZone()).thenReturn(DateTimeZone.UTC);
Mockito.when(accountInternalApi.getAccountById(Mockito.<UUID>any(), Mockito.<InternalTenantContext>any())).thenReturn(account);
Mockito.when(accountInternalApi.getImmutableAccountDataById(Mockito.<UUID>any(), Mockito.<InternalTenantContext>any())).thenReturn(account);
- Mockito.when(accountInternalApi.getBCD(Mockito.<UUID>any(), Mockito.<InternalTenantContext>any())).thenReturn(billCycleDay);
+ Mockito.when(accountInternalApi.getBCD(Mockito.<InternalTenantContext>any())).thenReturn(billCycleDay);
return account;
}
diff --git a/junction/src/test/java/org/killbill/billing/junction/plumbing/billing/TestDefaultInternalBillingApi.java b/junction/src/test/java/org/killbill/billing/junction/plumbing/billing/TestDefaultInternalBillingApi.java
index b4a01d1..106b185 100644
--- a/junction/src/test/java/org/killbill/billing/junction/plumbing/billing/TestDefaultInternalBillingApi.java
+++ b/junction/src/test/java/org/killbill/billing/junction/plumbing/billing/TestDefaultInternalBillingApi.java
@@ -76,7 +76,7 @@ public class TestDefaultInternalBillingApi extends JunctionTestSuiteWithEmbedded
final List<Entitlement> entitlements = entitlementApi.getAllEntitlementsForAccountId(account.getId(), callContext);
Assert.assertEquals(entitlements.size(), 1);
Assert.assertEquals(entitlements.get(0).getLastActiveProduct().getName(), "Cannon");
- Assert.assertEquals(entitlements.get(0).getBillCycleDayLocal(), (Integer) 7);
+ Assert.assertNull(entitlements.get(0).getBillCycleDayLocal());
// Account still has no BCD
final Account accountNoBCD = accountApi.getAccountById(account.getId(), callContext);
@@ -125,7 +125,7 @@ public class TestDefaultInternalBillingApi extends JunctionTestSuiteWithEmbedded
final List<Entitlement> entitlements = entitlementApi.getAllEntitlementsForAccountId(account.getId(), callContext);
Assert.assertEquals(entitlements.size(), 1);
Assert.assertEquals(entitlements.get(0).getLastActiveProduct().getName(), "Trebuchet");
- Assert.assertEquals(entitlements.get(0).getBillCycleDayLocal(), (Integer) 7);
+ Assert.assertNull(entitlements.get(0).getBillCycleDayLocal());
// Account still has no BCD
final Account accountNoBCD = accountApi.getAccountById(account.getId(), callContext);
@@ -175,9 +175,10 @@ public class TestDefaultInternalBillingApi extends JunctionTestSuiteWithEmbedded
final List<Entitlement> entitlements = entitlementApi.getAllEntitlementsForAccountId(account.getId(), callContext);
Assert.assertEquals(entitlements.size(), 2);
Assert.assertEquals(entitlements.get(0).getLastActiveProduct().getName(), "Shotgun");
- Assert.assertEquals(entitlements.get(0).getBillCycleDayLocal(), (Integer) 6);
+ // See bug description at https://github.com/killbill/killbill/issues/865 and PR discussion at https://github.com/killbill/killbill/pull/1067/files/926ca68c32c8f8c93bd5eda94fba17f6e19e593d#r237981095
+ Assert.assertNull(entitlements.get(0).getBillCycleDayLocal());
Assert.assertEquals(entitlements.get(1).getLastActiveProduct().getName(), "Cabinet");
- Assert.assertEquals(entitlements.get(1).getBillCycleDayLocal(), (Integer) 7);
+ Assert.assertNull(entitlements.get(1).getBillCycleDayLocal());
// Account still has no BCD
final Account accountNoBCD = accountApi.getAccountById(account.getId(), callContext);
@@ -186,11 +187,7 @@ public class TestDefaultInternalBillingApi extends JunctionTestSuiteWithEmbedded
List<BillingEvent> events = ImmutableList.<BillingEvent>copyOf(billingInternalApi.getBillingEventsForAccountAndUpdateAccountBCD(account.getId(), null, internalCallContext));
Assert.assertEquals(events.size(), 3);
for (final BillingEvent billingEvent : events) {
- if (billingEvent.getSubscription().getId().equals(entitlements.get(1).getId())) {
- Assert.assertEquals(billingEvent.getBillCycleDayLocal(), 7);
- } else {
- Assert.assertEquals(billingEvent.getBillCycleDayLocal(), 6);
- }
+ Assert.assertEquals(billingEvent.getBillCycleDayLocal(), 7);
}
// Verify BCD
diff --git a/subscription/src/main/java/org/killbill/billing/subscription/api/SubscriptionBaseApiService.java b/subscription/src/main/java/org/killbill/billing/subscription/api/SubscriptionBaseApiService.java
index 2b97be8..1ee196d 100644
--- a/subscription/src/main/java/org/killbill/billing/subscription/api/SubscriptionBaseApiService.java
+++ b/subscription/src/main/java/org/killbill/billing/subscription/api/SubscriptionBaseApiService.java
@@ -30,8 +30,6 @@ import org.killbill.billing.catalog.api.CatalogApiException;
import org.killbill.billing.catalog.api.PhaseType;
import org.killbill.billing.catalog.api.Plan;
import org.killbill.billing.catalog.api.PlanChangeResult;
-import org.killbill.billing.catalog.api.PlanPhasePriceOverride;
-import org.killbill.billing.catalog.api.PlanPhaseSpecifier;
import org.killbill.billing.catalog.api.PlanSpecifier;
import org.killbill.billing.entitlement.api.EntitlementSpecifier;
import org.killbill.billing.subscription.api.user.DefaultSubscriptionBase;
@@ -52,10 +50,10 @@ public interface SubscriptionBaseApiService {
public boolean cancelWithRequestedDate(DefaultSubscriptionBase subscription, DateTime requestedDate, CallContext context)
throws SubscriptionBaseApiException;
- public boolean cancelWithPolicy(DefaultSubscriptionBase subscription, BillingActionPolicy policy, int accountBillCycleDayLocal, CallContext context)
+ public boolean cancelWithPolicy(DefaultSubscriptionBase subscription, BillingActionPolicy policy, CallContext context)
throws SubscriptionBaseApiException;
- public boolean cancelWithPolicyNoValidationAndCatalog(Iterable<DefaultSubscriptionBase> subscriptions, BillingActionPolicy policy, int accountBillCycleDayLocal, Catalog catalog, InternalCallContext context)
+ public boolean cancelWithPolicyNoValidationAndCatalog(Iterable<DefaultSubscriptionBase> subscriptions, BillingActionPolicy policy, Catalog catalog, InternalCallContext context)
throws SubscriptionBaseApiException;
public boolean uncancel(DefaultSubscriptionBase subscription, CallContext context)
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 317f272..2680ba5 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
@@ -35,14 +35,11 @@ import org.killbill.billing.ErrorCode;
import org.killbill.billing.callcontext.InternalCallContext;
import org.killbill.billing.callcontext.InternalTenantContext;
import org.killbill.billing.catalog.api.BillingActionPolicy;
-import org.killbill.billing.catalog.api.BillingAlignment;
import org.killbill.billing.catalog.api.Catalog;
import org.killbill.billing.catalog.api.CatalogApiException;
import org.killbill.billing.catalog.api.CatalogInternalApi;
import org.killbill.billing.catalog.api.Plan;
-import org.killbill.billing.catalog.api.PlanPhasePriceOverride;
import org.killbill.billing.catalog.api.PlanPhasePriceOverridesWithCallContext;
-import org.killbill.billing.catalog.api.PlanPhaseSpecifier;
import org.killbill.billing.catalog.api.Product;
import org.killbill.billing.catalog.api.ProductCategory;
import org.killbill.billing.entitlement.api.Entitlement.EntitlementState;
@@ -71,7 +68,6 @@ import org.killbill.billing.subscription.engine.dao.model.SubscriptionBundleMode
import org.killbill.billing.subscription.events.SubscriptionBaseEvent;
import org.killbill.billing.subscription.events.bcd.BCDEvent;
import org.killbill.billing.subscription.events.bcd.BCDEventData;
-import org.killbill.billing.util.bcd.BillCycleDayCalculator;
import org.killbill.billing.util.cache.AccountIdFromBundleIdCacheLoader;
import org.killbill.billing.util.cache.BundleIdFromSubscriptionIdCacheLoader;
import org.killbill.billing.util.cache.Cachable.CacheType;
@@ -158,7 +154,7 @@ public class DefaultSubscriptionInternalApi extends DefaultSubscriptionBaseCreat
}
@Override
- public void cancelBaseSubscriptions(final Iterable<SubscriptionBase> subscriptions, final BillingActionPolicy policy, int accountBillCycleDayLocal, final InternalCallContext context) throws SubscriptionBaseApiException {
+ public void cancelBaseSubscriptions(final Iterable<SubscriptionBase> subscriptions, final BillingActionPolicy policy, final InternalCallContext context) throws SubscriptionBaseApiException {
try {
final Catalog catalog = catalogInternalApi.getFullCatalog(true, true, context);
@@ -174,7 +170,6 @@ public class DefaultSubscriptionInternalApi extends DefaultSubscriptionBaseCreat
}
}),
policy,
- accountBillCycleDayLocal,
catalog,
context);
} catch (CatalogApiException e) {
@@ -458,16 +453,6 @@ public class DefaultSubscriptionInternalApi extends DefaultSubscriptionBaseCreat
}
@Override
- public int getDefaultBillCycleDayLocal(final Map<UUID, Integer> bcdCache, final SubscriptionBase subscription, final SubscriptionBase baseSubscription, final PlanPhaseSpecifier planPhaseSpecifier, final int accountBillCycleDayLocal, final Catalog catalog, final InternalTenantContext context) throws SubscriptionBaseApiException {
- try {
- final BillingAlignment alignment = catalog.billingAlignment(planPhaseSpecifier, clock.getUTCNow(), subscription.getStartDate());
- return BillCycleDayCalculator.calculateBcdForAlignment(bcdCache, subscription, baseSubscription, alignment, context, accountBillCycleDayLocal);
- } catch (final CatalogApiException e) {
- throw new SubscriptionBaseApiException(e);
- }
- }
-
- @Override
public UUID getAccountIdFromBundleId(final UUID bundleId, final InternalTenantContext context) throws SubscriptionBaseApiException {
final CacheLoaderArgument arg = createAccountIdFromBundleIdCacheLoaderArgument(context);
return accountIdCacheController.get(bundleId, arg);
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 da5ae17..fc09a99 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
@@ -39,7 +39,6 @@ import org.killbill.billing.catalog.api.CatalogApiException;
import org.killbill.billing.catalog.api.PhaseType;
import org.killbill.billing.catalog.api.Plan;
import org.killbill.billing.catalog.api.PlanPhase;
-import org.killbill.billing.catalog.api.PlanPhasePriceOverride;
import org.killbill.billing.catalog.api.PriceList;
import org.killbill.billing.catalog.api.Product;
import org.killbill.billing.catalog.api.ProductCategory;
@@ -262,8 +261,8 @@ public class DefaultSubscriptionBase extends EntityBase implements SubscriptionB
}
@Override
- public boolean cancelWithPolicy(final BillingActionPolicy policy, final int accountBillCycleDayLocal, final CallContext context) throws SubscriptionBaseApiException {
- return apiService.cancelWithPolicy(this, policy, accountBillCycleDayLocal, context);
+ public boolean cancelWithPolicy(final BillingActionPolicy policy, final CallContext context) throws SubscriptionBaseApiException {
+ return apiService.cancelWithPolicy(this, policy, context);
}
@Override
diff --git a/subscription/src/main/java/org/killbill/billing/subscription/api/user/DefaultSubscriptionBaseApiService.java b/subscription/src/main/java/org/killbill/billing/subscription/api/user/DefaultSubscriptionBaseApiService.java
index ac01a59..ff95732 100644
--- a/subscription/src/main/java/org/killbill/billing/subscription/api/user/DefaultSubscriptionBaseApiService.java
+++ b/subscription/src/main/java/org/killbill/billing/subscription/api/user/DefaultSubscriptionBaseApiService.java
@@ -32,6 +32,8 @@ import org.joda.time.DateTime;
import org.joda.time.ReadableInstant;
import org.killbill.billing.ErrorCode;
import org.killbill.billing.ObjectType;
+import org.killbill.billing.account.api.AccountApiException;
+import org.killbill.billing.account.api.AccountInternalApi;
import org.killbill.billing.callcontext.InternalCallContext;
import org.killbill.billing.callcontext.InternalTenantContext;
import org.killbill.billing.catalog.api.BillingActionPolicy;
@@ -87,16 +89,22 @@ public class DefaultSubscriptionBaseApiService implements SubscriptionBaseApiSer
private final Clock clock;
private final SubscriptionDao dao;
+ private final AccountInternalApi accountInternalApi;
private final CatalogInternalApi catalogInternalApi;
private final PlanAligner planAligner;
private final AddonUtils addonUtils;
private final InternalCallContextFactory internalCallContextFactory;
@Inject
- public DefaultSubscriptionBaseApiService(final Clock clock, final SubscriptionDao dao, final CatalogInternalApi catalogInternalApi,
- final PlanAligner planAligner, final AddonUtils addonUtils,
+ public DefaultSubscriptionBaseApiService(final Clock clock,
+ final SubscriptionDao dao,
+ final AccountInternalApi accountInternalApi,
+ final CatalogInternalApi catalogInternalApi,
+ final PlanAligner planAligner,
+ final AddonUtils addonUtils,
final InternalCallContextFactory internalCallContextFactory) {
this.clock = clock;
+ this.accountInternalApi = accountInternalApi;
this.catalogInternalApi = catalogInternalApi;
this.planAligner = planAligner;
this.dao = dao;
@@ -207,7 +215,7 @@ public class DefaultSubscriptionBaseApiService implements SubscriptionBaseApiSer
}
@Override
- public boolean cancelWithPolicy(final DefaultSubscriptionBase subscription, final BillingActionPolicy policy, int accountBillCycleDayLocal, final CallContext context) throws SubscriptionBaseApiException {
+ public boolean cancelWithPolicy(final DefaultSubscriptionBase subscription, final BillingActionPolicy policy, final CallContext context) throws SubscriptionBaseApiException {
final EntitlementState currentState = subscription.getState();
if (currentState == EntitlementState.CANCELLED) {
throw new SubscriptionBaseApiException(ErrorCode.SUB_CANCEL_BAD_STATE, subscription.getId(), currentState);
@@ -217,14 +225,14 @@ public class DefaultSubscriptionBaseApiService implements SubscriptionBaseApiSer
final Catalog fullCatalog;
try {
fullCatalog = catalogInternalApi.getFullCatalog(true, true, internalCallContext);
- return cancelWithPolicyNoValidationAndCatalog(ImmutableList.<DefaultSubscriptionBase>of(subscription), policy, accountBillCycleDayLocal, fullCatalog, internalCallContext);
- } catch (CatalogApiException e) {
+ return cancelWithPolicyNoValidationAndCatalog(ImmutableList.<DefaultSubscriptionBase>of(subscription), policy, fullCatalog, internalCallContext);
+ } catch (final CatalogApiException e) {
throw new SubscriptionBaseApiException(e);
}
}
@Override
- public boolean cancelWithPolicyNoValidationAndCatalog(final Iterable<DefaultSubscriptionBase> subscriptions, final BillingActionPolicy policy, final int accountBillCycleDayLocal, final Catalog catalog, final InternalCallContext context) throws SubscriptionBaseApiException {
+ public boolean cancelWithPolicyNoValidationAndCatalog(final Iterable<DefaultSubscriptionBase> subscriptions, final BillingActionPolicy policy, final Catalog catalog, final InternalCallContext context) throws SubscriptionBaseApiException {
final Map<DefaultSubscriptionBase, DateTime> subscriptionsWithEffectiveDate = new HashMap<DefaultSubscriptionBase, DateTime>();
try {
@@ -232,12 +240,15 @@ public class DefaultSubscriptionBaseApiService implements SubscriptionBaseApiSer
final BillingAlignment billingAlignment = (subscription.getState() == EntitlementState.PENDING ? null : catalog.billingAlignment(new PlanPhaseSpecifier(subscription.getLastActivePlan().getName(), subscription.getLastActivePhase().getPhaseType()),
clock.getUTCNow(),
subscription.getStartDate()));
+ final Integer accountBillCycleDayLocal = accountInternalApi.getBCD(context);
final DateTime effectiveDate = subscription.getPlanChangeEffectiveDate(policy, billingAlignment, accountBillCycleDayLocal, context);
subscriptionsWithEffectiveDate.put(subscription, effectiveDate);
}
return doCancelPlan(subscriptionsWithEffectiveDate, catalog, context);
} catch (final CatalogApiException e) {
throw new SubscriptionBaseApiException(e);
+ } catch (final AccountApiException e) {
+ throw new SubscriptionBaseApiException(e);
}
}
diff --git a/subscription/src/test/java/org/killbill/billing/subscription/api/user/TestUserApiCancel.java b/subscription/src/test/java/org/killbill/billing/subscription/api/user/TestUserApiCancel.java
index b32981b..f1e5f39 100644
--- a/subscription/src/test/java/org/killbill/billing/subscription/api/user/TestUserApiCancel.java
+++ b/subscription/src/test/java/org/killbill/billing/subscription/api/user/TestUserApiCancel.java
@@ -383,7 +383,7 @@ public class TestUserApiCancel extends SubscriptionTestSuiteWithEmbeddedDB {
// Move ahead a bit abd cancel START_OF_TERM
clock.addDays(5);
testListener.pushExpectedEvent(NextEvent.CANCEL);
- subscription.cancelWithPolicy(BillingActionPolicy.START_OF_TERM, accountData.getBillCycleDayLocal(), callContext);
+ subscription.cancelWithPolicy(BillingActionPolicy.START_OF_TERM, callContext);
assertListenerStatus();
subscription = (DefaultSubscriptionBase) subscriptionInternalApi.getSubscriptionFromId(subscription.getId(), internalCallContext);
@@ -408,7 +408,7 @@ public class TestUserApiCancel extends SubscriptionTestSuiteWithEmbeddedDB {
// Cancel / Uncancel a few times to make sure this works and we end up on a stable state
for (int i = 0; i < 3; i++) {
- subscription.cancelWithPolicy(BillingActionPolicy.IMMEDIATE, -1, callContext);
+ subscription.cancelWithPolicy(BillingActionPolicy.IMMEDIATE, callContext);
subscription = (DefaultSubscriptionBase) subscriptionInternalApi.getSubscriptionFromId(subscription.getId(), internalCallContext);
assertEquals(subscription.getState(), EntitlementState.PENDING);
@@ -512,7 +512,7 @@ public class TestUserApiCancel extends SubscriptionTestSuiteWithEmbeddedDB {
assertEquals(subscription.getState(), Entitlement.EntitlementState.PENDING);
assertEquals(subscription.getStartDate().compareTo(startDate.toDateTime(accountData.getReferenceTime())), 0);
- subscription.cancelWithPolicy(BillingActionPolicy.IMMEDIATE, 1, callContext);
+ subscription.cancelWithPolicy(BillingActionPolicy.IMMEDIATE, callContext);
testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.CANCEL);
clock.addDays(5);
diff --git a/subscription/src/test/java/org/killbill/billing/subscription/api/user/TestUserApiError.java b/subscription/src/test/java/org/killbill/billing/subscription/api/user/TestUserApiError.java
index 8b97f5d..96e7726 100644
--- a/subscription/src/test/java/org/killbill/billing/subscription/api/user/TestUserApiError.java
+++ b/subscription/src/test/java/org/killbill/billing/subscription/api/user/TestUserApiError.java
@@ -146,7 +146,7 @@ public class TestUserApiError extends SubscriptionTestSuiteNoDB {
subscription = subscriptionInternalApi.getSubscriptionFromId(subscription.getId(), internalCallContext);
- subscription.cancelWithPolicy(BillingActionPolicy.END_OF_TERM, -1, callContext);
+ subscription.cancelWithPolicy(BillingActionPolicy.END_OF_TERM, callContext);
try {
final PlanPhaseSpecifier planPhaseSpecifier = new PlanPhaseSpecifier("Pistol", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME);
subscription.changePlanWithDate(new DefaultEntitlementSpecifier(planPhaseSpecifier), clock.getUTCNow(), callContext);
diff --git a/util/src/main/java/org/killbill/billing/util/bcd/BillCycleDayCalculator.java b/util/src/main/java/org/killbill/billing/util/bcd/BillCycleDayCalculator.java
index d53a0a9..59e00d7 100644
--- a/util/src/main/java/org/killbill/billing/util/bcd/BillCycleDayCalculator.java
+++ b/util/src/main/java/org/killbill/billing/util/bcd/BillCycleDayCalculator.java
@@ -1,6 +1,6 @@
/*
- * Copyright 2014-2017 Groupon, Inc
- * Copyright 2014-2017 The Billing Project, LLC
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 The Billing Project, LLC
*
* The Billing Project licenses this file to you under the Apache License, version 2.0
* (the "License"); you may not use this file except in compliance with the
@@ -31,6 +31,8 @@ import org.killbill.billing.subscription.api.SubscriptionBase;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import com.google.common.base.Preconditions;
+
public abstract class BillCycleDayCalculator {
private static final Logger log = LoggerFactory.getLogger(BillCycleDayCalculator.class);
@@ -39,7 +41,8 @@ public abstract class BillCycleDayCalculator {
int result = 0;
switch (alignment) {
case ACCOUNT:
- result = accountBillCycleDayLocal != 0 ? accountBillCycleDayLocal : calculateOrRetrieveBcdFromSubscription(bcdCache, subscription, internalTenantContext);
+ Preconditions.checkState(accountBillCycleDayLocal != 0, "Account BCD should be set at this point");
+ result = accountBillCycleDayLocal;
break;
case BUNDLE:
result = calculateOrRetrieveBcdFromSubscription(bcdCache, baseSubscription, internalTenantContext);
diff --git a/util/src/test/java/org/killbill/billing/mock/MockSubscription.java b/util/src/test/java/org/killbill/billing/mock/MockSubscription.java
index f686884..3017228 100644
--- a/util/src/test/java/org/killbill/billing/mock/MockSubscription.java
+++ b/util/src/test/java/org/killbill/billing/mock/MockSubscription.java
@@ -26,8 +26,6 @@ import org.killbill.billing.catalog.api.BillingActionPolicy;
import org.killbill.billing.catalog.api.BillingPeriod;
import org.killbill.billing.catalog.api.Plan;
import org.killbill.billing.catalog.api.PlanPhase;
-import org.killbill.billing.catalog.api.PlanPhasePriceOverride;
-import org.killbill.billing.catalog.api.PlanPhaseSpecifier;
import org.killbill.billing.catalog.api.PriceList;
import org.killbill.billing.catalog.api.Product;
import org.killbill.billing.catalog.api.ProductCategory;
@@ -73,9 +71,9 @@ public class MockSubscription implements SubscriptionBase {
}
@Override
- public boolean cancelWithPolicy(BillingActionPolicy policy, int accountBillCycleDayLocal, CallContext context)
+ public boolean cancelWithPolicy(final BillingActionPolicy policy, final CallContext context)
throws SubscriptionBaseApiException {
- return sub.cancelWithPolicy(policy, accountBillCycleDayLocal, context);
+ return sub.cancelWithPolicy(policy, context);
}
@Override