Commit 4b69d55c zshaohui

1.增加双库位获取库位号,移库功能

1 个父辈 a6ad05c1
......@@ -100,4 +100,8 @@ public interface IStoragePosManager extends IBaseManager<StoragePos> {
List<StoragePos> findPosListByPartNumber(List<String> storageIdList, String pn, Collection<String> excludePosIds, CHECKOUT_TYPE checkOutType,Map<String,String> appendData);
List<StoragePos> findPosListByMpn(List<String> availableStorageIds, String mpn, Collection<String> excludePosIds, CHECKOUT_TYPE checkoutType, Map<String, String> appendDate);
int getRemainPosCountByStorage(Storage storage, Barcode barcode, Collection<String> excludePosIds, String lastPosId, String endStr) throws ValidateException;
StoragePos dualPosNameGetEmptyPosByStorage(Storage storage, Barcode barcode, Collection<String> excludePosIds,String lastPosId,String needMovePosName,String endStr,List<String> needExcludePosNameList) throws ValidateException;
}
......@@ -1033,4 +1033,95 @@ public class StoragePosManagerImpl implements IStoragePosManager {
q.with(sort);
return storagePosDao.findByQuery(q);
}
@Override
public int getRemainPosCountByStorage(Storage storage, Barcode barcode, Collection<String> excludePosIds, String lastPosId, String endStr) throws ValidateException {
Criteria c = Criteria.where("storageId").is(storage.getId());
COMPATIBLE_TYPE compatibleType = storage.getCompatibleType();
if (compatibleType == COMPATIBLE_TYPE.EXACT_MATCH) {//完全匹配
c = c.and("w").is(barcode.getPlateSize()).and("h").is(barcode.getHeight());
} else if (compatibleType == COMPATIBLE_TYPE.FULLY_COMPATIBLE) {//同厚度兼容
c = c.and("w").gte(barcode.getPlateSize()).and("h").gte(barcode.getHeight());//除7寸外,完全兼容
} else if (compatibleType == COMPATIBLE_TYPE.SIZE_COMPATIBLE) {//同尺寸兼容
c = c.and("w").is(barcode.getPlateSize()).and("h").gte(barcode.getHeight());//宽度等于料盘宽度,高度大于等于料盘高度
}
c = c.and("enabled").is(true)//可用
.and("used").is(false);//未使用
//去除的仓位
if (excludePosIds != null && !excludePosIds.isEmpty()) {
c = c.and("id").nin(excludePosIds);
}
if (StringUtils.isNotEmpty(endStr)) {
String regex = "" + endStr + "$";
c.and("posName").regex(Pattern.compile(regex));
}
Query query = new Query(c);
query.with(Sort.by(Sort.Direction.ASC, "w").and(Sort.by(Sort.Direction.ASC, "h")).and(Sort.by(Sort.Direction.DESC, "priority")));
return storagePosDao.countByQuery(query);
}
private static boolean max = true;
@Override
public StoragePos dualPosNameGetEmptyPosByStorage(Storage storage, Barcode barcode, Collection<String> excludePosIds,String lastPosId,String needMovePosName,String endStr,List<String> needExcludePosNameList) throws ValidateException {
Criteria c = Criteria.where("storageId").is(storage.getId());
COMPATIBLE_TYPE compatibleType = storage.getCompatibleType();
if (compatibleType == COMPATIBLE_TYPE.EXACT_MATCH) {//完全匹配
c = c.and("w").is(barcode.getPlateSize()).and("h").is(barcode.getHeight());
} else if (compatibleType == COMPATIBLE_TYPE.FULLY_COMPATIBLE) {//同厚度兼容
c = c.and("w").gte(barcode.getPlateSize()).and("h").gte(barcode.getHeight());//除7寸外,完全兼容
} else if (compatibleType == COMPATIBLE_TYPE.SIZE_COMPATIBLE) {//同尺寸兼容
c = c.and("w").is(barcode.getPlateSize()).and("h").gte(barcode.getHeight());//宽度等于料盘宽度,高度大于等于料盘高度
}
c = c.and("enabled").is(true)//可用
.and("used").is(false);//未使用
//去除的仓位
if (excludePosIds != null && !excludePosIds.isEmpty()) {
c = c.and("id").nin(excludePosIds);
}
if (StringUtils.isNotEmpty(needMovePosName) && StringUtils.isNotEmpty(endStr)) {
Criteria posNameCriteria = new Criteria();
String regex = ""+endStr+"$";
posNameCriteria.andOperator(Criteria.where("posName").ne(needMovePosName), Criteria.where("posName").regex(Pattern.compile(regex)));
c.andOperator(posNameCriteria);
}
if (needExcludePosNameList != null && !needExcludePosNameList.isEmpty()){
c.and("posName").nin(needExcludePosNameList);
}
Query query = new Query(c);
String msg = "";
// if (lastPosId == null || lastPosId.equals("")) {
//优先放入最合适的位置(根据尺寸),相同尺寸按优先级排序
if (max){
query.with(Sort.by(Sort.Direction.ASC, "w").and(Sort.by(Sort.Direction.ASC, "h")).and(Sort.by(Sort.Direction.DESC, "priority")));
max = true;
} else {
query.with(Sort.by(Sort.Direction.ASC, "w").and(Sort.by(Sort.Direction.ASC, "h")).and(Sort.by(Sort.Direction.ASC, "priority")));
max = false;
}
StoragePos pos = storagePosDao.findOne(query);
if ((!ObjectUtil.isNotEmpty(msg) )&& (pos != null)) {
Point targetP = PointUtil.getPosPoint(lastPosId, false);
log.debug(msg + "结果:[" + pos.getPosName() + "][" + targetP.getX() + "," + targetP.getY() + "]");
}
return pos;
}
}
......@@ -1448,4 +1448,169 @@ public class TaskService {
}
}
}
public StoragePos dualPosNameFindEmptyPosForPutIn(List<Storage> storageList, Barcode barcode, String inRFID, String lastPosId,String needMovePosName,String endStr) throws ValidateException {
verifyBarcodePutIn(storageList, barcode, inRFID);
List<String> storageIds=new ArrayList<>();
//查找任务数最少的料仓
final Map<String, Integer> storageTaskCountMap = new HashMap<>();
for (Storage storage : storageList) {
storageTaskCountMap.put(storage.getId(), 0);
storageIds.add(storage.getId());
}
Set<String> hasOutTaskStorageIds = new HashSet<>();
//如果有正在执行的任务,把库位发过去
Collection<DataLog> allTasks = taskMap.values();
for (DataLog task : allTasks) {
if (barcode.getBarcode().equals(task.getBarcode())) {
String posId = task.getPosId();
log.info(barcode.getBarcode() + " 已有任务,返回任务中的库位:" + task.getPosName());
return storagePosManager.get(posId);
}
String storageId = task.getStorageId();
if (!Strings.isNullOrEmpty(storageId)) {
Integer taskCount = storageTaskCountMap.get(storageId);
if (taskCount != null) {
taskCount = taskCount + 1;
storageTaskCountMap.put(storageId, taskCount);
}
if (task.isCheckOutTask()) {
hasOutTaskStorageIds.add(storageId);
}
}
}
String lockPosId = ReelLockPosUtil.getReelLockPosId(barcode.getBarcode());
StoragePos pos = null;
if (!Strings.isNullOrEmpty(lockPosId)) {
//已有锁定库位
pos = storagePosManager.get(lockPosId);
if (pos != null) {
if(!storageIds.contains(pos.getStorageId())){
log.info("条码[" + barcode.getBarcode() + "]已有锁定库位[" + pos.getPosName() + "],料仓ID["+pos.getStorageId()+"]不在请求列表["+String.join(",",storageIds)+"]中,重新查找库位");
pos = null;
}
else if (pos.getW() != barcode.getPlateSize() || pos.getH() != barcode.getHeight()) {
log.info("条码[" + barcode.getBarcode() + "]尺寸已改变,无法放入已锁定库位[" + pos.getPosName() + "],重新查找库位");
pos = null;
} else {
Barcode posBarcode = pos.getBarcode();
if (posBarcode == null) {
log.info("条码[" + barcode.getBarcode() + "]已锁定库位[" + pos.getPosName() + "],返回锁定中的库位");
} else {
log.info("条码[" + barcode.getBarcode() + "]已锁定库位[" + pos.getPosName() + "]中已有物料[" + posBarcode.getBarcode() + "],重新查找库位");
pos = null;
}
}
}
}
if (pos != null) {
return pos;
}
//可用的料仓(在线,且可以放入)
List<Storage> availbleStorageList = new ArrayList<>();
for (Storage storage : storageList) {
if (storage.canPutIn(barcode.getPlateSize(), barcode.getHeight())) {
availbleStorageList.add(storage);
}
}
if (availbleStorageList.isEmpty()) {
throw new ValidateException("smfcore.noValidStorage", "[{0}]料仓列表中未找到可用的料仓",new String[]{barcode.getBarcode()});
}
availbleStorageList.sort(new Comparator<Storage>() {
@Override
public int compare(Storage o1, Storage o2) {
Integer taskCount1 = storageTaskCountMap.get(o1.getId());
Integer taskCount2 = storageTaskCountMap.get(o2.getId());
return taskCount1.compareTo(taskCount2);
}
});
return dualPosNameFindEmptyPosInStorages(barcode, availbleStorageList, hasOutTaskStorageIds, lastPosId,needMovePosName,endStr);
}
private synchronized StoragePos dualPosNameFindEmptyPosInStorages(Barcode barcode, List<Storage> availbleStorageList, final Set<String> hasOutTaskStorageIds, String lastPosId,String needMovePosName,String endStr) {
List<String> needExcludePosName = new ArrayList<>();
//新增外侧有料,里侧没料,排除里侧的库位信息
List<StoragePos> allUsePosList = new ArrayList<>();
for (Storage storage : availbleStorageList) {
Map<String, StoragePos> usedPosList = dataCache.getUsedPosList(storage.getCid());
for (StoragePos pos : usedPosList.values()) {
allUsePosList.add(pos);
}
}
for (StoragePos pos : allUsePosList) {
String posName = pos.getPosName();
if (posName.endsWith("_F")) {
boolean hasEndBPos = false;
String posName_B = posName.substring(0, posName.length() - 1) + "B";
for (StoragePos usePos : allUsePosList) {
if (posName_B.equals(usePos.getPosName())) {
hasEndBPos = true;
break;
}
}
if (!hasEndBPos) {
needExcludePosName.add(posName_B);
}
}
}
//第一遍查找,先不查找有出库任务的料仓
for (Storage storage : availbleStorageList) {
if(!storage.isSmdDuo()){//DUO料仓无论是否有出库任务,都可以查找空库位
if(hasOutTaskStorageIds.contains(storage.getId())){
continue;
}
}
try {
Collection<String> operatingPosIds = excludePosIds();
log.debug("尝试从[" + storage.getCid() + "]中为[" + barcode.getBarcode() + "]查找空位");
StoragePos pos = storagePosManager.dualPosNameGetEmptyPosByStorage(storage, barcode, operatingPosIds, lastPosId,needMovePosName,endStr,needExcludePosName);
if (pos != null) {
return pos;
}
} catch (Exception e) {
log.error("尝试从[" + storage.getCid() + "]中为[" + barcode.getBarcode() + "]查找空位失败:" + e.getMessage());
}
}
//第二遍查找,从所有料仓中查找
for (Storage storage : availbleStorageList) {
try {
Collection<String> operatingPosIds = excludePosIds();
log.debug("尝试从[" + storage.getCid() + "]中为[" + barcode.getBarcode() + "]查找空位");
StoragePos pos = storagePosManager.dualPosNameGetEmptyPosByStorage(storage, barcode, operatingPosIds, lastPosId,needMovePosName,endStr,needExcludePosName);
if (pos != null) {
return pos;
}
} catch (Exception e) {
log.error("尝试从[" + storage.getCid() + "]中为[" + barcode.getBarcode() + "]查找空位失败:" + e.getMessage());
}
}
try {
String cids = "";
for (Storage storage : availbleStorageList) {
cids = cids + storage.getCid() + ",";
}
log.info(barcode.getBarcode() + " 未找到可用库位,可用料仓:" + cids);
} catch (Exception e) {
log.error("打印可用料仓出错", e);
}
return null;
}
}
支持 Markdown 格式
你添加了 0 到此讨论。请谨慎行事。
Finish editing this message first!