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

📚目录

  • 需求
  • 业务解释
  • 解决代码
  • 效果

需求

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

业务解释

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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/307893.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

算法基础day1

归并排序模版 #include <iostream> using namespace std; int n; const int N 1e610; int q[N],tmp[N]; void merge_sort(int l,int r,int q[]){if(l>r) return;int mid lr>>1;merge_sort(l,mid,q);merge_sort(mid1,r,q);//归并的的过程int k0,il,jmid1;while(…

MPLS动态协议LDP配置示例

一、预习&#xff1a; MPLS是一种根据报文中携带的标签来转发数据的技术&#xff0c;两台LSR必须在它们之间转的数据 的标签使用上“达成共识”。LSR之间可以运行LDP来告知其他LSR本设备上的标签绑定信息&#xff0c;从而实现标签报文的正确转发。 LSR&#xff1a;Label Switch…

TP-LINK 路由器忘记密码 - 恢复出厂设置

TP-LINK 路由器忘记密码 - 恢复出厂设置 1. 恢复出厂设置2. 创建管理员密码3. 上网设置4. 无线设置5. TP-LINK ID6. 网络状态References 1. 恢复出厂设置 在设备通电的情况下&#xff0c;按住路由器背面的 Reset 按钮直到所有指示灯同时亮起后松开。 2. 创建管理员密码 3. 上网…

java设计模式学习之【访问者模式】

文章目录 引言访问者模式简介定义与用途实现方式 使用场景优势与劣势在Spring框架中的应用电脑示例代码地址 引言 设想你是一个艺术馆的管理员&#xff0c;艺术馆里有各种各样的艺术品。每当有游客来访时&#xff0c;根据他们的兴趣&#xff0c;他们可能只想看画、雕塑或特定的…

如何通过易舟云财务软件,进行结转结账?

如何通过易舟云财务软件&#xff0c;进行结转结账&#xff1f; 前言财务软件操作步骤1、期末检查2、计提所得税3、结转损益4、断号检查5、结账 注意事项 前言 财务软件的结转结账功能是指在财务管理过程中&#xff0c;将上一期的未结转的财务数据进行处理&#xff0c;包括将未…

MyBatis-config.xml配置文件

1、基本介绍&#xff1a; mybatis的核心配置文件(mybatis-config.xml)&#xff0c;比如配置jdbc连接信息&#xff0c;注册mapper等等&#xff0c;我们需要对这个配置文件有详细的了解。 官网地址有详细介绍 mybatis – MyBatis 3 | 配置 2、properties属性 在通常的情况下&am…

右键添加 idea 打开功能

1.开始运行regedit 2.找到: HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Directory\shell _3.开始设置 一、右键shell目录新建项Idea二、右键Idea新建command三、选择Idea 右侧空白出新建字符串 名字为Icon 值填入idea的运行程序地址 四、选择command 默认项填入idea的运行程序地址…

腾讯经典面试题-如何做一个迷你版的微信抢红包呢?

&#x1f44f;作者简介&#xff1a;大家好&#xff0c;我是爱吃芝士的土豆倪&#xff0c;24届校招生Java选手&#xff0c;很高兴认识大家&#x1f4d5;系列专栏&#xff1a;Spring源码、JUC源码、Kafka原理、分布式技术原理、数据库技术&#x1f525;如果感觉博主的文章还不错的…

[Angular] 笔记 17:提交表单 - ngSubmit

Submitting Forms (ngSubmit) 表单的一般完整写法&#xff1a; 如果表单验证失败&#xff0c;必须 disable 提交按钮&#xff0c;阻止用户提交不合法的数据。 提交表单后&#xff0c;与表单对应的 json 数据 post 到后端&#xff1a; {"id":1,"name":…

单片机开发从小工到专家

有道无术&#xff0c;术尚可求&#xff1b;有术无道&#xff0c;止于术 背景 向单片机嵌入式开发小伙伴推荐了几本书&#xff0c;阅读量破10 1. 适用范围 2. 书籍推荐 书籍推荐 3. 大师介绍 大师介绍 4. 大师书籍编写逻辑 25年大师出版的关于&#xff1a;嵌入式单片…

《我与地坛》当时只道是寻常;只是当时已惘然

《我与地坛》当时只道是寻常&#xff1b;只是当时已惘然 史铁生&#xff08;1951/1/4-2010/12/31&#xff09;&#xff0c;作家&#xff0c;散文家&#xff0c;代表作有《我与地坛》《命若琴弦》《奶奶的星星》等。 文章目录 《我与地坛》当时只道是寻常&#xff1b;只是当时已…

以社区为基石,IvorySQL逐步成为中国基础软件开源数据库产业重要一员

编者按&#xff1a;开源数据库技术&#xff0c;作为软件开发领域的一大趋势&#xff0c;正逐渐改变整个软件产业的面貌。在这个充满活力的领域中&#xff0c;瀚高股份的IvorySQL凭借其社区活跃度和影响力&#xff0c;已经成为中国基础软件开源数据库产业的重要一员。随着《2023…