Search in sources :

Example 21 with SubscriptionBaseEvent

use of org.killbill.billing.subscription.events.SubscriptionBaseEvent in project killbill by killbill.

the class TestUserApiCreate method testSimpleCreateSubscription.

@Test(groups = "slow")
public void testSimpleCreateSubscription() throws SubscriptionBaseApiException {
    final DateTime init = clock.getUTCNow();
    final String productName = "Shotgun";
    final BillingPeriod term = BillingPeriod.MONTHLY;
    final String planSetName = PriceListSet.DEFAULT_PRICELIST_NAME;
    final DefaultSubscriptionBase subscription = testUtil.createSubscription(bundle, productName, term, planSetName);
    assertNotNull(subscription);
    assertEquals(subscription.getBundleExternalKey(), bundle.getExternalKey());
    testUtil.assertDateWithin(subscription.getStartDate(), init, clock.getUTCNow());
    testUtil.assertDateWithin(subscription.getBundleStartDate(), init, clock.getUTCNow());
    final Plan currentPlan = subscription.getCurrentPlan();
    assertNotNull(currentPlan);
    assertEquals(currentPlan.getProduct().getName(), productName);
    assertEquals(currentPlan.getProduct().getCategory(), ProductCategory.BASE);
    assertEquals(currentPlan.getRecurringBillingPeriod(), BillingPeriod.MONTHLY);
    final PlanPhase currentPhase = subscription.getCurrentPhase();
    assertNotNull(currentPhase);
    assertEquals(currentPhase.getPhaseType(), PhaseType.TRIAL);
    assertListenerStatus();
    final List<SubscriptionBaseEvent> events = dao.getPendingEventsForSubscription(subscription.getId(), internalCallContext);
    assertNotNull(events);
    testUtil.printEvents(events);
    assertTrue(events.size() == 1);
    assertTrue(events.get(0) instanceof PhaseEvent);
    final DateTime nextPhaseChange = ((PhaseEvent) events.get(0)).getEffectiveDate();
    final DateTime nextExpectedPhaseChange = TestSubscriptionHelper.addDuration(subscription.getStartDate(), currentPhase.getDuration());
    assertEquals(nextPhaseChange, nextExpectedPhaseChange);
    testListener.pushExpectedEvent(NextEvent.PHASE);
    final Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(31));
    clock.addDeltaFromReality(it.toDurationMillis());
    final DateTime futureNow = clock.getUTCNow();
    assertTrue(futureNow.isAfter(nextPhaseChange));
    assertListenerStatus();
}
Also used : PhaseEvent(org.killbill.billing.subscription.events.phase.PhaseEvent) BillingPeriod(org.killbill.billing.catalog.api.BillingPeriod) PlanPhase(org.killbill.billing.catalog.api.PlanPhase) Plan(org.killbill.billing.catalog.api.Plan) SubscriptionBaseEvent(org.killbill.billing.subscription.events.SubscriptionBaseEvent) DateTime(org.joda.time.DateTime) Interval(org.joda.time.Interval) Test(org.testng.annotations.Test)

Example 22 with SubscriptionBaseEvent

use of org.killbill.billing.subscription.events.SubscriptionBaseEvent in project killbill by killbill.

the class DefaultSubscriptionDao method undoOperation.

private void undoOperation(final DefaultSubscriptionBase subscription, final List<SubscriptionBaseEvent> inputEvents, final ApiEventType targetOperation, final SubscriptionBaseTransitionType transitionType, final InternalCallContext context) {
    final InternalCallContext contextWithUpdatedDate = contextWithUpdatedDate(context);
    transactionalSqlDao.execute(false, new EntitySqlDaoTransactionWrapper<Void>() {

        @Override
        public Void inTransaction(final EntitySqlDaoWrapperFactory entitySqlDaoWrapperFactory) throws Exception {
            final SubscriptionEventSqlDao transactional = entitySqlDaoWrapperFactory.become(SubscriptionEventSqlDao.class);
            final UUID subscriptionId = subscription.getId();
            Set<SubscriptionEventModelDao> targetEvents = new HashSet<SubscriptionEventModelDao>();
            final Date now = context.getCreatedDate().toDate();
            final List<SubscriptionEventModelDao> eventModels = transactional.getFutureActiveEventForSubscription(subscriptionId.toString(), now, contextWithUpdatedDate);
            for (final SubscriptionEventModelDao cur : eventModels) {
                if (cur.getEventType() == EventType.API_USER && cur.getUserType() == targetOperation) {
                    targetEvents.add(cur);
                } else if (cur.getEventType() == EventType.PHASE) {
                    targetEvents.add(cur);
                }
            }
            if (!targetEvents.isEmpty()) {
                for (SubscriptionEventModelDao target : targetEvents) {
                    transactional.unactiveEvent(target.getId().toString(), contextWithUpdatedDate);
                }
                for (final SubscriptionBaseEvent cur : inputEvents) {
                    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, inputEvents.get(inputEvents.size() - 1), transitionType, 0, contextWithUpdatedDate);
            }
            return null;
        }
    });
}
Also used : Set(java.util.Set) HashSet(java.util.HashSet) InternalCallContext(org.killbill.billing.callcontext.InternalCallContext) SubscriptionEventModelDao(org.killbill.billing.subscription.engine.dao.model.SubscriptionEventModelDao) CatalogApiException(org.killbill.billing.catalog.api.CatalogApiException) SubscriptionApiException(org.killbill.billing.entitlement.api.SubscriptionApiException) IOException(java.io.IOException) SubscriptionBaseApiException(org.killbill.billing.subscription.api.user.SubscriptionBaseApiException) EventBusException(org.killbill.bus.api.PersistentBus.EventBusException) EntityPersistenceException(org.killbill.billing.entity.EntityPersistenceException) Date(java.util.Date) LocalDate(org.joda.time.LocalDate) SubscriptionNotificationKey(org.killbill.billing.subscription.engine.core.SubscriptionNotificationKey) EntitySqlDaoWrapperFactory(org.killbill.billing.util.entity.dao.EntitySqlDaoWrapperFactory) ArrayList(java.util.ArrayList) List(java.util.List) ImmutableList(com.google.common.collect.ImmutableList) LinkedList(java.util.LinkedList) UUID(java.util.UUID) SubscriptionBaseEvent(org.killbill.billing.subscription.events.SubscriptionBaseEvent)

Example 23 with SubscriptionBaseEvent

use of org.killbill.billing.subscription.events.SubscriptionBaseEvent in project killbill by killbill.

the class DefaultSubscriptionDao method transferBundleDataFromTransaction.

private void transferBundleDataFromTransaction(final BundleTransferData bundleTransferData, final EntitySqlDao transactional, final EntitySqlDaoWrapperFactory entitySqlDaoWrapperFactory, final InternalCallContext context) throws EntityPersistenceException {
    final SubscriptionSqlDao transSubDao = entitySqlDaoWrapperFactory.become(SubscriptionSqlDao.class);
    final BundleSqlDao transBundleDao = entitySqlDaoWrapperFactory.become(BundleSqlDao.class);
    final DefaultSubscriptionBaseBundle bundleData = bundleTransferData.getData();
    final SubscriptionBundleModelDao existingBundleForAccount = transBundleDao.getBundlesFromAccountAndKey(bundleData.getAccountId().toString(), bundleData.getExternalKey(), context);
    if (existingBundleForAccount != null) {
        log.warn("Bundle already exists for accountId='{}', bundleExternalKey='{}'", bundleData.getAccountId(), bundleData.getExternalKey());
        return;
    }
    for (final SubscriptionTransferData curSubscription : bundleTransferData.getSubscriptions()) {
        final DefaultSubscriptionBase subData = curSubscription.getData();
        for (final SubscriptionBaseEvent curEvent : curSubscription.getInitialEvents()) {
            createAndRefresh(transactional, new SubscriptionEventModelDao(curEvent), context);
            recordFutureNotificationFromTransaction(entitySqlDaoWrapperFactory, curEvent.getEffectiveDate(), new SubscriptionNotificationKey(curEvent.getId()), context);
        }
        createAndRefresh(transSubDao, new SubscriptionModelDao(subData), context);
        // Notify the Bus of the latest requested change
        final SubscriptionBaseEvent finalEvent = curSubscription.getInitialEvents().get(curSubscription.getInitialEvents().size() - 1);
        notifyBusOfRequestedChange(entitySqlDaoWrapperFactory, subData, finalEvent, SubscriptionBaseTransitionType.TRANSFER, 0, context);
    }
    createAndRefresh(transBundleDao, new SubscriptionBundleModelDao(bundleData), context);
}
Also used : SubscriptionNotificationKey(org.killbill.billing.subscription.engine.core.SubscriptionNotificationKey) SubscriptionModelDao(org.killbill.billing.subscription.engine.dao.model.SubscriptionModelDao) DefaultSubscriptionBaseBundle(org.killbill.billing.subscription.api.user.DefaultSubscriptionBaseBundle) SubscriptionBundleModelDao(org.killbill.billing.subscription.engine.dao.model.SubscriptionBundleModelDao) DefaultSubscriptionBase(org.killbill.billing.subscription.api.user.DefaultSubscriptionBase) SubscriptionTransferData(org.killbill.billing.subscription.api.transfer.SubscriptionTransferData) SubscriptionBaseEvent(org.killbill.billing.subscription.events.SubscriptionBaseEvent) SubscriptionEventModelDao(org.killbill.billing.subscription.engine.dao.model.SubscriptionEventModelDao)

Example 24 with SubscriptionBaseEvent

use of org.killbill.billing.subscription.events.SubscriptionBaseEvent in project killbill by killbill.

the class DefaultSubscriptionDao method mergeDryRunEvents.

private void mergeDryRunEvents(final UUID subscriptionId, final List<SubscriptionBaseEvent> events, @Nullable final Collection<SubscriptionBaseEvent> dryRunEvents) {
    if (dryRunEvents == null || dryRunEvents.isEmpty()) {
        return;
    }
    for (final SubscriptionBaseEvent curDryRun : dryRunEvents) {
        boolean swapChangeEventWithCreate = false;
        if (curDryRun.getSubscriptionId() != null && curDryRun.getSubscriptionId().equals(subscriptionId)) {
            final boolean isApiChange = curDryRun.getType() == EventType.API_USER && ((ApiEvent) curDryRun).getApiEventType() == ApiEventType.CHANGE;
            final Iterator<SubscriptionBaseEvent> it = events.iterator();
            while (it.hasNext()) {
                final SubscriptionBaseEvent event = it.next();
                if (event.getEffectiveDate().isAfter(curDryRun.getEffectiveDate())) {
                    it.remove();
                } else if (event.getEffectiveDate().compareTo(curDryRun.getEffectiveDate()) == 0 && isApiChange && (event.getType() == EventType.API_USER && (((ApiEvent) event).getApiEventType() == ApiEventType.CREATE) || ((ApiEvent) event).getApiEventType() == ApiEventType.TRANSFER)) {
                    it.remove();
                    swapChangeEventWithCreate = true;
                }
            }
            // Set total ordering value of the fake dryRun event to make sure billing events are correctly ordered
            // and also transform CHANGE event into CREATE in case of perfect effectiveDate match
            final EventBaseBuilder eventBuilder;
            switch(curDryRun.getType()) {
                case PHASE:
                    eventBuilder = new PhaseEventBuilder((PhaseEvent) curDryRun);
                    break;
                case BCD_UPDATE:
                    eventBuilder = new BCDEventBuilder((BCDEvent) curDryRun);
                    break;
                case API_USER:
                default:
                    eventBuilder = new ApiEventBuilder((ApiEvent) curDryRun);
                    if (swapChangeEventWithCreate) {
                        ((ApiEventBuilder) eventBuilder).setApiEventType(ApiEventType.CREATE);
                    }
                    break;
            }
            if (!events.isEmpty()) {
                eventBuilder.setTotalOrdering(events.get(events.size() - 1).getTotalOrdering() + 1);
            }
            events.add(eventBuilder.build());
        }
    }
}
Also used : PhaseEvent(org.killbill.billing.subscription.events.phase.PhaseEvent) ApiEventBuilder(org.killbill.billing.subscription.events.user.ApiEventBuilder) ApiEvent(org.killbill.billing.subscription.events.user.ApiEvent) BCDEventBuilder(org.killbill.billing.subscription.events.bcd.BCDEventBuilder) EventBaseBuilder(org.killbill.billing.subscription.events.EventBaseBuilder) BCDEvent(org.killbill.billing.subscription.events.bcd.BCDEvent) PhaseEventBuilder(org.killbill.billing.subscription.events.phase.PhaseEventBuilder) SubscriptionBaseEvent(org.killbill.billing.subscription.events.SubscriptionBaseEvent)

Example 25 with SubscriptionBaseEvent

use of org.killbill.billing.subscription.events.SubscriptionBaseEvent in project killbill by killbill.

the class DefaultSubscriptionDao method cancelSubscriptionsFromTransaction.

private void cancelSubscriptionsFromTransaction(final EntitySqlDaoWrapperFactory entitySqlDaoWrapperFactory, final List<DefaultSubscriptionBase> subscriptions, final List<SubscriptionBaseEvent> cancelEvents, final SubscriptionCatalog catalog, final InternalCallContext context) throws EntityPersistenceException {
    for (int i = 0; i < subscriptions.size(); i++) {
        final DefaultSubscriptionBase subscription = subscriptions.get(i);
        final SubscriptionBaseEvent cancelEvent = cancelEvents.get(i);
        cancelSubscriptionFromTransaction(subscription, cancelEvent, entitySqlDaoWrapperFactory, catalog, context, subscriptions.size() - i - 1);
    }
}
Also used : DefaultSubscriptionBase(org.killbill.billing.subscription.api.user.DefaultSubscriptionBase) SubscriptionBaseEvent(org.killbill.billing.subscription.events.SubscriptionBaseEvent)

Aggregations

SubscriptionBaseEvent (org.killbill.billing.subscription.events.SubscriptionBaseEvent)75 DateTime (org.joda.time.DateTime)31 ApiEventBuilder (org.killbill.billing.subscription.events.user.ApiEventBuilder)26 LinkedList (java.util.LinkedList)25 ArrayList (java.util.ArrayList)23 UUID (java.util.UUID)22 DefaultSubscriptionBase (org.killbill.billing.subscription.api.user.DefaultSubscriptionBase)21 InternalCallContext (org.killbill.billing.callcontext.InternalCallContext)16 CatalogApiException (org.killbill.billing.catalog.api.CatalogApiException)14 Test (org.testng.annotations.Test)14 Plan (org.killbill.billing.catalog.api.Plan)13 PhaseEvent (org.killbill.billing.subscription.events.phase.PhaseEvent)13 ApiEvent (org.killbill.billing.subscription.events.user.ApiEvent)13 ApiEventCancel (org.killbill.billing.subscription.events.user.ApiEventCancel)12 ApiEventCreate (org.killbill.billing.subscription.events.user.ApiEventCreate)11 SubscriptionBase (org.killbill.billing.subscription.api.SubscriptionBase)10 SubscriptionBuilder (org.killbill.billing.subscription.api.user.SubscriptionBuilder)9 SubscriptionNotificationKey (org.killbill.billing.subscription.engine.core.SubscriptionNotificationKey)8 ApiEventChange (org.killbill.billing.subscription.events.user.ApiEventChange)8 ImmutableList (com.google.common.collect.ImmutableList)7