use of org.killbill.billing.invoice.dao.InvoiceModelDao in project killbill by killbill.
the class TestIntegrationInvoiceWithRepairLogic method testRegressionFor170.
// This is a beatrix level test matching our invoice TestDefaultInvoiceGenerator#testRegressionFor170
@Test(groups = "slow")
public void testRegressionFor170() throws Exception {
final DateTime initialDate = new DateTime(2013, 6, 15, 0, 0, 0, 0, testTimeZone);
final LocalDate startDate = initialDate.toLocalDate();
clock.setDeltaFromReality(initialDate.getMillis() - clock.getUTCNow().getMillis());
final Account account = createAccountWithNonOsgiPaymentMethod(getAccountData(15));
assertNotNull(account);
add_AUTO_PAY_OFF_Tag(account.getId(), ObjectType.ACCOUNT);
final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("pistol-monthly-notrial");
busHandler.pushExpectedEvents(NextEvent.BLOCK, NextEvent.CREATE, NextEvent.INVOICE);
final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), new DefaultEntitlementSpecifier(spec, null, null, null), null, startDate, startDate, false, false, ImmutableList.<PluginProperty>of(), callContext);
final Entitlement bpEntitlement = entitlementApi.getEntitlementForId(entitlementId, callContext);
assertListenerStatus();
final Invoice invoice = invoiceChecker.checkInvoice(account.getId(), 1, callContext, new ExpectedInvoiceItemCheck(new LocalDate(2013, 6, 15), new LocalDate(2013, 7, 15), InvoiceItemType.RECURRING, new BigDecimal("19.95")));
add_AUTO_INVOICING_OFF_Tag(account.getId(), ObjectType.ACCOUNT);
final UUID linkedItemId = invoice.getInvoiceItems().get(0).getId();
final InvoiceModelDao repairInvoice = new InvoiceModelDao(UUID.randomUUID(), clock.getUTCNow(), account.getId(), null, startDate, startDate, Currency.USD, false, InvoiceStatus.COMMITTED, false);
final InvoiceItemModelDao wrongRepair = new InvoiceItemModelDao(repairInvoice.getCreatedDate(), InvoiceItemType.REPAIR_ADJ, repairInvoice.getId(), repairInvoice.getAccountId(), bpEntitlement.getBundleId(), bpEntitlement.getBaseEntitlementId(), null, null, null, null, null, null, new LocalDate(2013, 6, 21), new LocalDate(2013, 6, 26), new BigDecimal("-3.33"), new BigDecimal("19.95"), account.getCurrency(), linkedItemId);
repairInvoice.addInvoiceItem(wrongRepair);
busHandler.pushExpectedEvents(NextEvent.INVOICE_ADJUSTMENT, NextEvent.INVOICE);
insertInvoiceItems(repairInvoice);
assertListenerStatus();
// Prior the change introduced in 6338109f8cdc7, this is what the code would have generated
final InvoiceModelDao prevBehaviorInvoice = new InvoiceModelDao(UUID.randomUUID(), clock.getUTCNow(), account.getId(), null, startDate, startDate, Currency.USD, false, InvoiceStatus.COMMITTED, false);
final InvoiceItemModelDao prevRecurring = new InvoiceItemModelDao(initialDate, InvoiceItemType.RECURRING, prevBehaviorInvoice.getId(), prevBehaviorInvoice.getAccountId(), bpEntitlement.getBundleId(), entitlementId, "", "Pistol", "pistol-monthly-notrial", "pistol-monthly-notrial-evergreen", null, null, new LocalDate(2013, 6, 15), new LocalDate(2013, 7, 15), new BigDecimal("19.85"), new BigDecimal("19.95"), account.getCurrency(), null);
final InvoiceItemModelDao prevRepair1 = new InvoiceItemModelDao(prevBehaviorInvoice.getCreatedDate(), InvoiceItemType.REPAIR_ADJ, prevBehaviorInvoice.getId(), prevBehaviorInvoice.getAccountId(), bpEntitlement.getBundleId(), bpEntitlement.getBaseEntitlementId(), null, null, null, null, null, null, new LocalDate(2013, 6, 15), new LocalDate(2013, 6, 21), new BigDecimal("-3.99"), new BigDecimal("19.95"), account.getCurrency(), linkedItemId);
final InvoiceItemModelDao prevRepair2 = new InvoiceItemModelDao(prevBehaviorInvoice.getCreatedDate(), InvoiceItemType.REPAIR_ADJ, prevBehaviorInvoice.getId(), prevBehaviorInvoice.getAccountId(), bpEntitlement.getBundleId(), bpEntitlement.getBaseEntitlementId(), null, null, null, null, null, null, new LocalDate(2013, 6, 26), new LocalDate(2013, 7, 15), new BigDecimal("-12.63"), new BigDecimal("19.95"), account.getCurrency(), linkedItemId);
prevBehaviorInvoice.addInvoiceItem(prevRecurring);
prevBehaviorInvoice.addInvoiceItem(prevRepair1);
prevBehaviorInvoice.addInvoiceItem(prevRepair2);
busHandler.pushExpectedEvents(NextEvent.INVOICE);
insertInvoiceItems(prevBehaviorInvoice);
assertListenerStatus();
// Nothing to generate - new behavior is compatible with older behavior
busHandler.pushExpectedEvents(NextEvent.NULL_INVOICE);
remove_AUTO_INVOICING_OFF_Tag(account.getId(), ObjectType.ACCOUNT);
assertListenerStatus();
checkNoMoreInvoiceToGenerate(account);
}
use of org.killbill.billing.invoice.dao.InvoiceModelDao in project killbill by killbill.
the class TestIntegrationWithDifferentBillingPeriods method testPauseResumeAnnualWithInvoicingOffMigrationPath_0_20_to_0_22.
@Test(groups = "slow")
public void testPauseResumeAnnualWithInvoicingOffMigrationPath_0_20_to_0_22() 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.setDeltaFromReality(today.toDateTimeAtCurrentTime(DateTimeZone.UTC).getMillis() - clock.getUTCNow().getMillis());
final String productName = "Shotgun";
//
// CREATE SUBSCRIPTION AND EXPECT BOTH EVENTS: NextEvent.CREATE, NextEvent.BLOCK NextEvent.INVOICE
//
final DefaultEntitlement bpEntitlement = createBaseEntitlementAndCheckForCompletion(account.getId(), "externalKey", productName, ProductCategory.BASE, BillingPeriod.ANNUAL, NextEvent.CREATE, NextEvent.BLOCK, NextEvent.INVOICE);
assertNotNull(bpEntitlement);
assertEquals(invoiceUserApi.getInvoicesByAccount(account.getId(), false, false, callContext).size(), 1);
assertEquals(bpEntitlement.getSubscriptionBase().getCurrentPlan().getRecurringBillingPeriod(), BillingPeriod.ANNUAL);
// Move out of trials for interesting invoices adjustments
busHandler.pushExpectedEvents(NextEvent.PHASE, NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
clock.addDays(31);
assertListenerStatus();
// Auto invoice off
busHandler.pushExpectedEvents(NextEvent.TAG);
tagUserApi.addTag(account.getId(), ObjectType.ACCOUNT, ControlTagType.AUTO_INVOICING_OFF.getId(), callContext);
assertListenerStatus();
// 2012-5-12
clock.addDays(10);
busHandler.pushExpectedEvents(NextEvent.BLOCK);
entitlementApi.pause(bpEntitlement.getBundleId(), clock.getUTCNow().toLocalDate(), ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
// 2012-6-4
clock.addDays(23);
busHandler.pushExpectedEvents(NextEvent.BLOCK);
entitlementApi.resume(bpEntitlement.getBundleId(), clock.getUTCNow().toLocalDate(), ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
// /
List<Invoice> invoices = invoiceUserApi.getInvoicesByAccount(account.getId(), false, false, callContext);
assertEquals(invoices.size(), 2);
final Invoice secondInvoice = invoices.get(1);
final UUID originalRecuringItemId = secondInvoice.getInvoiceItems().get(0).getId();
final InvoiceModelDao invoiceForRepair_0_20 = new InvoiceModelDao(UUID.randomUUID(), clock.getUTCNow(), account.getId(), null, clock.getUTCToday(), clock.getUTCToday(), Currency.USD, false, InvoiceStatus.COMMITTED, false);
final InvoiceItemModelDao repair = new InvoiceItemModelDao(invoiceForRepair_0_20.getCreatedDate(), InvoiceItemType.REPAIR_ADJ, invoiceForRepair_0_20.getId(), account.getId(), UUID.randomUUID(), bpEntitlement.getId(), null, null, null, null, null, null, new LocalDate(2012, 5, 12), new LocalDate(2013, 5, 1), new BigDecimal("-2327.62"), new BigDecimal("-2327.62"), account.getCurrency(), originalRecuringItemId);
final InvoiceItemModelDao recurring = new InvoiceItemModelDao(invoiceForRepair_0_20.getCreatedDate(), InvoiceItemType.RECURRING, invoiceForRepair_0_20.getId(), account.getId(), UUID.randomUUID(), bpEntitlement.getId(), "", "Shotgun", "shotgun-monthly", "shotgun-monthly-evergreen", null, null, new LocalDate(2012, 6, 4), new LocalDate(2013, 6, 1), new BigDecimal("2380.22"), new BigDecimal("2380.22"), account.getCurrency(), null);
invoiceForRepair_0_20.addInvoiceItem(repair);
invoiceForRepair_0_20.addInvoiceItem(recurring);
busHandler.pushExpectedEvents(NextEvent.INVOICE, NextEvent.INVOICE_PAYMENT, NextEvent.PAYMENT);
insertInvoiceItems(invoiceForRepair_0_20);
assertListenerStatus();
//
// We should not generate any invoice, instead, we generate a new invoice with 2 canceling items
//
// busHandler.pushExpectedEvents(NextEvent.TAG, NextEvent.NULL_INVOICE);
busHandler.pushExpectedEvents(NextEvent.TAG, NextEvent.INVOICE);
tagUserApi.removeTag(account.getId(), ObjectType.ACCOUNT, ControlTagType.AUTO_INVOICING_OFF.getId(), callContext);
assertListenerStatus();
invoices = invoiceUserApi.getInvoicesByAccount(account.getId(), false, false, callContext);
assertEquals(invoices.size(), 4);
ImmutableList<ExpectedInvoiceItemCheck> toBeChecked = ImmutableList.<ExpectedInvoiceItemCheck>of(new ExpectedInvoiceItemCheck(new LocalDate(2012, 6, 4), new LocalDate(2013, 6, 1), InvoiceItemType.RECURRING, new BigDecimal("2380.22")), // Cancels similar item previously added from 0_22
new ExpectedInvoiceItemCheck(new LocalDate(2012, 6, 4), new LocalDate(2013, 6, 1), InvoiceItemType.REPAIR_ADJ, new BigDecimal("-2380.22")));
invoiceChecker.checkInvoice(invoices.get(3).getId(), callContext, toBeChecked);
checkNoMoreInvoiceToGenerate(account);
}
use of org.killbill.billing.invoice.dao.InvoiceModelDao in project killbill by killbill.
the class InvoiceApiHelper method dispatchToInvoicePluginsAndInsertItems.
public List<InvoiceItem> dispatchToInvoicePluginsAndInsertItems(final UUID accountId, final boolean isDryRun, final WithAccountLock withAccountLock, final CallContext context) throws InvoiceApiException {
GlobalLock lock = null;
try {
lock = locker.lockWithNumberOfTries(LockerType.ACCNT_INV_PAY.toString(), accountId.toString(), invoiceConfig.getMaxGlobalLockRetries());
final Iterable<Invoice> invoicesForPlugins = withAccountLock.prepareInvoices();
final List<InvoiceModelDao> invoiceModelDaos = new LinkedList<InvoiceModelDao>();
for (final Invoice invoiceForPlugin : invoicesForPlugins) {
// Call plugin
final List<InvoiceItem> additionalInvoiceItems = invoicePluginDispatcher.getAdditionalInvoiceItems(invoiceForPlugin, isDryRun, context);
invoiceForPlugin.addInvoiceItems(additionalInvoiceItems);
// Transformation to InvoiceModelDao
final InvoiceModelDao invoiceModelDao = new InvoiceModelDao(invoiceForPlugin);
final List<InvoiceItem> invoiceItems = invoiceForPlugin.getInvoiceItems();
final List<InvoiceItemModelDao> invoiceItemModelDaos = toInvoiceItemModelDao(invoiceItems);
invoiceModelDao.addInvoiceItems(invoiceItemModelDaos);
// Keep track of modified invoices
invoiceModelDaos.add(invoiceModelDao);
}
final InternalCallContext internalCallContext = internalCallContextFactory.createInternalCallContext(accountId, context);
final List<InvoiceItemModelDao> createdInvoiceItems = dao.createInvoices(invoiceModelDaos, internalCallContext);
return fromInvoiceItemModelDao(createdInvoiceItems);
} catch (final LockFailedException e) {
log.warn("Failed to process invoice items for accountId='{}'", accountId.toString(), e);
return ImmutableList.<InvoiceItem>of();
} finally {
if (lock != null) {
lock.release();
}
}
}
use of org.killbill.billing.invoice.dao.InvoiceModelDao in project killbill by killbill.
the class InvoiceTestUtils method createAndPersistInvoice.
public static Invoice createAndPersistInvoice(final TestInvoiceHelper testInvoiceHelper, final InvoiceDao invoiceDao, final Clock clock, final Iterable<BigDecimal> amounts, final Currency currency, final InternalCallContext internalCallContext) throws EntityPersistenceException {
final Invoice invoice = Mockito.mock(Invoice.class);
final UUID invoiceId = UUID.randomUUID();
final UUID accountId;
try {
final Account account = testInvoiceHelper.createAccount(internalCallContext.toCallContext(null, null));
accountId = account.getId();
} catch (final AccountApiException e) {
Assert.fail(e.getMessage());
return null;
}
Mockito.when(invoice.getId()).thenReturn(invoiceId);
Mockito.when(invoice.getAccountId()).thenReturn(accountId);
final LocalDate today = clock.getUTCToday();
Mockito.when(invoice.getInvoiceDate()).thenReturn(today);
Mockito.when(invoice.getTargetDate()).thenReturn(today);
Mockito.when(invoice.getCurrency()).thenReturn(currency);
Mockito.when(invoice.isMigrationInvoice()).thenReturn(false);
Mockito.when(invoice.getStatus()).thenReturn(InvoiceStatus.COMMITTED);
final List<InvoiceItem> invoiceItems = new ArrayList<InvoiceItem>();
final List<InvoiceItemModelDao> invoiceModelItems = new ArrayList<InvoiceItemModelDao>();
for (final BigDecimal amount : amounts) {
final InvoiceItem invoiceItem = createInvoiceItem(clock, invoiceId, accountId, amount, currency);
invoiceModelItems.add(new InvoiceItemModelDao(invoiceItem));
invoiceItems.add(invoiceItem);
}
Mockito.when(invoice.getInvoiceItems()).thenReturn(invoiceItems);
final InvoiceModelDao invoiceModelDao = new InvoiceModelDao(invoice);
invoiceModelDao.addInvoiceItems(invoiceModelItems);
invoiceDao.createInvoices(ImmutableList.<InvoiceModelDao>of(invoiceModelDao), null, ImmutableSet.of(), internalCallContext);
return invoice;
}
use of org.killbill.billing.invoice.dao.InvoiceModelDao in project killbill by killbill.
the class TestInvoiceHelper method createInvoice.
public void createInvoice(final Invoice invoice, final InternalCallContext internalCallContext) throws EntityPersistenceException {
final InvoiceModelDao invoiceModelDao = new InvoiceModelDao(invoice);
final List<InvoiceItemModelDao> invoiceItemModelDaos = ImmutableList.<InvoiceItemModelDao>copyOf(Collections2.transform(invoice.getInvoiceItems(), new Function<InvoiceItem, InvoiceItemModelDao>() {
@Override
public InvoiceItemModelDao apply(final InvoiceItem input) {
return new InvoiceItemModelDao(input);
}
}));
invoiceSqlDao.create(invoiceModelDao, internalCallContext);
for (final InvoiceItem invoiceItem : invoice.getInvoiceItems()) {
createInvoiceItem(invoiceItem, internalCallContext);
}
}
Aggregations