Authored by mali

Merge branch 'test6.9.16' of http://git.yoho.cn/ufo/yohoufo-fore into test6.9.16

... ... @@ -11,6 +11,8 @@ import java.util.List;
*/
@Data
public class SellerOrderComputeResult {
Integer uid;
Integer storageId;
BigDecimal prdPrice;
EarnestMoney earnestMoney;
... ...
... ... @@ -5,7 +5,6 @@ import com.google.common.collect.Lists;
import com.yoho.core.rabbitmq.YhProducer;
import com.yohobuy.ufo.model.order.bo.CustomsClearanceResult;
import com.yohobuy.ufo.model.order.bo.MerchantOrderAttachInfo;
import com.yohobuy.ufo.model.order.common.MetaConfigKey;
import com.yohobuy.ufo.model.order.common.OrderStatus;
import com.yohobuy.ufo.model.order.common.SellerOrderStatus;
import com.yohobuy.ufo.model.order.common.SkupStatus;
... ... @@ -20,7 +19,6 @@ import com.yohoufo.common.alarm.UfoInfluxdbVo;
import com.yohoufo.common.constant.InfluxdbFieldEnum;
import com.yohoufo.common.constant.InfluxdbMeasurementEnum;
import com.yohoufo.common.exception.UfoServiceException;
import com.yohoufo.common.utils.BigDecimalHelper;
import com.yohoufo.common.utils.DateUtil;
import com.yohoufo.dal.order.*;
import com.yohoufo.dal.order.model.*;
... ... @@ -32,7 +30,6 @@ import com.yohoufo.order.constants.ClearanceFailType;
import com.yohoufo.order.constants.MetaKey;
import com.yohoufo.order.event.*;
import com.yohoufo.order.model.PayRefundBo;
import com.yohoufo.order.model.dto.BuyerPenalty;
import com.yohoufo.order.model.dto.BuyerPenaltyCalResult;
import com.yohoufo.order.model.request.PaymentRequest;
import com.yohoufo.order.model.request.TranseferCellNode;
... ... @@ -56,6 +53,7 @@ import lombok.Setter;
import lombok.val;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
... ... @@ -64,7 +62,6 @@ import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
... ... @@ -173,9 +170,10 @@ public class BuyerOrderCancelService {
logger.info("in buyer cancel BeforeSellerDeliver, event {} BuyerPenaltyCalResult {}", bsdEvent, bpcr);
//买家实付金额(货款+运费)小于赔偿金的额度,不够赔偿的,则不允许取消
BigDecimal penaltyAmount;
if(bsdEvent.getAmount()==null||bsdEvent.getAmount().compareTo(penaltyAmount=bpcr.getPenaltyAmount()) < 0){
Pair<Boolean,UfoServiceException> penaltyAmountIsEnough = checkPenaltyAmount(bsdEvent.getAmount(), penaltyAmount=bpcr.getPenaltyAmount());
if(!penaltyAmountIsEnough.getLeft()){
logger.warn("in buyer cancel BeforeSellerDeliver not allow cancel cause of buyer amount lower than BuyerCompensateMoney, event {} compensate {}", bsdEvent, bpcr);
throw new com.yohoufo.common.exception.UfoServiceException(400,"买家赔偿金低于商品售价,不允许取消");
throw penaltyAmountIsEnough.getRight();
}
... ... @@ -301,6 +299,14 @@ public class BuyerOrderCancelService {
.cancel();
}
private Pair<Boolean,UfoServiceException> checkPenaltyAmount(BigDecimal actualPaidAmount, BigDecimal penaltyAmount){
boolean isEnough = (actualPaidAmount !=null && actualPaidAmount.compareTo(penaltyAmount) >= 0);
UfoServiceException ex = null;
if(!isEnough){
ex = new com.yohoufo.common.exception.UfoServiceException(400,"实付金额低于订单违约金,不允许取消");
}
return Pair.of(isEnough, ex);
}
public void cancel(BeforeDepotReceiveEvent bdrEvent){
int buyerUid = bdrEvent.getBuyerUid();
... ... @@ -315,12 +321,12 @@ public class BuyerOrderCancelService {
logger.info("in buyer cancel BeforeDepotReceive, event {} compensate {}", bdrEvent, bpcr);
//买家实付金额(货款+运费)小于赔偿金的额度,不够赔偿的,则不允许取消
BigDecimal penaltyAmount;
if(bdrEvent.getAmount()==null||bdrEvent.getAmount().compareTo(penaltyAmount=bpcr.getPenaltyAmount()) < 0){
Pair<Boolean,UfoServiceException> amountIsEnough = checkPenaltyAmount(bdrEvent.getAmount(), penaltyAmount=bpcr.getPenaltyAmount());
if(!amountIsEnough.getLeft()){
logger.warn("in buyer cancel BeforeDepotReceive not allow cancel cause of buyer amount lower than BuyerCompensateMoney, event {} compensate {}", bdrEvent, bpcr);
throw new com.yohoufo.common.exception.UfoServiceException(400,"买家赔偿金低于商品售价,不允许取消");
throw amountIsEnough.getRight();
}
OrderStatus expected = bdrEvent.getExpected();
int currentTime = DateUtil.getCurrentTimeSecond();
int rows = buyerOrderMapper.updateStatusByOrderCode(orderCode, buyerUid, expected.getCode(), targetOrderStatus.getCode(), currentTime);
... ...
... ... @@ -131,7 +131,7 @@ public class SellerBidPublishService {
.storageId(storageId).prdPrice(saleableBidSkup.getPrice()).build();
priceComputePrepareProcessor.checkPulishAuthNPriceRange(pqr, true);
SellerOrderComputeResult pcc = getSellerBidGoodsFeeRate(uid, skupType);
SellerOrderComputeResult pcc = getSellerBidGoodsFeeRate(uid, storageId, skupType);
OrderComputeHandler computeHandler = orderComputeProvider.findBySkupType(skupType);
SellerOrderComputeResult computeResult = computeHandler.compute(saleableBidSkup.getPrice(), pcc);
... ... @@ -227,13 +227,15 @@ public class SellerBidPublishService {
return Pair.of(noHiddenBackAddress, hiddenBackAddress);
}
public SellerOrderComputeResult getSellerBidGoodsFeeRate(int uid, SkupType skupType) {
public SellerOrderComputeResult getSellerBidGoodsFeeRate(int uid, int storageId, SkupType skupType) {
logger.info("in getSellerBidGoodsFeeRate uid {}, skupType {}",
uid, skupType);
ServiceFeeRate rate = getSellerBidGoodsFeeRate(skupType);
List<ServiceFeeRate> allConfig = Lists.newArrayList(rate);
SellerOrderComputeResult socr = new SellerOrderComputeResult();
socr.setServiceFeeRates(allConfig);
socr.setUid(uid);
socr.setStorageId(storageId);
return socr;
}
... ...
... ... @@ -5,8 +5,6 @@ import com.yohoufo.common.utils.BigDecimalHelper;
import com.yohoufo.order.model.dto.*;
import com.yohoufo.order.service.impl.MetaConfigService;
import com.yohoufo.order.service.impl.OrderDynamicConfig;
import com.yohoufo.order.service.seller.fee.GoodsServiceFeeRateDimension;
import com.yohoufo.order.service.seller.fee.GoodsServiceFeeRateWrapper;
import com.yohoufo.order.utils.LoggerUtils;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.tuple.Pair;
... ... @@ -50,21 +48,23 @@ public abstract class AbsSellerOrderComputeHandler implements OrderComputeHandle
@Override
public SellerOrderComputeResult compute(BigDecimal prdPrice,
SellerOrderComputeResult personalComputeConfig){
final boolean personalComputeConfigExist;
Integer uid = (personalComputeConfigExist= Objects.nonNull(personalComputeConfig)) ? personalComputeConfig.getUid() : null;
Integer storageId = personalComputeConfigExist ? personalComputeConfig.getStorageId() : null;
//计算保证金(28-200(按照卖家发布商品的货款金额5%计算,最低28,封顶200))
EarnestMoney earnestMoney = calEarnestMoney(prdPrice);
//init fee rate
List<ServiceFeeRate> psfr = personalComputeConfig!=null ? personalComputeConfig.getServiceFeeRates() : null;
List<ServiceFeeRate> psfr = personalComputeConfigExist ? personalComputeConfig.getServiceFeeRates() : null;
//目前根据商品类型匹配费率,未来的趋势是有多维度配置,根据策略择优
PlatformFeeDto ppf = personalComputeConfig!=null ? personalComputeConfig.getPlatformFee() : null;
PlatformFeeDto ppf = personalComputeConfigExist ? personalComputeConfig.getPlatformFee() : null;
//计算平台费用:1.鉴定费 2.包装费 3.货款抽成
Pair<ServiceFeeRate,PlatformFeeDto> calPlatformFee = calPlatformFee(prdPrice, psfr, ppf);
Pair<ServiceFeeRate,PlatformFeeDto> calPlatformFee = calPlatformFee(uid, storageId, prdPrice, psfr, ppf);
ServiceFeeRate serviceFeeRate = calPlatformFee.getLeft();
PlatformFeeDto platformFeeDto = calPlatformFee.getRight();
//计算支付服务费
BigDecimal bankTransferFee = calBankTransferFee(prdPrice, serviceFeeRate.getPayChannelRate());
logger.info("in SellerOrder Compute, prdPrice {}, platformFee {}, bankTransferFee {}",
prdPrice, platformFeeDto, bankTransferFee);
logger.info("in SellerOrder Compute,uid {} storageId {}, prdPrice {}, platformFee {}, bankTransferFee {}",
uid, storageId, prdPrice, platformFeeDto, bankTransferFee);
//计算收入
BigDecimal income = calIncome(prdPrice, platformFeeDto.getTotal(), bankTransferFee);
//目前只有预售有买家和卖家阶梯处罚
... ... @@ -151,7 +151,11 @@ public abstract class AbsSellerOrderComputeHandler implements OrderComputeHandle
* 服务费参与计算后需要考虑精度问题(四舍五入)
* @return
*/
protected Pair<ServiceFeeRate,PlatformFeeDto> calPlatformFee(BigDecimal price, List<ServiceFeeRate> serviceFeeRates, PlatformFeeDto ppf){
protected Pair<ServiceFeeRate,PlatformFeeDto> calPlatformFee(Integer uid,
Integer storageId,
BigDecimal price,
List<ServiceFeeRate> serviceFeeRates,
PlatformFeeDto ppf){
PlatformFeeDto platformFee = new PlatformFeeDto();
... ... @@ -173,7 +177,7 @@ public abstract class AbsSellerOrderComputeHandler implements OrderComputeHandle
}
//目前而言,商品抽成的阈值只有公共配置
PriceRange defaultGoodsServiceFeeRange = pfc.getGoodsServiceFeeRange();
ChooseServiceReeRateAndCalServiceFeeModel chooseServiceReeRateAndCalServiceFee = new ChooseServiceReeRateAndCalServiceFeeModel(price, serviceFeeRates, defaultGoodsServiceFeeRange)
ChooseServiceReeRateAndCalServiceFeeModel chooseServiceReeRateAndCalServiceFee = new ChooseServiceReeRateAndCalServiceFeeModel(uid, storageId, price, serviceFeeRates, defaultGoodsServiceFeeRange)
.invoke();
ServiceFeeRate serviceFeeRate = chooseServiceReeRateAndCalServiceFee.getServiceFeeRate();
BigDecimal serviceFee = chooseServiceReeRateAndCalServiceFee.getServiceFee();
... ... @@ -231,13 +235,21 @@ public abstract class AbsSellerOrderComputeHandler implements OrderComputeHandle
protected abstract Collection<BuyerPenalty.Fee> buildStagedCollection();
private class ChooseServiceReeRateAndCalServiceFeeModel {
private Integer uid;
private Integer storageId;
private BigDecimal price;
private List<ServiceFeeRate> serviceFeeRates;
private PriceRange defaultGoodsServiceFeeRange;
private ServiceFeeRate serviceFeeRate;
private BigDecimal serviceFee;
public ChooseServiceReeRateAndCalServiceFeeModel(BigDecimal price, List<ServiceFeeRate> serviceFeeRates, PriceRange defaultGoodsServiceFeeRange) {
public ChooseServiceReeRateAndCalServiceFeeModel(Integer uid,
Integer storageId,
BigDecimal price,
List<ServiceFeeRate> serviceFeeRates,
PriceRange defaultGoodsServiceFeeRange) {
this.uid = uid;
this.storageId = storageId;
this.price = price;
this.serviceFeeRates = serviceFeeRates;
this.defaultGoodsServiceFeeRange = defaultGoodsServiceFeeRange;
... ... @@ -256,16 +268,27 @@ public abstract class AbsSellerOrderComputeHandler implements OrderComputeHandle
serviceFeeRate = buildDefaultServiceFeeRate();
serviceFee = calServiceFee(price, serviceFeeRate, defaultGoodsServiceFeeRange);
} else {
for (ServiceFeeRate e : serviceFeeRates) {
PriceRange priceRange = Objects.nonNull(e.getGoodsPaymentPriceRange()) ? e.getGoodsPaymentPriceRange() : defaultGoodsServiceFeeRange;
BigDecimal tmp = calServiceFee(price, e, priceRange);
if (Objects.isNull(serviceFee) || serviceFee.compareTo(tmp) > 0) {
serviceFeeRate = e;
ServiceFeeRate minSFR = matchMinRate(serviceFeeRates);
logger.info("compute CalServiceFee uid {} storageId {} price {} serviceFeeRates {} defaultGoodsServiceFeeRange {} minSFR{}",
uid, storageId, price, serviceFeeRates, defaultGoodsServiceFeeRange, minSFR);
PriceRange priceRange = Objects.nonNull(minSFR.getGoodsPaymentPriceRange()) ? minSFR.getGoodsPaymentPriceRange() : defaultGoodsServiceFeeRange;
BigDecimal tmp = calServiceFee(price, minSFR, priceRange);
serviceFeeRate = minSFR;
serviceFee = tmp;
}
return this;
}
private ServiceFeeRate matchMinRate(List<ServiceFeeRate> serviceFeeRates){
ServiceFeeRate min = null;
for (ServiceFeeRate e : serviceFeeRates) {
if (Objects.isNull(min) || min.getGoodsPaymentRate().compareTo(e.getGoodsPaymentRate()) > 0) {
min = e;
}
return this;
}
return min;
}
}
}
... ...
... ... @@ -17,10 +17,8 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
@Service
public class GoodsAmountService {
... ... @@ -60,6 +58,8 @@ public class GoodsAmountService {
SellerOrderComputeResult socr = new SellerOrderComputeResult();
socr.setServiceFeeRates(allConfig);
socr.setUid(uid);
socr.setStorageId(storageId);
return socr;
}
... ...
package com.yohoufo.order.service.seller;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.yohobuy.ufo.model.order.bo.SoldPrdComputeBo;
import com.yohobuy.ufo.model.order.constants.SkupType;
import com.yohoufo.order.BaseWebTest;
import com.yohoufo.order.convert.SellerOrderConvertor;
import com.yohoufo.order.model.dto.PriceRange;
import com.yohoufo.order.model.dto.SellerOrderComputeResult;
import com.yohoufo.order.model.dto.ServiceFeeRate;
import com.yohoufo.order.service.proxy.ResourcesProxyService;
import com.yohoufo.order.service.seller.fee.GoodsServiceFeeRateDimension;
import com.yohoufo.order.service.seller.fee.GoodsServiceFeeRateWrapper;
import com.yohoufo.order.service.seller.inStock.SellerOrderComputeHandler;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Supplier;
/**
* Created by chenchao on 2018/9/14.
*/
public class SellerOrderServiceTest {
public class SellerOrderServiceTest extends BaseWebTest {
@Autowired
private OrderComputeProvider orderComputeProvider;
@Test
public void testBuildSoldPrdComputeBo(){
SellerOrderComputeHandler sos = new SellerOrderComputeHandler();
BigDecimal prdPrice = new BigDecimal(100D);
SellerOrderComputeResult bo = sos.compute(prdPrice, null);
SkupType skupType = SkupType.IN_STOCK;
OrderComputeHandler sos = orderComputeProvider.findBySkupType(skupType);
BigDecimal prdPrice = new BigDecimal(5009D);
PriceRange goodsPaymentPriceRange;
ServiceFeeRate serviceFeeRateOnDB = new ServiceFeeRate();
serviceFeeRateOnDB.setPayChannelRate(new BigDecimal(0.01D));
serviceFeeRateOnDB.setGoodsPaymentRate(new BigDecimal(0.03D));
//
goodsPaymentPriceRange = new PriceRange();
goodsPaymentPriceRange.setMin(0D);
goodsPaymentPriceRange.setMax(100D);
serviceFeeRateOnDB.setGoodsPaymentPriceRange(goodsPaymentPriceRange);
//
List<ServiceFeeRate> allConfig = Lists.newArrayListWithCapacity(3);
//
BigDecimal feeRateOfOUOGT = new BigDecimal(0.05);
GoodsServiceFeeRateWrapper gsfrwOfOUOGT = new GoodsServiceFeeRateWrapper(GoodsServiceFeeRateDimension.ONE_USER_ONE_GOODS_TYPE, serviceFeeRateOnDB);
gsfrwOfOUOGT.setGoodsPaymentRate(feeRateOfOUOGT);
//
allConfig.add(gsfrwOfOUOGT);
//
allConfig.add(new GoodsServiceFeeRateWrapper(GoodsServiceFeeRateDimension.GOODS_TYPE, serviceFeeRateOnDB));
SellerOrderComputeResult socr = new SellerOrderComputeResult();
socr.setServiceFeeRates(allConfig);
SellerOrderComputeResult computeResult = sos.compute(prdPrice, socr);
System.out.println("in testBuildSoldPrdComputeBo :"+ JSONObject.toJSONString(computeResult));
System.out.println("in testBuildSoldPrdComputeBo :"+ JSONObject.toJSONString(bo));
Supplier<Map<String,String>> tipsConfigSupplier = () -> {
Map<String,String> tipsConfigMap = new HashMap<>();
tipsConfigMap.put(ResourcesProxyService.KEY_SERVICETIPSDESC,"5%");
tipsConfigMap.put(ResourcesProxyService.KEY_SERVICETIPSSUMARY,"5%");
return tipsConfigMap;
};
SoldPrdComputeBo spc;
spc = SellerOrderConvertor.computeResult2SoldPrdComputeBo(computeResult, tipsConfigSupplier);
System.out.println("computeResult2SoldPrdComputeBo computeResult ->"+ JSONObject.toJSONString(spc));
}
}
... ...
... ... @@ -126,7 +126,9 @@ rabbit_user=yoho
rabbit_password=yoho
#二次发货提醒 24*60 minutes
mq.seller.deliverNotice.second=1440
mq.seller.deliverNotice.second=40
mq.seller.deliverNotice.totalTime=60
mq.seller.deliverNotice.lastTime=20
#发货失败提醒 36*60 minutes
mq.seller.deliverNotice.third=15
... ... @@ -155,3 +157,5 @@ ufo.certification.timesLimit=3
# Unionpay
unionpay.env=00
unionpay.notifyurl=http://testapi.yohops.com/payment/ufo_unionpay_notify
ufo.alipay.sendPaymentInfo.switch=false
... ...