Commit c80451cc sunke

成本中心领料-大于等于需求量最小的料盘数量

线边仓间转储出库,转外协出库,发运单出库-整盘优先原则,不足发散盘
已使用库位加入缓存
产线补料出库BUG修正
1 个父辈 ad6cd77e
...@@ -45,7 +45,7 @@ public class DataInitManager { ...@@ -45,7 +45,7 @@ public class DataInitManager {
MainTimer mainTimer; MainTimer mainTimer;
//@Value("${menu.show}") //@Value("${menu.show}")
private String[] menuShowList = new String[]{"productionLineReple","productionLineOut"}; private String[] menuShowList = new String[]{"productionLineReple","productionLineOut","interfaceException"};
//@Value("${menu.hide}") //@Value("${menu.hide}")
private String[] menuHideList = new String[]{}; private String[] menuHideList = new String[]{};
......
...@@ -29,6 +29,7 @@ import com.neotel.smfcore.security.TokenProvider; ...@@ -29,6 +29,7 @@ import com.neotel.smfcore.security.TokenProvider;
import com.neotel.smfcore.security.annotation.AnonymousAccess; import com.neotel.smfcore.security.annotation.AnonymousAccess;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.query.Criteria; import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query; import org.springframework.data.mongodb.core.query.Query;
...@@ -52,71 +53,6 @@ public class NLPShelfHandler extends BaseDeviceHandler{ ...@@ -52,71 +53,6 @@ public class NLPShelfHandler extends BaseDeviceHandler{
super(apiList); super(apiList);
} }
// /**
// * 扫码
// */
// @ApiOperation("扫码入库")
// @PostMapping("/api/sensorShelf/codeIn")
// @PreAuthorize("@el.check('sensorShelf:putIn')")
// public ResultBean codeIn( @RequestBody Map<String, String> mapValues,HttpServletRequest request) {
// String code = mapValues.get("code");
// String groupId = mapValues.get("group");
// String storageId=mapValues.get("storageId");
// String sourceId=mapValues.get("sourceId");
// String token = tokenProvider.getToken(request);
// if(ObjectUtils.isEmpty(code)){
// throw new ValidateException("smfcore.valueCanotNull", "{0}不能为空", new String[]{"code"});
// }
// if(groupId==null&&storageId==null){
// throw new ValidateException("smfcore.valueCanotNull", "{0}不能为空", new String[]{"group"});
// }
// if(groupId==null&&storageId!=null){
// Storage storage=dataCache.getStorageById(storageId);
// if(storage!=null){
// groupId=storage.getGroupId();
// }
// }
// if(groupId!=null&&groupId.equals("-1")){
// groupId="";
// }
// // WebSocketServer.sendMsg("", new SocketMsg("{0}未找到库位:{1}"+code, MsgType.INFO,"smfclient.nlp.cannotFindPos",new String[]{"消息测试","库位号"}));
// String loginUser = SecurityUtils.getLoginUsername();
// Collection<DataLog> queueTasks = taskService.getQueueTasks();
// ResultBean resultBean = null;
// for (DataLog queueTask : queueTasks) {
// if (queueTask.isPutInTask() && queueTask.isWait()) {
// if (!Strings.isNullOrEmpty(groupId) && queueTask.getGroupId().equals(groupId)) {
// log.info("codeIn [" + code + "][" + groupId + "]入库失败:条码[" + queueTask.getBarcode() + "]的任务还未结束 ");
// throw new ValidateException("smfcore.unfinished", "the task of [{0}] is unfinished", new String[]{queueTask.getBarcode()});
// }
// if (!Strings.isNullOrEmpty(storageId) && queueTask.getStorageId().equals(storageId)) {
// log.info("codeIn [" + code + "][" + storageId + "]入库失败:条码[" + queueTask.getBarcode() + "]的任务还未结束 ");
// throw new ValidateException("smfcore.unfinished", "the task of [{0}] is unfinished", new String[]{queueTask.getBarcode()});
// }
// }
// }
//
// Barcode barcodeSave = resolveBarcodeFromApiForShelf(new CodeValidateParam( loginUser,groupId,storageId,code,token));
// if(barcodeSave == null){
// barcodeSave = codeResolve.resolveOneValideBarcode("=1x1="+code);
// }
//
// Date expireDate = barcodeSave.getExpireDate();
// if (expireDate != null) {
// if (System.currentTimeMillis() > expireDate.getTime()) {
// throw new ValidateException("smfcore.error.barcode.expired", "物料已过期,无法入库.");
// }
// }
//
// //从API验证
// Barcode verResult = verifyPutInFromApi(barcodeSave);
//
// if(verResult==null){
// return testPutIn(loginUser,groupId,storageId, barcodeSave,token);
// }
//// resultBean = hellaServiceHandler.checkMaterial(loginUser, groupId, code);
// return ResultBean.newOkResult("");
// }
private ResultBean testPutIn(String loginUser, String groupId,String storageId,Barcode barcode,String token) { private ResultBean testPutIn(String loginUser, String groupId,String storageId,Barcode barcode,String token) {
...@@ -226,13 +162,14 @@ public class NLPShelfHandler extends BaseDeviceHandler{ ...@@ -226,13 +162,14 @@ public class NLPShelfHandler extends BaseDeviceHandler{
} }
} }
if (color != null) { if (color != null) {
queueTask.setStatus(OP_STATUS.EXECUTING.name()); queueTask.setStatus(OP_STATUS.EXECUTING.name());
taskService.updateQueueTask(queueTask); taskService.updateQueueTask(queueTask);
if(Strings.isNotBlank(queueTask.getPosName())){
statusBean.addData("open", queueTask.getPosName() + "=" + color.name()); statusBean.addData("open", queueTask.getPosName() + "=" + color.name());
log.info("库位[" + queueTask.getPosName() + "]["+queueTask.getBarcode()+"]+亮灯:" + color.name()); log.info("库位[" + queueTask.getPosName() + "]["+queueTask.getBarcode()+"]+亮灯:" + color.name());
} }
} }
}
// else if(queueTask.isCancel()){ // else if(queueTask.isCancel()){
// if(queueTask.isCheckOutTask()){ // if(queueTask.isCheckOutTask()){
// //
...@@ -277,21 +214,9 @@ public class NLPShelfHandler extends BaseDeviceHandler{ ...@@ -277,21 +214,9 @@ public class NLPShelfHandler extends BaseDeviceHandler{
noReelPosErrorList = new String[]{}; noReelPosErrorList = new String[]{};
} }
List<String> ngToOk=new ArrayList<>(); List<String> ngToOk=new ArrayList<>();
// //数据库无信息,实际有料
// if(hasReelPosErrorList.length>0){
// Query query=new Query(Criteria.where("posName").in(hasReelPosErrorList));
// List<StoragePos> posList= storagePosManager.findByQuery(query);
// for (StoragePos pos:posList
// ) {
// if(pos.isUsed()){
// ngToOk.add(pos.getPosName());
// log.info("sensorChange 客户端上传 hasReelPosErrorList 库位["+pos.getPosName()+"]数据库有信息,放入ngToOk");
// }
// }
// }
//数据库有信息,实际无料 //数据库有信息,实际无料
if(noReelPosErrorList.length>0){ if(noReelPosErrorList.length>0){
log.info("开始检测noReelPosErrorList");
Query query=new Query(Criteria.where("posName").in(noReelPosErrorList)); Query query=new Query(Criteria.where("posName").in(noReelPosErrorList));
List<StoragePos> posList= storagePosManager.findByQuery(query); List<StoragePos> posList= storagePosManager.findByQuery(query);
for (StoragePos pos:posList) { for (StoragePos pos:posList) {
...@@ -313,6 +238,7 @@ public class NLPShelfHandler extends BaseDeviceHandler{ ...@@ -313,6 +238,7 @@ public class NLPShelfHandler extends BaseDeviceHandler{
List<String> outNgList = new ArrayList<>(); List<String> outNgList = new ArrayList<>();
if(hasReelPosList != null){ if(hasReelPosList != null){
log.info("开始检测hasReelPosList");
List<String> newList=new ArrayList<>(); List<String> newList=new ArrayList<>();
for (String posName : hasReelPosList) { for (String posName : hasReelPosList) {
StoragePos pos = storagePosManager.getByPosName(posName); StoragePos pos = storagePosManager.getByPosName(posName);
...@@ -337,6 +263,7 @@ public class NLPShelfHandler extends BaseDeviceHandler{ ...@@ -337,6 +263,7 @@ public class NLPShelfHandler extends BaseDeviceHandler{
inNgList.add(posStr); inNgList.add(posStr);
} }
}else if (hasReelPosList.length==1){ }else if (hasReelPosList.length==1){
log.info("开始检测执行入库");
StoragePos pos = storagePosManager.getByPosName(hasReelPosList[0]); StoragePos pos = storagePosManager.getByPosName(hasReelPosList[0]);
if(pos == null){ if(pos == null){
String msg = "未找到库位:"+String.join(",",hasReelPosList) ; String msg = "未找到库位:"+String.join(",",hasReelPosList) ;
...@@ -372,15 +299,17 @@ public class NLPShelfHandler extends BaseDeviceHandler{ ...@@ -372,15 +299,17 @@ public class NLPShelfHandler extends BaseDeviceHandler{
queueTask.setStorageName(storage.getName()); queueTask.setStorageName(storage.getName());
try { try {
//入库完成,发送入库完成请求 //入库完成,发送入库完成请求
log.info("入库完成,发送入库完成请求");
super.finishedPutIn(cid, pos.getPosName()); super.finishedPutIn(cid, pos.getPosName());
inOkList.add(hasReelPosList[0]); inOkList.add(hasReelPosList[0]);
String msg = queueTask.getBarcode() + "入库到" + pos.getPosName() + "成功"; String msg = queueTask.getBarcode() + "入库到" + pos.getPosName() + "成功";
log.error(msg); log.info(msg);
WebSocketServer.sendMsg("",new SocketMsg(msg, MsgType.INFO,"smfclient.nlp.inputOk",new String[]{queueTask.getBarcode(),pos.getPosName()})); WebSocketServer.sendMsg("",new SocketMsg(msg, MsgType.INFO,"smfclient.nlp.inputOk",new String[]{queueTask.getBarcode(),pos.getPosName()}));
try { try {
//判断是否是入库单入库 //判断是否是入库单入库
if (queueTask.getInType() == 5) { if (queueTask.getInType() == 5) {
log.info("入库单入库");
Barcode barcode = barcodeManager.findByBarcode(queueTask.getBarcode()); Barcode barcode = barcodeManager.findByBarcode(queueTask.getBarcode());
InListItem item = inListCache.UpdateInList(queueTask.getSourceName(), pos, barcode); InListItem item = inListCache.UpdateInList(queueTask.getSourceName(), pos, barcode);
...@@ -392,6 +321,8 @@ public class NLPShelfHandler extends BaseDeviceHandler{ ...@@ -392,6 +321,8 @@ public class NLPShelfHandler extends BaseDeviceHandler{
} }
} else { } else {
log.info("调用 7.5入库上架过账接口");
//入库完成,调用 7.5入库上架过账接口 //入库完成,调用 7.5入库上架过账接口
boolean result = HikApi.putInApi(queueTask.getOperator(), InOutApiInfo.inputInfo(queueTask.getInType(), queueTask.getBarcode(), queueTask.getNum())); boolean result = HikApi.putInApi(queueTask.getOperator(), InOutApiInfo.inputInfo(queueTask.getInType(), queueTask.getBarcode(), queueTask.getNum()));
...@@ -419,6 +350,8 @@ public class NLPShelfHandler extends BaseDeviceHandler{ ...@@ -419,6 +350,8 @@ public class NLPShelfHandler extends BaseDeviceHandler{
} }
if(noReelPosList != null){ if(noReelPosList != null){
//出库 //出库
log.info("出库检测noReelPosList");
for (String posName : noReelPosList) { for (String posName : noReelPosList) {
StoragePos pos = storagePosManager.getByPosName(posName); StoragePos pos = storagePosManager.getByPosName(posName);
if(pos==null){ if(pos==null){
...@@ -490,16 +423,7 @@ public class NLPShelfHandler extends BaseDeviceHandler{ ...@@ -490,16 +423,7 @@ public class NLPShelfHandler extends BaseDeviceHandler{
@AnonymousAccess @AnonymousAccess
public ResultBean shelfStatus(HttpServletRequest request){ public ResultBean shelfStatus(HttpServletRequest request){
String cid = request.getParameter("cid"); String cid = request.getParameter("cid");
Storage storage = dataCache.getStorage(cid); List<String> posList = dataCache.getUsedPosNameList(cid);
if(storage == null){
return ResultBean.newErrorResult(-1,"smfcore.shelfNotExist", "{0}对应的料架不存在",new String[]{cid} );
}
List<StoragePos> allPos = storagePosManager.findNotEmptyByStorageId(storage.getId());
List<String> posList = new ArrayList<>();
for (StoragePos pos : allPos) {
posList.add(pos.getPosName());
}
List<String> outTaskPosList = new ArrayList<>(); List<String> outTaskPosList = new ArrayList<>();
Collection<DataLog> queueTasks = taskService.getQueueTasks(cid); Collection<DataLog> queueTasks = taskService.getQueueTasks(cid);
for (DataLog task : queueTasks) { for (DataLog task : queueTasks) {
...@@ -518,6 +442,7 @@ public class NLPShelfHandler extends BaseDeviceHandler{ ...@@ -518,6 +442,7 @@ public class NLPShelfHandler extends BaseDeviceHandler{
Map<String,List<String>> dataMap = new HashMap<>(); Map<String,List<String>> dataMap = new HashMap<>();
dataMap.put("hasReelPosList",posList); dataMap.put("hasReelPosList",posList);
dataMap.put("outTaskList",outTaskPosList); dataMap.put("outTaskList",outTaskPosList);
//log.info("客户端获取["+cid+"]库位占用情况返回");
return ResultBean.newOkResult(dataMap); return ResultBean.newOkResult(dataMap);
} }
...@@ -529,15 +454,7 @@ public class NLPShelfHandler extends BaseDeviceHandler{ ...@@ -529,15 +454,7 @@ public class NLPShelfHandler extends BaseDeviceHandler{
@AnonymousAccess @AnonymousAccess
public ResultBean checkAll(HttpServletRequest request){ public ResultBean checkAll(HttpServletRequest request){
String cid = request.getParameter("cid"); String cid = request.getParameter("cid");
Storage storage = dataCache.getStorage(cid); List<String> posList = dataCache.getUsedPosNameList(cid);
if(storage == null){
return ResultBean.newErrorResult(-1,"smfcore.shelfNotExist", "{0}对应的料架不存在",new String[]{cid} );
}
List<StoragePos> allPos = storagePosManager.findNotEmptyByStorageId(storage.getId());
List<String> posList = new ArrayList<>();
for (StoragePos pos : allPos) {
posList.add(pos.getPosName());
}
return ResultBean.newOkResult(posList); return ResultBean.newOkResult(posList);
} }
@Override @Override
......
...@@ -270,6 +270,10 @@ public class DataCache { ...@@ -270,6 +270,10 @@ public class DataCache {
*/ */
private static Map<String,Map<String,InventoryItem>> inventoryMap = new ConcurrentHashMap<>(); private static Map<String,Map<String,InventoryItem>> inventoryMap = new ConcurrentHashMap<>();
/**
* 库位占用Map, key为cid,value为已使用的库位列表
*/
private static Map<String,List<String>> usedPosNameMap = new ConcurrentHashMap<>();
/** /**
...@@ -518,6 +522,44 @@ public class DataCache { ...@@ -518,6 +522,44 @@ public class DataCache {
} }
/**
* 出库时清除使用库位列表
*/
private void removeUsedPosNameList(String cid, String posName){
List<String> usedPosNameList = getUsedPosNameList(cid);
usedPosNameList.remove(posName);
usedPosNameMap.put(cid, usedPosNameList);
}
/**
* 入库时增加使用库位列表
*/
private void addUsedPosNameList(String cid, String posName){
List<String> usedPosNameList = getUsedPosNameList(cid);
usedPosNameList.add(posName);
usedPosNameMap.put(cid, usedPosNameList);
}
/**
* 获取设备所有占用的库位名称列表
*/
public List<String> getUsedPosNameList(String cid){
List<String> posNameList = usedPosNameMap.get(cid);
if(posNameList == null){
Storage storage = getStorage(cid);
posNameList = new ArrayList<>();
if(storage != null){
log.info("加载["+cid+"]所有已使用库位到缓存");
List<StoragePos> allPos = storagePosManager.findNotEmptyByStorageId(storage.getId());
for (StoragePos pos : allPos) {
posNameList.add(pos.getPosName());
}
usedPosNameMap.put(cid,posNameList);
}
}
return posNameList;
}
public InventoryItem getStorageInventoryByPartNumber(String cid, String partNumber){ public InventoryItem getStorageInventoryByPartNumber(String cid, String partNumber){
Map<String, InventoryItem> storageInventory = getStorageInventory(cid); Map<String, InventoryItem> storageInventory = getStorageInventory(cid);
InventoryItem partNumberInventoryItem = storageInventory.get(partNumber); InventoryItem partNumberInventoryItem = storageInventory.get(partNumber);
...@@ -558,7 +600,7 @@ public class DataCache { ...@@ -558,7 +600,7 @@ public class DataCache {
* @param amount * @param amount
* @return * @return
*/ */
public int updateInventoryAmount(String cid,String partNumber,int amount){ private int updateInventoryAmount(String cid,String partNumber,int amount){
if(amount != 0){ if(amount != 0){
InventoryItem inventoryItem = getStorageInventoryByPartNumber(cid,partNumber); InventoryItem inventoryItem = getStorageInventoryByPartNumber(cid,partNumber);
if(inventoryItem == null){ if(inventoryItem == null){
...@@ -586,11 +628,12 @@ public class DataCache { ...@@ -586,11 +628,12 @@ public class DataCache {
//出库 //出库
amount = - barcode.getAmount(); amount = - barcode.getAmount();
storage.emptyOnePos(pos); storage.emptyOnePos(pos);
removeUsedPosNameList(cid, pos.getPosName());
}else{ }else{
//入库 //入库
amount = barcode.getAmount(); amount = barcode.getAmount();
storage.useOnePos(pos); storage.useOnePos(pos);
addUsedPosNameList(cid, pos.getPosName());
//入库单处理 //入库单处理
if(ObjectUtil.isNotEmpty(storage.getInListName())){ if(ObjectUtil.isNotEmpty(storage.getInListName())){
inListCache.UpdateInList(storage.getInListName(),pos,barcode); inListCache.UpdateInList(storage.getInListName(),pos,barcode);
......
...@@ -42,8 +42,7 @@ public class LanguageMsgService { ...@@ -42,8 +42,7 @@ public class LanguageMsgService {
int hasCount=1; int hasCount=1;
Map<String,Map<String, LanguageMsg>> resourceMap=new HashMap<>(); Map<String,Map<String, LanguageMsg>> resourceMap=new HashMap<>();
List<LanguageMsg> msgs = languageMsgManager.findByQuery(new Query()); List<LanguageMsg> msgs = languageMsgManager.findByQuery(new Query());
for (LanguageMsg msg : for (LanguageMsg msg : msgs) {
msgs) {
if(msg.getCode().startsWith("smfcode.")||msg.getType().equals("smfcode")){ if(msg.getCode().startsWith("smfcode.")||msg.getType().equals("smfcode")){
String newCode=msg.getCode().replace("smfcode.","smfcore."); String newCode=msg.getCode().replace("smfcode.","smfcore.");
msg.setCode(newCode); msg.setCode(newCode);
...@@ -235,10 +234,8 @@ public class LanguageMsgService { ...@@ -235,10 +234,8 @@ public class LanguageMsgService {
List<LanguageMsg> newLanguageList = new ArrayList<>(); List<LanguageMsg> newLanguageList = new ArrayList<>();
List<LanguageMsg> updateLanguageList = new ArrayList<>(); List<LanguageMsg> updateLanguageList = new ArrayList<>();
if (proMap != null && proMap.size() > 0) { if (proMap != null && proMap.size() > 0) {
for (String key : for (String key : proMap.keySet()) {
proMap.keySet()) {
//如果Key爲空,直接返回 //如果Key爲空,直接返回
if(ObjectUtil.isEmpty(key)) if(ObjectUtil.isEmpty(key))
{ {
...@@ -273,8 +270,7 @@ public class LanguageMsgService { ...@@ -273,8 +270,7 @@ public class LanguageMsgService {
if (newLanguageList.size() > 0) { if (newLanguageList.size() > 0) {
languageMsgManager.insertAll(newLanguageList); languageMsgManager.insertAll(newLanguageList);
for (LanguageMsg msg : for (LanguageMsg msg : newLanguageList) {
newLanguageList) {
MessageUtils.updateMsg(msg); MessageUtils.updateMsg(msg);
} }
} }
......
...@@ -283,6 +283,15 @@ public class LiteOrderCache implements ITaskListener { ...@@ -283,6 +283,15 @@ public class LiteOrderCache implements ITaskListener {
newItems = (ArrayList<HikOrderInfo>) apiResult.getData(); newItems = (ArrayList<HikOrderInfo>) apiResult.getData();
} }
} }
// newItems = Lists.newArrayList();
// HikOrderInfo item = new HikOrderInfo();
// item.setBaseCode("BaseCode");
// item.setQty(1000);
// item.setMaterialNo("100100704");
// item.setStation("AAA");
// item.setJobNo("1001583501_1");
// item.setReplenishmentNo("8001B22070600061");
// newItems.add(item);
if (newItems != null) { if (newItems != null) {
//删除旧的Items //删除旧的Items
...@@ -439,13 +448,12 @@ public class LiteOrderCache implements ITaskListener { ...@@ -439,13 +448,12 @@ public class LiteOrderCache implements ITaskListener {
boolean needJieliao =false; boolean needJieliao =false;
//查找PN的所有库存,PN=pn,未锁定,qty 从大到小,入库时间正序 //查找PN的所有库存,PN=pn,未锁定,qty 从大到小,批次正序, 入库时间正序
List<StoragePos> posList = storagePosManager.findOrderItemInStorage(availableStorageIds, pn, excludePosIds); List<StoragePos> posList = storagePosManager.findOrderItemInStorage(availableStorageIds, pn, excludePosIds);
int storageNum=0; int storageNum=0;
int reelNum=posList.size(); int reelNum=posList.size();
for (StoragePos pos :posList for (StoragePos pos :posList) {
) {
storageNum+=pos.getBarcode().getAmount(); storageNum+=pos.getBarcode().getAmount();
} }
...@@ -455,9 +463,9 @@ public class LiteOrderCache implements ITaskListener { ...@@ -455,9 +463,9 @@ public class LiteOrderCache implements ITaskListener {
log.info("工单[" + cacheOrder.getOrderNo() + "]缺料出库: 物料号[" + pn + "] ,需求数量[" + orderItem.getWemng() + "], 未找到元器件信息 "); log.info("工单[" + cacheOrder.getOrderNo() + "]缺料出库: 物料号[" + pn + "] ,需求数量[" + orderItem.getWemng() + "], 未找到元器件信息 ");
shortage = true; shortage = true;
//判断库存 使用最小库存盘数:当前盘数<=最小库存盘数时,需要截料 //判断库存 使用最小库存盘数:当前盘数<=最小库存盘数时,需要截料
if(component.getMinStoreNum()>0&& reelNum<=component.getMinStoreNum()){ // if(component.getMinStoreNum()>0&& reelNum<=component.getMinStoreNum()){
needJieliao=true; // needJieliao=true;
} // }
}else { }else {
log.info("工单[" + cacheOrder.getOrderNo() + "] 物料号[" + pn + "] ,需求数量[" + orderItem.getWemng() + "], 未找到元器件信息, 缺料 "); log.info("工单[" + cacheOrder.getOrderNo() + "] 物料号[" + pn + "] ,需求数量[" + orderItem.getWemng() + "], 未找到元器件信息, 缺料 ");
return materialShortPro(userName, cacheOrder); return materialShortPro(userName, cacheOrder);
...@@ -488,15 +496,18 @@ public class LiteOrderCache implements ITaskListener { ...@@ -488,15 +496,18 @@ public class LiteOrderCache implements ITaskListener {
} }
} }
//判断库存 使用最小库存盘数:当前盘数<=最小库存盘数时,需要截料
if(component.getMinStoreNum()>0&& reelNum<=component.getMinStoreNum()){
needJieliao=true;
}
List<StoragePos> itemPosList = new ArrayList<>(); List<StoragePos> itemPosList = new ArrayList<>();
List<String> itemPosNameList = new ArrayList<>(); List<String> itemPosNameList = new ArrayList<>();
//此PN未完成 //此PN未完成
int targetNum = needNum; int targetNum = needNum;
for (int i=0;i<posList.size();i++ for (int i=0;i<posList.size();i++) {
) {
List<StoragePos> forPosList=new ArrayList<>(); List<StoragePos> forPosList=new ArrayList<>();
for (StoragePos pos : for (StoragePos pos : posList) {
posList) {
if(!itemPosNameList.contains(pos.getPosName())){ if(!itemPosNameList.contains(pos.getPosName())){
forPosList.add(pos); forPosList.add(pos);
} }
...@@ -504,8 +515,7 @@ public class LiteOrderCache implements ITaskListener { ...@@ -504,8 +515,7 @@ public class LiteOrderCache implements ITaskListener {
//循环剩余的库位,查找 //循环剩余的库位,查找
int forIndex=-1; int forIndex=-1;
for (StoragePos pos : for (StoragePos pos : forPosList) {
forPosList) {
forIndex++; forIndex++;
boolean isLast=(forIndex==(forPosList.size()-1)); boolean isLast=(forIndex==(forPosList.size()-1));
//已经在出库列表 //已经在出库列表
...@@ -621,6 +631,9 @@ public class LiteOrderCache implements ITaskListener { ...@@ -621,6 +631,9 @@ public class LiteOrderCache implements ITaskListener {
int itemReelCount=0; int itemReelCount=0;
int itemOutCount=0; int itemOutCount=0;
List<StoragePos> posList=needOutPosMap.get(orderItem.getMaterialNo()); List<StoragePos> posList=needOutPosMap.get(orderItem.getMaterialNo());
if(posList == null){
posList = new ArrayList<>();
}
for (StoragePos pos : posList) { for (StoragePos pos : posList) {
DataLog task = taskService.newTask(pos) ; DataLog task = taskService.newTask(pos) ;
...@@ -650,7 +663,12 @@ public class LiteOrderCache implements ITaskListener { ...@@ -650,7 +663,12 @@ public class LiteOrderCache implements ITaskListener {
if(addOutbound){ if(addOutbound){
task.setInOperate(true); task.setInOperate(true);
task.setAddOutbound(true); task.setAddOutbound(true);
task.setLightColor(ORDER_COLOR.PINK.getRgb());//补料出库 颜色:PINK task.setLightColor(ORDER_COLOR.PINK.getRgb());//缺料出库 颜色:PINK
}
if(cacheOrder.isRepleOrder()){
//产线补料
task.setLightColor(ORDER_COLOR.FORESTGREEN.getRgb());//产线补料出库 颜色:FORESTGREEN
} }
try{ try{
taskService.addTaskToExecute(task); taskService.addTaskToExecute(task);
......
...@@ -29,6 +29,10 @@ public enum ORDER_COLOR { ...@@ -29,6 +29,10 @@ public enum ORDER_COLOR {
// 'white':[15,125,125,125], // 'white':[15,125,125,125],
// 'off':[16,0,0,0], // 'off':[16,0,0,0],
// 'magenta':[17,125,125,0] // 'magenta':[17,125,125,0]
//手动出库:BLUE;入库:DARKGREEN;
// 工单首盘料:CYAN;工单截料:PURPLE;工单备件:SKYBLUE;
// 工单缺料出库:PINK;普通转储出库单:FIREBRICK;产线实料出库 颜色:FORESTGREEN
BLUE("0000FF"), BLUE("0000FF"),
//MAGENTA("FF00FF"), //MAGENTA("FF00FF"),
CYAN("00FFFF"), CYAN("00FFFF"),
...@@ -37,8 +41,8 @@ public enum ORDER_COLOR { ...@@ -37,8 +41,8 @@ public enum ORDER_COLOR {
SKYBLUE("6CA6CD"), SKYBLUE("6CA6CD"),
PINK("FF1493"), PINK("FF1493"),
FORESTGREEN("228B22"), FORESTGREEN("228B22"),
LIGHTBLUE("8470FF"), LIGHTBLUE("8470FF"),//暂时未使用
INDIANRED("8B3A3A"), INDIANRED("8B3A3A"),//暂时未使用
DARKGREEN("556B2F"), DARKGREEN("556B2F"),
; ;
......
...@@ -212,7 +212,7 @@ public class RepleOrderController { ...@@ -212,7 +212,7 @@ public class RepleOrderController {
@ApiOperation("料盘出库界面,获取执行的工单列表") @ApiOperation("料盘出库界面,获取执行的工单列表")
@GetMapping("/executeOrders") @GetMapping("/executeOrders")
@PreAuthorize("@el.check('reelOut')") @PreAuthorize("@el.check('productionLineReple')")
public List<OrderDto> queryExecuteOrder() { public List<OrderDto> queryExecuteOrder() {
//查询正在执行的工单列表 //查询正在执行的工单列表
Query query = new Query(Criteria.where("status").is(LITEORDER_STATUS.EXECUTING).and("replenishmentNo").ne(null)); Query query = new Query(Criteria.where("status").is(LITEORDER_STATUS.EXECUTING).and("replenishmentNo").ne(null));
...@@ -252,7 +252,7 @@ public class RepleOrderController { ...@@ -252,7 +252,7 @@ public class RepleOrderController {
@ApiOperation("料盘出库界面,获取当前产线补料任务列表") @ApiOperation("料盘出库界面,获取当前产线补料任务列表")
@GetMapping("/reelOutTasks") @GetMapping("/reelOutTasks")
@PreAuthorize("@el.check('reelOut')") @PreAuthorize("@el.check('productionLineReple')")
public List<TaskDto> queryReelOutTasks(@RequestParam Map<String, String> paramsMap) { public List<TaskDto> queryReelOutTasks(@RequestParam Map<String, String> paramsMap) {
//查询正在执行的工单列表 //查询正在执行的工单列表
...@@ -276,7 +276,7 @@ public class RepleOrderController { ...@@ -276,7 +276,7 @@ public class RepleOrderController {
@ApiOperation("料盘出库界面,切换到下一个工单") @ApiOperation("料盘出库界面,切换到下一个工单")
@PostMapping("/nextOrder") @PostMapping("/nextOrder")
@PreAuthorize("@el.check('reelOut')") @PreAuthorize("@el.check('productionLineReple')")
public ResultBean nextOrder(@RequestParam Map<String, String> paramsMap) { public ResultBean nextOrder(@RequestParam Map<String, String> paramsMap) {
if (ObjectUtil.isNotEmpty(currOrderNo)) { if (ObjectUtil.isNotEmpty(currOrderNo)) {
...@@ -295,6 +295,7 @@ public class RepleOrderController { ...@@ -295,6 +295,7 @@ public class RepleOrderController {
} }
LiteOrder liteOrder = orderList.get(0); LiteOrder liteOrder = orderList.get(0);
currOrderNo = liteOrder.getOrderNo();
//设置此工单的任务可以发送给料架 //设置此工单的任务可以发送给料架
List<DataLog> taskList = getOrderTaskByUser(liteOrder, true); List<DataLog> taskList = getOrderTaskByUser(liteOrder, true);
for (DataLog datalog : taskList) { for (DataLog datalog : taskList) {
...@@ -306,7 +307,7 @@ public class RepleOrderController { ...@@ -306,7 +307,7 @@ public class RepleOrderController {
} }
@ApiOperation("齐套页面,获取齐套数据") @ApiOperation("齐套页面,获取齐套数据")
@GetMapping("/orderSet") @GetMapping("/orderSet")
@PreAuthorize("@el.check('workOrder')") @PreAuthorize("@el.check('productionLineReple')")
public List<OrderPnDto> orderSetData( ) { public List<OrderPnDto> orderSetData( ) {
List<OrderPnInfo> orderPnInfos=orderPnCache.getDataList(); List<OrderPnInfo> orderPnInfos=orderPnCache.getDataList();
...@@ -315,7 +316,7 @@ public class RepleOrderController { ...@@ -315,7 +316,7 @@ public class RepleOrderController {
} }
@ApiOperation("齐套页面,刷新齐套数据") @ApiOperation("齐套页面,刷新齐套数据")
@PostMapping("/orderSet/update") @PostMapping("/orderSet/update")
@PreAuthorize("@el.check('workOrder')") @PreAuthorize("@el.check('productionLineReple')")
public ResultBean updateOrderSet(HttpServletRequest request ) { public ResultBean updateOrderSet(HttpServletRequest request ) {
boolean result = orderPnCache.reloadData(); boolean result = orderPnCache.reloadData();
if (!result) { if (!result) {
...@@ -328,7 +329,7 @@ public class RepleOrderController { ...@@ -328,7 +329,7 @@ public class RepleOrderController {
@ApiOperation("导出齐套列表") @ApiOperation("导出齐套列表")
@GetMapping(value = "/orderSet/download") @GetMapping(value = "/orderSet/download")
@PreAuthorize("@el.check('workOrder')") @PreAuthorize("@el.check('productionLineReple')")
public void download(HttpServletResponse response, HttpServletRequest request) throws IOException { public void download(HttpServletResponse response, HttpServletRequest request) throws IOException {
List<OrderPnInfo> orderPnInfos=orderPnCache.getDataList(); List<OrderPnInfo> orderPnInfos=orderPnCache.getDataList();
download(orderPnInfos,response,request.getLocale()); download(orderPnInfos,response,request.getLocale());
...@@ -353,7 +354,7 @@ public class RepleOrderController { ...@@ -353,7 +354,7 @@ public class RepleOrderController {
private List<LiteOrder> getExecuteOrders() { private List<LiteOrder> getExecuteOrders() {
//查询正在执行的工单列表 //查询正在执行的工单列表
Query query = new Query(Criteria.where("status").is(LITEORDER_STATUS.EXECUTING).and("replenishmentNo").not()); Query query = new Query(Criteria.where("status").is(LITEORDER_STATUS.EXECUTING).and("replenishmentNo").ne(null));
//根据开始出库时间排序 //根据开始出库时间排序
Sort sort = Sort.by(Sort.Direction.ASC, "startOutTime"); Sort sort = Sort.by(Sort.Direction.ASC, "startOutTime");
query.with(sort); query.with(sort);
......
...@@ -8,6 +8,7 @@ import com.neotel.smfcore.core.order.enums.LITEORDER_STATUS; ...@@ -8,6 +8,7 @@ import com.neotel.smfcore.core.order.enums.LITEORDER_STATUS;
import com.neotel.smfcore.hikvision.bean.HikOrderInfo; import com.neotel.smfcore.hikvision.bean.HikOrderInfo;
import lombok.Data; import lombok.Data;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.util.Strings;
import org.springframework.data.annotation.Transient; import org.springframework.data.annotation.Transient;
import org.springframework.data.mongodb.core.mapping.Document; import org.springframework.data.mongodb.core.mapping.Document;
...@@ -260,6 +261,15 @@ public class LiteOrder extends BasePo implements Serializable { ...@@ -260,6 +261,15 @@ public class LiteOrder extends BasePo implements Serializable {
return status == LITEORDER_STATUS.ADDOUTBOUND; return status == LITEORDER_STATUS.ADDOUTBOUND;
} }
/**
* 是否是产线补(有补料单号)
* @return
*/
public boolean isRepleOrder(){
//是否是产线补料
return Strings.isNotBlank(replenishmentNo);
}
public void setTaskReelCount(int taskReelCount) { public void setTaskReelCount(int taskReelCount) {
......
...@@ -270,23 +270,16 @@ public class OutListCache implements ITaskListener { ...@@ -270,23 +270,16 @@ public class OutListCache implements ITaskListener {
} }
} }
List<StoragePos> itemPosList = new ArrayList<>();
//此PN未完成 //此PN未完成
int targetNum = needNum; int targetNum = needNum;
int docType = outList.getDocType();
List<StoragePos> itemPosList = pickReels(docType,itemPosNameList,posList,targetNum);
//循环剩余的库位,查找 for (StoragePos storagePos : itemPosList) {
//int forIndex = -1; itemPosNameList.add(storagePos.getPosName());
for (StoragePos pos : posList) { targetNum -= storagePos.getBarcode().getAmount();
if(!itemPosNameList.contains(pos.getPosName())){
itemPosList.add(pos);
itemPosNameList.add(pos.getPosName());
targetNum -= pos.getBarcode().getAmount();
if (targetNum <= 0) {
break;
}
} }
}
//判断数量是否满足 //判断数量是否满足
if (targetNum > 0) { if (targetNum > 0) {
int outNum = needNum - targetNum; int outNum = needNum - targetNum;
...@@ -336,7 +329,7 @@ public class OutListCache implements ITaskListener { ...@@ -336,7 +329,7 @@ public class OutListCache implements ITaskListener {
task.setOutType(4); task.setOutType(4);
} }
task.setLightColor(ORDER_COLOR.SKYBLUE.getRgb());//普通转储出库单 颜色:SKYBLUE task.setLightColor(ORDER_COLOR.FIREBRICK.getRgb());//普通转储出库单 颜色:FIREBRICK
taskService.addTaskToExecute(task); taskService.addTaskToExecute(task);
log.info("转储出库单[" + name + "],任务数[" + taskReelCount + "]仓位【" + pos.getPosName() + "】RI=[" + pos.getBarcode().getBarcode() + "] PN=[" + outListItem.getMaterialNo() + "] Amount[" + pos.getBarcode().getAmount() + log.info("转储出库单[" + name + "],任务数[" + taskReelCount + "]仓位【" + pos.getPosName() + "】RI=[" + pos.getBarcode().getBarcode() + "] PN=[" + outListItem.getMaterialNo() + "] Amount[" + pos.getBarcode().getAmount() +
"] 首盘[" + task.isFirstReel() + "] 截料[" + task.isNeedSplitting() + "][" + task.getNeedQty() + "]"); "] 首盘[" + task.isFirstReel() + "] 截料[" + task.isNeedSplitting() + "][" + task.getNeedQty() + "]");
...@@ -374,5 +367,64 @@ public class OutListCache implements ITaskListener { ...@@ -374,5 +367,64 @@ public class OutListCache implements ITaskListener {
return ""; return "";
} }
/**
* 1,成本中心领料-大于等于需求量最小的料盘数量
* 2,线边仓间转储出库,转外协出库,发运单出库-整盘优先原则,不足发散盘
*/
private List<StoragePos> pickReels(int docType, List<String> outPosNameList, List<StoragePos> posList, int targetNum){
List<String> excludePosNameList = new ArrayList<>(outPosNameList);
List<StoragePos> itemPickPosList = new ArrayList<>();
boolean pickMaxQtyReel = true;
if(docType == 3){
//1,成本中心领料-大于等于需求量最小的料盘数量
pickMaxQtyReel = false;
}else{
//2,线边仓间转储出库,转外协出库,发运单出库-整盘优先原则,不足发散盘
pickMaxQtyReel = true;
}
do {
StoragePos outPos = pickOneReel(excludePosNameList,posList,targetNum, pickMaxQtyReel);
if(outPos == null){
break;
}else{
log.info("挑选到批次["+outPos.getBarcode().getBatch()+"]物料:" + outPos.getBarcode().getBarcode() + " 数量:" + outPos.getBarcode().getAmount());
itemPickPosList.add(outPos);
excludePosNameList.add(outPos.getPosName());
targetNum = targetNum - outPos.getBarcode().getAmount();
if(targetNum <=0){
break;
}
}
} while(true);
return itemPickPosList;
}
private StoragePos pickOneReel(List<String> excluedPosNameList, List<StoragePos> posList, int targetNum, boolean pickMaxQtyReel){
StoragePos outPos = null;
if(targetNum > 0){
for (StoragePos pos : posList) {
if(!excluedPosNameList.contains(pos.getPosName())){
if(outPos == null){
//先取第一盘(数量最大的盘)
outPos = pos;
if(pickMaxQtyReel){
return outPos;
}
}
int qty = pos.getBarcode().getAmount();
if(qty < outPos.getBarcode().getAmount() && qty >= targetNum){
//如果当前盘小于已挑料盘并且这盘料出库后可以满足需求,那么替换已挑料盘
outPos = pos;
}
if(qty < targetNum){
//当前料盘挑完还不满足需求
return outPos;
}
}
}
}
return outPos;
}
} }
...@@ -600,9 +600,9 @@ public class StoragePosManagerImpl implements IStoragePosManager { ...@@ -600,9 +600,9 @@ public class StoragePosManagerImpl implements IStoragePosManager {
} }
Query q = new Query(c); Query q = new Query(c);
//数量从大到小,出库先进先出 //数量从大到小,出库先进先出
Sort sort = Sort.by(Sort.Direction.ASC, "barcode.amount"); Sort sort = Sort.by(Sort.Direction.DESC, "barcode.amount");
sort.and(Sort.by(Sort.Direction.ASC, "barcode.batch")); sort.and(Sort.by(Sort.Direction.ASC, "barcode.batch"));
sort.and(Sort.by(Sort.Direction.ASC, "canCheckOutTime")); //sort.and(Sort.by(Sort.Direction.ASC, "canCheckOutTime"));
q.with(sort); q.with(sort);
List<StoragePos> posList = storagePosDao.findByQuery(q); List<StoragePos> posList = storagePosDao.findByQuery(q);
if (posList == null || posList.size() <= 0) { if (posList == null || posList.size() <= 0) {
......
支持 Markdown 格式
你添加了 0 到此讨论。请谨慎行事。
Finish editing this message first!