use of org.killbill.billing.invoice.model.FixedPriceInvoiceItem in project killbill by killbill.
the class TestDefaultInvoiceFormatter method testMergeItems.
@Test(groups = "fast")
public void testMergeItems() throws Exception {
// Scenario: single item with payment
// * $10 item
// Then, a repair occur:
// * $-10 repair
// * $10 generated CBA due to the repair (assume previous payment)
// Then, the invoice is adjusted for $1:
// * $-1 credit adjustment
// * $1 generated CBA due to the credit adjustment
final FixedPriceInvoiceItem fixedItem = new FixedPriceInvoiceItem(UUID.randomUUID(), UUID.randomUUID(), null, null, UUID.randomUUID().toString(), UUID.randomUUID().toString(), UUID.randomUUID().toString(), null, new LocalDate(), BigDecimal.TEN, Currency.USD);
final RepairAdjInvoiceItem repairAdjInvoiceItem = new RepairAdjInvoiceItem(fixedItem.getInvoiceId(), fixedItem.getAccountId(), fixedItem.getStartDate(), fixedItem.getEndDate(), fixedItem.getAmount().negate(), fixedItem.getCurrency(), fixedItem.getId());
final CreditBalanceAdjInvoiceItem creditBalanceAdjInvoiceItem = new CreditBalanceAdjInvoiceItem(fixedItem.getInvoiceId(), fixedItem.getAccountId(), fixedItem.getStartDate(), fixedItem.getAmount(), fixedItem.getCurrency());
final CreditAdjInvoiceItem creditAdjInvoiceItem = new CreditAdjInvoiceItem(fixedItem.getInvoiceId(), fixedItem.getAccountId(), fixedItem.getStartDate(), null, BigDecimal.ONE.negate(), fixedItem.getCurrency(), null);
final CreditBalanceAdjInvoiceItem creditBalanceAdjInvoiceItem2 = new CreditBalanceAdjInvoiceItem(fixedItem.getInvoiceId(), fixedItem.getAccountId(), fixedItem.getStartDate(), creditAdjInvoiceItem.getAmount().negate(), fixedItem.getCurrency());
final DefaultInvoice invoice = new DefaultInvoice(fixedItem.getInvoiceId(), fixedItem.getAccountId(), null, new LocalDate(), new LocalDate(), Currency.USD, false, InvoiceStatus.COMMITTED);
invoice.addInvoiceItem(fixedItem);
invoice.addInvoiceItem(repairAdjInvoiceItem);
invoice.addInvoiceItem(creditBalanceAdjInvoiceItem);
invoice.addInvoiceItem(creditAdjInvoiceItem);
invoice.addInvoiceItem(creditBalanceAdjInvoiceItem2);
invoice.addPayment(new DefaultInvoicePayment(InvoicePaymentType.ATTEMPT, UUID.randomUUID(), invoice.getId(), clock.getUTCNow(), BigDecimal.TEN, Currency.USD, Currency.USD, null, true));
invoice.addPayment(new DefaultInvoicePayment(InvoicePaymentType.REFUND, UUID.randomUUID(), invoice.getId(), clock.getUTCNow(), BigDecimal.ONE.negate(), Currency.USD, Currency.USD, null, true));
// Check the scenario
Assert.assertEquals(invoice.getBalance().doubleValue(), 1.00);
Assert.assertEquals(invoice.getCreditedAmount().doubleValue(), 11.00);
Assert.assertEquals(invoice.getRefundedAmount().doubleValue(), -1.00);
// Verify the merge
final InvoiceFormatter formatter = new DefaultInvoiceFormatter(config, invoice, Locale.US, null, resourceBundleFactory, internalCallContext);
final List<InvoiceItem> invoiceItems = formatter.getInvoiceItems();
Assert.assertEquals(invoiceItems.size(), 4);
Assert.assertEquals(invoiceItems.get(0).getInvoiceItemType(), InvoiceItemType.FIXED);
Assert.assertEquals(invoiceItems.get(0).getAmount().doubleValue(), 10.00);
Assert.assertEquals(invoiceItems.get(1).getInvoiceItemType(), InvoiceItemType.REPAIR_ADJ);
Assert.assertEquals(invoiceItems.get(1).getAmount().doubleValue(), -10.00);
Assert.assertEquals(invoiceItems.get(2).getInvoiceItemType(), InvoiceItemType.CBA_ADJ);
Assert.assertEquals(invoiceItems.get(2).getAmount().doubleValue(), 11.00);
Assert.assertEquals(invoiceItems.get(3).getInvoiceItemType(), InvoiceItemType.CREDIT_ADJ);
Assert.assertEquals(invoiceItems.get(3).getAmount().doubleValue(), -1.00);
}
use of org.killbill.billing.invoice.model.FixedPriceInvoiceItem in project killbill by killbill.
the class TestDefaultInvoiceFormatter method testFormattedAmountFranceAndEUR.
@Test(groups = "fast", enabled = false, description = "JDK dependent")
public void testFormattedAmountFranceAndEUR() throws Exception {
final FixedPriceInvoiceItem fixedItemEUR = new FixedPriceInvoiceItem(UUID.randomUUID(), UUID.randomUUID(), null, null, UUID.randomUUID().toString(), UUID.randomUUID().toString(), UUID.randomUUID().toString(), null, new LocalDate(), new BigDecimal("1499.95"), Currency.EUR);
final Invoice invoiceEUR = new DefaultInvoice(UUID.randomUUID(), new LocalDate(), new LocalDate(), Currency.EUR);
invoiceEUR.addInvoiceItem(fixedItemEUR);
checkOutput(invoiceEUR, "<tr>\n" + " <td class=\"amount\"><strong>{{invoice.formattedChargedAmount}}</strong></td>\n" + "</tr>\n" + "<tr>\n" + " <td class=\"amount\"><strong>{{invoice.formattedPaidAmount}}</strong></td>\n" + "</tr>\n" + "<tr>\n" + " <td class=\"amount\"><strong>{{invoice.formattedBalance}}</strong></td>\n" + "</tr>", "<tr>\n" + " <td class=\"amount\"><strong>1 499,95 €</strong></td>\n" + "</tr>\n" + "<tr>\n" + " <td class=\"amount\"><strong>0,00 €</strong></td>\n" + "</tr>\n" + "<tr>\n" + " <td class=\"amount\"><strong>1 499,95 €</strong></td>\n" + "</tr>", Locale.FRANCE);
}
use of org.killbill.billing.invoice.model.FixedPriceInvoiceItem in project killbill by killbill.
the class TestDefaultInvoiceFormatter method testFormattedAmountUSAndBTC.
@Test(groups = "fast")
public void testFormattedAmountUSAndBTC() throws Exception {
final FixedPriceInvoiceItem fixedItem = new FixedPriceInvoiceItem(UUID.randomUUID(), UUID.randomUUID(), null, null, UUID.randomUUID().toString(), UUID.randomUUID().toString(), UUID.randomUUID().toString(), null, new LocalDate(), new BigDecimal("1105.28843439"), Currency.BTC);
final Invoice invoice = new DefaultInvoice(UUID.randomUUID(), new LocalDate(), new LocalDate(), Currency.BTC);
invoice.addInvoiceItem(fixedItem);
checkOutput(invoice, "<tr>\n" + " <td class=\"amount\"><strong>{{invoice.formattedChargedAmount}}</strong></td>\n" + "</tr>\n" + "<tr>\n" + " <td class=\"amount\"><strong>{{invoice.formattedPaidAmount}}</strong></td>\n" + "</tr>\n" + "<tr>\n" + " <td class=\"amount\"><strong>{{invoice.formattedBalance}}</strong></td>\n" + "</tr>", "<tr>\n" + " <td class=\"amount\"><strong>Ƀ1,105.28843439</strong></td>\n" + "</tr>\n" + "<tr>\n" + " <td class=\"amount\"><strong>Ƀ0.00000000</strong></td>\n" + "</tr>\n" + "<tr>\n" + " <td class=\"amount\"><strong>Ƀ1,105.28843439</strong></td>\n" + "</tr>", Locale.US);
}
use of org.killbill.billing.invoice.model.FixedPriceInvoiceItem in project killbill by killbill.
the class TestDefaultInvoiceFormatter method testForDisplay.
// No Assertion, just to print the html
@Test(groups = "fast")
public void testForDisplay() throws Exception {
final FixedPriceInvoiceItem fixedItemBRL = new FixedPriceInvoiceItem(UUID.randomUUID(), UUID.randomUUID(), null, null, UUID.randomUUID().toString(), UUID.randomUUID().toString(), UUID.randomUUID().toString(), null, new LocalDate(), new BigDecimal("1499.95"), Currency.BRL);
final Invoice invoice = new DefaultInvoice(UUID.randomUUID(), UUID.randomUUID(), new Integer(234), new LocalDate(), new LocalDate(), Currency.BRL, false, InvoiceStatus.COMMITTED);
invoice.addInvoiceItem(fixedItemBRL);
final String template = "<html>\n" + " <head>\n" + " <style type=\"text/css\">\n" + " #header td { width: 250px; }\n" + " #header .company_info { width: 450px; }\n" + " #header .label { text-align: right; font-weight: bold; }\n" + " #header .label_value { padding-left: 10px; }\n" + "\n" + " #invoice_items { margin-top: 50px; }\n" + " #invoice_items th { border-bottom: solid 2px black; }\n" + " #invoice_items td { width: 250px; }\n" + " #invoice_items td.amount { width: 125px; }\n" + " #invoice_items td.network { width: 350px; }\n" + " #invoice_items .amount { text-align: right; }\n" + " #invoice_items .label { text-align: right; font-weight: bold; }\n" + " </style>\n" + " </head>\n" + " <body>\n" + " <table id=\"header\">\n" + " <tr>\n" + " <td class=\"company_info\"/>\n" + " <td />\n" + " <td><h1>{{text.invoiceTitle}}</h1></td>\n" + " </tr>\n" + " <tr>\n" + " <td colspan=\"3\"><img src=\"http://static.foo.com/www/0/main/gfx/front/logo.png\"/></td>\n" + " </tr>\n" + " <tr>\n" + " <td class=\"company_info\" />\n" + " <td class=\"label\">{{text.invoiceDate}}</td>\n" + " <td class=\"label_value\">{{invoice.formattedInvoiceDate}}</td>\n" + " </tr>\n" + " <tr>\n" + " <td class=\"company_info\" />\n" + " <td class=\"label\">{{text.invoiceNumber}}</td>\n" + " <td class=\"label_value\">{{invoice.invoiceNumber}}</td>\n" + " </tr>\n" + " <tr>\n" + " <td class=\"company_info\">{{text.companyCountry}}</td>\n" + " <td colspan=\"2\" />\n" + " </tr>\n" + " <tr>\n" + " <td class=\"company_info\">{{text.companyUrl}}</td>\n" + " <td colspan=\"2\" />\n" + " </tr>\n" + " </table>\n" + "\n" + " <table id=\"invoice_items\">\n" + " <tr>\n" + " <th class=\"network\">{{text.invoiceItemBundleName}}</td>\n" + " <th>{{text.invoiceItemDescription}}</td>\n" + " <th>{{text.invoiceItemServicePeriod}}</td>\n" + " <th>{{text.invoiceItemAmount}}</td>\n" + " </tr>\n" + " {{#invoice.invoiceItems}}\n" + " <tr>\n" + " <td class=\"network\">{{description}}</td>\n" + " <td>{{planName}}</td>\n" + " <td>{{formattedStartDate}}{{#formattedEndDate}} - {{formattedEndDate}}{{/formattedEndDate}}</td>\n" + " <td class=\"amount\">{{formattedAmount}}</td>\n" + " </tr>\n" + " {{/invoice.invoiceItems}}\n" + " <tr>\n" + " <td colspan=\"4\" height=\"50px\"></td>\n" + " </tr>\n" + " <tr>\n" + " <td colspan=\"2\" />\n" + " <td class=\"label\">{{text.invoiceAmount}}</td>\n" + " <td class=\"amount\"><strong>{{invoice.formattedChargedAmount}}</strong></td>\n" + " </tr>\n" + " <tr>\n" + " <td colspan=\"2\" />\n" + " <td class=\"label\">{{text.invoiceAmountPaid}}" + " {{#invoice.processedCurrency}}" + " (*)" + " {{/invoice.processedCurrency}}\n" + " </td>\n" + " <td class=\"amount\"><strong>{{invoice.formattedPaidAmount}}</strong></td>\n" + " </tr>\n" + " <tr>\n" + " <td colspan=\"2\" />\n" + " <td class=\"label\">{{text.invoiceBalance}}</td>\n" + " <td class=\"amount\"><strong>{{invoice.formattedBalance}}</strong></td>\n" + " </tr>\n" + " </table>\n" + " {{#invoice.processedCurrency}}" + " {{text.processedPaymentCurrency}} {{invoice.processedCurrency}}." + " {{#invoice.processedPaymentRate}}\n" + " {{text.processedPaymentRate}} {{invoice.processedPaymentRate}}.\n" + " {{/invoice.processedPaymentRate}}" + " {{/invoice.processedCurrency}}" + " </body>\n" + "</html>\n";
final Map<String, Object> data = new HashMap<String, Object>();
final String bundlePath = "org/killbill/billing/util/template/translation/InvoiceTranslation";
final ResourceBundle bundle = resourceBundleFactory.createBundle(Locale.US, bundlePath, ResourceBundleType.INVOICE_TRANSLATION, internalCallContext);
final DefaultInvoiceTranslator translator = new DefaultInvoiceTranslator(bundle, null);
data.put("text", translator);
data.put("invoice", new DefaultInvoiceFormatter(config, invoice, Locale.US, currencyConversionApi, resourceBundleFactory, internalCallContext));
final String formattedText = templateEngine.executeTemplateText(template, data);
System.out.println(formattedText);
}
use of org.killbill.billing.invoice.model.FixedPriceInvoiceItem in project killbill by killbill.
the class TestInvoiceDao method testAccountBalanceWithAllSortsOfThings.
@Test(groups = "slow")
public void testAccountBalanceWithAllSortsOfThings() 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 amount1 = new BigDecimal("5.0");
final BigDecimal rate1 = new BigDecimal("20.0");
final BigDecimal rate2 = new BigDecimal("10.0");
// Fixed Item
final FixedPriceInvoiceItem item1 = new FixedPriceInvoiceItem(invoice1.getId(), accountId, bundleId, UUID.randomUUID(), "test product", "test plan", "test phase A", null, startDate, amount1, Currency.USD);
invoiceUtil.createInvoiceItem(item1, context);
BigDecimal balance = invoiceDao.getAccountBalance(accountId, context);
assertEquals(balance.compareTo(new BigDecimal("5.00")), 0);
// Recurring item
final RecurringInvoiceItem item2 = new RecurringInvoiceItem(invoice1.getId(), accountId, bundleId, UUID.randomUUID(), "test product", "test plan", "test phase B", null, startDate, endDate, rate1, rate1, Currency.USD);
invoiceUtil.createInvoiceItem(item2, context);
balance = invoiceDao.getAccountBalance(accountId, context);
assertEquals(balance.compareTo(new BigDecimal("25.00")), 0);
// Pay the whole thing
final BigDecimal payment1 = amount1.add(rate1);
final InvoicePayment payment = new DefaultInvoicePayment(InvoicePaymentType.ATTEMPT, UUID.randomUUID(), 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);
// Repair previous item with rate 2
final RepairAdjInvoiceItem item2Repair = new RepairAdjInvoiceItem(invoice1.getId(), accountId, startDate, endDate, rate1.negate(), Currency.USD, item2.getId());
final RecurringInvoiceItem item2Replace = new RecurringInvoiceItem(invoice1.getId(), accountId, bundleId, UUID.randomUUID(), "test product", "test plan", "test phase B", null, startDate, endDate, rate2, rate2, Currency.USD);
invoiceUtil.createInvoiceItem(item2Repair, context);
invoiceUtil.createInvoiceItem(item2Replace, context);
balance = invoiceDao.getAccountBalance(accountId, context);
assertEquals(balance.compareTo(new BigDecimal("-10.00")), 0);
// CBA
final CreditBalanceAdjInvoiceItem cbaItem = new CreditBalanceAdjInvoiceItem(invoice1.getId(), accountId, new LocalDate(), balance.negate(), Currency.USD);
invoiceUtil.createInvoiceItem(cbaItem, context);
balance = invoiceDao.getAccountBalance(accountId, context);
assertEquals(balance.compareTo(new BigDecimal("-10.00")), 0);
BigDecimal cba = invoiceDao.getAccountCBA(accountId, context);
assertEquals(cba.compareTo(new BigDecimal("10.00")), 0);
// partial REFUND on the payment (along with CBA generated by the system)
final InvoicePayment refund = new DefaultInvoicePayment(UUID.randomUUID(), InvoicePaymentType.ATTEMPT, UUID.randomUUID(), invoice1.getId(), new DateTime(), rate2.negate(), Currency.USD, Currency.USD, null, payment.getId());
invoiceUtil.createPayment(refund, context);
final CreditBalanceAdjInvoiceItem cbaItem2 = new CreditBalanceAdjInvoiceItem(invoice1.getId(), accountId, new LocalDate(), rate2.negate(), Currency.USD);
invoiceUtil.createInvoiceItem(cbaItem2, context);
balance = invoiceDao.getAccountBalance(accountId, context);
assertEquals(balance.compareTo(BigDecimal.ZERO), 0);
cba = invoiceDao.getAccountCBA(accountId, context);
assertEquals(cba.compareTo(BigDecimal.ZERO), 0);
// NEXT RECURRING on invoice 2
final Invoice invoice2 = new DefaultInvoice(accountId, clock.getUTCToday(), targetDate1.plusMonths(1), Currency.USD);
invoiceUtil.createInvoice(invoice2, context);
final RecurringInvoiceItem nextItem = new RecurringInvoiceItem(invoice2.getId(), accountId, bundleId, UUID.randomUUID(), "test product", "test plan", "test bla", null, startDate.plusMonths(1), endDate.plusMonths(1), rate2, rate2, Currency.USD);
invoiceUtil.createInvoiceItem(nextItem, context);
balance = invoiceDao.getAccountBalance(accountId, context);
assertEquals(balance.compareTo(new BigDecimal("10.00")), 0);
cba = invoiceDao.getAccountCBA(accountId, context);
assertEquals(cba.compareTo(new BigDecimal("0.00")), 0);
// FINALLY ISSUE A CREDIT ADJ
final CreditAdjInvoiceItem creditItem = new CreditAdjInvoiceItem(invoice2.getId(), accountId, new LocalDate(), null, rate2.negate(), Currency.USD, null);
invoiceUtil.createInvoiceItem(creditItem, context);
balance = invoiceDao.getAccountBalance(accountId, context);
assertEquals(balance.compareTo(new BigDecimal("0.00")), 0);
cba = invoiceDao.getAccountCBA(accountId, context);
assertEquals(cba.compareTo(new BigDecimal("0.00")), 0);
}
Aggregations