Browse Source

2026-01-20

跨区调拨优化
拆合组托优化
master
fengyuan_yang 1 month ago
parent
commit
4b80fa46ed
  1. 58
      src/main/java/com/gaotao/modules/crossAreaTransfer/service/impl/CrossAreaTransferServiceImpl.java
  2. 133
      src/main/java/com/gaotao/modules/labelSplitMerge/service/impl/LabelSplitMergeServiceImpl.java
  3. 4
      src/main/resources/mapper/warehouse/LabelTransactionLogMapper.xml

58
src/main/java/com/gaotao/modules/crossAreaTransfer/service/impl/CrossAreaTransferServiceImpl.java

@ -149,7 +149,7 @@ public class CrossAreaTransferServiceImpl extends ServiceImpl<CrossAreaTransferM
throw new RuntimeException("该库位已停用,请检查");
}
// 2. 调用出库存储过程 GetSaveLabelVerification跨区调拨-出库
// 2. 调用出库存储过程 GetSaveLabelVerification调拨出库
logger.info("开始调用出库存储过程,site: {}, buNo: {}, sourceLocation: {}", site, buNo, sourceLocation);
List<Object> outboundParams = new ArrayList<>();
outboundParams.add(site); // 参数1: site
@ -160,7 +160,7 @@ public class CrossAreaTransferServiceImpl extends ServiceImpl<CrossAreaTransferM
outboundParams.add("label".equals(transferMode) ? "标签" : "库位"); // 参数6: 扫描的类型 "标签/库位"
outboundParams.add(sourceLocation); // 参数7: 扫描的标签条码/库位号
outboundParams.add(targetLocation != null ? targetLocation : ""); // 参数8: 保存时的库位
outboundParams.add("跨区调拨-出库"); // 参数9: 跨区调拨-出库
outboundParams.add("调拨出库"); // 参数9: 调拨出库
outboundParams.add(operator); // 参数10: 当前登陆人
List<Map<String, Object>> outboundResultList = procedureMapper.getProcedureData("GetSaveLabelVerification", outboundParams);
@ -178,34 +178,41 @@ public class CrossAreaTransferServiceImpl extends ServiceImpl<CrossAreaTransferM
throw new RuntimeException("跨区调拨出库失败: " + msg);
}
// 如果出库返回的transNo有值且不为"*"则异步调用ERP接口
// 获取出库返回的transNo用于入库时传递
String outboundTransNo = String.valueOf(outboundResult.get("transNo"));
// 如果出库返回的synced_flag为'Y'则异步调用ERP接口
try {
String outboundTransNo = String.valueOf(outboundResult.get("transNo"));
if (outboundTransNo != null && !outboundTransNo.isEmpty() && !"*".equals(outboundTransNo) && !"null".equals(outboundTransNo)) {
String returnSite = String.valueOf(outboundResult.get("Site"));
String returnBuNo = String.valueOf(outboundResult.get("buNo"));
logger.info("跨区调拨出库存储过程执行成功,准备异步调用ERP接口,site={}, buNo={}, transNo={}",
returnSite, returnBuNo, outboundTransNo);
erpInterfaceService.asyncCallErpInterface(returnSite, returnBuNo, outboundTransNo);
String syncedFlag = String.valueOf(outboundResult.get("syncedFlag"));
if ("Y".equalsIgnoreCase(syncedFlag)) {
if (outboundTransNo != null && !outboundTransNo.isEmpty() && !"*".equals(outboundTransNo) && !"null".equals(outboundTransNo)) {
String returnSite = String.valueOf(outboundResult.get("Site"));
String returnBuNo = String.valueOf(outboundResult.get("buNo"));
logger.info("跨区调拨出库存储过程执行成功,synced_flag=Y,准备异步调用ERP接口,site={}, buNo={}, transNo={}",
returnSite, returnBuNo, outboundTransNo);
erpInterfaceService.asyncCallErpInterface(returnSite, returnBuNo, outboundTransNo);
}
} else {
logger.info("跨区调拨出库transNo为空或'*',不调用ERP接口");
logger.info("跨区调拨出库synced_flag不为'Y',不调用ERP接口,synced_flag={}", syncedFlag);
}
} catch (Exception e) {
logger.error("跨区调拨出库异步调用ERP接口触发失败(不影响主流程),错误: {}", e.getMessage(), e);
}
// 3. 调用入库存储过程 GetSaveLabelVerification跨区调拨-入库
logger.info("开始调用入库存储过程,site: {}, buNo: {}, targetLocation: {}", site, buNo, targetLocation);
// 3. 调用入库存储过程 GetSaveLabelVerification调拨入库
// 入库时需要传递出库返回的transNo作为第三个参数
logger.info("开始调用入库存储过程,site: {}, buNo: {}, targetLocation: {}, outboundTransNo: {}", site, buNo, targetLocation, outboundTransNo);
List<Object> inboundParams = new ArrayList<>();
inboundParams.add(site); // 参数1: site
inboundParams.add(buNo); // 参数2: buNo
inboundParams.add(""); // 参数3: 空字符串
// 参数3: 传递出库返回的transNo
inboundParams.add(outboundTransNo != null && !"null".equals(outboundTransNo) && !"*".equals(outboundTransNo) ? outboundTransNo : "");
inboundParams.add(""); // 参数4: 空字符串
inboundParams.add(""); // 参数5: 空字符串
inboundParams.add("label".equals(transferMode) ? "标签" : "库位"); // 参数6: 扫描的类型 "标签/库位"
inboundParams.add(sourceLocation); // 参数7: 扫描的标签条码/库位号
inboundParams.add(targetLocation != null ? targetLocation : ""); // 参数8: 保存时的库位目标库位
inboundParams.add("跨区调拨-入库"); // 参数9: 跨区调拨-入库
inboundParams.add("调拨入库"); // 参数9: 调拨入库
inboundParams.add(operator); // 参数10: 当前登陆人
List<Map<String, Object>> inboundResultList = procedureMapper.getProcedureData("GetSaveLabelVerification", inboundParams);
@ -223,17 +230,20 @@ public class CrossAreaTransferServiceImpl extends ServiceImpl<CrossAreaTransferM
throw new RuntimeException("跨区调拨入库失败: " + msg);
}
// 如果入库返回的transNo有值且不为"*"则异步调用ERP接口
// 如果入库返回的synced_flag为'Y'则异步调用ERP接口
try {
String inboundTransNo = String.valueOf(inboundResult.get("transNo"));
if (inboundTransNo != null && !inboundTransNo.isEmpty() && !"*".equals(inboundTransNo) && !"null".equals(inboundTransNo)) {
String returnSite = String.valueOf(inboundResult.get("Site"));
String returnBuNo = String.valueOf(inboundResult.get("buNo"));
logger.info("跨区调拨入库存储过程执行成功,准备异步调用ERP接口,site={}, buNo={}, transNo={}",
returnSite, returnBuNo, inboundTransNo);
erpInterfaceService.asyncCallErpInterface(returnSite, returnBuNo, inboundTransNo);
String inboundSyncedFlag = String.valueOf(inboundResult.get("syncedFlag"));
if ("Y".equalsIgnoreCase(inboundSyncedFlag)) {
String inboundTransNo = String.valueOf(inboundResult.get("transNo"));
if (inboundTransNo != null && !inboundTransNo.isEmpty() && !"*".equals(inboundTransNo) && !"null".equals(inboundTransNo)) {
String returnSite = String.valueOf(inboundResult.get("Site"));
String returnBuNo = String.valueOf(inboundResult.get("buNo"));
logger.info("跨区调拨入库存储过程执行成功,synced_flag=Y,准备异步调用ERP接口,site={}, buNo={}, transNo={}",
returnSite, returnBuNo, inboundTransNo);
erpInterfaceService.asyncCallErpInterface(returnSite, returnBuNo, inboundTransNo);
}
} else {
logger.info("跨区调拨入库transNo为空或'*',不调用ERP接口");
logger.info("跨区调拨入库synced_flag不为'Y',不调用ERP接口,synced_flag={}", inboundSyncedFlag);
}
} catch (Exception e) {
logger.error("跨区调拨入库异步调用ERP接口触发失败(不影响主流程),错误: {}", e.getMessage(), e);

133
src/main/java/com/gaotao/modules/labelSplitMerge/service/impl/LabelSplitMergeServiceImpl.java

@ -84,22 +84,18 @@ public class LabelSplitMergeServiceImpl extends ServiceImpl<LabelSplitMergeMappe
String operator = (String) params.get("operator");
Float originalQuantity = Float.parseFloat(params.get("originalQuantity").toString());
// 获取拆分张数默认为1兼容旧版本
Integer splitCount = params.get("splitCount") != null ? Integer.parseInt(params.get("splitCount").toString()) : 1;
Float splitQuantity = Float.parseFloat(params.get("splitQuantity").toString());
Float remainingQuantity = originalQuantity - splitQuantity;
// 总拆分数量 = 拆分张数 * 每张数量
Float totalSplitQuantity = splitCount * splitQuantity;
Float remainingQuantity = originalQuantity - totalSplitQuantity;
if (splitQuantity <= 0 || splitQuantity >= originalQuantity) {
throw new RuntimeException("拆分数必须大于0且小于原数量");
if (splitCount <= 0) {
throw new RuntimeException("拆分数必须大于0");
}
// 1. 生成新的标签条码
TransNoControl transNoControl = transNoControlService.getTransNo(site, "LabelNo", buNo);
if (transNoControl == null) {
throw new RuntimeException("生成标签条码失败");
}
String newLabelCode = transNoControl.getNewTransNo();
if (newLabelCode == null || newLabelCode.trim().isEmpty()) {
throw new RuntimeException("生成新标签条码失败");
if (splitQuantity <= 0 || totalSplitQuantity >= originalQuantity) {
throw new RuntimeException("拆分总数量必须大于0且小于原数量");
}
// 2. 更新原标签的库存数量
@ -115,45 +111,61 @@ public class LabelSplitMergeServiceImpl extends ServiceImpl<LabelSplitMergeMappe
throw new RuntimeException("更新原标签库存失败");
}
// 3. 创建新标签的库存记录
Map<String, Object> insertParams = new HashMap<>();
insertParams.put("site", site);
insertParams.put("buNo", buNo);
insertParams.put("rollNo", newLabelCode);
insertParams.put("parentRollNo", newLabelCode);
insertParams.put("partNo", partNo);
insertParams.put("labelTypeTb", params.get("labelTypeTb"));
insertParams.put("labelType", params.get("labelType"));
insertParams.put("warehouseId", warehouseId);
insertParams.put("locationId", locationId);
insertParams.put("batchNo", batchNo);
insertParams.put("wdr", params.get("wdr"));
insertParams.put("statusTb", params.get("statusTb"));
insertParams.put("status", params.get("status"));
insertParams.put("firstInDate", params.get("firstInDate"));
insertParams.put("latestInDate", new Date());
insertParams.put("activeDate", new Date());
insertParams.put("inQty", splitQuantity);
insertParams.put("outQty", 0.0f);
insertParams.put("qtyOnHand", splitQuantity);
insertParams.put("qtyReserved", 0.0f);
insertParams.put("freezeFlag", params.get("freezeFlag"));
insertParams.put("manufactureDate", params.get("manufactureDate"));
insertParams.put("expiredDate", params.get("expiredDate"));
insertParams.put("orderref0", "标签拆分入库");
insertParams.put("orderref1", params.get("orderref1"));
insertParams.put("orderref2", params.get("orderref2"));
insertParams.put("orderref3", params.get("orderref3"));
int insertCount = labelSplitMergeMapper.insertInventoryStock(insertParams);
if (insertCount == 0) {
throw new RuntimeException("创建新标签库存失败");
}
// 3. 循环创建多张新标签的库存记录
List<String> newLabelCodes = new ArrayList<>();
for (int i = 0; i < splitCount; i++) {
// 生成新的标签条码
TransNoControl transNoControl = transNoControlService.getTransNo(site, "LabelNo", buNo);
if (transNoControl == null) {
throw new RuntimeException("生成标签条码失败");
}
String newLabelCode = transNoControl.getNewTransNo();
// 5. 生成标签变动事务记录
generateSplitTransaction(site, buNo, warehouseId, originalLabelCode, newLabelCode, partNo, batchNo, splitQuantity, remainingQuantity, locationId);
if (newLabelCode == null || newLabelCode.trim().isEmpty()) {
throw new RuntimeException("生成新标签条码失败");
}
newLabelCodes.add(newLabelCode);
// 创建新标签的库存记录
Map<String, Object> insertParams = new HashMap<>();
insertParams.put("site", site);
insertParams.put("buNo", buNo);
insertParams.put("rollNo", newLabelCode);
insertParams.put("parentRollNo", newLabelCode);
insertParams.put("partNo", partNo);
insertParams.put("labelTypeTb", params.get("labelTypeTb"));
insertParams.put("labelType", params.get("labelType"));
insertParams.put("warehouseId", warehouseId);
insertParams.put("locationId", locationId);
insertParams.put("batchNo", batchNo);
insertParams.put("wdr", params.get("wdr"));
insertParams.put("statusTb", params.get("statusTb"));
insertParams.put("status", params.get("status"));
insertParams.put("firstInDate", params.get("firstInDate"));
insertParams.put("latestInDate", new Date());
insertParams.put("activeDate", new Date());
insertParams.put("inQty", splitQuantity);
insertParams.put("outQty", 0.0f);
insertParams.put("qtyOnHand", splitQuantity);
insertParams.put("qtyReserved", 0.0f);
insertParams.put("freezeFlag", params.get("freezeFlag"));
insertParams.put("manufactureDate", params.get("manufactureDate"));
insertParams.put("expiredDate", params.get("expiredDate"));
insertParams.put("orderref0", "标签拆分入库");
insertParams.put("orderref1", params.get("orderref1"));
insertParams.put("orderref2", params.get("orderref2"));
insertParams.put("orderref3", params.get("orderref3"));
int insertCount = labelSplitMergeMapper.insertInventoryStock(insertParams);
if (insertCount == 0) {
throw new RuntimeException("创建新标签库存失败");
}
// 6. 获取打印参数列表拆分需要打印两张标签原标签和新标签
// 生成标签变动事务记录
generateSplitTransaction(site, buNo, warehouseId, originalLabelCode, newLabelCode, partNo, batchNo, splitQuantity, remainingQuantity, locationId);
}
// 6. 获取打印参数列表拆分需要打印多张标签原标签 + 所有新标签
List<Map<String, Object>> printList = new ArrayList<>();
try {
// 原标签打印参数
@ -164,25 +176,30 @@ public class LabelSplitMergeServiceImpl extends ServiceImpl<LabelSplitMergeMappe
printList.add(printData1);
}
// 新标签打印参数
Map<String, Object> printData2 = wmsPrintDao.callUspPartLabelTemplate(
site, buNo, "*", "", "", "", partNo, "", newLabelCode
);
if (printData2 != null) {
printList.add(printData2);
// 所有新标签打印参数
for (String newLabelCode : newLabelCodes) {
Map<String, Object> printData = wmsPrintDao.callUspPartLabelTemplate(
site, buNo, "*", "", "", "", partNo, "", newLabelCode
);
if (printData != null) {
printList.add(printData);
}
}
} catch (Exception e) {
logger.warn("获取打印参数失败,不影响拆分操作", e);
}
Map<String, Object> result = new HashMap<>();
result.put("newLabelCode", newLabelCode);
result.put("newLabelCode", newLabelCodes.isEmpty() ? "" : newLabelCodes.get(0)); // 兼容旧版本
result.put("newLabelCodes", newLabelCodes); // 新版本返回所有新标签
result.put("originalQuantity", originalQuantity);
result.put("splitCount", splitCount);
result.put("splitQuantity", splitQuantity);
result.put("totalSplitQuantity", totalSplitQuantity);
result.put("remainingQuantity", remainingQuantity);
result.put("printList", printList);
logger.info("标签拆分成功,原标签: {}, 新标签: {}, 拆分数量: {}", originalLabelCode, newLabelCode, splitQuantity);
logger.info("标签拆分成功,原标签: {}, 新标签: {}, 拆分张数: {}, 每张数量: {}", originalLabelCode, newLabelCodes, splitCount, splitQuantity);
return result;
} catch (Exception e) {

4
src/main/resources/mapper/warehouse/LabelTransactionLogMapper.xml

@ -41,7 +41,7 @@
<if test="query.documentType != null and query.documentType != ''">
<choose>
<when test="query.documentType == '移库调拨'">
AND a.document_type IN ('跨区调拨-出库', '跨区调拨-入库')
AND a.document_type IN ('调拨出库', '调拨入库')
</when>
<otherwise>
AND a.document_type = #{query.documentType}
@ -97,7 +97,7 @@
<if test="query.documentType != null and query.documentType != ''">
<choose>
<when test="query.documentType == '移库调拨'">
AND a.document_type IN ('跨区调拨-出库', '跨区调拨-入库')
AND a.document_type IN ('调拨出库', '调拨入库')
</when>
<otherwise>
AND a.document_type = #{query.documentType}

Loading…
Cancel
Save