/*
* Copyright 2008-2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.ssbusy.controller.cart;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.StringUtils;
import org.broadleafcommerce.common.currency.domain.BroadleafCurrency;
import org.broadleafcommerce.core.catalog.domain.Sku;
import org.broadleafcommerce.core.offer.domain.OfferCode;
import org.broadleafcommerce.core.offer.service.exception.OfferMaxUseExceededException;
import org.broadleafcommerce.core.order.domain.NullOrderImpl;
import org.broadleafcommerce.core.order.domain.Order;
import org.broadleafcommerce.core.order.service.exception.AddToCartException;
import org.broadleafcommerce.core.order.service.exception.ProductOptionValidationException;
import org.broadleafcommerce.core.order.service.exception.RemoveFromCartException;
import org.broadleafcommerce.core.order.service.exception.RequiredAttributeNotProvidedException;
import org.broadleafcommerce.core.order.service.exception.UpdateCartException;
import org.broadleafcommerce.core.pricing.service.exception.PricingException;
import org.broadleafcommerce.core.web.controller.cart.BroadleafCartController;
import org.broadleafcommerce.core.web.order.CartState;
import org.broadleafcommerce.core.web.order.model.AddToCartItemEx;
import org.broadleafcommerce.inventory.exception.InventoryUnavailableException;
import org.broadleafcommerce.profile.web.core.CustomerState;
import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import com.ssbusy.core.product.service.ProductService;
@Controller("ssbCartController")
public class CartController extends BroadleafCartController {
@Resource(name = "ssbProductService")
protected ProductService productService;
@Override
@RequestMapping("/cart")
public String cart(HttpServletRequest request,
HttpServletResponse response, Model model) throws PricingException {
String v = super.cart(request, response, model);
// if (CartState.getCart() != null) {
// Money total = CartState.getCart().getTotal();
// if (total != null) {
// List<Sku> skus = productService.findProductsByPrice(total
// .getAmount());
// model.addAttribute("skus", skus);
// }
// }
// TODO 临时
// Order cart = CartState.getCart();
// if(cart != null) {
// boolean fixed = false;
// List<OrderItem> orderItems = cart.getOrderItems();
// if(orderItems != null) {
// for (OrderItem oi : orderItems) {
// if(oi instanceof DiscreteOrderItem) {
// DiscreteOrderItem doi = (DiscreteOrderItem) oi;
// if(doi.getProduct() == null && doi.getSku() != null) {
// doi.setProduct(doi.getSku().getProduct());
// fixed = true;
// }
// }
// }
// }
// if(fixed)
// orderService.save(cart, Boolean.FALSE);
// }
if (super.isAjaxRequest(request))
return v;
else
return "redirect:/checkout";
}
/*
* The Heat Clnic does not show the cart when a product is added. Instead,
* when the product is added via an AJAX POST that requests JSON, we only
* need to return a few attributes to update the state of the page. The most
* efficient way to do this is to call the regular add controller method,
* but instead return a map that contains the necessary attributes. By using
* the @ResposeBody tag, Spring will automatically use Jackson to convert
* the returned object into JSON for easy processing via JavaScript.
*/
@RequestMapping(value = "/cart/add", produces = "application/json")
public @ResponseBody
Map<String, Object> addJson(HttpServletRequest request,
HttpServletResponse response, Model model,
@ModelAttribute("addToCartItem") AddToCartItemEx addToCartItem)
throws IOException, PricingException, AddToCartException {
addToCartItem.validateLocationId();
Map<String, Object> responseMap = new HashMap<String, Object>();
try {
add0(request, response, model, addToCartItem);
// responseMap.put("productName",
// catalogService.findProductById(addToCartItem.getProductId()).getName());
responseMap.put("quantityAdded", addToCartItem.getQuantity());
responseMap.put("cartItemCount",
String.valueOf(CartState.getCart().getItemCount()));
responseMap.put("cartTotal",
String.valueOf(CartState.getCart().getTotal()));
responseMap.put("cartSubTotal",
String.valueOf(CartState.getCart().getSubTotal()));
if (addToCartItem.getItemAttributes() == null
|| addToCartItem.getItemAttributes().size() == 0) {
// We don't want to return a productId to hide actions for when
// it is a product that has multiple
// product options. The user may want the product in another
// version of the options as well.
responseMap.put("productId", addToCartItem.getProductId());
}
} catch (AddToCartException e) {
if (e.getCause() instanceof RequiredAttributeNotProvidedException) {
responseMap.put("error", "allOptionsRequired");
responseMap.put("errorMessage", "抱歉,加入购物车失败");
} else if (e.getCause() instanceof ProductOptionValidationException) {
ProductOptionValidationException exception = (ProductOptionValidationException) e
.getCause();
responseMap.put("error", "productOptionValidationError");
responseMap.put("errorCode", exception.getErrorCode());
responseMap.put("errorMessage", exception.getMessage());
// blMessages.getMessage(exception.get, lfocale))
} else if (e.getCause() instanceof InventoryUnavailableException
|| e.getCause().getCause() instanceof InventoryUnavailableException) {
responseMap.put("error", "inventoryUnavailable");
responseMap.put("errorMessage", "这个太受欢迎,已经抢光了,抱歉下次再来吧!");
} else if (e.getCause() instanceof IllegalArgumentException
&& e.getCause().getMessage() != null
&& e.getCause().getMessage().indexOf("currencies") > 0) {
responseMap.put("error", "currencyError");
responseMap.put("errorMessage", "抱歉,积分商品不能与普通商品同买,");
} else {
responseMap.put("error", "addToCartException");
responseMap.put("errorMessage", e.getMessage());
}
} catch (Exception e1) {
if (e1 instanceof InventoryUnavailableException) {
responseMap.put("error", "inventoryUnavailable");
responseMap.put("errorMessage", "这个太受欢迎,已经抢光了,抱歉下次再来吧!");
} else
throw new RuntimeException("error add", e1);
}
return responseMap;
}
/*
* The Heat Clinic does not support adding products with required product
* options from a category browse page when JavaScript is disabled. When
* this occurs, we will redirect the user to the full product details page
* for the given product so that the required options may be chosen.
*/
@RequestMapping(value = "/cart/add", produces = { "text/html", "*/*" })
public String add(HttpServletRequest request, HttpServletResponse response,
Model model, RedirectAttributes redirectAttributes,
@ModelAttribute("addToCartItem") AddToCartItemEx addToCartItem)
throws IOException, PricingException, AddToCartException {
Boolean w_flag = (Boolean)request.getSession().getAttribute("w_flag");
addToCartItem.validateLocationId();
try {
String return_url = add0(request, response, model, addToCartItem);
if(w_flag!=null&&w_flag){
return "redirect:/weixin/cart";
}else{
return return_url;
}
} catch (AddToCartException e) {
// FIXME 异常信息反馈到页面
Sku sku = catalogService.findSkuById(addToCartItem.getSkuId());
if (sku == null)
return "redirect:/";
String errorMsg;
if (e.getCause() instanceof RequiredAttributeNotProvidedException) {
errorMsg = "请选择商品规格,";
} else if (e.getCause() instanceof ProductOptionValidationException) {
errorMsg = "请选择商品规格,";
// blMessages.getMessage(exception.get, lfocale))
} else if (e.getCause() instanceof InventoryUnavailableException
|| e.getCause().getCause() instanceof InventoryUnavailableException) {
errorMsg = "这个太好了,被抢光了,下次来早点吧。";
} else if (e.getCause() instanceof IllegalArgumentException
&& e.getCause().getMessage() != null) {
if (e.getCause().getMessage().indexOf("currencies") > 0)
errorMsg = "抱歉,积分商品不能与普通商品同买,";
else
errorMsg = e.getCause().getMessage();
} else {
errorMsg = "抱歉,加入购物车出错了!";
}
return "redirect:" + sku.getProduct().getUrl() + "?errorMessage="
+ URLEncoder.encode(errorMsg, "UTF-8");
} catch (Exception e1) {
if (e1 instanceof InventoryUnavailableException) {
Sku sku = catalogService.findSkuById(addToCartItem.getSkuId());
if (sku == null)
return "redirect:/";
return "redirect:" + sku.getProduct().getUrl()
+ "?errorMessage="
+ URLEncoder.encode("这个太好了,被抢光了,下次来早点吧。", "UTF-8");
} else
throw new RuntimeException("error add", e1);
}
}
@RequestMapping(value = "/cart/add-cou")
public String addCou(HttpServletRequest request,
HttpServletResponse response, Model model,
RedirectAttributes redirectAttributes,
@ModelAttribute("addToCartItem") AddToCartItemEx addToCartItem)
throws IOException, PricingException, AddToCartException {
addToCartItem.validateLocationId();
try {
add0(request, response, model, addToCartItem);
return "redirect:/checkout";
} catch (AddToCartException e) {
// FIXME 异常信息反馈到页面
Sku sku = catalogService.findSkuById(addToCartItem.getSkuId());
if (sku == null)
return "redirect:/";
String errorMsg;
if (e.getCause() instanceof RequiredAttributeNotProvidedException) {
errorMsg = "请选择商品规格,";
} else if (e.getCause() instanceof ProductOptionValidationException) {
errorMsg = "请选择商品规格,";
// blMessages.getMessage(exception.get, lfocale))
} else if (e.getCause() instanceof InventoryUnavailableException
|| e.getCause().getCause() instanceof InventoryUnavailableException) {
errorMsg = "这个太好了,被抢光了,下次来早点吧。";
} else if (e.getCause() instanceof IllegalArgumentException
&& e.getCause().getMessage() != null) {
if (e.getCause().getMessage().indexOf("currencies") > 0)
errorMsg = "抱歉,积分商品不能与普通商品同买,";
else
errorMsg = e.getCause().getMessage();
} else {
errorMsg = "抱歉,加入购物车出错了!";
}
return "redirect:" + sku.getProduct().getUrl() + "?errorMessage="
+ URLEncoder.encode(errorMsg, "UTF-8");
} catch (Exception e1) {
if (e1 instanceof InventoryUnavailableException) {
Sku sku = catalogService.findSkuById(addToCartItem.getSkuId());
if (sku == null)
return "redirect:/";
return "redirect:" + sku.getProduct().getUrl()
+ "?errorMessage="
+ URLEncoder.encode("这个太好了,被抢光了,下次来早点吧。", "UTF-8");
} else
throw new RuntimeException("error add", e1);
}
}
public String add0(HttpServletRequest request,
HttpServletResponse response, Model model, AddToCartItemEx itemRequest)
throws IOException, AddToCartException, PricingException {
itemRequest.setOverrideRetailPrice(null);
itemRequest.setOverrideSalePrice(null);
// 必须干掉productId, 以skuId为准
itemRequest.setProductId(null);
Order cart = CartState.getCart();
if (cart == null || cart instanceof NullOrderImpl) {
cart = orderService.createNewCartForCustomer(CustomerState
.getCustomer(request));
}
if (cart.getItemCount() == 0) {
Long skuid = itemRequest.getSkuId();
if (skuid == null)
skuid = itemRequest.getProductId();
if (skuid == null)
return getCartView();
Sku sku = catalogService.findSkuById(skuid);
BroadleafCurrency currency = sku.getCurrency();
cart.setCurrency(currency);
if (CustomerState.getCustomer().isAnonymous()
&& (currency == null || !"CNY".equals(currency
.getCurrencyCode()))) {
throw new AddToCartException("未登录会员不能仙丹换购,请先登录或注册~",
new IllegalArgumentException("未登录会员不能仙丹换购,请先登录或注册~"));
}
}
// Order cart = CartState.getCart();
// if (cart == null || cart instanceof NullOrderImpl) {
// cart = orderService.createNewCartForCustomer(CustomerState
// .getCustomer(request));
// }
//
// Sku sku = null;
// if (itemRequest.getProductId() != null) {
// Product product = catalogService.findProductById(itemRequest
// .getProductId());
// if (product != null) {
// sku = product.getDefaultSku();
// }
// }
// if (sku == null)
// sku = catalogService.findSkuById(itemRequest.getSkuId());
// BroadleafCurrency currency = sku.getCurrency();
// if (cart.getItemCount() == 0) {
// cart.setCurrency(currency);
// }
updateCartService.validateCart(cart);
cart = orderService.addItem(cart.getId(), itemRequest, false);
cart = orderService.save(cart, true);
CartState.setCart(cart);
return isAjaxRequest(request) ? getCartView() : getCartPageRedirect();
}
@RequestMapping("/cart/updateQuantity")
public String updateQuantity(
HttpServletRequest request,
HttpServletResponse response,
Model model,
@RequestParam(value = "redirect", required = false) String redirect,
@ModelAttribute("addToCartItem") AddToCartItemEx addToCartItem)
throws IOException, PricingException, UpdateCartException,
RemoveFromCartException {
Boolean w_flag = (Boolean)request.getSession().getAttribute("w_flag");
addToCartItem.validateLocationId();
try {
String update = super.updateQuantity(request, response, model,
addToCartItem);
// if (CartState.getCart() != null) {
// Money total = CartState.getCart().getTotal();
// if (total != null) { // FIXME 凑整,币种
// List<Sku> skus = productService
// .findProductsByPriceAndCurrency(total.getAmount(),
// CartState.getCart().getCurrency());
// model.addAttribute("skus", skus);
// }
// }
if(w_flag!=null&&w_flag){
return "redirect:/weixin/cart";
}else{
return StringUtils.isBlank(redirect) ? update : redirect;
}
} catch (UpdateCartException e) {
if (e.getCause() instanceof InventoryUnavailableException) {
if (isAjaxRequest(request)) {
Map<String, Object> extraData = new HashMap<String, Object>(
1);
extraData.put("error", "InventoryUnavailable");
model.addAttribute("blcextradata",
new ObjectMapper().writeValueAsString(extraData));
}
return StringUtils.isBlank(redirect) ? "/cart/cart_error"
: redirect
+ "?error=%E6%8A%B1%E6%AD%89%EF%BC%8C%E5%BA%93%E5%AD%98%E4%B8%8D%E8%B6%B3%E4%BA%86";
} else {
throw e;
}
}
}
@RequestMapping("/cart/remove")
public String remove(HttpServletRequest request,
HttpServletResponse response, Model model,
@ModelAttribute("addToCartItem") AddToCartItemEx addToCartItem)
throws IOException, PricingException, RemoveFromCartException {
addToCartItem.validateLocationId();
String remove = super.remove(request, response, model, addToCartItem);
// if (CartState.getCart() != null) {
// Money total = CartState.getCart().getTotal();
// if (total != null) {
// List<Sku> skus = productService.findProductsByPriceAndCurrency(
// total.getAmount(), CartState.getCart().getCurrency());
// model.addAttribute("skus", skus);
// }
// }
return remove;
}
@Override
@RequestMapping("/cart/empty")
public String empty(HttpServletRequest request,
HttpServletResponse response, Model model) throws PricingException {
// return super.empty(request, response, model);
return "ajaxredirect:/";
}
@Override
@RequestMapping("/cart/promo")
public String addPromo(HttpServletRequest request,
HttpServletResponse response, Model model,
@RequestParam("promoCode") String customerOffer)
throws IOException, PricingException {
OfferCode offerCode = null;
Boolean promoAdded = false;
String exception = "";
try {
offerCode = addPromo0(request, response, model, customerOffer);
} catch (OfferMaxUseExceededException e) {
exception = "优惠券已过期~";
}
if (offerCode == null) {
exception = "无效优惠码,请确认后再试~";
} else {
promoAdded = true;
}
if (isAjaxRequest(request)) {
Map<String, Object> extraData = new HashMap<String, Object>();
extraData.put("promoAdded", promoAdded);
extraData.put("exception", exception);
model.addAttribute("blcextradata",
new ObjectMapper().writeValueAsString(extraData));
} else {
model.addAttribute("error_pro", exception);
}
return "redirect:/checkout";
}
private OfferCode addPromo0(HttpServletRequest request,
HttpServletResponse response, Model model, String customerOffer)
throws PricingException, JsonGenerationException,
JsonMappingException, IOException, OfferMaxUseExceededException {
Order cart = CartState.getCart();
OfferCode offerCode = offerService.lookupOfferCodeByCode(customerOffer);
if (offerCode != null) {
orderService.addOfferCode(cart, offerCode, false);
cart = orderService.save(cart, true);
// offerCode.setUserCustomerId(userCustomerId);
}
CartState.setCart(cart);
return offerCode;
}
@Override
@RequestMapping("/cart/promo/remove")
public String removePromo(HttpServletRequest request,
HttpServletResponse response, Model model,
@RequestParam("offerCodeId") Long offerCodeId) throws IOException,
PricingException {
return super.removePromo(request, response, model, offerCodeId);
}
@RequestMapping(value = "/app/cart/promo")
@ResponseBody
public Map<String, Object> addAppPromo(HttpServletRequest request,
HttpServletResponse response, Model model,
@RequestParam("promoCode") String customerOffer)
throws IOException, PricingException {
OfferCode offerCode = null;
String exception = "";
try {
offerCode = addPromo0(request, response, model, customerOffer);
} catch (OfferMaxUseExceededException e) {
exception = "优惠券已过期~";
}
if (offerCode == null) {
exception = "无效优惠码,请确认后再试~";
}
Map<String, Object> ret = new HashMap<String, Object>(2);
if (!("".equals(exception))) {
ret.put("error", "promo_error");
ret.put("errorMessage", exception);
} else {
ret.put("marketingMessage", offerCode.getOffer()
.getMarketingMessage());
}
return ret;
}
@RequestMapping("/weixin/cart")
public String weixinCart(HttpServletRequest request,
HttpServletResponse response, Model model) throws PricingException {
super.cart(request, response, model);
return "weixin/cart/w_cart";
}
}