Search in sources :

Example 56 with PlanPhase

use of org.killbill.billing.catalog.api.PlanPhase in project killbill by killbill.

the class TestInvoiceDispatcher method testDryRunInvoice.

@Test(groups = "slow")
public void testDryRunInvoice() throws InvoiceApiException, AccountApiException, CatalogApiException, SubscriptionBaseApiException {
    final UUID accountId = account.getId();
    final BillingEventSet events = new MockBillingEventSet();
    final Plan plan = MockPlan.createBicycleNoTrialEvergreen1USD();
    final PlanPhase planPhase = MockPlanPhase.create1USDMonthlyEvergreen();
    final DateTime effectiveDate = clock.getUTCNow().minusDays(1);
    final Currency currency = Currency.USD;
    final BigDecimal fixedPrice = null;
    events.add(invoiceUtil.createMockBillingEvent(account, subscription, effectiveDate, plan, planPhase, fixedPrice, BigDecimal.ONE, currency, BillingPeriod.MONTHLY, 1, BillingMode.IN_ADVANCE, "", 1L, SubscriptionBaseTransitionType.CREATE));
    Mockito.when(billingApi.getBillingEventsForAccountAndUpdateAccountBCD(Mockito.<UUID>any(), Mockito.<DryRunArguments>any(), Mockito.<InternalCallContext>any())).thenReturn(events);
    final LocalDate target = internalCallContext.toLocalDate(effectiveDate);
    final InvoiceNotifier invoiceNotifier = new NullInvoiceNotifier();
    final InvoiceDispatcher dispatcher = new InvoiceDispatcher(generator, accountApi, billingApi, subscriptionApi, invoiceDao, internalCallContextFactory, invoiceNotifier, invoicePluginDispatcher, locker, busService.getBus(), null, invoiceConfig, clock, parkedAccountsManager);
    Invoice invoice = dispatcher.processAccountFromNotificationOrBusEvent(accountId, target, new DryRunFutureDateArguments(), context);
    Assert.assertNotNull(invoice);
    List<InvoiceModelDao> invoices = invoiceDao.getInvoicesByAccount(context);
    Assert.assertEquals(invoices.size(), 0);
    // Try it again to double check
    invoice = dispatcher.processAccountFromNotificationOrBusEvent(accountId, target, new DryRunFutureDateArguments(), context);
    Assert.assertNotNull(invoice);
    invoices = invoiceDao.getInvoicesByAccount(context);
    Assert.assertEquals(invoices.size(), 0);
    // This time no dry run
    invoice = dispatcher.processAccountFromNotificationOrBusEvent(accountId, target, null, context);
    Assert.assertNotNull(invoice);
    invoices = invoiceDao.getInvoicesByAccount(context);
    Assert.assertEquals(invoices.size(), 1);
}
Also used : Invoice(org.killbill.billing.invoice.api.Invoice) NullInvoiceNotifier(org.killbill.billing.invoice.notification.NullInvoiceNotifier) InvoiceNotifier(org.killbill.billing.invoice.api.InvoiceNotifier) InvoiceModelDao(org.killbill.billing.invoice.dao.InvoiceModelDao) MockPlan(org.killbill.billing.catalog.MockPlan) Plan(org.killbill.billing.catalog.api.Plan) LocalDate(org.joda.time.LocalDate) DateTime(org.joda.time.DateTime) BigDecimal(java.math.BigDecimal) NullInvoiceNotifier(org.killbill.billing.invoice.notification.NullInvoiceNotifier) BillingEventSet(org.killbill.billing.junction.BillingEventSet) Currency(org.killbill.billing.catalog.api.Currency) DryRunFutureDateArguments(org.killbill.billing.invoice.TestInvoiceHelper.DryRunFutureDateArguments) PlanPhase(org.killbill.billing.catalog.api.PlanPhase) MockPlanPhase(org.killbill.billing.catalog.MockPlanPhase) UUID(java.util.UUID) Test(org.testng.annotations.Test)

Example 57 with PlanPhase

use of org.killbill.billing.catalog.api.PlanPhase in project killbill by killbill.

the class PlanAligner method getPhaseAlignments.

private List<TimedPhase> getPhaseAlignments(final Plan plan, @Nullable final PhaseType initialPhase, final DateTime initialPhaseStartDate) throws SubscriptionBaseApiException {
    if (plan == null) {
        return Collections.emptyList();
    }
    final List<TimedPhase> result = new LinkedList<TimedPhase>();
    DateTime curPhaseStart = (initialPhase == null) ? initialPhaseStartDate : null;
    DateTime nextPhaseStart;
    for (final PlanPhase cur : plan.getAllPhases()) {
        // For create we can specify the phase so skip any phase until we reach initialPhase
        if (curPhaseStart == null) {
            if (initialPhase != cur.getPhaseType()) {
                continue;
            }
            curPhaseStart = initialPhaseStartDate;
        }
        result.add(new TimedPhase(cur, curPhaseStart));
        // STEPH check for duration null instead TimeUnit UNLIMITED
        if (cur.getPhaseType() != PhaseType.EVERGREEN) {
            final Duration curPhaseDuration = cur.getDuration();
            nextPhaseStart = addDuration(curPhaseStart, curPhaseDuration);
            if (nextPhaseStart == null) {
                throw new SubscriptionBaseError(String.format("Unexpected non ending UNLIMITED phase for plan %s", plan.getName()));
            }
            curPhaseStart = nextPhaseStart;
        }
    }
    if (initialPhase != null && curPhaseStart == null) {
        throw new SubscriptionBaseApiException(ErrorCode.SUB_CREATE_BAD_PHASE, initialPhase);
    }
    return result;
}
Also used : SubscriptionBaseError(org.killbill.billing.subscription.exceptions.SubscriptionBaseError) PlanPhase(org.killbill.billing.catalog.api.PlanPhase) Duration(org.killbill.billing.catalog.api.Duration) LinkedList(java.util.LinkedList) DateTime(org.joda.time.DateTime) SubscriptionBaseApiException(org.killbill.billing.subscription.api.user.SubscriptionBaseApiException)

Example 58 with PlanPhase

use of org.killbill.billing.catalog.api.PlanPhase in project killbill by killbill.

the class DefaultSubscriptionInternalApi method createSubscription.

@Override
public SubscriptionBase createSubscription(final UUID bundleId, final PlanPhaseSpecifier spec, final List<PlanPhasePriceOverride> overrides, final DateTime requestedDateWithMs, final boolean isMigrated, final InternalCallContext context) throws SubscriptionBaseApiException {
    try {
        final DateTime now = clock.getUTCNow();
        final DateTime effectiveDate = (requestedDateWithMs != null) ? DefaultClock.truncateMs(requestedDateWithMs) : now;
        /*
            if (requestedDate.isAfter(now)) {
                throw new SubscriptionBaseApiException(ErrorCode.SUB_INVALID_REQUESTED_DATE, now.toString(), requestedDate.toString());
            }
            */
        final CallContext callContext = internalCallContextFactory.createCallContext(context);
        final Catalog catalog = catalogService.getFullCatalog(true, true, context);
        final PlanPhasePriceOverridesWithCallContext overridesWithContext = new DefaultPlanPhasePriceOverridesWithCallContext(overrides, 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()));
        }
        final SubscriptionBaseBundle bundle = dao.getSubscriptionBundleFromId(bundleId, context);
        if (bundle == null) {
            throw new SubscriptionBaseApiException(ErrorCode.SUB_CREATE_NO_BUNDLE, bundleId);
        }
        final DefaultSubscriptionBase baseSubscription = (DefaultSubscriptionBase) dao.getBaseSubscription(bundleId, context);
        // verify the number of subscriptions (of the same kind) allowed per bundle
        if (ProductCategory.ADD_ON.toString().equalsIgnoreCase(plan.getProduct().getCategory().toString())) {
            if (plan.getPlansAllowedInBundle() != -1 && plan.getPlansAllowedInBundle() > 0 && addonUtils.countExistingAddOnsWithSamePlanName(getSubscriptionsForBundle(bundleId, null, context), plan.getName()) >= 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 DateTime bundleStartDate = getBundleStartDateWithSanity(bundleId, baseSubscription, plan, effectiveDate, context);
        return apiService.createPlan(new SubscriptionBuilder().setId(UUIDs.randomUUID()).setBundleId(bundleId).setBundleExternalKey(bundle.getExternalKey()).setCategory(plan.getProduct().getCategory()).setBundleStartDate(bundleStartDate).setAlignStartDate(effectiveDate).setMigrated(isMigrated), plan, spec.getPhaseType(), plan.getPriceListName(), effectiveDate, now, callContext);
    } catch (final CatalogApiException e) {
        throw new SubscriptionBaseApiException(e);
    }
}
Also used : SubscriptionBuilder(org.killbill.billing.subscription.api.user.SubscriptionBuilder) Plan(org.killbill.billing.catalog.api.Plan) PlanPhasePriceOverridesWithCallContext(org.killbill.billing.catalog.api.PlanPhasePriceOverridesWithCallContext) CallContext(org.killbill.billing.util.callcontext.CallContext) InternalCallContext(org.killbill.billing.callcontext.InternalCallContext) DateTime(org.joda.time.DateTime) Catalog(org.killbill.billing.catalog.api.Catalog) PlanPhasePriceOverridesWithCallContext(org.killbill.billing.catalog.api.PlanPhasePriceOverridesWithCallContext) SubscriptionBaseError(org.killbill.billing.subscription.exceptions.SubscriptionBaseError) CatalogApiException(org.killbill.billing.catalog.api.CatalogApiException) PlanPhase(org.killbill.billing.catalog.api.PlanPhase) SubscriptionBaseBundle(org.killbill.billing.subscription.api.user.SubscriptionBaseBundle) DefaultSubscriptionBaseBundle(org.killbill.billing.subscription.api.user.DefaultSubscriptionBaseBundle) DefaultSubscriptionBase(org.killbill.billing.subscription.api.user.DefaultSubscriptionBase) SubscriptionBaseApiException(org.killbill.billing.subscription.api.user.SubscriptionBaseApiException) PlanPhasePriceOverride(org.killbill.billing.catalog.api.PlanPhasePriceOverride)

Example 59 with PlanPhase

use of org.killbill.billing.catalog.api.PlanPhase in project killbill by killbill.

the class TestBillingApi method testBillingEventsWithBlock.

@Test(groups = "fast")
public void testBillingEventsWithBlock() throws CatalogApiException, AccountApiException, SubscriptionBaseApiException {
    final Plan nextPlan = catalog.findPlan("3-PickupTrialEvergreen10USD", clock.getUTCNow());
    final PlanPhase nextPhase = nextPlan.getAllPhases()[1];
    final DateTime now = createSubscriptionCreationEvent(nextPlan, nextPhase);
    final Account account = createAccount(32);
    final BlockingState blockingState1 = new DefaultBlockingState(bunId, BlockingStateType.SUBSCRIPTION_BUNDLE, DISABLED_BUNDLE, "test", true, true, true, now.plusDays(1));
    final BlockingState blockingState2 = new DefaultBlockingState(bunId, BlockingStateType.SUBSCRIPTION_BUNDLE, CLEAR_BUNDLE, "test", false, false, false, now.plusDays(2));
    blockingStateDao.setBlockingStatesAndPostBlockingTransitionEvent(ImmutableMap.<BlockingState, Optional<UUID>>of(blockingState1, Optional.<UUID>absent(), blockingState2, Optional.<UUID>absent()), internalCallContext);
    final SortedSet<BillingEvent> events = billingInternalApi.getBillingEventsForAccountAndUpdateAccountBCD(account.getId(), null, internalCallContext);
    Assert.assertEquals(events.size(), 3);
    final Iterator<BillingEvent> it = events.iterator();
    checkEvent(it.next(), nextPlan, account.getBillCycleDayLocal(), subId, now, nextPhase, SubscriptionBaseTransitionType.CREATE.toString(), nextPhase.getFixed().getPrice(), nextPhase.getRecurring().getRecurringPrice());
    checkEvent(it.next(), nextPlan, account.getBillCycleDayLocal(), subId, now.plusDays(1), nextPhase, SubscriptionBaseTransitionType.START_BILLING_DISABLED.toString(), null, null);
    checkEvent(it.next(), nextPlan, account.getBillCycleDayLocal(), subId, now.plusDays(2), nextPhase, SubscriptionBaseTransitionType.END_BILLING_DISABLED.toString(), nextPhase.getFixed().getPrice(), nextPhase.getRecurring().getRecurringPrice());
}
Also used : Account(org.killbill.billing.account.api.Account) PlanPhase(org.killbill.billing.catalog.api.PlanPhase) DefaultBlockingState(org.killbill.billing.junction.DefaultBlockingState) BlockingState(org.killbill.billing.entitlement.api.BlockingState) BillingEvent(org.killbill.billing.junction.BillingEvent) Plan(org.killbill.billing.catalog.api.Plan) UUID(java.util.UUID) DateTime(org.joda.time.DateTime) DefaultBlockingState(org.killbill.billing.junction.DefaultBlockingState) Test(org.testng.annotations.Test)

Example 60 with PlanPhase

use of org.killbill.billing.catalog.api.PlanPhase in project killbill by killbill.

the class TestBillingApi method testBillingEventsAutoInvoicingOffBundle.

@Test(groups = "fast")
public void testBillingEventsAutoInvoicingOffBundle() throws CatalogApiException, AccountApiException, TagApiException, SubscriptionBaseApiException {
    final Plan nextPlan = catalog.findPlan("3-PickupTrialEvergreen10USD", clock.getUTCNow());
    final PlanPhase nextPhase = nextPlan.getAllPhases()[1];
    createSubscriptionCreationEvent(nextPlan, nextPhase);
    final Account account = createAccount(32);
    tagInternalApi.addTag(bunId, ObjectType.BUNDLE, ControlTagType.AUTO_INVOICING_OFF.getId(), internalCallContext);
    final BillingEventSet events = billingInternalApi.getBillingEventsForAccountAndUpdateAccountBCD(account.getId(), null, internalCallContext);
    assertEquals(events.getSubscriptionIdsWithAutoInvoiceOff().size(), 1);
    assertEquals(events.getSubscriptionIdsWithAutoInvoiceOff().get(0), subId);
    assertEquals(events.size(), 0);
}
Also used : Account(org.killbill.billing.account.api.Account) BillingEventSet(org.killbill.billing.junction.BillingEventSet) PlanPhase(org.killbill.billing.catalog.api.PlanPhase) Plan(org.killbill.billing.catalog.api.Plan) Test(org.testng.annotations.Test)

Aggregations

PlanPhase (org.killbill.billing.catalog.api.PlanPhase)98 Plan (org.killbill.billing.catalog.api.Plan)77 Test (org.testng.annotations.Test)71 MockPlan (org.killbill.billing.catalog.MockPlan)50 MockPlanPhase (org.killbill.billing.catalog.MockPlanPhase)49 LocalDate (org.joda.time.LocalDate)47 DateTime (org.joda.time.DateTime)43 BillingEventSet (org.killbill.billing.junction.BillingEventSet)43 BigDecimal (java.math.BigDecimal)42 BillingEvent (org.killbill.billing.junction.BillingEvent)41 MockBillingEventSet (org.killbill.billing.invoice.MockBillingEventSet)40 Invoice (org.killbill.billing.invoice.api.Invoice)39 DefaultInvoice (org.killbill.billing.invoice.model.DefaultInvoice)36 UUID (java.util.UUID)34 DefaultPrice (org.killbill.billing.catalog.DefaultPrice)22 MockInternationalPrice (org.killbill.billing.catalog.MockInternationalPrice)22 RecurringInvoiceItem (org.killbill.billing.invoice.model.RecurringInvoiceItem)22 SubscriptionBase (org.killbill.billing.subscription.api.SubscriptionBase)22 InvoiceItem (org.killbill.billing.invoice.api.InvoiceItem)21 FixedPriceInvoiceItem (org.killbill.billing.invoice.model.FixedPriceInvoiceItem)21