Search in sources :

Example 51 with BillingEvent

use of org.killbill.billing.junction.BillingEvent in project killbill by killbill.

the class TestBlockingCalculator method testCreateNewEventsClosedPrevBetw.

// Closed duration with a previous event and in-between event
// --X--[------Y-----]---------------------
@Test(groups = "fast")
public void testCreateNewEventsClosedPrevBetw() throws CatalogApiException {
    final DateTime now = clock.getUTCNow();
    final List<DisabledDuration> disabledDuration = new ArrayList<BlockingCalculator.DisabledDuration>();
    final SortedSet<BillingEvent> billingEvents = new TreeSet<BillingEvent>();
    disabledDuration.add(new DisabledDuration(now, now.plusDays(2)));
    billingEvents.add(createRealEvent(now.minusDays(1), subscription1));
    billingEvents.add(createRealEvent(now.plusDays(1), subscription1));
    final SortedSet<BillingEvent> results = blockingCalculator.createNewEvents(disabledDuration, billingEvents, subscription1, internalCallContext);
    assertEquals(results.size(), 2);
    assertEquals(results.first().getEffectiveDate(), now);
    assertNull(results.first().getFixedPrice());
    assertNull(results.first().getRecurringPrice(null));
    assertEquals(results.first().getBillingPeriod(), BillingPeriod.NO_BILLING_PERIOD);
    assertEquals(results.first().getTransitionType(), SubscriptionBaseTransitionType.START_BILLING_DISABLED);
    assertEquals(results.last().getEffectiveDate(), now.plusDays(2));
    assertEquals(results.last().getRecurringPrice(null), billingEvents.first().getRecurringPrice(null));
    assertEquals(results.last().getTransitionType(), SubscriptionBaseTransitionType.END_BILLING_DISABLED);
}
Also used : DisabledDuration(org.killbill.billing.junction.plumbing.billing.BlockingCalculator.DisabledDuration) TreeSet(java.util.TreeSet) ArrayList(java.util.ArrayList) BillingEvent(org.killbill.billing.junction.BillingEvent) DateTime(org.joda.time.DateTime) Test(org.testng.annotations.Test)

Example 52 with BillingEvent

use of org.killbill.billing.junction.BillingEvent in project killbill by killbill.

the class TestBlockingCalculator method testCreateNewEventsOpenPrevFollow.

// Open with previous and following events
// --X--[----Y-----------------------------
@Test(groups = "fast")
public void testCreateNewEventsOpenPrevFollow() throws CatalogApiException {
    final DateTime now = clock.getUTCNow();
    final List<DisabledDuration> disabledDuration = new ArrayList<BlockingCalculator.DisabledDuration>();
    final SortedSet<BillingEvent> billingEvents = new TreeSet<BillingEvent>();
    disabledDuration.add(new DisabledDuration(now, null));
    billingEvents.add(createRealEvent(now.minusDays(1), subscription1));
    billingEvents.add(createRealEvent(now.plusDays(1), subscription1));
    final SortedSet<BillingEvent> results = blockingCalculator.createNewEvents(disabledDuration, billingEvents, subscription1, internalCallContext);
    assertEquals(results.size(), 1);
    assertEquals(results.first().getEffectiveDate(), now);
    assertNull(results.first().getFixedPrice());
    assertNull(results.first().getRecurringPrice(null));
    assertEquals(results.first().getBillingPeriod(), BillingPeriod.NO_BILLING_PERIOD);
    assertEquals(results.first().getTransitionType(), SubscriptionBaseTransitionType.START_BILLING_DISABLED);
}
Also used : DisabledDuration(org.killbill.billing.junction.plumbing.billing.BlockingCalculator.DisabledDuration) TreeSet(java.util.TreeSet) ArrayList(java.util.ArrayList) BillingEvent(org.killbill.billing.junction.BillingEvent) DateTime(org.joda.time.DateTime) Test(org.testng.annotations.Test)

Example 53 with BillingEvent

use of org.killbill.billing.junction.BillingEvent in project killbill by killbill.

the class TestBlockingCalculator method testInsertBlockingEventsForBundle.

// S1-S2-S3 subscriptions in B1
// B1 -----[--------]
// S1 --A-------------------------------------
// S2 --B------C------------------------------
// S3 ------------------D---------------------
//Result
// S1 --A--[-------]--------------------------
// S2 --B--[-------]--------------------------
// S3 ------------------D---------------------
@Test(groups = "fast")
public void testInsertBlockingEventsForBundle() throws CatalogApiException {
    final DateTime now = clock.getUTCNow();
    final BillingEvent A = createRealEvent(now.minusDays(1).minusHours(1), subscription1);
    final BillingEvent B = createRealEvent(now.minusDays(1), subscription2);
    final BillingEvent C = createRealEvent(now.plusDays(1), subscription2);
    final BillingEvent D = createRealEvent(now.plusDays(3), subscription3);
    final SortedSet<BillingEvent> billingEvents = new TreeSet<BillingEvent>();
    billingEvents.add(A);
    billingEvents.add(B);
    billingEvents.add(C);
    billingEvents.add(D);
    final BlockingState blockingState1 = new DefaultBlockingState(bundleId1, BlockingStateType.SUBSCRIPTION_BUNDLE, DISABLED_BUNDLE, "test", true, true, true, now);
    final BlockingState blockingState2 = new DefaultBlockingState(bundleId1, BlockingStateType.SUBSCRIPTION_BUNDLE, CLEAR_BUNDLE, "test", false, false, false, now.plusDays(2));
    blockingStateDao.setBlockingStatesAndPostBlockingTransitionEvent(ImmutableMap.<BlockingState, Optional<UUID>>of(blockingState1, Optional.<UUID>absent(), blockingState2, Optional.<UUID>absent()), internalCallContext);
    blockingCalculator.insertBlockingEvents(billingEvents, new HashSet<UUID>(), internalCallContext);
    assertEquals(billingEvents.size(), 7);
    final SortedSet<BillingEvent> s1Events = blockingCalculator.filter(billingEvents, subscription1);
    final Iterator<BillingEvent> it1 = s1Events.iterator();
    assertEquals(it1.next(), A);
    assertEquals(it1.next().getTransitionType(), SubscriptionBaseTransitionType.START_BILLING_DISABLED);
    assertEquals(it1.next().getTransitionType(), SubscriptionBaseTransitionType.END_BILLING_DISABLED);
    final SortedSet<BillingEvent> s2Events = blockingCalculator.filter(billingEvents, subscription2);
    final Iterator<BillingEvent> it2 = s2Events.iterator();
    assertEquals(it2.next(), B);
    assertEquals(it2.next().getTransitionType(), SubscriptionBaseTransitionType.START_BILLING_DISABLED);
    assertEquals(it2.next().getTransitionType(), SubscriptionBaseTransitionType.END_BILLING_DISABLED);
    final SortedSet<BillingEvent> s3Events = blockingCalculator.filter(billingEvents, subscription3);
    final Iterator<BillingEvent> it3 = s3Events.iterator();
    assertEquals(it3.next(), D);
}
Also used : TreeSet(java.util.TreeSet) BillingEvent(org.killbill.billing.junction.BillingEvent) DefaultBlockingState(org.killbill.billing.junction.DefaultBlockingState) BlockingState(org.killbill.billing.entitlement.api.BlockingState) UUID(java.util.UUID) DateTime(org.joda.time.DateTime) DefaultBlockingState(org.killbill.billing.junction.DefaultBlockingState) Test(org.testng.annotations.Test)

Example 54 with BillingEvent

use of org.killbill.billing.junction.BillingEvent in project killbill by killbill.

the class FixedAndRecurringInvoiceItemGenerator method processFixedBillingEvents.

@VisibleForTesting
void processFixedBillingEvents(final UUID invoiceId, final UUID accountId, final BillingEventSet events, final LocalDate targetDate, final Currency currency, final List<InvoiceItem> proposedItems, final InternalCallContext internalCallContext) throws InvoiceApiException {
    if (events.isEmpty()) {
        return;
    }
    InvoiceItem prevItem = null;
    // Pretty-print the generated invoice items from the junction events
    final InvoiceItemGeneratorLogger invoiceItemGeneratorLogger = new InvoiceItemGeneratorLogger(invoiceId, accountId, "fixed", log);
    final Iterator<BillingEvent> eventIt = events.iterator();
    while (eventIt.hasNext()) {
        final BillingEvent thisEvent = eventIt.next();
        final InvoiceItem currentFixedPriceItem = generateFixedPriceItem(invoiceId, accountId, thisEvent, targetDate, currency, invoiceItemGeneratorLogger, internalCallContext);
        if (!isSameDayAndSameSubscription(prevItem, thisEvent, internalCallContext) && prevItem != null) {
            proposedItems.add(prevItem);
        }
        prevItem = currentFixedPriceItem;
    }
    // The last one if not null can always be inserted as there is nothing after to cancel it off.
    if (prevItem != null) {
        proposedItems.add(prevItem);
    }
    invoiceItemGeneratorLogger.logItems();
}
Also used : FixedPriceInvoiceItem(org.killbill.billing.invoice.model.FixedPriceInvoiceItem) RecurringInvoiceItem(org.killbill.billing.invoice.model.RecurringInvoiceItem) InvoiceItem(org.killbill.billing.invoice.api.InvoiceItem) BillingEvent(org.killbill.billing.junction.BillingEvent) VisibleForTesting(com.google.common.annotations.VisibleForTesting)

Example 55 with BillingEvent

use of org.killbill.billing.junction.BillingEvent 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)

Aggregations

BillingEvent (org.killbill.billing.junction.BillingEvent)98 Test (org.testng.annotations.Test)82 DateTime (org.joda.time.DateTime)52 LocalDate (org.joda.time.LocalDate)49 Plan (org.killbill.billing.catalog.api.Plan)42 PlanPhase (org.killbill.billing.catalog.api.PlanPhase)41 MockPlan (org.killbill.billing.catalog.MockPlan)40 MockPlanPhase (org.killbill.billing.catalog.MockPlanPhase)40 BigDecimal (java.math.BigDecimal)36 ArrayList (java.util.ArrayList)36 UUID (java.util.UUID)35 MockBillingEventSet (org.killbill.billing.invoice.MockBillingEventSet)35 BillingEventSet (org.killbill.billing.junction.BillingEventSet)33 Invoice (org.killbill.billing.invoice.api.Invoice)32 DefaultInvoice (org.killbill.billing.invoice.model.DefaultInvoice)32 TreeSet (java.util.TreeSet)30 InvoiceItem (org.killbill.billing.invoice.api.InvoiceItem)27 FixedPriceInvoiceItem (org.killbill.billing.invoice.model.FixedPriceInvoiceItem)26 DefaultPrice (org.killbill.billing.catalog.DefaultPrice)25 MockInternationalPrice (org.killbill.billing.catalog.MockInternationalPrice)25