例:订单总金额100,使用优惠券5元,需要把5元优惠券按照商品行金额占比分摊到商品行上去。

订单号:1000001,商品总金额:100元,优惠券:5元,实际支付金额:95元
商品名称 单价 优惠券分摊算法 优惠券分摊金额
苹果 60元 5*(60/100) 3元
香蕉 30元 (5-3)*(30/(100-60)) 1.5元
橘子 10元 (5-3-1.5)*(10/(100-60-30)) 0.5元

计算公式为:(需要分摊金额-已分摊金额) * (当前商品行金额 / (商品行总金额-已使用商品行金额))=当前行分摊金额

代码实例如下:

import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

@Slf4j
@Service
public class AmountShareService {

    /**
     * 处理商品行需要分摊的优惠券、促销、营销费用等,需要按照每一行商品金额占比来分摊
     * @param rowAmountList 分行商品金额集合
     * @param shareAmount 需要分摊的金额
     * @return List<BigDecimal> 返回每一行商品上的分摊占比金额
     */
    public static List<BigDecimal> handleAmountShare(List<BigDecimal> rowAmountList, BigDecimal shareAmount) {
        List<BigDecimal> amountShareList = new ArrayList<>();
        if (CollectionUtils.isEmpty(rowAmountList)) {
            log.error("参与分摊的商品集合不能为空,rowAmountList:{}", JSON.toJSONString(rowAmountList));
            return amountShareList;
        }
        //商品集合金额合计
        BigDecimal sum = rowAmountList.stream().reduce(BigDecimal.ZERO, BigDecimal::add);

        for (BigDecimal nowMoney : rowAmountList) {
            BigDecimal lastMoney = BigDecimal.ZERO;
            if (shareAmount.compareTo(BigDecimal.ZERO) == 0) {
                log.error("参与分摊金额不能为0!shareAmount: {}", JSON.toJSONString(shareAmount));
                break;
            }
            //分摊金额不能大于等于合计金额
            if (shareAmount.compareTo(sum) > -1) {
                log.error("参与分摊金额:{},不能大于商品总金额:{}", shareAmount, sum);
                break;
            }
            //当前商品行金额,在未使用商品行总金额中的占比,四舍五入保留两位小数
            BigDecimal oneMoneyScope = nowMoney.divide(sum, 2, BigDecimal.ROUND_UP);
            //占比 * 还未分摊金额,四舍五入保留两位小数
            lastMoney = oneMoneyScope.multiply(shareAmount).setScale(2, BigDecimal.ROUND_UP);
            //计算出来的当前行分摊金额不能大于当前行商品金额
            if (lastMoney.compareTo(nowMoney) == 1) {
                log.error("当前商品行分摊金额:{},不能大于当前行商品金额:{}", lastMoney, nowMoney);
                break;
            }
            amountShareList.add(lastMoney);
            //剩余分摊金额=剩余分摊金额-当前商品行已分摊金额
            shareAmount = shareAmount.subtract(lastMoney);
            //未参与分摊商品行总金额=未参与分摊商品行总金额-当前商品行金额
            sum = sum.subtract(nowMoney);
        }
        return amountShareList;
    }

    public static void main(String[] args) {
        List<BigDecimal> list = new ArrayList<>();
        list.add(new BigDecimal("60"));
        list.add(new BigDecimal("30"));
        list.add(new BigDecimal("10"));
        List<BigDecimal> result = handleAmountShare(list, new BigDecimal("5"));
        System.out.println(JSON.toJSONString(list));
        System.out.println(JSON.toJSONString(result));
    }
}

 

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐