Browse Source

2025-10-31

pda调整扫描、查询、确认逻辑(生产退仓)
master
fengyuan_yang 4 months ago
parent
commit
553510b77b
  1. 86
      src/main/java/com/gaotao/modules/productionReturn/controller/ProductionReturnController.java
  2. 7
      src/main/java/com/gaotao/modules/productionReturn/dao/ProductionReturnMapper.java
  3. 38
      src/main/java/com/gaotao/modules/productionReturn/service/ProductionReturnService.java
  4. 127
      src/main/java/com/gaotao/modules/productionReturn/service/impl/ProductionReturnServiceImpl.java
  5. 15
      src/main/resources/mapper/productionReturn/ProductionReturnMapper.xml

86
src/main/java/com/gaotao/modules/productionReturn/controller/ProductionReturnController.java

@ -89,24 +89,36 @@ public class ProductionReturnController extends AbstractController {
}
/**
* 验证生产标签与入库单是否匹配
* 从SFDC_ROLLS表验证标签
* 验证生产标签通过存储过程
*/
@PostMapping("validateLabelWithReturn")
public R validateLabelWithReturn(@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("标签条码不能为空");
}
if (inboundNo == null || inboundNo.trim().isEmpty()) {
return R.error("入库单号不能为空");
return R.error("生产订单号不能为空");
}
if (site == null || site.trim().isEmpty()) {
return R.error("站点不能为空");
}
Map<String, Object> result = productionReturnService.validateLabelWithInbound(labelCode, inboundNo, partNo, site, buNo);
if (buNo == null || buNo.trim().isEmpty()) {
return R.error("业务单元不能为空");
}
if (operationType == null || operationType.trim().isEmpty()) {
return R.error("操作类型不能为空");
}
String userName = getUser().getUsername();
Map<String, Object> result = productionReturnService.validateLabelWithInbound(
site, buNo, inboundNo, labelCode, operationType, userName);
return R.ok().put("data", result);
} catch (Exception e) {
logger.error("生产标签验证失败", e);
@ -115,13 +127,8 @@ public class ProductionReturnController extends AbstractController {
}
/**
* 确认生产入库上架
* 系统逻辑
* 1. 更新SFDC_ROLLS表中的标签状态为"已入库"
* 2. 更改inbound_notification_head表中的单据状态入库状态为"已入库"
* 3. 在WMS库存表中插入标签数据状态为"在库"
* 4. 生成WMS入库记录Transheader...
* 5. 异步调用ERP接口回传数据
* 确认生产退仓上架通过存储过程
* 系统逻辑存储过程GetSaveLabelVerification处理所有入库逻辑
*/
@PostMapping("confirmReturnStorage")
public R confirmReturnStorage(@RequestBody Map<String, Object> params) {
@ -130,33 +137,30 @@ public class ProductionReturnController 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("入库单号不能为空");
return R.error("生产订单号不能为空");
}
if (locationCode == null || locationCode.trim().isEmpty()) {
return R.error("库位号不能为空");
}
if (labels == null || labels.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 (site == null || site.trim().isEmpty()) {
return R.error("站点不能为空");
}
if (buNo == null || buNo.trim().isEmpty()) {
return R.error("业务单元不能为空");
}
boolean success = productionReturnService.confirmInboundStorage(inboundNo, locationCode, labels, site, buNo);
String userName = getUser().getUsername();
boolean success = productionReturnService.confirmInboundStorage(
site, buNo, inboundNo, locationCode, userName);
if (success) {
return R.ok("上架成功");
} else {
return R.error("上架失败");
}
} catch (Exception e) {
logger.error("生产入库上架失败", e);
logger.error("生产退仓上架失败", e);
return R.error(e.getMessage());
}
}
@ -193,4 +197,36 @@ public class ProductionReturnController extends AbstractController {
return R.error("获取物料清单失败: " + e.getMessage());
}
}
/**
* 获取已扫描标签列表从缓存表
* 根据sitebuNoorderNo从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 = productionReturnService.getScannedLabelList(site, buNo, inboundNo);
return R.ok().put("data", scannedList);
} catch (Exception e) {
logger.error("获取已扫描标签列表失败", e);
return R.error("获取已扫描标签列表失败: " + e.getMessage());
}
}
}

7
src/main/java/com/gaotao/modules/productionReturn/dao/ProductionReturnMapper.java

@ -68,4 +68,11 @@ public interface ProductionReturnMapper {
List<Map<String, Object>> getMaterialList(@Param("site") String site,
@Param("buNo") String buNo,
@Param("inboundNo") String inboundNo);
/**
* 获取已扫描标签列表从缓存表
*/
List<Map<String, Object>> getScannedLabelList(@Param("site") String site,
@Param("buNo") String buNo,
@Param("orderNo") String orderNo);
}

38
src/main/java/com/gaotao/modules/productionReturn/service/ProductionReturnService.java

@ -28,32 +28,27 @@ public interface ProductionReturnService {
Map<String, Object> getInboundDetails(String orderNo, String warehouseId, String site, String buNo);
/**
* 验证生产标签与入库单是否匹配
* 从SFDC_ROLLS表验证标签信息
* @param labelCode 标签条码
* @param orderNo 入库单号
* @param partNo 物料编码
* 验证生产标签通过存储过程
* @param site 站点
* @param buNo 业务单元
* @param orderNo 生产订单号
* @param labelCode 标签条码
* @param operationType 操作类型 I-添加 D-移除
* @param userName 当前登录人
* @return 标签信息
*/
Map<String, Object> validateLabelWithInbound(String labelCode, String inboundNo, String partNo, String site, String buNo);
Map<String, Object> validateLabelWithInbound(String site, String buNo, String orderNo, String labelCode, String operationType, String userName);
/**
* 确认生产入库上架
* 1. 更新SFDC_ROLLS表中的标签状态
* 2. 更新inbound_notification_head表状态
* 3. 插入库存数据
* 4. 生成事务记录
* @param orderNo 入库单号
* @param partNo 物料编码
* @param warehouseId 仓库ID
* @param locationCode 库位号
* @param labels 标签列表
* 确认生产退仓上架通过存储过程
* @param site 站点
* @param buNo 业务单元
* @param orderNo 生产订单号
* @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 orderNo, String locationCode, String userName);
/**
* 获取生产物料清单
@ -64,4 +59,13 @@ public interface ProductionReturnService {
* @return 物料清单
*/
List<Map<String, Object>> getMaterialList(String site, String buNo, String inboundNo);
/**
* 获取已扫描标签列表从缓存表
* @param site 站点
* @param buNo 业务单元
* @param orderNo 生产订单号
* @return 已扫描标签列表
*/
List<Map<String, Object>> getScannedLabelList(String site, String buNo, String orderNo);
}

127
src/main/java/com/gaotao/modules/productionReturn/service/impl/ProductionReturnServiceImpl.java

@ -8,6 +8,7 @@ import com.gaotao.modules.productionInbound.dao.ProductionInboundMapper;
import com.gaotao.modules.productionInbound.service.ProductionInboundService;
import com.gaotao.modules.productionReturn.dao.ProductionReturnMapper;
import com.gaotao.modules.productionReturn.service.ProductionReturnService;
import com.gaotao.modules.schedule.mapper.ProcedureMapper;
import com.gaotao.modules.sys.entity.SysUserEntity;
import com.gaotao.modules.trans.entity.TransDetail;
import com.gaotao.modules.trans.entity.TransDetailDto;
@ -50,6 +51,9 @@ public class ProductionReturnServiceImpl implements ProductionReturnService {
@Autowired
private TransDetailSubService transDetailSubService;
@Autowired
private ProcedureMapper procedureMapper;
@Override
public List<Map<String, Object>> getQualifiedInboundList(String site, String warehouseId, String searchCode, String status) {
SysUserEntity sysUserEntity = (SysUserEntity) SecurityUtils.getSubject().getPrincipal();
@ -64,60 +68,81 @@ public class ProductionReturnServiceImpl implements ProductionReturnService {
}
@Override
public Map<String, Object> validateLabelWithInbound(String labelCode, String inboundNo, String partNo, String site, String buNo) {
// 从SFDC_ROLLS表验证标签信息
Map<String, Object> result = productionReturnMapper.validateLabelWithInbound(labelCode, inboundNo, partNo, site, buNo);
public Map<String, Object> validateLabelWithInbound(String site, String buNo, String orderNo, String labelCode, String operationType, String userName) {
logger.info("开始验证标签,标签条码: {}, 生产订单号: {}, 操作类型: {}", labelCode, orderNo, operationType);
// 调用存储过程 GetScanLabelVerification
List<Object> params = new ArrayList<>();
params.add(site); // 参数1: site
params.add(buNo); // 参数2: buNo
params.add(""); // 参数3: 空字符串
params.add(orderNo); // 参数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("存储过程调用失败");
}
if (result == null || result.isEmpty()) {
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 orderNo, String locationCode, String userName) {
logger.info("开始确认生产退仓上架,生产订单号: {}, 库位号: {}", orderNo, locationCode);
try {
// 1. 验证库位是否存在且可用
Map<String, Object> locationInfo = productionReturnMapper.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("该库位未绑定仓库,请检查");
}
// 2. 提取标签条码列表
List<String> labelCodes = labels.stream()
.map(label -> (String) label.get("labelCode"))
.collect(Collectors.toList());
// // 3. 更新SFDC_ROLLS表中标签状态为"已入库"
// int updatedLabels = productionReturnMapper.updateSfdcRollsStatus(labelCodes, "已入库", site, buNo);
// if (updatedLabels != labelCodes.size()) {
// throw new RuntimeException("部分标签状态更新失败");
// }
// 调用存储过程 GetSaveLabelVerification
List<Object> params = new ArrayList<>();
params.add(site); // 参数1: site
params.add(buNo); // 参数2: buNo
params.add(""); // 参数3: 空字符串
params.add(orderNo); // 参数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);
// 5. 插入库存数据
insertInventoryStock(orderNo, warehouseId, locationCode, labels, site, buNo);
// 判断返回结果
if (resultList == null || resultList.isEmpty()) {
throw new RuntimeException("存储过程调用失败");
}
// 6. 生成入库事务记录
generateInboundTransaction(orderNo, warehouseId, locationCode, labels, site, buNo);
Map<String, Object> result = resultList.get(0);
String code = String.valueOf(result.get("code"));
// 7. 异步调用ERP接口这里可以发送消息到队列
//asyncCallErpInterface(orderNo, partNo, labels);
if (!"200".equals(code)) {
String msg = String.valueOf(result.get("message"));
throw new RuntimeException(msg);
}
logger.info("生产入库上架确认完成,入库单号: {}", orderNo);
logger.info("生产退仓上架成功,生产订单号: {}", orderNo);
return true;
} catch (Exception e) {
logger.error("生产入库确认失败,入库单号: {}, 错误信息: {}", orderNo, e.getMessage(), e);
logger.error("生产退仓上架失败,生产订单号: {}, 错误信息: {}", orderNo, e.getMessage(), e);
throw new RuntimeException("入库确认失败: " + e.getMessage(), e);
}
}
@ -308,6 +333,28 @@ public class ProductionReturnServiceImpl implements ProductionReturnService {
}
}
@Override
public List<Map<String, Object>> getScannedLabelList(String site, String buNo, String orderNo) {
logger.info("获取已扫描标签列表,站点: {}, 业务单元: {}, 生产订单号: {}", site, buNo, orderNo);
try {
List<Map<String, Object>> scannedList = productionReturnMapper.getScannedLabelList(site, buNo, orderNo);
if (scannedList == null) {
scannedList = new ArrayList<>();
}
logger.info("获取已扫描标签列表成功,站点: {}, 业务单元: {}, 生产订单号: {}, 记录数: {}",
site, buNo, orderNo, scannedList.size());
return scannedList;
} catch (Exception e) {
logger.error("获取已扫描标签列表失败,站点: {}, 业务单元: {}, 生产订单号: {}, 错误信息: {}",
site, buNo, orderNo, e.getMessage(), e);
throw new RuntimeException("获取已扫描标签列表失败: " + e.getMessage(), e);
}
}
/**
* 生成事务明细记录
*/

15
src/main/resources/mapper/productionReturn/ProductionReturnMapper.xml

@ -141,4 +141,19 @@
GROUP BY h.site, h.bu_no,d.part_no
</select>
<!-- 获取已扫描标签列表(从缓存表) -->
<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 OrderNo = #{orderNo}
ORDER BY RollNo DESC
</select>
</mapper>
Loading…
Cancel
Save