killbill-aplcache
Changes
invoice/src/main/java/org/killbill/billing/invoice/usage/ContiguousIntervalUsageInArrear.java 100(+51 -49)
Details
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/config/MultiTenantInvoiceConfig.java b/invoice/src/main/java/org/killbill/billing/invoice/config/MultiTenantInvoiceConfig.java
index 98e14d7..bf83074 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/config/MultiTenantInvoiceConfig.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/config/MultiTenantInvoiceConfig.java
@@ -180,10 +180,11 @@ public class MultiTenantInvoiceConfig extends MultiTenantConfigBase implements I
return UsageDetailMode.valueOf(result);
}
- if (mode.compareTo(UsageDetailMode.AGGREGATE) != 0 || mode.compareTo(UsageDetailMode.DETAIL) != 0) {
- return UsageDetailMode.AGGREGATE;
+ if (mode == UsageDetailMode.AGGREGATE || mode == UsageDetailMode.DETAIL) {
+ return mode;
}
- return mode;
+
+ return UsageDetailMode.AGGREGATE;
}
@Override
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/model/InvoiceItemBase.java b/invoice/src/main/java/org/killbill/billing/invoice/model/InvoiceItemBase.java
index 329d2f1..b183ebe 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/model/InvoiceItemBase.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/model/InvoiceItemBase.java
@@ -72,21 +72,21 @@ public abstract class InvoiceItemBase extends EntityBase implements InvoiceItem
// For parent invoices
public InvoiceItemBase(final UUID id, @Nullable final DateTime createdDate, final UUID invoiceId, final UUID accountId, final UUID childAccountId,
- final BigDecimal amount, final Currency currency, final String description) {
+ final BigDecimal amount, final Currency currency, final String description) {
this(id, createdDate, invoiceId, accountId, childAccountId, null, null, description, null, null, amount, null, currency, null, null, null);
}
public InvoiceItemBase(final UUID id, @Nullable final DateTime createdDate, final UUID invoiceId, final UUID accountId, @Nullable final UUID childAccountId, @Nullable final UUID bundleId,
- @Nullable final UUID subscriptionId, @Nullable final String description,
- @Nullable final LocalDate startDate, final LocalDate endDate, final BigDecimal amount, final BigDecimal rate, final Currency currency,
- final UUID reversedItemId){
+ @Nullable final UUID subscriptionId, @Nullable final String description,
+ @Nullable final LocalDate startDate, final LocalDate endDate, final BigDecimal amount, final BigDecimal rate, final Currency currency,
+ final UUID reversedItemId) {
this(id, createdDate, invoiceId, accountId, childAccountId, bundleId, subscriptionId, description, startDate, endDate, amount, rate, currency, reversedItemId, null, null);
}
private InvoiceItemBase(final UUID id, @Nullable final DateTime createdDate, final UUID invoiceId, final UUID accountId, @Nullable final UUID childAccountId, @Nullable final UUID bundleId,
@Nullable final UUID subscriptionId, @Nullable final String description,
@Nullable final LocalDate startDate, final LocalDate endDate, final BigDecimal amount, final BigDecimal rate, final Currency currency,
- final UUID reversedItemId,@Nullable final Integer quantity,@Nullable final String itemDetails) {
+ final UUID reversedItemId, @Nullable final Integer quantity, @Nullable final String itemDetails) {
super(id, createdDate, createdDate);
this.invoiceId = invoiceId;
this.accountId = accountId;
@@ -154,13 +154,11 @@ public abstract class InvoiceItemBase extends EntityBase implements InvoiceItem
return linkedItemId;
}
-
@Override
public UUID getChildAccountId() {
return childAccountId;
}
-
@Override
public String getPlanName() {
return null;
@@ -192,10 +190,14 @@ public abstract class InvoiceItemBase extends EntityBase implements InvoiceItem
}
@Override
- public Integer getQuantity() { return quantity; }
+ public Integer getQuantity() {
+ return quantity;
+ }
@Override
- public String getItemDetails() { return itemDetails; }
+ public String getItemDetails() {
+ return itemDetails;
+ }
@Override
public boolean equals(final Object o) {
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/usage/ContiguousIntervalUsageInArrear.java b/invoice/src/main/java/org/killbill/billing/invoice/usage/ContiguousIntervalUsageInArrear.java
index edb497f..c992206 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/usage/ContiguousIntervalUsageInArrear.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/usage/ContiguousIntervalUsageInArrear.java
@@ -49,7 +49,6 @@ import org.killbill.billing.junction.BillingEvent;
import org.killbill.billing.usage.RawUsage;
import org.killbill.billing.usage.api.RolledUpUnit;
import org.killbill.billing.usage.api.RolledUpUsage;
-import org.killbill.billing.util.config.definition.InvoiceConfig;
import org.killbill.billing.util.config.definition.InvoiceConfig.UsageDetailMode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -95,6 +94,7 @@ public class ContiguousIntervalUsageInArrear {
private final LocalDate rawUsageStartDate;
private final InternalTenantContext internalTenantContext;
private final UsageDetailMode usageDetailMode;
+ private static final ObjectMapper objectMapper = new ObjectMapper();
public ContiguousIntervalUsageInArrear(final Usage usage,
final UUID accountId,
@@ -196,7 +196,7 @@ public class ContiguousIntervalUsageInArrear {
final List<RolledUpUsage> allUsage = getRolledUpUsage();
for (final RolledUpUsage ru : allUsage) {
int tierNum = 1;
- List<ConsumableInArrearDetail> toBeBilledUsageDetails = Lists.newLinkedList();
+ List<UsageInArrearDetail> toBeBilledUsageDetails = Lists.newLinkedList();
BigDecimal toBeBilledUsage = BigDecimal.ZERO;
if (usage.getUsageType() == UsageType.CAPACITY) {
toBeBilledUsageDetails.addAll(computeToBeBilledCapacityInArrear(ru.getRolledUpUnits(), tierNum));
@@ -225,8 +225,8 @@ public class ContiguousIntervalUsageInArrear {
final BigDecimal amountToBill = toBeBilledForUnit(toBeBilledUsageDetails);
if (amountToBill.compareTo(BigDecimal.ZERO) > 0) {
- if (UsageDetailMode.DETAIL.compareTo(usageDetailMode) == 0){
- for (ConsumableInArrearDetail toBeBilledUsageDetail : toBeBilledUsageDetails){
+ if (UsageDetailMode.DETAIL == usageDetailMode){
+ for (UsageInArrearDetail toBeBilledUsageDetail : toBeBilledUsageDetails){
final InvoiceItem item = new UsageInvoiceItem(invoiceId, accountId, getBundleId(), getSubscriptionId(), getPlanName(),
getPhaseName(), usage.getName(), ru.getStart(), ru.getEnd(), toBeBilledUsageDetail.getAmount(), toBeBilledUsageDetail.getTierPrice(), getCurrency(),toBeBilledUsageDetail.getQuantity(),null);
result.add(item);
@@ -386,13 +386,13 @@ public class ContiguousIntervalUsageInArrear {
* @throws CatalogApiException
*/
@VisibleForTesting
- List<ConsumableInArrearDetail> computeToBeBilledCapacityInArrear(final List<RolledUpUnit> roUnits, int tierNum) throws CatalogApiException {
+ List<UsageInArrearDetail> computeToBeBilledCapacityInArrear(final List<RolledUpUnit> roUnits, int tierNum) throws CatalogApiException {
Preconditions.checkState(isBuilt.get());
final List<Tier> tiers = getCapacityInArrearTier(usage);
for (final Tier cur : tiers) {
- List<ConsumableInArrearDetail> toBeBilledDetails = Lists.newLinkedList();
+ List<UsageInArrearDetail> toBeBilledDetails = Lists.newLinkedList();
boolean complies = true;
for (final RolledUpUnit ro : roUnits) {
final Limit tierLimit = getTierLimit(cur, ro.getUnitType());
@@ -402,7 +402,7 @@ public class ContiguousIntervalUsageInArrear {
complies = false;
break;
}
- toBeBilledDetails.add(new ConsumableInArrearDetail(tierNum++, ro.getUnitType(), cur.getRecurringPrice().getPrice(getCurrency()), ro.getAmount().intValue(), BigDecimal.ZERO, null, null));
+ toBeBilledDetails.add(new UsageInArrearDetail(tierNum++, ro.getUnitType(), cur.getRecurringPrice().getPrice(getCurrency()), ro.getAmount().intValue(), BigDecimal.ZERO, null, null));
}
if (complies) {
@@ -423,7 +423,7 @@ public class ContiguousIntervalUsageInArrear {
* @throws CatalogApiException
*/
@VisibleForTesting
- List<ConsumableInArrearDetail> computeToBeBilledConsumableInArrear(final RolledUpUnit roUnit, int tierNum) throws CatalogApiException {
+ List<UsageInArrearDetail> computeToBeBilledConsumableInArrear(final RolledUpUnit roUnit, int tierNum) throws CatalogApiException {
Preconditions.checkState(isBuilt.get());
final List<TieredBlock> tieredBlocks = getConsumableInArrearTieredBlocks(usage, roUnit.getUnitType());
@@ -439,9 +439,9 @@ public class ContiguousIntervalUsageInArrear {
}
- List<ConsumableInArrearDetail> computeToBeBilledConsumableInArrearWith_ALL_TIERS(final List<TieredBlock> tieredBlocks, final Long units, int tierNum) throws CatalogApiException {
+ List<UsageInArrearDetail> computeToBeBilledConsumableInArrearWith_ALL_TIERS(final List<TieredBlock> tieredBlocks, final Long units, int tierNum) throws CatalogApiException {
- List<ConsumableInArrearDetail> toBeBilledDetails = Lists.newLinkedList();
+ List<UsageInArrearDetail> toBeBilledDetails = Lists.newLinkedList();
BigDecimal result = BigDecimal.ZERO;
int remainingUnits = units.intValue();
for (final TieredBlock tieredBlock : tieredBlocks) {
@@ -456,12 +456,12 @@ public class ContiguousIntervalUsageInArrear {
nbUsedTierBlocks = tmp;
remainingUnits = 0;
}
- toBeBilledDetails.add(new ConsumableInArrearDetail(tierNum, tieredBlock.getUnit().getName(), tieredBlock.getPrice().getPrice(getCurrency()), nbUsedTierBlocks));
+ toBeBilledDetails.add(new UsageInArrearDetail(tierNum, tieredBlock.getUnit().getName(), tieredBlock.getPrice().getPrice(getCurrency()), nbUsedTierBlocks));
}
return toBeBilledDetails;
}
- ConsumableInArrearDetail computeToBeBilledConsumableInArrearWith_TOP_TIER(final List<TieredBlock> tieredBlocks, final Long units, int tierNum) throws CatalogApiException {
+ UsageInArrearDetail computeToBeBilledConsumableInArrearWith_TOP_TIER(final List<TieredBlock> tieredBlocks, final Long units, int tierNum) throws CatalogApiException {
int remainingUnits = units.intValue();
@@ -482,7 +482,7 @@ public class ContiguousIntervalUsageInArrear {
final int lastBlockTierSize = targetBlock.getSize().intValue();
final int nbBlocks = units.intValue() / lastBlockTierSize + (units.intValue() % lastBlockTierSize == 0 ? 0 : 1);
- return new ConsumableInArrearDetail(tierNum, targetBlock.getUnit().getName(), targetBlock.getPrice().getPrice(getCurrency()), nbBlocks);
+ return new UsageInArrearDetail(tierNum, targetBlock.getUnit().getName(), targetBlock.getPrice().getPrice(getCurrency()), nbBlocks);
}
@@ -589,44 +589,43 @@ public class ContiguousIntervalUsageInArrear {
}
}
- public BigDecimal toBeBilledForUnit(List<ConsumableInArrearDetail> toBeBilledDetails){
+ public BigDecimal toBeBilledForUnit(List<UsageInArrearDetail> toBeBilledDetails){
BigDecimal result = BigDecimal.ZERO;
- for (ConsumableInArrearDetail toBeBilled: toBeBilledDetails){
+ for (UsageInArrearDetail toBeBilled: toBeBilledDetails){
result = result.add(toBeBilled.getAmount());
}
return result;
}
- private List<ConsumableInArrearDetail> reconcileExistedBilledWithToBeBilled(Iterable<InvoiceItem> billedItems, List<ConsumableInArrearDetail> toBeBilledConsumableInArrearDetails) {
+ private List<UsageInArrearDetail> reconcileExistedBilledWithToBeBilled(Iterable<InvoiceItem> billedItems, List<UsageInArrearDetail> toBeBilledUsageInArrearDetails) {
for (final InvoiceItem bi : billedItems) {
- List<ConsumableInArrearDetail> billedUsageItemDetails = fromJson(bi.getItemDetails());
+ List<UsageInArrearDetail> billedUsageItemDetails = fromJson(bi.getItemDetails());
if (billedUsageItemDetails != null && billedUsageItemDetails.size() > 0) {
- for (final ConsumableInArrearDetail toBeBilledConsumable : toBeBilledConsumableInArrearDetails) {
+ for (final UsageInArrearDetail toBeBilledConsumable : toBeBilledUsageInArrearDetails) {
billedUsageItemDetails = toBeBilledConsumable.reconcile(billedUsageItemDetails);
}
if (billedUsageItemDetails != null && billedUsageItemDetails.size() > 0) {
- for (final ConsumableInArrearDetail billedUsage : billedUsageItemDetails) {
- toBeBilledConsumableInArrearDetails.add(new ConsumableInArrearDetail(billedUsage.getTier(), billedUsage.getTierUnit(), billedUsage.getTierPrice(),
- billedUsage.getQuantity(), billedUsage.getAmount().negate(), null, bi.getId().toString()));
+ for (final UsageInArrearDetail billedUsage : billedUsageItemDetails) {
+ toBeBilledUsageInArrearDetails.add(new UsageInArrearDetail(billedUsage.getTier(), billedUsage.getTierUnit(), billedUsage.getTierPrice(),
+ billedUsage.getQuantity(), billedUsage.getAmount().negate(), null, bi.getId().toString()));
}
}
} else {
- toBeBilledConsumableInArrearDetails.add(new ConsumableInArrearDetail(bi.getRate(), bi.getQuantity(), bi.getAmount().negate(), bi.getId().toString()));
+ toBeBilledUsageInArrearDetails.add(new UsageInArrearDetail(bi.getRate(), bi.getQuantity(), bi.getAmount().negate(), bi.getId().toString()));
}
}
- return toBeBilledConsumableInArrearDetails;
+ return toBeBilledUsageInArrearDetails;
}
- public static final String toJson(List<ConsumableInArrearDetail> toBeBilledConsumableInArrearDetails) {
+ private static final String toJson(List<UsageInArrearDetail> toBeBilledUsageInArrearDetails) {
String result = null;
- if (toBeBilledConsumableInArrearDetails != null && toBeBilledConsumableInArrearDetails.size() > 0){
- ObjectMapper objectMapper = new ObjectMapper();
+ if (toBeBilledUsageInArrearDetails != null && toBeBilledUsageInArrearDetails.size() > 0){
try {
- result = objectMapper.writeValueAsString(toBeBilledConsumableInArrearDetails);
+ result = objectMapper.writeValueAsString(toBeBilledUsageInArrearDetails);
} catch (JsonProcessingException e) {
Preconditions.checkState(false, e.getMessage());
}
@@ -634,23 +633,20 @@ public class ContiguousIntervalUsageInArrear {
return result;
}
- public static final List<ConsumableInArrearDetail> fromJson(String itemDetails){
- List<ConsumableInArrearDetail> toBeBilledConsumableInArrearDetails = null;
+ private static final List<UsageInArrearDetail> fromJson(String itemDetails){
+ List<UsageInArrearDetail> toBeBilledUsageInArrearDetails = null;
if (itemDetails != null){
- ObjectMapper objectMapper = new ObjectMapper();
try {
- toBeBilledConsumableInArrearDetails = objectMapper.reader()
- .forType(new TypeReference<List<ConsumableInArrearDetail>>() {})
- .readValue(itemDetails);
+ toBeBilledUsageInArrearDetails = objectMapper.readValue(itemDetails, new TypeReference<List<UsageInArrearDetail>>() {});
} catch (IOException e) {
Preconditions.checkState(false, e.getMessage());
}
}
- return toBeBilledConsumableInArrearDetails;
+ return toBeBilledUsageInArrearDetails;
}
- public class ConsumableInArrearDetail {
+ public class UsageInArrearDetail {
private final int tier;
private final String tierUnit;
@@ -660,19 +656,19 @@ public class ContiguousIntervalUsageInArrear {
private BigDecimal existingUsageAmount;
private BigDecimal amount;
- public ConsumableInArrearDetail(BigDecimal tierPrice, Integer quantity, BigDecimal existingUsageAmount, String reference){
+ public UsageInArrearDetail(BigDecimal tierPrice, Integer quantity, BigDecimal existingUsageAmount, String reference) {
this(0, null, tierPrice, quantity, existingUsageAmount, BigDecimal.ZERO, reference);
}
- public ConsumableInArrearDetail(int tier, String tierUnit, BigDecimal tierPrice, Integer quantity){
+ public UsageInArrearDetail(int tier, String tierUnit, BigDecimal tierPrice, Integer quantity) {
this(tier, tierUnit, tierPrice, quantity, tierPrice.multiply(new BigDecimal(quantity)), null, null);
}
@JsonCreator
- public ConsumableInArrearDetail(@JsonProperty("tier") int tier, @JsonProperty("tierUnit") String tierUnit,
- @JsonProperty("tierPrice") BigDecimal tierPrice, @JsonProperty("quantity") Integer quantity,
- @JsonProperty("amount") BigDecimal amount, @JsonProperty("existingUsageAmount") BigDecimal existingUsageAmount,
- @JsonProperty("reference") String reference){
+ public UsageInArrearDetail(@JsonProperty("tier") int tier, @JsonProperty("tierUnit") String tierUnit,
+ @JsonProperty("tierPrice") BigDecimal tierPrice, @JsonProperty("quantity") Integer quantity,
+ @JsonProperty("amount") BigDecimal amount, @JsonProperty("existingUsageAmount") BigDecimal existingUsageAmount,
+ @JsonProperty("reference") String reference) {
this.tier = tier;
this.tierUnit = tierUnit;
this.tierPrice = tierPrice;
@@ -685,19 +681,27 @@ public class ContiguousIntervalUsageInArrear {
public int getTier() {
return tier;
}
+
public String getTierUnit() {
return tierUnit;
}
- public BigDecimal getTierPrice() {
+ public BigDecimal getTierPrice() {
return tierPrice;
}
+
public Integer getQuantity() {
return quantity;
}
+
public BigDecimal getExistingUsageAmount() {
return existingUsageAmount;
}
+
+ public void setExistingUsageAmount(BigDecimal existingUsageAmount) {
+ this.existingUsageAmount = existingUsageAmount;
+ }
+
public BigDecimal getAmount() {
return amount;
}
@@ -705,17 +709,15 @@ public class ContiguousIntervalUsageInArrear {
public void setAmount(BigDecimal amount) {
this.amount = amount;
}
- public void setExistingUsageAmount(BigDecimal existingUsageAmount) {
- this.existingUsageAmount = existingUsageAmount;
- }
+
public void setReference(String reference) {
this.reference = reference;
}
- public List<ConsumableInArrearDetail> reconcile(List<ConsumableInArrearDetail> billedUsageItemDetails){
- List<ConsumableInArrearDetail> unreconciledUsage = Lists.newLinkedList();
- for (ConsumableInArrearDetail billedUsageDetail : billedUsageItemDetails){
- if( tierUnit == billedUsageDetail.tierUnit ) {
+ public List<UsageInArrearDetail> reconcile(List<UsageInArrearDetail> billedUsageItemDetails) {
+ List<UsageInArrearDetail> unreconciledUsage = Lists.newLinkedList();
+ for (UsageInArrearDetail billedUsageDetail : billedUsageItemDetails) {
+ if (tierUnit.equals(billedUsageDetail.tierUnit)) {
existingUsageAmount = billedUsageDetail.amount.abs();
amount = amount.subtract(existingUsageAmount);
} else {
diff --git a/invoice/src/test/java/org/killbill/billing/invoice/usage/TestContiguousIntervalCapacityInArrear.java b/invoice/src/test/java/org/killbill/billing/invoice/usage/TestContiguousIntervalCapacityInArrear.java
index ed06f21..b37b357 100644
--- a/invoice/src/test/java/org/killbill/billing/invoice/usage/TestContiguousIntervalCapacityInArrear.java
+++ b/invoice/src/test/java/org/killbill/billing/invoice/usage/TestContiguousIntervalCapacityInArrear.java
@@ -26,7 +26,6 @@ import org.joda.time.DateTimeZone;
import org.joda.time.LocalDate;
import org.killbill.billing.catalog.DefaultLimit;
import org.killbill.billing.catalog.DefaultTier;
-import org.killbill.billing.catalog.DefaultTieredBlock;
import org.killbill.billing.catalog.DefaultUnit;
import org.killbill.billing.catalog.DefaultUsage;
import org.killbill.billing.catalog.api.BillingPeriod;
@@ -36,24 +35,20 @@ import org.killbill.billing.catalog.api.Usage;
import org.killbill.billing.invoice.api.InvoiceItem;
import org.killbill.billing.invoice.model.FixedPriceInvoiceItem;
import org.killbill.billing.invoice.model.UsageInvoiceItem;
-import org.killbill.billing.invoice.usage.ContiguousIntervalUsageInArrear.ConsumableInArrearDetail;
+import org.killbill.billing.invoice.usage.ContiguousIntervalUsageInArrear.UsageInArrearDetail;
import org.killbill.billing.invoice.usage.ContiguousIntervalUsageInArrear.UsageInArrearItemsAndNextNotificationDate;
import org.killbill.billing.junction.BillingEvent;
import org.killbill.billing.usage.RawUsage;
import org.killbill.billing.usage.api.RolledUpUnit;
-import org.killbill.billing.usage.api.RolledUpUsage;
import org.killbill.billing.usage.api.svcs.DefaultRawUsage;
-import org.testng.Assert;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
-import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
-import com.google.common.collect.Ordering;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
@@ -120,19 +115,23 @@ public class TestContiguousIntervalCapacityInArrear extends TestUsageInArrearBas
final DefaultUnit unit1 = new DefaultUnit().setName("unit1");
final DefaultUnit unit2 = new DefaultUnit().setName("unit2");
+ final DefaultUnit unit3 = new DefaultUnit().setName("unit3");
final DefaultLimit limit1_1 = new DefaultLimit().setUnit(unit1).setMax((double) 100).setMin((double) -1);
final DefaultLimit limit1_2 = new DefaultLimit().setUnit(unit2).setMax((double) 1000).setMin((double) -1);
- final DefaultTier tier1 = createDefaultTierWithLimits(BigDecimal.TEN, limit1_1, limit1_2);
+ final DefaultLimit limit1_3 = new DefaultLimit().setUnit(unit3).setMax((double) 50).setMin((double) -1);
+ final DefaultTier tier1 = createDefaultTierWithLimits(BigDecimal.TEN, limit1_1, limit1_2, limit1_3);
final DefaultLimit limit2_1 = new DefaultLimit().setUnit(unit1).setMax((double) 200).setMin((double) -1);
final DefaultLimit limit2_2 = new DefaultLimit().setUnit(unit2).setMax((double) 2000).setMin((double) -1);
- final DefaultTier tier2 = createDefaultTierWithLimits(new BigDecimal("20.0"), limit2_1, limit2_2);
+ final DefaultLimit limit2_3 = new DefaultLimit().setUnit(unit3).setMax((double) 100).setMin((double) -1);
+ final DefaultTier tier2 = createDefaultTierWithLimits(new BigDecimal("20.0"), limit2_1, limit2_2, limit2_3);
// Don't define any max for last tier to allow any number
final DefaultLimit limit3_1 = new DefaultLimit().setUnit(unit1).setMin((double) -1).setMax((double) -1);
final DefaultLimit limit3_2 = new DefaultLimit().setUnit(unit2).setMin((double) -1).setMax((double) -1);
- final DefaultTier tier3 = createDefaultTierWithLimits(new BigDecimal("30.0"), limit3_1, limit3_2);
+ final DefaultLimit limit3_3 = new DefaultLimit().setUnit(unit3).setMax((double) -1).setMin((double) -1);
+ final DefaultTier tier3 = createDefaultTierWithLimits(new BigDecimal("30.0"), limit3_1, limit3_2, limit3_3);
final DefaultUsage usage = createCapacityInArrearUsage(usageName, BillingPeriod.MONTHLY, tier1, tier2, tier3);
@@ -145,8 +144,10 @@ public class TestContiguousIntervalCapacityInArrear extends TestUsageInArrearBas
Collections.<Usage>emptyList())
);
// Tier 1 (both units from tier 1)
- List<ConsumableInArrearDetail> result = intervalCapacityInArrear.computeToBeBilledCapacityInArrear(ImmutableList.<RolledUpUnit>of(new DefaultRolledUpUnit("unit1", 100L),
- new DefaultRolledUpUnit("unit2", 1000L)), 1);
+ List<UsageInArrearDetail> result = intervalCapacityInArrear.computeToBeBilledCapacityInArrear(ImmutableList.<RolledUpUnit>of(new DefaultRolledUpUnit("unit1", 100L),
+ new DefaultRolledUpUnit("unit2", 1000L),
+ new DefaultRolledUpUnit("unit3", 50L)), 1);
+ assertEquals(result.size(), 3);
assertEquals(intervalCapacityInArrear.toBeBilledForUnit(result), BigDecimal.TEN);
// Tier 2 (only one unit from tier 1)
diff --git a/invoice/src/test/java/org/killbill/billing/invoice/usage/TestContiguousIntervalConsumableInArrear.java b/invoice/src/test/java/org/killbill/billing/invoice/usage/TestContiguousIntervalConsumableInArrear.java
index 1351ae4..1483fa4 100644
--- a/invoice/src/test/java/org/killbill/billing/invoice/usage/TestContiguousIntervalConsumableInArrear.java
+++ b/invoice/src/test/java/org/killbill/billing/invoice/usage/TestContiguousIntervalConsumableInArrear.java
@@ -37,7 +37,7 @@ import org.killbill.billing.catalog.api.Usage;
import org.killbill.billing.invoice.api.InvoiceItem;
import org.killbill.billing.invoice.model.FixedPriceInvoiceItem;
import org.killbill.billing.invoice.model.UsageInvoiceItem;
-import org.killbill.billing.invoice.usage.ContiguousIntervalUsageInArrear.ConsumableInArrearDetail;
+import org.killbill.billing.invoice.usage.ContiguousIntervalUsageInArrear.UsageInArrearDetail;
import org.killbill.billing.invoice.usage.ContiguousIntervalUsageInArrear.UsageInArrearItemsAndNextNotificationDate;
import org.killbill.billing.junction.BillingEvent;
import org.killbill.billing.usage.RawUsage;
@@ -145,7 +145,7 @@ public class TestContiguousIntervalConsumableInArrear extends TestUsageInArrearB
Collections.<Usage>emptyList())
);
- List<ConsumableInArrearDetail> result = intervalConsumableInArrear.computeToBeBilledConsumableInArrear(new DefaultRolledUpUnit("unit", 111L), 1);
+ List<UsageInArrearDetail> result = intervalConsumableInArrear.computeToBeBilledConsumableInArrear(new DefaultRolledUpUnit("unit", 111L), 1);
assertEquals(result.size(), 3);
// 111 = 10 (tier1) + 100 (tier2) + 1 (tier3) => 10 * 1.5 + 100 * 1 + 1 * 0.5 = 115.5
assertEquals(result.get(0).getAmount(), new BigDecimal("15.0"));
@@ -173,7 +173,7 @@ public class TestContiguousIntervalConsumableInArrear extends TestUsageInArrearB
Collections.<Usage>emptyList())
);
- List<ConsumableInArrearDetail> result = intervalConsumableInArrear.computeToBeBilledConsumableInArrear(new DefaultRolledUpUnit("unit", 5325L),1);
+ List<UsageInArrearDetail> result = intervalConsumableInArrear.computeToBeBilledConsumableInArrear(new DefaultRolledUpUnit("unit", 5325L), 1);
assertEquals(result.size(), 2);
// 5000 = 1000 (tier1) + 4325 (tier2) => 10 + 5 = 15
@@ -207,23 +207,23 @@ public class TestContiguousIntervalConsumableInArrear extends TestUsageInArrearB
//
// In this model unit amount is first used to figure out which tier we are in, and then we price all unit at that 'target' tier
//
- List<ConsumableInArrearDetail> inputTier1 = intervalConsumableInArrear.computeToBeBilledConsumableInArrear(new DefaultRolledUpUnit("unit", 1000L), 1);
+ List<UsageInArrearDetail> inputTier1 = intervalConsumableInArrear.computeToBeBilledConsumableInArrear(new DefaultRolledUpUnit("unit", 1000L), 1);
assertEquals(inputTier1.size(), 1);
// 1000 units => (tier1) : 1000 / 100 + 1000 % 100 = 10
assertEquals(inputTier1.get(0).getAmount(), new BigDecimal("10"));
- List<ConsumableInArrearDetail> inputTier2 = intervalConsumableInArrear.computeToBeBilledConsumableInArrear(new DefaultRolledUpUnit("unit", 101000L), 1);
+ List<UsageInArrearDetail> inputTier2 = intervalConsumableInArrear.computeToBeBilledConsumableInArrear(new DefaultRolledUpUnit("unit", 101000L), 1);
assertEquals(inputTier2.size(), 1);
// 101000 units => (tier2) : 101000 / 1000 + 101000 % 1000 = 101 + 0 = 101
assertEquals(inputTier2.get(0).getAmount(), new BigDecimal("101"));
- List<ConsumableInArrearDetail> inputTier3 = intervalConsumableInArrear.computeToBeBilledConsumableInArrear(new DefaultRolledUpUnit("unit", 101001L), 1);
+ List<UsageInArrearDetail> inputTier3 = intervalConsumableInArrear.computeToBeBilledConsumableInArrear(new DefaultRolledUpUnit("unit", 101001L), 1);
assertEquals(inputTier3.size(), 1);
// 101001 units => (tier3) : 101001 / 1000 + 101001 % 1000 = 101 + 1 = 102 units => $51
assertEquals(inputTier3.get(0).getAmount(), new BigDecimal("51.0"));
// If we pass the maximum of the last tier, we price all units at the last tier
- List<ConsumableInArrearDetail> inputLastTier = intervalConsumableInArrear.computeToBeBilledConsumableInArrear(new DefaultRolledUpUnit("unit", 300000L), 1);
+ List<UsageInArrearDetail> inputLastTier = intervalConsumableInArrear.computeToBeBilledConsumableInArrear(new DefaultRolledUpUnit("unit", 300000L), 1);
assertEquals(inputLastTier.size(), 1);
// 300000 units => (tier3) : 300000 / 1000 + 300000 % 1000 = 300 units => $150
assertEquals(inputLastTier.get(0).getAmount(), new BigDecimal("150.0"));
@@ -252,7 +252,7 @@ public class TestContiguousIntervalConsumableInArrear extends TestUsageInArrearB
Collections.<Usage>emptyList())
);
- List<ConsumableInArrearDetail> result = intervalConsumableInArrear.computeToBeBilledConsumableInArrear(new DefaultRolledUpUnit("unit", 111L),1);
+ List<UsageInArrearDetail> result = intervalConsumableInArrear.computeToBeBilledConsumableInArrear(new DefaultRolledUpUnit("unit", 111L), 1);
assertEquals(result.size(), 1);
// 111 = 111 * 0.5 =
@@ -320,9 +320,8 @@ public class TestContiguousIntervalConsumableInArrear extends TestUsageInArrearB
assertTrue(result.get(0).getEndDate().compareTo(firstBCDDate) == 0);
// check item detail
- List<MockToBeBilledConsumableInArrearDetail> itemDetails = objectMapper.reader()
- .forType(new TypeReference<List<MockToBeBilledConsumableInArrearDetail>>() {})
- .readValue(result.get(0).getItemDetails());
+ List<MockToBeBilledConsumableInArrearDetail> itemDetails = objectMapper.readValue(result.get(0).getItemDetails(), new TypeReference<List<MockToBeBilledConsumableInArrearDetail>>() {});
+
assertEquals(itemDetails.size(), 2);
assertEquals(itemDetails.get(0).getAmount().compareTo(new BigDecimal("5")),0);
assertEquals(itemDetails.get(1).getAmount().compareTo(new BigDecimal("-1")),0);
@@ -341,9 +340,7 @@ public class TestContiguousIntervalConsumableInArrear extends TestUsageInArrearB
assertTrue(result.get(1).getEndDate().compareTo(endDate) == 0);
// check item detail
- List<MockToBeBilledConsumableInArrearDetail> itemDetails2 = objectMapper.reader()
- .forType(new TypeReference<List<MockToBeBilledConsumableInArrearDetail>>() {})
- .readValue(result.get(1).getItemDetails());
+ List<MockToBeBilledConsumableInArrearDetail> itemDetails2 = objectMapper.readValue(result.get(0).getItemDetails(), new TypeReference<List<MockToBeBilledConsumableInArrearDetail>>() {});
assertEquals(itemDetails2.size(), 2);
assertEquals(itemDetails2.get(0).getAmount().compareTo(new BigDecimal("2")),0);
assertEquals(itemDetails2.get(1).getAmount().compareTo(new BigDecimal("-1")),0);
@@ -450,6 +447,28 @@ public class TestContiguousIntervalConsumableInArrear extends TestUsageInArrearB
assertEquals(res.getTransitionTimes().size(), 0);
}
+ @Test(groups = "fast")
+ public void testTobeBilledForUnit() throws CatalogApiException {
+
+ final DefaultTieredBlock block1 = createDefaultTieredBlock("cell-phone-minutes", 1000, 10000, new BigDecimal("0.5"));
+ final DefaultTieredBlock block2 = createDefaultTieredBlock("Mbytes", 512, 512000, new BigDecimal("0.3"));
+ final DefaultTier tier = createDefaultTierWithBlocks(block1, block2);
+
+ final DefaultUsage usage = createConsumableInArrearUsage(usageName, BillingPeriod.MONTHLY, TierBlockPolicy.ALL_TIERS, tier);
+ final LocalDate targetDate = new LocalDate(2014, 03, 20);
+ final ContiguousIntervalUsageInArrear intervalConsumableInArrear = createContiguousIntervalConsumableInArrear(usage, ImmutableList.<RawUsage>of(), targetDate, false,
+ createMockBillingEvent(targetDate.toDateTimeAtStartOfDay(DateTimeZone.UTC),
+ BillingPeriod.MONTHLY,
+ Collections.<Usage>emptyList())
+ );
+ List<UsageInArrearDetail> results = Lists.newArrayList();
+ results.addAll(intervalConsumableInArrear.computeToBeBilledConsumableInArrear(new DefaultRolledUpUnit("cell-phone-minutes", 1000L), 1));
+ results.addAll(intervalConsumableInArrear.computeToBeBilledConsumableInArrear(new DefaultRolledUpUnit("Mbytes", 30720L), 2));
+ assertEquals(results.size(), 2);
+
+ assertEquals(intervalConsumableInArrear.toBeBilledForUnit(results), new BigDecimal("18.5"));
+ }
+
public static class MockToBeBilledConsumableInArrearDetail {
private final int tier;