Search in sources :

Example 61 with DefaultEntitlementSpecifier

use of org.killbill.billing.entitlement.api.DefaultEntitlementSpecifier in project killbill by killbill.

the class TestWithInArrearSubscriptions method testWithCancelation.

@Test(groups = "slow")
public void testWithCancelation() throws Exception {
    final DateTime initialCreationDate = new DateTime(2020, 1, 1, 0, 0, 0, 0, testTimeZone);
    clock.setTime(initialCreationDate);
    final Account account = createAccountWithNonOsgiPaymentMethod(getAccountData(1));
    final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("basic-support-monthly-notrial", null);
    busHandler.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK, NextEvent.NULL_INVOICE);
    final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec, null, null, null), "bundleExternalKey", null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
    assertListenerStatus();
    final Entitlement entitlement = entitlementApi.getEntitlementForId(entitlementId, callContext);
    // 2020-02-01
    busHandler.pushExpectedEvents(NextEvent.INVOICE, NextEvent.INVOICE_PAYMENT, NextEvent.PAYMENT);
    clock.addMonths(1);
    assertListenerStatus();
    invoiceChecker.checkInvoice(account.getId(), 1, callContext, new ExpectedInvoiceItemCheck(new LocalDate(2020, 1, 1), new LocalDate(2020, 2, 1), InvoiceItemType.RECURRING, new BigDecimal("100.00")));
    // 2020-03-01
    busHandler.pushExpectedEvents(NextEvent.INVOICE, NextEvent.INVOICE_PAYMENT, NextEvent.PAYMENT);
    clock.addMonths(1);
    assertListenerStatus();
    invoiceChecker.checkInvoice(account.getId(), 2, callContext, new ExpectedInvoiceItemCheck(new LocalDate(2020, 2, 1), new LocalDate(2020, 3, 1), InvoiceItemType.RECURRING, new BigDecimal("100.00")));
    // Cancel 2020-03-01
    busHandler.pushExpectedEvents(NextEvent.CANCEL, NextEvent.BLOCK, NextEvent.NULL_INVOICE);
    entitlement.cancelEntitlementWithPolicyOverrideBillingPolicy(EntitlementActionPolicy.IMMEDIATE, BillingActionPolicy.IMMEDIATE, ImmutableList.of(), callContext);
    assertListenerStatus();
    busHandler.pushExpectedEvents(NextEvent.NULL_INVOICE);
    clock.addMonths(1);
    assertListenerStatus();
    for (int i = 0; i < 7; i++) {
        clock.addMonths(1);
        assertListenerStatus();
    }
    checkNoMoreInvoiceToGenerate(account);
}
Also used : PlanPhaseSpecifier(org.killbill.billing.catalog.api.PlanPhaseSpecifier) DefaultEntitlementSpecifier(org.killbill.billing.entitlement.api.DefaultEntitlementSpecifier) Account(org.killbill.billing.account.api.Account) UUID(java.util.UUID) Entitlement(org.killbill.billing.entitlement.api.Entitlement) DefaultEntitlement(org.killbill.billing.entitlement.api.DefaultEntitlement) ExpectedInvoiceItemCheck(org.killbill.billing.beatrix.util.InvoiceChecker.ExpectedInvoiceItemCheck) LocalDate(org.joda.time.LocalDate) DateTime(org.joda.time.DateTime) BigDecimal(java.math.BigDecimal) Test(org.testng.annotations.Test)

Example 62 with DefaultEntitlementSpecifier

use of org.killbill.billing.entitlement.api.DefaultEntitlementSpecifier in project killbill by killbill.

the class TestWithInArrearSubscriptions method testWithPauseResume.

@Test(groups = "slow")
public void testWithPauseResume() throws Exception {
    final DateTime initialDate = new DateTime(2020, 1, 1, 0, 3, 42, 0, testTimeZone);
    // set clock to the initial start date
    clock.setDeltaFromReality(initialDate.getMillis() - clock.getUTCNow().getMillis());
    final Account account = createAccountWithNonOsgiPaymentMethod(getAccountData(1));
    final UUID accountId = account.getId();
    assertNotNull(account);
    final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("basic-support-monthly-notrial", null);
    busHandler.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK, NextEvent.NULL_INVOICE);
    final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec, null, null, null), "bundleExternalKey", null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
    assertListenerStatus();
    // 2020-01-15
    clock.addDays(14);
    // Pause subscription. System will invoice for 2020-01-01 -> 2020-01-15
    DefaultEntitlement entitlement = (DefaultEntitlement) entitlementApi.getEntitlementForId(entitlementId, callContext);
    busHandler.pushExpectedEvents(NextEvent.BLOCK, NextEvent.INVOICE, NextEvent.INVOICE_PAYMENT, NextEvent.PAYMENT);
    entitlementApi.pause(entitlement.getBundleId(), clock.getUTCNow().toLocalDate(), ImmutableList.<PluginProperty>of(), callContext);
    assertListenerStatus();
    invoiceChecker.checkInvoice(account.getId(), 1, callContext, new ExpectedInvoiceItemCheck(new LocalDate(2020, 1, 1), new LocalDate(2020, 1, 15), InvoiceItemType.RECURRING, new BigDecimal("45.16")));
    // 2020-01-20
    clock.addDays(5);
    // Resume subscription.  System will invoice for remaining 2020-01-20 -> 2020-02-1
    busHandler.pushExpectedEvents(NextEvent.BLOCK, NextEvent.NULL_INVOICE);
    entitlementApi.resume(entitlement.getBundleId(), clock.getUTCNow().toLocalDate(), ImmutableList.<PluginProperty>of(), callContext);
    assertListenerStatus();
    // 2020-02-01
    busHandler.pushExpectedEvents(NextEvent.INVOICE, NextEvent.INVOICE_PAYMENT, NextEvent.PAYMENT);
    clock.addDays(12);
    assertListenerStatus();
    invoiceChecker.checkInvoice(account.getId(), 2, callContext, new ExpectedInvoiceItemCheck(new LocalDate(2020, 1, 20), new LocalDate(2020, 2, 1), InvoiceItemType.RECURRING, new BigDecimal("38.71")));
    // 2020-03-01
    busHandler.pushExpectedEvents(NextEvent.INVOICE, NextEvent.INVOICE_PAYMENT, NextEvent.PAYMENT);
    clock.addMonths(1);
    assertListenerStatus();
    checkNoMoreInvoiceToGenerate(account);
}
Also used : PlanPhaseSpecifier(org.killbill.billing.catalog.api.PlanPhaseSpecifier) DefaultEntitlementSpecifier(org.killbill.billing.entitlement.api.DefaultEntitlementSpecifier) Account(org.killbill.billing.account.api.Account) DefaultEntitlement(org.killbill.billing.entitlement.api.DefaultEntitlement) UUID(java.util.UUID) ExpectedInvoiceItemCheck(org.killbill.billing.beatrix.util.InvoiceChecker.ExpectedInvoiceItemCheck) LocalDate(org.joda.time.LocalDate) DateTime(org.joda.time.DateTime) BigDecimal(java.math.BigDecimal) Test(org.testng.annotations.Test)

Example 63 with DefaultEntitlementSpecifier

use of org.killbill.billing.entitlement.api.DefaultEntitlementSpecifier in project killbill by killbill.

the class TestWithInvoiceOptimization method testRecurringInArrear3.

@Test(groups = "slow")
public void testRecurringInArrear3() throws Exception {
    invoiceConfig.setMaxInvoiceLimit(new Period("P1m"));
    clock.setTime(new DateTime("2020-02-18T3:56:02"));
    final Account account = createAccountWithNonOsgiPaymentMethod(getAccountData(1));
    assertNotNull(account);
    busHandler.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK, NextEvent.NULL_INVOICE);
    final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("blowdart-in-arrear-monthly-notrial");
    final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec), "Something", null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
    assertListenerStatus();
    // 2020-03-01
    busHandler.pushExpectedEvents(NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
    clock.addDays(12);
    assertListenerStatus();
    invoiceChecker.checkInvoice(account.getId(), 1, callContext, new ExpectedInvoiceItemCheck(new LocalDate(2020, 2, 18), new LocalDate(2020, 3, 1), InvoiceItemType.RECURRING, new BigDecimal("41.38")));
    // 2020-04-01
    busHandler.pushExpectedEvents(NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
    clock.addMonths(1);
    assertListenerStatus();
    invoiceChecker.checkInvoice(account.getId(), 2, callContext, new ExpectedInvoiceItemCheck(new LocalDate(2020, 3, 1), new LocalDate(2020, 4, 1), InvoiceItemType.RECURRING, new BigDecimal("100.00")));
    // 2020-04-01
    clock.addDays(15);
    assertListenerStatus();
    busHandler.pushExpectedEvents(NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
    invoiceUserApi.triggerInvoiceGeneration(account.getId(), new LocalDate(2020, 5, 1), callContext);
    assertListenerStatus();
    invoiceChecker.checkInvoice(account.getId(), 3, callContext, new ExpectedInvoiceItemCheck(new LocalDate(2020, 4, 1), new LocalDate(2020, 5, 1), InvoiceItemType.RECURRING, new BigDecimal("100.00")));
}
Also used : PlanPhaseSpecifier(org.killbill.billing.catalog.api.PlanPhaseSpecifier) DefaultEntitlementSpecifier(org.killbill.billing.entitlement.api.DefaultEntitlementSpecifier) Account(org.killbill.billing.account.api.Account) Period(org.joda.time.Period) BillingPeriod(org.killbill.billing.catalog.api.BillingPeriod) UUID(java.util.UUID) ExpectedInvoiceItemCheck(org.killbill.billing.beatrix.util.InvoiceChecker.ExpectedInvoiceItemCheck) LocalDate(org.joda.time.LocalDate) DateTime(org.joda.time.DateTime) BigDecimal(java.math.BigDecimal) Test(org.testng.annotations.Test)

Example 64 with DefaultEntitlementSpecifier

use of org.killbill.billing.entitlement.api.DefaultEntitlementSpecifier in project killbill by killbill.

the class TestWithInvoiceOptimization method testBillRunInArrearWithUsageAndRecurring.

@Test(groups = "slow")
public void testBillRunInArrearWithUsageAndRecurring() throws Exception {
    // Usage records are pulled using the most aggressive cuttoffDt
    // 1. Because we set zeroAmountUsageDisabled=true, we don't rely on existing state (i.e the latest endDate of all usage items) to find the starting point of the cuttoffDt
    // but instead, we default to 1 period (month) prior the date of the bill run
    // 2. Because maxRawUsagePreviousPeriod=0, we don't go past the cuttoffDt computed in 1
    // So, for bill run= Feb 1st -> (usage) cuttoffDt = Jan 1st - anything prior that will be ignored.
    // 
    invoiceConfig.setMaxRawUsagePreviousPeriod(0);
    invoiceConfig.setZeroAmountUsageDisabled(true);
    // We make sure that our invoice optimization cuttOffDt is not greater than the usage optimization date, otherwise this could create issues
    // as reflected by the WARN https://github.com/killbill/killbill/blob/killbill-0.22.27/invoice/src/main/java/org/killbill/billing/invoice/generator/UsageInvoiceItemGenerator.java#L131
    // 
    // To make it simpler we keep both cuttoffDt on the same value, but we could set any value, e.g P1m, P2m, ...
    // So, for bill run= Feb 1st -> invoice cuttOffDt = Jan 1st
    invoiceConfig.setMaxInvoiceLimit(new Period("P1m"));
    clock.setTime(new DateTime("2021-01-15T3:56:02"));
    final Account account = createAccountWithNonOsgiPaymentMethod(getAccountData(15));
    assertNotNull(account);
    // Don't allow system generated invoices
    add_AUTO_INVOICING_OFF_Tag(account.getId(), ObjectType.ACCOUNT);
    // Reuse invoice until committed
    add_AUTO_INVOICING_DRAFT_Tag(account.getId(), ObjectType.ACCOUNT);
    add_AUTO_INVOICING_REUSE_DRAFT_Tag(account.getId(), ObjectType.ACCOUNT);
    // Create an in-arrear RECURRING subscription
    final LocalDate effDt1 = new LocalDate(2020, 8, 15);
    busHandler.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK, NextEvent.BCD_CHANGE);
    final PlanPhaseSpecifier spec1 = new PlanPhaseSpecifier("blowdart-in-arrear-monthly-notrial");
    final UUID entitlementId1 = entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec1, 15, null, null), null, effDt1, effDt1, false, true, ImmutableList.<PluginProperty>of(), callContext);
    final Subscription sub1 = subscriptionApi.getSubscriptionForEntitlementId(entitlementId1, callContext);
    assertListenerStatus();
    // Create an in-arrear USAGE subscription
    final LocalDate effDt2 = new LocalDate(2020, 9, 1);
    busHandler.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK, NextEvent.BCD_CHANGE);
    final PlanPhaseSpecifier spec2 = new PlanPhaseSpecifier("training-usage-in-arrear");
    final UUID entitlementId2 = entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec2, 1, null, null), null, effDt2, effDt2, false, true, ImmutableList.<PluginProperty>of(), callContext);
    final Subscription sub2 = subscriptionApi.getSubscriptionForEntitlementId(entitlementId2, callContext);
    assertListenerStatus();
    // Generate some usage data for past months
    recordUsageData(sub2.getId(), "tracking-old-1", "hours", new LocalDate(2020, 9, 19), 1L, callContext);
    recordUsageData(sub2.getId(), "tracking-old-2", "hours", new LocalDate(2020, 10, 19), 1L, callContext);
    recordUsageData(sub2.getId(), "tracking-old-3", "hours", new LocalDate(2020, 11, 19), 1L, callContext);
    recordUsageData(sub2.getId(), "tracking-old-4", "hours", new LocalDate(2020, 12, 19), 1L, callContext);
    // Generate usage data for this month
    recordUsageData(sub2.getId(), "tracking-1", "hours", new LocalDate(2021, 1, 19), 1L, callContext);
    // 2021-02-01
    // (Hum... Interestingly, there is no future notification set on the 1st although sub2#BCD is the 1st...)
    clock.addDays(17);
    Thread.sleep(1000);
    // Bill run on the 2021-02-01 with targetDate end of month (EOM)
    invoiceUserApi.triggerInvoiceGeneration(account.getId(), new LocalDate(2021, 2, 28), callContext);
    Invoice invoice = getCurrentDraftInvoice(account.getId(), new Function<Invoice, Boolean>() {

        @Override
        public Boolean apply(final Invoice invoice) {
            return invoice.getInvoiceItems().size() == 3;
        }
    }, 10);
    busHandler.pushExpectedEvents(NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
    invoiceUserApi.commitInvoice(invoice.getId(), callContext);
    assertListenerStatus();
    // The original invoice is a catchup invoice since there is no invoice and both subscriptions started way in the past
    // However, with our aggressive cuttoffDt, we only see what we would normally expect to see on this invoice if we had invoiced up to this point
    // (The catchup invoice already contains everything it should have and nothing more)
    invoiceChecker.checkInvoice(account.getId(), 1, callContext, new ExpectedInvoiceItemCheck(new LocalDate(2020, 12, 15), new LocalDate(2021, 1, 15), InvoiceItemType.RECURRING, new BigDecimal("100.00")), new ExpectedInvoiceItemCheck(new LocalDate(2021, 1, 15), new LocalDate(2021, 2, 15), InvoiceItemType.RECURRING, new BigDecimal("100.00")), new ExpectedInvoiceItemCheck(new LocalDate(2021, 1, 1), new LocalDate(2021, 2, 1), InvoiceItemType.USAGE, new BigDecimal("100.00")));
    // 2021-02-15
    // Invoice notification on the 15 (Recurring subscription)
    clock.addDays(14);
    Thread.sleep(1000);
    recordUsageData(sub2.getId(), "tracking-2-a", "hours", new LocalDate(2021, 2, 15), 1L, callContext);
    // 2021-03-01
    clock.addDays(14);
    Thread.sleep(1000);
    recordUsageData(sub2.getId(), "tracking-2-b", "hours", new LocalDate(2021, 2, 25), 1L, callContext);
    invoiceUserApi.triggerInvoiceGeneration(account.getId(), new LocalDate(2021, 3, 31), callContext);
    invoice = getCurrentDraftInvoice(account.getId(), new Function<Invoice, Boolean>() {

        @Override
        public Boolean apply(final Invoice invoice) {
            return invoice.getInvoiceItems().size() == 2;
        }
    }, 10);
    busHandler.pushExpectedEvents(NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
    invoiceUserApi.commitInvoice(invoice.getId(), callContext);
    assertListenerStatus();
    invoiceChecker.checkInvoice(account.getId(), 2, callContext, new ExpectedInvoiceItemCheck(new LocalDate(2021, 2, 15), new LocalDate(2021, 3, 15), InvoiceItemType.RECURRING, new BigDecimal("100.00")), new ExpectedInvoiceItemCheck(new LocalDate(2021, 2, 1), new LocalDate(2021, 3, 1), InvoiceItemType.USAGE, new BigDecimal("200.00")));
    // 2021-03-15
    // Invoice notification on the 15 (Recurring subscription)
    clock.addDays(14);
    Thread.sleep(1000);
    recordUsageData(sub2.getId(), "tracking-3", "hours", new LocalDate(2021, 3, 15), 1L, callContext);
    // 2021-04-01
    clock.addDays(17);
    Thread.sleep(1000);
    invoiceUserApi.triggerInvoiceGeneration(account.getId(), new LocalDate(2021, 4, 30), callContext);
    invoice = getCurrentDraftInvoice(account.getId(), new Function<Invoice, Boolean>() {

        @Override
        public Boolean apply(final Invoice invoice) {
            return invoice.getInvoiceItems().size() == 2;
        }
    }, 10);
    busHandler.pushExpectedEvents(NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
    invoiceUserApi.commitInvoice(invoice.getId(), callContext);
    assertListenerStatus();
    invoiceChecker.checkInvoice(account.getId(), 3, callContext, new ExpectedInvoiceItemCheck(new LocalDate(2021, 3, 15), new LocalDate(2021, 4, 15), InvoiceItemType.RECURRING, new BigDecimal("100.00")), new ExpectedInvoiceItemCheck(new LocalDate(2021, 3, 1), new LocalDate(2021, 4, 1), InvoiceItemType.USAGE, new BigDecimal("100.00")));
    // 2021-04-15
    // Invoice notification on the 15 (Recurring subscription)
    clock.addDays(14);
    Thread.sleep(1000);
    recordUsageData(sub2.getId(), "tracking-4", "hours", new LocalDate(2021, 4, 15), 1L, callContext);
    // 2021-05-01
    clock.addDays(16);
    Thread.sleep(1000);
    invoiceUserApi.triggerInvoiceGeneration(account.getId(), new LocalDate(2021, 5, 31), callContext);
    invoice = getCurrentDraftInvoice(account.getId(), new Function<Invoice, Boolean>() {

        @Override
        public Boolean apply(final Invoice invoice) {
            return invoice.getInvoiceItems().size() == 2;
        }
    }, 10);
    busHandler.pushExpectedEvents(NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
    invoiceUserApi.commitInvoice(invoice.getId(), callContext);
    assertListenerStatus();
    invoiceChecker.checkInvoice(account.getId(), 4, callContext, new ExpectedInvoiceItemCheck(new LocalDate(2021, 4, 15), new LocalDate(2021, 5, 15), InvoiceItemType.RECURRING, new BigDecimal("100.00")), new ExpectedInvoiceItemCheck(new LocalDate(2021, 4, 1), new LocalDate(2021, 5, 1), InvoiceItemType.USAGE, new BigDecimal("100.00")));
}
Also used : PlanPhaseSpecifier(org.killbill.billing.catalog.api.PlanPhaseSpecifier) Account(org.killbill.billing.account.api.Account) Invoice(org.killbill.billing.invoice.api.Invoice) Period(org.joda.time.Period) BillingPeriod(org.killbill.billing.catalog.api.BillingPeriod) LocalDate(org.joda.time.LocalDate) ExpectedInvoiceItemCheck(org.killbill.billing.beatrix.util.InvoiceChecker.ExpectedInvoiceItemCheck) DateTime(org.joda.time.DateTime) BigDecimal(java.math.BigDecimal) DefaultEntitlementSpecifier(org.killbill.billing.entitlement.api.DefaultEntitlementSpecifier) Function(com.google.common.base.Function) UUID(java.util.UUID) Subscription(org.killbill.billing.entitlement.api.Subscription) Test(org.testng.annotations.Test)

Example 65 with DefaultEntitlementSpecifier

use of org.killbill.billing.entitlement.api.DefaultEntitlementSpecifier in project killbill by killbill.

the class TestWithInvoiceOptimization method testRecurringInAdvance.

@Test(groups = "slow")
public void testRecurringInAdvance() throws Exception {
    invoiceConfig.setMaxInvoiceLimit(new Period("P1m"));
    clock.setTime(new DateTime("2020-01-01T3:56:02"));
    final Account account = createAccountWithNonOsgiPaymentMethod(getAccountData(1));
    assertNotNull(account);
    busHandler.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK, NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
    final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Blowdart", BillingPeriod.MONTHLY, "notrial", null);
    final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec), "Something", null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
    assertListenerStatus();
    invoiceChecker.checkInvoice(account.getId(), 1, callContext, new ExpectedInvoiceItemCheck(new LocalDate(2020, 1, 1), new LocalDate(2020, 2, 1), InvoiceItemType.RECURRING, new BigDecimal("29.95")));
    // 2020-02-01
    busHandler.pushExpectedEvents(NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
    clock.addMonths(1);
    assertListenerStatus();
    invoiceChecker.checkInvoice(account.getId(), 2, callContext, new ExpectedInvoiceItemCheck(new LocalDate(2020, 2, 1), new LocalDate(2020, 3, 1), InvoiceItemType.RECURRING, new BigDecimal("29.95")));
    // 2020-03-01
    busHandler.pushExpectedEvents(NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
    clock.addMonths(1);
    assertListenerStatus();
    invoiceChecker.checkInvoice(account.getId(), 3, callContext, new ExpectedInvoiceItemCheck(new LocalDate(2020, 3, 1), new LocalDate(2020, 4, 1), InvoiceItemType.RECURRING, new BigDecimal("29.95")));
    final Entitlement entitlement = entitlementApi.getEntitlementForId(entitlementId, callContext);
    final PlanPhaseSpecifier spec2 = new PlanPhaseSpecifier("pistol-monthly-notrial");
    // Trigger a change way in the past (prior the cuttoff date)
    // org.killbill.invoice.maxInvoiceLimit= 1 month => cuttoff date = 2020-02-01
    // 
    // We verify that invoice only tried to REPAIR from cutoff date -- and in particular the period 2020-01-15 - 2020-02-01 is left untouched.
    busHandler.pushExpectedEvents(NextEvent.CHANGE, NextEvent.INVOICE);
    entitlement.changePlanWithDate(new DefaultEntitlementSpecifier(spec2, null, null, null), new LocalDate(2020, 1, 15), ImmutableList.<PluginProperty>of(), callContext);
    assertListenerStatus();
    invoiceChecker.checkInvoice(account.getId(), 4, callContext, new ExpectedInvoiceItemCheck(new LocalDate(2020, 2, 1), new LocalDate(2020, 3, 1), InvoiceItemType.RECURRING, new BigDecimal("19.95")), new ExpectedInvoiceItemCheck(new LocalDate(2020, 2, 1), new LocalDate(2020, 3, 1), InvoiceItemType.REPAIR_ADJ, new BigDecimal("-29.95")), new ExpectedInvoiceItemCheck(new LocalDate(2020, 3, 1), new LocalDate(2020, 4, 1), InvoiceItemType.RECURRING, new BigDecimal("19.95")), new ExpectedInvoiceItemCheck(new LocalDate(2020, 3, 1), new LocalDate(2020, 4, 1), InvoiceItemType.REPAIR_ADJ, new BigDecimal("-29.95")), new ExpectedInvoiceItemCheck(new LocalDate(2020, 3, 1), new LocalDate(2020, 3, 1), InvoiceItemType.CBA_ADJ, new BigDecimal("20.00")));
    // Issue a first dry-run on 2020-03-02
    // We should not see the items that were repaired a month prior now because of the cutoff date
    final DateTime nextDate1 = clock.getUTCNow().plusDays(1);
    checkNothingToInvoice(account.getId(), new LocalDate(nextDate1, testTimeZone), true);
    // Issue a series of dry-run starting on 2020-04-01
    DateTime nextDate = clock.getUTCNow().plusMonths(1);
    for (int i = 0; i < 5; i++) {
        final Invoice invoice = invoiceUserApi.triggerDryRunInvoiceGeneration(account.getId(), new LocalDate(nextDate, testTimeZone), new TestDryRunArguments(DryRunType.TARGET_DATE), callContext);
        // Filter to eliminate CBA
        final int actualRecurring = Iterables.size(Iterables.filter(invoice.getInvoiceItems(), new Predicate<InvoiceItem>() {

            @Override
            public boolean apply(final InvoiceItem invoiceItem) {
                return invoiceItem.getInvoiceItemType() == InvoiceItemType.RECURRING;
            }
        }));
        // 
        assertEquals(actualRecurring, 1);
        nextDate = nextDate.plusMonths(1);
    }
}
Also used : PlanPhaseSpecifier(org.killbill.billing.catalog.api.PlanPhaseSpecifier) Account(org.killbill.billing.account.api.Account) Invoice(org.killbill.billing.invoice.api.Invoice) InvoiceItem(org.killbill.billing.invoice.api.InvoiceItem) Period(org.joda.time.Period) BillingPeriod(org.killbill.billing.catalog.api.BillingPeriod) ExpectedInvoiceItemCheck(org.killbill.billing.beatrix.util.InvoiceChecker.ExpectedInvoiceItemCheck) LocalDate(org.joda.time.LocalDate) DateTime(org.joda.time.DateTime) BigDecimal(java.math.BigDecimal) Predicate(com.google.common.base.Predicate) DefaultEntitlementSpecifier(org.killbill.billing.entitlement.api.DefaultEntitlementSpecifier) UUID(java.util.UUID) DefaultEntitlement(org.killbill.billing.entitlement.api.DefaultEntitlement) Entitlement(org.killbill.billing.entitlement.api.Entitlement) Test(org.testng.annotations.Test)

Aggregations

DefaultEntitlementSpecifier (org.killbill.billing.entitlement.api.DefaultEntitlementSpecifier)141 PlanPhaseSpecifier (org.killbill.billing.catalog.api.PlanPhaseSpecifier)140 Test (org.testng.annotations.Test)129 LocalDate (org.joda.time.LocalDate)105 Account (org.killbill.billing.account.api.Account)98 UUID (java.util.UUID)87 Entitlement (org.killbill.billing.entitlement.api.Entitlement)64 BigDecimal (java.math.BigDecimal)62 DateTime (org.joda.time.DateTime)61 ExpectedInvoiceItemCheck (org.killbill.billing.beatrix.util.InvoiceChecker.ExpectedInvoiceItemCheck)59 DefaultEntitlement (org.killbill.billing.entitlement.api.DefaultEntitlement)56 Invoice (org.killbill.billing.invoice.api.Invoice)40 BillingPeriod (org.killbill.billing.catalog.api.BillingPeriod)27 ArrayList (java.util.ArrayList)24 AccountData (org.killbill.billing.account.api.AccountData)23 EntitlementApiException (org.killbill.billing.entitlement.api.EntitlementApiException)20 DefaultBlockingState (org.killbill.billing.junction.DefaultBlockingState)14 BlockingState (org.killbill.billing.entitlement.api.BlockingState)13 Interval (org.joda.time.Interval)12 Period (org.joda.time.Period)12