@RequestMapping(value = "/cart/add", method = RequestMethod.POST, produces = "application/json")
  public String addToCartPickup(
      @RequestParam("productCodePost") final String code,
      @RequestParam("storeNamePost") final String storeId,
      final Model model,
      @Valid final PickupInStoreForm form,
      final BindingResult bindingErrors) {
    if (bindingErrors.hasErrors()) {
      return getViewWithBindingErrorMessages(model, bindingErrors);
    }

    final long qty = form.getHiddenPickupQty();

    if (qty <= 0) {
      model.addAttribute("errorMsg", "basket.error.quantity.invalid");
      return ControllerConstants.Views.Fragments.Cart.AddToCartPopup;
    }

    try {
      final CartModificationData cartModification = cartFacade.addToCart(code, qty, storeId);
      model.addAttribute("quantity", Long.valueOf(cartModification.getQuantityAdded()));
      model.addAttribute("entry", cartModification.getEntry());

      if (cartModification.getQuantityAdded() == 0L) {
        model.addAttribute(
            "errorMsg",
            "basket.information.quantity.noItemsAdded." + cartModification.getStatusCode());
      } else if (cartModification.getQuantityAdded() < qty) {
        model.addAttribute(
            "errorMsg",
            "basket.information.quantity.reducedNumberOfItemsAdded."
                + cartModification.getStatusCode());
      }

      // Put in the cart again after it has been modified
      model.addAttribute("cartData", cartFacade.getSessionCart());
    } catch (final CommerceCartModificationException ex) {
      model.addAttribute("errorMsg", "basket.error.occurred");
      model.addAttribute("quantity", Long.valueOf(0L));
      LOG.warn("Couldn't add product of code " + code + " to cart.", ex);
    }

    final ProductData productData =
        productFacade.getProductForCodeAndOptions(
            code, Arrays.asList(ProductOption.BASIC, ProductOption.PRICE));
    model.addAttribute("product", productData);

    model.addAttribute("cartData", cartFacade.getSessionCart());

    return ControllerConstants.Views.Fragments.Cart.AddToCartPopup;
  }
  @RequestMapping(value = "/cart/add", method = RequestMethod.POST, produces = "application/json")
  public String addToCart(
      @RequestParam("productCodePost") final String code,
      final Model model,
      @Valid final AddToCartForm form,
      final BindingResult bindingErrors) {
    if (bindingErrors.hasErrors()) {
      return getViewWithBindingErrorMessages(model, bindingErrors);
    }

    final long qty = form.getQty();

    if (qty <= 0) {
      model.addAttribute(ERROR_MSG_TYPE, "basket.error.quantity.invalid");
      model.addAttribute("quantity", Long.valueOf(0L));
    } else {
      try {
        final CartModificationData cartModification = cartFacade.addToCart(code, qty);
        model.addAttribute("quantity", Long.valueOf(cartModification.getQuantityAdded()));
        model.addAttribute("entry", cartModification.getEntry());
        model.addAttribute("cartCode", cartModification.getCartCode());

        if (cartModification.getQuantityAdded() == 0L) {
          model.addAttribute(
              ERROR_MSG_TYPE,
              "basket.information.quantity.noItemsAdded." + cartModification.getStatusCode());
        } else if (cartModification.getQuantityAdded() < qty) {
          model.addAttribute(
              ERROR_MSG_TYPE,
              "basket.information.quantity.reducedNumberOfItemsAdded."
                  + cartModification.getStatusCode());
        }
      } catch (final CommerceCartModificationException ex) {
        model.addAttribute(ERROR_MSG_TYPE, "basket.error.occurred");
        model.addAttribute("quantity", Long.valueOf(0L));
      }
    }

    model.addAttribute(
        "product",
        productFacade.getProductForCodeAndOptions(code, Arrays.asList(ProductOption.BASIC)));

    return ControllerConstants.Views.Fragments.Cart.AddToCartPopup;
  }
  @RequestMapping(value = "/getProductVariantMatrix", method = RequestMethod.GET)
  @RequireHardLogIn
  public String getProductVariantMatrix(
      @RequestParam("productCode") final String productCode, final Model model) {
    final ProductData productData =
        productFacade.getProductForCodeAndOptions(
            productCode,
            Arrays.asList(
                ProductOption.BASIC,
                ProductOption.CATEGORIES,
                ProductOption.VARIANT_MATRIX_BASE,
                ProductOption.VARIANT_MATRIX_PRICE,
                ProductOption.VARIANT_MATRIX_MEDIA,
                ProductOption.VARIANT_MATRIX_STOCK));

    model.addAttribute("product", productData);

    return ControllerConstants.Views.Fragments.Checkout.ReadOnlyExpandedOrderForm;
  }
  @RequestMapping(
      value = "/summary",
      method = {RequestMethod.GET, RequestMethod.POST})
  @RequireHardLogIn
  public String checkoutSummary(final Model model) throws CMSItemNotFoundException {

    if (!b2bUserGroupProvider.isCurrentUserAuthorizedToCheckOut()) {
      GlobalMessages.addErrorMessage(model, "checkout.error.invalid.accountType");
      return FORWARD_PREFIX + "/cart";
    }

    if (!hasItemsInCart()) {
      // no items in the cart
      return FORWARD_PREFIX + "/cart";
    }

    getCheckoutFacade().setDeliveryAddressIfAvailable();
    getCheckoutFacade().setDeliveryModeIfAvailable();
    getCheckoutFacade().setPaymentInfoIfAvailable();

    // Set to default payment type
    final B2BPaymentTypeData paymentTypeData = new B2BPaymentTypeData();
    paymentTypeData.setCode(CheckoutPaymentType.ACCOUNT.getCode());

    final CartData tempCartData = new CartData();
    tempCartData.setPaymentType(paymentTypeData);

    final CartData cartData = getB2BCheckoutFacade().updateCheckoutCart(tempCartData);

    // final CartData cartData = getCheckoutFacade().getCheckoutCart();
    if (cartData.getEntries() != null && !cartData.getEntries().isEmpty()) {
      for (final OrderEntryData entry : cartData.getEntries()) {
        final String productCode = entry.getProduct().getCode();
        final ProductData product =
            productFacade.getProductForCodeAndOptions(
                productCode,
                Arrays.asList(
                    ProductOption.BASIC,
                    ProductOption.PRICE,
                    ProductOption.PRICE_RANGE,
                    ProductOption.VARIANT_MATRIX));
        entry.setProduct(product);
      }
    }

    model.addAttribute("cartData", cartData);
    model.addAttribute("allItems", cartData.getEntries());
    model.addAttribute("deliveryAddress", cartData.getDeliveryAddress());
    model.addAttribute("deliveryMode", cartData.getDeliveryMode());
    model.addAttribute("paymentInfo", cartData.getPaymentInfo());
    model.addAttribute("costCenter", cartData.getCostCenter());
    model.addAttribute("quoteText", new B2BCommentData());
    // TODO:Make configuration hmc driven than hardcoding in controllers
    model.addAttribute("nDays", getNumberRange(1, 30));
    model.addAttribute("nthDayOfMonth", getNumberRange(1, 31));
    model.addAttribute("nthWeek", getNumberRange(1, 12));

    model.addAttribute(new AddressForm());
    model.addAttribute(new PaymentDetailsForm());
    if (!model.containsAttribute("placeOrderForm")) {
      final PlaceOrderForm placeOrderForm = new PlaceOrderForm();
      // TODO: Make setting of default recurrence enum value hmc driven rather hard coding in
      // controller
      placeOrderForm.setReplenishmentRecurrence(B2BReplenishmentRecurrenceEnum.MONTHLY);
      placeOrderForm.setnDays("14");
      final List<DayOfWeek> daysOfWeek = new ArrayList<DayOfWeek>();
      daysOfWeek.add(DayOfWeek.MONDAY);
      placeOrderForm.setnDaysOfWeek(daysOfWeek);
      model.addAttribute("placeOrderForm", placeOrderForm);
    }
    storeCmsPageInModel(model, getContentPageForLabelOrId(SINGLE_STEP_CHECKOUT_SUMMARY_CMS_PAGE));
    setUpMetaDataForContentPage(
        model, getContentPageForLabelOrId(SINGLE_STEP_CHECKOUT_SUMMARY_CMS_PAGE));
    model.addAttribute("metaRobots", "no-index,no-follow");
    return ControllerConstants.Views.Pages.SingleStepCheckout.CheckoutSummaryPage;
  }