use of org.killbill.billing.catalog.api.PlanPhaseSpecifier in project killbill by killbill.
the class TestDefaultEntitlementApi method testCreateBaseWithEntitlementInThePast.
@Test(groups = "slow")
public void testCreateBaseWithEntitlementInThePast() throws AccountApiException, EntitlementApiException, SubscriptionApiException {
final LocalDate initialDate = new LocalDate(2013, 8, 7);
clock.setDay(initialDate);
final Account account = createAccount(getAccountData(7));
final LocalDate entitlementDate = initialDate.minusDays(3);
final LocalDate billingDate = null;
final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Shotgun", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null);
testListener.pushExpectedEvents(NextEvent.BLOCK, NextEvent.CREATE);
final Entitlement entitlement = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, entitlementDate, billingDate, false, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
assertEquals(entitlement.getState(), EntitlementState.ACTIVE);
assertEquals(entitlement.getEffectiveStartDate(), entitlementDate);
}
use of org.killbill.billing.catalog.api.PlanPhaseSpecifier in project killbill by killbill.
the class SubscriptionResource method createEntitlement.
@TimedResource
@POST
@Consumes(APPLICATION_JSON)
@Produces(APPLICATION_JSON)
@ApiOperation(value = "Create an entitlement")
@ApiResponses(value = { @ApiResponse(code = 400, message = "Invalid entitlement supplied") })
public Response createEntitlement(final SubscriptionJson entitlement, @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_BCD) final Integer newBCD, @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 {
verifyNonNullOrEmpty(entitlement, "SubscriptionJson body should be specified");
if (entitlement.getPlanName() == null) {
verifyNonNullOrEmpty(entitlement.getProductName(), "SubscriptionJson productName needs to be set", entitlement.getProductCategory(), "SubscriptionJson productCategory needs to be set", entitlement.getBillingPeriod(), "SubscriptionJson billingPeriod needs to be set", entitlement.getPriceList(), "SubscriptionJson priceList needs to be set");
}
logDeprecationParameterWarningIfNeeded(QUERY_REQUESTED_DT, QUERY_ENTITLEMENT_REQUESTED_DT, QUERY_BILLING_REQUESTED_DT);
// For ADD_ON we can provide externalKey or the bundleId
final boolean createAddOnEntitlement = ProductCategory.ADD_ON.toString().equals(entitlement.getProductCategory());
if (createAddOnEntitlement) {
Preconditions.checkArgument(entitlement.getExternalKey() != null || entitlement.getBundleId() != null, "SubscriptionJson bundleId or externalKey should be specified for ADD_ON");
}
final Iterable<PluginProperty> pluginProperties = extractPluginProperties(pluginPropertiesString);
final CallContext callContext = context.createContext(createdBy, reason, comment, request);
final EntitlementCallCompletionCallback<Entitlement> callback = new EntitlementCallCompletionCallback<Entitlement>() {
@Override
public Entitlement doOperation(final CallContext ctx) throws InterruptedException, TimeoutException, EntitlementApiException, SubscriptionApiException, AccountApiException {
final Account account = getAccountFromSubscriptionJson(entitlement, callContext);
final PhaseType phaseType = entitlement.getPhaseType() != null ? PhaseType.valueOf(entitlement.getPhaseType()) : null;
final PlanPhaseSpecifier spec = entitlement.getPlanName() != null ? new PlanPhaseSpecifier(entitlement.getPlanName(), phaseType) : new PlanPhaseSpecifier(entitlement.getProductName(), BillingPeriod.valueOf(entitlement.getBillingPeriod()), entitlement.getPriceList(), phaseType);
final LocalDate resolvedEntitlementDate = requestedDate != null ? toLocalDate(requestedDate) : toLocalDate(entitlementDate);
final LocalDate resolvedBillingDate = requestedDate != null ? toLocalDate(requestedDate) : toLocalDate(billingDate);
final List<PlanPhasePriceOverride> overrides = PhasePriceOverrideJson.toPlanPhasePriceOverrides(entitlement.getPriceOverrides(), spec, account.getCurrency());
final Entitlement result = createAddOnEntitlement ? entitlementApi.addEntitlement(getBundleIdForAddOnCreation(entitlement), spec, overrides, resolvedEntitlementDate, resolvedBillingDate, isMigrated, pluginProperties, callContext) : entitlementApi.createBaseEntitlement(account.getId(), spec, entitlement.getExternalKey(), overrides, resolvedEntitlementDate, resolvedBillingDate, isMigrated, pluginProperties, callContext);
if (newBCD != null) {
result.updateBCD(newBCD, null, callContext);
}
return result;
}
private UUID getBundleIdForAddOnCreation(final SubscriptionJson entitlement) throws SubscriptionApiException {
if (entitlement.getBundleId() != null) {
return UUID.fromString(entitlement.getBundleId());
}
// If user only specified the externalKey we need to fech the bundle (expensive operation) to extract the bundleId
final SubscriptionBundle bundle = subscriptionApi.getActiveSubscriptionBundleForExternalKey(entitlement.getExternalKey(), callContext);
return bundle.getId();
}
@Override
public boolean isImmOperation() {
return true;
}
@Override
public Response doResponseOk(final Entitlement createdEntitlement) {
return uriBuilder.buildResponse(uriInfo, SubscriptionResource.class, "getEntitlement", createdEntitlement.getId(), request);
}
};
final EntitlementCallCompletion<Entitlement> callCompletionCreation = new EntitlementCallCompletion<Entitlement>();
return callCompletionCreation.withSynchronization(callback, timeoutSec, callCompletion, callContext);
}
use of org.killbill.billing.catalog.api.PlanPhaseSpecifier in project killbill by killbill.
the class TestDefaultSubscriptionApi method testCancelFutureSubscription.
@Test(groups = "slow")
public void testCancelFutureSubscription() throws AccountApiException, EntitlementApiException, SubscriptionApiException {
final LocalDate initialDate = new LocalDate(2013, 8, 7);
clock.setDay(initialDate);
final Account account = createAccount(getAccountData(7));
final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Shotgun", BillingPeriod.ANNUAL, PriceListSet.DEFAULT_PRICELIST_NAME, null);
final LocalDate futureDate = new LocalDate(2013, 9, 1);
// No CREATE event as this is set in the future
final Entitlement createdEntitlement = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, futureDate, futureDate, false, ImmutableList.<PluginProperty>of(), callContext);
assertEquals(createdEntitlement.getEffectiveStartDate().compareTo(futureDate), 0);
assertEquals(createdEntitlement.getEffectiveEndDate(), null);
final Entitlement baseEntitlement = entitlementApi.getEntitlementForId(createdEntitlement.getId(), callContext);
assertEquals(baseEntitlement.getEffectiveStartDate().compareTo(futureDate), 0);
assertEquals(baseEntitlement.getEffectiveEndDate(), null);
final Entitlement cancelledEntitlement = baseEntitlement.cancelEntitlementWithPolicyOverrideBillingPolicy(EntitlementActionPolicy.IMMEDIATE, BillingActionPolicy.IMMEDIATE, null, callContext);
assertEquals(cancelledEntitlement.getEffectiveEndDate().compareTo(futureDate), 0);
final Subscription subscription = subscriptionApi.getSubscriptionForEntitlementId(cancelledEntitlement.getId(), callContext);
assertEquals(subscription.getEffectiveEndDate().compareTo(futureDate), 0);
assertListenerStatus();
}
use of org.killbill.billing.catalog.api.PlanPhaseSpecifier in project killbill by killbill.
the class TestDefaultSubscriptionApi method testAddBlockingState.
@Test(groups = "slow")
public void testAddBlockingState() throws AccountApiException, EntitlementApiException, SubscriptionApiException {
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", BillingPeriod.ANNUAL, PriceListSet.DEFAULT_PRICELIST_NAME, null);
testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK);
final Entitlement createdEntitlement = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, initialDate, initialDate, false, ImmutableList.<PluginProperty>of(), callContext);
final Iterable<BlockingState> iterableForCreateState = subscriptionApi.getBlockingStates(account.getId(), ImmutableList.of(BlockingStateType.SUBSCRIPTION), null, OrderingType.ASCENDING, SubscriptionApi.ALL_EVENTS, callContext);
assertTrue(iterableForCreateState.iterator().hasNext());
final BlockingState createState = iterableForCreateState.iterator().next();
assertEquals(createState.getService(), EntitlementService.ENTITLEMENT_SERVICE_NAME);
assertListenerStatus();
testListener.pushExpectedEvent(NextEvent.BLOCK);
final BlockingState state1 = new DefaultBlockingState(account.getId(), BlockingStateType.ACCOUNT, "accountBlock", "svc1", false, true, false, clock.getUTCNow());
subscriptionApi.addBlockingState(state1, null, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
Entitlement updateEntitlement = entitlementApi.getEntitlementForId(createdEntitlement.getId(), callContext);
Assert.assertEquals(updateEntitlement.getState(), EntitlementState.BLOCKED);
clock.addDays(1);
testListener.pushExpectedEvent(NextEvent.BLOCK);
final BlockingState state2 = new DefaultBlockingState(createdEntitlement.getId(), BlockingStateType.SUBSCRIPTION, "subscriptionBlock", "svc2", false, false, false, clock.getUTCNow());
subscriptionApi.addBlockingState(state2, null, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
// Still blocked because this is a different service
updateEntitlement = entitlementApi.getEntitlementForId(createdEntitlement.getId(), callContext);
Assert.assertEquals(updateEntitlement.getState(), EntitlementState.BLOCKED);
// Now we remove the blocking state for the same service but at the SUBSCRIPTION level
testListener.pushExpectedEvent(NextEvent.BLOCK);
final BlockingState state3 = new DefaultBlockingState(createdEntitlement.getId(), BlockingStateType.SUBSCRIPTION, "subscriptionUnBlock", "svc1", false, false, false, clock.getUTCNow());
subscriptionApi.addBlockingState(state3, null, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
updateEntitlement = entitlementApi.getEntitlementForId(createdEntitlement.getId(), callContext);
Assert.assertEquals(updateEntitlement.getState(), EntitlementState.BLOCKED);
final DateTime futureEffectiveDate = clock.getUTCNow().plusDays(1);
final BlockingState state4 = new DefaultBlockingState(createdEntitlement.getBundleId(), BlockingStateType.SUBSCRIPTION_BUNDLE, "blockBilling", "svc1", true, false, false, futureEffectiveDate);
subscriptionApi.addBlockingState(state4, internalCallContext.toLocalDate(futureEffectiveDate), ImmutableList.<PluginProperty>of(), callContext);
final Iterable<BlockingState> blockingStates1 = subscriptionApi.getBlockingStates(account.getId(), ImmutableList.of(BlockingStateType.ACCOUNT, BlockingStateType.SUBSCRIPTION), ImmutableList.of("svc1", "svc2"), OrderingType.ASCENDING, SubscriptionApi.PAST_OR_PRESENT_EVENTS, callContext);
verifyBlockingStates(blockingStates1, ImmutableList.<BlockingState>of(state1, state2, state3));
final Iterable<BlockingState> blockingStates2 = subscriptionApi.getBlockingStates(account.getId(), ImmutableList.of(BlockingStateType.SUBSCRIPTION), ImmutableList.of("svc1", "svc2"), OrderingType.DESCENDING, SubscriptionApi.PAST_OR_PRESENT_EVENTS, callContext);
verifyBlockingStates(blockingStates2, ImmutableList.<BlockingState>of(state3, state2));
final Iterable<BlockingState> blockingStates3 = subscriptionApi.getBlockingStates(account.getId(), ImmutableList.of(BlockingStateType.SUBSCRIPTION), ImmutableList.of("svc2"), OrderingType.DESCENDING, SubscriptionApi.PAST_OR_PRESENT_EVENTS, callContext);
verifyBlockingStates(blockingStates3, ImmutableList.<BlockingState>of(state2));
final Iterable<BlockingState> blockingStates4 = subscriptionApi.getBlockingStates(account.getId(), null, null, OrderingType.DESCENDING, SubscriptionApi.ALL_EVENTS, callContext);
verifyBlockingStates(blockingStates4, ImmutableList.<BlockingState>of(state4, state3, state2, state1, createState));
final Iterable<BlockingState> blockingStates5 = subscriptionApi.getBlockingStates(account.getId(), ImmutableList.of(BlockingStateType.SUBSCRIPTION_BUNDLE), null, OrderingType.ASCENDING, SubscriptionApi.FUTURE_EVENTS, callContext);
verifyBlockingStates(blockingStates5, ImmutableList.<BlockingState>of(state4));
testListener.pushExpectedEvent(NextEvent.BLOCK);
clock.addDays(1);
assertListenerStatus();
final Iterable<BlockingState> blockingStates6 = subscriptionApi.getBlockingStates(account.getId(), null, null, OrderingType.ASCENDING, SubscriptionApi.PAST_OR_PRESENT_EVENTS, callContext);
verifyBlockingStates(blockingStates6, ImmutableList.<BlockingState>of(createState, state1, state2, state3, state4));
}
use of org.killbill.billing.catalog.api.PlanPhaseSpecifier in project killbill by killbill.
the class TestDefaultSubscriptionApi method testAuditLogsForEntitlementAndSubscriptionBaseObjects.
@Test(groups = "slow", description = "Test for https://github.com/killbill/killbill/issues/136")
public void testAuditLogsForEntitlementAndSubscriptionBaseObjects() throws AccountApiException, EntitlementApiException, SubscriptionApiException {
final LocalDate initialDate = new LocalDate(2013, 8, 7);
clock.setDay(initialDate);
final Account account = createAccount(getAccountData(7));
// Create entitlement
testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK);
final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Shotgun", BillingPeriod.ANNUAL, PriceListSet.DEFAULT_PRICELIST_NAME, null);
final Entitlement baseEntitlement = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, null, null, false, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
// Get the phase event out of the way
testListener.pushExpectedEvents(NextEvent.PHASE);
clock.setDay(new LocalDate(2013, 9, 7));
assertListenerStatus();
final LocalDate pauseDate = new LocalDate(2013, 9, 17);
entitlementApi.pause(baseEntitlement.getBundleId(), pauseDate, ImmutableList.<PluginProperty>of(), callContext);
testListener.pushExpectedEvents(NextEvent.BLOCK);
clock.setDay(pauseDate);
assertListenerStatus();
final LocalDate resumeDate = new LocalDate(2013, 12, 24);
entitlementApi.resume(baseEntitlement.getBundleId(), resumeDate, ImmutableList.<PluginProperty>of(), callContext);
testListener.pushExpectedEvents(NextEvent.BLOCK);
clock.setDay(resumeDate);
assertListenerStatus();
final LocalDate cancelDate = new LocalDate(2013, 12, 27);
baseEntitlement.cancelEntitlementWithDate(cancelDate, true, ImmutableList.<PluginProperty>of(), callContext);
testListener.pushExpectedEvents(NextEvent.CANCEL, NextEvent.BLOCK);
clock.setDay(cancelDate);
assertListenerStatus();
final SubscriptionBundle bundle = subscriptionApi.getSubscriptionBundle(baseEntitlement.getBundleId(), callContext);
final List<SubscriptionEvent> transitions = bundle.getTimeline().getSubscriptionEvents();
assertEquals(transitions.size(), 9);
checkSubscriptionEventAuditLog(transitions, 0, SubscriptionEventType.START_ENTITLEMENT);
checkSubscriptionEventAuditLog(transitions, 1, SubscriptionEventType.START_BILLING);
checkSubscriptionEventAuditLog(transitions, 2, SubscriptionEventType.PHASE);
checkSubscriptionEventAuditLog(transitions, 3, SubscriptionEventType.PAUSE_ENTITLEMENT);
checkSubscriptionEventAuditLog(transitions, 4, SubscriptionEventType.PAUSE_BILLING);
checkSubscriptionEventAuditLog(transitions, 5, SubscriptionEventType.RESUME_ENTITLEMENT);
checkSubscriptionEventAuditLog(transitions, 6, SubscriptionEventType.RESUME_BILLING);
checkSubscriptionEventAuditLog(transitions, 7, SubscriptionEventType.STOP_ENTITLEMENT);
checkSubscriptionEventAuditLog(transitions, 8, SubscriptionEventType.STOP_BILLING);
}
Aggregations