@Test(groups = "fast") public void testCalculateBCDForAOWithBPCancelledBundleAligned() throws Exception { final DateTimeZone accountTimeZone = DateTimeZone.UTC; final DateTime bpStartDateUTC = new DateTime(2012, 7, 16, 21, 0, 0, DateTimeZone.UTC); final int expectedBCDUTC = 16; // Create a Bundle associated with a subscription final SubscriptionBaseBundle bundle = Mockito.mock(SubscriptionBaseBundle.class); final SubscriptionBase subscription = Mockito.mock(SubscriptionBase.class); Mockito.when(subscription.getStartDate()).thenReturn(bpStartDateUTC); // Create a the base plan associated with that subscription final Plan plan = Mockito.mock(Plan.class); final Catalog catalog = Mockito.mock(Catalog.class); Mockito.when(catalog.findPlan(Mockito.anyString(), Mockito.<DateTime>any(), Mockito.<DateTime>any())).thenReturn(plan); Mockito.when(subscription.getLastActivePlan()).thenReturn(plan); Mockito.when(subscription.getDateOfFirstRecurringNonZeroCharge()).thenReturn(bpStartDateUTC); final ImmutableAccountData account = Mockito.mock(ImmutableAccountData.class); Mockito.when(account.getTimeZone()).thenReturn(accountTimeZone); final Integer billCycleDayLocal = BillCycleDayCalculator.calculateBcdForAlignment(new HashMap<UUID, Integer>(), subscription, subscription, BillingAlignment.BUNDLE, internalCallContext, 0); Assert.assertEquals(billCycleDayLocal, (Integer) expectedBCDUTC); }
private BillingPeriod getBillingPeriod(final Catalog catalog, @Nullable final String phaseName, final DateTime effectiveDate, DateTime startDate) throws CatalogApiException { if (phaseName == null) { return BillingPeriod.NO_BILLING_PERIOD; } final PlanPhase phase = catalog.findPhase(phaseName, effectiveDate, startDate); return phase.getRecurring() != null ? phase.getRecurring().getBillingPeriod() : BillingPeriod.NO_BILLING_PERIOD; }
@Override public boolean cancelWithPolicyNoValidationAndCatalog(final Iterable<DefaultSubscriptionBase> subscriptions, final BillingActionPolicy policy, final Catalog catalog, final InternalCallContext context) throws SubscriptionBaseApiException { final Map<DefaultSubscriptionBase, DateTime> subscriptionsWithEffectiveDate = new HashMap<DefaultSubscriptionBase, DateTime>(); try { for (final DefaultSubscriptionBase subscription : subscriptions) { final BillingAlignment billingAlignment = (subscription.getState() == EntitlementState.PENDING ? null : catalog.billingAlignment(new PlanPhaseSpecifier(subscription.getLastActivePlan().getName(), subscription.getLastActivePhase().getPhaseType()), clock.getUTCNow(), subscription.getStartDate())); final Integer accountBillCycleDayLocal = accountInternalApi.getBCD(context); final DateTime effectiveDate = subscription.getPlanChangeEffectiveDate(policy, billingAlignment, accountBillCycleDayLocal, context); subscriptionsWithEffectiveDate.put(subscription, effectiveDate); } return doCancelPlan(subscriptionsWithEffectiveDate, catalog, context); } catch (final CatalogApiException e) { throw new SubscriptionBaseApiException(e); } catch (final AccountApiException e) { throw new SubscriptionBaseApiException(e); } }
final Plan nextPlan = (nextPlanName != null) ? catalog.findPlan(nextPlanName, cur.getEffectiveDate(), getAlignStartDate()) : null; final PlanPhase nextPhase = (nextPlan != null && nextPhaseName != null) ? nextPlan.findPhase(nextPhaseName) : null; final PriceList nextPriceList = (nextPlan != null) ? catalog.findPriceListForPlan(nextPlanName, cur.getEffectiveDate(), getAlignStartDate()) : null;
private List<TimedPhase> getTimedPhaseOnCreate(final DateTime subscriptionStartDate, final DateTime bundleStartDate, final Plan plan, @Nullable final PhaseType initialPhase, final Catalog catalog, final DateTime catalogEffectiveDate, final InternalTenantContext context) throws CatalogApiException, SubscriptionBaseApiException { final PlanSpecifier planSpecifier = new PlanSpecifier(plan.getName()); final DateTime planStartDate; final PlanAlignmentCreate alignment = catalog.planCreateAlignment(planSpecifier, catalogEffectiveDate, subscriptionStartDate); switch (alignment) { case START_OF_SUBSCRIPTION: planStartDate = subscriptionStartDate; break; case START_OF_BUNDLE: planStartDate = bundleStartDate; break; default: throw new SubscriptionBaseError(String.format("Unknown PlanAlignmentCreate %s", alignment)); } return getPhaseAlignments(plan, initialPhase, planStartDate); }
final Plan plan = isInputSpecNullOrEmpty ? null : catalog.createOrFindPlan(inputSpec, overridesWithContext, utcNow); final PlanPhaseSpecifier spec = new PlanPhaseSpecifier(currentPlan.getName(), subscriptionForCancellation.getCurrentPhase().getPhaseType()); policy = catalog.planCancelPolicy(spec, clock.getUTCNow(), subscriptionForCancellation.getStartDate());
final PlanPhasePriceOverridesWithCallContext overridesWithContext = new DefaultPlanPhasePriceOverridesWithCallContext(cur.getOverrides(), callContext); final Plan plan = catalog.createOrFindPlan(cur.getPlanPhaseSpecifier(), overridesWithContext, effectiveDate);
final Plan nextPlan = (nextPlanName != null) ? catalog.findPlan(nextPlanName, cur.getEffectiveDate(), getAlignStartDate()) : null; final PlanPhase nextPhase = (nextPlan != null && nextPhaseName != null) ? nextPlan.findPhase(nextPhaseName) : null; final PriceList nextPriceList = (nextPlan != null) ? catalog.findPriceListForPlan(nextPlanName, cur.getEffectiveDate(), getAlignStartDate()) : null;
@Test(groups = "slow") public void testAddonCreateWithBundleAlign() throws CatalogApiException, SubscriptionBaseApiException { final String aoProduct = "Telescopic-Scope"; final BillingPeriod aoTerm = BillingPeriod.MONTHLY; final String aoPriceList = PriceListSet.DEFAULT_PRICELIST_NAME; // This is just to double check our test catalog gives us what we want before we start the test final PlanSpecifier planSpecifier = new PlanSpecifier(aoProduct, aoTerm, aoPriceList); final DateTime utcNow = clock.getUTCNow(); final PlanAlignmentCreate alignment = catalog.planCreateAlignment(planSpecifier, utcNow, utcNow); assertEquals(alignment, PlanAlignmentCreate.START_OF_BUNDLE); testAddonCreateInternal(aoProduct, aoTerm, aoPriceList, alignment); }
final Plan plan = isInputSpecNullOrEmpty ? null : catalog.createOrFindPlan(inputSpec, overridesWithContext, utcNow); final PlanPhaseSpecifier spec = new PlanPhaseSpecifier(currentPlan.getName(), subscriptionForCancellation.getCurrentPhase().getPhaseType()); policy = catalog.planCancelPolicy(spec, clock.getUTCNow(), subscriptionForCancellation.getStartDate());
private void doChangePlan(final DefaultSubscriptionBase subscription, final EntitlementSpecifier spec, final DateTime effectiveDate, final CallContext context) throws SubscriptionBaseApiException, CatalogApiException { final InternalCallContext internalCallContext = createCallContextFromBundleId(subscription.getBundleId(), context); final PlanPhasePriceOverridesWithCallContext overridesWithContext = new DefaultPlanPhasePriceOverridesWithCallContext(spec.getOverrides(), context); final Catalog fullCatalog = catalogInternalApi.getFullCatalog(true, true, internalCallContext); final PlanPhaseSpecifier planPhaseSpecifier = spec.getPlanPhaseSpecifier(); final Plan newPlan = fullCatalog.createOrFindPlan(planPhaseSpecifier, overridesWithContext, effectiveDate, subscription.getStartDate()); final PhaseType initialPhaseType = planPhaseSpecifier.getPhaseType(); if (ProductCategory.ADD_ON.toString().equalsIgnoreCase(newPlan.getProduct().getCategory().toString())) { if (newPlan.getPlansAllowedInBundle() != -1 && newPlan.getPlansAllowedInBundle() > 0 && addonUtils.countExistingAddOnsWithSamePlanName(dao.getSubscriptions(subscription.getBundleId(), null, fullCatalog, internalCallContext), newPlan.getName()) >= newPlan.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, newPlan.getName()); } } if (newPlan.getProduct().getCategory() != subscription.getCategory()) { throw new SubscriptionBaseApiException(ErrorCode.SUB_CHANGE_INVALID, subscription.getId()); } final List<DefaultSubscriptionBase> addOnSubscriptionsToBeCancelled = new ArrayList<DefaultSubscriptionBase>(); final List<SubscriptionBaseEvent> addOnCancelEvents = new ArrayList<SubscriptionBaseEvent>(); final List<SubscriptionBaseEvent> changeEvents = getEventsOnChangePlan(subscription, newPlan, newPlan.getPriceListName(), effectiveDate, true, addOnSubscriptionsToBeCancelled, addOnCancelEvents, initialPhaseType, spec.getBillCycleDay(), fullCatalog, internalCallContext); dao.changePlan(subscription, changeEvents, addOnSubscriptionsToBeCancelled, addOnCancelEvents, fullCatalog, internalCallContext); subscription.rebuildTransitions(dao.getEventsForSubscription(subscription.getId(), internalCallContext), fullCatalog); }
final Plan basePlan = catalog.findPlan(baseChangeEvent.getEventPlan(), baseChangeEvent.getEffectiveDate(), cur.getAlignStartDate()); final Product baseProduct = basePlan.getProduct();
final PlanPhase currentPhase = existingEvent.getPlanPhaseName() != null ? catalog.findPhase(existingEvent.getPlanPhaseName(), effectiveDate, subscription.getAlignStartDate()) : null;
@Test(groups = "slow") public void testAddonCreateWithSubscriptionAlign() throws SubscriptionBaseApiException, CatalogApiException { final String aoProduct = "Laser-Scope"; final BillingPeriod aoTerm = BillingPeriod.MONTHLY; final String aoPriceList = PriceListSet.DEFAULT_PRICELIST_NAME; // This is just to double check our test catalog gives us what we want before we start the test final PlanSpecifier planSpecifier = new PlanSpecifier(aoProduct, aoTerm, aoPriceList); final DateTime utcNow = clock.getUTCNow(); final PlanAlignmentCreate alignment = catalog.planCreateAlignment(planSpecifier, utcNow, utcNow); assertEquals(alignment, PlanAlignmentCreate.START_OF_SUBSCRIPTION); testAddonCreateInternal(aoProduct, aoTerm, aoPriceList, alignment); }
final BillingAlignment alignment = catalog.billingAlignment(getPlanPhaseSpecifierFromTransition(catalog, transition), transition.getEffectiveTransitionTime(), subscription.getStartDate());
@Override public DateTime getDryRunChangePlanEffectiveDate(final SubscriptionBase subscription, final EntitlementSpecifier spec, final DateTime requestedDateWithMs, final BillingActionPolicy requestedPolicy, 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 = catalogInternalApi.getFullCatalog(true, true, context); final DateTime effectiveDate = (requestedDateWithMs != null) ? DefaultClock.truncateMs(requestedDateWithMs) : null; final DateTime effectiveCatalogDate = effectiveDate != null ? effectiveDate : context.getCreatedDate(); final PlanPhasePriceOverridesWithCallContext overridesWithContext = new DefaultPlanPhasePriceOverridesWithCallContext(spec.getOverrides(), callContext); final Plan plan = catalog.createOrFindPlan(spec.getPlanPhaseSpecifier(), overridesWithContext, effectiveCatalogDate, subscription.getStartDate()); if (ProductCategory.ADD_ON.toString().equalsIgnoreCase(plan.getProduct().getCategory().toString())) { if (plan.getPlansAllowedInBundle() != -1 && plan.getPlansAllowedInBundle() > 0 && addonUtils.countExistingAddOnsWithSamePlanName(getSubscriptionsForBundle(subscription.getBundleId(), null, catalog, addonUtils, callContext, 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, effectiveDate, requestedPolicy, tenantContext); }
apiType = userEV.getApiEventType(); planPhaseName = userEV.getEventPlanPhase(); plan = (userEV.getEventPlan() != null) ? catalog.findPlan(userEV.getEventPlan(), cur.getEffectiveDate(), startDate) : null; phaseType = (plan != null && userEV.getEventPlanPhase() != null) ? plan.findPhase(userEV.getEventPlanPhase()).getPhaseType() : prevPhaseType; productName = (plan != null) ? plan.getProduct().getName() : prevProductName;
private BillingPeriod getBillingPeriod(final Catalog catalog, @Nullable final String phaseName, final DateTime effectiveDate, DateTime startDate) throws CatalogApiException { if (phaseName == null) { return BillingPeriod.NO_BILLING_PERIOD; } final PlanPhase phase = catalog.findPhase(phaseName, effectiveDate, startDate); return phase.getRecurring() != null ? phase.getRecurring().getBillingPeriod() : BillingPeriod.NO_BILLING_PERIOD; }
private List<TimedPhase> getTimedPhaseOnCreate(final DateTime subscriptionStartDate, final DateTime bundleStartDate, final Plan plan, @Nullable final PhaseType initialPhase, final Catalog catalog, final DateTime catalogEffectiveDate, final InternalTenantContext context) throws CatalogApiException, SubscriptionBaseApiException { final PlanSpecifier planSpecifier = new PlanSpecifier(plan.getName()); final DateTime planStartDate; final PlanAlignmentCreate alignment = catalog.planCreateAlignment(planSpecifier, catalogEffectiveDate, subscriptionStartDate); switch (alignment) { case START_OF_SUBSCRIPTION: planStartDate = subscriptionStartDate; break; case START_OF_BUNDLE: planStartDate = bundleStartDate; break; default: throw new SubscriptionBaseError(String.format("Unknown PlanAlignmentCreate %s", alignment)); } return getPhaseAlignments(plan, initialPhase, planStartDate); }
@Override public boolean cancelWithPolicyNoValidationAndCatalog(final Iterable<DefaultSubscriptionBase> subscriptions, final BillingActionPolicy policy, final Catalog catalog, final InternalCallContext context) throws SubscriptionBaseApiException { final Map<DefaultSubscriptionBase, DateTime> subscriptionsWithEffectiveDate = new HashMap<DefaultSubscriptionBase, DateTime>(); try { for (final DefaultSubscriptionBase subscription : subscriptions) { final BillingAlignment billingAlignment = (subscription.getState() == EntitlementState.PENDING ? null : catalog.billingAlignment(new PlanPhaseSpecifier(subscription.getLastActivePlan().getName(), subscription.getLastActivePhase().getPhaseType()), clock.getUTCNow(), subscription.getStartDate())); final Integer accountBillCycleDayLocal = accountInternalApi.getBCD(context); final DateTime effectiveDate = subscription.getPlanChangeEffectiveDate(policy, billingAlignment, accountBillCycleDayLocal, context); subscriptionsWithEffectiveDate.put(subscription, effectiveDate); } return doCancelPlan(subscriptionsWithEffectiveDate, catalog, context); } catch (final CatalogApiException e) { throw new SubscriptionBaseApiException(e); } catch (final AccountApiException e) { throw new SubscriptionBaseApiException(e); } }