use of org.killbill.billing.invoice.api.Invoice in project killbill by killbill.
the class TestDefaultInvoiceGenerator method testMixedModeLifeCycle.
@Test(groups = "fast")
public void testMixedModeLifeCycle() throws InvoiceApiException, CatalogApiException {
// create a SubscriptionBase with a fixed price and recurring price
final Plan plan1 = new MockPlan();
final BigDecimal monthlyRate = FIVE;
final BigDecimal fixedCost = TEN;
final PlanPhase phase1 = createMockMonthlyPlanPhase(monthlyRate, fixedCost, PhaseType.TRIAL);
final BillingEventSet events = new MockBillingEventSet();
final UUID subscriptionId = UUID.randomUUID();
final UUID bundleId = UUID.randomUUID();
final LocalDate startDate = new LocalDate(2011, 1, 1);
final BillingEvent event1 = createBillingEvent(subscriptionId, bundleId, startDate, plan1, phase1, 1);
events.add(event1);
// ensure both components are invoiced
final InvoiceWithMetadata invoiceWithMetadata1 = generator.generateInvoice(account, events, null, startDate, Currency.USD, internalCallContext);
final Invoice invoice1 = invoiceWithMetadata1.getInvoice();
assertNotNull(invoice1);
assertEquals(invoice1.getNumberOfItems(), 2);
assertEquals(invoice1.getBalance(), KillBillMoney.of(FIFTEEN, invoice1.getCurrency()));
final List<Invoice> invoiceList = new ArrayList<Invoice>();
invoiceList.add(invoice1);
// move forward in time one billing period
final LocalDate currentDate = startDate.plusMonths(1);
// ensure that only the recurring price is invoiced
final InvoiceWithMetadata invoiceWithMetadata2 = generator.generateInvoice(account, events, invoiceList, currentDate, Currency.USD, internalCallContext);
final Invoice invoice2 = invoiceWithMetadata2.getInvoice();
assertNotNull(invoice2);
assertEquals(invoice2.getNumberOfItems(), 1);
assertEquals(invoice2.getBalance(), KillBillMoney.of(FIVE, invoice2.getCurrency()));
}
use of org.killbill.billing.invoice.api.Invoice in project killbill by killbill.
the class TestDefaultInvoiceGenerator method testRepairForPaidInvoice.
@Test(groups = "fast")
public void testRepairForPaidInvoice() throws CatalogApiException, InvoiceApiException {
// create an invoice
final LocalDate april25 = new LocalDate(2012, 4, 25);
// create a base plan on April 25th
final SubscriptionBase originalSubscription = createSubscription();
final Plan originalPlan = new MockPlan("original plan");
final MockInternationalPrice price10 = new MockInternationalPrice(new DefaultPrice(TEN, Currency.USD));
final PlanPhase originalPlanEvergreen = new MockPlanPhase(price10, null, BillingPeriod.MONTHLY, PhaseType.EVERGREEN);
final BillingEventSet events = new MockBillingEventSet();
events.add(createBillingEvent(originalSubscription.getId(), originalSubscription.getBundleId(), april25, originalPlan, originalPlanEvergreen, 25));
final InvoiceWithMetadata invoiceWithMetadata1 = generator.generateInvoice(account, events, null, april25, Currency.USD, internalCallContext);
final Invoice invoice1 = invoiceWithMetadata1.getInvoice();
printDetailInvoice(invoice1);
assertEquals(invoice1.getNumberOfItems(), 1);
final List<Invoice> invoices = new ArrayList<Invoice>();
invoices.add(invoice1);
// pay the invoice
invoice1.addPayment(new DefaultInvoicePayment(InvoicePaymentType.ATTEMPT, UUID.randomUUID(), invoice1.getId(), april25.toDateTimeAtCurrentTime(), TEN, Currency.USD, Currency.USD, null, true));
assertEquals(invoice1.getBalance().compareTo(ZERO), 0);
// change the plan (i.e. repair) on start date
events.clear();
final SubscriptionBase newSubscription = createSubscription();
final Plan newPlan = new MockPlan("new plan");
final MockInternationalPrice price5 = new MockInternationalPrice(new DefaultPrice(FIVE, Currency.USD));
final PlanPhase newPlanEvergreen = new MockPlanPhase(price5, null, BillingPeriod.MONTHLY, PhaseType.EVERGREEN);
events.add(createBillingEvent(newSubscription.getId(), originalSubscription.getBundleId(), april25, newPlan, newPlanEvergreen, 25));
// generate a new invoice
final InvoiceWithMetadata invoiceWithMetadata2 = generator.generateInvoice(account, events, invoices, april25, Currency.USD, internalCallContext);
final Invoice invoice2 = invoiceWithMetadata2.getInvoice();
printDetailInvoice(invoice2);
assertEquals(invoice2.getNumberOfItems(), 2);
invoices.add(invoice2);
// move items to the correct invoice (normally, the dao calls will sort that out)
distributeItems(invoices);
// ensure that the original invoice balance is zero
assertEquals(invoice1.getBalance().compareTo(BigDecimal.ZERO), 0);
// ensure that the account balance is correct
assertEquals(invoice2.getBalance().compareTo(new BigDecimal("-5.0")), 0);
}
use of org.killbill.billing.invoice.api.Invoice in project killbill by killbill.
the class TestInvoiceDao method testAccountBalanceWithRefundInternal.
private void testAccountBalanceWithRefundInternal(final boolean withAdjustment) throws InvoiceApiException, EntityPersistenceException {
final UUID accountId = account.getId();
final UUID bundleId = UUID.randomUUID();
final LocalDate targetDate1 = new LocalDate(2011, 10, 6);
final Invoice invoice1 = new DefaultInvoice(accountId, clock.getUTCToday(), targetDate1, Currency.USD);
invoiceUtil.createInvoice(invoice1, context);
final LocalDate startDate = new LocalDate(2011, 3, 1);
final LocalDate endDate = startDate.plusMonths(1);
final BigDecimal rate1 = new BigDecimal("20.0");
final BigDecimal refund1 = new BigDecimal("7.00");
// Recurring item
final RecurringInvoiceItem item2 = new RecurringInvoiceItem(invoice1.getId(), accountId, bundleId, UUID.randomUUID(), "test plan", "test phase B", startDate, endDate, rate1, rate1, Currency.USD);
invoiceUtil.createInvoiceItem(item2, context);
BigDecimal balance = invoiceDao.getAccountBalance(accountId, context);
assertEquals(balance.compareTo(new BigDecimal("20.00")), 0);
// Pay the whole thing
final UUID paymentId = UUID.randomUUID();
final BigDecimal payment1 = rate1;
final InvoicePayment payment = new DefaultInvoicePayment(InvoicePaymentType.ATTEMPT, paymentId, invoice1.getId(), new DateTime(), payment1, Currency.USD, Currency.USD, null, true);
invoiceUtil.createPayment(payment, context);
balance = invoiceDao.getAccountBalance(accountId, context);
assertEquals(balance.compareTo(new BigDecimal("0.00")), 0);
invoiceDao.createRefund(paymentId, refund1, withAdjustment, ImmutableMap.<UUID, BigDecimal>of(), UUID.randomUUID().toString(), context);
balance = invoiceDao.getAccountBalance(accountId, context);
if (withAdjustment) {
assertEquals(balance.compareTo(BigDecimal.ZERO), 0);
} else {
assertEquals(balance.compareTo(new BigDecimal("7.00")), 0);
}
}
use of org.killbill.billing.invoice.api.Invoice in project killbill by killbill.
the class TestInvoiceDao method testRefundCBAFullyConsumedTwice.
@Test(groups = "slow")
public void testRefundCBAFullyConsumedTwice() throws Exception {
final UUID accountId = account.getId();
// Create invoice 1
// Scenario: single item with payment
// * $10 item
// Then, a repair occur:
// * $-10 repair
// * $10 generated CBA due to the repair (assume previous payment)
final Invoice invoice1 = new DefaultInvoice(accountId, clock.getUTCToday(), clock.getUTCToday(), Currency.USD);
final InvoiceItem fixedItem1 = new FixedPriceInvoiceItem(invoice1.getId(), invoice1.getAccountId(), null, null, UUID.randomUUID().toString(), UUID.randomUUID().toString(), clock.getUTCToday(), BigDecimal.TEN, Currency.USD);
final RepairAdjInvoiceItem repairAdjInvoiceItem = new RepairAdjInvoiceItem(fixedItem1.getInvoiceId(), fixedItem1.getAccountId(), fixedItem1.getStartDate(), fixedItem1.getEndDate(), fixedItem1.getAmount().negate(), fixedItem1.getCurrency(), fixedItem1.getId());
final CreditBalanceAdjInvoiceItem creditBalanceAdjInvoiceItem1 = new CreditBalanceAdjInvoiceItem(fixedItem1.getInvoiceId(), fixedItem1.getAccountId(), fixedItem1.getStartDate(), fixedItem1.getAmount(), fixedItem1.getCurrency());
invoiceUtil.createInvoice(invoice1, context);
invoiceUtil.createInvoiceItem(fixedItem1, context);
invoiceUtil.createInvoiceItem(repairAdjInvoiceItem, context);
invoiceUtil.createInvoiceItem(creditBalanceAdjInvoiceItem1, context);
final BigDecimal paymentAmount = new BigDecimal("10.00");
final UUID paymentId = UUID.randomUUID();
final DefaultInvoicePayment defaultInvoicePayment = new DefaultInvoicePayment(InvoicePaymentType.ATTEMPT, paymentId, invoice1.getId(), clock.getUTCNow().plusDays(12), paymentAmount, Currency.USD, Currency.USD, "cookie", true);
invoiceDao.notifyOfPaymentCompletion(new InvoicePaymentModelDao(defaultInvoicePayment), context);
// Create invoice 2
// Scenario: single item
// * $5 item
// * $-5 CBA used
final DefaultInvoice invoice2 = new DefaultInvoice(accountId, clock.getUTCToday(), clock.getUTCToday(), Currency.USD);
final InvoiceItem fixedItem2 = new FixedPriceInvoiceItem(invoice2.getId(), invoice1.getAccountId(), null, null, UUID.randomUUID().toString(), UUID.randomUUID().toString(), clock.getUTCToday(), new BigDecimal("5"), Currency.USD);
final CreditBalanceAdjInvoiceItem creditBalanceAdjInvoiceItem2 = new CreditBalanceAdjInvoiceItem(fixedItem2.getInvoiceId(), fixedItem2.getAccountId(), fixedItem2.getStartDate(), fixedItem2.getAmount().negate(), fixedItem2.getCurrency());
invoiceUtil.createInvoice(invoice2, context);
invoiceUtil.createInvoiceItem(fixedItem2, context);
invoiceUtil.createInvoiceItem(creditBalanceAdjInvoiceItem2, context);
// Create invoice 3
// Scenario: single item
// * $5 item
// * $-5 CBA used
final DefaultInvoice invoice3 = new DefaultInvoice(accountId, clock.getUTCToday(), clock.getUTCToday(), Currency.USD);
final InvoiceItem fixedItem3 = new FixedPriceInvoiceItem(invoice3.getId(), invoice1.getAccountId(), null, null, UUID.randomUUID().toString(), UUID.randomUUID().toString(), clock.getUTCToday(), new BigDecimal("5"), Currency.USD);
final CreditBalanceAdjInvoiceItem creditBalanceAdjInvoiceItem3 = new CreditBalanceAdjInvoiceItem(fixedItem3.getInvoiceId(), fixedItem3.getAccountId(), fixedItem3.getStartDate(), fixedItem3.getAmount().negate(), fixedItem3.getCurrency());
invoiceUtil.createInvoice(invoice3, context);
invoiceUtil.createInvoiceItem(fixedItem3, context);
invoiceUtil.createInvoiceItem(creditBalanceAdjInvoiceItem3, context);
// Verify scenario - all CBA should have been used
Assert.assertEquals(invoiceDao.getAccountCBA(accountId, context).doubleValue(), 0.00);
invoiceUtil.verifyInvoice(invoice1.getId(), 0.00, 10.00, context);
invoiceUtil.verifyInvoice(invoice2.getId(), 0.00, -5.00, context);
invoiceUtil.verifyInvoice(invoice3.getId(), 0.00, -5.00, context);
invoiceDao.createRefund(paymentId, paymentAmount, false, ImmutableMap.<UUID, BigDecimal>of(), UUID.randomUUID().toString(), context);
// Verify all three invoices were affected
Assert.assertEquals(invoiceDao.getAccountCBA(accountId, context).doubleValue(), 0.00);
invoiceUtil.verifyInvoice(invoice1.getId(), 10.00, 10.00, context);
invoiceUtil.verifyInvoice(invoice2.getId(), 0.00, -5.00, context);
invoiceUtil.verifyInvoice(invoice3.getId(), 0.00, -5.00, context);
}
use of org.killbill.billing.invoice.api.Invoice in project killbill by killbill.
the class TestInvoiceDao method testGetUnpaidInvoicesByAccountId.
@Test(groups = "slow")
public void testGetUnpaidInvoicesByAccountId() throws EntityPersistenceException {
final UUID accountId = account.getId();
final UUID bundleId = UUID.randomUUID();
final LocalDate targetDate1 = new LocalDate(2011, 10, 6);
final Invoice invoice1 = new DefaultInvoice(accountId, clock.getUTCToday(), targetDate1, Currency.USD);
invoiceUtil.createInvoice(invoice1, context);
final LocalDate startDate = new LocalDate(2011, 3, 1);
final LocalDate endDate = startDate.plusMonths(1);
final BigDecimal rate1 = new BigDecimal("17.0");
final BigDecimal rate2 = new BigDecimal("42.0");
final RecurringInvoiceItem item1 = new RecurringInvoiceItem(invoice1.getId(), accountId, bundleId, UUID.randomUUID(), "test plan", "test phase A", startDate, endDate, rate1, rate1, Currency.USD);
invoiceUtil.createInvoiceItem(item1, context);
final RecurringInvoiceItem item2 = new RecurringInvoiceItem(invoice1.getId(), accountId, bundleId, UUID.randomUUID(), "test plan", "test phase B", startDate, endDate, rate2, rate2, Currency.USD);
invoiceUtil.createInvoiceItem(item2, context);
LocalDate upToDate;
Collection<InvoiceModelDao> invoices;
upToDate = new LocalDate(2011, 1, 1);
invoices = invoiceDao.getUnpaidInvoicesByAccountId(accountId, upToDate, context);
assertEquals(invoices.size(), 0);
upToDate = new LocalDate(2012, 1, 1);
invoices = invoiceDao.getUnpaidInvoicesByAccountId(accountId, upToDate, context);
assertEquals(invoices.size(), 1);
final LocalDate targetDate2 = new LocalDate(2011, 7, 1);
final Invoice invoice2 = new DefaultInvoice(accountId, clock.getUTCToday(), targetDate2, Currency.USD);
invoiceUtil.createInvoice(invoice2, context);
final LocalDate startDate2 = new LocalDate(2011, 6, 1);
final LocalDate endDate2 = startDate2.plusMonths(3);
final BigDecimal rate3 = new BigDecimal("21.0");
final RecurringInvoiceItem item3 = new RecurringInvoiceItem(invoice2.getId(), accountId, bundleId, UUID.randomUUID(), "test plan", "test phase C", startDate2, endDate2, rate3, rate3, Currency.USD);
invoiceUtil.createInvoiceItem(item3, context);
upToDate = new LocalDate(2011, 1, 1);
invoices = invoiceDao.getUnpaidInvoicesByAccountId(accountId, upToDate, context);
assertEquals(invoices.size(), 0);
upToDate = new LocalDate(2012, 1, 1);
invoices = invoiceDao.getUnpaidInvoicesByAccountId(accountId, upToDate, context);
assertEquals(invoices.size(), 2);
}
Aggregations