Search in sources :

Example 31 with InternalCallContext

use of org.killbill.billing.callcontext.InternalCallContext in project killbill by killbill.

the class DefaultPaymentApi method createAuthorizationWithPaymentControl.

@Override
public Payment createAuthorizationWithPaymentControl(final Account account, final UUID paymentMethodId, @Nullable final UUID paymentId, final BigDecimal amount, final Currency currency, @Nullable final String paymentExternalKey, @Nullable final String paymentTransactionExternalKey, final Iterable<PluginProperty> properties, final PaymentOptions paymentOptions, final CallContext callContext) throws PaymentApiException {
    final List<String> paymentControlPluginNames = toPaymentControlPluginNames(paymentOptions, callContext);
    if (paymentControlPluginNames.isEmpty()) {
        return createAuthorization(account, paymentMethodId, paymentId, amount, currency, paymentExternalKey, paymentTransactionExternalKey, properties, callContext);
    }
    checkNotNullParameter(account, "account");
    if (paymentId == null) {
        checkNotNullParameter(amount, "amount");
        checkNotNullParameter(currency, "currency");
    }
    checkNotNullParameter(properties, "plugin properties");
    checkExternalKeyLength(paymentExternalKey);
    final String transactionType = TransactionType.AUTHORIZE.name();
    Payment payment = null;
    PaymentTransaction paymentTransaction = null;
    PaymentApiException exception = null;
    try {
        logEnterAPICall(log, transactionType, account, paymentMethodId, paymentId, null, amount, currency, paymentExternalKey, paymentTransactionExternalKey, null, paymentControlPluginNames);
        final InternalCallContext internalCallContext = internalCallContextFactory.createInternalCallContext(account.getId(), callContext);
        payment = pluginControlPaymentProcessor.createAuthorization(IS_API_PAYMENT, account, paymentMethodId, paymentId, amount, currency, paymentExternalKey, paymentTransactionExternalKey, properties, paymentControlPluginNames, callContext, internalCallContext);
        paymentTransaction = findPaymentTransaction(payment, paymentTransactionExternalKey);
        return payment;
    } catch (PaymentApiException e) {
        exception = e;
        throw e;
    } finally {
        logExitAPICall(log, transactionType, account, payment != null ? payment.getPaymentMethodId() : null, payment != null ? payment.getId() : null, paymentTransaction != null ? paymentTransaction.getId() : null, paymentTransaction != null ? paymentTransaction.getProcessedAmount() : null, paymentTransaction != null ? paymentTransaction.getProcessedCurrency() : null, payment != null ? payment.getExternalKey() : null, paymentTransaction != null ? paymentTransaction.getExternalKey() : null, paymentTransaction != null ? paymentTransaction.getTransactionStatus() : null, paymentControlPluginNames, exception);
    }
}
Also used : InternalCallContext(org.killbill.billing.callcontext.InternalCallContext)

Example 32 with InternalCallContext

use of org.killbill.billing.callcontext.InternalCallContext in project killbill by killbill.

the class DefaultPaymentApi method createPurchaseWithPaymentControl.

@Override
public Payment createPurchaseWithPaymentControl(final Account account, @Nullable final UUID paymentMethodId, @Nullable final UUID paymentId, final BigDecimal amount, final Currency currency, @Nullable final String paymentExternalKey, final String paymentTransactionExternalKey, final Iterable<PluginProperty> properties, final PaymentOptions paymentOptions, final CallContext callContext) throws PaymentApiException {
    final List<String> paymentControlPluginNames = toPaymentControlPluginNames(paymentOptions, callContext);
    if (paymentControlPluginNames.isEmpty()) {
        return createPurchase(account, paymentMethodId, paymentId, amount, currency, paymentExternalKey, paymentTransactionExternalKey, properties, callContext);
    }
    checkNotNullParameter(account, "account");
    if (paymentId == null) {
        checkNotNullParameter(amount, "amount");
        checkNotNullParameter(currency, "currency");
    }
    checkNotNullParameter(properties, "plugin properties");
    checkExternalKeyLength(paymentTransactionExternalKey);
    if (paymentMethodId == null && !paymentOptions.isExternalPayment()) {
        throw new PaymentApiException(ErrorCode.PAYMENT_NO_DEFAULT_PAYMENT_METHOD, "paymentMethodId", "should not be null");
    }
    final InternalCallContext internalCallContext = internalCallContextFactory.createInternalCallContext(account.getId(), callContext);
    // TODO validate if the code is located properly here
    // The code should understand that the external payment method needs to be created
    // if it doesn't exist yet and trigger a CREDIT using the (built-in) external payment plugin.
    final UUID nonNullPaymentMethodId = (paymentMethodId != null) ? paymentMethodId : paymentMethodProcessor.createOrGetExternalPaymentMethod(UUIDs.randomUUID().toString(), account, properties, callContext, internalCallContext);
    final String transactionType = TransactionType.PURCHASE.name();
    Payment payment = null;
    PaymentTransaction paymentTransaction = null;
    PaymentApiException exception = null;
    try {
        logEnterAPICall(log, transactionType, account, paymentMethodId, paymentId, null, amount, currency, paymentExternalKey, paymentTransactionExternalKey, null, paymentControlPluginNames);
        payment = pluginControlPaymentProcessor.createPurchase(IS_API_PAYMENT, account, nonNullPaymentMethodId, paymentId, amount, currency, paymentExternalKey, paymentTransactionExternalKey, properties, paymentControlPluginNames, callContext, internalCallContext);
        paymentTransaction = findPaymentTransaction(payment, paymentTransactionExternalKey);
        return payment;
    } catch (PaymentApiException e) {
        exception = e;
        throw e;
    } finally {
        logExitAPICall(log, transactionType, account, payment != null ? payment.getPaymentMethodId() : null, payment != null ? payment.getId() : null, paymentTransaction != null ? paymentTransaction.getId() : null, paymentTransaction != null ? paymentTransaction.getProcessedAmount() : null, paymentTransaction != null ? paymentTransaction.getProcessedCurrency() : null, payment != null ? payment.getExternalKey() : null, paymentTransaction != null ? paymentTransaction.getExternalKey() : null, paymentTransaction != null ? paymentTransaction.getTransactionStatus() : null, paymentControlPluginNames, exception);
    }
}
Also used : InternalCallContext(org.killbill.billing.callcontext.InternalCallContext) UUID(java.util.UUID)

Example 33 with InternalCallContext

use of org.killbill.billing.callcontext.InternalCallContext in project killbill by killbill.

the class DefaultEntitlement method cancelEntitlementWithDate.

@Override
public Entitlement cancelEntitlementWithDate(@Nullable final LocalDate entitlementEffectiveDate, final boolean overrideBillingEffectiveDate, final Iterable<PluginProperty> properties, final CallContext callContext) throws EntitlementApiException {
    logCancelEntitlement(log, this, entitlementEffectiveDate, overrideBillingEffectiveDate, null, null);
    checkForPermissions(Permission.ENTITLEMENT_CAN_CANCEL, callContext);
    // Get the latest state from disk
    refresh(callContext);
    if (entitlementEffectiveDate != null && entitlementEffectiveDate.compareTo(getEffectiveStartDate()) < 0) {
        throw new EntitlementApiException(ErrorCode.SUB_INVALID_REQUESTED_DATE, entitlementEffectiveDate, getEffectiveStartDate());
    }
    final LocalDate billingEffectiveDate = overrideBillingEffectiveDate ? entitlementEffectiveDate : null;
    final BaseEntitlementWithAddOnsSpecifier baseEntitlementWithAddOnsSpecifier = new DefaultBaseEntitlementWithAddOnsSpecifier(getBundleId(), getExternalKey(), null, entitlementEffectiveDate, billingEffectiveDate, false);
    final List<BaseEntitlementWithAddOnsSpecifier> baseEntitlementWithAddOnsSpecifierList = new ArrayList<BaseEntitlementWithAddOnsSpecifier>();
    baseEntitlementWithAddOnsSpecifierList.add(baseEntitlementWithAddOnsSpecifier);
    final EntitlementContext pluginContext = new DefaultEntitlementContext(OperationType.CANCEL_SUBSCRIPTION, getAccountId(), null, baseEntitlementWithAddOnsSpecifierList, null, properties, callContext);
    final WithEntitlementPlugin<Entitlement> cancelEntitlementWithPlugin = new WithEntitlementPlugin<Entitlement>() {

        @Override
        public Entitlement doCall(final EntitlementApi entitlementApi, final EntitlementContext updatedPluginContext) throws EntitlementApiException {
            if (eventsStream.isEntitlementCancelled()) {
                throw new EntitlementApiException(ErrorCode.SUB_CANCEL_BAD_STATE, getId(), EntitlementState.CANCELLED);
            }
            final InternalCallContext contextWithValidAccountRecordId = internalCallContextFactory.createInternalCallContext(getAccountId(), callContext);
            final DateTime effectiveCancelDate = dateHelper.fromLocalDateAndReferenceTimeWithMinimum(entitlementEffectiveDate, getEventsStream().getEntitlementEffectiveStartDateTime(), contextWithValidAccountRecordId);
            try {
                if (overrideBillingEffectiveDate) {
                    getSubscriptionBase().cancelWithDate(effectiveCancelDate, callContext);
                } else {
                    getSubscriptionBase().cancel(callContext);
                }
            } catch (final SubscriptionBaseApiException e) {
                throw new EntitlementApiException(e);
            }
            final BlockingState newBlockingState = new DefaultBlockingState(getId(), BlockingStateType.SUBSCRIPTION, DefaultEntitlementApi.ENT_STATE_CANCELLED, EntitlementService.ENTITLEMENT_SERVICE_NAME, 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) LocalDate(org.joda.time.LocalDate) 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) PlanPhasePriceOverride(org.killbill.billing.catalog.api.PlanPhasePriceOverride)

Example 34 with InternalCallContext

use of org.killbill.billing.callcontext.InternalCallContext in project killbill by killbill.

the class DefaultEntitlement method uncancelEntitlement.

@Override
public void uncancelEntitlement(final Iterable<PluginProperty> properties, final CallContext callContext) throws EntitlementApiException {
    logUncancelEntitlement(log, this);
    checkForPermissions(Permission.ENTITLEMENT_CAN_CANCEL, callContext);
    // Get the latest state from disk
    refresh(callContext);
    final BaseEntitlementWithAddOnsSpecifier baseEntitlementWithAddOnsSpecifier = new DefaultBaseEntitlementWithAddOnsSpecifier(getBundleId(), getExternalKey(), null, null, null, false);
    final List<BaseEntitlementWithAddOnsSpecifier> baseEntitlementWithAddOnsSpecifierList = new ArrayList<BaseEntitlementWithAddOnsSpecifier>();
    baseEntitlementWithAddOnsSpecifierList.add(baseEntitlementWithAddOnsSpecifier);
    final EntitlementContext pluginContext = new DefaultEntitlementContext(OperationType.UNCANCEL_SUBSCRIPTION, getAccountId(), null, baseEntitlementWithAddOnsSpecifierList, null, properties, callContext);
    final WithEntitlementPlugin<Void> uncancelEntitlementWithPlugin = new WithEntitlementPlugin<Void>() {

        @Override
        public Void doCall(final EntitlementApi entitlementApi, final EntitlementContext updatedPluginContext) throws EntitlementApiException {
            if (eventsStream.isSubscriptionCancelled()) {
                throw new EntitlementApiException(ErrorCode.SUB_UNCANCEL_BAD_STATE, getId());
            }
            final InternalCallContext contextWithValidAccountRecordId = internalCallContextFactory.createInternalCallContext(getAccountId(), callContext);
            final Collection<BlockingState> pendingEntitlementCancellationEvents = eventsStream.getPendingEntitlementCancellationEvents();
            if (eventsStream.isEntitlementCancelled()) {
                final BlockingState cancellationEvent = eventsStream.getEntitlementCancellationEvent();
                blockingStateDao.unactiveBlockingState(cancellationEvent.getId(), contextWithValidAccountRecordId);
            } else if (pendingEntitlementCancellationEvents.size() > 0) {
                //
                for (final BlockingState futureCancellation : pendingEntitlementCancellationEvents) {
                    blockingStateDao.unactiveBlockingState(futureCancellation.getId(), contextWithValidAccountRecordId);
                }
            } else {
                // Entitlement is NOT cancelled (or future cancelled), there is nothing to do
                throw new EntitlementApiException(ErrorCode.ENT_UNCANCEL_BAD_STATE, getId());
            }
            // If billing was previously cancelled, reactivate
            if (getSubscriptionBase().getFutureEndDate() != null) {
                try {
                    getSubscriptionBase().uncancel(callContext);
                } catch (final SubscriptionBaseApiException e) {
                    throw new EntitlementApiException(e);
                }
            }
            return null;
        }
    };
    pluginExecution.executeWithPlugin(uncancelEntitlementWithPlugin, pluginContext);
}
Also used : WithEntitlementPlugin(org.killbill.billing.entitlement.api.EntitlementPluginExecution.WithEntitlementPlugin) ArrayList(java.util.ArrayList) InternalCallContext(org.killbill.billing.callcontext.InternalCallContext) DefaultBlockingState(org.killbill.billing.junction.DefaultBlockingState) EntitlementContext(org.killbill.billing.entitlement.plugin.api.EntitlementContext) SubscriptionBaseApiException(org.killbill.billing.subscription.api.user.SubscriptionBaseApiException) PlanPhasePriceOverride(org.killbill.billing.catalog.api.PlanPhasePriceOverride)

Example 35 with InternalCallContext

use of org.killbill.billing.callcontext.InternalCallContext in project killbill by killbill.

the class DefaultEntitlement method changePlan.

@Override
public Entitlement changePlan(final PlanSpecifier spec, final List<PlanPhasePriceOverride> overrides, final Iterable<PluginProperty> properties, final CallContext callContext) throws EntitlementApiException {
    logChangePlan(log, this, spec, overrides, null, null);
    checkForPermissions(Permission.ENTITLEMENT_CAN_CHANGE_PLAN, callContext);
    // Get the latest state from disk
    refresh(callContext);
    final BaseEntitlementWithAddOnsSpecifier baseEntitlementWithAddOnsSpecifier = new DefaultBaseEntitlementWithAddOnsSpecifier(getBundleId(), getExternalKey(), 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, null, properties, callContext);
    final WithEntitlementPlugin<Entitlement> changePlanWithPlugin = new WithEntitlementPlugin<Entitlement>() {

        @Override
        public Entitlement doCall(final EntitlementApi entitlementApi, final EntitlementContext updatedPluginContext) throws EntitlementApiException {
            if (!eventsStream.isEntitlementActive()) {
                throw new EntitlementApiException(ErrorCode.SUB_CHANGE_NON_ACTIVE, getId(), getState());
            }
            final InternalCallContext context = internalCallContextFactory.createInternalCallContext(getAccountId(), callContext);
            final DateTime effectiveChangeDate;
            try {
                effectiveChangeDate = subscriptionInternalApi.getDryRunChangePlanEffectiveDate(getSubscriptionBase(), spec, null, null, overrides, 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(), effectiveChangeDate, context);
            } catch (final BlockingApiException e) {
                throw new EntitlementApiException(e, e.getCode(), e.getMessage());
            }
            try {
                getSubscriptionBase().changePlan(spec, overrides, callContext);
            } catch (final SubscriptionBaseApiException e) {
                throw new EntitlementApiException(e);
            }
            final Collection<NotificationEvent> notificationEvents = new ArrayList<NotificationEvent>();
            final Iterable<BlockingState> addOnsBlockingStates = computeAddOnBlockingStates(effectiveChangeDate, 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(effectiveChangeDate, 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) PlanPhasePriceOverride(org.killbill.billing.catalog.api.PlanPhasePriceOverride)

Aggregations

InternalCallContext (org.killbill.billing.callcontext.InternalCallContext)110 PlanPhasePriceOverride (org.killbill.billing.catalog.api.PlanPhasePriceOverride)26 DateTime (org.joda.time.DateTime)25 UUID (java.util.UUID)24 ArrayList (java.util.ArrayList)21 SubscriptionBaseApiException (org.killbill.billing.subscription.api.user.SubscriptionBaseApiException)17 InvoiceApiException (org.killbill.billing.invoice.api.InvoiceApiException)14 CallContext (org.killbill.billing.util.callcontext.CallContext)14 CatalogApiException (org.killbill.billing.catalog.api.CatalogApiException)13 WithEntitlementPlugin (org.killbill.billing.entitlement.api.EntitlementPluginExecution.WithEntitlementPlugin)13 EntitlementContext (org.killbill.billing.entitlement.plugin.api.EntitlementContext)13 AccountApiException (org.killbill.billing.account.api.AccountApiException)12 DefaultBlockingState (org.killbill.billing.junction.DefaultBlockingState)12 NotificationEvent (org.killbill.notificationq.api.NotificationEvent)9 BigDecimal (java.math.BigDecimal)8 LinkedList (java.util.LinkedList)8 InternalTenantContext (org.killbill.billing.callcontext.InternalTenantContext)8 Invoice (org.killbill.billing.invoice.api.Invoice)8 AllowConcurrentEvents (com.google.common.eventbus.AllowConcurrentEvents)7 Subscribe (com.google.common.eventbus.Subscribe)7