Browse Source

中山自动移库优化

master
常熟吴彦祖 2 weeks ago
parent
commit
6c9b2126d8
  1. 133
      src/main/java/com/gaotao/modules/api/service/impl/WmsMessageServiceImpl.java

133
src/main/java/com/gaotao/modules/api/service/impl/WmsMessageServiceImpl.java

@ -804,11 +804,10 @@ public class WmsMessageServiceImpl implements WmsMessageService {
}
/**
* @Description 执行自动化托运托盘移库(IFS调用改为写入队列表)- rqrq
* @param request 移库请求参数
* @return 处理结果
* @author rqrq
* @date 2026/08/24
* @Description 执行自动化托运托盘移库(IFS调用改为写入队列表)。开头只收在库Y且标签表存在的明细,查不到或非Y的留盘不抛错,避免脏标签把WCS/AGV整托打死 - rqrq
* @param request 移库请求,site/palletId/目标仓库库位来自回调,username用于事务审计 - rqrq
* @return 处理结果说明;无可搬标签时返回无需移库,调用方仍可更新托盘位置 - rqrq
*/
@Override
@Transactional(rollbackFor = Exception.class)
@ -834,43 +833,16 @@ public class WmsMessageServiceImpl implements WmsMessageService {
pallet.setLocationCode(request.getToStation());
pallet.setWcsLocation(request.getToStation());
String fromWarehouseId;
String fromLocationId;
// 从pallet_detail的第一条记录获取serialNo,查询handling_unit的仓库和库位 - rqrq
PalletDetail firstPalletDetail = palletDetails.get(0);
HandlingUnit firstHu = handlingUnitService.lambdaQuery()
.eq(HandlingUnit::getSite, request.getSite())
.eq(HandlingUnit::getUnitId, firstPalletDetail.getSerialNo())
.one();
if (firstHu == null) {
throw new RuntimeException("未找到条码对应的处理单元:" + firstPalletDetail.getSerialNo());
}
fromWarehouseId = firstHu.getWarehouseId();
fromLocationId = firstHu.getLocationId();
if(fromWarehouseId.equals(request.getToWarehouseId())&&fromLocationId.equals(request.getToLocationId())){
return "托盘无需执行移库操作:" + request.getPalletId();
}
// 5. 获取条码对应的HandlingUnit信息
List<String> serialNos = palletDetails.stream()
.map(PalletDetail::getSerialNo)
.collect(Collectors.toList());
List<HandlingUnit> handlingUnits = handlingUnitService.lambdaQuery()
.eq(HandlingUnit::getSite, request.getSite())
.in(HandlingUnit::getUnitId, serialNos)
.list();
// 只收可自动搬库的Y标签:查不到/非Y/数量无效/已在目标库的明细留盘,不按第一条标签决定整托 - rqrq
List<HandlingUnit> handlingUnits = collectAutoTransferHandlingUnits(
request.getSite(), request.getPalletId(), request.getToWarehouseId(), request.getToLocationId(), palletDetails);
if (handlingUnits.isEmpty()) {
throw new RuntimeException("未找到托盘上的条码信息");
return "托盘无需执行移库操作:" + request.getPalletId();
}
// 事务头来源仓库取第一份可搬Y标签;后续明细仍按标签自身库位分组,兼容混库位 - rqrq
String fromWarehouseId = handlingUnits.get(0).getWarehouseId();
// 6. 生成移库出库和入库的事务号
TransNoControl stoTransData = transNoControlService.getTransNo(request.getSite(), "STO", 10);
@ -1104,6 +1076,89 @@ public class WmsMessageServiceImpl implements WmsMessageService {
detailSub.setEngChgLevel(hu.getEngChgLevel()); // 添加工程更改级别 - rqrq
return detailSub;
}
/**
* @author rqrq
* @Description 自动移库开头收紧可搬标签:只保留handling_unit存在、in_stock_flag=Y、数量>0、且仓库或库位与目标不同的标签。
* 查不到、非Y、数量无效或已在目标库的明细留在托盘不抛错、不删pallet_detail,避免脏数据把整托回调打死。
* 同一条码只收一次,防止重复明细把数量算两次。- rqrq
* @param site 请求工厂,必须与托盘和标签site一致,禁止登录态兜底 - rqrq
* @param palletId 托盘号,仅用于日志定位留盘标签 - rqrq
* @param toWarehouseId 目标仓库,与当前仓库都相同且库位也相同时该标签跳过 - rqrq
* @param toLocationId 目标库位,与当前库位都相同且仓库也相同时该标签跳过 - rqrq
* @param palletDetails 当前托盘全部明细,本方法不改明细表 - rqrq
* @return 需要自动移库的Y标签列表,空表示整托跳过移库 - rqrq
*/
private List<HandlingUnit> collectAutoTransferHandlingUnits(String site, String palletId, String toWarehouseId,
String toLocationId, List<PalletDetail> palletDetails) {
List<HandlingUnit> movableUnits = new ArrayList<HandlingUnit>();
if (palletDetails == null || palletDetails.isEmpty()) {
return movableUnits;
}
List<String> serialNos = new ArrayList<String>();
for (PalletDetail detail : palletDetails) {
if (detail == null || !StringUtils.hasText(detail.getSerialNo())) {
continue;
}
serialNos.add(detail.getSerialNo().trim());
}
if (serialNos.isEmpty()) {
log.warn("自动移库跳过:托盘明细没有有效条码,site={},palletId={} - rqrq", site, palletId);
return movableUnits;
}
// 按site+条码批量查标签主数据;查不到的后面按明细逐条留盘,这里空结果不抛错 - rqrq
List<HandlingUnit> foundUnits = handlingUnitService.lambdaQuery()
.eq(HandlingUnit::getSite, site)
.in(HandlingUnit::getUnitId, serialNos)
.list();
Map<String, HandlingUnit> huByUnitId = new LinkedHashMap<String, HandlingUnit>();
if (foundUnits != null) {
for (HandlingUnit hu : foundUnits) {
if (hu != null && StringUtils.hasText(hu.getUnitId())) {
huByUnitId.put(hu.getUnitId().trim(), hu);
}
}
}
Set<String> acceptedSerialNos = new HashSet<String>();
String targetWarehouse = StringUtils.hasText(toWarehouseId) ? toWarehouseId.trim() : "";
String targetLocation = StringUtils.hasText(toLocationId) ? toLocationId.trim() : "";
for (PalletDetail detail : palletDetails) {
if (detail == null || !StringUtils.hasText(detail.getSerialNo())) {
continue;
}
String serialNo = detail.getSerialNo().trim();
if (!acceptedSerialNos.add(serialNo)) {
continue;
}
HandlingUnit hu = huByUnitId.get(serialNo);
if (hu == null) {
log.warn("自动移库留盘:标签表不存在,site={},palletId={},serialNo={} - rqrq", site, palletId, serialNo);
continue;
}
if (!"Y".equalsIgnoreCase(StringUtils.hasText(hu.getInStockFlag()) ? hu.getInStockFlag().trim() : "")) {
log.warn("自动移库留盘:标签非在库Y,site={},palletId={},serialNo={},inStockFlag={} - rqrq",
site, palletId, serialNo, hu.getInStockFlag());
continue;
}
if (hu.getQty() == null || hu.getQty().compareTo(BigDecimal.ZERO) <= 0) {
log.warn("自动移库留盘:标签数量无效,site={},palletId={},serialNo={},qty={} - rqrq",
site, palletId, serialNo, hu.getQty());
continue;
}
String currentWarehouse = StringUtils.hasText(hu.getWarehouseId()) ? hu.getWarehouseId().trim() : "";
String currentLocation = StringUtils.hasText(hu.getLocationId()) ? hu.getLocationId().trim() : "";
if (targetWarehouse.equals(currentWarehouse) && targetLocation.equals(currentLocation)) {
log.info("自动移库跳过:标签已在目标仓库库位,site={},palletId={},serialNo={} - rqrq",
site, palletId, serialNo);
continue;
}
movableUnits.add(hu);
}
if (movableUnits.isEmpty()) {
log.info("自动移库跳过:托盘没有可搬的在库Y标签,site={},palletId={} - rqrq", site, palletId);
}
return movableUnits;
}
/**
* 获取托盘明细信息

Loading…
Cancel
Save