package org.xmx0632.deliciousfruit.service; import java.math.BigDecimal; import java.util.ArrayList; import java.util.Date; import java.util.List; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.xmx0632.deliciousfruit.api.v1.bo.OrderRequest; import org.xmx0632.deliciousfruit.api.v1.bo.OrderRequest.OrderItem; import org.xmx0632.deliciousfruit.api.v1.bo.OrderRequest.OrderRequestReceiver; import org.xmx0632.deliciousfruit.api.v1.bo.OrderRequest.Payment.DeliveryPeriod; import org.xmx0632.deliciousfruit.api.v1.bo.OrderResponse; import org.xmx0632.deliciousfruit.api.v1.bo.OrderResponse.DeductionPay; import org.xmx0632.deliciousfruit.api.v1.bo.OrderResponse.PayByCashCoupon; import org.xmx0632.deliciousfruit.api.v1.bo.OrderResponse.PayByEcoupon; import org.xmx0632.deliciousfruit.api.v1.bo.OrderResponse.PayByGiftCard; import org.xmx0632.deliciousfruit.api.v1.bo.Result; import org.xmx0632.deliciousfruit.api.v1.bo.SettlementRequest; import org.xmx0632.deliciousfruit.api.v1.bo.SettlementRequest.ShoppingItem; import org.xmx0632.deliciousfruit.api.v1.bo.SettlementResponse; import org.xmx0632.deliciousfruit.api.v1.bo.SettlementResponse.ProductFreeInfo; import org.xmx0632.deliciousfruit.api.v1.bo.SettlementResponse.PromotionDetails; import org.xmx0632.deliciousfruit.api.v1.bo.SettlementResponse.PromotionInfo; import org.xmx0632.deliciousfruit.entity.Order; import org.xmx0632.deliciousfruit.entity.OrderGiveEcoupon; import org.xmx0632.deliciousfruit.entity.OrderPayByCashCoupon; import org.xmx0632.deliciousfruit.entity.OrderPayByEcoupon; import org.xmx0632.deliciousfruit.entity.OrderPayByGiftCard; import org.xmx0632.deliciousfruit.entity.OrderProduct; import org.xmx0632.deliciousfruit.entity.OrderProductFree; import org.xmx0632.deliciousfruit.entity.ReceiverInfo; import org.xmx0632.deliciousfruit.entity.UserAccount; import org.xmx0632.deliciousfruit.erp.bo.DeductionMessage; import com.google.common.collect.Lists; /** * 与客户端IOS的结算逻辑,客户端确定购买加入购物车的商品后,发送消息到ERP,扣除相关帐户余额/积分/现金券等信息 * * @author xmx0632 * */ @Component public class IosPayoffService { private static Logger log = LoggerFactory.getLogger(IosPayoffService.class); @Autowired private IosOrderService iosOrderService; @Autowired private ReceiverInfoService receiverInfoService; @Autowired private DeductionPayService deductionPayService; @Autowired private OrderService orderService; public OrderResponse process(OrderRequest orderRequest, UserAccount userAccount) { log.debug("userAccount:{} orderRequest:{}", userAccount, orderRequest); String transactionID = orderRequest.getTransactionID(); OrderResponse response = new OrderResponse(); response.setTransactionID(transactionID); OrderRequestReceiver receiverInfo = orderRequest.getReceiverInfo(); log.debug("receiverInfo:{}", receiverInfo); if (receiverInfo == null) { log.error("receiverInfo:{}", receiverInfo); response.setResult(new Result(Result.FAIL, "no receiverInfo")); log.debug("response:{}", response); return response; } // 检查收货地址是否有变化,如果变化更新到数据库中 createOrUpdateReceiverInfoIfNecessary(receiverInfo); // 按照促销规则计算商品价格 SettlementRequest settlementRequest = getSettlementRequest(orderRequest); SettlementResponse settlementResponse = iosOrderService .caculatePromotionInfo(settlementRequest); log.debug("settlementResponse:{}", settlementResponse); BigDecimal actualAmount = settlementResponse.getActualAmount(); PromotionInfo promotionInfo = settlementResponse.getPromotionInfo(); BigDecimal totalPrice = settlementResponse.getTotalPrice(); log.debug( "actualAmount:{}\npromotionInfo:{}\ntotalPrice:{}\ntransactionID:{}", actualAmount, promotionInfo, totalPrice, transactionID); DeductionMessage deductionMessage = null; try { // 到ERP查询抵扣(各种)付款 DeductionPay deductionPay = deductionPayService.getDeductionPay( orderRequest, "customerId"); response.setDeductionPay(deductionPay); deductionMessage = deductionPay.getDeductionMessage(); // 发送抵扣消息到ERP deductionPayService.sendDeductionPayMessage(deductionMessage); // TODO 发送订单消息到ERP,订单号(ERPID),从ERP响应消息中获得 String orderNumber = "ORDER10000001"; response.setOrderNumber(orderNumber); response.setFreight(settlementResponse.getFreight());// 运费 response.setFreightPay(settlementResponse.getFreightPay()); // 实际运费 response.setPayAmount(settlementResponse.getActualAmount());// 实际支付=商品价格+实际运费 response.setPaymentMethod(orderRequest.getPayment() .getPaymentMethod()); PromotionDetails promotionDetails = getPromotionDetails(settlementResponse); response.setPromotionDetails(promotionDetails); response.setTotalPrice(totalPrice); response.setResult(Result.SUCCESS_RESULT); // TODO saveOrder saveOrder(orderRequest, response, userAccount); return response; } catch (Exception e) { // 回滚抵扣消息 if (deductionMessage != null) { deductionPayService .rollbackDeductionPayMessage(deductionMessage); } log.error("deductionPay error:{}", e.getMessage(), e); response.setResult(new Result(Result.FAIL, e.getMessage())); log.debug("response:{}", response); return response; } } private void saveOrder(OrderRequest request, OrderResponse response, UserAccount userAccount) { Date orderTime = new Date(); Order order = new Order(); // TODO 账户余额?不记录 BigDecimal accountBalance = BigDecimal.ZERO; order.setAccountBalance(accountBalance); DeliveryPeriod deliveryPeriod = request.getDeliveryPeriod(); order.setDeliveryDatePeriod(deliveryPeriod.getDatePeriod()); order.setDeliveryTimePeriod(deliveryPeriod.getTimePeriod()); order.setFreight(response.getFreight()); order.setFreightPay(response.getFreightPay()); // TODO giveEcoupon 赠送电子券?没有 List<OrderGiveEcoupon> giveEcoupon = null; order.setGiveEcoupon(giveEcoupon); order.setGivePoint(response.getGivePoint()); order.setOrderNumber(response.getOrderNumber()); order.setOrderTime(orderTime); order.setPayAmount(response.getPayAmount()); DeductionPay deductionPay = response.getDeductionPay(); List<OrderPayByCashCoupon> payByCashCoupons = getPayByCashCoupons( order, deductionPay); order.setPayByCashCoupon(payByCashCoupons); List<OrderPayByEcoupon> payByEcoupons = getPayByEcoupons(order, deductionPay); order.setPayByEcoupon(payByEcoupons); List<OrderPayByGiftCard> payByGiftCards = getPayByGiftCards(order, deductionPay); order.setPayByGiftCard(payByGiftCards); order.setPayByPoint(deductionPay.getPayByPoint()); order.setPayFromAccount(deductionPay.getPayFromAccount()); order.setPaymentMethod(response.getPaymentMethod()); // TODO pointLeft,不记录 Integer pointLeft = 0; order.setPointLeft(pointLeft); PromotionDetails promotionDetails = response.getPromotionDetails(); order.setPriceOff(promotionDetails.getPriceOff()); // productList 订购产品列表 List<OrderItem> orderList = request.getOrderList(); for (OrderItem orderItem : orderList) { OrderProduct orderProduct = new OrderProduct(order, orderItem.getProductId()); order.getProductList().add(orderProduct); } List<OrderProductFree> productsFreeList = getProductsFreeList(order, promotionDetails); order.setProductsFree(productsFreeList); OrderRequestReceiver receiverInfo = request.getReceiverInfo(); order.setReceiverAddress(receiverInfo.getAddress()); order.setReceiverCity(receiverInfo.getCity()); order.setReceiverDistrict(receiverInfo.getDistrict()); order.setReceiverName(receiverInfo.getName()); order.setReceiverPhoneNumber(receiverInfo.getPhoneNumber()); order.setReceiverProvince(receiverInfo.getProvince()); order.setTotalPrice(response.getTotalPrice()); // TODO order.setUserAccount(userAccount); orderService.saveOrder(order); } private List<OrderProductFree> getProductsFreeList(Order order, PromotionDetails promotionDetails) { List<OrderProductFree> productsFreeList = Lists.newArrayList(); List<ProductFreeInfo> productsFrees = promotionDetails .getProductsFree(); for (ProductFreeInfo productFreeInfo : productsFrees) { OrderProductFree e = new OrderProductFree(order, productFreeInfo.getProductName(), productFreeInfo.getQuantity()); e.setSpec(productFreeInfo.getSpec()); e.setUnit(productFreeInfo.getUnit()); productsFreeList.add(e); } return productsFreeList; } private List<OrderPayByGiftCard> getPayByGiftCards(Order order, DeductionPay deductionPay) { List<OrderPayByGiftCard> payByGiftCards = Lists.newArrayList(); List<PayByGiftCard> payByGiftCardInfo = deductionPay .getPayByGiftCardInfo(); for (PayByGiftCard payByGiftCard : payByGiftCardInfo) { // TODO save OrderPayByGiftCard OrderPayByGiftCard e = new OrderPayByGiftCard(order, payByGiftCard.getId()); e.setBalance(payByGiftCard.getBalance()); e.setDeductionAmount(payByGiftCard.getDeductionAmount()); payByGiftCards.add(e); } return payByGiftCards; } private List<OrderPayByEcoupon> getPayByEcoupons(Order order, DeductionPay deductionPay) { List<OrderPayByEcoupon> payByEcoupons = Lists.newArrayList(); List<PayByEcoupon> payByEcouponInfo = deductionPay .getPayByEcouponInfo(); for (PayByEcoupon payByEcoupon : payByEcouponInfo) { // TODO save payByEcoupon OrderPayByEcoupon e = new OrderPayByEcoupon(order, payByEcoupon.getId()); e.setAmount(payByEcoupon.getAmount()); payByEcoupons.add(e); } return payByEcoupons; } private List<OrderPayByCashCoupon> getPayByCashCoupons(Order order, DeductionPay deductionPay) { List<PayByCashCoupon> payByCashCouponInfo = deductionPay .getPayByCashCouponInfo(); List<OrderPayByCashCoupon> payByCashCoupons = Lists.newArrayList(); for (PayByCashCoupon payByCashCoupon : payByCashCouponInfo) { // TODO save payByCashCoupon OrderPayByCashCoupon e = new OrderPayByCashCoupon(order, payByCashCoupon.getId()); e.setDeductionAmount(payByCashCoupon.getDeductionAmount()); e.setPayLeftTimes(payByCashCoupon.getPayLeftTimes()); payByCashCoupons.add(e); } return payByCashCoupons; } private void createOrUpdateReceiverInfoIfNecessary( OrderRequestReceiver receiverInfo) { ReceiverInfo ri = null; if (receiverInfo.getId() == null) { ri = new ReceiverInfo(); ri.setAddress(receiverInfo.getAddress()); ri.setReceiver(receiverInfo.getName()); ri.setTelephone(receiverInfo.getPhoneNumber()); ri.setMobile(receiverInfo.getPhoneNumber()); ri.setProvince(receiverInfo.getProvince()); ri.setCity(receiverInfo.getCity()); ri.setDistrict(receiverInfo.getDistrict()); receiverInfoService.saveReceiverInfo(ri); } else { ri = receiverInfoService.getReceiverInfo(receiverInfo.getId()); if (ri == null) { log.error("can not find ReceiverInfo with id:{}", receiverInfo.getId()); return; } if (isChanged(receiverInfo, ri)) { ri.setAddress(receiverInfo.getAddress()); ri.setReceiver(receiverInfo.getName()); ri.setTelephone(receiverInfo.getPhoneNumber()); ri.setMobile(receiverInfo.getPhoneNumber()); ri.setProvince(receiverInfo.getProvince()); ri.setCity(receiverInfo.getCity()); ri.setDistrict(receiverInfo.getDistrict()); receiverInfoService.saveReceiverInfo(ri); } } } private boolean isChanged(OrderRequestReceiver receiverInfo, ReceiverInfo ri) { if (ri.getAddress().equals(receiverInfo.getAddress()) && ri.getReceiver().equals(receiverInfo.getName()) && ri.getTelephone().equals(receiverInfo.getPhoneNumber()) && ri.getMobile().equals(receiverInfo.getPhoneNumber()) && ri.getProvince().equals(receiverInfo.getProvince()) && ri.getCity().equals(receiverInfo.getCity()) && ri.getDistrict().equals(receiverInfo.getDistrict())) { return true; } return false; } private SettlementRequest getSettlementRequest(OrderRequest orderRequest) { SettlementRequest settlementRequest = new SettlementRequest(); List<ShoppingItem> shoppingList = getShoppingList(orderRequest); settlementRequest.setShoppingList(shoppingList); settlementRequest.setTransactionID(orderRequest.getTransactionID()); return settlementRequest; } private List<ShoppingItem> getShoppingList(OrderRequest orderRequest) { List<ShoppingItem> shoppingList = new ArrayList<ShoppingItem>(); List<OrderItem> orderList = orderRequest.getOrderList(); for (OrderItem orderItem : orderList) { shoppingList.add(new ShoppingItem(orderItem.getProductId(), orderItem.getQuantity())); } return shoppingList; } // 合并totalPromotion和productPromotion private PromotionDetails getPromotionDetails( SettlementResponse settlementResponse) { PromotionInfo promotionInfo = settlementResponse.getPromotionInfo(); PromotionDetails productPromotion = promotionInfo .getPromotionForProduct(); PromotionDetails totalPromotion = promotionInfo.getPromotionForTotal(); PromotionDetails promotionDetails = new PromotionDetails(); promotionDetails.addPriceOff(productPromotion.getPriceOff()); promotionDetails.addPriceOff(totalPromotion.getPriceOff()); promotionDetails .addProductsFreeList(productPromotion.getProductsFree()); promotionDetails.addProductsFreeList(totalPromotion.getProductsFree()); return promotionDetails; } }