|
|
package com.yohoufo.order.service.impl.processor;
|
|
|
|
|
|
import com.google.common.base.Splitter;
|
|
|
import com.yohobuy.ufo.model.order.common.OrderStatus;
|
|
|
import com.yohobuy.ufo.model.order.common.SkupStatus;
|
|
|
import com.yohobuy.ufo.model.order.req.BatchChangePriceReq;
|
|
|
import com.yohoufo.common.exception.GatewayException;
|
|
|
import com.yohoufo.common.exception.UfoServiceException;
|
|
|
import com.yohoufo.common.utils.BigDecimalHelper;
|
|
|
import com.yohoufo.dal.order.BuyerOrderGoodsMapper;
|
|
|
import com.yohoufo.dal.order.BuyerOrderMapper;
|
|
|
import com.yohoufo.dal.order.SellerOrderGoodsMapper;
|
|
|
import com.yohoufo.dal.order.SellerOrderMapper;
|
|
|
import com.yohoufo.dal.order.model.BuyerOrder;
|
|
|
import com.yohoufo.dal.order.model.BuyerOrderGoods;
|
|
|
import com.yohoufo.dal.order.model.SellerOrder;
|
|
|
import com.yohoufo.dal.order.model.SellerOrderGoods;
|
|
|
import com.yohoufo.order.model.dto.ChangePricePrepareDTO;
|
|
|
import com.yohoufo.order.model.dto.SellerOrderComputeResult;
|
|
|
import com.yohoufo.order.model.dto.SkupDto;
|
|
|
import com.yohoufo.order.service.handler.SellerOrderComputeHandler;
|
|
|
import com.yohoufo.order.service.impl.SellerService;
|
|
|
import com.yohoufo.order.service.proxy.ProductProxyService;
|
|
|
import com.yohoufo.order.utils.LoggerUtils;
|
|
|
import org.apache.commons.collections.CollectionUtils;
|
|
|
import org.apache.commons.lang3.StringUtils;
|
|
|
import org.slf4j.Logger;
|
|
|
import org.slf4j.LoggerFactory;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
import org.springframework.util.Assert;
|
|
|
|
|
|
import java.math.BigDecimal;
|
|
|
import java.util.*;
|
|
|
import java.util.Arrays;
|
|
|
import java.util.HashMap;
|
|
|
import java.util.List;
|
|
|
import java.util.Map;
|
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
/**
|
|
|
* Created by chao.chen on 2018/11/21.
|
|
|
* 根据批次号来调价
|
|
|
*/
|
|
|
@Service
|
|
|
public class ChangePricePrepareProcessor {
|
|
|
|
|
|
private final Logger logger = LoggerUtils.getSellerOrderLogger();
|
|
|
|
|
|
@Autowired
|
|
|
private BuyerOrderGoodsMapper buyerOrderGoodsMapper;
|
|
|
|
|
|
@Autowired
|
|
|
private BuyerOrderMapper buyerOrderMapper;
|
|
|
|
|
|
@Autowired
|
|
|
private SellerOrderMapper sellerOrderMapper;
|
|
|
public class ChangePricePrepareProcessor extends AbstractChangePricePrepareProcessor<BatchChangePriceReq> {
|
|
|
|
|
|
@Autowired
|
|
|
private SellerOrderGoodsMapper sellerOrderGoodsMapper;
|
|
|
|
|
|
@Autowired
|
|
|
private SellerOrderPrepareProcessor sellerOrderPrepareProcessor;
|
|
|
|
|
|
@Autowired
|
|
|
private SellerOrderComputeHandler computeHandler;
|
|
|
|
|
|
@Autowired
|
|
|
private PriceComputePrepareProcessor priceComputePrepareProcessor;
|
|
|
|
|
|
@Autowired
|
|
|
private SellerService sellerService;
|
|
|
|
|
|
@Override
|
|
|
public ChangePricePrepareDTO checkAndAcquire(BatchChangePriceReq req) throws GatewayException {
|
|
|
int uid = req.getUid();
|
|
|
if (uid <= 0){
|
|
|
logger.warn("ChangePrice checkAndAcquire uid illegal , req {}", req);
|
|
|
throw new UfoServiceException(400, "参数[uid]错误");
|
|
|
}
|
|
|
|
|
|
if(!sellerOrderPrepareProcessor.checkIsEntry(uid)){
|
|
|
logger.warn("ChangePrice checkAndAcquire uid is not entry shop , req {}", req);
|
|
|
throw new UfoServiceException(400, "您不是入驻商家");
|
|
|
}
|
|
|
String skupList = req.getSkupList();
|
|
|
if (StringUtils.isBlank(skupList)){
|
|
|
if (StringUtils.isBlank(skupList)) {
|
|
|
logger.warn("ChangePrice checkAndAcquire uid illegal , req {}", req);
|
|
|
throw new UfoServiceException(400, "参数[skupList]为空");
|
|
|
}
|
|
|
//考虑到并发,需要进行过滤,将不是出售中状态的skup排除掉;
|
|
|
//不做过滤导致后面的数量 扣费检查都可能不对
|
|
|
List<String> skupStrList = Splitter.on(',').trimResults().omitEmptyStrings().splitToList(skupList);
|
|
|
List<Integer> needChangePriceSkupList = skupStrList.parallelStream().map(Integer::valueOf).collect(Collectors.toList());
|
|
|
//check batch no
|
|
|
Long batchNo = checkNAcquireBatchNo(req.getBatchNo(), req);
|
|
|
|
|
|
BigDecimal salePrice = priceComputePrepareProcessor.checkAndAcquireSalePrice(req.getPrice());
|
|
|
|
|
|
//检查是否有买家下单,返回的是可售 待买家付款的skup
|
|
|
Map<Integer, SkupDto> skupOfSalingMap = checkExistWaitingBuyerPay(batchNo, req);
|
|
|
//若needChangePriceSkupList中有skup出现不存在于skupOfSalingMap keys中,说明该skup走到了其他状态中
|
|
|
Map<Integer, SkupDto> skupMap = checkNeedProcessSkups(needChangePriceSkupList,skupOfSalingMap);
|
|
|
//
|
|
|
SkupDto sampleSkupDto = skupMap.values().iterator().next();
|
|
|
int sampleSkup = sampleSkupDto.getSkup();
|
|
|
SellerOrderGoods sampleSog = sampleSkupDto.getSellerOrderGoods();
|
|
|
BigDecimal preSalePrice = sampleSog.getGoodsPrice();
|
|
|
if (preSalePrice.compareTo(salePrice) == 0){
|
|
|
throw new UfoServiceException(401, "前后价格没有变化");
|
|
|
}
|
|
|
return super.checkAndAcquire(req);
|
|
|
}
|
|
|
|
|
|
SellerOrder sellerOrder = sellerOrderMapper.selectBySkup(sampleSkup);
|
|
|
BigDecimal sourceEM = sellerOrder.getEarnestMoney();
|
|
|
int storageId = sampleSog.getStorageId();
|
|
|
|
|
|
String tips = null;
|
|
|
ProductProxyService.PrdPrice prdPrice;
|
|
|
prdPrice = sellerOrderPrepareProcessor.checkPrice(storageId, salePrice, req.isShowPriceError());
|
|
|
try {
|
|
|
sellerOrderPrepareProcessor.checkSuggestPrice(prdPrice, salePrice);
|
|
|
}catch (UfoServiceException ex){
|
|
|
tips = ex.getErrorMessage();
|
|
|
}
|
|
|
// compute every fee from price
|
|
|
SellerOrderComputeResult computeResult = computeHandler.compute(salePrice);
|
|
|
int num = skupMap.size();
|
|
|
//作为入驻商户 检查钱包
|
|
|
BigDecimal targetEM = computeResult.getEarnestMoney().getEarnestMoney();
|
|
|
BigDecimal diffEarnestMoney = calDiffOfEM(sourceEM,targetEM);
|
|
|
boolean isSuper = sellerService.isSuperEntrySeller(uid);
|
|
|
if (diffEarnestMoney.compareTo(BigDecimal.ZERO)>0){
|
|
|
sellerOrderPrepareProcessor.checkNGetMergeEarnestMoney(uid, diffEarnestMoney, num, salePrice, isSuper);
|
|
|
}
|
|
|
sellerOrderPrepareProcessor.checkIncome(storageId, computeResult.getIncome());
|
|
|
|
|
|
return ChangePricePrepareDTO.builder()
|
|
|
.baseSellerOrderGoods(sampleSog)
|
|
|
.prdPrice(prdPrice)
|
|
|
.salePrice(salePrice)
|
|
|
.diffEarnestMoney(diffEarnestMoney)
|
|
|
.skupMap(skupMap)
|
|
|
.computeResult(computeResult)
|
|
|
.preEarnestMoney(sourceEM)
|
|
|
.preSalePrice(preSalePrice)
|
|
|
.tips(tips).isSuper(isSuper)
|
|
|
.build();
|
|
|
@Override
|
|
|
protected List<Integer> getExpectedSkups(BatchChangePriceReq req) {
|
|
|
List<String> skupStrList = Splitter.on(',').trimResults().omitEmptyStrings().splitToList(req.getSkupList());
|
|
|
return skupStrList.parallelStream().map(Integer::valueOf).collect(Collectors.toList());
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
protected List<SellerOrderGoods> getRealSkupOrderGoodsList(BatchChangePriceReq req) {
|
|
|
Long batchNo = checkNAcquireBatchNo(req.getBatchNo());
|
|
|
SellerOrderGoods condition = new SellerOrderGoods();
|
|
|
condition.setBatchNo(batchNo);
|
|
|
//按照批次,同一个批次不需要有两个价格,需要排除支付中的订单
|
|
|
return sellerOrderGoodsMapper.selectByBatchNo(condition, Arrays.asList(SkupStatus.CAN_SELL.getCode(), SkupStatus.SELL_OUT.getCode()));
|
|
|
}
|
|
|
|
|
|
Map<Integer, SkupDto> checkNeedProcessSkups(List<Integer> needChangePriceSkupList, Map<Integer, SkupDto> skupOfSalingMap){
|
|
|
Map<Integer, SkupDto> map = new HashMap<>(needChangePriceSkupList.size());
|
|
|
@Override
|
|
|
protected Map<Integer, SkupDto> checkNeedProcessSkups(List<Integer> expectedSkups,
|
|
|
BigDecimal oldPrice,
|
|
|
BigDecimal newPrice,
|
|
|
Map<Integer, SkupDto> skupOfSalingMap) {
|
|
|
Assert.notEmpty(expectedSkups,"expectedSkups must not be empty");
|
|
|
Assert.notEmpty(skupOfSalingMap,"skupOfSalingMap must not be empty");
|
|
|
Map<Integer, SkupDto> map = new HashMap<>(expectedSkups.size());
|
|
|
|
|
|
for(Integer skup: needChangePriceSkupList) {
|
|
|
for (Integer skup : expectedSkups) {
|
|
|
|
|
|
if (!skupOfSalingMap.containsKey(skup)) {
|
|
|
logger.warn("ChangePrice checkNeedProcessSkups skup is in other status , skup {}", skup);
|
|
|
throw new UfoServiceException(501, "部分商品不可调价");
|
|
|
}
|
|
|
|
|
|
SellerOrderGoods sellerOrderGoods = skupOfSalingMap.get(skup).getSellerOrderGoods();
|
|
|
|
|
|
//校验价格
|
|
|
if (sellerOrderGoods.getGoodsPrice().compareTo(newPrice) == 0) {
|
|
|
logger.warn("skup:{} goodsPrice:{} and newPrice:{} must not be equals",
|
|
|
skup, sellerOrderGoods.getGoodsPrice(), newPrice);
|
|
|
throw new UfoServiceException(401, "前后价格没有变化");
|
|
|
}
|
|
|
|
|
|
map.put(skup, skupOfSalingMap.get(skup));
|
|
|
}
|
|
|
|
|
|
|
|
|
return map;
|
|
|
}
|
|
|
|
|
|
private BigDecimal calDiffOfEM(BigDecimal sourceEM, BigDecimal targetEM){
|
|
|
return targetEM.subtract(sourceEM);
|
|
|
}
|
|
|
|
|
|
private Long checkNAcquireBatchNo(String batchNoStr, BatchChangePriceReq req){
|
|
|
private Long checkNAcquireBatchNo(String batchNoStr) {
|
|
|
Long batchNo = null;
|
|
|
boolean isIllegalBatchNo;
|
|
|
try {
|
|
|
isIllegalBatchNo = (StringUtils.isBlank(batchNoStr) || (batchNo = Long.valueOf(batchNoStr)) <= 0L);
|
|
|
|
|
|
}catch (Exception ex){
|
|
|
} catch (Exception ex) {
|
|
|
isIllegalBatchNo = true;
|
|
|
logger.warn("ChangePrice checkAndAcquire batchNoStr illegal , req {}", req, ex);
|
|
|
logger.warn("ChangePrice checkAndAcquire batchNoStr illegal , batchNoStr {}", batchNoStr, ex);
|
|
|
}
|
|
|
|
|
|
if (isIllegalBatchNo){
|
|
|
if (isIllegalBatchNo) {
|
|
|
throw new UfoServiceException(400, "参数[batchNoStr]非法");
|
|
|
}
|
|
|
return batchNo;
|
|
|
}
|
|
|
|
|
|
private Map<Integer, SkupDto> checkExistWaitingBuyerPay(long batchNo, BatchChangePriceReq req){
|
|
|
SellerOrderGoods condition = new SellerOrderGoods();
|
|
|
condition.setBatchNo(batchNo);
|
|
|
List<SellerOrderGoods> sellerOrderGoodList = sellerOrderGoodsMapper.selectByBatchNo(condition, Arrays.asList(SkupStatus.CAN_SELL.getCode(), SkupStatus.SELL_OUT.getCode()));
|
|
|
if (CollectionUtils.isEmpty(sellerOrderGoodList)){
|
|
|
logger.warn("ChangePrice checkAndAcquire not find skups by batchNo, req {}", req);
|
|
|
throw new UfoServiceException(501, "商品不能变价");
|
|
|
}
|
|
|
List<Integer> skups = sellerOrderGoodList.parallelStream().map(SellerOrderGoods::getId).collect(Collectors.toList());
|
|
|
logger.info("batch change price checkExistWaitingBuyerPay req {} skups {}", req, skups);
|
|
|
List<BuyerOrderGoods> buyerOrderGoodsList = buyerOrderGoodsMapper.selectBySkups(skups);
|
|
|
List<BuyerOrder> buyerOrderList = null;
|
|
|
if (CollectionUtils.isNotEmpty(buyerOrderGoodsList)){
|
|
|
List<Long> orderCodeList = buyerOrderGoodsList.parallelStream()
|
|
|
.map(BuyerOrderGoods::getOrderCode).collect(Collectors.toList());
|
|
|
buyerOrderList = buyerOrderMapper.selectByOrderCodes(orderCodeList, Arrays.asList(OrderStatus.WAITING_PAY.getCode()));
|
|
|
}
|
|
|
if (CollectionUtils.isNotEmpty(buyerOrderList)){
|
|
|
List<Long> waitingPayOrderCodes = buyerOrderList.parallelStream().map(BuyerOrder::getOrderCode).collect(Collectors.toList());
|
|
|
logger.warn("ChangePrice checkAndAcquire exist waiting pay skup , req {} waitingPayOrderCodes {}", req, waitingPayOrderCodes);
|
|
|
throw new UfoServiceException(400, "部分商品正在等待买家支付");
|
|
|
}
|
|
|
return sellerOrderGoodList.parallelStream().collect(Collectors.toMap(SellerOrderGoods::getId,
|
|
|
(sog)-> SkupDto.builder().skup(sog.getId()).sellerOrderGoods(sog).batchNo(sog.getBatchNo()).build()));
|
|
|
}
|
|
|
|
|
|
|
|
|
} |
...
|
...
|
|