Commit fd909f20 LN

工单挑料逻辑。料盘出库界面接口。

1 个父辈 dc5bb044
......@@ -78,7 +78,7 @@ public class DataInitManager {
operator = roleManager.save(operator);
log.info("创建默认角色:" + operator.toString());
admin = new User(userName, "admin@qq.com", "zh-CN", role.getId(), "$2a$10$Egp1/gvFlt7zhlXVfEFw4OfWQCGPw0ClmMcc6FjTnvXNRVf9zdMRa", true, true, new Date(), groupIds, "");
admin = new User(userName, "admin@qq.com", "zh-CN", role.getId(), "$2a$10$Egp1/gvFlt7zhlXVfEFw4OfWQCGPw0ClmMcc6FjTnvXNRVf9zdMRa", true, true, new Date(), groupIds, "","");
userManager.save(admin);
log.info("创建默认用户:" + admin.toString());
......
......@@ -107,7 +107,7 @@ public class UserCodeUtil {
String langu="";
String roleId="";
User user=new User(username,email,langu,roleId,"",true
,false,new Date(),new HashSet<>(),"");
,false,new Date(),new HashSet<>(),"","");
user.setId(id);
user.setCreateDate(createData);
list.add(user);
......
......@@ -6,31 +6,30 @@ import com.neotel.smfcore.common.bean.ResultBean;
import com.neotel.smfcore.common.exception.ValidateException;
import com.neotel.smfcore.common.utils.Constants;
import com.neotel.smfcore.core.barcode.service.manager.IBarcodeManager;
import com.neotel.smfcore.core.barcode.service.manager.IComponentManager;
import com.neotel.smfcore.core.barcode.service.po.Barcode;
import com.neotel.smfcore.core.device.bean.StatusBean;
import com.neotel.smfcore.core.barcode.service.po.Component;
import com.neotel.smfcore.core.device.enums.OP;
import com.neotel.smfcore.core.device.enums.OP_STATUS;
import com.neotel.smfcore.core.device.util.DataCache;
import com.neotel.smfcore.core.language.util.MessageUtils;
import com.neotel.smfcore.core.order.enums.LITEORDER_STATUS;
import com.neotel.smfcore.core.order.enums.ORDER_COLOR;
import com.neotel.smfcore.core.order.service.dao.ILiteOrderDao;
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.storage.enums.CHECKOUT_TYPE;
import com.neotel.smfcore.core.storage.rest.mapstruct.SafetyInventoryMapper;
import com.neotel.smfcore.core.storage.service.manager.IStoragePosManager;
import com.neotel.smfcore.core.storage.service.po.Storage;
import com.neotel.smfcore.core.storage.service.po.StoragePos;
import com.neotel.smfcore.core.system.bean.MSDAppendInfo;
import com.neotel.smfcore.core.system.listener.ITaskListener;
import com.neotel.smfcore.core.system.service.po.DataLog;
import com.neotel.smfcore.core.system.util.TaskService;
import javafx.concurrent.Task;
import com.neotel.smfcore.hikvision.HikApi;
import com.neotel.smfcore.hikvision.bean.OrderItemInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Service;
import java.util.*;
......@@ -144,12 +143,13 @@ public class LiteOrderCache implements ITaskListener {
public void executeOrderTask(){
for (LiteOrder order :
liteOrderMap.values()) {
if(order.isNew()||order.isTaskFinished()){
if(order.isNew() ){
// if(order.isNew()||order.isTaskFinished()){
//判断是否到达时间
Date curr=new Date();
if(order.getStartDate().before(curr)){
//开始自动出库
String result= checkOutLiteOrder(order.getOrderNo(),false);
String result= checkOutLiteOrder("system",order.getOrderNo() );
if(!ObjectUtil.isEmpty(result)){
String msg= MessageUtils.getText(result,MessageUtils.getDefaultLocal(),"");
log.info("自动执行工单 【"+order.getOrderNo()+"】 失败:"+msg);
......@@ -285,6 +285,8 @@ public class LiteOrderCache implements ITaskListener {
}
if(closed){
order.setClosed(closed);
//工单出库完成,调用7.11订单发料完成通知接口
boolean result=HikApi.orderEndApi(order.getOperateUser(),order.getJobNo());
}
}
} else {
......@@ -313,10 +315,131 @@ public class LiteOrderCache implements ITaskListener {
ORDER_COLOR nextColor = ORDER_COLOR.nextColor(currentColors);
return nextColor;
}
/**
* 工单出库前,如果是new工单,需要从API重新获取工单详情
* @param liteOrder
* @return
*/
public LiteOrder updateOrderFromApi(String userName,LiteOrder liteOrder) {
if (!liteOrder.isNew()) {
return liteOrder;
}
//判断是工单号查询还是补料单号查询
List<Object> apiResults = null;
List<OrderItemInfo> newItems = null;
if (ObjectUtil.isNotEmpty(liteOrder.getReplenishmentNo())) {
// 7.9补料单发料状态查询接口
apiResults = HikApi.updateReplenishmentOrderApi(userName, liteOrder.getReplenishmentNo());
} else {
// 7.7工单发料状态查询接口
apiResults = HikApi.updateOrderApi(userName, liteOrder.getOrderNo());
}
if (apiResults != null && apiResults.size() == 2) {
int code = Integer.parseInt(apiResults.get(0).toString());
if (code == 33) {
liteOrder.setClosed(true);
liteOrderManager.save(liteOrder);
log.info(" API更新 工单【" + liteOrder.getOrderNo() + "】已关闭,直接关闭不需要出库");
addOrderToMap(liteOrder);
return liteOrder;
} else {
newItems = (ArrayList<OrderItemInfo>) apiResults.get(1);
}
}
if (newItems != null) {
for (OrderItemInfo apiItems : newItems
) {
LiteOrderItem newItem = apiItems.crateOrderItem(liteOrder.getOrderNo());
liteOrder = updateOrderItem(liteOrder, newItem);
}
liteOrderManager.save(liteOrder);
addOrderToMap(liteOrder);
}
return liteOrder;
}
/**
* 更新工单指定的物料信息
* @param order
* @param item
* @return
*/
public LiteOrder updateOrderItem(LiteOrder order,LiteOrderItem item) {
List<LiteOrderItem> items = order.getOrderItems();
boolean find = false;
for (LiteOrderItem oldItem :
items) {
if (oldItem.getMaterialNo().equals(item.getMaterialNo())) {
oldItem.UpdateData(item);
liteOrderItemManager.save(oldItem);
find = true;
break;
}
}
if (!find) {
item = liteOrderItemManager.save(item);
items.add(item);
order.setOrderItems(items);
}
return order;
}
@Autowired
private IComponentManager componentManager;
@Autowired
private SafetyInventoryMapper safetyInventoryMapper;
// /**
// * 获取需要截料的物料
// * @return key=需要截料的物料编号
// */
// private Map<String,SafetyInventoryDto> getSafetyInventoryMap( ) {
// List<Component> componentList = componentManager.findByQuery(new Query());
// Map<String, InventoryItem> inventoryItemMap = dataCache.getAllInventory(null, "");
//
//
// Map<String, SafetyInventoryDto> resultsMap = new HashMap<>();
// //循环PN
// for (Component com :
// componentList) {
// InventoryItem item = inventoryItemMap.get(com.getPartNumber());
// SafetyInventoryDto dto = new SafetyInventoryDto();
// if (item == null) {
// } else {
// dto = safetyInventoryMapper.toDto(item);
// }
// dto.setPartNumber(com.getPartNumber());
// dto.setAmount(com.getAmount());
// dto.setSupplementReel(0);
// //截料: 库存物料的盘数≤设定值 ,设定值使用安全库存
// if (dto.getStockCount() < com.getSafetyStoreNum()) {
//
// if (dto.getStockReel() > 0 && dto.getStockCount() > 0) {
//
// int reelCount = dto.getStockCount() / dto.getStockReel();
// //补充盘数
// int needReel = (com.getMinStoreNum() - dto.getStockCount()) / reelCount;
// dto.setSupplementReel(needReel);
// } else {
// int needReel = com.getMinStoreNum() / dto.getAmount();
// dto.setSupplementReel(needReel);
// }
// }
//
// resultsMap.put(com.getPartNumber(), dto);
// }
// return resultsMap;
// }
/**
* 锁定物料
*/
public synchronized String checkOutLiteOrder(String orderNo, boolean outBom) {
public synchronized String checkOutLiteOrder(String userName, String orderNo) {
LiteOrder cacheOrder = liteOrderMap.get(orderNo);
if (cacheOrder == null) {
......@@ -336,9 +459,16 @@ public class LiteOrderCache implements ITaskListener {
return "smfcore.order.hasClose";
}
updateOrderFromApi(userName,cacheOrder);
//如果更新完工单已关闭,直接提示
if(cacheOrder.isClosed()) {
log.info("工单[" + orderNo + "]已关闭,无法出库");
return "smfcore.order.hasClose";
}
ORDER_COLOR nextColor = getNextColor();
if (nextColor == null) {
log.info("执行工单[" + orderNo + "] outBom=" + outBom + "时,已达最大可执行工单数");
log.info("执行工单[" + orderNo + "] 时, 已达最大可执行工单数");
return "smfcore.order.out.maxOrder";
}
......@@ -348,81 +478,266 @@ public class LiteOrderCache implements ITaskListener {
return checkOutOrder(cacheOrder).getMsgKey();
}
log.info("开始执行工单[" + orderNo + "] outBom=" + outBom);
cacheOrder.setTaskReelCount(0);
cacheOrder.setTaskFinishedTime(-1);
cacheOrder.setFinishedReelCount(0);
if (outBom) {
cacheOrder.setStatus(LITEORDER_STATUS.BOM);
} else {
cacheOrder.setStatus(LITEORDER_STATUS.TAILS);
}
//liteOrderMap.put(cacheOrder.getOrderNo(), cacheOrder);
int taskReelCount = 0;
CHECKOUT_TYPE checkoutType = dataCache.getCheckOutType();
List<String> availableStorageIds = dataCache.getAvailableStorageIds();
// 出库策略(系统判断逻辑由上到下依次满足):
//①湿敏超期物料所在仓位锁定,不允许备料;
//②贵重物料,不允许超发,按实际需求发料;
//③截料:库存物料的盘数≤设定值,SMF仓位分配
// 锁定时要标识需要截料并按工单实际需求发料,料
// 盘相同要先进先出
//④发料盘分配逻辑:
// 1、散盘与整盘如何分配;
// 2、订单发料:
// 2.1、订单数量>200;
// 2.1.1 散盘:整盘=3:7(比例可调,物料数量)
// 2.1.2 整盘数量=需求数量*整盘占比/最小包装(四
// 舍五入)
// 2.1.3 剩余发散盘,优先取散盘(由多到少发送),
// 散盘不满足情况下补充整盘
// 2.2、订单数量≤200;(料盘最少原则)
// 2.2.1 优先发单盘
// 2.2.1 单盘不满足,发最大量+补充盘
// 3 MES传输实际需求+超发需求
// 3.1 优先满足实际需求+超发需求
// 3.2 只满足实际需求,不满足超发需求,发出
// 3.3 不满足实际需求,不发,报缺料
// 料盘相同要先进先出(物料配置小单标准不需要再
// 单独写逻辑考虑)
//⑤ 锁定仓位要指定首件所在的仓位,首件取经过①
//②③④筛选锁定料盘中的最大料盘
log.info("开始为工单[" + orderNo + "]挑选出库物料 ");
List<String> availableStorageIds = dataCache.getAvailableStorageIds();
//其他出库模式一次性全部生成任务
Map<String ,List<StoragePos>> needOutPosMap=new HashMap<>();//挑出的需要出库的料列表,key=pn,value=库位
Map<String,Integer> jieliaoPosMap=new HashMap<>();//需要截料的物料列表,key=PosName,value=此工单使用数量
//获取此工单出库的所有物料
for (LiteOrderItem orderItem : cacheOrder.getOrderItems()) {
orderItem.setOutNum(0);
orderItem.setOutReelCount(0);
liteOrderItemManager.save(orderItem);
//剩余未出数量
Float totalNum = orderItem.getQty() * cacheOrder.getOrderTimes();
int remainNum = totalNum.intValue() - orderItem.getOutNum();
String pn = orderItem.getMaterialNo();
//需求数量
int needNum = orderItem.getQty() + orderItem.getIncrement();
////②贵重物料,不允许超发,按实际需求发料;
boolean isGuizhong = orderItem.getOverFlag()==1;
//判断是否需要截料
boolean needJieliao =false;
// boolean needJieliao = jieliaoMap.containsKey(pn);
if (needNum <= 0) {
continue;
}
List<StoragePos> itemPosList = new ArrayList<>();
List<String> itemPosNameList = new ArrayList<>();
//查找PN的所有库存,PN=pn,未锁定,qty 从大到小,入库时间正序
List<StoragePos> posList = storagePosManager.findOrderItemInStorage(availableStorageIds, pn, excludePosIds());
int storageNum=0;
for (StoragePos pos :posList
) {
storageNum+=pos.getBarcode().getAmount();
}
Component component = componentManager.findOneByPN(pn);
if(component==null){
log.info("工单[" + cacheOrder.getOrderNo() + "] 物料号[" + pn + "] ,需求数量[" + orderItem.getWemng() + "], 未找到元器件信息, 缺料 ");
return "smfcore.order.out.short";
}
//判断库存
if(storageNum<component.getSafetyStoreNum()){
needJieliao=true;
}
//判断库存数量是否小于需求数量,小于直接返回缺料
if(storageNum<orderItem.getQty()){
//不满足实际需求,不发,报缺料
log.info("工单[" + cacheOrder.getOrderNo() + "] 物料号[" + pn + "] ,需求数量[" + orderItem.getWemng() + "], 库存总数量[" + storageNum + "], 不满足实际需求,缺料 ");
return "smfcore.order.out.short";
}
int wholeReelCount = 0;
int needWholeReelCount = 0;
//判断整盘散盘比
if (orderItem.getWemng() > 200) {
if (component.getWholeReel() >= 0) {
wholeReelCount = needNum * (component.getWholeReel() / (component.getWholeReel() + component.getHalfReel())) / component.getAmount();
needWholeReelCount = wholeReelCount;
log.info("工单[" + cacheOrder.getOrderNo() + "] 物料号[" + pn + "] ,订单数量[" + orderItem.getWemng() + "],计算的整盘数量:" + wholeReelCount);
}
}
//此PN未完成
if (remainNum > 0) {
if (outBom) {
//套料出库,设置剩余数量为1,这样就只会出一盘
remainNum = 1;
int targetNum = needNum;
StoragePos tempPos = null;
for (StoragePos pos :
posList) {
//已经在出库列表
if (itemPosNameList.contains(pos.getPosName())) {
continue;
}
int assignNum = 0;
while (assignNum < remainNum) {
Collection<String> excludePosIds = excludePosIds();
String partNumber = orderItem.getMaterialNo();
StoragePos pos = null;
if(cacheOrder.getType()==2){
//RI
pos=storagePosManager.getByBarcode(orderItem.getRi());
if(excludePosIds.contains(pos.getId())) {
log.info("工单[" + orderNo + "]RI出库,任务数[" + taskReelCount + "]出库位置仓位【" + pos.getPosName() + "】RI=[" + pos.getBarcode().getBarcode() + "]已在操作队列中,跳过不处理");
break;
if (isGuizhong || needJieliao) {
//一盘是否满足
if (pos.getBarcode().getAmount() > targetNum) {
tempPos = pos;
} else if (pos.getBarcode().getAmount() == targetNum) {
//一盘刚好满足
targetNum = 0;
itemPosList.add(pos);
itemPosNameList.add(pos.getPosName());
break;
} else {
//数量不满足,如果暂存有料,使用暂存物料,一盘料满足
if (tempPos != null) {
itemPosList.add(tempPos);
itemPosNameList.add(tempPos.getPosName());
targetNum -= tempPos.getBarcode().getAmount();
//截料的数量
if (targetNum < 0) {
jieliaoPosMap.put(tempPos.getPosName(), targetNum);
}
} else {
//一盘料不足,直接加入
itemPosList.add(pos);
itemPosNameList.add(pos.getPosName());
targetNum -= pos.getBarcode().getAmount();
if (targetNum < 0) {
jieliaoPosMap.put(tempPos.getPosName(), targetNum);
}
}
}else{
//PN
pos=storagePosManager.findPartNumberInStorages(availableStorageIds, partNumber, excludePosIds, checkoutType);
}
if (pos == null) {
// log.error("未找到可以出库的物料[" + partNumber + "]");
break;
} else if (wholeReelCount > 0) {
boolean isWholeReel = pos.getBarcode().getAmount() >= component.getAmount();
if (needWholeReelCount > 0) {
//判断数量,先出整盘料
if (pos.getBarcode().getAmount() >= targetNum) {
if (isWholeReel) {
needWholeReelCount--;
}
itemPosList.add(pos);
itemPosNameList.add(pos.getPosName());
targetNum -= pos.getBarcode().getAmount();
}
} else {
assignNum = assignNum + pos.getBarcode().getAmount();
taskReelCount = taskReelCount + 1;
log.info("工单[" + orderNo + "],任务数[" + taskReelCount + "]出库位置仓位【" + pos.getPosName() + "】RI=[" + pos.getBarcode().getBarcode() + "] PN=[" + partNumber + "] num:" + pos.getBarcode().getAmount());
DataLog task = newTask(pos) ;
task.setSourceId(cacheOrder.getId());
task.setSourceName(cacheOrder.getOrderNo());
task.setSubSourceId(orderItem.getId());
task.setSubSourceInfo(orderItem.getStation());
task.setType(OP.CHECKOUT);
task.setLightColor(nextColor.getRgb());
task.setStatus(OP_STATUS.WAIT.name());
// task = dataLogDao.save(task);
taskService.addTaskToExecute(task);
//整盘已出完
if (!isWholeReel) {
itemPosList.add(pos);
itemPosNameList.add(pos.getPosName());
targetNum -= pos.getBarcode().getAmount();
}
}
} else {
//不需要截料,也不按照整盘比,直接数量最大的发料
itemPosList.add(pos);
itemPosNameList.add(pos.getPosName());
targetNum -= pos.getBarcode().getAmount();
}
if (targetNum <= 0) {
break;
}
}
//第一轮循环完,判断是否需要再次循环
if (targetNum > 0 && wholeReelCount > 0) {
//如果是散盘料不足,需要再次循环
for (StoragePos pos :
posList) {
//已经在出库列表
if (itemPosNameList.contains(pos.getPosName())) {
continue;
}
//如果是RI出库,只有一盘,出完就结束
if(cacheOrder.getType()==2){
itemPosList.add(pos);
itemPosNameList.add(pos.getPosName());
targetNum -= pos.getBarcode().getAmount();
if (targetNum <= 0) {
break;
}
}
}
//判断数量是否满足
if (targetNum > 0) {
int outNum = needNum - targetNum;
if (outNum < orderItem.getQty()) {
//不满足实际需求,不发,报缺料
log.info("工单[" + cacheOrder.getOrderNo() + "] 物料号[" + pn + "] ,需求数量[" + orderItem.getWemng() + "], 库存可发数量[" + outNum + "], 不满足实际需求,缺料 ");
return "smfcore.order.out.short";
}
}
//可以出库
needOutPosMap.put(pn, itemPosList);
}
log.info("开始执行工单[" + orderNo + "] ");
cacheOrder.setTaskReelCount(0);
cacheOrder.setTaskFinishedTime(-1);
cacheOrder.setFinishedReelCount(0);
cacheOrder.setStatus(LITEORDER_STATUS.TAILS);
//设置出库操作人
cacheOrder.setOperateUser(userName);
cacheOrder.setStartDate(new Date());
int taskReelCount = 0;
//物料筛选完成,开始生成出库任务
for (LiteOrderItem orderItem : cacheOrder.getOrderItems()) {
int itemReelCount=0;
int itemOutCount=0;
List<StoragePos> posList=needOutPosMap.get(orderItem.getMaterialNo());
for (StoragePos pos :
posList) {
DataLog task = newTask(pos) ;
task.setSourceId(cacheOrder.getId());
task.setSourceName(cacheOrder.getOrderNo());
task.setSubSourceId(orderItem.getId());
task.setSubSourceInfo(orderItem.getStation());
task.setType(OP.CHECKOUT);
task.setLightColor(nextColor.getRgb());
task.setStatus(OP_STATUS.WAIT.name());
if(itemReelCount==0){
task.setFirstReel(true);
task.setLightColor(ORDER_COLOR.CYAN.getRgb());//首盘料 颜色:CYAN
}
else if(jieliaoPosMap.containsKey(pos.getPosName())){
//需要截料
int count=jieliaoPosMap.get(pos.getPosName());
task.setNeedSplitting(true);
task.setNeedQty(count);
task.setLightColor(ORDER_COLOR.PURPLE.getRgb());//截料料 颜色:PURPLE
}else{
task.setLightColor(ORDER_COLOR.SKYBLUE.getRgb());//普通工单 颜色:SKYBLUE
}
taskService.addTaskToExecute(task);
log.info("工单[" + orderNo + "],任务数[" + taskReelCount + "]仓位【" + pos.getPosName() + "】RI=[" + pos.getBarcode().getBarcode() + "] PN=[" + orderItem.getMaterialNo() + "] Amount[" + pos.getBarcode().getAmount()+
"] 首盘["+task.isFirstReel()+"] 截料["+task.isNeedSplitting()+"]["+task.getNeedQty()+"]");
taskReelCount++;
itemReelCount++;
itemOutCount+=pos.getBarcode().getAmount();
}
orderItem.setTotalOutReelCount(orderItem.getTotalOutReelCount()+itemReelCount);
orderItem.setTotalOutNum(orderItem.getTotalOutNum()+itemOutCount);
orderItem.setOutReelCount(itemReelCount);
orderItem.setOutNum(itemOutCount);
liteOrderItemManager.save(orderItem);
}
cacheOrder.setTaskReelCount(taskReelCount);
cacheOrder.setTaskReelCount(taskReelCount);
cacheOrder.setTotalTaskReelCount(cacheOrder.getTotalTaskReelCount()+taskReelCount);
......@@ -433,7 +748,6 @@ public class LiteOrderCache implements ITaskListener {
}
liteOrderManager.save(cacheOrder);
liteOrderMap.put(cacheOrder.getOrderNo(), cacheOrder);
if (taskReelCount <= 0) {
//return "工单无可执行的任务";
......@@ -441,6 +755,142 @@ public class LiteOrderCache implements ITaskListener {
}
return "";
}
// /**
// * 锁定物料
// */
// public synchronized String checkOutLiteOrder(String userName, String orderNo, boolean outBom) {
// LiteOrder cacheOrder = liteOrderMap.get(orderNo);
//
// if (cacheOrder == null) {
// cacheOrder = liteOrderManager.findByOrderNo(orderNo);
// }
//
// if (cacheOrder == null) {
// return "smfcore.order.out.notFound";
// }
//
// if ( !cacheOrder.isTaskFinished() && !cacheOrder.isNew()) {
// log.info("工单[" + orderNo + "]正在执行");
// return "smfcore.order.out.executing";
// }
// if(cacheOrder.isClosed()) {
// log.info("工单[" + orderNo + "]已关闭,无法出库");
// return "smfcore.order.hasClose";
// }
//
// updateOrderFromApi(userName,cacheOrder);
// //如果更新完工单已关闭,直接提示
// if(cacheOrder.isClosed()) {
// log.info("工单[" + orderNo + "]已关闭,无法出库");
// return "smfcore.order.hasClose";
// }
//
// ORDER_COLOR nextColor = getNextColor();
// if (nextColor == null) {
// log.info("执行工单[" + orderNo + "] outBom=" + outBom + "时,已达最大可执行工单数");
// return "smfcore.order.out.maxOrder";
// }
//
// //先查找是否已经锁定过库位,如果已经锁定过,出锁定的库位
// List<StoragePos> lockPosList = storagePosManager.findLockPos(cacheOrder.getOrderNo());
// if(lockPosList!=null&& lockPosList.size()>0){
// return checkOutOrder(cacheOrder).getMsgKey();
// }
//
// log.info("开始执行工单[" + orderNo + "] outBom=" + outBom);
// cacheOrder.setTaskReelCount(0);
// cacheOrder.setTaskFinishedTime(-1);
// cacheOrder.setFinishedReelCount(0);
// if (outBom) {
// cacheOrder.setStatus(LITEORDER_STATUS.BOM);
// } else {
// cacheOrder.setStatus(LITEORDER_STATUS.TAILS);
// }
// //liteOrderMap.put(cacheOrder.getOrderNo(), cacheOrder);
// int taskReelCount = 0;
// CHECKOUT_TYPE checkoutType = dataCache.getCheckOutType();
// List<String> availableStorageIds = dataCache.getAvailableStorageIds();
//
//
// //其他出库模式一次性全部生成任务
// for (LiteOrderItem orderItem : cacheOrder.getOrderItems()) {
// orderItem.setOutNum(0);
// orderItem.setOutReelCount(0);
// liteOrderItemManager.save(orderItem);
// //剩余未出数量
// Float totalNum = orderItem.getQty() * cacheOrder.getOrderTimes();
//
// int remainNum = totalNum.intValue() - orderItem.getOutNum();
//
// //此PN未完成
// if (remainNum > 0) {
// if (outBom) {
// //套料出库,设置剩余数量为1,这样就只会出一盘
// remainNum = 1;
// }
// int assignNum = 0;
// while (assignNum < remainNum) {
// Collection<String> excludePosIds = excludePosIds();
// String partNumber = orderItem.getMaterialNo();
//
// StoragePos pos = null;
// if(cacheOrder.getType()==2){
// //RI
// pos=storagePosManager.getByBarcode(orderItem.getRi());
// if(excludePosIds.contains(pos.getId())) {
// log.info("工单[" + orderNo + "]RI出库,任务数[" + taskReelCount + "]出库位置仓位【" + pos.getPosName() + "】RI=[" + pos.getBarcode().getBarcode() + "]已在操作队列中,跳过不处理");
// break;
// }
// }else{
// //PN
// pos=storagePosManager.findPartNumberInStorages(availableStorageIds, partNumber, excludePosIds, checkoutType);
// }
// if (pos == null) {
//// log.error("未找到可以出库的物料[" + partNumber + "]");
// break;
// } else {
// assignNum = assignNum + pos.getBarcode().getAmount();
// taskReelCount = taskReelCount + 1;
// log.info("工单[" + orderNo + "],任务数[" + taskReelCount + "]出库位置仓位【" + pos.getPosName() + "】RI=[" + pos.getBarcode().getBarcode() + "] PN=[" + partNumber + "] num:" + pos.getBarcode().getAmount());
// DataLog task = newTask(pos) ;
//
// task.setSourceId(cacheOrder.getId());
// task.setSourceName(cacheOrder.getOrderNo());
// task.setSubSourceId(orderItem.getId());
// task.setSubSourceInfo(orderItem.getStation());
// task.setType(OP.CHECKOUT);
// task.setLightColor(nextColor.getRgb());
// task.setStatus(OP_STATUS.WAIT.name());
//// task = dataLogDao.save(task);
// taskService.addTaskToExecute(task);
// }
// //如果是RI出库,只有一盘,出完就结束
// if(cacheOrder.getType()==2){
// break;
// }
// }
// }
//
// }
//
// cacheOrder.setTaskReelCount(taskReelCount);
// cacheOrder.setTotalTaskReelCount(cacheOrder.getTotalTaskReelCount()+taskReelCount);
// log.info("工单[" + orderNo + "]任务分配结束,任务数[" + taskReelCount + "]");
// //有需要出库的
// if (taskReelCount <= 0) {
// cacheOrder.finishedTasks();
// }
//
// liteOrderManager.save(cacheOrder);
//
// liteOrderMap.put(cacheOrder.getOrderNo(), cacheOrder);
// if (taskReelCount <= 0) {
// //return "工单无可执行的任务";
// return "smfcore.order.out.noTask";
// }
// return "";
// }
/**
* 防止仓位任务重复,需要排除掉已经分配掉的仓位
*/
......@@ -498,65 +948,65 @@ public class LiteOrderCache implements ITaskListener {
return "smfcore.order.close.success";
}
/**
* 工单详情补料出库
* @param orderNo
* @param orderItemId
* @return
*/
public String orderItemSupplementOut(String orderNo, String orderItemId) {
LiteOrder cacheOrder = liteOrderMap.get(orderNo);
if (cacheOrder == null) {
cacheOrder=liteOrderManager.findByOrderNo(orderNo);
if(cacheOrder==null){
return "smfcore.order.out.notFound";
}
}
if(cacheOrder.isClosed()){
return "smfcore.order.hasClose";
}
for (LiteOrderItem orderItem:cacheOrder.getOrderItems()
) {
if(orderItem.getId().equals(orderItemId)){
CHECKOUT_TYPE checkoutType = dataCache.getCheckOutType();
List<String> availableStorageIds = dataCache.getAvailableStorageIds();
Collection<String> excludePosIds = excludePosIds();
String partNumber = orderItem.getMaterialNo();
StoragePos pos = null;
if(cacheOrder.getType()==2){
//RI
pos=storagePosManager.getByBarcode(orderItem.getRi());
if(excludePosIds.contains(pos.getId())) {
log.info("工单[" + orderNo + "]RI出库,仓位【" + pos.getPosName() + "】RI=[" + pos.getBarcode().getBarcode() + "]已在操作队列中,跳过不处理");
}
}else {
//PN
pos = storagePosManager.findPartNumberInStorages(availableStorageIds, partNumber, excludePosIds, checkoutType);
}
if (pos == null) {
return "smfcore.order.supplementOutFail";
} else {
log.info("工单[" + orderNo + "]["+partNumber+"]补料出库:仓位[" + pos.getPosName() + "]RI=[" + pos.getBarcode().getBarcode() + "] PN=[" + partNumber + "] num:" + pos.getBarcode().getAmount());
DataLog task = newTask(pos) ;
task.setSourceId(cacheOrder.getId());
task.setSourceName(cacheOrder.getOrderNo());
task.setSubSourceId(orderItem.getId());
task.setSubSourceInfo(orderItem.getStation());
task.setType(OP.CHECKOUT);
// task.setLightColor(nextColor.getRgb());
task.setStatus(OP_STATUS.WAIT.name());
// task = dataLogDao.save(task);
taskService.addTaskToExecute(task);
return "";
}
}
}
return "smfcore.order.supplementOutFail";
}
// /**
// * 工单详情补料出库
// * @param orderNo
// * @param orderItemId
// * @return
// */
// public String orderItemSupplementOut(String orderNo, String orderItemId) {
// LiteOrder cacheOrder = liteOrderMap.get(orderNo);
// if (cacheOrder == null) {
// cacheOrder=liteOrderManager.findByOrderNo(orderNo);
// if(cacheOrder==null){
// return "smfcore.order.out.notFound";
// }
// }
// if(cacheOrder.isClosed()){
// return "smfcore.order.hasClose";
// }
//
// for (LiteOrderItem orderItem:cacheOrder.getOrderItems()
// ) {
// if(orderItem.getId().equals(orderItemId)){
// CHECKOUT_TYPE checkoutType = dataCache.getCheckOutType();
// List<String> availableStorageIds = dataCache.getAvailableStorageIds();
// Collection<String> excludePosIds = excludePosIds();
//
// String partNumber = orderItem.getMaterialNo();
// StoragePos pos = null;
// if(cacheOrder.getType()==2){
// //RI
// pos=storagePosManager.getByBarcode(orderItem.getRi());
// if(excludePosIds.contains(pos.getId())) {
// log.info("工单[" + orderNo + "]RI出库,仓位【" + pos.getPosName() + "】RI=[" + pos.getBarcode().getBarcode() + "]已在操作队列中,跳过不处理");
// }
// }else {
// //PN
// pos = storagePosManager.findPartNumberInStorages(availableStorageIds, partNumber, excludePosIds, checkoutType);
// }
// if (pos == null) {
// return "smfcore.order.supplementOutFail";
// } else {
// log.info("工单[" + orderNo + "]["+partNumber+"]补料出库:仓位[" + pos.getPosName() + "]RI=[" + pos.getBarcode().getBarcode() + "] PN=[" + partNumber + "] num:" + pos.getBarcode().getAmount());
// DataLog task = newTask(pos) ;
//
// task.setSourceId(cacheOrder.getId());
// task.setSourceName(cacheOrder.getOrderNo());
// task.setSubSourceId(orderItem.getId());
// task.setSubSourceInfo(orderItem.getStation());
// task.setType(OP.CHECKOUT);
//// task.setLightColor(nextColor.getRgb());
// task.setStatus(OP_STATUS.WAIT.name());
//// task = dataLogDao.save(task);
// taskService.addTaskToExecute(task);
//
// return "";
// }
// }
// }
// return "smfcore.order.supplementOutFail";
// }
public LiteOrder getOrderSortItems(String sourceId) {
LiteOrder order = liteOrderManager.findByOrderNo(sourceId);
......
......@@ -7,6 +7,7 @@ import com.neotel.smfcore.common.bean.PageData;
import com.neotel.smfcore.common.bean.ResultBean;
import com.neotel.smfcore.common.exception.ValidateException;
import com.neotel.smfcore.common.utils.*;
import com.neotel.smfcore.core.device.util.DataCache;
import com.neotel.smfcore.core.order.LiteOrderCache;
import com.neotel.smfcore.core.order.enums.LITEORDER_STATUS;
import com.neotel.smfcore.core.order.rest.bean.dto.OrderDto;
......@@ -18,43 +19,31 @@ 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.order.util.OrderFileWatch;
import com.neotel.smfcore.core.storage.service.po.Storage;
import com.neotel.smfcore.core.storage.service.po.StoragePos;
import com.neotel.smfcore.core.system.bean.OrderSetting;
import com.neotel.smfcore.core.system.rest.bean.dto.TaskDto;
import com.neotel.smfcore.core.system.rest.bean.mapstruct.TaskMapper;
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.bean.FileProperties;
import com.neotel.smfcore.security.rest.bean.vo.UserPassVo;
import com.neotel.smfcore.security.service.manager.IGroupManager;
import com.neotel.smfcore.security.service.manager.IRoleManager;
import com.neotel.smfcore.security.service.manager.IUserManager;
import com.neotel.smfcore.security.service.po.Group;
import com.neotel.smfcore.security.service.po.Role;
import com.neotel.smfcore.security.service.po.User;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import javafx.concurrent.Task;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;
......@@ -92,6 +81,15 @@ public class OrderController {
@Autowired
private OrderFileWatch orderFileWatch;
@Autowired
private DataCache dataCache;
@Autowired
private TaskService taskService;
@Autowired
private TaskMapper taskMapper;
// @ApiOperation("导出用户数据")
// @GetMapping(value = "/download")
// @PreAuthorize("@el.check('user:list')")
......@@ -109,10 +107,10 @@ public class OrderController {
if (!user.getIsAdmin()) {
Set<String> groupIds = user.getGroups();
List<String> excludeSources = Lists.newArrayList();
List<Group> groups=groupManager.findAll();
List<Group> groups = groupManager.findAll();
for (Group group :
groups) {
if(groupIds.contains(group.getId())){
if (groupIds.contains(group.getId())) {
continue;
}
excludeSources.add(group.getGroupName());
......@@ -134,13 +132,10 @@ public class OrderController {
}
}
PageData<LiteOrder> orderList = liteOrderManager.findByPage(query, pageable);
PageData<OrderDto> resultList=orderMapper.toDto(orderList);
PageData<OrderDto> resultList = orderMapper.toDto(orderList);
return resultList;
}
//
@ApiOperation("工单详情")
@GetMapping("/detial")
@PreAuthorize("@el.check('workOrder:detial')")
......@@ -150,14 +145,14 @@ public class OrderController {
if (!ObjectUtils.isEmpty(id)) {
LiteOrder liteOrder = liteOrderManager.get(id);
if (liteOrder != null) {
OrderDto dto= orderMapper.toDto(liteOrder);
OrderDto dto = orderMapper.toDto(liteOrder);
dto.setOrderItems(orderItemMapper.toDto(liteOrder.getOrderItems()));
return dto;
}
} else if (!ObjectUtils.isEmpty(orderNo)) {
LiteOrder liteOrder = liteOrderManager.findByOrderNo(orderNo);
if (liteOrder != null) {
OrderDto dto= orderMapper.toDto(liteOrder);
OrderDto dto = orderMapper.toDto(liteOrder);
dto.setOrderItems(orderItemMapper.toDto(liteOrder.getOrderItems()));
return dto;
}
......@@ -173,20 +168,20 @@ public class OrderController {
String image = "csv";
String fileType = FileUtil.getExtensionName(orderFile.getOriginalFilename());
String fileName= FileUtil.getFileNameNoEx(orderFile.getOriginalFilename());
String fileName = FileUtil.getFileNameNoEx(orderFile.getOriginalFilename());
if (fileType != null && !image.contains(fileType)) {
throw new ValidateException("smfcore.feleFormatError", "文件格式错误!, 仅支持{0}格式", new String[]{image});
}
File folder = new File(properties.getPath(), "pos");
File localFile = FileUtil.upload(orderFile, folder.getAbsolutePath());
Map<String, List<LiteOrderItem>> itemMap = orderFileWatch.readCsvFile(fileName,localFile.getAbsolutePath());
Map<String, List<LiteOrderItem>> itemMap = orderFileWatch.readCsvFile(fileName, localFile.getAbsolutePath());
if (itemMap == null || itemMap.size() <= 0) {
throw new ValidateException("smfcore.fileError", "文件解析失败");
}
for (String so:itemMap.keySet()
) {
for (String so : itemMap.keySet()
) {
List<LiteOrderItem> liteOrderItems = itemMap.get(so);
if (liteOrderItems.size() <= 0) {
......@@ -213,7 +208,7 @@ public class OrderController {
liteOrderCache.addOrderToMap(liteOrder);
}
return ResultBean.newOkResult("smfcore.order.uploadOK","工单上传成功","");
return ResultBean.newOkResult("smfcore.order.uploadOK", "工单上传成功", "");
}
@ApiOperation("工单出库")
......@@ -228,135 +223,222 @@ public class OrderController {
if (liteOrder == null) {
throw new ValidateException("smfcore.valueNotFind", "未找到{0}[{1}]", new String[]{"orderNo", orderNo});
}
String result= liteOrderCache.checkOutLiteOrder(liteOrder.getOrderNo(),false);
if(ObjectUtil.isEmpty(result)){
String result = liteOrderCache.checkOutLiteOrder(SecurityUtils.getCurrentUsername(), liteOrder.getOrderNo());
if (ObjectUtil.isEmpty(result)) {
return ResultBean.newOkResult(result);
}else{
return ResultBean.newErrorResult(-1,result,result);
} else {
return ResultBean.newErrorResult(-1, result, result);
}
}
@ApiOperation("套料出库")
@PostMapping(value = "/outBom")
@ApiOperation("关闭工单")
@PostMapping(value = "/closeOrder")
@PreAuthorize("@el.check('workOrder')")
public ResultBean outBom(@RequestBody Map<String, String> mapValues) {
public ResultBean closeOrder(@RequestBody Map<String, String> mapValues) {
String orderNo = mapValues.get("orderNo");
if (orderNo == null) {
throw new ValidateException("smfcore.valueCanotNull", "{0}不能为空", new String[]{"orderNo"});
}
String result= liteOrderCache.checkOutLiteOrder(orderNo,true);
if(ObjectUtil.isEmpty(result)){
return ResultBean.newOkResult(result);
}else{
return ResultBean.newErrorResult(-1,result,result);
String result = liteOrderCache.closeOrder(orderNo);
if (ObjectUtil.isEmpty(result)) {
return ResultBean.newOkResult(result, result, result);
} else {
return ResultBean.newErrorResult(-1, result, result);
}
}
}
@ApiOperation("尾料出库")
@PostMapping(value = "/outTails")
@ApiOperation("修改工单线别")
@PostMapping(value = "/updateLine")
@PreAuthorize("@el.check('workOrder')")
public ResultBean outTails(@RequestBody Map<String, String> mapValues) {
String orderNo = mapValues.get("orderNo");
if (orderNo == null) {
public ResultBean updateLine(@RequestBody OrderDto param) {
if (param.getId() == null) {
throw new ValidateException("smfcore.valueCanotNull", "{0}不能为空", new String[]{"orderNo"});
}
if (param.getWorkLine() == null) {
throw new ValidateException("smfcore.order.lineCanotNull", "线别不能为空");
}
String result= liteOrderCache.checkOutLiteOrder(orderNo,false);
if(ObjectUtil.isEmpty(result)){
return ResultBean.newOkResult(result);
}else{
return ResultBean.newErrorResult(-1,result,result);
LiteOrder order = liteOrderManager.get(param.getId());
if (order == null) {
throw new ValidateException("smfcore.valueCanotNull", "{0}不能为空", new String[]{"orderNo"});
}
if (!order.isNew()) {
throw new ValidateException("smfcore.order.cannotUpdateLine", "工单已出库,不能修改线别");
}
order.setWorkLine(param.getWorkLine());
liteOrderManager.save(order);
liteOrderCache.addOrderToMap(order);
return ResultBean.newOkResult(orderMapper.toDto(order));
}
@ApiOperation("补料出库")
@PostMapping(value = "/supplementOut")
@PreAuthorize("@el.check('workOrder')")
public ResultBean supplementOut(@RequestBody Map<String, String> mapValues) {
String orderNo = mapValues.get("orderNo");
String orderItemId = mapValues.get("orderItemId");
if (orderNo == null) {
throw new ValidateException("smfcore.valueCanotNull", "{0}不能为空", new String[]{"orderNo"});
@ApiOperation("料盘出库界面,获取执行的工单列表")
@GetMapping("/executeOrders")
@PreAuthorize("@el.check('reelOut')")
public List<OrderDto> queryExecuteOrder() {
User user = userManager.findByUserName(SecurityUtils.getCurrentUsername());
//查询正在执行的工单列表
Query query = new Query(Criteria.where("status").ne(LITEORDER_STATUS.CLOSED).ne(LITEORDER_STATUS.NEW));
//根据开始出库时间排序
Sort sort = Sort.by(Sort.Direction.ASC, "startOutTime");
query.with(sort);
List<LiteOrder> orderList = liteOrderManager.findByQuery(query);
List<OrderDto> resultList = orderMapper.toDto(orderList);
boolean findOrder = false;
//只返回当前有任务的工单
for (LiteOrder order :
orderList) {
List<DataLog> tasks = getOrderTaskByUser(user, order, true);
if (tasks.size() > 0) {
OrderDto dto = orderMapper.toDto(order);
dto.setTaskCount(tasks.size());
if (ObjectUtil.isNotEmpty(user.getCurrOrderNo())) {
if (order.getOrderNo().equals(user.getCurrOrderNo()))
findOrder = true;
dto.setInOperate(true);
}
resultList.add(dto);
}
}
String result= liteOrderCache.orderItemSupplementOut(orderNo,orderItemId);
if(ObjectUtil.isEmpty(result)){
return ResultBean.newOkResult(result);
}else{
return ResultBean.newErrorResult(-1,result,result);
if (ObjectUtil.isNotEmpty(user.getCurrOrderNo())) {
if (!findOrder) {
log.info("用户[" + user.getUsername() + "] 当前工单 [" + user.getCurrOrderNo() + "] 已不在出库工单列表中,清理当前工单,更新用户信息");
user.setCurrOrderNo("");
userManager.save(user);
}
}
return resultList;
}
@ApiOperation("料盘出库界面,获取当前工单任务列表")
@GetMapping("/reelOutTasks")
@PreAuthorize("@el.check('reelOut')")
public List<TaskDto> queryReelOutTasks(@RequestParam Map<String, String> paramsMap) {
@ApiOperation("修改工单数量")
@PostMapping(value = "/updateNum")
@PreAuthorize("@el.check('workOrder')")
public ResultBean updateNum(@RequestBody OrderDto param) {
String orderNo = param.getOrderNo();
float orderTimes= param.getOrderTimes();
if (orderNo == null) {
// throw new ValidateException("工单号不能为空");
throw new ValidateException("smfcore.valueCanotNull", "{0}不能为空", new String[]{"orderNo"});
//查询正在执行的工单列表
User user = userManager.findByUserName(SecurityUtils.getCurrentUsername());
String orderNo = user.getCurrOrderNo();
if (ObjectUtil.isEmpty(orderNo)) {
return new ArrayList<>();
}
LiteOrder liteOrder = liteOrderManager.findByOrderNo(orderNo);
if (liteOrder == null) {
throw new ValidateException("smfcore.valueNotFind", "未找到{0}[{1}]", new String[]{"orderNo", orderNo});
}
if(!liteOrder.isNew()){
throw new ValidateException("smfcore.cannotUpdateOrderNum", "工单已出库,不能修改数量" );
}
if(orderTimes<1){
orderTimes=1;
if (liteOrder.isNew() || liteOrder.isClosed()) {
throw new ValidateException("smfcore.order.notExecute", "工单[{0}]不在出库中", new String[]{liteOrder.getOrderNo()});
}
liteOrder.setOrderTimes(orderTimes);
liteOrderManager.save(liteOrder );
liteOrderCache.addOrderToMap(liteOrder);
return ResultBean.newOkResult(orderMapper.toDto(liteOrder) );
List<DataLog> taskList = getOrderTaskByUser(user, liteOrder, false);
return taskMapper.toDto(taskList);
}
@ApiOperation("关闭工单")
@PostMapping(value = "/closeOrder")
@PreAuthorize("@el.check('workOrder')")
public ResultBean closeOrder(@RequestBody Map<String, String> mapValues) {
String orderNo = mapValues.get("orderNo");
if (orderNo == null) {
throw new ValidateException("smfcore.valueCanotNull", "{0}不能为空", new String[]{"orderNo"});
@ApiOperation("料盘出库界面,切换到下一个工单")
@PostMapping("/nextOrder")
@PreAuthorize("@el.check('reelOut')")
public ResultBean nextOrder(@RequestParam Map<String, String> paramsMap) {
User user = userManager.findByUserName(SecurityUtils.getCurrentUsername());
if (ObjectUtil.isNotEmpty(user.getCurrOrderNo())) {
//判断上个工单是否已完成
LiteOrder preOrder = liteOrderCache.findOrderByNo(user.getCurrOrderNo());
List<DataLog> preTasks = getOrderTaskByUser(user, preOrder, true);
if (preTasks.size() > 0) {
return ResultBean.newErrorResult(-1, "smfcore.order.preNotEnd", "工单[" + preOrder + "]还有[" + preTasks.size() + "]个出库任务未结束",
new String[]{user.getCurrOrderNo(), preTasks.size() + ""});
}
}
String result=liteOrderCache.closeOrder(orderNo);
if(ObjectUtil.isEmpty(result)){
return ResultBean.newOkResult(result, result,result);
}else{
return ResultBean.newErrorResult(-1,result,result);
List<LiteOrder> orderList = getExecuteOrders(user);
if (orderList.size() <= 0) {
return ResultBean.newErrorResult(-1, "smfcore.order.noOrder", "暂无可操作性的工单");
}
LiteOrder liteOrder = orderList.get(0);
//设置此工单的任务可以发送给料架
List<DataLog> taskList = getOrderTaskByUser(user, liteOrder, true);
for (DataLog datalog :
taskList) {
datalog.setInOperate(true);
taskService.updateQueueTask(datalog);
}
user.setCurrOrderNo(liteOrder.getOrderNo());
userManager.save(user);
log.info("用户[" + user.getUsername() + "]切换到工单[" + liteOrder.getOrderNo() + "],共更新["+taskList.size()+"]个任务状态为操作中");
return ResultBean.newOkResult("smfcore.order.nextOk", "成功切换到下一个工单", "");
}
@ApiOperation("修改工单线别")
@PostMapping(value = "/updateLine")
@PreAuthorize("@el.check('workOrder')")
public ResultBean updateLine(@RequestBody OrderDto param) {
if (param.getId() == null) {
throw new ValidateException("smfcore.valueCanotNull", "{0}不能为空", new String[]{"orderNo"});
}
if (param.getWorkLine() == null) {
throw new ValidateException("smfcore.order.lineCanotNull", "线别不能为空");
private List<LiteOrder> getExecuteOrders(User user) {
//查询正在执行的工单列表
Query query = new Query(Criteria.where("status").ne(LITEORDER_STATUS.CLOSED).ne(LITEORDER_STATUS.NEW));
//根据开始出库时间排序
Sort sort = Sort.by(Sort.Direction.ASC, "startOutTime");
query.with(sort);
List<LiteOrder> orderList = liteOrderManager.findByQuery(query);
List<LiteOrder> returnList = new ArrayList<>();
//只返回当前有任务的工单
for (LiteOrder order :
orderList) {
List<DataLog> taskList = getOrderTaskByUser(user, order, true);
if (taskList.size() > 0) {
returnList.add(order);
}
}
return returnList;
}
LiteOrder order = liteOrderManager.get(param.getId());
if (order == null) {
throw new ValidateException("smfcore.valueCanotNull", "{0}不能为空", new String[]{"orderNo"});
private List<DataLog> getOrderTaskByUser(User user, LiteOrder liteOrder, boolean onlyNotEndTask) {
if (user == null || liteOrder == null) {
return new ArrayList<>();
}
if (liteOrder.isNew() || liteOrder.isClosed()) {
return new ArrayList<>();
}
//查询正在执行的工单列表
List<String> myStorageIds = new ArrayList<>();
if (user != null) {
for (String groupId :
user.getGroups()) {
List<String> storageIds = dataCache.getStorageIdsByGroupId(groupId, false);
myStorageIds.addAll(storageIds);
}
}
if (!order.isNew()) {
throw new ValidateException("smfcore.order.cannotUpdateLine", "工单已出库,不能修改线别");
List<DataLog> returnTasks = new ArrayList<>();
List<DataLog> allTasks = taskService.getAllTasks();
for (DataLog datalog :
allTasks) {
//是否需要判断任务是否已结束
if (onlyNotEndTask) {
if (datalog.isEnd() || datalog.isFinished() || datalog.isCancel()) {
continue;
}
}
if (datalog.isCheckOutTask() && datalog.getSourceId().equals(liteOrder.getId())) {
//判断是否再自己的权限范围内
if (myStorageIds.contains(datalog.getStorageId())) {
returnTasks.add(datalog);
}
}
}
order.setWorkLine(param.getWorkLine());
liteOrderManager.save(order);
liteOrderCache.addOrderToMap(order);
return ResultBean.newOkResult(orderMapper.toDto(order));
return returnTasks;
}
}
......@@ -93,6 +93,12 @@ public class OrderDto implements Serializable {
@ApiModelProperty("创建时间")
private Date createDate = new Date();
@ApiModelProperty("任务数")
private Integer taskCount;
@ApiModelProperty("是否是当前操作工单")
private boolean inOperate=false;
// @ApiModelProperty("建议出仓时间")
// private Date sdate=new Date();
......
......@@ -26,10 +26,13 @@ public class OrderItemDto {
@ApiModelProperty(value = "发料增量")
private Integer increment;
@ApiModelProperty(value = "排程数量")
private Integer wemng;
@ApiModelProperty(value = "移动原因")
private String reason;
@ApiModelProperty("需求盘数")
@ApiModelProperty("需求盘数")
private int needReelCount = 0;
@ApiModelProperty("已出数量")
......
......@@ -116,21 +116,26 @@ public class LiteOrder extends BasePo implements Serializable {
@Transient
private long taskFinishedTime = -1;
/**
* 套(倍)数
*/
private float orderTimes = 1f;
// /**
// * 套(倍)数
// */
// private float orderTimes = 1f;
/**
* 工单类型,默认1=PN,2=RI
*/
private int type=1;
/**
* 操作用户名
* 操作用户名:点击工单出库的用户名
*/
private String operateUser;
/**
* 开始出库的时间
*/
private Date startOutTime;
/**
* 订单的详细信息
*/
@Transient
......@@ -231,12 +236,12 @@ public class LiteOrder extends BasePo implements Serializable {
}
public float getOrderTimes() {
if(orderTimes == 0){
orderTimes = 1f;
}
return orderTimes;
}
// public float getOrderTimes() {
// if(orderTimes == 0){
// orderTimes = 1f;
// }
// return orderTimes;
// }
public Date getStartDate(){
if(startDate==null){
return getCreateDate();
......
......@@ -23,17 +23,17 @@ public class LiteOrderItem extends BasePo implements Serializable ,Comparable<Li
/**
*qty Integer true 需求数量
*/
private Integer qty;
private int qty=0;
/**
*overFlag Integer true 超发标识[贵重物料](1是不允许超发,0是允许超发)
*/
private Integer overFlag;
private int overFlag=0;
/**
*increment Integer true 发料增量
*/
private Integer increment;
private int increment=0;
/**
......@@ -41,6 +41,10 @@ public class LiteOrderItem extends BasePo implements Serializable ,Comparable<Li
*/
private String reason;
/**
*wemng Integer true 排程数量
*/
private int wemng=0;
//
/**
......@@ -98,6 +102,7 @@ public class LiteOrderItem extends BasePo implements Serializable ,Comparable<Li
setOverFlag(item.getOverFlag());
setQty(item.getQty());
setStation(item.getStation());
setWemng(item.getWemng());
}
......
......@@ -64,4 +64,6 @@ public interface IStoragePosManager extends IBaseManager<StoragePos> {
List<StoragePos> findPosList(String storageId, List<String> posNames);
List<StoragePos> getSameSizeContinuityEmptyPosList(Storage storage, Barcode barcode) throws ValidateException;
List<StoragePos> findOrderItemInStorage( List<String> storageIdList, String pn, Collection<String> excludePosIds );
}
......@@ -588,6 +588,28 @@ public class StoragePosManagerImpl implements IStoragePosManager {
return new ArrayList<>();
}
@Override
public List<StoragePos> findOrderItemInStorage(List<String> storageIdList,String pn, Collection<String> excludePosIds ) {
Criteria c = Criteria.where("barcode.partNumber").is(pn)
.and("id").nin(excludePosIds)
.and("enabled").is(true)//可用
.and("barcode.lockId").is(null)//没有被锁定的仓位;
.and("barcode.lockMsl").is(false);//湿敏超期物料所在仓位锁定, 不允许备料
if (storageIdList != null) {
c = c.and("storageId").in(storageIdList);
}
Query q = new Query(c);
//数量从大到小,出库先进先出
Sort sort = Sort.by(Sort.Direction.DESC, "barcode.amount");
sort.and(Sort.by(Sort.Direction.ASC, "canCheckOutTime"));
q.with(sort);
List<StoragePos> posList = storagePosDao.findByQuery(q);
if (posList == null || posList.size() <= 0) {
log.info("findOrderItemInStorage 挑料 partNumber=" + pn + ",未找到可以出库的物料 ");
}
return posList;
}
/**
* 获取下一库位的库位名(后缀数字+1)
*/
......
......@@ -221,6 +221,27 @@ public class DataLog extends BasePo implements Serializable {
* 库位
*/
private String lgort;
/**
* 是否是需要截料物料
*/
private boolean needSplitting=false;
/**
* 截料的物料此次出库需要的数量
*/
private Integer needQty;
/**
* 是否是首盘料
*/
private boolean firstReel=false;
/**
* 工单出料,需要手动切换到工单后任务才能发给料架
*/
private boolean inOperate=false;
/**
* MSD附加信息
*/
......
......@@ -128,13 +128,13 @@ public class HikApi {
RequestParam info = new RequestParam(getReqCode(), userName, data);
HikApiRequest request = new HikApiRequest(1, url, new Date(), info);
log.info("Hik 转储单接口 (transferOrder): 发送" + data);
boolean needResend = false;
try {
ResponseParam responseInfo = HttpHelper.postJson(url, info);
boolean needResend = false;
if (responseInfo == null || responseInfo.getCode().equals(-1)) {
needResend = true;
log.info(apiName+"未收到返回值,需要重发");
// needResend = true;
log.info(apiName+"未收到反馈");
} else if (responseInfo.getCode().equals(CODE_PARAMERROR) || responseInfo.getCode().equals(CODE_REPEAT)) {
needResend = true;
......@@ -147,7 +147,9 @@ public class HikApi {
} catch (Exception e) {
log.error(apiName+" 出错", e);
}
HikApiCache.addFailedRequest(request);
if(needResend){
HikApiCache.addFailedRequest(request);
}
return null;
}
......@@ -174,13 +176,13 @@ public class HikApi {
RequestParam info = new RequestParam(getReqCode(), userName, data);
HikApiRequest request = new HikApiRequest(1, url, new Date(), info);
log.info(apiName+" 发送" + data);
boolean needResend = false;
try {
ResponseParam responseInfo = HttpHelper.postJson(url, info);
boolean needResend = false;
if (responseInfo == null || responseInfo.getCode().equals(-1)) {
needResend = true;
log.info(apiName+" 未收到返回值,需要重发");
// needResend = true;
log.info(apiName+"未收到反馈");
} else if (responseInfo.getCode().equals(CODE_PARAMERROR) || responseInfo.getCode().equals(CODE_REPEAT)) {
needResend = true;
......@@ -193,7 +195,9 @@ public class HikApi {
} catch (Exception e) {
log.error(apiName+"出错", e);
}
HikApiCache.addFailedRequest(request);
if(needResend){
HikApiCache.addFailedRequest(request);
}
return false;
}
/**
......@@ -230,13 +234,13 @@ public class HikApi {
RequestParam info = new RequestParam(getReqCode(), userName, data);
HikApiRequest request = new HikApiRequest(1, url, new Date(), info);
log.info(apiName+" 发送" + data);
boolean needResend = false;
try {
ResponseParam responseInfo = HttpHelper.postJson(url, info);
boolean needResend = false;
if (responseInfo == null || responseInfo.getCode().equals(-1)) {
needResend = true;
log.info(apiName+" 未收到返回值,需要重发");
// needResend = true;
log.info(apiName+"未收到反馈");
} else if (responseInfo.getCode().equals(CODE_PARAMERROR) || responseInfo.getCode().equals(CODE_REPEAT)) {
needResend = true;
......@@ -249,7 +253,9 @@ public class HikApi {
} catch (Exception e) {
log.error(apiName+"出错", e);
}
HikApiCache.addFailedRequest(request);
if(needResend){
HikApiCache.addFailedRequest(request);
}
return false;
}
......@@ -272,13 +278,13 @@ public class HikApi {
RequestParam info = new RequestParam(getReqCode(), userName, trayId);
HikApiRequest request = new HikApiRequest(1, url, new Date(), info);
log.info(apiName+" 发送" + info.getData());
boolean needResend = false;
try {
ResponseParam responseInfo = HttpHelper.postJson(url, info);
boolean needResend = false;
if (responseInfo == null || responseInfo.getCode().equals(-1)) {
needResend = true;
log.info(apiName+" 未收到返回值,需要重发");
// needResend = true;
log.info(apiName+"未收到反馈");
} else if (responseInfo.getCode().equals(CODE_PARAMERROR) || responseInfo.getCode().equals(CODE_REPEAT)) {
needResend = true;
......@@ -294,7 +300,9 @@ public class HikApi {
} catch (Exception e) {
log.error(apiName+"出错", e);
}
HikApiCache.addFailedRequest(request);
if(needResend){
HikApiCache.addFailedRequest(request);
}
return -1;
}
......@@ -345,13 +353,13 @@ public class HikApi {
RequestParam info = new RequestParam(getReqCode(), userName, data);
HikApiRequest request = new HikApiRequest(1, url, new Date(), info);
log.info(apiName+" 发送" + data);
boolean needResend = false;
try {
ResponseParam responseInfo = HttpHelper.postJson(url, info);
boolean needResend = false;
if (responseInfo == null || responseInfo.getCode().equals(-1)) {
needResend = true;
log.info(apiName+" 未收到返回值,需要重发");
// needResend = true;
log.info(apiName+"未收到反馈");
} else if (responseInfo.getCode().equals(CODE_PARAMERROR) || responseInfo.getCode().equals(CODE_REPEAT)) {
needResend = true;
......@@ -364,7 +372,9 @@ public class HikApi {
} catch (Exception e) {
log.error(apiName+"出错", e);
}
HikApiCache.addFailedRequest(request);
if(needResend){
HikApiCache.addFailedRequest(request);
}
return false;
}
......@@ -402,13 +412,13 @@ public class HikApi {
RequestParam info = new RequestParam(getReqCode(), userName, data);
HikApiRequest request = new HikApiRequest(1, url, new Date(), info);
log.info(apiName+" 发送" + data);
boolean needResend = false;
try {
ResponseParam responseInfo = HttpHelper.postJson(url, info);
boolean needResend = false;
if (responseInfo == null || responseInfo.getCode().equals(-1)) {
needResend = true;
log.info(apiName+" 未收到返回值,需要重发");
// needResend = true;
log.info(apiName+"未收到反馈");
} else if (responseInfo.getCode().equals(CODE_PARAMERROR) || responseInfo.getCode().equals(CODE_REPEAT)) {
needResend = true;
......@@ -421,7 +431,9 @@ public class HikApi {
} catch (Exception e) {
log.error(apiName+"出错", e);
}
HikApiCache.addFailedRequest(request);
if(needResend){
HikApiCache.addFailedRequest(request);
}
return false;
}
......@@ -432,6 +444,7 @@ public class HikApi {
* @return 保存下架过账信息 是否成功,true=成功
*/
public static List<Object> updateOrderApi(String userName, String orderNo){
boolean needResend = false;
String apiName="Hik 工单发料状态查询接口 (updateOrderApi): ";
String url = getUrl( "工单发料状态查询接口");
// data String 16 是 工单号/合单号
......@@ -441,11 +454,10 @@ public class HikApi {
log.info(apiName+" 发送" + info.getData());
try {
ResponseParam responseInfo = HttpHelper.postJson(url, info);
boolean needResend = false;
if (responseInfo == null || responseInfo.getCode().equals(-1)) {
needResend = true;
log.info(apiName+" 未收到返回值,需要重发");
// needResend = true;
log.info(apiName+"未收到反馈");
} else if (responseInfo.getCode().equals(CODE_PARAMERROR) || responseInfo.getCode().equals(CODE_REPEAT)) {
needResend = true;
......@@ -471,7 +483,9 @@ public class HikApi {
} catch (Exception e) {
log.error(apiName+"出错", e);
}
HikApiCache.addFailedRequest(request);
if(needResend){
HikApiCache.addFailedRequest(request);
}
return null;
}
......@@ -508,13 +522,13 @@ public class HikApi {
RequestParam info = new RequestParam(getReqCode(), userName, data);
HikApiRequest request = new HikApiRequest(1, url, new Date(), info);
log.info(apiName+" 发送" + info.getData());
boolean needResend = false;
try {
ResponseParam responseInfo = HttpHelper.postJson(url, info);
boolean needResend = false;
if (responseInfo == null || responseInfo.getCode().equals(-1)) {
needResend = true;
log.info(apiName+" 未收到返回值,需要重发");
// needResend = true;
log.info(apiName+"未收到反馈");
} else if (responseInfo.getCode().equals(CODE_PARAMERROR) || responseInfo.getCode().equals(CODE_REPEAT)) {
needResend = true;
......@@ -526,7 +540,9 @@ public class HikApi {
} catch (Exception e) {
log.error(apiName+"出错", e);
}
HikApiCache.addFailedRequest(request);
if(needResend){
HikApiCache.addFailedRequest(request);
}
return null;
}
......@@ -544,13 +560,13 @@ public class HikApi {
RequestParam info = new RequestParam(getReqCode(), userName, replenishmentNo);
HikApiRequest request = new HikApiRequest(1, url, new Date(), info);
log.info(apiName+" 发送" + info.getData());
boolean needResend = false;
try {
ResponseParam responseInfo = HttpHelper.postJson(url, info);
boolean needResend = false;
if (responseInfo == null || responseInfo.getCode().equals(-1)) {
needResend = true;
log.info(apiName+" 未收到返回值,需要重发");
// needResend = true;
log.info(apiName+"未收到反馈");
} else if (responseInfo.getCode().equals(CODE_PARAMERROR) || responseInfo.getCode().equals(CODE_REPEAT)) {
needResend = true;
......@@ -574,7 +590,9 @@ public class HikApi {
} catch (Exception e) {
log.error(apiName+"出错", e);
}
HikApiCache.addFailedRequest(request);
if(needResend){
HikApiCache.addFailedRequest(request);
}
return null;
}
......@@ -601,14 +619,13 @@ public class HikApi {
RequestParam info = new RequestParam(getReqCode(), userName, data);
HikApiRequest request = new HikApiRequest(1, url, new Date(), info);
log.info(apiName+" 发送" + info.getData());
boolean needResend = false;
try {
ResponseParam responseInfo = HttpHelper.postJson(url, info);
boolean needResend = false;
if (responseInfo == null || responseInfo.getCode().equals(-1)) {
needResend = true;
log.info(apiName+" 未收到返回值,需要重发");
// needResend = true;
log.info(apiName+"未收到反馈");
} else if (responseInfo.getCode().equals(CODE_PARAMERROR) || responseInfo.getCode().equals(CODE_REPEAT)) {
needResend = true;
log.info(apiName+"返回code=" + responseInfo.getCode() + ",需要重发," + JsonUtil.toJsonStr(responseInfo));
......@@ -622,7 +639,9 @@ public class HikApi {
} catch (Exception e) {
log.error(apiName+"出错", e);
}
HikApiCache.addFailedRequest(request);
if(needResend){
HikApiCache.addFailedRequest(request);
}
return null;
}
/**
......@@ -650,13 +669,13 @@ public class HikApi {
RequestParam info = new RequestParam(getReqCode(), userName, orderNo);
HikApiRequest request = new HikApiRequest(1, url, new Date(), info);
log.info(apiName+" 发送" + info.getData());
boolean needResend = false;
try {
ResponseParam responseInfo = HttpHelper.postJson(url, info);
boolean needResend = false;
if (responseInfo == null || responseInfo.getCode().equals(-1)) {
needResend = true;
log.info(apiName+" 未收到返回值,需要重发");
// needResend = true;
log.info(apiName+"未收到反馈");
} else if (responseInfo.getCode().equals(CODE_PARAMERROR) || responseInfo.getCode().equals(CODE_REPEAT)) {
needResend = true;
......@@ -669,7 +688,9 @@ public class HikApi {
} catch (Exception e) {
log.error(apiName+"出错", e);
}
HikApiCache.addFailedRequest(request);
if(needResend){
HikApiCache.addFailedRequest(request);
}
return false;
}
}
......@@ -11,10 +11,7 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
@Slf4j
......@@ -26,7 +23,7 @@ public class HikApiCache {
/**
* 需要重发的指令列表
*/
private static Map<String, HikApiRequest> failedRequestMap;
private static Map<String, HikApiRequest> failedRequestMap=new HashMap<>();
private static boolean isProcessTimer = false;
......
......@@ -90,6 +90,7 @@ public class HikOutInfo implements Serializable {
item.setOverFlag(this.getOverFlag());
item.setIncrement(this.getIncrement());
item.setReason(this.getReason());
item.setWemng(this.wemng);
return item;
}
......
......@@ -18,12 +18,12 @@ public class ResponseParam implements Serializable {
/**
* code 是 String 结果码:0-成功,1~N-失败
*/
private String code;
private String code="-1";
/**
* message 是 String 0:成功 1~N:失败原因
*/
private String message;
private String message="";
/**
*data 选填 Json 返回的数据结构
......
package com.neotel.smfcore.hikvision.util;
import cn.hutool.core.util.ObjectUtil;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.neotel.smfcore.common.exception.ApiException;
......@@ -468,7 +469,10 @@ public class HttpHelper {
throw new ApiException("Request [" + url + "] failed:" + e.getMessage());
}
}
public static ResponseParam postJson(String url, RequestParam requestInfo) throws ApiException {
public static ResponseParam postJson(String url, RequestParam requestInfo) throws ApiException {
if(ObjectUtil.isEmpty(url)){
return null;
}
Map<String, Object> params = new HashMap<>();
HashMap<String, String> cookies = null;
String protocol = "http";
......
......@@ -52,5 +52,8 @@ public class UserDto implements Serializable {
@ApiModelProperty("是否已进入调试模式")
private Boolean debugModel=false;
@ApiModelProperty("当前正在操作的工单号")
private String currOrderNo;
}
......@@ -35,7 +35,6 @@ import java.util.Set;
public class User extends BasePo implements Serializable {
private String username;
private String email;
......@@ -58,6 +57,11 @@ public class User extends BasePo implements Serializable {
private String checkCode;
/**
* 当前正在操作的工单号
*/
private String currOrderNo;
public boolean hasGroup(String groupId) {
if (groupId == null || groupId.equals("") || groupId.equals("-1")) {
......
支持 Markdown 格式
你添加了 0 到此讨论。请谨慎行事。
Finish editing this message first!