Commit 93d0803f sunke

Merge remote-tracking branch 'origin/master'

2 个父辈 d6eb11b2 2a622d86
正在显示 25 个修改的文件 包含 894 行增加70 行删除
package com.neotel.smfcore.common.excel;
import com.alibaba.excel.EasyExcel;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class ExcelReader {
public static List<Map<Integer, String>> noModelRead(String fileName) {
// 这里 只要,然后读取第一个sheet 同步读取会自动finish
NoModelDataListener listener = new NoModelDataListener();
EasyExcel.read(fileName, listener).sheet().doRead();
List<Map<Integer, String>> data = listener.getData();
Map<Integer, String> headerMap = listener.getHeaderMap();
if (headerMap != null) {
if (data == null) {
data = new ArrayList<>();
}
data.add(0, headerMap);
}
return data;
}
// public static List<OrderLineItem> ReadOrder(String fileName){
// ExcelReaderBuilder workBook = EasyExcel.read
// (fileName, OrderLineItem.class, new OrderReaderListener());
//
// // 封装工作表
// ExcelReaderSheetBuilder sheet1 = workBook.sheet();
// // 读取
// sheet1.doRead();
//
// //写入数据库
// List<OrderLineItem> orderLineItems = OrderReaderListener.getStudentList();
// return orderLineItems;
//
// }
}
package com.neotel.smfcore.common.excel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.metadata.data.ReadCellData;
import com.alibaba.excel.util.ConverterUtils;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Slf4j
public class NoModelDataListener extends AnalysisEventListener<Map<Integer, String>> {
private List<Map<Integer, String>> cachedDataList =new ArrayList<>();
private Map<Integer,String> headerMap=new HashMap<>();
@Override
public void invoke(Map<Integer, String> data, AnalysisContext context) {
log.debug("解析到一条数据:{}", JSON.toJSONString(data));
cachedDataList.add(data);
}
@Override
public void doAfterAllAnalysed(AnalysisContext context) {
log.info("所有数据解析完成,共"+cachedDataList.size()+"条数据!");
}
public List<Map<Integer, String>> getData(){
return cachedDataList ;
}
public Map<Integer, String> getHeaderMap(){
return headerMap;
}
@Override
public void invokeHead(Map<Integer, ReadCellData<?>> headMap, AnalysisContext context) {
log.debug("解析到一条头数据:{}", JSON.toJSONString(headMap));
headerMap= ConverterUtils.convertToStringMap(headMap, context);
// 如果想转成成 Map<Integer,String>
// 方案1: 不要implements ReadListener 而是 extends AnalysisEventListener
// 方案2: 调用 ConverterUtils.convertToStringMap(headMap, context) 自动会转换
}
}
......@@ -861,6 +861,13 @@ public class BarcodeRule {
rule = "PN[5:0:-1]|BATCH[2:0:-1]|LOT|QTY[2:0:-1]|RI|SP[5:0:-1]|EXPDATEdd-MM-yyyy[2:0:-1]|xxx|xxx|xxx";
rule = "PN[5:0:-1]|BATCH[2:0:-1]|LOT|QTY[2_7Q:0:-1]|RI|SP[5:0:-1]|EXPDATEdd-MM-yyyy[2:0:-1]|xxx|xxx|xxx";
codeStr="zBYHNMC3.41+250123|1TBYHNMC3.41|7Q1000|1TBYHNMC3.41|P466385|1PMT29F2T08EMHBFJ4-T:B";
rule="EXPDATEyyMMdd[12:0:-1]|BATCH[2:0:-1]|QTY[2:0:-1]|RI[2:0:-1]|PN[1:0:-1]|XXX";
codeStr="=1+0x0-400x62=zJFSRW46.11+250205|1TJFSRW46.11|7Q404|1TJFSRW46.11|P530828|1PMT29F2T08ELLEEG7-QD:E";
rule="EXPDATEyyMMdd[12:0:-1]|BATCH[2:0:-1]|QTY[2:0:-1]|RI[2:0:-1]|PN[1:0:-1]|XXX";
// rule="PN[1:0:-1]|BATCH[2:0:-1]|LOT[2:0:-1]|QTY[2_7Q:0:-1]|RI[1:0:-1]|SP[3:0:-1]|PRODATEyyyyMMdd[2:0:-1]|xxx";
BarcodeRule br = BarcodeRule.newRule(rule);
Barcode b = br.toCodeBean(codeStr).getBarcode();
if(b != null){
......@@ -874,6 +881,7 @@ public class BarcodeRule {
System.out.println("Supllier:"+b.getProvider());
System.out.println("Memo:"+b.getMemo());
}else{
System.out.println("解析失败");
log.info("解析失败");
}
......
......@@ -161,6 +161,11 @@ public class CodeResolve {
}
}
}
if(barcodeFromRule.getExpireDate()!=null &&barcode.getExpireDate()==null){
barcode.setExpireDate(barcodeFromRule.getExpireDate());
log.info("重新设置"+codeBeanFromRule.getCodeStr()+"的过期日期");
needUpdate = true;
}
if(needUpdate){
try {
......
......@@ -908,6 +908,29 @@ public class BaseDeviceHandler implements IDeviceHandler {
return dataLogs;
}
protected StatusBean sendOutTaskToClient(DataLog outTask, StatusBean statusBean, Storage storage ) {
if (outTask != null) {
log.info("分配出库任务" + outTask.getBarcode() + "[" + outTask.getPosName() + "]到 " + storage.getCid());
outTask.setStatus(OP_STATUS.EXECUTING.name());
taskService.updateQueueTask(outTask);
statusBean.setOp(OP.CHECKOUT);
String posName = outTask.getPosName();
Barcode codeObj = barcodeManager.findByBarcode(outTask.getBarcode());
int plateW = 0;
int plateH = 0;
if (codeObj != null) {
plateW = codeObj.getPlateSize();
plateH = codeObj.getHeight();
} else {
log.warn("出库无料仓位" + storage.getName() + "[" + posName + "]");
}
statusBean.addPosInfo(outTask.getBarcode(), posName, plateW, plateH, false);
log.info("出库" + storage.getName() + "[" + posName + "]物料[" + outTask.getBarcode() + "] 发送到客户端" + storage.getCid());
}
return statusBean;
}
/**
* 判断是否打开了亮灯指引功能
* @return
......
......@@ -23,13 +23,13 @@ import com.neotel.smfcore.core.storage.service.po.StoragePos;
import com.neotel.smfcore.core.system.service.dao.IAlarmInfoDao;
import com.neotel.smfcore.core.system.service.po.AlarmInfo;
import com.neotel.smfcore.core.system.service.po.DataLog;
import com.neotel.smfcore.custom.micron1053.util.MicronDataCache;
import com.neotel.smfcore.security.annotation.AnonymousAccess;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
......@@ -97,11 +97,35 @@ public class RobotBoxHandler extends BaseDeviceHandler {
if (dataCache.getCache(Constants.CACHE_StopOut)) {
return statusBean;
}
String cid = statusBean.getCid();
// 任务根据时间排序。查找当前正在出的工单和料架 (入库任务不计算)
List<DataLog> allTasks=taskService.getAllTasks();
Collections.sort(allTasks);
List<String> shelfType=new ArrayList<>();
List<String> sourceIds=new ArrayList<>();
for (DataLog task :
allTasks) {
if(task.isPutInTask()|| task.isEnd()||task.isFinished()||task.isCancel()){
continue;
}
if(task.isCheckOutTask()&&task.isWait()){
continue;
}
String shelf= MicronDataCache.getShelfType(task);
if(!shelfType.contains(shelf)){
shelfType.add(shelf);
}
if(ObjectUtil.isNotEmpty(task.getSourceId())&&(!sourceIds.contains(task.getSourceId()))){
sourceIds.add(task.getSourceId());
}
}
//查询
List<DataLog> queueTasks=new ArrayList<>();
queueTasks.addAll(taskService.getQueueTasks());
Collections.sort(queueTasks);
Collection<DataLog> queueTasks = taskService.getQueueTasks();
int executingOutTaskSize = 0;
DataLog outTask = null;
for (DataLog queueTask : queueTasks) {
......@@ -125,34 +149,33 @@ public class RobotBoxHandler extends BaseDeviceHandler {
outTask = null;
break;
}
outTask = queueTask;
if (queueTask.isUrgentReel()) {
outTask = queueTask;
break;
}
//如果料架>=2,当前任务的料架在已出料架中,可以直接出
//如果料架<2,且当前任务属于已出工单,可以直接出
//循环查找,当前任务不满足时查找下一个任务
String shelf = MicronDataCache.getShelfType(queueTask);
if (shelfType.size() < 2 || shelfType.contains(shelf)) {
//料架正确,工单为空,返回
if (ObjectUtil.isEmpty(queueTask.getSourceId())) {
outTask = queueTask;
break;
} else if (sourceIds.size() < 1 || sourceIds.contains(queueTask.getSourceId())) {
outTask = queueTask;
break;
}
}
}
}
}
}
if (outTask != null) {
log.info("分配出库任务" + outTask.getBarcode() + "[" + outTask.getPosName() + "]到 " + cid);
outTask.setStatus(OP_STATUS.EXECUTING.name());
taskService.updateQueueTask(outTask);
statusBean.setOp(OP.CHECKOUT);
String posName = outTask.getPosName();
Barcode codeObj = barcodeManager.findByBarcode(outTask.getBarcode());
int plateW = 0;
int plateH = 0;
if (codeObj != null) {
plateW = codeObj.getPlateSize();
plateH = codeObj.getHeight();
} else {
log.warn("出库无料仓位" + storage.getName() + "[" + posName + "]");
}
statusBean.addPosInfo(outTask.getBarcode(), posName, plateW, plateH, false);
log.info("出库" + storage.getName() + "[" + posName + "]物料[" + outTask.getBarcode() + "] 发送到客户端" + cid);
}
statusBean= sendOutTaskToClient(outTask,statusBean,storage);
} catch (Exception e) {
log.error("出库出错", e);
......@@ -160,7 +183,6 @@ public class RobotBoxHandler extends BaseDeviceHandler {
return statusBean;
}
protected StatusBean handleFinished(StatusBean statusBean) {
Map<String, BoxStatusBean> statusOfBoxes = statusBean.getBoxStatus();
if (statusOfBoxes != null) {
......
package com.neotel.smfcore.core.device.handler.impl;
import cn.hutool.core.util.ObjectUtil;
import com.google.common.base.Strings;
import com.neotel.smfcore.common.exception.ValidateException;
import com.neotel.smfcore.common.utils.Constants;
......@@ -16,15 +17,13 @@ import com.neotel.smfcore.core.storage.enums.DeviceType;
import com.neotel.smfcore.core.storage.service.po.Storage;
import com.neotel.smfcore.core.storage.service.po.StoragePos;
import com.neotel.smfcore.core.system.service.po.DataLog;
import com.neotel.smfcore.core.system.util.DevicesStatusUtil;
import com.neotel.smfcore.custom.micron1053.util.MicronDataCache;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletRequest;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.*;
@Service
@Slf4j
public class ThirdBoxHandler extends BaseDeviceHandler{
......@@ -83,17 +82,41 @@ public class ThirdBoxHandler extends BaseDeviceHandler{
if (dataCache.getCache(Constants.CACHE_StopOut)) {
return statusBean;
}
String cid = statusBean.getCid();
// 任务根据时间排序。查找当前正在出的工单和料架 (入库任务不计算)
List<DataLog> allTasks=taskService.getAllTasks();
Collections.sort(allTasks);
List<String> shelfType=new ArrayList<>();
List<String> sourceIds=new ArrayList<>();
for (DataLog task :
allTasks) {
if(task.isPutInTask()|| task.isEnd()||task.isFinished()||task.isCancel()){
continue;
}
if(task.isCheckOutTask()&&task.isWait()){
continue;
}
String shelf= MicronDataCache.getShelfType(task);
if(!shelfType.contains(shelf)){
shelfType.add(shelf);
}
if(ObjectUtil.isNotEmpty(task.getSourceId())&&(!sourceIds.contains(task.getSourceId()))){
sourceIds.add(task.getSourceId());
}
}
//查询
List<DataLog> queueTasks=new ArrayList<>();
queueTasks.addAll(taskService.getQueueTasks());
Collections.sort(queueTasks);
Collection<DataLog> queueTasks = taskService.getQueueTasks();
int executingOutTaskSize = 0;
DataLog outTask = null;
for (DataLog queueTask : queueTasks) {
if (queueTask.getCid().equals(cid)) {
//有入库任务不分配出库任务
if (queueTask.isPutInTask()) {
if (queueTask.isPutInTask()) {
return statusBean;
} else {
if (queueTask.isExecuting()) {
......@@ -111,34 +134,33 @@ public class ThirdBoxHandler extends BaseDeviceHandler{
outTask = null;
break;
}
outTask = queueTask;
if (queueTask.isUrgentReel()) {
outTask = queueTask;
break;
}
//如果料架>=2,当前任务的料架在已出料架中,可以直接出
//如果料架<2,且当前任务属于已出工单,可以直接出
//循环查找,当前任务不满足时查找下一个任务
String shelf = MicronDataCache.getShelfType(queueTask);
if (shelfType.size() < 2 || shelfType.contains(shelf)) {
//料架正确,工单为空,返回
if (ObjectUtil.isEmpty(queueTask.getSourceId())) {
outTask = queueTask;
break;
} else if (sourceIds.size() < 1 || sourceIds.contains(queueTask.getSourceId())) {
outTask = queueTask;
break;
}
}
}
}
}
}
if (outTask != null) {
log.info("分配出库任务" + outTask.getBarcode() + "[" + outTask.getPosName() + "]到 " + cid);
outTask.setStatus(OP_STATUS.EXECUTING.name());
taskService.updateQueueTask(outTask);
statusBean.setOp(OP.CHECKOUT);
String posName = outTask.getPosName();
Barcode codeObj = barcodeManager.findByBarcode(outTask.getBarcode());
int plateW = 0;
int plateH = 0;
if (codeObj != null) {
plateW = codeObj.getPlateSize();
plateH = codeObj.getHeight();
} else {
log.warn("出库无料仓位" + storage.getName() + "[" + posName + "]");
}
statusBean.addPosInfo(outTask.getBarcode(), posName, plateW, plateH, false);
log.info("出库" + storage.getName() + "[" + posName + "]物料[" + outTask.getBarcode() + "] 发送到客户端" + cid);
}
statusBean= sendOutTaskToClient(outTask,statusBean,storage );
} catch (Exception e) {
log.error("出库出错", e);
......
......@@ -3,6 +3,7 @@ package com.neotel.smfcore.core.order.listener;
import cn.hutool.core.util.ObjectUtil;
import com.google.common.collect.Lists;
import com.neotel.smfcore.common.csv.CsvReader;
import com.neotel.smfcore.common.excel.ExcelReader;
import com.neotel.smfcore.core.device.util.DataCache;
import com.neotel.smfcore.core.order.LiteOrderCache;
import com.neotel.smfcore.core.order.service.manager.ILiteOrderManager;
......@@ -42,12 +43,16 @@ public class DefaultOrderFileListener implements IOrderFileListener {
// if(!fileName.endsWith(".process") && fileName.endsWith("_result.txt")){
//
// }
if(isFileType(fileName,"csv")){
if(isFileType(fileName,"csv")||isFileType(fileName,"xlsx")){
LiteOrder fileNameOrder = liteOrderManager.findBySource(fileName);
if(fileNameOrder == null){
try{
Map<String, List<LiteOrderItem>> itemMap = readCsvFile(fileName,orderFile.getAbsolutePath());
Map<String, List<LiteOrderItem>> itemMap =null;
if(isFileType(fileName,"csv")) {
itemMap = readCsvFile(fileName, orderFile.getAbsolutePath());
}else if(isFileType(fileName,"xlsx")){
itemMap = readExcelFile(fileName, orderFile.getAbsolutePath());
}
if (itemMap != null && itemMap.size() > 0) {
for (String so:itemMap.keySet()) {
......@@ -178,6 +183,89 @@ public class DefaultOrderFileListener implements IOrderFileListener {
}
public Map<String , List<LiteOrderItem>> readExcelFile(String fileName, String fileURL) {
try {
fileName = fileName.replace(".xlsx", "");
Map<String, List<LiteOrderItem>> itemMap = new HashMap<>();
List<Map<Integer, String>> data= ExcelReader.noModelRead(fileURL);
if(data!=null&&data.size()>=2){
Map<Integer, String> headerData=data.get(0);
Map<String,Integer> headerMap=new HashMap<>();
for (Integer key :
headerData.keySet()) {
String v=headerData.get(key);
headerMap.put(v,key);
}
OrderSetting orderSetting = dataCache.getOrderSetting();
int partNumberIndex = headerMap.getOrDefault( orderSetting.getPn(),-1);
int qtyIndex = headerMap.getOrDefault( orderSetting.getQty(),-1);
int feederIndex = headerMap.getOrDefault( orderSetting.getFeeder(),-1);
int riIndex = headerMap.getOrDefault( orderSetting.getRi(),-1);
int soIndex = headerMap.getOrDefault( orderSetting.getSo(),-1);
for(int i=1;i<data.size();i++){
Map<Integer, String> lineValues = data.get(i);
String partNumber = lineValues.get(partNumberIndex);
String ri="";
if(riIndex!=-1){
ri=lineValues.get(riIndex);
}
if (partNumber.isEmpty()&&ri.isEmpty()) {
log.warn("行[partNumber=" + partNumber + "]中PN和RI都 为空,此行忽略");
} else {
int num = 1;
if (qtyIndex != -1) {
String numStr = lineValues.get(qtyIndex) ;
if (Strings.isNotBlank(numStr)) {
try {
num = Integer.valueOf(numStr);
} catch (Exception e) {
log.error(partNumber + "的数量:" + numStr + " 不是数字,使用1");
}
}
}
String feeder = "";
if (feederIndex != -1) {
feeder = lineValues.get(feederIndex);
}
String so=fileName;
if(soIndex!=-1){
so=lineValues.get(soIndex);
}
if(!ObjectUtil.isNotEmpty(so)){
so=fileName;
}
LiteOrderItem item = new LiteOrderItem();
item.setPn(partNumber);
if(partNumber.isEmpty()){
item.setNeedReelCount(1);
}
item.setNeedNum(num);
item.setFeederInfo(feeder);
item.setRi(ri);
if(!itemMap.containsKey(so)){
itemMap.put(so,new ArrayList<LiteOrderItem>());
}
itemMap.get(so).add(item);
}
}
}
return itemMap;
} catch (Exception ex) {
log.error("解析上传的工单出错:" + ex.toString());
} finally {
}
return null;
}
protected boolean isFileType(String smbFile, String type){
//判断是否是有效的工单文件
if(smbFile.toLowerCase().endsWith(type)){
......
......@@ -129,11 +129,12 @@ public class OrderController {
@AnonymousAccess
public ResultBean updateAvatar(@RequestParam MultipartFile orderFile) {
String image = "csv";
String csv = "csv";
String excel="xlsx";
String fileType = FileUtil.getExtensionName(orderFile.getOriginalFilename());
String fileName = FileUtil.getFileNameNoEx(orderFile.getOriginalFilename());
if (fileType != null && !image.contains(fileType)) {
throw new ValidateException("smfcore.feleFormatError", "文件格式错误!, 仅支持{0}格式", new String[]{image});
if (fileType != null &&(!csv.contains(fileType))&&(!excel.contains(fileType)) ) {
throw new ValidateException("smfcore.feleFormatError", "文件格式错误!, 仅支持{0}格式", new String[]{csv+","+excel});
}
File folder = new File(properties.getPath(), "pos");
File localFile = FileUtil.upload(orderFile, folder.getAbsolutePath());
......
......@@ -16,4 +16,6 @@ public interface IDataLogDao extends IBaseDao {
List<DataLog> findHistory(String bid, int num);
List<SpDailyLog> getSpDailyLogs(Date start,Date end, String inoutType);
List<SpDailyLog> getSpPnSummaryLists(String inoutType);
}
......@@ -85,5 +85,20 @@ public class DataLogDaoImpl extends AbstractBaseDao implements IDataLogDao {
return results.getMappedResults();
}
@Override
public List<SpDailyLog> getSpPnSummaryLists(String inoutType) {
Criteria criteria=Criteria.where("partNumber").exists(true);
if (ObjectUtil.isNotEmpty(inoutType)) {
criteria = criteria.and("inOutType").is(inoutType);
}//过去一月
Aggregation agg = Aggregation.newAggregation(
Aggregation.match(criteria),
Aggregation.group("partNumber").count().as("value"),
Aggregation.project("value").and("partNumber").previousOperation()
);
AggregationResults<SpDailyLog> results = getMongoTemplate().aggregate(agg, getEntityClass(), SpDailyLog.class);
return results.getMappedResults();
}
}
......@@ -15,4 +15,6 @@ public interface IDataLogManager extends IBaseManager<DataLog> {
List<DataLog> findUnFinishedTasks();
List<SpDailyLog> getSpDailyLogs(Date start, Date end, String inoutType);
List<SpDailyLog> getSpPnSummaryLists(String inoutType);
}
......@@ -76,4 +76,10 @@ public class DataLogManagerImpl implements IDataLogManager {
return dataLogDao.getSpDailyLogs(start,end,inoutType);
}
@Override
public List<SpDailyLog> getSpPnSummaryLists(String inoutType) {
return dataLogDao.getSpPnSummaryLists( inoutType );
}
}
......@@ -19,7 +19,7 @@ import java.util.List;
@Data
@Document
public class DataLog extends BasePo implements Serializable {
public class DataLog extends BasePo implements Serializable ,Comparable<DataLog> {
public DataLog(){
......@@ -435,4 +435,9 @@ public class DataLog extends BasePo implements Serializable {
}
return false;
}
@Override
public int compareTo(DataLog o) {
return this.getId().compareTo(o.getId());
}
}
......@@ -702,11 +702,28 @@ public class TaskService {
}
});
return findEmptyPosInStorages(barcode, availbleStorageList, storageTaskCountMap, lastPosId);
return findEmptyPosInStorages(barcode, availbleStorageList, hasOutTaskStorageIds, 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 Set<String> hasOutTaskStorageIds, String lastPosId) {
//第一遍查找,先不查找有出库任务的料仓
for (Storage storage : availbleStorageList) {
if(hasOutTaskStorageIds.contains(storage.getId())){
continue;
}
try {
Collection<String> operatingPosIds = excludePosIds();
log.debug("尝试从[" + storage.getCid() + "]中为[" + barcode.getBarcode() + "]查找空位");
StoragePos pos = storagePosManager.getEmptyPosByStorage(storage, barcode, operatingPosIds, lastPosId);
if (pos != null) {
return pos;
}
} catch (Exception e) {
log.error("尝试从[" + storage.getCid() + "]中为[" + barcode.getBarcode() + "]查找空位失败:" + e.getMessage());
}
}
//第二遍查找,从所有料仓中查找
for (Storage storage : availbleStorageList) {
try {
Collection<String> operatingPosIds = excludePosIds();
......@@ -719,7 +736,6 @@ public class TaskService {
log.error("尝试从[" + storage.getCid() + "]中为[" + barcode.getBarcode() + "]查找空位失败:" + e.getMessage());
}
}
try {
String cids = "";
for (Storage storage : availbleStorageList) {
......
......@@ -14,6 +14,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
......@@ -51,14 +52,21 @@ public class MicronDeviceController {
@ResponseBody
@AnonymousAccess
public ResultBean getTaskCount( HttpServletRequest request) {
// String type = request.getParameter("type");
// 根据时间排序,获取所有任务,Wait和已完成的 任务不发
List<DataLog> dataLogs = taskService.getAllTasks();
// String[] types=new String[]{"pizzaBox","pcb","tray","reel"};
Collections.sort(dataLogs);
Map<String, Integer> resultMap = new HashMap<>();
for (DataLog task : dataLogs
) {
if(task.isEnd()||task.isFinished()||task.isCancel()){
continue;
}
if(task.isCheckOutTask()&&task.isWait()){
continue;
}
String taskType = MicronDataCache.GetMaterialType(task);
String key = taskType + "_out";
if (task.isPutInTask()) {
......
......@@ -16,10 +16,7 @@ import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
@Slf4j
@RestController
......@@ -64,9 +61,18 @@ public class MicronML5Controller {
}
Map<String, Integer> needShelfs = new HashMap<>();
// 根据时间排序,获取所有任务,Wait和已完成的 任务不发
List<DataLog> dataLogs = taskService.getAllTasks();
Collections.sort(dataLogs);
for (DataLog task : dataLogs
) {
if(task.isPutInTask()|| task.isEnd()||task.isFinished()||task.isCancel()){
continue;
}
if(task.isCheckOutTask()&&task.isWait()){
continue;
}
String taskType = MicronDataCache.GetMaterialType(task);
String shelf = MicronDataCache.getShelfType(taskType);
if (needShelfs.containsKey(shelf)) {
......
......@@ -86,6 +86,10 @@ public class MicronDataCache {
public static String GetMaterialType(DataLog dataLog){
return GetMaterialType(dataLog.getCid(),dataLog.getStorageId(),dataLog.getW(),dataLog.getH());
}
public static String getShelfType(DataLog dataLog){
String mType=GetMaterialType(dataLog);
return getShelfType(mType);
}
public static String getShelfType(String materialType){
if(materialType.equals(PIZZABOX)){
return "M01";
......
package com.neotel.smfcore.custom.micron20031;
import cn.hutool.core.util.ObjectUtil;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.neotel.smfcore.common.bean.PageData;
import com.neotel.smfcore.common.utils.QueryHelp;
import com.neotel.smfcore.core.device.util.DataCache;
import com.neotel.smfcore.core.storage.bean.InventoryItem;
import com.neotel.smfcore.core.storage.rest.dto.InventoryItemDto;
import com.neotel.smfcore.core.storage.rest.dto.StoragePosDto;
import com.neotel.smfcore.core.storage.rest.mapstruct.InventoryItemMapper;
import com.neotel.smfcore.core.storage.rest.mapstruct.StoragePosMapper;
import com.neotel.smfcore.core.storage.rest.query.InventoryQueryCriteria;
import com.neotel.smfcore.core.storage.rest.query.StoragePosFindCriteria;
import com.neotel.smfcore.core.storage.service.manager.IStoragePosManager;
import com.neotel.smfcore.core.storage.service.po.StoragePos;
import com.neotel.smfcore.core.system.service.manager.IDataLogManager;
import com.neotel.smfcore.custom.micron20031.bean.MInOutType;
import com.neotel.smfcore.custom.micron20031.bean.SpDailyLog;
import com.neotel.smfcore.custom.micron20031.bean.dto.SpDailyLogDto;
import com.neotel.smfcore.security.annotation.AnonymousAccess;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
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.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.stream.Collectors;
@Slf4j
@Api(tags = "20031:Inventory reports 库存报表")
@RestController
@RequestMapping("/rest/micron/sp/IReport")
@RequiredArgsConstructor
public class MicronInventoryReportsController {
@Autowired
private DataCache dataCache;
@Autowired
private InventoryItemMapper inventoryItemMapper;
@Autowired
private IStoragePosManager storagePosManager;
@Autowired
private StoragePosMapper storagePosMapper;
@Autowired
private IDataLogManager dataLogManager;
@ApiOperation("Inventory Chart(All) I2 :库存列表饼图报表")
@GetMapping(value = "/inventory")
@AnonymousAccess
public List<InventoryItemDto> inventory(InventoryQueryCriteria criteria, Pageable pageable) {
List<InventoryItemDto> results= getInventory(criteria, pageable);
return results;
}
private List<InventoryItemDto> getInventory(InventoryQueryCriteria criteria, Pageable pageable){
Map<String, InventoryItem> inventoryItemMap = dataCache.getAllInventory(criteria.getStorageIdList(),criteria.getBlurry());
List<InventoryItem> list = Lists.newArrayList(inventoryItemMap.values());
List<InventoryItemDto> dtoList = inventoryItemMapper.toDto(list);
List<InventoryItemDto> resultList = new ArrayList<>();
//过滤掉没有库存的
for (InventoryItemDto inventoryItemDto : dtoList) {
if(inventoryItemDto.getStockReel() > 0){
resultList.add(inventoryItemDto);
}
}
Comparator<InventoryItemDto> comparator = Comparator.comparing(InventoryItemDto::getPartNumber);
Sort.Order lockReelOrder = pageable.getSort().getOrderFor("lockReel");
if(lockReelOrder != null){
comparator = Comparator.comparing(InventoryItemDto::getStockReel,Comparator.nullsFirst(Integer::compareTo));
if(lockReelOrder.isDescending()){
comparator = comparator.reversed();
}
}
Sort.Order stockCountOrder = pageable.getSort().getOrderFor("stockCount");
if(stockCountOrder != null){
comparator = Comparator.comparing(InventoryItemDto::getStockCount,Comparator.nullsFirst(Integer::compareTo));
if(stockCountOrder.isDescending()){
comparator = comparator.reversed();
}
}
Sort.Order partNumberOrder = pageable.getSort().getOrderFor("partNumber");
if(partNumberOrder != null){
comparator = Comparator.comparing(InventoryItemDto::getPartNumber,Comparator.nullsFirst(String::compareTo));
if(partNumberOrder.isDescending()){
comparator = comparator.reversed();
}
}
resultList = resultList.stream().sorted(comparator).collect(Collectors.toList());
// System.out.println("================");
// for (InventoryItemDto dto : resultList) {
// System.out.println(dto.getPartNumber() + "---" + dto.getStockCount() + " --- " + dto.getStockReel());
// }
return resultList;
}
@ApiOperation("Inventory Detial Report- Detailed full inventory history I3:库存表格")
@GetMapping("/detialReport")
@AnonymousAccess
public PageData<StoragePosDto> storagePosFind(StoragePosFindCriteria criteria, Pageable pageable, HttpServletRequest request) {
Query query=getPosFindCriteria(criteria);
PageData<StoragePos> pages = storagePosManager.findByPage(query, pageable);
List<StoragePosDto> StoragePosDtos = storagePosMapper.toDto(pages.getContent());
return new PageData(StoragePosDtos, pages.getTotalElements());
}
private Query getPosFindCriteria(StoragePosFindCriteria criteria){
if (ObjectUtil.isNotEmpty(criteria.getStorageId()) && criteria.getStorageId().equals("0")) {
criteria.setStorageId(null);
}
Query query = QueryHelp.getQuery(criteria);
Criteria baseCriteria = Criteria.where("used").is(true);
int componentType = criteria.getComponentType();
if (componentType != -1) {
baseCriteria.and("barcode.type").is(componentType);
}
String expire = criteria.getExpire();
if (!Strings.isNullOrEmpty(expire)) {
if ("solder".equalsIgnoreCase(expire)) {
baseCriteria.and("barcode.expTime").lte(new Date());
} else if ("pcb".equalsIgnoreCase(expire)) {
baseCriteria.and("barcode.expireDate").lte(new Date());
}
}
query.addCriteria(baseCriteria);
return query;
}
@ApiOperation("Empty Bin Report- Empty storage bins I5: 空库位展示")
@GetMapping("/emptyPosReport")
@AnonymousAccess
public PageData<StoragePosDto> emptyPosReport(StoragePosFindCriteria criteria, Pageable pageable, HttpServletRequest request) {
//TODO 空库位展示
Query query=QueryHelp.getQuery(criteria);
Criteria baseCriteria = Criteria.where("used").is(false);
query.addCriteria(baseCriteria);
PageData<StoragePos> pages = storagePosManager.findByPage(query, pageable);
List<StoragePosDto> StoragePosDtos = storagePosMapper.toDto(pages.getContent());
return new PageData(StoragePosDtos, pages.getTotalElements());
}
@ApiOperation("Inventory Summary Report- Fresh & Partial material inventory I4:新料,退料,过期料")
@GetMapping("/summaryReport")
@AnonymousAccess
public List<SpDailyLogDto> materialList( ) {
//TODO 根据partNo排序,每种物料的 新料,退料,过期料数量
Criteria c = null;
List<SpDailyLog> results = dataLogManager.getSpPnSummaryLists("");
HashMap<String, SpDailyLogDto> dailyLogDtos = new HashMap<String, SpDailyLogDto>();
List<String> types = new ArrayList<>();
types.add(MInOutType.OFFLINE);
types.add(MInOutType.DESPOSIT);
types.add(MInOutType.REMOVED);
types.add(MInOutType.RETURNED);
types.add(MInOutType.WITHDRAWN);
types.add("");
for (String type : types) {
List<SpDailyLog> logs = dataLogManager.getSpPnSummaryLists(type);
for (SpDailyLog log :
logs) {
SpDailyLogDto dto = dailyLogDtos.getOrDefault(log.getPartNumber(), new SpDailyLogDto());
dto.setPartNumber(log.getPartNumber());
if (dto.getTypeCounts() == null) {
dto.setTypeCounts(new HashMap<>());
}
if(ObjectUtil.isEmpty(type)){
type="all";
}
dto.getTypeCounts().put(type, log.getValue());
dailyLogDtos.put(log.getPartNumber(), dto);
}
}
return new ArrayList<>(dailyLogDtos.values());
}
@ApiOperation("Self-Audit Report - Audit report(monthly-finance , when door is opened,etc) I7")
@GetMapping("/selfAuditReport")
public PageData<StoragePosDto> selfAuditReport(StoragePosFindCriteria criteria, Pageable pageable, HttpServletRequest request) {
//TODO 自检报告:包含库位号,part number,RFID信息,以及以上信息是否匹配
Query query=getPosFindCriteria(criteria);
PageData<StoragePos> pages = storagePosManager.findByPage(query, pageable);
List<StoragePosDto> StoragePosDtos = storagePosMapper.toDto(pages.getContent());
return new PageData(StoragePosDtos, pages.getTotalElements());
}
}
......@@ -32,7 +32,7 @@ import java.text.SimpleDateFormat;
import java.util.*;
@Slf4j
@Api(tags = "20031:Report 报表")
@Api(tags = "20031:Material movement report 报表")
@RestController
@RequestMapping("/rest/micron/sp")
@RequiredArgsConstructor
......@@ -102,7 +102,7 @@ public class MicronReportController {
start = time.getTime();
c = Criteria.where("createDate").gte(time.getTime()).lte(new Date());
}
List<SpDailyLog> results = dataLogManager.getSpDailyLogs(start, end, "");
// List<SpDailyLog> results = dataLogManager.getSpDailyLogs(start, end, "");
HashMap<String, SpDailyLogDto> dailyLogDtos = new HashMap<String, SpDailyLogDto>();
List<String> types = new ArrayList<>();
types.add(MInOutType.OFFLINE);
......
......@@ -21,5 +21,6 @@ public class SpDailyLog implements Serializable {
private int value;
private String partNumber;
}
......@@ -14,6 +14,8 @@ public class SpDailyLogDto implements Serializable {
private String dayOfYear;
private String partNumber;
private HashMap<String,Integer> typeCounts;
}
package com.neotel.smfcore.custom.sungya20456;
import com.neotel.smfcore.common.exception.ApiException;
import com.neotel.smfcore.common.exception.ValidateException;
import com.neotel.smfcore.common.utils.DateUtil;
import com.neotel.smfcore.common.utils.HttpHelper;
import com.neotel.smfcore.common.utils.JsonUtil;
import com.neotel.smfcore.common.utils.StringUtils;
import com.neotel.smfcore.core.api.bean.CodeValidateParam;
import com.neotel.smfcore.core.api.listener.BaseSmfApiListener;
import com.neotel.smfcore.core.barcode.service.manager.IBarcodeManager;
import com.neotel.smfcore.core.barcode.service.po.Barcode;
import com.neotel.smfcore.core.device.util.DataCache;
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.service.po.Storage;
import com.neotel.smfcore.core.system.service.po.DataLog;
import com.neotel.smfcore.custom.sungya20456.bean.Item;
import com.neotel.smfcore.custom.sungya20456.bean.SungyaResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.Map;
@Service
@Slf4j
public class SungyaApi extends BaseSmfApiListener {
@Autowired
private IBarcodeManager barcodeManager;
@Autowired
private ILiteOrderManager liteOrderManager;
@Autowired
private ILiteOrderItemManager liteOrderItemManager;
@Autowired
private DataCache dataCache;
@Override
public boolean isForThisApi(String apiName) {
return apiName != null && apiName.equalsIgnoreCase("sungya");
}
/**
* 入库判定接口
*
* @param inCheckUrl
* @param params
* @param barcode
* @return
* @throws ValidateException
*/
@Override
public Barcode canPutInAfterResolve(String inCheckUrl, CodeValidateParam params, Barcode barcode) throws ValidateException {
try {
Map<String, Object> paramMap = new HashMap<>();
paramMap.put("funcname", "INWHCK");
Map<String, String> bodyMap = new HashMap<>();
bodyMap.put("reelId", barcode.getBarcode());
bodyMap.put("fullCode", barcode.getFullCode());
paramMap.put("body", bodyMap);
log.info(barcode.getBarcode() + "入库验证,参数:" + JsonUtil.toJsonStr(paramMap));
String result = HttpHelper.postJson(inCheckUrl, paramMap);
log.info(barcode.getBarcode() + "入库验证,出参:" + result);
SungyaResult sungyaResult = JsonUtil.toObj(result, SungyaResult.class);
if ("1".equals(sungyaResult.getStatus())) {
Item item = sungyaResult.getItem();
//物料编号
if (StringUtils.isNotBlank(item.getPartNum())) {
barcode.setPartNumber(item.getPartNum());
}
//供应商信息
if (StringUtils.isNotBlank(item.getVendor())) {
barcode.setProvider(item.getVendor());
}
//物料数量
if (item.getQty() != null) {
barcode.setAmount(item.getQty());
}
//尺寸
if (item.getW() != null) {
barcode.setPlateSize(item.getW());
}
//厚度
if (item.getH() != null) {
barcode.setHeight(item.getH());
}
//生产日期
if (StringUtils.isNotBlank(item.getProduceDate())) {
barcode.setProduceDate(DateUtil.toDate(item.getProduceDate(), "yyyy-MM-dd HH:mm:ss"));
}
//过期时间
if (StringUtils.isNotBlank(item.getExpireDate())) {
barcode.setExpireDate(DateUtil.toDate(item.getExpireDate(), "yyyy-MM-dd HH:mm:ss"));
}
//批次
if (StringUtils.isNotBlank(item.getBatch())) {
barcode.setBatch(item.getBatch());
}
//搅拌时间(锡膏料仓使用)
if (item.getMixTime() != null) {
barcode.setMixTime(item.getMixTime());
}
return barcode;
} else {
throw new ValidateException("smfcore.mesApi.inCheck.error", "MES 返回NG[" + sungyaResult.getStatus() + "]:" + sungyaResult.get_returnmsg());
}
} catch (ApiException e) {
log.error("入库验证接口出错:" + e.getMessage());
throw new ValidateException("smfcore.mesApi.inCheck.error", "MES验证出错:" + e.getMessage());
}
}
/**
* 入库完成通知
*
* @param inNotifyUrl
* @param task
*/
@Override
public void inTaskStatusChange(String inNotifyUrl, DataLog task) {
if (task.isFinished()) {
try {
Map<String, Object> paramMap = new HashMap<>();
paramMap.put("funcname", "INWHDONE");
Map<String, String> bodyMap = new HashMap<>();
bodyMap.put("reelId", task.getBarcode());
bodyMap.put("location", task.getPosName());
bodyMap.put("source", "SMF");
bodyMap.put("fullCode", "");
Barcode barcode = barcodeManager.findByBarcode(task.getBarcode());
if (barcode != null) {
bodyMap.put("fullCode", barcode.getFullCode());
}
paramMap.put("body", bodyMap);
String requestParams = JsonUtil.toJsonStr(paramMap);
log.info(task.getBarcode() + "入库通知,参数" + requestParams);
String responseInfo = HttpHelper.postJson(inNotifyUrl, paramMap);
log.info(task.getBarcode() + "入库通知返回" + responseInfo);
} catch (Exception e) {
log.error("入库通知接口出错:" + e.getMessage());
}
}
}
/**
* 出库完成通知
*
* @param outNotifyUrl
* @param task
*/
@Override
public void outTaskStatusChange(String outNotifyUrl, DataLog task) {
try {
Map<String, Object> paramMap = new HashMap<>();
paramMap.put("funcname", "OUTWHDONE");
Map<String, Object> bodyMap = new HashMap<>();
bodyMap.put("source", "SMF");
bodyMap.put("reelId", task.getBarcode());
bodyMap.put("partNum", task.getPartNumber());
bodyMap.put("qty", task.getNum());
bodyMap.put("boxNo", "");
Storage storage = dataCache.getStorage(task.getCid());
if (storage != null) {
bodyMap.put("boxNo", storage.getName());
}
bodyMap.put("location", task.getPosName());
bodyMap.put("hSerial", "");
bodyMap.put("so", "");
bodyMap.put("slotNum", "");
bodyMap.put("feederInfo", "");
String sourceName = task.getSourceName();
if (StringUtils.isNotBlank(sourceName)) {
LiteOrder orderNo = liteOrderManager.findByOrderNo(sourceName);
if (orderNo != null) {
bodyMap.put("hSerial", orderNo.getOrderNo());
bodyMap.put("so", orderNo.getSo());
}
}
String subSourceId = task.getSubSourceId();
if (StringUtils.isNotBlank(subSourceId)) {
LiteOrderItem orderItem = liteOrderItemManager.get(subSourceId);
if (orderItem != null) {
bodyMap.put("slotNum", orderItem.getSlotNum());
bodyMap.put("feederInfo", orderItem.getFeederInfo());
}
}
paramMap.put("body", bodyMap);
String requestParams = JsonUtil.toJsonStr(paramMap);
log.info(task.getBarcode() + "出库完成通知,参数" + requestParams);
String result = HttpHelper.postJson(outNotifyUrl, paramMap);
log.info(task.getBarcode() + "出库完成通知返回" + result);
} catch (ApiException e) {
e.printStackTrace();
}
}
}
package com.neotel.smfcore.custom.sungya20456.bean;
import lombok.Data;
@Data
public class Item {
/**
* 物料编码
*/
private String partNum;
/**
* 供应商信息
*/
private String vendor;
/**
* 物料数量
*/
private Integer qty;
/**
* 尺寸
*/
private Integer w;
/**
* 厚度
*/
private Integer h;
/**
* 生产日期,格式为yyyy-MM-dd HH:mm:ss
*/
private String produceDate;
/**
* 过期时间,格式为 yyyy-MM-dd HH:mm:ss
*/
private String expireDate;
/**
* 批次信息
*/
private String batch;
/**
* 搅拌时间(锡膏料仓使用)
*/
private Integer mixTime;
}
package com.neotel.smfcore.custom.sungya20456.bean;
import lombok.Data;
@Data
public class SungyaResult {
/**
* 成功:”1”, 失败:”0”
*/
private String status;
/**
* 预留字段,暂时没用
*/
private String msgcode;
/**
* 返回提示消息
*/
private String _returnmsg;
/**
* 额外字段
*/
private Object returncnt;
/**
* 额外字段
*/
private Object exectms;
/**
* 定制传送明细
*/
private Item item;
}
支持 Markdown 格式
你添加了 0 到此讨论。请谨慎行事。
Finish editing this message first!