use of org.killbill.billing.invoice.api.InvoiceItem in project killbill by killbill.
the class UsageInvoiceItemGenerator method extractPerSubscriptionExistingInArrearUsageItems.
private Map<UUID, List<InvoiceItem>> extractPerSubscriptionExistingInArrearUsageItems(final Map<String, Usage> knownUsage, @Nullable final List<Invoice> existingInvoices) {
if (existingInvoices == null || existingInvoices.isEmpty()) {
return ImmutableMap.of();
}
final Map<UUID, List<InvoiceItem>> result = new HashMap<UUID, List<InvoiceItem>>();
final Iterable<InvoiceItem> usageInArrearItems = Iterables.concat(Iterables.transform(existingInvoices, new Function<Invoice, Iterable<InvoiceItem>>() {
@Override
public Iterable<InvoiceItem> apply(final Invoice input) {
return Iterables.filter(input.getInvoiceItems(), new Predicate<InvoiceItem>() {
@Override
public boolean apply(final InvoiceItem input) {
if (input.getInvoiceItemType() == InvoiceItemType.USAGE) {
final Usage usage = knownUsage.get(input.getUsageName());
return usage.getBillingMode() == BillingMode.IN_ARREAR;
}
return false;
}
});
}
}));
for (final InvoiceItem cur : usageInArrearItems) {
List<InvoiceItem> perSubscriptionUsageItems = result.get(cur.getSubscriptionId());
if (perSubscriptionUsageItems == null) {
perSubscriptionUsageItems = new LinkedList<InvoiceItem>();
result.put(cur.getSubscriptionId(), perSubscriptionUsageItems);
}
perSubscriptionUsageItems.add(cur);
}
return result;
}
use of org.killbill.billing.invoice.api.InvoiceItem in project killbill by killbill.
the class AccountItemTree method build.
/**
* build the subscription trees after they have been populated with existing items on disk
*/
public void build() {
Preconditions.checkState(!isBuilt);
if (pendingItemAdj.size() > 0) {
for (InvoiceItem item : pendingItemAdj) {
addExistingItem(item, true);
}
pendingItemAdj.clear();
}
for (SubscriptionItemTree tree : subscriptionItemTree.values()) {
tree.build();
}
isBuilt = true;
}
use of org.killbill.billing.invoice.api.InvoiceItem in project killbill by killbill.
the class AccountItemTree method addExistingItem.
private void addExistingItem(final InvoiceItem existingItem, final boolean failOnMissingSubscription) {
Preconditions.checkState(!isBuilt);
// Only used to retrieve the original item for linked items
allExistingItems.add(existingItem);
switch(existingItem.getInvoiceItemType()) {
case EXTERNAL_CHARGE:
case TAX:
case CBA_ADJ:
case CREDIT_ADJ:
case USAGE:
return;
case RECURRING:
case REPAIR_ADJ:
case FIXED:
case ITEM_ADJ:
break;
case PARENT_SUMMARY:
break;
default:
Preconditions.checkState(false, "Unknown invoice item type " + existingItem.getInvoiceItemType());
}
if (existingItem.getInvoiceItemType() == InvoiceItemType.ITEM_ADJ) {
final InvoiceItem linkedInvoiceItem = getLinkedInvoiceItem(existingItem, allExistingItems);
if (linkedInvoiceItem != null && linkedInvoiceItem.getInvoiceItemType() != InvoiceItemType.RECURRING && linkedInvoiceItem.getInvoiceItemType() != InvoiceItemType.FIXED) {
// (we assume that REPAIR_ADJ and ITEM_ADJ items cannot be adjusted)
return;
}
}
final UUID subscriptionId = getSubscriptionId(existingItem, allExistingItems);
Preconditions.checkState(subscriptionId != null || !failOnMissingSubscription, "Missing subscription id");
if (subscriptionId == null && existingItem.getInvoiceItemType() == InvoiceItemType.ITEM_ADJ) {
pendingItemAdj.add(existingItem);
return;
}
if (!subscriptionItemTree.containsKey(subscriptionId)) {
subscriptionItemTree.put(subscriptionId, new SubscriptionItemTree(subscriptionId, targetInvoiceId));
}
final SubscriptionItemTree tree = subscriptionItemTree.get(subscriptionId);
tree.addItem(existingItem);
}
use of org.killbill.billing.invoice.api.InvoiceItem in project killbill by killbill.
the class ItemsInterval method createNewItem.
/**
* Create a new item based on the existing items and new service period
* <p/>
* <ul>
* <li>During the build phase, we only consider ADD items. This happens when for instance an existing item was partially repaired
* and there is a need to create a new item which represents the part left -- that was not repaired.
* <li>During the merge phase, we create new items that are the missing repaired items (CANCEL).
* </ul>
*
* @param startDate start date of the new item to create
* @param endDate end date of the new item to create
* @param mergeMode mode to consider.
* @return new item for this service period or null
*/
private Item createNewItem(@Nullable final LocalDate startDate, @Nullable final LocalDate endDate, @Nullable final UUID targetInvoiceId, final boolean mergeMode) {
// Find the ADD (build phase) or CANCEL (merge phase) item of this interval
final Item item = getResultingItem(mergeMode);
if (item == null || startDate == null || endDate == null || targetInvoiceId == null) {
return item;
}
// Prorate (build phase) or repair (merge phase) this item, as needed
final InvoiceItem proratedInvoiceItem = item.toProratedInvoiceItem(startDate, endDate);
if (proratedInvoiceItem == null) {
return null;
} else {
// Keep track of the repaired amount for this item
item.incrementCurrentRepairedAmount(proratedInvoiceItem.getAmount().abs());
return new Item(proratedInvoiceItem, targetInvoiceId, item.getAction());
}
}
use of org.killbill.billing.invoice.api.InvoiceItem in project killbill by killbill.
the class ContiguousIntervalUsageInArrear method computeBilledUsage.
/**
* @param filteredUsageForInterval the list of invoiceItem to consider
* @return the price amount that was already billed for that period and usage section (across unitTypes)
*/
@VisibleForTesting
BigDecimal computeBilledUsage(final Iterable<InvoiceItem> filteredUsageForInterval) {
Preconditions.checkState(isBuilt.get());
BigDecimal billedAmount = BigDecimal.ZERO;
for (final InvoiceItem ii : filteredUsageForInterval) {
billedAmount = billedAmount.add(ii.getAmount());
}
// Return the billed $ amount (not the # of units)
return billedAmount;
}
Aggregations