From affdf333cb411be14dc8749a56ad1f333d2d5a7c Mon Sep 17 00:00:00 2001 From: shenzhouyu Date: Thu, 22 Jan 2026 10:54:52 +0800 Subject: [PATCH] =?UTF-8?q?=E7=AE=97=E6=B3=95=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../impl/CustomerIssueServiceImpl.java | 75 +++++++++++-------- 1 file changed, 45 insertions(+), 30 deletions(-) diff --git a/src/main/java/com/gaotao/modules/customer/service/impl/CustomerIssueServiceImpl.java b/src/main/java/com/gaotao/modules/customer/service/impl/CustomerIssueServiceImpl.java index cdc51b3..f06e68b 100644 --- a/src/main/java/com/gaotao/modules/customer/service/impl/CustomerIssueServiceImpl.java +++ b/src/main/java/com/gaotao/modules/customer/service/impl/CustomerIssueServiceImpl.java @@ -237,6 +237,7 @@ public class CustomerIssueServiceImpl implements CustomerIssueService { shipmentReserveVos.add(shipmentReserveVo); } List reserveVos = splitReserves(shipmentReserveVos, customerIssueDto.getShipmentLine()); + log.info("拆分后的数组:{},ifsline:{}",reserveVos,customerIssueDto.getShipmentLine()); //调用ifs接口 for (ShipmentReserveVo lineVo : reserveVos){ @@ -295,12 +296,10 @@ public class CustomerIssueServiceImpl implements CustomerIssueService { reserveTotalMap.put(key, reserveTotalMap.getOrDefault(key, BigDecimal.ZERO).add(reserve.getTransQty())); } - // 验证总量一致性:比较两个 map 中每个 key 的总数量是否一致 - // 注意:假设 contract 对应 site,inventoryPartNo 对应 partNo,所以两个 key 格式的值应该相同 + // 验证总量一致性 Set allKeys = new HashSet<>(); allKeys.addAll(lineTotalMap.keySet()); allKeys.addAll(reserveTotalMap.keySet()); - for (String key : allKeys) { BigDecimal lineTotal = lineTotalMap.getOrDefault(key, BigDecimal.ZERO); BigDecimal reserveTotal = reserveTotalMap.getOrDefault(key, BigDecimal.ZERO); @@ -311,29 +310,53 @@ public class CustomerIssueServiceImpl implements CustomerIssueService { } } - // 构建以contract|inventoryPartNo为键的lines映射表(用于后续拆分) - Map> lineMap = new HashMap<>(); + // 构建以contract|inventoryPartNo为键的lines队列(保持原有顺序用来逐个吃掉数量) + Map> lineQueueMap = new HashMap<>(); for (ShipmentLineVo line : lines) { + BigDecimal availableQty = line.getInventoryQty().subtract(line.getQtyAssigned()); + if (availableQty.compareTo(BigDecimal.ZERO) <= 0) { + continue; + } String key = line.getContract() + "|" + line.getInventoryPartNo(); - lineMap.computeIfAbsent(key, k -> new ArrayList<>()).add(line); + lineQueueMap.computeIfAbsent(key, k -> new LinkedList<>()) + .add(new LineAllocation(line, availableQty)); } List result = new ArrayList<>(); // 遍历reserves进行拆分处理 for (ShipmentReserveVo reserve : reserves) { - // 使用 site|partNo 格式查找(假设 contract=site, inventoryPartNo=partNo,所以 key 值相同) String key = reserve.getSite() + "|" + reserve.getPartNo(); - List matchedLines = lineMap.get(key); + Queue queue = lineQueueMap.get(key); + if (queue == null || queue.isEmpty()) { + throw new IllegalStateException("未找到匹配的ShipmentLine用于分配数量,key=" + key); + } + + BigDecimal remainingReserve = reserve.getTransQty(); + while (remainingReserve.compareTo(BigDecimal.ZERO) > 0) { + LineAllocation current = queue.peek(); + if (current == null) { + throw new IllegalStateException("可分配数量不足,key=" + key); + } - if (matchedLines != null && !matchedLines.isEmpty()) { - // 执行拆分并赋值 - for (ShipmentLineVo line : matchedLines) { - result.add(createSplitReserve(reserve, line)); + BigDecimal alloc = remainingReserve.min(current.remaining); + + ShipmentReserveVo split = new ShipmentReserveVo(); + BeanUtils.copyProperties(reserve, split); + split.setTransQty(alloc); + split.setIfsSourceRef1(current.line.getSourceRef1()); + split.setIfsSourceRef2(current.line.getSourceRef2()); + split.setIfsSourceRef3(current.line.getSourceRef3()); + split.setIfsInputUoM(current.line.getInventoryUom()); + split.setIfsBlockedForPickByChoice(current.line.getCreditBlocked()); + result.add(split); + + // 更新剩余量 + remainingReserve = remainingReserve.subtract(alloc); + current.remaining = current.remaining.subtract(alloc); + if (current.remaining.compareTo(BigDecimal.ZERO) == 0) { + queue.poll(); } - } else { - // 处理无匹配lines的情况(保留原始对象) - result.add(reserve); } } return result; @@ -345,22 +368,14 @@ public class CustomerIssueServiceImpl implements CustomerIssueService { .reduce(BigDecimal.ZERO, BigDecimal::add); } - private ShipmentReserveVo createSplitReserve(ShipmentReserveVo reserve, ShipmentLineVo line) { - // 创建新对象并复制基础字段 - ShipmentReserveVo split = new ShipmentReserveVo(); - BeanUtils.copyProperties(reserve, split); - - // 设置拆分后的数量 - split.setTransQty(line.getInventoryQty().subtract(line.getQtyAssigned())); + private static class LineAllocation { + private ShipmentLineVo line; + private BigDecimal remaining; - // 从line复制附加字段 - split.setIfsSourceRef1(line.getSourceRef1()); - split.setIfsSourceRef2(line.getSourceRef2()); - split.setIfsSourceRef3(line.getSourceRef3()); - split.setIfsInputUoM(line.getInventoryUom()); - split.setIfsBlockedForPickByChoice(line.getCreditBlocked()); - - return split; + LineAllocation(ShipmentLineVo line, BigDecimal remaining) { + this.line = line; + this.remaining = remaining; + } } public List mapShipmentData(List reserves, List lines) {