Search in sources :

Example 1 with EntitlementApiException

use of org.killbill.billing.entitlement.api.EntitlementApiException in project killbill by killbill.

the class TestCatalogRetireElements method testRetirePriceList.

@Test(groups = "slow")
public void testRetirePriceList() throws Exception {
    // Catalog v1 starts in 2011-01-01
    // Catalog v2 starts in 2015-12-01
    // Catalog v3 starts in 2016-01-01
    final LocalDate today = new LocalDate(2015, 11, 1);
    // Set clock to the initial start date - we implicitly assume here that the account timezone is UTC
    clock.setDay(today);
    final Account account = createAccountWithNonOsgiPaymentMethod(getAccountData(1));
    //accountUserApi.createAccount(getAccountData(1), callContext);
    final String productName = "Pistol";
    final BillingPeriod term = BillingPeriod.MONTHLY;
    final PlanPhaseSpecifier spec = new PlanPhaseSpecifier(productName, term, "SpecialDiscount", null);
    busHandler.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK, NextEvent.INVOICE);
    final Entitlement bpEntitlement = entitlementApi.createBaseEntitlement(account.getId(), spec, "externalKey", null, null, null, false, ImmutableList.<PluginProperty>of(), callContext);
    assertListenerStatus();
    assertNotNull(bpEntitlement);
    assertEquals(invoiceUserApi.getInvoicesByAccount(account.getId(), false, callContext).size(), 1);
    // Move out a month.
    busHandler.pushExpectedEvents(NextEvent.PHASE, NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
    clock.addMonths(1);
    assertListenerStatus();
    // Move out a month.
    busHandler.pushExpectedEvents(NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
    clock.addMonths(1);
    assertListenerStatus();
    try {
        entitlementApi.createBaseEntitlement(account.getId(), spec, "externalKey2", null, null, null, false, ImmutableList.<PluginProperty>of(), callContext);
        // force to fail is there is not an exception
        fail();
    } catch (final EntitlementApiException e) {
        assertTrue(e.getLocalizedMessage().startsWith("Could not find any product named 'Pistol'"));
    }
    // Move out a month and verify 'Pistol' plan continue working as expected.
    busHandler.pushExpectedEvents(NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
    clock.addMonths(1);
    assertListenerStatus();
    // Move out a month.
    busHandler.pushExpectedEvents(NextEvent.PHASE, NextEvent.NULL_INVOICE, NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
    clock.addMonths(1);
    assertListenerStatus();
    final List<Invoice> invoices = invoiceUserApi.getInvoicesByAccount(account.getId(), false, callContext);
    assertEquals(invoices.size(), 5);
    assertTrue(invoices.get(0).getInvoiceItems().get(0).getPhaseName().equals("discount-pistol-monthly-trial"));
    assertTrue(invoices.get(1).getInvoiceItems().get(0).getPhaseName().equals("discount-pistol-monthly-discount"));
    assertTrue(invoices.get(2).getInvoiceItems().get(0).getPhaseName().equals("discount-pistol-monthly-discount"));
    assertTrue(invoices.get(3).getInvoiceItems().get(0).getPhaseName().equals("discount-pistol-monthly-discount"));
    assertTrue(invoices.get(4).getInvoiceItems().get(0).getPhaseName().equals("discount-pistol-monthly-evergreen"));
}
Also used : PlanPhaseSpecifier(org.killbill.billing.catalog.api.PlanPhaseSpecifier) Account(org.killbill.billing.account.api.Account) Invoice(org.killbill.billing.invoice.api.Invoice) BillingPeriod(org.killbill.billing.catalog.api.BillingPeriod) EntitlementApiException(org.killbill.billing.entitlement.api.EntitlementApiException) Entitlement(org.killbill.billing.entitlement.api.Entitlement) DefaultEntitlement(org.killbill.billing.entitlement.api.DefaultEntitlement) LocalDate(org.joda.time.LocalDate) Test(org.testng.annotations.Test)

Example 2 with EntitlementApiException

use of org.killbill.billing.entitlement.api.EntitlementApiException in project killbill by killbill.

the class DefaultEntitlementApiBase method resume.

public void resume(final UUID bundleId, @Nullable final LocalDate localEffectiveDate, final Iterable<PluginProperty> properties, final InternalCallContext internalCallContext) throws EntitlementApiException {
    final BaseEntitlementWithAddOnsSpecifier baseEntitlementWithAddOnsSpecifier = new DefaultBaseEntitlementWithAddOnsSpecifier(bundleId, null, null, localEffectiveDate, localEffectiveDate, false);
    final List<BaseEntitlementWithAddOnsSpecifier> baseEntitlementWithAddOnsSpecifierList = new ArrayList<BaseEntitlementWithAddOnsSpecifier>();
    baseEntitlementWithAddOnsSpecifierList.add(baseEntitlementWithAddOnsSpecifier);
    final EntitlementContext pluginContext = new DefaultEntitlementContext(OperationType.RESUME_BUNDLE, null, null, baseEntitlementWithAddOnsSpecifierList, null, properties, internalCallContextFactory.createCallContext(internalCallContext));
    final WithEntitlementPlugin<Void> resumeWithPlugin = new WithEntitlementPlugin<Void>() {

        @Override
        public Void doCall(final EntitlementApi entitlementApi, final EntitlementContext updatedPluginContext) throws EntitlementApiException {
            try {
                final SubscriptionBase baseSubscription = subscriptionInternalApi.getBaseSubscription(bundleId, internalCallContext);
                blockUnblockBundle(bundleId, DefaultEntitlementApi.ENT_STATE_CLEAR, EntitlementService.ENTITLEMENT_SERVICE_NAME, localEffectiveDate, false, false, false, baseSubscription, internalCallContext);
            } catch (SubscriptionBaseApiException e) {
                throw new EntitlementApiException(e);
            }
            return null;
        }
    };
    pluginExecution.executeWithPlugin(resumeWithPlugin, pluginContext);
}
Also used : WithEntitlementPlugin(org.killbill.billing.entitlement.api.EntitlementPluginExecution.WithEntitlementPlugin) ArrayList(java.util.ArrayList) EntitlementApiException(org.killbill.billing.entitlement.api.EntitlementApiException) DefaultEntitlementApi(org.killbill.billing.entitlement.api.DefaultEntitlementApi) EntitlementApi(org.killbill.billing.entitlement.api.EntitlementApi) SubscriptionBase(org.killbill.billing.subscription.api.SubscriptionBase) BaseEntitlementWithAddOnsSpecifier(org.killbill.billing.entitlement.api.BaseEntitlementWithAddOnsSpecifier) DefaultBaseEntitlementWithAddOnsSpecifier(org.killbill.billing.entitlement.api.DefaultBaseEntitlementWithAddOnsSpecifier) DefaultEntitlementContext(org.killbill.billing.entitlement.api.DefaultEntitlementContext) DefaultBaseEntitlementWithAddOnsSpecifier(org.killbill.billing.entitlement.api.DefaultBaseEntitlementWithAddOnsSpecifier) DefaultEntitlementContext(org.killbill.billing.entitlement.api.DefaultEntitlementContext) EntitlementContext(org.killbill.billing.entitlement.plugin.api.EntitlementContext) SubscriptionBaseApiException(org.killbill.billing.subscription.api.user.SubscriptionBaseApiException)

Example 3 with EntitlementApiException

use of org.killbill.billing.entitlement.api.EntitlementApiException in project killbill by killbill.

the class EventsStreamBuilder method buildForBaseSubscription.

public EventsStream buildForBaseSubscription(final UUID bundleId, final TenantContext tenantContext) throws EntitlementApiException {
    final SubscriptionBase baseSubscription;
    try {
        final InternalTenantContext internalTenantContext = internalCallContextFactory.createInternalTenantContext(bundleId, ObjectType.BUNDLE, tenantContext);
        baseSubscription = subscriptionInternalApi.getBaseSubscription(bundleId, internalTenantContext);
    } catch (SubscriptionBaseApiException e) {
        throw new EntitlementApiException(e);
    }
    return buildForEntitlement(baseSubscription.getId(), tenantContext);
}
Also used : SubscriptionBase(org.killbill.billing.subscription.api.SubscriptionBase) InternalTenantContext(org.killbill.billing.callcontext.InternalTenantContext) EntitlementApiException(org.killbill.billing.entitlement.api.EntitlementApiException) SubscriptionBaseApiException(org.killbill.billing.subscription.api.user.SubscriptionBaseApiException)

Example 4 with EntitlementApiException

use of org.killbill.billing.entitlement.api.EntitlementApiException in project killbill by killbill.

the class EventsStreamBuilder method buildForAccount.

// Special signature for ProxyBlockingStateDao to save a DAO call
public AccountEventsStreams buildForAccount(final Map<UUID, List<SubscriptionBase>> subscriptions, final InternalTenantContext internalTenantContext) throws EntitlementApiException {
    // Retrieve the account
    final ImmutableAccountData account;
    try {
        account = accountInternalApi.getImmutableAccountDataByRecordId(internalTenantContext.getAccountRecordId(), internalTenantContext);
    } catch (AccountApiException e) {
        throw new EntitlementApiException(e);
    }
    if (subscriptions.isEmpty()) {
        // Bail early
        return new DefaultAccountEventsStreams(account);
    }
    // Retrieve the bundles
    final List<SubscriptionBaseBundle> bundles = subscriptionInternalApi.getBundlesForAccount(account.getId(), internalTenantContext);
    // Map bundle id -> bundles
    final Map<UUID, SubscriptionBaseBundle> bundlesPerId = new HashMap<UUID, SubscriptionBaseBundle>();
    for (final SubscriptionBaseBundle bundle : bundles) {
        bundlesPerId.put(bundle.getId(), bundle);
    }
    // Retrieve the blocking states
    final List<BlockingState> blockingStatesForAccount = defaultBlockingStateDao.getBlockingAllForAccountRecordId(internalTenantContext);
    // Optimization: build lookup tables for blocking states states
    final Collection<BlockingState> accountBlockingStates = new LinkedList<BlockingState>();
    final Map<UUID, List<BlockingState>> blockingStatesPerSubscription = new HashMap<UUID, List<BlockingState>>();
    final Map<UUID, List<BlockingState>> blockingStatesPerBundle = new HashMap<UUID, List<BlockingState>>();
    for (final BlockingState blockingState : blockingStatesForAccount) {
        if (BlockingStateType.SUBSCRIPTION.equals(blockingState.getType())) {
            if (blockingStatesPerSubscription.get(blockingState.getBlockedId()) == null) {
                blockingStatesPerSubscription.put(blockingState.getBlockedId(), new LinkedList<BlockingState>());
            }
            blockingStatesPerSubscription.get(blockingState.getBlockedId()).add(blockingState);
        } else if (BlockingStateType.SUBSCRIPTION_BUNDLE.equals(blockingState.getType())) {
            if (blockingStatesPerBundle.get(blockingState.getBlockedId()) == null) {
                blockingStatesPerBundle.put(blockingState.getBlockedId(), new LinkedList<BlockingState>());
            }
            blockingStatesPerBundle.get(blockingState.getBlockedId()).add(blockingState);
        } else if (BlockingStateType.ACCOUNT.equals(blockingState.getType()) && account.getId().equals(blockingState.getBlockedId())) {
            accountBlockingStates.add(blockingState);
        }
    }
    // Build the EventsStream objects
    final Map<UUID, Integer> bcdCache = new HashMap<UUID, Integer>();
    final Map<UUID, Collection<EventsStream>> entitlementsPerBundle = new HashMap<UUID, Collection<EventsStream>>();
    for (final UUID bundleId : subscriptions.keySet()) {
        final SubscriptionBaseBundle bundle = bundlesPerId.get(bundleId);
        final List<SubscriptionBase> allSubscriptionsForBundle = subscriptions.get(bundleId);
        final SubscriptionBase baseSubscription = findBaseSubscription(allSubscriptionsForBundle);
        final List<BlockingState> bundleBlockingStates = MoreObjects.firstNonNull(blockingStatesPerBundle.get(bundleId), ImmutableList.<BlockingState>of());
        if (entitlementsPerBundle.get(bundleId) == null) {
            entitlementsPerBundle.put(bundleId, new LinkedList<EventsStream>());
        }
        for (final SubscriptionBase subscription : allSubscriptionsForBundle) {
            final List<BlockingState> subscriptionBlockingStatesOnDisk = MoreObjects.firstNonNull(blockingStatesPerSubscription.get(subscription.getId()), ImmutableList.<BlockingState>of());
            // We cannot always use blockingStatesForAccount here: we need subscriptionBlockingStates to contain the events not on disk when building an EventsStream
            // for an add-on - which means going through the magic of ProxyBlockingStateDao, which will recursively
            // create EventsStream objects. To avoid an infinite recursion, bypass ProxyBlockingStateDao when it's not
            // needed, i.e. if this EventStream is for a standalone or a base subscription
            final List<BlockingState> subscriptionBlockingStates;
            if (baseSubscription == null || subscription.getId().equals(baseSubscription.getId())) {
                subscriptionBlockingStates = subscriptionBlockingStatesOnDisk;
            } else {
                subscriptionBlockingStates = blockingStateDao.getBlockingHistory(subscriptionBlockingStatesOnDisk, blockingStatesForAccount, account, bundle, baseSubscription, subscription, allSubscriptionsForBundle, internalTenantContext);
            }
            // Merge the BlockingStates
            final Collection<BlockingState> blockingStateSet = new LinkedHashSet<BlockingState>(accountBlockingStates);
            blockingStateSet.addAll(bundleBlockingStates);
            blockingStateSet.addAll(subscriptionBlockingStates);
            final List<BlockingState> blockingStates = ProxyBlockingStateDao.sortedCopy(blockingStateSet);
            final EventsStream eventStream = buildForEntitlement(account, bundle, baseSubscription, subscription, allSubscriptionsForBundle, blockingStates, bcdCache, internalTenantContext);
            entitlementsPerBundle.get(bundleId).add(eventStream);
        }
    }
    return new DefaultAccountEventsStreams(account, bundles, entitlementsPerBundle);
}
Also used : LinkedHashSet(java.util.LinkedHashSet) ImmutableAccountData(org.killbill.billing.account.api.ImmutableAccountData) HashMap(java.util.HashMap) EventsStream(org.killbill.billing.entitlement.EventsStream) BlockingState(org.killbill.billing.entitlement.api.BlockingState) SubscriptionBase(org.killbill.billing.subscription.api.SubscriptionBase) AccountApiException(org.killbill.billing.account.api.AccountApiException) SubscriptionBaseBundle(org.killbill.billing.subscription.api.user.SubscriptionBaseBundle) List(java.util.List) ImmutableList(com.google.common.collect.ImmutableList) LinkedList(java.util.LinkedList) DefaultAccountEventsStreams(org.killbill.billing.entitlement.api.svcs.DefaultAccountEventsStreams) UUID(java.util.UUID) EntitlementApiException(org.killbill.billing.entitlement.api.EntitlementApiException) LinkedList(java.util.LinkedList) Collection(java.util.Collection)

Example 5 with EntitlementApiException

use of org.killbill.billing.entitlement.api.EntitlementApiException in project killbill by killbill.

the class OverdueStateApplicator method cancelSubscriptionsIfRequired.

private void cancelSubscriptionsIfRequired(final DateTime effectiveDate, final ImmutableAccountData account, final OverdueState nextOverdueState, final InternalCallContext context) throws OverdueException {
    if (nextOverdueState.getOverdueCancellationPolicy() == OverdueCancellationPolicy.NONE) {
        return;
    }
    final CallContext callContext = internalCallContextFactory.createCallContext(context);
    try {
        final BillingActionPolicy actionPolicy;
        switch(nextOverdueState.getOverdueCancellationPolicy()) {
            case END_OF_TERM:
                actionPolicy = BillingActionPolicy.END_OF_TERM;
                break;
            case IMMEDIATE:
                actionPolicy = BillingActionPolicy.IMMEDIATE;
                break;
            default:
                throw new IllegalStateException("Unexpected OverdueCancellationPolicy " + nextOverdueState.getOverdueCancellationPolicy());
        }
        final List<Entitlement> toBeCancelled = new LinkedList<Entitlement>();
        computeEntitlementsToCancel(account, toBeCancelled, callContext);
        try {
            entitlementInternalApi.cancel(toBeCancelled, context.toLocalDate(effectiveDate), actionPolicy, ImmutableList.<PluginProperty>of(), context);
        } catch (final EntitlementApiException e) {
            throw new OverdueException(e);
        }
    } catch (final EntitlementApiException e) {
        throw new OverdueException(e);
    }
}
Also used : BillingActionPolicy(org.killbill.billing.catalog.api.BillingActionPolicy) EntitlementApiException(org.killbill.billing.entitlement.api.EntitlementApiException) OverdueException(org.killbill.billing.overdue.config.api.OverdueException) Entitlement(org.killbill.billing.entitlement.api.Entitlement) CallContext(org.killbill.billing.util.callcontext.CallContext) InternalCallContext(org.killbill.billing.callcontext.InternalCallContext) LinkedList(java.util.LinkedList)

Aggregations

EntitlementApiException (org.killbill.billing.entitlement.api.EntitlementApiException)19 DefaultEntitlement (org.killbill.billing.entitlement.api.DefaultEntitlement)12 Entitlement (org.killbill.billing.entitlement.api.Entitlement)10 PlanPhaseSpecifier (org.killbill.billing.catalog.api.PlanPhaseSpecifier)9 SubscriptionBase (org.killbill.billing.subscription.api.SubscriptionBase)7 Test (org.testng.annotations.Test)7 LocalDate (org.joda.time.LocalDate)6 Account (org.killbill.billing.account.api.Account)6 SubscriptionBaseApiException (org.killbill.billing.subscription.api.user.SubscriptionBaseApiException)4 Function (com.google.common.base.Function)3 ArrayList (java.util.ArrayList)3 HashMap (java.util.HashMap)3 LinkedList (java.util.LinkedList)3 UUID (java.util.UUID)3 Nullable (javax.annotation.Nullable)3 AccountApiException (org.killbill.billing.account.api.AccountApiException)3 BillingPeriod (org.killbill.billing.catalog.api.BillingPeriod)3 BaseEntitlementWithAddOnsSpecifier (org.killbill.billing.entitlement.api.BaseEntitlementWithAddOnsSpecifier)3 BlockingState (org.killbill.billing.entitlement.api.BlockingState)3 DefaultBaseEntitlementWithAddOnsSpecifier (org.killbill.billing.entitlement.api.DefaultBaseEntitlementWithAddOnsSpecifier)3