Commit 5a8586c2 zshaohui

1.工单关闭和清空库位增加权限密码

2.缺料预警设置指定时间生成出库任务
3.出库时调用不同的接口
4.解析物料供应商,批次修改
5.内外仓一键导入功能
6.外仓上传工单增加库别和线体
7.外仓工单出库优化
1 个父辈 0eebc292
正在显示 67 个修改的文件 包含 1225 行增加256 行删除
......@@ -235,6 +235,7 @@ public class DataInitManager {
addNewFunctionMenu(88,pMenuReport,"innerIssueReport","发料","innerIssueReport","innerWarehouse/issueReport/index","IssueRe",functionMenuMap);
addNewFunctionMenu(89,pMenuReport,"innerMaShortReport","缺料","innerMaShortReport","innerWarehouse/maShortReport/index","maShort",functionMenuMap);
addNewFunctionMenu(90,pMenuReport,"innerProLimitReport","禁限用","innerProLimitReport","innerWarehouse/proLimitReport/index","proLimit",functionMenuMap);
addNewFunctionMenu(91,pMenuReport,"imDetailsReport","导入明细","imDetailsReport","innerWarehouse/imDetailsReport/index","feeding",functionMenuMap);
//可观测性:物料追踪
......@@ -307,6 +308,25 @@ public class DataInitManager {
addNewFunctionMenu(1,null,"elecKanban", "电子看板","elecKanban", "elecKanban/index","kanban",functionMenuMap);
addNewFunctionMenu(135,null,"sysInventory", "盘点出库","sysInventory", "system/sysInventory/index","mIDList",functionMenuMap);
//汇总报表
Menu meMenuReport = Menu.CreatePMenu("汇总报表", 17, "meReport", 3, "inOutData",null);
Menu meOuterMenuReport = Menu.CreatePMenu("外仓", 18, "meOuterReport", 7, "inOutData",meMenuReport);
addNewFunctionMenu(136,meOuterMenuReport,"meIssueDetailsList","发料","meIssueDetailsList","report/mIssueDetailsList/index","IssueRe",functionMenuMap);
addNewFunctionMenu(137,meOuterMenuReport,"meProhibitedReport","禁限用","meProhibitedReport","report/prohibitedReport/index","proLimit",functionMenuMap);
addNewFunctionMenu(138,meOuterMenuReport,"meMPreListReport","备料清单","meMPreListReport","report/mPreListReport/index","mPreListReport",functionMenuMap);
addNewFunctionMenu(139,meOuterMenuReport,"meChangeReport","异动","meChangeReport","report/changeReport/index","chageReport",functionMenuMap);
addNewFunctionMenu(140,meOuterMenuReport,"meMShortageReport","缺料","meMShortageReport","report/mShortageReport/index","maShort",functionMenuMap);
addNewFunctionMenu(141,meOuterMenuReport,"mePkSearch","PK查询","mePkSearch","report/pkSearch/index","findOut",functionMenuMap);
addNewFunctionMenu(142,meOuterMenuReport,"meSysInReport","盘点","meSysInReport","report/sysInReport/index","mIDList",functionMenuMap);
Menu meInnerMenuReport = Menu.CreatePMenu("内仓", 19, "meInnerReport", 1, "inOutData",meMenuReport);
addNewFunctionMenu(143,meInnerMenuReport,"meInnerChangeReport","异动","meInnerChangeReport","report/inner/changeReport/index","chageReport",functionMenuMap);
addNewFunctionMenu(144,meInnerMenuReport,"meInnerMShortageReport","缺料","meInnerMShortageReport","report/inner/maShortReport/index","maShort",functionMenuMap);
addNewFunctionMenu(145,meInnerMenuReport,"meInnerProLimitReport","禁限用","meInnerProLimitReport","report/inner/proLimitReport/index","proLimit",functionMenuMap);
addNewFunctionMenu(136,meMenuReport,"meInventory","汇总库存","meInventory","report/inventory/index","inventory",functionMenuMap);
return functionMenuMap;
}
......
package com.neotel.smfcore.common.init;
import com.neotel.smfcore.common.utils.Constants;
import com.neotel.smfcore.core.device.util.DataCache;
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;
......@@ -29,19 +31,22 @@ public class MainTimer {
@Autowired
LiteOrderCache liteOrderCache;
public void init() {
initTask();
@Autowired
DataCache dataCache;
public void init() {
initTask();
liteOrderCache.loadUnEndOrderInfos();
log.info("主定时器开启,60秒后开始执行, 每300s执行一次");
log.info("主定时器开启,60秒后开始执行");
//1 分钟之后执行,每秒钟执行一次
scheduledThreadPool.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
timerTask();
}
}, 60, 300, TimeUnit.SECONDS);
}, 5, 10, TimeUnit.SECONDS);
//log.info("如果是人工叫料,则每2分钟执行一次");
scheduledThreadPool.scheduleAtFixedRate(new Runnable() {
......@@ -49,7 +54,7 @@ public class MainTimer {
public void run() {
timerTaskLz();
}
}, 60, 5, TimeUnit.SECONDS);
}, 5, 10, TimeUnit.SECONDS);
}
private void initTask() {
log.info("开始加载未完成的任务...");
......@@ -66,9 +71,13 @@ public class MainTimer {
log.info("加载未完成的任务完成,共[" + unExecuteTasks.size() + "]条数据...");
}
private void timerTask(){
try{
//log.info("机器叫料,每5分钟执行一次");
private void timerTask() {
if (!preGenerateTaskTime()) {
return;
}
lastPreGenerateTaskTime = System.currentTimeMillis();
try {
log.info("生成缺料预警任务");
PreWarningItemCache.runTimer(0);
//liteOrderCache.runTimer(0);
//设备状态判断
......@@ -76,9 +85,9 @@ public class MainTimer {
//其他设备状态判断
EquipStatusUtil.runTimer();
}catch (Exception e){
log.error("定时器执行出错",e);
}finally {
} catch (Exception e) {
log.error("定时器执行出错", e);
} finally {
}
}
......@@ -94,4 +103,22 @@ public class MainTimer {
log.error("定时器执行出错", e);
}
}
//判断当前时间与上一次执行时间相差时间是否与配置相同
private static long lastPreGenerateTaskTime = 0l;
private boolean preGenerateTaskTime() {
int min = 0;
try {
min = dataCache.getCache(Constants.CACHE_preGenerateTask);
} catch (Exception e) {
e.printStackTrace();
log.error("设置缺料预警执行时间报错");
dataCache.updateCache(Constants.CACHE_preGenerateTask,0);
}
if (min == 0) {
min = 5;
}
return System.currentTimeMillis() - lastPreGenerateTaskTime >= min * 60 * 1000 ? true : false;
}
}
......@@ -154,4 +154,20 @@ public class Constants {
* 上次自动存档时间
*/
public static final String LAST_BACKUP_TIME_KEY = "db.backup.lastTime";
/**
* 缺料预警生成工单时间
*/
public static final String CACHE_preGenerateTask = "preGenerateTask";
/**
* 权限密码
*/
public static final String CACHE_permissionPassword = "permissionPassword";
/**
* 楼层
*/
public static final String CACHE_floor = "floor";
}
......@@ -117,6 +117,18 @@ public class ReelLockPosUtil {
return lockPosIds;
}
public static boolean posIsLock(String posName){
boolean isLock = false;
for (ReelLockPosInfo info : reelLocKPosMap.values()) {
if (posName.equals(info.getLockPosName())){
isLock = true;
break;
}
}
return isLock;
}
public static Collection<ReelLockPosInfo> getAllReelLockPosInfo(){
return reelLocKPosMap.values();
}
......
......@@ -8,6 +8,7 @@ import com.neotel.smfcore.core.api.bean.CodeValidateParam;
import com.neotel.smfcore.core.device.util.DataCache;
import com.neotel.smfcore.core.order.service.po.LiteOrder;
import com.neotel.smfcore.core.system.service.po.DataLog;
import com.neotel.smfcore.custom.lizhen.LizhenApi;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.factory.annotation.Autowired;
......@@ -61,6 +62,9 @@ public class SmfApi {
@Value("${api.importUrl}")
protected String importUrl;
@Autowired
private LizhenApi lizhenApi;
@PostConstruct
public void init(){
apiName = dataCache.getConfigCache("api.name",apiName);
......@@ -178,4 +182,14 @@ public class SmfApi {
}
return false;
}
public void outTaskStatusChange(List<DataLog> dataLogList) {
for (ISmfApiListener apiListener : apiListenerList) {
if (apiListener.isForThisApi(apiName)) {
if (isUrlExist(outNotifyUrl)) {
apiListener.outTaskStatusChange(outNotifyUrl, dataLogList);
}
}
}
}
}
......@@ -82,6 +82,11 @@ public class DefaultSmfApiListener extends BaseSmfApiListener {
}
}
@Override
public void outTaskStatusChange(String outNotifyUrl, List<DataLog> dataLogList) {
}
private String getData(Map<String,Object> dataMap, String dataKey){
Object data = dataMap.get(dataKey);
if(data == null){
......
......@@ -6,6 +6,8 @@ import com.neotel.smfcore.core.api.bean.CodeValidateParam;
import com.neotel.smfcore.core.order.service.po.LiteOrder;
import com.neotel.smfcore.core.system.service.po.DataLog;
import java.util.List;
public interface ISmfApiListener {
/**
......@@ -24,6 +26,9 @@ public interface ISmfApiListener {
*/
void outTaskStatusChange(String outNotifyUrl, DataLog task);
void outTaskStatusChange(String outNotifyUrl, List<DataLog> dataLogList);
/**
* 是否可入库验证
*/
......
......@@ -556,14 +556,22 @@ public class BarcodeRule {
codeBean.setError("smfcore.error.barcode.noField",new String[]{"PN"}, "条码解析失败,未找到{0}字段");
return codeBean;
}
if(batch_item.hasThisField()){
if(batch_item.hasThisField()) {
String batch = batch_item.getStrValue(codeArr);
if (batch.indexOf("-") == -1){
if (batch.indexOf("-") == -1) {
log.info("条码解析失败,BATCH字段不合规则");
codeBean.setError("smfcore.error.barcode.noField",new String[]{"BATCH"},"条码解析失败,未找到{0}字段");
codeBean.setError("smfcore.error.barcode.noField", new String[]{"BATCH"}, "条码解析失败,未找到{0}字段");
return codeBean;
}
batch = batch.substring(0,batch.lastIndexOf("-"));
if (batch.contains(",")) {
String[] batchStr = batch.split(",");
for (String str : batchStr) {
batch = str.substring(0, str.lastIndexOf("-"));
break;
}
} else {
batch = batch.substring(0, batch.lastIndexOf("-"));
}
b.setBatch(batch);
}
int quantity = 0;
......@@ -574,6 +582,13 @@ public class BarcodeRule {
codeBean.setError("smfcore.error.barcode.noField",new String[]{"QTY"},"条码解析失败,未找到{0}字段");
return codeBean;
}
if (quantity == 0) {
if (!(codeStr.startsWith("CS") || codeStr.startsWith("CM") || codeStr.startsWith("CB"))) {
log.info("条码解析失败,未找到QTY 字段");
codeBean.setError("smfcore.error.barcode.noField", new String[]{"QTY"}, "条码解析失败,未找到{0}字段");
return codeBean;
}
}
}
Date produceDate= produceDate_item.getDateValue(codeArr);
......@@ -613,14 +628,28 @@ public class BarcodeRule {
b.setMemo(memo);
}
if (dateCode_item.hasThisField()){
if (dateCode_item.hasThisField()) {
String dateCode = dateCode_item.getStrValue(codeArr);
if (dateCode.indexOf("-") == -1){
if (dateCode.indexOf("-") == -1) {
log.info("条码解析失败,DATECODE字段不合规则");
codeBean.setError("smfcore.error.barcode.noField",new String[]{"DATECODE"},"条码解析失败,未找到{0}字段");
codeBean.setError("smfcore.error.barcode.noField", new String[]{"DATECODE"}, "条码解析失败,未找到{0}字段");
return codeBean;
}
dateCode = dateCode.substring(dateCode.lastIndexOf("-")+1);
//判断是否包含","
if (dateCode.contains(",")) {
String newDateCode = "";
String[] dateCodeStr = dateCode.split(",");
for (String str : dateCodeStr) {
if (StringUtils.isBlank(newDateCode)) {
newDateCode = str.substring(str.lastIndexOf("-") + 1);
} else {
newDateCode = newDateCode + "/" + str.substring(str.lastIndexOf("-") + 1);
}
}
dateCode = newDateCode;
} else {
dateCode = dateCode.substring(dateCode.lastIndexOf("-") + 1);
}
b.setDateCode(dateCode);
}
......@@ -867,6 +896,9 @@ public class BarcodeRule {
codeStr = "353S03035-620140|F10-9FHLF6-2302|15000|M35620140022302AF|QORVO|";
rule = "PN[-1:50:-1]PROVIDERNUMBER[-1:50:-1]|BATCH[-1:50:-1]DATECODE[-1:50:-1]|QTY|RI|SP|6";
codeStr = "=7X8=CS0010-1";
rule = "RI[0:6:2]PN[-1:2:-1]";
BarcodeRule br = BarcodeRule.newRule(rule);
Barcode b = br.toCodeBean(codeStr).getBarcode();
if(b != null){
......
......@@ -4,6 +4,7 @@ import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.neotel.smfcore.common.exception.ValidateException;
import com.neotel.smfcore.common.utils.DateUtil;
import com.neotel.smfcore.common.utils.StringUtils;
import com.neotel.smfcore.core.barcode.bean.BarcodeRule;
import com.neotel.smfcore.core.barcode.bean.CodeBean;
import com.neotel.smfcore.core.barcode.enums.COMPONENT_TYPE;
......@@ -20,6 +21,7 @@ import org.yaml.snakeyaml.comments.CommentType;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Locale;
/**
* Created by sunke on 2021/7/13.
......@@ -52,7 +54,7 @@ public class CodeResolve {
* 解析条码为单个 Barcode,自动保存到数据库
*/
public CodeBean resolveSingleCode(String barcodeItemStr,int type){
//barcodeItemStr = barcodeItemStr.toUpperCase(Locale.ROOT);
if(barcodeRuleList == null || barcodeRuleList.isEmpty()){
CodeBean codeBean = new CodeBean();
codeBean.setBarcode(null);
......@@ -94,7 +96,7 @@ public class CodeResolve {
codeBeanFromRule.setShowImg(component.getShowImg());
//如果已经确认尺寸,使用确认的尺寸
if (component.isSizeConfirmed() || ((component.hasSizeInfo()) && (!codeBeanFromRule.hasReelSizeInfo()))) {
if (component.isSizeConfirmed() /*|| ((component.hasSizeInfo()) && (!codeBeanFromRule.hasReelSizeInfo()))*/) {
codeBeanFromRule.setReelWidth(component.getPlateSize());
codeBeanFromRule.setReelHeight(component.getHeight());
......@@ -154,10 +156,27 @@ public class CodeResolve {
}
}
}
//判断供应商代码是否为空
String providerNumber = barcodeFromRule.getProviderNumber();
if (StringUtils.isNotBlank(providerNumber)){
barcode.setProviderNumber(providerNumber);
needUpdate = true;
}
//判断日期代码
String dateCode = barcodeFromRule.getDateCode();
if (StringUtils.isNotBlank(dateCode)){
barcode.setDateCode(dateCode);
needUpdate = true;
}
//判断批次
String batch = barcodeFromRule.getBatch();
if (StringUtils.isNotBlank(batch)){
barcode.setBatch(batch);
needUpdate = true;
}
if(needUpdate){
try {
barcodeManager.save(barcode);
barcode = barcodeManager.save(barcode);
}catch (Exception e){
log.error("",e);
}
......
package com.neotel.smfcore.core.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.web.PageableHandlerMethodArgumentResolver;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import java.util.List;
@Configuration
public class PageConfig extends WebMvcConfigurerAdapter {
private static final int PMP_MAX_PAGE_SIZE = 10000;
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
PageableHandlerMethodArgumentResolver resolver = new PageableHandlerMethodArgumentResolver();
resolver.setMaxPageSize(PMP_MAX_PAGE_SIZE);
argumentResolvers.add(resolver);
super.addArgumentResolvers(argumentResolvers);
}
}
......@@ -181,19 +181,21 @@ public class DeviceController {
StoragePos storagePos = storagePosManager.getByBarcode(barcode.getBarcode());
if (storagePos != null) {
Storage storage = dataCache.getStorageById(storagePos.getStorageId());
DataLog dataLog = new DataLog(storage, barcode, storagePos);
dataLog.setStatus(OP_STATUS.FINISHED.name());
dataLog.setExtendType(ExtendType.VIRTUAL_CHECKOUT); //虚拟出库
taskService.updateFinishedTask(dataLog);
taskService.removeFinishedTask(dataLog);
log.info("智能仓储入库,虚拟仓出库:" + barcode.getBarcode() + ",库位名称为:" + storagePos.getPosName());
storagePos.setBarcode(null);
barcode.setPosName(null);
barcode = barcodeManager.save(barcode);
//进行库位更改
storagePos.setUsed(false);
storagePosManager.save(storagePos);
dataCache.updateInventory(storagePos, barcode);
if (storage.isVirtual()) {
DataLog dataLog = new DataLog(storage, barcode, storagePos);
dataLog.setStatus(OP_STATUS.FINISHED.name());
dataLog.setExtendType(ExtendType.VIRTUAL_CHECKOUT); //虚拟出库
taskService.updateFinishedTask(dataLog);
taskService.removeFinishedTask(dataLog);
log.info("智能仓储入库,虚拟仓出库:" + barcode.getBarcode() + ",库位名称为:" + storagePos.getPosName());
storagePos.setBarcode(null);
barcode.setPosName(null);
barcode = barcodeManager.save(barcode);
//进行库位更改
storagePos.setUsed(false);
storagePosManager.save(storagePos);
dataCache.updateInventory(storagePos, barcode);
}
}
Barcode barcodeCanPutIn = smfApi.canPutInAfterResolve(barcode);
......
......@@ -6,6 +6,7 @@ import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.neotel.smfcore.common.exception.ValidateException;
import com.neotel.smfcore.common.utils.Constants;
import com.neotel.smfcore.core.barcode.bean.PlateSizeBean;
import com.neotel.smfcore.core.barcode.service.manager.IComponentManager;
import com.neotel.smfcore.core.barcode.service.po.Barcode;
import com.neotel.smfcore.core.barcode.service.po.Component;
......@@ -16,17 +17,15 @@ import com.neotel.smfcore.core.language.util.MessageUtils;
import com.neotel.smfcore.core.storage.bean.InventoryItem;
import com.neotel.smfcore.core.storage.enums.CHECKOUT_TYPE;
import com.neotel.smfcore.core.storage.enums.COMPATIBLE_TYPE;
import com.neotel.smfcore.core.storage.enums.DeviceType;
import com.neotel.smfcore.core.storage.service.manager.IStorageManager;
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.OrderSetting;
import com.neotel.smfcore.core.system.service.dao.ICacheItemDao;
import com.neotel.smfcore.core.system.service.dao.ISettingsDao;
import com.neotel.smfcore.core.barcode.bean.PlateSizeBean;
import com.neotel.smfcore.core.storage.service.manager.IStorageManager;
import com.neotel.smfcore.core.storage.service.manager.IStoragePosManager;
import com.neotel.smfcore.core.system.service.po.CacheItem;
import com.neotel.smfcore.core.system.service.po.Settings;
import com.neotel.smfcore.core.storage.service.po.Storage;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
......@@ -66,7 +65,6 @@ public class DataCache {
@Autowired
private IComponentManager componentManager;
/**
* 是否需要推送温湿度报警值
*/
......
......@@ -291,7 +291,9 @@ public class LiteOrderCache {
}
else if (task.isFinished()) {
order.setTotalFinishedReelCount(order.getTotalFinishedReelCount() + 1);
order.setFinishedReelCount(order.getFinishedReelCount() + 1);
if (task.getExtendType() != ExtendType.MANUAL_FEEDING) {
order.setFinishedReelCount(order.getFinishedReelCount() + 1);
}
String orderItemId = task.getSubSourceId();
List<LiteOrderItem> orderItems = order.getOrderItems();
List<LiteOrderItem> liteOrderItems = new ArrayList<>();
......@@ -544,10 +546,10 @@ public class LiteOrderCache {
//PN
do {
//首先按空闲料仓进行出库
pos = storagePosManager.findPartNumberInStorages(freeStorageIds, partNumber, excludePosIds, checkoutType);
pos = storagePosManager.findPartNumberInStorages(freeStorageIds, partNumber, excludePosIds, checkoutType,orderItem.getBrand());
//如果为空的话,则出全部的
if (pos == null) {
pos = storagePosManager.findPartNumberInStorages(availableStorageIds, partNumber, excludePosIds, checkoutType);
pos = storagePosManager.findPartNumberInStorages(availableStorageIds, partNumber, excludePosIds, checkoutType,orderItem.getBrand());
}
if (pos == null) {
break;
......@@ -557,6 +559,7 @@ public class LiteOrderCache {
} catch (ValidateException e) {
e.printStackTrace();
log.error(pos.getBarcode().getBarcode() + ":" + e.getMessage());
excludePosIds.add(pos.getId());
pos = null;
}
} while (pos == null);
......@@ -769,7 +772,7 @@ public class LiteOrderCache {
}
public synchronized String checkOutLiteOrderOut(String orderNo, boolean outBom,List<String> orderItemIds) {
public String checkOutLiteOrderOut(String orderNo, boolean outBom,List<String> orderItemIds) {
LiteOrder cacheOrder = liteOrderMap.get(orderNo);
if (cacheOrder == null) {
cacheOrder = liteOrderManager.findByOrderNo(orderNo);
......@@ -969,7 +972,8 @@ public class LiteOrderCache {
if (needOutPoss != null && !needOutPoss.isEmpty()) {
for (StoragePos pos : needOutPoss) {
Barcode barcode = pos.getBarcode();
DataLog task = new DataLog(dataCache.getStorageById(pos.getStorageId()), barcode, pos);
Storage storage = dataCache.getStorageById(pos.getStorageId());
DataLog task = new DataLog(storage, barcode, pos);
task.setSourceId(cacheOrder.getId());
task.setSourceName(cacheOrder.getOrderNo());
task.setSubSourceId(barcode.getLockName());
......@@ -977,6 +981,11 @@ public class LiteOrderCache {
task.setType(OP.CHECKOUT);
task.setCreator(SecurityUtils.getCurrentUsername());
task.setStatus(OP_STATUS.WAIT.name());
if (storage.isVirtual()){
task.setExtendType(ExtendType.VIRTUAL_CHECKOUT);
} else {
task.setExtendType(ExtendType.STORAGE_CHECKOUT);
}
try {
log.info("生成任务开始");
taskService.addTaskToExecute(task);
......
......@@ -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.utils.StringUtils;
import com.neotel.smfcore.core.device.util.DataCache;
import com.neotel.smfcore.core.order.LiteOrderCache;
import com.neotel.smfcore.core.order.enums.LITEORDER_SOURCE;
......@@ -18,6 +19,7 @@ import org.springframework.stereotype.Service;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;
/**
* Created by sunke on 2021/7/12.
......@@ -38,11 +40,6 @@ public class DefaultOrderFileListener implements IOrderFileListener {
@Override
public boolean handleOrderFile(File orderFile) {
String fileName = orderFile.getName();
//String backupFileName = fileName +"_" + System.currentTimeMillis();
//看数据库是否已有此工单
// if(!fileName.endsWith(".process") && fileName.endsWith("_result.txt")){
//
// }
if(isFileType(fileName,"csv")){
LiteOrder fileNameOrder = liteOrderManager.findBySource(fileName);
if(fileNameOrder == null){
......@@ -75,25 +72,76 @@ public class DefaultOrderFileListener implements IOrderFileListener {
}
}
log.info("watchOrderDir:新增加订单:" + liteOrder.getOrderNo() + ",共" + liteOrderItems.size() + "条工单详情");
String lineStr = "";
for (LiteOrderItem liteOrderItem : liteOrderItems) {
String line = liteOrderItem.getLine();
if (lineStr.contains(line)) {
continue;
} else {
if (StringUtils.isNotBlank(lineStr)) {
lineStr = lineStr + "," + line;
} else {
lineStr = line;
}
}
}
liteOrder.setLine(lineStr);
liteOrder.setSource(LITEORDER_SOURCE.OUTTER.name());
liteOrder = liteOrderManager.createWithItems(liteOrder);
liteOrderCache.addOrderToMap(liteOrder);
//resultFile = new File(localDir+File.separator + "sucess",backupFileName);
return true;
}
}
}catch (Exception e){
log.error("read order from file ["+orderFile.getAbsolutePath()+"] :",e);
//resultFile = new File(localDir+File.separator + "error",backupFileName);
}
}
//resultFile = new File(localDir+File.separator + "sucess",backupFileName);
}
return false;
}
@Override
public String verifyOrderFile(File orderFile) {
String fileName = orderFile.getName();
if (isFileType(fileName, "csv")) {
LiteOrder fileNameOrder = liteOrderManager.findBySource(fileName);
if (fileNameOrder == null) {
return verifyOrderFile(fileName,orderFile.getAbsolutePath());
}
}
return "";
}
private String verifyOrderFile(String fileName, String fileURL) {
CsvReader csvRead = null;
try {
OrderSetting orderSetting = dataCache.getOrderSetting();
csvRead = CsvReader.newReader(fileURL, "PN", orderSetting.getPn());
int lineIndex = csvRead.getIndex("LINE", orderSetting.getLine());
int warehouseCodeIndex = csvRead.getIndex("WAREHOUSECODE", orderSetting.getWarehouseCode());
while (csvRead.readRecord()) {
String[] lineValues = csvRead.getValues();
if (lineIndex != -1) {
String lineValue = lineValues[lineIndex];
if (StringUtils.isBlank(lineValue)) {
return "线别Line不能为空";
}
}
if (warehouseCodeIndex != -1){
String lineValue = lineValues[warehouseCodeIndex];
if (StringUtils.isBlank(lineValue)){
return "库别不能为空";
}
}
}
} catch (Exception ex) {
log.error("解析上传的工单出错:" + ex.toString());
} finally {
if (csvRead != null) {
csvRead.close();
}
}
return "";
}
public Map<String , List<LiteOrderItem>> readCsvFile(String fileName, String fileURL) {
......@@ -102,16 +150,13 @@ public class DefaultOrderFileListener implements IOrderFileListener {
fileName=fileName.replace(".csv","");
Map<String ,List<LiteOrderItem>> itemMap=new HashMap<>();
List<LiteOrderItem> items = Lists.newArrayList();
OrderSetting orderSetting = dataCache.getOrderSetting();
csvRead = CsvReader.newReader(fileURL,"PN", orderSetting.getPn());
int partNumberIndex = csvRead.getIndex("PN", orderSetting.getPn());
//int qtyIndex = csvRead.getIndex("QTY", orderSetting.getQty());
//int feederIndex = csvRead.getIndex("FEEDER", orderSetting.getFeeder());
//int riIndex = csvRead.getIndex("RI",orderSetting.getRi());
int soIndex = csvRead.getIndex("SO", orderSetting.getSo());
int reelCountIndex = csvRead.getIndex("REELCOUNT", orderSetting.getSo());
int lineIndex = csvRead.getIndex("LINE", orderSetting.getLine());
int warehouseCodeIndex = csvRead.getIndex("WAREHOUSECODE", orderSetting.getWarehouseCode());
int row = 1;
int newRowCount = 0;
......@@ -121,30 +166,10 @@ public class DefaultOrderFileListener implements IOrderFileListener {
row++;
String[] lineValues = csvRead.getValues();
String partNumber = lineValues[partNumberIndex];
//String ri="";
/*if(riIndex!=-1){
ri=lineValues[riIndex];
}*/
if (partNumber.isEmpty()/*&&ri.isEmpty()*/) {
log.warn("行[partNumber=" + partNumber + "]中PN和RI都 为空,此行忽略");
} else {
//int num = 1;
/*if (qtyIndex != -1) {
String numStr = lineValues[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[feederIndex];
}*/
String so=fileName;
if(soIndex!=-1){
so=lineValues[soIndex];
}
......@@ -152,15 +177,11 @@ public class DefaultOrderFileListener implements IOrderFileListener {
so=fileName;
}
LiteOrderItem item = new LiteOrderItem();
item.setManualUpload(true);
item.setPn(partNumber);
if(partNumber.isEmpty()){
item.setNeedReelCount(1);
}
//item.setNeedNum(num);
//item.setFeederInfo(feeder);
//item.setRi(ri);
int count = 1;
if (reelCountIndex != -1) {
String countStr = lineValues[reelCountIndex];
......@@ -174,12 +195,18 @@ public class DefaultOrderFileListener implements IOrderFileListener {
}
item.setNeedReelCount(count);
if (lineIndex != -1){
String lineValue = lineValues[lineIndex];
item.setLine(lineValue);
}
if (warehouseCodeIndex != -1){
String warehouseCodeValue = lineValues[warehouseCodeIndex];
item.setWarehouseCode(warehouseCodeValue);
}
if(!itemMap.containsKey(so)){
itemMap.put(so,new ArrayList<LiteOrderItem>());
}
itemMap.get(so).add(item);
items.add(item);
}
}
......
......@@ -9,4 +9,5 @@ public interface IOrderFileListener {
boolean handleOrderFile(File orderFile);
String verifyOrderFile(File orderFile);
}
......@@ -3,6 +3,7 @@ package com.neotel.smfcore.core.order.rest;
import cn.hutool.core.util.ObjectUtil;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.neotel.smfcore.common.bean.PageData;
import com.neotel.smfcore.common.bean.ResultBean;
import com.neotel.smfcore.common.exception.ValidateException;
......@@ -16,6 +17,7 @@ import com.neotel.smfcore.core.barcode.service.po.Barcode;
import com.neotel.smfcore.core.barcode.utils.CodeResolve;
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.order.LiteOrderCache;
import com.neotel.smfcore.core.order.enums.LITEORDER_SOURCE;
import com.neotel.smfcore.core.order.enums.LITEORDER_STATUS;
......@@ -57,10 +59,13 @@ import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;
@Slf4j
......@@ -111,6 +116,11 @@ public class OrderController {
@Autowired
SmfApi smfApi;
@Autowired
DataCache dataCache;
Map<String,Long> onClickWorkOrderOut = Maps.newConcurrentMap();
// @ApiOperation("导出用户数据")
// @GetMapping(value = "/download")
// @PreAuthorize("@el.check('user:list')")
......@@ -131,48 +141,18 @@ public class OrderController {
}
File folder = new File(properties.getPath(), "pos");
File localFile = FileUtil.upload(orderFile, folder.getAbsolutePath());
String result = orderFileWatch.verifyOrderFile(localFile);
if (StringUtils.isNotBlank(result)){
return ResultBean.newErrorResult(-1,"",result);
}
orderFileWatch.handleOrderFile(localFile);
// 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()
// ) {
//
// List<LiteOrderItem> liteOrderItems = itemMap.get(so);
// if (liteOrderItems.size() <= 0) {
// continue;
// }
// LiteOrder liteOrder = new LiteOrder(so, liteOrderItems);
// liteOrder.setSource(localFile.getName());
// LiteOrder dbOrder = liteOrderManager.findByOrderNo(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, "smfcore.order.ameExists", "工单名称[{0}]已存在", new String[]{liteOrder.getOrderNo()});
// }
// }
// log.info("新增加订单:" + liteOrder.getOrderNo() + ",共" + liteOrderItems.size() + "条工单详情");
// liteOrder = liteOrderManager.createWithItems(liteOrder);
// liteOrderCache.addOrderToMap(liteOrder);
// }
return ResultBean.newOkResult("smfcore.order.uploadOK", "工单上传成功", "");
}
@ApiOperation("工单出库")
@PostMapping(value = "/out")
@PreAuthorize("@el.check('workOrder')")
public synchronized ResultBean checkOut(@RequestBody Map<String, String> mapValues) {
public ResultBean checkOut(@RequestBody Map<String, String> mapValues) {
String orderNo = mapValues.get("orderNo");
if (orderNo == null) {
throw new ValidateException("smfcore.valueCanotNull", "{0}不能为空", new String[]{"orderNo"});
......@@ -181,13 +161,21 @@ public class OrderController {
if (liteOrder == null) {
throw new ValidateException("smfcore.valueNotFind", "未找到{0}[{1}]", new String[]{"orderNo", orderNo});
}
synchronized (this) {
Long time = onClickWorkOrderOut.get(orderNo);
if (time != null && System.currentTimeMillis() - time < 1000 * 1 * 60 * 60) {
return ResultBean.newErrorResult(-1, "", orderNo + "已经在执行工单出库,请勿重复点击");
}
onClickWorkOrderOut.put(orderNo, System.currentTimeMillis());
}
log.info("开始执行工单出库:" + orderNo);
String result = "";
if (LITEORDER_SOURCE.OUTTER.name().equals(liteOrder.getSource())) {
result = liteOrderCache.checkOutLiteOrderOut(liteOrder.getOrderNo(),false,null);
result = liteOrderCache.checkOutLiteOrderOut(liteOrder.getOrderNo(), false, null);
} else {
result = liteOrderCache.checkOutLiteOrder(liteOrder.getOrderNo(), false);
}
onClickWorkOrderOut.remove(orderNo);
if (ObjectUtil.isEmpty(result)) {
return ResultBean.newOkResult(result);
} else {
......@@ -417,7 +405,17 @@ public class OrderController {
if (orderNo == null) {
throw new ValidateException("smfcore.valueCanotNull", "{0}不能为空", new String[]{"orderNo"});
}
//判断是否有权限密码
String permissionPasswordCache = dataCache.getCache(Constants.CACHE_permissionPassword);
if (StringUtils.isNotBlank(permissionPasswordCache)) {
String permissionPassword = mapValues.get("permissionPassword");
if (StringUtils.isBlank(permissionPassword)) {
throw new ValidateException("smfcore.valueCanotNull", "{0}不能为空", new String[]{"permissionPassword"});
}
if (!permissionPasswordCache.equals(permissionPassword)) {
throw new ValidateException("smfcore.error.permissionPassword", "权限密码错误");
}
}
String result = liteOrderCache.closeOrder(orderNo);
if (ObjectUtil.isEmpty(result)) {
return ResultBean.newOkResult(result, result, result);
......
......@@ -134,6 +134,7 @@ public class LiteOrder extends BasePo implements Serializable {
*/
private boolean confirmExcess = false;
public void setClosed(boolean value){
this.closed=value;
if(value){
......
......@@ -198,6 +198,11 @@ public class LiteOrderItem extends BasePo implements Serializable ,Comparable<Li
private String reel;
/**
* 是否人工上传
*/
private boolean isManualUpload = false;
/**
* 出库是否满足要求,已出库数量大于需求数量
*/
public boolean isOutFinished(){
......
......@@ -4,6 +4,7 @@ import cn.hutool.core.util.ObjectUtil;
import com.google.common.collect.Lists;
import com.neotel.smfcore.common.csv.CsvReader;
import com.neotel.smfcore.common.utils.SmbUtil;
import com.neotel.smfcore.common.utils.StringUtils;
import com.neotel.smfcore.core.device.util.DataCache;
import com.neotel.smfcore.core.order.LiteOrderCache;
import com.neotel.smfcore.core.order.listener.IOrderFileListener;
......@@ -128,6 +129,7 @@ public class OrderFileWatch {
private String getLocalDir(String orderDir){
//String[] fileTypes=new String[]{"csv","xml","txt"};
String localDir = orderDir;
......@@ -178,4 +180,16 @@ public class OrderFileWatch {
}
return localDir;
}
//校验工单文件数据
public String verifyOrderFile(File orderFile) {
log.info("开始处理Order文件:" + orderFile.getAbsolutePath());
for (IOrderFileListener orderFileListener : orderFileListenerList) {
String result = orderFileListener.verifyOrderFile(orderFile);
if (StringUtils.isNotBlank(result)) {
return result;
}
}
return "";
}
}
......@@ -32,6 +32,7 @@ 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.TaskService;
import com.neotel.smfcore.custom.lizhen.innerBox.enums.ExtendType;
import com.neotel.smfcore.custom.siemens.SiemensApi;
import com.neotel.smfcore.security.annotation.AnonymousAccess;
import io.swagger.annotations.Api;
......@@ -113,6 +114,9 @@ public class StoragePosController {
Storage storage=dataCache.getStorageById(StoragePosDtos.get(i).getStorageId());
if(storage!=null){
StoragePosDtos.get(i).setStorageName(storage.getName());
if (!storage.isVirtual()){
StoragePosDtos.get(i).setNeedPermissionPassword(true);
}
}
}
return new PageData(StoragePosDtos, pages.getTotalElements());
......@@ -198,6 +202,21 @@ public class StoragePosController {
if (storagePos != null) {
try {
log.info("开始手动清空库位[" + storagePos.getPosName() + "]");
//排除虚拟仓密码加密
Storage storage = dataCache.getStorageById(storagePos.getStorageId());
if (!storage.isVirtual()) {
//判断是否有权限密码
String permissionPasswordCache = dataCache.getCache(Constants.CACHE_permissionPassword);
if (StringUtils.isNotBlank(permissionPasswordCache)) {
String permissionPassword = map.get("permissionPassword");
if (StringUtils.isBlank(permissionPassword)) {
throw new ValidateException("smfcore.valueCanotNull", "{0}不能为空", new String[]{"permissionPassword"});
}
if (!permissionPasswordCache.equals(permissionPassword)) {
throw new ValidateException("smfcore.error.permissionPassword", "权限密码错误");
}
}
}
// QisdaApi.ClearStockBy(storagePos.getPosName());
Barcode barcode = storagePos.getBarcode();
if (barcode != null) {
......@@ -319,15 +338,12 @@ public class StoragePosController {
map.put("是否可用", pos.isEnabled() ? "是" : "否");
map.put("条码", null);
map.put("料件编号", null);
map.put("是否锁定", null);
boolean isLock = ReelLockPosUtil.posIsLock(pos.getPosName());
map.put("是否锁定", isLock ? "是" : "否");
Barcode barcode = pos.getBarcode();
if (barcode != null) {
map.put("条码", barcode.getBarcode());
map.put("料件编号", barcode.getPartNumber());
String reelLockPosId = ReelLockPosUtil.getReelLockPosId(barcode.getBarcode());
if (StringUtils.isNotBlank(reelLockPosId)) {
map.put("是否锁定", "是");
}
}
list.add(map);
}
......@@ -498,7 +514,8 @@ public class StoragePosController {
}
if (hasOutReel) {
DataLog task = new DataLog(dataCache.getStorageById(pos.getStorageId()), pos.getBarcode(), pos);
Storage storage = dataCache.getStorageById(pos.getStorageId());
DataLog task = new DataLog(storage, pos.getBarcode(), pos);
task.setType(OP.CHECKOUT);
task.setPutInDate(pos.getBarcode().getPutInDate());
task.setStatus(OP_STATUS.WAIT.name());
......@@ -509,6 +526,11 @@ public class StoragePosController {
task.setLoc(stationName);
}
task.setBoxPosName(pos.getPosName());
if (storage.isVirtual()){
task.setExtendType(ExtendType.VIRTUAL_CHECKOUT);
} else {
task.setExtendType(ExtendType.STORAGE_CHECKOUT);
}
//task.setPosId(pos.getId());
taskService.updateQueueTask(task);
}
......
......@@ -12,6 +12,7 @@ import java.util.List;
@Getter
@Setter
public class StoragePosDto implements Serializable {
@ApiModelProperty("库位ID")
private String id;
......@@ -80,4 +81,10 @@ public class StoragePosDto implements Serializable {
@ApiModelProperty("盘点状态")
private String inventoryStatus = "";
@ApiModelProperty("是否需要权限密码")
private boolean needPermissionPassword = false;
@ApiModelProperty("来源")
public String source;
}
......@@ -33,6 +33,8 @@ public interface IStoragePosManager extends IBaseManager<StoragePos> {
StoragePos findPartNumberInStorages(List<String> storageIdList,String labelId, String pn, Collection<String> excludePosIds, CHECKOUT_TYPE checkOutType);
StoragePos findPartNumberInStorages(List<String> storageIdList, String pn, Collection<String> excludePosIds, CHECKOUT_TYPE checkOutType,String brand);
List<StoragePos> findByQuery(Query query, Pageable pageable);
void removePosByStorageId(String storageId);
......
......@@ -334,6 +334,31 @@ public class StoragePosManagerImpl implements IStoragePosManager {
return pos;
}
@Override
public StoragePos findPartNumberInStorages(List<String> storageIdList, String pn, Collection<String> excludePosIds, CHECKOUT_TYPE checkOutType, String brand) {
Criteria c = Criteria.where("barcode.partNumber").is(pn)
.and("id").nin(excludePosIds)
.and("enabled").is(true)//可用
.and("barcode.lockId").is(null);//没有被锁定的仓位;
if (storageIdList != null) {
c = c.and("storageId").in(storageIdList);
}
if (StringUtils.isNotBlank(brand)) {
c.and("barcode.provider").is(brand);
}
Query q = new Query(c);
//Sort sort = getSortByCheckOutType(checkOutType);
Sort sort = Sort.by(Sort.Direction.ASC, "barcode.amount", "barcode.putInDate");
q.with(sort);
StoragePos pos = storagePosDao.findOne(q);
if (pos == null) {
log.info("使用" + checkOutType + " 策略出库 partNumber=" + pn + ",未找到可以出库的物料 ");
} else {
log.info("使用" + checkOutType + " 策略出库 partNumber=" + pn + ",找到出仓位置【" + pos.getPosName() + "】,RI【" + pos.getBarcode().getBarcode() + "】 ");
}
return pos;
}
@Override
public StoragePos findPartNumberInStorages(List<String> storageIdList, String pn, Collection<String> excludePosIds, CHECKOUT_TYPE checkOutType, String warehouseCode, String brand, boolean isOut) {
......
......@@ -137,6 +137,11 @@ public class StoragePos extends BasePo implements Serializable {
*/
private String inventoryStatus = "";
/**
* 来源
*/
private String source;
public String getLabelStr(){
String posNameLabel = posName;
int index = posNameLabel.lastIndexOf(":");
......
......@@ -25,6 +25,10 @@ public class OrderSetting implements Serializable {
public String reelCount = "REELCOUNT";
private String line = "LINE";
private String warehouseCode = "WAREHOUSECODE";
/**
* 是否显示料架亮灯方式
*/
......
......@@ -72,10 +72,16 @@ public class SettingsController {
boolean stopOut = dataCache.getCache(Constants.CACHE_StopOut);
boolean startJob = dataCache.getCache(Constants.CACHE_StartJob);
Integer backUpMonth = dataCache.getCache(Constants.BACKUP_MONTH_KEY);
Integer preGenerateTask = dataCache.getCache(Constants.CACHE_preGenerateTask);
String permissionPassword = dataCache.getCache(Constants.CACHE_permissionPassword);
String floor = dataCache.getCache(Constants.CACHE_floor);
SysSettingsDto dto = new SysSettingsDto();
dto.setStartJob(startJob);
dto.setStopOut(stopOut);
dto.setBackUpMonth(backUpMonth);
dto.setPreGenerateTask(preGenerateTask);
dto.setPermissionPassword(permissionPassword);
dto.setFloor(floor);
return dto;
}
......@@ -85,10 +91,17 @@ public class SettingsController {
public ResultBean updateSysSettings(@Validated @RequestBody SysSettingsDto sysSettingsDto) {
dataCache.updateCache(Constants.CACHE_StopOut, sysSettingsDto.isStopOut());
dataCache.updateCache(Constants.CACHE_StartJob, sysSettingsDto.isStartJob());
dataCache.updateCache(Constants.BACKUP_MONTH_KEY,sysSettingsDto.getBackUpMonth());
log.info("更改系统设置:stopout=" + sysSettingsDto.isStopOut() + ",stopjob=" + sysSettingsDto.isStartJob()+",backUpMonth="+sysSettingsDto.getBackUpMonth());
dataCache.updateCache(Constants.BACKUP_MONTH_KEY, sysSettingsDto.getBackUpMonth());
dataCache.updateCache(Constants.CACHE_preGenerateTask, sysSettingsDto.getPreGenerateTask());
dataCache.updateCache(Constants.CACHE_permissionPassword,sysSettingsDto.getPermissionPassword());
dataCache.updateCache(Constants.CACHE_floor,sysSettingsDto.getFloor());
log.info("更改系统设置:stopout=" + sysSettingsDto.isStopOut() + ",stopjob=" + sysSettingsDto.isStartJob()
+ ",backUpMonth=" + sysSettingsDto.getBackUpMonth()
+ ",preGenerateTask=" + sysSettingsDto.getPreGenerateTask()
+ ",permissionPassword=" + sysSettingsDto.getPermissionPassword()
+ ",floor=" + sysSettingsDto.getFloor()
);
return ResultBean.newOkResult("保存成功");
}
@ApiOperation("获取出库策略信息")
......@@ -196,6 +209,8 @@ public class SettingsController {
titles.add(orderSetting.getRi());
titles.add(orderSetting.getSo());*/
titles.add(orderSetting.getReelCount());
titles.add(orderSetting.getLine());
titles.add(orderSetting.getWarehouseCode());
for(int i=1;i<=10;i++) {
Map<String, Object> map = new LinkedHashMap<>();
......@@ -206,6 +221,8 @@ public class SettingsController {
map.put(orderSetting.getRi(),"");
map.put(orderSetting.getSo(),"WO1001" );*/
map.put(orderSetting.getReelCount(),i);
map.put(orderSetting.getLine(),"line");
map.put(orderSetting.getWarehouseCode(),"W10B");
}
else{
map.put(orderSetting.getPn(),"PN2"+i);
......@@ -214,6 +231,8 @@ public class SettingsController {
map.put(orderSetting.getRi(),"");
map.put(orderSetting.getSo(),"WO1002" );*/
map.put(orderSetting.getReelCount(),i);
map.put(orderSetting.getLine(),"line");
map.put(orderSetting.getWarehouseCode(),"W10B");
}
maps.add(map);
}
......
......@@ -104,56 +104,44 @@ public class TaskController {
@PreAuthorize("@el.check('taskLog')")
public void download(HttpServletResponse response, TaskQueryCondition criteria, Pageable pageable, HttpServletRequest request) throws IOException {
Query query = getQuery(criteria);
FileUtil.downloadExcel(query, pageable, response, new IExcelDownLoad() {
@Override
public List<List<String>> getHeader() {
List<List<String>> headerList = new ArrayList<>();
headerList.add(Lists.newArrayList("料件编号"));
headerList.add(Lists.newArrayList("条码编号"));
headerList.add(Lists.newArrayList("料仓名称"));
headerList.add(Lists.newArrayList("数量"));
headerList.add(Lists.newArrayList("类型"));
headerList.add(Lists.newArrayList("来源"));
headerList.add(Lists.newArrayList("状态"));
headerList.add(Lists.newArrayList("操作人"));
headerList.add(Lists.newArrayList("创建时间"));
headerList.add(Lists.newArrayList("更新时间"));
return headerList;
}
//dataLogManager.download(query, pageable, response,request.getLocale());
// FileUtil.downloadExcel(query, pageable, response, new IExcelDownLoad() {
// @Override
// public List<List<String>> getHeader() {
// List<List<String>> header = new ArrayList<>();
// header.add(Lists.newArrayList("类型"));
// header.add(Lists.newArrayList("单号"));
// header.add(Lists.newArrayList("料仓名称"));
// header.add(Lists.newArrayList("条码编号"));
// header.add(Lists.newArrayList("料件编号"));
// header.add(Lists.newArrayList("批次"));
// header.add(Lists.newArrayList("数量"));
// header.add(Lists.newArrayList("用户"));
//
// header.add(Lists.newArrayList("供应商"));
// header.add(Lists.newArrayList("来源二"));
// header.add(Lists.newArrayList("状态"));
// header.add(Lists.newArrayList("更新时间"));
// return header;
// }
//
// @Override
// public List<List<Object>> getPageData(Query query, Pageable pageable) {
// List<List<Object>> dataList = new ArrayList<>();
// List<DataLog> dataLogList = dataLogManager.findByQuery(query, pageable);
// DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
// for (DataLog dataLog : dataLogList) {
// List<Object> data = new ArrayList<>();
//
// data.add(dataLog.getDetailTypeStr());//"类型"
// data.add(dataLog.getSourceName());//"单号"
// data.add(dataLog.getPosName());//"料仓名称"
// data.add(dataLog.getBarcode());//"条码编号"
// data.add(dataLog.getPartNumber());//"料件编号"
// data.add(dataLog.getBatchInfo());//"批次"
// data.add(dataLog.getReelQty());//"数量"
// data.add(dataLog.getOperator());//"用户"
//
// data.add(dataLog.getProvider());//"供应商"
// data.add(dataLog.getSubSourceInfo());//"来源二"
// data.add(dataLog.getStatusStr());//"状态"
// String updateTimeStr = dateFormat.format(dataLog.getUpdateDate());
// data.add(updateTimeStr);//"更新时间"
// dataList.add(data);
// }
// return dataList;
// }
// });
@Override
public List<List<Object>> getPageData(Query query, Pageable pageable) {
List<List<Object>> dataList = new ArrayList<>();
PageData<DataLog> data = dataLogManager.findByPage(query, pageable);
for (DataLog dataLog : data.getContent()) {
List<Object> result = new ArrayList<>();
result.add(dataLog.getPartNumber());
result.add(dataLog.getBarcode());
result.add(dataLog.getPosName()+" "+dataLog.getStorageName());
result.add(dataLog.getNum());
result.add(dataLog.getType() == 1 ? "入库" : "出库");
result.add(dataLog.getSourceName());
result.add(dataLog.getStatus());
result.add(dataLog.getCreator());
result.add(dataLog.getCreateDate());
result.add(dataLog.getUpdateDate());
dataList.add(result);
}
return dataList;
}
});
}
@ApiOperation("获取某个分组队列中的任务")
......
......@@ -17,5 +17,14 @@ public class SysSettingsDto implements Serializable {
private boolean startJob = false;
@ApiModelProperty("备份时间")
private Integer backUpMonth=0;
private Integer backUpMonth = 0;
@ApiModelProperty("缺料预警生成工单时间")
private Integer preGenerateTask = 0;
@ApiModelProperty("权限密码")
private String permissionPassword = "";
@ApiModelProperty("楼层信息")
private String floor="";
}
......@@ -3,6 +3,7 @@ package com.neotel.smfcore.core.system.service.manager;
import com.neotel.smfcore.common.base.IBaseManager;
import com.neotel.smfcore.core.system.service.po.DataLog;
import org.springframework.data.domain.Pageable;
import org.springframework.data.mongodb.core.query.Query;
import java.util.Date;
import java.util.List;
......@@ -15,4 +16,8 @@ public interface IDataLogManager extends IBaseManager<DataLog> {
List<DataLog> getDatalogs(String orderNo, String line, Pageable pageable);
int getInOutData(Date startDate, Date endDate, int type,String stationName);
int countBySourceName(String barcodeStr, String orderNo);
int countByQuery(Query subSourceId);
}
......@@ -100,6 +100,7 @@ public class DataLogManagerImpl implements IDataLogManager {
Pattern p = Pattern.compile(QueryHelp.escapeExprSpecialWord(line), Pattern.CASE_INSENSITIVE);
c.and("line").regex(p);
}
c.and("status").is(OP_STATUS.FINISHED.name());
PageData<DataLog> data = findByPage(new Query(c), pageable);
//log.info("orderNo:"+orderNo+",line:"+line+",数量为:"+data.getTotalElements());
return data.getContent();
......@@ -116,4 +117,16 @@ public class DataLogManagerImpl implements IDataLogManager {
}
return dataLogDao.countByQuery(query.addCriteria(criteria));
}
@Override
public int countBySourceName(String barcodeStr, String orderNo) {
Query query = new Query();
Criteria criteria = Criteria.where("sourceName").is(orderNo).and("barcode").is(barcodeStr);
return dataLogDao.countByQuery(query.addCriteria(criteria));
}
@Override
public int countByQuery(Query query) {
return dataLogDao.countByQuery(query);
}
}
......@@ -318,9 +318,20 @@ public class DataLog extends BasePo implements Serializable {
private MSDAppendInfo msdAppendInfo;
/**
* 是否人工上传
*/
private boolean isManualUpload = false;
/**
* 是否整箱出库
*/
private boolean isBoxOut = false;
/**
* 出库类型(手动喂料,清空库位,智能仓储出库,手动出库,虚拟仓入库,虚拟仓出库,智能仓储入库)
*/
private int extendType;
private int extendType = -1;
public String getBarcode() {
if(barcode == null){
......@@ -351,6 +362,10 @@ public class DataLog extends BasePo implements Serializable {
return OP_STATUS.EXECUTING.name().equals(status);
}
public boolean isOnInnerLine(){
return OP_STATUS.ON_INNER_LINE.name().equals(status);
}
public boolean isFinished(){
return OP_STATUS.FINISHED.name().equals(status);
}
......
......@@ -13,6 +13,7 @@ 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.core.system.service.po.Humiture;
import com.neotel.smfcore.custom.lizhen.innerBox.bean.VirImportLog;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
......@@ -59,12 +60,12 @@ public class DbBackupService {
if(dbBackupMonth != null && dbBackupMonth > 0){
Date lastBackupTime = dataCache.getCache(Constants.LAST_BACKUP_TIME_KEY);
boolean needBackup = false;
if(lastBackupTime == null){
if(lastBackupTime == null) {
needBackup = true;
}else{
long monthNum = cn.hutool.core.date.DateUtil.betweenMonth(lastBackupTime, new Date(), true);
if(monthNum >= 1){
//未备份过的或上次备份时间距当前一个月的,进行备份
}else {
long dayNum = cn.hutool.core.date.DateUtil.betweenDay(lastBackupTime, new Date(), true);
if (dayNum >= 7) {
//备份超过7天就进行备份
needBackup = true;
}
}
......@@ -93,7 +94,7 @@ public class DbBackupService {
processing = true;
Integer dbBackupMonth = dataCache.getCache(Constants.BACKUP_MONTH_KEY);
if(dbBackupMonth == null){
dbBackupMonth = 12;//默认备份12个月前的数据
dbBackupMonth = 6;//默认备份6个月前的数据
dataCache.updateCache(Constants.BACKUP_MONTH_KEY,dbBackupMonth);
}
backupTable(dbBackupMonth,
......@@ -104,7 +105,8 @@ public class DbBackupService {
InList.class,
InListItem.class,
Message.class,
AlarmInfo.class
AlarmInfo.class,
VirImportLog.class
);
dataCache.updateCache(Constants.LAST_BACKUP_TIME_KEY,new Date());
processing = false;
......
......@@ -19,6 +19,7 @@ import com.neotel.smfcore.core.device.enums.OP_STATUS;
import com.neotel.smfcore.core.device.util.DataCache;
import com.neotel.smfcore.core.message.util.DeviceMessageUtil;
import com.neotel.smfcore.core.order.LiteOrderCache;
import com.neotel.smfcore.core.order.service.manager.ILiteOrderItemManager;
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;
......@@ -30,7 +31,9 @@ import com.neotel.smfcore.core.storage.service.po.StoragePos;
import com.neotel.smfcore.core.system.bean.MSDAppendInfo;
import com.neotel.smfcore.core.system.service.dao.IDataLogDao;
import com.neotel.smfcore.core.system.service.po.DataLog;
import com.neotel.smfcore.custom.lizhen.LizhenApi;
import com.neotel.smfcore.custom.lizhen.innerBox.enums.ExtendType;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
......@@ -59,6 +62,12 @@ public class TaskService {
@Autowired
private SmfApi smfApi;
@Autowired
private ILiteOrderItemManager liteOrderItemManager;
@Autowired
private LizhenApi lizhenApi;
/**
* 任务队列,Key 为dataLog的ID,value 为本区域待执行的任务
*/
......@@ -74,6 +83,12 @@ public class TaskService {
*/
private static Map<String,String> posSideMap = Maps.newConcurrentMap();
/**
* key为料箱号,value库位号
*/
private static Map<String,String> boxPosName = Maps.newConcurrentMap();
// public TaskService(List<ITaskListener> listenerList){
// for (ITaskListener taskListener: listenerList) {
// taskListenerList.add(taskListener);
......@@ -283,6 +298,15 @@ public class TaskService {
log.info("任务取消,屏蔽库位:库位号[" + pos.getId() + "][" + pos.getPosName() + "]barcode[" + task.getBarcode() + "]");
DeviceMessageUtil.addEnabledPosMessage(pos, SecurityUtils.getCurrentUsername());
}
//清除标记
Barcode barcode = clearOut(pos.getBarcode());
//如果是出库任务,同时更新库位信息
if (task.isCheckOutTask()) {
if (pos.getBarcode() != null) {
pos.setBarcode(barcode);
storagePosManager.save(pos);
}
}
}
}
//解除绑定
......@@ -431,7 +455,20 @@ public class TaskService {
log.info("分配优先(单盘或无工单)出库任务" + singleOutTask.getBarcode() + "[" + singleOutTask.getPosName() + "]到 " + cid);
return singleOutTask;
}
//判断发送的任务与当前执行的工单是否一致
if (outTask != null) {
for (DataLog task : allTasks) {
if (outTask.getCid().equals(task.getCid())) {
if (StringUtils.isNotBlank(outTask.getSourceName())) {
if (!outTask.getSourceName().equals(task.getSourceName())) {
if (task.isExecuting() || task.isOnInnerLine()) {
return null;
}
}
}
}
}
}
return outTask;
}
......@@ -1042,4 +1079,80 @@ public class TaskService {
taskMap.remove(task.getId());
theFinishedTaskMap.put(task.getId(), task);
}
private synchronized Barcode clearOut(Barcode barcode) {
if (barcode != null) {
List<Barcode> subCodeList = barcode.getSubCodeList();
if (subCodeList != null && !subCodeList.isEmpty()){
for (Barcode subCode : subCodeList) {
subCode = barcodeManager.get(subCode.getId());
if (subCode.isOut()) {
log.info("出库任务取消,清除标记");
String orderItemId = subCode.getOrderItemId();
subCode.setOut(false);
subCode.setSelectMsg(null);
subCode.setOrderItemId(null);
subCode = barcodeManager.save(subCode);
barcode.UpdateSubCode(subCode);
barcode = barcodeManager.save(barcode);
generateTask(subCode, OP_STATUS.CANCEL.name(), subCode.getAmount(),OP.CHECKOUT , orderItemId, "", ExtendType.TASK_CANNEL);
log.info("点击完成扫码并入库,任务取消,barcode:" + subCode.getBarcode() + ",OrderItemId为:" + orderItemId);
}
}
}
}
return barcode;
}
private void generateTask(Barcode barcode, String opStatus, int opQty, int opType, String orderItemId,String name,int extendType) {
//生成任务
DataLog task = new DataLog();
task.setStatus(opStatus);
task.setPartNumber(barcode.getPartNumber());
task.setBarcode(barcode.getBarcode());
task.setNum(opQty);
task.setType(opType);
task.setPosName(barcode.getPosName());
task.setOperator(SecurityUtils.getCurrentUsername());
task.setDateCode(barcode.getDateCode());
task.setBatchInfo(barcode.getBatch());
task.setProvider(barcode.getProvider());
task.setProviderNumber(barcode.getProviderNumber());
task.setKeeperCode(barcode.getKeeperCode());
//task.setReelPosName(barcode.getPosName());
task.setSubSourceId(orderItemId);
task.setWarehouseCode(barcode.getWarehouseCode());
task.setStationName(name);
task.setExtendType(extendType);
if (StringUtils.isNotBlank(orderItemId)) {
LiteOrderItem orderItem = liteOrderItemManager.get(orderItemId);
if (orderItem != null) {
task.setSourceName(orderItem.getOrderNo());
task.setLine(orderItem.getLine());
task.setMo(orderItem.getMo());
task.setSide(orderItem.getSide());
task.setPlantCode(orderItem.getPlantCode());
task.setOrderNo(orderItem.getOrderNo());
task.setSubSourceId(orderItem.getId());
}
}
updateFinishedTask(task);
}
public void addBoxPosName(DataLog dataLog){
boxPosName.put(dataLog.getBarcode(),dataLog.getPosName());
}
public void removePosName(String boxStr){
boxPosName.remove(boxStr);
}
public String getPosName(String boxStr){
return boxPosName.get(boxStr);
}
public void outTaskStatusChange(List<DataLog> dataLogList) {
smfApi.outTaskStatusChange(dataLogList);
}
}
......@@ -243,6 +243,11 @@ public class AdvantechApi extends BaseSmfApiListener {
}
}
@Override
public void outTaskStatusChange(String outNotifyUrl, List<DataLog> dataLogList) {
}
/**
* {
* "webServiceType": "AKMU1",
......
......@@ -4,10 +4,13 @@ import com.neotel.smfcore.common.exception.ValidateException;
import com.neotel.smfcore.core.api.listener.BaseSmfApiListener;
import com.neotel.smfcore.core.barcode.service.po.Barcode;
import com.neotel.smfcore.core.api.bean.CodeValidateParam;
import com.neotel.smfcore.core.system.service.po.DataLog;
import com.neotel.smfcore.custom.hella.tcp.HellaTcpClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class HellaApiHandler extends BaseSmfApiListener {
......@@ -31,6 +34,11 @@ public class HellaApiHandler extends BaseSmfApiListener {
}
@Override
public void outTaskStatusChange(String outNotifyUrl, List<DataLog> dataLogList) {
}
@Override
public Barcode canPutIn(String inCheckUrl, Barcode barcode) throws ValidateException {
if (!HellaTcpClient.isEnable()) {
return null;
......
......@@ -578,6 +578,11 @@ public class HellaServiceHandler extends BaseSmfApiListener implements IoHandler
}
@Override
public void outTaskStatusChange(String outNotifyUrl, List<DataLog> dataLogList) {
}
@Override
public void exceptionCaught(IoSession session, Throwable cause) throws Exception {
log.error("连接发生异常:" + cause.getMessage());
}
......
package com.neotel.smfcore.custom.lizhen;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSONObject;
import com.neotel.smfcore.common.bean.ResultBean;
import com.neotel.smfcore.common.exception.ApiException;
......@@ -208,6 +209,7 @@ public class LizhenController {
item.setItemId(data.get("ID"));
item.setPriority(Integer.valueOf(data.get("PRIORITY")));
item.setReel(data.get("REEL"));
item.setBrand(data.get("VENDOR"));
PreWarningItemCache.addItems(Arrays.asList(item));
return ResultBean.newOkResult("");
}
......
package com.neotel.smfcore.custom.lizhen.agvBox.bean.query;
import com.neotel.smfcore.common.annotation.QueryCondition;
import com.neotel.smfcore.common.bean.BetweenData;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
@Data
public class InventoryQuery {
@QueryCondition(type = QueryCondition.Type.BETWEEN, propName = "createDate")
@DateTimeFormat(pattern = "yyyy-MM-dd")
private BetweenData<Date> createDate;
private String type;
}
package com.neotel.smfcore.custom.lizhen.agvBox.enums;
/**
* 异动类型
*/
public enum CHANGE_TYPE {
PICKING_DETAIL("PK发料"),
GR_PUTIN("GR入库"),
MANUAL_PUTIN("手动入库"),
MANUAL_CHECKOUT("手动出库"),
TASK_CANNEL("任务取消"),
VIRTUAL_PICKING_DETAIL("虚拟仓PK发料"),
VIRTUAL_CHECKOUT("虚拟仓出库");
private final String name;
CHANGE_TYPE(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
......@@ -391,6 +391,7 @@ public class AgvBoxDeviceClientController {
lockRfidTarget.remove(opTask.getBarcode());
//已完成,从完成缓存中清除
taskService.removeFinishedTask(opTask);
taskService.addBoxPosName(opTask);
}
}
......
package com.neotel.smfcore.custom.lizhen.agvBox.rest;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSONArray;
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.system.service.manager.IDataLogManager;
import com.neotel.smfcore.core.system.service.po.DataLog;
import com.neotel.smfcore.custom.lizhen.report.merge.utils.FloorUtils;
import com.neotel.smfcore.security.annotation.AnonymousAccess;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
......@@ -9,6 +15,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
import java.util.Map;
/**
* 外仓外部接口控制类
......@@ -19,6 +26,31 @@ public class WarehouseExtController {
@Autowired
private IDataLogManager dataLogManager;
@Autowired
private FloorUtils floorUtils;
@RequestMapping("/forward/getDataLogs")
@AnonymousAccess
public List<DataLog> forwardGetDataLogs(String orderNo, String line, Pageable pageable){
String url = "";
Map<String, String> allFloor = floorUtils.getAllFloor(2);
for (String floor : allFloor.values()) {
if (floorUtils.isB15(floor)){
url = floorUtils.getUrlByFloor(floor);
break;
}
}
if (StringUtils.isNotBlank(url)){
url = url + "/ext/getDatalogs"+"?orderNo=" + orderNo + "&line=" + line + "&page=" + pageable.getPageNumber() + "&size=" + pageable.getPageSize();
String result = HttpUtil.get(url);
if (StringUtils.isNotBlank(result)){
return JSONArray.parseArray(result,DataLog.class);
}
}
return null;
}
@RequestMapping("/getDatalogs")
@AnonymousAccess
public List<DataLog> getDatalogs(String orderNo, String line, Pageable pageable) {
......
......@@ -46,13 +46,15 @@ public class BoxUtil {
*/
public static String getBoxStr(String str) {
String boxStr = "";
if (str.startsWith("CS") || str.startsWith("CM") || str.startsWith("CB")) {
if (str.endsWith("A") || str.endsWith("B")) {
boxStr = str.substring(0, str.length() - 1);
} else if (str.indexOf("-") != -1) {
boxStr = str.substring(0, str.indexOf("-"));
} else {
boxStr = str;
if (StringUtils.isNotBlank(str)) {
if (str.startsWith("CS") || str.startsWith("CM") || str.startsWith("CB")) {
if (str.endsWith("A") || str.endsWith("B")) {
boxStr = str.substring(0, str.length() - 1);
} else if (str.indexOf("-") != -1) {
boxStr = str.substring(0, str.indexOf("-"));
} else {
boxStr = str;
}
}
}
return boxStr;
......@@ -131,7 +133,7 @@ public class BoxUtil {
infoMap.put(partition, info);
}
if (boxSideStr.endsWith("A")) {
if (boxSideStr.startsWith("CS")) {
if (boxSideStr.startsWith("CS") || boxSideStr.startsWith("CB")) {
for (int i = 8; i > 4; i--) {
String partition = boxStr + "-" + i;
infoList.add(infoMap.get(partition));
......@@ -147,7 +149,7 @@ public class BoxUtil {
}
}
} else if (boxSideStr.endsWith("B")) {
if (boxSideStr.startsWith("CS")) {
if (boxSideStr.startsWith("CS") || boxSideStr.startsWith("CB")) {
for (int i = 4; i > 0; i--) {
String partition = boxStr + "-" + i;
infoList.add(infoMap.get(partition));
......@@ -187,4 +189,30 @@ public class BoxUtil {
}
return true;
}
/**
* 判断是否可以入库
* @param partitionStr
* @return
*/
public static boolean isCanPutIn(String partitionStr) {
List<String> partitionList = new ArrayList<>();
String boxStr = getBoxStr(partitionStr);
if (partitionStr.startsWith("CS") || partitionStr.startsWith("CB")) {
for (int i = 1; i < 9; i++) {
partitionList.add(boxStr+"-"+i);
}
} else {
for (int i = 1; i < 3; i++) {
partitionList.add(boxStr+"-"+i);
}
}
if (partitionList != null && !partitionList.isEmpty()){
if (partitionList.contains(partitionStr)){
return true;
}
}
return false;
}
}
......@@ -29,7 +29,7 @@ public class PreWarningItem extends BasePo {
private String partnumber;
private String itemId;
private String reel;
private String brand;
/**
* 优先级,1:人工 0:机器
*/
......
package com.neotel.smfcore.custom.lizhen.innerBox.bean;
import com.neotel.smfcore.common.base.BasePo;
import lombok.Data;
/**
* 虚拟仓导入明细
*/
@Data
public class VirImportLog extends BasePo {
/**
* barcode
*/
private String barcode;
/**
* 提示信息
*/
private String msg;
/**
* 是否成功
*/
private boolean isSuccess = false;
/**
* 楼层
*/
private String floor;
/**
* 工单号(pickingId)
*/
private String orderNo;
/**
* 创建人
*/
private String creator;
}
......@@ -57,5 +57,89 @@ public class ExtendType {
/**
* 盘点入库
*/
public final static int INVENTORY_PUTIN = 9;
public final static int INVENTORY_PUTIN = 10;
/**
* pk发料
*/
public final static int PICKING_DETAIL = 11;
/**
* GR入库
*/
public final static int GR_PUTIN = 12;
/**
* 手动入库
*/
public final static int MANUAL_PUTIN = 13;
/**
* 任务取消
*/
public final static int TASK_CANNEL = 14;
/**
* 虚拟仓pk发料
*/
public final static int VIRTUAL_PICKING_DETAIL = 15;
public static String getName(int type) {
String name = "";
switch (type) {
case 0:
name = "智能仓储入库";
break;
case 1:
name = "智能仓储出库";
break;
case 2:
name = "虚拟仓入库";
break;
case 3:
name = "虚拟仓出库";
break;
case 4:
name = "手动出库";
break;
case 5:
name = "手动喂料";
break;
case 6:
name = "清空库位";
break;
case 7:
name = "料架入库";
break;
case 8:
name = "料架出库";
break;
case 9:
name = "盘点出库";
break;
case 10:
name = "盘点入库";
break;
case 11:
name = "PK发料";
break;
case 12:
name = "GR入库";
break;
case 13:
name = "手动入库";
break;
case 14:
name = "任务取消";
break;
case 15:
name = "虚拟仓pk发料";
break;
}
return name;
}
}
package com.neotel.smfcore.custom.lizhen.innerBox.service.dao;
import com.neotel.smfcore.common.base.IBaseDao;
public interface IVirImportLogDao extends IBaseDao {
}
package com.neotel.smfcore.custom.lizhen.innerBox.service.dao.impl;
import com.neotel.smfcore.common.base.AbstractBaseDao;
import com.neotel.smfcore.custom.lizhen.innerBox.bean.VirImportLog;
import com.neotel.smfcore.custom.lizhen.innerBox.service.dao.IVirImportLogDao;
import org.springframework.stereotype.Service;
@Service
public class IVirImportLogDaoImpl extends AbstractBaseDao implements IVirImportLogDao {
@Override
public Class getEntityClass() {
return VirImportLog.class;
}
}
package com.neotel.smfcore.custom.lizhen.innerBox.service.manager;
import com.neotel.smfcore.common.base.IBaseManager;
import com.neotel.smfcore.custom.lizhen.innerBox.bean.VirImportLog;
public interface IVirImportLogManager extends IBaseManager<VirImportLog> {
void updateVirImportLog(String barcodeStr, String msg, boolean isSuccess, String floor, String orderNo);
int countByBarcodeAndOrderNo(String barcodeStr, String orderNo);
}
package com.neotel.smfcore.custom.lizhen.innerBox.service.manager.impl;
import com.neotel.smfcore.common.base.BasePo;
import com.neotel.smfcore.common.bean.PageData;
import com.neotel.smfcore.common.exception.ValidateException;
import com.neotel.smfcore.common.utils.SecurityUtils;
import com.neotel.smfcore.core.barcode.service.po.Barcode;
import com.neotel.smfcore.custom.lizhen.innerBox.bean.VirImportLog;
import com.neotel.smfcore.custom.lizhen.innerBox.service.dao.IVirImportLogDao;
import com.neotel.smfcore.custom.lizhen.innerBox.service.manager.IVirImportLogManager;
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;
import java.security.Security;
import java.util.Date;
import java.util.List;
@Service
public class IVirImportLogManagerImpl implements IVirImportLogManager {
@Autowired
private IVirImportLogDao virImportLogDao;
@Override
public VirImportLog get(String id) {
return null;
}
@Override
public VirImportLog save(VirImportLog object) throws ValidateException {
return null;
}
@Override
public void delete(VirImportLog object) throws ValidateException {
}
@Override
public PageData<VirImportLog> findByPage(Query query, Pageable pageable) {
int count = virImportLogDao.countByQuery(query);
List<VirImportLog> barcodes= virImportLogDao.findByQuery(query,pageable);
return new PageData(barcodes,count);
}
@Override
public List<VirImportLog> findByQuery(Query query) {
return virImportLogDao.findByQuery(query);
}
@Override
public void updateVirImportLog(String barcodeStr, String msg, boolean isSuccess, String floor, String orderNo) {
Query query = new Query();
Criteria criteria = Criteria.where("barcode").is(barcodeStr).and("orderNo").is(orderNo);
VirImportLog virImportLog = virImportLogDao.findOne(query.addCriteria(criteria));
if (virImportLog == null){
virImportLog = new VirImportLog();
}
virImportLog.setBarcode(barcodeStr);
virImportLog.setMsg(msg);
virImportLog.setSuccess(isSuccess);
virImportLog.setFloor(floor);
virImportLog.setOrderNo(orderNo);
virImportLog.setUpdateDate(new Date());
//virImportLog.setCreator(SecurityUtils.getCurrentUsername());
virImportLogDao.save(virImportLog);
}
@Override
public int countByBarcodeAndOrderNo(String barcodeStr, String orderNo) {
Query query = new Query();
Criteria criteria = Criteria.where("barcode").is(barcodeStr).and("orderNo").is(orderNo).and("isSuccess").is(true);
return virImportLogDao.countByQuery(query.addCriteria(criteria));
}
}
......@@ -140,6 +140,7 @@ public class PreWarningItemCache {
orderItem.setPriority(item.getPriority());
orderItem.setMachineName(item.getMachinename());
orderItem.setReel(item.getReel());
orderItem.setBrand(item.getBrand());
orderItems.add(orderItem);
}
}
......
......@@ -112,17 +112,17 @@ public class InnerKanbanController {
status = bean.getStatus();
}
//出入库数据
int inCount = dataLogManager.getInOutData(currentDate, endDate, OP.PUT_IN, "", -1, storage.getId());
int outCount = dataLogManager.getInOutData(currentDate, endDate, OP.CHECKOUT, "", -1, storage.getId());
//int inCount = dataLogManager.getInOutData(currentDate, endDate, OP.PUT_IN, "", -1, storage.getId());
//int outCount = dataLogManager.getInOutData(currentDate, endDate, OP.CHECKOUT, "", -1, storage.getId());
DevicesStatusDto dto = new DevicesStatusDto();
dto.setName(name);
dto.setPosUseCount(useSlots);
dto.setPosAllCount(totalSlots);
dto.setInCount(inCount);
dto.setOutCount(outCount);
//dto.setInCount(inCount);
//dto.setOutCount(outCount);
dto.setUsage(usage);
dto.setStauts(status);
dto.setStatus(status);
if (storage.isNLShelf()){
dto.setType(0);
} else {
......@@ -134,6 +134,30 @@ public class InnerKanbanController {
return ResultBean.newOkResult(resultList);
}
/**
* 所有设备库位使率汇总
* @return
*/
@RequestMapping("/getAllUsage")
@AnonymousAccess
public ResultBean getAllUsage(){
int usage = 0;
List<Storage> resultList = new ArrayList<>();
Collection<Storage> collection = dataCache.getAllStorage().values();
for (Storage storage : collection) {
if (!storage.isVirtual()){
resultList.add(storage);
}
}
if (resultList != null && !resultList.isEmpty()){
int totalSlots = resultList.stream().mapToInt(Storage::getTotalSlots).sum();
int emptySlots = resultList.stream().mapToInt(Storage::getEmptySlots).sum();
usage = (int) (((double) (totalSlots - emptySlots) / totalSlots) * 100); //库位使用率
}
return ResultBean.newOkResult(usage);
}
public static void main(String[] args) {
int i = (int) (((double) (99 - 88) / 99) * 100);
System.out.println(i);
......
......@@ -31,7 +31,7 @@ public class DevicesStatusDto {
/**
* 设备状态
*/
private int stauts;
private int status;
/**
* 所有库位
......
package com.neotel.smfcore.custom.lizhen.report.bean.dto;
import lombok.Data;
@Data
public class MergeInventoryDto extends InventoryDto{
}
......@@ -101,6 +101,15 @@ public class ReportQueryCondition {
private String status;
@ApiModelProperty("盘点批次")
@QueryCondition(type = QueryCondition.Type.EQ, propName = "inventoryBatch")
private Long inventoryBatch;
@QueryCondition(blurry = "inventoryBatch")
private String inventoryBatch;
//楼层
private String floor;
private int page;
private int size;
private String sort;
}
......@@ -2,10 +2,7 @@ package com.neotel.smfcore.custom.lizhen.report.inner;
import com.neotel.smfcore.common.bean.PageData;
import com.neotel.smfcore.common.bean.ResultBean;
import com.neotel.smfcore.common.utils.DateUtil;
import com.neotel.smfcore.common.utils.FileUtil;
import com.neotel.smfcore.common.utils.QueryHelp;
import com.neotel.smfcore.common.utils.StringUtils;
import com.neotel.smfcore.common.utils.*;
import com.neotel.smfcore.core.barcode.bean.CodeBean;
import com.neotel.smfcore.core.barcode.rest.bean.dto.BarcodeDto;
import com.neotel.smfcore.core.barcode.rest.bean.mapstruct.BarcodeMapper;
......@@ -33,8 +30,11 @@ import com.neotel.smfcore.core.storage.service.po.StoragePos;
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 com.neotel.smfcore.custom.lizhen.innerBox.bean.VirImportLog;
import com.neotel.smfcore.custom.lizhen.innerBox.enums.ExtendType;
import com.neotel.smfcore.custom.lizhen.innerBox.service.manager.IVirImportLogManager;
import com.neotel.smfcore.custom.lizhen.report.bean.query.ReportQueryCondition;
import com.neotel.smfcore.custom.lizhen.report.merge.utils.FloorUtils;
import com.neotel.smfcore.security.annotation.AnonymousAccess;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
......@@ -103,6 +103,9 @@ public class InnerReportController {
@Autowired
private CodeResolve codeResolve;
@Autowired
private IVirImportLogManager virImportLogManager;
@ApiOperation("喂料")
@RequestMapping("/feeding")
@AnonymousAccess
......@@ -175,10 +178,21 @@ public class InnerReportController {
@RequestMapping("floorPullDown")
@AnonymousAccess
public ResultBean floorPullDown() {
String floor = dataCache.getCache(Constants.CACHE_floor);
Map<String, String> resultMap = new LinkedHashMap<>();
resultMap.put(F2, F2);
resultMap.put(F3, F3);
resultMap.put(F5, F5);
if (StringUtils.isNotBlank(floor)) {
if (F2.equals(floor)) {
resultMap.put(F2, F2);
} else if (F3.equals(floor)) {
resultMap.put(F3, F3);
} else if (F5.equals(floor)) {
resultMap.put(F5, F5);
}
} else {
resultMap.put(F2, F2);
resultMap.put(F3, F3);
resultMap.put(F5, F5);
}
return ResultBean.newOkResult(resultMap);
}
......@@ -217,10 +231,21 @@ public class InnerReportController {
if (pageable != null) {
PageData<StoragePos> page = storagePosManager.findByPage(query, pageable);
resultData.setTotalElements(page.getTotalElements());
resultData.setContent(storagePosMapper.toDto(page.getContent()));
List<StoragePos> storagePosList = page.getContent();
storagePosList.stream().forEach(item -> {
String storageId = item.getStorageId();
Storage storage = dataCache.getStorageById(storageId);
item.setSource(storage.getName());
});
resultData.setContent(storagePosMapper.toDto(storagePosList));
} else {
List<StoragePos> storagePosList = storagePosManager.findByQuery(query);
if (storagePosList != null && !storagePosList.isEmpty()) {
storagePosList.stream().forEach(item -> {
String storageId = item.getStorageId();
Storage storage = dataCache.getStorageById(storageId);
item.setSource(storage.getName());
});
resultData.setContent(storagePosMapper.toDto(storagePosList));
resultData.setTotalElements(storagePosList.size());
}
......@@ -440,6 +465,7 @@ public class InnerReportController {
public PageData lackPicking(ReportQueryCondition queryCondition, Pageable pageable) {
Collection<LiteOrder> liteOrders = liteOrderCache.getAllLiteOrder();
PageData resultData = new PageData();
resultData.setContent(new ArrayList());
if (liteOrders != null && !liteOrders.isEmpty()) {
//先按创建时间进行升序
liteOrders = liteOrders.stream().sorted(Comparator.comparing(LiteOrder::getCreateDate)).collect(Collectors.toList());
......@@ -626,6 +652,55 @@ public class InnerReportController {
}
}
@ApiOperation("一键导入明细")
@RequestMapping("/virImportLog")
@AnonymousAccess
public PageData<VirImportLog> virImportLog(ReportQueryCondition queryCondition, Pageable pageable) {
Query query = QueryHelp.getQuery(queryCondition);
if (pageable != null) {
return virImportLogManager.findByPage(query, pageable);
} else {
List<VirImportLog> virImportLogList = virImportLogManager.findByQuery(query);
if (virImportLogList == null) {
virImportLogList = new ArrayList<>();
}
return new PageData<VirImportLog>(virImportLogList, virImportLogList.size());
}
}
@ApiOperation("一键导入明细导出")
@RequestMapping("/virImportLog/download")
@AnonymousAccess
public void virImportLogDownload(ReportQueryCondition queryCondition, HttpServletResponse response) {
PageData<VirImportLog> pageData = virImportLog(queryCondition, null);
if (pageData.getTotalElements() != 0) {
List<VirImportLog> importLogList = pageData.getContent();
List<Map<String, Object>> results = new ArrayList<>();
if (importLogList != null && !importLogList.isEmpty()) {
for (VirImportLog log : importLogList) {
Map<String, Object> resultMap = new LinkedHashMap<>();
resultMap.put("唯一码",log.getBarcode());
resultMap.put("提示信息",log.getMsg());
resultMap.put("是否成功",log.isSuccess() ? "是" : "否");
resultMap.put("楼层",log.getFloor());
resultMap.put("pickingId",log.getOrderNo());
resultMap.put("创建人",log.getCreator());
resultMap.put("创建时间",log.getCreateDate());
resultMap.put("修改时间",log.getUpdateDate());
results.add(resultMap);
}
}
try {
FileUtil.downloadExcel(results, response);
} catch (IOException e) {
e.printStackTrace();
log.info("内仓禁限用导出导出失败--" + e.getMessage());
}
}
}
private List<LiteOrderItem> getLackItems(Collection<LiteOrder> liteOrders, ReportQueryCondition queryCondition) {
List<LiteOrderItem> lackItems = new ArrayList<>();
//排除虚拟仓的
......@@ -667,7 +742,7 @@ public class InnerReportController {
}
InventoryItem inventoryItem = inventoryMap.get(orderItem.getPn());
if (inventoryItem != null) {
if (inventoryItem.getStockReel() - inventoryItem.getLockReel() - inventoryItem.getBindReel() > 0) {
if (inventoryItem.getStockReel() /*- inventoryItem.getLockReel()*/ - inventoryItem.getBindReel() > 0) {
inventoryItem.setBindReel(inventoryItem.getBindReel() + 1);
} else {
lackItems.add(orderItem);
......
package com.neotel.smfcore.custom.lizhen.report.merge.utils;
import com.neotel.smfcore.core.device.util.DataCache;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* 楼层工具类
*/
@Service
public class FloorUtils {
@Autowired
private DataCache dataCache;
@Value("${forward.f2.name}")
private String forwardF2Name;
@Value("${forward.f2.url}")
private String forwardF2Url;
@Value("${forward.f3.name}")
private String forwardF3Name;
@Value("${forward.f3.url}")
private String forwardF3Url;
@Value("${forward.f5.name}")
private String forwardF5Name;
@Value("${forward.f5.url}")
private String forwardF5Url;
@Value("${forward.b15.name}")
private String forwardB15Name;
@Value("${forward.b15.url}")
private String forwardB15Url;
@PostConstruct
public void init() {
forwardF2Name = dataCache.getConfigCache("forward.f2.name", forwardF2Name);
forwardF2Url = dataCache.getConfigCache("forward.f2.url", forwardF2Url);
forwardF3Name = dataCache.getConfigCache("forward.f3.name", forwardF3Name);
forwardF3Url = dataCache.getConfigCache("forward.f3.url", forwardF3Url);
forwardF5Name = dataCache.getConfigCache("forward.f5.name", forwardF5Name);
forwardF5Url = dataCache.getConfigCache("forward.f5.url", forwardF5Url);
forwardB15Name = dataCache.getConfigCache("forward.b15.name", forwardB15Name);
forwardB15Url = dataCache.getConfigCache("forward.b15.url", forwardB15Url);
}
public Map<String, String> getAllFloor(int type) {
Map<String, String> resultMap = new LinkedHashMap<>();
if (type == 0) {
resultMap.put(forwardF2Name, forwardF2Name);
resultMap.put(forwardF3Name, forwardF3Name);
resultMap.put(forwardF5Name, forwardF5Name);
resultMap.put(forwardB15Name, forwardB15Name);
} else if (type == 1){
resultMap.put(forwardF2Name, forwardF2Name);
resultMap.put(forwardF3Name, forwardF3Name);
resultMap.put(forwardF5Name, forwardF5Name);
} else if (type == 2){
resultMap.put(forwardB15Name, forwardB15Name);
}
return resultMap;
}
public String getUrlByFloor(String floor) {
String url = "";
if (forwardF2Name.equals(floor)) {
url = forwardF2Url;
} else if (forwardF3Name.equals(floor)) {
url = forwardF3Url;
} else if (forwardF5Name.equals(floor)) {
url = forwardF5Url;
} else if (forwardB15Name.equals(floor)) {
url = forwardB15Url;
}
return url;
}
public boolean isB15(String floor){
return floor.equals(forwardB15Name);
}
}
......@@ -448,6 +448,11 @@ public class PanaApiController extends BaseSmfApiListener {
}
}
@Override
public void outTaskStatusChange(String outNotifyUrl, List<DataLog> dataLogList) {
}
/**
* 入库完成通知
......
......@@ -20,6 +20,7 @@ import org.springframework.stereotype.Component;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
......@@ -70,6 +71,11 @@ public class SiemensApi extends BaseSmfApiListener {
}
}
@Override
public void outTaskStatusChange(String outNotifyUrl, List<DataLog> dataLogList) {
}
private static boolean lotInOut(String url, String lot,int inoutType,String deviceId) {
//String url=config.url;
......
<?xml version="1.0" encoding="UTF-8"?>
<configuration status="WARN">
<Properties>
<Property name="LOG_HOME">logs</Property>
<Property name="LOG_HOME">D:/Smflogs</Property>
<Property name="LOG_NAME">smf.txt</Property>
</Properties>
<appenders>
......
......@@ -264,7 +264,7 @@ smfcore.error.virtualOut.noItem=\u5DE5\u5355{0}\u4E2D\u672A\u627E\u5230\u5BF9\u5
smfcore.error.mimo.outFial=\u672A\u627E\u5230\u53EF\u51FA\u5E93\u7684\u7269\u6599
smfcore.error.getMaterialLot.in=\u6761\u7801[{0}]\u9A8C\u8BC1\u5931\u8D25\uFF0C\u65E0\u6CD5\u5165\u5E93
smfcore.error.getMaterialLot.out=\u6761\u7801[{0}]\u9A8C\u8BC1\u5931\u8D25\uFF0C\u65E0\u6CD5\u51FA\u5E93
smfcore.error.permissionPassword = \u6743\u9650\u5BC6\u7801\u9519\u8BEF;
#smfclient.nlp.onlyOneTray=\u4E0D\u53EF\u540C\u65F6\u653E\u5165\u591A\u76D8\u7269\u6599:{0}
#smfclient.nlp.cannotFindPos={0}\u672A\u627E\u5230\u5E93\u4F4D:{1}
#smfclient.nlp.inputOk={0}\u5165\u5E93\u5230{1}\u6210\u529F
......
支持 Markdown 格式
你添加了 0 到此讨论。请谨慎行事。
Finish editing this message first!