Browse Source

2025-11-03

pda调整扫描、查询、确认逻辑(销售出库)
master
fengyuan_yang 8 months ago
parent
commit
a38e95c439
  1. 83
      src/main/java/com/gaotao/modules/salesOutbound/controller/SalesOutboundController.java
  2. 10
      src/main/java/com/gaotao/modules/salesOutbound/dao/SalesOutboundMapper.java
  3. 47
      src/main/java/com/gaotao/modules/salesOutbound/service/SalesOutboundService.java
  4. 123
      src/main/java/com/gaotao/modules/salesOutbound/service/impl/SalesOutboundServiceImpl.java
  5. 17
      src/main/resources/mapper/salesOutbound/SalesOutboundMapper.xml

83
src/main/java/com/gaotao/modules/salesOutbound/controller/SalesOutboundController.java

@ -85,7 +85,7 @@ public class SalesOutboundController extends AbstractController {
}
/**
* 验证标签与销售出库单是否匹配并检查库存
* 验证标签与销售出库单是否匹配通过存储过程
*/
@PostMapping("/validateLabelWithOutbound")
@ApiOperation("验证标签与出库单匹配")
@ -93,9 +93,12 @@ public class SalesOutboundController extends AbstractController {
try {
String labelCode = (String) params.get("labelCode");
String outboundNo = (String) params.get("outboundNo");
String warehouseId = (String) params.get("warehouseId");
String relatedNo = (String) params.get("relatedNo");
String relatedLineNo = (String) params.get("relatedLineNo");
String site = (String) params.get("site");
String buNo = (String) params.get("buNo");
String operationType = (String) params.get("operationType");
String warehouseId = (String) params.get("warehouseId");
if (labelCode == null || labelCode.trim().isEmpty()) {
return R.error("标签条码不能为空");
@ -105,7 +108,15 @@ public class SalesOutboundController extends AbstractController {
return R.error("出库单号不能为空");
}
List<Map<String, Object>> result = salesOutboundService.validateLabelWithOutbound(labelCode, outboundNo, warehouseId, site, buNo);
if (operationType == null || operationType.trim().isEmpty()) {
operationType = "I"; // 默认为添加
}
// 获取当前登录用户
String userName = getUser().getUsername();
Map<String, Object> result = salesOutboundService.validateLabelWithOutbound(
site, buNo, outboundNo, relatedNo, relatedLineNo, labelCode, operationType, userName, warehouseId);
return R.ok().put("data", result);
} catch (Exception e) {
@ -115,12 +126,7 @@ public class SalesOutboundController extends AbstractController {
}
/**
* 确认销售出库
* 系统逻辑
* 1. 更新库存表中的标签状态
* 2. 更改outbound_notification_head表中的单据状态为"已出库"
* 3. 生成WMS出库记录Transheader...
* 4. 异步调用ERP接口回传数据
* 确认销售出库通过存储过程
*/
@PostMapping("/confirmSalesOutbound")
@ApiOperation("确认销售出库")
@ -129,27 +135,19 @@ public class SalesOutboundController 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 = salesOutboundService.confirmSalesOutbound(site, buNo, outboundNo, warehouseId, labels);
// 获取当前登录用户
String userName = getUser().getUsername();
boolean success = salesOutboundService.confirmSalesOutbound(
site, buNo, outboundNo, relatedNo, relatedLineNo, locationCode, userName);
if (success) {
return R.ok("出库成功");
} else {
@ -193,4 +191,39 @@ public class SalesOutboundController extends AbstractController {
return R.error("获取物料清单失败: " + e.getMessage());
}
}
/**
* 获取已扫描标签列表从临时表
*/
@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 (site == null || site.trim().isEmpty()) {
return R.error("站点不能为空");
}
if (buNo == null || buNo.trim().isEmpty()) {
return R.error("业务单元不能为空");
}
if (outboundNo == null || outboundNo.trim().isEmpty()) {
return R.error("出库单号不能为空");
}
List<Map<String, Object>> labelList = salesOutboundService.getScannedLabelList(
site, buNo, outboundNo, relatedNo, relatedLineNo);
return R.ok().put("data", labelList);
} catch (Exception e) {
logger.error("获取已扫描标签列表失败", e);
return R.error("获取已扫描标签列表失败: " + e.getMessage());
}
}
}

10
src/main/java/com/gaotao/modules/salesOutbound/dao/SalesOutboundMapper.java

@ -61,4 +61,14 @@ public interface SalesOutboundMapper {
List<Map<String, Object>> getMaterialList(@Param("site") String site,
@Param("buNo") String buNo,
@Param("outboundNo") String outboundNo);
/**
* 获取已扫描标签列表从临时表
* 数据来源ScannedRollTempTable
*/
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/salesOutbound/service/SalesOutboundService.java

@ -32,32 +32,37 @@ public interface SalesOutboundService {
Map<String, Object> getOutboundDetails(String outboundNo, String buNo, String warehouseId, String site);
/**
* 验证标签与销售出库单是否匹配并检查库存
* 从库存表验证标签信息
* @param labelCode 标签条码
* @param outboundNo 出库单号
* @param warehouseId 仓库ID
* 验证标签与销售出库单是否匹配通过存储过程
* @param site 站点
* @param buNo 业务单元
* @param outboundNo 出库单号
* @param relatedNo 关联单号
* @param relatedLineNo 关联单行号
* @param labelCode 标签条码
* @param operationType 操作类型 I-添加 D-移除
* @param userName 当前登录人
* @param warehouseId 仓库ID
* @return 标签信息
*/
List<Map<String, Object>> validateLabelWithOutbound(String labelCode, String outboundNo,
String warehouseId, String site, String buNo);
Map<String, Object> validateLabelWithOutbound(String site, String buNo, String outboundNo,
String relatedNo, String relatedLineNo,
String labelCode, String operationType,
String userName, String warehouseId);
/**
* 确认销售出库
* 1. 更新库存表中的标签状态
* 2. 更新outbound_notification_head表状态
* 3. 生成出库事务记录
* 确认销售出库通过存储过程
* @param site 站点
* @param buNo 业务单元
* @param outboundNo 出库单号
* @param warehouseId 仓库ID
* @param labels 标签列表
* @param relatedNo 关联单号
* @param relatedLineNo 关联单行号
* @param locationCode 库位
* @param userName 当前登录人
* @return 处理结果
*/
boolean confirmSalesOutbound(String site, String buNo, String outboundNo,
String warehouseId, List<Map<String, Object>> labels);
boolean confirmSalesOutbound(String site, String buNo, String outboundNo,
String relatedNo, String relatedLineNo,
String locationCode, String userName);
/**
* 获取销售出库单物料清单
@ -68,4 +73,16 @@ public interface SalesOutboundService {
* @return 物料清单
*/
List<Map<String, Object>> getMaterialList(String site, String buNo, String outboundNo);
/**
* 获取已扫描标签列表从临时表
* @param site 站点
* @param buNo 业务单元
* @param outboundNo 出库单号
* @param relatedNo 关联单号
* @param relatedLineNo 关联单行号
* @return 标签列表
*/
List<Map<String, Object>> getScannedLabelList(String site, String buNo, String outboundNo,
String relatedNo, String relatedLineNo);
}

123
src/main/java/com/gaotao/modules/salesOutbound/service/impl/SalesOutboundServiceImpl.java

@ -11,6 +11,7 @@ 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 com.gaotao.modules.schedule.mapper.ProcedureMapper;
import org.apache.shiro.SecurityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -42,6 +43,9 @@ public class SalesOutboundServiceImpl implements SalesOutboundService {
@Autowired
private TransDetailSubService transDetailSubService;
@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();
@ -56,48 +60,95 @@ public class SalesOutboundServiceImpl implements SalesOutboundService {
}
@Override
public List<Map<String, Object>> validateLabelWithOutbound(String labelCode, String outboundNo, String warehouseId, String site, String buNo) {
// 从库存表验证标签信息并检查是否与出库单匹配
List<Map<String, Object>> result = salesOutboundMapper.validateLabelWithOutbound(labelCode, outboundNo, warehouseId, site, buNo);
if (result == null || result.isEmpty()) {
throw new RuntimeException("该标签与出库单不符,请检查");
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 {
// 调用存储过程 GetScanLabelVerification
List<Object> params = new ArrayList<>();
params.add(site); // 参数1: site
params.add(buNo); // 参数2: buNo
params.add(outboundNo); // 参数3: 出库单号
params.add(relatedNo); // 参数4: 关联单号
params.add(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 = 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, operationType);
return result;
} catch (Exception e) {
logger.error("标签验证失败,标签: {}, 错误: {}", labelCode, e.getMessage(), e);
throw new RuntimeException(e.getMessage(), e);
}
return result;
}
@Override
@Transactional(rollbackFor = Exception.class)
public boolean confirmSalesOutbound(String site, String buNo, String outboundNo, String warehouseId, List<Map<String, Object>> labels) {
logger.info("开始确认销售出库,出库单号: {}, 仓库ID: {}, 标签数量: {}", outboundNo, warehouseId, labels.size());
public boolean confirmSalesOutbound(String site, String buNo, String outboundNo,
String relatedNo, String relatedLineNo,
String locationCode, String userName) {
logger.info("开始确认销售出库,site: {}, buNo: {}, 出库单号: {}, 关联单号: {}, 关联行号: {}, 库位: {}",
site, buNo, outboundNo, relatedNo, relatedLineNo, locationCode);
try {
// 1. 提取标签条码列表
List<String> labelCodes = labels.stream()
.map(label -> (String) label.get("labelCode"))
.collect(Collectors.toList());
// 2. 更新库存表中标签状态为"出库"
int updatedLabels = salesOutboundMapper.updateInventoryStatus(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(outboundNo); // 参数3: 出库单号
params.add(relatedNo); // 参数4: 关联单号
params.add(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("存储过程调用失败");
}
// // 3. 更新outbound_notification_head表状态为"已出库"
// int updatedHead = salesOutboundMapper.updateOutboundNotificationStatus(outboundNo, "已出库", site, buNo);
// if (updatedHead == 0) {
// throw new RuntimeException("出库单状态更新失败");
// }
// 4. 生成出库事务记录
generateOutboundTransaction(outboundNo, warehouseId, labels, site, buNo);
Map<String, Object> result = resultList.get(0);
String code = String.valueOf(result.get("code"));
// 5. 异步调用ERP接口这里可以发送消息到队列
//asyncCallErpInterface(outboundNo, labels);
if (!"200".equals(code)) {
String msg = String.valueOf(result.get("message"));
throw new RuntimeException(msg);
}
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);
}
}
@ -154,6 +205,20 @@ public class SalesOutboundServiceImpl implements SalesOutboundService {
}
}
@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 salesOutboundMapper.getScannedLabelList(site, buNo, outboundNo, relatedNo, relatedLineNo);
} catch (Exception e) {
logger.error("获取已扫描标签列表失败,错误: {}", e.getMessage(), e);
return new ArrayList<>();
}
}
/**
* 生成事务明细记录
*/

17
src/main/resources/mapper/salesOutbound/SalesOutboundMapper.xml

@ -135,4 +135,21 @@
ORDER BY ond.PART_NO
</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}
AND OrderNo = #{relatedNo}
AND seqNo = #{relatedLineNo}
ORDER BY RollNo DESC
</select>
</mapper>
Loading…
Cancel
Save