use of org.killbill.billing.catalog.api.PlanPhasePriceOverride in project killbill by killbill.
the class TestCatalogOverrideDao method testGetOverriddenPlanPhasesWithUsageOverrides.
@Test(groups = "slow")
public void testGetOverriddenPlanPhasesWithUsageOverrides() throws Exception {
final StandaloneCatalog catalog = getCatalog("SpyCarAdvanced.xml");
final Plan plan = catalog.findPlan("gas-monthly");
final PlanPhasePriceOverride[] resolvedOverrides = new PlanPhasePriceOverride[plan.getAllPhases().length];
List<TieredBlockPriceOverride> tieredBlockPriceOverrides = new ArrayList<TieredBlockPriceOverride>();
DefaultTieredBlockPriceOverride tieredBlockPriceOverride = new DefaultTieredBlockPriceOverride("gallons", new Double("1"), new BigDecimal(4), Currency.USD, new Double("100"));
tieredBlockPriceOverrides.add(tieredBlockPriceOverride);
List<TierPriceOverride> tierPriceOverrides = new ArrayList<TierPriceOverride>();
DefaultTierPriceOverride tierPriceOverride = new DefaultTierPriceOverride(tieredBlockPriceOverrides);
tierPriceOverrides.add(tierPriceOverride);
List<UsagePriceOverride> usagePriceOverrides = new ArrayList<UsagePriceOverride>();
DefaultUsagePriceOverride usagePriceOverride = new DefaultUsagePriceOverride("gas-monthly-in-arrear", UsageType.CONSUMABLE, tierPriceOverrides);
usagePriceOverrides.add(usagePriceOverride);
// Override the gallons price from $3.95 to $4 and also the recurring price from $0 to $348.64
resolvedOverrides[0] = new DefaultPlanPhasePriceOverride(plan.getFinalPhase().getName(), Currency.USD, BigDecimal.ZERO, new BigDecimal("348.64"), usagePriceOverrides);
final CatalogOverridePlanDefinitionModelDao newPlan = catalogOverrideDao.getOrCreateOverridePlanDefinition(plan, new DateTime(catalog.getEffectiveDate()), resolvedOverrides, internalCallContext);
final List<CatalogOverridePhaseDefinitionModelDao> phases = catalogOverrideDao.getOverriddenPlanPhases(newPlan.getRecordId(), internalCallContext);
assertEquals(phases.size(), 1);
final CatalogOverridePhaseDefinitionModelDao curPhase = phases.get(0);
assertEquals(curPhase.getCurrency(), resolvedOverrides[0].getCurrency().name());
assertEquals(curPhase.getFixedPrice().compareTo(resolvedOverrides[0].getFixedPrice()), 0);
assertEquals(curPhase.getRecurringPrice().compareTo(resolvedOverrides[0].getRecurringPrice()), 0);
assertEquals(curPhase.getParentPhaseName(), resolvedOverrides[0].getPhaseName());
final List<CatalogOverrideUsageDefinitionModelDao> usages = catalogOverrideDao.getOverriddenPhaseUsages(curPhase.getRecordId(), internalCallContext);
assertEquals(usages.size(), 1);
final CatalogOverrideUsageDefinitionModelDao curUsage = usages.get(0);
assertEquals(curUsage.getParentUsageName(), usagePriceOverride.getName());
assertEquals(curUsage.getType(), usagePriceOverride.getUsageType().toString());
final List<CatalogOverrideTierDefinitionModelDao> tiers = catalogOverrideDao.getOverriddenUsageTiers(curUsage.getRecordId(), internalCallContext);
assertEquals(tiers.size(), 1);
final CatalogOverrideTierDefinitionModelDao curTier = tiers.get(0);
final List<CatalogOverrideBlockDefinitionModelDao> tierBlocks = catalogOverrideDao.getOverriddenTierBlocks(curTier.getRecordId(), internalCallContext);
assertEquals(tierBlocks.size(), 1);
final CatalogOverrideBlockDefinitionModelDao curTieredBlock = tierBlocks.get(0);
assertEquals(curTieredBlock.getParentUnitName(), tieredBlockPriceOverride.getUnitName());
assertEquals(curTieredBlock.getPrice().compareTo(tieredBlockPriceOverride.getPrice()), 0);
assertEquals(curTieredBlock.getSize(), (double) tieredBlockPriceOverride.getSize());
assertEquals(curTieredBlock.getMax(), (double) tieredBlockPriceOverride.getMax());
}
use of org.killbill.billing.catalog.api.PlanPhasePriceOverride in project killbill by killbill.
the class EntitlementLoggingHelper method logPlanPhasePriceOverrides.
private static void logPlanPhasePriceOverrides(final StringBuilder logLine, final List<PlanPhasePriceOverride> overrides) {
if (overrides != null && !overrides.isEmpty()) {
logLine.append(", overrides='[");
boolean first = true;
for (final PlanPhasePriceOverride cur : overrides) {
if (!first) {
logLine.append(",");
}
logPlanPhasePriceOverride(logLine, cur);
first = false;
}
logLine.append("]'");
}
}
use of org.killbill.billing.catalog.api.PlanPhasePriceOverride in project killbill by killbill.
the class DefaultPriceOverride method getOrCreateOverriddenPlan.
@Override
public DefaultPlan getOrCreateOverriddenPlan(final StandaloneCatalog standaloneCatalog, final Plan parentPlan, final DateTime catalogEffectiveDate, final List<PlanPhasePriceOverride> overrides, @Nullable final InternalCallContext context) throws CatalogApiException {
final PlanPhasePriceOverride[] resolvedOverride = new PlanPhasePriceOverride[parentPlan.getAllPhases().length];
int index = 0;
for (final PlanPhase curPhase : parentPlan.getAllPhases()) {
final PlanPhasePriceOverride curOverride = Iterables.tryFind(overrides, new Predicate<PlanPhasePriceOverride>() {
@Override
public boolean apply(final PlanPhasePriceOverride input) {
if (input.getPhaseName() != null) {
return input.getPhaseName().equals(curPhase.getName());
}
// If the phaseName was not passed, we infer by matching the phaseType. This obviously would not work in a case where
// a plan is defined with multiple phases of the same type.
final PlanPhaseSpecifier curPlanPhaseSpecifier = input.getPlanPhaseSpecifier();
if (curPlanPhaseSpecifier.getPhaseType().equals(curPhase.getPhaseType())) {
return true;
}
return false;
}
}).orNull();
if (curOverride != null) {
List<UsagePriceOverride> resolvedUsageOverrides = getResolvedUsageOverrides(curPhase.getUsages(), curOverride.getUsagePriceOverrides());
resolvedOverride[index++] = new DefaultPlanPhasePriceOverride(curPhase.getName(), curOverride.getCurrency(), curOverride.getFixedPrice(), curOverride.getRecurringPrice(), resolvedUsageOverrides);
} else {
resolvedOverride[index++] = null;
}
}
for (int i = 0; i < resolvedOverride.length; i++) {
final PlanPhasePriceOverride curOverride = resolvedOverride[i];
if (curOverride != null) {
final DefaultPlanPhase curPhase = (DefaultPlanPhase) parentPlan.getAllPhases()[i];
if (curPhase.getFixed() == null && curOverride.getFixedPrice() != null) {
final String error = String.format("There is no existing fixed price for the phase %s", curPhase.getName());
throw new CatalogApiException(ErrorCode.CAT_INVALID_INVALID_PRICE_OVERRIDE, parentPlan.getName(), error);
}
if (curPhase.getRecurring() == null && curOverride.getRecurringPrice() != null) {
final String error = String.format("There is no existing recurring price for the phase %s", curPhase.getName());
throw new CatalogApiException(ErrorCode.CAT_INVALID_INVALID_PRICE_OVERRIDE, parentPlan.getName(), error);
}
}
}
final String planName;
if (context != null) {
final CatalogOverridePlanDefinitionModelDao overriddenPlan = overrideDao.getOrCreateOverridePlanDefinition(parentPlan, catalogEffectiveDate, resolvedOverride, context);
planName = new StringBuffer(parentPlan.getName()).append("-").append(overriddenPlan.getRecordId()).toString();
} else {
planName = new StringBuffer(parentPlan.getName()).append("-dryrun-").append(DRY_RUN_PLAN_IDX.incrementAndGet()).toString();
}
final DefaultPlan result = new DefaultPlan(planName, (DefaultPlan) parentPlan, resolvedOverride);
result.initialize(standaloneCatalog);
if (context == null) {
overriddenPlanCache.addDryRunPlan(planName, result);
}
return result;
}
use of org.killbill.billing.catalog.api.PlanPhasePriceOverride in project killbill by killbill.
the class TestDefaultPriceOverride method testBasicWithLegacyNamePattern.
@Test(groups = "slow")
public void testBasicWithLegacyNamePattern() throws Exception {
final StandaloneCatalog catalog = getCatalog("SpyCarAdvanced.xml");
catalog.initialize(catalog);
final Plan plan = catalog.findPlan("discount-standard-monthly");
final List<PlanPhasePriceOverride> overrides = new ArrayList<PlanPhasePriceOverride>();
final PlanPhasePriceOverride phase1 = new DefaultPlanPhasePriceOverride(plan.getAllPhases()[0].getName(), Currency.USD, BigDecimal.ONE, null, null);
overrides.add(phase1);
final PlanPhasePriceOverride phase3 = new DefaultPlanPhasePriceOverride(plan.getAllPhases()[2].getName(), Currency.USD, null, new BigDecimal("142.41"), null);
overrides.add(phase3);
final DefaultPlan overriddenPlan = priceOverride.getOrCreateOverriddenPlan(catalog, plan, new DateTime(catalog.getEffectiveDate()), overrides, internalCallContext);
final String[] parts = priceOverridePattern.getPlanParts(overriddenPlan.getName());
assertEquals(parts[0], plan.getName());
assertEquals(overriddenPlan.getProduct().getName(), plan.getProduct().getName());
assertEquals(overriddenPlan.getRecurringBillingPeriod(), plan.getRecurringBillingPeriod());
if (plan.getEffectiveDateForExistingSubscriptions() != null) {
assertEquals(overriddenPlan.getEffectiveDateForExistingSubscriptions().compareTo(plan.getEffectiveDateForExistingSubscriptions()), 0);
}
assertNotEquals(overriddenPlan.getFinalPhase().getName(), plan.getFinalPhase().getName());
assertEquals(overriddenPlan.getPlansAllowedInBundle(), plan.getPlansAllowedInBundle());
assertEquals(overriddenPlan.getAllPhases().length, overriddenPlan.getAllPhases().length);
for (int i = 0; i < overriddenPlan.getAllPhases().length; i++) {
final DefaultPlanPhase initialPhase = (DefaultPlanPhase) plan.getAllPhases()[i];
final DefaultPlanPhase newPhase = (DefaultPlanPhase) overriddenPlan.getAllPhases()[i];
final PlanPhasePriceOverride override = Iterables.tryFind(overrides, new Predicate<PlanPhasePriceOverride>() {
@Override
public boolean apply(final PlanPhasePriceOverride input) {
return input.getPhaseName().equals(initialPhase.getName());
}
}).orNull();
assertNotEquals(newPhase.getName(), initialPhase.getName());
assertEquals(newPhase.getDuration(), initialPhase.getDuration());
assertEquals(newPhase.getPhaseType(), initialPhase.getPhaseType());
assertEquals(newPhase.getUsages().length, initialPhase.getUsages().length);
if (initialPhase.getFixed() != null) {
assertEquals(newPhase.getFixed().getType(), initialPhase.getFixed().getType());
assertInternationalPrice(newPhase.getFixed().getPrice(), initialPhase.getFixed().getPrice(), override, true);
}
if (initialPhase.getRecurring() != null) {
assertInternationalPrice(newPhase.getRecurring().getRecurringPrice(), initialPhase.getRecurring().getRecurringPrice(), override, false);
}
}
}
use of org.killbill.billing.catalog.api.PlanPhasePriceOverride in project killbill by killbill.
the class DefaultOverriddenPlanCache method loadOverriddenPlan.
private DefaultPlan loadOverriddenPlan(final String planName, final StandaloneCatalog catalog, final InternalTenantContext context) throws CatalogApiException {
final String[] parts = priceOverridePattern.getPlanParts(planName);
final String parentPlanName = parts[0];
final Long planDefRecordId = Long.parseLong(parts[1]);
final List<CatalogOverridePhaseDefinitionModelDao> phaseDefs = overrideDao.getOverriddenPlanPhases(planDefRecordId, context);
final DefaultPlan defaultPlan = catalog.findPlan(parentPlanName);
final PlanPhasePriceOverride[] overrides = createOverrides(defaultPlan, phaseDefs, context);
final DefaultPlan result = new DefaultPlan(priceOverridePattern.getPlanName(parts), defaultPlan, overrides);
result.initialize(catalog);
return result;
}
Aggregations