Search in sources :

Example 11 with PhaseEvent

use of org.killbill.billing.subscription.events.phase.PhaseEvent 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;
}
Also used : ApiEventType(org.killbill.billing.subscription.events.user.ApiEventType) PlanPhaseSpecifier(org.killbill.billing.catalog.api.PlanPhaseSpecifier) PhaseEvent(org.killbill.billing.subscription.events.phase.PhaseEvent) SubscriptionBaseTransitionType(org.killbill.billing.subscription.api.SubscriptionBaseTransitionType) BCDEvent(org.killbill.billing.subscription.events.bcd.BCDEvent) Plan(org.killbill.billing.catalog.api.Plan) LinkedList(java.util.LinkedList) DateTime(org.joda.time.DateTime) ApiEvent(org.killbill.billing.subscription.events.user.ApiEvent) PhaseType(org.killbill.billing.catalog.api.PhaseType) ProductCategory(org.killbill.billing.catalog.api.ProductCategory) UUID(java.util.UUID) SubscriptionBaseEvent(org.killbill.billing.subscription.events.SubscriptionBaseEvent)

Example 12 with PhaseEvent

use of org.killbill.billing.subscription.events.phase.PhaseEvent in project killbill by killbill.

the class DefaultSubscriptionBaseApiService method uncancel.

@Override
public boolean uncancel(final DefaultSubscriptionBase subscription, final CallContext context) throws SubscriptionBaseApiException {
    if (!subscription.isFutureCancelled()) {
        throw new SubscriptionBaseApiException(ErrorCode.SUB_UNCANCEL_BAD_STATE, subscription.getId().toString());
    }
    try {
        final InternalCallContext internalCallContext = createCallContextFromBundleId(subscription.getBundleId(), context);
        final SubscriptionCatalog catalog = subscriptionCatalogApi.getFullCatalog(internalCallContext);
        final SubscriptionBaseEvent uncancelEvent = new ApiEventUncancel(new ApiEventBuilder().setSubscriptionId(subscription.getId()).setEffectiveDate(context.getCreatedDate()).setFromDisk(true));
        final List<SubscriptionBaseEvent> uncancelEvents = new ArrayList<SubscriptionBaseEvent>();
        uncancelEvents.add(uncancelEvent);
        // 
        // Used to compute effective for next phase (which was set unactive during cancellation).
        // In case of a pending subscription we don't want to pass an effective date prior the CREATE event as we would end up with the wrong
        // transition in PlanAligner (next transition would be CREATE instead of potential next PHASE)
        // 
        final DateTime planAlignerEffectiveDate = subscription.getState() == EntitlementState.PENDING ? subscription.getStartDate() : context.getCreatedDate();
        final TimedPhase nextTimedPhase = planAligner.getNextTimedPhase(subscription, planAlignerEffectiveDate, catalog, internalCallContext);
        final PhaseEvent nextPhaseEvent = (nextTimedPhase != null) ? PhaseEventData.createNextPhaseEvent(subscription.getId(), nextTimedPhase.getPhase().getName(), nextTimedPhase.getStartPhase()) : null;
        if (nextPhaseEvent != null) {
            uncancelEvents.add(nextPhaseEvent);
        }
        dao.uncancelSubscription(subscription, uncancelEvents, internalCallContext);
        subscription.rebuildTransitions(dao.getEventsForSubscription(subscription.getId(), internalCallContext), catalog);
        return true;
    } catch (final CatalogApiException e) {
        throw new SubscriptionBaseApiException(e);
    }
}
Also used : PhaseEvent(org.killbill.billing.subscription.events.phase.PhaseEvent) ApiEventBuilder(org.killbill.billing.subscription.events.user.ApiEventBuilder) CatalogApiException(org.killbill.billing.catalog.api.CatalogApiException) ArrayList(java.util.ArrayList) TimedPhase(org.killbill.billing.subscription.alignment.TimedPhase) ApiEventUncancel(org.killbill.billing.subscription.events.user.ApiEventUncancel) InternalCallContext(org.killbill.billing.callcontext.InternalCallContext) SubscriptionCatalog(org.killbill.billing.subscription.catalog.SubscriptionCatalog) SubscriptionBaseEvent(org.killbill.billing.subscription.events.SubscriptionBaseEvent) DateTime(org.joda.time.DateTime)

Example 13 with PhaseEvent

use of org.killbill.billing.subscription.events.phase.PhaseEvent in project killbill by killbill.

the class DefaultSubscriptionBaseApiService method undoChangePlan.

@Override
public boolean undoChangePlan(final DefaultSubscriptionBase subscription, final CallContext context) throws SubscriptionBaseApiException {
    if (!subscription.isPendingChangePlan()) {
        throw new SubscriptionBaseApiException(ErrorCode.SUB_UNDO_CHANGE_BAD_STATE, subscription.getId().toString());
    }
    try {
        final InternalCallContext internalCallContext = createCallContextFromBundleId(subscription.getBundleId(), context);
        final SubscriptionCatalog catalog = subscriptionCatalogApi.getFullCatalog(internalCallContext);
        final SubscriptionBaseEvent undoChangePlanEvent = new ApiEventUndoChange(new ApiEventBuilder().setSubscriptionId(subscription.getId()).setEffectiveDate(context.getCreatedDate()).setFromDisk(true));
        final List<SubscriptionBaseEvent> undoChangePlanEvents = new ArrayList<SubscriptionBaseEvent>();
        undoChangePlanEvents.add(undoChangePlanEvent);
        // 
        // Used to compute effective for next phase (which was set unactive during cancellation).
        // In case of a pending subscription we don't want to pass an effective date prior the CREATE event as we would end up with the wrong
        // transition in PlanAligner (next transition would be CREATE instead of potential next PHASE)
        // 
        final DateTime planAlignerEffectiveDate = subscription.getState() == EntitlementState.PENDING ? subscription.getStartDate() : context.getCreatedDate();
        final TimedPhase nextTimedPhase = planAligner.getNextTimedPhase(subscription, planAlignerEffectiveDate, catalog, internalCallContext);
        final PhaseEvent nextPhaseEvent = (nextTimedPhase != null) ? PhaseEventData.createNextPhaseEvent(subscription.getId(), nextTimedPhase.getPhase().getName(), nextTimedPhase.getStartPhase()) : null;
        if (nextPhaseEvent != null) {
            undoChangePlanEvents.add(nextPhaseEvent);
        }
        dao.undoChangePlan(subscription, undoChangePlanEvents, internalCallContext);
        subscription.rebuildTransitions(dao.getEventsForSubscription(subscription.getId(), internalCallContext), catalog);
        return true;
    } catch (final CatalogApiException e) {
        throw new SubscriptionBaseApiException(e);
    }
}
Also used : ApiEventUndoChange(org.killbill.billing.subscription.events.user.ApiEventUndoChange) PhaseEvent(org.killbill.billing.subscription.events.phase.PhaseEvent) ApiEventBuilder(org.killbill.billing.subscription.events.user.ApiEventBuilder) CatalogApiException(org.killbill.billing.catalog.api.CatalogApiException) ArrayList(java.util.ArrayList) TimedPhase(org.killbill.billing.subscription.alignment.TimedPhase) InternalCallContext(org.killbill.billing.callcontext.InternalCallContext) SubscriptionCatalog(org.killbill.billing.subscription.catalog.SubscriptionCatalog) SubscriptionBaseEvent(org.killbill.billing.subscription.events.SubscriptionBaseEvent) DateTime(org.joda.time.DateTime)

Example 14 with PhaseEvent

use of org.killbill.billing.subscription.events.phase.PhaseEvent in project killbill by killbill.

the class DefaultSubscriptionBaseService method onPhaseEvent.

private boolean onPhaseEvent(final DefaultSubscriptionBase subscription, final SubscriptionBaseEvent readyPhaseEvent, final SubscriptionCatalog catalog, final InternalCallContext context) {
    try {
        final TimedPhase nextTimedPhase = planAligner.getNextTimedPhase(subscription, readyPhaseEvent.getEffectiveDate(), catalog, context);
        final PhaseEvent nextPhaseEvent = (nextTimedPhase != null) ? PhaseEventData.createNextPhaseEvent(subscription.getId(), nextTimedPhase.getPhase().getName(), nextTimedPhase.getStartPhase()) : null;
        if (nextPhaseEvent != null) {
            dao.createNextPhaseEvent(subscription, readyPhaseEvent, nextPhaseEvent, context);
            return true;
        }
    } catch (final SubscriptionBaseError e) {
        log.warn("Error inserting next phase for subscriptionId='{}'", subscription.getId(), e);
    }
    return false;
}
Also used : PhaseEvent(org.killbill.billing.subscription.events.phase.PhaseEvent) SubscriptionBaseError(org.killbill.billing.subscription.exceptions.SubscriptionBaseError) TimedPhase(org.killbill.billing.subscription.alignment.TimedPhase)

Example 15 with PhaseEvent

use of org.killbill.billing.subscription.events.phase.PhaseEvent in project killbill by killbill.

the class TestSubscriptionHelper method checkNextPhaseChange.

public void checkNextPhaseChange(final DefaultSubscriptionBase subscription, final int expPendingEvents, final DateTime expPhaseChange) {
    final List<SubscriptionBaseEvent> events = dao.getPendingEventsForSubscription(subscription.getId(), internalCallContext);
    assertNotNull(events);
    printEvents(events);
    assertEquals(events.size(), expPendingEvents);
    if (events.size() > 0 && expPhaseChange != null) {
        boolean foundPhase = false;
        boolean foundChange = false;
        for (final SubscriptionBaseEvent cur : events) {
            if (cur instanceof PhaseEvent) {
                assertEquals(foundPhase, false);
                foundPhase = true;
                assertEquals(cur.getEffectiveDate(), expPhaseChange);
            } else if (cur instanceof ApiEvent) {
                final ApiEvent uEvent = (ApiEvent) cur;
                assertEquals(ApiEventType.CHANGE, uEvent.getApiEventType());
                assertEquals(foundChange, false);
                foundChange = true;
            } else {
                assertFalse(true);
            }
        }
    }
}
Also used : PhaseEvent(org.killbill.billing.subscription.events.phase.PhaseEvent) ApiEvent(org.killbill.billing.subscription.events.user.ApiEvent) SubscriptionBaseEvent(org.killbill.billing.subscription.events.SubscriptionBaseEvent)

Aggregations

PhaseEvent (org.killbill.billing.subscription.events.phase.PhaseEvent)15 SubscriptionBaseEvent (org.killbill.billing.subscription.events.SubscriptionBaseEvent)13 TimedPhase (org.killbill.billing.subscription.alignment.TimedPhase)8 DateTime (org.joda.time.DateTime)7 ApiEventBuilder (org.killbill.billing.subscription.events.user.ApiEventBuilder)7 ArrayList (java.util.ArrayList)6 ApiEvent (org.killbill.billing.subscription.events.user.ApiEvent)6 Plan (org.killbill.billing.catalog.api.Plan)5 BCDEvent (org.killbill.billing.subscription.events.bcd.BCDEvent)5 UUID (java.util.UUID)4 ApiEventType (org.killbill.billing.subscription.events.user.ApiEventType)4 SubscriptionBaseError (org.killbill.billing.subscription.exceptions.SubscriptionBaseError)4 PlanPhase (org.killbill.billing.catalog.api.PlanPhase)3 BCDEventBuilder (org.killbill.billing.subscription.events.bcd.BCDEventBuilder)3 LinkedList (java.util.LinkedList)2 InternalCallContext (org.killbill.billing.callcontext.InternalCallContext)2 BillingPeriod (org.killbill.billing.catalog.api.BillingPeriod)2 CatalogApiException (org.killbill.billing.catalog.api.CatalogApiException)2 PhaseType (org.killbill.billing.catalog.api.PhaseType)2 PlanPhaseSpecifier (org.killbill.billing.catalog.api.PlanPhaseSpecifier)2