Search in sources :

Example 26 with Currency

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

the class IncompletePaymentTransactionTask method updatePaymentAndTransactionInternal.

private boolean updatePaymentAndTransactionInternal(final PaymentModelDao payment, @Nullable final Integer attemptNumber, @Nullable final UUID userToken, final PaymentTransactionModelDao paymentTransaction, final PaymentTransactionInfoPlugin paymentTransactionInfoPlugin, final InternalTenantContext internalTenantContext) {
    final CallContext callContext = createCallContext("IncompletePaymentTransactionTask", internalTenantContext);
    // First obtain the new transactionStatus,
    // Then compute the new paymentState; this one is mostly interesting in case of success (to compute the lastSuccessPaymentState below)
    final TransactionStatus transactionStatus = computeNewTransactionStatusFromPaymentTransactionInfoPlugin(paymentTransactionInfoPlugin, paymentTransaction.getTransactionStatus());
    final String newPaymentState;
    switch(transactionStatus) {
        case PENDING:
            newPaymentState = paymentStateMachineHelper.getPendingStateForTransaction(paymentTransaction.getTransactionType());
            break;
        case SUCCESS:
            newPaymentState = paymentStateMachineHelper.getSuccessfulStateForTransaction(paymentTransaction.getTransactionType());
            break;
        case PAYMENT_FAILURE:
            newPaymentState = paymentStateMachineHelper.getFailureStateForTransaction(paymentTransaction.getTransactionType());
            break;
        case PLUGIN_FAILURE:
            newPaymentState = paymentStateMachineHelper.getErroredStateForTransaction(paymentTransaction.getTransactionType());
            break;
        case UNKNOWN:
        default:
            if (transactionStatus != paymentTransaction.getTransactionStatus()) {
                log.info("Unable to repair paymentId='{}', paymentTransactionId='{}', currentTransactionStatus='{}', newTransactionStatus='{}'", payment.getId(), paymentTransaction.getId(), paymentTransaction.getTransactionStatus(), transactionStatus);
            }
            // We can't get anything interesting from the plugin...
            insertNewNotificationForUnresolvedTransactionIfNeeded(paymentTransaction.getId(), attemptNumber, userToken, internalTenantContext.getAccountRecordId(), internalTenantContext.getTenantRecordId());
            return false;
    }
    // Our status did not change, so we just insert a new notification (attemptNumber will be incremented)
    if (transactionStatus == paymentTransaction.getTransactionStatus()) {
        log.debug("Janitor IncompletePaymentTransactionTask repairing payment {}, transaction {}, transitioning transactionStatus from {} -> {}", payment.getId(), paymentTransaction.getId(), paymentTransaction.getTransactionStatus(), transactionStatus);
        insertNewNotificationForUnresolvedTransactionIfNeeded(paymentTransaction.getId(), attemptNumber, userToken, internalTenantContext.getAccountRecordId(), internalTenantContext.getTenantRecordId());
        return false;
    }
    // Recompute new lastSuccessPaymentState. This is important to be able to allow new operations on the state machine (for e.g an AUTH_SUCCESS would now allow a CAPTURE operation)
    final String lastSuccessPaymentState = paymentStateMachineHelper.isSuccessState(newPaymentState) ? newPaymentState : null;
    // Update processedAmount and processedCurrency
    final BigDecimal processedAmount;
    if (TransactionStatus.SUCCESS.equals(transactionStatus) || TransactionStatus.PENDING.equals(transactionStatus)) {
        if (paymentTransactionInfoPlugin == null || paymentTransactionInfoPlugin.getAmount() == null) {
            processedAmount = paymentTransaction.getProcessedAmount();
        } else {
            processedAmount = paymentTransactionInfoPlugin.getAmount();
        }
    } else {
        processedAmount = BigDecimal.ZERO;
    }
    final Currency processedCurrency;
    if (paymentTransactionInfoPlugin == null || paymentTransactionInfoPlugin.getCurrency() == null) {
        processedCurrency = paymentTransaction.getProcessedCurrency();
    } else {
        processedCurrency = paymentTransactionInfoPlugin.getCurrency();
    }
    // Update the gatewayErrorCode, gatewayError if we got a paymentTransactionInfoPlugin
    final String gatewayErrorCode = paymentTransactionInfoPlugin != null ? paymentTransactionInfoPlugin.getGatewayErrorCode() : paymentTransaction.getGatewayErrorCode();
    final String gatewayError = paymentTransactionInfoPlugin != null ? paymentTransactionInfoPlugin.getGatewayError() : paymentTransaction.getGatewayErrorMsg();
    log.info("Repairing paymentId='{}', paymentTransactionId='{}', currentTransactionStatus='{}', newTransactionStatus='{}'", payment.getId(), paymentTransaction.getId(), paymentTransaction.getTransactionStatus(), transactionStatus);
    final InternalCallContext internalCallContext = internalCallContextFactory.createInternalCallContext(payment.getAccountId(), callContext);
    paymentDao.updatePaymentAndTransactionOnCompletion(payment.getAccountId(), paymentTransaction.getAttemptId(), payment.getId(), paymentTransaction.getTransactionType(), newPaymentState, lastSuccessPaymentState, paymentTransaction.getId(), transactionStatus, processedAmount, processedCurrency, gatewayErrorCode, gatewayError, internalCallContext);
    return true;
}
Also used : Currency(org.killbill.billing.catalog.api.Currency) TransactionStatus(org.killbill.billing.payment.api.TransactionStatus) InternalCallContext(org.killbill.billing.callcontext.InternalCallContext) InternalCallContext(org.killbill.billing.callcontext.InternalCallContext) CallContext(org.killbill.billing.util.callcontext.CallContext) BigDecimal(java.math.BigDecimal)

Example 27 with Currency

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

the class DefaultInvoiceUserApi method insertExternalCharges.

@Override
public List<InvoiceItem> insertExternalCharges(final UUID accountId, final LocalDate effectiveDate, final Iterable<InvoiceItem> charges, final boolean autoCommit, final CallContext context) throws InvoiceApiException {
    for (final InvoiceItem charge : charges) {
        if (charge.getAmount() == null || charge.getAmount().compareTo(BigDecimal.ZERO) <= 0) {
            throw new InvoiceApiException(ErrorCode.EXTERNAL_CHARGE_AMOUNT_INVALID, charge.getAmount());
        }
    }
    final WithAccountLock withAccountLock = new WithAccountLock() {

        @Override
        public Iterable<Invoice> prepareInvoices() throws InvoiceApiException {
            final InternalTenantContext internalTenantContext = internalCallContextFactory.createInternalTenantContext(accountId, context);
            final LocalDate invoiceDate = internalTenantContext.toLocalDate(context.getCreatedDate());
            // Group all new external charges on the same invoice (per currency)
            final Map<Currency, Invoice> newInvoicesForExternalCharges = new HashMap<Currency, Invoice>();
            final Map<UUID, Invoice> existingInvoicesForExternalCharges = new HashMap<UUID, Invoice>();
            for (final InvoiceItem charge : charges) {
                final Invoice invoiceForExternalCharge;
                final UUID invoiceIdForExternalCharge = charge.getInvoiceId();
                // Create an invoice for that external charge if it doesn't exist
                if (invoiceIdForExternalCharge == null) {
                    final Currency currency = charge.getCurrency();
                    if (newInvoicesForExternalCharges.get(currency) == null) {
                        final InvoiceStatus status = autoCommit ? InvoiceStatus.COMMITTED : InvoiceStatus.DRAFT;
                        final Invoice newInvoiceForExternalCharge = new DefaultInvoice(accountId, invoiceDate, effectiveDate, currency, status);
                        newInvoicesForExternalCharges.put(currency, newInvoiceForExternalCharge);
                    }
                    invoiceForExternalCharge = newInvoicesForExternalCharges.get(currency);
                } else {
                    if (existingInvoicesForExternalCharges.get(invoiceIdForExternalCharge) == null) {
                        final Invoice existingInvoiceForExternalCharge = getInvoice(invoiceIdForExternalCharge, context);
                        existingInvoicesForExternalCharges.put(invoiceIdForExternalCharge, existingInvoiceForExternalCharge);
                    }
                    invoiceForExternalCharge = existingInvoicesForExternalCharges.get(invoiceIdForExternalCharge);
                }
                final InvoiceItem externalCharge = new ExternalChargeInvoiceItem(UUIDs.randomUUID(), context.getCreatedDate(), invoiceForExternalCharge.getId(), accountId, charge.getBundleId(), charge.getDescription(), effectiveDate, charge.getAmount(), charge.getCurrency());
                invoiceForExternalCharge.addInvoiceItem(externalCharge);
            }
            return Iterables.<Invoice>concat(newInvoicesForExternalCharges.values(), existingInvoicesForExternalCharges.values());
        }
    };
    return invoiceApiHelper.dispatchToInvoicePluginsAndInsertItems(accountId, false, withAccountLock, context);
}
Also used : InvoiceItem(org.killbill.billing.invoice.api.InvoiceItem) ExternalChargeInvoiceItem(org.killbill.billing.invoice.model.ExternalChargeInvoiceItem) CreditAdjInvoiceItem(org.killbill.billing.invoice.model.CreditAdjInvoiceItem) Invoice(org.killbill.billing.invoice.api.Invoice) HtmlInvoice(org.killbill.billing.invoice.template.HtmlInvoice) DefaultInvoice(org.killbill.billing.invoice.model.DefaultInvoice) HashMap(java.util.HashMap) WithAccountLock(org.killbill.billing.invoice.api.WithAccountLock) ExternalChargeInvoiceItem(org.killbill.billing.invoice.model.ExternalChargeInvoiceItem) LocalDate(org.joda.time.LocalDate) InvoiceApiException(org.killbill.billing.invoice.api.InvoiceApiException) InternalTenantContext(org.killbill.billing.callcontext.InternalTenantContext) Currency(org.killbill.billing.catalog.api.Currency) UUID(java.util.UUID) InvoiceStatus(org.killbill.billing.invoice.api.InvoiceStatus) DefaultInvoice(org.killbill.billing.invoice.model.DefaultInvoice)

Example 28 with Currency

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

the class InvoiceItemFactory method fromModelDao.

public static InvoiceItem fromModelDao(final InvoiceItemModelDao invoiceItemModelDao) {
    if (invoiceItemModelDao == null) {
        return null;
    }
    final UUID id = invoiceItemModelDao.getId();
    final DateTime createdDate = invoiceItemModelDao.getCreatedDate();
    final UUID invoiceId = invoiceItemModelDao.getInvoiceId();
    final UUID accountId = invoiceItemModelDao.getAccountId();
    final UUID childAccountId = invoiceItemModelDao.getChildAccountId();
    final UUID bundleId = invoiceItemModelDao.getBundleId();
    final UUID subscriptionId = invoiceItemModelDao.getSubscriptionId();
    final String planName = invoiceItemModelDao.getPlanName();
    final String phaseName = invoiceItemModelDao.getPhaseName();
    final String usageName = invoiceItemModelDao.getUsageName();
    final String description = invoiceItemModelDao.getDescription();
    final LocalDate startDate = invoiceItemModelDao.getStartDate();
    final LocalDate endDate = invoiceItemModelDao.getEndDate();
    final BigDecimal amount = invoiceItemModelDao.getAmount();
    final BigDecimal rate = invoiceItemModelDao.getRate();
    final Currency currency = invoiceItemModelDao.getCurrency();
    final UUID linkedItemId = invoiceItemModelDao.getLinkedItemId();
    final InvoiceItem item;
    final InvoiceItemType type = invoiceItemModelDao.getType();
    switch(type) {
        case EXTERNAL_CHARGE:
            item = new ExternalChargeInvoiceItem(id, createdDate, invoiceId, accountId, bundleId, description, startDate, amount, currency);
            break;
        case FIXED:
            item = new FixedPriceInvoiceItem(id, createdDate, invoiceId, accountId, bundleId, subscriptionId, planName, phaseName, description, startDate, amount, currency);
            break;
        case RECURRING:
            item = new RecurringInvoiceItem(id, createdDate, invoiceId, accountId, bundleId, subscriptionId, planName, phaseName, description, startDate, endDate, amount, rate, currency);
            break;
        case CBA_ADJ:
            item = new CreditBalanceAdjInvoiceItem(id, createdDate, invoiceId, accountId, startDate, linkedItemId, description, amount, currency);
            break;
        case CREDIT_ADJ:
            item = new CreditAdjInvoiceItem(id, createdDate, invoiceId, accountId, startDate, description, amount, currency);
            break;
        case REPAIR_ADJ:
            item = new RepairAdjInvoiceItem(id, createdDate, invoiceId, accountId, startDate, endDate, description, amount, currency, linkedItemId);
            break;
        case ITEM_ADJ:
            item = new ItemAdjInvoiceItem(id, createdDate, invoiceId, accountId, startDate, description, amount, currency, linkedItemId);
            break;
        case USAGE:
            item = new UsageInvoiceItem(id, createdDate, invoiceId, accountId, bundleId, subscriptionId, planName, phaseName, usageName, startDate, endDate, description, amount, currency);
            break;
        case TAX:
            item = new TaxInvoiceItem(id, createdDate, invoiceId, accountId, bundleId, subscriptionId, planName, phaseName, usageName, startDate, description, amount, currency, linkedItemId);
            break;
        case PARENT_SUMMARY:
            item = new ParentInvoiceItem(id, createdDate, invoiceId, accountId, childAccountId, amount, currency, description);
            break;
        default:
            throw new RuntimeException("Unexpected type of event item " + type);
    }
    return item;
}
Also used : InvoiceItem(org.killbill.billing.invoice.api.InvoiceItem) LocalDate(org.joda.time.LocalDate) DateTime(org.joda.time.DateTime) BigDecimal(java.math.BigDecimal) Currency(org.killbill.billing.catalog.api.Currency) UUID(java.util.UUID) InvoiceItemType(org.killbill.billing.invoice.api.InvoiceItemType)

Example 29 with Currency

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

the class BlockingCalculator method createNewDisableEvent.

protected BillingEvent createNewDisableEvent(final DateTime odEventTime, final BillingEvent previousEvent, final Catalog catalog, final InternalTenantContext context) throws CatalogApiException {
    final int billCycleDay = previousEvent.getBillCycleDayLocal();
    final SubscriptionBase subscription = previousEvent.getSubscription();
    final DateTime effectiveDate = odEventTime;
    final PlanPhase planPhase = previousEvent.getPlanPhase();
    final Plan plan = previousEvent.getPlan();
    // Make sure to set the fixed price to null and the billing period to NO_BILLING_PERIOD,
    // which makes invoice disregard this event
    final BigDecimal fixedPrice = null;
    final BillingPeriod billingPeriod = BillingPeriod.NO_BILLING_PERIOD;
    final Currency currency = previousEvent.getCurrency();
    final String description = "";
    final SubscriptionBaseTransitionType type = SubscriptionBaseTransitionType.START_BILLING_DISABLED;
    final Long totalOrdering = globaltotalOrder.getAndIncrement();
    final DateTimeZone tz = previousEvent.getTimeZone();
    return new DefaultBillingEvent(subscription, effectiveDate, true, plan, planPhase, fixedPrice, currency, billingPeriod, billCycleDay, description, totalOrdering, type, tz, catalog, true);
}
Also used : BillingPeriod(org.killbill.billing.catalog.api.BillingPeriod) SubscriptionBaseTransitionType(org.killbill.billing.subscription.api.SubscriptionBaseTransitionType) Plan(org.killbill.billing.catalog.api.Plan) DateTime(org.joda.time.DateTime) BigDecimal(java.math.BigDecimal) DateTimeZone(org.joda.time.DateTimeZone) SubscriptionBase(org.killbill.billing.subscription.api.SubscriptionBase) Currency(org.killbill.billing.catalog.api.Currency) AtomicLong(java.util.concurrent.atomic.AtomicLong) PlanPhase(org.killbill.billing.catalog.api.PlanPhase)

Example 30 with Currency

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

the class BlockingCalculator method createNewReenableEvent.

protected BillingEvent createNewReenableEvent(final DateTime odEventTime, final BillingEvent previousEvent, final Catalog catalog, final InternalTenantContext context) throws CatalogApiException {
    // All fields are populated with the event state from before the blocking period, for invoice to resume invoicing
    final int billCycleDay = previousEvent.getBillCycleDayLocal();
    final SubscriptionBase subscription = previousEvent.getSubscription();
    final DateTime effectiveDate = odEventTime;
    final PlanPhase planPhase = previousEvent.getPlanPhase();
    final BigDecimal fixedPrice = previousEvent.getFixedPrice();
    final Plan plan = previousEvent.getPlan();
    final Currency currency = previousEvent.getCurrency();
    final String description = "";
    final BillingPeriod billingPeriod = previousEvent.getBillingPeriod();
    final SubscriptionBaseTransitionType type = SubscriptionBaseTransitionType.END_BILLING_DISABLED;
    final Long totalOrdering = globaltotalOrder.getAndIncrement();
    final DateTimeZone tz = previousEvent.getTimeZone();
    return new DefaultBillingEvent(subscription, effectiveDate, true, plan, planPhase, fixedPrice, currency, billingPeriod, billCycleDay, description, totalOrdering, type, tz, catalog, false);
}
Also used : BillingPeriod(org.killbill.billing.catalog.api.BillingPeriod) SubscriptionBaseTransitionType(org.killbill.billing.subscription.api.SubscriptionBaseTransitionType) Plan(org.killbill.billing.catalog.api.Plan) DateTime(org.joda.time.DateTime) BigDecimal(java.math.BigDecimal) DateTimeZone(org.joda.time.DateTimeZone) SubscriptionBase(org.killbill.billing.subscription.api.SubscriptionBase) Currency(org.killbill.billing.catalog.api.Currency) AtomicLong(java.util.concurrent.atomic.AtomicLong) PlanPhase(org.killbill.billing.catalog.api.PlanPhase)

Aggregations

Currency (org.killbill.billing.catalog.api.Currency)65 BigDecimal (java.math.BigDecimal)36 UUID (java.util.UUID)31 DateTime (org.joda.time.DateTime)21 Test (org.testng.annotations.Test)20 LocalDate (org.joda.time.LocalDate)18 PluginProperty (org.killbill.billing.payment.api.PluginProperty)16 Invoice (org.killbill.billing.invoice.api.Invoice)15 MockPlan (org.killbill.billing.catalog.MockPlan)13 Plan (org.killbill.billing.catalog.api.Plan)13 Account (org.killbill.billing.account.api.Account)12 PlanPhase (org.killbill.billing.catalog.api.PlanPhase)12 DefaultInvoice (org.killbill.billing.invoice.model.DefaultInvoice)12 PaymentOptions (org.killbill.billing.payment.api.PaymentOptions)12 CallContext (org.killbill.billing.util.callcontext.CallContext)12 MockPlanPhase (org.killbill.billing.catalog.MockPlanPhase)11 Payment (org.killbill.billing.payment.api.Payment)11 SubscriptionBase (org.killbill.billing.subscription.api.SubscriptionBase)11 AccountInvoices (org.killbill.billing.invoice.optimizer.InvoiceOptimizerBase.AccountInvoices)9 BillingEventSet (org.killbill.billing.junction.BillingEventSet)9