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");
}
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);
}
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);
}
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;
}
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;
}
Aggregations