Search in sources :

Example 76 with CatalogApiException

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

the class DefaultSubscriptionApi method getBlockingStates.

@Override
public Iterable<BlockingState> getBlockingStates(final UUID accountId, @Nullable final List<BlockingStateType> typeFilter, @Nullable final List<String> svcsFilter, final OrderingType orderingType, final int timeFilter, final TenantContext tenantContext) throws EntitlementApiException {
    try {
        final InternalTenantContext internalTenantContextWithValidAccountRecordId = internalCallContextFactory.createInternalTenantContext(accountId, tenantContext);
        final VersionedCatalog catalog = catalogInternalApi.getFullCatalog(true, true, internalTenantContextWithValidAccountRecordId);
        final List<BlockingState> allBlockingStates = blockingStateDao.getBlockingAllForAccountRecordId(catalog, internalTenantContextWithValidAccountRecordId);
        final ImmutableAccountData account = accountApi.getImmutableAccountDataById(accountId, internalTenantContextWithValidAccountRecordId);
        final Iterable<BlockingState> filteredByTypes = typeFilter != null && !typeFilter.isEmpty() ? Iterables.filter(allBlockingStates, new Predicate<BlockingState>() {

            @Override
            public boolean apply(final BlockingState input) {
                return typeFilter.contains(input.getType());
            }
        }) : allBlockingStates;
        final Iterable<BlockingState> filteredByTypesAndSvcs = svcsFilter != null && !svcsFilter.isEmpty() ? Iterables.filter(filteredByTypes, new Predicate<BlockingState>() {

            @Override
            public boolean apply(final BlockingState input) {
                return svcsFilter.contains(input.getService());
            }
        }) : filteredByTypes;
        final LocalDate localDateNowInAccountTimezone = internalTenantContextWithValidAccountRecordId.toLocalDate(clock.getUTCNow());
        final List<BlockingState> result = new ArrayList<BlockingState>();
        for (final BlockingState cur : filteredByTypesAndSvcs) {
            final LocalDate eventDate = internalTenantContextWithValidAccountRecordId.toLocalDate(cur.getEffectiveDate());
            final int comp = eventDate.compareTo(localDateNowInAccountTimezone);
            if ((comp <= 1 && ((timeFilter & SubscriptionApi.PAST_EVENTS) == SubscriptionApi.PAST_EVENTS)) || (comp == 0 && ((timeFilter & SubscriptionApi.PRESENT_EVENTS) == SubscriptionApi.PRESENT_EVENTS)) || (comp >= 1 && ((timeFilter & SubscriptionApi.FUTURE_EVENTS) == SubscriptionApi.FUTURE_EVENTS))) {
                result.add(cur);
            }
        }
        return orderingType == OrderingType.ASCENDING ? result : Lists.reverse(result);
    } catch (final AccountApiException e) {
        throw new EntitlementApiException(e);
    } catch (final CatalogApiException e) {
        throw new EntitlementApiException(e);
    }
}
Also used : ImmutableAccountData(org.killbill.billing.account.api.ImmutableAccountData) ArrayList(java.util.ArrayList) DefaultBlockingState(org.killbill.billing.junction.DefaultBlockingState) EntitlementLoggingHelper.logAddBlockingState(org.killbill.billing.entitlement.logging.EntitlementLoggingHelper.logAddBlockingState) LocalDate(org.joda.time.LocalDate) Predicate(com.google.common.base.Predicate) VersionedCatalog(org.killbill.billing.catalog.api.VersionedCatalog) InternalTenantContext(org.killbill.billing.callcontext.InternalTenantContext) CatalogApiException(org.killbill.billing.catalog.api.CatalogApiException) AccountApiException(org.killbill.billing.account.api.AccountApiException)

Example 77 with CatalogApiException

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

the class DefaultEntitlement method changePlanOverrideBillingPolicy.

@Override
public Entitlement changePlanOverrideBillingPolicy(final EntitlementSpecifier spec, final LocalDate unused, final BillingActionPolicy actionPolicy, final Iterable<PluginProperty> properties, final CallContext callContext) throws EntitlementApiException {
    logChangePlan(log, this, spec, null, actionPolicy);
    checkForPermissions(Permission.ENTITLEMENT_CAN_CHANGE_PLAN, callContext);
    // Get the latest state from disk
    refresh(callContext);
    final BaseEntitlementWithAddOnsSpecifier baseEntitlementWithAddOnsSpecifier = new DefaultBaseEntitlementWithAddOnsSpecifier(getBundleId(), getBundleExternalKey(), null, null, null, false);
    final List<BaseEntitlementWithAddOnsSpecifier> baseEntitlementWithAddOnsSpecifierList = new ArrayList<BaseEntitlementWithAddOnsSpecifier>();
    baseEntitlementWithAddOnsSpecifierList.add(baseEntitlementWithAddOnsSpecifier);
    final EntitlementContext pluginContext = new DefaultEntitlementContext(OperationType.CHANGE_PLAN, getAccountId(), null, baseEntitlementWithAddOnsSpecifierList, actionPolicy, properties, callContext);
    final WithEntitlementPlugin<Entitlement> changePlanWithPlugin = new WithEntitlementPlugin<Entitlement>() {

        @Override
        public Entitlement doCall(final EntitlementApi entitlementApi, final DefaultEntitlementContext updatedPluginContext) throws EntitlementApiException {
            final InternalCallContext context = internalCallContextFactory.createInternalCallContext(getAccountId(), callContext);
            final DateTime resultingEffectiveDate;
            try {
                resultingEffectiveDate = subscriptionInternalApi.getDryRunChangePlanEffectiveDate(getSubscriptionBase(), spec, null, actionPolicy, context);
            } catch (final SubscriptionBaseApiException e) {
                throw new EntitlementApiException(e, e.getCode(), e.getMessage());
            } catch (final CatalogApiException e) {
                throw new EntitlementApiException(e, e.getCode(), e.getMessage());
            }
            try {
                checker.checkBlockedChange(getSubscriptionBase(), resultingEffectiveDate, context);
            } catch (final BlockingApiException e) {
                throw new EntitlementApiException(e, e.getCode(), e.getMessage());
            }
            try {
                getSubscriptionBase().changePlanWithPolicy(spec, actionPolicy, callContext);
            } catch (final SubscriptionBaseApiException e) {
                throw new EntitlementApiException(e);
            }
            final Collection<NotificationEvent> notificationEvents = new ArrayList<NotificationEvent>();
            final Iterable<BlockingState> addOnsBlockingStates = computeAddOnBlockingStates(resultingEffectiveDate, notificationEvents, callContext, context);
            // Record the new state first, then insert the notifications to avoid race conditions
            setBlockingStates(addOnsBlockingStates, context);
            for (final NotificationEvent notificationEvent : notificationEvents) {
                recordFutureNotification(resultingEffectiveDate, notificationEvent, context);
            }
            return entitlementApi.getEntitlementForId(getId(), callContext);
        }
    };
    return pluginExecution.executeWithPlugin(changePlanWithPlugin, 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) CatalogApiException(org.killbill.billing.catalog.api.CatalogApiException) 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)

Example 78 with CatalogApiException

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

the class UsageInvoiceItemGenerator method generateItems.

@Override
public InvoiceGeneratorResult generateItems(final ImmutableAccountData account, final UUID invoiceId, final BillingEventSet eventSet, final AccountInvoices existingInvoices, final LocalDate targetDate, final Currency targetCurrency, final Map<UUID, SubscriptionFutureNotificationDates> perSubscriptionFutureNotificationDates, final DryRunInfo dryRunInfo, final InternalCallContext internalCallContext) throws InvoiceApiException {
    final Map<UUID, List<InvoiceItem>> perSubscriptionInArrearUsageItems = extractPerSubscriptionExistingInArrearUsageItems(eventSet.getUsages(), existingInvoices.getInvoices());
    try {
        // Pretty-print the generated invoice items from the junction events
        final InvoiceItemGeneratorLogger invoiceItemGeneratorLogger = new InvoiceItemGeneratorLogger(invoiceId, account.getId(), "usage", log);
        final UsageDetailMode usageDetailMode = invoiceConfig.getItemResultBehaviorMode(internalCallContext);
        final LocalDate minBillingEventDate = getMinBillingEventDate(eventSet, internalCallContext);
        final Set<TrackingRecordId> trackingIds = new HashSet<>();
        final List<InvoiceItem> items = Lists.newArrayList();
        final Iterator<BillingEvent> events = eventSet.iterator();
        final boolean isDryRun = dryRunInfo != null;
        RawUsageOptimizerResult rawUsgRes = null;
        List<BillingEvent> curEvents = Lists.newArrayList();
        UUID curSubscriptionId = null;
        while (events.hasNext()) {
            final BillingEvent event = events.next();
            // Skip events that are posterior to the targetDate
            final LocalDate eventLocalEffectiveDate = internalCallContext.toLocalDate(event.getEffectiveDate());
            if (eventLocalEffectiveDate.isAfter(targetDate)) {
                continue;
            }
            // Optimize to do the usage query only once after we know there are indeed some usage items
            if (rawUsgRes == null && Iterables.any(event.getUsages(), new Predicate<Usage>() {

                @Override
                public boolean apply(final Usage input) {
                    return input.getBillingMode() == BillingMode.IN_ARREAR;
                }
            })) {
                rawUsgRes = rawUsageOptimizer.getInArrearUsage(minBillingEventDate, targetDate, Iterables.concat(perSubscriptionInArrearUsageItems.values()), eventSet.getUsages(), dryRunInfo, internalCallContext);
                // Ask Kill Bill team for an optimal configuration based on your use case ;-)
                if (existingInvoices.getCutoffDate() != null && existingInvoices.getCutoffDate().compareTo(rawUsgRes.getRawUsageStartDate()) > 0) {
                    log.warn("Detected an invoice cuttOff date={}, and usage optimized start date= {} that could lead to some issues", existingInvoices.getCutoffDate(), rawUsgRes.getRawUsageStartDate());
                }
            }
            // None of the billing events report any usage IN_ARREAR sections
            if (rawUsgRes == null) {
                continue;
            }
            final UUID subscriptionId = event.getSubscriptionId();
            if (curSubscriptionId != null && !curSubscriptionId.equals(subscriptionId)) {
                final SubscriptionUsageInArrear subscriptionUsageInArrear = new SubscriptionUsageInArrear(account.getId(), invoiceId, curEvents, rawUsgRes.getRawUsage(), rawUsgRes.getExistingTrackingIds(), targetDate, rawUsgRes.getRawUsageStartDate(), usageDetailMode, invoiceConfig, internalCallContext);
                final List<InvoiceItem> usageInArrearItems = perSubscriptionInArrearUsageItems.get(curSubscriptionId);
                final SubscriptionUsageInArrearItemsAndNextNotificationDate subscriptionResult = subscriptionUsageInArrear.computeMissingUsageInvoiceItems(usageInArrearItems != null ? usageInArrearItems : ImmutableList.<InvoiceItem>of(), invoiceItemGeneratorLogger, isDryRun);
                final List<InvoiceItem> newInArrearUsageItems = subscriptionResult.getInvoiceItems();
                items.addAll(newInArrearUsageItems);
                trackingIds.addAll(subscriptionResult.getTrackingIds());
                updatePerSubscriptionNextNotificationUsageDate(curSubscriptionId, subscriptionResult.getPerUsageNotificationDates(), BillingMode.IN_ARREAR, perSubscriptionFutureNotificationDates);
                curEvents = Lists.newArrayList();
            }
            curSubscriptionId = subscriptionId;
            curEvents.add(event);
        }
        if (curSubscriptionId != null) {
            final SubscriptionUsageInArrear subscriptionUsageInArrear = new SubscriptionUsageInArrear(account.getId(), invoiceId, curEvents, rawUsgRes.getRawUsage(), rawUsgRes.getExistingTrackingIds(), targetDate, rawUsgRes.getRawUsageStartDate(), usageDetailMode, invoiceConfig, internalCallContext);
            final List<InvoiceItem> usageInArrearItems = perSubscriptionInArrearUsageItems.get(curSubscriptionId);
            final SubscriptionUsageInArrearItemsAndNextNotificationDate subscriptionResult = subscriptionUsageInArrear.computeMissingUsageInvoiceItems(usageInArrearItems != null ? usageInArrearItems : ImmutableList.<InvoiceItem>of(), invoiceItemGeneratorLogger, isDryRun);
            final List<InvoiceItem> newInArrearUsageItems = subscriptionResult.getInvoiceItems();
            items.addAll(newInArrearUsageItems);
            trackingIds.addAll(subscriptionResult.getTrackingIds());
            updatePerSubscriptionNextNotificationUsageDate(curSubscriptionId, subscriptionResult.getPerUsageNotificationDates(), BillingMode.IN_ARREAR, perSubscriptionFutureNotificationDates);
        }
        invoiceItemGeneratorLogger.logItems();
        return new InvoiceGeneratorResult(items, trackingIds);
    } catch (final CatalogApiException e) {
        throw new InvoiceApiException(e);
    }
}
Also used : TrackingRecordId(org.killbill.billing.invoice.generator.InvoiceWithMetadata.TrackingRecordId) Usage(org.killbill.billing.catalog.api.Usage) InvoiceItem(org.killbill.billing.invoice.api.InvoiceItem) SubscriptionUsageInArrearItemsAndNextNotificationDate(org.killbill.billing.invoice.usage.SubscriptionUsageInArrear.SubscriptionUsageInArrearItemsAndNextNotificationDate) UsageDetailMode(org.killbill.billing.util.config.definition.InvoiceConfig.UsageDetailMode) LocalDate(org.joda.time.LocalDate) Predicate(com.google.common.base.Predicate) InvoiceApiException(org.killbill.billing.invoice.api.InvoiceApiException) CatalogApiException(org.killbill.billing.catalog.api.CatalogApiException) RawUsageOptimizerResult(org.killbill.billing.invoice.usage.RawUsageOptimizer.RawUsageOptimizerResult) ImmutableList(com.google.common.collect.ImmutableList) LinkedList(java.util.LinkedList) List(java.util.List) BillingEvent(org.killbill.billing.junction.BillingEvent) SubscriptionUsageInArrear(org.killbill.billing.invoice.usage.SubscriptionUsageInArrear) UUID(java.util.UUID) HashSet(java.util.HashSet)

Example 79 with CatalogApiException

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

the class StandaloneCatalog method createOrFindPlan.

@Override
public Plan createOrFindPlan(final PlanSpecifier spec, final PlanPhasePriceOverridesWithCallContext unused) throws CatalogApiException {
    final Plan result;
    if (spec.getPlanName() != null) {
        result = findPlan(spec.getPlanName());
    } else {
        if (spec.getProductName() == null) {
            throw new CatalogApiException(ErrorCode.CAT_NULL_PRODUCT_NAME);
        }
        if (spec.getBillingPeriod() == null) {
            throw new CatalogApiException(ErrorCode.CAT_NULL_BILLING_PERIOD);
        }
        final String inputOrDefaultPricelist = (spec.getPriceListName() == null) ? PriceListSet.DEFAULT_PRICELIST_NAME : spec.getPriceListName();
        final Product product = findProduct(spec.getProductName());
        result = ((DefaultPriceListSet) priceLists).getPlanFrom(product, spec.getBillingPeriod(), inputOrDefaultPricelist);
    }
    if (result == null) {
        throw new CatalogApiException(ErrorCode.CAT_PLAN_NOT_FOUND, spec.getPlanName() != null ? spec.getPlanName() : "undefined", spec.getProductName() != null ? spec.getProductName() : "undefined", spec.getBillingPeriod() != null ? spec.getBillingPeriod() : "undefined", spec.getPriceListName() != null ? spec.getPriceListName() : "undefined");
    }
    return result;
}
Also used : CatalogApiException(org.killbill.billing.catalog.api.CatalogApiException) Product(org.killbill.billing.catalog.api.Product) Plan(org.killbill.billing.catalog.api.Plan)

Example 80 with CatalogApiException

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

the class DefaultCatalogUserApi method deleteCatalog.

@Override
public void deleteCatalog(final CallContext callContext) throws CatalogApiException {
    final InternalTenantContext internalTenantContext = internalCallContextFactory.createInternalTenantContextWithoutAccountRecordId(callContext);
    try {
        tenantApi.deleteTenantKey(TenantKey.CATALOG.toString(), callContext);
        catalogCache.clearCatalog(internalTenantContext);
        createDefaultEmptyCatalog(callContext.getCreatedDate(), callContext);
    } catch (final TenantApiException e) {
        throw new CatalogApiException(e);
    }
}
Also used : InternalTenantContext(org.killbill.billing.callcontext.InternalTenantContext) TenantApiException(org.killbill.billing.tenant.api.TenantApiException) CatalogApiException(org.killbill.billing.catalog.api.CatalogApiException)

Aggregations

CatalogApiException (org.killbill.billing.catalog.api.CatalogApiException)106 DateTime (org.joda.time.DateTime)36 SubscriptionBaseApiException (org.killbill.billing.subscription.api.user.SubscriptionBaseApiException)28 InternalCallContext (org.killbill.billing.callcontext.InternalCallContext)22 ArrayList (java.util.ArrayList)21 SubscriptionCatalog (org.killbill.billing.subscription.catalog.SubscriptionCatalog)20 Plan (org.killbill.billing.catalog.api.Plan)19 PlanPhasePriceOverride (org.killbill.billing.catalog.api.PlanPhasePriceOverride)19 DefaultSubscriptionBase (org.killbill.billing.subscription.api.user.DefaultSubscriptionBase)17 UUID (java.util.UUID)14 LinkedList (java.util.LinkedList)13 InternalTenantContext (org.killbill.billing.callcontext.InternalTenantContext)13 StaticCatalog (org.killbill.billing.catalog.api.StaticCatalog)13 HashMap (java.util.HashMap)10 PlanPhaseSpecifier (org.killbill.billing.catalog.api.PlanPhaseSpecifier)10 ImmutableList (com.google.common.collect.ImmutableList)9 List (java.util.List)9 SubscriptionBase (org.killbill.billing.subscription.api.SubscriptionBase)9 SubscriptionBaseEvent (org.killbill.billing.subscription.events.SubscriptionBaseEvent)9 Test (org.testng.annotations.Test)9