Index: persistence/src/main/java/org/yes/cart/domain/entity/impl/ProductDynamicBoostStrategy.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- persistence/src/main/java/org/yes/cart/domain/entity/impl/ProductDynamicBoostStrategy.java (revision da025f7c1e8734fae7021d0d8ea8c3a765ca5f8f) +++ persistence/src/main/java/org/yes/cart/domain/entity/impl/ProductDynamicBoostStrategy.java (revision ) @@ -50,7 +50,7 @@ for (final ProductCategory pcat : product.getProductCategory()) { // 500 is base rank, anything lower reduces boost, higher increased boost // 1pt == 0.001f boost - boost += ((float) (pcat.getRank() - 500)) / 1000f; + boost += pcat.getRank() == 500 ? 0 : ((float) (pcat.getRank() - 500)) / 1000f; } return boost; } Index: web/support/src/main/resources/websupport-storefront.xml IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- web/support/src/main/resources/websupport-storefront.xml (revision da025f7c1e8734fae7021d0d8ea8c3a765ca5f8f) +++ web/support/src/main/resources/websupport-storefront.xml (revision ) @@ -239,6 +239,7 @@ + \ No newline at end of file Index: web/support/src/test/java/org/yes/cart/web/support/service/impl/CentralViewResolverProductImplTest.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- web/support/src/test/java/org/yes/cart/web/support/service/impl/CentralViewResolverProductImplTest.java (revision da025f7c1e8734fae7021d0d8ea8c3a765ca5f8f) +++ web/support/src/test/java/org/yes/cart/web/support/service/impl/CentralViewResolverProductImplTest.java (revision ) @@ -24,11 +24,17 @@ import org.yes.cart.domain.entity.ProductSku; import org.yes.cart.domain.entity.ProductType; import org.yes.cart.domain.misc.Pair; +import org.yes.cart.domain.query.LuceneQueryFactory; +import org.yes.cart.domain.queryobject.NavigationContext; import org.yes.cart.service.domain.ProductService; +import org.yes.cart.util.ShopCodeContext; import org.yes.cart.web.support.constants.CentralViewLabel; import org.yes.cart.web.support.constants.WebParametersKeys; +import java.util.Arrays; import java.util.HashMap; +import java.util.List; +import java.util.Map; import static org.junit.Assert.*; @@ -46,8 +52,9 @@ public void testResolveMainPanelRendererLabelNA() throws Exception { final ProductService productService = context.mock(ProductService.class, "productService"); + final LuceneQueryFactory luceneQueryFactory = context.mock(LuceneQueryFactory.class, "luceneQueryFactory"); - CentralViewResolverProductImpl resolver = new CentralViewResolverProductImpl(productService); + CentralViewResolverProductImpl resolver = new CentralViewResolverProductImpl(productService, luceneQueryFactory); final Pair resolved = resolver.resolveMainPanelRendererLabel(new HashMap() {{ put("someparam", "1"); @@ -62,8 +69,9 @@ public void testResolveMainPanelRendererLabelSkuNaN() throws Exception { final ProductService productService = context.mock(ProductService.class, "productService"); + final LuceneQueryFactory luceneQueryFactory = context.mock(LuceneQueryFactory.class, "luceneQueryFactory"); - CentralViewResolverProductImpl resolver = new CentralViewResolverProductImpl(productService); + CentralViewResolverProductImpl resolver = new CentralViewResolverProductImpl(productService, luceneQueryFactory); final Pair resolved = resolver.resolveMainPanelRendererLabel(new HashMap() {{ put(WebParametersKeys.SKU_ID, "abc"); @@ -74,21 +82,69 @@ } @Test + public void testResolveMainPanelRendererLabelSkuNoSkuInIndex() throws Exception { + + final ProductService productService = context.mock(ProductService.class, "productService"); + final LuceneQueryFactory luceneQueryFactory = context.mock(LuceneQueryFactory.class, "luceneQueryFactory"); + final NavigationContext hasProducts = context.mock(NavigationContext.class, "hasProducts"); + + CentralViewResolverProductImpl resolver = new CentralViewResolverProductImpl(productService, luceneQueryFactory); + + context.checking(new Expectations() {{ + one(luceneQueryFactory).getFilteredNavigationQueryChain(with(11L), with((List) null), with(false), with(any(Map.class))); will(returnValue(hasProducts)); + one(hasProducts).getProductQuery(); + one(productService).getProductQty(null); will(returnValue(0)); + }}); + + try { + + ShopCodeContext.setShopId(11L); + + final Pair resolved = resolver.resolveMainPanelRendererLabel(new HashMap() {{ + put(WebParametersKeys.SKU_ID, "1"); + }}); + + assertNull(resolved); + + } finally { + + ShopCodeContext.clear(); + + } + context.assertIsSatisfied(); + } + + @Test public void testResolveMainPanelRendererLabelSkuNoSku() throws Exception { final ProductService productService = context.mock(ProductService.class, "productService"); + final LuceneQueryFactory luceneQueryFactory = context.mock(LuceneQueryFactory.class, "luceneQueryFactory"); + final NavigationContext hasProducts = context.mock(NavigationContext.class, "hasProducts"); - CentralViewResolverProductImpl resolver = new CentralViewResolverProductImpl(productService); + CentralViewResolverProductImpl resolver = new CentralViewResolverProductImpl(productService, luceneQueryFactory); context.checking(new Expectations() {{ + one(luceneQueryFactory).getFilteredNavigationQueryChain(with(11L), with((List) null), with(false), with(any(Map.class))); will(returnValue(hasProducts)); + one(hasProducts).getProductQuery(); + one(productService).getProductQty(null); will(returnValue(1)); one(productService).getSkuById(1L, true); will(returnValue(null)); }}); + try { + + ShopCodeContext.setShopId(11L); + - final Pair resolved = resolver.resolveMainPanelRendererLabel(new HashMap() {{ - put(WebParametersKeys.SKU_ID, "1"); - }}); + final Pair resolved = resolver.resolveMainPanelRendererLabel(new HashMap() {{ + put(WebParametersKeys.SKU_ID, "1"); + }}); - assertNull(resolved); + assertNull(resolved); + + } finally { + + ShopCodeContext.clear(); + + } context.assertIsSatisfied(); } @@ -96,26 +152,41 @@ public void testResolveMainPanelRendererLabelSkuTemplate() throws Exception { final ProductService productService = context.mock(ProductService.class, "productService"); + final LuceneQueryFactory luceneQueryFactory = context.mock(LuceneQueryFactory.class, "luceneQueryFactory"); + final NavigationContext hasProducts = context.mock(NavigationContext.class, "hasProducts"); final ProductSku sku = context.mock(ProductSku.class, "sku"); final Product product = context.mock(Product.class, "product"); final ProductType type = context.mock(ProductType.class, "type"); - CentralViewResolverProductImpl resolver = new CentralViewResolverProductImpl(productService); + CentralViewResolverProductImpl resolver = new CentralViewResolverProductImpl(productService, luceneQueryFactory); context.checking(new Expectations() {{ + one(luceneQueryFactory).getFilteredNavigationQueryChain(with(11L), with((List) null), with(false), with(any(Map.class))); will(returnValue(hasProducts)); + one(hasProducts).getProductQuery(); + one(productService).getProductQty(null); will(returnValue(1)); one(productService).getSkuById(1L, true); will(returnValue(sku)); one(sku).getProduct(); will(returnValue(product)); one(product).getProducttype(); will(returnValue(type)); one(type).getUitemplate(); will(returnValue("skutemplate1")); }}); + try { + + ShopCodeContext.setShopId(11L); + - final Pair resolved = resolver.resolveMainPanelRendererLabel(new HashMap() {{ - put(WebParametersKeys.SKU_ID, "1"); - }}); + final Pair resolved = resolver.resolveMainPanelRendererLabel(new HashMap() {{ + put(WebParametersKeys.SKU_ID, "1"); + }}); - assertNotNull(resolved); - assertEquals("skutemplate1", resolved.getFirst()); - assertEquals(CentralViewLabel.SKU, resolved.getSecond()); + assertNotNull(resolved); + assertEquals("skutemplate1", resolved.getFirst()); + assertEquals(CentralViewLabel.SKU, resolved.getSecond()); + + } finally { + + ShopCodeContext.clear(); + + } context.assertIsSatisfied(); } @@ -123,26 +194,41 @@ public void testResolveMainPanelRendererLabelSkuNoTemplate() throws Exception { final ProductService productService = context.mock(ProductService.class, "productService"); + final LuceneQueryFactory luceneQueryFactory = context.mock(LuceneQueryFactory.class, "luceneQueryFactory"); + final NavigationContext hasProducts = context.mock(NavigationContext.class, "hasProducts"); final ProductSku sku = context.mock(ProductSku.class, "sku"); final Product product = context.mock(Product.class, "product"); final ProductType type = context.mock(ProductType.class, "type"); - CentralViewResolverProductImpl resolver = new CentralViewResolverProductImpl(productService); + CentralViewResolverProductImpl resolver = new CentralViewResolverProductImpl(productService, luceneQueryFactory); context.checking(new Expectations() {{ + one(luceneQueryFactory).getFilteredNavigationQueryChain(with(11L), with((List) null), with(false), with(any(Map.class))); will(returnValue(hasProducts)); + one(hasProducts).getProductQuery(); + one(productService).getProductQty(null); will(returnValue(1)); one(productService).getSkuById(1L, true); will(returnValue(sku)); one(sku).getProduct(); will(returnValue(product)); one(product).getProducttype(); will(returnValue(type)); one(type).getUitemplate(); will(returnValue("")); }}); + try { + + ShopCodeContext.setShopId(11L); + - final Pair resolved = resolver.resolveMainPanelRendererLabel(new HashMap() {{ - put(WebParametersKeys.SKU_ID, "1"); - }}); + final Pair resolved = resolver.resolveMainPanelRendererLabel(new HashMap() {{ + put(WebParametersKeys.SKU_ID, "1"); + }}); - assertNotNull(resolved); - assertEquals(CentralViewLabel.SKU, resolved.getFirst()); - assertEquals(CentralViewLabel.SKU, resolved.getSecond()); + assertNotNull(resolved); + assertEquals(CentralViewLabel.SKU, resolved.getFirst()); + assertEquals(CentralViewLabel.SKU, resolved.getSecond()); + + } finally { + + ShopCodeContext.clear(); + + } context.assertIsSatisfied(); } @@ -150,8 +236,9 @@ public void testResolveMainPanelRendererLabelProductNaN() throws Exception { final ProductService productService = context.mock(ProductService.class, "productService"); + final LuceneQueryFactory luceneQueryFactory = context.mock(LuceneQueryFactory.class, "luceneQueryFactory"); - CentralViewResolverProductImpl resolver = new CentralViewResolverProductImpl(productService); + CentralViewResolverProductImpl resolver = new CentralViewResolverProductImpl(productService, luceneQueryFactory); final Pair resolved = resolver.resolveMainPanelRendererLabel(new HashMap() {{ put(WebParametersKeys.PRODUCT_ID, "abc"); @@ -162,21 +249,70 @@ } @Test + public void testResolveMainPanelRendererLabelProductNoProductInIndex() throws Exception { + + final ProductService productService = context.mock(ProductService.class, "productService"); + final LuceneQueryFactory luceneQueryFactory = context.mock(LuceneQueryFactory.class, "luceneQueryFactory"); + final NavigationContext hasProducts = context.mock(NavigationContext.class, "hasProducts"); + + CentralViewResolverProductImpl resolver = new CentralViewResolverProductImpl(productService, luceneQueryFactory); + + context.checking(new Expectations() {{ + one(luceneQueryFactory).getFilteredNavigationQueryChain(with(11L), with((List) null), with(false), with(any(Map.class))); will(returnValue(hasProducts)); + one(hasProducts).getProductQuery(); + one(productService).getProductQty(null); will(returnValue(0)); + }}); + + try { + + ShopCodeContext.setShopId(11L); + + + final Pair resolved = resolver.resolveMainPanelRendererLabel(new HashMap() {{ + put(WebParametersKeys.PRODUCT_ID, "1"); + }}); + + assertNull(resolved); + + } finally { + + ShopCodeContext.clear(); + + } + context.assertIsSatisfied(); + } + + @Test public void testResolveMainPanelRendererLabelProductNoProduct() throws Exception { final ProductService productService = context.mock(ProductService.class, "productService"); + final LuceneQueryFactory luceneQueryFactory = context.mock(LuceneQueryFactory.class, "luceneQueryFactory"); + final NavigationContext hasProducts = context.mock(NavigationContext.class, "hasProducts"); - CentralViewResolverProductImpl resolver = new CentralViewResolverProductImpl(productService); + CentralViewResolverProductImpl resolver = new CentralViewResolverProductImpl(productService, luceneQueryFactory); context.checking(new Expectations() {{ + one(luceneQueryFactory).getFilteredNavigationQueryChain(with(11L), with((List) null), with(false), with(any(Map.class))); will(returnValue(hasProducts)); + one(hasProducts).getProductQuery(); + one(productService).getProductQty(null); will(returnValue(1)); one(productService).getProductById(1L, true); will(returnValue(null)); }}); + try { + + ShopCodeContext.setShopId(11L); + - final Pair resolved = resolver.resolveMainPanelRendererLabel(new HashMap() {{ - put(WebParametersKeys.PRODUCT_ID, "1"); - }}); + final Pair resolved = resolver.resolveMainPanelRendererLabel(new HashMap() {{ + put(WebParametersKeys.PRODUCT_ID, "1"); + }}); - assertNull(resolved); + assertNull(resolved); + + } finally { + + ShopCodeContext.clear(); + + } context.assertIsSatisfied(); } @@ -184,24 +320,39 @@ public void testResolveMainPanelRendererLabelProductTemplate() throws Exception { final ProductService productService = context.mock(ProductService.class, "productService"); + final LuceneQueryFactory luceneQueryFactory = context.mock(LuceneQueryFactory.class, "luceneQueryFactory"); + final NavigationContext hasProducts = context.mock(NavigationContext.class, "hasProducts"); final Product product = context.mock(Product.class, "product"); final ProductType type = context.mock(ProductType.class, "type"); - CentralViewResolverProductImpl resolver = new CentralViewResolverProductImpl(productService); + CentralViewResolverProductImpl resolver = new CentralViewResolverProductImpl(productService, luceneQueryFactory); context.checking(new Expectations() {{ + one(luceneQueryFactory).getFilteredNavigationQueryChain(with(11L), with((List) null), with(false), with(any(Map.class))); will(returnValue(hasProducts)); + one(hasProducts).getProductQuery(); + one(productService).getProductQty(null); will(returnValue(1)); one(productService).getProductById(1L, true); will(returnValue(product)); one(product).getProducttype(); will(returnValue(type)); one(type).getUitemplate(); will(returnValue("producttemplate1")); }}); + try { + + ShopCodeContext.setShopId(11L); + - final Pair resolved = resolver.resolveMainPanelRendererLabel(new HashMap() {{ - put(WebParametersKeys.PRODUCT_ID, "1"); - }}); + final Pair resolved = resolver.resolveMainPanelRendererLabel(new HashMap() {{ + put(WebParametersKeys.PRODUCT_ID, "1"); + }}); - assertNotNull(resolved); - assertEquals("producttemplate1", resolved.getFirst()); - assertEquals(CentralViewLabel.PRODUCT, resolved.getSecond()); + assertNotNull(resolved); + assertEquals("producttemplate1", resolved.getFirst()); + assertEquals(CentralViewLabel.PRODUCT, resolved.getSecond()); + + } finally { + + ShopCodeContext.clear(); + + } context.assertIsSatisfied(); } @@ -209,24 +360,44 @@ public void testResolveMainPanelRendererLabelProductNoTemplate() throws Exception { final ProductService productService = context.mock(ProductService.class, "productService"); + final LuceneQueryFactory luceneQueryFactory = context.mock(LuceneQueryFactory.class, "luceneQueryFactory"); + final NavigationContext hasProducts = context.mock(NavigationContext.class, "hasProducts"); final Product product = context.mock(Product.class, "product"); final ProductType type = context.mock(ProductType.class, "type"); - CentralViewResolverProductImpl resolver = new CentralViewResolverProductImpl(productService); + CentralViewResolverProductImpl resolver = new CentralViewResolverProductImpl(productService, luceneQueryFactory); context.checking(new Expectations() {{ - one(productService).getProductById(1L, true); will(returnValue(product)); - one(product).getProducttype(); will(returnValue(type)); - one(type).getUitemplate(); will(returnValue("")); + one(luceneQueryFactory).getFilteredNavigationQueryChain(with(11L), with((List) null), with(false), with(any(Map.class))); + will(returnValue(hasProducts)); + one(hasProducts).getProductQuery(); + one(productService).getProductQty(null); + will(returnValue(1)); + one(productService).getProductById(1L, true); + will(returnValue(product)); + one(product).getProducttype(); + will(returnValue(type)); + one(type).getUitemplate(); + will(returnValue("")); }}); + try { + + ShopCodeContext.setShopId(11L); + - final Pair resolved = resolver.resolveMainPanelRendererLabel(new HashMap() {{ - put(WebParametersKeys.PRODUCT_ID, "1"); - }}); + final Pair resolved = resolver.resolveMainPanelRendererLabel(new HashMap() {{ + put(WebParametersKeys.PRODUCT_ID, "1"); + }}); - assertNotNull(resolved); - assertEquals(CentralViewLabel.PRODUCT, resolved.getFirst()); - assertEquals(CentralViewLabel.PRODUCT, resolved.getSecond()); + assertNotNull(resolved); + assertEquals(CentralViewLabel.PRODUCT, resolved.getFirst()); + assertEquals(CentralViewLabel.PRODUCT, resolved.getSecond()); + + } finally { + + ShopCodeContext.clear(); + + } context.assertIsSatisfied(); } Index: web/support/src/main/java/org/yes/cart/web/support/service/impl/CentralViewResolverProductImpl.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- web/support/src/main/java/org/yes/cart/web/support/service/impl/CentralViewResolverProductImpl.java (revision da025f7c1e8734fae7021d0d8ea8c3a765ca5f8f) +++ web/support/src/main/java/org/yes/cart/web/support/service/impl/CentralViewResolverProductImpl.java (revision ) @@ -21,12 +21,18 @@ import org.yes.cart.domain.entity.Product; import org.yes.cart.domain.entity.ProductSku; import org.yes.cart.domain.misc.Pair; +import org.yes.cart.domain.query.LuceneQueryFactory; +import org.yes.cart.domain.query.ProductSearchQueryBuilder; +import org.yes.cart.domain.queryobject.NavigationContext; import org.yes.cart.service.domain.ProductService; +import org.yes.cart.util.ShopCodeContext; import org.yes.cart.web.support.constants.CentralViewLabel; import org.yes.cart.web.support.constants.WebParametersKeys; import org.yes.cart.web.support.service.CentralViewResolver; import org.yes.cart.web.support.util.HttpUtil; +import java.util.Collections; +import java.util.List; import java.util.Map; /** @@ -40,9 +46,11 @@ private static final Pair DEFAULT_P = new Pair(CentralViewLabel.PRODUCT, CentralViewLabel.PRODUCT); private final ProductService productService; + private final LuceneQueryFactory luceneQueryFactory; - public CentralViewResolverProductImpl(final ProductService productService) { + public CentralViewResolverProductImpl(final ProductService productService, final LuceneQueryFactory luceneQueryFactory) { this.productService = productService; + this.luceneQueryFactory = luceneQueryFactory; } /** @@ -65,25 +73,43 @@ final long skuId = NumberUtils.toLong(HttpUtil.getSingleValue(parameters.get(WebParametersKeys.SKU_ID))); if (skuId > 0L) { + + final long shopId = ShopCodeContext.getShopId(); + // shopId will be used for inStock check + final NavigationContext hasProducts = luceneQueryFactory.getFilteredNavigationQueryChain(shopId, null, false, + Collections.singletonMap(ProductSearchQueryBuilder.SKU_ID_FIELD, (List) Collections.singletonList(skuId))); + + if (productService.getProductQty(hasProducts.getProductQuery()) > 0) { + - final ProductSku sku = productService.getSkuById(skuId, true); // Need to load it the same way as central view does - if (sku != null) { - final String template = sku.getProduct().getProducttype().getUitemplate(); - if (StringUtils.isNotBlank(template)) { - return new Pair(template, CentralViewLabel.SKU); - } - return DEFAULT_S; - } - } + final ProductSku sku = productService.getSkuById(skuId, true); // Need to load it the same way as central view does + if (sku != null) { + final String template = sku.getProduct().getProducttype().getUitemplate(); + if (StringUtils.isNotBlank(template)) { + return new Pair(template, CentralViewLabel.SKU); + } + return DEFAULT_S; + } + } + } } else if (parameters.containsKey(WebParametersKeys.PRODUCT_ID)) { final long prodId = NumberUtils.toLong(HttpUtil.getSingleValue(parameters.get(WebParametersKeys.PRODUCT_ID))); if (prodId > 0L) { + + final long shopId = ShopCodeContext.getShopId(); + // shopId will be used for inStock check + final NavigationContext hasProducts = luceneQueryFactory.getFilteredNavigationQueryChain(shopId, null, false, + Collections.singletonMap(ProductSearchQueryBuilder.PRODUCT_ID_FIELD, (List) Collections.singletonList(prodId))); + + if (productService.getProductQty(hasProducts.getProductQuery()) > 0) { + - final Product product = productService.getProductById(prodId, true); // Need to load it the same way as central view does - if (product != null) { - final String template = product.getProducttype().getUitemplate(); - if (StringUtils.isNotBlank(template)) { - return new Pair(template, CentralViewLabel.PRODUCT); - } - return DEFAULT_P; + final Product product = productService.getProductById(prodId, true); // Need to load it the same way as central view does + if (product != null) { + final String template = product.getProducttype().getUitemplate(); + if (StringUtils.isNotBlank(template)) { + return new Pair(template, CentralViewLabel.PRODUCT); + } + return DEFAULT_P; + } } } }