Search in sources :

Example 86 with DefaultEntitlementSpecifier

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

the class TestWithInvoiceOptimization method testRecurringInArrear2.

@Test(groups = "slow")
public void testRecurringInArrear2() 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.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-02-01
    busHandler.pushExpectedEvents(NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_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")));
    // Cancel in the past (previous period)
    final Entitlement entitlement = entitlementApi.getEntitlementForId(entitlementId, callContext);
    busHandler.pushExpectedEvents(NextEvent.CANCEL, NextEvent.BLOCK, NextEvent.INVOICE);
    entitlement.cancelEntitlementWithDate(new LocalDate(2020, 1, 28), true, ImmutableList.<PluginProperty>of(), callContext);
    assertListenerStatus();
    // Verify the system does not generate anything (subscription was canceled)
    // 2020-03-01
    busHandler.pushExpectedEvents(NextEvent.NULL_INVOICE);
    clock.addMonths(1);
    assertListenerStatus();
    checkNothingToInvoice(account.getId(), new LocalDate(2020, 3, 1), false);
}
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) DefaultEntitlement(org.killbill.billing.entitlement.api.DefaultEntitlement) Entitlement(org.killbill.billing.entitlement.api.Entitlement) 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 87 with DefaultEntitlementSpecifier

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

the class TestWithInvoiceOptimization method testRecurringInAdvance2.

// Used to demonstrate what happens when maxInvoiceLimit = 0 and we do billing IN_ADVANCE
@Test(groups = "slow")
public void testRecurringInAdvance2() throws Exception {
    // Never fetch any existing invoices from disk during invoicing process
    invoiceConfig.setMaxInvoiceLimit(new Period("P0m"));
    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")));
    final Entitlement entitlement = entitlementApi.getEntitlementForId(entitlementId, callContext);
    final PlanPhaseSpecifier spec2 = new PlanPhaseSpecifier("pistol-monthly-notrial");
    // 2020-01-16
    clock.addDays(15);
    // Do a change one day in the past => Nothing will be generated
    // - System does not fetch any existing invoices as cutoffDt= 2020-01-16 and there are no invoices whose targetDt >= cutoffDt
    // - Proposed items correctly generate the 2 expected items but both are filtered because their startDt < cutoffDt
    busHandler.pushExpectedEvents(NextEvent.CHANGE, NextEvent.NULL_INVOICE);
    entitlement.changePlanWithDate(new DefaultEntitlementSpecifier(spec2, null, null, null), clock.getUTCToday().minusDays(1), ImmutableList.<PluginProperty>of(), callContext);
    assertListenerStatus();
    // Do a change today => Only new item 2020-01-16 - 2020-02-01 gets generated
    // - System does not fetch any existing invoices as cutoffDt= 2020-01-16 and there are no invoices whose targetDt >= cutoffDt
    // - Proposed items correctly generate the 2 expected items but the first one is filtered because its start date  2020-01-15 < cutoffDt
    busHandler.pushExpectedEvents(NextEvent.CHANGE, NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
    entitlement.changePlanWithDate(new DefaultEntitlementSpecifier(spec2, null, null, null), clock.getUTCToday(), ImmutableList.<PluginProperty>of(), callContext);
    assertListenerStatus();
    // Double invoicing due to bad config! (no REPAIR)
    invoiceChecker.checkInvoice(account.getId(), 2, callContext, new ExpectedInvoiceItemCheck(new LocalDate(2020, 1, 16), new LocalDate(2020, 2, 1), InvoiceItemType.RECURRING, new BigDecimal("10.30")));
}
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) DefaultEntitlement(org.killbill.billing.entitlement.api.DefaultEntitlement) Entitlement(org.killbill.billing.entitlement.api.Entitlement) 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 88 with DefaultEntitlementSpecifier

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

the class TestWithInvoiceOptimization method testBillRunInAdvanceLeadingProration.

@Test(groups = "slow")
public void testBillRunInAdvanceLeadingProration() throws Exception {
    // Set P1m to look one month back from NOW
    // Very interesting, we cannot set P0m otherwise the Draft invoice isn not being returned as part of the
    // existing invoices and we end up with 2 Draft invoices... ah ah...
    // 
    invoiceConfig.setMaxInvoiceLimit(new Period("P1m"));
    clock.setTime(new DateTime("2020-01-15T3:56:02"));
    final Account account = createAccountWithNonOsgiPaymentMethod(getAccountData(1));
    assertNotNull(account);
    add_AUTO_INVOICING_DRAFT_Tag(account.getId(), ObjectType.ACCOUNT);
    add_AUTO_INVOICING_REUSE_DRAFT_Tag(account.getId(), ObjectType.ACCOUNT);
    busHandler.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK);
    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();
    // Check initial invoice got created
    Invoice invoice = getCurrentDraftInvoice(account.getId(), null, 10);
    // 2020-02-01
    clock.addDays(17);
    invoice = getCurrentDraftInvoice(account.getId(), new Function<Invoice, Boolean>() {

        // The first item is generated immediately as we create the subscription and the second as we move the clock but we have no event to sync on because of AUTO_INVOICING_DRAFT
        @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();
    // We see the leading pro-ration + the in-advance full period
    invoiceChecker.checkInvoice(account.getId(), 1, callContext, new ExpectedInvoiceItemCheck(new LocalDate(2020, 1, 15), new LocalDate(2020, 2, 1), InvoiceItemType.RECURRING, new BigDecimal("16.42")), new ExpectedInvoiceItemCheck(new LocalDate(2020, 2, 1), new LocalDate(2020, 3, 1), InvoiceItemType.RECURRING, new BigDecimal("29.95")));
    // 2020-03-01
    clock.addMonths(1);
    invoice = getCurrentDraftInvoice(account.getId(), null, 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(2020, 3, 1), new LocalDate(2020, 4, 1), InvoiceItemType.RECURRING, new BigDecimal("29.95")));
    // 2020-04-01
    clock.addMonths(1);
    invoice = getCurrentDraftInvoice(account.getId(), null, 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(2020, 4, 1), new LocalDate(2020, 5, 1), InvoiceItemType.RECURRING, new BigDecimal("29.95")));
}
Also used : PlanPhaseSpecifier(org.killbill.billing.catalog.api.PlanPhaseSpecifier) DefaultEntitlementSpecifier(org.killbill.billing.entitlement.api.DefaultEntitlementSpecifier) Account(org.killbill.billing.account.api.Account) Function(com.google.common.base.Function) Invoice(org.killbill.billing.invoice.api.Invoice) 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 89 with DefaultEntitlementSpecifier

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

the class TestWithInvoiceOptimization method testRecurringInArrear.

@Test(groups = "slow")
public void testRecurringInArrear() 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.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-02-01
    busHandler.pushExpectedEvents(NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_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.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("100.00")));
    // 2020-04-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("100.00")));
    final Entitlement entitlement = entitlementApi.getEntitlementForId(entitlementId, callContext);
    // Cancel way in the past (prior the cuttoff date)
    // org.killbill.invoice.maxInvoiceLimit= 1 month => cuttoff date = 2020-03-01
    // NOTE that for IN_ARREAR a cuttoff date of 2020-03-01 returns items from 2020-02-01 - 2020-03-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.CANCEL, NextEvent.BLOCK, NextEvent.INVOICE);
    entitlement.cancelEntitlementWithDate(new LocalDate(2020, 1, 15), true, ImmutableList.<PluginProperty>of(), callContext);
    assertListenerStatus();
    invoiceChecker.checkInvoice(account.getId(), 4, callContext, new ExpectedInvoiceItemCheck(new LocalDate(2020, 2, 1), new LocalDate(2020, 3, 1), InvoiceItemType.REPAIR_ADJ, new BigDecimal("-100.00")), new ExpectedInvoiceItemCheck(new LocalDate(2020, 3, 1), new LocalDate(2020, 4, 1), InvoiceItemType.REPAIR_ADJ, new BigDecimal("-100.00")), new ExpectedInvoiceItemCheck(new LocalDate(2020, 4, 1), new LocalDate(2020, 4, 1), InvoiceItemType.CBA_ADJ, new BigDecimal("200.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) DefaultEntitlement(org.killbill.billing.entitlement.api.DefaultEntitlement) Entitlement(org.killbill.billing.entitlement.api.Entitlement) 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 90 with DefaultEntitlementSpecifier

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

the class TestWithInvoiceOptimization method testRecurringInArrear5.

@Test(groups = "slow")
public void testRecurringInArrear5() throws Exception {
    // If we want to catch the early cancelation, we need to set at least P1m (if not this is ignored)
    invoiceConfig.setMaxRawUsagePreviousPeriod(0);
    invoiceConfig.setZeroAmountUsageDisabled(true);
    invoiceConfig.setMaxInvoiceLimit(new Period("P1m"));
    clock.setTime(new DateTime("2020-01-01T3:56:02"));
    final Account account = createAccountWithNonOsgiPaymentMethod(getAccountData(1));
    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);
    busHandler.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK);
    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-02-01
    clock.addMonths(1);
    // Bill run on the 2020-02-01 with targetDate end of month (EOM)
    invoiceUserApi.triggerInvoiceGeneration(account.getId(), new LocalDate(2020, 2, 28), callContext);
    Invoice invoice = getCurrentDraftInvoice(account.getId(), new Function<Invoice, Boolean>() {

        @Override
        public Boolean apply(final Invoice invoice) {
            return invoice.getInvoiceItems().size() == 1;
        }
    }, 10);
    busHandler.pushExpectedEvents(NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
    invoiceUserApi.commitInvoice(invoice.getId(), callContext);
    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-02-15
    clock.addDays(14);
    // Cancel in the past (previous period)
    final Entitlement entitlement = entitlementApi.getEntitlementForId(entitlementId, callContext);
    busHandler.pushExpectedEvents(NextEvent.CANCEL, NextEvent.BLOCK);
    entitlement.cancelEntitlementWithDate(new LocalDate(2020, 2, 15), true, ImmutableList.<PluginProperty>of(), callContext);
    assertListenerStatus();
    // 2020-03-01
    clock.addMonths(1);
    // Bill run on the 2020-02-01 with targetDate end of month (EOM)
    invoiceUserApi.triggerInvoiceGeneration(account.getId(), new LocalDate(2020, 3, 31), callContext);
    invoice = getCurrentDraftInvoice(account.getId(), new Function<Invoice, Boolean>() {

        @Override
        public Boolean apply(final Invoice invoice) {
            return invoice.getInvoiceItems().size() == 1;
        }
    }, 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(2020, 2, 1), new LocalDate(2020, 2, 15), InvoiceItemType.RECURRING, new BigDecimal("48.28")));
    checkNothingToInvoice(account.getId(), new LocalDate(2020, 3, 1), false);
}
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) 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