Search in sources :

Example 1 with SubscriptionNotification

use of org.killbill.billing.invoice.InvoiceDispatcher.FutureAccountNotifications.SubscriptionNotification in project killbill by killbill.

the class InvoiceDispatcher method createNextFutureNotificationDate.

private FutureAccountNotifications createNextFutureNotificationDate(final InvoiceWithMetadata invoiceWithMetadata, final InternalCallContext context) {
    final Map<UUID, List<SubscriptionNotification>> result = new HashMap<UUID, List<SubscriptionNotification>>();
    for (final UUID subscriptionId : invoiceWithMetadata.getPerSubscriptionFutureNotificationDates().keySet()) {
        final List<SubscriptionNotification> perSubscriptionNotifications = new ArrayList<SubscriptionNotification>();
        final SubscriptionFutureNotificationDates subscriptionFutureNotificationDates = invoiceWithMetadata.getPerSubscriptionFutureNotificationDates().get(subscriptionId);
        // Add next recurring date if any
        if (subscriptionFutureNotificationDates.getNextRecurringDate() != null) {
            perSubscriptionNotifications.add(new SubscriptionNotification(context.toUTCDateTime(subscriptionFutureNotificationDates.getNextRecurringDate()), true));
        }
        // Add next usage dates if any
        if (subscriptionFutureNotificationDates.getNextUsageDates() != null) {
            for (final UsageDef usageDef : subscriptionFutureNotificationDates.getNextUsageDates().keySet()) {
                final LocalDate nextNotificationDateForUsage = subscriptionFutureNotificationDates.getNextUsageDates().get(usageDef);
                final DateTime subscriptionUsageCallbackDate = nextNotificationDateForUsage != null ? context.toUTCDateTime(nextNotificationDateForUsage) : null;
                perSubscriptionNotifications.add(new SubscriptionNotification(subscriptionUsageCallbackDate, true));
            }
        }
        if (!perSubscriptionNotifications.isEmpty()) {
            result.put(subscriptionId, perSubscriptionNotifications);
        }
    }
    // If dryRunNotification is enabled we also need to fetch the upcoming PHASE dates (we add SubscriptionNotification with isForInvoiceNotificationTrigger = false)
    final boolean isInvoiceNotificationEnabled = invoiceConfig.getDryRunNotificationSchedule(context).getMillis() > 0;
    if (isInvoiceNotificationEnabled) {
        final Map<UUID, DateTime> upcomingPhasesForSubscriptions = subscriptionApi.getNextFutureEventForSubscriptions(SubscriptionBaseTransitionType.PHASE, context);
        for (final UUID cur : upcomingPhasesForSubscriptions.keySet()) {
            final DateTime curDate = upcomingPhasesForSubscriptions.get(cur);
            List<SubscriptionNotification> resultValue = result.get(cur);
            if (resultValue == null) {
                resultValue = new ArrayList<SubscriptionNotification>();
            }
            resultValue.add(new SubscriptionNotification(curDate, false));
            result.put(cur, resultValue);
        }
    }
    return new FutureAccountNotifications(result);
}
Also used : SubscriptionFutureNotificationDates(org.killbill.billing.invoice.generator.InvoiceWithMetadata.SubscriptionFutureNotificationDates) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) SubscriptionNotification(org.killbill.billing.invoice.InvoiceDispatcher.FutureAccountNotifications.SubscriptionNotification) LocalDate(org.joda.time.LocalDate) DateTime(org.joda.time.DateTime) UsageDef(org.killbill.billing.invoice.generator.InvoiceWithMetadata.SubscriptionFutureNotificationDates.UsageDef) ArrayList(java.util.ArrayList) List(java.util.List) ImmutableList(com.google.common.collect.ImmutableList) LinkedList(java.util.LinkedList) UUID(java.util.UUID)

Example 2 with SubscriptionNotification

use of org.killbill.billing.invoice.InvoiceDispatcher.FutureAccountNotifications.SubscriptionNotification in project killbill by killbill.

the class DefaultInvoiceDao method notifyOfFutureBillingEvents.

private void notifyOfFutureBillingEvents(final EntitySqlDaoWrapperFactory entitySqlDaoWrapperFactory, final UUID accountId, final FutureAccountNotifications callbackDateTimePerSubscriptions, final InternalCallContext internalCallContext) {
    final long dryRunNotificationTime = invoiceConfig.getDryRunNotificationSchedule(internalCallContext).getMillis();
    final boolean isInvoiceNotificationEnabled = dryRunNotificationTime > 0;
    for (final UUID subscriptionId : callbackDateTimePerSubscriptions.getNotifications().keySet()) {
        final List<SubscriptionNotification> callbackDateTimeUTC = callbackDateTimePerSubscriptions.getNotifications().get(subscriptionId);
        for (final SubscriptionNotification cur : callbackDateTimeUTC) {
            if (isInvoiceNotificationEnabled) {
                final DateTime curDryRunNotificationTime = cur.getEffectiveDate().minus(dryRunNotificationTime);
                final DateTime effectiveCurDryRunNotificationTime = (curDryRunNotificationTime.isAfter(clock.getUTCNow())) ? curDryRunNotificationTime : clock.getUTCNow();
                nextBillingDatePoster.insertNextBillingDryRunNotificationFromTransaction(entitySqlDaoWrapperFactory, accountId, subscriptionId, effectiveCurDryRunNotificationTime, cur.getEffectiveDate(), internalCallContext);
            }
            if (cur.isForInvoiceNotificationTrigger()) {
                nextBillingDatePoster.insertNextBillingNotificationFromTransaction(entitySqlDaoWrapperFactory, accountId, subscriptionId, cur.getEffectiveDate(), internalCallContext);
            }
        }
    }
}
Also used : UUID(java.util.UUID) SubscriptionNotification(org.killbill.billing.invoice.InvoiceDispatcher.FutureAccountNotifications.SubscriptionNotification) DateTime(org.joda.time.DateTime)

Example 3 with SubscriptionNotification

use of org.killbill.billing.invoice.InvoiceDispatcher.FutureAccountNotifications.SubscriptionNotification in project killbill by killbill.

the class TestIntegrationInvoiceWithRepairLogic method testWithSuperflousRepairedItems.

@Test(groups = "slow")
public void testWithSuperflousRepairedItems() throws Exception {
    // We take april as it has 30 days (easier to play with BCD)
    final LocalDate today = new LocalDate(2012, 4, 1);
    final Account account = createAccountWithNonOsgiPaymentMethod(getAccountData(1));
    // Set clock to the initial start date - we implicitly assume here that the account timezone is UTC
    clock.setDay(today);
    final String productName = "Shotgun";
    final BillingPeriod term = BillingPeriod.MONTHLY;
    final String pricelistName = PriceListSet.DEFAULT_PRICELIST_NAME;
    //
    // CREATE SUBSCRIPTION AND EXPECT BOTH EVENTS: NextEvent.CREATE NextEvent.INVOICE
    //
    final DefaultEntitlement bpEntitlement = createBaseEntitlementAndCheckForCompletion(account.getId(), "externalKey", productName, ProductCategory.BASE, term, NextEvent.CREATE, NextEvent.INVOICE, NextEvent.BLOCK);
    assertNotNull(bpEntitlement);
    List<Invoice> invoices = invoiceUserApi.getInvoicesByAccount(account.getId(), false, callContext);
    assertEquals(invoices.size(), 1);
    ImmutableList<ExpectedInvoiceItemCheck> toBeChecked = ImmutableList.<ExpectedInvoiceItemCheck>of(new ExpectedInvoiceItemCheck(new LocalDate(2012, 4, 1), null, InvoiceItemType.FIXED, BigDecimal.ZERO));
    invoiceChecker.checkInvoice(invoices.get(0).getId(), callContext, toBeChecked);
    //
    // Check we get the first invoice at the phase event
    //
    busHandler.pushExpectedEvents(NextEvent.PHASE, NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
    // Move the clock to 2012-05-02
    clock.addDays(31);
    assertListenerStatus();
    invoices = invoiceUserApi.getInvoicesByAccount(account.getId(), false, callContext);
    assertEquals(invoices.size(), 2);
    toBeChecked = ImmutableList.<ExpectedInvoiceItemCheck>of(new ExpectedInvoiceItemCheck(new LocalDate(2012, 4, 1), null, InvoiceItemType.FIXED, BigDecimal.ZERO));
    invoiceChecker.checkInvoice(invoices.get(0).getId(), callContext, toBeChecked);
    toBeChecked = ImmutableList.<ExpectedInvoiceItemCheck>of(new ExpectedInvoiceItemCheck(new LocalDate(2012, 5, 1), new LocalDate(2012, 6, 1), InvoiceItemType.RECURRING, new BigDecimal("249.95")));
    final Invoice lastInvoice = invoices.get(1);
    invoiceChecker.checkInvoice(lastInvoice.getId(), callContext, toBeChecked);
    //
    // Let's add a bunch of items by hand to pretend we have lots of cancelling items that should be cleaned (data issue after a potential invoice bug)
    //
    // We test both full and partial repair.
    /*
        final UUID id, @Nullable final DateTime createdDate, final UUID accountId,
                           @Nullable final Integer invoiceNumber, final LocalDate invoiceDate, final LocalDate targetDate,
                           final Currency currency, final boolean migrated, final InvoiceStatus status, final boolean isParentInvoice
         */
    final InvoiceModelDao shellInvoice = new InvoiceModelDao(UUID.randomUUID(), lastInvoice.getCreatedDate(), lastInvoice.getAccountId(), null, lastInvoice.getInvoiceDate(), lastInvoice.getTargetDate(), lastInvoice.getCurrency(), false, InvoiceStatus.COMMITTED, false);
    final InvoiceItemModelDao recurring1 = new InvoiceItemModelDao(lastInvoice.getCreatedDate(), InvoiceItemType.RECURRING, lastInvoice.getId(), lastInvoice.getAccountId(), bpEntitlement.getBundleId(), bpEntitlement.getBaseEntitlementId(), "", "shotgun-monthly", "shotgun-monthly-evergreen", null, new LocalDate(2012, 5, 1), new LocalDate(2012, 6, 1), new BigDecimal("249.95"), new BigDecimal("249.95"), account.getCurrency(), null);
    final InvoiceItemModelDao repair1 = new InvoiceItemModelDao(lastInvoice.getCreatedDate(), InvoiceItemType.REPAIR_ADJ, lastInvoice.getId(), lastInvoice.getAccountId(), bpEntitlement.getBundleId(), bpEntitlement.getBaseEntitlementId(), null, null, null, null, new LocalDate(2012, 5, 1), new LocalDate(2012, 6, 1), new BigDecimal("-249.95"), new BigDecimal("-249.95"), account.getCurrency(), recurring1.getId());
    final InvoiceItemModelDao recurring2 = new InvoiceItemModelDao(lastInvoice.getCreatedDate(), InvoiceItemType.RECURRING, lastInvoice.getId(), lastInvoice.getAccountId(), bpEntitlement.getBundleId(), bpEntitlement.getBaseEntitlementId(), "", "shotgun-monthly", "shotgun-monthly-evergreen", null, new LocalDate(2012, 5, 1), new LocalDate(2012, 6, 1), new BigDecimal("249.95"), new BigDecimal("249.95"), account.getCurrency(), null);
    final InvoiceItemModelDao repair21 = new InvoiceItemModelDao(lastInvoice.getCreatedDate(), InvoiceItemType.REPAIR_ADJ, lastInvoice.getId(), lastInvoice.getAccountId(), bpEntitlement.getBundleId(), bpEntitlement.getBaseEntitlementId(), null, null, null, null, new LocalDate(2012, 5, 1), new LocalDate(2012, 5, 13), new BigDecimal("-100.95"), new BigDecimal("-100.95"), account.getCurrency(), recurring2.getId());
    final InvoiceItemModelDao repair22 = new InvoiceItemModelDao(lastInvoice.getCreatedDate(), InvoiceItemType.REPAIR_ADJ, lastInvoice.getId(), lastInvoice.getAccountId(), bpEntitlement.getBundleId(), bpEntitlement.getBaseEntitlementId(), null, null, null, null, new LocalDate(2012, 5, 13), new LocalDate(2012, 5, 22), new BigDecimal("-100"), new BigDecimal("-100"), account.getCurrency(), recurring2.getId());
    final InvoiceItemModelDao repair23 = new InvoiceItemModelDao(lastInvoice.getCreatedDate(), InvoiceItemType.REPAIR_ADJ, lastInvoice.getId(), lastInvoice.getAccountId(), bpEntitlement.getBundleId(), bpEntitlement.getBaseEntitlementId(), null, null, null, null, new LocalDate(2012, 5, 22), new LocalDate(2012, 6, 1), new BigDecimal("-49"), new BigDecimal("-49"), account.getCurrency(), recurring2.getId());
    final InvoiceItemModelDao recurring3 = new InvoiceItemModelDao(lastInvoice.getCreatedDate(), InvoiceItemType.RECURRING, lastInvoice.getId(), lastInvoice.getAccountId(), bpEntitlement.getBundleId(), bpEntitlement.getBaseEntitlementId(), "", "shotgun-monthly", "shotgun-monthly-evergreen", null, new LocalDate(2012, 5, 1), new LocalDate(2012, 6, 1), new BigDecimal("249.95"), new BigDecimal("249.95"), account.getCurrency(), null);
    final InvoiceItemModelDao repair3 = new InvoiceItemModelDao(lastInvoice.getCreatedDate(), InvoiceItemType.REPAIR_ADJ, lastInvoice.getId(), lastInvoice.getAccountId(), bpEntitlement.getBundleId(), bpEntitlement.getBaseEntitlementId(), null, null, null, null, new LocalDate(2012, 5, 1), new LocalDate(2012, 6, 1), new BigDecimal("-249.95"), new BigDecimal("-249.95"), account.getCurrency(), recurring3.getId());
    List<InvoiceItemModelDao> newItems = new ArrayList<InvoiceItemModelDao>();
    newItems.add(recurring1);
    newItems.add(repair1);
    newItems.add(recurring2);
    newItems.add(repair21);
    newItems.add(repair22);
    newItems.add(repair23);
    newItems.add(recurring3);
    newItems.add(repair3);
    shellInvoice.addInvoiceItems(newItems);
    invoiceDao.createInvoice(shellInvoice, new FutureAccountNotifications(new HashMap<UUID, List<SubscriptionNotification>>()), internalCallContext);
    // Move ahead one month, verify nothing from previous data was generated
    busHandler.pushExpectedEvents(NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
    clock.addMonths(1);
    assertListenerStatus();
    invoices = invoiceUserApi.getInvoicesByAccount(account.getId(), false, callContext);
    assertEquals(invoices.size(), 3);
    toBeChecked = ImmutableList.<ExpectedInvoiceItemCheck>of(new ExpectedInvoiceItemCheck(new LocalDate(2012, 6, 1), new LocalDate(2012, 7, 1), InvoiceItemType.RECURRING, new BigDecimal("249.95")));
    invoiceChecker.checkInvoice(invoices.get(2).getId(), callContext, toBeChecked);
}
Also used : Account(org.killbill.billing.account.api.Account) Invoice(org.killbill.billing.invoice.api.Invoice) BillingPeriod(org.killbill.billing.catalog.api.BillingPeriod) HashMap(java.util.HashMap) InvoiceModelDao(org.killbill.billing.invoice.dao.InvoiceModelDao) FutureAccountNotifications(org.killbill.billing.invoice.InvoiceDispatcher.FutureAccountNotifications) ArrayList(java.util.ArrayList) SubscriptionNotification(org.killbill.billing.invoice.InvoiceDispatcher.FutureAccountNotifications.SubscriptionNotification) LocalDate(org.joda.time.LocalDate) ExpectedInvoiceItemCheck(org.killbill.billing.beatrix.util.InvoiceChecker.ExpectedInvoiceItemCheck) BigDecimal(java.math.BigDecimal) DefaultEntitlement(org.killbill.billing.entitlement.api.DefaultEntitlement) InvoiceItemModelDao(org.killbill.billing.invoice.dao.InvoiceItemModelDao) Test(org.testng.annotations.Test)

Aggregations

SubscriptionNotification (org.killbill.billing.invoice.InvoiceDispatcher.FutureAccountNotifications.SubscriptionNotification)3 ArrayList (java.util.ArrayList)2 HashMap (java.util.HashMap)2 UUID (java.util.UUID)2 DateTime (org.joda.time.DateTime)2 LocalDate (org.joda.time.LocalDate)2 ImmutableList (com.google.common.collect.ImmutableList)1 BigDecimal (java.math.BigDecimal)1 LinkedList (java.util.LinkedList)1 List (java.util.List)1 Account (org.killbill.billing.account.api.Account)1 ExpectedInvoiceItemCheck (org.killbill.billing.beatrix.util.InvoiceChecker.ExpectedInvoiceItemCheck)1 BillingPeriod (org.killbill.billing.catalog.api.BillingPeriod)1 DefaultEntitlement (org.killbill.billing.entitlement.api.DefaultEntitlement)1 FutureAccountNotifications (org.killbill.billing.invoice.InvoiceDispatcher.FutureAccountNotifications)1 Invoice (org.killbill.billing.invoice.api.Invoice)1 InvoiceItemModelDao (org.killbill.billing.invoice.dao.InvoiceItemModelDao)1 InvoiceModelDao (org.killbill.billing.invoice.dao.InvoiceModelDao)1 SubscriptionFutureNotificationDates (org.killbill.billing.invoice.generator.InvoiceWithMetadata.SubscriptionFutureNotificationDates)1 UsageDef (org.killbill.billing.invoice.generator.InvoiceWithMetadata.SubscriptionFutureNotificationDates.UsageDef)1