Search in sources :

Example 41 with DefaultBlockingState

use of org.killbill.billing.junction.DefaultBlockingState in project killbill by killbill.

the class DefaultEntitlement method cancelEntitlementWithDateOverrideBillingPolicy.

// See also EntitlementInternalApi#cancel for the bulk API
@Override
public Entitlement cancelEntitlementWithDateOverrideBillingPolicy(@Nullable final LocalDate entitlementEffectiveDate, final BillingActionPolicy billingPolicy, final Iterable<PluginProperty> properties, final CallContext callContext) throws EntitlementApiException {
    logCancelEntitlement(log, this, entitlementEffectiveDate, null, null, billingPolicy);
    checkForPermissions(Permission.ENTITLEMENT_CAN_CANCEL, callContext);
    // Get the latest state from disk
    refresh(callContext);
    final BaseEntitlementWithAddOnsSpecifier baseEntitlementWithAddOnsSpecifier = new DefaultBaseEntitlementWithAddOnsSpecifier(getBundleId(), getBundleExternalKey(), null, entitlementEffectiveDate, entitlementEffectiveDate, false);
    final List<BaseEntitlementWithAddOnsSpecifier> baseEntitlementWithAddOnsSpecifierList = new ArrayList<BaseEntitlementWithAddOnsSpecifier>();
    baseEntitlementWithAddOnsSpecifierList.add(baseEntitlementWithAddOnsSpecifier);
    final EntitlementContext pluginContext = new DefaultEntitlementContext(OperationType.CANCEL_SUBSCRIPTION, getAccountId(), null, baseEntitlementWithAddOnsSpecifierList, billingPolicy, properties, callContext);
    final WithEntitlementPlugin<Entitlement> cancelEntitlementWithPlugin = new WithEntitlementPlugin<Entitlement>() {

        @Override
        public Entitlement doCall(final EntitlementApi entitlementApi, final DefaultEntitlementContext updatedPluginContext) throws EntitlementApiException {
            if (eventsStream.isEntitlementCancelled()) {
                throw new EntitlementApiException(ErrorCode.SUB_CANCEL_BAD_STATE, getId(), EntitlementState.CANCELLED);
            }
            final InternalCallContext contextWithValidAccountRecordId = internalCallContextFactory.createInternalCallContext(getAccountId(), callContext);
            try {
                // Cancel subscription base first, to correctly compute the add-ons entitlements we need to cancel (see below)
                getSubscriptionBase().cancelWithPolicy(billingPolicy, callContext);
            } catch (final SubscriptionBaseApiException e) {
                throw new EntitlementApiException(e);
            }
            final DateTime effectiveCancelDate = dateHelper.fromLocalDateAndReferenceTimeWithMinimum(entitlementEffectiveDate, getEventsStream().getEntitlementEffectiveStartDateTime(), updatedPluginContext.getCreatedDate(), contextWithValidAccountRecordId);
            final BlockingState newBlockingState = new DefaultBlockingState(getId(), BlockingStateType.SUBSCRIPTION, DefaultEntitlementApi.ENT_STATE_CANCELLED, KILLBILL_SERVICES.ENTITLEMENT_SERVICE.getServiceName(), true, true, false, effectiveCancelDate);
            final Collection<NotificationEvent> notificationEvents = new ArrayList<NotificationEvent>();
            final Collection<BlockingState> addOnsBlockingStates = computeAddOnBlockingStates(effectiveCancelDate, notificationEvents, callContext, contextWithValidAccountRecordId);
            // Record the new state first, then insert the notifications to avoid race conditions
            setBlockingStates(newBlockingState, addOnsBlockingStates, contextWithValidAccountRecordId);
            for (final NotificationEvent notificationEvent : notificationEvents) {
                recordFutureNotification(effectiveCancelDate, notificationEvent, contextWithValidAccountRecordId);
            }
            return entitlementApi.getEntitlementForId(getId(), callContext);
        }
    };
    return pluginExecution.executeWithPlugin(cancelEntitlementWithPlugin, pluginContext);
}
Also used : WithEntitlementPlugin(org.killbill.billing.entitlement.api.EntitlementPluginExecution.WithEntitlementPlugin) ArrayList(java.util.ArrayList) NotificationEvent(org.killbill.notificationq.api.NotificationEvent) InternalCallContext(org.killbill.billing.callcontext.InternalCallContext) DefaultBlockingState(org.killbill.billing.junction.DefaultBlockingState) DateTime(org.joda.time.DateTime) EntitlementLoggingHelper.logCancelEntitlement(org.killbill.billing.entitlement.logging.EntitlementLoggingHelper.logCancelEntitlement) EntitlementLoggingHelper.logUncancelEntitlement(org.killbill.billing.entitlement.logging.EntitlementLoggingHelper.logUncancelEntitlement) EntitlementContext(org.killbill.billing.entitlement.plugin.api.EntitlementContext) SubscriptionBaseApiException(org.killbill.billing.subscription.api.user.SubscriptionBaseApiException) DefaultBlockingState(org.killbill.billing.junction.DefaultBlockingState)

Example 42 with DefaultBlockingState

use of org.killbill.billing.junction.DefaultBlockingState in project killbill by killbill.

the class DefaultEventsStream method computeAddonsBlockingStatesForSubscriptionBaseEvent.

private Collection<BlockingState> computeAddonsBlockingStatesForSubscriptionBaseEvent(@Nullable final Product baseTransitionTriggerNextProduct, final DateTime blockingStateEffectiveDate) {
    if (baseSubscription == null || baseSubscription.getLastActivePlan() == null || !ProductCategory.BASE.equals(baseSubscription.getLastActivePlan().getProduct().getCategory())) {
        return ImmutableList.<BlockingState>of();
    }
    // Compute included and available addons for the new product
    final Collection<String> includedAddonsForProduct;
    final Collection<String> availableAddonsForProduct;
    if (baseTransitionTriggerNextProduct == null) {
        includedAddonsForProduct = ImmutableList.<String>of();
        availableAddonsForProduct = ImmutableList.<String>of();
    } else {
        includedAddonsForProduct = Collections2.<Product, String>transform(ImmutableSet.<Product>copyOf(baseTransitionTriggerNextProduct.getIncluded()), new Function<Product, String>() {

            @Override
            public String apply(final Product product) {
                return product.getName();
            }
        });
        availableAddonsForProduct = Collections2.<Product, String>transform(ImmutableSet.<Product>copyOf(baseTransitionTriggerNextProduct.getAvailable()), new Function<Product, String>() {

            @Override
            public String apply(final Product product) {
                return product.getName();
            }
        });
    }
    // Retrieve all add-ons to block for that base subscription
    final Collection<SubscriptionBase> futureBlockedAddons = Collections2.<SubscriptionBase>filter(allSubscriptionsForBundle, new Predicate<SubscriptionBase>() {

        @Override
        public boolean apply(final SubscriptionBase subscription) {
            final Plan lastActivePlan = subscription.getLastActivePlan();
            final boolean result = ProductCategory.ADD_ON.equals(subscription.getCategory()) && // Check the subscription started, if not we don't want it, and that way we avoid doing NPE a few lines below.
            lastActivePlan != null && // Check the entitlement for that add-on hasn't been cancelled yet
            getEntitlementCancellationEvent(subscription.getId()) == null && (// Base subscription cancelled
            baseTransitionTriggerNextProduct == null || (// Change plan - check which add-ons to cancel
            includedAddonsForProduct.contains(lastActivePlan.getProduct().getName()) || !availableAddonsForProduct.contains(subscription.getLastActivePlan().getProduct().getName())));
            return result;
        }
    });
    // Create the blocking states
    return Collections2.<SubscriptionBase, BlockingState>transform(futureBlockedAddons, new Function<SubscriptionBase, BlockingState>() {

        @Override
        public BlockingState apply(final SubscriptionBase input) {
            return new DefaultBlockingState(input.getId(), BlockingStateType.SUBSCRIPTION, DefaultEntitlementApi.ENT_STATE_CANCELLED, KILLBILL_SERVICES.ENTITLEMENT_SERVICE.getServiceName(), true, true, false, blockingStateEffectiveDate);
        }
    });
}
Also used : SubscriptionBase(org.killbill.billing.subscription.api.SubscriptionBase) Function(com.google.common.base.Function) Product(org.killbill.billing.catalog.api.Product) DefaultBlockingState(org.killbill.billing.junction.DefaultBlockingState) BlockingState(org.killbill.billing.entitlement.api.BlockingState) Plan(org.killbill.billing.catalog.api.Plan) DefaultBlockingState(org.killbill.billing.junction.DefaultBlockingState)

Example 43 with DefaultBlockingState

use of org.killbill.billing.junction.DefaultBlockingState in project killbill by killbill.

the class TestBlockingApi method testApi.

@Test(groups = "slow")
public void testApi() {
    final UUID uuid = UUID.randomUUID();
    final String overdueStateName = "WayPassedItMan";
    final String service = "TEST";
    final boolean blockChange = true;
    final boolean blockEntitlement = false;
    final boolean blockBilling = false;
    testListener.pushExpectedEvent(NextEvent.BLOCK);
    final BlockingState state1 = new DefaultBlockingState(uuid, BlockingStateType.ACCOUNT, overdueStateName, service, blockChange, blockEntitlement, blockBilling, clock.getUTCNow());
    blockingInternalApi.setBlockingState(state1, internalCallContext);
    assertListenerStatus();
    clock.setDeltaFromReality(1000 * 3600 * 24);
    testListener.pushExpectedEvent(NextEvent.BLOCK);
    final String overdueStateName2 = "NoReallyThisCantGoOn";
    final BlockingState state2 = new DefaultBlockingState(uuid, BlockingStateType.ACCOUNT, overdueStateName2, service, blockChange, blockEntitlement, blockBilling, clock.getUTCNow());
    blockingInternalApi.setBlockingState(state2, internalCallContext);
    assertListenerStatus();
    Assert.assertEquals(blockingInternalApi.getBlockingStateForService(uuid, BlockingStateType.ACCOUNT, service, internalCallContext).getStateName(), overdueStateName2);
}
Also used : DefaultBlockingState(org.killbill.billing.junction.DefaultBlockingState) BlockingState(org.killbill.billing.entitlement.api.BlockingState) UUID(java.util.UUID) DefaultBlockingState(org.killbill.billing.junction.DefaultBlockingState) Test(org.testng.annotations.Test)

Example 44 with DefaultBlockingState

use of org.killbill.billing.junction.DefaultBlockingState in project killbill by killbill.

the class TestBlockingApi method testBlockingAcrossTypes.

@Test(groups = "slow")
public void testBlockingAcrossTypes() throws Exception {
    final String stateNameBlock = "stateBlock";
    final String stateNameUnBlock = "stateUnBlock";
    final String service = "SVC_BLOC_TYPES";
    final boolean blockChange = false;
    final boolean blockEntitlement = true;
    final boolean blockBilling = true;
    final Account account = createAccount(getAccountData(7));
    testListener.pushExpectedEvent(NextEvent.BLOCK);
    final BlockingState state1 = new DefaultBlockingState(account.getId(), BlockingStateType.ACCOUNT, stateNameBlock, service, blockChange, blockEntitlement, blockBilling, clock.getUTCNow());
    subscriptionApi.addBlockingState(state1, null, ImmutableList.<PluginProperty>of(), callContext);
    assertListenerStatus();
    final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Shotgun", BillingPeriod.ANNUAL, PriceListSet.DEFAULT_PRICELIST_NAME, null);
    testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK);
    final UUID baseEntitlementId = entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec), account.getExternalKey(), null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
    assertListenerStatus();
    Entitlement baseEntitlement = entitlementApi.getEntitlementForId(baseEntitlementId, callContext);
    assertEquals(baseEntitlement.getState(), EntitlementState.BLOCKED);
    // Add blocking at bundle level.
    clock.addDays(1);
    testListener.pushExpectedEvent(NextEvent.BLOCK);
    final BlockingState state2 = new DefaultBlockingState(baseEntitlement.getBundleId(), BlockingStateType.SUBSCRIPTION_BUNDLE, stateNameBlock, service, blockChange, blockEntitlement, blockBilling, null);
    subscriptionApi.addBlockingState(state2, null, ImmutableList.<PluginProperty>of(), callContext);
    assertListenerStatus();
    baseEntitlement = entitlementApi.getEntitlementForId(baseEntitlement.getId(), callContext);
    assertEquals(baseEntitlement.getState(), EntitlementState.BLOCKED);
    // Remove blocking at account level
    clock.addDays(1);
    testListener.pushExpectedEvent(NextEvent.BLOCK);
    final BlockingState state3 = new DefaultBlockingState(account.getId(), BlockingStateType.ACCOUNT, stateNameUnBlock, service, false, false, false, clock.getUTCNow());
    subscriptionApi.addBlockingState(state3, null, ImmutableList.<PluginProperty>of(), callContext);
    assertListenerStatus();
    baseEntitlement = entitlementApi.getEntitlementForId(baseEntitlement.getId(), callContext);
    assertEquals(baseEntitlement.getState(), EntitlementState.BLOCKED);
    // Remove blocking at bundle level.
    clock.addDays(1);
    testListener.pushExpectedEvent(NextEvent.BLOCK);
    final BlockingState state4 = new DefaultBlockingState(baseEntitlement.getBundleId(), BlockingStateType.SUBSCRIPTION_BUNDLE, stateNameUnBlock, service, false, false, false, null);
    subscriptionApi.addBlockingState(state4, null, ImmutableList.<PluginProperty>of(), callContext);
    assertListenerStatus();
    baseEntitlement = entitlementApi.getEntitlementForId(baseEntitlement.getId(), callContext);
    assertEquals(baseEntitlement.getState(), EntitlementState.ACTIVE);
    final List<BlockingState> blockingAll = blockingInternalApi.getBlockingActiveForAccount(catalog, null, internalCallContext);
    final List<BlockingState> history = ImmutableList.<BlockingState>copyOf(Collections2.<BlockingState>filter(blockingAll, new Predicate<BlockingState>() {

        @Override
        public boolean apply(final BlockingState input) {
            return input.getService().equals(service);
        }
    }));
    Assert.assertEquals(history.size(), 4);
}
Also used : PlanPhaseSpecifier(org.killbill.billing.catalog.api.PlanPhaseSpecifier) DefaultEntitlementSpecifier(org.killbill.billing.entitlement.api.DefaultEntitlementSpecifier) Account(org.killbill.billing.account.api.Account) DefaultBlockingState(org.killbill.billing.junction.DefaultBlockingState) BlockingState(org.killbill.billing.entitlement.api.BlockingState) UUID(java.util.UUID) Entitlement(org.killbill.billing.entitlement.api.Entitlement) DefaultBlockingState(org.killbill.billing.junction.DefaultBlockingState) Predicate(com.google.common.base.Predicate) Test(org.testng.annotations.Test)

Example 45 with DefaultBlockingState

use of org.killbill.billing.junction.DefaultBlockingState in project killbill by killbill.

the class TestBlockingApi method testApiHistory.

@Test(groups = "slow")
public void testApiHistory() throws Exception {
    final String overdueStateName = "WayPassedItMan";
    final String service = "TEST";
    final boolean blockChange = true;
    final boolean blockEntitlement = false;
    final boolean blockBilling = true;
    final Account account = createAccount(getAccountData(7));
    testListener.pushExpectedEvent(NextEvent.BLOCK);
    final BlockingState state1 = new DefaultBlockingState(account.getId(), BlockingStateType.ACCOUNT, overdueStateName, service, blockChange, blockEntitlement, blockBilling, clock.getUTCNow());
    blockingInternalApi.setBlockingState(state1, internalCallContext);
    assertListenerStatus();
    clock.setDeltaFromReality(1000 * 3600 * 24);
    testListener.pushExpectedEvent(NextEvent.BLOCK);
    final String overdueStateName2 = "NoReallyThisCantGoOn";
    final BlockingState state2 = new DefaultBlockingState(account.getId(), BlockingStateType.ACCOUNT, overdueStateName2, service, blockChange, blockEntitlement, blockBilling, clock.getUTCNow());
    blockingInternalApi.setBlockingState(state2, internalCallContext);
    assertListenerStatus();
    final List<BlockingState> blockingAll = blockingInternalApi.getBlockingActiveForAccount(catalog, null, internalCallContext);
    final List<BlockingState> history = ImmutableList.<BlockingState>copyOf(Collections2.<BlockingState>filter(blockingAll, new Predicate<BlockingState>() {

        @Override
        public boolean apply(final BlockingState input) {
            return input.getService().equals(service);
        }
    }));
    Assert.assertEquals(history.size(), 2);
    Assert.assertEquals(history.get(0).getStateName(), overdueStateName);
    Assert.assertEquals(history.get(1).getStateName(), overdueStateName2);
}
Also used : Account(org.killbill.billing.account.api.Account) DefaultBlockingState(org.killbill.billing.junction.DefaultBlockingState) BlockingState(org.killbill.billing.entitlement.api.BlockingState) DefaultBlockingState(org.killbill.billing.junction.DefaultBlockingState) Predicate(com.google.common.base.Predicate) Test(org.testng.annotations.Test)

Aggregations

DefaultBlockingState (org.killbill.billing.junction.DefaultBlockingState)63 UUID (java.util.UUID)46 DateTime (org.joda.time.DateTime)38 BlockingState (org.killbill.billing.entitlement.api.BlockingState)37 Test (org.testng.annotations.Test)35 LocalDate (org.joda.time.LocalDate)34 Account (org.killbill.billing.account.api.Account)23 ArrayList (java.util.ArrayList)21 PlanPhaseSpecifier (org.killbill.billing.catalog.api.PlanPhaseSpecifier)19 DateTimeZone (org.joda.time.DateTimeZone)14 DefaultEntitlementSpecifier (org.killbill.billing.entitlement.api.DefaultEntitlementSpecifier)14 SubscriptionBaseTransition (org.killbill.billing.subscription.api.user.SubscriptionBaseTransition)11 SubscriptionBase (org.killbill.billing.subscription.api.SubscriptionBase)9 Entitlement (org.killbill.billing.entitlement.api.Entitlement)8 InternalCallContext (org.killbill.billing.callcontext.InternalCallContext)7 WithEntitlementPlugin (org.killbill.billing.entitlement.api.EntitlementPluginExecution.WithEntitlementPlugin)7 EntitlementContext (org.killbill.billing.entitlement.plugin.api.EntitlementContext)7 SubscriptionBaseApiException (org.killbill.billing.subscription.api.user.SubscriptionBaseApiException)7 BigDecimal (java.math.BigDecimal)6 BillingEvent (org.killbill.billing.junction.BillingEvent)6