Commit e9e210c8 LN

看板修改。工单增加补料出库,线别修改,定时自动出库

1 个父辈 533db9b4
......@@ -41,13 +41,11 @@ public class DataInitManager {
IRoleManager roleManager;
@Autowired
IMenuManager menuManager;
// @Autowired
// IGroupManager groupManager;
@Autowired
TaskService taskService;
@Autowired
IDataLogManager dataLogManager;
MainTimer mainTimer;
@Autowired
PermissionInitUtil annotationUtil;
......@@ -101,7 +99,7 @@ public class DataInitManager {
}
}
initTask();
mainTimer.init();
allPermissionSet= annotationUtil.initPermission();
} catch (Exception exception) {
......@@ -109,20 +107,7 @@ public class DataInitManager {
}
}
private void initTask() {
log.info("开始加载未完成的任务...");
List<DataLog> unExecuteTasks = dataLogManager.findUnFinishedTasks();
for (DataLog unExecuteTask : unExecuteTasks) {
if (unExecuteTask.isExecuting() || unExecuteTask.isWait()) {
try {
taskService.addTaskToExecute(unExecuteTask);
}catch (Exception e){
log.error("初始化任务["+unExecuteTask+"]出错:"+e);
}
}
}
log.info("加载未完成的任务完成,共[" + unExecuteTasks.size() + "]条数据...");
}
private int sortValue=0;
......
package com.neotel.smfcore.common.init;
import com.neotel.smfcore.core.order.LiteOrderCache;
import com.neotel.smfcore.core.system.service.manager.IDataLogManager;
import com.neotel.smfcore.core.system.service.po.DataLog;
import com.neotel.smfcore.core.system.util.TaskService;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
@Service
public class MainTimer {
protected final transient Logger log = LogManager.getLogger(getClass());
ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(1);
@Autowired
TaskService taskService;
@Autowired
IDataLogManager dataLogManager;
@Autowired
LiteOrderCache liteOrderCache;
public void init(){
initTask();
liteOrderCache.loadUnEndOrderInfos();
log.info("主定时器开启,60秒后开始执行, 每10s执行一次");
//1 分钟之后执行,每秒钟执行一次
scheduledThreadPool.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
timerTask();
}
}, 60, 10, TimeUnit.SECONDS);
}
private void initTask() {
log.info("开始加载未完成的任务...");
List<DataLog> unExecuteTasks = dataLogManager.findUnFinishedTasks();
for (DataLog unExecuteTask : unExecuteTasks) {
if (unExecuteTask.isExecuting() || unExecuteTask.isWait()) {
try {
taskService.addTaskToExecute(unExecuteTask);
}catch (Exception e){
log.error("初始化任务["+unExecuteTask+"]出错:"+e);
}
}
}
log.info("加载未完成的任务完成,共[" + unExecuteTasks.size() + "]条数据...");
}
private void timerTask(){
try{
liteOrderCache.runTimer();
}catch (Exception e){
log.error("定时器执行出错",e);
}finally {
}
}
}
......@@ -527,4 +527,17 @@ public class DataCache {
}
return cidList;
}
public List<String> getAvailableStorageIds(){
List<String> availableStorageIds = new ArrayList<>();
for (Storage storage : getAllStorage().values()) {
//默认所有料仓可用
// StatusBean statusBean =dataCache. getStatus(storage.getCid());
// if (statusBean.isAvailable())
{
availableStorageIds.add(storage.getId());
}
}
return availableStorageIds;
}
}
......@@ -177,17 +177,26 @@ public class BoxKanbanController {
String[] blurrys = blurry.split(",");
String[] valueArray = new String[]{datalog.getPosName(), datalog.getStorageName(), datalog.getCid(), datalog.getPartNumber(), datalog.getBarcode(), datalog.getSourceName()};
for (String s : blurrys) {
for (String v :
valueArray) {
Pattern pattern = Pattern.compile(QueryHelp.escapeExprSpecialWord(s), Pattern.CASE_INSENSITIVE);
Matcher m = pattern.matcher(v);
while (m.find()) {
blurryOk = true;
break;
if(ObjectUtil.isNotEmpty(s)){
for (String v :
valueArray) {
try {
Pattern pattern = Pattern.compile(QueryHelp.escapeExprSpecialWord(s), Pattern.CASE_INSENSITIVE);
Matcher m = pattern.matcher(v);
while (m.find()) {
blurryOk = true;
break;
}
if (blurryOk) break;
}catch (Exception ex){
log.error(ex.toString());
}
}
if (blurryOk) break;
}
if (blurryOk) break;
else{
blurryOk=true;
}
}
......@@ -236,9 +245,9 @@ public class BoxKanbanController {
@ApiOperation("料仓详情")
@GetMapping("/boxView")
@PreAuthorize("@el.check('boxkanban:boxView')")
public BoxStatusDto boxView(String storageId) {
public BoxStatusDto boxView(String id) {
List<DataLog> allTasks=taskService.getAllTasks();
Storage storage=dataCache.getStorageById(storageId);
Storage storage=dataCache.getStorageById(id);
BoxStatusDto dto=getBoxDto(storage,allTasks);
return dto;
}
......
......@@ -29,13 +29,6 @@ public class BoxStatusDto {
@ApiModelProperty("是否在线")
private boolean onLine=false;
/// <summary>
/// 单台BOX状态
///1=正常运行中
/// 2=急停,3=故障,4=警告,5=调试中
/// 6入库执行中,7入仓位完成,8入库失败
/// 9出库执行中,10出仓位完成,11出库失败
/// </summary>
@ApiModelProperty("单台BOX状态,0=离线,1=正常运行中, 2=急停,3=故障,4=警告,5=调试中,6入库执行中,7入仓位完成,8入库失败, 9出库执行中,10出仓位完成,11出库失败")
private int status=0;
@ApiModelProperty("温度")
......@@ -56,10 +49,6 @@ public class BoxStatusDto {
@ApiModelProperty("当前执行任务的,0=无,1=入库,2=出库")
private int currTaskType=0;
/**
* 当前执行任务的 任务状态:OP_STATUS:NONE,WAIT=等待,EXECUTING=正在执行,PAUSE=已暂停,FINISHED=已完成,CANCEL=已取消,END=已结束
*/
@ApiModelProperty("当前执行任务的 任务状态:OP_STATUS:NONE,WAIT=等待,EXECUTING=正在执行,PAUSE=已暂停,FINISHED=已完成,CANCEL=已取消,END=已结束")
private String currTaskStatus;
......
......@@ -17,6 +17,10 @@ import java.util.Locale;
@Slf4j
public class MessageUtils {
public static Locale getDefaultLocal(){
return new Locale("zh-CH");
}
private static MessageSource messageSource;
public MessageUtils(MessageSource messageSource) {
......
package com.neotel.smfcore.core.order;
import cn.hutool.core.util.ObjectUtil;
import com.google.common.base.Strings;
import com.neotel.smfcore.common.bean.ResultBean;
import com.neotel.smfcore.common.exception.ValidateException;
......@@ -10,6 +11,7 @@ import com.neotel.smfcore.core.device.bean.StatusBean;
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;
......@@ -27,6 +29,7 @@ import com.neotel.smfcore.core.system.util.TaskService;
import javafx.concurrent.Task;
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.*;
......@@ -61,6 +64,52 @@ public class LiteOrderCache implements ITaskListener {
*/
public static Map<String, LiteOrder> liteOrderMap = new ConcurrentHashMap<>();
public void loadUnEndOrderInfos() {
log.info("开始加载未完成的需求单");
List<LiteOrder> unEndOutInfoList = liteOrderManager.findUnEndOrdersList();
long now = System.currentTimeMillis();
for (LiteOrder order : unEndOutInfoList) {
if (now - order.getCreateDate().getTime() > 7 * 24 * 60 * 60 * 1000) {
//7天前的需求单,关闭,并解绑
log.info("需求单 =[" + order.getOrderNo() + "]为7天前,关闭并解绑工单");
closeOrder(order.getOrderNo());
} else {
addOrderToMap(order);
}
}
}
public void addOrderToMap(LiteOrder order ){
if(order==null|| order.getOrderNo()==null){
return;
}
if(liteOrderMap.containsKey(order.getOrderNo())){
liteOrderMap.remove(order.getOrderNo());
}
liteOrderMap.put(order.getOrderNo(), order);
}
private boolean isProcessTimer = false;
public void runTimer(){
if(!isProcessTimer){
isProcessTimer = true;
try {
boolean stopJob = dataCache.getCache(Constants.CACHE_StopJob);
if(!stopJob){
//定时执行工单任务
executeOrderTask();
}
}catch (Exception e){
log.error("需求单定时器执行出错:",e);
}finally {
isProcessTimer = false;
}
}
}
@Override
public void onTaskStatusChange(DataLog task) {
try {
......@@ -74,13 +123,32 @@ public class LiteOrderCache implements ITaskListener {
}
}
public ResultBean checkOutOrder(LiteOrder liteOrder) throws ValidateException {
//设置颜色
Set<String> currentColors = new HashSet<>();
for (DataLog dataLog : taskService.getQueueTasks()) {
currentColors.add(dataLog.getLightColor());
public void executeOrderTask(){
for (LiteOrder order :
liteOrderMap.values()) {
if(order.isNew()||order.isTaskFinished()){
//判断是否到达时间
Date curr=new Date();
if(order.getSDate().before(curr)){
//开始自动出库
String result= checkOutLiteOrder(order.getOrderNo(),false);
if(!ObjectUtil.isEmpty(result)){
String msg= MessageUtils.getText(result,MessageUtils.getDefaultLocal(),"");
log.info("自动执行工单 【"+order.getOrderNo()+"】 失败:"+msg);
}else{
log.info("自动执行工单 【"+order.getOrderNo()+"】 成功");
}
break;
}
}
}
ORDER_COLOR nextColor = ORDER_COLOR.nextColor(currentColors);
}
public ResultBean checkOutOrder(LiteOrder liteOrder) throws ValidateException {
ORDER_COLOR nextColor = getNextColor();
if (nextColor == null) {
log.info("执行工单[" + liteOrder.getOrderNo() + "] 时,已达最大可执行工单数");
throw new ValidateException("order.out.maxOrder","已达最大可执行工单数");
......@@ -212,6 +280,15 @@ public class LiteOrderCache implements ITaskListener {
}
}
public ORDER_COLOR getNextColor() {
//设置颜色
Set<String> currentColors = new HashSet<>();
for (DataLog dataLog :taskService. getQueueTasks()) {
currentColors.add(dataLog.getLightColor());
}
ORDER_COLOR nextColor = ORDER_COLOR.nextColor(currentColors);
return nextColor;
}
/**
* 锁定物料
*/
......@@ -230,13 +307,7 @@ public class LiteOrderCache implements ITaskListener {
}
//设置颜色
Set<String> currentColors = new HashSet<>();
for (DataLog dataLog : taskService.getQueueTasks()) {
currentColors.add(dataLog.getLightColor());
}
ORDER_COLOR nextColor = ORDER_COLOR.nextColor(currentColors);
ORDER_COLOR nextColor = getNextColor();
if (nextColor == null) {
log.info("执行工单[" + orderNo + "] outBom=" + outBom + "时,已达最大可执行工单数");
return "smfcode.order.out.maxOrder";
......@@ -254,15 +325,7 @@ public class LiteOrderCache implements ITaskListener {
//liteOrderMap.put(cacheOrder.getOrderNo(), cacheOrder);
int taskReelCount = 0;
CHECKOUT_TYPE checkoutType = dataCache.getCheckOutType();
List<String> availableStorageIds = new ArrayList<>();
for (Storage storage : dataCache.getAllStorage().values()) {
//默认所有料仓可用
// StatusBean statusBean =dataCache. getStatus(storage.getCid());
// if (statusBean.isAvailable())
{
availableStorageIds.add(storage.getId());
}
}
List<String> availableStorageIds = dataCache.getAvailableStorageIds();
//其他出库模式一次性全部生成任务
......@@ -400,4 +463,54 @@ public class LiteOrderCache implements ITaskListener {
liteOrderManager.save(liteOrder);
return "smfcode.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 "smfcode.order.out.notFound";
}
}
if(cacheOrder.isClosed()){
return "smfcode.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.getPn();
StoragePos pos = storagePosManager.findPartNumberInStorages(availableStorageIds, partNumber, excludePosIds, checkoutType);
if (pos == null) {
return "smfcode.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.getFeederInfo());
task.setType(OP.CHECKOUT);
// task.setLightColor(nextColor.getRgb());
task.setStatus(OP_STATUS.WAIT.name());
// task = dataLogDao.save(task);
taskService.addTaskToExecute(task);
return "";
}
}
}
return "smfcode.order.supplementOutFail";
}
}
......@@ -22,6 +22,7 @@ import com.neotel.smfcore.core.order.service.po.LiteOrder;
import com.neotel.smfcore.core.order.service.po.LiteOrderItem;
import com.neotel.smfcore.core.storage.service.po.Storage;
import com.neotel.smfcore.core.storage.service.po.StoragePos;
import com.neotel.smfcore.core.system.rest.bean.dto.TaskDto;
import com.neotel.smfcore.core.system.rest.bean.mapstruct.TaskMapper;
import com.neotel.smfcore.security.annotation.AnonymousAccess;
import com.neotel.smfcore.security.bean.FileProperties;
......@@ -55,6 +56,7 @@ 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.*;
......@@ -134,21 +136,25 @@ public class OrderController {
liteOrder.setSource(localFile.getName());
liteOrder.setStatus(LITEORDER_STATUS.NEW);
LiteOrder dbOrder = liteOrderManager.findByOrderNo(liteOrder.getOrderNo());
if (dbOrder == null) {
log.info("新增加订单:" + liteOrder.getOrderNo() + ",共" + liteOrderItems.size() + "条工单详情");
liteOrder = liteOrderManager.createWithItems(liteOrder);
// TaskService.liteOrderMap.put(liteOrder.getOrderNo(), liteOrder);
} else {
log.info("数据库中已存在工单号为[" + liteOrder.getOrderNo() + "],忽略文件:" + localFile.getAbsolutePath());
// throw new ValidateException("smfcode.valueAlreadyExist", "{0}[{1}]已存在", new String[]{"orderNo", liteOrder.getOrderNo()});
// throw new ValidateException("工单号[" + liteOrder.getOrderNo() + "]已存在");
if (dbOrder != null) {
SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss");
//把名字改为带时间的
String newOrderNo = liteOrder.getOrderNo() + "-" + format.format(new Date());
dbOrder = liteOrderManager.findByOrderNo(newOrderNo);
if (dbOrder == null) {
liteOrder.setOrderNo(newOrderNo);
} else {
log.info("数据库中已存在工单号为[" + liteOrder.getOrderNo() + "],忽略文件:" + localFile.getAbsolutePath());
return ResultBean.newErrorResult(-1, "smfcode.order.ameExists", "工单名称[{0}]已存在", new String[]{liteOrder.getOrderNo()});
}
}
log.info("新增加订单:" + liteOrder.getOrderNo() + ",共" + liteOrderItems.size() + "条工单详情");
liteOrder = liteOrderManager.createWithItems(liteOrder);
liteOrderCache.addOrderToMap(liteOrder);
}
return ResultBean.newOkResult("工单上传成功");
return ResultBean.newOkResult("smfcode.order.uploadOK","工单上传成功","");
}
@ApiOperation("工单出库")
......@@ -206,6 +212,23 @@ public class OrderController {
}
}
@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("smfcode.valueCanotNull", "{0}不能为空", new String[]{"orderNo"});
}
String result= liteOrderCache.orderItemSupplementOut(orderNo,orderItemId);
if(ObjectUtil.isEmpty(result)){
return ResultBean.newOkResult(result);
}else{
return ResultBean.newErrorResult(-1,result,result);
}
}
@ApiOperation("查询工单")
@GetMapping
@PreAuthorize("@el.check('workOrder')")
......@@ -248,6 +271,7 @@ public class OrderController {
protected Map<String ,List<LiteOrderItem>> handleOrderCsv(String fileName,String fileURL) {
try {
fileName=fileName.replace(".csv","");
log.info("开始更解析上传的工单");
Map<String ,List<LiteOrderItem>> itemMap=new HashMap<>();
List<LiteOrderItem> items = Lists.newArrayList();
......@@ -293,6 +317,9 @@ public class OrderController {
if(soIndex!=-1){
so=lineValues[soIndex];
}
if(!ObjectUtil.isNotEmpty(so)){
so=fileName;
}
LiteOrderItem item = new LiteOrderItem();
item.setPn(partNumber);
item.setNeedNum(num);
......@@ -362,6 +389,7 @@ public class OrderController {
}
liteOrder.setOrderTimes(orderTimes);
liteOrderManager.save(liteOrder );
liteOrderCache.addOrderToMap(liteOrder);
return ResultBean.newOkResult(orderMapper.toDto(liteOrder) );
}
......@@ -382,4 +410,30 @@ public class OrderController {
}
}
@ApiOperation("修改工单线别")
@PostMapping(value = "/updateLine")
@PreAuthorize("@el.check('workOrder')")
public ResultBean updateLine(@RequestBody OrderDto param) {
if (param.getId() == null) {
throw new ValidateException("smfcode.valueCanotNull", "{0}不能为空", new String[]{"orderNo"});
}
if (param.getLine() == null) {
throw new ValidateException("smfcode.order.lineCanotNull", "线别不能为空");
}
LiteOrder order = liteOrderManager.get(param.getId());
if (order == null) {
throw new ValidateException("smfcode.valueCanotNull", "{0}不能为空", new String[]{"orderNo"});
}
if (!order.isNew()) {
throw new ValidateException("smfcode.order.cannotUpdateLine", "工单已出库,不能修改线别");
}
order.setLine(param.getLine());
liteOrderManager.save(order);
liteOrderCache.addOrderToMap(order);
return ResultBean.newOkResult(orderMapper.toDto(order));
}
}
......@@ -79,4 +79,8 @@ public class OrderDto implements Serializable {
@ApiModelProperty("创建时间")
private Date createDate = new Date();
@ApiModelProperty("工单线别")
private String line = "";
}
......@@ -5,7 +5,11 @@ import com.neotel.smfcore.common.exception.ValidateException;
import com.neotel.smfcore.core.barcode.service.po.Barcode;
import com.neotel.smfcore.core.order.service.po.LiteOrder;
import java.util.List;
public interface ILiteOrderManager extends IBaseManager<LiteOrder> {
LiteOrder findByOrderNo(String orderNo);
LiteOrder createWithItems(LiteOrder liteOrder) throws ValidateException;
List<LiteOrder> findUnEndOrdersList();
}
......@@ -6,6 +6,7 @@ import com.neotel.smfcore.common.exception.ValidateException;
import com.neotel.smfcore.core.barcode.service.dao.IBarcodeDao;
import com.neotel.smfcore.core.barcode.service.manager.IBarcodeManager;
import com.neotel.smfcore.core.barcode.service.po.Barcode;
import com.neotel.smfcore.core.order.enums.LITEORDER_STATUS;
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;
......@@ -15,6 +16,7 @@ import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;
......@@ -76,6 +78,22 @@ public class LiteOrderManagerImpl implements ILiteOrderManager {
}
@Override
public List<LiteOrder> findUnEndOrdersList() {
Criteria c = new Criteria();
c.and("status").nin(LITEORDER_STATUS.CLOSED);
Query query = new Query(c);
List<LiteOrder> orders = findByQuery(query);
for (LiteOrder order : orders
) {
if (order != null && order.getOrderItems() == null) {
List<LiteOrderItem> items = liteOrderItemManager.findOrderItems(order.getOrderNo());
order.setOrderItems(items);
}
}
return orders;
}
@Override
public PageData<LiteOrder> findByPage(Query query, Pageable pageable) {
int totalCount = liteOrderDao.countByQuery(query);
List<LiteOrder> list = liteOrderDao.findByQuery(query, pageable);
......
......@@ -112,11 +112,13 @@ public class LiteOrder extends BasePo implements Serializable {
*/
public void finishedTasks(){
if(isOutOne()){
setStatus(LITEORDER_STATUS.ONE_FINISHED);
// setStatus(LITEORDER_STATUS.ONE_FINISHED);
setClosed(true);
}else if(isOutBom()){
setStatus(LITEORDER_STATUS.BOM_FINISHED);
}else if(isOutTails()){
setStatus(LITEORDER_STATUS.TAILS_FINISHED);
// setStatus(LITEORDER_STATUS.TAILS_FINISHED);
setClosed(true);
}
setTaskFinishedTime(System.currentTimeMillis());
......
......@@ -64,24 +64,24 @@ public class TaskService {
/**
* 完成的任务列表Key 为dataLog的ID, Value 为 Datalog
*/
private static Map<String,DataLog> theFinishedTaskMap = Maps.newConcurrentMap();
private static Map<String, DataLog> theFinishedTaskMap = Maps.newConcurrentMap();
// public TaskService(List<ITaskListener> listenerList){
// for (ITaskListener taskListener: listenerList) {
// taskListenerList.add(taskListener);
// }
// }
private void check(String barcode, String posName) throws ValidateException {
}
/**
* 条码入库,加入要执行的任务
*/
public synchronized DataLog addPutInTaskToExecute(Storage storage, Barcode barcode, StoragePos storagePos) throws ValidateException {
DataLog task = new DataLog(storage, barcode, storagePos);
task.setType(OP.PUT_IN);
task.setStatus(OP_STATUS.EXECUTING.name());
......@@ -95,19 +95,20 @@ public class TaskService {
/**
* 库位出库
* @param storage 料仓
* @param pos 库位
*
* @param storage 料仓
* @param pos 库位
* @param isSingleOut 是否是单盘出库
* @return
* @throws ValidateException
*/
public synchronized String checkout(Storage storage, StoragePos pos, boolean isSingleOut,String opUserName) throws ValidateException {
public synchronized String checkout(Storage storage, StoragePos pos, boolean isSingleOut, String opUserName) throws ValidateException {
if (pos.getBarcode() == null) {
String msg = "库位[" + pos.getPosName() + "]中已无物料,忽略";
log.info(msg);
throw new ValidateException("smfcore.allBoxView.noReel","库位中无物料");
throw new ValidateException("smfcore.allBoxView.noReel", "库位中无物料");
}
DataLog task = new DataLog(storage, pos.getBarcode(), pos);
task.setType(OP.CHECKOUT);
task.setStatus(OP_STATUS.WAIT.name());
......@@ -119,9 +120,10 @@ public class TaskService {
/**
* 触发任务状态改变事件
*
* @param task
*/
private void tiggerTaskChangeListener(DataLog task){
private void tiggerTaskChangeListener(DataLog task) {
for (ITaskListener taskListener : taskListenerList) {
taskListener.onTaskStatusChange(task);
}
......@@ -129,6 +131,7 @@ public class TaskService {
/**
* 更新队列中的任务状态
*
* @param task
*/
public DataLog updateQueueTask(DataLog task) {
......@@ -140,9 +143,10 @@ public class TaskService {
/**
* 更新完成列表中的任务状态
*
* @param task
*/
public void updateFinishedTask(DataLog task){
public void updateFinishedTask(DataLog task) {
dataLogDao.save(task);
theFinishedTaskMap.put(task.getId(), task);
tiggerTaskChangeListener(task);
......@@ -155,10 +159,10 @@ public class TaskService {
String posName = taskToExecute.getPosName();
if (!Strings.isNullOrEmpty(barcode) && task.getBarcode().equals(barcode)) {
log.info("二维码:[" + barcode + "]已在操作队列中,操作失败");
throw new ValidateException("smfcode.error.barcode.inQueue","二维码[{0}]已在操作队列中,操作失败", new String[]{barcode});
throw new ValidateException("smfcode.error.barcode.inQueue", "二维码[{0}]已在操作队列中,操作失败", new String[]{barcode});
} else if (task.getPosName().equals(posName)) {
log.info("位置:[" + posName + "]已在操作队列中,操作失败");
throw new ValidateException("smfcode.error.pos.inQueue","位置:[{0}}]已在操作队列中,操作失败", new String[]{posName});
throw new ValidateException("smfcode.error.pos.inQueue", "位置:[{0}}]已在操作队列中,操作失败", new String[]{posName});
}
}
updateQueueTask(taskToExecute);
......@@ -174,10 +178,10 @@ public class TaskService {
/**
* 获取所有任务
*/
public List<DataLog> getAllTasks(){
public List<DataLog> getAllTasks() {
List<DataLog> allTasks = getFinishedTasks();
Collection<DataLog> queueTasks = getQueueTasks();
if(!queueTasks.isEmpty()){
if (!queueTasks.isEmpty()) {
allTasks.addAll(queueTasks);
}
return allTasks;
......@@ -218,14 +222,14 @@ public class TaskService {
/**
* 清除某个已经完成或取消的任务
*/
public void removeFinishedTask(DataLog task){
public void removeFinishedTask(DataLog task) {
theFinishedTaskMap.remove(task.getId());
}
/**
* 清除队列中等待执行或正在执行的任务
*/
public void removeQueueTask(DataLog task){
public void removeQueueTask(DataLog task) {
taskMap.remove(task.getId());
}
......@@ -247,6 +251,7 @@ public class TaskService {
/**
* 根据料仓编号和库位获取已完成/取消的任务
*
* @param cid
* @param posName
* @return
......@@ -272,6 +277,7 @@ public class TaskService {
}
return null;
}
/**
* 是否有正在执行的任务
*
......@@ -290,7 +296,7 @@ public class TaskService {
* 为 box 分配出库任务
*/
private DataLog findCheckoutBoxTask(Storage storage) {
String cid=storage.getCid();
String cid = storage.getCid();
int checkoutSize = 0;
Collection<DataLog> allTasks = taskMap.values();
for (DataLog task : allTasks) {
......@@ -348,10 +354,11 @@ public class TaskService {
return outTask;
}
/**
* 出库处理
*/
public StatusBean checkOut(Storage storage,StatusBean statusBean ) {
public StatusBean checkOut(Storage storage, StatusBean statusBean) {
try {
String cid = storage.getCid();
......@@ -401,6 +408,7 @@ public class TaskService {
/**
* 已分配的库位号
*
* @return
*/
public Collection<String> excludePosIds() {
......@@ -501,6 +509,7 @@ public class TaskService {
addTaskToExecute(task);
return "";
}
public DataLog newTask(StoragePos pos) {
DataLog task = new DataLog();
......@@ -528,11 +537,12 @@ public class TaskService {
/**
* 查找可以入库的空位
*
* @param storageList
* @param barcode
* @return
*/
public StoragePos findEmptyPosForPutIn(List<Storage> storageList, Barcode barcode, String inRFID,String lastPosId) throws ValidateException {
public StoragePos findEmptyPosForPutIn(List<Storage> storageList, Barcode barcode, String inRFID, String lastPosId) throws ValidateException {
verifyBarcodePutIn(storageList, barcode, inRFID);
//查找任务数最少的料仓
......@@ -567,27 +577,27 @@ public class TaskService {
String lockPosId = ReelLockPosUtil.getReelLockPosId(barcode.getBarcode());
StoragePos pos = null;
if(!Strings.isNullOrEmpty(lockPosId)){
if (!Strings.isNullOrEmpty(lockPosId)) {
//已有锁定库位
pos = storagePosManager.get(lockPosId);
if(pos != null ){
if(pos.getW() < barcode.getPlateSize() || pos.getH() < barcode.getHeight()){
log.info("条码["+barcode.getBarcode()+"]尺寸已改变,无法放入已锁定库位["+pos.getPosName()+"],重新查找库位");
if (pos != null) {
if (pos.getW() < barcode.getPlateSize() || pos.getH() < barcode.getHeight()) {
log.info("条码[" + barcode.getBarcode() + "]尺寸已改变,无法放入已锁定库位[" + pos.getPosName() + "],重新查找库位");
pos = null;
}else{
} else {
Barcode posBarcode = pos.getBarcode();
if(posBarcode == null){
log.info("条码["+barcode.getBarcode()+"]已锁定库位["+pos.getPosName()+"],返回锁定中的库位");
}else{
log.info("条码["+barcode.getBarcode()+"]已锁定库位["+pos.getPosName()+"]中已有物料["+posBarcode.getBarcode()+"],重新查找库位");
if (posBarcode == null) {
log.info("条码[" + barcode.getBarcode() + "]已锁定库位[" + pos.getPosName() + "],返回锁定中的库位");
} else {
log.info("条码[" + barcode.getBarcode() + "]已锁定库位[" + pos.getPosName() + "]中已有物料[" + posBarcode.getBarcode() + "],重新查找库位");
pos = null;
}
}
}
}
if(pos != null){
if (pos != null) {
return pos;
}
......@@ -616,81 +626,83 @@ public class TaskService {
return findEmptyPosInStorages(barcode, availbleStorageList, storageTaskCountMap, lastPosId);
}
private synchronized StoragePos findEmptyPosInStorages(Barcode barcode, List<Storage> availbleStorageList, final Map<String,Integer> executingTaskCountMap,String lastPosId){
private synchronized StoragePos findEmptyPosInStorages(Barcode barcode, List<Storage> availbleStorageList, final Map<String, Integer> executingTaskCountMap, String lastPosId) {
for (Storage storage : availbleStorageList) {
try{
try {
Collection<String> operatingPosIds = excludePosIds();
log.debug("尝试从["+storage.getCid()+"]中为["+barcode.getBarcode()+"]查找空位");
StoragePos pos = storagePosManager.getEmptyPosByStorage(storage, barcode , operatingPosIds,lastPosId);
if(pos != null){
log.debug("尝试从[" + storage.getCid() + "]中为[" + barcode.getBarcode() + "]查找空位");
StoragePos pos = storagePosManager.getEmptyPosByStorage(storage, barcode, operatingPosIds, lastPosId);
if (pos != null) {
return pos;
}
}catch(Exception e){
log.error("尝试从["+storage.getCid()+"]中为["+barcode.getBarcode()+"]查找空位失败:" + e.getMessage());
} catch (Exception e) {
log.error("尝试从[" + storage.getCid() + "]中为[" + barcode.getBarcode() + "]查找空位失败:" + e.getMessage());
}
}
try{
try {
String cids = "";
for (Storage storage : availbleStorageList) {
cids =cids + storage.getCid() + ",";
cids = cids + storage.getCid() + ",";
}
log.info(barcode.getBarcode()+ " 未找到可用库位,可用料仓:"+cids);
}catch (Exception e){
log.error("打印可用料仓出错",e);
log.info(barcode.getBarcode() + " 未找到可用库位,可用料仓:" + cids);
} catch (Exception e) {
log.error("打印可用料仓出错", e);
}
return null;
}
/**
* 检查二维码是否合法并且可以入库,没问题的话存入到数据库
*/
private Barcode verifyBarcodePutIn(List<Storage> storageList, Barcode barcodeSave, String inRFID) throws ValidateException {
if(barcodeSave == null){
throw new ValidateException("smfcode.error.barcode.invalid","条码无效");
if (barcodeSave == null) {
throw new ValidateException("smfcode.error.barcode.invalid", "条码无效");
}
StoragePos pos;
//夹具,查询 relationCode
if(COMPONENT_TYPE.FIXTURE == barcodeSave.getType()){
if (COMPONENT_TYPE.FIXTURE == barcodeSave.getType()) {
pos = storagePosManager.getByFixtureCode(barcodeSave.getBarcode());
}else {
} else {
pos = storagePosManager.getByBarcodeId(barcodeSave.getId());
if (barcodeSave.getAmount() <= 0) {
throw new ValidateException("smfcode.error.barcode.wrongQty","条码[{0}]对应的数量<=0为: {1}" ,new String[]{ barcodeSave.getBarcode() , barcodeSave.getAmount()+""});
throw new ValidateException("smfcode.error.barcode.wrongQty", "条码[{0}]对应的数量<=0为: {1}", new String[]{barcodeSave.getBarcode(), barcodeSave.getAmount() + ""});
}
}
if (pos != null) {
//如果已在库位中,那么自动将该库位的物料出库
log.info("出库已在库位中的物料["+barcodeSave.getBarcode()+"]");
log.info("出库已在库位中的物料[" + barcodeSave.getBarcode() + "]");
Storage storage = dataCache.getStorageById(pos.getStorageId());
checkout(storage, pos, true,"");
checkout(storage, pos, true, "");
throw new ValidateException("smfcode.error.barcode.exist", "[{0}}]已在{1}}[{2}}]中",new String[]{ barcodeSave.getBarcode(),storage.getName(),pos.getPosName()});
throw new ValidateException("smfcode.error.barcode.exist", "[{0}}]已在{1}}[{2}}]中", new String[]{barcodeSave.getBarcode(), storage.getName(), pos.getPosName()});
}
Collection<DataLog> queueTasks = getQueueTasks();
List<DataLog> allTasks = getFinishedTasks();
if(!queueTasks.isEmpty()){
if (!queueTasks.isEmpty()) {
allTasks.addAll(queueTasks);
}
for (DataLog task : allTasks) {
if(task.isPutInTask()){
if(task.getBarcode().equals(barcodeSave.getBarcode())){
if (task.isPutInTask()) {
if (task.getBarcode().equals(barcodeSave.getBarcode())) {
//同一个条码的入库任务
for (Storage storage : storageList) {
if(task.getStorageId().equals(storage.getId()) && task.isPutInTask()){
if (task.getStorageId().equals(storage.getId()) && task.isPutInTask()) {
return barcodeSave;
}
}
throw new ValidateException("smfcode.error.barcode.taskNotEnd", "料盘[{0}}]的操作未完成,无法执行入库操作",new String[]{ barcodeSave.getBarcode()});
throw new ValidateException("smfcode.error.barcode.taskNotEnd", "料盘[{0}}]的操作未完成,无法执行入库操作", new String[]{barcodeSave.getBarcode()});
}
}
}
......@@ -701,28 +713,28 @@ public class TaskService {
}
public void addTaskToFinished(StoragePos pos, Barcode barcode, String opUser){
try{
public void addTaskToFinished(StoragePos pos, Barcode barcode, String opUser) {
try {
Collection<DataLog> allTasks = taskMap.values();
if(pos.getBarcode() != null){
if (pos.getBarcode() != null) {
barcode = pos.getBarcode();
for(DataLog task : allTasks){
if(task.isCheckOutTask()){
for (DataLog task : allTasks) {
if (task.isCheckOutTask()) {
String executeBarcode = task.getBarcode();
String executePosId = task.getPosId();
boolean isSameTask = false;
if(executeBarcode != null && barcode.getBarcode().equals(executeBarcode)){
if (executeBarcode != null && barcode.getBarcode().equals(executeBarcode)) {
isSameTask = true;
}
if(executePosId != null && pos.getId().equals(executePosId)){
if (executePosId != null && pos.getId().equals(executePosId)) {
isSameTask = true;
}
if(isSameTask){
log.info(executeBarcode + "找到正在执行的出库任务["+pos.getPosName()+"],直接完成");
if(task.isWait()){
taskMap.put(task.getId(),task);
if (isSameTask) {
log.info(executeBarcode + "找到正在执行的出库任务[" + pos.getPosName() + "],直接完成");
if (task.isWait()) {
taskMap.put(task.getId(), task);
}
task.setOperator(opUser);
checkoutFinished(task);
......@@ -733,18 +745,16 @@ public class TaskService {
}
//没有正在执行的任务,直接添加一条已完成的任务
DataLog task = newTask(pos);
if(pos.getBarcode() == null){
log.info(opUser + "入库【"+barcode.getBarcode()+"】到【"+pos.getPosName()+"】");
if (pos.getBarcode() == null) {
log.info(opUser + "入库【" + barcode.getBarcode() + "】到【" + pos.getPosName() + "】");
task.setType(OP.PUT_IN);
barcode.setUsedCount(barcode.getUsedCount() + 1);
barcode.setUsedDate(new Date());
barcode.setPutInTime(System.currentTimeMillis());
barcode.setInOpor(opUser);
barcode.setCheckOutDate(null,"");
barcode.setCheckOutDate(null, "");
barcode.setPosName(task.getPosName());
barcodeManager.save(barcode);
......@@ -759,17 +769,17 @@ public class TaskService {
task.setBarcode(barcode.getBarcode());
task.setNum(barcode.getInitialAmount());
dataCache.updateInventory(pos,barcode);
dataCache.updateInventory(pos, barcode);
//dataCache.updateStorage(task.getCid());
}else{
} else {
barcode = pos.getBarcode();
log.info(opUser + "将【"+barcode.getBarcode()+"】从【"+pos.getPosName()+"】出库");
log.info(opUser + "将【" + barcode.getBarcode() + "】从【" + pos.getPosName() + "】出库");
task.setType(OP.CHECKOUT);
barcode.setUsed(true);
barcode.setUsedDate(new Date());
//仓位状态
barcode.setCheckOutDate(new Date(),task.getOperator());
barcode.setCheckOutDate(new Date(), task.getOperator());
barcode.setPosName("");
barcodeManager.save(barcode);
......@@ -785,11 +795,12 @@ public class TaskService {
task.setStatus(OP_STATUS.FINISHED.name());
task = dataLogDao.save(task);
theFinishedTaskMap.put(task.getBarcode(),task);
}catch (Exception e){
log.error("addTaskToFinished Error:",e);
theFinishedTaskMap.put(task.getBarcode(), task);
} catch (Exception e) {
log.error("addTaskToFinished Error:", e);
}
}
/**
* 出库完成
*/
......@@ -799,30 +810,30 @@ public class TaskService {
StoragePos storagePos = storagePosManager.get(task.getPosId());
Barcode barcode = storagePos.getBarcode();
if(barcode == null){
if (barcode == null) {
//记录日志
task.setStatus(OP_STATUS.CANCEL.name());
taskMap.remove(task.getId());
theFinishedTaskMap.put(task.getBarcode(),task);
log.warn("任务:"+task.getBarcode() +" 仓位:"+task.getPosName()+" 的 Barcode 为null, 之前可能处理过直接返回");
theFinishedTaskMap.put(task.getBarcode(), task);
log.warn("任务:" + task.getBarcode() + " 仓位:" + task.getPosName() + " 的 Barcode 为null, 之前可能处理过直接返回");
return;
}
//记录在库时长
task.setInStoreTime(barcode.getInStoreMiniute());
barcode = barcodeManager.get(barcode.getId());
if(barcode != null){
if (barcode != null) {
//二维码状态
barcode.setUsed(true);
barcode.setUsedDate(new Date());
//仓位状态
barcode.setCheckOutDate(new Date(),task.getOperator());
barcode.setCheckOutDate(new Date(), task.getOperator());
barcode.setPosName("");
barcodeManager.save(barcode);
String specifiedBatchId = barcode.getLockId();
if(!Strings.isNullOrEmpty(specifiedBatchId)){
if (!Strings.isNullOrEmpty(specifiedBatchId)) {
task.setBatchId(specifiedBatchId);
task.setBatchInfo(barcode.getLockName());
}
......@@ -835,25 +846,25 @@ public class TaskService {
log.info(task.getBarcode() + "出库完成,清空仓位: " + storagePos.getId() + "[" + storagePos.getPosName() + "]");
//更新缓存中的库存信息
dataCache.updateInventory(storagePos,barcode);
dataCache.updateInventory(storagePos, barcode);
//记录日志
task.setStatus(OP_STATUS.FINISHED.name());
if(isCancelTask){
if (isCancelTask) {
task.setStatus(OP_STATUS.CANCEL.name());
}
dataLogDao.save(task);
//从队列里面移除操作
DataLog removeTask = taskMap.remove(task.getId());
try{
if(removeTask == null){
log.error(task.getBarcode()+"的出库任务["+task.getId()+"]清除失败");
try {
if (removeTask == null) {
log.error(task.getBarcode() + "的出库任务[" + task.getId() + "]清除失败");
}
}catch (Exception e){
} catch (Exception e) {
log.error(e.getMessage());
}
theFinishedTaskMap.put(task.getBarcode(),task);
theFinishedTaskMap.put(task.getBarcode(), task);
// //任务已经被取消就不再更新需求单信息
......@@ -866,11 +877,10 @@ public class TaskService {
}
/**
* 策略出库
*/
public synchronized void tacticsCheckOut(Set<TacticsOutDto> tacticsOutDtos) {
public synchronized void tacticsCheckOut(Set<TacticsOutDto> tacticsOutDtos) {
CHECKOUT_TYPE checkoutType = dataCache.getCheckOutType();
List<String> availableStorageIds = new ArrayList<>();
......
......@@ -377,6 +377,7 @@ public class HellaServiceHandler extends IoHandlerAdapter implements ITaskListen
liteOrder.setSource(groupName);
log.info("新增加订单:" + liteOrder.getOrderNo());
liteOrder = liteOrderManager.createWithItems(liteOrder);
liteOrderCache.addOrderToMap(liteOrder);
//对工单进行锁定
List<String> storageIdList = new ArrayList<>();
......
支持 Markdown 格式
你添加了 0 到此讨论。请谨慎行事。
Finish editing this message first!