/*
   * This controller method is for demonstration purposes only. It contains a call to
   * catalogService.findActiveProductsByCategory, which may return a large list. A
   * more performant solution would be to utilize data paging techniques.
   */
  protected boolean addProductsToModel(
      HttpServletRequest request, ModelMap model, CatalogSort catalogSort) {
    boolean productFound = false;

    String productId = request.getParameter("productId");
    Product product = null;
    try {
      product = catalogService.findProductById(new Long(productId));
    } catch (Exception e) {
      // If product is not found, return all values in category
    }

    if (product != null && product.isActive()) {
      productFound = validateProductAndAddToModel(product, model);
      addRatingSummaryToModel(productId, model);
    } else {
      Category currentCategory = (Category) model.get("currentCategory");
      List<Product> productList =
          catalogService.findActiveProductsByCategory(currentCategory, SystemTime.asDate());
      SearchFilterUtil.filterProducts(
          productList, request.getParameterMap(), new String[] {"manufacturer", "sku.salePrice"});

      if ((catalogSort != null) && (catalogSort.getSort() != null)) {
        populateProducts(productList, currentCategory);
        model.addAttribute("displayProducts", sortProducts(catalogSort, productList));
      } else {
        catalogSort = new CatalogSort();
        catalogSort.setSort("featured");
        populateProducts(productList, currentCategory);
        model.addAttribute("displayProducts", sortProducts(catalogSort, productList));
      }
    }

    return productFound;
  }
  protected boolean addCategoryListToModel(
      List<Category> categoryList, Category rootCategory, String url, ModelMap model) {
    boolean categoryError = false;

    while (categoryList == null) {
      categoryError = true;

      int pos = url.indexOf("/");
      if (pos == -1) {
        categoryList = new ArrayList<Category>(1);
        categoryList.add(rootCategory);
      } else {
        url = url.substring(0, url.lastIndexOf("/"));
        List<Long> categoryIdList =
            catalogService.getChildCategoryURLMapByCategoryId(rootCategory.getId()).get(url);
        if (categoryIdList != null) {
          categoryList = new ArrayList<Category>(categoryIdList.size());
          for (Long id : categoryIdList) {
            categoryList.add(catalogService.findCategoryById(id));
          }
        }
      }
    }

    List<Category> siblingCategories = new ArrayList<Category>();
    Category currentCategory = (Category) categoryList.get(categoryList.size() - 1);
    siblingCategories = currentCategory.getAllChildCategories();

    model.addAttribute("breadcrumbCategories", categoryList);
    model.addAttribute("currentCategory", categoryList.get(categoryList.size() - 1));
    model.addAttribute("categoryError", categoryError);
    model.addAttribute("displayCategories", siblingCategories);

    return categoryError;
  }
  @RequestMapping(value = "/viewCart.htm", method = RequestMethod.GET)
  public String viewCart(ModelMap model, HttpServletRequest request) throws PricingException {
    Order cart = retrieveCartOrder(request, model);
    CartSummary cartSummary = new CartSummary();

    if (cart.getOrderItems() != null) {
      for (OrderItem orderItem : cart.getOrderItems()) {
        if (orderItem instanceof DiscreteOrderItem) {
          Sku sku = catalogService.findSkuById(((DiscreteOrderItem) orderItem).getSku().getId());
          if (!(sku.getSalePrice().equals(((DiscreteOrderItem) orderItem).getSalePrice()))) {
            orderItem.setSalePrice(sku.getSalePrice());
          }
          if (!(sku.getRetailPrice().equals(((DiscreteOrderItem) orderItem).getRetailPrice()))) {
            orderItem.setRetailPrice(sku.getRetailPrice());
          }

          if (orderItem.getSalePrice() != orderItem.getRetailPrice()) {
            orderItem.setPrice(orderItem.getSalePrice());
          } else {
            orderItem.setPrice(orderItem.getRetailPrice());
          }

          orderItem.getPrice();
        }
      }
    }

    if (cart.getOrderItems() != null) {
      for (OrderItem orderItem : cart.getOrderItems()) {
        CartOrderItem cartOrderItem = new CartOrderItem();
        cartOrderItem.setOrderItem(orderItem);
        cartOrderItem.setQuantity(orderItem.getQuantity());
        cartSummary.getRows().add(cartOrderItem);
      }
    }

    if ((cart.getFulfillmentGroups() != null) && (cart.getFulfillmentGroups().isEmpty() == false)) {
      String cartShippingMethod = cart.getFulfillmentGroups().get(0).getMethod();
      String cartShippingService = cart.getFulfillmentGroups().get(0).getService();

      if (cartShippingMethod != null) {
        if (cartShippingMethod.equals("standard")) {
          cartSummary = createFulfillmentGroup(cartSummary, "standard", cartShippingService, cart);
        } else if (cartShippingMethod.equals("expedited")) {
          cartSummary = createFulfillmentGroup(cartSummary, "expedited", cartShippingService, cart);
        }
      }
    }

    updateFulfillmentGroups(cartSummary, cart);
    cartSummary.setOrderDiscounts(cart.getTotalAdjustmentsValue().getAmount());
    model.addAttribute("cartSummary", cartSummary);
    return cartViewRedirect ? "redirect:" + cartView : cartView;
  }
  protected void addCategoryToModel(HttpServletRequest request, ModelMap model) {
    Category rootCategory = null;
    if (getRootCategoryId() != null) {
      rootCategory = catalogService.findCategoryById(getRootCategoryId());
    } else if (getRootCategoryName() != null) {
      rootCategory = catalogService.findCategoryByName(getRootCategoryName());
    }

    if (rootCategory == null) {
      throw new IllegalStateException(
          "Catalog Controller configured incorrectly - rootId category not found: "
              + rootCategoryId);
    }

    String url =
        pathHelper.getRequestUri(request).substring(pathHelper.getContextPath(request).length());
    String categoryId = request.getParameter("categoryId");
    if (categoryId != null) {
      Category category = catalogService.findCategoryById(new Long(categoryId));
      if (category != null) {
        url = category.getUrl();
      }
    }

    List<Long> categoryIdList =
        catalogService.getChildCategoryURLMapByCategoryId(rootCategory.getId()).get(url);
    List<Category> categoryList = null;
    if (categoryIdList != null) {
      categoryList = new ArrayList<Category>(categoryIdList.size());
      for (Long id : categoryIdList) {
        categoryList.add(catalogService.findCategoryById(id));
      }
    }

    addCategoryListToModel(categoryList, rootCategory, url, model);
    model.addAttribute("rootCategory", rootCategory);
  }
  /*
   * This controller method is for demonstration purposes only. It contains a call to
   * catalogService.findActiveProductsByCategory, which may return a large list. A
   * more performant solution would be to utilize data paging techniques.
   */
  protected boolean validateProductAndAddToModel(Product product, ModelMap model) {
    Category currentCategory = (Category) model.get("currentCategory");
    Category rootCategory = (Category) model.get("rootCategory");
    int productPosition = 0;

    List<Product> productList =
        catalogService.findActiveProductsByCategory(currentCategory, SystemTime.asDate());
    if (productList != null) {
      populateProducts(productList, currentCategory);
      model.addAttribute("products", productList);
    }
    productPosition = findProductPositionInList(product, productList);
    if (productPosition == 0) {
      // look for product in its default category and override category from request URL
      currentCategory = product.getDefaultCategory();
      if (currentCategory.isActive()) {
        model.put("currentCategory", currentCategory);
        productList =
            catalogService.findActiveProductsByCategory(currentCategory, SystemTime.asDate());
        if (productList != null) {
          model.put("currentProducts", productList);
        }
        String url = currentCategory.getGeneratedUrl();

        // override category list settings using this products default
        List<Long> categoryIdList =
            catalogService.getChildCategoryURLMapByCategoryId(rootCategory.getId()).get(url);
        List<Category> categoryList = null;
        if (categoryIdList != null) {
          categoryList = new ArrayList<Category>(categoryIdList.size());
          for (Long id : categoryIdList) {
            categoryList.add(catalogService.findCategoryById(id));
          }
        }
        if (categoryList != null
            && !addCategoryListToModel(categoryList, rootCategory, url, model)) {
          productPosition = findProductPositionInList(product, productList);
        }
      }
    }

    if (productPosition != 0) {
      model.addAttribute("productError", false);
      model.addAttribute("currentProduct", product);
      model.addAttribute("productPosition", productPosition);
      if (productPosition != 1) {
        model.addAttribute("previousProduct", productList.get(productPosition - 2));
      }
      if (productPosition < productList.size()) {
        model.addAttribute("nextProduct", productList.get(productPosition));
      }
      model.addAttribute("totalProducts", productList.size());
    } else {
      model.addAttribute("productError", true);
    }

    WishlistRequest wishlistRequest = new WishlistRequest();
    wishlistRequest.setAddCategoryId(currentCategory.getId());
    wishlistRequest.setAddProductId(product.getId());
    wishlistRequest.setQuantity(1);
    wishlistRequest.setAddSkuId(((ProductSku) product).getSku().getId());
    model.addAttribute("wishlistRequest", wishlistRequest);

    return (productPosition != 0);
  }