Commit eb59e043 LN

设备通信增加获取库位号的emptyPosForPutin接口

1 个父辈 eafaf694
...@@ -177,7 +177,7 @@ public class DataInitManager { ...@@ -177,7 +177,7 @@ public class DataInitManager {
menus.addAll(createMenus(menukanban)); menus.addAll(createMenus(menukanban));
//料架分组 //料架分组
Menu menuShelf = new Menu(new ArrayList<Menu>(), 1, "menu:list", "料架分组", 1, "lightGroup", "neolight/lightGroup/index", "", 0, "list"); Menu menuShelf = new Menu(new ArrayList<Menu>(), 1, "menu:list", "料架分组", 1, "lightGroup", "neolight/lightGroup/index", "", 0, "list");
menuShelf.setHidden(true); // menuShelf.setHidden(true);
menus.addAll(createMenus(menuShelf)); menus.addAll(createMenus(menuShelf));
//出库:工单,查找出库 //出库:工单,查找出库
......
...@@ -70,7 +70,13 @@ public class Barcode extends BasePo implements Serializable { ...@@ -70,7 +70,13 @@ public class Barcode extends BasePo implements Serializable {
* 标签解析出来的数量,用于判断条码是否是重新打印的,重新打印的条码需要重新设置数量 * 标签解析出来的数量,用于判断条码是否是重新打印的,重新打印的条码需要重新设置数量
*/ */
private int labelAmount = 0; private int labelAmount = 0;
/**
* 盘宽
*/
private int plateSize=0; private int plateSize=0;
/**
* 盘高
*/
private int height=0; private int height=0;
private String provider; private String provider;
/** /**
...@@ -350,6 +356,13 @@ public class Barcode extends BasePo implements Serializable { ...@@ -350,6 +356,13 @@ public class Barcode extends BasePo implements Serializable {
return false; return false;
} }
/**
* 是否是小料(7x8)的料
*/
public boolean isSmallReel(){
if(getPlateSize() == 7){
return getHeight() == 8 || getHeight() == 12;
}
return false;
}
} }
...@@ -126,4 +126,15 @@ public class BoxStatusBean { ...@@ -126,4 +126,15 @@ public class BoxStatusBean {
public String getPosId(){ public String getPosId(){
return data.get("posId"); return data.get("posId");
} }
/**
* 获取客户端发送上来的出入库完成的库位信息
*/
public int getExecuteTime (){
if(data!=null&&data.containsKey("executeTime")){
return Integer.parseInt(data.get("executeTime"));
}
return -1;
}
} }
...@@ -364,13 +364,14 @@ public class BaseDeviceHandler implements IDeviceHandler { ...@@ -364,13 +364,14 @@ public class BaseDeviceHandler implements IDeviceHandler {
//出库入库完成处理 //出库入库完成处理
int status = boxStatus.getStatus(); int status = boxStatus.getStatus();
String posName = boxStatus.getPosId(); String posName = boxStatus.getPosId();
int executeTime=boxStatus.getExecuteTime();
if (!Strings.isNullOrEmpty(posName)) {//客户端发一次完成之后,会发空的 posName,不需要处理 if (!Strings.isNullOrEmpty(posName)) {//客户端发一次完成之后,会发空的 posName,不需要处理
if (BOX_STATUS.IN_FINISHED == status) {//入仓完成 if (BOX_STATUS.IN_FINISHED == status) {//入仓完成
finishedPutIn(statusBean.getCid(),posName); finishedPutIn(statusBean.getCid(),posName,executeTime);
} else if (BOX_STATUS.IN_FAILED == status) {//入库失败 } else if (BOX_STATUS.IN_FAILED == status) {//入库失败
//暂不处理 //暂不处理
} else if (BOX_STATUS.OUT_FINISHED == status) {//出仓完成 } else if (BOX_STATUS.OUT_FINISHED == status) {//出仓完成
finishedOutPos(statusBean.getCid(),posName); finishedOutPos(statusBean.getCid(),posName,executeTime);
} else if (BOX_STATUS.OUT_END == status) {//出库完成(放到仓门口 } else if (BOX_STATUS.OUT_END == status) {//出库完成(放到仓门口
//暂不处理 //暂不处理
} }
...@@ -447,18 +448,25 @@ public class BaseDeviceHandler implements IDeviceHandler { ...@@ -447,18 +448,25 @@ public class BaseDeviceHandler implements IDeviceHandler {
return statusBean; return statusBean;
} }
protected void finishedPutIn(String cid, String posName ) throws ValidateException {
finishedPutIn(cid,posName,-1);
}
/** /**
* 入仓位完成处理 * 入仓位完成处理
* @param cid * @param cid
* @param posName * @param posName
* @param executeTime 执行时间
* @throws ValidateException * @throws ValidateException
*/ */
protected void finishedPutIn(String cid, String posName) throws ValidateException { protected void finishedPutIn(String cid, String posName,int executeTime) throws ValidateException {
DataLog task = taskService.findExecutingTask(cid, posName); DataLog task = taskService.findExecutingTask(cid, posName);
if (task != null && task.isPutInTask()) { if (task != null && task.isPutInTask()) {
log.info(task.getBarcode() + "入仓位[" + task.getPosName() + "]完成"); if(executeTime>0){
task.setExecuteTime(executeTime);
updatePosExecuteTime(posName,executeTime);
}
log.info(task.getBarcode() + "入仓位[" + task.getPosName() + "]完成,执行时间["+executeTime+"]秒");
DataLog cancelTask = taskService.findFinishedTask(cid, posName); DataLog cancelTask = taskService.findFinishedTask(cid, posName);
if (cancelTask != null && cancelTask.isCancel()) { if (cancelTask != null && cancelTask.isCancel()) {
//将相同库位已经取消的任务从完成队列里删除 //将相同库位已经取消的任务从完成队列里删除
...@@ -471,7 +479,11 @@ public class BaseDeviceHandler implements IDeviceHandler { ...@@ -471,7 +479,11 @@ public class BaseDeviceHandler implements IDeviceHandler {
task = taskService.findFinishedTask(cid, posName); task = taskService.findFinishedTask(cid, posName);
if (task != null && task.isPutInTask()) { if (task != null && task.isPutInTask()) {
if (task.isCancel()) {//被取消的任务,客户端发完成信号过来,修改取消状态为已完成 if (task.isCancel()) {//被取消的任务,客户端发完成信号过来,修改取消状态为已完成
log.info(task.getBarcode() + "入仓位[" + task.getPosName() + "]完成,但任务已被取消,修改为完成"); if(executeTime>0){
task.setExecuteTime(executeTime);
updatePosExecuteTime(posName,executeTime);
}
log.info(task.getBarcode() + "入仓位[" + task.getPosName() + "]完成,但任务已被取消,修改为完成,执行时间["+executeTime+"]秒");
updatePutInData(task); updatePutInData(task);
} }
} else { } else {
...@@ -480,16 +492,24 @@ public class BaseDeviceHandler implements IDeviceHandler { ...@@ -480,16 +492,24 @@ public class BaseDeviceHandler implements IDeviceHandler {
} }
} }
protected void finishedOutPos(String cid, String posName) throws ValidateException {
finishedOutPos(cid,posName,-1);
}
/** /**
* 出仓位完成处理 * 出仓位完成处理
* @param cid * @param cid
* @param posName * @param posName
* @param executeTime 执行时间
* @throws ValidateException * @throws ValidateException
*/ */
protected void finishedOutPos(String cid, String posName) throws ValidateException { protected void finishedOutPos(String cid, String posName,int executeTime) throws ValidateException {
DataLog task = taskService.findExecutingTask(cid, posName); DataLog task = taskService.findExecutingTask(cid, posName);
if (task != null && task.isCheckOutTask()) { if (task != null && task.isCheckOutTask()) {
log.info(task.getBarcode() + "出仓位[" + task.getPosName() + "]完成"); if(executeTime>0){
task.setExecuteTime(executeTime);
}
log.info(task.getBarcode() + "出仓位[" + task.getPosName() + "]完成,执行时间["+executeTime+"]秒");
DataLog cancelTask = taskService.findFinishedTask(cid, posName); DataLog cancelTask = taskService.findFinishedTask(cid, posName);
if (cancelTask != null && cancelTask.isCancel()) { if (cancelTask != null && cancelTask.isCancel()) {
//将相同库位已经取消的任务从完成队列里删除 //将相同库位已经取消的任务从完成队列里删除
...@@ -503,7 +523,10 @@ public class BaseDeviceHandler implements IDeviceHandler { ...@@ -503,7 +523,10 @@ public class BaseDeviceHandler implements IDeviceHandler {
task = taskService.findFinishedTask(cid, posName); task = taskService.findFinishedTask(cid, posName);
if (task != null && task.isCheckOutTask()) { if (task != null && task.isCheckOutTask()) {
if (task.isCancel()) {//被取消的任务,客户端发完成信号过来,修改取消状态为已完成 if (task.isCancel()) {//被取消的任务,客户端发完成信号过来,修改取消状态为已完成
log.info(task.getBarcode() + "出仓位[" + task.getPosName() + "]完成,但任务已被取消,修改为完成"); if(executeTime>0){
task.setExecuteTime(executeTime);
}
log.info(task.getBarcode() + "出仓位[" + task.getPosName() + "]完成,但任务已被取消,修改为完成,执行时间["+executeTime+"]秒");
updateCheckoutData(task); updateCheckoutData(task);
} }
} else { } else {
...@@ -511,7 +534,29 @@ public class BaseDeviceHandler implements IDeviceHandler { ...@@ -511,7 +534,29 @@ public class BaseDeviceHandler implements IDeviceHandler {
} }
} }
} }
/**
* 入库完成时,更新库位的最小入库时间
* @param posId
* @param exTime
*/
private void updatePosExecuteTime(String posId, double exTime) {
if (posId == null || exTime <= 0) {
return;
}
StoragePos pos = storagePosManager.getByPosName(posId);
if (pos != null) {
if (pos.getPriority() <= 0 || pos.getPriority() > exTime) {
pos.setPriority(exTime);
log.info("更改库位[" + posId + "]的最小入库时间=[" + exTime + "]秒");
try {
storagePosManager.save(pos);
} catch (ValidateException e) {
log.error("更改库位[" + posId + "]的最小入库时间=[" + exTime + "]秒 出错: " + e.toString());
}
}
}
}
/** /**
* 入仓位完成 * 入仓位完成
*/ */
...@@ -587,6 +632,9 @@ public class BaseDeviceHandler implements IDeviceHandler { ...@@ -587,6 +632,9 @@ public class BaseDeviceHandler implements IDeviceHandler {
barcode.setPosName(""); barcode.setPosName("");
barcodeManager.save(barcode); barcodeManager.save(barcode);
task.setBatchInfo(barcode.getBatch()); task.setBatchInfo(barcode.getBatch());
//记录在库时长
task.setInStoreTime(barcode.getInStoreMiniute());
} }
storagePos.setBarcode(null); storagePos.setBarcode(null);
......
package com.neotel.smfcore.core.device.rest; package com.neotel.smfcore.core.device.rest;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.neotel.smfcore.common.exception.ValidateException;
import com.neotel.smfcore.core.barcode.service.po.Barcode;
import com.neotel.smfcore.core.barcode.utils.CodeResolve;
import com.neotel.smfcore.core.storage.service.po.StoragePos;
import com.neotel.smfcore.core.system.service.dao.IAlarmInfoDao;
import com.neotel.smfcore.core.system.service.po.AlarmInfo;
import com.neotel.smfcore.core.system.service.po.DataLog;
import com.neotel.smfcore.core.system.util.TaskService;
import com.neotel.smfcore.security.annotation.AnonymousAccess; import com.neotel.smfcore.security.annotation.AnonymousAccess;
import com.neotel.smfcore.security.annotation.AnonymousPostMapping; import com.neotel.smfcore.security.annotation.AnonymousPostMapping;
import com.neotel.smfcore.core.storage.enums.DeviceType; import com.neotel.smfcore.core.storage.enums.DeviceType;
...@@ -16,6 +27,7 @@ import org.springframework.beans.factory.annotation.Autowired; ...@@ -16,6 +27,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
...@@ -29,6 +41,15 @@ public class DeviceController { ...@@ -29,6 +41,15 @@ public class DeviceController {
@Autowired @Autowired
private DataCache dataCahche; private DataCache dataCahche;
@Autowired
private TaskService taskService;
@Autowired
private IAlarmInfoDao alarmInfoDao;
@Autowired
private CodeResolve codeResolve;
private Map<String, IDeviceHandler> handlerMap = new HashMap<>(); private Map<String, IDeviceHandler> handlerMap = new HashMap<>();
public DeviceController(List<IDeviceHandler> deviceHandlerList){ public DeviceController(List<IDeviceHandler> deviceHandlerList){
...@@ -65,4 +86,214 @@ public class DeviceController { ...@@ -65,4 +86,214 @@ public class DeviceController {
} }
return statusBean; return statusBean;
} }
/**
* 流水线提示消息
*/
private static String lineMsg = "";
/**
* 流水线入库查找空的料格
*/
@ApiOperation("环行线扫码获取库位号")
@PostMapping(value = "/emptyPosForPutin")
@ResponseBody
@AnonymousAccess
public Map<String,Object> emptyPosForPutin(HttpServletRequest request) {
String code = request.getParameter("code");
String cids = request.getParameter("cids");
String rfid = request.getParameter("rfid");
String rfidLoc = request.getParameter("rfidLoc");
String lastPosId=request.getParameter("lastPosId");
lineMsg = "";
// if(Strings.isNullOrEmpty(cids)){
// cids = "line-ac-11,line-ac-12";
// }
log.info("流水线["+cids+"]获取["+rfid+"]["+code+"]的入库库位");
Map<String,Object> resultMap = Maps.newHashMap();
if(dataCahche.getSettings().isStopOut()){
lineMsg = "系统更新中,暂停出入库";
resultMap.put("result","100");
resultMap.put("msg",lineMsg);
return resultMap;
}
String okMsg = "";
String errorMsg = "";
if(Strings.isNullOrEmpty(cids)){
resultMap.put("result","101");
resultMap.put("msg","未指定料仓 cids ");
}else{
List<Storage> storageList = Lists.newArrayList();
for (String cid: cids.split(",")) {
String notIntoCids = dataCahche.getSettings().getNotIntoCids();
if(notIntoCids != null){
if(notIntoCids.contains(cid)){
log.info("料仓["+cid+"]已被屏蔽入库");
continue;
}
}
Storage storage = dataCahche.getStorage(cid);
if(storage != null){
storageList.add(storage);
}
}
if(storageList.isEmpty()){
resultMap.put("result","99");
errorMsg = "无可用的料仓";
resultMap.put("msg",errorMsg);
}else{
try {
Barcode barcode = codeResolve.resolveOneValideBarcode(code);
for (DataLog dataLog : taskService.getAllTasks()) {
// if(!dataLog.isPackageReel()){
//已经在任务当中,返回对应的信息
if (dataLog.getBarcode().equals(barcode.getBarcode())) {
if (dataLog.isPutInTask()) {
//已有入库任务
errorMsg = "物料[" + dataLog.getBarcode() + "]已有入库任务,需继续执行入库动作";
resultMap.put("pos", dataLog.getPosName());
resultMap.put("barcode", barcode.getBarcode());
resultMap.put("cid", dataLog.getCid());
return resultMap;
} else {
//已有出库任务
errorMsg = "物料[" + dataLog.getBarcode() + "]已有出库任务,需继续执行出库动作";
resultMap.put("result", "98");
resultMap.put("msg", errorMsg);
resultMap.put("posId", dataLog.getPosName());
resultMap.put("plateW", barcode.getPlateSize());
resultMap.put("plateH", barcode.getHeight());
resultMap.put("singleOut", dataLog.isSingleOut() + "");
//紧急料
resultMap.put("urgentReel", dataLog.isUrgentReel() + "");
//需要分盘,进入分盘料
resultMap.put("cutReel", dataLog.isCutReel() + "");
resultMap.put("rfid", "");
resultMap.put("realRfid", "");
resultMap.put("rfidLoc", "");
// resultMap.put("rfid", dataLog.getTempRfid());
// resultMap.put("realRfid",dataLog.getAppendInfo().getRfid());
// resultMap.put("rfidLoc", dataLog.getAppendInfo().getRfidLoc() + "");
resultMap.put("barcode", dataLog.getBarcode());
boolean smallReel = barcode.isSmallReel();
resultMap.put("smallReel", smallReel + "");
return resultMap;
}
// }
}
}
StoragePos pos = taskService.findEmptyPosForPutIn(storageList,barcode, rfid,lastPosId);
if(pos != null){
// Storage storage = dataCache.getStorageById(pos.getStorageId());
// if(!storage.isPackage()){
// //不是包装仓,如果所在料仓有出库任务,暂停入库
// Collection<DataLog> tasks = taskService.getQueueTasks();
// for (DataLog task : tasks) {
// if(task.isCheckOutTask() && task.getStorageId().equals(pos.getStorageId())){
// errorMsg = "库位["+ pos.getPosName() + "]所在料仓有出库任务,暂停入库";
// lineMsg = errorMsg;
// resultMap.put("result","99");
// resultMap.put("msg",errorMsg);
// return resultMap;
// }
// }
// }
Storage theStorage = dataCahche.getStorageById(pos.getStorageId());
resultMap.put("result","0");
resultMap.put("msg","");
okMsg = "["+rfid+"]["+barcode.getBarcode()+"]锁定库位["+pos.getPosName()+"]";
// ReelLockPosInfo oldLockInfo = QisdaCache.getLockPosInfoByRfidLoc(rfid, rfidLoc);
// if(oldLockInfo != null){
// if(!oldLockInfo.getBarcode().equals(barcode.getBarcode())){
// String result = "-1";
// okMsg = rfid+"["+ rfidLoc +"]["+barcode.getBarcode()+"]锁定库位["+pos.getPosName()+"],清理旧有锁定信息";
// resultMap.put("result",result);
// resultMap.put("msg",okMsg);
// //已经锁定过库位,但不是同一个条码,需要把对应位置的锁定信息清理掉
// //QisdaCache.removeReelLockPosInfo(barcode.getBarcode());
// List<ReelLockPosInfo> lockPosInfoList = QisdaCache.getShelfLockPosInfo(rfid);
// for (ReelLockPosInfo reelLockPosInfo : lockPosInfoList) {
// QisdaCache.removeReelLockPosInfo(reelLockPosInfo.getBarcode());
// log.info("清理料架"+reelLockPosInfo.getRfid()+"["+reelLockPosInfo.getRfidLoc()+"]上物料["+reelLockPosInfo.getBarcode()+"]锁定的库位");
// }
// }
// }
//log.info(okMsg + oldLockInfo);
// ReelLockPosInfo reelLocInfo = new ReelLockPosInfo();
// reelLocInfo.setBarcode(barcode.getBarcode());
// reelLocInfo.setCid(theStorage.getCid());
// reelLocInfo.setLockPosName(pos.getPosName());
// reelLocInfo.setLockPosId(pos.getId());
// reelLocInfo.setRfid(rfid);
// reelLocInfo.setRfidLoc(rfidLoc);
// reelLocInfo = QisdaCache.addReelLockPosInfo(reelLocInfo);
// if(reelLocInfo == null){
// errorMsg = "库位已被锁定,暂停入库";
// lineMsg = errorMsg;
// resultMap.put("result","99");
// resultMap.put("msg",errorMsg);
// return resultMap;
// }else{
resultMap.put("pos",pos.getPosName());
resultMap.put("barcode",barcode.getBarcode());
resultMap.put("cid",theStorage.getCid());
// }
}else{
resultMap.put("result","104");
errorMsg = "["+barcode.getBarcode()+"]未找到可用的["+barcode.getPlateSize() + "x" + barcode.getHeight()+"]仓位";
resultMap.put("msg",errorMsg);
}
} catch (ValidateException ve) {
errorMsg = ve.getMessage();
log.info("查找空库位失败:" + errorMsg);
resultMap.put("result","105");
resultMap.put("msg",errorMsg);
} catch (Exception e) {
errorMsg = e.getMessage();
log.info("查找空库位失败,",e);
resultMap.put("result","105");
resultMap.put("msg",errorMsg);
}
}
}
//没入成功
if(!errorMsg.isEmpty()){
//有错误,记录日志
AlarmInfo alarmInfo = new AlarmInfo();
alarmInfo.setBoxId("0");
alarmInfo.setStorageName("流水线");
alarmInfo.setInOutStatus("1");
alarmInfo.setAlarmType("入库");
Date date = new Date();
alarmInfo.setStartTime(date);
alarmInfo.setEndTime(date);
String msg = "["+code+"]"+errorMsg;
alarmInfo.setAlarmMsg(msg);
alarmInfoDao.save(alarmInfo);
lineMsg = errorMsg;
}else{
lineMsg = okMsg;
}
return resultMap;
}
} }
...@@ -34,9 +34,15 @@ public interface IStoragePosManager extends IBaseManager<StoragePos> { ...@@ -34,9 +34,15 @@ public interface IStoragePosManager extends IBaseManager<StoragePos> {
StoragePos getEmptyPosByStorage(Storage storage, Barcode barcode, Collection<String> excludePosIds) throws ValidateException ; StoragePos getEmptyPosByStorage(Storage storage, Barcode barcode, Collection<String> excludePosIds) throws ValidateException ;
StoragePos getEmptyPosByStorage(Storage storage, Barcode barcode, Collection<String> excludePosIds, String lastPosId) throws ValidateException;
List<StoragePos> findNotEmpty(); List<StoragePos> findNotEmpty();
List<StoragePos> findByStorage(String storageId); List<StoragePos> findByStorage(String storageId);
void insertAll(List<StoragePos> posList); void insertAll(List<StoragePos> posList);
StoragePos getByFixtureCode(String fixtureBarcode);
StoragePos getByBarcodeId(String barcodeId);
} }
...@@ -4,6 +4,7 @@ import com.google.common.base.Strings; ...@@ -4,6 +4,7 @@ import com.google.common.base.Strings;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import com.neotel.smfcore.common.bean.PageData; import com.neotel.smfcore.common.bean.PageData;
import com.neotel.smfcore.common.exception.ValidateException; import com.neotel.smfcore.common.exception.ValidateException;
import com.neotel.smfcore.common.utils.PointUtil;
import com.neotel.smfcore.common.utils.StringUtils; import com.neotel.smfcore.common.utils.StringUtils;
import com.neotel.smfcore.core.barcode.bean.PlateSizeBean; import com.neotel.smfcore.core.barcode.bean.PlateSizeBean;
import com.neotel.smfcore.core.barcode.service.po.Barcode; import com.neotel.smfcore.core.barcode.service.po.Barcode;
...@@ -18,6 +19,7 @@ import lombok.extern.slf4j.Slf4j; ...@@ -18,6 +19,7 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort; import org.springframework.data.domain.Sort;
import org.springframework.data.geo.Point;
import org.springframework.data.mongodb.core.aggregation.Aggregation; import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.AggregationResults; import org.springframework.data.mongodb.core.aggregation.AggregationResults;
import org.springframework.data.mongodb.core.query.Criteria; import org.springframework.data.mongodb.core.query.Criteria;
...@@ -314,6 +316,41 @@ public class StoragePosManagerImpl implements IStoragePosManager { ...@@ -314,6 +316,41 @@ public class StoragePosManagerImpl implements IStoragePosManager {
StoragePos pos = storagePosDao.findOne(query); StoragePos pos = storagePosDao.findOne(query);
return pos; return pos;
} }
@Override
public StoragePos getEmptyPosByStorage(Storage storage, Barcode barcode, Collection<String> excludePosIds,String lastPosId) 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);
}
Query query = new Query(c);
if(lastPosId==null||lastPosId.equals("")){
//优先放入最合适的位置(根据尺寸),相同尺寸按优先级排序
query.with(Sort.by(Sort.Direction.ASC, "w").and(Sort.by(Sort.Direction.ASC, "h")).and(Sort.by(Sort.Direction.DESC, "priority")));
}else{
Point point= PointUtil.getPosPoint(lastPosId,false);
query.addCriteria(Criteria.where("coordinate").nearSphere(point));
}
StoragePos pos = storagePosDao.findOne(query);
return pos;
}
@Override @Override
public List<StoragePos> findNotEmpty(){ public List<StoragePos> findNotEmpty(){
return findNotEmptyByStorageId(null); return findNotEmptyByStorageId(null);
...@@ -328,4 +365,14 @@ public class StoragePosManagerImpl implements IStoragePosManager { ...@@ -328,4 +365,14 @@ public class StoragePosManagerImpl implements IStoragePosManager {
storagePosDao.insertAll(posList); storagePosDao.insertAll(posList);
} }
@Override
public StoragePos getByFixtureCode(String fixtureCode) {
return storagePosDao.findOneByCondition(new String[]{"barcode.fixtureCode"}, new String[]{fixtureCode});
}
@Override
public StoragePos getByBarcodeId(String barcodeId) {
return storagePosDao.findOneByCondition(new String[]{"barcode.id"}, new String[]{barcodeId});
}
} }
package com.neotel.smfcore.core.system.service.po; package com.neotel.smfcore.core.system.service.po;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.google.common.base.Strings; import com.google.common.base.Strings;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.neotel.smfcore.common.base.BasePo; import com.neotel.smfcore.common.base.BasePo;
...@@ -72,6 +73,36 @@ public class DataLog extends BasePo implements Serializable { ...@@ -72,6 +73,36 @@ public class DataLog extends BasePo implements Serializable {
//二维码(Reel ID) //二维码(Reel ID)
private String barcode = ""; private String barcode = "";
/**
* 料盘宽度信息
*/
private int w;
/**
* 料盘高度信息
*/
private int h;
/**
* 是否是分盘料卷(Barcode中有CutMap)
*/
private boolean cutReel;
/**
* 紧急物料,指定物料,单独出库物料
*/
private boolean urgentReel = false;
/**
* 缺料补发(使用料串)
*/
private boolean lessSendReel = false;
/**
* 是否是包装料卷
*/
private boolean packageReel;
/** /**
* 物料编号 * 物料编号
......
...@@ -164,4 +164,21 @@ public class Settings extends BasePo implements Serializable { ...@@ -164,4 +164,21 @@ public class Settings extends BasePo implements Serializable {
*/ */
private String orderFileDir; private String orderFileDir;
/**
* 准备进行更新,不允许需求单出库
*/
private boolean stopOut = false;
/**
* 停止定时器任务
*/
private boolean stopJob = false;
/**
* 不入库的料仓列表
*/
private String notIntoCids = "";
private boolean checkLineShelf = false;
} }
...@@ -6,13 +6,17 @@ import com.google.common.collect.Maps; ...@@ -6,13 +6,17 @@ import com.google.common.collect.Maps;
import com.neotel.smfcore.common.exception.ValidateException; import com.neotel.smfcore.common.exception.ValidateException;
import com.neotel.smfcore.common.utils.SecurityUtils; import com.neotel.smfcore.common.utils.SecurityUtils;
import com.neotel.smfcore.common.utils.StorageConstants; import com.neotel.smfcore.common.utils.StorageConstants;
import com.neotel.smfcore.core.barcode.enums.COMPONENT_TYPE;
import com.neotel.smfcore.core.barcode.service.manager.IBarcodeManager; import com.neotel.smfcore.core.barcode.service.manager.IBarcodeManager;
import com.neotel.smfcore.core.barcode.service.po.Barcode; import com.neotel.smfcore.core.barcode.service.po.Barcode;
import com.neotel.smfcore.core.device.bean.StatusBean; import com.neotel.smfcore.core.device.bean.StatusBean;
import com.neotel.smfcore.core.device.enums.OP; import com.neotel.smfcore.core.device.enums.OP;
import com.neotel.smfcore.core.device.enums.OP_STATUS; import com.neotel.smfcore.core.device.enums.OP_STATUS;
import com.neotel.smfcore.core.device.util.DataCache; import com.neotel.smfcore.core.device.util.DataCache;
import com.neotel.smfcore.core.storage.enums.DeviceType;
import com.neotel.smfcore.core.storage.service.manager.IStorageManager;
import com.neotel.smfcore.core.storage.service.manager.IStoragePosManager; import com.neotel.smfcore.core.storage.service.manager.IStoragePosManager;
import com.neotel.smfcore.core.storage.service.manager.impl.StorageManagerImpl;
import com.neotel.smfcore.core.storage.service.manager.impl.StoragePosManagerImpl; import com.neotel.smfcore.core.storage.service.manager.impl.StoragePosManagerImpl;
import com.neotel.smfcore.core.storage.service.po.Storage; import com.neotel.smfcore.core.storage.service.po.Storage;
import com.neotel.smfcore.core.storage.service.po.StoragePos; import com.neotel.smfcore.core.storage.service.po.StoragePos;
...@@ -41,6 +45,7 @@ public class TaskService { ...@@ -41,6 +45,7 @@ public class TaskService {
@Autowired @Autowired
protected IStoragePosManager storagePosManager; protected IStoragePosManager storagePosManager;
@Autowired @Autowired
private List<ITaskListener> taskListenerList = new ArrayList<>(); private List<ITaskListener> taskListenerList = new ArrayList<>();
...@@ -511,4 +516,180 @@ public class TaskService { ...@@ -511,4 +516,180 @@ public class TaskService {
return task; return task;
} }
/**
* 查找可以入库的空位
* @param storageList
* @param barcode
* @return
*/
public StoragePos findEmptyPosForPutIn(List<Storage> storageList, Barcode barcode, String inRFID,String lastPosId) throws ValidateException{
verifyBarcodePutIn(storageList ,barcode, inRFID);
//查找任务数最少的料仓
final Map<String,Integer> storageTaskCountMap = new HashMap<>();
for (Storage storage : storageList) {
storageTaskCountMap.put(storage.getId(), 0);
}
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 = QisdaCache.getReelLockPosId(barcode.getBarcode());
// StoragePos pos = null;
// if(!Strings.isNullOrEmpty(lockPosId)){
// //已有锁定库位
// pos = storagePosManager.get(lockPosId);
//
// if(pos != null ){
// 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","料仓列表中未找到可用的料仓");
}
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 findEmptyPosInStorages(barcode, availbleStorageList, storageTaskCountMap,lastPosId);
return null;
}
private synchronized StoragePos findEmptyPosInStorages(Barcode barcode, List<Storage> availbleStorageList, final Map<String,Integer> executingTaskCountMap,String lastPosId){
for (Storage storage : availbleStorageList) {
try{
Collection<String> operatingPosIds = excludePosIds();
log.debug("尝试从["+storage.getCid()+"]中为["+barcode.getBarcode()+"]查找空位");
StoragePos pos = storagePosManager.getEmptyPosByStorage(storage, barcode , operatingPosIds,lastPosId);
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;
}
/**
* 检查二维码是否合法并且可以入库,没问题的话存入到数据库
*/
private Barcode verifyBarcodePutIn(List<Storage> storageList, Barcode barcodeSave, String inRFID) throws ValidateException {
if(barcodeSave == null){
throw new ValidateException("smfcode.error.barcode.invalid","条码无效");
}
StoragePos pos;
//夹具,查询 relationCode
if(COMPONENT_TYPE.FIXTURE == barcodeSave.getType()){
pos = storagePosManager.getByFixtureCode(barcodeSave.getBarcode());
}else {
pos = storagePosManager.getByBarcodeId(barcodeSave.getId());
if (barcodeSave.getAmount() <= 0) {
throw new ValidateException("smfcode.error.barcode.wrongQty","条码[{0}]对应的数量<=0为: {1}" ,new String[]{ barcodeSave.getBarcode() , barcodeSave.getAmount()+""});
}
}
if (pos != null) {
//如果已在库位中,那么自动将该库位的物料出库
log.info("出库已在库位中的物料["+barcodeSave.getBarcode()+"]");
Storage storage = dataCache.getStorageById(pos.getStorageId());
checkout(storage, pos, true);
throw new ValidateException("smfcode.error.barcode.exist", "[{0}}]已在{1}}[{2}}]中",new String[]{ barcodeSave.getBarcode(),storage.getName(),pos.getPosName()});
}
Collection<DataLog> queueTasks = getQueueTasks();
List<DataLog> allTasks = getFinishedTasks();
if(!queueTasks.isEmpty()){
allTasks.addAll(queueTasks);
}
for (DataLog task : allTasks) {
if(task.isPutInTask()){
if(task.getBarcode().equals(barcodeSave.getBarcode())){
//同一个条码的入库任务
for (Storage storage : storageList) {
if(task.getStorageId().equals(storage.getId()) && task.isPutInTask()){
return barcodeSave;
}
}
throw new ValidateException("smfcode.error.barcode.taskNotEnd", "料盘[{0}}]的操作未完成,无法执行入库操作",new String[]{ barcodeSave.getBarcode()});
}
}
}
barcodeSave = barcodeManager.save(barcodeSave);
return barcodeSave;
}
} }
支持 Markdown 格式
你添加了 0 到此讨论。请谨慎行事。
Finish editing this message first!