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

本文主要是介绍需求:多笔流水的金额分配给多个订单,确保流水总金额和订单总金额一致,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

📚目录

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

需求

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

业务解释

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

相关文章

Java中Switch Case多个条件处理方法举例

《Java中SwitchCase多个条件处理方法举例》Java中switch语句用于根据变量值执行不同代码块,适用于多个条件的处理,:本文主要介绍Java中SwitchCase多个条件处理的相... 目录前言基本语法处理多个条件示例1:合并相同代码的多个case示例2:通过字符串合并多个case进阶用法使用

Java编译生成多个.class文件的原理和作用

《Java编译生成多个.class文件的原理和作用》作为一名经验丰富的开发者,在Java项目中执行编译后,可能会发现一个.java源文件有时会产生多个.class文件,从技术实现层面详细剖析这一现象... 目录一、内部类机制与.class文件生成成员内部类(常规内部类)局部内部类(方法内部类)匿名内部类二、

基于Flask框架添加多个AI模型的API并进行交互

《基于Flask框架添加多个AI模型的API并进行交互》:本文主要介绍如何基于Flask框架开发AI模型API管理系统,允许用户添加、删除不同AI模型的API密钥,感兴趣的可以了解下... 目录1. 概述2. 后端代码说明2.1 依赖库导入2.2 应用初始化2.3 API 存储字典2.4 路由函数2.5 应

Python实现合并与拆分多个PDF文档中的指定页

《Python实现合并与拆分多个PDF文档中的指定页》这篇文章主要为大家详细介绍了如何使用Python实现将多个PDF文档中的指定页合并生成新的PDF以及拆分PDF,感兴趣的小伙伴可以参考一下... 安装所需要的库pip install PyPDF2 -i https://pypi.tuna.tsingh

Python中Windows和macOS文件路径格式不一致的解决方法

《Python中Windows和macOS文件路径格式不一致的解决方法》在Python中,Windows和macOS的文件路径字符串格式不一致主要体现在路径分隔符上,这种差异可能导致跨平台代码在处理文... 目录方法 1:使用 os.path 模块方法 2:使用 pathlib 模块(推荐)方法 3:统一使

mysql8.0无备份通过idb文件恢复数据的方法、idb文件修复和tablespace id不一致处理

《mysql8.0无备份通过idb文件恢复数据的方法、idb文件修复和tablespaceid不一致处理》文章描述了公司服务器断电后数据库故障的过程,作者通过查看错误日志、重新初始化数据目录、恢复备... 周末突然接到一位一年多没联系的妹妹打来电话,“刘哥,快来救救我”,我脑海瞬间冒出妙瓦底,电信火苲马扁.

nginx upstream六种方式分配小结

《nginxupstream六种方式分配小结》本文主要介绍了nginxupstream六种方式分配小结,包括轮询、加权轮询、IP哈希、公平轮询、URL哈希和备份服务器,具有一定的参考价格,感兴趣的可... 目录1 轮询(默认)2 weight3 ip_hash4 fair(第三方)5 url_hash(第三

Java中实现订单超时自动取消功能(最新推荐)

《Java中实现订单超时自动取消功能(最新推荐)》本文介绍了Java中实现订单超时自动取消功能的几种方法,包括定时任务、JDK延迟队列、Redis过期监听、Redisson分布式延迟队列、Rocket... 目录1、定时任务2、JDK延迟队列 DelayQueue(1)定义实现Delayed接口的实体类 (

Python自动化办公之合并多个Excel

《Python自动化办公之合并多个Excel》在日常的办公自动化工作中,尤其是处理大量数据时,合并多个Excel表格是一个常见且繁琐的任务,下面小编就来为大家介绍一下如何使用Python轻松实现合... 目录为什么选择 python 自动化目标使用 Python 合并多个 Excel 文件安装所需库示例代码

Java实现检查多个时间段是否有重合

《Java实现检查多个时间段是否有重合》这篇文章主要为大家详细介绍了如何使用Java实现检查多个时间段是否有重合,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录流程概述步骤详解China编程步骤1:定义时间段类步骤2:添加时间段步骤3:检查时间段是否有重合步骤4:输出结果示例代码结语作