use of org.killbill.billing.subscription.exceptions.SubscriptionBaseError in project killbill by killbill.
the class DefaultSubscriptionInternalApi method verifyAndBuildSubscriptionSpecifiers.
private List<SubscriptionSpecifier> verifyAndBuildSubscriptionSpecifiers(final UUID bundleId, final String externalKey, final Iterable<EntitlementSpecifier> entitlements, final boolean isMigrated, final InternalCallContext context, final DateTime now, final DateTime effectiveDate, final Catalog catalog, final CallContext callContext) throws SubscriptionBaseApiException, CatalogApiException {
final List<SubscriptionSpecifier> subscriptions = new ArrayList<SubscriptionSpecifier>();
boolean first = true;
final List<SubscriptionBase> subscriptionsForBundle = getSubscriptionsForBundle(bundleId, null, context);
for (final EntitlementSpecifier entitlement : entitlements) {
final PlanPhaseSpecifier spec = entitlement.getPlanPhaseSpecifier();
final PlanPhasePriceOverridesWithCallContext overridesWithContext = new DefaultPlanPhasePriceOverridesWithCallContext(entitlement.getOverrides(), callContext);
final Plan plan = catalog.createOrFindPlan(spec, overridesWithContext, effectiveDate);
final PlanPhase phase = plan.getAllPhases()[0];
if (phase == null) {
throw new SubscriptionBaseError(String.format("No initial PlanPhase for Product %s, term %s and set %s does not exist in the catalog", spec.getProductName(), spec.getBillingPeriod().toString(), plan.getPriceListName()));
}
if (first) {
first = false;
if (plan.getProduct().getCategory() != ProductCategory.BASE) {
throw new SubscriptionBaseApiException(new IllegalArgumentException(), ErrorCode.SUB_CREATE_NO_BP.getCode(), "Missing Base Subscription.");
}
}
// verify the number of subscriptions (of the same kind) allowed per bundle and the existing ones
if (ProductCategory.ADD_ON.toString().equalsIgnoreCase(plan.getProduct().getCategory().toString())) {
if (plan.getPlansAllowedInBundle() != -1 && plan.getPlansAllowedInBundle() > 0) {
final int existingAddOnsWithSamePlanName = addonUtils.countExistingAddOnsWithSamePlanName(subscriptionsForBundle, plan.getName());
final int currentAddOnsWithSamePlanName = countCurrentAddOnsWithSamePlanName(entitlements, catalog, plan.getName(), effectiveDate, callContext);
if ((existingAddOnsWithSamePlanName + currentAddOnsWithSamePlanName) > plan.getPlansAllowedInBundle()) {
// a new ADD_ON subscription of the same plan can't be added because it has reached its limit by bundle
throw new SubscriptionBaseApiException(ErrorCode.SUB_CREATE_AO_MAX_PLAN_ALLOWED_BY_BUNDLE, plan.getName());
}
}
}
final SubscriptionSpecifier subscription = new SubscriptionSpecifier();
subscription.setRealPriceList(plan.getPriceListName());
subscription.setEffectiveDate(effectiveDate);
subscription.setProcessedDate(now);
subscription.setPlan(plan);
subscription.setInitialPhase(spec.getPhaseType());
subscription.setBuilder(new SubscriptionBuilder().setId(UUIDs.randomUUID()).setBundleId(bundleId).setBundleExternalKey(externalKey).setCategory(plan.getProduct().getCategory()).setBundleStartDate(effectiveDate).setAlignStartDate(effectiveDate).setMigrated(isMigrated));
subscriptions.add(subscription);
}
return subscriptions;
}
use of org.killbill.billing.subscription.exceptions.SubscriptionBaseError in project killbill by killbill.
the class DefaultSubscriptionDao method uncancelSubscription.
@Override
public void uncancelSubscription(final DefaultSubscriptionBase subscription, final List<SubscriptionBaseEvent> uncancelEvents, final InternalCallContext context) {
final InternalCallContext contextWithUpdatedDate = contextWithUpdatedDate(context);
transactionalSqlDao.execute(new EntitySqlDaoTransactionWrapper<Void>() {
@Override
public Void inTransaction(final EntitySqlDaoWrapperFactory entitySqlDaoWrapperFactory) throws Exception {
final SubscriptionEventSqlDao transactional = entitySqlDaoWrapperFactory.become(SubscriptionEventSqlDao.class);
final UUID subscriptionId = subscription.getId();
SubscriptionEventModelDao cancelledEvent = null;
final Date now = clock.getUTCNow().toDate();
final List<SubscriptionEventModelDao> eventModels = transactional.getFutureActiveEventForSubscription(subscriptionId.toString(), now, contextWithUpdatedDate);
for (final SubscriptionEventModelDao cur : eventModels) {
if (cur.getUserType() == ApiEventType.CANCEL) {
if (cancelledEvent != null) {
throw new SubscriptionBaseError(String.format("Found multiple cancelWithRequestedDate active events for subscriptions %s", subscriptionId.toString()));
}
cancelledEvent = cur;
}
}
if (cancelledEvent != null) {
final String cancelledEventId = cancelledEvent.getId().toString();
transactional.unactiveEvent(cancelledEventId, contextWithUpdatedDate);
for (final SubscriptionBaseEvent cur : uncancelEvents) {
transactional.create(new SubscriptionEventModelDao(cur), contextWithUpdatedDate);
recordFutureNotificationFromTransaction(entitySqlDaoWrapperFactory, cur.getEffectiveDate(), new SubscriptionNotificationKey(cur.getId()), contextWithUpdatedDate);
}
// Notify the Bus of the latest requested change
notifyBusOfRequestedChange(entitySqlDaoWrapperFactory, subscription, uncancelEvents.get(uncancelEvents.size() - 1), SubscriptionBaseTransitionType.UNCANCEL, contextWithUpdatedDate);
}
return null;
}
});
}
use of org.killbill.billing.subscription.exceptions.SubscriptionBaseError in project killbill by killbill.
the class AddonUtils method isAddonIncludedFromPlanName.
public boolean isAddonIncludedFromPlanName(final String basePlanName, final Plan targetAddOnPlan, final DateTime requestedDate, final InternalTenantContext context) {
try {
final Plan plan = catalogService.getFullCatalog(true, true, context).findPlan(basePlanName, requestedDate);
final Product product = plan.getProduct();
return isAddonIncluded(product, targetAddOnPlan);
} catch (CatalogApiException e) {
throw new SubscriptionBaseError(e);
}
}
use of org.killbill.billing.subscription.exceptions.SubscriptionBaseError in project killbill by killbill.
the class PlanAligner method getTimedPhaseOnCreate.
private List<TimedPhase> getTimedPhaseOnCreate(final DateTime subscriptionStartDate, final DateTime bundleStartDate, final Plan plan, @Nullable final PhaseType initialPhase, final SubscriptionCatalog 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);
}
use of org.killbill.billing.subscription.exceptions.SubscriptionBaseError in project killbill by killbill.
the class TestUserApiError method testChangeSubscriptionWithPolicy.
@Test(groups = "fast")
public void testChangeSubscriptionWithPolicy() throws Exception {
final SubscriptionBase subscription = testUtil.createSubscription(bundle, "Shotgun", BillingPeriod.ANNUAL, PriceListSet.DEFAULT_PRICELIST_NAME);
try {
final PlanPhaseSpecifier planPhaseSpecifier = new PlanPhaseSpecifier("Pistol", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME);
subscription.changePlanWithPolicy(new DefaultEntitlementSpecifier(planPhaseSpecifier), BillingActionPolicy.ILLEGAL, callContext);
Assert.fail("Call changePlanWithPolicy should have failed");
} catch (final SubscriptionBaseError error) {
assertTrue(true);
assertEquals(subscriptionInternalApi.getSubscriptionFromId(subscription.getId(), internalCallContext).getCurrentPlan().getRecurringBillingPeriod(), BillingPeriod.ANNUAL);
}
// Assume the call takes less than a second
final PlanPhaseSpecifier planPhaseSpecifier = new PlanPhaseSpecifier("Pistol", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME);
assertEquals(DefaultClock.truncateMs(subscription.changePlanWithPolicy(new DefaultEntitlementSpecifier(planPhaseSpecifier), BillingActionPolicy.IMMEDIATE, callContext)), DefaultClock.truncateMs(clock.getUTCNow()));
assertEquals(subscriptionInternalApi.getSubscriptionFromId(subscription.getId(), internalCallContext).getCurrentPlan().getRecurringBillingPeriod(), BillingPeriod.MONTHLY);
}
Aggregations