diff --git a/src/main/java/com/xujie/sys/modules/ecss/service/impl/CoDelServiceImpl.java b/src/main/java/com/xujie/sys/modules/ecss/service/impl/CoDelServiceImpl.java index 67c65436..15f43a17 100644 --- a/src/main/java/com/xujie/sys/modules/ecss/service/impl/CoDelServiceImpl.java +++ b/src/main/java/com/xujie/sys/modules/ecss/service/impl/CoDelServiceImpl.java @@ -213,46 +213,63 @@ public class CoDelServiceImpl implements CoDelService { if (parts.isEmpty()) { throw new RuntimeException("修改失败:物料:" + data.getPn() + "不存在!"); } + // 只有料号或数量变化才清装箱。新增明细视为数量变化;只改单价、备注等字段时必须传 false。 + boolean pnOrQtyModified = false; if (data.getAddFlag()==1) { List ecssCoDelNotifyDetail = coDelMapper.getEcssCoDelNotifyDetail(data); if (ecssCoDelNotifyDetail.isEmpty()){ throw new RuntimeException("该发货通知单明细不存在"); - } else if (checkHeader.getFirst().getBuNo().equals("03-RFID") || checkHeader.getFirst().getBuNo().equals("01-Label")) { - // 判断数量是否变化 - boolean qtyChanged = ecssCoDelNotifyDetail.get(0).getQty().compareTo(data.getQty()) != 0; - // 判断PN是否变化 - boolean pnChanged = !ecssCoDelNotifyDetail.get(0).getPn().equals(data.getPn()); - - if (qtyChanged || pnChanged) { - data.setModifyFlag(true); - - // 只有数量变化时才设置 modifyQtyFlag=true - if (qtyChanged) { - data.setModifyQtyFlag(true); - } + } + EcssCoDelNotifyDetailData currentDetail = ecssCoDelNotifyDetail.get(0); + boolean qtyChanged = currentDetail.getQty() == null || data.getQty() == null + ? !Objects.equals(currentDetail.getQty(), data.getQty()) + : currentDetail.getQty().compareTo(data.getQty()) != 0; + boolean pnChanged = !Objects.equals(currentDetail.getPn(), data.getPn()); + pnOrQtyModified = qtyChanged || pnChanged; + if ((checkHeader.getFirst().getBuNo().equals("03-RFID") || checkHeader.getFirst().getBuNo().equals("01-Label")) + && pnOrQtyModified) { + data.setModifyFlag(true); + + // 只有数量变化时才设置 modifyQtyFlag=true + if (qtyChanged) { + data.setModifyQtyFlag(true); + } - // 取消订单 通知仓库和单证人员 - //设置邮件内容 - String text = "" + "
发货通知单" +data.getDelNo()+"【发票:"+ data.getCmcInvoice()+"】改单" + "
"+ - "
PN:" + data.getPn() + "发货数量变更,"+" 变更前数量:"+ - ecssCoDelNotifyDetail.get(0).getQty().setScale(0, RoundingMode.HALF_UP)+"" - +" 变更后数量:"+data.getQty()+"
"; - String textHead = data.getDelNo()+"【发票:"+ data.getCmcInvoice()+"】改单[发货数量变更]"; - String[] mailAddress = coDelMapper.queryUsersByRoleName("关务仓库",data.getSite()).stream() - .filter(Objects::nonNull).map(SysUserEntity::getEmail).toArray(String[]::new); - - // 安全获取创建人邮箱,防止用户不存在或邮箱为空的空指针异常 - SysUserEntity creator = coDelMapper.queryByUserName(checkHeader.get(0).getCreateBy()); - String[] mailAddress2 = (creator != null && creator.getEmail() != null) ? - new String[]{creator.getEmail()} : new String[]{}; - String[] mailAddressAll = ArrayUtils.addAll(mailAddress, mailAddress2); - if (mailAddressAll.length>0) { - sendMailUtil(textHead, text,mailAddressAll, checkHeader.get(0)); - } + // 取消订单 通知仓库和单证人员 + //设置邮件内容 + String oldQtyText = currentDetail.getQty() == null ? "" : currentDetail.getQty().setScale(0, RoundingMode.HALF_UP).toString(); + String text = "" + "
发货通知单" +data.getDelNo()+"【发票:"+ data.getCmcInvoice()+"】改单" + "
"+ + "
PN:" + data.getPn() + "发货数量变更,"+" 变更前数量:"+ + oldQtyText+"" + +" 变更后数量:"+data.getQty()+"
"; + String textHead = data.getDelNo()+"【发票:"+ data.getCmcInvoice()+"】改单[发货数量变更]"; + String[] mailAddress = coDelMapper.queryUsersByRoleName("关务仓库",data.getSite()).stream() + .filter(Objects::nonNull).map(SysUserEntity::getEmail).toArray(String[]::new); + + // 安全获取创建人邮箱,防止用户不存在或邮箱为空的空指针异常 + SysUserEntity creator = coDelMapper.queryByUserName(checkHeader.get(0).getCreateBy()); + String[] mailAddress2 = (creator != null && creator.getEmail() != null) ? + new String[]{creator.getEmail()} : new String[]{}; + String[] mailAddressAll = ArrayUtils.addAll(mailAddress, mailAddress2); + if (mailAddressAll.length>0) { + sendMailUtil(textHead, text,mailAddressAll, checkHeader.get(0)); } } coDelMapper.updateEcssDelDetail(data); + // update 会把当前行 surplus_qty 写成订单数量。料号和数量都没变时装箱还在,必须写回原剩余量。 + if ((checkHeader.getFirst().getBuNo().equals("03-RFID") || checkHeader.getFirst().getBuNo().equals("01-Label")) + && !pnOrQtyModified) { + EcssCoDelNotifyDetailData surplusData = new EcssCoDelNotifyDetailData(); + surplusData.setSite(data.getSite()); + surplusData.setBuNo(StringUtils.isNotBlank(data.getBuNo()) ? data.getBuNo() : currentDetail.getBuNo()); + surplusData.setDelNo(data.getDelNo()); + surplusData.setPartNo(StringUtils.isNotBlank(data.getPartNo()) ? data.getPartNo() : currentDetail.getPartNo()); + surplusData.setItemNo(data.getItemNo()); + surplusData.setSurplusQty(currentDetail.getSurplusQty()); + coDelMapper.updateEcssCoDelNotifyDetailSurplus(surplusData); + } } else { + pnOrQtyModified = true; String site = coDelMapper.getSiteByBu(data.getBuNo()); data.setSite(site); int itemNo = coDelMapper.getEcssDelDetailItemNo(data); @@ -283,9 +300,9 @@ public class CoDelServiceImpl implements CoDelService { header.setDelNo(data.getDelNo()); header.setModifyFlag(true); coDelMapper.updateEcssDelHeaderForModify(header); - // 改单导入后的状态处理逻辑 - 新增/修改发货涉及PN/Qty变化 + // 新增明细,或修改了料号/数量:清装箱并还原全部剩余数量。只改其他字段:保留装箱。 if (checkHeader.getFirst().getBuNo().equals("03-RFID") || checkHeader.getFirst().getBuNo().equals("01-Label")){ - handleNotifyStatusAfterModify(checkHeader.get(0), true); + handleNotifyStatusAfterModify(checkHeader.get(0), pnOrQtyModified); } } @@ -2996,13 +3013,12 @@ public class CoDelServiceImpl implements CoDelService { *

处理逻辑:

* * * @param headerData 发货通知单头数据 * @param isPnOrQtyModified 是否修改了PN/Qty或删除了PN - * @author AI Assistant * @date 2024-10-09 */ private void handleNotifyStatusAfterModify(EcssCoDelNotifyHeaderData headerData, boolean isPnOrQtyModified) { @@ -3041,7 +3057,10 @@ public class CoDelServiceImpl implements CoDelService { inData.setBuNo(headerData.getBuNo()); inData.setDelNo(headerData.getDelNo()); coDelMapper.deletePalletHeader(inData); - log.info("发货通知单{}状态已更新为已下达,托盘数据已删除", headerData.getDelNo()); + // 装箱是整单删除,剩余可装箱数量也必须整单还原。 + // 单行修改的 update 只会把当前行 surplus_qty 写成新数量,其他行仍停在装箱扣减后的值,后续无法再装。 + coDelMapper.restoreEcssDelDetailSurplusQty(headerData); + log.info("发货通知单{}状态已更新为已下达,托盘数据已删除,有效明细剩余可装箱数量已还原为订单数量", headerData.getDelNo()); } else { // 仅修改了其他字段(Destination、Shipping Mode、Currency、TP等):不删除托盘数据,状态更新为"仓库已确认" log.info("仅修改了其他字段(Destination、Shipping Mode、Currency、TP等),保留托盘数据并将状态更新为仓库已确认"); diff --git a/src/main/resources/mapper/ecss/CoDelMapper.xml b/src/main/resources/mapper/ecss/CoDelMapper.xml index 073ced34..fb4e7e21 100644 --- a/src/main/resources/mapper/ecss/CoDelMapper.xml +++ b/src/main/resources/mapper/ecss/CoDelMapper.xml @@ -169,7 +169,7 @@ select a.site,a.bu_no,a.delNo,a.item_no,a.salesOrder,a.salesOrder_item_no,a.customerPO,a.line,a.version,a.status,a.family, a.part_no,a.part_description,a.qty,a.lt,a.cmc_comment,a.saleType,a.awb_bl,a.shipping_number,a.forwarder_info, a.currency,a.tp,a.ttl_amount,a.sum_price,a.so,a.upc,a.remark,a.erp_delItemNo,a.pn,CONVERT(DECIMAL(20, 0),a.nocartons) as nocartons, - a.modifyFlag,a.modifyQtyFlag + a.modifyFlag,a.modifyQtyFlag,a.surplus_qty from ecss_CoDelNotifydetail a And a.site = #{site}