Commit bd32adc0 LN

料架分配

1 个父辈 69bd99ca
......@@ -18,14 +18,22 @@ import java.util.Locale;
@Slf4j
@Data
public class ResultBean<T> {
public static ResultBean newErrorResult(int code, String msgKey, String msg ,Object data) {
ResultBean resultBean= newErrorResult(code, msgKey, msg, new String[]{},true);
resultBean.setData(data);
return resultBean;
}
public static ResultBean newErrorResult(int code, String msgKey, String msg,String[] params,Object data) {
ResultBean resultBean= newErrorResult(code, msgKey, msg, params,true);
resultBean.setData(data);
return resultBean;
}
public static ResultBean newErrorResult(int code, String msgKey, String msg ) {
return newErrorResult(code, msgKey, msg, new String[]{},true);
}
public static ResultBean newErrorResult(int code, String msgKey, String msg,String[] params) {
return newErrorResult(code, msgKey, msg, params,true);
}
public static ResultBean newErrorResult(int code, String msgKey, String msg,String[] params, boolean writeLog) {
ResultBean result = new ResultBean();
result.setCode(code);
......
......@@ -10,6 +10,7 @@ import com.neotel.smfcore.core.message.enums.MessageType;
import com.neotel.smfcore.core.message.service.manager.IMessageManager;
import com.neotel.smfcore.core.message.service.po.Message;
import com.neotel.smfcore.core.order.util.OrderFileWatch;
import com.neotel.smfcore.core.shelf.TaskShelfUtil;
import com.neotel.smfcore.security.service.manager.IMenuManager;
import com.neotel.smfcore.security.service.manager.IRoleManager;
import com.neotel.smfcore.security.service.manager.IUserManager;
......@@ -112,6 +113,10 @@ public class DataInitManager {
dataCache.getAllInventory(null,"");
TaskShelfUtil.dataCache=dataCache;
TaskShelfUtil.initShelfMap();
} catch (Exception exception) {
log.error("初始化环境出错..." + exception.toString(),exception);
}
......
......@@ -770,9 +770,9 @@ public class DataCache {
List<String> availableStorageIds = new ArrayList<>();
for (Storage storage : getAllStorage().values()) {
StatusBean bean = DevicesStatusUtil.getStatusBean(storage.getCid());
if (bean == null || bean.timeOut() || !bean.isAvailable()) {
continue;
}
// if (bean == null || bean.timeOut() || !bean.isAvailable()) {
// continue;
// }
availableStorageIds.add(storage.getId());
}
return availableStorageIds;
......
......@@ -21,6 +21,7 @@ import com.neotel.smfcore.core.order.service.manager.ILiteOrderItemManager;
import com.neotel.smfcore.core.order.service.manager.ILiteOrderManager;
import com.neotel.smfcore.core.order.service.po.LiteOrder;
import com.neotel.smfcore.core.order.service.po.LiteOrderItem;
import com.neotel.smfcore.core.shelf.TaskShelfUtil;
import com.neotel.smfcore.core.storage.enums.CHECKOUT_TYPE;
import com.neotel.smfcore.core.storage.service.manager.IStoragePosManager;
import com.neotel.smfcore.core.storage.service.po.Storage;
......@@ -259,7 +260,10 @@ public class LiteOrderCache {
order.setTotalTaskReelCount(order.getTotalTaskReelCount()-1);
log.info("工单[" + orderNo + "]的任务" + task.getPartNumber() + "[" + task.getBarcode() + "]已取消,任务数-1=" + order.getFinishedReelCount() + "/" + order.getTaskReelCount());
checkoutAgain(task,order);
//取消任务料架位置锁定
TaskShelfUtil.cancelReelTask(task);
// checkoutAgain(task,order);
}
else if (task.isFinished() || task.isEnd()) {
order.setFinishedReelCount(order.getFinishedReelCount() + 1);
......@@ -360,6 +364,7 @@ public class LiteOrderCache {
}
CHECKOUT_TYPE checkoutType = dataCache.getCheckOutType();
Collection<String> excludePosIds = excludeOutPosIds();
excludePosIds.add(task.getPosId());
StoragePos pos = storagePosManager.findPartNumberInStorages(availableStorageIds, item.getPn(), excludePosIds, checkoutType);
if (pos == null) {
log.error("工单[" + orderNo + "],PN[" + item.getPn() + "]出库任务被取消,补发失败:未找到可以出库的物料 ");
......@@ -376,9 +381,14 @@ public class LiteOrderCache {
newTasktask.setLightColor(task.getLightColor());
newTasktask.setStatus(OP_STATUS.WAIT.name());
newTasktask.setSingleOut(task.isSingleOut());
taskService.addTaskToExecute(task);
taskService.addTaskToExecute(newTasktask);
//增加一个料架位置
TaskShelfUtil.addLoc(newTasktask);
order.setTaskReelCount(order.getTaskReelCount() + 1);
order.setTotalTaskReelCount(order.getTotalTaskReelCount() + 1);
break;
}
}
}
......@@ -525,6 +535,9 @@ public class LiteOrderCache {
task.setSingleOut(singleOut);
// task = dataLogDao.save(task);
taskService.addTaskToExecute(task);
//增加一个料架位置
TaskShelfUtil.addLoc(task);
}
//如果是RI出库,只有一盘,出完就结束
if(!Strings.isNullOrEmpty(reelId)){
......
......@@ -32,13 +32,13 @@ public enum ORDER_COLOR {
BLUE("0000FF"),
//MAGENTA("FF00FF"),
CYAN("00FFFF"),
FIREBRICK("B22222"),
PURPLE("A020F0"),
SKYBLUE("6CA6CD"),
PINK("FF1493"),
FORESTGREEN("228B22"),
LIGHTBLUE("8470FF"),
INDIANRED("8B3A3A"),
// FIREBRICK("B22222"),
// PURPLE("A020F0"),
// SKYBLUE("6CA6CD"),
// PINK("FF1493"),
// FORESTGREEN("228B22"),
// LIGHTBLUE("8470FF"),
// INDIANRED("8B3A3A"),
DARKGREEN("556B2F"),
;
......
package com.neotel.smfcore.core.shelf.bean;
import cn.hutool.core.util.ObjectUtil;
import com.neotel.smfcore.core.shelf.enums.SHELF_TYPE;
import com.neotel.smfcore.core.system.service.po.DataLog;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Slf4j
public class ShelfInfo {
public ShelfInfo(String type,int maxNum){
shelfType=type ;
maxLocCount=maxNum;
}
/**
* F料架位置数量,1-26是小料,27=31是大料
*/
private static int F_POS_COUNT=31;
private static int MAX_F_SMALL_NUM=26;//F料架小料位置最大编号
/**
* 工单号
*/
private String orderNo;
/**
* 料架出库顺序编号
*/
private int rfidIndex;
/**
* 来源需求单号,用于分盘料,紧急料和工单的料区分
*/
private String sourceWo;
/**
* 实际编号
*/
private String realRfid;
/**
* 料架类型
*/
private String shelfType;
/**
* 料架的架位数
*/
private int maxLocCount = 0;
public static ShelfInfo newFShelf(){
return new ShelfInfo(SHELF_TYPE.F,31);
}
/**
* 架位放置情况, key小于0表示已经放过,key>0为空的库位
*/
private Map<Integer, ShelfLoc> locMap = new ConcurrentHashMap<>();
public String tempRfid(){
return getOrderNo() + "-" + rfidIndex + shelfType;
}
public boolean cancelLimitLoc(String barcode) {
for (ShelfLoc shelfLoc : locMap.values()) {
if (shelfLoc.isInThisLoc(barcode)) {
if (shelfLoc.isEmpty()) {
shelfLoc.putIn(barcode);
locMap.put(shelfLoc.getLoc(), shelfLoc);
return true;
} else {
log.error("料盘[" + barcode + "]解除绑定架位" + tempRfid() + "[" + shelfLoc.getLoc() + "]失败,此位置料盘已放入");
return false;
}
}
}
return false;
}
/**
* 根据条码获取库位信息
*/
public int getBarcodeLoc(String barcode) {
for (ShelfLoc shelfLoc : locMap.values()) {
if (shelfLoc.isLock() && shelfLoc.getBarcode().equals(barcode)) {
return shelfLoc.getLoc();
}
}
return -1;
}
/**
* 为不需要按顺序摆放的料盘锁定一个架位,如果已经锁定过,返回对应的架位
*/
public ShelfLoc lockOneEmptyLoc(DataLog task){
//先看看此条码是否已经锁定过
for (ShelfLoc shelfLoc : locMap.values()) {
if(shelfLoc.isLock() && shelfLoc.getBarcode().equals(task.getBarcode())){
log.info("找到条码["+task.getBarcode()+"]锁定的架位["+shelfLoc.getLoc()+"]");
return shelfLoc;
}
}
for(int i=1; i<= maxLocCount; i++){
ShelfLoc shelfLoc = lockLocation(i,task);
if(shelfLoc != null){
return shelfLoc;
}
}
return null;
}
/**
* 锁定库位,如果成功返回库位,如果失败返回null
*/
private ShelfLoc lockLocation(int loc, DataLog task){
ShelfLoc shelfLoc = locMap.get(loc);
if(shelfLoc != null && shelfLoc.isEmpty() && !shelfLoc.isLock() && getReelType(task) == shelfLoc.getReelType()){
log.info("为[" + task.getBarcode() + "]锁定架位"+tempRfid() + "["+loc+"]");
//未放过料,且未锁定
shelfLoc.setBarcode(task.getBarcode());
shelfLoc.setReelType(getReelType(task));
locMap.put(loc, shelfLoc);
return shelfLoc;
}
return null;
}
/**
* 添加一个库位
*/
public int addUnLimitLoc(DataLog task){
for(int i=1; i<= maxLocCount; i++){
ShelfLoc shelfLoc = locMap.get(i);
if(shelfLoc == null){
boolean addThis = false;
if(isSmallReel(task)){
if(i<= MAX_F_SMALL_NUM){
addThis = true;
}
}else{
if(i> MAX_F_SMALL_NUM){
addThis = true;
}
}
if(addThis){
shelfLoc = new ShelfLoc();
shelfLoc.setLoc(i);
shelfLoc.setBarcode("");
shelfLoc.setReelType(getReelType(task));
shelfLoc.setTempRfid(tempRfid());
if(ObjectUtil.isNotEmpty(realRfid)){
shelfLoc.setRealRfid(realRfid);
}
locMap.put(i, shelfLoc);
return i;
}
}
}
return -1;
}
/**
* 将料盘放入库位
* @param loc
* @param barcode
*/
public boolean putInLoc(String rfid, int loc, String barcode){
if(ObjectUtil.isNotEmpty(realRfid)){
//已绑定过真实料架,必须一致才能放入
if(!this.realRfid.equals(rfid)){
return false;
}
}
if(!rfid.contains(shelfType)){
//未绑定过料架的,需要判断类型是否一致
return false;
}
int lockLocation = -1;
for (ShelfLoc shelfLoc : locMap.values()) {
if(shelfLoc.isLock() && shelfLoc.getBarcode().equals(barcode)){
log.info("找到条码["+barcode+"]锁定的架位["+shelfLoc.getLoc()+"]");
lockLocation = shelfLoc.getLoc();
}
}
if(lockLocation == -1){
log.error("["+tempRfid()+"]未找到["+barcode+"]锁定的位置信息");
return false;
}
if(lockLocation != loc){
log.error(barcode + "放置位置["+loc+"]与锁定位置["+lockLocation+"]不一致");
return false;
}
this.setRealRfid(rfid);
ShelfLoc shelfLoc = locMap.get(loc);
if(shelfLoc == null){
log.error("未找到["+loc+"]的位置信息,当前料架位置信息:"+ locMap);
return false;
}
if(shelfLoc.isEmpty()){
boolean putInResult = shelfLoc.putIn(barcode);
locMap.put(loc, shelfLoc);
return putInResult;
}else{
log.error("料盘["+barcode+"]放入位置"+rfid+"["+loc+"]失败,此位置料盘已放入");
return false;
}
}
public boolean isFull(){
for (ShelfLoc loc : locMap.values()) {
if(loc.isEmpty()){
return false;
}
}
return true;
}
/**
* 为 取消一个库位
*/
public boolean cancelLoc(String rfidType, DataLog task){
if(rfidType.equals(this.getShelfType())){
for(int i=maxLocCount; i> 0; i--){
ShelfLoc shelfLoc = locMap.get(i);
if(shelfLoc != null && shelfLoc.isEmpty() && !shelfLoc.isLock() && shelfLoc.getReelType() == getReelType(task)){
//未放过料,且未锁定
shelfLoc.putIn(task.getBarcode());
return true;
}
}
}
return false;
}
public int getReelType(DataLog task){
return 0;
}
public boolean isSmallReel(DataLog task){
return true;
}
}
package com.neotel.smfcore.core.shelf.bean;
import com.neotel.smfcore.core.shelf.enums.REEL_TYPE;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Slf4j
public class ShelfLoc {
public ShelfLoc(String realRfid, int loc) {
this.loc = loc;
this.realRfid = realRfid;
}
/**
* 料架RFID编号
*/
private String realRfid;
/**
* 虚拟料架号
*/
private String tempRfid;
/**
* 架位号1-31
*/
private int loc;
/**
* 物料编码
*/
private String barcode;
/**
* 物料类型:1=小料,2=大料
*/
private int reelType;
/**
* 是否为空,放料后=false
*/
private boolean empty = true;
/**
* 是否已锁定
*/
private boolean isLock = false;
/**
* 判断该架位锁定的条码是否与给定的条码一样
*
* @param barcode
* @return
*/
public boolean isInThisLoc(String barcode) {
if (this.isLock()) {
return this.getBarcode().equals(barcode);
}
return false;
}
public boolean putIn(String barcode) {
boolean canPut = false;
//库位未锁定或条码与锁定barcode一样,可放入
if (!isLock()) {
canPut = true;
} else if (this.getBarcode().equals(barcode)) {
canPut = true;
}
if (canPut) {
this.setBarcode(barcode);
setEmpty(false);
}
return canPut;
}
public boolean isSmallLoc() {
return reelType == REEL_TYPE.SMALL;
}
public boolean isBigLoc() {
return reelType == REEL_TYPE.BIG;
}
}
package com.neotel.smfcore.core.shelf.enums;
public class REEL_TYPE {
public static int SMALL=1;
public static int BIG=2;
}
package com.neotel.smfcore.core.shelf.enums;
public class SHELF_TYPE {
public static String F="F";
}
......@@ -15,7 +15,9 @@ import org.springframework.data.mongodb.core.mapping.Document;
import java.io.Serializable;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Data
@Document
......@@ -257,6 +259,50 @@ public class DataLog extends BasePo implements Serializable ,Comparable<DataLog>
return posId;
}
/**
* 自定义的附加信息
*/
private Map<String,Object> appendData = new HashMap<>();
/**
* 添加或更新自定义附加信息
* @param appendKey
* @param appendValue
*/
public void updateAppendData(String appendKey, Object appendValue){
appendData.put(appendKey, appendValue);
}
/**
* 获取自定义附加信息 工单料架信息: tempRfid, rfidLoc
* @param appendKey
* @param <T>
* @return
*/
public <T> T getAppendData(String appendKey){
Object value = appendData.get(appendKey);
if(value != null){
return (T)value;
}
return null;
}
public void setTempRfid(String tempRfid) {
updateAppendData("tempRfid", tempRfid);
}
public void setRfidLoc(int rfidLoc) {
updateAppendData("rfidLoc", rfidLoc);
}
public String getTempRfid(){
return getAppendData("tempRfid");
}
public Integer getRfidLoc(){
return getAppendData("rfidLoc");
}
/**
* 是否被取消
*/
public boolean isCancel(){
......
支持 Markdown 格式
你添加了 0 到此讨论。请谨慎行事。
Finish editing this message first!