Browse Source

2025-10-31

pda调整扫描、查询、确认逻辑(采购入库)
master
fengyuan_yang 9 months ago
parent
commit
d9fc98b18a
  1. 1
      src/main/java/com/gaotao/modules/boxManage/data/SoReceiveCasesData.java
  2. 1
      src/main/java/com/gaotao/modules/boxManage/entity/SoReceiveCases.java
  3. 89
      src/main/java/com/gaotao/modules/inboundNotification/controller/InboundNotificationController.java
  4. 11
      src/main/java/com/gaotao/modules/inboundNotification/dao/InboundNotificationHeadMapper.java
  5. 33
      src/main/java/com/gaotao/modules/inboundNotification/service/InboundNotificationService.java
  6. 159
      src/main/java/com/gaotao/modules/inboundNotification/service/impl/InboundNotificationServiceImpl.java
  7. 15
      src/main/resources/mapper/inboundNotification/InboundNotificationHeadMapper.xml

1
src/main/java/com/gaotao/modules/boxManage/data/SoReceiveCasesData.java

@ -42,3 +42,4 @@ public class SoReceiveCasesData extends SoReceiveCases {

1
src/main/java/com/gaotao/modules/boxManage/entity/SoReceiveCases.java

@ -185,3 +185,4 @@ public class SoReceiveCases {

89
src/main/java/com/gaotao/modules/inboundNotification/controller/InboundNotificationController.java

@ -5,14 +5,7 @@ import com.gaotao.common.utils.R;
import com.gaotao.modules.inboundNotification.entity.vo.InboundNotificationDetailVo;
import com.gaotao.modules.inboundNotification.entity.vo.InboundNotificationHeadVo;
import com.gaotao.modules.inboundNotification.service.InboundNotificationService;
import com.gaotao.modules.pms.data.QcFAIRecordData;
import com.gaotao.modules.pms.data.QcMethodData;
import com.gaotao.modules.pms.data.QcTemplateData;
import com.gaotao.modules.pms.entity.LocationEntity;
import com.gaotao.modules.pms.entity.vo.PartDefectTrackingVo;
import com.gaotao.modules.pms.entity.vo.PartInformationVo;
import com.gaotao.modules.sys.controller.AbstractController;
import com.gaotao.modules.toolman.entity.Location;
import com.gaotao.modules.trans.entity.TransDetailSub;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@ -94,15 +87,17 @@ public class InboundNotificationController extends AbstractController {
}
/**
* 验证标签与入库单是否匹配
* 验证标签与入库单是否匹配通过存储过程
*/
@PostMapping("validateLabelWithInbound")
public R validateLabelWithInbound(@RequestBody Map<String, Object> params) {
try {
String labelCode = (String) params.get("labelCode");
String inboundNo = (String) params.get("inboundNo");
String partNo = (String) params.get("partNo");
String site = (String) params.get("site");
String buNo = (String) params.get("buNo");
String operationType = (String) params.get("operationType"); // I-添加 D-移除
if (labelCode == null || labelCode.trim().isEmpty()) {
return R.error("标签条码不能为空");
}
@ -110,8 +105,22 @@ public class InboundNotificationController extends AbstractController {
if (inboundNo == null || inboundNo.trim().isEmpty()) {
return R.error("入库单号不能为空");
}
if (site == null || site.trim().isEmpty()) {
return R.error("站点不能为空");
}
if (buNo == null || buNo.trim().isEmpty()) {
return R.error("业务单元不能为空");
}
if (operationType == null || operationType.trim().isEmpty()) {
return R.error("操作类型不能为空");
}
Map<String, Object> result = inboundNotificationService.validateLabelWithInbound(labelCode, inboundNo, partNo,site);
String userName = getUser().getUsername();
Map<String, Object> result = inboundNotificationService.validateLabelWithInbound(
site, buNo, inboundNo, labelCode, operationType, userName);
return R.ok().put("data", result);
} catch (Exception e) {
logger.error("标签验证失败", e);
@ -120,13 +129,8 @@ public class InboundNotificationController extends AbstractController {
}
/**
* 确认入库上架
* 系统逻辑
* 1. 更新po_order_roll_no表中的标签状态为"已入库"
* 2. 更改InboundNotificationHead表中的单据状态入库状态为"已入库"
* 3. 在WMS库存表中插入标签数据状态为"待入"
* 4. 生成WMS入库记录Transheader...
* 5. 异步调用ERP接口回传数据
* 确认入库上架通过存储过程
* 系统逻辑存储过程GetSaveLabelVerification处理所有入库逻辑
*/
@PostMapping("confirmInboundStorage")
public R confirmInboundStorage(@RequestBody Map<String, Object> params) {
@ -135,24 +139,23 @@ public class InboundNotificationController extends AbstractController {
String locationCode = (String) params.get("locationCode");
String site = (String) params.get("site");
String buNo = (String) params.get("buNo");
List<Map<String, Object>> labels = (List<Map<String, Object>>) params.get("labels");
if (inboundNo == null || inboundNo.trim().isEmpty()) {
return R.error("入库单号不能为空");
}
if (locationCode == null || locationCode.trim().isEmpty()) {
return R.error("库位号不能为空");
}
if (labels == null || labels.isEmpty()) {
return R.error("标签列表不能为空");
if (site == null || site.trim().isEmpty()) {
return R.error("站点不能为空");
}
// 验证标签数据完整性
for (Map<String, Object> label : labels) {
String labelCode = (String) label.get("labelCode");
if (labelCode == null || labelCode.trim().isEmpty()) {
return R.error("标签条码不能为空");
}
if (buNo == null || buNo.trim().isEmpty()) {
return R.error("业务单元不能为空");
}
boolean success = inboundNotificationService.confirmInboundStorage(inboundNo, locationCode, labels, site,buNo);
String userName = getUser().getUsername();
boolean success = inboundNotificationService.confirmInboundStorage(
site, buNo, inboundNo, locationCode, userName);
if (success) {
return R.ok("上架成功");
} else {
@ -218,6 +221,38 @@ public class InboundNotificationController extends AbstractController {
}
}
/**
* 获取已扫描标签列表从缓存表
* 根据sitebuNoinboundNo从ScannedRollTempTable表获取已扫描的标签
*/
@PostMapping("getScannedLabelList")
public R getScannedLabelList(@RequestBody Map<String, Object> params) {
try {
String site = (String) params.get("site");
String buNo = (String) params.get("buNo");
String inboundNo = (String) params.get("inboundNo");
if (site == null || site.trim().isEmpty()) {
return R.error("站点不能为空");
}
if (buNo == null || buNo.trim().isEmpty()) {
return R.error("业务单元不能为空");
}
if (inboundNo == null || inboundNo.trim().isEmpty()) {
return R.error("入库单号不能为空");
}
List<Map<String, Object>> scannedList = inboundNotificationService.getScannedLabelList(site, buNo, inboundNo);
return R.ok().put("data", scannedList);
} catch (Exception e) {
logger.error("获取已扫描标签列表失败", e);
return R.error("获取已扫描标签列表失败: " + e.getMessage());
}
}
// =========================== PC ===========================

11
src/main/java/com/gaotao/modules/inboundNotification/dao/InboundNotificationHeadMapper.java

@ -79,6 +79,17 @@ public interface InboundNotificationHeadMapper extends BaseMapper<InboundNotific
@Param("site") String site,
@Param("buNo") String buNo);
/**
* 获取已扫描标签列表从缓存表
* @param site 站点
* @param buNo 业务单元
* @param inboundNo 入库单号
* @return 已扫描标签列表
*/
List<Map<String, Object>> getScannedLabelList(@Param("site") String site,
@Param("buNo") String buNo,
@Param("inboundNo") String inboundNo);
IPage<InboundNotificationHeadVo> searchInboundNotification(Page<InboundNotificationHeadVo> inboundNotificationHeadVoPage, @Param("query") InboundNotificationHeadVo data);

33
src/main/java/com/gaotao/modules/inboundNotification/service/InboundNotificationService.java

@ -3,7 +3,6 @@ package com.gaotao.modules.inboundNotification.service;
import com.gaotao.common.utils.PageUtils;
import com.gaotao.modules.inboundNotification.entity.vo.InboundNotificationDetailVo;
import com.gaotao.modules.inboundNotification.entity.vo.InboundNotificationHeadVo;
import com.gaotao.modules.pms.entity.vo.PartDefectTrackingVo;
import com.gaotao.modules.trans.entity.TransDetailSub;
import java.util.List;
@ -30,24 +29,27 @@ public interface InboundNotificationService {
Map<String, Object> getInboundDetails(String orderNo, String warehouseId,String site, String buNo);
/**
* 验证标签与入库单是否匹配
* 验证标签与入库单是否匹配通过存储过程
* @param site 站点
* @param buNo 业务单元
* @param inboundNo 入库单号
* @param labelCode 标签条码
* @param orderNo 入库单号
* @param partNo 物料编码
* @param operationType 操作类型 I-添加 D-移除
* @param userName 当前登录人
* @return 标签信息
*/
Map<String, Object> validateLabelWithInbound(String labelCode, String orderNo, String partNo,String site);
Map<String, Object> validateLabelWithInbound(String site, String buNo, String inboundNo, String labelCode, String operationType, String userName);
/**
* 确认入库上架
* @param orderNo 入库单号
* @param warehouseId 仓库ID
* @param locationCode 库位号
* @param labels 标签列表
* 确认入库上架通过存储过程
* @param site 站点
* @param buNo 业务单元
* @param inboundNo 入库单号
* @param locationCode 库位号
* @param userName 当前登录人
* @return 处理结果
*/
boolean confirmInboundStorage(String orderNo, String locationCode, List<Map<String, Object>> labels, String site,String buNo);
boolean confirmInboundStorage(String site, String buNo, String inboundNo, String locationCode, String userName);
/**
* 获取物料清单
@ -58,6 +60,15 @@ public interface InboundNotificationService {
*/
List<Map<String, Object>> getMaterialList(String site, String buNo, String inboundNo);
/**
* 获取已扫描标签列表从缓存表
* @param site 站点
* @param buNo 业务单元
* @param inboundNo 入库单号
* @return 已扫描标签列表
*/
List<Map<String, Object>> getScannedLabelList(String site, String buNo, String inboundNo);
PageUtils searchInboundNotification(InboundNotificationHeadVo data);
void saveInboundNotification(InboundNotificationHeadVo data);

159
src/main/java/com/gaotao/modules/inboundNotification/service/impl/InboundNotificationServiceImpl.java

@ -2,7 +2,6 @@ package com.gaotao.modules.inboundNotification.service.impl;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.gaotao.common.exception.XJException;
import com.gaotao.common.utils.PageUtils;
import com.gaotao.modules.inboundNotification.dao.InboundNotificationDetailMapper;
import com.gaotao.modules.inboundNotification.dao.InboundNotificationHeadMapper;
@ -12,10 +11,6 @@ import com.gaotao.modules.inboundNotification.service.InboundNotificationService
import com.gaotao.modules.inventoryStock.dao.InventoryStockMapper;
import com.gaotao.modules.inventoryStock.entity.InventoryStock;
import com.gaotao.modules.inventoryStock.service.InventoryStockService;
import com.gaotao.modules.pms.data.QcFAIRecordData;
import com.gaotao.modules.pms.data.QcMethodData;
import com.gaotao.modules.pms.data.QcTemplateData;
import com.gaotao.modules.pms.entity.vo.PartDefectTrackingVo;
import com.gaotao.modules.pms.entity.vo.PartInformationVo;
import com.gaotao.modules.pms.entity.vo.PartLabelTemplateVo;
import com.gaotao.modules.schedule.mapper.ProcedureMapper;
@ -34,7 +29,6 @@ import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;
@Service
public class InboundNotificationServiceImpl implements InboundNotificationService {
@ -81,86 +75,81 @@ public class InboundNotificationServiceImpl implements InboundNotificationServic
}
@Override
public Map<String, Object> validateLabelWithInbound(String labelCode, String orderNo, String partNo,String site) {
Map<String, Object> result = detailMapper.validateLabelWithInbound(labelCode, orderNo, partNo,site);
if (result == null || result.isEmpty()) {
throw new RuntimeException("该标签与入库单不符,请检查");
public Map<String, Object> validateLabelWithInbound(String site, String buNo, String inboundNo, String labelCode, String operationType, String userName) {
logger.info("开始验证标签,标签条码: {}, 入库单号: {}, 操作类型: {}", labelCode, inboundNo, operationType);
// 调用存储过程 GetScanLabelVerification
List<Object> params = new ArrayList<>();
params.add(site); // 参数1: site
params.add(buNo); // 参数2: buNo
params.add(inboundNo); // 参数3: 入库单号
params.add(""); // 参数4: 空字符串
params.add(""); // 参数5: 空字符串
params.add(""); // 参数6: 空字符串
params.add(""); // 参数7: 空字符串
params.add(labelCode); // 参数8: 扫描的标签条码
params.add(""); // 参数9: 空字符串
params.add("采购入库"); // 参数10: 采购入库
params.add(operationType); // 参数11: I-添加 D-移除
params.add(userName); // 参数12: 当前登陆人
List<Map<String, Object>> resultList = procedureMapper.getProcedureData("GetScanLabelVerification", params);
// 判断返回结果
if (resultList == null || resultList.isEmpty()) {
throw new RuntimeException("存储过程调用失败");
}
String hardtagInFlag = (String) result.get("hardtagInFlag");
if (!"未入库".equals(hardtagInFlag)) {
throw new RuntimeException("该标签状态不允许入库");
Map<String, Object> result = resultList.get(0);
String code = String.valueOf(result.get("code"));
if (!"200".equals(code)) {
String msg = String.valueOf(result.get("message"));
throw new RuntimeException(msg);
}
logger.info("标签验证成功,标签条码: {}", labelCode);
return result;
}
@Override
@Transactional(rollbackFor = Exception.class)
public boolean confirmInboundStorage(String orderNo, String locationCode, List<Map<String, Object>> labels, String site,String buNo) {
logger.info("开始确认入库上架,入库单号: {}, 库位号: {}, 标签数量: {}", orderNo, locationCode, labels.size());
public boolean confirmInboundStorage(String site, String buNo, String inboundNo, String locationCode, String userName) {
logger.info("开始确认入库上架,入库单号: {}, 库位号: {}", inboundNo, locationCode);
try {
// 1. 验证库位是否存在且可用
Map<String, Object> locationInfo = headMapper.validateLocation(locationCode, site);
if (locationInfo == null || locationInfo.isEmpty()) {
throw new RuntimeException("该库位不存在,请检查");
}
String locationStatus = (String) locationInfo.get("status");
if (!"Y".equals(locationStatus)) {
throw new RuntimeException("该库位已停用,请检查");
}
// 根据库位获取仓库ID
String warehouseId = (String) locationInfo.get("warehouseId");
if (warehouseId == null && warehouseId.trim().isEmpty()) {
throw new RuntimeException("该库位未绑定仓库,请检查");
// 调用存储过程 GetSaveLabelVerification
List<Object> params = new ArrayList<>();
params.add(site); // 参数1: site
params.add(buNo); // 参数2: buNo
params.add(inboundNo); // 参数3: 入库单号
params.add(""); // 参数4: 空字符串
params.add(""); // 参数5: 空字符串
params.add(""); // 参数6: 空字符串
params.add(""); // 参数7: 空字符串
params.add(locationCode); // 参数8: 入库库位
params.add("采购入库"); // 参数9: 采购入库
params.add(userName); // 参数10: 当前登陆人
List<Map<String, Object>> resultList = procedureMapper.getProcedureData("GetSaveLabelVerification", params);
// 判断返回结果
if (resultList == null || resultList.isEmpty()) {
throw new RuntimeException("存储过程调用失败");
}
// 2. 提取标签条码列表
List<String> labelCodes = labels.stream()
.map(label -> (String) label.get("labelCode"))
.collect(Collectors.toList());
// 2. 更新标签状态为"已入库"
int updatedLabels = detailMapper.updateLabelStatus(labelCodes, "已入库", site, buNo);
if (updatedLabels != labelCodes.size()) {
throw new RuntimeException("部分标签状态更新失败");
Map<String, Object> result = resultList.get(0);
String code = String.valueOf(result.get("code"));
if (!"200".equals(code)) {
String msg = String.valueOf(result.get("message"));
throw new RuntimeException(msg);
}
// // 3. 检查是否所有标签都已入库决定是否更新入库单状态
// Map<String, Object> labelStats = headMapper.checkAllLabelsInbound(orderNo, site, buNo);
// if (labelStats != null) {
// Integer totalLabels = (Integer) labelStats.get("totalLabels");
// Integer inboundLabels = (Integer) labelStats.get("inboundLabels");
//
// logger.info("入库单 {} 标签统计: 总标签数={}, 已入库标签数={}", orderNo, totalLabels, inboundLabels);
//
// // 只有当所有标签都已入库时才更新入库单状态为"已完成"
// if (totalLabels != null && inboundLabels != null && totalLabels.equals(inboundLabels) && totalLabels > 0) {
// int updatedHead = headMapper.updateInboundStatus(orderNo, "已完成", site, buNo);
// if (updatedHead > 0) {
// logger.info("入库单 {} 所有标签已入库,状态更新为已完成", orderNo);
// }
// } else {
// logger.info("入库单 {} 还有标签未入库,保持待入库状态", orderNo);
// }
// }
// 5. 插入库存数据
insertInventoryStock(orderNo, warehouseId, locationCode, labels, site, buNo);
// 6. 生成入库事务记录
generateInboundTransaction(orderNo, warehouseId, locationCode, labels, site, buNo);
// 7. 异步调用ERP接口这里可以发送消息到队列
//asyncCallErpInterface(orderNo, partNo, labels);
logger.info("入库上架确认完成,入库单号: {}", orderNo);
logger.info("入库上架成功,入库单号: {}", inboundNo);
return true;
} catch (Exception e) {
logger.error("入库确认失败,入库单号: {}, 错误信息: {}", orderNo, e.getMessage(), e);
logger.error("入库确认失败,入库单号: {}, 错误信息: {}", inboundNo, e.getMessage(), e);
throw new RuntimeException("入库确认失败: " + e.getMessage(), e);
}
}
@ -347,6 +336,28 @@ public class InboundNotificationServiceImpl implements InboundNotificationServic
}
}
@Override
public List<Map<String, Object>> getScannedLabelList(String site, String buNo, String inboundNo) {
logger.info("获取已扫描标签列表,站点: {}, 业务单元: {}, 入库单号: {}", site, buNo, inboundNo);
try {
List<Map<String, Object>> scannedList = headMapper.getScannedLabelList(site, buNo, inboundNo);
if (scannedList == null) {
scannedList = new ArrayList<>();
}
logger.info("获取已扫描标签列表成功,站点: {}, 业务单元: {}, 入库单号: {}, 记录数: {}",
site, buNo, inboundNo, scannedList.size());
return scannedList;
} catch (Exception e) {
logger.error("获取已扫描标签列表失败,站点: {}, 业务单元: {}, 入库单号: {}, 错误信息: {}",
site, buNo, inboundNo, e.getMessage(), e);
throw new RuntimeException("获取已扫描标签列表失败: " + e.getMessage(), e);
}
}
/**
* 生成事务明细记录
* @return 生成的明细记录列表用于子明细关联

15
src/main/resources/mapper/inboundNotification/InboundNotificationHeadMapper.xml

@ -212,4 +212,19 @@
updated_date = GETDATE()
WHERE site = #{site} AND bu_no = #{buNo} AND order_no = #{orderNo}
</update>
<!-- 获取已扫描标签列表(从缓存表) -->
<select id="getScannedLabelList" resultType="java.util.Map">
SELECT
site,
bu_no as buNo,
part_no as partNo,
RollNo as labelCode,
RollQty as quantity
FROM ScannedRollTempTable
WHERE site = #{site}
AND bu_no = #{buNo}
AND NotifyNo = #{inboundNo}
ORDER BY RollNo DESC
</select>
</mapper>
Loading…
Cancel
Save