/**
* Most of the code in the Qalingo project is copyrighted Hoteia and licensed
* under the Apache License Version 2.0 (release version 0.8.0)
* http://www.apache.org/licenses/LICENSE-2.0
*
* Copyright (c) Hoteia, 2012-2014
* http://www.hoteia.com - http://twitter.com/hoteia - contact@hoteia.com
*
*/
package org.hoteia.qalingo.web.mvc.controller.catalog;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.StringUtils;
import org.hibernate.Hibernate;
import org.hoteia.qalingo.core.ModelConstants;
import org.hoteia.qalingo.core.RequestConstants;
import org.hoteia.qalingo.core.domain.CatalogCategoryMaster_;
import org.hoteia.qalingo.core.domain.CatalogCategoryVirtual;
import org.hoteia.qalingo.core.domain.CatalogCategoryVirtual_;
import org.hoteia.qalingo.core.domain.Localization;
import org.hoteia.qalingo.core.domain.ProductBrand;
import org.hoteia.qalingo.core.domain.ProductBrand_;
import org.hoteia.qalingo.core.domain.ProductMarketing;
import org.hoteia.qalingo.core.domain.ProductMarketing_;
import org.hoteia.qalingo.core.domain.ProductSku;
import org.hoteia.qalingo.core.domain.ProductSkuStorePrice_;
import org.hoteia.qalingo.core.domain.ProductSku_;
import org.hoteia.qalingo.core.domain.enumtype.FoUrls;
import org.hoteia.qalingo.core.fetchplan.FetchPlan;
import org.hoteia.qalingo.core.fetchplan.SpecificFetchMode;
import org.hoteia.qalingo.core.i18n.FoMessageKey;
import org.hoteia.qalingo.core.i18n.enumtype.ScopeCommonMessage;
import org.hoteia.qalingo.core.i18n.enumtype.ScopeWebMessage;
import org.hoteia.qalingo.core.service.CatalogCategoryService;
import org.hoteia.qalingo.core.service.ProductService;
import org.hoteia.qalingo.core.web.mvc.form.CustomerCommentForm;
import org.hoteia.qalingo.core.web.mvc.viewbean.BreadcrumbViewBean;
import org.hoteia.qalingo.core.web.mvc.viewbean.CatalogBreadcrumbViewBean;
import org.hoteia.qalingo.core.web.mvc.viewbean.CatalogCategoryViewBean;
import org.hoteia.qalingo.core.web.mvc.viewbean.CustomerProductRatesViewBean;
import org.hoteia.qalingo.core.web.mvc.viewbean.MenuViewBean;
import org.hoteia.qalingo.core.web.mvc.viewbean.ProductBrandViewBean;
import org.hoteia.qalingo.core.web.mvc.viewbean.ProductMarketingViewBean;
import org.hoteia.qalingo.core.web.mvc.viewbean.ProductSkuViewBean;
import org.hoteia.qalingo.core.web.mvc.viewbean.SeoDataViewBean;
import org.hoteia.qalingo.core.web.resolver.RequestData;
import org.hoteia.qalingo.core.web.servlet.ModelAndViewThemeDevice;
import org.hoteia.qalingo.core.web.servlet.view.RedirectView;
import org.hoteia.qalingo.web.mvc.controller.AbstractMCommerceController;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
/**
*
*/
@Controller("productDetailsController")
public class ProductDetailsController extends AbstractMCommerceController {
@Autowired
protected CatalogCategoryService catalogCategoryService;
@Autowired
protected ProductService productService;
protected List<SpecificFetchMode> productSkuFetchPlans = new ArrayList<SpecificFetchMode>();
protected List<SpecificFetchMode> productMarketingFetchPlans = new ArrayList<SpecificFetchMode>();
protected List<SpecificFetchMode> categoryVirtualFetchPlans = new ArrayList<SpecificFetchMode>();
public ProductDetailsController() {
productSkuFetchPlans.add(new SpecificFetchMode(ProductSku_.productMarketing.getName()));
productSkuFetchPlans.add(new SpecificFetchMode(ProductSku_.productMarketing.getName() + "." + ProductMarketing_.productBrand.getName()));
productSkuFetchPlans.add(new SpecificFetchMode(ProductSku_.attributes.getName()));
productSkuFetchPlans.add(new SpecificFetchMode(ProductSku_.prices.getName()));
productSkuFetchPlans.add(new SpecificFetchMode(ProductSku_.prices.getName() + "." + ProductSkuStorePrice_.currency.getName()));
productSkuFetchPlans.add(new SpecificFetchMode(ProductSku_.assets.getName()));
productMarketingFetchPlans.add(new SpecificFetchMode(ProductMarketing_.productBrand.getName()));
productMarketingFetchPlans.add(new SpecificFetchMode(ProductMarketing_.productBrand.getName() + "." + ProductBrand_.attributes.getName()));
productMarketingFetchPlans.add(new SpecificFetchMode(ProductMarketing_.productMarketingType.getName()));
productMarketingFetchPlans.add(new SpecificFetchMode(ProductMarketing_.attributes.getName()));
productMarketingFetchPlans.add(new SpecificFetchMode(ProductMarketing_.productSkus.getName()));
productMarketingFetchPlans.add(new SpecificFetchMode(ProductMarketing_.productSkus.getName() + "." + ProductSku_.prices.getName()));
productMarketingFetchPlans.add(new SpecificFetchMode(ProductMarketing_.productSkus.getName() + "." + ProductSku_.prices.getName() + "." + ProductSkuStorePrice_.currency.getName()));
productMarketingFetchPlans.add(new SpecificFetchMode(ProductMarketing_.productSkus.getName() + "." + ProductSku_.customerComments.getName()));
productMarketingFetchPlans.add(new SpecificFetchMode(ProductMarketing_.productAssociationLinks.getName()));
productMarketingFetchPlans.add(new SpecificFetchMode(ProductMarketing_.assets.getName()));
categoryVirtualFetchPlans.add(new SpecificFetchMode(CatalogCategoryVirtual_.catalogCategories.getName()));
categoryVirtualFetchPlans.add(new SpecificFetchMode(CatalogCategoryVirtual_.parentCatalogCategory.getName()));
categoryVirtualFetchPlans.add(new SpecificFetchMode(CatalogCategoryVirtual_.attributes.getName()));
categoryVirtualFetchPlans.add(new SpecificFetchMode(CatalogCategoryVirtual_.parentCatalogCategory.getName() + "." + CatalogCategoryVirtual_.categoryMaster.getName()));
categoryVirtualFetchPlans.add(new SpecificFetchMode(CatalogCategoryVirtual_.assets.getName()));
categoryVirtualFetchPlans.add(new SpecificFetchMode(CatalogCategoryVirtual_.categoryMaster.getName()));
categoryVirtualFetchPlans.add(new SpecificFetchMode(CatalogCategoryVirtual_.categoryMaster.getName() + "." + CatalogCategoryMaster_.catalogCategoryType.getName()));
categoryVirtualFetchPlans.add(new SpecificFetchMode(CatalogCategoryVirtual_.categoryMaster.getName() + "." + CatalogCategoryMaster_.attributes.getName()));
}
@RequestMapping(FoUrls.PRODUCT_DETAILS_OLD_URL)
public ModelAndView productDetailsOld(final HttpServletRequest request, final HttpServletResponse response ,final Model model, @PathVariable(RequestConstants.URL_PATTERN_CATEGORY_CODE) final String categoryCode,
@PathVariable(RequestConstants.URL_PATTERN_PRODUCT_MARKETING_CODE) final String productMarketingCode,
@PathVariable(RequestConstants.URL_PATTERN_PRODUCT_SKU_CODE) final String productSkuCode,
@ModelAttribute(ModelConstants.CUSTOMER_COMMENT_FORM) CustomerCommentForm customerCommentForm) throws Exception {
final RequestData requestData = requestUtil.getRequestData(request);
CatalogCategoryVirtual catalogCategory = catalogCategoryService.getVirtualCatalogCategoryByCode(categoryCode, requestData.getVirtualCatalogCode(), requestData.getMasterCatalogCode(), new FetchPlan(categoryVirtualFetchPlans));
ProductMarketing productMarketing = productService.getProductMarketingByCode(productMarketingCode, new FetchPlan(productMarketingFetchPlans));
ProductSku productSku = productService.getProductSkuByCode(productSkuCode, new FetchPlan(productSkuFetchPlans));
if (productMarketing.isEnabledB2C() && productSku.isEnabledB2C()) {
final String urlRedirect = urlService.generateRedirectUrl(FoUrls.PRODUCT_DETAILS, requestData, catalogCategory, productMarketing, productSku);
return new ModelAndView(new RedirectView(urlRedirect));
}
final String urlRedirect = urlService.generateRedirectUrl(FoUrls.HOME, requestData);
return new ModelAndView(new RedirectView(urlRedirect));
}
@RequestMapping(FoUrls.PRODUCT_DETAILS_URL)
public ModelAndView productDetails(final HttpServletRequest request, final HttpServletResponse response ,final Model model, @PathVariable(RequestConstants.URL_PATTERN_CATEGORY_CODE) final String categoryCode,
@PathVariable(RequestConstants.URL_PATTERN_PRODUCT_MARKETING_CODE) final String productMarketingCode,
@PathVariable(RequestConstants.URL_PATTERN_PRODUCT_SKU_CODE) final String productSkuCode,
@ModelAttribute(ModelConstants.CUSTOMER_COMMENT_FORM) CustomerCommentForm customerCommentForm) throws Exception {
ModelAndViewThemeDevice modelAndView = new ModelAndViewThemeDevice(getCurrentVelocityPath(request), FoUrls.PRODUCT_DETAILS.getVelocityPage());
final RequestData requestData = requestUtil.getRequestData(request);
CatalogCategoryVirtual catalogCategory = catalogCategoryService.getVirtualCatalogCategoryByCode(categoryCode, requestData.getVirtualCatalogCode(), requestData.getMasterCatalogCode(), new FetchPlan(categoryVirtualFetchPlans));
ProductMarketing productMarketing = productService.getProductMarketingByCode(productMarketingCode, new FetchPlan(productMarketingFetchPlans));
ProductSku productSku = productService.getProductSkuByCode(productSkuCode, new FetchPlan(productSkuFetchPlans));
final CatalogCategoryViewBean catalogCategoryViewBean = frontofficeViewBeanFactory.buildViewBeanVirtualCatalogCategory(requestUtil.getRequestData(request), catalogCategory);
model.addAttribute(ModelConstants.CATALOG_CATEGORY_VIEW_BEAN, catalogCategoryViewBean);
final ProductMarketingViewBean productMarketingViewBean = frontofficeViewBeanFactory.buildViewBeanProductMarketing(requestUtil.getRequestData(request), catalogCategory, productMarketing, productSku);
model.addAttribute(ModelConstants.PRODUCT_MARKETING_VIEW_BEAN, productMarketingViewBean);
final ProductSkuViewBean productSkuViewBean = frontofficeViewBeanFactory.buildViewBeanProductSku(requestData, catalogCategory, productMarketing, productSku);
model.addAttribute(ModelConstants.PRODUCT_SKU_VIEW_BEAN, productSkuViewBean);
final CatalogBreadcrumbViewBean catalogBreadcrumbViewBean = frontofficeViewBeanFactory.buildViewBeanCatalogBreadcrumb(requestUtil.getRequestData(request) , catalogCategory);
model.addAttribute(ModelConstants.CATALOG_BREADCRUMB_VIEW_BEAN, catalogBreadcrumbViewBean);
//for now, get the featured products in same category
//TODO: define related products
final List<ProductMarketingViewBean> relatedProducts = catalogCategoryViewBean.getFeaturedProductMarketings();
model.addAttribute(ModelConstants.RELATED_PRODUCT_MARKETING_VIEW_BEAN, relatedProducts);
final CustomerProductRatesViewBean customerProductRatesViewBean = frontofficeViewBeanFactory.getProductMarketingCustomerRateDetails(productMarketing.getId());
model.addAttribute(ModelConstants.PRODUCT_MARKETING_RATES_VIEW_BEAN, customerProductRatesViewBean);
customerCommentForm = formFactory.buildCustomerCommentForm(requestData, productMarketing.getCode());
model.addAttribute(ModelConstants.CUSTOMER_COMMENT_FORM, customerCommentForm);
model.addAttribute(ModelConstants.PRODUCT_COMMENT_SUBMIT_URL, urlService.generateUrl(FoUrls.PRODUCT_COMMENT, requestData, productMarketing));
requestUtil.addOrUpdateRecentProductToCookie(request, response, requestData.getVirtualCatalogCode(), catalogCategory.getCode(), productMarketing.getCode(), productSku.getCode());
Object[] params = { productMarketingViewBean.getI18nName() };
overrideDefaultPageTitle(request, modelAndView, FoUrls.PRODUCT_DETAILS.getKey(), params);
model.addAttribute(ModelConstants.BREADCRUMB_VIEW_BEAN, buildBreadcrumbViewBean(requestData, catalogCategory, productMarketing));
model.addAttribute(ModelConstants.SEO_DATA_VIEW_BEAN, initSeo(request, model, productMarketingViewBean));
model.addAttribute(ModelConstants.PRODUCT_BRANDS_VIEW_BEAN, brandList(request, model));
return modelAndView;
}
protected BreadcrumbViewBean buildBreadcrumbViewBean(final RequestData requestData, CatalogCategoryVirtual catalogCategory, ProductMarketing productMarketing) {
final Localization localization = requestData.getMarketAreaLocalization();
final String localizationCode = localization.getCode();
final Locale locale = requestData.getLocale();
Object[] params = { productMarketing.getI18nName(localizationCode) };
// BREADCRUMB
BreadcrumbViewBean breadcrumbViewBean = new BreadcrumbViewBean();
breadcrumbViewBean.setName(getSpecificMessage(ScopeWebMessage.HEADER_MENU, FoUrls.PRODUCT_DETAILS.getMessageKey(), params, locale));
List<MenuViewBean> menuViewBeans = breadcrumbViewBean.getMenus();
MenuViewBean menu = new MenuViewBean();
menu.setKey(FoUrls.HOME.getKey());
menu.setName(getSpecificMessage(ScopeWebMessage.HEADER_MENU, FoUrls.HOME.getMessageKey(), locale));
menu.setUrl(urlService.generateUrl(FoUrls.HOME, requestData));
menuViewBeans.add(menu);
menu = new MenuViewBean();
Object[] catalogCategoryParams = { productMarketing.getI18nName(localizationCode) };
menu.setKey(FoUrls.HOME.getKey());
menu.setName(getSpecificMessage(ScopeWebMessage.HEADER_MENU, FoUrls.CATEGORY_AS_LINE.getMessageKey(), catalogCategoryParams, locale));
menu.setUrl(urlService.generateUrl(FoUrls.CATEGORY_AS_LINE, requestData, catalogCategory));
menuViewBeans.add(menu);
menu = new MenuViewBean();
menu.setKey(FoUrls.PRODUCT_DETAILS.getKey());
menu.setName(getSpecificMessage(ScopeWebMessage.HEADER_MENU, FoUrls.PRODUCT_DETAILS.getMessageKey(), params, locale));
menu.setUrl(urlService.generateUrl(FoUrls.PRODUCT_DETAILS, requestData, productMarketing));
menu.setActive(true);
menuViewBeans.add(menu);
return breadcrumbViewBean;
}
protected List<ProductBrandViewBean> brandList(final HttpServletRequest request, final Model model) throws Exception {
final RequestData requestData = requestUtil.getRequestData(request);
final List<Long> productBrandIds = productService.findAllProductBrandIdsEnabled();
final List<ProductBrandViewBean> productBrandViewBeans = new ArrayList<ProductBrandViewBean>();
for (Long productBrandId : productBrandIds) {
ProductBrand productBrand = productService.getProductBrandById(productBrandId);
ProductBrandViewBean productBrandViewBean = frontofficeViewBeanFactory.buildViewBeanProductBrand(requestData, productBrand);
productBrandViewBeans.add(productBrandViewBean);
}
return productBrandViewBeans;
}
protected SeoDataViewBean initSeo(final HttpServletRequest request, final Model model, final ProductMarketingViewBean productMarketingViewBean) throws Exception {
final RequestData requestData = requestUtil.getRequestData(request);
final Locale locale = requestData.getLocale();
SeoDataViewBean seoDataViewBean = frontofficeViewBeanFactory.buildViewSeoData(requestData);
String seoPageTitle = getCommonMessage(ScopeCommonMessage.SEO, FoMessageKey.PAGE_META_OG_TITLE, locale);
if(seoPageTitle != null && !seoPageTitle.trim().endsWith("-")){
seoPageTitle += " - ";
}
if(productMarketingViewBean.getBrand() != null){
seoPageTitle += productMarketingViewBean.getBrand().getI18nName() + " ";
}
seoPageTitle += productMarketingViewBean.getI18nName();
// SEO
seoDataViewBean.setPageTitle(seoPageTitle);
seoDataViewBean.setMetaDescription(productMarketingViewBean.getI18nDescription());
seoDataViewBean.setMetaOgTitle(seoPageTitle);
seoDataViewBean.setMetaOgDescription(productMarketingViewBean.getI18nDescription());
if(productMarketingViewBean.getDefaultAsset() != null){
seoDataViewBean.setMetaOgImage(productMarketingViewBean.getDefaultAsset().getAbsoluteWebPath());
}
return seoDataViewBean;
}
}