Details
diff --git a/api/src/main/java/com/ning/billing/entitlement/api/user/Subscription.java b/api/src/main/java/com/ning/billing/entitlement/api/user/Subscription.java
index e75ea1b..cb8993d 100644
--- a/api/src/main/java/com/ning/billing/entitlement/api/user/Subscription.java
+++ b/api/src/main/java/com/ning/billing/entitlement/api/user/Subscription.java
@@ -58,6 +58,8 @@ public interface Subscription extends Entity, Blockable {
public DateTime getEndDate();
+ public DateTime getFutureEndDate();
+
public Plan getCurrentPlan();
public PriceList getCurrentPriceList();
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionData.java b/entitlement/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionData.java
index d5586e9..58fe83c 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionData.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionData.java
@@ -146,6 +146,24 @@ public class SubscriptionData extends EntityBase implements Subscription {
}
@Override
+ public DateTime getFutureEndDate() {
+ if (transitions == null) {
+ return null;
+ }
+ final SubscriptionTransitionDataIterator it = new SubscriptionTransitionDataIterator(
+ clock, transitions, Order.ASC_FROM_PAST, Kind.ENTITLEMENT,
+ Visibility.ALL, TimeLimit.FUTURE_ONLY);
+ while (it.hasNext()) {
+ final SubscriptionTransitionData cur = it.next();
+ if (cur.getTransitionType() == SubscriptionTransitionType.CANCEL) {
+ return cur.getEffectiveTransitionTime();
+ }
+ }
+ return null;
+ }
+
+
+ @Override
public boolean cancel(final DateTime requestedDate, final boolean eot,
final CallContext context) throws EntitlementUserApiException {
return apiService.cancel(this, requestedDate, eot, context);
@@ -264,6 +282,7 @@ public class SubscriptionData extends EntityBase implements Subscription {
return true;
}
+ @Override
public List<EffectiveSubscriptionEvent> getBillingTransitions() {
if (transitions == null) {
@@ -343,20 +362,9 @@ public class SubscriptionData extends EntityBase implements Subscription {
throw new EntitlementError(String.format("Failed to find InitialTransitionForCurrentPlan id = %s", getId()));
}
+
public boolean isSubscriptionFutureCancelled() {
- if (transitions == null) {
- return false;
- }
- final SubscriptionTransitionDataIterator it = new SubscriptionTransitionDataIterator(
- clock, transitions, Order.ASC_FROM_PAST, Kind.ENTITLEMENT,
- Visibility.ALL, TimeLimit.FUTURE_ONLY);
- while (it.hasNext()) {
- final SubscriptionTransitionData cur = it.next();
- if (cur.getTransitionType() == SubscriptionTransitionType.CANCEL) {
- return true;
- }
- }
- return false;
+ return getFutureEndDate() != null;
}
public DateTime getPlanChangeEffectiveDate(final ActionPolicy policy,
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCancel.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCancel.java
index afebb34..879bb90 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCancel.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCancel.java
@@ -117,6 +117,9 @@ public abstract class TestUserApiCancel extends TestApiBase {
assertFalse(testListener.isCompleted(3000));
testListener.reset();
+ DateTime futureEndDate = subscription.getFutureEndDate();
+ Assert.assertNotNull(futureEndDate);
+
// MOVE TO EOT + RECHECK
testListener.pushExpectedEvent(NextEvent.CANCEL);
it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusMonths(1));
@@ -124,6 +127,8 @@ public abstract class TestUserApiCancel extends TestApiBase {
final DateTime future = clock.getUTCNow();
assertTrue(testListener.isCompleted(5000));
+ assertTrue(futureEndDate.compareTo(subscription.getEndDate()) == 0);
+
final PlanPhase currentPhase = subscription.getCurrentPhase();
assertNull(currentPhase);
checkNextPhaseChange(subscription, 0, null);
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/SubscriptionJsonNoEvents.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/SubscriptionJsonNoEvents.java
index 3c7b2f6..988daed 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/SubscriptionJsonNoEvents.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/SubscriptionJsonNoEvents.java
@@ -39,6 +39,8 @@ public class SubscriptionJsonNoEvents extends SubscriptionJsonSimple {
private final DateTime chargedThroughDate;
+ private final DateTime cancelledDate;
+
@JsonCreator
public SubscriptionJsonNoEvents(@JsonProperty("subscriptionId") @Nullable final String subscriptionId,
@JsonProperty("bundleId") @Nullable final String bundleId,
@@ -47,7 +49,8 @@ public class SubscriptionJsonNoEvents extends SubscriptionJsonSimple {
@JsonProperty("productCategory") @Nullable final String productCategory,
@JsonProperty("billingPeriod") @Nullable final String billingPeriod,
@JsonProperty("priceList") @Nullable final String priceList,
- @JsonProperty("chargedThroughDate") @Nullable final DateTime chargedThroughDate) {
+ @JsonProperty("chargedThroughDate") @Nullable final DateTime chargedThroughDate,
+ @JsonProperty("cancelledDate") @Nullable final DateTime cancelledDate) {
super(subscriptionId);
this.bundleId = bundleId;
this.startDate = startDate;
@@ -56,18 +59,21 @@ public class SubscriptionJsonNoEvents extends SubscriptionJsonSimple {
this.billingPeriod = billingPeriod;
this.priceList = priceList;
this.chargedThroughDate = chargedThroughDate;
+ this.cancelledDate = cancelledDate;
}
public SubscriptionJsonNoEvents() {
- this(null, null, null, null, null, null, null, null);
+ this(null, null, null, null, null, null, null, null, null);
}
public SubscriptionJsonNoEvents(final Subscription data) {
this(data.getId().toString(), data.getBundleId().toString(), data.getStartDate(), data.getCurrentPlan().getProduct().getName(),
data.getCurrentPlan().getProduct().getCategory().toString(), data.getCurrentPlan().getBillingPeriod().toString(),
- data.getCurrentPriceList().getName(), data.getChargedThroughDate());
+ data.getCurrentPriceList().getName(), data.getChargedThroughDate(),
+ data.getEndDate() != null ? data.getEndDate() : data.getFutureEndDate());
}
+ @Override
public String getSubscriptionId() {
return subscriptionId;
}
@@ -100,6 +106,10 @@ public class SubscriptionJsonNoEvents extends SubscriptionJsonSimple {
return chargedThroughDate;
}
+ public DateTime getCancelledDate() {
+ return cancelledDate;
+ }
+
@Override
public String toString() {
return "SubscriptionJson [subscriptionId=" + subscriptionId
diff --git a/jaxrs/src/test/java/com/ning/billing/jaxrs/json/TestSubscriptionJsonNoEvents.java b/jaxrs/src/test/java/com/ning/billing/jaxrs/json/TestSubscriptionJsonNoEvents.java
index 42d0794..c663b30 100644
--- a/jaxrs/src/test/java/com/ning/billing/jaxrs/json/TestSubscriptionJsonNoEvents.java
+++ b/jaxrs/src/test/java/com/ning/billing/jaxrs/json/TestSubscriptionJsonNoEvents.java
@@ -54,9 +54,11 @@ public class TestSubscriptionJsonNoEvents {
final String billingPeriod = UUID.randomUUID().toString();
final String priceList = UUID.randomUUID().toString();
final DateTime chargedThroughDate = new DateTime(DateTimeZone.UTC);
+ final DateTime endDate = new DateTime(DateTimeZone.UTC);
+
final SubscriptionJsonNoEvents subscriptionJsonNoEvents = new SubscriptionJsonNoEvents(subscriptionId, bundleId, startDate,
productName, productCategory, billingPeriod,
- priceList, chargedThroughDate);
+ priceList, chargedThroughDate, endDate);
Assert.assertEquals(subscriptionJsonNoEvents.getSubscriptionId(), subscriptionId);
Assert.assertEquals(subscriptionJsonNoEvents.getBundleId(), bundleId);
Assert.assertEquals(subscriptionJsonNoEvents.getStartDate(), startDate);
@@ -74,7 +76,8 @@ public class TestSubscriptionJsonNoEvents {
"\"productCategory\":\"" + subscriptionJsonNoEvents.getProductCategory() + "\"," +
"\"billingPeriod\":\"" + subscriptionJsonNoEvents.getBillingPeriod() + "\"," +
"\"priceList\":\"" + subscriptionJsonNoEvents.getPriceList() + "\"," +
- "\"chargedThroughDate\":\"" + subscriptionJsonNoEvents.getChargedThroughDate().toDateTimeISO().toString() + "\"}");
+ "\"chargedThroughDate\":\"" + subscriptionJsonNoEvents.getChargedThroughDate().toDateTimeISO().toString() + "\"," +
+ "\"cancelledDate\":\"" + subscriptionJsonNoEvents.getCancelledDate().toDateTimeISO().toString() + "\"}");
final SubscriptionJsonNoEvents fromJson = mapper.readValue(asJson, SubscriptionJsonNoEvents.class);
Assert.assertEquals(fromJson, subscriptionJsonNoEvents);
diff --git a/junction/src/main/java/com/ning/billing/junction/plumbing/api/BlockingSubscription.java b/junction/src/main/java/com/ning/billing/junction/plumbing/api/BlockingSubscription.java
index fb41a88..bfce70b 100644
--- a/junction/src/main/java/com/ning/billing/junction/plumbing/api/BlockingSubscription.java
+++ b/junction/src/main/java/com/ning/billing/junction/plumbing/api/BlockingSubscription.java
@@ -49,18 +49,22 @@ public class BlockingSubscription implements Subscription {
this.checker = checker;
}
+ @Override
public UUID getId() {
return subscription.getId();
}
+ @Override
public boolean cancel(final DateTime requestedDate, final boolean eot, final CallContext context) throws EntitlementUserApiException {
return subscription.cancel(requestedDate, eot, context);
}
+ @Override
public boolean uncancel(final CallContext context) throws EntitlementUserApiException {
return subscription.uncancel(context);
}
+ @Override
public boolean changePlan(final String productName, final BillingPeriod term, final String planSet, final DateTime requestedDate,
final CallContext context) throws EntitlementUserApiException {
try {
@@ -71,59 +75,78 @@ public class BlockingSubscription implements Subscription {
return subscription.changePlan(productName, term, planSet, requestedDate, context);
}
+ @Override
public boolean recreate(final PlanPhaseSpecifier spec, final DateTime requestedDate, final CallContext context)
throws EntitlementUserApiException {
return subscription.recreate(spec, requestedDate, context);
}
+ @Override
public UUID getBundleId() {
return subscription.getBundleId();
}
+ @Override
public SubscriptionState getState() {
return subscription.getState();
}
+ @Override
public DateTime getStartDate() {
return subscription.getStartDate();
}
+ @Override
public DateTime getEndDate() {
return subscription.getEndDate();
}
+ @Override
+ public DateTime getFutureEndDate() {
+ return subscription.getFutureEndDate();
+ }
+
+ @Override
public Plan getCurrentPlan() {
return subscription.getCurrentPlan();
}
+ @Override
public PriceList getCurrentPriceList() {
return subscription.getCurrentPriceList();
}
+ @Override
public PlanPhase getCurrentPhase() {
return subscription.getCurrentPhase();
}
+ @Override
public DateTime getChargedThroughDate() {
return subscription.getChargedThroughDate();
}
+ @Override
public DateTime getPaidThroughDate() {
return subscription.getPaidThroughDate();
}
+ @Override
public ProductCategory getCategory() {
return subscription.getCategory();
}
+ @Override
public EffectiveSubscriptionEvent getPendingTransition() {
return subscription.getPendingTransition();
}
+ @Override
public EffectiveSubscriptionEvent getPreviousTransition() {
return subscription.getPreviousTransition();
}
+ @Override
public List<EffectiveSubscriptionEvent> getBillingTransitions() {
return subscription.getBillingTransitions();
}
@@ -133,6 +156,7 @@ public class BlockingSubscription implements Subscription {
return subscription.getAllTransitions();
}
+ @Override
public BlockingState getBlockingState() {
if (blockingState == null) {
blockingState = blockingApi.getBlockingStateFor(this);
@@ -143,4 +167,5 @@ public class BlockingSubscription implements Subscription {
public Subscription getDelegateSubscription() {
return subscription;
}
+
}
diff --git a/server/src/test/java/com/ning/billing/jaxrs/TestJaxrsBase.java b/server/src/test/java/com/ning/billing/jaxrs/TestJaxrsBase.java
index 1b7008a..160fa9b 100644
--- a/server/src/test/java/com/ning/billing/jaxrs/TestJaxrsBase.java
+++ b/server/src/test/java/com/ning/billing/jaxrs/TestJaxrsBase.java
@@ -1,4 +1,4 @@
-/*
+/*
* Copyright 2010-2011 Ning, Inc.
*
* Ning licenses this file to you under the Apache License, version 2.0
@@ -192,11 +192,12 @@ public class TestJaxrsBase {
}
}
+ @Override
protected void installKillbillModules() {
/*
* For a lack of getting module override working, copy all install modules from parent class...
- *
+ *
super.installKillbillModules();
Modules.override(new com.ning.billing.payment.setup.PaymentModule()).with(new PaymentMockModule());
*/
@@ -258,7 +259,7 @@ public class TestJaxrsBase {
mapper.registerModule(new JodaModule());
mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
- //mapper.setPropertyNamingStrategy(new PropertyNamingStrategy.LowerCaseWithUnderscoresStrategy());
+ //mapper.setPropertyNamingStrategy(new PropertyNamingStrategy.LowerCaseWithUnderscoresStrategy());
busHandler = new TestApiListener(null);
this.helper = listener.getMysqlTestingHelper();
@@ -427,7 +428,7 @@ public class TestJaxrsBase {
protected SubscriptionJsonNoEvents createSubscription(final String bundleId, final String productName, final String productCategory, final String billingPeriod, final boolean waitCompletion) throws Exception {
- final SubscriptionJsonNoEvents input = new SubscriptionJsonNoEvents(null, bundleId, null, productName, productCategory, billingPeriod, PriceListSet.DEFAULT_PRICELIST_NAME, null);
+ final SubscriptionJsonNoEvents input = new SubscriptionJsonNoEvents(null, bundleId, null, productName, productCategory, billingPeriod, PriceListSet.DEFAULT_PRICELIST_NAME, null, null);
String baseJson = mapper.writeValueAsString(input);
diff --git a/server/src/test/java/com/ning/billing/jaxrs/TestSubscription.java b/server/src/test/java/com/ning/billing/jaxrs/TestSubscription.java
index dff76bd..4997c96 100644
--- a/server/src/test/java/com/ning/billing/jaxrs/TestSubscription.java
+++ b/server/src/test/java/com/ning/billing/jaxrs/TestSubscription.java
@@ -1,4 +1,4 @@
-/*
+/*
* Copyright 2010-2011 Ning, Inc.
*
* Ning licenses this file to you under the Apache License, version 2.0
@@ -36,6 +36,7 @@ import com.ning.billing.jaxrs.resources.JaxrsResource;
import com.ning.http.client.Response;
import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertTrue;
public class TestSubscription extends TestJaxrsBase {
@@ -80,7 +81,7 @@ public class TestSubscription extends TestJaxrsBase {
newProductName,
subscriptionJson.getProductCategory(),
subscriptionJson.getBillingPeriod(),
- subscriptionJson.getPriceList(), null);
+ subscriptionJson.getPriceList(), null, null);
baseJson = mapper.writeValueAsString(newInput);
final Map<String, String> queryParams = getQueryParamsForCallCompletion(CALL_COMPLETION_TIMEOUT_SEC);
@@ -96,12 +97,22 @@ public class TestSubscription extends TestJaxrsBase {
crappyWaitForLackOfProperSynchonization();
- //
+ //
// Cancel EOT
uri = JaxrsResource.SUBSCRIPTIONS_PATH + "/" + subscriptionJson.getSubscriptionId().toString();
response = doDelete(uri, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
+
+ // Retrieves to check EndDate
+ uri = JaxrsResource.SUBSCRIPTIONS_PATH + "/" + subscriptionJson.getSubscriptionId().toString();
+ response = doGet(uri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+ assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
+ baseJson = response.getResponseBody();
+ objFromJson = mapper.readValue(baseJson, SubscriptionJsonNoEvents.class);
+ assertNotNull(objFromJson.getCancelledDate());
+ assertTrue(objFromJson.getCancelledDate().compareTo(clock.getUTCNow()) > 0);
+
// Uncancel
uri = JaxrsResource.SUBSCRIPTIONS_PATH + "/" + subscriptionJson.getSubscriptionId().toString() + "/uncancel";
response = doPut(uri, baseJson, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
@@ -111,7 +122,8 @@ public class TestSubscription extends TestJaxrsBase {
@Test(groups = "slow", enabled = true)
public void testWithNonExistentSubscription() throws Exception {
final String uri = JaxrsResource.SUBSCRIPTIONS_PATH + "/" + UUID.randomUUID().toString();
- final SubscriptionJsonNoEvents subscriptionJson = new SubscriptionJsonNoEvents(null, UUID.randomUUID().toString(), null, "Pistol", ProductCategory.BASE.toString(), BillingPeriod.MONTHLY.toString(), PriceListSet.DEFAULT_PRICELIST_NAME, null);
+ final SubscriptionJsonNoEvents subscriptionJson = new SubscriptionJsonNoEvents(null, UUID.randomUUID().toString(), null, "Pistol", ProductCategory.BASE.toString(), BillingPeriod.MONTHLY.toString(),
+ PriceListSet.DEFAULT_PRICELIST_NAME, null, null);
final String baseJson = mapper.writeValueAsString(subscriptionJson);
Response response = doPut(uri, baseJson, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
diff --git a/util/src/test/java/com/ning/billing/mock/MockSubscription.java b/util/src/test/java/com/ning/billing/mock/MockSubscription.java
index 447cb08..af6628d 100644
--- a/util/src/test/java/com/ning/billing/mock/MockSubscription.java
+++ b/util/src/test/java/com/ning/billing/mock/MockSubscription.java
@@ -66,80 +66,99 @@ public class MockSubscription implements Subscription {
Subscription sub = BrainDeadProxyFactory.createBrainDeadProxyFor(Subscription.class);
+ @Override
public boolean cancel(final DateTime requestedDate, final boolean eot, final CallContext context) throws EntitlementUserApiException {
return sub.cancel(requestedDate, eot, context);
}
+ @Override
public boolean uncancel(final CallContext context) throws EntitlementUserApiException {
return sub.uncancel(context);
}
+ @Override
public boolean changePlan(final String productName, final BillingPeriod term, final String planSet, final DateTime requestedDate,
final CallContext context) throws EntitlementUserApiException {
return sub.changePlan(productName, term, planSet, requestedDate, context);
}
+ @Override
public boolean recreate(final PlanPhaseSpecifier spec, final DateTime requestedDate, final CallContext context)
throws EntitlementUserApiException {
return sub.recreate(spec, requestedDate, context);
}
+ @Override
public UUID getId() {
return id;
}
+ @Override
public UUID getBundleId() {
return bundleId;
}
+ @Override
public SubscriptionState getState() {
return state;
}
+ @Override
public DateTime getStartDate() {
return startDate;
}
+ @Override
public DateTime getEndDate() {
return sub.getEndDate();
}
+ @Override
public Plan getCurrentPlan() {
return plan;
}
+ @Override
public BlockingState getBlockingState() {
return sub.getBlockingState();
}
+ @Override
public PriceList getCurrentPriceList() {
return new MockPriceList();
}
+ @Override
public PlanPhase getCurrentPhase() {
return phase;
}
+ @Override
public DateTime getChargedThroughDate() {
return sub.getChargedThroughDate();
}
+ @Override
public DateTime getPaidThroughDate() {
return sub.getPaidThroughDate();
}
+ @Override
public ProductCategory getCategory() {
return sub.getCategory();
}
+ @Override
public EffectiveSubscriptionEvent getPendingTransition() {
return sub.getPendingTransition();
}
+ @Override
public EffectiveSubscriptionEvent getPreviousTransition() {
return sub.getPreviousTransition();
}
+ @Override
public List<EffectiveSubscriptionEvent> getBillingTransitions() {
return transitions;
}
@@ -148,4 +167,10 @@ public class MockSubscription implements Subscription {
public List<EffectiveSubscriptionEvent> getAllTransitions() {
return transitions;
}
+
+ @Override
+ public DateTime getFutureEndDate() {
+ // TODO Auto-generated method stub
+ return null;
+ }
}