BigDecimal sumBalance(final SortedSet<Invoice> unpaidInvoices) { BigDecimal sum = BigDecimal.ZERO; for (final Invoice unpaidInvoice : unpaidInvoices) { sum = sum.add(unpaidInvoice.getBalance()); } return sum; }
@Override public int compare(final Invoice i1, final Invoice i2) { final LocalDate d1 = i1.getInvoiceDate(); final LocalDate d2 = i2.getInvoiceDate(); if (d1.compareTo(d2) == 0) { return i1.hashCode() - i2.hashCode(); // consistent (arbitrary) resolution for tied dates } return d1.compareTo(d2); } }
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; }
public static boolean isCharge(final InvoiceItem invoiceItem) { return InvoiceItemType.TAX.equals(invoiceItem.getInvoiceItemType()) || InvoiceItemType.EXTERNAL_CHARGE.equals(invoiceItem.getInvoiceItemType()) || InvoiceItemType.FIXED.equals(invoiceItem.getInvoiceItemType()) || InvoiceItemType.USAGE.equals(invoiceItem.getInvoiceItemType()) || InvoiceItemType.RECURRING.equals(invoiceItem.getInvoiceItemType()); }
public BillingState calculateBillingState(final ImmutableAccountData account, final InternalCallContext context) throws OverdueException { final SortedSet<Invoice> unpaidInvoices = unpaidInvoicesForAccount(account.getId(), context); final int numberOfUnpaidInvoices = unpaidInvoices.size(); final BigDecimal unpaidInvoiceBalance = sumBalance(unpaidInvoices); LocalDate dateOfEarliestUnpaidInvoice = null; UUID idOfEarliestUnpaidInvoice = null; final Invoice invoice = earliest(unpaidInvoices); if (invoice != null) { dateOfEarliestUnpaidInvoice = invoice.getInvoiceDate(); idOfEarliestUnpaidInvoice = invoice.getId(); } final PaymentResponse responseForLastFailedPayment = PaymentResponse.INSUFFICIENT_FUNDS; //TODO MDW final List<Tag> accountTags = tagApi.getTags(account.getId(), ObjectType.ACCOUNT, context); final Tag[] tags = accountTags.toArray(new Tag[accountTags.size()]); return new BillingState(account.getId(), numberOfUnpaidInvoices, unpaidInvoiceBalance, dateOfEarliestUnpaidInvoice, idOfEarliestUnpaidInvoice, responseForLastFailedPayment, tags); }
@Override public boolean apply(final InvoiceItem input) { return input.getInvoiceItemType() == InvoiceItemType.EXTERNAL_CHARGE; } }).orNull();
final TenantContext tenantContext, final InternalTenantContext context) throws SubscriptionBaseApiException, CatalogApiException { if (dryRunArguments == null || dryRunArguments.getAction() == null) { return; final EntitlementSpecifier entitlementSpecifier = dryRunArguments.getEntitlementSpecifier(); final PlanPhaseSpecifier inputSpec = entitlementSpecifier.getPlanPhaseSpecifier(); final boolean isInputSpecNullOrEmpty = inputSpec == null || switch (dryRunArguments.getAction()) { case START_BILLING: final SubscriptionBase baseSubscription = dao.getBaseSubscription(bundleId, catalog, context); final DateTime startEffectiveDate = dryRunArguments.getEffectiveDate() != null ? context.toUTCDateTime(dryRunArguments.getEffectiveDate()) : utcNow; final DateTime bundleStartDate = getBundleStartDateWithSanity(bundleId, baseSubscription, plan, startEffectiveDate, addonUtils, context); final UUID subscriptionId = UUIDs.randomUUID(); final DefaultSubscriptionBase subscriptionForChange = (DefaultSubscriptionBase) dao.getSubscriptionFromId(dryRunArguments.getSubscriptionId(), catalog, context); DateTime changeEffectiveDate = getDryRunEffectiveDate(dryRunArguments.getEffectiveDate(), subscriptionForChange, context); if (changeEffectiveDate == null) { BillingActionPolicy policy = dryRunArguments.getBillingActionPolicy(); if (policy == null) { final PlanChangeResult planChangeResult = apiService.getPlanChangeResult(subscriptionForChange, inputSpec, utcNow, tenantContext); final DefaultSubscriptionBase subscriptionForCancellation = (DefaultSubscriptionBase) dao.getSubscriptionFromId(dryRunArguments.getSubscriptionId(), catalog, context); DateTime cancelEffectiveDate = getDryRunEffectiveDate(dryRunArguments.getEffectiveDate(), subscriptionForCancellation, context); if (dryRunArguments.getEffectiveDate() == null) { BillingActionPolicy policy = dryRunArguments.getBillingActionPolicy();
@Override public Comparable apply(final InvoiceItem invoiceItem) { return invoiceItem.getEndDate(); } });
@Override public UUID apply(final InvoicePayment input) { return input.getPaymentId(); } }));
SortedSet<Invoice> unpaidInvoicesForAccount(final UUID accountId, final InternalCallContext context) { final Collection<Invoice> invoices = invoiceApi.getUnpaidInvoicesByAccountId(accountId, context.toLocalDate(context.getCreatedDate()), context); final SortedSet<Invoice> sortedInvoices = new TreeSet<Invoice>(new InvoiceDateComparator()); sortedInvoices.addAll(invoices); return sortedInvoices; } }
@Override public boolean apply(final InvoiceItem input) { return input.matches(invoiceItem); } }).orNull();
@Override public boolean apply(final InvoiceItem invoiceItem) { return InvoiceItemType.ITEM_ADJ.equals(invoiceItem.getInvoiceItemType()); } });
@Test(groups = "fast") public void testEarliest() { final BillingStateCalculator calc = createBSCalc(); final SortedSet<Invoice> invoices = calc.unpaidInvoicesForAccount(new UUID(0L, 0L), internalCallContext); Assert.assertEquals(calc.earliest(invoices).getInvoiceDate(), now); } }
@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); }
@Override public boolean apply(final InvoiceItem input) { return input.getInvoiceItemType() == InvoiceItemType.ITEM_ADJ; } }).orNull();
public BillingStateCalculator createBSCalc() { now = new LocalDate(); final Collection<Invoice> invoices = new ArrayList<Invoice>(); invoices.add(createInvoice(now, BigDecimal.ZERO, null)); invoices.add(createInvoice(now.plusDays(1), BigDecimal.TEN, null)); invoices.add(createInvoice(now.plusDays(2), new BigDecimal("100.0"), null)); Mockito.when(invoiceApi.getUnpaidInvoicesByAccountId(Mockito.<UUID>any(), Mockito.<LocalDate>any(), Mockito.<InternalTenantContext>any())).thenReturn(invoices); return new BillingStateCalculator(invoiceApi, clock, tagInternalApi) { @Override public BillingState calculateBillingState(final ImmutableAccountData overdueable, final InternalCallContext context) { return null; } }; }
protected boolean isTaxItem(final InvoiceItem invoiceItem) { return InvoiceItemType.TAX.equals(invoiceItem.getInvoiceItemType()); }
public static boolean isParentSummaryItem(final InvoiceItem invoiceItem) { return InvoiceItemType.PARENT_SUMMARY.equals(invoiceItem.getInvoiceItemType()); }
@Override public boolean apply(final InvoiceItem input) { return InvoiceItemType.RECURRING.equals(input.getInvoiceItemType()); } });