From 1c2e761d1d359aa8f8eb58147699da76f699574b Mon Sep 17 00:00:00 2001 From: "han\\hanst" Date: Thu, 22 Oct 2026 14:35:44 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=9B=E5=BB=BA=E9=A2=86=E6=96=99=E5=8D=95?= =?UTF-8?q?=E6=97=B6=EF=BC=8C=E5=90=8C=E4=B8=80=E8=AF=95=E9=AA=8C=E5=8D=95?= =?UTF-8?q?=E7=9A=84=E5=90=8C=E4=B8=80=E5=B7=A5=E5=BA=8F=E7=8E=B0=E5=9C=A8?= =?UTF-8?q?=E5=8F=AA=E5=86=99=E4=B8=80=E6=9D=A1=20SOIssueNotifyOrderList?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/impl/ErfExpIssueServiceImpl.java | 71 ++++++++++++++++--- 1 file changed, 61 insertions(+), 10 deletions(-) diff --git a/src/main/java/com/xujie/sys/modules/erf/service/impl/ErfExpIssueServiceImpl.java b/src/main/java/com/xujie/sys/modules/erf/service/impl/ErfExpIssueServiceImpl.java index 8b2fc686..72cf3985 100644 --- a/src/main/java/com/xujie/sys/modules/erf/service/impl/ErfExpIssueServiceImpl.java +++ b/src/main/java/com/xujie/sys/modules/erf/service/impl/ErfExpIssueServiceImpl.java @@ -38,7 +38,7 @@ import java.util.stream.Collectors; * * * @author System @@ -197,19 +197,40 @@ public class ErfExpIssueServiceImpl implements ErfExpIssueService { String finalUserName = StringUtils.hasText(userName) ? userName : "system"; String notifyNo = createErfNotifyNo(site, finalUserName, data.getRemark(), planIssueDate); - int createdOrderCount = 0; - int createdMaterialCount = 0; + // 同一试验单的同一工序只建一条工单行。按原材料逐条建会把同一工序拆成多条 SOIssueNotifyOrderList。 + Map> processGroupMap = new LinkedHashMap<>(); for (ErfExpIssueMaterialData materialItem : validatedMaterialList) { if (materialItem == null || materialItem.getRawMaterialId() == null) { continue; } - BigDecimal issueQty = safeDecimal(issueQtyMap.get(materialItem.getRawMaterialId())); + String groupKey = buildProcessGroupKey(materialItem); + List groupList = processGroupMap.get(groupKey); + if (groupList == null) { + groupList = new ArrayList<>(); + processGroupMap.put(groupKey, groupList); + } + groupList.add(materialItem); + } + + int createdOrderCount = 0; + int createdMaterialCount = 0; + for (List processMaterials : processGroupMap.values()) { + if (CollectionUtils.isEmpty(processMaterials)) { + continue; + } + ErfExpIssueMaterialData headerMaterial = processMaterials.get(0); + // 工单行领取数量是该工序下各原材料本次领料数量的合计,物料行仍各自保存自己的数量。 + BigDecimal orderIssueQty = resolveProcessIssueQty(processMaterials, issueQtyMap); - SOIssueNotifyOrderList orderData = buildNotifyOrderList(notifyNo, site, materialItem, issueQty); + SOIssueNotifyOrderList orderData = buildNotifyOrderList(notifyNo, site, headerMaterial, orderIssueQty); Double itemNo = issureNotifyService.saveSOIssueNotifyOrderList(orderData); - List saveMaterialList = - buildNotifyMaterialList(notifyNo, site, itemNo, materialItem, issueQty); + // saveMaterialDetail 会先按 ItemNo 删掉已有物料再整批插入,必须一次提交该工序的全部物料。 + List saveMaterialList = new ArrayList<>(); + for (ErfExpIssueMaterialData materialItem : processMaterials) { + BigDecimal issueQty = safeDecimal(issueQtyMap.get(materialItem.getRawMaterialId())); + saveMaterialList.addAll(buildNotifyMaterialList(notifyNo, site, itemNo, materialItem, issueQty)); + } issureNotifyService.saveMaterialDetail(saveMaterialList); createdOrderCount++; @@ -220,7 +241,7 @@ public class ErfExpIssueServiceImpl implements ErfExpIssueService { throw new XJException("未生成任何领料明细,请检查后重试"); } - log.info("创建试验单领料单成功(复用SOIssueNotify表): notifyNo={}, 派工单条数={}, 物料条数={}, 操作人ID={}", + log.info("创建试验单领料单成功(复用SOIssueNotify表): notifyNo={}, 工序条数={}, 物料条数={}, 操作人ID={}", notifyNo, createdOrderCount, createdMaterialCount, userId); return notifyNo; } @@ -277,7 +298,37 @@ public class ErfExpIssueServiceImpl implements ErfExpIssueService { } /** - * 组装SOIssueNotifyOrderList(按原材料一条一建) + * 同一试验单、同一工序共用一条工单行。 + * 不同试验单即使工序名称相同也不能合并,工单号和成品料号都按试验单取。 + * 工序为空时按原材料拆开,避免未维护工序的物料被误合并。 + */ + private String buildProcessGroupKey(ErfExpIssueMaterialData materialItem) { + String applyNo = materialItem.getApplyNo() == null ? "" : materialItem.getApplyNo().trim(); + String processStep = materialItem.getProcessStep() == null ? "" : materialItem.getProcessStep().trim(); + if (!StringUtils.hasText(processStep)) { + return applyNo + "||__RM__||" + materialItem.getRawMaterialId(); + } + return applyNo + "||" + processStep; + } + + /** + * 工单行领取数量等于该工序下原材料本次领料数量之和。 + * 物料行 QtyToIssue 仍按各自数量写入,不因为合并工单行而改掉单物料数量。 + */ + private BigDecimal resolveProcessIssueQty(List processMaterials, + Map issueQtyMap) { + BigDecimal processIssueQty = BigDecimal.ZERO; + for (ErfExpIssueMaterialData materialItem : processMaterials) { + if (materialItem == null || materialItem.getRawMaterialId() == null) { + continue; + } + processIssueQty = processIssueQty.add(safeDecimal(issueQtyMap.get(materialItem.getRawMaterialId()))); + } + return processIssueQty; + } + + /** + * 组装SOIssueNotifyOrderList(按工序一条一建) */ private SOIssueNotifyOrderList buildNotifyOrderList(String notifyNo, String site, @@ -303,7 +354,7 @@ public class ErfExpIssueServiceImpl implements ErfExpIssueService { } /** - * 组装SOIssueNotifyOrderMaterialList(按原材料一条一建) + * 组装SOIssueNotifyOrderMaterialList(同一工序下每条原材料一行,ItemNo 与工单行一致) */ private List buildNotifyMaterialList(String notifyNo, String site,