需求:多笔流水的金额分配给多个订单,确保流水总金额和订单总金额一致

需求

按照一定规则将多笔流水的金额分配给多个订单,确保流水总金额和订单总金额一致。

业务解释

       之前系统做了个功能,允许对订单进行录错退款,并且重新关联新的订单,审核通过完成后录错的订单自动变为废弃状态,而重新下单的则会变成正常的订单,这个功能的存在就是为了,门店在录订单可能会出现问题导致订单不正确的一种补救方式,但是这会有个问题录错的订单通常是使用二维码进行扫码支付会产生流水数据,这样财务对账的时候可以知道这边流水属于那个订单上的他们就好算工资,所以需要解决重新下单的订单关联上原订单的流水,并且他们重新下的订单总金额需要和原订单的总流水金额要一致,下面就是流水和订单关联的2种关系。
在这里插入图片描述

录错退款:允许一拆一,一拆多的模式

在这里插入图片描述

       所以当一个订单出现多笔流水(图中关系二),然后这个订单还录错退款拆分了多个小订单(图中一对多个订单),那他们之间的金额该如何分配呢?

       结果应该是这样的,订单的总金额和总流水需要对的上,至于一个流水的金额可以被才分成若干个小金额的订单,就如bill3流水才分成了三个小金额的订单100,200,200,这些订单相加的金额又等于流水的金额500。然后按照订单上看order7(300)=bill2(100)+bill3(200) 由多个流水中小订单金额相加等于,原订单的总金额。

{
   
    "bill2": {
   
        "order7": 100
    },
    "bill3": {
   
        "order5": 100,
        "order6": 200,
        "order7": 200
    }
}
或者可以按照这样分配
{
   
    "bill2": {
   
        "order5": 100
    },
    "bill3": {
   
        "order6": 200,
        "order7": 300
    }
}

解决代码

public static void main(String[] args) {
   
        Map<String, Long> billNoAndAmountMap  = new HashMap<>();
        billNoAndAmountMap.put("billNo1",100L);
        billNoAndAmountMap.put("billNo2",100L);
        billNoAndAmountMap.put("billNo3",120L);
        Map<String, Long> orderAndAmountMap = new HashMap<>();
        orderAndAmountMap.put("orderNo1",60L);
        orderAndAmountMap.put("orderNo2",150L);
        orderAndAmountMap.put("orderNo3",110L);
        Map<String, Map<String, Long>> allocation = flowAndOrderAmountAllocation(billNoAndAmountMap, orderAndAmountMap);
        System.out.println("分配完成后的结果:\n"+ JSONUtil.toJsonStr(allocation));
    }
    /**
     * 流水与订单的金额分配
     *
     * @param billNoAndAmountMap 流水集合
     * @param orderAndAmountMap  多个订单和金额的Map
     * @return <billNo,<orderNo,amount>>
     */
    public static Map<String, Map<String, Long>> flowAndOrderAmountAllocation(Map<String, Long> billNoAndAmountMap, Map<String, Long> orderAndAmountMap) {
   
        Map<String, Map<String, Long>> result = new TreeMap<>();

        // 确认传入的总金额可以对应上
        long billAmountTotal = billNoAndAmountMap.values().stream().mapToLong(Long::valueOf).sum();
        long orderAmountTotal = orderAndAmountMap.values().stream().mapToLong(Long::valueOf).sum();
        if (billAmountTotal != orderAmountTotal) {
   
            throw new RuntimeException("传参流水与订单的金额累加不一致");
        }

        List<String> allocationOrder = new ArrayList<>();
        long remainingBillAmount = billAmountTotal;

        for (Map.Entry<String, Long> billEntry : billNoAndAmountMap.entrySet()) {
   
            String billNo = billEntry.getKey();
            long billAmount = billEntry.getValue();
            Map<String, Long> orderMap = new TreeMap<>();
            for (Map.Entry<String, Long> orderEntry : orderAndAmountMap.entrySet()) {
   
                String orderNo = orderEntry.getKey();
                if (allocationOrder.contains(orderNo)) {
   
                    continue;
                }
                long orderAmount = orderEntry.getValue();
                if (orderAmount > billAmount) {
   
                    long orderSurplusAmount = orderAmount - billAmount;
                    orderAmount = billAmount;
                    orderEntry.setValue(orderSurplusAmount);
                } else {
   
                    allocationOrder.add(orderNo);
                }
                billAmount -= orderAmount;
                orderMap.put(orderNo, orderAmount);
                if (billAmount == 0L) {
   
                    break;
                }
            }
            result.put(billNo, orderMap);
            remainingBillAmount -= billAmount;
            if (remainingBillAmount == 0L) {
   
                break;
            }
        }
        return result;
    }

效果

运行结果

分配完成后的结果:
{
   "billNo1":{
   "orderNo3":100},"billNo2":{
   "orderNo1":60,"orderNo2":30,"orderNo3":10},"billNo3":{
   "orderNo2":120}}

在这里插入图片描述
在这里插入图片描述

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2023-12-30 00:26:01       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2023-12-30 00:26:01       100 阅读
  3. 在Django里面运行非项目文件

    2023-12-30 00:26:01       82 阅读
  4. Python语言-面向对象

    2023-12-30 00:26:01       91 阅读

热门阅读

  1. Vue.js项目部署至Linux服务器的详细步骤

    2023-12-30 00:26:01       51 阅读
  2. git回退2个错误的分支

    2023-12-30 00:26:01       50 阅读
  3. Docker六 | Docker Compose容器编排

    2023-12-30 00:26:01       42 阅读
  4. 安装 yarn、pnpm、功能比较

    2023-12-30 00:26:01       61 阅读
  5. Python开发雷点总结

    2023-12-30 00:26:01       57 阅读
  6. Ascend C算子开发常见问题案例

    2023-12-30 00:26:01       52 阅读
  7. C语言,指针链表详解解说及代码示例

    2023-12-30 00:26:01       66 阅读
  8. 面试题:BIO、NIO、AIO 的区别是什么?

    2023-12-30 00:26:01       70 阅读
  9. Top100 C++编程面试问题

    2023-12-30 00:26:01       45 阅读
  10. 网络安全面试题目

    2023-12-30 00:26:01       57 阅读
  11. Linux 系统参数和变量配置

    2023-12-30 00:26:01       49 阅读
  12. 篇章二 | Python 入门指南:深入理解基础数据类型

    2023-12-30 00:26:01       56 阅读
  13. Impala中kudu基础理论详解(超详细)

    2023-12-30 00:26:01       53 阅读
  14. centos 编译安装 cmake

    2023-12-30 00:26:01       66 阅读