killbill-memoizeit
Changes
invoice/src/main/java/org/killbill/billing/invoice/generator/FixedAndRecurringInvoiceItemGenerator.java 16(+3 -13)
invoice/src/main/java/org/killbill/billing/invoice/generator/UsageInvoiceItemGenerator.java 9(+3 -6)
invoice/src/main/java/org/killbill/billing/invoice/usage/ContiguousIntervalConsumableInArrear.java 71(+31 -40)
Details
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/generator/FixedAndRecurringInvoiceItemGenerator.java b/invoice/src/main/java/org/killbill/billing/invoice/generator/FixedAndRecurringInvoiceItemGenerator.java
index f8787d7..55106c2 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/generator/FixedAndRecurringInvoiceItemGenerator.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/generator/FixedAndRecurringInvoiceItemGenerator.java
@@ -48,12 +48,10 @@ import org.killbill.billing.invoice.tree.AccountItemTree;
import org.killbill.billing.junction.BillingEvent;
import org.killbill.billing.junction.BillingEventSet;
import org.killbill.billing.util.currency.KillBillMoney;
-import org.killbill.clock.Clock;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.annotations.VisibleForTesting;
-import com.google.inject.Inject;
import static org.killbill.billing.invoice.generator.InvoiceDateUtils.calculateNumberOfWholeBillingPeriods;
import static org.killbill.billing.invoice.generator.InvoiceDateUtils.calculateProRationAfterLastBillingCycleDate;
@@ -63,16 +61,9 @@ public class FixedAndRecurringInvoiceItemGenerator extends InvoiceItemGenerator
private static final Logger log = LoggerFactory.getLogger(FixedAndRecurringInvoiceItemGenerator.class);
- private final Clock clock;
-
- @Inject
- public FixedAndRecurringInvoiceItemGenerator(final Clock clock) {
- this.clock = clock;
- }
-
public List<InvoiceItem> generateItems(final ImmutableAccountData account, final UUID invoiceId, final BillingEventSet eventSet,
@Nullable final List<Invoice> existingInvoices, final LocalDate targetDate,
- final Currency targetCurrency, Map<UUID, SubscriptionFutureNotificationDates> perSubscriptionFutureNotificationDate,
+ final Currency targetCurrency, final Map<UUID, SubscriptionFutureNotificationDates> perSubscriptionFutureNotificationDate,
final InternalCallContext internalCallContext) throws InvoiceApiException {
final AccountItemTree accountItemTree = new AccountItemTree(account.getId(), invoiceId);
if (existingInvoices != null) {
@@ -196,7 +187,7 @@ public class FixedAndRecurringInvoiceItemGenerator extends InvoiceItemGenerator
final RecurringInvoiceItemDataWithNextBillingCycleDate itemDataWithNextBillingCycleDate;
try {
itemDataWithNextBillingCycleDate = generateInvoiceItemData(startDate, endDate, targetDate, billCycleDayLocal, billingPeriod, billingMode);
- } catch (InvalidDateSequenceException e) {
+ } catch (final InvalidDateSequenceException e) {
throw new InvoiceApiException(ErrorCode.INVOICE_INVALID_DATE_SEQUENCE, startDate, endDate, targetDate);
}
for (final RecurringInvoiceItemData itemDatum : itemDataWithNextBillingCycleDate.getItemData()) {
@@ -228,7 +219,6 @@ public class FixedAndRecurringInvoiceItemGenerator extends InvoiceItemGenerator
// For debugging purposes
invoiceItemGeneratorLogger.append(thisEvent, items);
-
return items;
} catch (final CatalogApiException e) {
throw new InvoiceApiException(e);
@@ -332,7 +322,7 @@ public class FixedAndRecurringInvoiceItemGenerator extends InvoiceItemGenerator
for (int i = 0; i < numberOfWholeBillingPeriods; i++) {
final LocalDate servicePeriodStartDate;
- if (results.size() > 0) {
+ if (!results.isEmpty()) {
// Make sure the periods align, especially with the pro-ration calculations above
servicePeriodStartDate = results.get(results.size() - 1).getEndDate();
} else if (i == 0) {
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/generator/UsageInvoiceItemGenerator.java b/invoice/src/main/java/org/killbill/billing/invoice/generator/UsageInvoiceItemGenerator.java
index f7b22d7..850b8a6 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/generator/UsageInvoiceItemGenerator.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/generator/UsageInvoiceItemGenerator.java
@@ -142,16 +142,14 @@ public class UsageInvoiceItemGenerator extends InvoiceItemGenerator {
invoiceItemGeneratorLogger.logItems();
return items;
- } catch (CatalogApiException e) {
+ } catch (final CatalogApiException e) {
throw new InvoiceApiException(e);
}
}
private LocalDate getMinBillingEventDate(final BillingEventSet eventSet, final InternalCallContext internalCallContext) {
DateTime minDate = null;
- final Iterator<BillingEvent> events = eventSet.iterator();
- while (events.hasNext()) {
- final BillingEvent cur = events.next();
+ for (final BillingEvent cur : eventSet) {
if (minDate == null || minDate.compareTo(cur.getEffectiveDate()) > 0) {
minDate = cur.getEffectiveDate();
}
@@ -175,7 +173,6 @@ public class UsageInvoiceItemGenerator extends InvoiceItemGenerator {
}
private Map<UUID, List<InvoiceItem>> extractPerSubscriptionExistingConsumableInArrearUsageItems(final Map<String, Usage> knownUsage, @Nullable final List<Invoice> existingInvoices) {
-
if (existingInvoices == null || existingInvoices.isEmpty()) {
return ImmutableMap.of();
}
@@ -198,7 +195,7 @@ public class UsageInvoiceItemGenerator extends InvoiceItemGenerator {
}
}));
- for (InvoiceItem cur : usageConsumableInArrearItems) {
+ for (final InvoiceItem cur : usageConsumableInArrearItems) {
List<InvoiceItem> perSubscriptionUsageItems = result.get(cur.getSubscriptionId());
if (perSubscriptionUsageItems == null) {
perSubscriptionUsageItems = new LinkedList<InvoiceItem>();
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/usage/ContiguousIntervalConsumableInArrear.java b/invoice/src/main/java/org/killbill/billing/invoice/usage/ContiguousIntervalConsumableInArrear.java
index 785b05e..65f5449 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/usage/ContiguousIntervalConsumableInArrear.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/usage/ContiguousIntervalConsumableInArrear.java
@@ -105,7 +105,6 @@ public class ContiguousIntervalConsumableInArrear {
*
* @param closedInterval whether there was a last billing event referencing the usage section or whether this is ongoing and
* then targetDate will define the endDate.
- * @return
*/
public ContiguousIntervalConsumableInArrear build(final boolean closedInterval) {
@@ -143,30 +142,10 @@ public class ContiguousIntervalConsumableInArrear {
return this;
}
- public class ConsumableInArrearItemsAndNextNotificationDate {
- private final List<InvoiceItem> invoiceItems;
- private final LocalDate nextNotificationDate;
-
- public ConsumableInArrearItemsAndNextNotificationDate(final List<InvoiceItem> invoiceItems, final LocalDate nextNotificationDate) {
- this.invoiceItems = invoiceItems;
- this.nextNotificationDate = nextNotificationDate;
- }
-
- public List<InvoiceItem> getInvoiceItems() {
- return invoiceItems;
- }
-
- public LocalDate getNextNotificationDate() {
- return nextNotificationDate;
- }
- }
-
-
/**
* Compute the missing usage invoice items based on what should be billed and what has been billed ($ amount comparison).
*
* @param existingUsage existing on disk usage items for the subscription
- * @return
* @throws CatalogApiException
*/
public ConsumableInArrearItemsAndNextNotificationDate computeMissingItemsAndNextNotificationDate(final List<InvoiceItem> existingUsage) throws CatalogApiException {
@@ -183,10 +162,10 @@ public class ContiguousIntervalConsumableInArrear {
// We start by generating 'marker' USAGE items with $0 that will allow to correctly insert the next notification for when there is no USAGE to bill.
// Those will be removed by the invoicing code later so as to not end up with superfluous $0 items
LocalDate prevDate = null;
- for (LocalDate curDate : transitionTimes) {
+ for (final LocalDate curDate : transitionTimes) {
if (prevDate != null) {
- InvoiceItem item = new UsageInvoiceItem(invoiceId, accountId, getBundleId(), getSubscriptionId(), getPlanName(),
- getPhaseName(), usage.getName(), prevDate, curDate, BigDecimal.ZERO, getCurrency());
+ final InvoiceItem item = new UsageInvoiceItem(invoiceId, accountId, getBundleId(), getSubscriptionId(), getPlanName(),
+ getPhaseName(), usage.getName(), prevDate, curDate, BigDecimal.ZERO, getCurrency());
result.add(item);
}
prevDate = curDate;
@@ -213,8 +192,8 @@ public class ContiguousIntervalConsumableInArrear {
if (!billedItems.iterator().hasNext() || billedUsage.compareTo(toBeBilledUsage) < 0) {
final BigDecimal amountToBill = toBeBilledUsage.subtract(billedUsage);
if (amountToBill.compareTo(BigDecimal.ZERO) > 0) {
- InvoiceItem item = new UsageInvoiceItem(invoiceId, accountId, getBundleId(), getSubscriptionId(), getPlanName(),
- getPhaseName(), usage.getName(), ru.getStart(), ru.getEnd(), amountToBill, getCurrency());
+ final InvoiceItem item = new UsageInvoiceItem(invoiceId, accountId, getBundleId(), getSubscriptionId(), getPlanName(),
+ getPhaseName(), usage.getName(), ru.getStart(), ru.getEnd(), amountToBill, getCurrency());
result.add(item);
}
}
@@ -246,10 +225,8 @@ public class ContiguousIntervalConsumableInArrear {
return result;
}
-
@VisibleForTesting
List<RolledUpUsage> getRolledUpUsage() {
-
final Iterator<RawUsage> rawUsageIterator = rawSubscriptionUsage.iterator();
if (!rawUsageIterator.hasNext()) {
return ImmutableList.of();
@@ -281,7 +258,7 @@ public class ContiguousIntervalConsumableInArrear {
// matching RolledUpUsage for that interval, and we'll detect that in the 'computeMissingItems' logic
//
LocalDate prevDate = null;
- for (LocalDate curDate : transitionTimes) {
+ for (final LocalDate curDate : transitionTimes) {
if (prevDate != null) {
@@ -291,8 +268,8 @@ public class ContiguousIntervalConsumableInArrear {
// Start consuming prevRawUsage element if it exists and falls into the range
if (prevRawUsage != null) {
if (prevRawUsage.getDate().compareTo(prevDate) >= 0 && prevRawUsage.getDate().compareTo(curDate) < 0) {
- Long currentAmount = perRangeUnitToAmount.get(prevRawUsage.getUnitType());
- Long updatedAmount = (currentAmount != null) ? currentAmount + prevRawUsage.getAmount() : prevRawUsage.getAmount();
+ final Long currentAmount = perRangeUnitToAmount.get(prevRawUsage.getUnitType());
+ final Long updatedAmount = (currentAmount != null) ? currentAmount + prevRawUsage.getAmount() : prevRawUsage.getAmount();
perRangeUnitToAmount.put(prevRawUsage.getUnitType(), updatedAmount);
prevRawUsage = null;
}
@@ -312,8 +289,8 @@ public class ContiguousIntervalConsumableInArrear {
break;
}
- Long currentAmount = perRangeUnitToAmount.get(curRawUsage.getUnitType());
- Long updatedAmount = (currentAmount != null) ? currentAmount + curRawUsage.getAmount() : curRawUsage.getAmount();
+ final Long currentAmount = perRangeUnitToAmount.get(curRawUsage.getUnitType());
+ final Long updatedAmount = (currentAmount != null) ? currentAmount + curRawUsage.getAmount() : curRawUsage.getAmount();
perRangeUnitToAmount.put(curRawUsage.getUnitType(), updatedAmount);
}
}
@@ -346,7 +323,7 @@ public class ContiguousIntervalConsumableInArrear {
BigDecimal result = BigDecimal.ZERO;
final List<TieredBlock> tieredBlocks = getConsumableInArrearTieredBlocks(usage, unitType);
int remainingUnits = nbUnits.intValue();
- for (TieredBlock tieredBlock : tieredBlocks) {
+ for (final TieredBlock tieredBlock : tieredBlocks) {
final int blockTierSize = tieredBlock.getSize().intValue();
final int tmp = remainingUnits / blockTierSize + (remainingUnits % blockTierSize == 0 ? 0 : 1);
@@ -372,7 +349,7 @@ public class ContiguousIntervalConsumableInArrear {
Preconditions.checkState(isBuilt.get());
BigDecimal billedAmount = BigDecimal.ZERO;
- for (InvoiceItem ii : filteredUsageForInterval) {
+ for (final InvoiceItem ii : filteredUsageForInterval) {
billedAmount = billedAmount.add(ii.getAmount());
}
// Return the billed $ amount (not the # of units)
@@ -415,7 +392,6 @@ public class ContiguousIntervalConsumableInArrear {
return billingEvents.get(0).getBillCycleDayLocal();
}
-
public UUID getBundleId() {
return billingEvents.get(0).getSubscription().getBundleId();
}
@@ -437,10 +413,6 @@ public class ContiguousIntervalConsumableInArrear {
return billingEvents.get(0).getCurrency();
}
- public DateTimeZone getAccountTimeZone() {
- return billingEvents.get(0).getTimeZone();
- }
-
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("ContiguousIntervalConsumableInArrear{");
@@ -451,4 +423,23 @@ public class ContiguousIntervalConsumableInArrear {
sb.append('}');
return sb.toString();
}
+
+ public class ConsumableInArrearItemsAndNextNotificationDate {
+
+ private final List<InvoiceItem> invoiceItems;
+ private final LocalDate nextNotificationDate;
+
+ public ConsumableInArrearItemsAndNextNotificationDate(final List<InvoiceItem> invoiceItems, final LocalDate nextNotificationDate) {
+ this.invoiceItems = invoiceItems;
+ this.nextNotificationDate = nextNotificationDate;
+ }
+
+ public List<InvoiceItem> getInvoiceItems() {
+ return invoiceItems;
+ }
+
+ public LocalDate getNextNotificationDate() {
+ return nextNotificationDate;
+ }
+ }
}
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/usage/RawUsageOptimizer.java b/invoice/src/main/java/org/killbill/billing/invoice/usage/RawUsageOptimizer.java
index eebec9d..1d3efeb 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/usage/RawUsageOptimizer.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/usage/RawUsageOptimizer.java
@@ -71,12 +71,11 @@ public class RawUsageOptimizer {
log.debug("ConsumableInArrear accountRecordId='{}', rawUsageStartDate='{}', firstEventStartDate='{}'",
internalCallContext.getAccountRecordId(), targetStartDate, firstEventStartDate);
final List<RawUsage> rawUsageData = usageApi.getRawUsageForAccount(targetStartDate, targetDate, internalCallContext);
- return new RawUsageOptimizerResult(firstEventStartDate, targetStartDate, rawUsageData);
+ return new RawUsageOptimizerResult(targetStartDate, rawUsageData);
}
@VisibleForTesting
LocalDate getOptimizedRawUsageStartDate(final LocalDate firstEventStartDate, final LocalDate targetDate, final Iterable<InvoiceItem> existingUsageItems, final Map<String, Usage> knownUsage, final InternalCallContext internalCallContext) {
-
if (!existingUsageItems.iterator().hasNext()) {
return firstEventStartDate;
@@ -99,7 +98,7 @@ public class RawUsageOptimizer {
//
final LocalDate[] perBillingPeriodMostRecentConsumableInArrearItemEndDate = new LocalDate[BillingPeriod.values().length - 1]; // Exclude the NO_BILLING_PERIOD
int idx = 0;
- for (BillingPeriod bp : BillingPeriod.values()) {
+ for (final BillingPeriod bp : BillingPeriod.values()) {
if (bp != BillingPeriod.NO_BILLING_PERIOD) {
final LocalDate makerDateThanCannotBeChosenAsTheMinOfAllDates = InvoiceDateUtils.advanceByNPeriods(targetDate, bp, config.getMaxRawUsagePreviousPeriod(internalCallContext));
perBillingPeriodMostRecentConsumableInArrearItemEndDate[idx++] = (knownUsageBillingPeriod.contains(bp)) ? null : makerDateThanCannotBeChosenAsTheMinOfAllDates;
@@ -124,7 +123,7 @@ public class RawUsageOptimizer {
// Extract the min from all the dates
LocalDate targetStartDate = null;
idx = 0;
- for (BillingPeriod bp : BillingPeriod.values()) {
+ for (final BillingPeriod bp : BillingPeriod.values()) {
if (bp != BillingPeriod.NO_BILLING_PERIOD) {
final LocalDate tmp = perBillingPeriodMostRecentConsumableInArrearItemEndDate[idx];
final LocalDate targetBillingPeriodDate = tmp != null ? InvoiceDateUtils.recedeByNPeriods(tmp, bp, config.getMaxRawUsagePreviousPeriod(internalCallContext)) : null;
@@ -152,20 +151,14 @@ public class RawUsageOptimizer {
public static class RawUsageOptimizerResult {
- private final LocalDate firstEventStartDate;
private final LocalDate rawUsageStartDate;
private final List<RawUsage> rawUsage;
- public RawUsageOptimizerResult(final LocalDate firstEventStartDate, final LocalDate rawUsageStartDate, final List<RawUsage> rawUsage) {
- this.firstEventStartDate = firstEventStartDate;
+ public RawUsageOptimizerResult(final LocalDate rawUsageStartDate, final List<RawUsage> rawUsage) {
this.rawUsageStartDate = rawUsageStartDate;
this.rawUsage = rawUsage;
}
- public LocalDate getFirstEventStartDate() {
- return firstEventStartDate;
- }
-
public LocalDate getRawUsageStartDate() {
return rawUsageStartDate;
}
@@ -174,5 +167,4 @@ public class RawUsageOptimizer {
return rawUsage;
}
}
-
}
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/usage/SubscriptionConsumableInArrear.java b/invoice/src/main/java/org/killbill/billing/invoice/usage/SubscriptionConsumableInArrear.java
index 4245c29..2f93a43 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/usage/SubscriptionConsumableInArrear.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/usage/SubscriptionConsumableInArrear.java
@@ -102,19 +102,16 @@ public class SubscriptionConsumableInArrear {
}));
}
-
/**
* Based on billing events, (@code existingUsage} and targetDate, figure out what remains to be billed.
*
* @param existingUsage the existing on disk usage items.
- * @return
* @throws CatalogApiException
*/
public SubscriptionConsumableInArrearItemsAndNextNotificationDate computeMissingUsageInvoiceItems(final List<InvoiceItem> existingUsage, final InvoiceItemGeneratorLogger invoiceItemGeneratorLogger) throws CatalogApiException {
-
final SubscriptionConsumableInArrearItemsAndNextNotificationDate result = new SubscriptionConsumableInArrearItemsAndNextNotificationDate();
final List<ContiguousIntervalConsumableInArrear> billingEventTransitionTimePeriods = computeInArrearUsageInterval();
- for (ContiguousIntervalConsumableInArrear usageInterval : billingEventTransitionTimePeriods) {
+ for (final ContiguousIntervalConsumableInArrear usageInterval : billingEventTransitionTimePeriods) {
final ConsumableInArrearItemsAndNextNotificationDate newItemsAndDate = usageInterval.computeMissingItemsAndNextNotificationDate(existingUsage);
// For debugging purposes
@@ -125,18 +122,15 @@ public class SubscriptionConsumableInArrear {
return result;
}
-
-
@VisibleForTesting
List<ContiguousIntervalConsumableInArrear> computeInArrearUsageInterval() {
-
final List<ContiguousIntervalConsumableInArrear> usageIntervals = Lists.newLinkedList();
final Map<String, ContiguousIntervalConsumableInArrear> inFlightInArrearUsageIntervals = new HashMap<String, ContiguousIntervalConsumableInArrear>();
final Set<String> allSeenUsage = new HashSet<String>();
- for (BillingEvent event : subscriptionBillingEvents) {
+ for (final BillingEvent event : subscriptionBillingEvents) {
// Extract all in arrear /consumable usage section for that billing event.
final List<Usage> usages = findConsumableInArrearUsages(event);
@@ -150,7 +144,7 @@ public class SubscriptionConsumableInArrear {
// All inflight usage interval are candidates to be closed unless we see that current billing event referencing the same usage section.
final Set<String> toBeClosed = new HashSet<String>(allSeenUsage);
- for (Usage usage : usages) {
+ for (final Usage usage : usages) {
// Add inflight usage interval if non existent
ContiguousIntervalConsumableInArrear existingInterval = inFlightInArrearUsageIntervals.get(usage.getName());
@@ -165,7 +159,7 @@ public class SubscriptionConsumableInArrear {
}
// Build the usage interval that are no longer referenced
- for (String usageName : toBeClosed) {
+ for (final String usageName : toBeClosed) {
final ContiguousIntervalConsumableInArrear interval = inFlightInArrearUsageIntervals.remove(usageName);
if (interval != null) {
interval.addBillingEvent(event);
@@ -173,20 +167,20 @@ public class SubscriptionConsumableInArrear {
}
}
}
- for (String usageName : inFlightInArrearUsageIntervals.keySet()) {
+ for (final String usageName : inFlightInArrearUsageIntervals.keySet()) {
usageIntervals.add(inFlightInArrearUsageIntervals.get(usageName).build(false));
}
inFlightInArrearUsageIntervals.clear();
return usageIntervals;
}
- List<Usage> findConsumableInArrearUsages(final BillingEvent event) {
- if (event.getUsages().size() == 0) {
+ private List<Usage> findConsumableInArrearUsages(final BillingEvent event) {
+ if (event.getUsages().isEmpty()) {
return Collections.emptyList();
}
final List<Usage> result = Lists.newArrayList();
- for (Usage usage : event.getUsages()) {
+ for (final Usage usage : event.getUsages()) {
if (usage.getUsageType() != UsageType.CONSUMABLE ||
usage.getBillingMode() != BillingMode.IN_ARREAR) {
continue;
@@ -197,6 +191,7 @@ public class SubscriptionConsumableInArrear {
}
public class SubscriptionConsumableInArrearItemsAndNextNotificationDate {
+
private List<InvoiceItem> invoiceItems;
private Map<String, LocalDate> perUsageNotificationDates;
@@ -230,5 +225,4 @@ public class SubscriptionConsumableInArrear {
return perUsageNotificationDates != null ? perUsageNotificationDates : ImmutableMap.<String, LocalDate>of();
}
}
-
}
diff --git a/usage/src/main/java/org/killbill/billing/usage/api/svcs/DefaultRawUsage.java b/usage/src/main/java/org/killbill/billing/usage/api/svcs/DefaultRawUsage.java
index dfd8c2b..f7a50f0 100644
--- a/usage/src/main/java/org/killbill/billing/usage/api/svcs/DefaultRawUsage.java
+++ b/usage/src/main/java/org/killbill/billing/usage/api/svcs/DefaultRawUsage.java
@@ -1,6 +1,6 @@
/*
- * Copyright 2014-2015 Groupon, Inc
- * Copyright 2014-2015 The Billing Project, LLC
+ * Copyright 2014-2016 Groupon, Inc
+ * Copyright 2014-2016 The Billing Project, LLC
*
* The Billing Project licenses this file to you under the Apache License, version 2.0
* (the "License"); you may not use this file except in compliance with the