diff --git a/src/main/java/com/gaotao/modules/otherOutbound/controller/OtherOutboundController.java b/src/main/java/com/gaotao/modules/otherOutbound/controller/OtherOutboundController.java index 53ac343..166b4fd 100644 --- a/src/main/java/com/gaotao/modules/otherOutbound/controller/OtherOutboundController.java +++ b/src/main/java/com/gaotao/modules/otherOutbound/controller/OtherOutboundController.java @@ -39,18 +39,13 @@ public class OtherOutboundController extends AbstractController { if (warehouseId == null || warehouseId.trim().isEmpty()) { return R.error("仓库ID不能为空"); } - // 默认状态为待出库 if (status == null || status.trim().isEmpty()) { status = "待出库"; } - logger.info("获取其他出库单列表,站点: {}, 仓库: {}, 搜索码: {}, 状态: {}", - site, warehouseId, searchCode, status); - - List> list = otherOutboundService.getOutboundList( - site, warehouseId, searchCode, status); - + logger.info("获取其他出库单列表,站点: {}, 仓库: {}, 搜索码: {}, 状态: {}", site, warehouseId, searchCode, status); + List> list = otherOutboundService.getOutboundList(site, warehouseId, searchCode, status); return R.ok().put("data", list); } catch (Exception e) { logger.error("获取其他出库单列表失败", e); @@ -78,13 +73,10 @@ public class OtherOutboundController extends AbstractController { return R.error("仓库ID不能为空"); } - Map result = otherOutboundService.getOutboundDetails( - outboundNo, buNo, warehouseId, site); - + Map result = otherOutboundService.getOutboundDetails(outboundNo, buNo, warehouseId, site); if (result == null || result.isEmpty()) { return R.error("未找到出库单详情"); } - return R.ok().put("data", result); } catch (Exception e) { logger.error("获取其他出库单详情失败", e); @@ -113,9 +105,7 @@ public class OtherOutboundController extends AbstractController { return R.error("出库单号不能为空"); } - Map result = otherOutboundService.validateLabelWithOutbound( - labelCode, outboundNo, warehouseId, site, buNo); - + Map result = otherOutboundService.validateLabelWithOutbound(labelCode, outboundNo, warehouseId, site, buNo); return R.ok().put("data", result); } catch (Exception e) { logger.error("其他出库标签验证失败", e); @@ -144,11 +134,9 @@ public class OtherOutboundController extends AbstractController { if (outboundNo == null || outboundNo.trim().isEmpty()) { return R.error("出库单号不能为空"); } - if (warehouseId == null || warehouseId.trim().isEmpty()) { return R.error("仓库ID不能为空"); } - if (labels == null || labels.isEmpty()) { return R.error("标签列表不能为空"); } @@ -161,9 +149,7 @@ public class OtherOutboundController extends AbstractController { } } - boolean success = otherOutboundService.confirmOtherOutbound( - site, buNo, outboundNo, warehouseId, labels); - + boolean success = otherOutboundService.confirmOtherOutbound(site, buNo, outboundNo, warehouseId, labels); if (success) { return R.ok("出库成功"); } else { @@ -171,7 +157,7 @@ public class OtherOutboundController extends AbstractController { } } catch (Exception e) { logger.error("其他出库失败", e); - return R.error("出库失败: " + e.getMessage()); + return R.error(e.getMessage()); } } diff --git a/src/main/java/com/gaotao/modules/otherOutbound/dao/OtherOutboundMapper.java b/src/main/java/com/gaotao/modules/otherOutbound/dao/OtherOutboundMapper.java index dedb253..16bece1 100644 --- a/src/main/java/com/gaotao/modules/otherOutbound/dao/OtherOutboundMapper.java +++ b/src/main/java/com/gaotao/modules/otherOutbound/dao/OtherOutboundMapper.java @@ -19,9 +19,10 @@ public interface OtherOutboundMapper extends BaseMapper { * @return 出库单列表 */ List> getOutboundList(@Param("site") String site, - @Param("warehouseId") String warehouseId, - @Param("searchCode") String searchCode, - @Param("status") String status); + @Param("warehouseId") String warehouseId, + @Param("searchCode") String searchCode, + @Param("status") String status, + @Param("userName") String userName); /** * 获取其他出库单详情 diff --git a/src/main/java/com/gaotao/modules/otherOutbound/service/impl/OtherOutboundServiceImpl.java b/src/main/java/com/gaotao/modules/otherOutbound/service/impl/OtherOutboundServiceImpl.java index d1163b2..2f5c22a 100644 --- a/src/main/java/com/gaotao/modules/otherOutbound/service/impl/OtherOutboundServiceImpl.java +++ b/src/main/java/com/gaotao/modules/otherOutbound/service/impl/OtherOutboundServiceImpl.java @@ -3,11 +3,15 @@ package com.gaotao.modules.otherOutbound.service.impl; import com.gaotao.modules.otherOutbound.dao.OtherOutboundMapper; import com.gaotao.modules.otherOutbound.service.OtherOutboundService; import com.gaotao.modules.inventoryStock.service.InventoryStockService; +import com.gaotao.modules.sys.entity.SysUserEntity; import com.gaotao.modules.trans.entity.TransDetail; import com.gaotao.modules.trans.entity.TransDetailDto; +import com.gaotao.modules.trans.entity.TransDetailSub; import com.gaotao.modules.trans.entity.TransHeader; import com.gaotao.modules.trans.service.TransDetailService; +import com.gaotao.modules.trans.service.TransDetailSubService; import com.gaotao.modules.trans.service.TransHeaderService; +import org.apache.shiro.SecurityUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -16,6 +20,7 @@ import org.springframework.transaction.annotation.Transactional; import java.math.BigDecimal; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Map; @@ -39,13 +44,16 @@ public class OtherOutboundServiceImpl implements OtherOutboundService { @Autowired private TransDetailService transDetailService; + @Autowired + private TransDetailSubService transDetailSubService; + @Override public List> getOutboundList(String site, String warehouseId, String searchCode, String status) { + SysUserEntity sysUserEntity = (SysUserEntity) SecurityUtils.getSubject().getPrincipal(); try { - logger.info("获取其他出库单列表,站点: {}, 仓库: {}, 搜索码: {}, 状态: {}", - site, warehouseId, searchCode, status); + logger.info("获取其他出库单列表,站点: {}, 仓库: {}, 搜索码: {}, 状态: {}", site, warehouseId, searchCode, status); - List> list = otherOutboundMapper.getOutboundList(site, warehouseId, searchCode, status); + List> list = otherOutboundMapper.getOutboundList(site, warehouseId, searchCode, status, sysUserEntity.getUsername()); logger.info("获取其他出库单列表成功,共{}条记录", list != null ? list.size() : 0); return list != null ? list : new ArrayList<>(); @@ -58,17 +66,14 @@ public class OtherOutboundServiceImpl implements OtherOutboundService { @Override public Map getOutboundDetails(String outboundNo, String buNo, String warehouseId, String site) { try { - logger.info("获取其他出库单详情,出库单号: {}, 业务单元: {}, 仓库: {}, 站点: {}", - outboundNo, buNo, warehouseId, site); + logger.info("获取其他出库单详情,出库单号: {}, 业务单元: {}, 仓库: {}, 站点: {}", outboundNo, buNo, warehouseId, site); Map details = otherOutboundMapper.getOutboundDetails(outboundNo, buNo, warehouseId, site); - if (details != null) { logger.info("获取其他出库单详情成功"); } else { logger.warn("未找到出库单详情"); } - return details; } catch (Exception e) { logger.error("获取其他出库单详情失败", e); @@ -77,28 +82,21 @@ public class OtherOutboundServiceImpl implements OtherOutboundService { } @Override - public Map validateLabelWithOutbound(String labelCode, String outboundNo, - String warehouseId, String site, String buNo) { + public Map validateLabelWithOutbound(String labelCode, String outboundNo, String warehouseId, String site, String buNo) { try { - logger.info("验证标签与其他出库单匹配,标签: {}, 出库单: {}, 仓库: {}, 站点: {}, 业务单元: {}", - labelCode, outboundNo, warehouseId, site, buNo); + logger.info("验证标签与其他出库单匹配,标签: {}, 出库单: {}, 仓库: {}, 站点: {}, 业务单元: {}", labelCode, outboundNo, warehouseId, site, buNo); - Map result = otherOutboundMapper.validateLabelWithOutbound( - labelCode, outboundNo, warehouseId, site, buNo); + Map result = otherOutboundMapper.validateLabelWithOutbound(labelCode, outboundNo, warehouseId, site, buNo); if (result == null || result.isEmpty()) { throw new RuntimeException("该标签与出库单不匹配或标签状态不正确"); } - // 检查标签状态,只有"在库"状态的标签才能出库 String labelStatus = (String) result.get("status"); if (!"在库".equals(labelStatus)) { throw new RuntimeException("标签状态为:" + labelStatus + ",无法出库"); } - - logger.info("标签验证成功,物料编码: {}, 数量: {}", - result.get("partNo"), result.get("quantity")); - + logger.info("标签验证成功,物料编码: {}, 数量: {}", result.get("partNo"), result.get("quantity")); return result; } catch (Exception e) { logger.error("验证标签与其他出库单匹配失败", e); @@ -108,10 +106,8 @@ public class OtherOutboundServiceImpl implements OtherOutboundService { @Override @Transactional(rollbackFor = Exception.class) - public boolean confirmOtherOutbound(String site, String buNo, String outboundNo, - String warehouseId, List> labels) { - logger.info("开始确认其他出库,出库单号: {}, 仓库ID: {}, 标签数量: {}", - outboundNo, warehouseId, labels.size()); + public boolean confirmOtherOutbound(String site, String buNo, String outboundNo, String warehouseId, List> labels) { + logger.info("开始确认其他出库,出库单号: {}, 仓库ID: {}, 标签数量: {}", outboundNo, warehouseId, labels.size()); try { // 1. 更新库存表中的标签状态为"已出库" List labelCodes = new ArrayList<>(); @@ -188,42 +184,38 @@ public class OtherOutboundServiceImpl implements OtherOutboundService { // 构建TransDetailDto对象 TransDetailDto transDetailDto = new TransDetailDto(); transDetailDto.setSite(site); // 站点 - transDetailDto.setRemark("其他出库 - " + outboundNo); + transDetailDto.setRemark("拣货出库"); transDetailDto.setOrderref1(outboundNo); // 出库单号 transDetailDto.setOrderref3(warehouseId); // 仓库ID // 使用TransHeaderService的genTrans方法生成事务头 TransHeader transHeader = transHeaderService.genTrans(transDetailDto, "OUT", warehouseId,buNo); - if (transHeader == null) { throw new RuntimeException("生成事务头记录失败"); } - logger.info("事务头记录生成成功,事务单号: {}", transHeader.getTransno()); // 生成事务明细记录 - generateTransactionDetails(transHeader.getTransno(), labels, site); + List transDetailList = generateTransactionDetails(transHeader.getTransno(), labels, site, buNo); + logger.info("出库事务记录生成完成,事务单号: {}, 出库单号: {}, 明细记录数: {}", transHeader.getTransno(), outboundNo, labels.size()); - logger.info("出库事务记录生成完成,事务单号: {}, 出库单号: {}, 明细记录数: {}", - transHeader.getTransno(), outboundNo, labels.size()); + // 生成事务子明细记录 + addSubTransactionDetails(transHeader.getTransno(), labels, site, buNo, transDetailList, warehouseId); + logger.info("出库事务子记录生成完成,事务单号: {}, 出库单号: {}, 明细记录数: {}", transHeader.getTransno(), outboundNo, labels.size()); } /** * 生成事务明细记录 */ - private void generateTransactionDetails(String transNo, List> labels, String site) { + private List generateTransactionDetails(String transNo, List> labels, String site, String buNo) { logger.info("开始生成事务明细记录,事务单号: {}, 明细数量: {}", transNo, labels.size()); - List transDetailList = new ArrayList<>(); - double itemNo = 1.0; // 行号从1开始 + // 统计每个partNo的数量总和 + Map partNoQuantityMap = new HashMap<>(); for (Map label : labels) { - String labelCode = (String) label.get("labelCode"); - Object quantityObj = label.get("quantity"); - String batchNo = (String) label.get("batchNo"); String partNo = (String) label.get("partNo"); - - // 转换数量 + Object quantityObj = label.get("quantity"); BigDecimal quantity = BigDecimal.ZERO; if (quantityObj != null) { if (quantityObj instanceof BigDecimal) { @@ -234,23 +226,24 @@ public class OtherOutboundServiceImpl implements OtherOutboundService { quantity = new BigDecimal(quantityObj.toString()); } } - - // 构建事务明细记录 + partNoQuantityMap.put(partNo, partNoQuantityMap.getOrDefault(partNo, BigDecimal.ZERO).add(quantity)); + } + // 构建合并后的事务明细 + double itemNo = 1.0; + for (Map.Entry entry : partNoQuantityMap.entrySet()) { + String partNo = entry.getKey(); + BigDecimal quantity = entry.getValue(); TransDetail transDetail = new TransDetail(); - transDetail.setSite(site); // 站点 + transDetail.setSite(site); transDetail.setTransno(transNo); transDetail.setItemno(itemNo); transDetail.setPartno(partNo); transDetail.setTransqty(quantity); - transDetail.setBatchno(batchNo); - transDetail.setDirection("-"); // 出库方向 - transDetail.setOrderref1(labelCode); // 标签条码 - transDetail.setOrderref2(partNo); // 物料编码 - transDetail.setOrderref3(batchNo); // 批次号 - transDetail.setRemark("其他出库 - 标签: " + labelCode); - + transDetail.setDirection("-"); + transDetail.setOrderref2(buNo); + transDetail.setRemark("其他出库"); transDetailList.add(transDetail); - itemNo += 1.0; // 行号递增 + itemNo += 1.0; } // 批量保存事务明细记录 @@ -261,5 +254,61 @@ public class OtherOutboundServiceImpl implements OtherOutboundService { } logger.info("事务明细记录生成成功,共生成 {} 条明细记录", transDetailList.size()); } + return transDetailList; + } + + /** + * 添加子明细数据 + * @param transNo 事务单号 + * @param labels 标签列表 + * @param site 站点 + * @param buNo 业务单元 + * @param transDetailList 明细记录列表,用于获取正确的 itemNo + */ + private void addSubTransactionDetails(String transNo, List> labels, String site, String buNo, List transDetailList, String warehouseId) { + logger.info("开始添加子明细数据,事务单号: {}, 标签数量: {}", transNo, labels.size()); + + // 创建 partNo 到 itemNo 的映射 + Map partNoToItemNoMap = new HashMap<>(); + for (TransDetail detail : transDetailList) { + partNoToItemNoMap.put(detail.getPartno(), detail.getItemno()); + } + + List subDetailList = new ArrayList<>(); + for (Map label : labels) { + String partNo = (String) label.get("partNo"); + String labelCode = (String) label.get("labelCode"); // subNo + String batchNo = (String) label.get("batchNo"); // orderRef3 + Object quantityObj = label.get("quantity"); // 标签数量 + String locationCode = (String) label.get("locationId"); // 库位 + Double quantity = quantityObj == null ? 0.0 : Double.parseDouble(quantityObj.toString()); + // 获取对应的明细 itemNo + Double itemNo = partNoToItemNoMap.get(partNo); + if (itemNo == null) { + logger.warn("未找到物料 {} 对应的明细记录,跳过该标签 {}", partNo, labelCode); + continue; + } + + TransDetailSub transDetail = new TransDetailSub(); + transDetail.setSite(site); + transDetail.setTransNo(transNo); + transDetail.setItemNo(itemNo); // 使用明细的 itemNo + transDetail.setSubNo(labelCode); + transDetail.setSubQty(quantity); + transDetail.setDirection("-"); + transDetail.setOrderRef2(buNo); + transDetail.setOrderRef3(batchNo); + transDetail.setOrderRef4(warehouseId); + transDetail.setOrderRef5(locationCode); + subDetailList.add(transDetail); + } + + if (!subDetailList.isEmpty()) { + boolean success = transDetailSubService.saveBatch(subDetailList); + if (!success) { + throw new RuntimeException("子明细记录保存失败"); + } + logger.info("子明细记录生成成功,共生成 {} 条子明细记录", subDetailList.size()); + } } } diff --git a/src/main/java/com/gaotao/modules/salesOutbound/controller/SalesOutboundController.java b/src/main/java/com/gaotao/modules/salesOutbound/controller/SalesOutboundController.java index bab6f24..fe71030 100644 --- a/src/main/java/com/gaotao/modules/salesOutbound/controller/SalesOutboundController.java +++ b/src/main/java/com/gaotao/modules/salesOutbound/controller/SalesOutboundController.java @@ -73,13 +73,10 @@ public class SalesOutboundController extends AbstractController { return R.error("仓库ID不能为空"); } - Map result = salesOutboundService.getOutboundDetails( - outboundNo, buNo, warehouseId, site); - + Map result = salesOutboundService.getOutboundDetails(outboundNo, buNo, warehouseId, site); if (result == null || result.isEmpty()) { return R.error("未找到出库单详情"); } - return R.ok().put("data", result); } catch (Exception e) { logger.error("获取销售出库单详情失败", e); @@ -108,8 +105,7 @@ public class SalesOutboundController extends AbstractController { return R.error("出库单号不能为空"); } - Map result = salesOutboundService.validateLabelWithOutbound( - labelCode, outboundNo, warehouseId, site, buNo); + Map result = salesOutboundService.validateLabelWithOutbound(labelCode, outboundNo, warehouseId, site, buNo); return R.ok().put("data", result); } catch (Exception e) { diff --git a/src/main/java/com/gaotao/modules/salesOutbound/service/impl/SalesOutboundServiceImpl.java b/src/main/java/com/gaotao/modules/salesOutbound/service/impl/SalesOutboundServiceImpl.java index e51e23b..e2174ad 100644 --- a/src/main/java/com/gaotao/modules/salesOutbound/service/impl/SalesOutboundServiceImpl.java +++ b/src/main/java/com/gaotao/modules/salesOutbound/service/impl/SalesOutboundServiceImpl.java @@ -72,8 +72,7 @@ public class SalesOutboundServiceImpl implements SalesOutboundService { @Override @Transactional(rollbackFor = Exception.class) public boolean confirmSalesOutbound(String site, String buNo, String outboundNo, String warehouseId, List> labels) { - logger.info("开始确认销售出库,出库单号: {}, 仓库ID: {}, 标签数量: {}", - outboundNo, warehouseId, labels.size()); + logger.info("开始确认销售出库,出库单号: {}, 仓库ID: {}, 标签数量: {}", outboundNo, warehouseId, labels.size()); try { // 1. 提取标签条码列表 List labelCodes = labels.stream() diff --git a/src/main/resources/mapper/orderIssure/IssureNotifyMapper.xml b/src/main/resources/mapper/orderIssure/IssureNotifyMapper.xml index 14827e3..5acb75e 100644 --- a/src/main/resources/mapper/orderIssure/IssureNotifyMapper.xml +++ b/src/main/resources/mapper/orderIssure/IssureNotifyMapper.xml @@ -131,24 +131,25 @@ RecordVersion,OutWorkOrderFlag,ProjectID,OrderType,AuthRuleID,bu) + + select a.NotifyNo,a.Site,a.ItemNo,a.ComponentPartNo,a.QtyToIssue,a.QtyToIssue_Original ,b.FGPartNo,b.OpsItemNo,b.SOOrderNo orderNo,b.SeqNo, dbo.Get_PartDesc(a.site,a.ComponentPartNo) partDesc - ,b.locationNo,a.issueType,b.needDate,a.remark, c.issue_method, c.outbound_warehouse_id + ,b.locationNo,a.issueType,b.needDate,a.remark, c.issue_method, W.WareHouseName AS outbound_warehouse_id from SOIssueNotifyOrderMaterialList a left join SOIssueNotifyOrderList b on a.site=b.site and a.NotifyNo=b.NotifyNo and a.ItemNo=b.ItemNo left join SOBOM c on c.site=b.site and b.SOOrderNo=c.OrderNo and c.ItemNo=b.OpsItemNo and c.ComponentPartNo=a.ComponentPartNo + left join WareHouse w on c.site=w.site and c.outbound_warehouse_id=w.WareHouseID where a.NotifyNo=#{notifyNo} and a.site=#{site} order by b.needDate,a.ItemNo diff --git a/src/main/resources/mapper/otherOutbound/OtherOutboundMapper.xml b/src/main/resources/mapper/otherOutbound/OtherOutboundMapper.xml index 2d17835..81edcab 100644 --- a/src/main/resources/mapper/otherOutbound/OtherOutboundMapper.xml +++ b/src/main/resources/mapper/otherOutbound/OtherOutboundMapper.xml @@ -6,54 +6,53 @@ @@ -66,31 +65,31 @@ inv.status AS status, inv.warehouse_id AS warehouseId, inv.location_id AS locationId - FROM inventory_stock inv - INNER JOIN outbound_notification_detail d ON inv.part_no = d.part_no - INNER JOIN outbound_notification_head h ON d.order_no = h.order_no AND d.site = h.site + FROM outbound_notification_head h + INNER JOIN outbound_notification_detail d ON h.order_no = d.order_no AND h.site = d.site AND H.bu_no = D.bu_no + INNER join inventory_stock inv on d.site = inv.site and d.bu_no = inv.bu_no and d.part_no = inv.part_no WHERE inv.roll_no = #{labelCode} - AND h.order_no = #{outboundNo} - AND inv.warehouse_id = #{warehouseId} - AND inv.site = #{site} - AND inv.bu_no = #{buNo} - AND h.order_type = '其他出库' - AND inv.status = '在库' - AND inv.qty_on_hand > 0 + AND h.order_no = #{outboundNo} + AND inv.warehouse_id = #{warehouseId} + AND inv.site = #{site} + AND inv.bu_no = #{buNo} + AND inv.status = '在库' + AND inv.qty_on_hand > 0 UPDATE inventory_stock - SET status = #{status}, - updated_date = GETDATE(), - updated_by = 'SYSTEM' - WHERE roll_no IN + SET STATUS = #{status}, + LATEST_OUT_DATE = getDate() + WHERE ROLL_NO IN #{labelCode} - AND site = #{site} - AND bu_no = #{buNo} + AND SITE = #{site} + + AND BU_NO = #{buNo} +