Search in sources :

Example 66 with PlanPhaseSpecifier

use of org.killbill.billing.catalog.api.PlanPhaseSpecifier in project killbill by killbill.

the class TestDefaultInternalBillingApi method testBlockingStatesWithSameEffectiveDate.

// This test was originally for https://github.com/killbill/killbill/issues/123.
// The invocationCount > 0 was to trigger an issue where events would come out-of-order randomly.
// While the bug shouldn't occur anymore, we're keeping it just in case (the test will also try to insert the events out-of-order manually).
// This test also checks we don't generate billing events for blocking durations less than a day (https://github.com/killbill/killbill/issues/267).
@Test(groups = "slow", description = "Check blocking states with same effective date are correctly handled", invocationCount = 10)
public void testBlockingStatesWithSameEffectiveDate() throws Exception {
    final LocalDate initialDate = new LocalDate(2013, 8, 7);
    clock.setDay(initialDate);
    final Account account = createAccount(getAccountData(7));
    testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK);
    final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Shotgun", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null);
    final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec), account.getExternalKey(), null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
    final Entitlement entitlement = entitlementApi.getEntitlementForId(entitlementId, callContext);
    final SubscriptionBase subscription = subscriptionInternalApi.getSubscriptionFromId(entitlement.getId(), internalCallContext);
    assertListenerStatus();
    final DateTime block1Date = clock.getUTCNow();
    testListener.pushExpectedEvents(NextEvent.BLOCK, NextEvent.BLOCK);
    final DefaultBlockingState state1 = new DefaultBlockingState(account.getId(), BlockingStateType.ACCOUNT, DefaultEntitlementApi.ENT_STATE_BLOCKED, KILLBILL_SERVICES.ENTITLEMENT_SERVICE.getServiceName(), true, true, true, block1Date);
    blockingInternalApi.setBlockingState(state1, internalCallContext);
    // Same date, we'll order by record id asc
    final DefaultBlockingState state2 = new DefaultBlockingState(account.getId(), BlockingStateType.ACCOUNT, DefaultEntitlementApi.ENT_STATE_CLEAR, KILLBILL_SERVICES.ENTITLEMENT_SERVICE.getServiceName(), false, false, false, block1Date);
    blockingInternalApi.setBlockingState(state2, internalCallContext);
    assertListenerStatus();
    clock.addDays(5);
    final DateTime block2Date = clock.getUTCNow();
    testListener.pushExpectedEvents(NextEvent.BLOCK, NextEvent.BLOCK);
    final DefaultBlockingState state3 = new DefaultBlockingState(entitlement.getBundleId(), BlockingStateType.SUBSCRIPTION_BUNDLE, DefaultEntitlementApi.ENT_STATE_BLOCKED, KILLBILL_SERVICES.ENTITLEMENT_SERVICE.getServiceName(), true, true, true, block2Date);
    blockingInternalApi.setBlockingState(state3, internalCallContext);
    // Same date, we'll order by record id asc
    final DefaultBlockingState state4 = new DefaultBlockingState(entitlement.getBundleId(), BlockingStateType.SUBSCRIPTION_BUNDLE, DefaultEntitlementApi.ENT_STATE_CLEAR, KILLBILL_SERVICES.ENTITLEMENT_SERVICE.getServiceName(), false, false, false, block2Date);
    blockingInternalApi.setBlockingState(state4, internalCallContext);
    assertListenerStatus();
    final DateTime block3Date = block2Date.plusDays(3);
    // Pass the phase
    testListener.pushExpectedEvent(NextEvent.PHASE);
    clock.addDays(50);
    assertListenerStatus();
    final DateTime block4Date = clock.getUTCNow();
    final DateTime block5Date = block4Date.plusDays(3);
    // Only one event on the bus (for state5)
    testListener.pushExpectedEvents(NextEvent.BLOCK);
    // Insert the clear state first, to make sure the order in which we insert blocking states doesn't matter
    // Since we are already in an ENT_STATE_CLEAR state for service ENTITLEMENT_SERVICE_NAME, we need to use a different
    // state name to simulate this behavior (otherwise, by design, this event won't be created)
    final DefaultBlockingState state6 = new DefaultBlockingState(entitlement.getBundleId(), BlockingStateType.SUBSCRIPTION_BUNDLE, DefaultEntitlementApi.ENT_STATE_CLEAR + "-something", KILLBILL_SERVICES.ENTITLEMENT_SERVICE.getServiceName(), false, false, false, block5Date);
    blockingInternalApi.setBlockingState(state6, internalCallContext);
    final DefaultBlockingState state5 = new DefaultBlockingState(entitlement.getBundleId(), BlockingStateType.SUBSCRIPTION_BUNDLE, DefaultEntitlementApi.ENT_STATE_BLOCKED + "-something", KILLBILL_SERVICES.ENTITLEMENT_SERVICE.getServiceName(), true, true, true, block4Date);
    blockingInternalApi.setBlockingState(state5, internalCallContext);
    assertListenerStatus();
    // Now, add back blocking states at an earlier date, for a different blockable id, to make sure the effective
    // date ordering is correctly respected when computing blocking durations
    testListener.pushExpectedEvents(NextEvent.BLOCK, NextEvent.BLOCK);
    final DefaultBlockingState state7 = new DefaultBlockingState(account.getId(), BlockingStateType.ACCOUNT, DefaultEntitlementApi.ENT_STATE_BLOCKED + "-something2", KILLBILL_SERVICES.ENTITLEMENT_SERVICE.getServiceName(), true, true, true, block3Date);
    blockingInternalApi.setBlockingState(state7, internalCallContext);
    final DefaultBlockingState state8 = new DefaultBlockingState(account.getId(), BlockingStateType.ACCOUNT, DefaultEntitlementApi.ENT_STATE_CLEAR + "-something2", KILLBILL_SERVICES.ENTITLEMENT_SERVICE.getServiceName(), false, false, false, block4Date);
    blockingInternalApi.setBlockingState(state8, internalCallContext);
    assertListenerStatus();
    // Advance for state6 to be active
    testListener.pushExpectedEvents(NextEvent.BLOCK);
    clock.addDays(5);
    assertListenerStatus();
    // Expected blocking duration:
    // * 2013-08-15 to 2013-10-04 [2013-08-15 to 2013-10-01 (block3Date -> block4Date) and 2013-10-01 to 2013-10-04 (block4Date -> block5Date)]
    final List<BillingEvent> events = ImmutableList.<BillingEvent>copyOf(billingInternalApi.getBillingEventsForAccountAndUpdateAccountBCD(account.getId(), null, null, internalCallContext));
    Assert.assertEquals(events.size(), 3);
    Assert.assertEquals(events.get(0).getTransitionType(), SubscriptionBaseTransitionType.CREATE);
    Assert.assertEquals(events.get(0).getEffectiveDate(), subscription.getStartDate());
    Assert.assertEquals(events.get(1).getTransitionType(), SubscriptionBaseTransitionType.START_BILLING_DISABLED);
    Assert.assertEquals(events.get(1).getEffectiveDate().compareTo(block3Date), 0);
    Assert.assertEquals(events.get(2).getTransitionType(), SubscriptionBaseTransitionType.END_BILLING_DISABLED);
    Assert.assertEquals(events.get(2).getEffectiveDate().compareTo(block5Date), 0);
}
Also used : PlanPhaseSpecifier(org.killbill.billing.catalog.api.PlanPhaseSpecifier) DefaultEntitlementSpecifier(org.killbill.billing.entitlement.api.DefaultEntitlementSpecifier) SubscriptionBase(org.killbill.billing.subscription.api.SubscriptionBase) Account(org.killbill.billing.account.api.Account) BillingEvent(org.killbill.billing.junction.BillingEvent) UUID(java.util.UUID) Entitlement(org.killbill.billing.entitlement.api.Entitlement) LocalDate(org.joda.time.LocalDate) DateTime(org.joda.time.DateTime) DefaultBlockingState(org.killbill.billing.junction.DefaultBlockingState) Test(org.testng.annotations.Test)

Example 67 with PlanPhaseSpecifier

use of org.killbill.billing.catalog.api.PlanPhaseSpecifier in project killbill by killbill.

the class TestDefaultInternalBillingApi method testUsageInArrear.

@Test(groups = "slow")
public void testUsageInArrear() throws Exception {
    final LocalDate initialDate = new LocalDate(2013, 8, 7);
    clock.setDay(initialDate);
    // Account with no BCD
    final Account account = createAccount(getAccountData(0));
    Assert.assertEquals(account.getBillCycleDayLocal(), (Integer) 0);
    // Create base entitlement
    final String bundleKey = UUID.randomUUID().toString();
    final EntitlementSpecifier entitlementSpecifierBase = new DefaultEntitlementSpecifier(new PlanPhaseSpecifier("Trebuchet", BillingPeriod.NO_BILLING_PERIOD, PriceListSet.DEFAULT_PRICELIST_NAME, null));
    final BaseEntitlementWithAddOnsSpecifier specifier = new DefaultBaseEntitlementWithAddOnsSpecifier(null, bundleKey, ImmutableList.of(entitlementSpecifierBase), null, null, false);
    testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK);
    entitlementApi.createBaseEntitlementsWithAddOns(account.getId(), ImmutableList.of(specifier), false, ImmutableList.<PluginProperty>of(), callContext);
    assertListenerStatus();
    final List<Entitlement> entitlements = entitlementApi.getAllEntitlementsForAccountId(account.getId(), callContext);
    Assert.assertEquals(entitlements.size(), 1);
    Assert.assertEquals(entitlements.get(0).getLastActiveProduct().getName(), "Trebuchet");
    Assert.assertNull(entitlements.get(0).getBillCycleDayLocal());
    // Account still has no BCD
    final Account accountNoBCD = accountApi.getAccountById(account.getId(), callContext);
    Assert.assertEquals(accountNoBCD.getBillCycleDayLocal(), (Integer) 0);
    List<BillingEvent> events = ImmutableList.<BillingEvent>copyOf(billingInternalApi.getBillingEventsForAccountAndUpdateAccountBCD(account.getId(), null, null, internalCallContext));
    Assert.assertEquals(events.size(), 1);
    Assert.assertEquals(events.get(0).getBillCycleDayLocal(), 7);
    // Verify BCD
    final Account accountWithBCD = accountApi.getAccountById(account.getId(), callContext);
    Assert.assertEquals(accountWithBCD.getBillCycleDayLocal(), (Integer) 7);
    // Verify GET
    final List<Entitlement> entitlementsUpdated = entitlementApi.getAllEntitlementsForAccountId(account.getId(), callContext);
    Assert.assertEquals(entitlementsUpdated.size(), 1);
    Assert.assertEquals(entitlementsUpdated.get(0).getLastActiveProduct().getName(), "Trebuchet");
    Assert.assertEquals(entitlementsUpdated.get(0).getBillCycleDayLocal(), (Integer) 7);
    events = ImmutableList.<BillingEvent>copyOf(billingInternalApi.getBillingEventsForAccountAndUpdateAccountBCD(account.getId(), null, null, internalCallContext));
    Assert.assertEquals(events.size(), 1);
    Assert.assertEquals(events.get(0).getBillCycleDayLocal(), 7);
}
Also used : EntitlementSpecifier(org.killbill.billing.entitlement.api.EntitlementSpecifier) DefaultEntitlementSpecifier(org.killbill.billing.entitlement.api.DefaultEntitlementSpecifier) DefaultEntitlementSpecifier(org.killbill.billing.entitlement.api.DefaultEntitlementSpecifier) PlanPhaseSpecifier(org.killbill.billing.catalog.api.PlanPhaseSpecifier) Account(org.killbill.billing.account.api.Account) BaseEntitlementWithAddOnsSpecifier(org.killbill.billing.entitlement.api.BaseEntitlementWithAddOnsSpecifier) DefaultBaseEntitlementWithAddOnsSpecifier(org.killbill.billing.entitlement.api.DefaultBaseEntitlementWithAddOnsSpecifier) BillingEvent(org.killbill.billing.junction.BillingEvent) Entitlement(org.killbill.billing.entitlement.api.Entitlement) LocalDate(org.joda.time.LocalDate) DefaultBaseEntitlementWithAddOnsSpecifier(org.killbill.billing.entitlement.api.DefaultBaseEntitlementWithAddOnsSpecifier) Test(org.testng.annotations.Test)

Example 68 with PlanPhaseSpecifier

use of org.killbill.billing.catalog.api.PlanPhaseSpecifier in project killbill by killbill.

the class SubscriptionApiBase method populateDryRunEvents.

private void populateDryRunEvents(@Nullable final UUID bundleId, @Nullable final DryRunArguments dryRunArguments, final Collection<SubscriptionBaseEvent> outputDryRunEvents, final Collection<DefaultSubscriptionBase> outputSubscriptions, final SubscriptionCatalog catalog, final AddonUtils addonUtils, final TenantContext tenantContext, final InternalTenantContext context) throws SubscriptionBaseApiException, CatalogApiException {
    if (dryRunArguments == null || dryRunArguments.getAction() == null) {
        return;
    }
    final DateTime utcNow = clock.getUTCNow();
    List<SubscriptionBaseEvent> dryRunEvents = null;
    final EntitlementSpecifier entitlementSpecifier = dryRunArguments.getEntitlementSpecifier();
    final PlanPhaseSpecifier inputSpec = entitlementSpecifier.getPlanPhaseSpecifier();
    final boolean isInputSpecNullOrEmpty = inputSpec == null || (inputSpec.getPlanName() == null && inputSpec.getProductName() == null && inputSpec.getBillingPeriod() == null);
    // Create an overridesWithContext with a null context to indicate this is dryRun and no price overridden plan should be created.
    final PlanPhasePriceOverridesWithCallContext overridesWithContext = new DefaultPlanPhasePriceOverridesWithCallContext(entitlementSpecifier.getOverrides(), null);
    final LocalDate dryRunEffDt = dryRunArguments.getEffectiveDate();
    // EffectiveDate for the event is LocalDate but Catalog effectiveDate is a DateTime, so to maximize the chance of finding 'a' version
    // on that date we take the time closer to midnight - if 2 versions where uploaded on the same LocalDate this is returns the latest one.
    final DateTime catalogTargetDt = dryRunEffDt != null ? dryRunEffDt.toDateTimeAtStartOfDay(DateTimeZone.UTC).plusDays(1).minusSeconds(1) : utcNow;
    final StaticCatalog staticCatalog = catalog.versionForDate(catalogTargetDt);
    final Plan plan = isInputSpecNullOrEmpty ? null : staticCatalog.createOrFindPlan(inputSpec, overridesWithContext);
    switch(dryRunArguments.getAction()) {
        case START_BILLING:
            final SubscriptionBase baseSubscription = dao.getBaseSubscription(bundleId, catalog, context);
            final DateTime startEffectiveDate = dryRunEffDt != null ? context.toUTCDateTime(dryRunEffDt) : utcNow;
            final DateTime bundleStartDate = getBundleStartDateWithSanity(bundleId, baseSubscription, plan, startEffectiveDate, addonUtils, context);
            final UUID subscriptionId = UUIDs.randomUUID();
            dryRunEvents = apiService.getEventsOnCreation(subscriptionId, startEffectiveDate, bundleStartDate, plan, inputSpec.getPhaseType(), plan.getPriceList().getName(), startEffectiveDate, entitlementSpecifier.getBillCycleDay(), catalog, context);
            final SubscriptionBuilder builder = new SubscriptionBuilder().setId(subscriptionId).setBundleId(bundleId).setBundleExternalKey(null).setCategory(plan.getProduct().getCategory()).setBundleStartDate(bundleStartDate).setAlignStartDate(startEffectiveDate);
            final DefaultSubscriptionBase newSubscription = new DefaultSubscriptionBase(builder, apiService, clock);
            newSubscription.rebuildTransitions(dryRunEvents, catalog);
            outputSubscriptions.add(newSubscription);
            break;
        case CHANGE:
            final DefaultSubscriptionBase subscriptionForChange = (DefaultSubscriptionBase) dao.getSubscriptionFromId(dryRunArguments.getSubscriptionId(), catalog, context);
            DateTime changeEffectiveDate = getDryRunEffectiveDate(dryRunEffDt, subscriptionForChange, context);
            if (changeEffectiveDate == null) {
                BillingActionPolicy policy = dryRunArguments.getBillingActionPolicy();
                if (policy == null) {
                    final PlanChangeResult planChangeResult = apiService.getPlanChangeResult(subscriptionForChange, inputSpec, utcNow, tenantContext);
                    policy = planChangeResult.getPolicy();
                }
                // We pass null for billingAlignment, accountTimezone, account BCD because this is not available which means that dryRun with START_OF_TERM BillingPolicy will fail
                changeEffectiveDate = subscriptionForChange.getEffectiveDateForPolicy(policy, null, -1, context);
            }
            dryRunEvents = apiService.getEventsOnChangePlan(subscriptionForChange, plan, plan.getPriceList().getName(), changeEffectiveDate, true, entitlementSpecifier.getBillCycleDay(), catalog, context);
            break;
        case STOP_BILLING:
            final DefaultSubscriptionBase subscriptionForCancellation = (DefaultSubscriptionBase) dao.getSubscriptionFromId(dryRunArguments.getSubscriptionId(), catalog, context);
            DateTime cancelEffectiveDate = getDryRunEffectiveDate(dryRunEffDt, subscriptionForCancellation, context);
            if (dryRunEffDt == null) {
                BillingActionPolicy policy = dryRunArguments.getBillingActionPolicy();
                if (policy == null) {
                    final Plan currentPlan = subscriptionForCancellation.getCurrentPlan();
                    final PlanPhaseSpecifier spec = new PlanPhaseSpecifier(currentPlan.getName(), subscriptionForCancellation.getCurrentPhase().getPhaseType());
                    policy = catalog.planCancelPolicy(spec, clock.getUTCNow(), subscriptionForCancellation.getStartDate());
                }
                // We pass null for billingAlignment, accountTimezone, account BCD because this is not available which means that dryRun with START_OF_TERM BillingPolicy will fail
                cancelEffectiveDate = subscriptionForCancellation.getEffectiveDateForPolicy(policy, null, -1, context);
            }
            dryRunEvents = apiService.getEventsOnCancelPlan(subscriptionForCancellation, cancelEffectiveDate, true, catalog, context);
            break;
        default:
            throw new IllegalArgumentException("Unexpected dryRunArguments action " + dryRunArguments.getAction());
    }
    if (dryRunEvents != null && !dryRunEvents.isEmpty()) {
        outputDryRunEvents.addAll(dryRunEvents);
    }
}
Also used : PlanPhaseSpecifier(org.killbill.billing.catalog.api.PlanPhaseSpecifier) BillingActionPolicy(org.killbill.billing.catalog.api.BillingActionPolicy) PlanChangeResult(org.killbill.billing.catalog.api.PlanChangeResult) SubscriptionBuilder(org.killbill.billing.subscription.api.user.SubscriptionBuilder) Plan(org.killbill.billing.catalog.api.Plan) LocalDate(org.joda.time.LocalDate) StaticCatalog(org.killbill.billing.catalog.api.StaticCatalog) DateTime(org.joda.time.DateTime) DefaultPlanPhasePriceOverridesWithCallContext(org.killbill.billing.subscription.api.svcs.DefaultPlanPhasePriceOverridesWithCallContext) EntitlementSpecifier(org.killbill.billing.entitlement.api.EntitlementSpecifier) DefaultSubscriptionBase(org.killbill.billing.subscription.api.user.DefaultSubscriptionBase) PlanPhasePriceOverridesWithCallContext(org.killbill.billing.catalog.api.PlanPhasePriceOverridesWithCallContext) DefaultPlanPhasePriceOverridesWithCallContext(org.killbill.billing.subscription.api.svcs.DefaultPlanPhasePriceOverridesWithCallContext) DefaultSubscriptionBase(org.killbill.billing.subscription.api.user.DefaultSubscriptionBase) UUID(java.util.UUID) SubscriptionBaseEvent(org.killbill.billing.subscription.events.SubscriptionBaseEvent)

Example 69 with PlanPhaseSpecifier

use of org.killbill.billing.catalog.api.PlanPhaseSpecifier in project killbill by killbill.

the class DefaultSubscriptionBaseApiService method getPlanChangeResult.

@Override
public PlanChangeResult getPlanChangeResult(final DefaultSubscriptionBase subscription, final PlanSpecifier toPlanPhase, final DateTime effectiveDate, final TenantContext context) throws SubscriptionBaseApiException {
    final PlanChangeResult planChangeResult;
    try {
        final InternalTenantContext internalCallContext = createTenantContextFromBundleId(subscription.getBundleId(), context);
        final Plan currentPlan = subscription.getCurrentOrPendingPlan();
        final PlanPhaseSpecifier fromPlanPhase = new PlanPhaseSpecifier(currentPlan.getName(), subscription.getCurrentOrPendingPhase().getPhaseType());
        final SubscriptionCatalog catalog = subscriptionCatalogApi.getFullCatalog(internalCallContext);
        planChangeResult = catalog.getPlanChangeResult(fromPlanPhase, toPlanPhase, effectiveDate);
    } catch (final CatalogApiException e) {
        throw new SubscriptionBaseApiException(e);
    }
    return planChangeResult;
}
Also used : PlanPhaseSpecifier(org.killbill.billing.catalog.api.PlanPhaseSpecifier) InternalTenantContext(org.killbill.billing.callcontext.InternalTenantContext) CatalogApiException(org.killbill.billing.catalog.api.CatalogApiException) PlanChangeResult(org.killbill.billing.catalog.api.PlanChangeResult) Plan(org.killbill.billing.catalog.api.Plan) SubscriptionCatalog(org.killbill.billing.subscription.catalog.SubscriptionCatalog)

Example 70 with PlanPhaseSpecifier

use of org.killbill.billing.catalog.api.PlanPhaseSpecifier in project killbill by killbill.

the class DefaultSubscriptionBaseApiService method cancel.

@Override
public boolean cancel(final DefaultSubscriptionBase subscription, final CallContext context) throws SubscriptionBaseApiException {
    final Plan currentPlan = subscription.getCurrentOrPendingPlan();
    final PlanPhaseSpecifier planPhase = new PlanPhaseSpecifier(currentPlan.getName(), null);
    try {
        final InternalCallContext internalCallContext = createCallContextFromBundleId(subscription.getBundleId(), context);
        final SubscriptionCatalog catalog = subscriptionCatalogApi.getFullCatalog(internalCallContext);
        final BillingActionPolicy policy = catalog.planCancelPolicy(planPhase, clock.getUTCNow(), subscription.getStartDate());
        Preconditions.checkState(policy != BillingActionPolicy.START_OF_TERM, "A default START_OF_TERM policy is not availaible");
        final DateTime effectiveDate = subscription.getEffectiveDateForPolicy(policy, null, -1, null);
        return doCancelPlan(ImmutableMap.<DefaultSubscriptionBase, DateTime>of(subscription, effectiveDate), catalog, internalCallContext);
    } catch (final CatalogApiException e) {
        throw new SubscriptionBaseApiException(e);
    }
}
Also used : PlanPhaseSpecifier(org.killbill.billing.catalog.api.PlanPhaseSpecifier) BillingActionPolicy(org.killbill.billing.catalog.api.BillingActionPolicy) CatalogApiException(org.killbill.billing.catalog.api.CatalogApiException) InternalCallContext(org.killbill.billing.callcontext.InternalCallContext) Plan(org.killbill.billing.catalog.api.Plan) SubscriptionCatalog(org.killbill.billing.subscription.catalog.SubscriptionCatalog) DateTime(org.joda.time.DateTime)

Aggregations

PlanPhaseSpecifier (org.killbill.billing.catalog.api.PlanPhaseSpecifier)220 Test (org.testng.annotations.Test)181 LocalDate (org.joda.time.LocalDate)153 Account (org.killbill.billing.account.api.Account)144 DefaultEntitlementSpecifier (org.killbill.billing.entitlement.api.DefaultEntitlementSpecifier)140 UUID (java.util.UUID)129 DateTime (org.joda.time.DateTime)79 Entitlement (org.killbill.billing.entitlement.api.Entitlement)68 BigDecimal (java.math.BigDecimal)63 ExpectedInvoiceItemCheck (org.killbill.billing.beatrix.util.InvoiceChecker.ExpectedInvoiceItemCheck)61 DefaultEntitlement (org.killbill.billing.entitlement.api.DefaultEntitlement)59 Invoice (org.killbill.billing.invoice.api.Invoice)42 ArrayList (java.util.ArrayList)30 BillingPeriod (org.killbill.billing.catalog.api.BillingPeriod)29 AccountData (org.killbill.billing.account.api.AccountData)23 EntitlementApiException (org.killbill.billing.entitlement.api.EntitlementApiException)22 DefaultBlockingState (org.killbill.billing.junction.DefaultBlockingState)19 EntitlementSpecifier (org.killbill.billing.entitlement.api.EntitlementSpecifier)18 PlanPhasePriceOverride (org.killbill.billing.catalog.api.PlanPhasePriceOverride)17 Plan (org.killbill.billing.catalog.api.Plan)16