killbill-memoizeit
Changes
beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestWithEntilementPlugin.java 28(+17 -11)
entitlement/src/main/java/org/killbill/billing/entitlement/api/DefaultBaseEntitlementWithAddOnsSpecifier.java 75(+75 -0)
entitlement/src/main/java/org/killbill/billing/entitlement/api/DefaultEntitlementApi.java 151(+114 -37)
entitlement/src/main/java/org/killbill/billing/entitlement/api/DefaultEntitlementContext.java 58(+8 -50)
entitlement/src/main/java/org/killbill/billing/entitlement/api/DefaultSubscriptionApi.java 31(+21 -10)
entitlement/src/main/java/org/killbill/billing/entitlement/api/svcs/DefaultEntitlementApiBase.java 32(+23 -9)
entitlement/src/main/java/org/killbill/billing/entitlement/api/svcs/DefaultEntitlementInternalApi.java 20(+14 -6)
entitlement/src/main/java/org/killbill/billing/entitlement/logging/EntitlementLoggingHelper.java 18(+17 -1)
jaxrs/src/main/java/org/killbill/billing/jaxrs/json/BulkBaseSubscriptionAndAddOnsJson.java 68(+68 -0)
pom.xml 2(+1 -1)
subscription/src/main/java/org/killbill/billing/subscription/api/SubscriptionBaseApiService.java 4(+4 -0)
subscription/src/main/java/org/killbill/billing/subscription/api/svcs/DefaultSubscriptionInternalApi.java 95(+95 -0)
subscription/src/main/java/org/killbill/billing/subscription/api/user/DefaultSubscriptionBaseApiService.java 55(+55 -0)
subscription/src/main/java/org/killbill/billing/subscription/api/user/SubscriptionAndAddOnsSpecifier.java 39(+39 -0)
subscription/src/main/java/org/killbill/billing/subscription/engine/dao/DefaultSubscriptionDao.java 53(+38 -15)
Details
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 fada42e..f4427c1 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
@@ -30,11 +30,11 @@ import org.joda.time.LocalDate;
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.BillingPeriod;
import org.killbill.billing.catalog.api.CatalogApiException;
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.BaseEntitlementWithAddOnsSpecifier;
import org.killbill.billing.entitlement.api.EntitlementAOStatusDryRun;
import org.killbill.billing.entitlement.api.EntitlementSpecifier;
import org.killbill.billing.events.EffectiveSubscriptionInternalEvent;
@@ -52,6 +52,9 @@ public interface SubscriptionBaseInternalApi {
public List<SubscriptionBase> createBaseSubscriptionWithAddOns(UUID bundleId, Iterable<EntitlementSpecifier> entitlements, DateTime requestedDateWithMs,
final boolean isMigrated, InternalCallContext context) throws SubscriptionBaseApiException;
+ public List<SubscriptionBase> createBaseSubscriptionsWithAddOns(UUID accountId, Iterable<BaseEntitlementWithAddOnsSpecifier> baseEntitlementWithAddOnsSpecifier,
+ InternalCallContext contextWithValidAccountRecordId) throws SubscriptionBaseApiException;
+
public void cancelBaseSubscriptions(Iterable<SubscriptionBase> subscriptions, BillingActionPolicy policy, InternalCallContext context) throws SubscriptionBaseApiException;
public SubscriptionBaseBundle createBundleForAccount(UUID accountId, String bundleName, InternalCallContext context)
diff --git a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestWithEntilementPlugin.java b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestWithEntilementPlugin.java
index e6f7499..862c735 100644
--- a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestWithEntilementPlugin.java
+++ b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestWithEntilementPlugin.java
@@ -34,6 +34,8 @@ import org.killbill.billing.catalog.api.BillingPeriod;
import org.killbill.billing.catalog.api.PlanPhasePriceOverride;
import org.killbill.billing.catalog.api.PlanPhaseSpecifier;
import org.killbill.billing.catalog.api.ProductCategory;
+import org.killbill.billing.entitlement.api.BaseEntitlementWithAddOnsSpecifier;
+import org.killbill.billing.entitlement.api.DefaultBaseEntitlementWithAddOnsSpecifier;
import org.killbill.billing.entitlement.api.DefaultEntitlement;
import org.killbill.billing.entitlement.api.DefaultEntitlementSpecifier;
import org.killbill.billing.entitlement.api.EntitlementSpecifier;
@@ -136,30 +138,34 @@ public class TestWithEntilementPlugin extends TestIntegrationBase {
@Override
public PriorEntitlementResult priorCall(final EntitlementContext entitlementContext, final Iterable<PluginProperty> properties) throws EntitlementPluginApiException {
if (planPhasePriceOverride != null) {
- final EntitlementSpecifier entitlementSpecifier = new DefaultEntitlementSpecifier(entitlementContext.getEntitlementSpecifiers().get(0).getPlanPhaseSpecifier(), planPhasePriceOverride);
+ final EntitlementSpecifier entitlementSpecifier = new DefaultEntitlementSpecifier(entitlementContext.getBaseEntitlementWithAddOnsSpecifiers().get(0).getEntitlementSpecifier().iterator().next().getPlanPhaseSpecifier(), planPhasePriceOverride);
final List<EntitlementSpecifier> entitlementSpecifiers = new ArrayList<EntitlementSpecifier>();
entitlementSpecifiers.add(entitlementSpecifier);
+ final BaseEntitlementWithAddOnsSpecifier baseEntitlementWithAddOnsSpecifier =
+ new DefaultBaseEntitlementWithAddOnsSpecifier(
+ entitlementContext.getBaseEntitlementWithAddOnsSpecifiers().get(0).getBundleId(),
+ entitlementContext.getBaseEntitlementWithAddOnsSpecifiers().get(0).getExternalKey(),
+ entitlementSpecifiers,
+ entitlementContext.getBaseEntitlementWithAddOnsSpecifiers().get(0).getEntitlementEffectiveDate(),
+ entitlementContext.getBaseEntitlementWithAddOnsSpecifiers().get(0).getBillingEffectiveDate(),
+ entitlementContext.getBaseEntitlementWithAddOnsSpecifiers().get(0).isMigrated()
+ );
+ final List<BaseEntitlementWithAddOnsSpecifier> baseEntitlementWithAddOnsSpecifiersList = new ArrayList<BaseEntitlementWithAddOnsSpecifier>();
+ baseEntitlementWithAddOnsSpecifiersList.add(baseEntitlementWithAddOnsSpecifier);
+
return new PriorEntitlementResult() {
@Override
public boolean isAborted() {
return false;
}
@Override
- public LocalDate getAdjustedEntitlementEffectiveDate() {
- return null;
- }
- @Override
- public LocalDate getAdjustedBillingEffectiveDate() {
- return null;
- }
- @Override
public BillingActionPolicy getAdjustedBillingActionPolicy() {
return null;
}
@Override
- public List<EntitlementSpecifier> getAdjustedEntitlementSpecifiers() {
- return entitlementSpecifiers;
+ public List<BaseEntitlementWithAddOnsSpecifier> getAdjustedBaseEntitlementWithAddOnsSpecifiers() {
+ return baseEntitlementWithAddOnsSpecifiersList;
}
@Override
public Iterable<PluginProperty> getAdjustedPluginProperties() {
diff --git a/entitlement/src/main/java/org/killbill/billing/entitlement/api/DefaultBaseEntitlementWithAddOnsSpecifier.java b/entitlement/src/main/java/org/killbill/billing/entitlement/api/DefaultBaseEntitlementWithAddOnsSpecifier.java
new file mode 100644
index 0000000..265d0b9
--- /dev/null
+++ b/entitlement/src/main/java/org/killbill/billing/entitlement/api/DefaultBaseEntitlementWithAddOnsSpecifier.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2016 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
+ * License. You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.killbill.billing.entitlement.api;
+
+import java.util.UUID;
+
+import org.joda.time.LocalDate;
+
+public class DefaultBaseEntitlementWithAddOnsSpecifier implements BaseEntitlementWithAddOnsSpecifier {
+
+ private final UUID bundleId;
+ private final String externalKey;
+ private final Iterable<EntitlementSpecifier> entitlementSpecifier;
+ private final LocalDate entitlementEffectiveDate;
+ private final LocalDate billingEffectiveDate;
+ private final boolean isMigrated;
+
+ public DefaultBaseEntitlementWithAddOnsSpecifier(final UUID bundleId,
+ final String externalKey,
+ final Iterable<EntitlementSpecifier> entitlementSpecifier,
+ final LocalDate entitlementEffectiveDate,
+ final LocalDate billingEffectiveDate,
+ final boolean isMigrated) {
+ this.bundleId = bundleId;
+ this.externalKey = externalKey;
+ this.entitlementSpecifier = entitlementSpecifier;
+ this.entitlementEffectiveDate = entitlementEffectiveDate;
+ this.billingEffectiveDate = billingEffectiveDate;
+ this.isMigrated = isMigrated;
+ }
+
+ @Override
+ public UUID getBundleId() {
+ return bundleId;
+ }
+
+ @Override
+ public String getExternalKey() {
+ return externalKey;
+ }
+
+ @Override
+ public Iterable<EntitlementSpecifier> getEntitlementSpecifier() {
+ return entitlementSpecifier;
+ }
+
+ @Override
+ public LocalDate getEntitlementEffectiveDate() {
+ return entitlementEffectiveDate;
+ }
+
+ @Override
+ public LocalDate getBillingEffectiveDate() {
+ return billingEffectiveDate;
+ }
+
+ @Override
+ public boolean isMigrated() {
+ return isMigrated;
+ }
+}
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 1f84737..cdc77ad 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
@@ -34,7 +34,6 @@ 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.BillingPeriod;
import org.killbill.billing.catalog.api.CatalogApiException;
import org.killbill.billing.catalog.api.Plan;
import org.killbill.billing.catalog.api.PlanPhase;
@@ -322,14 +321,19 @@ public class DefaultEntitlement extends EntityBase implements Entitlement {
}
final LocalDate billingEffectiveDate = overrideBillingEffectiveDate ? entitlementEffectiveDate : null;
+ final BaseEntitlementWithAddOnsSpecifier baseEntitlementWithAddOnsSpecifier = new DefaultBaseEntitlementWithAddOnsSpecifier(
+ getBundleId(),
+ getExternalKey(),
+ null,
+ entitlementEffectiveDate,
+ billingEffectiveDate,
+ false);
+ final List<BaseEntitlementWithAddOnsSpecifier> baseEntitlementWithAddOnsSpecifierList = new ArrayList<BaseEntitlementWithAddOnsSpecifier>();
+ baseEntitlementWithAddOnsSpecifierList.add(baseEntitlementWithAddOnsSpecifier);
final EntitlementContext pluginContext = new DefaultEntitlementContext(OperationType.CANCEL_SUBSCRIPTION,
getAccountId(),
null,
- getBundleId(),
- getExternalKey(),
- null,
- entitlementEffectiveDate,
- billingEffectiveDate,
+ baseEntitlementWithAddOnsSpecifierList,
null,
properties,
callContext);
@@ -382,14 +386,19 @@ public class DefaultEntitlement extends EntityBase implements Entitlement {
// Get the latest state from disk
refresh(callContext);
+ final BaseEntitlementWithAddOnsSpecifier baseEntitlementWithAddOnsSpecifier = new DefaultBaseEntitlementWithAddOnsSpecifier(
+ getBundleId(),
+ getExternalKey(),
+ null,
+ null,
+ null,
+ false);
+ final List<BaseEntitlementWithAddOnsSpecifier> baseEntitlementWithAddOnsSpecifierList = new ArrayList<BaseEntitlementWithAddOnsSpecifier>();
+ baseEntitlementWithAddOnsSpecifierList.add(baseEntitlementWithAddOnsSpecifier);
final EntitlementContext pluginContext = new DefaultEntitlementContext(OperationType.UNCANCEL_SUBSCRIPTION,
getAccountId(),
null,
- getBundleId(),
- getExternalKey(),
- null,
- null,
- null,
+ baseEntitlementWithAddOnsSpecifierList,
null,
properties,
callContext);
@@ -460,14 +469,19 @@ public class DefaultEntitlement extends EntityBase implements Entitlement {
// Get the latest state from disk
refresh(callContext);
+ final BaseEntitlementWithAddOnsSpecifier baseEntitlementWithAddOnsSpecifier = new DefaultBaseEntitlementWithAddOnsSpecifier(
+ getBundleId(),
+ getExternalKey(),
+ null,
+ entitlementEffectiveDate,
+ entitlementEffectiveDate,
+ false);
+ final List<BaseEntitlementWithAddOnsSpecifier> baseEntitlementWithAddOnsSpecifierList = new ArrayList<BaseEntitlementWithAddOnsSpecifier>();
+ baseEntitlementWithAddOnsSpecifierList.add(baseEntitlementWithAddOnsSpecifier);
final EntitlementContext pluginContext = new DefaultEntitlementContext(OperationType.CANCEL_SUBSCRIPTION,
getAccountId(),
null,
- getBundleId(),
- getExternalKey(),
- null,
- entitlementEffectiveDate,
- null,
+ baseEntitlementWithAddOnsSpecifierList,
billingPolicy,
properties,
callContext);
@@ -537,14 +551,19 @@ public class DefaultEntitlement extends EntityBase implements Entitlement {
// Get the latest state from disk
refresh(callContext);
+ final BaseEntitlementWithAddOnsSpecifier baseEntitlementWithAddOnsSpecifier = new DefaultBaseEntitlementWithAddOnsSpecifier(
+ getBundleId(),
+ getExternalKey(),
+ null,
+ null,
+ null,
+ false);
+ final List<BaseEntitlementWithAddOnsSpecifier> baseEntitlementWithAddOnsSpecifierList = new ArrayList<BaseEntitlementWithAddOnsSpecifier>();
+ baseEntitlementWithAddOnsSpecifierList.add(baseEntitlementWithAddOnsSpecifier);
final EntitlementContext pluginContext = new DefaultEntitlementContext(OperationType.CHANGE_PLAN,
getAccountId(),
null,
- getBundleId(),
- getExternalKey(),
- null,
- null,
- null,
+ baseEntitlementWithAddOnsSpecifierList,
null,
properties,
callContext);
@@ -603,14 +622,19 @@ public class DefaultEntitlement extends EntityBase implements Entitlement {
// Get the latest state from disk
refresh(callContext);
+ final BaseEntitlementWithAddOnsSpecifier baseEntitlementWithAddOnsSpecifier = new DefaultBaseEntitlementWithAddOnsSpecifier(
+ getBundleId(),
+ getExternalKey(),
+ null,
+ effectiveDate,
+ effectiveDate,
+ false);
+ final List<BaseEntitlementWithAddOnsSpecifier> baseEntitlementWithAddOnsSpecifierList = new ArrayList<BaseEntitlementWithAddOnsSpecifier>();
+ baseEntitlementWithAddOnsSpecifierList.add(baseEntitlementWithAddOnsSpecifier);
final EntitlementContext pluginContext = new DefaultEntitlementContext(OperationType.CHANGE_PLAN,
getAccountId(),
null,
- getBundleId(),
- getExternalKey(),
- null,
- effectiveDate,
- effectiveDate,
+ baseEntitlementWithAddOnsSpecifierList,
null,
properties,
callContext);
@@ -623,7 +647,7 @@ public class DefaultEntitlement extends EntityBase implements Entitlement {
}
final InternalCallContext context = internalCallContextFactory.createInternalCallContext(getAccountId(), callContext);
- final DateTime effectiveChangeDate = dateHelper.fromLocalDateAndReferenceTime(updatedPluginContext.getBillingEffectiveDate(), context);
+ final DateTime effectiveChangeDate = dateHelper.fromLocalDateAndReferenceTime(updatedPluginContext.getBaseEntitlementWithAddOnsSpecifiers().get(0).getBillingEffectiveDate(), context);
final DateTime resultingEffectiveDate;
try {
@@ -671,14 +695,19 @@ public class DefaultEntitlement extends EntityBase implements Entitlement {
// Get the latest state from disk
refresh(callContext);
+ final BaseEntitlementWithAddOnsSpecifier baseEntitlementWithAddOnsSpecifier = new DefaultBaseEntitlementWithAddOnsSpecifier(
+ getBundleId(),
+ getExternalKey(),
+ null,
+ entitlementEffectiveDate,
+ null,
+ false);
+ final List<BaseEntitlementWithAddOnsSpecifier> baseEntitlementWithAddOnsSpecifierList = new ArrayList<BaseEntitlementWithAddOnsSpecifier>();
+ baseEntitlementWithAddOnsSpecifierList.add(baseEntitlementWithAddOnsSpecifier);
final EntitlementContext pluginContext = new DefaultEntitlementContext(OperationType.CHANGE_PLAN,
getAccountId(),
null,
- getBundleId(),
- getExternalKey(),
- null,
- entitlementEffectiveDate,
- null,
+ baseEntitlementWithAddOnsSpecifierList,
actionPolicy,
properties,
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 f26c167..31e6957 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
@@ -37,7 +37,6 @@ import org.killbill.billing.callcontext.InternalTenantContext;
import org.killbill.billing.catalog.api.BillingActionPolicy;
import org.killbill.billing.catalog.api.PlanPhasePriceOverride;
import org.killbill.billing.catalog.api.PlanPhaseSpecifier;
-import org.killbill.billing.catalog.api.ProductCategory;
import org.killbill.billing.entitlement.AccountEventsStreams;
import org.killbill.billing.entitlement.EntitlementService;
import org.killbill.billing.entitlement.EventsStream;
@@ -47,7 +46,6 @@ import org.killbill.billing.entitlement.block.BlockingChecker;
import org.killbill.billing.entitlement.dao.BlockingStateDao;
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.junction.DefaultBlockingState;
@@ -74,6 +72,7 @@ import com.google.common.collect.Lists;
import static org.killbill.billing.entitlement.logging.EntitlementLoggingHelper.logCreateEntitlement;
import static org.killbill.billing.entitlement.logging.EntitlementLoggingHelper.logCreateEntitlementWithAOs;
+import static org.killbill.billing.entitlement.logging.EntitlementLoggingHelper.logCreateEntitlementsWithAOs;
import static org.killbill.billing.entitlement.logging.EntitlementLoggingHelper.logPauseResumeEntitlement;
import static org.killbill.billing.entitlement.logging.EntitlementLoggingHelper.logTransferEntitlement;
@@ -133,14 +132,21 @@ public class DefaultEntitlementApi extends DefaultEntitlementApiBase implements
final EntitlementSpecifier entitlementSpecifier = new DefaultEntitlementSpecifier(planPhaseSpecifier, overrides);
final List<EntitlementSpecifier> entitlementSpecifierList = new ArrayList<EntitlementSpecifier>();
entitlementSpecifierList.add(entitlementSpecifier);
+ final BaseEntitlementWithAddOnsSpecifier baseEntitlementWithAddOnsSpecifier = new DefaultBaseEntitlementWithAddOnsSpecifier(
+ null,
+ externalKey,
+ entitlementSpecifierList,
+ entitlementEffectiveDate,
+ billingEffectiveDate,
+ isMigrated);
+ final List<BaseEntitlementWithAddOnsSpecifier> baseEntitlementWithAddOnsSpecifierList = new ArrayList<BaseEntitlementWithAddOnsSpecifier>();
+ baseEntitlementWithAddOnsSpecifierList.add(baseEntitlementWithAddOnsSpecifier);
+
+
final EntitlementContext pluginContext = new DefaultEntitlementContext(OperationType.CREATE_SUBSCRIPTION,
accountId,
null,
- null,
- externalKey,
- entitlementSpecifierList,
- entitlementEffectiveDate,
- billingEffectiveDate,
+ baseEntitlementWithAddOnsSpecifierList,
null,
properties,
callContext);
@@ -156,11 +162,11 @@ public class DefaultEntitlementApi extends DefaultEntitlementApiBase implements
final SubscriptionBaseBundle bundle = subscriptionBaseInternalApi.createBundleForAccount(accountId, externalKey, contextWithValidAccountRecordId);
- final DateTime billingRequestedDate = dateHelper.fromLocalDateAndReferenceTime(updatedPluginContext.getBillingEffectiveDate(), contextWithValidAccountRecordId);
- final EntitlementSpecifier specifier = getFirstEntitlementSpecifier(updatedPluginContext.getEntitlementSpecifiers());
+ final DateTime billingRequestedDate = dateHelper.fromLocalDateAndReferenceTime(updatedPluginContext.getBaseEntitlementWithAddOnsSpecifiers().get(0).getBillingEffectiveDate(), contextWithValidAccountRecordId);
+ final EntitlementSpecifier specifier = getFirstEntitlementSpecifier(updatedPluginContext.getBaseEntitlementWithAddOnsSpecifiers());
final SubscriptionBase subscription = subscriptionBaseInternalApi.createSubscription(bundle.getId(), specifier.getPlanPhaseSpecifier(), specifier.getOverrides(), billingRequestedDate, isMigrated, contextWithValidAccountRecordId);
- final DateTime entitlementRequestedDate = dateHelper.fromLocalDateAndReferenceTime(updatedPluginContext.getEntitlementEffectiveDate(), contextWithValidAccountRecordId);
+ final DateTime entitlementRequestedDate = dateHelper.fromLocalDateAndReferenceTime(updatedPluginContext.getBaseEntitlementWithAddOnsSpecifiers().get(0).getEntitlementEffectiveDate(), contextWithValidAccountRecordId);
final BlockingState newBlockingState = new DefaultBlockingState(subscription.getId(), BlockingStateType.SUBSCRIPTION, DefaultEntitlementApi.ENT_STATE_START, EntitlementService.ENTITLEMENT_SERVICE_NAME, false, false, false, entitlementRequestedDate);
entitlementUtils.setBlockingStatesAndPostBlockingTransitionEvent(ImmutableList.<BlockingState>of(newBlockingState), subscription.getBundleId(), contextWithValidAccountRecordId);
@@ -175,11 +181,13 @@ public class DefaultEntitlementApi extends DefaultEntitlementApiBase implements
return pluginExecution.executeWithPlugin(createBaseEntitlementWithPlugin, pluginContext);
}
- private EntitlementSpecifier getFirstEntitlementSpecifier(final List<EntitlementSpecifier> entitlementSpecifiers) throws SubscriptionBaseApiException {
- if ((entitlementSpecifiers == null) || entitlementSpecifiers.isEmpty()) {
- throw new SubscriptionBaseApiException(ErrorCode.SUB_CREATE_INVALID_ENTITLEMENT_SPECIFIER);
+ private EntitlementSpecifier getFirstEntitlementSpecifier(final List<BaseEntitlementWithAddOnsSpecifier> baseEntitlementWithAddOnsSpecifiers) throws SubscriptionBaseApiException {
+ if ((baseEntitlementWithAddOnsSpecifiers == null) || baseEntitlementWithAddOnsSpecifiers.isEmpty()) {
+ if ((baseEntitlementWithAddOnsSpecifiers.get(0).getEntitlementSpecifier() == null) || !baseEntitlementWithAddOnsSpecifiers.get(0).getEntitlementSpecifier().iterator().hasNext()) {
+ throw new SubscriptionBaseApiException(ErrorCode.SUB_CREATE_INVALID_ENTITLEMENT_SPECIFIER);
+ }
}
- return entitlementSpecifiers.get(0);
+ return baseEntitlementWithAddOnsSpecifiers.get(0).getEntitlementSpecifier().iterator().next();
}
@Override
@@ -193,15 +201,20 @@ public class DefaultEntitlementApi extends DefaultEntitlementApiBase implements
final List<EntitlementSpecifier> entitlementSpecifierList = new ArrayList<EntitlementSpecifier>();
Iterables.addAll(entitlementSpecifierList, entitlementSpecifiers);
+ final BaseEntitlementWithAddOnsSpecifier baseEntitlementWithAddOnsSpecifier = new DefaultBaseEntitlementWithAddOnsSpecifier(
+ null,
+ externalKey,
+ entitlementSpecifierList,
+ entitlementEffectiveDate,
+ billingEffectiveDate,
+ isMigrated);
+ final List<BaseEntitlementWithAddOnsSpecifier> baseEntitlementWithAddOnsSpecifierList = new ArrayList<BaseEntitlementWithAddOnsSpecifier>();
+ baseEntitlementWithAddOnsSpecifierList.add(baseEntitlementWithAddOnsSpecifier);
final EntitlementContext pluginContext = new DefaultEntitlementContext(OperationType.CREATE_SUBSCRIPTIONS_WITH_AO,
accountId,
null,
- null,
- externalKey,
- entitlementSpecifierList,
- entitlementEffectiveDate,
- billingEffectiveDate,
+ baseEntitlementWithAddOnsSpecifierList,
null,
properties,
callContext);
@@ -218,10 +231,10 @@ public class DefaultEntitlementApi extends DefaultEntitlementApiBase implements
final SubscriptionBaseBundle bundle = subscriptionBaseInternalApi.createBundleForAccount(accountId, externalKey, contextWithValidAccountRecordId);
- final DateTime billingRequestedDate = dateHelper.fromLocalDateAndReferenceTime(updatedPluginContext.getBillingEffectiveDate(), contextWithValidAccountRecordId);
+ final DateTime billingRequestedDate = dateHelper.fromLocalDateAndReferenceTime(updatedPluginContext.getBaseEntitlementWithAddOnsSpecifiers().get(0).getBillingEffectiveDate(), contextWithValidAccountRecordId);
final List<SubscriptionBase> subscriptionBases = subscriptionBaseInternalApi.createBaseSubscriptionWithAddOns(bundle.getId(), entitlementSpecifiers, billingRequestedDate, isMigrated, contextWithValidAccountRecordId);
- final DateTime entitlementRequestedDate = dateHelper.fromLocalDateAndReferenceTime(updatedPluginContext.getEntitlementEffectiveDate(), contextWithValidAccountRecordId);
+ final DateTime entitlementRequestedDate = dateHelper.fromLocalDateAndReferenceTime(updatedPluginContext.getBaseEntitlementWithAddOnsSpecifiers().get(0).getEntitlementEffectiveDate(), contextWithValidAccountRecordId);
final List<BlockingState> blockingStates = new ArrayList<BlockingState>();
for (final SubscriptionBase cur : subscriptionBases) {
final BlockingState blockingState = new DefaultBlockingState(cur.getId(), BlockingStateType.SUBSCRIPTION, DefaultEntitlementApi.ENT_STATE_START, EntitlementService.ENTITLEMENT_SERVICE_NAME, false, false, false, entitlementRequestedDate);
@@ -245,6 +258,58 @@ public class DefaultEntitlementApi extends DefaultEntitlementApiBase implements
}
@Override
+ public List<Entitlement> createBaseEntitlementsWithAddOns(final UUID accountId, final Iterable<BaseEntitlementWithAddOnsSpecifier> baseEntitlementSpecifiersWithAddOns, final Iterable<PluginProperty> properties, final CallContext callContext) throws EntitlementApiException {
+
+ logCreateEntitlementsWithAOs(log, baseEntitlementSpecifiersWithAddOns);
+
+ final List<BaseEntitlementWithAddOnsSpecifier> baseEntitlementSpecifiersWithAddOnsList = new ArrayList<BaseEntitlementWithAddOnsSpecifier>();
+ Iterables.addAll(baseEntitlementSpecifiersWithAddOnsList, baseEntitlementSpecifiersWithAddOns);
+
+ final EntitlementContext pluginContext = new DefaultEntitlementContext(OperationType.CREATE_SHOPPING_CART_SUBSCRIPTIONS,
+ accountId,
+ null,
+ baseEntitlementSpecifiersWithAddOnsList,
+ null,
+ properties,
+ callContext);
+
+ final WithEntitlementPlugin<List<Entitlement>> createBaseEntitlementsWithAddOns = new WithEntitlementPlugin<List<Entitlement>>() {
+ @Override
+ public List<Entitlement> doCall(final EntitlementApi entitlementApi, final EntitlementContext updatedPluginContext) throws EntitlementApiException {
+ final InternalCallContext contextWithValidAccountRecordId = internalCallContextFactory.createInternalCallContext(accountId, callContext);
+
+ try {
+ final List<SubscriptionBase> subscriptionsWithAddOns = subscriptionBaseInternalApi.createBaseSubscriptionsWithAddOns(accountId, baseEntitlementSpecifiersWithAddOns, contextWithValidAccountRecordId);
+
+ final DateTime entitlementRequestedDate = dateHelper.fromLocalDateAndReferenceTime(updatedPluginContext.getBaseEntitlementWithAddOnsSpecifiers().get(0).getEntitlementEffectiveDate(), contextWithValidAccountRecordId);
+ final List<BlockingState> blockingStates = new ArrayList<BlockingState>();
+ for (final SubscriptionBase cur : subscriptionsWithAddOns) {
+ final BlockingState blockingState = new DefaultBlockingState(cur.getId(), BlockingStateType.SUBSCRIPTION, DefaultEntitlementApi.ENT_STATE_START, EntitlementService.ENTITLEMENT_SERVICE_NAME, false, false, false, entitlementRequestedDate);
+ blockingStates.add(blockingState);
+ }
+ entitlementUtils.setBlockingStatesAndPostBlockingTransitionEvent(blockingStates, subscriptionsWithAddOns.get(0).getBundleId(), contextWithValidAccountRecordId);
+
+ return buildEntitlementList(accountId, subscriptionsWithAddOns, callContext);
+ } catch (final SubscriptionBaseApiException e) {
+ throw new EntitlementApiException(e);
+ }
+ }
+ };
+ return pluginExecution.executeWithPlugin(createBaseEntitlementsWithAddOns, pluginContext);
+ }
+
+ private List<Entitlement> buildEntitlementList(final UUID accountId, final List<SubscriptionBase> subscriptionsWithAddOns, final CallContext callContext) throws EntitlementApiException {
+ List<Entitlement> result = new ArrayList<Entitlement>();
+ for (SubscriptionBase subscriptionWithAddOns : subscriptionsWithAddOns) {
+ Entitlement entitlement = new DefaultEntitlement(accountId, subscriptionWithAddOns.getId(), eventsStreamBuilder, entitlementApi, pluginExecution,
+ blockingStateDao, subscriptionBaseInternalApi, checker, notificationQueueService,
+ entitlementUtils, dateHelper, clock, securityApi, internalCallContextFactory, callContext);
+ result.add(entitlement);
+ }
+ return result;
+ }
+
+ @Override
public Entitlement addEntitlement(final UUID bundleId, final PlanPhaseSpecifier planPhaseSpecifier, final List<PlanPhasePriceOverride> overrides, @Nullable final LocalDate entitlementEffectiveDate, @Nullable final LocalDate billingEffectiveDate,
final boolean isMigrated, final Iterable<PluginProperty> properties, final CallContext callContext) throws EntitlementApiException {
@@ -254,14 +319,20 @@ public class DefaultEntitlementApi extends DefaultEntitlementApiBase implements
final EntitlementSpecifier entitlementSpecifier = new DefaultEntitlementSpecifier(planPhaseSpecifier, overrides);
final List<EntitlementSpecifier> entitlementSpecifierList = new ArrayList<EntitlementSpecifier>();
entitlementSpecifierList.add(entitlementSpecifier);
+ final BaseEntitlementWithAddOnsSpecifier baseEntitlementWithAddOnsSpecifier = new DefaultBaseEntitlementWithAddOnsSpecifier(
+ bundleId,
+ null,
+ entitlementSpecifierList,
+ entitlementEffectiveDate,
+ billingEffectiveDate,
+ isMigrated);
+ final List<BaseEntitlementWithAddOnsSpecifier> baseEntitlementWithAddOnsSpecifierList = new ArrayList<BaseEntitlementWithAddOnsSpecifier>();
+ baseEntitlementWithAddOnsSpecifierList.add(baseEntitlementWithAddOnsSpecifier);
+
final EntitlementContext pluginContext = new DefaultEntitlementContext(OperationType.CREATE_SUBSCRIPTION,
null,
null,
- bundleId,
- null,
- entitlementSpecifierList,
- entitlementEffectiveDate,
- billingEffectiveDate,
+ baseEntitlementWithAddOnsSpecifierList,
null,
properties,
callContext);
@@ -281,13 +352,13 @@ public class DefaultEntitlementApi extends DefaultEntitlementApiBase implements
throw new EntitlementApiException(new BlockingApiException(ErrorCode.BLOCK_BLOCKED_ACTION, BlockingChecker.ACTION_CHANGE, BlockingChecker.TYPE_SUBSCRIPTION, eventsStreamForBaseSubscription.getEntitlementId().toString()));
}
- final DateTime billingRequestedDate = dateHelper.fromLocalDateAndReferenceTime(updatedPluginContext.getBillingEffectiveDate(), eventsStreamForBaseSubscription.getInternalTenantContext());
+ final DateTime billingRequestedDate = dateHelper.fromLocalDateAndReferenceTime(updatedPluginContext.getBaseEntitlementWithAddOnsSpecifiers().get(0).getBillingEffectiveDate(), eventsStreamForBaseSubscription.getInternalTenantContext());
try {
final InternalCallContext context = internalCallContextFactory.createInternalCallContext(eventsStreamForBaseSubscription.getAccountId(), callContext);
- final EntitlementSpecifier specifier = getFirstEntitlementSpecifier(updatedPluginContext.getEntitlementSpecifiers());
+ final EntitlementSpecifier specifier = getFirstEntitlementSpecifier(updatedPluginContext.getBaseEntitlementWithAddOnsSpecifiers());
final SubscriptionBase subscription = subscriptionBaseInternalApi.createSubscription(bundleId, specifier.getPlanPhaseSpecifier(), specifier.getOverrides(), billingRequestedDate, isMigrated, context);
- final DateTime entitlementRequestedDate = dateHelper.fromLocalDateAndReferenceTime(updatedPluginContext.getEntitlementEffectiveDate(), eventsStreamForBaseSubscription.getInternalTenantContext());
+ final DateTime entitlementRequestedDate = dateHelper.fromLocalDateAndReferenceTime(updatedPluginContext.getBaseEntitlementWithAddOnsSpecifiers().get(0).getEntitlementEffectiveDate(), eventsStreamForBaseSubscription.getInternalTenantContext());
final BlockingState newBlockingState = new DefaultBlockingState(subscription.getId(), BlockingStateType.SUBSCRIPTION, DefaultEntitlementApi.ENT_STATE_START, EntitlementService.ENTITLEMENT_SERVICE_NAME, false, false, false, entitlementRequestedDate);
entitlementUtils.setBlockingStatesAndPostBlockingTransitionEvent(ImmutableList.<BlockingState>of(newBlockingState), subscription.getBundleId(), context);
@@ -402,15 +473,21 @@ public class DefaultEntitlementApi extends DefaultEntitlementApiBase implements
logTransferEntitlement(log, sourceAccountId, destAccountId, externalKey, effectiveDate, billingPolicy);
+ final BaseEntitlementWithAddOnsSpecifier baseEntitlementWithAddOnsSpecifier = new DefaultBaseEntitlementWithAddOnsSpecifier(
+ null,
+ externalKey,
+ new ArrayList<EntitlementSpecifier>(),
+ effectiveDate,
+ effectiveDate,
+ false);
+ final List<BaseEntitlementWithAddOnsSpecifier> baseEntitlementWithAddOnsSpecifierList = new ArrayList<BaseEntitlementWithAddOnsSpecifier>();
+ baseEntitlementWithAddOnsSpecifierList.add(baseEntitlementWithAddOnsSpecifier);
+
final EntitlementContext pluginContext = new DefaultEntitlementContext(OperationType.TRANSFER_BUNDLE,
sourceAccountId,
destAccountId,
- null,
- externalKey,
- new ArrayList<EntitlementSpecifier>(),
- effectiveDate,
- effectiveDate,
- null,
+ baseEntitlementWithAddOnsSpecifierList,
+ billingPolicy,
properties,
context);
@@ -442,7 +519,7 @@ public class DefaultEntitlementApi extends DefaultEntitlementApiBase implements
throw new EntitlementApiException(new SubscriptionBaseApiException(ErrorCode.SUB_GET_INVALID_BUNDLE_KEY, externalKey));
}
- final DateTime requestedDate = dateHelper.fromLocalDateAndReferenceTime(updatedPluginContext.getBillingEffectiveDate(), contextWithSourceAccountRecordId);
+ final DateTime requestedDate = dateHelper.fromLocalDateAndReferenceTime(updatedPluginContext.getBaseEntitlementWithAddOnsSpecifiers().get(0).getBillingEffectiveDate(), contextWithSourceAccountRecordId);
final SubscriptionBaseBundle newBundle = subscriptionBaseTransferApi.transferBundle(sourceAccountId, destAccountId, externalKey, requestedDate, true, cancelImm, context);
@@ -460,7 +537,7 @@ public class DefaultEntitlementApi extends DefaultEntitlementApiBase implements
final InternalCallContext contextWithDestAccountRecordId = internalCallContextFactory.createInternalCallContext(destAccountId, context);
blockingStates.clear();
- final DateTime entitlementRequestedDate = dateHelper.fromLocalDateAndReferenceTime(updatedPluginContext.getEntitlementEffectiveDate(), contextWithDestAccountRecordId);
+ final DateTime entitlementRequestedDate = dateHelper.fromLocalDateAndReferenceTime(updatedPluginContext.getBaseEntitlementWithAddOnsSpecifiers().get(0).getEntitlementEffectiveDate(), contextWithDestAccountRecordId);
for (final SubscriptionBase subscriptionBase : subscriptionBaseInternalApi.getSubscriptionsForBundle(newBundle.getId(), null, contextWithDestAccountRecordId)) {
final BlockingState newBlockingState = new DefaultBlockingState(subscriptionBase.getId(), BlockingStateType.SUBSCRIPTION, DefaultEntitlementApi.ENT_STATE_START, EntitlementService.ENTITLEMENT_SERVICE_NAME, false, false, false, entitlementRequestedDate);
blockingStates.put(newBlockingState, subscriptionBase.getBundleId());
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 d5ec969..6f6033f 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
@@ -23,7 +23,6 @@ import java.util.UUID;
import javax.annotation.Nullable;
import org.joda.time.DateTime;
-import org.joda.time.LocalDate;
import org.killbill.billing.catalog.api.BillingActionPolicy;
import org.killbill.billing.entitlement.plugin.api.EntitlementContext;
import org.killbill.billing.entitlement.plugin.api.OperationType;
@@ -39,11 +38,7 @@ public class DefaultEntitlementContext implements EntitlementContext {
private final OperationType operationType;
private final UUID accountId;
private final UUID destinationAccountId;
- private final UUID bundleId;
- private final String externalKey;
- private final List<EntitlementSpecifier> entitlementSpecifiers;
- private final LocalDate entitlementEffectiveDate;
- private final LocalDate billingEffectiveDate;
+ private final List<BaseEntitlementWithAddOnsSpecifier> baseEntitlementWithAddOnsSpecifiers;
private final BillingActionPolicy billingActionPolicy;
private final Iterable<PluginProperty> pluginProperties;
private final UUID userToken;
@@ -62,11 +57,7 @@ public class DefaultEntitlementContext implements EntitlementContext {
this(prev.getOperationType(),
prev.getAccountId(),
prev.getDestinationAccountId(),
- prev.getBundleId(),
- prev.getExternalKey(),
- pluginResult != null && pluginResult.getAdjustedEntitlementSpecifiers() != null ? pluginResult.getAdjustedEntitlementSpecifiers() : prev.getEntitlementSpecifiers(),
- pluginResult != null && pluginResult.getAdjustedEntitlementEffectiveDate() != null ? pluginResult.getAdjustedEntitlementEffectiveDate() : prev.getEntitlementEffectiveDate(),
- pluginResult != null && pluginResult.getAdjustedBillingEffectiveDate() != null ? pluginResult.getAdjustedBillingEffectiveDate() : prev.getBillingEffectiveDate(),
+ pluginResult != null && pluginResult.getAdjustedBaseEntitlementWithAddOnsSpecifiers() != null ? pluginResult.getAdjustedBaseEntitlementWithAddOnsSpecifiers() : prev.getBaseEntitlementWithAddOnsSpecifiers(),
pluginResult != null && pluginResult.getAdjustedBillingActionPolicy() != null ? pluginResult.getAdjustedBillingActionPolicy() : prev.getBillingActionPolicy(),
pluginResult != null && pluginResult.getAdjustedPluginProperties() != null ? pluginResult.getAdjustedPluginProperties() : prev.getPluginProperties(),
prev);
@@ -75,15 +66,11 @@ public class DefaultEntitlementContext implements EntitlementContext {
public DefaultEntitlementContext(final OperationType operationType,
final UUID accountId,
final UUID destinationAccountId,
- final UUID bundleId,
- final String externalKey,
- final List<EntitlementSpecifier> entitlementSpecifiers,
- @Nullable final LocalDate entitlementEffectiveDate,
- @Nullable final LocalDate billingEffectiveDate,
+ final List<BaseEntitlementWithAddOnsSpecifier> baseEntitlementWithAddOnsSpecifiers,
@Nullable final BillingActionPolicy actionPolicy,
final Iterable<PluginProperty> pluginProperties,
final CallContext callContext) {
- this(operationType, accountId, destinationAccountId, bundleId, externalKey, entitlementSpecifiers, entitlementEffectiveDate, billingEffectiveDate, actionPolicy, pluginProperties,
+ this(operationType, accountId, destinationAccountId, baseEntitlementWithAddOnsSpecifiers, actionPolicy, pluginProperties,
callContext.getUserToken(), callContext.getUserName(), callContext.getCallOrigin(), callContext.getUserType(), callContext.getReasonCode(),
callContext.getComments(), callContext.getCreatedDate(), callContext.getUpdatedDate(), callContext.getTenantId());
}
@@ -92,11 +79,7 @@ public class DefaultEntitlementContext implements EntitlementContext {
public DefaultEntitlementContext(final OperationType operationType,
final UUID accountId,
final UUID destinationAccountId,
- final UUID bundleId,
- final String externalKey,
- final List<EntitlementSpecifier> entitlementSpecifiers,
- @Nullable final LocalDate entitlementEffectiveDate,
- @Nullable final LocalDate billingEffectiveDate,
+ final List<BaseEntitlementWithAddOnsSpecifier> baseEntitlementWithAddOnsSpecifiers,
@Nullable final BillingActionPolicy actionPolicy,
final Iterable<PluginProperty> pluginProperties,
final UUID userToken,
@@ -111,11 +94,7 @@ public class DefaultEntitlementContext implements EntitlementContext {
this.operationType = operationType;
this.accountId = accountId;
this.destinationAccountId = destinationAccountId;
- this.bundleId = bundleId;
- this.externalKey = externalKey;
- this.entitlementSpecifiers = entitlementSpecifiers;
- this.entitlementEffectiveDate = entitlementEffectiveDate;
- this.billingEffectiveDate = billingEffectiveDate;
+ this.baseEntitlementWithAddOnsSpecifiers = baseEntitlementWithAddOnsSpecifiers;
this.billingActionPolicy = actionPolicy;
this.pluginProperties = pluginProperties;
this.userToken = userToken;
@@ -145,29 +124,8 @@ public class DefaultEntitlementContext implements EntitlementContext {
}
@Override
- public UUID getBundleId() {
- return bundleId;
- }
-
- @Override
- public String getExternalKey() {
- return externalKey;
- }
-
- @Override
- public List<EntitlementSpecifier> getEntitlementSpecifiers() {
- return entitlementSpecifiers;
- }
-
-
- @Override
- public LocalDate getEntitlementEffectiveDate() {
- return entitlementEffectiveDate;
- }
-
- @Override
- public LocalDate getBillingEffectiveDate() {
- return billingEffectiveDate;
+ public List<BaseEntitlementWithAddOnsSpecifier> getBaseEntitlementWithAddOnsSpecifiers() {
+ return baseEntitlementWithAddOnsSpecifiers;
}
@Override
diff --git a/entitlement/src/main/java/org/killbill/billing/entitlement/api/DefaultSubscriptionApi.java b/entitlement/src/main/java/org/killbill/billing/entitlement/api/DefaultSubscriptionApi.java
index a6fbfb9..1ea62df 100644
--- a/entitlement/src/main/java/org/killbill/billing/entitlement/api/DefaultSubscriptionApi.java
+++ b/entitlement/src/main/java/org/killbill/billing/entitlement/api/DefaultSubscriptionApi.java
@@ -279,15 +279,21 @@ public class DefaultSubscriptionApi implements SubscriptionApi {
throw new EntitlementApiException(e);
}
+
final LocalDate effectiveDate = new LocalDate(clock.getUTCNow(), account.getTimeZone());
+ final BaseEntitlementWithAddOnsSpecifier baseEntitlementWithAddOnsSpecifier = new DefaultBaseEntitlementWithAddOnsSpecifier(
+ bundleId,
+ newExternalKey,
+ new ArrayList<EntitlementSpecifier>(),
+ effectiveDate,
+ effectiveDate,
+ false);
+ final List<BaseEntitlementWithAddOnsSpecifier> baseEntitlementWithAddOnsSpecifierList = new ArrayList<BaseEntitlementWithAddOnsSpecifier>();
+ baseEntitlementWithAddOnsSpecifierList.add(baseEntitlementWithAddOnsSpecifier);
final EntitlementContext pluginContext = new DefaultEntitlementContext(OperationType.UPDATE_BUNDLE_EXTERNAL_KEY,
bundle.getAccountId(),
null,
- bundleId,
- newExternalKey,
- new ArrayList<EntitlementSpecifier>(),
- effectiveDate,
- effectiveDate,
+ baseEntitlementWithAddOnsSpecifierList,
null,
ImmutableList.<PluginProperty>of(),
callContext);
@@ -365,14 +371,19 @@ public class DefaultSubscriptionApi implements SubscriptionApi {
final DateTime effectiveDate = inputEffectiveDate == null ? clock.getUTCNow() : internalCallContextWithValidAccountId.toUTCDateTime(inputEffectiveDate);
final DefaultBlockingState blockingState = new DefaultBlockingState(inputBlockingState, effectiveDate);
+ final BaseEntitlementWithAddOnsSpecifier baseEntitlementWithAddOnsSpecifier = new DefaultBaseEntitlementWithAddOnsSpecifier(
+ bundleId,
+ externalKey,
+ new ArrayList<EntitlementSpecifier>(),
+ internalCallContextWithValidAccountId.toLocalDate(effectiveDate),
+ internalCallContextWithValidAccountId.toLocalDate(effectiveDate),
+ false);
+ final List<BaseEntitlementWithAddOnsSpecifier> baseEntitlementWithAddOnsSpecifierList = new ArrayList<BaseEntitlementWithAddOnsSpecifier>();
+ baseEntitlementWithAddOnsSpecifierList.add(baseEntitlementWithAddOnsSpecifier);
final EntitlementContext pluginContext = new DefaultEntitlementContext(OperationType.ADD_BLOCKING_STATE,
accountId,
null,
- bundleId,
- externalKey,
- new ArrayList<EntitlementSpecifier>(),
- internalCallContextWithValidAccountId.toLocalDate(effectiveDate),
- null,
+ baseEntitlementWithAddOnsSpecifierList,
null,
properties,
callContext);
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 3044aca..f1c8e57 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
@@ -17,9 +17,11 @@
package org.killbill.billing.entitlement.api.svcs;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedList;
+import java.util.List;
import java.util.Map;
import java.util.UUID;
@@ -34,8 +36,10 @@ import org.killbill.billing.entitlement.AccountEntitlements;
import org.killbill.billing.entitlement.AccountEventsStreams;
import org.killbill.billing.entitlement.EntitlementService;
import org.killbill.billing.entitlement.EventsStream;
+import org.killbill.billing.entitlement.api.BaseEntitlementWithAddOnsSpecifier;
import org.killbill.billing.entitlement.api.BlockingState;
import org.killbill.billing.entitlement.api.BlockingStateType;
+import org.killbill.billing.entitlement.api.DefaultBaseEntitlementWithAddOnsSpecifier;
import org.killbill.billing.entitlement.api.DefaultEntitlement;
import org.killbill.billing.entitlement.api.DefaultEntitlementApi;
import org.killbill.billing.entitlement.api.DefaultEntitlementContext;
@@ -138,15 +142,20 @@ public class DefaultEntitlementApiBase {
public void pause(final UUID bundleId, @Nullable final LocalDate localEffectiveDate, final Iterable<PluginProperty> properties, final InternalCallContext internalCallContext) throws EntitlementApiException {
+ final BaseEntitlementWithAddOnsSpecifier baseEntitlementWithAddOnsSpecifier = new DefaultBaseEntitlementWithAddOnsSpecifier(
+ bundleId,
+ null,
+ null,
+ localEffectiveDate,
+ localEffectiveDate,
+ false);
+ final List<BaseEntitlementWithAddOnsSpecifier> baseEntitlementWithAddOnsSpecifierList = new ArrayList<BaseEntitlementWithAddOnsSpecifier>();
+ baseEntitlementWithAddOnsSpecifierList.add(baseEntitlementWithAddOnsSpecifier);
final EntitlementContext pluginContext = new DefaultEntitlementContext(OperationType.PAUSE_BUNDLE,
null,
null,
- bundleId,
null,
null,
- localEffectiveDate,
- localEffectiveDate,
- null,
properties,
internalCallContextFactory.createCallContext(internalCallContext));
@@ -167,14 +176,19 @@ public class DefaultEntitlementApiBase {
public void resume(final UUID bundleId, @Nullable final LocalDate localEffectiveDate, final Iterable<PluginProperty> properties, final InternalCallContext internalCallContext) throws EntitlementApiException {
+ final BaseEntitlementWithAddOnsSpecifier baseEntitlementWithAddOnsSpecifier = new DefaultBaseEntitlementWithAddOnsSpecifier(
+ bundleId,
+ null,
+ null,
+ localEffectiveDate,
+ localEffectiveDate,
+ false);
+ final List<BaseEntitlementWithAddOnsSpecifier> baseEntitlementWithAddOnsSpecifierList = new ArrayList<BaseEntitlementWithAddOnsSpecifier>();
+ baseEntitlementWithAddOnsSpecifierList.add(baseEntitlementWithAddOnsSpecifier);
final EntitlementContext pluginContext = new DefaultEntitlementContext(OperationType.RESUME_BUNDLE,
null,
null,
- bundleId,
- null,
- null,
- localEffectiveDate,
- localEffectiveDate,
+ baseEntitlementWithAddOnsSpecifierList,
null,
properties,
internalCallContextFactory.createCallContext(internalCallContext));
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 3fc96da..557c568 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
@@ -40,8 +40,10 @@ 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;
+import org.killbill.billing.entitlement.api.DefaultBaseEntitlementWithAddOnsSpecifier;
import org.killbill.billing.entitlement.api.DefaultEntitlement;
import org.killbill.billing.entitlement.api.DefaultEntitlementApi;
import org.killbill.billing.entitlement.api.DefaultEntitlementContext;
@@ -107,14 +109,20 @@ public class DefaultEntitlementInternalApi extends DefaultEntitlementApiBase imp
continue;
}
+ final BaseEntitlementWithAddOnsSpecifier baseEntitlementWithAddOnsSpecifier = new DefaultBaseEntitlementWithAddOnsSpecifier(
+ entitlement.getBundleId(),
+ entitlement.getExternalKey(),
+ null,
+ effectiveDate,
+ null,
+ false);
+ final List<BaseEntitlementWithAddOnsSpecifier> baseEntitlementWithAddOnsSpecifierList = new ArrayList<BaseEntitlementWithAddOnsSpecifier>();
+ baseEntitlementWithAddOnsSpecifierList.add(baseEntitlementWithAddOnsSpecifier);
+
final EntitlementContext pluginContext = new DefaultEntitlementContext(OperationType.CANCEL_SUBSCRIPTION,
entitlement.getAccountId(),
null,
- entitlement.getBundleId(),
- entitlement.getExternalKey(),
- null,
- effectiveDate,
- null,
+ baseEntitlementWithAddOnsSpecifierList,
billingPolicy,
properties,
callContext);
@@ -219,7 +227,7 @@ public class DefaultEntitlementInternalApi extends DefaultEntitlementApiBase imp
@Override
public Entitlement doCall(final EntitlementApi entitlementApi, final EntitlementContext updatedPluginContext) throws EntitlementApiException {
- DateTime effectiveDate = dateHelper.fromLocalDateAndReferenceTime(updatedPluginContext.getEntitlementEffectiveDate(), internalCallContext);
+ DateTime effectiveDate = dateHelper.fromLocalDateAndReferenceTime(updatedPluginContext.getBaseEntitlementWithAddOnsSpecifiers().get(0).getEntitlementEffectiveDate(), internalCallContext);
// Avoid timing issues for IMM cancellations (we don't want an entitlement cancel date one second or so after the subscription cancel date or
// add-ons cancellations computations won't work).
if (effectiveDate.compareTo(entitlement.getSubscriptionBase().getEndDate()) > 0) {
diff --git a/entitlement/src/main/java/org/killbill/billing/entitlement/logging/EntitlementLoggingHelper.java b/entitlement/src/main/java/org/killbill/billing/entitlement/logging/EntitlementLoggingHelper.java
index 7e7f2e2..8f47820 100644
--- a/entitlement/src/main/java/org/killbill/billing/entitlement/logging/EntitlementLoggingHelper.java
+++ b/entitlement/src/main/java/org/killbill/billing/entitlement/logging/EntitlementLoggingHelper.java
@@ -22,10 +22,10 @@ import java.util.UUID;
import org.joda.time.LocalDate;
import org.killbill.billing.catalog.api.BillingActionPolicy;
-import org.killbill.billing.catalog.api.BillingPeriod;
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.BaseEntitlementWithAddOnsSpecifier;
import org.killbill.billing.entitlement.api.BlockingState;
import org.killbill.billing.entitlement.api.Entitlement;
import org.killbill.billing.entitlement.api.Entitlement.EntitlementActionPolicy;
@@ -69,6 +69,22 @@ public abstract class EntitlementLoggingHelper {
}
}
+ public static void logCreateEntitlementsWithAOs(final Logger log, final Iterable<BaseEntitlementWithAddOnsSpecifier> baseEntitlementSpecifiersWithAddOns) {
+ if (log.isInfoEnabled()) {
+ final StringBuilder logLine = new StringBuilder("Create Entitlements with AddOns: ");
+
+ if (baseEntitlementSpecifiersWithAddOns != null && baseEntitlementSpecifiersWithAddOns.iterator().hasNext()) {
+ for (BaseEntitlementWithAddOnsSpecifier cur : baseEntitlementSpecifiersWithAddOns) {
+ logCreateEntitlementWithAOs(log, cur.getExternalKey(),
+ cur.getEntitlementSpecifier(),
+ cur.getEntitlementEffectiveDate(),
+ cur.getBillingEffectiveDate());
+ }
+ }
+ log.info(logLine.toString());
+ }
+ }
+
public static void logCreateEntitlementWithAOs(final Logger log,
final String externalKey,
final Iterable<EntitlementSpecifier> entitlementSpecifiers,
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/BulkBaseSubscriptionAndAddOnsJson.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/BulkBaseSubscriptionAndAddOnsJson.java
new file mode 100644
index 0000000..b5367d1
--- /dev/null
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/BulkBaseSubscriptionAndAddOnsJson.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2016 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
+ * License. You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.killbill.billing.jaxrs.json;
+
+import java.util.List;
+
+import javax.annotation.Nullable;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.annotations.ApiModelProperty;
+
+public class BulkBaseSubscriptionAndAddOnsJson {
+
+ @ApiModelProperty(required = true)
+ private final List<SubscriptionJson> baseEntitlementAndAddOns;
+
+ @JsonCreator
+ public BulkBaseSubscriptionAndAddOnsJson(
+ @JsonProperty("baseEntitlementAndAddOns") @Nullable final List<SubscriptionJson> baseEntitlementAndAddOns) {
+ this.baseEntitlementAndAddOns = baseEntitlementAndAddOns;
+ }
+
+ public List<SubscriptionJson> getBaseEntitlementAndAddOns() {
+ return baseEntitlementAndAddOns;
+ }
+
+ @Override
+ public String toString() {
+ return "BulkBaseSubscriptionAndAddOnsJson{" +
+ "baseEntitlementAndAddOns=" + baseEntitlementAndAddOns +
+ '}';
+ }
+
+ @Override
+ public boolean equals(final Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+
+ final BulkBaseSubscriptionAndAddOnsJson that = (BulkBaseSubscriptionAndAddOnsJson) o;
+
+ return baseEntitlementAndAddOns != null ? baseEntitlementAndAddOns.equals(that.baseEntitlementAndAddOns) : that.baseEntitlementAndAddOns == null;
+
+ }
+
+ @Override
+ public int hashCode() {
+ return baseEntitlementAndAddOns != null ? baseEntitlementAndAddOns.hashCode() : 0;
+ }
+}
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 8a9a799..4e1a83f 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
@@ -53,6 +53,7 @@ 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.ProductCategory;
+import org.killbill.billing.entitlement.api.BaseEntitlementWithAddOnsSpecifier;
import org.killbill.billing.entitlement.api.BlockingStateType;
import org.killbill.billing.entitlement.api.Entitlement;
import org.killbill.billing.entitlement.api.Entitlement.EntitlementActionPolicy;
@@ -72,6 +73,7 @@ import org.killbill.billing.events.PaymentErrorInternalEvent;
import org.killbill.billing.events.PaymentInfoInternalEvent;
import org.killbill.billing.events.PaymentPluginErrorInternalEvent;
import org.killbill.billing.jaxrs.json.BlockingStateJson;
+import org.killbill.billing.jaxrs.json.BulkBaseSubscriptionAndAddOnsJson;
import org.killbill.billing.jaxrs.json.CustomFieldJson;
import org.killbill.billing.jaxrs.json.PhasePriceOverrideJson;
import org.killbill.billing.jaxrs.json.SubscriptionJson;
@@ -357,6 +359,147 @@ public class SubscriptionResource extends JaxRsResourceBase {
}
@TimedResource
+ @POST
+ @Path("/createEntitlementsWithAddOns")
+ @Consumes(APPLICATION_JSON)
+ @Produces(APPLICATION_JSON)
+ @ApiOperation(value = "Create multiple entitlements with addOn products")
+ @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid entitlements supplied")})
+ public Response createEntitlementsWithAddOns(final List<BulkBaseSubscriptionAndAddOnsJson> entitlementsWithAddOns,
+ @QueryParam(QUERY_REQUESTED_DT) final String requestedDate, /* This is deprecated, only used for backward compatibility */
+ @QueryParam(QUERY_ENTITLEMENT_REQUESTED_DT) final String entitlementDate,
+ @QueryParam(QUERY_BILLING_REQUESTED_DT) final String billingDate,
+ @QueryParam(QUERY_MIGRATED) @DefaultValue("false") final Boolean isMigrated,
+ @QueryParam(QUERY_CALL_COMPLETION) @DefaultValue("false") final Boolean callCompletion,
+ @QueryParam(QUERY_CALL_TIMEOUT) @DefaultValue("3") final long timeoutSec,
+ @QueryParam(QUERY_PLUGIN_PROPERTY) final List<String> pluginPropertiesString,
+ @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,
+ @javax.ws.rs.core.Context final UriInfo uriInfo) throws EntitlementApiException, AccountApiException, SubscriptionApiException {
+
+ Preconditions.checkArgument(Iterables.size(entitlementsWithAddOns) > 0, "Subscription bulk list mustn't be null or empty.");
+
+ logDeprecationParameterWarningIfNeeded(QUERY_REQUESTED_DT, QUERY_ENTITLEMENT_REQUESTED_DT, QUERY_BILLING_REQUESTED_DT);
+
+ final Iterable<PluginProperty> pluginProperties = extractPluginProperties(pluginPropertiesString);
+ final CallContext callContext = context.createContext(createdBy, reason, comment, request);
+
+ final SubscriptionJson baseEntitlement = Iterables.tryFind(entitlementsWithAddOns.get(0).getBaseEntitlementAndAddOns(), new Predicate<SubscriptionJson>() {
+ @Override
+ public boolean apply(final SubscriptionJson subscription) {
+ return ProductCategory.BASE.toString().equalsIgnoreCase(subscription.getProductCategory());
+ }
+ }).orNull();
+ verifyNonNull(baseEntitlement.getAccountId(), "SubscriptionJson accountId needs to be set for BASE product.");
+
+ final Account account = getAccountFromSubscriptionJson(baseEntitlement, callContext);
+
+ final List<BaseEntitlementWithAddOnsSpecifier> baseEntitlementWithAddOnsSpecifierList = new ArrayList<BaseEntitlementWithAddOnsSpecifier>();
+ for (BulkBaseSubscriptionAndAddOnsJson bulkBaseEntitlementWithAddOns : entitlementsWithAddOns) {
+ final List<EntitlementSpecifier> entitlementSpecifierList = new ArrayList<EntitlementSpecifier>();
+
+ // verify the number of BASE subscriptions
+ final int baseSubscriptionsSize = Iterables.size(Iterables.filter(bulkBaseEntitlementWithAddOns.getBaseEntitlementAndAddOns(), new Predicate<SubscriptionJson>() {
+ @Override
+ public boolean apply(final SubscriptionJson subscription) {
+ return subscription.getProductCategory().equals(ProductCategory.BASE.toString());
+ }
+ }));
+ verifyNumberOfElements(baseSubscriptionsSize, 1, "Only one BASE product is allowed.");
+
+ final int addOnSubscriptionsSize = Iterables.size(Iterables.filter(bulkBaseEntitlementWithAddOns.getBaseEntitlementAndAddOns(), new Predicate<SubscriptionJson>() {
+ @Override
+ public boolean apply(final SubscriptionJson subscription) {
+ return subscription.getProductCategory().equals(ProductCategory.ADD_ON.toString());
+ }
+ }));
+ verifyNumberOfElements(addOnSubscriptionsSize, entitlementsWithAddOns.size() - 1, "It should be " + (entitlementsWithAddOns.size() - 1) + " ADD_ON products.");
+
+ for (final SubscriptionJson entitlement : bulkBaseEntitlementWithAddOns.getBaseEntitlementAndAddOns()) {
+ // verifications
+ verifyNonNullOrEmpty(entitlement, "SubscriptionJson body should be specified for each element");
+ if (entitlement.getPlanName() == null) {
+ verifyNonNullOrEmpty(entitlement.getProductName(), "SubscriptionJson productName needs to be set for each element",
+ entitlement.getProductCategory(), "SubscriptionJson productCategory needs to be set for each element",
+ entitlement.getBillingPeriod(), "SubscriptionJson billingPeriod needs to be set for each element",
+ entitlement.getPriceList(), "SubscriptionJson priceList needs to be set for each element");
+ }
+
+ // create the entitlementSpecifier
+ final PlanPhaseSpecifier planPhaseSpecifier = entitlement.getPlanName() != null ?
+ new PlanPhaseSpecifier(entitlement.getPlanName(), null) :
+ new PlanPhaseSpecifier(entitlement.getProductName(),
+ BillingPeriod.valueOf(entitlement.getBillingPeriod()), entitlement.getPriceList(), null);
+ final List<PlanPhasePriceOverride> overrides = PhasePriceOverrideJson.toPlanPhasePriceOverrides(entitlement.getPriceOverrides(), planPhaseSpecifier, account.getCurrency());
+
+ EntitlementSpecifier specifier = new EntitlementSpecifier() {
+ @Override
+ public PlanPhaseSpecifier getPlanPhaseSpecifier() {
+ return planPhaseSpecifier;
+ }
+ @Override
+ public List<PlanPhasePriceOverride> getOverrides() {
+ return overrides;
+ }
+ };
+ entitlementSpecifierList.add(specifier);
+ }
+
+ // create the baseEntitlementSpecifierWithAddOns
+ final LocalDate resolvedEntitlementDate = requestedDate != null ? toLocalDate(requestedDate) : toLocalDate(entitlementDate);
+ final LocalDate resolvedBillingDate = requestedDate != null ? toLocalDate(requestedDate) : toLocalDate(billingDate);
+ final UUID bundleId = baseEntitlement.getBundleId() != null ? UUID.fromString(baseEntitlement.getBundleId()) : null;
+
+ BaseEntitlementWithAddOnsSpecifier baseEntitlementSpecifierWithAddOns = new BaseEntitlementWithAddOnsSpecifier() {
+ @Override
+ public UUID getBundleId() {
+ return bundleId;
+ }
+ @Override
+ public String getExternalKey() {
+ return baseEntitlement.getExternalKey();
+ }
+ @Override
+ public Iterable<EntitlementSpecifier> getEntitlementSpecifier() {
+ return entitlementSpecifierList;
+ }
+ @Override
+ public LocalDate getEntitlementEffectiveDate() {
+ return resolvedEntitlementDate;
+ }
+ @Override
+ public LocalDate getBillingEffectiveDate() {
+ return resolvedBillingDate;
+ }
+ @Override
+ public boolean isMigrated() {
+ return isMigrated;
+ }
+ };
+ baseEntitlementWithAddOnsSpecifierList.add(baseEntitlementSpecifierWithAddOns);
+ }
+
+ final EntitlementCallCompletionCallback<List<Entitlement>> callback = new EntitlementCallCompletionCallback<List<Entitlement>>() {
+ @Override
+ public List<Entitlement> doOperation(final CallContext ctx) throws InterruptedException, TimeoutException, EntitlementApiException, SubscriptionApiException, AccountApiException {
+ return entitlementApi.createBaseEntitlementsWithAddOns(account.getId(), baseEntitlementWithAddOnsSpecifierList, pluginProperties, callContext);
+ }
+ @Override
+ public boolean isImmOperation() {
+ return true;
+ }
+ @Override
+ public Response doResponseOk(final List<Entitlement> entitlement) {
+ return Response.status(Status.CREATED).build();
+ }
+ };
+ final EntitlementCallCompletion<List<Entitlement>> callCompletionCreation = new EntitlementCallCompletion<List<Entitlement>>();
+ return callCompletionCreation.withSynchronization(callback, timeoutSec, callCompletion, callContext);
+ }
+
+ @TimedResource
@PUT
@Path("/{subscriptionId:" + UUID_PATTERN + "}/uncancel")
@Produces(APPLICATION_JSON)
pom.xml 2(+1 -1)
diff --git a/pom.xml b/pom.xml
index 1e442c2..250ee1d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -21,7 +21,7 @@
<parent>
<artifactId>killbill-oss-parent</artifactId>
<groupId>org.kill-bill.billing</groupId>
- <version>0.133</version>
+ <version>0.134-SNAPSHOT</version>
</parent>
<artifactId>killbill</artifactId>
<version>0.17.6-SNAPSHOT</version>
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 dc345c6..3067e37 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
@@ -33,6 +33,7 @@ import org.killbill.billing.catalog.api.PlanChangeResult;
import org.killbill.billing.catalog.api.PlanPhasePriceOverride;
import org.killbill.billing.catalog.api.PlanSpecifier;
import org.killbill.billing.subscription.api.user.DefaultSubscriptionBase;
+import org.killbill.billing.subscription.api.user.SubscriptionAndAddOnsSpecifier;
import org.killbill.billing.subscription.api.user.SubscriptionBaseApiException;
import org.killbill.billing.subscription.api.user.SubscriptionBuilder;
import org.killbill.billing.subscription.api.user.SubscriptionSpecifier;
@@ -50,6 +51,9 @@ public interface SubscriptionBaseApiService {
public List<DefaultSubscriptionBase> createPlans(Iterable<SubscriptionSpecifier> subscriptions, CallContext context)
throws SubscriptionBaseApiException;
+ public List<List<DefaultSubscriptionBase>> createPlansWithAddOns(UUID accountId, Iterable<SubscriptionAndAddOnsSpecifier> subscriptionsAndAddOns, CallContext context)
+ throws SubscriptionBaseApiException;
+
public boolean cancel(DefaultSubscriptionBase subscription, CallContext context)
throws SubscriptionBaseApiException;
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 4b18a23..48391d5 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
@@ -48,6 +48,7 @@ import org.killbill.billing.catalog.api.PlanPhasePriceOverridesWithCallContext;
import org.killbill.billing.catalog.api.PlanPhaseSpecifier;
import org.killbill.billing.catalog.api.PlanSpecifier;
import org.killbill.billing.catalog.api.ProductCategory;
+import org.killbill.billing.entitlement.api.BaseEntitlementWithAddOnsSpecifier;
import org.killbill.billing.entitlement.api.Entitlement.EntitlementState;
import org.killbill.billing.entitlement.api.EntitlementAOStatusDryRun;
import org.killbill.billing.entitlement.api.EntitlementAOStatusDryRun.DryRunChangeReason;
@@ -63,6 +64,7 @@ import org.killbill.billing.subscription.api.user.DefaultSubscriptionBase;
import org.killbill.billing.subscription.api.user.DefaultSubscriptionBaseApiService;
import org.killbill.billing.subscription.api.user.DefaultSubscriptionBaseBundle;
import org.killbill.billing.subscription.api.user.DefaultSubscriptionStatusDryRun;
+import org.killbill.billing.subscription.api.user.SubscriptionAndAddOnsSpecifier;
import org.killbill.billing.subscription.api.user.SubscriptionBaseApiException;
import org.killbill.billing.subscription.api.user.SubscriptionBaseBundle;
import org.killbill.billing.subscription.api.user.SubscriptionBaseTransition;
@@ -275,6 +277,99 @@ public class DefaultSubscriptionInternalApi extends SubscriptionApiBase implemen
}
}
+ @Override
+ public List<SubscriptionBase> createBaseSubscriptionsWithAddOns(final UUID accountId, final Iterable<BaseEntitlementWithAddOnsSpecifier> baseEntitlementWithAddOnsSpecifier, final InternalCallContext context) throws SubscriptionBaseApiException {
+ try {
+ final Catalog catalog = catalogService.getFullCatalog(true, true, context);
+ final CallContext callContext = internalCallContextFactory.createCallContext(context);
+
+ final List<SubscriptionAndAddOnsSpecifier> subscriptionAndAddOns = new ArrayList<SubscriptionAndAddOnsSpecifier>();
+ for (BaseEntitlementWithAddOnsSpecifier entitlementWithAddOnsSpecifier : baseEntitlementWithAddOnsSpecifier) {
+ final List<SubscriptionSpecifier> subscriptions = new ArrayList<SubscriptionSpecifier>();
+ final DateTime now = clock.getUTCNow();
+ final DateTime effectiveDate = (entitlementWithAddOnsSpecifier.getEntitlementEffectiveDate() != null) ?
+ DefaultClock.truncateMs(entitlementWithAddOnsSpecifier.getEntitlementEffectiveDate().toDateTimeAtCurrentTime()) : now;
+
+ final SubscriptionBaseBundle bundle = createBundleForAccount(accountId, entitlementWithAddOnsSpecifier.getExternalKey(), context);
+ final List<SubscriptionBase> subscriptionWithAddOns = createBaseSubscriptionWithAddOns(bundle.getId(), entitlementWithAddOnsSpecifier.getEntitlementSpecifier(),
+ entitlementWithAddOnsSpecifier.getEntitlementEffectiveDate().toDateTimeAtCurrentTime(),
+ entitlementWithAddOnsSpecifier.isMigrated(), context);
+ boolean first = true;
+ for (EntitlementSpecifier entitlement : entitlementWithAddOnsSpecifier.getEntitlementSpecifier()) {
+ final PlanPhaseSpecifier spec = entitlement.getPlanPhaseSpecifier();
+
+ final PlanPhasePriceOverridesWithCallContext overridesWithContext = new DefaultPlanPhasePriceOverridesWithCallContext(entitlement.getOverrides(), callContext);
+
+ final Plan plan = catalog.createOrFindPlan(spec, overridesWithContext, entitlementWithAddOnsSpecifier.getEntitlementEffectiveDate().toDateTimeAtCurrentTime());
+ final PlanPhase phase = plan.getAllPhases()[0];
+ if (phase == null) {
+ throw new SubscriptionBaseError(String.format("No initial PlanPhase for Product %s, term %s and set %s does not exist in the catalog",
+ spec.getProductName(), spec.getBillingPeriod().toString(), plan.getPriceListName()));
+ }
+
+ if (first) {
+ first = false;
+ if (plan.getProduct().getCategory() != ProductCategory.BASE) {
+ throw new SubscriptionBaseApiException(new IllegalArgumentException(), ErrorCode.SUB_CREATE_NO_BP.getCode(), "Missing Base Subscription.");
+ }
+ }
+
+ // verify the number of subscriptions (of the same kind) allowed per bundle and the existing ones
+ if (ProductCategory.ADD_ON.toString().equalsIgnoreCase(plan.getProduct().getCategory().toString())) {
+ if (plan.getPlansAllowedInBundle() != -1 && plan.getPlansAllowedInBundle() > 0) {
+ int existingAddOnsWithSamePlanName = addonUtils.countExistingAddOnsWithSamePlanName(subscriptionWithAddOns, plan.getName());
+ int currentAddOnsWithSamePlanName = countCurrentAddOnsWithSamePlanName(entitlementWithAddOnsSpecifier.getEntitlementSpecifier(), catalog, plan.getName(), effectiveDate, callContext);
+ if ((existingAddOnsWithSamePlanName + currentAddOnsWithSamePlanName) > plan.getPlansAllowedInBundle()) {
+ // a new ADD_ON subscription of the same plan can't be added because it has reached its limit by bundle
+ throw new SubscriptionBaseApiException(ErrorCode.SUB_CREATE_AO_MAX_PLAN_ALLOWED_BY_BUNDLE, plan.getName());
+ }
+ }
+ }
+
+ SubscriptionSpecifier subscription = new SubscriptionSpecifier();
+ subscription.setRealPriceList(plan.getPriceListName());
+ subscription.setEffectiveDate(effectiveDate);
+ subscription.setProcessedDate(now);
+ subscription.setPlan(plan);
+ subscription.setInitialPhase(spec.getPhaseType());
+ subscription.setBuilder(new SubscriptionBuilder()
+ .setId(UUIDs.randomUUID())
+ .setBundleId(bundle.getId())
+ .setCategory(plan.getProduct().getCategory())
+ .setBundleStartDate(effectiveDate)
+ .setAlignStartDate(effectiveDate)
+ .setMigrated(entitlementWithAddOnsSpecifier.isMigrated()));
+
+ subscriptions.add(subscription);
+ }
+ SubscriptionAndAddOnsSpecifier subscriptionAndAddOnsSpecifier = new SubscriptionAndAddOnsSpecifier();
+ subscriptionAndAddOnsSpecifier.setSubscriptionSpecifiers(subscriptions);
+ subscriptionAndAddOns.add(subscriptionAndAddOnsSpecifier);
+ }
+
+ final List<List<DefaultSubscriptionBase>> result = apiService.createPlansWithAddOns(accountId, subscriptionAndAddOns, callContext);
+ return buildSubscriptionBaseList(result);
+
+ } catch (CatalogApiException e) {
+ throw new SubscriptionBaseApiException(e);
+ }
+ }
+
+ private List<SubscriptionBase> buildSubscriptionBaseList(final List<List<DefaultSubscriptionBase>> defaultSubscriptionBaseList) {
+ List<SubscriptionBase> result = new ArrayList<SubscriptionBase>();
+
+ for (List<DefaultSubscriptionBase> defaultSubscriptionBase : defaultSubscriptionBaseList) {
+ final ImmutableList<SubscriptionBase> subscriptionBases = ImmutableList.copyOf(Iterables.transform(defaultSubscriptionBase, new Function<DefaultSubscriptionBase, SubscriptionBase>() {
+ @Override
+ public SubscriptionBase apply(final DefaultSubscriptionBase input) {
+ return input;
+ }
+ }));
+ result.addAll(subscriptionBases);
+ }
+ return result;
+ }
+
private int countCurrentAddOnsWithSamePlanName(final Iterable<EntitlementSpecifier> entitlements,
final Catalog catalog, final String planName,
final DateTime effectiveDate, final CallContext callContext) throws CatalogApiException {
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 0fee918..4137398 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
@@ -118,6 +118,57 @@ public class DefaultSubscriptionBaseApiService implements SubscriptionBaseApiSer
}
@Override
+ public List<List<DefaultSubscriptionBase>> createPlansWithAddOns(final UUID accountId, final Iterable<SubscriptionAndAddOnsSpecifier> subscriptionsAndAddOns, final CallContext context) throws SubscriptionBaseApiException {
+
+ Map<UUID, List<SubscriptionBaseEvent>> eventsMap = new HashMap<UUID, List<SubscriptionBaseEvent>>();
+ List<List<DefaultSubscriptionBase>> subscriptionBaseAndAddOnsList = new ArrayList<List<DefaultSubscriptionBase>>();
+
+ for (SubscriptionAndAddOnsSpecifier subscriptionAndAddOns : subscriptionsAndAddOns) {
+ List<DefaultSubscriptionBase> subscriptionBaseList = new ArrayList<DefaultSubscriptionBase>();
+ for (SubscriptionSpecifier subscription : subscriptionAndAddOns.getSubscriptionSpecifiers()) {
+
+ try {
+ final DefaultSubscriptionBase subscriptionBase = new DefaultSubscriptionBase(subscription.getBuilder(), this, clock);
+ final InternalCallContext internalCallContext = createCallContextFromBundleId(subscriptionBase.getBundleId(), context);
+ final List<SubscriptionBaseEvent> events = getEventsOnCreation(subscriptionBase.getBundleId(), subscriptionBase.getId(), subscriptionBase.getAlignStartDate(),
+ subscriptionBase.getBundleStartDate(), subscription.getPlan(),
+ subscription.getInitialPhase(), subscription.getRealPriceList(),
+ subscription.getEffectiveDate(), subscription.getProcessedDate(), internalCallContext);
+ eventsMap.put(subscriptionBase.getId(), events);
+ subscriptionBaseList.add(subscriptionBase);
+
+ } catch (final CatalogApiException e) {
+ throw new SubscriptionBaseApiException(e);
+ }
+ }
+ subscriptionBaseAndAddOnsList.add(subscriptionBaseList);
+ }
+
+ final InternalCallContext internalCallContext = createCallContextFromAccountId(accountId, context);
+ dao.createSubscriptionsWithAddOns(subscriptionBaseAndAddOnsList, eventsMap, internalCallContext);
+
+ for (List<DefaultSubscriptionBase> subscriptionBase : subscriptionBaseAndAddOnsList) {
+ final DefaultSubscriptionBase baseSubscription = findBaseSubscription(subscriptionBase);
+ try {
+ baseSubscription.rebuildTransitions(dao.getEventsForSubscription(baseSubscription.getId(), internalCallContext),
+ catalogService.getFullCatalog(true, true, internalCallContext));
+
+ for (final DefaultSubscriptionBase input : subscriptionBase) {
+ if (input.getId().equals(baseSubscription.getId())) {
+ continue;
+ }
+
+ input.rebuildTransitions(dao.getEventsForSubscription(input.getId(), internalCallContext),
+ catalogService.getFullCatalog(true, true, internalCallContext));
+ }
+ } catch (CatalogApiException e) {
+ throw new SubscriptionBaseApiException(e);
+ }
+ }
+ return subscriptionBaseAndAddOnsList;
+ }
+
+ @Override
public List<DefaultSubscriptionBase> createPlans(final Iterable<SubscriptionSpecifier> subscriptions, final CallContext context) throws SubscriptionBaseApiException {
Map<UUID, List<SubscriptionBaseEvent>> eventsMap = new HashMap<UUID, List<SubscriptionBaseEvent>>();
@@ -592,6 +643,10 @@ public class DefaultSubscriptionBaseApiService implements SubscriptionBaseApiSer
return internalCallContextFactory.createInternalCallContext(bundleId, ObjectType.BUNDLE, context);
}
+ private InternalCallContext createCallContextFromAccountId(final UUID accountId, final CallContext context) {
+ return internalCallContextFactory.createInternalCallContext(accountId, ObjectType.ACCOUNT, context);
+ }
+
private InternalTenantContext createTenantContextFromBundleId(final UUID bundleId, final TenantContext context) {
return internalCallContextFactory.createInternalTenantContext(bundleId, ObjectType.BUNDLE, context);
}
diff --git a/subscription/src/main/java/org/killbill/billing/subscription/api/user/SubscriptionAndAddOnsSpecifier.java b/subscription/src/main/java/org/killbill/billing/subscription/api/user/SubscriptionAndAddOnsSpecifier.java
new file mode 100644
index 0000000..9d9af7c
--- /dev/null
+++ b/subscription/src/main/java/org/killbill/billing/subscription/api/user/SubscriptionAndAddOnsSpecifier.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2016 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
+ * License. You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.killbill.billing.subscription.api.user;
+
+import java.util.List;
+
+public class SubscriptionAndAddOnsSpecifier {
+
+ private List<SubscriptionSpecifier> subscriptionSpecifiers;
+
+ public SubscriptionAndAddOnsSpecifier() {
+ }
+
+ public SubscriptionAndAddOnsSpecifier(final List<SubscriptionSpecifier> subscriptionSpecifiers) {
+ this.subscriptionSpecifiers = subscriptionSpecifiers;
+ }
+
+ public List<SubscriptionSpecifier> getSubscriptionSpecifiers() {
+ return subscriptionSpecifiers;
+ }
+
+ public void setSubscriptionSpecifiers(final List<SubscriptionSpecifier> subscriptionSpecifiers) {
+ this.subscriptionSpecifiers = subscriptionSpecifiers;
+ }
+}
diff --git a/subscription/src/main/java/org/killbill/billing/subscription/engine/dao/DefaultSubscriptionDao.java b/subscription/src/main/java/org/killbill/billing/subscription/engine/dao/DefaultSubscriptionDao.java
index 8899098..cd3a84a 100644
--- a/subscription/src/main/java/org/killbill/billing/subscription/engine/dao/DefaultSubscriptionDao.java
+++ b/subscription/src/main/java/org/killbill/billing/subscription/engine/dao/DefaultSubscriptionDao.java
@@ -513,34 +513,57 @@ public class DefaultSubscriptionDao extends EntityDaoBase<SubscriptionBundleMode
}
@Override
- public void createSubscriptionWithAddOns(final List<DefaultSubscriptionBase> subscriptions, final Map<UUID, List<SubscriptionBaseEvent>> initialEventsMap, final InternalCallContext context) {
+ public void createSubscriptionsWithAddOns(final List<List<DefaultSubscriptionBase>> subscriptionsWithAddOns,
+ final Map<UUID, List<SubscriptionBaseEvent>> initialEventsMap,
+ final InternalCallContext context) {
transactionalSqlDao.execute(new EntitySqlDaoTransactionWrapper<Void>() {
@Override
public Void inTransaction(final EntitySqlDaoWrapperFactory entitySqlDaoWrapperFactory) throws Exception {
+
final SubscriptionSqlDao transactional = entitySqlDaoWrapperFactory.become(SubscriptionSqlDao.class);
final SubscriptionEventSqlDao eventsDaoFromSameTransaction = entitySqlDaoWrapperFactory.become(SubscriptionEventSqlDao.class);
- for (DefaultSubscriptionBase subscription : subscriptions) {
- transactional.create(new SubscriptionModelDao(subscription), context);
-
- final List<SubscriptionBaseEvent> initialEvents = initialEventsMap.get(subscription.getId());
- for (final SubscriptionBaseEvent cur : initialEvents) {
- eventsDaoFromSameTransaction.create(new SubscriptionEventModelDao(cur), context);
+ for (List<DefaultSubscriptionBase> subscriptionWithAddOns : subscriptionsWithAddOns) {
+ createSubscription(entitySqlDaoWrapperFactory, transactional, eventsDaoFromSameTransaction, subscriptionWithAddOns, context, initialEventsMap);
+ }
+ return null;
+ }
+ });
+ }
- final boolean isBusEvent = cur.getEffectiveDate().compareTo(clock.getUTCNow()) <= 0 && (cur.getType() == EventType.API_USER);
- recordBusOrFutureNotificationFromTransaction(subscription, cur, entitySqlDaoWrapperFactory, isBusEvent, 0, context);
+ @Override
+ public void createSubscriptionWithAddOns(final List<DefaultSubscriptionBase> subscriptions, final Map<UUID, List<SubscriptionBaseEvent>> initialEventsMap, final InternalCallContext context) {
+ transactionalSqlDao.execute(new EntitySqlDaoTransactionWrapper<Void>() {
+ @Override
+ public Void inTransaction(final EntitySqlDaoWrapperFactory entitySqlDaoWrapperFactory) throws Exception {
+ final SubscriptionSqlDao transactional = entitySqlDaoWrapperFactory.become(SubscriptionSqlDao.class);
+ final SubscriptionEventSqlDao eventsDaoFromSameTransaction = entitySqlDaoWrapperFactory.become(SubscriptionEventSqlDao.class);
- }
- // Notify the Bus of the latest requested change, if needed
- if (initialEvents.size() > 0) {
- notifyBusOfRequestedChange(entitySqlDaoWrapperFactory, subscription, initialEvents.get(initialEvents.size() - 1), SubscriptionBaseTransitionType.CREATE, context);
- }
- }
+ createSubscription(entitySqlDaoWrapperFactory, transactional, eventsDaoFromSameTransaction, subscriptions, context, initialEventsMap);
return null;
}
});
}
+ private void createSubscription(final EntitySqlDaoWrapperFactory entitySqlDaoWrapperFactory, final SubscriptionSqlDao transactional, final SubscriptionEventSqlDao eventsDaoFromSameTransaction, final List<DefaultSubscriptionBase> subscriptions, final InternalCallContext context, final Map<UUID, List<SubscriptionBaseEvent>> initialEventsMap) throws EntityPersistenceException {
+ for (DefaultSubscriptionBase subscription : subscriptions) {
+ transactional.create(new SubscriptionModelDao(subscription), context);
+
+ final List<SubscriptionBaseEvent> initialEvents = initialEventsMap.get(subscription.getId());
+ for (final SubscriptionBaseEvent cur : initialEvents) {
+ eventsDaoFromSameTransaction.create(new SubscriptionEventModelDao(cur), context);
+
+ final boolean isBusEvent = cur.getEffectiveDate().compareTo(clock.getUTCNow()) <= 0 && (cur.getType() == EventType.API_USER);
+ recordBusOrFutureNotificationFromTransaction(subscription, cur, entitySqlDaoWrapperFactory, isBusEvent, 0, context);
+
+ }
+ // Notify the Bus of the latest requested change, if needed
+ if (initialEvents.size() > 0) {
+ notifyBusOfRequestedChange(entitySqlDaoWrapperFactory, subscription, initialEvents.get(initialEvents.size() - 1), SubscriptionBaseTransitionType.CREATE, context);
+ }
+ }
+ }
+
@Override
public void cancelSubscriptionsOnBasePlanEvent(final DefaultSubscriptionBase subscription, final SubscriptionBaseEvent event, final List<DefaultSubscriptionBase> subscriptions, final List<SubscriptionBaseEvent> cancelEvents, final InternalCallContext context) {
transactionalSqlDao.execute(new EntitySqlDaoTransactionWrapper<Void>() {
diff --git a/subscription/src/main/java/org/killbill/billing/subscription/engine/dao/SubscriptionDao.java b/subscription/src/main/java/org/killbill/billing/subscription/engine/dao/SubscriptionDao.java
index 846be18..d08cd40 100644
--- a/subscription/src/main/java/org/killbill/billing/subscription/engine/dao/SubscriptionDao.java
+++ b/subscription/src/main/java/org/killbill/billing/subscription/engine/dao/SubscriptionDao.java
@@ -83,6 +83,8 @@ public interface SubscriptionDao extends EntityDao<SubscriptionBundleModelDao, S
public void createSubscriptionWithAddOns(List<DefaultSubscriptionBase> subscriptions, Map<UUID, List<SubscriptionBaseEvent>> initialEventsMap, InternalCallContext context);
+ public void createSubscriptionsWithAddOns(List<List<DefaultSubscriptionBase>> subscriptionsWithAddOns, Map<UUID, List<SubscriptionBaseEvent>> initialEventsMap, InternalCallContext context);
+
public void cancelSubscriptionsOnBasePlanEvent(DefaultSubscriptionBase subscription, SubscriptionBaseEvent event, List<DefaultSubscriptionBase> subscriptions, List<SubscriptionBaseEvent> cancelEvents, InternalCallContext context);
public void cancelSubscriptions(List<DefaultSubscriptionBase> subscriptions, List<SubscriptionBaseEvent> cancelEvents, InternalCallContext context);
diff --git a/subscription/src/test/java/org/killbill/billing/subscription/engine/dao/MockSubscriptionDaoMemory.java b/subscription/src/test/java/org/killbill/billing/subscription/engine/dao/MockSubscriptionDaoMemory.java
index b3bde6d..6291b97 100644
--- a/subscription/src/test/java/org/killbill/billing/subscription/engine/dao/MockSubscriptionDaoMemory.java
+++ b/subscription/src/test/java/org/killbill/billing/subscription/engine/dao/MockSubscriptionDaoMemory.java
@@ -239,6 +239,26 @@ public class MockSubscriptionDaoMemory extends MockEntityDaoBase<SubscriptionBun
}
@Override
+ public void createSubscriptionsWithAddOns(final List<List<DefaultSubscriptionBase>> subscriptionsWithAddOns,
+ final Map<UUID, List<SubscriptionBaseEvent>> initialEventsMap,
+ final InternalCallContext context) {
+ synchronized (events) {
+ for (List<DefaultSubscriptionBase> subscriptionAndAddOns : subscriptionsWithAddOns) {
+ for (DefaultSubscriptionBase subscription : subscriptionAndAddOns) {
+ final List<SubscriptionBaseEvent> initialEvents = initialEventsMap.get(subscription.getId());
+ events.addAll(initialEvents);
+ for (final SubscriptionBaseEvent cur : initialEvents) {
+ recordFutureNotificationFromTransaction(null, cur.getEffectiveDate(), new SubscriptionNotificationKey(cur.getId()), context);
+ }
+ final SubscriptionBase updatedSubscription = buildSubscription(subscription, context);
+ this.subscriptions.add(updatedSubscription);
+ mockNonEntityDao.addTenantRecordIdMapping(updatedSubscription.getId(), context);
+ }
+ }
+ }
+ }
+
+ @Override
public List<SubscriptionBase> getSubscriptions(final UUID bundleId, final List<SubscriptionBaseEvent> dryRunEvents, final InternalTenantContext context) {
final List<SubscriptionBase> results = new ArrayList<SubscriptionBase>();
for (final SubscriptionBase cur : subscriptions) {