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

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

📚目录

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

需求

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

业务解释

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

相关文章

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:输出结果示例代码结语作

Java判断多个时间段是否重合的方法小结

《Java判断多个时间段是否重合的方法小结》这篇文章主要为大家详细介绍了Java中判断多个时间段是否重合的方法,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录判断多个时间段是否有间隔判断时间段集合是否与某时间段重合判断多个时间段是否有间隔实体类内容public class D

linux下多个硬盘划分到同一挂载点问题

《linux下多个硬盘划分到同一挂载点问题》在Linux系统中,将多个硬盘划分到同一挂载点需要通过逻辑卷管理(LVM)来实现,首先,需要将物理存储设备(如硬盘分区)创建为物理卷,然后,将这些物理卷组成... 目录linux下多个硬盘划分到同一挂载点需要明确的几个概念硬盘插上默认的是非lvm总结Linux下多

mysqld_multi在Linux服务器上运行多个MySQL实例

《mysqld_multi在Linux服务器上运行多个MySQL实例》在Linux系统上使用mysqld_multi来启动和管理多个MySQL实例是一种常见的做法,这种方式允许你在同一台机器上运行多个... 目录1. 安装mysql2. 配置文件示例配置文件3. 创建数据目录4. 启动和管理实例启动所有实例

使用SQL语言查询多个Excel表格的操作方法

《使用SQL语言查询多个Excel表格的操作方法》本文介绍了如何使用SQL语言查询多个Excel表格,通过将所有Excel表格放入一个.xlsx文件中,并使用pandas和pandasql库进行读取和... 目录如何用SQL语言查询多个Excel表格如何使用sql查询excel内容1. 简介2. 实现思路3

Springboot的ThreadPoolTaskScheduler线程池轻松搞定15分钟不操作自动取消订单

《Springboot的ThreadPoolTaskScheduler线程池轻松搞定15分钟不操作自动取消订单》:本文主要介绍Springboot的ThreadPoolTaskScheduler线... 目录ThreadPoolTaskScheduler线程池实现15分钟不操作自动取消订单概要1,创建订单后