BigDecimal sumBalance(final SortedSet<Invoice> unpaidInvoices) { BigDecimal sum = BigDecimal.ZERO; for (final Invoice unpaidInvoice : unpaidInvoices) { sum = sum.add(unpaidInvoice.getBalance()); } return sum; }
@Test(groups = "fast") public void testUnpaidInvoices() { final BillingStateCalculator calc = createBSCalc(); final SortedSet<Invoice> invoices = calc.unpaidInvoicesForAccount(new UUID(0L, 0L), internalCallContext); Assert.assertEquals(invoices.size(), 3); Assert.assertEquals(BigDecimal.ZERO.compareTo(invoices.first().getBalance()), 0); Assert.assertEquals(new BigDecimal("100.0").compareTo(invoices.last().getBalance()), 0); }
public Invoice createInvoice(final LocalDate date, final BigDecimal balance, final List<InvoiceItem> invoiceItems) { final Invoice invoice = Mockito.mock(Invoice.class); Mockito.when(invoice.getBalance()).thenReturn(balance); Mockito.when(invoice.getInvoiceDate()).thenReturn(date); Mockito.when(invoice.getInvoiceItems()).thenReturn(invoiceItems); Mockito.when(invoice.getId()).thenReturn(UUID.randomUUID()); return invoice; }
public Account createAccount(final LocalDate dateOfLastUnPaidInvoice) throws SubscriptionBaseApiException, AccountApiException { final UUID accountId = UUID.randomUUID(); final Account account = Mockito.mock(Account.class); Mockito.when(account.getId()).thenReturn(accountId); Mockito.when(account.getTimeZone()).thenReturn(DateTimeZone.UTC); Mockito.when(accountInternalApi.getAccountById(Mockito.eq(account.getId()), Mockito.<InternalTenantContext>any())).thenReturn(account); final Invoice invoice = Mockito.mock(Invoice.class); Mockito.when(invoice.getInvoiceDate()).thenReturn(dateOfLastUnPaidInvoice); Mockito.when(invoice.getBalance()).thenReturn(BigDecimal.TEN); Mockito.when(invoice.getStatus()).thenReturn(InvoiceStatus.COMMITTED); Mockito.when(invoice.getId()).thenReturn(UUID.randomUUID()); final InvoiceItem item = Mockito.mock(InvoiceItem.class); final List<InvoiceItem> items = new ArrayList<InvoiceItem>(); items.add(item); Mockito.when(invoice.getInvoiceItems()).thenReturn(items); final List<Invoice> invoices = new ArrayList<Invoice>(); invoices.add(invoice); Mockito.when(invoiceInternalApi.getUnpaidInvoicesByAccountId(Mockito.<UUID>any(), Mockito.<LocalDate>any(), Mockito.<InternalTenantContext>any())).thenReturn(invoices); final Tag tag = Mockito.mock(Tag.class); Mockito.when(tag.getObjectId()).thenReturn(accountId); Mockito.when(tag.getObjectType()).thenReturn(ObjectType.ACCOUNT); Mockito.when(tag.getTagDefinitionId()).thenReturn(ControlTagType.TEST.getId()); final List<Tag> tags = new ArrayList<Tag>(); tags.add(tag); Mockito.when(tagInternalApi.getTags(Mockito.eq(account.getId()), Mockito.eq(ObjectType.ACCOUNT), Mockito.<InternalTenantContext>any())) .thenReturn(tags); return account; }
BigDecimal sumBalance(final SortedSet<Invoice> unpaidInvoices) { BigDecimal sum = BigDecimal.ZERO; for (final Invoice unpaidInvoice : unpaidInvoices) { sum = sum.add(unpaidInvoice.getBalance()); } return sum; }
@Override public BigDecimal getBalance() { return MoreObjects.firstNonNull(invoice.getBalance(), BigDecimal.ZERO); }
public boolean hasZeroParentBalance() { return (parentInvoice != null) && (parentInvoice.getBalance().compareTo(BigDecimal.ZERO) == 0); }
public void processSubscriptionForInvoiceNotification(final UUID subscriptionId, final LocalDate targetDate, final InternalCallContext context) throws InvoiceApiException { final Invoice dryRunInvoice = processSubscriptionInternal(subscriptionId, targetDate, true, false, context); if (dryRunInvoice != null && dryRunInvoice.getBalance().compareTo(BigDecimal.ZERO) > 0) { final InvoiceNotificationInternalEvent event = new DefaultInvoiceNotificationInternalEvent(dryRunInvoice.getAccountId(), dryRunInvoice.getBalance(), dryRunInvoice.getCurrency(), context.toUTCDateTime(targetDate), context.getAccountRecordId(), context.getTenantRecordId(), context.getUserToken()); try { eventBus.post(event); } catch (EventBusException e) { log.warn("Failed to post event {}", event, e); } } }
@Test(groups = "slow") public void testAddRemoveWrittenOffTag() throws InvoiceApiException, TagApiException { final Invoice originalInvoice = invoiceUserApi.getInvoice(invoiceId, callContext); assertEquals(originalInvoice.getBalance().compareTo(BigDecimal.ZERO), 1); invoiceUserApi.tagInvoiceAsWrittenOff(invoiceId, callContext); List<Tag> tags = tagUserApi.getTagsForObject(invoiceId, ObjectType.INVOICE, false, callContext); assertEquals(tags.size(), 1); assertEquals(tags.get(0).getTagDefinitionId(), ControlTagType.WRITTEN_OFF.getId()); final Invoice invoiceWithTag = invoiceUserApi.getInvoice(invoiceId, callContext); assertEquals(invoiceWithTag.getBalance().compareTo(BigDecimal.ZERO), 0); invoiceUserApi.tagInvoiceAsNotWrittenOff(invoiceId, callContext); tags = tagUserApi.getTagsForObject(invoiceId, ObjectType.INVOICE, false, callContext); assertEquals(tags.size(), 0); final Invoice invoiceAfterTagRemoval = invoiceUserApi.getInvoice(invoiceId, callContext); assertEquals(invoiceAfterTagRemoval.getBalance().compareTo(BigDecimal.ZERO), 1); }
private Invoice createInvoice() { final LocalDate startDate = new LocalDate(new DateTime().minusMonths(1), DateTimeZone.UTC); final LocalDate endDate = new LocalDate(DateTimeZone.UTC); final BigDecimal price1 = new BigDecimal("29.95"); final BigDecimal price2 = new BigDecimal("59.95"); final Invoice dummyInvoice = Mockito.mock(Invoice.class); Mockito.when(dummyInvoice.getInvoiceDate()).thenReturn(startDate); Mockito.when(dummyInvoice.getInvoiceNumber()).thenReturn(42); Mockito.when(dummyInvoice.getCurrency()).thenReturn(Currency.USD); Mockito.when(dummyInvoice.getChargedAmount()).thenReturn(price1.add(price2)); Mockito.when(dummyInvoice.getPaidAmount()).thenReturn(BigDecimal.ZERO); Mockito.when(dummyInvoice.getBalance()).thenReturn(price1.add(price2)); final List<InvoiceItem> items = new ArrayList<InvoiceItem>(); items.add(createInvoiceItem(price1, "Domain 1", startDate, endDate, "ning-plus")); items.add(createInvoiceItem(price2, "Domain 2", startDate, endDate, "ning-pro")); Mockito.when(dummyInvoice.getInvoiceItems()).thenReturn(items); return dummyInvoice; }
protected Payment createPaymentAndCheckForCompletion(final Account account, final Invoice invoice, final NextEvent... events) { return createPaymentAndCheckForCompletion(account, invoice, invoice.getBalance(), invoice.getCurrency(), events); }
private void printDetailInvoice(final Invoice invoice) { log.info("-------------------- START DETAIL ----------------------"); log.info("Invoice " + invoice.getId() + ": BALANCE = " + invoice.getBalance() + ", CBA = " + invoice.getCreditedAmount() + ", CHARGE_AMOUNT = " + invoice.getChargedAmount() + ", ADJ_AMOUNT = " + invoice.getCreditedAmount()); for (final InvoiceItem cur : invoice.getInvoiceItems()) { log.info(cur.toString()); } log.info("-------------------- END DETAIL ----------------------"); } }
@Test(groups = "slow", description = "Verify invoice/account balance with migrated invoice. Verify account credit is not consumed and that invoice/account balance does not take into account migrated invoice.") public void testMigratedInvoiceWithAccountCredit() throws Exception { // Add credit on the account invoiceUserApi.insertCredit(accountId, BigDecimal.TEN, null, accountCurrency, true, null, null, null, callContext); final UUID invoiceId = invoiceUserApi.createMigrationInvoice(accountId, null, ImmutableList.<InvoiceItem>of(new FixedPriceInvoiceItem(UUID.randomUUID(), clock.getUTCNow(), null, accountId, null, null, null, "foo", "bar", null, null, BigDecimal.ONE, accountCurrency)), callContext); final Invoice invoice1 = invoiceUserApi.getInvoice(invoiceId, callContext); assertEquals(invoice1.getBalance().compareTo(BigDecimal.ZERO), 0); // Verify credit is **not applied** against migration invoice final BigDecimal accountBalance0 = invoiceUserApi.getAccountBalance(accountId, callContext); assertEquals(accountBalance0.compareTo(new BigDecimal("-10.0")), 0); final BigDecimal accountCBA0 = invoiceUserApi.getAccountCBA(accountId, callContext); assertEquals(accountCBA0.compareTo(BigDecimal.TEN), 0); }
@Test(groups = "slow") public void testRefundWithNoAdjustments() throws Exception { // Although we don't adjust the invoice, the invoicing system sends an event because invoice balance changes and overdue system-- in particular-- needs to know about it. refundPaymentAndCheckForCompletion(account, payment, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT); refundChecker.checkRefund(payment.getId(), callContext, new ExpectedRefundCheck(payment.getId(), false, new BigDecimal("233.82"), Currency.USD, initialCreationDate.toLocalDate())); final Invoice invoiceRefreshed = invoiceUserApi.getInvoice(invoice.getId(), callContext); assertTrue(invoiceRefreshed.getBalance().compareTo(new BigDecimal("233.82")) == 0); final BigDecimal accountBalance = invoiceUserApi.getAccountBalance(account.getId(), callContext); assertTrue(accountBalance.compareTo(new BigDecimal("233.82")) == 0); }
private void testInvoiceGeneration(final UUID accountId, final BillingEventSet events, final List<Invoice> existingInvoices, final LocalDate targetDate, final int expectedNumberOfItems, final BigDecimal expectedAmount) throws InvoiceApiException { final Currency currency = Currency.USD; final InvoiceWithMetadata invoiceWithMetadata = generator.generateInvoice(account, events, existingInvoices, null, targetDate, currency, internalCallContext); final Invoice invoice = invoiceWithMetadata.getInvoice(); assertNotNull(invoice); assertEquals(invoice.getNumberOfItems(), expectedNumberOfItems); existingInvoices.add(invoice); distributeItems(existingInvoices); assertEquals(invoice.getBalance(), KillBillMoney.of(expectedAmount, invoice.getCurrency())); }
private void verifyExternalChargeOnNewInvoice(final BigDecimal initialAccountBalance, @Nullable final UUID bundleId, final BigDecimal externalChargeAmount, final InvoiceItem externalChargeInvoiceItem) throws InvoiceApiException { Assert.assertNotNull(externalChargeInvoiceItem.getInvoiceId()); Assert.assertNotEquals(externalChargeInvoiceItem.getInvoiceId(), invoiceId); Assert.assertEquals(externalChargeInvoiceItem.getBundleId(), bundleId); Assert.assertEquals(externalChargeInvoiceItem.getInvoiceItemType(), InvoiceItemType.EXTERNAL_CHARGE); Assert.assertEquals(externalChargeInvoiceItem.getAccountId(), accountId); Assert.assertEquals(externalChargeInvoiceItem.getAmount().compareTo(externalChargeAmount), 0); Assert.assertEquals(externalChargeInvoiceItem.getCurrency(), accountCurrency); Assert.assertNull(externalChargeInvoiceItem.getLinkedItemId()); // Verify the adjusted invoice balance final BigDecimal adjustedInvoiceBalance = invoiceUserApi.getInvoice(externalChargeInvoiceItem.getInvoiceId(), callContext).getBalance(); Assert.assertEquals(adjustedInvoiceBalance.compareTo(externalChargeAmount), 0); // Verify the adjusted account balance final BigDecimal adjustedAccountBalance = invoiceUserApi.getAccountBalance(accountId, callContext); Assert.assertEquals(adjustedAccountBalance, initialAccountBalance.add(externalChargeAmount)); }
@Test(groups = "slow") public void testVoidInvoiceThatIsPaid() throws Exception { InternalCallContext context = internalCallContextFactory.createInternalCallContext(accountId, callContext); // Verify the initial invoice balance final BigDecimal invoiceBalance = invoiceUserApi.getInvoice(invoiceId, callContext).getBalance(); Assert.assertEquals(invoiceBalance.compareTo(BigDecimal.ZERO), 1); // Verify the initial account balance final BigDecimal accountBalance = invoiceUserApi.getAccountBalance(accountId, callContext); Assert.assertEquals(accountBalance, invoiceBalance); // create payment final InvoicePayment payment = new DefaultInvoicePayment(InvoicePaymentType.ATTEMPT, UUID.randomUUID(), invoiceId, new DateTime(), invoiceBalance, Currency.USD, Currency.USD, null, true); invoiceUtil.createPayment(payment, context); // try to void invoice, it should fail try { invoiceUserApi.voidInvoice(invoiceId, callContext); Assert.fail("Should fail to void invoice that is already paid"); } catch (final InvoiceApiException e) { Assert.assertEquals(e.getCode(), ErrorCode.CAN_NOT_VOID_INVOICE_THAT_IS_PAID.getCode()); } } }
private void verifyRefund(final Invoice invoice, final BigDecimal invoiceAmount, final BigDecimal refundAmount, final BigDecimal finalInvoiceAmount, final boolean adjusted, final Map<UUID, BigDecimal> invoiceItemIdsWithAmounts) throws InvoiceApiException { final InvoicePayment payment = createAndPersistPayment(invoiceInternalApi, clock, invoice.getId(), invoiceAmount, CURRENCY, internalCallContext); // Verify the initial invoice balance final BigDecimal initialInvoiceBalance = invoiceInternalApi.getInvoiceById(invoice.getId(), internalCallContext).getBalance(); Assert.assertEquals(initialInvoiceBalance.compareTo(BigDecimal.ZERO), 0); // Create a full refund with no adjustment final InvoicePayment refund = invoiceInternalApi.recordRefund(payment.getPaymentId(), refundAmount, adjusted, invoiceItemIdsWithAmounts, UUID.randomUUID().toString(), internalCallContext); Assert.assertEquals(refund.getAmount().compareTo(refundAmount.negate()), 0); Assert.assertEquals(refund.getCurrency(), CURRENCY); Assert.assertEquals(refund.getInvoiceId(), invoice.getId()); Assert.assertEquals(refund.getPaymentId(), payment.getPaymentId()); Assert.assertEquals(refund.getType(), InvoicePaymentType.REFUND); // Verify the current invoice balance final BigDecimal newInvoiceBalance = invoiceInternalApi.getInvoiceById(invoice.getId(), internalCallContext).getBalance(); Assert.assertEquals(newInvoiceBalance.compareTo(finalInvoiceAmount), 0); } }
public InvoiceJson(final Invoice input, final String bundleKeys, final List<CreditJson> credits, final List<AuditLog> auditLogs) { this(input.getChargedAmount(), input.getCurrency(), input.getStatus(), input.getCreditedAmount(), input.getRefundedAmount(), input.getId(), input.getInvoiceDate(), input.getTargetDate(), String.valueOf(input.getInvoiceNumber()), input.getBalance(), input.getAccountId(), bundleKeys, credits, null, input.isParentInvoice(), input.getParentInvoiceId(), input.getParentAccountId(), toAuditLogJson(auditLogs)); }
@Test(groups = "fast") public void testWithSingleMonthlyEventWithLeadingProRation() throws InvoiceApiException, CatalogApiException { final BillingEventSet events = new MockBillingEventSet(); final SubscriptionBase sub = createSubscription(); final LocalDate startDate = invoiceUtil.buildDate(2011, 9, 1); final Plan plan = new MockPlan(); final BigDecimal rate = TEN; final PlanPhase phase = createMockMonthlyPlanPhase(rate); final BillingEvent event = createBillingEvent(sub.getId(), sub.getBundleId(), startDate, plan, phase, 15); events.add(event); final LocalDate targetDate = invoiceUtil.buildDate(2011, 10, 3); final InvoiceWithMetadata invoiceWithMetadata = generator.generateInvoice(account, events, null, null, targetDate, Currency.USD, internalCallContext); final Invoice invoice = invoiceWithMetadata.getInvoice(); assertNotNull(invoice); assertEquals(invoice.getNumberOfItems(), 2); final BigDecimal expectedNumberOfBillingCycles; expectedNumberOfBillingCycles = ONE.add(FOURTEEN.divide(THIRTY_ONE, KillBillMoney.ROUNDING_METHOD)); final BigDecimal expectedAmount = KillBillMoney.of(expectedNumberOfBillingCycles.multiply(rate), invoice.getCurrency()); assertEquals(invoice.getBalance(), expectedAmount); }