diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/api/DefaultSubscriptionApi.java b/entitlement/src/main/java/com/ning/billing/entitlement/api/DefaultSubscriptionApi.java
index e599a4f..34ddd2b 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/api/DefaultSubscriptionApi.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/api/DefaultSubscriptionApi.java
@@ -24,7 +24,6 @@ import java.util.List;
import java.util.Set;
import java.util.UUID;
-import javax.annotation.Nullable;
import javax.inject.Inject;
import org.joda.time.DateTimeZone;
@@ -46,7 +45,6 @@ import com.ning.billing.util.svcapi.subscription.SubscriptionBaseInternalApi;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.collect.Collections2;
-import com.google.common.collect.Iterables;
import com.google.common.collect.LinkedListMultimap;
import com.google.common.collect.ListMultimap;
@@ -153,6 +151,28 @@ public class DefaultSubscriptionApi implements SubscriptionApi {
}
@Override
+ public List<SubscriptionBundle> getSubscriptionBundlesForExternalKey(final String externalKey, final TenantContext context) throws SubscriptionApiException {
+
+ final InternalTenantContext internalContext = internalCallContextFactory.createInternalTenantContext(context);
+ try {
+ final List<SubscriptionBaseBundle> baseBundles = subscriptionInternalApi.getBundlesForKey(externalKey, internalContext);
+ final List<SubscriptionBundle> result = new ArrayList<SubscriptionBundle>(baseBundles.size());
+ for (SubscriptionBaseBundle cur : baseBundles) {
+ final List<Entitlement> allEntitlementsForBundle = entitlementApi.getAllEntitlementsForBundle(cur.getId(), context);
+ final SubscriptionBundle bundle = getSubscriptionBundleFromEntitlements(cur.getId(), allEntitlementsForBundle, context);
+ result.add(bundle);
+ }
+ return result;
+ } catch (SubscriptionBaseApiException e) {
+ throw new SubscriptionApiException(e);
+ } catch (EntitlementApiException e) {
+ throw new SubscriptionApiException(e);
+ } catch (AccountApiException e) {
+ throw new SubscriptionApiException(e);
+ }
+ }
+
+ @Override
public List<SubscriptionBundle> getSubscriptionBundlesForAccountId(final UUID accountId,
final TenantContext context) throws SubscriptionApiException {
try {
@@ -161,19 +181,7 @@ public class DefaultSubscriptionApi implements SubscriptionApi {
if (entitlements.isEmpty()) {
return Collections.emptyList();
}
-
- final ListMultimap<UUID, Entitlement> perBundleEntitlements = LinkedListMultimap.create();
- for (Entitlement cur : entitlements) {
- perBundleEntitlements.put(cur.getBundleId(), cur);
- }
-
- final List<SubscriptionBundle> result = new ArrayList<SubscriptionBundle>(perBundleEntitlements.keySet().size());
- for (UUID bundleId : perBundleEntitlements.keySet()) {
- final List<Entitlement> e = perBundleEntitlements.get(bundleId);
- final SubscriptionBundle b = getSubscriptionBundleFromEntitlements(bundleId, e, context);
- result.add(b);
- }
- return result;
+ return getSubscriptionBundles(entitlements, context);
} catch (EntitlementApiException e) {
throw new SubscriptionApiException(e);
} catch (SubscriptionBaseApiException e) {
@@ -183,6 +191,21 @@ public class DefaultSubscriptionApi implements SubscriptionApi {
}
}
+ private List<SubscriptionBundle> getSubscriptionBundles(final List<Entitlement> entitlements, final TenantContext context) throws SubscriptionBaseApiException, AccountApiException {
+ final ListMultimap<UUID, Entitlement> perBundleEntitlements = LinkedListMultimap.create();
+ for (Entitlement cur : entitlements) {
+ perBundleEntitlements.put(cur.getBundleId(), cur);
+ }
+
+ final List<SubscriptionBundle> result = new ArrayList<SubscriptionBundle>(perBundleEntitlements.keySet().size());
+ for (UUID bundleId : perBundleEntitlements.keySet()) {
+ final List<Entitlement> allEntitlementsForBundle = perBundleEntitlements.get(bundleId);
+ final SubscriptionBundle bundle = getSubscriptionBundleFromEntitlements(bundleId, allEntitlementsForBundle, context);
+ result.add(bundle);
+ }
+ return result;
+ }
+
private Subscription fromEntitlement(final Entitlement entitlement, final InternalTenantContext internalTenantContext) {
final List<BlockingState> states = blockingStateDao.getBlockingState(entitlement.getId(), internalTenantContext);
@@ -225,7 +248,7 @@ public class DefaultSubscriptionApi implements SubscriptionApi {
}));
final SubscriptionBundleTimeline timeline = new DefaultSubscriptionBundleTimeline(accountTimeZone, account.getId(), bundleId, baseBundle.getExternalKey(), entitlements, filteredBlockingStates);
- final DefaultSubscriptionBundle bundle = new DefaultSubscriptionBundle(bundleId, baseBundle.getAccountId(), baseBundle.getExternalKey(), subscriptions, timeline, baseBundle.getCreatedDate(), baseBundle.getUpdatedDate());
+ final DefaultSubscriptionBundle bundle = new DefaultSubscriptionBundle(bundleId, baseBundle.getAccountId(), baseBundle.getExternalKey(), subscriptions, timeline, baseBundle.getOriginalCreatedDate() , baseBundle.getCreatedDate(), baseBundle.getUpdatedDate());
return bundle;
}
}
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/api/DefaultSubscriptionBundle.java b/entitlement/src/main/java/com/ning/billing/entitlement/api/DefaultSubscriptionBundle.java
index 8cd38f9..a75713e 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/api/DefaultSubscriptionBundle.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/api/DefaultSubscriptionBundle.java
@@ -30,13 +30,16 @@ public class DefaultSubscriptionBundle implements SubscriptionBundle {
private final SubscriptionBundleTimeline bundleTimeline;
private final DateTime createdDate;
private final DateTime updatedDate;
+ private final DateTime originalCreatedDate;
- public DefaultSubscriptionBundle(final UUID id, final UUID accountId, final String externalKey, final List<Subscription> subscriptions, final SubscriptionBundleTimeline bundleTimeline, final DateTime createdDate, final DateTime updatedDate) {
+ public DefaultSubscriptionBundle(final UUID id, final UUID accountId, final String externalKey, final List<Subscription> subscriptions, final SubscriptionBundleTimeline bundleTimeline,
+ final DateTime originalCreatedDate, final DateTime createdDate, final DateTime updatedDate) {
this.id = id;
this.accountId = accountId;
this.externalKey = externalKey;
this.subscriptions = subscriptions;
this.bundleTimeline = bundleTimeline;
+ this.originalCreatedDate = originalCreatedDate;
this.createdDate = createdDate;
this.updatedDate = updatedDate;
}
@@ -52,6 +55,11 @@ public class DefaultSubscriptionBundle implements SubscriptionBundle {
}
@Override
+ public DateTime getOriginalCreatedDate() {
+ return originalCreatedDate;
+ }
+
+ @Override
public List<Subscription> getSubscriptions() {
return subscriptions;
}
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/TestDefaultSubscriptionApi.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/TestDefaultSubscriptionApi.java
new file mode 100644
index 0000000..6af89f5
--- /dev/null
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/TestDefaultSubscriptionApi.java
@@ -0,0 +1,120 @@
+package com.ning.billing.entitlement.api;
+
+import java.util.List;
+
+import org.joda.time.LocalDate;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import com.ning.billing.account.api.Account;
+import com.ning.billing.account.api.AccountApiException;
+import com.ning.billing.catalog.api.BillingPeriod;
+import com.ning.billing.catalog.api.PlanPhaseSpecifier;
+import com.ning.billing.catalog.api.PriceListSet;
+import com.ning.billing.catalog.api.ProductCategory;
+import com.ning.billing.entitlement.EntitlementTestSuiteWithEmbeddedDB;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNull;
+
+public class TestDefaultSubscriptionApi extends EntitlementTestSuiteWithEmbeddedDB {
+
+
+ @Test(groups = "slow")
+ public void testWithMultipleBundle() {
+
+ try {
+
+
+ final String externalKey = "fooXXX";
+
+ final LocalDate initialDate = new LocalDate(2013, 8, 7);
+ clock.setDay(initialDate);
+
+ final Account account = accountApi.createAccount(getAccountData(7), callContext);
+
+ final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Shotgun", ProductCategory.BASE, BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null);
+
+ // Create entitlement and check each field
+ final Entitlement entitlement = entitlementApi.createBaseEntitlement(account.getId(), spec, externalKey, initialDate, callContext);
+ assertEquals(entitlement.getAccountId(), account.getId());
+ assertEquals(entitlement.getExternalKey(), externalKey);
+
+ assertEquals(entitlement.getEffectiveStartDate(), initialDate);
+ assertNull(entitlement.getEffectiveEndDate());
+
+ final List<SubscriptionBundle> bundles = subscriptionApi.getSubscriptionBundlesForExternalKey(externalKey, callContext);
+ assertEquals(bundles.size(), 1);
+
+ // Cancel entitlement
+ clock.addDays(3);
+ entitlement.cancelEntitlementWithDate(new LocalDate(clock.getUTCNow(), account.getTimeZone()), true, callContext);
+
+ clock.addDays(1);
+ // Re-create a new bundle with same externalKey
+ final PlanPhaseSpecifier spec2 = new PlanPhaseSpecifier("Pistol", ProductCategory.BASE, BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null);
+
+ // Create entitlement and check each field
+ final Entitlement entitlement2 = entitlementApi.createBaseEntitlement(account.getId(), spec2, externalKey, new LocalDate(clock.getUTCNow(), account.getTimeZone()), callContext);
+ assertEquals(entitlement2.getAccountId(), account.getId());
+ assertEquals(entitlement2.getExternalKey(), externalKey);
+
+ final List<SubscriptionBundle> bundles2 = subscriptionApi.getSubscriptionBundlesForExternalKey(externalKey, callContext);
+ assertEquals(bundles2.size(), 2);
+
+ SubscriptionBundle firstbundle = bundles2.get(0);
+ assertEquals(firstbundle.getSubscriptions().size(), 1);
+ assertEquals(firstbundle.getSubscriptions().get(0).getEffectiveStartDate(), new LocalDate(2013, 8, 7));
+ assertEquals(firstbundle.getSubscriptions().get(0).getBillingStartDate(), new LocalDate(2013, 8, 7));
+ assertEquals(firstbundle.getSubscriptions().get(0).getEffectiveEndDate(), new LocalDate(2013, 8, 10));
+ assertEquals(firstbundle.getSubscriptions().get(0).getBillingEndDate(), new LocalDate(2013, 8, 10));
+
+ SubscriptionBundle secondbundle = bundles2.get(1);
+ assertEquals(secondbundle.getSubscriptions().size(), 1);
+ assertEquals(secondbundle.getSubscriptions().get(0).getEffectiveStartDate(), new LocalDate(2013, 8, 11));
+ assertEquals(secondbundle.getSubscriptions().get(0).getBillingStartDate(), new LocalDate(2013, 8, 11));
+ assertNull(secondbundle.getSubscriptions().get(0).getEffectiveEndDate());
+ assertNull(secondbundle.getSubscriptions().get(0).getBillingEndDate());
+ assertEquals(secondbundle.getOriginalCreatedDate().compareTo(firstbundle.getCreatedDate()), 0);
+
+
+ clock.addDays(3);
+ final Account account2 = accountApi.createAccount(getAccountData(7), callContext);
+
+ entitlementApi.transferEntitlements(account.getId(), account2.getId(), externalKey, new LocalDate(clock.getUTCNow(), account.getTimeZone()), callContext);
+
+ final List<SubscriptionBundle> bundles3 = subscriptionApi.getSubscriptionBundlesForExternalKey(externalKey, callContext);
+ assertEquals(bundles3.size(), 3);
+
+ firstbundle = bundles3.get(0);
+ assertEquals(firstbundle.getSubscriptions().size(), 1);
+ assertEquals(firstbundle.getSubscriptions().get(0).getEffectiveStartDate(), new LocalDate(2013, 8, 7));
+ assertEquals(firstbundle.getSubscriptions().get(0).getBillingStartDate(), new LocalDate(2013, 8, 7));
+ assertEquals(firstbundle.getSubscriptions().get(0).getEffectiveEndDate(), new LocalDate(2013, 8, 10));
+ assertEquals(firstbundle.getSubscriptions().get(0).getBillingEndDate(), new LocalDate(2013, 8, 10));
+
+ secondbundle = bundles3.get(1);
+ assertEquals(secondbundle.getSubscriptions().size(), 1);
+ assertEquals(secondbundle.getSubscriptions().get(0).getEffectiveStartDate(), new LocalDate(2013, 8, 11));
+ assertEquals(secondbundle.getSubscriptions().get(0).getBillingStartDate(), new LocalDate(2013, 8, 11));
+ assertEquals(secondbundle.getSubscriptions().get(0).getEffectiveEndDate(), new LocalDate(2013, 8, 14));
+ assertEquals(secondbundle.getSubscriptions().get(0).getBillingEndDate(), new LocalDate(2013, 8, 14));
+ assertEquals(secondbundle.getOriginalCreatedDate().compareTo(firstbundle.getCreatedDate()), 0);
+
+ SubscriptionBundle thirdBundle = bundles3.get(2);
+ assertEquals(thirdBundle.getSubscriptions().size(), 1);
+ assertEquals(thirdBundle.getSubscriptions().get(0).getEffectiveStartDate(), new LocalDate(2013, 8, 14));
+ assertEquals(thirdBundle.getSubscriptions().get(0).getBillingStartDate(), new LocalDate(2013, 8, 14));
+ assertNull(thirdBundle.getSubscriptions().get(0).getEffectiveEndDate());
+ assertNull(thirdBundle.getSubscriptions().get(0).getBillingEndDate());
+ assertEquals(thirdBundle.getOriginalCreatedDate().compareTo(firstbundle.getCreatedDate()), 0);
+
+ } catch (EntitlementApiException e) {
+ Assert.fail("Test failed " + e.getMessage());
+ } catch (AccountApiException e) {
+ Assert.fail("Test failed " + e.getMessage());
+ } catch (SubscriptionApiException e) {
+ Assert.fail("Test failed " + e.getMessage());
+ }
+ }
+}