Browse Source

2025-12-26

pda其他出库调用存储过程,且调用erp接口
master
fengyuan_yang 3 weeks ago
parent
commit
3f356690a7
  1. 71
      src/main/java/com/gaotao/modules/otherOutbound/controller/OtherOutboundController.java
  2. 15
      src/main/java/com/gaotao/modules/otherOutbound/dao/OtherOutboundMapper.java
  3. 47
      src/main/java/com/gaotao/modules/otherOutbound/service/OtherOutboundService.java
  4. 150
      src/main/java/com/gaotao/modules/otherOutbound/service/impl/OtherOutboundServiceImpl.java
  5. 21
      src/main/resources/mapper/otherOutbound/OtherOutboundMapper.xml

71
src/main/java/com/gaotao/modules/otherOutbound/controller/OtherOutboundController.java

@ -86,7 +86,7 @@ public class OtherOutboundController extends AbstractController {
}
/**
* 验证标签与其他出库单是否匹配并检查库存
* 验证标签与其他出库单是否匹配调用存储过程
*/
@PostMapping("/validateLabelWithOutbound")
@ApiOperation("验证标签与出库单匹配")
@ -97,6 +97,9 @@ public class OtherOutboundController extends AbstractController {
String warehouseId = (String) params.get("warehouseId");
String site = (String) params.get("site");
String buNo = (String) params.get("buNo");
String relatedNo = (String) params.get("relatedNo");
String relatedLineNo = (String) params.get("relatedLineNo");
String operationType = (String) params.get("operationType");
if (labelCode == null || labelCode.trim().isEmpty()) {
return R.error("标签条码不能为空");
@ -106,7 +109,15 @@ public class OtherOutboundController extends AbstractController {
return R.error("出库单号不能为空");
}
Map<String, Object> result = otherOutboundService.validateLabelWithOutbound(labelCode, outboundNo, warehouseId, site, buNo);
// 默认操作类型为添加
if (operationType == null || operationType.trim().isEmpty()) {
operationType = "I";
}
String userName = getUser().getUsername();
Map<String, Object> result = otherOutboundService.validateLabelWithOutbound(
site, buNo, outboundNo, relatedNo, relatedLineNo,
labelCode, operationType, userName, warehouseId);
return R.ok().put("data", result);
} catch (Exception e) {
logger.error("其他出库标签验证失败", e);
@ -115,12 +126,7 @@ public class OtherOutboundController extends AbstractController {
}
/**
* 确认其他出库
* 系统逻辑
* 1. 更新库存表中的标签状态
* 2. 更改return_notification_head表中的单据状态为"已出库"
* 3. 生成WMS出库记录Transheader...
* 4. 异步调用ERP接口回传数据
* 确认其他出库调用存储过程并异步调用ERP接口
*/
@PostMapping("/confirmOtherOutbound")
@ApiOperation("确认其他出库")
@ -129,28 +135,17 @@ public class OtherOutboundController extends AbstractController {
String site = (String) params.get("site");
String buNo = (String) params.get("buNo");
String outboundNo = (String) params.get("outboundNo");
String warehouseId = (String) params.get("warehouseId");
List<Map<String, Object>> labels = (List<Map<String, Object>>) params.get("labels");
String relatedNo = (String) params.get("relatedNo");
String relatedLineNo = (String) params.get("relatedLineNo");
String locationCode = (String) params.get("locationCode");
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("标签列表不能为空");
}
// 验证标签数据完整性
for (Map<String, Object> label : labels) {
String labelCode = (String) label.get("labelCode");
if (labelCode == null || labelCode.trim().isEmpty()) {
return R.error("标签条码不能为空");
}
}
boolean success = otherOutboundService.confirmOtherOutbound(site, buNo, outboundNo, warehouseId, labels);
String userName = getUser().getUsername();
boolean success = otherOutboundService.confirmOtherOutbound(
site, buNo, outboundNo, relatedNo, relatedLineNo, locationCode, userName);
if (success) {
return R.ok("出库成功");
} else {
@ -162,6 +157,32 @@ public class OtherOutboundController extends AbstractController {
}
}
/**
* 获取已扫描标签列表从临时表
*/
@PostMapping("/getScannedLabelList")
@ApiOperation("获取已扫描标签列表")
public R getScannedLabelList(@RequestBody Map<String, Object> params) {
try {
String site = (String) params.get("site");
String buNo = (String) params.get("buNo");
String outboundNo = (String) params.get("outboundNo");
String relatedNo = (String) params.get("relatedNo");
String relatedLineNo = (String) params.get("relatedLineNo");
if (outboundNo == null || outboundNo.trim().isEmpty()) {
return R.error("出库单号不能为空");
}
List<Map<String, Object>> result = otherOutboundService.getScannedLabelList(
site, buNo, outboundNo, relatedNo, relatedLineNo);
return R.ok().put("data", result);
} catch (Exception e) {
logger.error("获取已扫描标签列表失败", e);
return R.error(e.getMessage());
}
}
/**
* 获取其他出库单物料清单
* 通过存储过程GetPartDetails获取物料信息

15
src/main/java/com/gaotao/modules/otherOutbound/dao/OtherOutboundMapper.java

@ -100,4 +100,19 @@ public interface OtherOutboundMapper extends BaseMapper {
List<Map<String, Object>> getMaterialList(@Param("site") String site,
@Param("buNo") String buNo,
@Param("outboundNo") String outboundNo);
/**
* 获取已扫描标签列表从临时表
* @param site 站点
* @param buNo 业务单元
* @param outboundNo 出库单号
* @param relatedNo 关联单号
* @param relatedLineNo 关联单行号
* @return 已扫描标签列表
*/
List<Map<String, Object>> getScannedLabelList(@Param("site") String site,
@Param("buNo") String buNo,
@Param("outboundNo") String outboundNo,
@Param("relatedNo") String relatedNo,
@Param("relatedLineNo") String relatedLineNo);
}

47
src/main/java/com/gaotao/modules/otherOutbound/service/OtherOutboundService.java

@ -32,32 +32,49 @@ public interface OtherOutboundService {
Map<String, Object> getOutboundDetails(String outboundNo, String buNo, String warehouseId, String site, String relatedNo);
/**
* 验证标签与其他出库单是否匹配并检查库存
* 从库存表验证标签信息
* @param labelCode 标签条码
* 验证标签与其他出库单是否匹配调用存储过程
* @param site 站点
* @param buNo 业务单元
* @param outboundNo 出库单号
* @param relatedNo 关联单号
* @param relatedLineNo 关联单行号
* @param labelCode 标签条码
* @param operationType 操作类型 I或D
* @param userName 当前登录用户
* @param warehouseId 仓库ID
* @return 验证结果
*/
Map<String, Object> validateLabelWithOutbound(String site, String buNo, String outboundNo,
String relatedNo, String relatedLineNo,
String labelCode, String operationType,
String userName, String warehouseId);
/**
* 确认其他出库调用存储过程并异步调用ERP接口
* @param site 站点
* @param buNo 业务单元
* @return 标签信息
* @param outboundNo 出库单号
* @param relatedNo 关联单号
* @param relatedLineNo 关联单行号
* @param locationCode 库位
* @param userName 当前登录用户
* @return 处理结果
*/
Map<String, Object> validateLabelWithOutbound(String labelCode, String outboundNo,
String warehouseId, String site, String buNo);
boolean confirmOtherOutbound(String site, String buNo, String outboundNo,
String relatedNo, String relatedLineNo,
String locationCode, String userName);
/**
* 确认其他出库
* 1. 更新库存表中的标签状态
* 2. 更新return_notification_head表状态
* 3. 生成出库事务记录
* 获取已扫描标签列表从临时表
* @param site 站点
* @param buNo 业务单元
* @param outboundNo 出库单号
* @param warehouseId 仓库ID
* @param labels 标签列表
* @return 处理结果
* @param relatedNo 关联单号
* @param relatedLineNo 关联单行号
* @return 已扫描标签列表
*/
boolean confirmOtherOutbound(String site, String buNo, String outboundNo,
String warehouseId, List<Map<String, Object>> labels);
List<Map<String, Object>> getScannedLabelList(String site, String buNo, String outboundNo,
String relatedNo, String relatedLineNo);
/**
* 获取其他出库单物料清单

150
src/main/java/com/gaotao/modules/otherOutbound/service/impl/OtherOutboundServiceImpl.java

@ -13,6 +13,7 @@ import com.gaotao.modules.trans.service.TransDetailService;
import com.gaotao.modules.trans.service.TransDetailSubService;
import com.gaotao.modules.trans.service.TransHeaderService;
import com.gaotao.modules.erp.service.ErpInterfaceService;
import com.gaotao.modules.schedule.mapper.ProcedureMapper;
import org.apache.shiro.SecurityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -55,6 +56,9 @@ public class OtherOutboundServiceImpl implements OtherOutboundService {
@Autowired
private ErpInterfaceService erpInterfaceService;
@Autowired
private ProcedureMapper procedureMapper;
@Override
public List<Map<String, Object>> getOutboundList(String site, String warehouseId, String searchCode, String status) {
SysUserEntity sysUserEntity = (SysUserEntity) SecurityUtils.getSubject().getPrincipal();
@ -90,75 +94,101 @@ public class OtherOutboundServiceImpl implements OtherOutboundService {
}
@Override
public Map<String, Object> validateLabelWithOutbound(String labelCode, String outboundNo, String warehouseId, String site, String buNo) {
public Map<String, Object> validateLabelWithOutbound(String site, String buNo, String outboundNo,
String relatedNo, String relatedLineNo,
String labelCode, String operationType,
String userName, String warehouseId) {
logger.info("验证其他出库标签,site: {}, buNo: {}, 出库单号: {}, 关联单号: {}, 关联行号: {}, 标签: {}, 操作类型: {}, 仓库: {}",
site, buNo, outboundNo, relatedNo, relatedLineNo, labelCode, operationType, warehouseId);
try {
logger.info("验证标签与其他出库单匹配,标签: {}, 出库单: {}, 仓库: {}, 站点: {}, 业务单元: {}", labelCode, outboundNo, warehouseId, site, buNo);
// 调用存储过程 GetScanLabelVerification
List<Object> params = new ArrayList<>();
params.add(site); // 参数1: site
params.add(buNo); // 参数2: buNo
params.add(outboundNo); // 参数3: 出库单号
params.add(relatedNo != null ? relatedNo : ""); // 参数4: 关联单号
params.add(relatedLineNo != null ? relatedLineNo : ""); // 参数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: 当前登陆人
params.add(warehouseId != null ? warehouseId : ""); // 参数13: 仓库ID
List<Map<String, Object>> resultList = procedureMapper.getProcedureData("GetScanLabelVerification", params);
// 判断返回结果
if (resultList == null || resultList.isEmpty()) {
throw new RuntimeException("存储过程调用失败");
}
Map<String, Object> result = otherOutboundMapper.validateLabelWithOutbound(labelCode, outboundNo, warehouseId, site, buNo);
Map<String, Object> result = resultList.get(0);
String code = String.valueOf(result.get("code"));
if (result == null || result.isEmpty()) {
throw new RuntimeException("该标签与出库单不匹配或标签状态不正确");
}
// 检查标签状态只有"在库"状态的标签才能出库
String labelStatus = (String) result.get("status");
if (!"在库".equals(labelStatus)) {
throw new RuntimeException("标签状态为:" + labelStatus + ",无法出库");
if (!"200".equals(code)) {
String msg = String.valueOf(result.get("message"));
throw new RuntimeException(msg);
}
logger.info("标签验证成功,物料编码: {}, 数量: {}", result.get("partNo"), result.get("quantity"));
logger.info("标签验证成功,标签: {}, 操作类型: {}", labelCode, operationType);
return result;
} catch (Exception e) {
logger.error("验证标签与其他出库单匹配失败", e);
throw new RuntimeException(e.getMessage());
logger.error("标签验证失败,标签: {}, 错误: {}", labelCode, e.getMessage(), e);
throw new RuntimeException(e.getMessage(), e);
}
}
@Override
@Transactional(rollbackFor = Exception.class)
public boolean confirmOtherOutbound(String site, String buNo, String outboundNo, String warehouseId, List<Map<String, Object>> labels) {
logger.info("开始确认其他出库,出库单号: {}, 仓库ID: {}, 标签数量: {}", outboundNo, warehouseId, labels.size());
try {
// 1. 更新库存表中的标签状态为"出库"
List<String> labelCodes = new ArrayList<>();
for (Map<String, Object> label : labels) {
labelCodes.add((String) label.get("labelCode"));
}
public boolean confirmOtherOutbound(String site, String buNo, String outboundNo,
String relatedNo, String relatedLineNo,
String locationCode, String userName) {
logger.info("开始确认其他出库,site: {}, buNo: {}, 出库单号: {}, 关联单号: {}, 关联行号: {}, 库位: {}",
site, buNo, outboundNo, relatedNo, relatedLineNo, locationCode);
int updatedLabels = otherOutboundMapper.updateInventoryStatus(labelCodes, "出库", site, buNo);
if (updatedLabels != labelCodes.size()) {
throw new RuntimeException("部分标签状态更新失败");
try {
// 调用存储过程 GetSaveLabelVerification
List<Object> params = new ArrayList<>();
params.add(site); // 参数1: site
params.add(buNo); // 参数2: buNo
params.add(outboundNo); // 参数3: 出库单号
params.add(relatedNo != null ? relatedNo : ""); // 参数4: 关联单号
params.add(relatedLineNo != null ? relatedLineNo : ""); // 参数5: 关联单行号
params.add(""); // 参数6: 空字符串
params.add(""); // 参数7: 空字符串
params.add(locationCode != null ? 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. 检查是否所有标签都已出库决定是否更新出库单状态
Map<String, Object> labelStats = otherOutboundMapper.checkAllLabelsOutbound(outboundNo, site, buNo);
if (labelStats != null) {
Integer totalLabels = (Integer) labelStats.get("totalLabels");
Integer outboundLabels = (Integer) labelStats.get("outboundLabels");
Map<String, Object> result = resultList.get(0);
String code = String.valueOf(result.get("code"));
logger.info("出库单 {} 标签统计: 总标签数={}, 已出库标签数={}", outboundNo, totalLabels, outboundLabels);
// 只有当所有标签都已出库时才更新出库单状态为"已完成"
if (totalLabels != null && outboundLabels != null && totalLabels.equals(outboundLabels) && totalLabels > 0) {
int updatedHead = otherOutboundMapper.updateOutboundStatus(outboundNo, "已完成", site, buNo);
if (updatedHead > 0) {
logger.info("出库单 {} 所有标签已出库,状态更新为已完成", outboundNo);
}
} else {
logger.info("出库单 {} 还有标签未出库,保持待出库状态", outboundNo);
}
if (!"200".equals(code)) {
String msg = String.valueOf(result.get("message"));
throw new RuntimeException(msg);
}
// 3. 生成出库事务记录
String transNo = generateOutboundTransaction(outboundNo, warehouseId, labels, site, buNo);
// 4. 异步调用ERP接口
// 新增存储过程返回200异步调用ERP接口
try {
if (transNo != null && !transNo.isEmpty()) {
logger.info("事务记录生成成功,准备异步调用ERP接口,site={}, buNo={}, transNo={}",
site, buNo, transNo);
// 异步调用ERP接口不阻塞当前流程
erpInterfaceService.asyncCallErpInterface(site, buNo, transNo);
}
String returnSite = String.valueOf(result.get("Site"));
String returnBuNo = String.valueOf(result.get("buNo"));
String transNo = String.valueOf(result.get("transNo"));
logger.info("存储过程执行成功,准备异步调用ERP接口,site={}, buNo={}, transNo={}",
returnSite, returnBuNo, transNo);
// 异步调用ERP接口不阻塞当前流程
erpInterfaceService.asyncCallErpInterface(returnSite, returnBuNo, transNo);
} catch (Exception e) {
// 异步调用失败不影响主流程只记录日志
logger.error("异步调用ERP接口触发失败(不影响主流程),出库单号: {}, 错误: {}", outboundNo, e.getMessage(), e);
@ -167,8 +197,22 @@ public class OtherOutboundServiceImpl implements OtherOutboundService {
logger.info("其他出库确认完成,出库单号: {}", outboundNo);
return true;
} catch (Exception e) {
logger.error("其他出库确认失败,出库单号: {}, 错误信息: {}", outboundNo, e.getMessage(), e);
throw new RuntimeException("出库确认失败: " + e.getMessage(), e);
logger.error("其他出库确认失败,出库单号: {}, 错误: {}", outboundNo, e.getMessage(), e);
throw new RuntimeException(e.getMessage(), e);
}
}
@Override
public List<Map<String, Object>> getScannedLabelList(String site, String buNo, String outboundNo,
String relatedNo, String relatedLineNo) {
logger.info("获取已扫描标签列表,site: {}, buNo: {}, 出库单号: {}, 关联单号: {}, 关联行号: {}",
site, buNo, outboundNo, relatedNo, relatedLineNo);
try {
return otherOutboundMapper.getScannedLabelList(site, buNo, outboundNo, relatedNo, relatedLineNo);
} catch (Exception e) {
logger.error("获取已扫描标签列表失败,错误: {}", e.getMessage(), e);
return new ArrayList<>();
}
}

21
src/main/resources/mapper/otherOutbound/OtherOutboundMapper.xml

@ -137,4 +137,25 @@
GROUP BY d.part_no, d.part_desc, d.required_qty
</select>
<!-- 获取已扫描标签列表(从临时表) -->
<select id="getScannedLabelList" resultType="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 = #{outboundNo}
<if test="relatedNo != null and relatedNo != ''">
AND OrderNo = #{relatedNo}
</if>
<if test="relatedLineNo != null and relatedLineNo != ''">
AND seqNo = #{relatedLineNo}
</if>
ORDER BY RollNo DESC
</select>
</mapper>
Loading…
Cancel
Save