Search in sources :

Example 86 with CatalogApiException

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

the class InvoiceItemFactory method computePrettyName.

// 
// Returns an array of string for 'pretty' names [prettyPlanName, prettyPlanPhaseName, prettyUsageName]
// 
private static String[] computePrettyName(final InvoiceItemType type, final DateTime transitionDate, @Nullable final String productName, @Nullable final String planName, @Nullable final String phaseName, @Nullable final String usageName, @Nullable final VersionedCatalog catalog) {
    final String[] result = new String[4];
    final boolean computePrettyName = catalog != null && (type == InvoiceItemType.FIXED || type == InvoiceItemType.RECURRING || type == InvoiceItemType.TAX || type == InvoiceItemType.USAGE);
    String prettyProductName = null;
    String prettyPlanName = null;
    String prettyPlanPhaseName = null;
    String prettyUsageName = null;
    // Trying to optimize safe default behavior by checking both input and each intermediary null result at each step -- and doing poor on the Cyclomatic complexity
    try {
        if (computePrettyName) {
            if (planName != null) {
                // We are simply looking for the most recent version of a catalog version having such plan
                // Finding the right entry would require some expensive operations which are probably not worth it for this use case.
                Plan plan = null;
                final List<StaticCatalog> versions = catalog.getVersions();
                for (int i = versions.size() - 1; i >= 0; i--) {
                    final StaticCatalog curVersion = versions.get(i);
                    try {
                        plan = curVersion.findPlan(planName);
                    } catch (final CatalogApiException e) {
                        if (e.getCode() != ErrorCode.CAT_NO_SUCH_PLAN.getCode()) {
                            throw e;
                        }
                    }
                    if (plan != null) {
                        break;
                    }
                }
                if (plan != null) {
                    prettyPlanName = plan.getPrettyName();
                    if (productName != null) {
                        Preconditions.checkState(plan.getProduct().getName().equals(productName));
                        prettyProductName = plan.getProduct().getPrettyName();
                    }
                    if (phaseName != null) {
                        final PlanPhase planPhase = plan.findPhase(phaseName);
                        if (planPhase != null) {
                            prettyPlanPhaseName = planPhase.getPrettyName();
                            if (usageName != null) {
                                Usage usage = null;
                                for (Usage cur : planPhase.getUsages()) {
                                    if (cur.getName().equals(usageName)) {
                                        usage = cur;
                                        break;
                                    }
                                }
                                if (usage != null) {
                                    prettyUsageName = usage.getPrettyName();
                                }
                            }
                        }
                    }
                }
            }
        }
    } catch (final CatalogApiException e) {
        log.warn("Failed to compute invoice pretty names:", e.getMessage());
    } finally {
        result[0] = prettyProductName;
        result[1] = prettyPlanName;
        result[2] = prettyPlanPhaseName;
        result[3] = prettyUsageName;
    }
    return result;
}
Also used : Usage(org.killbill.billing.catalog.api.Usage) CatalogApiException(org.killbill.billing.catalog.api.CatalogApiException) PlanPhase(org.killbill.billing.catalog.api.PlanPhase) Plan(org.killbill.billing.catalog.api.Plan) StaticCatalog(org.killbill.billing.catalog.api.StaticCatalog)

Example 87 with CatalogApiException

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

the class BundleResource method searchBundles.

@TimedResource
@GET
@Path("/" + SEARCH + "/{searchKey:" + ANYTHING_PATTERN + "}")
@Produces(APPLICATION_JSON)
@ApiOperation(value = "Search bundles", response = BundleJson.class, responseContainer = "List")
@ApiResponses(value = {})
public Response searchBundles(@PathParam("searchKey") final String searchKey, @QueryParam(QUERY_SEARCH_OFFSET) @DefaultValue("0") final Long offset, @QueryParam(QUERY_SEARCH_LIMIT) @DefaultValue("100") final Long limit, @QueryParam(QUERY_AUDIT) @DefaultValue("NONE") final AuditMode auditMode, @javax.ws.rs.core.Context final HttpServletRequest request) throws SubscriptionApiException {
    final TenantContext tenantContext = context.createTenantContextNoAccountId(request);
    final Pagination<SubscriptionBundle> bundles = subscriptionApi.searchSubscriptionBundles(searchKey, offset, limit, tenantContext);
    final URI nextPageUri = uriBuilder.nextPage(BundleResource.class, "searchBundles", bundles.getNextOffset(), limit, ImmutableMap.<String, String>of(QUERY_AUDIT, auditMode.getLevel().toString()), ImmutableMap.<String, String>of("searchKey", searchKey));
    final AtomicReference<Map<UUID, AccountAuditLogs>> accountsAuditLogs = new AtomicReference<Map<UUID, AccountAuditLogs>>(new HashMap<UUID, AccountAuditLogs>());
    return buildStreamingPaginationResponse(bundles, new Function<SubscriptionBundle, BundleJson>() {

        @Override
        public BundleJson apply(final SubscriptionBundle bundle) {
            // Cache audit logs per account
            if (accountsAuditLogs.get().get(bundle.getAccountId()) == null) {
                accountsAuditLogs.get().put(bundle.getAccountId(), auditUserApi.getAccountAuditLogs(bundle.getAccountId(), auditMode.getLevel(), tenantContext));
            }
            try {
                return new BundleJson(bundle, null, accountsAuditLogs.get().get(bundle.getAccountId()));
            } catch (final CatalogApiException unused) {
                // Does not happen because we pass a null Currency
                throw new RuntimeException(unused);
            }
        }
    }, nextPageUri);
}
Also used : TenantContext(org.killbill.billing.util.callcontext.TenantContext) AtomicReference(java.util.concurrent.atomic.AtomicReference) URI(java.net.URI) BundleJson(org.killbill.billing.jaxrs.json.BundleJson) SubscriptionBundle(org.killbill.billing.entitlement.api.SubscriptionBundle) CatalogApiException(org.killbill.billing.catalog.api.CatalogApiException) UUID(java.util.UUID) AccountAuditLogs(org.killbill.billing.util.audit.AccountAuditLogs) Map(java.util.Map) ImmutableMap(com.google.common.collect.ImmutableMap) HashMap(java.util.HashMap) Path(javax.ws.rs.Path) TimedResource(org.killbill.commons.metrics.TimedResource) Produces(javax.ws.rs.Produces) GET(javax.ws.rs.GET) ApiOperation(io.swagger.annotations.ApiOperation) ApiResponses(io.swagger.annotations.ApiResponses)

Example 88 with CatalogApiException

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

the class DefaultSubscriptionBaseTransferApi method toEvents.

@VisibleForTesting
List<SubscriptionBaseEvent> toEvents(final List<ExistingEvent> existingEvents, final DefaultSubscriptionBase subscription, final DateTime transferDate, final InternalTenantContext context) throws SubscriptionBaseTransferApiException {
    try {
        final List<SubscriptionBaseEvent> result = new LinkedList<SubscriptionBaseEvent>();
        SubscriptionBaseEvent event = null;
        ExistingEvent prevEvent = null;
        boolean firstEvent = true;
        for (ExistingEvent cur : existingEvents) {
            // Skip all events prior to the transferDate
            if (cur.getEffectiveDate().isBefore(transferDate)) {
                prevEvent = cur;
                continue;
            }
            // Add previous event the first time if needed
            if (prevEvent != null) {
                event = createEvent(firstEvent, prevEvent, subscription, transferDate, context);
                if (event != null) {
                    result.add(event);
                    firstEvent = false;
                }
                prevEvent = null;
            }
            event = createEvent(firstEvent, cur, subscription, transferDate, context);
            if (event != null) {
                result.add(event);
                firstEvent = false;
            }
        }
        // Previous loop did not get anything because transferDate is greater than effectiveDate of last event
        if (prevEvent != null) {
            event = createEvent(firstEvent, prevEvent, subscription, transferDate, context);
            if (event != null) {
                result.add(event);
            }
            prevEvent = null;
        }
        return result;
    } catch (CatalogApiException e) {
        throw new SubscriptionBaseTransferApiException(e);
    }
}
Also used : CatalogApiException(org.killbill.billing.catalog.api.CatalogApiException) ExistingEvent(org.killbill.billing.subscription.api.timeline.SubscriptionBaseTimeline.ExistingEvent) SubscriptionBaseEvent(org.killbill.billing.subscription.events.SubscriptionBaseEvent) LinkedList(java.util.LinkedList) VisibleForTesting(com.google.common.annotations.VisibleForTesting)

Example 89 with CatalogApiException

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

the class DefaultSubscriptionBaseApiService method doCancelPlan.

private boolean doCancelPlan(final Map<DefaultSubscriptionBase, DateTime> subscriptions, final SubscriptionCatalog catalog, final InternalCallContext internalCallContext) throws SubscriptionBaseApiException {
    final List<DefaultSubscriptionBase> subscriptionsToBeCancelled = new LinkedList<DefaultSubscriptionBase>();
    final List<SubscriptionBaseEvent> cancelEvents = new LinkedList<SubscriptionBaseEvent>();
    try {
        for (final DefaultSubscriptionBase subscription : subscriptions.keySet()) {
            final EntitlementState currentState = subscription.getState();
            if (currentState == EntitlementState.CANCELLED) {
                throw new SubscriptionBaseApiException(ErrorCode.SUB_CANCEL_BAD_STATE, subscription.getId(), currentState);
            }
            final DateTime effectiveDate = subscriptions.get(subscription);
            // If subscription was future cancelled at an earlier date we disallow the operation -- i.e,
            // user should first uncancel prior trying to cancel again.
            // However, note that in case a future cancellation already exists with a greater or equal effectiveDate,
            // the operation is allowed, but such existing cancellation would become invalidated (is_active=0)
            final SubscriptionBaseTransition pendingTransition = subscription.getPendingTransition();
            if (pendingTransition != null && pendingTransition.getTransitionType() == SubscriptionBaseTransitionType.CANCEL && pendingTransition.getEffectiveTransitionTime().compareTo(effectiveDate) < 0) {
                throw new SubscriptionBaseApiException(ErrorCode.SUB_CANCEL_BAD_STATE, subscription.getId(), "PENDING CANCELLED");
            }
            validateEffectiveDate(subscription, effectiveDate);
            subscriptionsToBeCancelled.add(subscription);
            cancelEvents.addAll(getEventsOnCancelPlan(subscription, effectiveDate, false, catalog, internalCallContext));
            if (subscription.getCategory() == ProductCategory.BASE) {
                subscriptionsToBeCancelled.addAll(computeAddOnsToCancel(cancelEvents, null, subscription.getBundleId(), effectiveDate, catalog, internalCallContext));
            }
        }
        dao.cancelSubscriptions(subscriptionsToBeCancelled, cancelEvents, catalog, internalCallContext);
        boolean allSubscriptionsCancelled = true;
        for (final DefaultSubscriptionBase subscription : subscriptions.keySet()) {
            subscription.rebuildTransitions(dao.getEventsForSubscription(subscription.getId(), internalCallContext), catalog);
            allSubscriptionsCancelled = allSubscriptionsCancelled && (subscription.getState() == EntitlementState.CANCELLED);
        }
        return allSubscriptionsCancelled;
    } catch (final CatalogApiException e) {
        throw new SubscriptionBaseApiException(e);
    }
}
Also used : CatalogApiException(org.killbill.billing.catalog.api.CatalogApiException) SubscriptionBaseEvent(org.killbill.billing.subscription.events.SubscriptionBaseEvent) LinkedList(java.util.LinkedList) EntitlementState(org.killbill.billing.entitlement.api.Entitlement.EntitlementState) DateTime(org.joda.time.DateTime)

Example 90 with CatalogApiException

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

the class DefaultSubscriptionBaseApiService method cancelWithPolicyNoValidationAndCatalog.

@Override
public boolean cancelWithPolicyNoValidationAndCatalog(final Iterable<DefaultSubscriptionBase> subscriptions, final BillingActionPolicy policy, final SubscriptionCatalog catalog, final InternalCallContext context) throws SubscriptionBaseApiException {
    final Map<DefaultSubscriptionBase, DateTime> subscriptionsWithEffectiveDate = new HashMap<DefaultSubscriptionBase, DateTime>();
    try {
        for (final DefaultSubscriptionBase subscription : subscriptions) {
            final BillingAlignment billingAlignment = (subscription.getState() == EntitlementState.PENDING ? null : catalog.billingAlignment(new PlanPhaseSpecifier(subscription.getLastActivePlan().getName(), subscription.getLastActivePhase().getPhaseType()), clock.getUTCNow(), subscription.getLastTransitionForCurrentPlan().getEffectiveTransitionTime()));
            final Integer accountBillCycleDayLocal = accountInternalApi.getBCD(context);
            final DateTime effectiveDate = subscription.getEffectiveDateForPolicy(policy, billingAlignment, accountBillCycleDayLocal, context);
            subscriptionsWithEffectiveDate.put(subscription, effectiveDate);
        }
        return doCancelPlan(subscriptionsWithEffectiveDate, catalog, context);
    } catch (final CatalogApiException e) {
        throw new SubscriptionBaseApiException(e);
    } catch (final AccountApiException e) {
        throw new SubscriptionBaseApiException(e);
    }
}
Also used : PlanPhaseSpecifier(org.killbill.billing.catalog.api.PlanPhaseSpecifier) HashMap(java.util.HashMap) CatalogApiException(org.killbill.billing.catalog.api.CatalogApiException) AccountApiException(org.killbill.billing.account.api.AccountApiException) BillingAlignment(org.killbill.billing.catalog.api.BillingAlignment) DateTime(org.joda.time.DateTime)

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