/* * 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.checkout; import java.io.Serializable; import java.io.UnsupportedEncodingException; import java.math.BigDecimal; import java.net.URLEncoder; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.map.LRUMap; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.broadleafcommerce.common.exception.ServiceException; import org.broadleafcommerce.common.money.Money; import org.broadleafcommerce.common.persistence.Status; import org.broadleafcommerce.common.rule.MvelHelper; import org.broadleafcommerce.common.time.SystemTime; import org.broadleafcommerce.core.checkout.service.exception.CheckoutException; import org.broadleafcommerce.core.checkout.service.workflow.CheckoutResponse; import org.broadleafcommerce.core.offer.domain.Offer; import org.broadleafcommerce.core.offer.service.type.OfferRuleType; import org.broadleafcommerce.core.offer.service.type.OfferType; import org.broadleafcommerce.core.order.domain.FulfillmentGroup; import org.broadleafcommerce.core.order.domain.NullOrderImpl; import org.broadleafcommerce.core.order.domain.Order; import org.broadleafcommerce.core.order.domain.OrderItem; import org.broadleafcommerce.core.order.domain.SkuAccessor; import org.broadleafcommerce.core.order.service.type.FulfillmentType; import org.broadleafcommerce.core.order.service.type.OrderStatus; import org.broadleafcommerce.core.payment.domain.PaymentInfo; import org.broadleafcommerce.core.payment.domain.Referenced; import org.broadleafcommerce.core.payment.service.exception.InsufficientFundsException; import org.broadleafcommerce.core.payment.service.type.PaymentInfoType; import org.broadleafcommerce.core.pricing.service.exception.PricingException; import org.broadleafcommerce.core.web.checkout.model.OrderInfoForm; import org.broadleafcommerce.core.web.order.CartState; import org.broadleafcommerce.inventory.domain.FulfillmentLocation; import org.broadleafcommerce.inventory.domain.Inventory; import org.broadleafcommerce.inventory.exception.InventoryUnavailableException; import org.broadleafcommerce.profile.core.domain.Address; import org.broadleafcommerce.profile.core.domain.Customer; import org.broadleafcommerce.profile.core.domain.CustomerAddress; import org.broadleafcommerce.profile.web.core.CustomerState; import org.mvel2.MVEL; import org.mvel2.ParserContext; import org.springframework.beans.factory.annotation.Value; import org.springframework.dao.DataAccessException; import org.springframework.security.authentication.RememberMeAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContext; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.validation.BeanPropertyBindingResult; import org.springframework.validation.BindingResult; import org.springframework.validation.ValidationUtils; import org.springframework.web.bind.ServletRequestDataBinder; import org.springframework.web.bind.annotation.InitBinder; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import com.ssbusy.core.account.domain.MyCustomer; import com.ssbusy.core.account.service.BalanceChangeType; import com.ssbusy.core.domain.AreaAddress; import com.ssbusy.core.domain.Dormitory; import com.ssbusy.core.domain.MyAddress; import com.ssbusy.core.inneraddress.service.DormitoryService; import com.ssbusy.core.myorder.domain.MyOrder; import com.ssbusy.core.myorder.service.MyOrderService; import com.ssbusy.core.offer.domain.MyOfferCode; import com.ssbusy.core.offer.service.MyOfferService; import com.ssbusy.core.region.domain.Region; import com.ssbusy.core.region.service.RegionService; import com.ssbusy.payment.service.type.AlipayPaymentInfo; import com.ssbusy.payment.service.type.MyPaymentInfoType; import com.ssbusy.site.myshippingform.MyBillingInfoForm; import com.ssbusy.site.myshippingform.MyShippingInfoForm; @Controller("checkoutController") public class CheckoutController extends MyBroadleafCheckoutController { private static final Log LOG = LogFactory.getLog(CheckoutController.class); private static final Map EXPRESSION_CACHE = new LRUMap(1000); /* * The Checkout page for Heat Clinic will have the shipping information * pre-populated with an address if the fulfillment group has an address and * fulfillment option associated with it. It also assumes that there is only * one payment info of type credit card on the order. If so, then the * billing address will be pre-populated. */ @Resource(name = "ssbDormitoryService") protected DormitoryService dormitoryService; @Resource(name = "ssbRegionService") protected RegionService regionService; @Resource(name = "blOfferService") protected MyOfferService offerService; @Resource(name = "ssbMyOrderService") protected MyOrderService myorderService; @Value("${couzheng_show_quantity}") private int couzheng_show_quantity; private static final String REDIRECT_REGION_SELECT = "redirect:/region"; private static final String REDIRECT_DENY = "redirect:/login"; /** * TODO 这一步其实是show cart,不是checkout */ @RequestMapping("/checkout") public String checkout(Model model) { Region region = null; MyCustomer myCustomer = (MyCustomer) CustomerState.getCustomer(); region = myCustomer.getRegion(); if (CartState.getCart() != null) { Money total = CartState.getCart().getTotal(); if (total != null && Math.floor(total.doubleValue()) != total.doubleValue()) { List<Inventory> invs = inventoryService .findProductsByPriceAndCurrency(total.getAmount(), CartState.getCart().getCurrency(), region.getFulfillmentLocations(), 0, 12); if (couzheng_show_quantity < invs.size()) { invs = invs.subList(0, couzheng_show_quantity); } model.addAttribute("inventories", invs); } } // 取出所有的优惠信息,并把过期的移除 List<Offer> offers = offerService.findAllOffers(); for (Iterator<Offer> iterator = offers.iterator(); iterator.hasNext();) { Offer offer = null; offer = iterator.next(); if (!((Status) offer).isActive()) { iterator.remove(); } } if (offers.iterator() != null) { Iterator<Offer> iterator = offers.iterator(); while (iterator.hasNext()) { // To do Offer offer = iterator.next(); if (offer.getOfferMatchRules().get( OfferRuleType.CUSTOMER.getType()) != null) { String maprule = offer.getOfferMatchRules() .get(OfferRuleType.CUSTOMER.getType()) .getMatchRule(); HashMap<String, Object> vars = new HashMap<String, Object>(); vars.put("customer", myCustomer); Boolean expressionOutcome = executeExpression(maprule, vars); if (expressionOutcome == null || !expressionOutcome) { iterator.remove(); } } } } model.addAttribute("offers", offers); List<MyOfferCode> myOfferCodes = offerService .listOfferCodeByOwner(CustomerState.getCustomer().getId()); model.addAttribute("offercodes", myOfferCodes); return getCheckoutView(); } @RequestMapping(value = "/checkout/checkout-step-2") public String saveGlobalOrderDetails( HttpServletRequest request, Model model, @ModelAttribute("orderInfoForm") OrderInfoForm orderInfoForm, @ModelAttribute("shippingInfoForm") MyShippingInfoForm shippingForm, @ModelAttribute("billingInfoForm") MyBillingInfoForm billingForm, BindingResult result) { MyCustomer myCustomer = (MyCustomer) CustomerState.getCustomer(); Region region = myCustomer.getRegion(); if (region == null) { return REDIRECT_REGION_SELECT; } SimpleDateFormat dateformat1 = new SimpleDateFormat("HH:mm"); String date = dateformat1.format(new Date()); String[] times = region.getShipping_time().split(";"); boolean isOutDeliveryDateRange = true; for (String time : times) { String[] shipping_time = time.split("-"); if ((date.compareTo(shipping_time[0]) > 0) && (date.compareTo(shipping_time[1]) < 0)) isOutDeliveryDateRange = false; } model.addAttribute("isOutDeliveryDateRange", isOutDeliveryDateRange); prepopulateCheckoutForms(CartState.getCart(), orderInfoForm, shippingForm, billingForm); return super.saveGlobalOrderDetails(request, model, orderInfoForm, result); } @RequestMapping(value = "/checkout/singleship", method = RequestMethod.GET) public String convertToSingleship(HttpServletRequest request, HttpServletResponse response, Model model) throws PricingException { return super.convertToSingleship(request, response, model); } @RequestMapping(value = "/checkout/singleship", method = RequestMethod.POST) public String saveSingleShip( HttpServletRequest request, HttpServletResponse response, Model model, @ModelAttribute("orderInfoForm") OrderInfoForm orderInfoForm, @ModelAttribute("billingInfoForm") MyBillingInfoForm billingForm, @ModelAttribute("shippingInfoForm") MyShippingInfoForm shippingForm, BindingResult result) throws Exception { /* * 验证是否remember登录并且采用余额和积分交易 */ SecurityContext context = SecurityContextHolder.getContext(); Authentication auth = context.getAuthentication(); Boolean b = (auth instanceof RememberMeAuthenticationToken) && ("integral_pay".equals(shippingForm.getPaymentMethod()) || "balance_pay" .equals(shippingForm.getPaymentMethod())); if (b) { return REDIRECT_DENY; } return saveSingleShip0(request, response, model, orderInfoForm, billingForm, shippingForm, result, false); } Date myDate1; Date myDate2; Date myDate3; Date myDate4; public CheckoutController() { DateFormat dateFormat1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); try { myDate1 = dateFormat1.parse("2013-11-11 11:11:00"); myDate2 = dateFormat1.parse("2013-11-11 15:11:00"); myDate3 = dateFormat1.parse("2013-11-11 19:11:00"); myDate4 = dateFormat1.parse("2013-11-11 23:11:00"); } catch (ParseException e) { // impossible } } private String saveSingleShip0(HttpServletRequest request, HttpServletResponse response, Model model, OrderInfoForm orderInfoForm, MyBillingInfoForm billingForm, MyShippingInfoForm shippingForm, BindingResult result, boolean ajax) throws PricingException, ServiceException, CheckoutException, ParseException { MyCustomer myCustomer = (MyCustomer) CustomerState.getCustomer(); Region region = myCustomer.getRegion(); Boolean w_flag = (Boolean)request.getSession().getAttribute("w_flag"); if (region == null) { if(w_flag!=null&&w_flag){ return "redirect:/weixin/region"; }else return REDIRECT_REGION_SELECT; } MyAddress myAddress = processShippingForm(shippingForm, result); if (result.hasErrors()) { putFulfillmentOptionsAndEstimationOnModel(model); populateModelWithShippingReferenceData(request, model); model.addAttribute("states", stateService.findStates()); model.addAttribute("countries", countryService.findCountries()); model.addAttribute("expirationMonths", populateExpirationMonths()); model.addAttribute("expirationYears", populateExpirationYears()); model.addAttribute("validShipping", false); if(w_flag!=null&&w_flag){ return "weixin/cart/w_checkout"; }else return checkoutAddress; } billingForm.setPaymentMethod(shippingForm.getPaymentMethod()); billingForm.setBp_pay(shippingForm.getBp_pay()); billingForm.setAlipay(shippingForm.getAlipay()); if (shippingForm.getBp_pay() == null || shippingForm.getBp_pay().doubleValue() < 0) billingForm.setBp_pay(BigDecimal.ZERO); if (shippingForm.getAlipay() == null || shippingForm.getAlipay().doubleValue() < 0) billingForm.setAlipay(BigDecimal.ZERO); billingForm.setMyAddress(myAddress); prepopulateCheckoutForms(CartState.getCart(), orderInfoForm, null, billingForm); String assign = request.getParameter("assign"); MyOrder cart = (MyOrder) CartState.getCart(); Date dStart = null, dEnd = null; Date nowDay = Calendar.getInstance().getTime(); if (nowDay.after(myDate1) && nowDay.before(myDate2)) { dStart = myDate1; dEnd = myDate2; } else if (nowDay.after(myDate2) && nowDay.before(myDate3)) { dStart = myDate2; dEnd = myDate3; } else if (nowDay.after(myDate3) && nowDay.before(myDate4)) { dStart = myDate3; dEnd = myDate4; } if (dStart != null) { List<Order> orders = myorderService.getAllSubmittedInTime( myCustomer.getId(), dStart, dEnd); boolean contain = ifCanAdd(orders); if (contain) { if(w_flag!=null&&w_flag){ return "redirect:/weixin/checkout"; }else return "redirect:/checkout/checkout-step-2?error=%E4%B8%8D%E8%A6%81%E5%A4%AA%E8%B4%AA%E5%BF%83%EF%BC%8C%E5%8F%AA%E8%83%BD%E6%8A%A21%E6%AC%A1%E5%93%A6"; } } String a1; Date a2; if ("2".equals(assign)) { String date = request.getParameter("date"); String detaildate = request.getParameter("detaildate"); int deta = 0; try { deta = Integer.parseInt(detaildate); } catch (Exception e) { // ignore } Calendar calendar = Calendar.getInstance(); calendar.set(Calendar.HOUR_OF_DAY, deta); if ("1".equals(date)) { calendar.set(Calendar.DAY_OF_MONTH, calendar.get(Calendar.DAY_OF_MONTH) + 1); } else if ("2".equals(date)) { calendar.set(Calendar.DAY_OF_MONTH, calendar.get(Calendar.DAY_OF_MONTH) + 2); } SimpleDateFormat dateformat1 = new SimpleDateFormat("HH:mm"); a2 = calendar.getTime(); a1 = dateformat1.format(a2); } else { SimpleDateFormat dateformat1 = new SimpleDateFormat("HH:mm"); a2 = new Date(); a1 = dateformat1.format(a2); } cart.setDelieverDate(a2); FulfillmentGroup fulfillmentGroup = cart.getFulfillmentGroups().get(0); fulfillmentGroup.setAddress(shippingForm.getMyAddress()); fulfillmentGroup.setPersonalMessage(shippingForm.getPersonalMessage()); fulfillmentGroup.setDeliveryInstruction(shippingForm .getDeliveryMessage()); cart = (MyOrder) orderService.save(cart, true); CartState.setCart(cart); CustomerAddress defaultAddress = customerAddressService .findDefaultCustomerAddress(CustomerState.getCustomer().getId()); if (defaultAddress == null) { MyAddress address = (MyAddress) addressService .saveAddress(shippingForm.getMyAddress()); CustomerAddress customerAddress = customerAddressService.create(); customerAddress.setAddress(address); customerAddress.setCustomer(CustomerState.getCustomer()); customerAddress = customerAddressService .saveCustomerAddress(customerAddress); customerAddressService.makeCustomerAddressDefault(customerAddress .getId(), customerAddress.getCustomer().getId()); } // 是否不验证送货时间 if (false) {// if("no".equals(request.getParameter("forcedSubmit"))){ String[] times = region.getShipping_time().split(";"); boolean isOutDeliveryDateRange = true; for (String time : times) { String[] shipping_time = time.split("-"); if ((a1.compareTo(shipping_time[0]) > 0) && (a1.compareTo(shipping_time[1]) < 0)) isOutDeliveryDateRange = false; } if (isOutDeliveryDateRange) { return "redirect:/checkout/checkout-step-2?flag=1"; } } try { if ("alipay_pay".equals(billingForm.getPaymentMethod())) { String description = ""; for (OrderItem ot : cart.getOrderItems()) { description = description + ot.getName() + ";"; if (description.length() > 50) { description = description + "...."; break; } } // TODO 直接取第一个location了 FulfillmentLocation loc = null; List<FulfillmentGroup> fgroups = cart.getFulfillmentGroups(); if (fgroups == null || fgroups.size() == 0) { Customer customer = CustomerState.getCustomer(); if (customer instanceof MyCustomer) loc = ((MyCustomer) customer).getRegion() .getFulfillmentLocations().get(0); } else { Address addr = fgroups.get(0).getAddress(); if (addr instanceof MyAddress) { loc = ((MyAddress) addr).getDormitory() .getAreaAddress().getRegion() .getFulfillmentLocations().get(0); } } // TODO path中的一切变量方法alipay相关的控制器里 String path = "/alipay/direct_pay?tradeNo=" + (new SimpleDateFormat("yyyyMMddHHmm") .format(SystemTime.asDate()) + cart.getId()) + "&subject=在校网 " + (loc == null ? "" : loc.getId()) + (new Date().getTime() % 1000000) + cart.getId() + " 号订单&description=" + description + "&tradeUrl=http://www.onxiao.com/customer/orders"; if (billingForm.getAlipay().compareTo( cart.getTotal().getAmount()) >= 0) { // 全部支付宝 path = path + "&totalFee=" + cart.getTotal(); return "forward:" + path; } else { if (billingForm.getAlipay().doubleValue() == 0) { return completeCodCheckout(request, response, model, billingForm, result); } else { // 部分支付宝 path = path + "&totalFee=" + billingForm.getAlipay(); return "forward:" + path; } } } else if ("balance_pay".equals(billingForm.getPaymentMethod())) { if (billingForm.getBp_pay().compareTo( cart.getTotal().getAmount()) >= 0) { return completeBpCheckout(request, response, model, billingForm, result); } else { if (billingForm.getAlipay().doubleValue() <= 0) { return completeCodCheckout(request, response, model, billingForm, result); } else { return complexCheckout(request, response, model, billingForm, result, MyPaymentInfoType.Payment_Bp, cart.getId()); } } } else if ("integral_pay".equals(billingForm.getPaymentMethod())) { return completeIntegrlCheckout(request, response, model, billingForm, result); } else { return completeCodCheckout(request, response, model, billingForm, result); } } catch (CheckoutException e) { if (ajax) throw e; if (e.getCause() instanceof InventoryUnavailableException) { try { if(w_flag!=null&&w_flag){ return "redirect:/weixin/checkout"; }else return "redirect:/checkout/checkout-step-2?inventoryError=1&errorMessage=" + URLEncoder.encode( ((InventoryUnavailableException) e .getCause()).getMessage(), "utf-8"); } catch (UnsupportedEncodingException e1) { if(w_flag!=null&&w_flag){ return "redirect:/weixin/checkout"; }else return "redirect:/checkout/checkout-step-2?inventoryError=1&errorMessage=" + ((InventoryUnavailableException) e.getCause()) .getMessage(); } } else if (e.getCause() instanceof InsufficientFundsException) { if(w_flag!=null&&w_flag){ return "redirect:/weixin/checkout"; }else return "redirect:/checkout/checkout-step-2?error=%E7%A7%AF%E5%88%86%E6%88%96%E8%80%85%E4%BD%99%E9%A2%9D%E4%B8%8D%E8%B6%B3"; } else { throw e; } } } @RequestMapping(value = "/checkout/alipaySucessOrFailed") public String alipayCheckout(HttpServletRequest request, HttpServletResponse response, Model model, MyBillingInfoForm billingForm, BindingResult result, String orderNum, String returnInfo, String total_fee) { LOG.info("this is our alipayCheckout function:"); /* * String orderNum = (String) request.getAttribute("order_id"); String * returnInfo = (String) request.getAttribute("return_info"); String * total_fee = (String) request.getAttribute("total_fee"); */ BigDecimal alipay = null; if ("".equals(total_fee) || total_fee == null) { LOG.error("total_fee is null"); } else { alipay = new BigDecimal(total_fee); } if (orderNum == null || returnInfo == null || alipay == null || orderNum.length() < 13 || !"success".equals(returnInfo)) { LOG.error("orderNum or retutnInfo or alipay is error"); return getCartPageRedirect(); } Long orderId; try { orderId = Long.parseLong(orderNum.substring(12)); } catch (NumberFormatException e) { LOG.error("substring orderNum throws an exception" + orderNum, e); return getCartPageRedirect(); } Order cart = orderService.findOrderById(orderId); if (cart != null && OrderStatus.IN_PROCESS.equals(cart.getStatus())) { if (alipay.compareTo(cart.getTotal().getAmount()) < 0) { billingForm.setAlipay(alipay); LOG.info("a part of the order is used alipay"); String ret = ""; try { ret = complexCheckout(request, response, model, billingForm, result, MyPaymentInfoType.Payment_Alipay, orderId); } catch (CheckoutException e) { if (e.getCause() instanceof InventoryUnavailableException) { LOG.info("InventoryUnavailableException so we pay balance to the customer"); return aplipayFailedRollBack2Banlance(alipay, cart); } else { LOG.info("not know exception", e); } } if (OrderStatus.IN_PROCESS.equals(cart.getStatus())) { return aplipayFailedRollBack2Banlance(alipay, cart); } else { LOG.info("alipay pay the part of the order is success"); return ret; } } copyShippingAddressToBillingAddress(cart, billingForm); billingInfoFormValidator.validate(billingForm, result); if (result.hasErrors()) { LOG.error("result.hasErrors() orderid=" + orderId); populateModelWithShippingReferenceData(request, model); return getCheckoutView(); } // 先把原有支付信息清理掉 cart.getPaymentInfos().clear(); PaymentInfo alipayInfo = alipayPaymentInfoFactory .constructPaymentInfo(cart); alipayInfo.setAddress(billingForm.getMyAddress()); cart.getPaymentInfos().add(alipayInfo); AlipayPaymentInfo alipayReference = (AlipayPaymentInfo) alipaySecurePaymentInfoService .create(MyPaymentInfoType.Payment_Alipay); alipayReference.setMessage("success"); alipayReference.setReferenceNumber("try"); Map<PaymentInfo, Referenced> payments = new HashMap<PaymentInfo, Referenced>( 1); payments.put(alipayInfo, alipayReference); CheckoutResponse checkoutResponse = null; try { checkoutResponse = checkoutService.performCheckout(cart, payments); } catch (CheckoutException e) { if (e.getCause() instanceof InventoryUnavailableException) { LOG.info("InventoryUnavailableException in all pay by alipay"); return aplipayFailedRollBack2Banlance(alipay, cart); } else { LOG.info("not know exception in all pay by alipay", e); } } if (!checkoutResponse.getPaymentResponse().getResponseItems() .get(alipayInfo).getTransactionSuccess()) { LOG.error("alipay is finished but the order is not success because some problems"); // 支付宝支付成功,但是我们这边有问题,查看客户是否注册,注册则返回到余额,没有注册则提醒联系客服。 return aplipayFailedRollBack2Banlance(alipay, cart); } LOG.info("alipay success, the order is success order id=" + orderId); return getConfirmationView(cart.getOrderNumber()); } else { LOG.error("alipay failed, the order is not normal order invalid: id=" + orderId); if (cart != null) { LOG.error("alipay failed OrderStatus is " + cart.getStatus()); } } return getCartPageRedirect(); } private String aplipayFailedRollBack2Banlance(BigDecimal alipay, Order cart) { MyCustomer myCustomer = (MyCustomer) cart.getCustomer(); if (myCustomer.isRegistered()) { LOG.info("return the alipay money to the customer Balance; The customer_id is " + myCustomer.getId() + ";return " + alipay + " balance to the Customer"); myCustomerService.rechargeToAccountBalance(myCustomer.getId(), alipay, BalanceChangeType.BPBACK); return "redirect:/checkout/checkout-step-2?alipayerrorCode=2"; } else { LOG.info("Customer is not registered so the customer will call you latter,orderId is " + cart.getId()); for (PaymentInfo pi : cart.getPaymentInfos()) { pi.setAmount(new Money(BigDecimal.ZERO, cart.getCurrency())); } return "redirect:/checkout/checkout-step-2?alipayerrorCode=1"; } } @SuppressWarnings("deprecation") private MyAddress processShippingForm(MyShippingInfoForm shippingForm, BindingResult result) { shippingInfoFormValidator.validate(shippingForm, result); if (result.hasErrors()) return null; // TODO ID为空的时候处理 // 这里先用address的AddressLine3保存dormitoryid然后根据id找dormitory对象,最后要改掉的。 MyAddress myAddress = shippingForm.getMyAddress(); Long dormitoryId; try { dormitoryId = Long.parseLong(myAddress.getAddressLine3()); } catch (NumberFormatException e) { ValidationUtils.rejectIfEmpty(result, "myAddress.addressLine3", "addressLine3.required"); return null; } if (myAddress.getDormitory() == null || !dormitoryId.equals(myAddress.getDormitory() .getDormitoryId())) { Dormitory dormitory = dormitoryService .loadDormitotyById(dormitoryId); if (dormitory == null) { ValidationUtils.rejectIfEmpty(result, "myAddress.addressLine3", "addressLine3.required"); return null; } // dormitory.id为-1的时候表示用户选择的是其他。 myAddress.setDormitory(dormitory); } myAddress.setAddressLine1("addressLine1"); myAddress.setCity("city"); myAddress.setPostalCode("310018"); if (myAddress.getLastName() != null && myAddress.getLastName().length() > 30) { myAddress.setLastName(myAddress.getLastName().substring(0, 30)); } myAddress.setState(shippingForm.getAddress().getState()); if (myAddress.getCountry() == null) myAddress.setCountry(shippingForm.getAddress().getCountry()); return myAddress; } // @RequestMapping(value = "/checkout/multiship", method = // RequestMethod.GET) // public String showMultiship( // HttpServletRequest request, // HttpServletResponse response, // Model model, // @ModelAttribute("orderMultishipOptionForm") OrderMultishipOptionForm // orderMultishipOptionForm, // BindingResult result) throws PricingException { // return super.showMultiship(request, response, model); // } // @RequestMapping(value = "/checkout/multiship", method = // RequestMethod.POST) // public String saveMultiship( // HttpServletRequest request, // HttpServletResponse response, // Model model, // @ModelAttribute("orderMultishipOptionForm") OrderMultishipOptionForm // orderMultishipOptionForm, // BindingResult result) throws PricingException, ServiceException { // return super.saveMultiship(request, response, model, // orderMultishipOptionForm, result); // } // @RequestMapping(value = "/checkout/add-address", method = // RequestMethod.GET) // public String showMultishipAddAddress(HttpServletRequest request, // HttpServletResponse response, Model model, // @ModelAttribute("addressForm") ShippingInfoForm addressForm, // BindingResult result) { // return super.showMultishipAddAddress(request, response, model); // } // @RequestMapping(value = "/checkout/add-address", method = // RequestMethod.POST) // public String saveMultishipAddAddress(HttpServletRequest request, // HttpServletResponse response, Model model, // @ModelAttribute("addressForm") ShippingInfoForm addressForm, // BindingResult result) throws ServiceException { // return super.saveMultishipAddAddress(request, response, model, // addressForm, result); // } @RequestMapping(value = "/checkout/complete", method = RequestMethod.POST) public String completeCheckout( HttpServletRequest request, HttpServletResponse response, Model model, @ModelAttribute("orderInfoForm") OrderInfoForm orderInfoForm, @ModelAttribute("shippingInfoForm") MyShippingInfoForm shippingForm, @ModelAttribute("billingInfoForm") MyBillingInfoForm billingForm, BindingResult result) throws Exception { /* * prepopulateCheckoutForms(CartState.getCart(), null, shippingForm, * billingForm); try { if (billingForm.getPaymentMethod().equals("cod")) * return super.completeCodCheckout(request, response, model, * billingForm, result); else if * (billingForm.getPaymentMethod().equals("balance_pay")) { return * super.completeBpCheckout(request, response, model, billingForm, * result); } else { return super.completeIntegrlCheckout(request, * response, model, billingForm, result); } } catch (CheckoutException * e) { if (e.getCause() instanceof InventoryUnavailableException) { * return "/checkout/checkout_error"; } else { throw e; } } catch * (Exception e) { if (e.getCause() instanceof * InsufficientFundsException) { return "/checkout/checkout_error"; } * else { throw e; } } */ return null; } protected void prepopulateOrderInfoForm(Order cart, OrderInfoForm orderInfoForm) { if (orderInfoForm == null) return; if (cart.getEmailAddress() == null || cart.getEmailAddress().length() == 0) orderInfoForm.setEmailAddress("admin@onxiao.com"); else orderInfoForm.setEmailAddress(cart.getEmailAddress()); } protected void prepopulateCheckoutForms(Order cart, OrderInfoForm orderInfoForm, MyShippingInfoForm shippingForm, MyBillingInfoForm billingForm) { if (orderInfoForm != null) prepopulateOrderInfoForm(cart, orderInfoForm); if (shippingForm != null) { MyAddress myAddress = null; List<FulfillmentGroup> groups = cart.getFulfillmentGroups(); if (CollectionUtils.isNotEmpty(groups)) { FulfillmentGroup fulfillmentGroup = groups.get(0); // if the cart has already has fulfillment information myAddress = (MyAddress) fulfillmentGroup.getAddress(); if (fulfillmentGroup.getFulfillmentOption() != null) { shippingForm.setFulfillmentOption(fulfillmentGroup .getFulfillmentOption()); shippingForm.setFulfillmentOptionId(fulfillmentGroup .getFulfillmentOption().getId()); } } if (myAddress == null) { Region region = ((MyCustomer) CustomerState.getCustomer()) .getRegion(); myAddress = getAddressByRegion(region); } if (myAddress != null) { // shippingForm.getAddress().setPrimaryPhone( // myAddress.getPrimaryPhone()); shippingForm.setMyAddress(myAddress); } } if (billingForm != null) { billingForm.setUseShippingAddress(true); } // if (cart.getPaymentInfos() != null) { // for (PaymentInfo paymentInfo : cart.getPaymentInfos()) { // if (PaymentInfoType.CREDIT_CARD.equals(paymentInfo.getType())) { // billingForm.setAddress(paymentInfo.getAddress()); // } // } // } } @InitBinder protected void initBinder(HttpServletRequest request, ServletRequestDataBinder binder) throws Exception { super.initBinder(request, binder); } @ResponseBody @RequestMapping({ "/checkout/getdormitory", "/app/list-dorms" }) public List<Map<String, Object>> getDormitoryByAreaId( @RequestParam("area_id") Long areaId) { AreaAddress areaAddress = areaService.getAreaById(areaId); if (areaAddress == null) return Collections.emptyList(); return wrapDorms(dormitoryService .listDormitoriesByAreaAddress(areaAddress)); } private List<Map<String, Object>> wrapDorms(List<Dormitory> dorms) { if (dorms == null || dorms.isEmpty()) return Collections.emptyList(); List<Map<String, Object>> ret = new ArrayList<Map<String, Object>>( dorms.size()); for (Dormitory d : dorms) { Map<String, Object> m = new HashMap<String, Object>(3); ret.add(m); m.put("dormitoryId", d.getDormitoryId()); m.put("dormitoryName", d.getDormitoryName()); m.put("displayName", getAbrevStr(d.toString(), 15)); } return ret; } // app //////////////////////////////////////////////////// @ResponseBody @RequestMapping("app/checkout") public Map<String, Object> checkoutApp( HttpServletRequest request, Model model, @ModelAttribute("orderInfoForm") OrderInfoForm orderInfoForm, @ModelAttribute("shippingInfoForm") MyShippingInfoForm shippingForm, @ModelAttribute("billingInfoForm") MyBillingInfoForm billingForm, BindingResult result) { Map<String, Object> ret = new HashMap<String, Object>(); Order cart = CartState.getCart(); if (cart == null || cart instanceof NullOrderImpl) { ret.put("error", "null_order"); ret.put("errorMessage", "您的购物车是空的哦~"); } else { String view = this.saveGlobalOrderDetails(request, model, orderInfoForm, shippingForm, billingForm, result); if (REDIRECT_REGION_SELECT.equals(view)) { ret.put("error", "region_select"); } else { boolean addrSet = shippingForm.getMyAddress().getDormitory() != null; String addressName = addrSet ? shippingForm.getAddressName() : ""; if (addressName == null || addressName.length() == 0) { addressName = getAddressName(shippingForm.getMyAddress(), true); } ret.put("addressName", addressName); ret.put("currencyCode", cart.getCurrency() == null ? null : cart.getCurrency().getCurrencyCode()); ret.put("subtotal", cart.getSubTotal()); ret.put("totalShipping", cart.getTotalShipping()); ret.put("orderAdjustmentsValue", cart.getOrderAdjustmentsValue()); ret.put("total", cart.getTotal()); } } return ret; } @SuppressWarnings("deprecation") @RequestMapping(value = "/app/checkout/singleship") @ResponseBody public Map<String, Object> singleShip(Model model, HttpServletRequest request, HttpServletResponse response, @ModelAttribute("shippingInfoForm") MyShippingInfoForm shippingForm) { Map<String, Object> ret = new HashMap<String, Object>(7); Region region = ((MyCustomer) CustomerState.getCustomer()).getRegion(); ret.put("regionName", region == null ? "" : region.getRegionName()); ret.put("areas", wrapAreas(areaService.listAreasByRegion(region))); prepopulateCheckoutForms(CartState.getCart(), null, shippingForm, null); MyAddress address = shippingForm.getMyAddress(); if (address.getDormitory() == null) return ret; ret.put("addressName", getAddressName(address, false)); ret.put("realName", address.getFirstName()); ret.put("mobile", address.getPrimaryPhone()); ret.put("dormitoryId", address.getDormitory() == null ? "" : address .getDormitory().getDormitoryId()); ret.put("roomNo", address.getRoomNo()); return ret; } private List<Map<String, Object>> wrapAreas(List<AreaAddress> areas) { if (areas == null || areas.isEmpty()) return Collections.emptyList(); List<Map<String, Object>> ret = new ArrayList<Map<String, Object>>( areas.size()); for (AreaAddress a : areas) { Map<String, Object> m = new HashMap<String, Object>(); ret.add(m); m.put("id", a.getAreaId()); m.put("name", a.getAreaName()); } return ret; } @RequestMapping(value = "/app/checkout/singleship/save") @ResponseBody public Map<String, Object> setShipAddress( @ModelAttribute("shippingInfoForm") MyShippingInfoForm shippingForm, BindingResult result) { Map<String, Object> ret = new HashMap<String, Object>(1); Order cart = CartState.getCart(); if (cart == null || cart instanceof NullOrderImpl) { ret.put("error", "null_order"); ret.put("errorMessage", "您的购物车是空的哦~"); return ret; } processShippingForm(shippingForm, result); if (result.hasErrors()) { ret.put("error", "error_address"); ret.put("errorMessage", "地址输入不正确"); return ret; } MyAddress myAddress = shippingForm.getMyAddress(); List<FulfillmentGroup> fgs = cart.getFulfillmentGroups(); if (fgs == null || fgs.isEmpty()) { ret.put("error", "error_no_fg"); return ret; } FulfillmentGroup group = fgs.get(0); group.setAddress(myAddress); try { fulfillmentGroupService.save(group); } catch (DataAccessException e) { ret.put("error", "error_db_access"); return ret; } return ret; } @RequestMapping(value = "/app/checkout/submit") @ResponseBody public Map<String, Object> checkoutSubmitApp(HttpServletRequest request, HttpServletResponse response, Model model, @RequestParam("paymentType") String paymentType) throws Exception { Order cart = CartState.getCart(); OrderInfoForm orderInfoForm = new OrderInfoForm(); MyBillingInfoForm billingForm = new MyBillingInfoForm(); MyShippingInfoForm shippingForm = new MyShippingInfoForm(); // address already saved prepopulateCheckoutForms(cart, orderInfoForm, shippingForm, billingForm); shippingForm.setPaymentMethod(paymentType); shippingForm.setBp_pay(cart.getTotal().getAmount()); String detial = request.getParameter("detial"); shippingForm.getMyAddress().setLastName(detial); /* * TODO app验证用户是否为remember登录,使用余额登陆。 */ Map<String, Object> ret = new HashMap<String, Object>(1); if (shippingForm.getMyAddress().getDormitory() == null) { ret.put("error", "error_address"); ret.put("errorMessage", "地址输入不正确"); return ret; } try { this.saveSingleShip0(request, response, model, orderInfoForm, billingForm, shippingForm, new BeanPropertyBindingResult( shippingForm, ""), true); ret.put("orderNum", cart.getOrderNumber()); ret.put("itemCount", cart.getItemCount()); ret.put("totalShipping", cart.getTotalFulfillmentCharges()); ret.put("total", cart.getTotal()); // TODO 改掉 List<PaymentInfo> paymentInfos = cart.getPaymentInfos(); if (paymentInfos != null && paymentInfos.size() > 0) { PaymentInfoType payType = paymentInfos.get(0).getType(); ret.put("payType", payType.getFriendlyType()); } } catch (CheckoutException e) { LOG.error("", e); ret.put("error", "error_checkout"); if (e.getCause() instanceof InventoryUnavailableException) { ret.put("errorMessage", "抱歉,东西被抢光了,下次出手要快哦"); } else if (e.getCause() instanceof InsufficientFundsException) { ret.put("errorMessage", "抱歉,你余额不足哈"); } else ret.put("errorMessage", "抱歉,提交订单失败"); } catch (PricingException e) { LOG.error("", e); ret.put("error", "error_price"); ret.put("errorMessage", "抱歉,提交订单失败"); } catch (ServiceException e) { LOG.error("", e); ret.put("error", "error_service"); ret.put("errorMessage", "抱歉,提交订单失败"); } return ret; } private String getAddressName(MyAddress address, boolean withRoomNo) { if (address.getDormitory() == null) return ""; String s = withRoomNo ? address.toString() : address.getDormitory() .toString(); return getAbrevStr(s, 15); } private String getAbrevStr(String s, int len) { if (s != null && s.length() > len) { s = s.substring(0, 5) + " ... " + s.substring(s.length() - 7); } return s; } public Boolean executeExpression(String expression, Map<String, Object> vars) { try { Serializable exp; synchronized (EXPRESSION_CACHE) { exp = (Serializable) EXPRESSION_CACHE.get(expression); if (exp == null) { ParserContext context = new ParserContext(); context.addImport("OfferType", OfferType.class); context.addImport("FulfillmentType", FulfillmentType.class); context.addImport("MVEL", MVEL.class); context.addImport("MvelHelper", MvelHelper.class); // StringBuffer completeExpression = new // StringBuffer(functions.toString()); // completeExpression.append(" ").append(expression); exp = MVEL.compileExpression(expression, context); EXPRESSION_CACHE.put(expression, exp); } } Object test = MVEL.executeExpression(exp, vars); return (Boolean) test; } catch (Exception e) { // Unable to execute the MVEL expression for some reason // Return false, but notify about the bad expression through logs LOG.warn( "Unable to parse and/or execute an mvel expression. Reporting to the logs and returning false " + "for the match expression:" + expression, e); return false; } } List<Long> ids = Arrays.asList(-1263L, 701L, 703L, 702L, -12111L, -109862L, -1091L, 663L, 664L, 665L, 661L, -12150L, -109780L); public boolean ifCanAdd(List<Order> orders) { int count = 0; boolean cotain = false; Iterator<Order> itro = orders.iterator(); while (itro.hasNext()) { Order eg = (Order) itro.next(); List<OrderItem> orderitems = eg.getOrderItems(); for (OrderItem item : orderitems) { if (!(item instanceof SkuAccessor)) continue; if (ids.contains(((SkuAccessor) item).getSku().getId())) { count++; // break; return true; } } } if (count >= 1) cotain = true; return cotain; } @RequestMapping(value = "/weixin/checkout") public String weixinSaveGlobalOrderDetails( HttpServletRequest request, Model model, @ModelAttribute("orderInfoForm") OrderInfoForm orderInfoForm, @ModelAttribute("shippingInfoForm") MyShippingInfoForm shippingForm, @ModelAttribute("billingInfoForm") MyBillingInfoForm billingForm, BindingResult result) { MyCustomer myCustomer = (MyCustomer) CustomerState.getCustomer(); Region region = myCustomer.getRegion(); if (region == null) { return "redirect:/weixin/region"; } SimpleDateFormat dateformat1 = new SimpleDateFormat("HH:mm"); String date = dateformat1.format(new Date()); String[] times = region.getShipping_time().split(";"); boolean isOutDeliveryDateRange = true; for (String time : times) { String[] shipping_time = time.split("-"); if ((date.compareTo(shipping_time[0]) > 0) && (date.compareTo(shipping_time[1]) < 0)) isOutDeliveryDateRange = false; } model.addAttribute("isOutDeliveryDateRange", isOutDeliveryDateRange); prepopulateCheckoutForms(CartState.getCart(), orderInfoForm, shippingForm, billingForm); super.saveGlobalOrderDetails(request, model, orderInfoForm, result); return "weixin/cart/w_checkout"; } @RequestMapping(value = "/weixin/checkout/singleship", method = RequestMethod.POST) public String weixinSaveSingleShip( HttpServletRequest request, HttpServletResponse response, Model model, @ModelAttribute("orderInfoForm") OrderInfoForm orderInfoForm, @ModelAttribute("billingInfoForm") MyBillingInfoForm billingForm, @ModelAttribute("shippingInfoForm") MyShippingInfoForm shippingForm, BindingResult result) throws Exception { return saveSingleShip0(request, response, model, orderInfoForm, billingForm, shippingForm, result, false); } }