/** * Adjust the invoice with a CBA item if the new invoice balance is negative. * * @param entitySqlDaoWrapperFactory the EntitySqlDaoWrapperFactory from the current transaction * @param invoice the invoice to adjust * @param context the call callcontext */ private void addCBAIfNeeded(final EntitySqlDaoWrapperFactory<EntitySqlDao> entitySqlDaoWrapperFactory, final InvoiceModelDao invoice, final InternalCallContext context) throws EntityPersistenceException { // If invoice balance becomes negative we add some CBA item final BigDecimal balance = InvoiceModelDaoHelper.getBalance(invoice); if (balance.compareTo(BigDecimal.ZERO) < 0) { final InvoiceItemSqlDao transInvoiceItemDao = entitySqlDaoWrapperFactory.become(InvoiceItemSqlDao.class); final InvoiceItemModelDao cbaAdjItem = new InvoiceItemModelDao(new CreditBalanceAdjInvoiceItem(invoice.getId(), invoice.getAccountId(), context.getCreatedDate().toLocalDate(), balance.negate(), invoice.getCurrency())); transInvoiceItemDao.create(cbaAdjItem, context); } }
@Override public String getDescription() { final String secondDescription; if (getAmount().compareTo(BigDecimal.ZERO) >= 0) { secondDescription = "account credit"; } else { secondDescription = "use of account credit"; } return String.format("Adjustment (%s)", secondDescription); } }
BigDecimal.TEN.negate(), invoice1.getCurrency(), UUID.randomUUID()); final CreditBalanceAdjInvoiceItem creditBalanceAdjInvoiceItem1 = new CreditBalanceAdjInvoiceItem(invoice1.getId(), invoice1.getAccountId(), invoice1.getInvoiceDate(), repairAdjInvoiceItem.getAmount().negate(), invoice1.getCurrency()); invoiceDao.deleteCBA(accountId, invoice1.getId(), creditBalanceAdjInvoiceItem1.getId(), context); Assert.fail(); } catch (InvoiceApiException e) {
fixedItem1.getAmount().negate(), fixedItem1.getCurrency(), fixedItem1.getId()); final CreditBalanceAdjInvoiceItem creditBalanceAdjInvoiceItem1 = new CreditBalanceAdjInvoiceItem(fixedItem1.getInvoiceId(), fixedItem1.getAccountId(), fixedItem1.getStartDate(), fixedItem1.getAmount(), fixedItem1.getCurrency()); invoiceDao.deleteCBA(accountId, invoice1.getId(), creditBalanceAdjInvoiceItem1.getId(), context);
private void useExistingCBAFromTransaction(final List<InvoiceModelDao> invoices, final EntitySqlDaoWrapperFactory<EntitySqlDao> entitySqlDaoWrapperFactory, final InternalCallContext context) throws InvoiceApiException, EntityPersistenceException { final BigDecimal accountCBA = getAccountCBAFromTransaction(invoices); if (accountCBA.compareTo(BigDecimal.ZERO) <= 0) { return; } final List<InvoiceModelDao> unpaidInvoices = invoiceDaoHelper.getUnpaidInvoicesByAccountFromTransaction(invoices, null); // We order the same os BillingStateCalculator-- should really share the comparator final List<InvoiceModelDao> orderedUnpaidInvoices = Ordering.from(new Comparator<InvoiceModelDao>() { @Override public int compare(final InvoiceModelDao i1, final InvoiceModelDao i2) { return i1.getInvoiceDate().compareTo(i2.getInvoiceDate()); } }).immutableSortedCopy(unpaidInvoices); BigDecimal remainingAccountCBA = accountCBA; for (InvoiceModelDao cur : orderedUnpaidInvoices) { final BigDecimal curInvoiceBalance = InvoiceModelDaoHelper.getBalance(cur); final BigDecimal cbaToApplyOnInvoice = remainingAccountCBA.compareTo(curInvoiceBalance) <= 0 ? remainingAccountCBA : curInvoiceBalance; remainingAccountCBA = remainingAccountCBA.subtract(cbaToApplyOnInvoice); final InvoiceItemModelDao cbaAdjItem = new InvoiceItemModelDao(new CreditBalanceAdjInvoiceItem(cur.getId(), cur.getAccountId(), context.getCreatedDate().toLocalDate(), cbaToApplyOnInvoice.negate(), cur.getCurrency())); final InvoiceItemSqlDao transInvoiceItemDao = entitySqlDaoWrapperFactory.become(InvoiceItemSqlDao.class); transInvoiceItemDao.create(cbaAdjItem, context); if (remainingAccountCBA.compareTo(BigDecimal.ZERO) <= 0) { break; } } }
private InvoiceItem mergeCBAItem(final List<InvoiceItem> invoiceItems, InvoiceItem mergedCBAItem, final InvoiceItem item) { if (mergedCBAItem == null) { mergedCBAItem = item; } else { // This is really just to be safe - they should always have the same currency if (!mergedCBAItem.getCurrency().equals(item.getCurrency())) { invoiceItems.add(item); } else { mergedCBAItem = new CreditBalanceAdjInvoiceItem(invoice.getId(), invoice.getAccountId(), invoice.getInvoiceDate(), mergedCBAItem.getAmount().add(item.getAmount()), mergedCBAItem.getCurrency()); } } return mergedCBAItem; }
@Test(groups = "slow") public void testCreditBalanceInvoiceSqlDao() throws EntityPersistenceException { final UUID invoiceId = UUID.randomUUID(); final UUID accountId = account.getId(); final LocalDate creditDate = new LocalDate(2012, 4, 1); final InvoiceItem creditInvoiceItem = new CreditBalanceAdjInvoiceItem(invoiceId, accountId, creditDate, TEN, Currency.USD); invoiceUtil.createInvoiceItem(creditInvoiceItem, context); final InvoiceItemModelDao savedItem = invoiceUtil.getInvoiceItemById(creditInvoiceItem.getId(), context); assertSameInvoiceItem(creditInvoiceItem, savedItem); }
@Test(groups = "fast") public void testIgnoreZeroAdjustments() throws Exception { // Scenario: single item with payment // * $10 item // * $-10 CBA // * $10 CBA final FixedPriceInvoiceItem fixedItem = new FixedPriceInvoiceItem(UUID.randomUUID(), UUID.randomUUID(), null, null, UUID.randomUUID().toString(), UUID.randomUUID().toString(), new LocalDate(), BigDecimal.TEN, Currency.USD); final CreditBalanceAdjInvoiceItem creditBalanceAdjInvoiceItem = new CreditBalanceAdjInvoiceItem(fixedItem.getInvoiceId(), fixedItem.getAccountId(), fixedItem.getStartDate(), fixedItem.getAmount(), fixedItem.getCurrency()); final CreditBalanceAdjInvoiceItem creditBalanceAdjInvoiceItem2 = new CreditBalanceAdjInvoiceItem(fixedItem.getInvoiceId(), fixedItem.getAccountId(), fixedItem.getStartDate(), fixedItem.getAmount().negate(), fixedItem.getCurrency()); final Invoice invoice = new DefaultInvoice(fixedItem.getInvoiceId(), fixedItem.getAccountId(), null, new LocalDate(), new LocalDate(), Currency.USD, false); invoice.addInvoiceItem(fixedItem); invoice.addInvoiceItem(creditBalanceAdjInvoiceItem); invoice.addInvoiceItem(creditBalanceAdjInvoiceItem2); // Check the scenario Assert.assertEquals(invoice.getBalance().doubleValue(), 10.00); Assert.assertEquals(invoice.getCreditedAmount().doubleValue(), 0.00); // Verify the merge final InvoiceFormatter formatter = new DefaultInvoiceFormatter(config, invoice, Locale.US, null); final List<InvoiceItem> invoiceItems = formatter.getInvoiceItems(); Assert.assertEquals(invoiceItems.size(), 1); Assert.assertEquals(invoiceItems.get(0).getInvoiceItemType(), InvoiceItemType.FIXED); Assert.assertEquals(invoiceItems.get(0).getAmount().doubleValue(), 10.00); }
invoiceUtil.createInvoiceItem(repairItem, context); final InvoiceItem cbaItem = new CreditBalanceAdjInvoiceItem(invoice.getId(), accountId, startDate, amount, Currency.USD); invoiceUtil.createInvoiceItem(cbaItem, context);
final CreditBalanceAdjInvoiceItem cbaItem = new CreditBalanceAdjInvoiceItem(invoice1.getId(), accountId, new LocalDate(), balance.negate(), Currency.USD); invoiceUtil.createInvoiceItem(cbaItem, context); balance = invoiceDao.getAccountBalance(accountId, context);
final CreditBalanceAdjInvoiceItem cbaItem = new CreditBalanceAdjInvoiceItem(invoice1.getId(), accountId, new LocalDate(), balance.negate(), Currency.USD); invoiceUtil.createInvoiceItem(cbaItem, context); balance = invoiceDao.getAccountBalance(accountId, context); 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);
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(), BigDecimal.ONE.negate(), fixedItem.getCurrency()); final CreditBalanceAdjInvoiceItem creditBalanceAdjInvoiceItem2 = new CreditBalanceAdjInvoiceItem(fixedItem.getInvoiceId(), fixedItem.getAccountId(), fixedItem.getStartDate(), creditAdjInvoiceItem.getAmount().negate(), fixedItem.getCurrency());
fixedItem1.getAmount().negate(), fixedItem1.getCurrency(), fixedItem1.getId()); final CreditBalanceAdjInvoiceItem creditBalanceAdjInvoiceItem1 = new CreditBalanceAdjInvoiceItem(fixedItem1.getInvoiceId(), fixedItem1.getAccountId(), fixedItem1.getStartDate(), fixedItem1.getAmount(), fixedItem1.getCurrency()); 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());
fixedItem1.getAmount().negate(), fixedItem1.getCurrency(), fixedItem1.getId()); final CreditBalanceAdjInvoiceItem creditBalanceAdjInvoiceItem1 = new CreditBalanceAdjInvoiceItem(fixedItem1.getInvoiceId(), fixedItem1.getAccountId(), fixedItem1.getStartDate(), fixedItem1.getAmount(), fixedItem1.getCurrency()); 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()); 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());
break; case CBA_ADJ: item = new CreditBalanceAdjInvoiceItem(id, createdDate, invoiceId, accountId, startDate, linkedItemId, amount, currency); break; case CREDIT_ADJ: