use of org.killbill.billing.entitlement.api.Entitlement in project killbill by killbill.
the class TestWithTimeZones method testReferenceTimeInDSTGap.
@Test(groups = "slow")
public void testReferenceTimeInDSTGap() throws Exception {
final DateTimeZone tz = DateTimeZone.forID("America/Los_Angeles");
clock.setTime(new DateTime(2015, 3, 7, 2, 0, 0, tz));
final AccountData accountData = new MockAccountBuilder().currency(Currency.USD).timeZone(tz).build();
final Account account = createAccountWithNonOsgiPaymentMethod(accountData);
accountChecker.checkAccount(account.getId(), accountData, callContext);
Assert.assertEquals(account.getTimeZone(), tz);
Assert.assertEquals(account.getFixedOffsetTimeZone(), DateTimeZone.forOffsetHours(-8));
// Note the gap: 2015-03-07T02:00:00.000-08:00 to 2015-03-08T03:00:00.000-07:00
clock.addDays(1);
try {
// See TimeAwareContext#toUTCDateTime (which uses account.getFixedOffsetTimeZone() instead)
new DateTime(clock.getUTCToday().getYear(), clock.getUTCToday().getMonthOfYear(), clock.getUTCToday().getDayOfMonth(), account.getReferenceTime().toDateTime(tz).getHourOfDay(), account.getReferenceTime().toDateTime(tz).getMinuteOfHour(), account.getReferenceTime().toDateTime(tz).getSecondOfMinute(), account.getTimeZone());
Assert.fail();
} catch (final IllegalInstantException e) {
// Illegal instant due to time zone offset transition (daylight savings time 'gap'): 2015-03-08T10:00:00.000 (America/Los_Angeles)
}
busHandler.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK, NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Blowdart", BillingPeriod.MONTHLY, "notrial", null);
// Pass a date of today, to trigger TimeAwareContext#toUTCDateTime
final Entitlement entitlement = entitlementApi.createBaseEntitlement(account.getId(), spec, "Something", ImmutableList.<PlanPhasePriceOverride>of(), clock.getUTCToday(), clock.getUTCToday(), false, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
Assert.assertEquals(entitlement.getEffectiveStartDate().compareTo(new LocalDate("2015-03-08")), 0);
Assert.assertEquals(((DefaultEntitlement) entitlement).getBasePlanSubscriptionBase().getStartDate().compareTo(new DateTime("2015-03-08T02:00:00.000-08:00")), 0);
invoiceChecker.checkChargedThroughDate(entitlement.getId(), new LocalDate("2015-04-08"), callContext);
busHandler.pushExpectedEvents(NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
clock.addDays(31);
assertListenerStatus();
invoiceChecker.checkChargedThroughDate(entitlement.getId(), new LocalDate("2015-05-08"), callContext);
for (int i = 0; i < 25; i++) {
busHandler.pushExpectedEvents(NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
clock.addMonths(1);
assertListenerStatus();
invoiceChecker.checkChargedThroughDate(entitlement.getId(), new LocalDate("2015-03-08").plusMonths(3 + i), callContext);
}
}
use of org.killbill.billing.entitlement.api.Entitlement in project killbill by killbill.
the class TestMigrationSubscriptions method testSimpleMigrationBPSkipTrial.
//
// Scenario: On 2016-1-1, we decide to migrate a subscription with a cutOverDate of 2015-12-20 (12 days in the past) and a billing date of 2016-2-01, we we want to skip the trial
// (note that since we skip the trial billingDate = 2016-2-01 aligns well with the BCD=1 we set on our test account)
//
//
@Test(groups = "slow")
public void testSimpleMigrationBPSkipTrial() throws Exception {
clock.setDay(new LocalDate(2016, 1, 1));
final AccountData accountData = getAccountData(1);
final Account account = createAccountWithNonOsgiPaymentMethod(accountData);
accountChecker.checkAccount(account.getId(), accountData, callContext);
final List<ExpectedInvoiceItemCheck> expectedInvoices = new ArrayList<ExpectedInvoiceItemCheck>();
// We set both entitlement and billing date with desired value
final LocalDate entitlementMigrationDate = new LocalDate(2015, 12, 20);
final LocalDate billingMigrationDate = new LocalDate(2016, 2, 1);
// Entitlement wil be created in ACTIVE state because entitlementMigrationDate was set in the past
busHandler.pushExpectedEvents(NextEvent.BLOCK);
final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Shotgun", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, PhaseType.EVERGREEN);
final Entitlement entitlement = entitlementApi.createBaseEntitlement(account.getId(), spec, "bundleKey", null, entitlementMigrationDate, billingMigrationDate, false, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
Assert.assertEquals(entitlement.getState(), EntitlementState.ACTIVE);
// Move clock next month for first RECURRING invoice (note that TRIAL was correctly skipped, we directly start RECURRING on billingMigrationDate
busHandler.pushExpectedEvents(NextEvent.CREATE, NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
clock.addMonths(1);
assertListenerStatus();
final LocalDate startDate = billingMigrationDate;
final LocalDate endDate = startDate.plusMonths(1);
expectedInvoices.add(new ExpectedInvoiceItemCheck(startDate, endDate, InvoiceItemType.RECURRING, new BigDecimal("249.95")));
invoiceChecker.checkInvoice(account.getId(), 1, callContext, expectedInvoices);
expectedInvoices.clear();
}
use of org.killbill.billing.entitlement.api.Entitlement in project killbill by killbill.
the class TestMigrationSubscriptions method testSimpleMigrationBPSkipTrialWithPendingCancellation.
//
// Scenario: On 2016-1-1, we decide to migrate a subscription with a cutOverDate of 2015-12-20 (12 days in the past) and a billing date of 2016-2-01, we we want to skip the trial.
// In addition we subscription needs to be future cancelled (2016-2-15) at the time we migrate it
// (note that since we skip the trial billingDate = 2016-2-01 aligns well with the BCD=1 we set on our test account)
//
//
@Test(groups = "slow")
public void testSimpleMigrationBPSkipTrialWithPendingCancellation() throws Exception {
clock.setDay(new LocalDate(2016, 1, 1));
final AccountData accountData = getAccountData(1);
final Account account = createAccountWithNonOsgiPaymentMethod(accountData);
accountChecker.checkAccount(account.getId(), accountData, callContext);
final List<ExpectedInvoiceItemCheck> expectedInvoices = new ArrayList<ExpectedInvoiceItemCheck>();
final LocalDate entitlementMigrationDate = new LocalDate(2015, 12, 20);
// We set both entitlement and billing date with desired value
final LocalDate billingMigrationDate = new LocalDate(2016, 2, 1);
final LocalDate effectiveCancellationDate = new LocalDate(2016, 2, 15);
// Entitlement wil be created in ACTIVE state because entitlementMigrationDate was set in the past
busHandler.pushExpectedEvents(NextEvent.BLOCK);
final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Shotgun", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, PhaseType.EVERGREEN);
final Entitlement entitlement = entitlementApi.createBaseEntitlement(account.getId(), spec, "bundleKey", null, entitlementMigrationDate, billingMigrationDate, false, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
Assert.assertEquals(entitlement.getState(), EntitlementState.ACTIVE);
// Perform the cancellation (we did not move the clock, the is is future cancellation done at the time we decide to migrate)
entitlement.cancelEntitlementWithDate(effectiveCancellationDate, true, ImmutableList.<PluginProperty>of(), callContext);
// Billing starts straight on EVERGREEN
busHandler.pushExpectedEvents(NextEvent.CREATE, NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
clock.addMonths(1);
assertListenerStatus();
// The invoice will be pro-rated up to the cancellation date
final LocalDate startDate = billingMigrationDate;
final LocalDate endDate = effectiveCancellationDate;
expectedInvoices.add(new ExpectedInvoiceItemCheck(startDate, endDate, InvoiceItemType.RECURRING, new BigDecimal("120.67")));
invoiceChecker.checkInvoice(account.getId(), 1, callContext, expectedInvoices);
expectedInvoices.clear();
// Move to cancellation date
busHandler.pushExpectedEvents(NextEvent.CANCEL, NextEvent.BLOCK, NextEvent.NULL_INVOICE, NextEvent.NULL_INVOICE);
clock.addMonths(14);
assertListenerStatus();
final Entitlement cancelledEntitlement = entitlementApi.getEntitlementForId(entitlement.getId(), callContext);
Assert.assertEquals(cancelledEntitlement.getState(), EntitlementState.CANCELLED);
}
use of org.killbill.billing.entitlement.api.Entitlement in project killbill by killbill.
the class TestSubscription method testCreateMultipleSubscriptionsWithAddOns.
@Test(groups = "slow")
public void testCreateMultipleSubscriptionsWithAddOns() throws Exception {
final LocalDate initialDate = new LocalDate(2015, 10, 1);
clock.setDay(initialDate);
final Account account = createAccountWithNonOsgiPaymentMethod(getAccountData(1));
final PlanPhaseSpecifier baseSpec = new PlanPhaseSpecifier("Shotgun", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null);
final PlanPhaseSpecifier addOnSpec1 = new PlanPhaseSpecifier("Telescopic-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null);
final PlanPhaseSpecifier addOnSpec2 = new PlanPhaseSpecifier("Laser-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null);
final String externalKeyA = "baseExternalKeyAAA";
final EntitlementSpecifier baseEntitlementSpecifier = new DefaultEntitlementSpecifier(baseSpec, null);
final EntitlementSpecifier addOnEntitlementSpecifier1 = new DefaultEntitlementSpecifier(addOnSpec1, null);
final EntitlementSpecifier addOnEntitlementSpecifier2 = new DefaultEntitlementSpecifier(addOnSpec2, null);
final List<EntitlementSpecifier> specifierListA = new ArrayList<EntitlementSpecifier>();
specifierListA.add(baseEntitlementSpecifier);
specifierListA.add(addOnEntitlementSpecifier1);
specifierListA.add(addOnEntitlementSpecifier2);
final String externalKeyB = "baseExternalKeyBBB";
final List<EntitlementSpecifier> specifierListB = new ArrayList<EntitlementSpecifier>();
specifierListB.add(baseEntitlementSpecifier);
specifierListB.add(addOnEntitlementSpecifier1);
specifierListB.add(addOnEntitlementSpecifier2);
final List<BaseEntitlementWithAddOnsSpecifier> entitlementWithAddOnsSpecifierList = new ArrayList<BaseEntitlementWithAddOnsSpecifier>();
final BaseEntitlementWithAddOnsSpecifier cartSpecifierA = new DefaultBaseEntitlementWithAddOnsSpecifier(null, externalKeyA, specifierListA, null, null, false);
final BaseEntitlementWithAddOnsSpecifier cartSpecifierB = new DefaultBaseEntitlementWithAddOnsSpecifier(null, externalKeyB, specifierListB, null, null, false);
entitlementWithAddOnsSpecifierList.add(cartSpecifierA);
entitlementWithAddOnsSpecifierList.add(cartSpecifierB);
busHandler.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK, NextEvent.CREATE, NextEvent.BLOCK, NextEvent.CREATE, NextEvent.BLOCK, NextEvent.CREATE, NextEvent.BLOCK, NextEvent.CREATE, NextEvent.BLOCK, NextEvent.CREATE, NextEvent.BLOCK, NextEvent.NULL_INVOICE, NextEvent.NULL_INVOICE, NextEvent.NULL_INVOICE, NextEvent.NULL_INVOICE, NextEvent.NULL_INVOICE, NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
final List<Entitlement> allEntitlements = entitlementApi.createBaseEntitlementsWithAddOns(account.getId(), entitlementWithAddOnsSpecifierList, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
checkNoMoreInvoiceToGenerate(account);
assertNotNull(allEntitlements);
assertEquals(allEntitlements.size(), 6);
final Entitlement baseEntitlement = allEntitlements.get(0);
final Entitlement addOnEntitlement1 = allEntitlements.get(1);
final Entitlement addOnEntitlement2 = allEntitlements.get(2);
assertEquals(baseEntitlement.getLastActiveProduct().getName(), "Shotgun");
assertEquals(baseEntitlement.getLastActiveProductCategory(), ProductCategory.BASE);
assertEquals(addOnEntitlement1.getLastActiveProduct().getName(), "Telescopic-Scope");
assertEquals(addOnEntitlement1.getLastActiveProductCategory(), ProductCategory.ADD_ON);
assertEquals(addOnEntitlement2.getLastActiveProduct().getName(), "Laser-Scope");
assertEquals(addOnEntitlement2.getLastActiveProductCategory(), ProductCategory.ADD_ON);
final List<Invoice> invoices = invoiceUserApi.getInvoicesByAccount(account.getId(), false, callContext);
// ONLY ONE INVOICE
assertEquals(invoices.size(), 1);
assertEquals(invoices.get(0).getInvoiceItems().size(), 6);
final ImmutableList<ExpectedInvoiceItemCheck> toBeChecked = ImmutableList.<ExpectedInvoiceItemCheck>of(// amount=387.05, rate=399.95 -> Telescopic-Scope
new ExpectedInvoiceItemCheck(initialDate, new LocalDate(2015, 10, 31), InvoiceItemType.RECURRING, new BigDecimal("387.05")), // amount=967.69, rate=999.95 -> Laser-Scope
new ExpectedInvoiceItemCheck(initialDate, new LocalDate(2015, 10, 31), InvoiceItemType.RECURRING, new BigDecimal("967.69")), // Shotgun
new ExpectedInvoiceItemCheck(initialDate, null, InvoiceItemType.FIXED, new BigDecimal("0")), // amount=387.05, rate=399.95 -> Telescopic-Scope
new ExpectedInvoiceItemCheck(initialDate, new LocalDate(2015, 10, 31), InvoiceItemType.RECURRING, new BigDecimal("387.05")), // amount=967.69, rate=999.95 -> Laser-Scope
new ExpectedInvoiceItemCheck(initialDate, new LocalDate(2015, 10, 31), InvoiceItemType.RECURRING, new BigDecimal("967.69")), // Shotgun
new ExpectedInvoiceItemCheck(initialDate, null, InvoiceItemType.FIXED, new BigDecimal("0")));
invoiceChecker.checkInvoice(invoices.get(0).getId(), callContext, toBeChecked);
}
use of org.killbill.billing.entitlement.api.Entitlement in project killbill by killbill.
the class TestIntegrationBase method verifyTestResult.
protected void verifyTestResult(final UUID accountId, final UUID subscriptionId, final DateTime startDate, @Nullable final DateTime endDate, final BigDecimal amount, final DateTime chargeThroughDate, final int totalInvoiceItemCount) throws EntitlementApiException {
final Entitlement entitlement = entitlementApi.getEntitlementForId(subscriptionId, callContext);
final SubscriptionBase subscription = ((DefaultEntitlement) entitlement).getSubscriptionBase();
final DateTime ctd = subscription.getChargedThroughDate();
assertNotNull(ctd);
log.info("Checking CTD: " + ctd.toString() + "; clock is " + clock.getUTCNow().toString());
// Either the ctd is today (start of the trial) or the clock is strictly before the CTD
assertTrue(clock.getUTCToday().compareTo(new LocalDate(ctd)) == 0 || clock.getUTCNow().isBefore(ctd));
assertTrue(ctd.toDateTime(testTimeZone).toLocalDate().compareTo(new LocalDate(chargeThroughDate.getYear(), chargeThroughDate.getMonthOfYear(), chargeThroughDate.getDayOfMonth())) == 0);
}
Aggregations