|
|
package com.yohoufo.order.service.handler;
|
|
|
|
|
|
import com.yohoufo.common.utils.BigDecimalHelper;
|
|
|
import com.yohoufo.order.model.dto.EarnestMoney;
|
|
|
import com.yohoufo.order.model.dto.PlatformFeeDto;
|
|
|
import com.yohoufo.order.model.dto.SellerOrderComputeResult;
|
|
|
import com.yohoufo.order.model.dto.ServiceFeeRate;
|
|
|
import com.yohoufo.order.utils.LoggerUtils;
|
|
|
import org.slf4j.Logger;
|
|
|
import org.slf4j.LoggerFactory;
|
|
|
import org.springframework.beans.factory.annotation.Value;
|
|
|
import com.yohoufo.order.service.seller.AbsSellerOrderComputeHandler;
|
|
|
import com.yohoufo.order.service.seller.OrderComputeHandler;
|
|
|
import org.springframework.stereotype.Component;
|
|
|
|
|
|
import javax.annotation.PostConstruct;
|
|
|
import java.math.BigDecimal;
|
|
|
|
|
|
/**
|
|
|
* Created by chenchao on 2018/9/14.
|
|
|
*/
|
|
|
@Component
|
|
|
public class SellerOrderComputeHandler {
|
|
|
|
|
|
private Logger logger = LoggerUtils.getSellerOrderLogger();
|
|
|
|
|
|
@Value("${order.seller.earnestmoney.min:28}")
|
|
|
private double earnestmoney_min;
|
|
|
@Value("${order.seller.earnestmoney.max:200}")
|
|
|
private double earnestmoney_max;
|
|
|
private BigDecimal[] EARNESTMONEYRANGE = new BigDecimal[2];
|
|
|
|
|
|
@Value("${order.seller.appraiseFee:5}")
|
|
|
private Double appraiseFee;
|
|
|
/**
|
|
|
* 有货包装费(暂定5元)
|
|
|
*/
|
|
|
@Value("${order.seller.packageFee:5}")
|
|
|
private Double packageFee ;
|
|
|
|
|
|
@Value("${order.seller.goodsPaymentRate}")
|
|
|
private Double goodsPaymentRate = 0.05D;
|
|
|
|
|
|
@Value("${order.seller.earnestMoneyRate}")
|
|
|
private Double earnestMoneyRate = 0.20D;
|
|
|
|
|
|
@Value("${order.seller.payChannelRate}")
|
|
|
private Double payChannelRate = 0.006D;
|
|
|
|
|
|
@PostConstruct
|
|
|
public void init(){
|
|
|
EARNESTMONEYRANGE[0] = new BigDecimal(earnestmoney_min);
|
|
|
EARNESTMONEYRANGE[1] = new BigDecimal(earnestmoney_max);
|
|
|
}
|
|
|
|
|
|
public BigDecimal[] getEarnestMoneyrange(){
|
|
|
return EARNESTMONEYRANGE;
|
|
|
}
|
|
|
|
|
|
public SellerOrderComputeResult compute(BigDecimal prdPrice){
|
|
|
|
|
|
//保证金(28-200(按照卖家发布商品的货款金额5%计算,最低28,封顶200))
|
|
|
EarnestMoney earnestMoney = calEarnestMoney(prdPrice);
|
|
|
//init fee rate
|
|
|
ServiceFeeRate serviceFeeRate = new ServiceFeeRate();
|
|
|
serviceFeeRate.setGoodsPaymentRate(new BigDecimal(goodsPaymentRate).setScale(2, BigDecimal.ROUND_HALF_UP));
|
|
|
serviceFeeRate.setEarnestMoneyRate(new BigDecimal(earnestMoneyRate).setScale(2, BigDecimal.ROUND_HALF_UP));
|
|
|
serviceFeeRate.setPayChannelRate(new BigDecimal(payChannelRate).setScale(4, BigDecimal.ROUND_HALF_UP));
|
|
|
//
|
|
|
PlatformFeeDto platformFeeDto = calPlatformFee(prdPrice, serviceFeeRate.getGoodsPaymentRate());
|
|
|
BigDecimal bankTransferFee = calBankTransferFee(prdPrice, serviceFeeRate.getPayChannelRate());
|
|
|
logger.info("in SellerOrder Compute, prdPrice {}, platformFee {}, bankTransferFee {}",
|
|
|
prdPrice, platformFeeDto, bankTransferFee);
|
|
|
BigDecimal income = calIncome(prdPrice, platformFeeDto.getTotal(), bankTransferFee);
|
|
|
//set
|
|
|
SellerOrderComputeResult result = new SellerOrderComputeResult();
|
|
|
result.setEarnestMoney(earnestMoney);
|
|
|
result.setPlatformFee(platformFeeDto);
|
|
|
result.setIncome(halfUp(income));
|
|
|
//TODO 根据配置文件
|
|
|
result.setServiceFeeRate(serviceFeeRate);
|
|
|
result.setBankTransferfee(bankTransferFee);
|
|
|
return result;
|
|
|
}
|
|
|
|
|
|
private BigDecimal calBankTransferFee(BigDecimal prdPrice, BigDecimal payServiceFeeRate){
|
|
|
//支付渠道转账费率(0.6%)
|
|
|
return halfUp(prdPrice.multiply(payServiceFeeRate));
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* (1-X-Z)*B-D-E *
|
|
|
B:货款(卖家发布商品自行输入);
|
|
|
D:有货鉴定费(暂定5元);
|
|
|
E:有货包装费(暂定5元);
|
|
|
X:货款抽成(暂定5%,后期可调整,上线初期为0,后期活动可根据活动进行减免,每个卖家可收费不一样);
|
|
|
Z:支付渠道费,调用银联支付接口时实时扣款(支付宝0.55%、微信均为0.6%,统一对用户收取0.6%,前期优惠策略可暂定0)
|
|
|
* @param prdPrice
|
|
|
* @param platformFee
|
|
|
* @return
|
|
|
*/
|
|
|
private BigDecimal calIncome(BigDecimal prdPrice,BigDecimal platformFee,BigDecimal bankTransferFee){
|
|
|
return prdPrice.subtract(platformFee).subtract(bankTransferFee);
|
|
|
}
|
|
|
|
|
|
public Double getAppraiseFee() {
|
|
|
return appraiseFee;
|
|
|
}
|
|
|
|
|
|
public Double getPackageFee() {
|
|
|
return packageFee;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 通过相加得出的数据
|
|
|
* 服务费参与计算后需要考虑精度问题(四舍五入)
|
|
|
* @return
|
|
|
*/
|
|
|
private PlatformFeeDto calPlatformFee(BigDecimal price, BigDecimal goodsServiceRate){
|
|
|
PlatformFeeDto platformFee = new PlatformFeeDto();
|
|
|
BigDecimal appraiseFee = new BigDecimal(getAppraiseFee());
|
|
|
BigDecimal packageFee = new BigDecimal(getPackageFee());
|
|
|
BigDecimal serviceFee = price.multiply(goodsServiceRate);
|
|
|
|
|
|
platformFee.setAppraiseFee(halfUp(appraiseFee));
|
|
|
platformFee.setPackageFee(halfUp(packageFee));
|
|
|
BigDecimal total = appraiseFee.add(packageFee).add(serviceFee);
|
|
|
|
|
|
platformFee.setTotal(halfUp(total));
|
|
|
platformFee.setServiceFee(halfUp(serviceFee));
|
|
|
return platformFee;
|
|
|
}
|
|
|
public class SellerOrderComputeHandler extends AbsSellerOrderComputeHandler implements OrderComputeHandler {
|
|
|
|
|
|
/**
|
|
|
* 相对独立 不涉及到计算其他费用
|
|
|
* @param prdPrice
|
|
|
* @return
|
|
|
*/
|
|
|
private EarnestMoney calEarnestMoney(BigDecimal prdPrice){
|
|
|
protected EarnestMoney calEarnestMoney(BigDecimal prdPrice){
|
|
|
BigDecimal[] EARNEST_MONEY_RANGE = orderDynamicConfig.getEMR();
|
|
|
EarnestMoney earnestMoney = new EarnestMoney();
|
|
|
|
|
|
//TODO earnestMoney.rate 需要调整为动态可配
|
|
|
BigDecimal real = halfUp(prdPrice.multiply(earnestMoney.getRate()));
|
|
|
final BigDecimal min = EARNESTMONEYRANGE[0] == null ? earnestMoney.getMin() : EARNESTMONEYRANGE[0];
|
|
|
final BigDecimal max = EARNESTMONEYRANGE[1] == null ? earnestMoney.getMax() : EARNESTMONEYRANGE[1];
|
|
|
if(real.subtract(min).doubleValue() < 0D){
|
|
|
real = min;
|
|
|
}
|
|
|
if (real.subtract(max).doubleValue() > 0D){
|
|
|
real = max;
|
|
|
}
|
|
|
final BigDecimal min = EARNEST_MONEY_RANGE[0] == null ? earnestMoney.getMin() : EARNEST_MONEY_RANGE[0];
|
|
|
final BigDecimal max = EARNEST_MONEY_RANGE[1] == null ? earnestMoney.getMax() : EARNEST_MONEY_RANGE[1];
|
|
|
real = calCrossWithThreshold(min, max, real);
|
|
|
earnestMoney.setMin(min);
|
|
|
earnestMoney.setMax(max);
|
|
|
earnestMoney.setEarnestMoney(real);
|
|
|
return earnestMoney;
|
|
|
}
|
|
|
|
|
|
private BigDecimal halfUp(BigDecimal fee){
|
|
|
return BigDecimalHelper.halfUp(fee);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
protected ServiceFeeRate buildServiceFeeRate() {
|
|
|
ServiceFeeRate serviceFeeRate = orderDynamicConfig.getServiceFeeRate();
|
|
|
return serviceFeeRate;
|
|
|
}
|
|
|
|
|
|
|
|
|
} |
...
|
...
|
|