Search in sources :

Example 91 with SubscriptionBase

use of org.killbill.billing.subscription.api.SubscriptionBase in project killbill by killbill.

the class DefaultSubscriptionBaseCreateApi method verifyAndBuildSubscriptionSpecifiers.

private List<SubscriptionSpecifier> verifyAndBuildSubscriptionSpecifiers(final SubscriptionBaseBundle bundle, final boolean hasBaseOrStandalonePlanSpecifier, final List<EntitlementSpecifier> entitlements, final List<Plan> entitlementsPlans, final boolean isMigrated, final DateTime effectiveDate, final SubscriptionCatalog catalog, final AddonUtils addonUtils, final TenantContext callContext, final InternalCallContext context) throws SubscriptionBaseApiException, CatalogApiException {
    final List<SubscriptionSpecifier> subscriptions = new ArrayList<SubscriptionSpecifier>();
    for (int i = 0; i < entitlements.size(); i++) {
        final EntitlementSpecifier entitlement = entitlements.get(i);
        final PlanPhaseSpecifier spec = entitlement.getPlanPhaseSpecifier();
        if (spec == null) {
            // BP already exists
            continue;
        }
        final Plan plan = entitlementsPlans.get(i);
        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.getPriceList()));
        }
        // 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) {
                // TODO We should also look to the specifiers being created for validation
                final List<DefaultSubscriptionBase> subscriptionsForBundle = getSubscriptionsForBundle(bundle.getId(), null, catalog, addonUtils, callContext, context);
                final int existingAddOnsWithSamePlanName = addonUtils.countExistingAddOnsWithSamePlanName(subscriptionsForBundle, plan.getName());
                final int currentAddOnsWithSamePlanName = countCurrentAddOnsWithSamePlanName(entitlementsPlans, plan);
                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 DateTime bundleStartDate;
        if (hasBaseOrStandalonePlanSpecifier) {
            bundleStartDate = effectiveDate;
        } else {
            final SubscriptionBase baseSubscription = dao.getBaseSubscription(bundle.getId(), catalog, context);
            bundleStartDate = getBundleStartDateWithSanity(bundle.getId(), baseSubscription, plan, effectiveDate, addonUtils, context);
        }
        final SubscriptionSpecifier subscription = new SubscriptionSpecifier();
        subscription.setRealPriceList(plan.getPriceList().getName());
        subscription.setEffectiveDate(effectiveDate);
        subscription.setProcessedDate(context.getCreatedDate());
        subscription.setPlan(plan);
        subscription.setInitialPhase(spec.getPhaseType());
        subscription.setBuilder(new SubscriptionBuilder().setId(UUIDs.randomUUID()).setBundleId(bundle.getId()).setExternalKey(entitlement.getExternalKey()).setBundleExternalKey(bundle.getExternalKey()).setCategory(plan.getProduct().getCategory()).setBundleStartDate(bundleStartDate).setAlignStartDate(effectiveDate).setMigrated(isMigrated).setSubscriptionBCD(entitlement.getBillCycleDay()));
        subscriptions.add(subscription);
    }
    return subscriptions;
}
Also used : SubscriptionSpecifier(org.killbill.billing.subscription.api.user.SubscriptionSpecifier) PlanPhaseSpecifier(org.killbill.billing.catalog.api.PlanPhaseSpecifier) ArrayList(java.util.ArrayList) SubscriptionBuilder(org.killbill.billing.subscription.api.user.SubscriptionBuilder) Plan(org.killbill.billing.catalog.api.Plan) DateTime(org.joda.time.DateTime) EntitlementSpecifier(org.killbill.billing.entitlement.api.EntitlementSpecifier) SubscriptionBase(org.killbill.billing.subscription.api.SubscriptionBase) DefaultSubscriptionBase(org.killbill.billing.subscription.api.user.DefaultSubscriptionBase) SubscriptionBaseError(org.killbill.billing.subscription.exceptions.SubscriptionBaseError) PlanPhase(org.killbill.billing.catalog.api.PlanPhase) DefaultSubscriptionBase(org.killbill.billing.subscription.api.user.DefaultSubscriptionBase) SubscriptionBaseApiException(org.killbill.billing.subscription.api.user.SubscriptionBaseApiException)

Example 92 with SubscriptionBase

use of org.killbill.billing.subscription.api.SubscriptionBase in project killbill by killbill.

the class TestBillCycleDayCalculator method verifyBCDCalculation.

private void verifyBCDCalculation(final DateTimeZone accountTimeZone, final DateTime startDateUTC, final int bcdLocal) throws AccountApiException, CatalogApiException {
    final SubscriptionBase subscription = Mockito.mock(SubscriptionBase.class);
    Mockito.when(subscription.getStartDate()).thenReturn(startDateUTC);
    Mockito.when(subscription.getDateOfFirstRecurringNonZeroCharge()).thenReturn(startDateUTC);
    final ImmutableAccountData account = Mockito.mock(ImmutableAccountData.class);
    Mockito.when(account.getTimeZone()).thenReturn(accountTimeZone);
    final Integer bcd = BillCycleDayCalculator.calculateBcdForAlignment(new HashMap<UUID, Integer>(), subscription, subscription, BillingAlignment.SUBSCRIPTION, internalCallContext, 0);
    Assert.assertEquals(bcd, (Integer) bcdLocal);
}
Also used : SubscriptionBase(org.killbill.billing.subscription.api.SubscriptionBase) ImmutableAccountData(org.killbill.billing.account.api.ImmutableAccountData) UUID(java.util.UUID)

Example 93 with SubscriptionBase

use of org.killbill.billing.subscription.api.SubscriptionBase in project killbill by killbill.

the class TestBillCycleDayCalculator method testCalculateBCDForAOWithBPCancelledBundleAligned.

@Test(groups = "fast")
public void testCalculateBCDForAOWithBPCancelledBundleAligned() throws Exception {
    final DateTimeZone accountTimeZone = DateTimeZone.UTC;
    final DateTime bpStartDateUTC = new DateTime(2012, 7, 16, 21, 0, 0, DateTimeZone.UTC);
    final int expectedBCDUTC = 16;
    // Create a Bundle associated with a subscription
    final SubscriptionBaseBundle bundle = Mockito.mock(SubscriptionBaseBundle.class);
    final SubscriptionBase subscription = Mockito.mock(SubscriptionBase.class);
    Mockito.when(subscription.getStartDate()).thenReturn(bpStartDateUTC);
    // Create a the base plan associated with that subscription
    final Plan plan = Mockito.mock(Plan.class);
    Mockito.when(subscription.getLastActivePlan()).thenReturn(plan);
    Mockito.when(subscription.getDateOfFirstRecurringNonZeroCharge()).thenReturn(bpStartDateUTC);
    final ImmutableAccountData account = Mockito.mock(ImmutableAccountData.class);
    Mockito.when(account.getTimeZone()).thenReturn(accountTimeZone);
    final Integer billCycleDayLocal = BillCycleDayCalculator.calculateBcdForAlignment(new HashMap<UUID, Integer>(), subscription, subscription, BillingAlignment.BUNDLE, internalCallContext, 0);
    Assert.assertEquals(billCycleDayLocal, (Integer) expectedBCDUTC);
}
Also used : SubscriptionBase(org.killbill.billing.subscription.api.SubscriptionBase) ImmutableAccountData(org.killbill.billing.account.api.ImmutableAccountData) SubscriptionBaseBundle(org.killbill.billing.subscription.api.user.SubscriptionBaseBundle) Plan(org.killbill.billing.catalog.api.Plan) UUID(java.util.UUID) DateTimeZone(org.joda.time.DateTimeZone) DateTime(org.joda.time.DateTime) Test(org.testng.annotations.Test)

Example 94 with SubscriptionBase

use of org.killbill.billing.subscription.api.SubscriptionBase in project killbill by killbill.

the class TestOverdueWithSubscriptionCancellation method testCheckSubscriptionCancellation.

@Test(groups = "slow", retryAnalyzer = FlakyRetryAnalyzer.class)
public void testCheckSubscriptionCancellation() throws Exception {
    clock.setTime(new DateTime(2012, 5, 1, 0, 3, 42, 0));
    setupAccount();
    // Set next invoice to fail and create subscription
    paymentPlugin.makeAllInvoicesFailWithError(true);
    final DefaultEntitlement baseEntitlement = createBaseEntitlementAndCheckForCompletion(account.getId(), "externalKey", productName, ProductCategory.BASE, term, NextEvent.CREATE, NextEvent.BLOCK, NextEvent.INVOICE);
    bundle = subscriptionApi.getSubscriptionBundle(baseEntitlement.getBundleId(), callContext);
    invoiceChecker.checkInvoice(account.getId(), 1, callContext, new ExpectedInvoiceItemCheck(new LocalDate(2012, 5, 1), null, InvoiceItemType.FIXED, new BigDecimal("0")));
    invoiceChecker.checkChargedThroughDate(baseEntitlement.getId(), new LocalDate(2012, 5, 1), callContext);
    final DefaultEntitlement addOn1 = addAOEntitlementAndCheckForCompletion(baseEntitlement.getBundleId(), "Holster", ProductCategory.ADD_ON, BillingPeriod.MONTHLY, NextEvent.CREATE, NextEvent.BLOCK, NextEvent.INVOICE);
    final DefaultEntitlement addOn2 = addAOEntitlementAndCheckForCompletion(baseEntitlement.getBundleId(), "Holster", ProductCategory.ADD_ON, BillingPeriod.MONTHLY, NextEvent.CREATE, NextEvent.BLOCK, NextEvent.INVOICE);
    // Cancel addOn1 one day after
    clock.addDays(1);
    cancelEntitlementAndCheckForCompletion(addOn1, NextEvent.BLOCK, NextEvent.CANCEL, NextEvent.NULL_INVOICE);
    // DAY 30 have to get out of trial before first payment
    addDaysAndCheckForCompletion(29, NextEvent.PHASE, NextEvent.PHASE, NextEvent.NULL_INVOICE, NextEvent.INVOICE, NextEvent.PAYMENT_ERROR, NextEvent.INVOICE_PAYMENT_ERROR);
    invoiceChecker.checkChargedThroughDate(baseEntitlement.getId(), new LocalDate(2012, 6, 30), callContext);
    // Should still be in clear state
    checkODState(OverdueWrapper.CLEAR_STATE_NAME);
    // DAY 36 -- RIGHT AFTER OD1 (two block events, for the cancellation and the OD1 state)
    // One BLOCK event is for the overdue state transition
    // The 2 other BLOCK are for the entitlement blocking states for both base plan and addOn2
    addDaysAndCheckForCompletion(6, NextEvent.BLOCK, NextEvent.BLOCK, NextEvent.BLOCK, NextEvent.CANCEL, NextEvent.CANCEL, NextEvent.INVOICE, NextEvent.INVOICE_ADJUSTMENT);
    // Should be in OD1
    checkODState("OD1");
    final SubscriptionBase cancelledBaseSubscription = ((DefaultEntitlement) entitlementApi.getEntitlementForId(baseEntitlement.getId(), callContext)).getSubscriptionBase();
    assertTrue(cancelledBaseSubscription.getState() == EntitlementState.CANCELLED);
    final SubscriptionBase cancelledAddon1 = ((DefaultEntitlement) entitlementApi.getEntitlementForId(addOn1.getId(), callContext)).getSubscriptionBase();
    assertTrue(cancelledAddon1.getState() == EntitlementState.CANCELLED);
}
Also used : SubscriptionBase(org.killbill.billing.subscription.api.SubscriptionBase) DefaultEntitlement(org.killbill.billing.entitlement.api.DefaultEntitlement) ExpectedInvoiceItemCheck(org.killbill.billing.beatrix.util.InvoiceChecker.ExpectedInvoiceItemCheck) LocalDate(org.joda.time.LocalDate) DateTime(org.joda.time.DateTime) BigDecimal(java.math.BigDecimal) Test(org.testng.annotations.Test)

Example 95 with SubscriptionBase

use of org.killbill.billing.subscription.api.SubscriptionBase in project killbill by killbill.

the class InvoiceChecker method checkChargedThroughDate.

public void checkChargedThroughDate(final UUID entitlementId, final LocalDate expectedLocalCTD, final CallContext context) {
    try {
        final DefaultEntitlement entitlement = (DefaultEntitlement) entitlementApi.getEntitlementForId(entitlementId, context);
        final SubscriptionBase subscription = entitlement.getSubscriptionBase();
        if (expectedLocalCTD == null) {
            assertNull(subscription.getChargedThroughDate());
        } else {
            final String msg = String.format("Checking CTD for entitlement %s : expectedLocalCTD = %s, got %s", entitlementId, expectedLocalCTD, subscription.getChargedThroughDate().toLocalDate());
            assertTrue(expectedLocalCTD.compareTo(subscription.getChargedThroughDate().toLocalDate()) == 0, msg);
        }
    } catch (final EntitlementApiException e) {
        fail("Failed to retrieve entitlement for " + entitlementId);
    }
}
Also used : SubscriptionBase(org.killbill.billing.subscription.api.SubscriptionBase) DefaultEntitlement(org.killbill.billing.entitlement.api.DefaultEntitlement) EntitlementApiException(org.killbill.billing.entitlement.api.EntitlementApiException)

Aggregations

SubscriptionBase (org.killbill.billing.subscription.api.SubscriptionBase)120 Test (org.testng.annotations.Test)47 UUID (java.util.UUID)46 DateTime (org.joda.time.DateTime)40 Plan (org.killbill.billing.catalog.api.Plan)37 ArrayList (java.util.ArrayList)35 LocalDate (org.joda.time.LocalDate)33 DefaultSubscriptionBase (org.killbill.billing.subscription.api.user.DefaultSubscriptionBase)32 BillingEvent (org.killbill.billing.junction.BillingEvent)30 PlanPhase (org.killbill.billing.catalog.api.PlanPhase)26 MockPlan (org.killbill.billing.catalog.MockPlan)24 MockPlanPhase (org.killbill.billing.catalog.MockPlanPhase)24 MockBillingEventSet (org.killbill.billing.invoice.MockBillingEventSet)23 SubscriptionBaseApiException (org.killbill.billing.subscription.api.user.SubscriptionBaseApiException)23 BigDecimal (java.math.BigDecimal)22 LinkedList (java.util.LinkedList)21 Invoice (org.killbill.billing.invoice.api.Invoice)21 AccountInvoices (org.killbill.billing.invoice.optimizer.InvoiceOptimizerBase.AccountInvoices)21 BillingEventSet (org.killbill.billing.junction.BillingEventSet)21 DefaultInvoice (org.killbill.billing.invoice.model.DefaultInvoice)20