|
|
|
@ -38,7 +38,7 @@ import java.util.stream.Collectors; |
|
|
|
* <ul> |
|
|
|
* <li>创建领料单复用 newSoIssueNotify 同一套表:SOIssueNotifyHeader / SOIssueNotifyOrderList / SOIssueNotifyOrderMaterialList</li> |
|
|
|
* <li>ERF试验单领料每次单独创建领料单,创建后默认状态=已下达,并写入单据类型标记</li> |
|
|
|
* <li>ERF领料创建时按原材料逐条落地:1条原材料对应1条SOIssueNotifyOrderList和1条SOIssueNotifyOrderMaterialList</li> |
|
|
|
* <li>ERF领料按工序落地:同一试验单的同一工序只建1条SOIssueNotifyOrderList,该工序下每条原材料对应1条SOIssueNotifyOrderMaterialList,并共用同一个ItemNo</li> |
|
|
|
* </ul> |
|
|
|
* |
|
|
|
* @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<String, List<ErfExpIssueMaterialData>> 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<ErfExpIssueMaterialData> 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<ErfExpIssueMaterialData> 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<SOIssueNotifyOrderMaterialListData> saveMaterialList = |
|
|
|
buildNotifyMaterialList(notifyNo, site, itemNo, materialItem, issueQty); |
|
|
|
// saveMaterialDetail 会先按 ItemNo 删掉已有物料再整批插入,必须一次提交该工序的全部物料。 |
|
|
|
List<SOIssueNotifyOrderMaterialListData> 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<ErfExpIssueMaterialData> processMaterials, |
|
|
|
Map<Integer, BigDecimal> 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<SOIssueNotifyOrderMaterialListData> buildNotifyMaterialList(String notifyNo, |
|
|
|
String site, |
|
|
|
|