Search in sources :

Example 1 with PlanPhasePriceOverride

use of org.killbill.billing.catalog.api.PlanPhasePriceOverride in project killbill by killbill.

the class DefaultSubscriptionInternalApi method getDryRunChangePlanEffectiveDate.

@Override
public DateTime getDryRunChangePlanEffectiveDate(final SubscriptionBase subscription, final PlanSpecifier spec, final DateTime requestedDateWithMs, final BillingActionPolicy requestedPolicy, final List<PlanPhasePriceOverride> overrides, final InternalCallContext context) throws SubscriptionBaseApiException, CatalogApiException {
    final TenantContext tenantContext = internalCallContextFactory.createTenantContext(context);
    final CallContext callContext = internalCallContextFactory.createCallContext(context);
    // verify the number of subscriptions (of the same kind) allowed per bundle
    final Catalog catalog = catalogService.getFullCatalog(true, true, context);
    final DateTime now = clock.getUTCNow();
    final DateTime effectiveDate = (requestedDateWithMs != null) ? DefaultClock.truncateMs(requestedDateWithMs) : now;
    final PlanPhasePriceOverridesWithCallContext overridesWithContext = new DefaultPlanPhasePriceOverridesWithCallContext(overrides, callContext);
    final Plan plan = catalog.createOrFindPlan(spec, overridesWithContext, effectiveDate);
    if (ProductCategory.ADD_ON.toString().equalsIgnoreCase(plan.getProduct().getCategory().toString())) {
        if (plan.getPlansAllowedInBundle() != -1 && plan.getPlansAllowedInBundle() > 0 && addonUtils.countExistingAddOnsWithSamePlanName(getSubscriptionsForBundle(subscription.getBundleId(), null, context), plan.getName()) >= plan.getPlansAllowedInBundle()) {
            // the plan can be changed to the new value, because it has reached its limit by bundle
            throw new SubscriptionBaseApiException(ErrorCode.SUB_CHANGE_AO_MAX_PLAN_ALLOWED_BY_BUNDLE, plan.getName());
        }
    }
    return apiService.dryRunChangePlan((DefaultSubscriptionBase) subscription, spec, requestedDateWithMs, requestedPolicy, tenantContext);
}
Also used : PlanPhasePriceOverridesWithCallContext(org.killbill.billing.catalog.api.PlanPhasePriceOverridesWithCallContext) InternalTenantContext(org.killbill.billing.callcontext.InternalTenantContext) TenantContext(org.killbill.billing.util.callcontext.TenantContext) Plan(org.killbill.billing.catalog.api.Plan) PlanPhasePriceOverridesWithCallContext(org.killbill.billing.catalog.api.PlanPhasePriceOverridesWithCallContext) CallContext(org.killbill.billing.util.callcontext.CallContext) InternalCallContext(org.killbill.billing.callcontext.InternalCallContext) Catalog(org.killbill.billing.catalog.api.Catalog) DateTime(org.joda.time.DateTime) SubscriptionBaseApiException(org.killbill.billing.subscription.api.user.SubscriptionBaseApiException) PlanPhasePriceOverride(org.killbill.billing.catalog.api.PlanPhasePriceOverride)

Example 2 with PlanPhasePriceOverride

use of org.killbill.billing.catalog.api.PlanPhasePriceOverride in project killbill by killbill.

the class TestWithPriceOverride method testCreatWithFixedPriceOverride.

@Test(groups = "slow")
public void testCreatWithFixedPriceOverride() throws Exception {
    // We take april as it has 30 days (easier to play with BCD)
    // Set clock to the initial start date - we implicitly assume here that the account timezone is UTC
    clock.setDay(new LocalDate(2012, 4, 1));
    final AccountData accountData = getAccountData(1);
    final Account account = createAccountWithNonOsgiPaymentMethod(accountData);
    accountChecker.checkAccount(account.getId(), accountData, callContext);
    final List<PlanPhasePriceOverride> overrides = new ArrayList<PlanPhasePriceOverride>();
    overrides.add(new DefaultPlanPhasePriceOverride("shotgun-monthly-trial", account.getCurrency(), BigDecimal.ONE, null));
    final DefaultEntitlement bpSubscription = createBaseEntitlementWithPriceOverrideAndCheckForCompletion(account.getId(), "bundleKey", "Shotgun", ProductCategory.BASE, BillingPeriod.MONTHLY, overrides, NextEvent.CREATE, NextEvent.BLOCK, NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
    // Check bundle after BP got created otherwise we get an error from auditApi.
    subscriptionChecker.checkSubscriptionCreated(bpSubscription.getId(), internalCallContext);
    invoiceChecker.checkInvoice(account.getId(), 1, callContext, new ExpectedInvoiceItemCheck(clock.getUTCToday(), null, InvoiceItemType.FIXED, new BigDecimal("1")));
}
Also used : Account(org.killbill.billing.account.api.Account) DefaultPlanPhasePriceOverride(org.killbill.billing.catalog.DefaultPlanPhasePriceOverride) AccountData(org.killbill.billing.account.api.AccountData) DefaultEntitlement(org.killbill.billing.entitlement.api.DefaultEntitlement) ArrayList(java.util.ArrayList) LocalDate(org.joda.time.LocalDate) ExpectedInvoiceItemCheck(org.killbill.billing.beatrix.util.InvoiceChecker.ExpectedInvoiceItemCheck) BigDecimal(java.math.BigDecimal) DefaultPlanPhasePriceOverride(org.killbill.billing.catalog.DefaultPlanPhasePriceOverride) PlanPhasePriceOverride(org.killbill.billing.catalog.api.PlanPhasePriceOverride) Test(org.testng.annotations.Test)

Example 3 with PlanPhasePriceOverride

use of org.killbill.billing.catalog.api.PlanPhasePriceOverride in project killbill by killbill.

the class PhasePriceOverrideJson method toPlanPhasePriceOverrides.

public static List<PlanPhasePriceOverride> toPlanPhasePriceOverrides(final List<PhasePriceOverrideJson> priceOverrides, final PlanSpecifier spec, final Currency currency) {
    if (priceOverrides == null || priceOverrides.isEmpty()) {
        return ImmutableList.<PlanPhasePriceOverride>of();
    }
    return ImmutableList.copyOf(Iterables.transform(priceOverrides, new Function<PhasePriceOverrideJson, PlanPhasePriceOverride>() {

        @Nullable
        @Override
        public PlanPhasePriceOverride apply(@Nullable final PhasePriceOverrideJson input) {
            if (input.getPhaseName() != null) {
                return new DefaultPlanPhasePriceOverride(input.getPhaseName(), currency, input.getFixedPrice(), input.getRecurringPrice());
            } else {
                final PhaseType phaseType = input.getPhaseType() != null ? PhaseType.valueOf(input.getPhaseType()) : null;
                final PlanPhaseSpecifier planPhaseSpecifier = spec.getPlanName() != null ? new PlanPhaseSpecifier(spec.getPlanName(), phaseType) : new PlanPhaseSpecifier(spec.getProductName(), spec.getBillingPeriod(), spec.getPriceListName(), phaseType);
                final Currency resolvedCurrency = input.getFixedPrice() != null || input.getRecurringPrice() != null ? currency : null;
                return new DefaultPlanPhasePriceOverride(planPhaseSpecifier, resolvedCurrency, input.getFixedPrice(), input.getRecurringPrice());
            }
        }
    }));
}
Also used : PlanPhaseSpecifier(org.killbill.billing.catalog.api.PlanPhaseSpecifier) Function(com.google.common.base.Function) DefaultPlanPhasePriceOverride(org.killbill.billing.catalog.DefaultPlanPhasePriceOverride) Currency(org.killbill.billing.catalog.api.Currency) PhaseType(org.killbill.billing.catalog.api.PhaseType) Nullable(javax.annotation.Nullable) DefaultPlanPhasePriceOverride(org.killbill.billing.catalog.DefaultPlanPhasePriceOverride) PlanPhasePriceOverride(org.killbill.billing.catalog.api.PlanPhasePriceOverride)

Example 4 with PlanPhasePriceOverride

use of org.killbill.billing.catalog.api.PlanPhasePriceOverride in project killbill by killbill.

the class TestDefaultPriceOverride method testBasic.

@Test(groups = "slow")
public void testBasic() throws Exception {
    final StandaloneCatalog catalog = XMLLoader.getObjectFromString(Resources.getResource("SpyCarAdvanced.xml").toExternalForm(), StandaloneCatalog.class);
    catalog.initialize(catalog, null);
    final Plan plan = catalog.findCurrentPlan("discount-standard-monthly");
    final List<PlanPhasePriceOverride> overrides = new ArrayList<PlanPhasePriceOverride>();
    final PlanPhasePriceOverride phase1 = new DefaultPlanPhasePriceOverride(plan.getAllPhases()[0].getName(), Currency.USD, BigDecimal.ONE, null);
    overrides.add(phase1);
    final PlanPhasePriceOverride phase3 = new DefaultPlanPhasePriceOverride(plan.getAllPhases()[2].getName(), Currency.USD, null, new BigDecimal("142.41"));
    overrides.add(phase3);
    final DefaultPlan overriddenPlan = priceOverride.getOrCreateOverriddenPlan(catalog, plan, new DateTime(catalog.getEffectiveDate()), overrides, internalCallContext);
    final Matcher m = DefaultPriceOverride.CUSTOM_PLAN_NAME_PATTERN.matcher(overriddenPlan.getName());
    assertTrue(m.matches());
    assertEquals(m.group(1), 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);
        }
    }
}
Also used : Matcher(java.util.regex.Matcher) ArrayList(java.util.ArrayList) Plan(org.killbill.billing.catalog.api.Plan) BigDecimal(java.math.BigDecimal) DateTime(org.joda.time.DateTime) Predicate(com.google.common.base.Predicate) PlanPhasePriceOverride(org.killbill.billing.catalog.api.PlanPhasePriceOverride) Test(org.testng.annotations.Test)

Example 5 with PlanPhasePriceOverride

use of org.killbill.billing.catalog.api.PlanPhasePriceOverride in project killbill by killbill.

the class EhCacheOverriddenPlanCache method loadOverriddenPlan.

private DefaultPlan loadOverriddenPlan(final String planName, final StaticCatalog catalog, final InternalTenantContext context) throws CatalogApiException {
    final Matcher m = DefaultPriceOverride.CUSTOM_PLAN_NAME_PATTERN.matcher(planName);
    if (!m.matches()) {
        throw new CatalogApiException(ErrorCode.CAT_NO_SUCH_PLAN, planName);
    }
    final String parentPlanName = m.group(1);
    final Long planDefRecordId = Long.parseLong(m.group(2));
    final List<CatalogOverridePhaseDefinitionModelDao> phaseDefs = overrideDao.getOverriddenPlanPhases(planDefRecordId, context);
    final DefaultPlan defaultPlan = (DefaultPlan) catalog.findCurrentPlan(parentPlanName);
    final PlanPhasePriceOverride[] overrides = createOverrides(defaultPlan, phaseDefs);
    final DefaultPlan result = new DefaultPlan(planName, defaultPlan, overrides);
    result.initialize((StandaloneCatalog) catalog, ((StandaloneCatalog) catalog).getCatalogURI());
    return result;
}
Also used : Matcher(java.util.regex.Matcher) CatalogOverridePhaseDefinitionModelDao(org.killbill.billing.catalog.dao.CatalogOverridePhaseDefinitionModelDao) DefaultPlan(org.killbill.billing.catalog.DefaultPlan) CatalogApiException(org.killbill.billing.catalog.api.CatalogApiException) PlanPhasePriceOverride(org.killbill.billing.catalog.api.PlanPhasePriceOverride) DefaultPlanPhasePriceOverride(org.killbill.billing.catalog.DefaultPlanPhasePriceOverride)

Aggregations

PlanPhasePriceOverride (org.killbill.billing.catalog.api.PlanPhasePriceOverride)49 ArrayList (java.util.ArrayList)28 DateTime (org.joda.time.DateTime)26 DefaultPlanPhasePriceOverride (org.killbill.billing.catalog.DefaultPlanPhasePriceOverride)24 Test (org.testng.annotations.Test)24 BigDecimal (java.math.BigDecimal)22 PlanPhaseSpecifier (org.killbill.billing.catalog.api.PlanPhaseSpecifier)16 Plan (org.killbill.billing.catalog.api.Plan)15 LocalDate (org.joda.time.LocalDate)14 Account (org.killbill.billing.account.api.Account)14 UsagePriceOverride (org.killbill.billing.catalog.api.UsagePriceOverride)13 ExpectedInvoiceItemCheck (org.killbill.billing.beatrix.util.InvoiceChecker.ExpectedInvoiceItemCheck)12 CatalogApiException (org.killbill.billing.catalog.api.CatalogApiException)11 DefaultEntitlement (org.killbill.billing.entitlement.api.DefaultEntitlement)10 DefaultEntitlementSpecifier (org.killbill.billing.entitlement.api.DefaultEntitlementSpecifier)9 Predicate (com.google.common.base.Predicate)8 InternalCallContext (org.killbill.billing.callcontext.InternalCallContext)8 Entitlement (org.killbill.billing.entitlement.api.Entitlement)8 SubscriptionBaseApiException (org.killbill.billing.subscription.api.user.SubscriptionBaseApiException)7 UUID (java.util.UUID)6