优惠金额分配算法
/**
* 优惠金额分配算法
*
* @param list 明细金额集合
* @param couponMoney 优惠金额
* @return 减去优惠金额后的集合
*/
public List<BigDecimal> preferentialDistributionAlgorithm(List<BigDecimal> list, BigDecimal couponMoney) {
List<BigDecimal> tempList = new ArrayList<>();
// 明细总和
BigDecimal sum = BigDecimal.ZERO;
for (BigDecimal decimal : list) {
sum = sum.add(decimal);
}
for (BigDecimal oneMoney : list) {
// 单个明细分配的优惠金额
BigDecimal lastMoney;
if (couponMoney.compareTo(BigDecimal.ZERO) == 0) {
continue;
}
//单个明细金额占比,除数保留位数越多,分配越精准
BigDecimal oneMoneyScope = oneMoney.divide(sum, 5, RoundingMode.UP);
//分配优惠券金额按比例 优惠金额末位舍0进1
lastMoney = oneMoneyScope.multiply(couponMoney).setScale(2, RoundingMode.UP);
//如果分配比例大于金额 则等于金额;这个判断注释掉(允许出现负的优惠金额)
if (lastMoney.compareTo(oneMoney) > 0) {
lastMoney = oneMoney;
}
//优惠金额去除本次优惠金额
couponMoney = couponMoney.subtract(lastMoney);
//总金额减去本次商品金额
sum = sum.subtract(oneMoney);
tempList.add(oneMoney.subtract(lastMoney));
}
//填平没有优惠的金额
int tempListSize = tempList.size();
if (tempListSize != list.size()) {
int size = list.size() - tempListSize;
for (int i = 0; i < size; i++) {
tempList.add(list.get(i + tempListSize));
}
}
return tempList;
}
public static void main(String[] args) {
List<BigDecimal> aa = new ArrayList<>();
aa.add(new BigDecimal("16")); //商品1原价
aa.add(new BigDecimal("20")); //商品2原价
aa.add(new BigDecimal("17")); //商品3原价
List<BigDecimal> bb = preferentialDistributionAlgorithm(aa, new BigDecimal("39.8")); //39.8订单实付金额
log.info(JSONUtil.toJsonStr(bb)); //输出每个商品优惠金额 [3.98,4.98,4.24]
}