Search in sources :

Example 6 with Usage

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

the class TestXMLReader method testUsageCapacityInAdvance.

@Test(groups = "fast")
public void testUsageCapacityInAdvance() {
    try {
        final StandaloneCatalog catalog = XMLLoader.getObjectFromString(Resources.getResource("UsageExperimental.xml").toExternalForm(), StandaloneCatalog.class);
        final Usage[] usages = getUsages(catalog, "capacity-in-advance-monthly");
        assertEquals(usages.length, 1);
        final Usage usage = usages[0];
        assertEquals(usage.getName(), "capacity-in-advance-monthly-usage1");
        assertEquals(usage.getBillingPeriod(), BillingPeriod.MONTHLY);
        assertEquals(usage.getUsageType(), UsageType.CAPACITY);
        assertEquals(usage.getBillingMode(), BillingMode.IN_ADVANCE);
        assertEquals(usage.getBlocks().length, 0);
        assertEquals(usage.getTiers().length, 0);
        assertEquals(usage.getLimits().length, 1);
        assertEquals(usage.getLimits()[0].getUnit().getName(), "members");
        assertEquals(usage.getLimits()[0].getMax(), new Double("100"));
        assertEquals(usage.getRecurringPrice().getPrices().length, 1);
        assertEquals(usage.getRecurringPrice().getPrices()[0].getCurrency(), Currency.BTC);
        assertEquals(usage.getRecurringPrice().getPrices()[0].getValue(), new BigDecimal("100.00"));
    } catch (Exception e) {
        Assert.fail(e.toString());
    }
}
Also used : Usage(org.killbill.billing.catalog.api.Usage) StandaloneCatalog(org.killbill.billing.catalog.StandaloneCatalog) BigDecimal(java.math.BigDecimal) CatalogApiException(org.killbill.billing.catalog.api.CatalogApiException) Test(org.testng.annotations.Test)

Example 7 with Usage

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

the class TestXMLReader method testUsageConsumableInAdvancePrepayCredit.

@Test(groups = "fast")
public void testUsageConsumableInAdvancePrepayCredit() {
    try {
        final StandaloneCatalog catalog = XMLLoader.getObjectFromString(Resources.getResource("UsageExperimental.xml").toExternalForm(), StandaloneCatalog.class);
        final Usage[] usages = getUsages(catalog, "consumable-in-advance-prepay-credit-monthly");
        assertEquals(usages.length, 1);
        final Usage usage = usages[0];
        assertEquals(usage.getName(), "consumable-in-advance-prepay-credit-monthly-usage1");
        assertEquals(usage.getBillingPeriod(), BillingPeriod.MONTHLY);
        assertEquals(usage.getUsageType(), UsageType.CONSUMABLE);
        assertEquals(usage.getBillingMode(), BillingMode.IN_ADVANCE);
        assertEquals(usage.getLimits().length, 0);
        assertEquals(usage.getTiers().length, 0);
        assertEquals(usage.getBlocks().length, 1);
        assertEquals(usage.getBlocks()[0].getUnit().getName(), "cell-phone-minutes");
        assertEquals(usage.getBlocks()[0].getSize(), new Double("1000"));
        assertEquals(usage.getBlocks()[0].getPrice().getPrices().length, 1);
        assertEquals(usage.getBlocks()[0].getPrice().getPrices()[0].getCurrency(), Currency.BTC);
        assertEquals(usage.getBlocks()[0].getPrice().getPrices()[0].getValue(), new BigDecimal("0.10"));
    } catch (Exception e) {
        Assert.fail(e.toString());
    }
}
Also used : Usage(org.killbill.billing.catalog.api.Usage) StandaloneCatalog(org.killbill.billing.catalog.StandaloneCatalog) BigDecimal(java.math.BigDecimal) CatalogApiException(org.killbill.billing.catalog.api.CatalogApiException) Test(org.testng.annotations.Test)

Example 8 with Usage

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

the class TestXMLReader method getUsages.

private Usage[] getUsages(final StandaloneCatalog catalog, final String planName) throws CatalogApiException {
    final Plan plan = catalog.findCurrentPlan(planName);
    assertNotNull(plan);
    final PlanPhase phase = plan.getFinalPhase();
    assertNotNull(phase);
    final Usage[] usages = phase.getUsages();
    return usages;
}
Also used : Usage(org.killbill.billing.catalog.api.Usage) PlanPhase(org.killbill.billing.catalog.api.PlanPhase) Plan(org.killbill.billing.catalog.api.Plan)

Example 9 with Usage

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

the class UsageInvoiceItemGenerator method generateItems.

@Override
public List<InvoiceItem> generateItems(final ImmutableAccountData account, final UUID invoiceId, final BillingEventSet eventSet, @Nullable final List<Invoice> existingInvoices, final LocalDate targetDate, final Currency targetCurrency, final Map<UUID, SubscriptionFutureNotificationDates> perSubscriptionFutureNotificationDates, final InternalCallContext internalCallContext) throws InvoiceApiException {
    final Map<UUID, List<InvoiceItem>> perSubscriptionInArrearUsageItems = extractPerSubscriptionExistingInArrearUsageItems(eventSet.getUsages(), existingInvoices);
    try {
        // Pretty-print the generated invoice items from the junction events
        final InvoiceItemGeneratorLogger invoiceItemGeneratorLogger = new InvoiceItemGeneratorLogger(invoiceId, account.getId(), "usage", log);
        final LocalDate minBillingEventDate = getMinBillingEventDate(eventSet, internalCallContext);
        final List<InvoiceItem> items = Lists.newArrayList();
        final Iterator<BillingEvent> events = eventSet.iterator();
        RawUsageOptimizerResult rawUsageOptimizerResult = 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 (rawUsageOptimizerResult == null && Iterables.any(event.getUsages(), new Predicate<Usage>() {

                @Override
                public boolean apply(@Nullable final Usage input) {
                    return input.getBillingMode() == BillingMode.IN_ARREAR;
                }
            })) {
                rawUsageOptimizerResult = rawUsageOptimizer.getInArrearUsage(minBillingEventDate, targetDate, Iterables.concat(perSubscriptionInArrearUsageItems.values()), eventSet.getUsages(), internalCallContext);
            }
            // None of the billing events report any usage IN_ARREAR sections
            if (rawUsageOptimizerResult == null) {
                continue;
            }
            final UUID subscriptionId = event.getSubscription().getId();
            if (curSubscriptionId != null && !curSubscriptionId.equals(subscriptionId)) {
                final SubscriptionUsageInArrear subscriptionUsageInArrear = new SubscriptionUsageInArrear(account.getId(), invoiceId, curEvents, rawUsageOptimizerResult.getRawUsage(), targetDate, rawUsageOptimizerResult.getRawUsageStartDate(), internalCallContext);
                final List<InvoiceItem> usageInArrearItems = perSubscriptionInArrearUsageItems.get(curSubscriptionId);
                final SubscriptionUsageInArrearItemsAndNextNotificationDate subscriptionResult = subscriptionUsageInArrear.computeMissingUsageInvoiceItems(usageInArrearItems != null ? usageInArrearItems : ImmutableList.<InvoiceItem>of(), invoiceItemGeneratorLogger);
                final List<InvoiceItem> newInArrearUsageItems = subscriptionResult.getInvoiceItems();
                items.addAll(newInArrearUsageItems);
                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, rawUsageOptimizerResult.getRawUsage(), targetDate, rawUsageOptimizerResult.getRawUsageStartDate(), internalCallContext);
            final List<InvoiceItem> usageInArrearItems = perSubscriptionInArrearUsageItems.get(curSubscriptionId);
            final SubscriptionUsageInArrearItemsAndNextNotificationDate subscriptionResult = subscriptionUsageInArrear.computeMissingUsageInvoiceItems(usageInArrearItems != null ? usageInArrearItems : ImmutableList.<InvoiceItem>of(), invoiceItemGeneratorLogger);
            final List<InvoiceItem> newInArrearUsageItems = subscriptionResult.getInvoiceItems();
            items.addAll(newInArrearUsageItems);
            updatePerSubscriptionNextNotificationUsageDate(curSubscriptionId, subscriptionResult.getPerUsageNotificationDates(), BillingMode.IN_ARREAR, perSubscriptionFutureNotificationDates);
        }
        invoiceItemGeneratorLogger.logItems();
        return items;
    } catch (final CatalogApiException e) {
        throw new InvoiceApiException(e);
    }
}
Also used : Usage(org.killbill.billing.catalog.api.Usage) InvoiceItem(org.killbill.billing.invoice.api.InvoiceItem) SubscriptionUsageInArrearItemsAndNextNotificationDate(org.killbill.billing.invoice.usage.SubscriptionUsageInArrear.SubscriptionUsageInArrearItemsAndNextNotificationDate) 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) Nullable(javax.annotation.Nullable)

Example 10 with Usage

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

the class RawUsageOptimizer method getOptimizedRawUsageStartDate.

@VisibleForTesting
LocalDate getOptimizedRawUsageStartDate(final LocalDate firstEventStartDate, final LocalDate targetDate, final Iterable<InvoiceItem> existingUsageItems, final Map<String, Usage> knownUsage, final InternalCallContext internalCallContext) {
    if (!existingUsageItems.iterator().hasNext()) {
        return firstEventStartDate;
    }
    // Extract all usage billing period known in that catalog
    final Set<BillingPeriod> knownUsageBillingPeriod = ImmutableSet.copyOf(Iterables.transform(knownUsage.values(), new Function<Usage, BillingPeriod>() {

        @Nullable
        @Override
        public BillingPeriod apply(final Usage input) {
            return input.getBillingPeriod();
        }
    }));
    // Make sure all usage items are sorted by endDate
    final List<InvoiceItem> sortedUsageItems = USAGE_ITEM_ORDERING.sortedCopy(existingUsageItems);
    // Compute an array with one date per BillingPeriod:
    // If BillingPeriod is never defined in the catalog (no need to look for items), we initialize its value
    // such that it cannot be chosen
    //
    // Exclude the NO_BILLING_PERIOD
    final LocalDate[] perBillingPeriodMostRecentConsumableInArrearItemEndDate = new LocalDate[BillingPeriod.values().length - 1];
    int idx = 0;
    for (final BillingPeriod bp : BillingPeriod.values()) {
        if (bp != BillingPeriod.NO_BILLING_PERIOD) {
            final LocalDate makerDateThanCannotBeChosenAsTheMinOfAllDates = InvoiceDateUtils.advanceByNPeriods(targetDate, bp, config.getMaxRawUsagePreviousPeriod(internalCallContext));
            perBillingPeriodMostRecentConsumableInArrearItemEndDate[idx++] = (knownUsageBillingPeriod.contains(bp)) ? null : makerDateThanCannotBeChosenAsTheMinOfAllDates;
        }
    }
    final ListIterator<InvoiceItem> iterator = sortedUsageItems.listIterator(sortedUsageItems.size());
    while (iterator.hasPrevious()) {
        final InvoiceItem previous = iterator.previous();
        Preconditions.checkState(previous instanceof UsageInvoiceItem);
        final UsageInvoiceItem item = (UsageInvoiceItem) previous;
        final Usage usage = knownUsage.get(item.getUsageName());
        if (perBillingPeriodMostRecentConsumableInArrearItemEndDate[usage.getBillingPeriod().ordinal()] == null) {
            perBillingPeriodMostRecentConsumableInArrearItemEndDate[usage.getBillingPeriod().ordinal()] = item.getEndDate();
            if (!containsNullEntries(perBillingPeriodMostRecentConsumableInArrearItemEndDate)) {
                break;
            }
        }
    }
    // Extract the min from all the dates
    LocalDate targetStartDate = null;
    idx = 0;
    for (final BillingPeriod bp : BillingPeriod.values()) {
        if (bp != BillingPeriod.NO_BILLING_PERIOD) {
            final LocalDate tmp = perBillingPeriodMostRecentConsumableInArrearItemEndDate[idx];
            final LocalDate targetBillingPeriodDate = tmp != null ? InvoiceDateUtils.recedeByNPeriods(tmp, bp, config.getMaxRawUsagePreviousPeriod(internalCallContext)) : null;
            if (targetStartDate == null || (targetBillingPeriodDate != null && targetBillingPeriodDate.compareTo(targetStartDate) < 0)) {
                targetStartDate = targetBillingPeriodDate;
            }
            idx++;
        }
    }
    final LocalDate result = targetStartDate.compareTo(firstEventStartDate) > 0 ? targetStartDate : firstEventStartDate;
    return result;
}
Also used : Function(com.google.common.base.Function) Usage(org.killbill.billing.catalog.api.Usage) RawUsage(org.killbill.billing.usage.RawUsage) UsageInvoiceItem(org.killbill.billing.invoice.model.UsageInvoiceItem) InvoiceItem(org.killbill.billing.invoice.api.InvoiceItem) BillingPeriod(org.killbill.billing.catalog.api.BillingPeriod) UsageInvoiceItem(org.killbill.billing.invoice.model.UsageInvoiceItem) LocalDate(org.joda.time.LocalDate) VisibleForTesting(com.google.common.annotations.VisibleForTesting)

Aggregations

Usage (org.killbill.billing.catalog.api.Usage)21 Test (org.testng.annotations.Test)14 LocalDate (org.joda.time.LocalDate)11 BigDecimal (java.math.BigDecimal)9 DefaultTier (org.killbill.billing.catalog.DefaultTier)9 InvoiceItem (org.killbill.billing.invoice.api.InvoiceItem)9 DefaultUsage (org.killbill.billing.catalog.DefaultUsage)8 HashMap (java.util.HashMap)7 DefaultTieredBlock (org.killbill.billing.catalog.DefaultTieredBlock)7 UsageInvoiceItem (org.killbill.billing.invoice.model.UsageInvoiceItem)7 RawUsage (org.killbill.billing.usage.RawUsage)7 CatalogApiException (org.killbill.billing.catalog.api.CatalogApiException)6 StandaloneCatalog (org.killbill.billing.catalog.StandaloneCatalog)5 BillingEvent (org.killbill.billing.junction.BillingEvent)5 Function (com.google.common.base.Function)4 ArrayList (java.util.ArrayList)4 RolledUpUsage (org.killbill.billing.usage.api.RolledUpUsage)4 DefaultRawUsage (org.killbill.billing.usage.api.svcs.DefaultRawUsage)4 VisibleForTesting (com.google.common.annotations.VisibleForTesting)2 ImmutableList (com.google.common.collect.ImmutableList)2