use of org.killbill.billing.catalog.api.TieredBlock in project killbill by killbill.
the class ContiguousIntervalConsumableUsageInArrear method computeToBeBilledConsumableInArrearWith_ALL_TIERS.
List<UsageConsumableInArrearTierUnitAggregate> computeToBeBilledConsumableInArrearWith_ALL_TIERS(final LocalDate startDate, final LocalDate endDate, final List<TieredBlock> tieredBlocks, final List<UsageConsumableInArrearTierUnitAggregate> previousUsage, final Long units) throws CatalogApiException {
List<UsageConsumableInArrearTierUnitAggregate> toBeBilledDetails = Lists.newLinkedList();
long remainingUnits = units;
int tierNum = 0;
// we count tier from 1, 2, ...
final int lastPreviousUsageTier = previousUsage.size();
final boolean hasPreviousUsage = lastPreviousUsageTier > 0;
for (final TieredBlock tieredBlock : tieredBlocks) {
tierNum++;
final long blockTierSize = tieredBlock.getSize().longValue();
final long tmp = remainingUnits / blockTierSize + (remainingUnits % blockTierSize == 0 ? 0 : 1);
long nbUsedTierBlocks;
if (tieredBlock.getMax() != (double) -1 && tmp > tieredBlock.getMax()) {
nbUsedTierBlocks = tieredBlock.getMax().longValue();
remainingUnits -= tieredBlock.getMax() * blockTierSize;
} else {
nbUsedTierBlocks = tmp;
remainingUnits = 0;
}
// We generate an entry if we consumed anything on this tier or if this is the first tier to also support $0 Usage item
if (hasPreviousUsage) {
final Long previousUsageQuantity = tierNum <= lastPreviousUsageTier ? previousUsage.get(tierNum - 1).getQuantity() : 0;
// Be lenient for dryRun use cases (as we could have plugin optimizations not returning full usage data) or unless configured.
if (!isDryRun && !invoiceConfig.isUsageMissingLenient(internalTenantContext)) {
if (tierNum < lastPreviousUsageTier) {
Preconditions.checkState(nbUsedTierBlocks == previousUsageQuantity, String.format("Expected usage for subscription='%s', targetDate='%s', startDt='%s', endDt='%s', tier='%d', unit='%s' to be full, instead found units='[%d/%d]'", getSubscriptionId(), targetDate, startDate, endDate, tierNum, tieredBlock.getUnit().getName(), nbUsedTierBlocks, previousUsageQuantity));
} else {
Preconditions.checkState(nbUsedTierBlocks - previousUsageQuantity >= 0, String.format("Expected usage for subscription='%s', targetDate='%s', startDt='%s', endDt='%s', tier='%d', unit='%s' to contain at least as much as current usage, instead found units='[%d/%d]'", getSubscriptionId(), targetDate, startDate, endDate, tierNum, tieredBlock.getUnit().getName(), nbUsedTierBlocks, previousUsageQuantity));
}
}
nbUsedTierBlocks = nbUsedTierBlocks - previousUsageQuantity;
}
if (tierNum == 1 || nbUsedTierBlocks > 0) {
toBeBilledDetails.add(new UsageConsumableInArrearTierUnitAggregate(tierNum, tieredBlock.getUnit().getName(), tieredBlock.getPrice().getPrice(getCurrency()), blockTierSize, nbUsedTierBlocks));
}
}
return toBeBilledDetails;
}
use of org.killbill.billing.catalog.api.TieredBlock in project killbill by killbill.
the class DefaultPriceOverride method getResolvedTierOverrides.
public List<TierPriceOverride> getResolvedTierOverrides(Tier[] tiers, List<TierPriceOverride> tierPriceOverrides) throws CatalogApiException {
List<TierPriceOverride> resolvedTierOverrides = new ArrayList<TierPriceOverride>();
for (final Tier curTier : tiers) {
final TierPriceOverride curOverride = Iterables.tryFind(tierPriceOverrides, new Predicate<TierPriceOverride>() {
@Override
public boolean apply(final TierPriceOverride input) {
if (input.getTieredBlockPriceOverrides() != null) {
for (TieredBlockPriceOverride blockPriceOverride : input.getTieredBlockPriceOverrides()) {
String unitName = blockPriceOverride.getUnitName();
Double max = blockPriceOverride.getMax();
Double size = blockPriceOverride.getSize();
for (int i = 0; i < curTier.getTieredBlocks().length; i++) {
TieredBlock curTieredBlock = curTier.getTieredBlocks()[i];
if (unitName.equals(curTieredBlock.getUnit().getName()) && Double.compare(size, curTieredBlock.getSize()) == 0 && Double.compare(max, curTieredBlock.getMax()) == 0) {
return true;
}
}
}
}
return false;
}
}).orNull();
if (curOverride != null) {
List<TieredBlockPriceOverride> tieredBlockPriceOverrides = getResolvedTieredBlockPriceOverrides(curTier.getTieredBlocks(), curOverride.getTieredBlockPriceOverrides());
resolvedTierOverrides.add(new DefaultTierPriceOverride(tieredBlockPriceOverrides));
} else {
resolvedTierOverrides.add(null);
}
}
return resolvedTierOverrides;
}
use of org.killbill.billing.catalog.api.TieredBlock in project killbill by killbill.
the class DefaultOverriddenPlanCache method getTierPriceOverrides.
List<TierPriceOverride> getTierPriceOverrides(Usage curUsage, CatalogOverrideUsageDefinitionModelDao overriddenUsage, final InternalTenantContext context) {
final List<TierPriceOverride> tierPriceOverrides = new ArrayList<TierPriceOverride>();
final List<CatalogOverrideTierDefinitionModelDao> tierDefs = overrideDao.getOverriddenUsageTiers(overriddenUsage.getRecordId(), context);
for (int i = 0; i < curUsage.getTiers().length; i++) {
final Tier curTier = curUsage.getTiers()[i];
final TieredBlock[] curTieredBlocks = curTier.getTieredBlocks();
final CatalogOverrideTierDefinitionModelDao overriddenTier = Iterables.tryFind(tierDefs, new Predicate<CatalogOverrideTierDefinitionModelDao>() {
@Override
public boolean apply(final CatalogOverrideTierDefinitionModelDao input) {
final List<CatalogOverrideBlockDefinitionModelDao> blockDefs = overrideDao.getOverriddenTierBlocks(input.getRecordId(), context);
for (CatalogOverrideBlockDefinitionModelDao blockDef : blockDefs) {
String unitName = blockDef.getParentUnitName();
Double max = blockDef.getMax();
Double size = blockDef.getSize();
for (TieredBlock curTieredBlock : curTieredBlocks) {
if (unitName.equals(curTieredBlock.getUnit().getName()) && Double.compare(size, curTieredBlock.getSize()) == 0 && Double.compare(max, curTieredBlock.getMax()) == 0) {
return true;
}
}
}
return false;
}
}).orNull();
if (overriddenTier != null) {
List<TieredBlockPriceOverride> tieredBlockPriceOverrides = getTieredBlockPriceOverrides(curTier, overriddenTier, context);
tierPriceOverrides.add(new DefaultTierPriceOverride(tieredBlockPriceOverrides));
}
}
return tierPriceOverrides;
}
Aggregations