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;
}
}