use of org.killbill.billing.catalog.api.ProductCategory in project killbill by killbill.
the class DefaultSubscriptionBaseTimeline method toExistingEvents.
private List<ExistingEvent> toExistingEvents(final Catalog catalog, final ProductCategory category, final List<SubscriptionBaseEvent> events) throws CatalogApiException {
final List<ExistingEvent> result = new LinkedList<SubscriptionBaseTimeline.ExistingEvent>();
String prevPlanName = null;
String prevProductName = null;
BillingPeriod prevBillingPeriod = null;
String prevPriceListName = null;
PhaseType prevPhaseType = null;
DateTime startDate = null;
for (final SubscriptionBaseEvent cur : events) {
if (!cur.isActive()) {
continue;
}
startDate = (startDate == null) ? cur.getEffectiveDate() : startDate;
String productName = null;
BillingPeriod billingPeriod = null;
String priceListName = null;
PhaseType phaseType = null;
String planName = null;
String planPhaseName = null;
Integer billCycleDayLocal = null;
ApiEventType apiType = null;
switch(cur.getType()) {
case PHASE:
final PhaseEvent phaseEV = (PhaseEvent) cur;
planPhaseName = phaseEV.getPhase();
phaseType = catalog.findPhase(phaseEV.getPhase(), cur.getEffectiveDate(), startDate).getPhaseType();
// A PHASE event always occurs within the same plan (and is never the first event)
planName = prevPlanName;
productName = prevProductName;
billingPeriod = getBillingPeriod(catalog, phaseEV.getPhase(), cur.getEffectiveDate(), startDate);
priceListName = prevPriceListName;
break;
case BCD_UPDATE:
final BCDEvent bcdEvent = (BCDEvent) cur;
billCycleDayLocal = bcdEvent.getBillCycleDayLocal();
break;
case API_USER:
final ApiEvent userEV = (ApiEvent) cur;
apiType = userEV.getApiEventType();
planName = userEV.getEventPlan();
planPhaseName = userEV.getEventPlanPhase();
final Plan plan = (userEV.getEventPlan() != null) ? catalog.findPlan(userEV.getEventPlan(), cur.getEffectiveDate(), startDate) : null;
phaseType = (userEV.getEventPlanPhase() != null) ? catalog.findPhase(userEV.getEventPlanPhase(), cur.getEffectiveDate(), startDate).getPhaseType() : prevPhaseType;
productName = (plan != null) ? plan.getProduct().getName() : prevProductName;
billingPeriod = (userEV.getEventPlanPhase() != null) ? getBillingPeriod(catalog, userEV.getEventPlanPhase(), cur.getEffectiveDate(), startDate) : prevBillingPeriod;
priceListName = (userEV.getPriceList() != null) ? userEV.getPriceList() : prevPriceListName;
break;
}
final SubscriptionBaseTransitionType transitionType = SubscriptionBaseTransitionData.toSubscriptionTransitionType(cur.getType(), apiType);
final String planNameWithClosure = planName;
final String planPhaseNameWithClosure = planPhaseName;
final Integer billCycleDayLocalWithClosure = billCycleDayLocal;
final PlanPhaseSpecifier spec = new PlanPhaseSpecifier(planName, phaseType);
result.add(new ExistingEvent() {
@Override
public SubscriptionBaseTransitionType getSubscriptionTransitionType() {
return transitionType;
}
@Override
public ProductCategory getProductCategory() {
return category;
}
@Override
public PlanPhaseSpecifier getPlanPhaseSpecifier() {
return spec;
}
@Override
public UUID getEventId() {
return cur.getId();
}
@Override
public DateTime getEffectiveDate() {
return cur.getEffectiveDate();
}
@Override
public String getPlanName() {
return planNameWithClosure;
}
@Override
public String getPlanPhaseName() {
return planPhaseNameWithClosure;
}
@Override
public Integer getBillCycleDayLocal() {
return billCycleDayLocalWithClosure;
}
});
prevPlanName = planName;
prevProductName = productName;
prevBillingPeriod = billingPeriod;
prevPriceListName = priceListName;
prevPhaseType = phaseType;
}
sortExistingEvent(result);
return result;
}
use of org.killbill.billing.catalog.api.ProductCategory in project killbill by killbill.
the class DefaultSubscriptionBaseTransferApi method transferBundle.
@Override
public SubscriptionBaseBundle transferBundle(final UUID sourceAccountId, final UUID destAccountId, final String bundleKey, final DateTime transferDate, final boolean transferAddOn, final boolean cancelImmediately, final CallContext context) throws SubscriptionBaseTransferApiException {
final InternalCallContext fromInternalCallContext = internalCallContextFactory.createInternalCallContext(sourceAccountId, context);
final InternalCallContext toInternalCallContext = internalCallContextFactory.createInternalCallContext(destAccountId, context);
try {
final SubscriptionCatalog catalog = subscriptionCatalogApi.getFullCatalog(fromInternalCallContext);
final DateTime effectiveTransferDate = transferDate == null ? context.getCreatedDate() : transferDate;
if (effectiveTransferDate.isAfter(context.getCreatedDate())) {
// (subscription always expects the first event to be in the past)
throw new SubscriptionBaseTransferApiException(ErrorCode.SUB_TRANSFER_INVALID_EFF_DATE, effectiveTransferDate);
}
final SubscriptionBaseBundle bundle = subscriptionBaseInternalApi.getActiveBundleForKey(catalog.getCatalog(), bundleKey, fromInternalCallContext);
if (bundle == null) {
throw new SubscriptionBaseTransferApiException(ErrorCode.SUB_CREATE_NO_BUNDLE, bundleKey);
}
// Get the bundle timeline for the old account
final BundleBaseTimeline bundleBaseTimeline = timelineApi.getBundleTimeline(bundle, context);
final DefaultSubscriptionBaseBundle subscriptionBundleData = new DefaultSubscriptionBaseBundle(bundleKey, destAccountId, effectiveTransferDate, bundle.getOriginalCreatedDate(), context.getCreatedDate(), context.getCreatedDate());
final List<SubscriptionTransferData> subscriptionTransferDataList = new LinkedList<SubscriptionTransferData>();
final List<TransferCancelData> transferCancelDataList = new LinkedList<TransferCancelData>();
DateTime bundleStartdate = null;
for (final SubscriptionBaseTimeline cur : bundleBaseTimeline.getSubscriptions()) {
final DefaultSubscriptionBase oldSubscription = (DefaultSubscriptionBase) dao.getSubscriptionFromId(cur.getId(), catalog, fromInternalCallContext);
// Skip already cancelled subscriptions
if (oldSubscription.getState() == EntitlementState.CANCELLED) {
continue;
}
final List<ExistingEvent> existingEvents = cur.getExistingEvents();
final ProductCategory productCategory = existingEvents.get(0).getProductCategory();
// on base plan cancellations, even though we don't support un-transfer today)
if (productCategory != ProductCategory.ADD_ON || cancelImmediately) {
// Create the cancelWithRequestedDate event on effectiveCancelDate
final DateTime effectiveCancelDate = !cancelImmediately && oldSubscription.getChargedThroughDate() != null && effectiveTransferDate.isBefore(oldSubscription.getChargedThroughDate()) ? oldSubscription.getChargedThroughDate() : effectiveTransferDate;
final SubscriptionBaseEvent cancelEvent = new ApiEventCancel(new ApiEventBuilder().setSubscriptionId(cur.getId()).setEffectiveDate(effectiveCancelDate).setFromDisk(true));
final TransferCancelData cancelData = new TransferCancelData(oldSubscription, cancelEvent);
transferCancelDataList.add(cancelData);
}
if (productCategory == ProductCategory.ADD_ON && !transferAddOn) {
continue;
}
// We Align with the original subscription
final DateTime subscriptionAlignStartDate = oldSubscription.getAlignStartDate();
if (bundleStartdate == null) {
bundleStartdate = oldSubscription.getStartDate();
}
// Create the new subscription for the new bundle on the new account
final DefaultSubscriptionBase defaultSubscriptionBase = createSubscriptionForApiUse(new SubscriptionBuilder().setId(UUIDs.randomUUID()).setBundleId(subscriptionBundleData.getId()).setBundleExternalKey(subscriptionBundleData.getExternalKey()).setCategory(productCategory).setBundleStartDate(effectiveTransferDate).setAlignStartDate(subscriptionAlignStartDate), ImmutableList.<SubscriptionBaseEvent>of(), catalog, fromInternalCallContext);
final List<SubscriptionBaseEvent> events = toEvents(existingEvents, defaultSubscriptionBase, effectiveTransferDate, fromInternalCallContext);
final SubscriptionTransferData curData = new SubscriptionTransferData(defaultSubscriptionBase, events, null);
subscriptionTransferDataList.add(curData);
}
final BundleTransferData bundleTransferData = new BundleTransferData(subscriptionBundleData, subscriptionTransferDataList);
// Atomically cancelWithRequestedDate all subscription on old account and create new bundle, subscriptions, events for new account
dao.transfer(sourceAccountId, destAccountId, bundleTransferData, transferCancelDataList, catalog, fromInternalCallContext, toInternalCallContext);
return bundleTransferData.getData();
} catch (SubscriptionBaseRepairException e) {
throw new SubscriptionBaseTransferApiException(e);
} catch (CatalogApiException e) {
throw new SubscriptionBaseTransferApiException(e);
}
}
use of org.killbill.billing.catalog.api.ProductCategory in project killbill by killbill.
the class DefaultCaseChange method getResult.
public T getResult(final PlanPhaseSpecifier from, final PlanSpecifier to, final StaticCatalog catalog) throws CatalogApiException {
final Product inFromProduct;
final BillingPeriod inFromBillingPeriod;
final ProductCategory inFromProductCategory;
final PriceList inFromPriceList;
if (from.getPlanName() != null) {
final Plan plan = catalog.findPlan(from.getPlanName());
inFromProduct = plan.getProduct();
inFromBillingPeriod = plan.getRecurringBillingPeriod();
inFromProductCategory = plan.getProduct().getCategory();
inFromPriceList = plan.getPriceList();
} else {
inFromProduct = catalog.findProduct(from.getProductName());
inFromBillingPeriod = from.getBillingPeriod();
inFromProductCategory = inFromProduct.getCategory();
inFromPriceList = from.getPriceListName() != null ? catalog.findPriceList(from.getPriceListName()) : null;
}
final Product inToProduct;
final BillingPeriod inToBillingPeriod;
final ProductCategory inToProductCategory;
final PriceList inToPriceList;
if (to.getPlanName() != null) {
final Plan plan = catalog.findPlan(to.getPlanName());
inToProduct = plan.getProduct();
inToBillingPeriod = plan.getRecurringBillingPeriod();
inToProductCategory = plan.getProduct().getCategory();
inToPriceList = plan.getPriceList();
} else {
inToProduct = catalog.findProduct(to.getProductName());
inToBillingPeriod = to.getBillingPeriod();
inToProductCategory = inToProduct.getCategory();
inToPriceList = to.getPriceListName() != null ? catalog.findPriceList(to.getPriceListName()) : null;
}
if ((phaseType == null || from.getPhaseType() == phaseType) && (fromProduct == null || fromProduct.equals(inFromProduct)) && (fromProductCategory == null || fromProductCategory.equals(inFromProductCategory)) && (fromBillingPeriod == null || fromBillingPeriod.equals(inFromBillingPeriod)) && (this.toProduct == null || this.toProduct.equals(inToProduct)) && (this.toProductCategory == null || this.toProductCategory.equals(inToProductCategory)) && (this.toBillingPeriod == null || this.toBillingPeriod.equals(inToBillingPeriod)) && (fromPriceList == null || fromPriceList.equals(inFromPriceList)) && (toPriceList == null || toPriceList.equals(inToPriceList))) {
return getResult();
}
return null;
}
use of org.killbill.billing.catalog.api.ProductCategory in project killbill by killbill.
the class DefaultCase method satisfiesCase.
protected boolean satisfiesCase(final PlanSpecifier planPhase, final StaticCatalog c) throws CatalogApiException {
final Product product;
final BillingPeriod billingPeriod;
final ProductCategory productCategory;
final PriceList priceList;
if (planPhase.getPlanName() != null) {
final Plan plan = c.findPlan(planPhase.getPlanName());
product = plan.getProduct();
billingPeriod = plan.getRecurringBillingPeriod();
productCategory = plan.getProduct().getCategory();
priceList = plan.getPriceList();
} else {
product = c.findProduct(planPhase.getProductName());
billingPeriod = planPhase.getBillingPeriod();
productCategory = product.getCategory();
priceList = getPriceList() != null ? c.findPriceList(planPhase.getPriceListName()) : null;
}
return (getProduct() == null || getProduct().equals(product)) && (getProductCategory() == null || getProductCategory().equals(productCategory)) && (getBillingPeriod() == null || getBillingPeriod().equals(billingPeriod)) && (getPriceList() == null || getPriceList().equals(priceList));
}
use of org.killbill.billing.catalog.api.ProductCategory in project killbill by killbill.
the class DefaultSubscriptionBaseTimeline method toExistingEvents.
private List<ExistingEvent> toExistingEvents(final SubscriptionCatalog catalog, final ProductCategory category, final List<SubscriptionBaseEvent> events) throws CatalogApiException {
final List<ExistingEvent> result = new LinkedList<SubscriptionBaseTimeline.ExistingEvent>();
Plan prevPlan = null;
String prevProductName = null;
String prevPriceListName = null;
PhaseType prevPhaseType = null;
DateTime startDate = null;
for (final SubscriptionBaseEvent cur : events) {
if (!cur.isActive()) {
continue;
}
startDate = (startDate == null) ? cur.getEffectiveDate() : startDate;
String productName = null;
String priceListName = null;
PhaseType phaseType = null;
Plan plan = null;
String planPhaseName = null;
Integer billCycleDayLocal = null;
ApiEventType apiType = null;
switch(cur.getType()) {
case PHASE:
final PhaseEvent phaseEV = (PhaseEvent) cur;
planPhaseName = phaseEV.getPhase();
// A PHASE event always occurs within the same plan (and is never the first event)
phaseType = prevPlan != null ? prevPlan.findPhase(phaseEV.getPhase()).getPhaseType() : null;
plan = prevPlan;
productName = prevProductName;
priceListName = prevPriceListName;
break;
case BCD_UPDATE:
final BCDEvent bcdEvent = (BCDEvent) cur;
billCycleDayLocal = bcdEvent.getBillCycleDayLocal();
break;
case API_USER:
final ApiEvent userEV = (ApiEvent) cur;
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;
priceListName = (userEV.getPriceList() != null) ? userEV.getPriceList() : prevPriceListName;
break;
}
final SubscriptionBaseTransitionType transitionType = SubscriptionBaseTransitionData.toSubscriptionTransitionType(cur.getType(), apiType);
final String planNameWithClosure = plan != null ? plan.getName() : null;
final String planPhaseNameWithClosure = planPhaseName;
final Integer billCycleDayLocalWithClosure = billCycleDayLocal;
final PlanPhaseSpecifier spec = new PlanPhaseSpecifier(planNameWithClosure, phaseType);
result.add(new ExistingEvent() {
@Override
public SubscriptionBaseTransitionType getSubscriptionTransitionType() {
return transitionType;
}
@Override
public ProductCategory getProductCategory() {
return category;
}
@Override
public PlanPhaseSpecifier getPlanPhaseSpecifier() {
return spec;
}
@Override
public UUID getEventId() {
return cur.getId();
}
@Override
public DateTime getEffectiveDate() {
return cur.getEffectiveDate();
}
@Override
public String getPlanName() {
return planNameWithClosure;
}
@Override
public String getPlanPhaseName() {
return planPhaseNameWithClosure;
}
@Override
public Integer getBillCycleDayLocal() {
return billCycleDayLocalWithClosure;
}
});
prevPlan = plan;
prevProductName = productName;
prevPriceListName = priceListName;
prevPhaseType = phaseType;
}
sortExistingEvent(result);
return result;
}
Aggregations