package com.salesmanager.shop.admin.controller.products; import com.salesmanager.core.business.services.catalog.product.ProductService; import com.salesmanager.core.business.services.catalog.product.attribute.ProductAttributeService; import com.salesmanager.core.business.services.catalog.product.attribute.ProductOptionService; import com.salesmanager.core.business.services.catalog.product.attribute.ProductOptionValueService; import com.salesmanager.core.business.utils.ProductPriceUtils; import com.salesmanager.core.business.utils.ajax.AjaxPageableResponse; import com.salesmanager.core.business.utils.ajax.AjaxResponse; import com.salesmanager.core.model.catalog.product.Product; import com.salesmanager.core.model.catalog.product.attribute.*; import com.salesmanager.core.model.merchant.MerchantStore; import com.salesmanager.core.model.reference.language.Language; import com.salesmanager.shop.admin.model.web.Menu; import com.salesmanager.shop.constants.Constants; import com.salesmanager.shop.utils.LabelUtils; import org.apache.commons.lang3.RandomStringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.validation.BindingResult; import org.springframework.validation.ObjectError; import org.springframework.web.bind.annotation.*; import javax.inject.Inject; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.validation.Valid; import java.math.BigDecimal; import java.util.*; @Controller public class ProductAttributeController { private static final Logger LOGGER = LoggerFactory.getLogger(ProductAttributeController.class); private final static String TEXT_OPTION = "text"; @Inject private ProductAttributeService productAttributeService; @Inject private ProductService productService; @Inject private ProductPriceUtils priceUtil; @Inject ProductOptionService productOptionService; @Inject ProductOptionValueService productOptionValueService; @Inject LabelUtils messages; @PreAuthorize("hasRole('PRODUCTS')") @RequestMapping(value="/admin/products/attributes/list.html", method=RequestMethod.GET) public String displayProductAttributes(@RequestParam("id") long productId, Model model, HttpServletRequest request, HttpServletResponse response) throws Exception { setMenu(model,request); MerchantStore store = (MerchantStore)request.getAttribute(Constants.ADMIN_STORE); Product product = productService.getById(productId); if(product==null) { return "redirect:/admin/products/products.html"; } if(product.getMerchantStore().getId().intValue()!=store.getId().intValue()) { return "redirect:/admin/products/products.html"; } model.addAttribute("product",product); return "admin-products-attributes"; } @SuppressWarnings({ "rawtypes", "unchecked" }) @PreAuthorize("hasRole('PRODUCTS')") @RequestMapping(value="/admin/products/attributes/page.html", method=RequestMethod.POST) public @ResponseBody ResponseEntity<String> pageAttributes(HttpServletRequest request, HttpServletResponse response) { //String attribute = request.getParameter("attribute"); String sProductId = request.getParameter("productId"); AjaxResponse resp = new AjaxResponse(); final HttpHeaders httpHeaders= new HttpHeaders(); httpHeaders.setContentType(MediaType.APPLICATION_JSON_UTF8); Long productId; Product product = null; try { productId = Long.parseLong(sProductId); } catch (Exception e) { resp.setStatus(AjaxPageableResponse.RESPONSE_STATUS_FAIURE); resp.setErrorString("Product id is not valid"); String returnString = resp.toJSONString(); return new ResponseEntity<String>(returnString,httpHeaders,HttpStatus.OK); } try { product = productService.getById(productId); Language language = (Language)request.getAttribute("LANGUAGE"); MerchantStore store = (MerchantStore)request.getAttribute(Constants.ADMIN_STORE); //List<ProductAttribute> attributes = productAttributeService.getByProductId(store, product, language); for(ProductAttribute attr : product.getAttributes()) { Map entry = new HashMap(); entry.put("attributeId", attr.getId()); List<ProductOptionDescription> optionsDescriptions = attr.getProductOption().getDescriptionsSettoList(); ProductOptionDescription optionDescription = attr.getProductOption().getDescriptionsSettoList().get(0); for(ProductOptionDescription desc : optionsDescriptions) { if(desc.getLanguage().getId().intValue()==language.getId().intValue()) { optionDescription = desc; } } List<ProductOptionValueDescription> optionValuesDescriptions = attr.getProductOptionValue().getDescriptionsSettoList(); ProductOptionValueDescription optionValueDescription = attr.getProductOptionValue().getDescriptionsSettoList().get(0); for(ProductOptionValueDescription desc : optionValuesDescriptions) { if(desc.getLanguage().getId().intValue()==language.getId().intValue()) { optionValueDescription = desc; } } entry.put("attribute", optionDescription.getName()); entry.put("display", attr.getAttributeDisplayOnly()); entry.put("value", optionValueDescription.getName()); entry.put("order", attr.getProductOptionSortOrder()); entry.put("price", priceUtil.getAdminFormatedAmountWithCurrency(store,attr.getProductAttributePrice())); resp.addDataEntry(entry); } resp.setStatus(AjaxPageableResponse.RESPONSE_STATUS_SUCCESS); } catch (Exception e) { LOGGER.error("Error while paging products", e); resp.setStatus(AjaxPageableResponse.RESPONSE_STATUS_FAIURE); resp.setErrorMessage(e); } String returnString = resp.toJSONString(); return new ResponseEntity<String>(returnString,httpHeaders,HttpStatus.OK); } @PreAuthorize("hasRole('PRODUCTS')") @RequestMapping(value="/admin/products/attributes/editAttribute.html", method=RequestMethod.GET) public String displayAttributeEdit(@RequestParam("productId") Long productId, @RequestParam("id") Long id, Model model, HttpServletRequest request, HttpServletResponse response) throws Exception { return displayAttribute(productId, id,model,request,response); } @PreAuthorize("hasRole('PRODUCTS')") @RequestMapping(value="/admin/products/attribute/createAttribute.html", method=RequestMethod.GET) public String displayAttributeCreate(@RequestParam("productId") Long productId, Model model, HttpServletRequest request, HttpServletResponse response) throws Exception { return displayAttribute(productId, null,model,request,response); } private String displayAttribute(Long productId, Long id, Model model, HttpServletRequest request, HttpServletResponse response) throws Exception { //display menu setMenu(model,request); MerchantStore store = (MerchantStore)request.getAttribute(Constants.ADMIN_STORE); Language language = (Language)request.getAttribute("LANGUAGE"); //get product Product product = productService.getById(productId); if(product.getMerchantStore().getId().intValue()!=store.getId().intValue()) { return "redirect:/admin/products/products.html"; } List<Language> languages = store.getLanguages(); ProductAttribute attribute = null; //get Options List<ProductOption> options = productOptionService.listByStore(store, language); //get OptionsValues List<ProductOptionValue> optionsValues = productOptionValueService.listByStoreNoReadOnly(store, language); if(id!=null && id.intValue()!=0) {//edit mode attribute = productAttributeService.getById(id); attribute.setAttributePrice(priceUtil.getAdminFormatedAmount(store, attribute.getProductAttributePrice())); attribute.setAttributeAdditionalWeight(String.valueOf(attribute.getProductAttributeWeight().intValue())); attribute.setAttributeSortOrder(String.valueOf(attribute.getProductOptionSortOrder())); } else { attribute = new ProductAttribute(); attribute.setProduct(product); ProductOptionValue value = new ProductOptionValue(); Set<ProductOptionValueDescription> descriptions = new HashSet<ProductOptionValueDescription>(); for(Language l : languages) { ProductOptionValueDescription desc = new ProductOptionValueDescription(); desc.setLanguage(l); descriptions.add(desc); } value.setDescriptions(descriptions); attribute.setProductOptionValue(value); } model.addAttribute("optionsValues",optionsValues); model.addAttribute("options",options); model.addAttribute("attribute",attribute); model.addAttribute("product",product); return "admin-products-attribute-details"; } @PreAuthorize("hasRole('PRODUCTS')") @RequestMapping(value="/admin/attributes/attribute/save.html", method=RequestMethod.POST) public String saveAttribute(@Valid @ModelAttribute("attribute") ProductAttribute attribute, BindingResult result, Model model, HttpServletRequest request, Locale locale) throws Exception { //display menu setMenu(model,request); Product product = productService.getById(attribute.getProduct().getId()); model.addAttribute("product",product); MerchantStore store = (MerchantStore)request.getAttribute(Constants.ADMIN_STORE); Language language = (Language)request.getAttribute("LANGUAGE"); //get Options List<ProductOption> options = productOptionService.listByStore(store, language); //get OptionsValues List<ProductOptionValue> optionsValues = productOptionValueService.listByStoreNoReadOnly(store, language); model.addAttribute("optionsValues",optionsValues); model.addAttribute("options",options); ProductAttribute dbEntity = null; if(attribute.getId() != null && attribute.getId() >0) { //edit entry //get from DB dbEntity = productAttributeService.getById(attribute.getId()); if(dbEntity==null) { return "redirect:/admin/products/attributes/list.html"; } if(dbEntity.getProductOption().getMerchantStore().getId().intValue()!=store.getId().intValue()) { return "redirect:/admin/products/attributes/list.html"; } } //validate price BigDecimal submitedPrice = null; try { submitedPrice = priceUtil.getAmount(attribute.getAttributePrice()); attribute.setProductAttributePrice(submitedPrice); } catch (Exception e) { ObjectError error = new ObjectError("attributePrice",messages.getMessage("NotEmpty.product.productPrice", locale)); result.addError(error); } //validate sort order try { Integer sortOrder = Integer.parseInt(attribute.getAttributeSortOrder()); attribute.setProductOptionSortOrder(sortOrder); } catch(Exception e) { ObjectError error = new ObjectError("attributeSortOrder",messages.getMessage("message.number.invalid", locale)); result.addError(error); } //validate weight try { Integer weight = Integer.parseInt(attribute.getAttributeAdditionalWeight()); attribute.setProductAttributeWeight(new BigDecimal(weight)); } catch(Exception e) { ObjectError error = new ObjectError("attributeAdditionalWeight",messages.getMessage("message.number.invalid", locale)); result.addError(error); } if(attribute.getProductOption()==null) { ObjectError error = new ObjectError("productOption.id",messages.getMessage("message.productoption.required", locale)); result.addError(error); return "admin-products-attribute-details"; } //check type ProductOption option = attribute.getProductOption(); option = productOptionService.getById(option.getId()); attribute.setProductOption(option); if(option.getProductOptionType().equals(TEXT_OPTION)) { if(dbEntity!=null && dbEntity.getProductOption().getProductOptionType().equals(TEXT_OPTION)) {//bcz it is overwrited by hidden product option value list if(dbEntity.getProductOptionValue()!=null) { ProductOptionValue optVal = dbEntity.getProductOptionValue(); List<ProductOptionValueDescription> descriptions = attribute.getProductOptionValue().getDescriptionsList(); Set<ProductOptionValueDescription> descriptionsSet = new HashSet<ProductOptionValueDescription>(); for(ProductOptionValueDescription description : descriptions) { description.setProductOptionValue(optVal); description.setName(description.getDescription().length()<15 ? description.getDescription() : description.getDescription().substring(0,15)); descriptionsSet.add(description); } optVal.setDescriptions(descriptionsSet); optVal.setProductOptionDisplayOnly(true); productOptionValueService.saveOrUpdate(optVal); attribute.setProductOptionValue(optVal); } } else {//create a new value //create new option value List<ProductOptionValueDescription> descriptions = attribute.getProductOptionValue().getDescriptionsList(); Set<ProductOptionValueDescription> newDescriptions = new HashSet<ProductOptionValueDescription>(); ProductOptionValue newValue = new ProductOptionValue(); for(ProductOptionValueDescription description : descriptions) { ProductOptionValueDescription optionValueDescription = new ProductOptionValueDescription(); optionValueDescription.setAuditSection(description.getAuditSection()); optionValueDescription.setLanguage(description.getLanguage()); optionValueDescription.setName(description.getDescription().length()<15 ? description.getDescription() : description.getDescription().substring(0,15)); optionValueDescription.setLanguage(description.getLanguage()); optionValueDescription.setDescription(description.getDescription()); optionValueDescription.setProductOptionValue(newValue); newDescriptions.add(optionValueDescription); } //code generation String code = RandomStringUtils.randomAlphanumeric(10).toUpperCase(); newValue.setCode(code); newValue.setMerchantStore(store); newValue.setProductOptionValueSortOrder(attribute.getProductOptionValue().getProductOptionValueSortOrder()); newValue.setDescriptions(newDescriptions); newValue.setProductOptionDisplayOnly(true); productOptionValueService.save(newValue); attribute.setProductOptionValue(newValue); attribute.setAttributeDisplayOnly(true); } } if(attribute.getProductOptionValue().getId()==null) { ObjectError error = new ObjectError("productOptionValue.id",messages.getMessage("message.productoptionvalue.required", locale)); result.addError(error); } model.addAttribute("attribute",attribute); if (result.hasErrors()) { return "admin-products-attribute-details"; } productAttributeService.saveOrUpdate(attribute); model.addAttribute("success","success"); return "admin-products-attribute-details"; } @PreAuthorize("hasRole('PRODUCTS')") @RequestMapping(value="/admin/attributes/attribute/remove.html", method=RequestMethod.POST) public @ResponseBody ResponseEntity<String> deleteProductPrice(HttpServletRequest request, HttpServletResponse response, Locale locale) { String sAttributeid = request.getParameter("attributeId"); MerchantStore store = (MerchantStore)request.getAttribute(Constants.ADMIN_STORE); AjaxResponse resp = new AjaxResponse(); final HttpHeaders httpHeaders= new HttpHeaders(); httpHeaders.setContentType(MediaType.APPLICATION_JSON_UTF8); try { Long attributeId = Long.parseLong(sAttributeid); ProductAttribute attribute = productAttributeService.getById(attributeId); if(attribute==null || attribute.getProduct().getMerchantStore().getId().intValue()!=store.getId()) { resp.setStatusMessage(messages.getMessage("message.unauthorized", locale)); resp.setStatus(AjaxResponse.RESPONSE_STATUS_FAIURE); String returnString = resp.toJSONString(); return new ResponseEntity<String>(returnString,httpHeaders,HttpStatus.OK); } productAttributeService.delete(attribute); resp.setStatus(AjaxResponse.RESPONSE_OPERATION_COMPLETED); } catch (Exception e) { LOGGER.error("Error while deleting product price", e); resp.setStatus(AjaxResponse.RESPONSE_STATUS_FAIURE); resp.setErrorMessage(e); } String returnString = resp.toJSONString(); return new ResponseEntity<String>(returnString,httpHeaders,HttpStatus.OK); } @SuppressWarnings({ "rawtypes", "unchecked" }) @PreAuthorize("hasRole('PRODUCTS')") @RequestMapping(value="/admin/products/attributes/getAttributeType.html", method=RequestMethod.POST) public @ResponseBody ResponseEntity<String> checkAttributeType(HttpServletRequest request, HttpServletResponse response, Locale locale) { String sOptionId = request.getParameter("optionId"); MerchantStore store = (MerchantStore)request.getAttribute(Constants.ADMIN_STORE); AjaxResponse resp = new AjaxResponse(); final HttpHeaders httpHeaders= new HttpHeaders(); httpHeaders.setContentType(MediaType.APPLICATION_JSON_UTF8); Long prodoptionId; ProductOption productOption = null; try { prodoptionId = Long.parseLong(sOptionId); } catch (Exception e) { resp.setStatus(AjaxPageableResponse.RESPONSE_STATUS_FAIURE); resp.setErrorString("Product Option id is not valid"); String returnString = resp.toJSONString(); return new ResponseEntity<String>(returnString,httpHeaders,HttpStatus.OK); } try { productOption = productOptionService.getById(prodoptionId); if(productOption==null) { resp.setStatusMessage(messages.getMessage("message.unauthorized", locale)); resp.setStatus(AjaxResponse.RESPONSE_STATUS_FAIURE); String returnString = resp.toJSONString(); return new ResponseEntity<String>(returnString,httpHeaders,HttpStatus.OK); } if(productOption.getMerchantStore().getId().intValue()!=store.getId().intValue()) { resp.setStatusMessage(messages.getMessage("message.unauthorized", locale)); resp.setStatus(AjaxResponse.RESPONSE_STATUS_FAIURE); String returnString = resp.toJSONString(); return new ResponseEntity<String>(returnString,httpHeaders,HttpStatus.OK); } Map entry = new HashMap(); entry.put("type", productOption.getProductOptionType()); resp.addDataEntry(entry); resp.setStatus(AjaxPageableResponse.RESPONSE_STATUS_SUCCESS); } catch (Exception e) { LOGGER.error("Error while paging products", e); resp.setStatus(AjaxPageableResponse.RESPONSE_STATUS_FAIURE); resp.setErrorMessage(e); } String returnString = resp.toJSONString(); return new ResponseEntity<String>(returnString,httpHeaders,HttpStatus.OK); } private void setMenu(Model model, HttpServletRequest request) throws Exception { //display menu Map<String,String> activeMenus = new HashMap<String,String>(); activeMenus.put("catalogue", "catalogue"); activeMenus.put("catalogue-products", "catalogue-products"); @SuppressWarnings("unchecked") Map<String, Menu> menus = (Map<String, Menu>)request.getAttribute("MENUMAP"); Menu currentMenu = (Menu)menus.get("catalogue"); model.addAttribute("currentMenu",currentMenu); model.addAttribute("activeMenus",activeMenus); // } }