diff --git a/src/main/java/com/xujie/sys/modules/erf/data/ErfExpIssueData.java b/src/main/java/com/xujie/sys/modules/erf/data/ErfExpIssueData.java index 50a51762..4a4df603 100644 --- a/src/main/java/com/xujie/sys/modules/erf/data/ErfExpIssueData.java +++ b/src/main/java/com/xujie/sys/modules/erf/data/ErfExpIssueData.java @@ -90,6 +90,13 @@ public class ErfExpIssueData implements Serializable { */ private String remark; + /** + * 计划发料时间,落库 SOIssueNotifyHeader.PlanIssueDate;未传时取明细最早要求发料时间 + */ + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm", timezone = "GMT+8") + private Date planIssueDate; + /** * 查询页码 */ diff --git a/src/main/java/com/xujie/sys/modules/erf/data/ErfExpIssueMaterialData.java b/src/main/java/com/xujie/sys/modules/erf/data/ErfExpIssueMaterialData.java index 9274f716..09140afd 100644 --- a/src/main/java/com/xujie/sys/modules/erf/data/ErfExpIssueMaterialData.java +++ b/src/main/java/com/xujie/sys/modules/erf/data/ErfExpIssueMaterialData.java @@ -89,4 +89,21 @@ public class ErfExpIssueMaterialData implements Serializable { * 单位 */ private String umid; + + /** + * 现场库存(与领料申请BOM子表 qtyOnHand 同源) + */ + private Double qtyOnHand; + + /** + * ERP库存(与领料申请BOM子表 stockQty 同源) + */ + private Double stockQty; + + /** + * 要求发料时间,落库 SOIssueNotifyOrderList.needDate + */ + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm", timezone = "GMT+8") + private Date needDate; } 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 cd687c50..8b2fc686 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 @@ -24,6 +24,7 @@ import org.springframework.util.StringUtils; import java.math.BigDecimal; import java.util.ArrayList; +import java.util.Comparator; import java.util.Date; import java.util.LinkedHashMap; import java.util.List; @@ -182,13 +183,19 @@ public class ErfExpIssueServiceImpl implements ErfExpIssueService { throw new XJException(String.format("试验单[%s]物料[%s]的本次领料数量超过可申请数量(%s)", dbItem.getApplyNo(), resolvePartText(dbItem), formatQty(availableQty))); } + if (inputItem.getNeedDate() == null) { + throw new XJException(String.format("试验单[%s]物料[%s]的要求发料时间不能为空", + dbItem.getApplyNo(), resolvePartText(dbItem))); + } issueQtyMap.put(rawMaterialId, issueQty); + dbItem.setNeedDate(inputItem.getNeedDate()); validatedMaterialList.add(dbItem); } + Date planIssueDate = resolvePlanIssueDate(data, validatedMaterialList); String finalUserName = StringUtils.hasText(userName) ? userName : "system"; - String notifyNo = createErfNotifyNo(site, finalUserName, data.getRemark()); + String notifyNo = createErfNotifyNo(site, finalUserName, data.getRemark(), planIssueDate); int createdOrderCount = 0; int createdMaterialCount = 0; @@ -235,7 +242,7 @@ public class ErfExpIssueServiceImpl implements ErfExpIssueService { * 2. 写入OrderType类型标记 * 3. 默认状态设为已下达 */ - private String createErfNotifyNo(String site, String userName, String remark) { + private String createErfNotifyNo(String site, String userName, String remark, Date planIssueDate) { SOIssueNotifyHeaderData createData = new SOIssueNotifyHeaderData(); createData.setSite(site); createData.setUserName(userName); @@ -262,7 +269,8 @@ public class ErfExpIssueServiceImpl implements ErfExpIssueService { SOIssueNotifyHeaderData xiadaData = new SOIssueNotifyHeaderData(); xiadaData.setSite(site); xiadaData.setNotifyNo(notifyNo); - xiadaData.setPlanIssueDate(new Date()); + // 主表计划发料时间与明细要求发料时间对齐,默认取明细最早时间 + xiadaData.setPlanIssueDate(planIssueDate == null ? new Date() : planIssueDate); xiadaData.setRemark(StringUtils.hasText(remark) ? remark : ERF_NOTIFY_DEFAULT_REMARK); issureNotifyService.xiadaNotifyHeader(xiadaData); return notifyNo; @@ -342,12 +350,32 @@ public class ErfExpIssueServiceImpl implements ErfExpIssueService { private Date resolveNeedDate(ErfExpIssueMaterialData materialItem) { + if (materialItem != null && materialItem.getNeedDate() != null) { + return materialItem.getNeedDate(); + } if (materialItem != null && materialItem.getScheduledDate() != null) { return materialItem.getScheduledDate(); } return new Date(); } + /** + * 主表 PlanIssueDate:前端显式传入优先,否则取明细最早要求发料时间 + */ + private Date resolvePlanIssueDate(ErfExpIssueData data, List materialList) { + if (data != null && data.getPlanIssueDate() != null) { + return data.getPlanIssueDate(); + } + if (CollectionUtils.isEmpty(materialList)) { + return new Date(); + } + return materialList.stream() + .map(ErfExpIssueMaterialData::getNeedDate) + .filter(needDate -> needDate != null) + .min(Comparator.naturalOrder()) + .orElse(new Date()); + } + private String buildMaterialRemark(ErfExpIssueMaterialData item) { if (item == null) { return "ERF试验单领料"; diff --git a/src/main/resources/mapper/erf/ErfExpIssueMapper.xml b/src/main/resources/mapper/erf/ErfExpIssueMapper.xml index e1302449..53ed5174 100644 --- a/src/main/resources/mapper/erf/ErfExpIssueMapper.xml +++ b/src/main/resources/mapper/erf/ErfExpIssueMapper.xml @@ -30,6 +30,8 @@ + + @@ -105,7 +107,8 @@ rm.part_desc, rm.quantity AS required_qty, ISNULL(issue_sum.issued_qty, 0) AS issued_qty, - rm.umid + rm.umid, + ISNULL(stock.stock_qty, 0) AS stock_qty FROM erf_exp_raw_material rm INNER JOIN erf_exp_apply ap ON ap.apply_no = rm.apply_no LEFT JOIN ( @@ -119,6 +122,14 @@ AND m.BOMItemNo LIKE 'ERF-%' GROUP BY m.BOMItemNo ) issue_sum ON issue_sum.BOMItemNo = ('ERF-' + CONVERT(VARCHAR(20), rm.id)) + LEFT JOIN ( + SELECT + h.site, + h.part_no, + ROUND(SUM(ISNULL(h.qty_on_hand, 0)), 2) AS stock_qty + FROM view_custdev_currentstock h + GROUP BY h.site, h.part_no + ) stock ON stock.site = rm.site AND stock.part_no = rm.part_no WHERE rm.is_deleted = '0' AND (ISNULL(rm.quantity, 0) - ISNULL(issue_sum.issued_qty, 0)) > 0 AND rm.apply_no IN @@ -141,7 +152,9 @@ rm.part_desc, rm.quantity AS required_qty, ISNULL(issue_sum.issued_qty, 0) AS issued_qty, - rm.umid + rm.umid, + ROUND(dbo.get_MaterialOnUse(rm.site, rm.apply_no + '#1', 0, rm.part_no), 3) AS qty_on_hand, + ISNULL(stock.stock_qty, 0) AS stock_qty FROM erf_exp_raw_material rm INNER JOIN erf_exp_apply ap ON ap.apply_no = rm.apply_no LEFT JOIN ( @@ -155,6 +168,14 @@ AND m.BOMItemNo LIKE 'ERF-%' GROUP BY m.BOMItemNo ) issue_sum ON issue_sum.BOMItemNo = ('ERF-' + CONVERT(VARCHAR(20), rm.id)) + LEFT JOIN ( + SELECT + h.site, + h.part_no, + ROUND(SUM(ISNULL(h.qty_on_hand, 0)), 2) AS stock_qty + FROM view_custdev_currentstock h + GROUP BY h.site, h.part_no + ) stock ON stock.site = rm.site AND stock.part_no = rm.part_no WHERE rm.is_deleted = '0' AND rm.id IN