Search in sources :

Example 6 with Product

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

the class TestCatalogUpdater method testAddNoTrialPlanOnFirstCatalog.

@Test(groups = "fast")
public void testAddNoTrialPlanOnFirstCatalog() throws CatalogApiException {
    final DateTime now = clock.getUTCNow();
    final SimplePlanDescriptor desc = new DefaultSimplePlanDescriptor("foo-monthly", "Foo", ProductCategory.BASE, Currency.EUR, BigDecimal.TEN, BillingPeriod.MONTHLY, 0, TimeUnit.UNLIMITED, ImmutableList.<String>of());
    final CatalogUpdater catalogUpdater = new CatalogUpdater(BillingMode.IN_ADVANCE, now, desc.getCurrency());
    catalogUpdater.addSimplePlanDescriptor(desc);
    final StandaloneCatalog catalog = catalogUpdater.getCatalog();
    assertEquals(catalog.getCurrentProducts().size(), 1);
    final Product product = catalog.getCurrentProducts().iterator().next();
    assertEquals(product.getName(), "Foo");
    assertEquals(product.getCategory(), ProductCategory.BASE);
    assertEquals(catalog.getCurrentPlans().size(), 1);
    final Plan plan = catalog.findCurrentPlan("foo-monthly");
    assertEquals(plan.getName(), "foo-monthly");
    assertEquals(plan.getInitialPhases().length, 0);
    assertEquals(plan.getFinalPhase().getPhaseType(), PhaseType.EVERGREEN);
    assertNull(plan.getFinalPhase().getFixed());
    assertEquals(plan.getFinalPhase().getName(), "foo-monthly-evergreen");
    assertEquals(plan.getFinalPhase().getRecurring().getBillingPeriod(), BillingPeriod.MONTHLY);
    assertEquals(plan.getFinalPhase().getRecurring().getRecurringPrice().getPrices().length, 1);
    assertEquals(plan.getFinalPhase().getRecurring().getRecurringPrice().getPrices()[0].getValue(), BigDecimal.TEN);
    assertEquals(plan.getFinalPhase().getRecurring().getRecurringPrice().getPrices()[0].getCurrency(), Currency.EUR);
    assertEquals(catalog.getPriceLists().getAllPriceLists().size(), 1);
    final PriceList priceList = catalog.getPriceLists().getAllPriceLists().get(0);
    assertEquals(priceList.getName(), new PriceListDefault().getName());
    assertEquals(priceList.getPlans().size(), 1);
    assertEquals(priceList.getPlans().iterator().next().getName(), "foo-monthly");
}
Also used : Product(org.killbill.billing.catalog.api.Product) Plan(org.killbill.billing.catalog.api.Plan) PriceList(org.killbill.billing.catalog.api.PriceList) DateTime(org.joda.time.DateTime) SimplePlanDescriptor(org.killbill.billing.catalog.api.SimplePlanDescriptor) DefaultSimplePlanDescriptor(org.killbill.billing.catalog.api.user.DefaultSimplePlanDescriptor) DefaultSimplePlanDescriptor(org.killbill.billing.catalog.api.user.DefaultSimplePlanDescriptor) Test(org.testng.annotations.Test)

Example 7 with Product

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

the class CatalogUpdater method addSimplePlanDescriptor.

public void addSimplePlanDescriptor(final SimplePlanDescriptor desc) throws CatalogApiException {
    // We need at least a planId
    if (desc == null || desc.getPlanId() == null) {
        throw new CatalogApiException(ErrorCode.CAT_INVALID_SIMPLE_PLAN_DESCRIPTOR, desc);
    }
    DefaultPlan plan = (DefaultPlan) getExistingPlan(desc.getPlanId());
    if (plan == null && desc.getProductName() == null) {
        throw new CatalogApiException(ErrorCode.CAT_INVALID_SIMPLE_PLAN_DESCRIPTOR, desc);
    }
    validateNewPlanDescriptor(desc);
    DefaultProduct product = plan != null ? (DefaultProduct) plan.getProduct() : (DefaultProduct) getExistingProduct(desc.getProductName());
    if (product == null) {
        product = new DefaultProduct();
        product.setName(desc.getProductName());
        product.setCatagory(desc.getProductCategory());
        product.initialize(catalog, DEFAULT_URI);
        catalog.addProduct(product);
    }
    if (plan == null) {
        plan = new DefaultPlan();
        plan.setName(desc.getPlanId());
        plan.setPriceListName(PriceListSet.DEFAULT_PRICELIST_NAME);
        plan.setProduct(product);
        if (desc.getTrialLength() > 0 && desc.getTrialTimeUnit() != TimeUnit.UNLIMITED) {
            final DefaultPlanPhase trialPhase = new DefaultPlanPhase();
            trialPhase.setPhaseType(PhaseType.TRIAL);
            trialPhase.setDuration(new DefaultDuration().setUnit(desc.getTrialTimeUnit()).setNumber(desc.getTrialLength()));
            trialPhase.setFixed(new DefaultFixed().setFixedPrice(new DefaultInternationalPrice().setPrices(new DefaultPrice[] { new DefaultPrice().setCurrency(desc.getCurrency()).setValue(BigDecimal.ZERO) })));
            plan.setInitialPhases(new DefaultPlanPhase[] { trialPhase });
        }
        catalog.addPlan(plan);
    } else {
        validateExistingPlan(plan, desc);
    }
    //
    if (!isCurrencySupported(desc.getCurrency())) {
        catalog.addCurrency(desc.getCurrency());
        // Reset the fixed price to null so the isZero() logic goes through new currencies and set the zero price for all
        if (plan.getInitialPhases().length == 1) {
            ((DefaultInternationalPrice) plan.getInitialPhases()[0].getFixed().getPrice()).setPrices(null);
        }
    }
    DefaultPlanPhase evergreenPhase = plan.getFinalPhase();
    if (evergreenPhase == null) {
        evergreenPhase = new DefaultPlanPhase();
        evergreenPhase.setPhaseType(PhaseType.EVERGREEN);
        evergreenPhase.setDuration(new DefaultDuration().setUnit(TimeUnit.UNLIMITED));
        plan.setFinalPhase(evergreenPhase);
    }
    DefaultRecurring recurring = (DefaultRecurring) evergreenPhase.getRecurring();
    if (recurring == null) {
        recurring = new DefaultRecurring();
        recurring.setBillingPeriod(desc.getBillingPeriod());
        recurring.setRecurringPrice(new DefaultInternationalPrice().setPrices(new DefaultPrice[0]));
        evergreenPhase.setRecurring(recurring);
    }
    if (!isPriceForCurrencyExists(recurring.getRecurringPrice(), desc.getCurrency())) {
        catalog.addRecurringPriceToPlan(recurring.getRecurringPrice(), new DefaultPrice().setCurrency(desc.getCurrency()).setValue(desc.getAmount()));
    }
    if (desc.getProductCategory() == ProductCategory.ADD_ON) {
        for (final String bp : desc.getAvailableBaseProducts()) {
            final Product targetBasePlan = getExistingProduct(bp);
            boolean found = false;
            for (Product cur : targetBasePlan.getAvailable()) {
                if (cur.getName().equals(product.getName())) {
                    found = true;
                    break;
                }
            }
            if (!found) {
                catalog.addProductAvailableAO(getExistingProduct(bp), product);
            }
        }
    }
    // Reinit catalog
    catalog.initialize(catalog, DEFAULT_URI);
}
Also used : CatalogApiException(org.killbill.billing.catalog.api.CatalogApiException) Product(org.killbill.billing.catalog.api.Product)

Example 8 with Product

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

the class TestEhCacheCatalogCache method testExistingTenantCatalog.

//
// Verify CatalogCache returns per tenant catalog:
// 1. We first mock TenantInternalApi to return a different catalog than the default one
// 2. We then mock TenantInternalApi to throw RuntimeException which means catalog was cached and there was no additional call
//    to the TenantInternalApi api (otherwise test would fail with RuntimeException)
//
@Test(groups = "fast")
public void testExistingTenantCatalog() throws CatalogApiException, URISyntaxException, IOException {
    final InternalCallContext differentMultiTenantContext = Mockito.mock(InternalCallContext.class);
    Mockito.when(differentMultiTenantContext.getTenantRecordId()).thenReturn(55667788L);
    final AtomicBoolean shouldThrow = new AtomicBoolean(false);
    final Long multiTenantRecordId = multiTenantContext.getTenantRecordId();
    final Long otherMultiTenantRecordId = otherMultiTenantContext.getTenantRecordId();
    final InputStream tenantInputCatalog = UriAccessor.accessUri(new URI(Resources.getResource("SpyCarAdvanced.xml").toExternalForm()));
    final String tenantCatalogXML = CharStreams.toString(new InputStreamReader(tenantInputCatalog, "UTF-8"));
    final InputStream otherTenantInputCatalog = UriAccessor.accessUri(new URI(Resources.getResource("SpyCarBasic.xml").toExternalForm()));
    final String otherTenantCatalogXML = CharStreams.toString(new InputStreamReader(otherTenantInputCatalog, "UTF-8"));
    Mockito.when(tenantInternalApi.getTenantCatalogs(Mockito.any(InternalTenantContext.class))).thenAnswer(new Answer<List<String>>() {

        @Override
        public List<String> answer(final InvocationOnMock invocation) throws Throwable {
            if (shouldThrow.get()) {
                throw new RuntimeException();
            }
            final InternalTenantContext internalContext = (InternalTenantContext) invocation.getArguments()[0];
            if (multiTenantRecordId.equals(internalContext.getTenantRecordId())) {
                return ImmutableList.<String>of(tenantCatalogXML);
            } else if (otherMultiTenantRecordId.equals(internalContext.getTenantRecordId())) {
                return ImmutableList.<String>of(otherTenantCatalogXML);
            } else {
                return ImmutableList.<String>of();
            }
        }
    });
    // Verify the lookup for a non-cached tenant. No system config is set yet but EhCacheCatalogCache returns a default empty one
    VersionedCatalog differentResult = catalogCache.getCatalog(true, true, differentMultiTenantContext);
    Assert.assertNotNull(differentResult);
    Assert.assertEquals(differentResult.getCatalogName(), "EmptyCatalog");
    // Make sure the cache loader isn't invoked, see https://github.com/killbill/killbill/issues/300
    shouldThrow.set(true);
    differentResult = catalogCache.getCatalog(true, true, differentMultiTenantContext);
    Assert.assertNotNull(differentResult);
    Assert.assertEquals(differentResult.getCatalogName(), "EmptyCatalog");
    shouldThrow.set(false);
    // Set a default config
    catalogCache.loadDefaultCatalog(Resources.getResource("SpyCarBasic.xml").toExternalForm());
    // Verify the lookup for this tenant
    final VersionedCatalog result = catalogCache.getCatalog(true, true, multiTenantContext);
    Assert.assertNotNull(result);
    final Collection<Product> products = result.getProducts(clock.getUTCNow());
    Assert.assertEquals(products.size(), 6);
    // Verify the lookup for another tenant
    final VersionedCatalog otherResult = catalogCache.getCatalog(true, true, otherMultiTenantContext);
    Assert.assertNotNull(otherResult);
    final Collection<Product> otherProducts = otherResult.getProducts(clock.getUTCNow());
    Assert.assertEquals(otherProducts.size(), 3);
    shouldThrow.set(true);
    // Verify the lookup for this tenant
    final VersionedCatalog result2 = catalogCache.getCatalog(true, true, multiTenantContext);
    Assert.assertEquals(result2, result);
    // Verify the lookup with another context for the same tenant
    final InternalCallContext sameMultiTenantContext = Mockito.mock(InternalCallContext.class);
    Mockito.when(sameMultiTenantContext.getAccountRecordId()).thenReturn(9102L);
    Mockito.when(sameMultiTenantContext.getTenantRecordId()).thenReturn(multiTenantRecordId);
    Assert.assertEquals(catalogCache.getCatalog(true, true, sameMultiTenantContext), result);
    // Verify the lookup with the other tenant
    Assert.assertEquals(catalogCache.getCatalog(true, true, otherMultiTenantContext), otherResult);
}
Also used : InputStreamReader(java.io.InputStreamReader) InputStream(java.io.InputStream) DefaultProduct(org.killbill.billing.catalog.DefaultProduct) Product(org.killbill.billing.catalog.api.Product) InternalCallContext(org.killbill.billing.callcontext.InternalCallContext) URI(java.net.URI) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) VersionedCatalog(org.killbill.billing.catalog.VersionedCatalog) InternalTenantContext(org.killbill.billing.callcontext.InternalTenantContext) InvocationOnMock(org.mockito.invocation.InvocationOnMock) ImmutableList(com.google.common.collect.ImmutableList) List(java.util.List) StandaloneCatalogWithPriceOverride(org.killbill.billing.catalog.StandaloneCatalogWithPriceOverride) Test(org.testng.annotations.Test)

Example 9 with Product

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

the class StandaloneCatalogMapper method toDefaultProduct.

private Product toDefaultProduct(@Nullable final Product input) {
    if (input == null) {
        return null;
    }
    if (tmpDefaultProducts != null) {
        final Product existingProduct = tmpDefaultProducts.get(input.getName());
        if (existingProduct == null)
            throw new IllegalStateException("Unknown product " + input.getName());
        return existingProduct;
    }
    final DefaultProduct result = new DefaultProduct();
    result.setCatalogName(catalogName);
    result.setCatagory(input.getCategory());
    result.setName(input.getName());
    return result;
}
Also used : DefaultProduct(org.killbill.billing.catalog.DefaultProduct) DefaultProduct(org.killbill.billing.catalog.DefaultProduct) Product(org.killbill.billing.catalog.api.Product)

Example 10 with Product

use of org.killbill.billing.catalog.api.Product 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.findCurrentPlan(from.getPlanName());
        inFromProduct = plan.getProduct();
        inFromBillingPeriod = plan.getRecurringBillingPeriod();
        inFromProductCategory = plan.getProduct().getCategory();
        inFromPriceList = catalog.findCurrentPricelist(plan.getPriceListName());
    } else {
        inFromProduct = catalog.findCurrentProduct(from.getProductName());
        inFromBillingPeriod = from.getBillingPeriod();
        inFromProductCategory = inFromProduct.getCategory();
        inFromPriceList = from.getPriceListName() != null ? catalog.findCurrentPricelist(from.getPriceListName()) : null;
    }
    final Product inToProduct;
    final BillingPeriod inToBillingPeriod;
    final ProductCategory inToProductCategory;
    final PriceList inToPriceList;
    if (to.getPlanName() != null) {
        final Plan plan = catalog.findCurrentPlan(to.getPlanName());
        inToProduct = plan.getProduct();
        inToBillingPeriod = plan.getRecurringBillingPeriod();
        inToProductCategory = plan.getProduct().getCategory();
        inToPriceList = catalog.findCurrentPricelist(plan.getPriceListName());
    } else {
        inToProduct = catalog.findCurrentProduct(to.getProductName());
        inToBillingPeriod = to.getBillingPeriod();
        inToProductCategory = inToProduct.getCategory();
        inToPriceList = to.getPriceListName() != null ? catalog.findCurrentPricelist(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;
}
Also used : BillingPeriod(org.killbill.billing.catalog.api.BillingPeriod) ProductCategory(org.killbill.billing.catalog.api.ProductCategory) DefaultProduct(org.killbill.billing.catalog.DefaultProduct) Product(org.killbill.billing.catalog.api.Product) Plan(org.killbill.billing.catalog.api.Plan) PriceList(org.killbill.billing.catalog.api.PriceList) DefaultPriceList(org.killbill.billing.catalog.DefaultPriceList)

Aggregations

Product (org.killbill.billing.catalog.api.Product)29 Plan (org.killbill.billing.catalog.api.Plan)15 DefaultProduct (org.killbill.billing.catalog.DefaultProduct)8 PriceList (org.killbill.billing.catalog.api.PriceList)7 Test (org.testng.annotations.Test)6 BillingPeriod (org.killbill.billing.catalog.api.BillingPeriod)5 DateTime (org.joda.time.DateTime)4 CatalogApiException (org.killbill.billing.catalog.api.CatalogApiException)4 PlanPhase (org.killbill.billing.catalog.api.PlanPhase)4 ArrayList (java.util.ArrayList)3 ProductCategory (org.killbill.billing.catalog.api.ProductCategory)3 SubscriptionBaseEvent (org.killbill.billing.subscription.events.SubscriptionBaseEvent)3 InternalCallContext (org.killbill.billing.callcontext.InternalCallContext)2 DefaultPriceList (org.killbill.billing.catalog.DefaultPriceList)2 StandaloneCatalog (org.killbill.billing.catalog.StandaloneCatalog)2 StandaloneCatalogWithPriceOverride (org.killbill.billing.catalog.StandaloneCatalogWithPriceOverride)2 VersionedCatalog (org.killbill.billing.catalog.VersionedCatalog)2 PlanPhasePriceOverride (org.killbill.billing.catalog.api.PlanPhasePriceOverride)2 SimplePlanDescriptor (org.killbill.billing.catalog.api.SimplePlanDescriptor)2 DefaultSimplePlanDescriptor (org.killbill.billing.catalog.api.user.DefaultSimplePlanDescriptor)2