Commit 99378dd1 zshaohui

立臻功能提交

1 个父辈 437a3c12
正在显示 68 个修改的文件 包含 4808 行增加1424 行删除
......@@ -159,9 +159,10 @@ public class DataInitManager {
Menu poutOut = Menu.CreatePMenu("物料管理", 1, "order", 2, "workOrder", null);
Menu out = Menu.CreatePMenu("查找出库", 11, "searchOut", 2, "findOut",poutOut);
addNewFunctionMenu(1,out,"checkOut", "UID出库", "singleOuput", "neolight/singleOuput/index","export1",functionMenuMap);
addNewFunctionMenu(2, out,"tacticsOuput", "PN出库", "tacticsOuput", "neolight/tacticsOuput/index", "tacticsOuput",functionMenuMap);
addNewFunctionMenu(1,out,"checkOut", "UID出库", "singleOuput", "neolight/singleOuput/index","export1",functionMenuMap);
addNewFunctionMenu(2, out,"tacticsOuput", "PN出库", "tacticsOuput", "neolight/tacticsOuput/index", "tacticsOuput",functionMenuMap);
//addNewFunctionMenu(2,poutOut,"checkHandOut", "手动出库", "singleOuput", "neolight/singleOuput/index","export1",functionMenuMap);
addNewFunctionMenu(1,poutOut,"workOrder", "工单出库","workOrder", "neolight/workOrder/index","orderOut",functionMenuMap);
addNewFunctionMenu(2,poutOut,"posOutput", "库位出库", "posOutput", "system/posOutput/index", "swagger",functionMenuMap);
addNewFunctionMenu(3, poutOut, "labelOuput", "物料标签", "labelOuput", "neolight/labelOuput/index", "mgroup",functionMenuMap);
......@@ -211,6 +212,18 @@ public class DataInitManager {
Menu pMenuReport = Menu.CreatePMenu("报表", 7, "report", 2, "inOutData",null);
addNewFunctionMenu(71, pMenuReport, "inOutData", "出入库", "inOutData", "neolight/inOutData/index", "outPut",functionMenuMap);
addNewFunctionMenu(72, pMenuReport,"inventory", "库存", "inventory", "neolight/inventory/index", "inventory",functionMenuMap);
addNewFunctionMenu(73, pMenuReport,"materialIssueDetailsList", "发料", "materialIssueDetailsList", "neolight/materialIssueDetailsList/index", "mIDList",functionMenuMap);
addNewFunctionMenu(74, pMenuReport,"overdueDelayReport", "过期延期", "overdueDelayReport", "neolight/overdueDelayReport/index", "oDReport",functionMenuMap);
addNewFunctionMenu(75, pMenuReport,"prohibitedReport", "禁限用", "prohibitedReport", "neolight/prohibitedReport/index", "workOrder",functionMenuMap);
addNewFunctionMenu(76, pMenuReport,"materialPreListReport", "备料清单", "materialPreListReport", "neolight/materialPreListReport/index", "mPreListReport",functionMenuMap);
addNewFunctionMenu(77, pMenuReport,"changeReport", "异动", "changeReport", "neolight/changeReport/index", "changeReport",functionMenuMap);
addNewFunctionMenu(78, pMenuReport,"materialReturnReport", "退料", "materialReturnReport", "neolight/materialReturnReport/index", "mReturnReport",functionMenuMap);
addNewFunctionMenu(79, pMenuReport,"OrderAutoInventoryReport", "内仓工单库存自动对比", "OrderAutoInventoryReport", "neolight/OrderAutoInventoryReport/index", "OAInventoryReport",functionMenuMap);
addNewFunctionMenu(80, pMenuReport,"inventoryReport", "库存", "inventoryReport", "neolight/inventoryReport/index", "BOM",functionMenuMap);
addNewFunctionMenu(81, pMenuReport,"materialShortageReport", "缺料", "materialShortageReport", "neolight/materialShortageReport/index", "mShortageReport",functionMenuMap);
addNewFunctionMenu(82,pMenuReport,"pkSearch","PK查询","pkSearch","neolight/pkSearch/index","findOut",functionMenuMap);
//addNewFunctionMenu(83,pMenuReport,"lackPicking","内仓缺料","lackPicking","neolight/lackPicking/index","mShortageReport",functionMenuMap);
addNewFunctionMenu(83,pMenuReport,"feeding","喂料","feeding","neolight/feeding/index","mShortageReport",functionMenuMap);
//可观测性:物料追踪
Menu guanceMenu = Menu.CreatePMenu("可观测性", 8, "observability", 2, "scanKey",null);
......@@ -231,7 +244,7 @@ public class DataInitManager {
addNewFunctionMenu(105,poutSet, "translation", "资源翻译", "translation", "system/translation/index", "translation",functionMenuMap);
// Menu orderSet = new Menu(, "orderSetting", "工单设置", "orderSetting", "system/orderSetting/index", "sysSet");
addNewFunctionMenu(106,poutSet, "shelfSetting", "料架设置", "shelfSetting", "system/shelfSetting/index", "translation",functionMenuMap);
addNewFunctionMenu(107,poutSet, "warehouseMaintenance", "库别维护", "warehouseMaintenance", "system/warehouseMaintenance/index", "translation",functionMenuMap);
//用户管理:用户管理,角色管理
Menu pMenuUser = Menu.CreatePMenu("用户管理", 11, "userManager", 2, "Steve-Jobs", null);
......
......@@ -29,19 +29,27 @@ public class MainTimer {
@Autowired
LiteOrderCache liteOrderCache;
public void init(){
public void init() {
initTask();
liteOrderCache.loadUnEndOrderInfos();
log.info("主定时器开启,60秒后开始执行, 每10s执行一次");
log.info("主定时器开启,60秒后开始执行, 每300s执行一次");
//1 分钟之后执行,每秒钟执行一次
scheduledThreadPool.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
timerTask();
}
}, 60, 10, TimeUnit.SECONDS);
}, 60, 300, TimeUnit.SECONDS);
//log.info("如果是人工叫料,则每2分钟执行一次");
scheduledThreadPool.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
timerTaskLz();
}
}, 60, 5, TimeUnit.SECONDS);
}
private void initTask() {
log.info("开始加载未完成的任务...");
......@@ -60,8 +68,9 @@ public class MainTimer {
private void timerTask(){
try{
PreWarningItemCache.runTimer();
liteOrderCache.runTimer();
//log.info("机器叫料,每5分钟执行一次");
PreWarningItemCache.runTimer(0);
//liteOrderCache.runTimer(0);
//设备状态判断
DevicesStatusUtil.runTimer();
......@@ -73,4 +82,16 @@ public class MainTimer {
}
}
private void timerTaskLz() {
try {
//log.info("人工叫料,每5s执行一次");
PreWarningItemCache.runTimer(1);
liteOrderCache.runTimer(1);
liteOrderCache.runTimer(0);
} catch (Exception e) {
e.printStackTrace();
log.error("定时器执行出错", e);
}
}
}
......@@ -139,4 +139,9 @@ public class Constants {
* 缺料预警配置
*/
public static final String CACHE_preWarningItem = "preWarningItem";
public static final String CACHE_outLotInfoMap = "outLotInfoMap";
public static final String CACHE_outLotInfos = "outLotInfos";
}
......@@ -174,18 +174,4 @@ public class SmfApi {
}
return false;
}
public Barcode barcodeInfo(Barcode barcode) {
if (isUrlExist(barcodeInfoUrl)) {
for (ISmfApiListener apiListener : apiListenerList) {
if (apiListener.isForThisApi(apiName)) {
Barcode responseBarcode = apiListener.barcodeInfo(barcodeInfoUrl,barcode);
if (responseBarcode != null) {
return responseBarcode;
}
}
}
}
return null;
}
}
......@@ -246,9 +246,4 @@ public class DefaultSmfApiListener extends BaseSmfApiListener {
public LiteOrder fetchOrder(String fetchOrderUrl, String orderNumber, String username){
return null;
}
@Override
public Barcode barcodeInfo(String barcodeInfoUrl,Barcode barcode) {
return null;
}
}
......@@ -48,6 +48,4 @@ public interface ISmfApiListener {
* @return
*/
LiteOrder fetchOrder(String url, String orderNumber, String username);
Barcode barcodeInfo(String barcodeInfoUrl,Barcode barcode);
}
......@@ -3,7 +3,9 @@ package com.neotel.smfcore.core.barcode.bean;
import com.google.common.base.Strings;
import com.neotel.smfcore.common.utils.DateUtil;
import com.neotel.smfcore.common.utils.HttpHelper;
import com.neotel.smfcore.common.utils.StringUtils;
import com.neotel.smfcore.core.barcode.service.po.Barcode;
import com.neotel.smfcore.custom.lizhen.agvBox.bean.GrLabel;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
......@@ -561,7 +563,7 @@ public class BarcodeRule {
}
b.setBatch(batch);
}
int quantity = 1;
int quantity = 0;
if(quantity_item.hasThisField()){
quantity = quantity_item.getIntValue(codeArr);
if(quantity == -1){
......@@ -619,7 +621,7 @@ public class BarcodeRule {
if (providerNumber_item.hasThisField()){
String providerNumber = providerNumber_item.getStrValue(codeArr);
if (providerNumber.indexOf("-") != -1){
providerNumber = providerNumber.substring(providerNumber.indexOf("-")+1,providerNumber.length());
providerNumber = providerNumber.substring(providerNumber.lastIndexOf("-")+1,providerNumber.length());
}
b.setProviderNumber(providerNumber);
}
......@@ -628,7 +630,7 @@ public class BarcodeRule {
codeBean.setCodeStr(reelId);
//如果是立臻的,则取-前面的
if (partNumber.indexOf("-") != -1){
partNumber = partNumber.substring(0,partNumber.indexOf("-"));
partNumber = partNumber.substring(0,partNumber.lastIndexOf("-"));
}
b.setPartNumber(partNumber);
b.setAmount(quantity);
......@@ -643,6 +645,76 @@ public class BarcodeRule {
return codeBean;
}
public GrLabel toGrLable(String codeStr) {
log.info("开始解析条码[" + codeStr + "]");
String[] codeArr = new String[]{codeStr};
if (!Strings.isNullOrEmpty(separator)) {
codeArr = codeStr.split(separator, -1);
//条码与规则长度对应不上
if (codeArr.length != length) {
log.info("条码[" + codeStr + "]与规则【" + ruleStr + "】长度不同");
return null;
} else {
codeArr = codeStr.split(separator, length);
}
}
GrLabel grLabel = new GrLabel();
grLabel.setFullCode(codeStr);
//得到gr标签唯一与行号
String reelId = "";
if (whole_reelId_item.hasThisField()) {
reelId = codeStr;
} else {
reelId = reelId_item.getStrValue(codeArr);
}
if (Strings.isNullOrEmpty(reelId)) {
log.info("条码解析失败,未找到RI字段");
//codeBean.setError("smfcore.error.barcode.noField",new String[]{"RI"},"条码解析失败,未找到{0}字段");
return null;
}
grLabel.setLabelId(reelId);
String memo = "";
if (memo_item.hasThisField()) {
memo = memo_item.getStrValue(codeArr);
}
if (Strings.isNullOrEmpty(memo)){
log.info("条码解析失败,未找到MEMO字段");
return null;
}
grLabel.setLabelItem(memo);
String partNumber = partNumber_item.getStrValue(codeArr);
if (Strings.isNullOrEmpty(partNumber)) {
log.info("条码解析失败,未找到PN字段");
return null;
}
grLabel.setPartNumber(partNumber);
int quantity = 0;
if (quantity_item.hasThisField()) {
quantity = quantity_item.getIntValue(codeArr);
if (quantity == -1) {
log.info("条码解析失败,未找到QTY 字段");
return null;
}
}
grLabel.setAmount(quantity);
grLabel.setRemainingAmount(quantity);
String supplier = supplier_item.getStrValue(codeArr);
grLabel.setProvider(supplier);
return grLabel;
}
/**
* 转义正则特殊字符 ($()*+.[]?\^{}
* @return
......@@ -776,6 +848,15 @@ public class BarcodeRule {
codeStr = "138S00138-012207|2022-1015|41625|L130122074222008AL|KYOCERA|";
rule = "PN[-1:20:-1]PROVIDERNUMBER[-1:20:-1]|BATCH[-1:20:-1]DATECODE[-1:20:-1]|QTY|RI|SP|6";
codeStr = "103S00358";
//codeStr = "138S00138-012207";
rule = "RI[0:6:2]PN[-1:2:-1]";
/* codeStr = "5001809171|1|138S00139|MURATA|450000";
rule = "RI|MEMO|PN|SP|QTY";*/
codeStr = "=1x1=806-33328-1000015|220812A-220812|6000|M8010000153322U50F|EVERWIN";
rule = "RI[0:6:2]PN[-1:2:-1]";
BarcodeRule br = BarcodeRule.newRule(rule);
Barcode b = br.toCodeBean(codeStr).getBarcode();
......
......@@ -247,4 +247,22 @@ public class BarcodeDto implements Serializable {
@ApiModelProperty("第一次入库时间")
private Date firstPutInDate;
@ApiModelProperty("日期代码")
private String dateCode;
@ApiModelProperty("禁用信息")
private String disableMsg;
@ApiModelProperty("卷数")
private int reelAmount;
@ApiModelProperty("库别")
private String warehouseCode;
@ApiModelProperty("隔口数量")
private int partitionCount = 0;
@ApiModelProperty("创建人")
private String creator;
}
......@@ -187,11 +187,11 @@ public class BarcodeManagerImpl implements IBarcodeManager {
// throw new ValidateException("smfcore.valueCanotNull","{0}不能为空",new String[]{"batch"} );
// throw new ValidateException("批次不能为空");
}
if (barcode.getAmount() <= 0) {
/*if (barcode.getAmount() <= 0) {
throw new ValidateException("smfcore.greaterThanZero","数量必须大于0",new String[]{"amout"} );
// throw new ValidateException("smfcore.valueCanotNull","{0}不能为空",new String[]{"amout"} );
// throw new ValidateException("["+barcode.getBarcode()+"]barcode.error.amount.negative" );
}
}*/
if (!validateUnique(barcode)) {
// throw new ValidateException("["+barcode.getBarcode()+"]barcode.error.unique" );
}
......
......@@ -8,6 +8,7 @@ import com.neotel.smfcore.core.barcode.enums.BARCODE_STATUS;
import com.neotel.smfcore.core.barcode.enums.COMPONENT_TYPE;
import com.neotel.smfcore.core.barcode.enums.SOLDER_STATUS;
import io.swagger.annotations.ApiModelProperty;
import lombok.*;
import org.springframework.data.annotation.Transient;
import org.springframework.data.mongodb.core.mapping.Document;
......@@ -152,6 +153,10 @@ public class Barcode extends BasePo implements Serializable {
private String dateCode;
/**
* 卷数
*/
private int reelAmount = 0;
/**
* 关联条码,夹具时关联相关的物料,用于入库完成时插入相关物料
*/
@Transient
......@@ -165,6 +170,21 @@ public class Barcode extends BasePo implements Serializable {
*/
private List<Barcode> subCodeList;
/**
* 禁用标识
*/
private String disableMsg;
/**
* 是否需要出库
*/
private boolean isOut = false;
/**
* 工单详情id
*/
private String orderItemId;
/**
* 是否是锡膏
*/
......@@ -228,6 +248,36 @@ public class Barcode extends BasePo implements Serializable {
* 呆滞到期时间(入库时间+呆滞日期)
*/
private Date sluggishTime;
/**
* gr标签
*/
private String grLabel;
private String keeperCode;
/**
* 库别
*/
private String warehouseCode;
/**
* 是否根据查询出库
*/
private String selectMsg;
/**
* 创建人
*/
private String creator;
/**
* 添加相关联条码
*
......@@ -454,7 +504,7 @@ public class Barcode extends BasePo implements Serializable {
return null;
}
public void UpdateSubCode(Barcode barcode) {
public synchronized void UpdateSubCode(Barcode barcode) {
if (subCodeList == null) {
subCodeList = Lists.newArrayList();
......
......@@ -11,6 +11,7 @@ import com.neotel.smfcore.core.barcode.service.manager.IBarcodeManager;
import com.neotel.smfcore.core.barcode.service.manager.IComponentManager;
import com.neotel.smfcore.core.barcode.service.po.Barcode;
import com.neotel.smfcore.core.barcode.service.po.Component;
import com.neotel.smfcore.custom.lizhen.agvBox.bean.GrLabel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
......@@ -350,6 +351,7 @@ public class CodeResolve {
//return codeBeanMap.values();
return codeBeans;
}
public Barcode resolveOneValideBarcode(String codeStr ) throws ValidateException{
return resolveOneValideBarcode(codeStr,COMPONENT_TYPE.COMPONENT);
}
......@@ -384,4 +386,15 @@ public class CodeResolve {
return barcode;
}
public GrLabel resolveGrLable(String codeStr) {
for (BarcodeRule codeRule : barcodeRuleList) {
GrLabel grLabel = codeRule.toGrLable(codeStr);
if (grLabel != null) {
return grLabel;
}
}
return null;
}
}
......@@ -61,5 +61,10 @@ public enum OP_STATUS {
ON_OUT_LINE,
GET_LABEL,
LABELED,
TO_BOX
TO_BOX,
/**
* 需要从流水线上拿走
*/
NEED_AWAY
}
......@@ -490,7 +490,7 @@ public class BaseDeviceHandler implements IDeviceHandler {
task.setExecuteTime(executeTime);
updatePosExecuteTime(posName,executeTime);
}
log.info(task.getBarcode() + "入仓位[" + task.getPosName() + "]完成,执行时间["+executeTime+"]秒");
log.info(task.getBarcode() + "入仓位[" + task.getPosName() + "]完成,执行时间["+executeTime+"]秒");
ReelLockPosUtil.removeReelLockPosInfo(task.getBarcode());
DataLog cancelTask = taskService.findFinishedTask(cid, posName);
if (cancelTask != null && cancelTask.isCancel()) {
......@@ -842,8 +842,8 @@ public class BaseDeviceHandler implements IDeviceHandler {
log.info("ACCSHELF: sourceId=" + sourceId + "的工单[" + order.getOrderNo() + "]开始执行任务:[" + dataLog.getPosName() + "][" + dataLog.getPartNumber() + "][" + dataLog.getBarcode() + "]");
dataLogs.add(dataLog);
isFind = true;
break;
/*isFind = true;
break;*/
}
}
}
......
......@@ -194,7 +194,7 @@ public class MimoBoxHandler extends BaseDeviceHandler {
// }
log.info("根据PN单盘出库:【" + storage.getName() + "_" + storage.getCid() + "】位置仓位【" + pos.getPosName() + "】");
String outResult = taskService.checkout(storage, pos, true, SecurityUtils.getCurrentUsername());
String outResult = taskService.checkout(storage, pos, true, SecurityUtils.getCurrentUsername(),"");
if (!Strings.isNullOrEmpty(outResult)) {
throw new ValidateException("smfcore.error", outResult);
}
......
......@@ -4,7 +4,9 @@ import cn.hutool.core.util.ObjectUtil;
import com.google.common.base.Strings;
import com.neotel.smfcore.common.bean.ResultBean;
import com.neotel.smfcore.common.exception.ValidateException;
import com.neotel.smfcore.common.utils.JsonUtil;
import com.neotel.smfcore.common.utils.SecurityUtils;
import com.neotel.smfcore.common.utils.StringUtils;
import com.neotel.smfcore.core.api.bean.CodeValidateParam;
import com.neotel.smfcore.core.barcode.service.po.Barcode;
import com.neotel.smfcore.core.device.bean.NLShelfOperateBean;
......@@ -21,12 +23,14 @@ import com.neotel.smfcore.core.system.bean.OrderSetting;
import com.neotel.smfcore.core.system.service.po.DataLog;
import com.neotel.smfcore.core.system.util.DevicesStatusUtil;
import com.neotel.smfcore.core.system.util.TaskService;
import com.neotel.smfcore.custom.lizhen.innerBox.rest.InnerBoxRestController;
import com.neotel.smfcore.security.TokenProvider;
import com.neotel.smfcore.security.annotation.AnonymousAccess;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import net.bytebuddy.asm.Advice;
import org.omg.CORBA.PRIVATE_MEMBER;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.ObjectUtils;
......@@ -35,6 +39,7 @@ import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
@Api(tags = "SHELF: NL(智能料架/亮灯料架/普通料架)")
@RestController
......@@ -56,6 +61,9 @@ public class NLShelfHandler extends BaseDeviceHandler {
String putInColor = "green";
int delayCloseTime = 30000;
@Autowired
private InnerBoxRestController innerBoxRestController;
@Override
public StatusBean handleClientRequest(StatusBean statusBean, HttpServletRequest request) {
statusBean.setClientIp(request.getRemoteHost());
......@@ -71,10 +79,10 @@ public class NLShelfHandler extends BaseDeviceHandler {
String cid = statusBean.getCid();
List<DataLog> finishedTasks = taskService.getFinishedTasks();
for (DataLog finishedTask : finishedTasks) {
if(finishedTask.getCid().equals(cid) && finishedTask.isCheckOutTask() && finishedTask.isCancel()){
if (finishedTask.getCid().equals(cid) && finishedTask.isCheckOutTask() && finishedTask.isCancel()) {
//取消的任务,需要关灯
taskService.removeFinishedTask(finishedTask);
statusBean.addData("close",finishedTask.getPosName());
statusBean.addData("close", finishedTask.getPosName());
}
}
......@@ -84,35 +92,52 @@ public class NLShelfHandler extends BaseDeviceHandler {
}
//亮灯
List<DataLog> dataLogs = new ArrayList<>();
Collection<DataLog> queueTasks = taskService.getQueueTasks(statusBean.getCid());
for (DataLog queueTask : queueTasks) {
if (queueTask.isWait()) {
queueTask.setStatus(OP_STATUS.EXECUTING.name());
taskService.updateQueueTask(queueTask);
String rgb = queueTask.getLightColor();
ORDER_COLOR color = ORDER_COLOR.fromRgb(rgb);
if (color == null) {
if (queueTask.isPutInTask()) {
color = ORDER_COLOR.DARKGREEN;
} else if (openZhiYin && ObjectUtil.isNotEmpty(queueTask.getSourceId())) {
List<DataLog> dataLogList = outMap.get(queueTask.getSourceId());
if (dataLogList == null) {
dataLogList = new ArrayList<>();
if (queueTasks != null && !queueTasks.isEmpty()) {
//判断有没有正在执行的任务,如果有,则跳过
boolean hasExecutingTask = false;
for (DataLog queueTask : queueTasks) {
if (queueTask.isExecuting()) {
hasExecutingTask = true;
break;
}
}
if (!hasExecutingTask) {
//按创建时间进行排序,取第一条
queueTasks = queueTasks.stream().distinct().sorted(Comparator.comparing(DataLog::getCreateDate)).collect(Collectors.toList());
DataLog task = null;
for (DataLog queueTask : queueTasks) {
if (task == null) {
task = queueTask;
}
if (task != null) {
String sourceId = task.getSourceId();
if (StringUtils.isNotBlank(sourceId)) {
if (sourceId.equals(queueTask.getSourceId())) {
dataLogs.add(queueTask);
}
} else {
if (StringUtils.isBlank(queueTask.getSourceId())) {
dataLogs.add(queueTask);
}
}
dataLogList.add(queueTask);
outMap.put(queueTask.getSourceId(), dataLogList);
} else {
color = ORDER_COLOR.BLUE;
}
}
statusBean.addData("open",queueTask.getPosName()+"="+color.name());
log.info("库位[" + queueTask.getPosName() + "]["+queueTask.getType()+"]+亮灯:" + color.name());
}
}
List<DataLog> dataLogs = getLightGuideTask(outMap);
for (DataLog task : dataLogs) {
statusBean.addData("open", task.getPosName() + "=" + ORDER_COLOR.fromRgb(task.getLightColor()).name());
task.setStatus(OP_STATUS.EXECUTING.name());
taskService.updateQueueTask(task);
String lightColor = task.getLightColor();
ORDER_COLOR color = ORDER_COLOR.fromRgb(lightColor);
if (color == null) {
color = ORDER_COLOR.BLUE;
}
log.info("料架亮灯:" + task.getPosName() + "=" + color.name());
statusBean.addData("open", task.getPosName() + "=" + color.name());
log.info(JsonUtil.toJsonStr(statusBean.getData()));
}
return statusBean;
}
......@@ -325,7 +350,13 @@ public class NLShelfHandler extends BaseDeviceHandler {
}
private ResultBean outProcess(String code, String sourceId, String loginUser){
Barcode barcode = codeResolve.resolveOneValideBarcode(code);
//判断是否有打印标签的需求,如果有,则返回错误
String nlLabelOrderItemId = innerBoxRestController.getLabelOrderItemId();
if (StringUtils.isNotBlank(nlLabelOrderItemId)){
return ResultBean.newErrorResult(1,"","上一个物料标签请打印完成后再进行出库操作");
}
String barcodeStr = "=1x1=" + code;
Barcode barcode = codeResolve.resolveOneValideBarcode(barcodeStr);
StoragePos inPos = storagePosManager.getByBarcode(barcode.getBarcode());
if (inPos != null) {
Collection<DataLog> allTasks = taskService.getQueueTasks();
......@@ -340,6 +371,11 @@ public class NLShelfHandler extends BaseDeviceHandler {
return ResultBean.newErrorResult(1, "smfcore.shelf.error.orderError", "任务与指定工单[{0}]不一致", new String[]{sourceId});
}
}
//设置nlLable
if (StringUtils.isNotBlank(task.getSubSourceId())) {
log.info(task.getBarcode() + "设置的标签orderItemId:" + task.getSubSourceId());
innerBoxRestController.setLabelOrderItemId(task.getSubSourceId());
}
taskService.addTaskToFinished(inPos, null, loginUser);
opPosLight("close", inPos, "");
log.info(code + " 出库完成, 库位[" + inPos.getPosName() + "]灭灯");
......
......@@ -23,6 +23,7 @@ import com.neotel.smfcore.core.system.service.po.AlarmInfo;
import com.neotel.smfcore.core.system.service.po.DataLog;
import com.neotel.smfcore.core.system.util.DevicesStatusUtil;
import com.neotel.smfcore.core.system.util.TaskService;
import com.neotel.smfcore.custom.lizhen.LizhenApi;
import com.neotel.smfcore.security.annotation.AnonymousAccess;
import com.neotel.smfcore.core.storage.enums.DeviceType;
import com.neotel.smfcore.core.device.handler.IDeviceHandler;
......@@ -62,6 +63,9 @@ public class DeviceController {
@Autowired
private SmfApi smfApi;
@Autowired
private LizhenApi lizhenApi;
private Map<String, IDeviceHandler> handlerMap = new HashMap<>();
public DeviceController(List<IDeviceHandler> deviceHandlerList) {
......@@ -111,7 +115,7 @@ public class DeviceController {
@PostMapping(value = "/service/store/emptyPosForPutin")
@ResponseBody
@AnonymousAccess
public Map<String, Object> emptyPosForPutin(HttpServletRequest request) {
public synchronized Map<String, Object> emptyPosForPutin(HttpServletRequest request) {
String code = request.getParameter("code");
String cids = request.getParameter("cids");
String rfid = request.getParameter("rfid");
......@@ -170,7 +174,7 @@ public class DeviceController {
barcode = barcodeCanPutIn;
}
Barcode barcodeApi = smfApi.barcodeInfo(barcode);
Barcode barcodeApi = lizhenApi.barcodeInfo(barcode);
if (barcodeApi != null){
barcode = barcodeApi;
}
......
......@@ -6,22 +6,16 @@ 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.common.utils.QueryHelp;
import com.neotel.smfcore.common.utils.StringUtils;
import com.neotel.smfcore.common.utils.YmlUpdateUtil;
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;
import com.neotel.smfcore.core.barcode.utils.CodeResolve;
import com.neotel.smfcore.core.device.bean.StatusBean;
import com.neotel.smfcore.core.inList.util.InListCache;
import com.neotel.smfcore.core.language.service.bean.LanguageInfo;
import com.neotel.smfcore.core.language.service.po.LanguageMsg;
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.po.StoragePos;
import com.neotel.smfcore.core.system.bean.OrderSetting;
import com.neotel.smfcore.core.system.service.dao.ICacheItemDao;
......@@ -32,7 +26,6 @@ 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 com.neotel.smfcore.core.system.util.DevicesStatusUtil;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
......@@ -41,8 +34,6 @@ import org.springframework.stereotype.Repository;
import javax.annotation.PostConstruct;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* 缓存
......@@ -74,6 +65,7 @@ public class DataCache {
@Autowired
private IComponentManager componentManager;
/**
* 是否需要推送温湿度报警值
*/
......@@ -155,8 +147,7 @@ public class DataCache {
List<String> ruleList=(List<String>)value;
codeResolve.updateBarcodeRuleList(ruleList);
}
log.info("updateCache ["+cacheKey+"]=["+value+"]");
//log.info("updateCache ["+cacheKey+"]=["+value+"]");
}
/**
......@@ -669,10 +660,10 @@ public class DataCache {
public List<String> getAvailableStorageIds(){
List<String> availableStorageIds = new ArrayList<>();
for (Storage storage : getAllStorage().values()) {
StatusBean bean = DevicesStatusUtil.getStatusBean(storage.getCid());
/*StatusBean bean = DevicesStatusUtil.getStatusBean(storage.getCid());
if (bean == null || bean.timeOut() || !bean.isAvailable()) {
continue;
}
}*/
availableStorageIds.add(storage.getId());
}
return availableStorageIds;
......
......@@ -144,6 +144,7 @@ public class LanguageMsgController {
@ApiOperation("新增资源")
@PostMapping
@PreAuthorize("@el.check('translation')")
@AnonymousAccess
public ResponseEntity<Object> create( @RequestBody LanguageMsgDto resources) {
LanguageMsg msg=languageMsgMapper.toEntity(resources);
languageMsgManager.saveMsg(msg);
......
......@@ -6,7 +6,9 @@ import com.google.common.collect.Lists;
import com.neotel.smfcore.common.bean.ResultBean;
import com.neotel.smfcore.common.exception.ValidateException;
import com.neotel.smfcore.common.utils.Constants;
import com.neotel.smfcore.common.utils.JsonUtil;
import com.neotel.smfcore.common.utils.SecurityUtils;
import com.neotel.smfcore.common.utils.StringUtils;
import com.neotel.smfcore.core.api.SmfApi;
import com.neotel.smfcore.core.barcode.service.manager.IBarcodeManager;
import com.neotel.smfcore.core.barcode.service.po.Barcode;
......@@ -14,6 +16,7 @@ import com.neotel.smfcore.core.device.enums.OP;
import com.neotel.smfcore.core.device.enums.OP_STATUS;
import com.neotel.smfcore.core.device.util.DataCache;
import com.neotel.smfcore.core.language.util.MessageUtils;
import com.neotel.smfcore.core.order.enums.LITEORDER_SOURCE;
import com.neotel.smfcore.core.order.enums.LITEORDER_STATUS;
import com.neotel.smfcore.core.order.enums.ORDER_COLOR;
import com.neotel.smfcore.core.order.service.manager.ILiteOrderItemManager;
......@@ -21,19 +24,23 @@ import com.neotel.smfcore.core.order.service.manager.ILiteOrderManager;
import com.neotel.smfcore.core.order.service.po.LiteOrder;
import com.neotel.smfcore.core.order.service.po.LiteOrderItem;
import com.neotel.smfcore.core.storage.enums.CHECKOUT_TYPE;
import com.neotel.smfcore.core.storage.enums.DeviceType;
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.service.po.DataLog;
import com.neotel.smfcore.core.system.util.TaskService;
import com.sun.org.apache.regexp.internal.RE;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;
import springfox.documentation.spring.web.json.Json;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
/**
* Created by sunke on 2021/7/12.
......@@ -108,7 +115,7 @@ public class LiteOrderCache {
private boolean isProcessTimer = false;
public void runTimer(){
public void runTimer(int priority){
if(!isProcessTimer){
isProcessTimer = true;
try {
......@@ -116,7 +123,7 @@ public class LiteOrderCache {
if(startJob){
//定时执行工单任务
executeOrderTask();
executeOrderTask(priority);
}
}catch (Exception e){
log.error("需求单定时器执行出错:",e);
......@@ -137,23 +144,34 @@ public class LiteOrderCache {
}
}
public void executeOrderTask(){
public void executeOrderTask(int priority) {
Collection<LiteOrder> liteOrders = liteOrderMap.values();
if (liteOrders != null && !liteOrders.isEmpty()) {
//先以创建时间进行排序,再以优先级进行排序
if (priority == 1){
liteOrders = liteOrders.stream().filter(t -> 1 == t.getPriority()).collect(Collectors.toList());
}else {
liteOrders = liteOrders.stream().filter(t -> 1 != t.getPriority()).collect(Collectors.toList());
}
liteOrders = liteOrders.stream().sorted(Comparator.comparing(LiteOrder :: getCreateDate)).collect(Collectors.toList());
//log.info("排序完的工单详情--"+ JsonUtil.toJsonStr(liteOrders));
}
for (LiteOrder order :
liteOrderMap.values()) {
if(order.isNew()||order.isTaskFinished()){
//判断是否到达时间
Date curr=new Date();
if(order.getSDate().before(curr)){
liteOrders) {
if (order.isNew() || order.isTaskFinished()) {
//判断是否到达时间
Date curr = new Date();
if (order.getSDate().before(curr)) {
//开始自动出库
String result= checkOutLiteOrder(order.getOrderNo(),false);
if(!ObjectUtil.isEmpty(result)){
String msg= MessageUtils.getText(result,MessageUtils.getDefaultLocal(),"");
log.info("自动执行工单 【"+order.getOrderNo()+"】 失败:"+msg);
}else{
log.info("自动执行工单 【"+order.getOrderNo()+"】 成功");
String result = checkOutLiteOrder(order.getOrderNo(), false);
if (!ObjectUtil.isEmpty(result)) {
String msg = MessageUtils.getText(result, MessageUtils.getDefaultLocal(), "");
log.info("自动执行工单 【" + order.getOrderNo() + "】 失败:" + msg);
} else {
log.info("自动执行工单 【" + order.getOrderNo() + "】 成功");
break;
}
break;
}
}
}
......@@ -216,19 +234,22 @@ public class LiteOrderCache {
/**
* 结束当前的任务
*/
public void finishedOrderTasks(LiteOrder liteOrder){
if(liteOrder.isOutOne()){
public void finishedOrderTasks(LiteOrder liteOrder) {
if (liteOrder.isOutOne()) {
// setStatus(LITEORDER_STATUS.ONE_FINISHED);
liteOrder.setClosed(true);
}else if(liteOrder.isOutBom()){
} else if (liteOrder.isOutBom()) {
liteOrder.setStatus(LITEORDER_STATUS.BOM_FINISHED);
}else if(liteOrder.isOutTails()){
// setStatus(LITEORDER_STATUS.TAILS_FINISHED);
} else if (liteOrder.isOutTails()) {
//if (!"out".equals(liteOrder.getLogo())) {
//liteOrder.setClosed(true);
//} else {
liteOrder.setStatus(LITEORDER_STATUS.TAILS_FINISHED);
//}
//liteOrder.setClosed(true);
} /*else if (liteOrder.isTaskFinished()) {
liteOrder.setClosed(true);
}else if (liteOrder.isNew()){
liteOrder.setClosed(true);
}
}*/
liteOrder.setTaskFinishedTime(System.currentTimeMillis());
smfApi.onOrderStatusChange(liteOrder);
}
......@@ -237,12 +258,17 @@ public class LiteOrderCache {
* 更新工单状态信息
*/
private synchronized void finishedOrderTask(DataLog task) throws ValidateException {
String barcode = task.getBarcode();
if (barcode.startsWith("CS") || barcode.startsWith("CM") || barcode.startsWith("CB")){
return;
}
if (OP.CHECKOUT == task.getType()) {
//更新工单状态
String orderNo = task.getSourceName();
if (!Strings.isNullOrEmpty(orderNo)) {
LiteOrder order = liteOrderMap.get(orderNo);
//LiteOrder order = null;
if (order == null) {
log.info("缓存中未找到[" + orderNo + "],从数据库中重新加载");
order = liteOrderManager.findByOrderNo(orderNo);
......@@ -260,37 +286,77 @@ public class LiteOrderCache {
}
else if (task.isFinished()) {
order.setFinishedReelCount(order.getFinishedReelCount() + 1);
order.setTotalFinishedReelCount(order.getTotalFinishedReelCount()+1);
order.setTotalFinishedReelCount(order.getTotalFinishedReelCount() + 1);
String orderItemId = task.getSubSourceId();
List<LiteOrderItem> items = new ArrayList<>();
for (LiteOrderItem liteOrderItem : order.getOrderItems()) {
if (liteOrderItem.getId().equals(orderItemId)) {
log.info("工单[" + orderNo + "]的任务" + task.getPartNumber() + "[" + task.getBarcode() + "]出库完成,已完成数量+1=" + order.getFinishedReelCount() + "/" + order.getTaskReelCount());
//更新对应条目的已出库数量和出库盘数
liteOrderItem.setOutNum(liteOrderItem.getOutNum() + task.getNum());
liteOrderItem.setOutReelCount(liteOrderItem.getOutReelCount() + 1);
liteOrderItem.setTotalOutNum(liteOrderItem.getTotalOutNum()+task.getNum());
liteOrderItem.setTotalOutReelCount(liteOrderItem.getTotalOutReelCount()+1);
liteOrderItem = liteOrderItemManager.save(liteOrderItem);
// Barcode barcode = barcodeManager.findByBarcode(task.getBarcode());
// if (barcode != null) {
// Float totalNeedNum = liteOrderItem.getNeedNum() * order.getOrderTimes();
// int barcodeRemainNum = liteOrderItem.getOutNum() - totalNeedNum.intValue();
// if (barcodeRemainNum < 0) {
// barcodeRemainNum = 0;
// }
// barcode.setAmount(barcodeRemainNum);
// log.info("条码[" + task.getBarcode() + "]从工单出库,更改数量为:" + barcodeRemainNum);
// try {
// barcodeManager.save(barcode);
// } catch (ValidateException e) {
// e.printStackTrace();
// }
// }
List<LiteOrderItem> orderItems = order.getOrderItems();
List<LiteOrderItem> liteOrderItems = new ArrayList<>();
if (LITEORDER_SOURCE.OUTTER.name().equals(order.getSource())) {
log.info("更新任务盘数:"+order.getTaskReelCount()+",已完成的数量:"+order.getFinishedReelCount());
if (orderItems != null && !orderItems.isEmpty()) {
for (LiteOrderItem liteOrderItem : orderItems) {
if (liteOrderItem.getId().equals(orderItemId)) {
//判断是否超发,如果是超发,则赋值
if (StringUtils.isNotBlank(order.getIsExcess()) && "true".equals(order.getIsExcess())){
if (!liteOrderItem.isOutFinished()) {
liteOrderItem.setOutNum(liteOrderItem.getOutNum() + task.getNum());
liteOrderItem.setTotalReelCountByOutNum(liteOrderItem.getTotalReelCountByOutNum() + 1);
} else {
liteOrderItem.setOutReelCount(liteOrderItem.getOutReelCount() + 1);
}
}
liteOrderItem.setTotalOutNum(liteOrderItem.getTotalOutNum() + task.getNum());
liteOrderItem.setTotalOutReelCount(liteOrderItem.getTotalOutReelCount() + 1);
liteOrderItem = liteOrderItemManager.save(liteOrderItem);
}
liteOrderItems.add(liteOrderItem);
}
}
order.setOrderItems(liteOrderItems);
} else {
if (orderItems != null && !orderItems.isEmpty()) {
for (LiteOrderItem liteOrderItem : orderItems) {
if (liteOrderItem.getId().equals(orderItemId)) {
log.info("工单[" + orderNo + "]的任务" + task.getPartNumber() + "[" + task.getBarcode() + "]出库完成,已完成数量+1=" + order.getFinishedReelCount() + "/" + order.getTaskReelCount());
//更新对应条目的已出库数量和出库盘数
liteOrderItem.setOutNum(liteOrderItem.getOutNum() + task.getNum());
liteOrderItem.setOutReelCount(liteOrderItem.getOutReelCount() + 1);
liteOrderItem.setTotalOutNum(liteOrderItem.getTotalOutNum() + task.getNum());
liteOrderItem.setTotalOutReelCount(liteOrderItem.getTotalOutReelCount() + 1);
liteOrderItem = liteOrderItemManager.save(liteOrderItem);
}
liteOrderItems.add(liteOrderItem);
}
}
items.add(liteOrderItem);
//log.info(order.getOrderNo() + "更新工单详情:" + JsonUtil.toJsonStr(liteOrderItems));
order.setOrderItems(liteOrderItems);
/* liteOrderManager.createWithItems(order);*/
}
order.setOrderItems(items);
} else {
log.error("工单[" + orderNo + "]的任务[" + task.getBarcode() + "]完成时,状态为:" + task.getStatus());
}
if (LITEORDER_SOURCE.OUTTER.name().equals(order.getSource())){
if (!order.isClosed()) {
//工单未关闭的话,检查状态,全部都出完进行关闭
boolean closed = true;
for (LiteOrderItem liteOrderItem : order.getOrderItems()) {
if (StringUtils.isNotBlank(order.getIsExcess()) && "true".equals(order.getIsExcess())){
if (liteOrderItem.getOutNum() < liteOrderItem.getNeedNum() || liteOrderItem.getOutReelCount() < liteOrderItem.getNeedReelCount()){
closed = false;
break;
}
} else {
if (liteOrderItem.getTotalOutNum() < liteOrderItem.getNeedNum() || liteOrderItem.getTotalOutReelCount() < liteOrderItem.getNeedReelCount()){
closed = false;
break;
}
}
}
if (closed) {
order.setClosed(closed);
}
}
} else {
if (!order.isClosed()) {
//工单未关闭的话,检查状态,全部都出完进行关闭
boolean closed = true;
......@@ -300,12 +366,10 @@ public class LiteOrderCache {
break;
}
}
if(closed){
if (closed) {
order.setClosed(closed);
}
}
} else {
log.error("工单[" + orderNo + "]的任务[" + task.getBarcode() + "]完成时,状态为:" + task.getStatus());
}
if (order.getFinishedReelCount() >= order.getTaskReelCount()) {
......@@ -334,8 +398,35 @@ public class LiteOrderCache {
* 锁定物料
*/
public synchronized String checkOutLiteOrder(String orderNo, boolean outBom) {
LiteOrder cacheOrder = liteOrderMap.get(orderNo);
List<String> freeStorageIds = new ArrayList<>();
//判断是否有空闲料仓
List<String> storageIds = dataCache.getAvailableStorageIds();
for (String storageId : storageIds) {
boolean hasOutTask = false;
Storage storage = dataCache.getStorageById(storageId);
if (!storage.isType(new DeviceType[]{DeviceType.SMD_XLR})) {
continue;
}
List<DataLog> allTasksByCid = taskService.getAllTasksByCid(storage.getCid());
for (DataLog task : allTasksByCid) {
if (!task.isFinished() && !task.isToBox()
&& task.isCheckOutTask()
&& StringUtils.isNotBlank(task.getSourceId()) && !task.isCancel()) {
hasOutTask = true;
break;
}
}
if (!hasOutTask) {
log.info("空闲料仓:" + storage.getName());
freeStorageIds.add(storageId);
}
}
if (freeStorageIds == null || freeStorageIds.isEmpty()) {
return orderNo + "前面已有出库任务,执行完继续执行";
}
LiteOrder cacheOrder = liteOrderMap.get(orderNo);
if (cacheOrder == null) {
cacheOrder = liteOrderManager.findByOrderNo(orderNo);
}
......@@ -344,11 +435,11 @@ public class LiteOrderCache {
return "smfcore.order.out.notFound";
}
if ( !cacheOrder.isTaskFinished() && !cacheOrder.isNew()) {
if (!cacheOrder.isTaskFinished() && !cacheOrder.isNew()) {
log.info("工单[" + orderNo + "]正在执行");
return "smfcore.order.out.executing";
}
if(cacheOrder.isClosed()) {
if (cacheOrder.isClosed()) {
log.info("工单[" + orderNo + "]已关闭,无法出库");
return "smfcore.order.hasClose";
}
......@@ -361,8 +452,8 @@ public class LiteOrderCache {
//先查找是否已经锁定过库位,如果已经锁定过,出锁定的库位
List<StoragePos> lockPosList = storagePosManager.findLockPos(cacheOrder.getOrderNo());
if(lockPosList!=null&& lockPosList.size()>0){
return checkOutOrder(cacheOrder).getMsgKey();
if (lockPosList != null && lockPosList.size() > 0) {
return checkOutOrder(cacheOrder).getMsgKey();
}
log.info("开始执行工单[" + orderNo + "] outBom=" + outBom);
......@@ -381,7 +472,12 @@ public class LiteOrderCache {
//其他出库模式一次性全部生成任务
//List<LiteOrderItem> orderItems = liteOrderItemManager.findOrderItems(cacheOrder.getId());
for (LiteOrderItem orderItem : cacheOrder.getOrderItems()) {
//如果已出数量大于已出盘数,则跳过
if (orderItem.getOutNum() > orderItem.getNeedNum()){
continue;
}
orderItem.setOutNum(0);
orderItem.setOutReelCount(0);
liteOrderItemManager.save(orderItem);
......@@ -398,22 +494,39 @@ public class LiteOrderCache {
}
int assignNum = 0;
while (assignNum < remainNum) {
Collection<String> excludePosIds = excludeOutPosIds();
Collection<String> excludePosIds = excludeOutPosIds();
String partNumber = orderItem.getPn();
StoragePos pos = null;
if(cacheOrder.getType()==2){
if (cacheOrder.getType() == 2) {
//RI
pos=storagePosManager.getByBarcode(orderItem.getRi());
pos = storagePosManager.getByBarcode(orderItem.getRi());
if (pos != null) {
if (excludePosIds.contains(pos.getId())) {
log.info("工单[" + orderNo + "]RI出库,任务数[" + taskReelCount + "]出库位置仓位【" + pos.getPosName() + "】RI=[" + pos.getBarcode().getBarcode() + "]已在操作队列中,跳过不处理");
break;
}
}
}else{
} else {
//PN
pos=storagePosManager.findPartNumberInStorages(availableStorageIds, partNumber, excludePosIds, checkoutType);
do {
//首先按空闲料仓进行出库
pos = storagePosManager.findPartNumberInStorages(freeStorageIds, partNumber, excludePosIds, checkoutType);
//如果为空的话,则出全部的
if (pos == null) {
pos = storagePosManager.findPartNumberInStorages(availableStorageIds, partNumber, excludePosIds, checkoutType);
}
if (pos == null) {
break;
}
try {
smfApi.canPutInAfterResolve(pos.getBarcode());
} catch (ValidateException e) {
e.printStackTrace();
log.error(pos.getBarcode().getBarcode() + ":" + e.getMessage());
pos = null;
}
} while (pos == null);
}
if (pos == null) {
// log.error("未找到可以出库的物料[" + partNumber + "]");
......@@ -422,16 +535,10 @@ public class LiteOrderCache {
assignNum = assignNum + pos.getBarcode().getAmount();
taskReelCount = taskReelCount + 1;
log.info("工单[" + orderNo + "],任务数[" + taskReelCount + "]出库位置仓位【" + pos.getPosName() + "】RI=[" + pos.getBarcode().getBarcode() + "] PN=[" + partNumber + "] num:" + pos.getBarcode().getAmount());
DataLog task = newTask(pos) ;
DataLog task = newTask(pos);
task.setSourceId(cacheOrder.getId());
if (pos.getBarcode().getBarcode().startsWith("CS") ||
pos.getBarcode().getBarcode().startsWith("CM") ||
pos.getBarcode().getBarcode().startsWith("CB")){
taskReelCount = cacheOrder.getOrderItems().size();
} else {
task.setSourceName(cacheOrder.getOrderNo());
}
task.setSourceName(cacheOrder.getOrderNo());
task.setSubSourceId(orderItem.getId());
task.setSubSourceInfo(orderItem.getFeederInfo());
task.setType(OP.CHECKOUT);
......@@ -442,7 +549,7 @@ public class LiteOrderCache {
taskService.addTaskToExecute(task);
}
//如果是RI出库,只有一盘,出完就结束
if(cacheOrder.getType()==2){
if (cacheOrder.getType() == 2) {
break;
}
}
......@@ -614,61 +721,194 @@ public class LiteOrderCache {
return null;
}
public Collection<String> excludeBarcodeIds() {
Collection<String> barcodeIds = new ArrayList<>();
Collection<LiteOrder> liteOrders = liteOrderMap.values();
if (liteOrders != null && !liteOrders.isEmpty()) {
for (LiteOrder liteOrder : liteOrderMap.values()) {
List<LiteOrderItem> orderItems = liteOrder.getOrderItems();
for (LiteOrderItem orderItem : orderItems) {
barcodeIds.add(orderItem.getRi());
}
}
public synchronized String checkOutLiteOrderOut(String orderNo, boolean outBom,List<String> orderItemIds,String isExcess) {
LiteOrder cacheOrder = liteOrderMap.get(orderNo);
if (cacheOrder == null) {
cacheOrder = liteOrderManager.findByOrderNo(orderNo);
}
return barcodeIds;
}
public String executeOrderByBarcode(String barcode){
Collection<LiteOrder> liteOrders = liteOrderMap.values();
if (liteOrders != null && !liteOrders.isEmpty()) {
for (LiteOrder liteOrder : liteOrderMap.values()) {
for (LiteOrderItem orderItem : liteOrder.getOrderItems()) {
if (orderItem.getRi().equals(barcode)) {
return liteOrder.getOrderNo();
}
}
}
if (cacheOrder == null) {
return "smfcore.order.out.notFound";
}
return null;
}
public Collection<LiteOrderItem> executeItems() {
Collection<LiteOrderItem> items = new ArrayList<>();
Collection<LiteOrder> liteOrders = liteOrderMap.values();
if (liteOrders != null && !liteOrders.isEmpty()) {
for (LiteOrder liteOrder : liteOrderMap.values()) {
List<LiteOrderItem> orderItems = liteOrder.getOrderItems();
for (LiteOrderItem orderItem : orderItems) {
items.add(orderItem);
}
}
if (cacheOrder.isClosed()) {
log.info("工单[" + orderNo + "]已关闭,无法出库");
return "smfcore.order.hasClose";
}
if (!cacheOrder.isTaskFinished() && !cacheOrder.isNew()) {
log.info("工单[" + orderNo + "]正在执行");
return "smfcore.order.out.executing";
}
return items;
}
ORDER_COLOR nextColor = getNextColor();
if (nextColor == null) {
log.info("执行工单[" + orderNo + "] outBom=" + outBom + "时,已达最大可执行工单数");
return "smfcore.order.out.maxOrder";
}
public Collection<String> executePartNumber(){
Collection<String> partNumbers = new ArrayList<>();
Collection<LiteOrder> liteOrders = liteOrderMap.values();
if (liteOrders != null && !liteOrders.isEmpty()) {
for (LiteOrder liteOrder : liteOrderMap.values()) {
List<LiteOrderItem> orderItems = liteOrder.getOrderItems();
for (LiteOrderItem orderItem : orderItems) {
partNumbers.add(orderItem.getPn());
//料仓信息
List<String> availableStorageIds = dataCache.getAvailableStorageIds();
//出库方式
CHECKOUT_TYPE checkoutType = dataCache.getCheckOutType();
log.info("开始执行工单[" + orderNo + "] outBom=" + outBom);
cacheOrder.setTaskReelCount(0);
cacheOrder.setTaskFinishedTime(-1);
cacheOrder.setFinishedReelCount(0);
cacheOrder.setStatus(LITEORDER_STATUS.TAILS);
//判断是否属于超发,如果为空,则取工单上的
if (StringUtils.isBlank(isExcess)){
isExcess = cacheOrder.getIsExcess();
}
List<StoragePos> needOutPoss = new ArrayList<>();
int orderTaskReelCount = 0;
//开始循环处理工单详情
for (LiteOrderItem orderItem : cacheOrder.getOrderItems()) {
//排除的仓位信息
Collection<String> excludePosIds = taskService.excludePosIds();
//判断是否包含需要出库的
if (orderItemIds != null && !orderItemIds.isEmpty()){
if (!orderItemIds.contains(orderItem.getId())){
continue;
}
}
int outReelCount = 0;
int outNumCount = 0;
//如果是超发情况
if (StringUtils.isNotBlank(isExcess) && "true".equals(isExcess)) {
if (orderItem.getOutNum() >= orderItem.getNeedNum() && orderItem.getOutReelCount() >= orderItem.getNeedReelCount()) {
continue;
}
outNumCount = orderItem.getOutNum();
outReelCount = orderItem.getOutReelCount();
}
//如果不是超发,则满足其中一个即可
else {
if (orderItem.getTotalOutNum() >= orderItem.getNeedNum() && orderItem.getTotalOutReelCount() >= orderItem.getNeedReelCount()) {
continue;
}
outNumCount = orderItem.getTotalOutNum();
outReelCount = orderItem.getTotalOutReelCount();
}
while (outReelCount < orderItem.getNeedReelCount() || outNumCount < orderItem.getNeedNum()) {
//根据查询条件,查找新的库位
boolean hasOutReel = false;
String warehouseCode = orderItem.getWarehouseCode(); //厂别
String brand = orderItem.getBrand(); //供应商
String pn = orderItem.getPn(); //料号
StoragePos pos = storagePosManager.findPartNumberInStorages(availableStorageIds, pn, excludePosIds, checkoutType, warehouseCode, brand);
if (pos == null) {
log.info(orderItem.getOrderId() + "厂商:" + warehouseCode + ",供应商:" + brand + ",料号:" + pn + "未找到存在库位,跳过");
break;
}
//String barcodeStr = pos.getBarcode().getBarcode();
Barcode barcode = pos.getBarcode();
List<Barcode> subCodeList = barcode.getSubCodeList();
//进行排序
subCodeList = subCodeList.stream().sorted(Comparator.comparing(Barcode::getPosName)).collect(Collectors.toList());
for (Barcode subCode : subCodeList) {
if (outReelCount >= orderItem.getNeedReelCount() && outNumCount >= orderItem.getNeedNum()) {
break;
}
if (subCode.isOut()) {
continue;
}
//判断厂别
if (StringUtils.isNotBlank(warehouseCode)) {
if (!warehouseCode.equals(subCode.getWarehouseCode())) {
continue;
}
}
//判断供应商
if (StringUtils.isNotBlank(brand)) {
if (!brand.equals(subCode.getProvider())) {
continue;
}
}
//判断料号
if (StringUtils.isNotBlank(pn)) {
if (!pn.equals(subCode.getPartNumber())) {
continue;
}
}
//校验是否为禁用料
try {
smfApi.canPutInAfterResolve(subCode);
} catch (ValidateException e) {
e.printStackTrace();
log.info(subCode.getBarcode() + "为禁用料,校验失败:" + e.getMessage());
continue;
}
subCode.setOut(true);
subCode.setOrderItemId(orderItem.getId());
subCode = barcodeManager.save(subCode);
barcode.UpdateSubCode(subCode);
barcodeManager.saveBarcode(barcode);
orderTaskReelCount ++;
log.info(subCode.getBarcode()+"---"+orderTaskReelCount);
hasOutReel = true;
//判断是否超发,如果超发,先判断是否满足数量.再判断是否满足卷数
if (StringUtils.isNotBlank(isExcess) && "true".equals(isExcess)) {
if (outNumCount >= orderItem.getNeedNum()) {
outReelCount++;
} else {
outNumCount = outNumCount + subCode.getAmount();
}
}
//如果不是超发订单,
else {
outReelCount++;
outNumCount = outNumCount + subCode.getAmount();
}
}
excludePosIds.add(pos.getId());
if (hasOutReel) {
needOutPoss.add(pos);
pos.setBarcode(barcode);
storagePosManager.save(pos);
}
}
}
return partNumbers;
if (needOutPoss != null && !needOutPoss.isEmpty()){
for (StoragePos pos : needOutPoss) {
Barcode barcode = pos.getBarcode();
DataLog task = new DataLog(dataCache.getStorageById(pos.getStorageId()), barcode, pos);
task.setSourceId(cacheOrder.getId());
task.setSourceName(cacheOrder.getOrderNo());
task.setSubSourceId(barcode.getLockName());
task.setSubSourceInfo(barcode.getLockName());
task.setType(OP.CHECKOUT);
//task.setCreator(SecurityUtils.getCurrentUsername());
task.setStatus(OP_STATUS.WAIT.name());
try {
taskService.addTaskToExecute(task);
}catch (Exception e){
e.getMessage();
}
}
}
cacheOrder.setIsExcess(isExcess);
cacheOrder.setTaskReelCount(orderTaskReelCount);
cacheOrder.setTotalTaskReelCount(cacheOrder.getTotalTaskReelCount() + orderTaskReelCount);
log.info("工单[" + orderNo + "]任务分配结束,任务数[" + orderTaskReelCount + "]");
smfApi.onOrderStatusChange(cacheOrder);
//有需要出库的
if (orderTaskReelCount <= 0) {
finishedOrderTasks(cacheOrder);
}
liteOrderManager.save(cacheOrder);
liteOrderMap.put(cacheOrder.getOrderNo(), cacheOrder);
if (orderTaskReelCount <= 0) {
//return "工单无可执行的任务";
return "smfcore.order.out.noTask";
}
return "";
}
}
package com.neotel.smfcore.core.order.enums;
public enum LITEORDER_SOURCE {
OUTTER,
INNER
}
......@@ -17,6 +17,7 @@ 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.order.LiteOrderCache;
import com.neotel.smfcore.core.order.enums.LITEORDER_SOURCE;
import com.neotel.smfcore.core.order.enums.LITEORDER_STATUS;
import com.neotel.smfcore.core.order.rest.bean.dto.OrderDto;
import com.neotel.smfcore.core.order.rest.bean.mapstruct.OrderItemMapper;
......@@ -179,7 +180,14 @@ public class OrderController {
if (liteOrder == null) {
throw new ValidateException("smfcore.valueNotFind", "未找到{0}[{1}]", new String[]{"orderNo", orderNo});
}
String result = liteOrderCache.checkOutLiteOrder(liteOrder.getOrderNo(), false);
String result = "";
String isExcess = mapValues.get("isExcess");
if (LITEORDER_SOURCE.OUTTER.name().equals(liteOrder.getSource())) {
result = liteOrderCache.checkOutLiteOrderOut(liteOrder.getOrderNo(),false,null,isExcess);
} else {
result = liteOrderCache.checkOutLiteOrder(liteOrder.getOrderNo(), false);
}
if (ObjectUtil.isEmpty(result)) {
return ResultBean.newOkResult(result);
} else {
......@@ -196,7 +204,17 @@ public class OrderController {
if (orderNo == null) {
throw new ValidateException("smfcore.valueCanotNull", "{0}不能为空", new String[]{"orderNo"});
}
String result = liteOrderCache.checkOutLiteOrder(orderNo, true);
LiteOrder liteOrder = liteOrderManager.findByOrderNo(orderNo);
if (liteOrder == null) {
throw new ValidateException("smfcore.valueNotFind", "未找到{0}[{1}]", new String[]{"orderNo", orderNo});
}
String result = "";
if ("out".equals(""/*liteO"rder.getLogo()*/)) {
result = liteOrderCache.checkOutLiteOrderOut(liteOrder.getOrderNo(),true,null,"");
} else {
result = liteOrderCache.checkOutLiteOrder(liteOrder.getOrderNo(), true);
}
if (ObjectUtil.isEmpty(result)) {
return ResultBean.newOkResult(result);
} else {
......@@ -210,11 +228,25 @@ public class OrderController {
@PreAuthorize("@el.check('workOrder')")
public ResultBean outTails(@RequestBody Map<String, String> mapValues) {
String orderNo = mapValues.get("orderNo");
String orderItemId = mapValues.get("orderItemId");
List<String> orderItemIds = new ArrayList<>();
if (StringUtils.isNotBlank(orderItemId)){
orderItemIds = JsonUtil.toList(orderItemId,String.class);
}
if (orderNo == null) {
throw new ValidateException("smfcore.valueCanotNull", "{0}不能为空", new String[]{"orderNo"});
}
String result = liteOrderCache.checkOutLiteOrder(orderNo, false);
LiteOrder liteOrder = liteOrderManager.findByOrderNo(orderNo);
if (liteOrder == null) {
throw new ValidateException("smfcore.valueNotFind", "未找到{0}[{1}]", new String[]{"orderNo", orderNo});
}
String result = "";
if (LITEORDER_SOURCE.OUTTER.name().equals(liteOrder.getSource())) {
result = liteOrderCache.checkOutLiteOrderOut(liteOrder.getOrderNo(),false,orderItemIds,"");
} else {
result = liteOrderCache.checkOutLiteOrder(liteOrder.getOrderNo(), false);
}
if (ObjectUtil.isEmpty(result)) {
return ResultBean.newOkResult(result);
} else {
......@@ -281,20 +313,51 @@ public class OrderController {
@GetMapping("/detial")
@PreAuthorize("@el.check('workOrder:detial')")
@AnonymousAccess
public OrderDto detial(@RequestParam(required = false) String id, @RequestParam(required = false) String orderNo) {
public OrderDto detial(@RequestParam(required = false) String id, @RequestParam(required = false) String orderNo,
@RequestParam(required = false) String warehouseCode,@RequestParam(required = false) String brand) {
if (!ObjectUtils.isEmpty(id)) {
LiteOrder liteOrder = liteOrderManager.get(id);
if (liteOrder != null) {
OrderDto dto = orderMapper.toDto(liteOrder);
dto.setOrderItems(orderItemMapper.toDto(liteOrder.getOrderItems()));
List<LiteOrderItem> orderItemsByWarehouseCode = new ArrayList<>();
List<LiteOrderItem> orderItems = liteOrder.getOrderItems();
for (LiteOrderItem orderItem : orderItems) {
if (StringUtils.isNotBlank(warehouseCode)) {
if (!warehouseCode.equals(orderItem.getWarehouseCode())) {
continue;
}
}
if (StringUtils.isNotBlank(brand)) {
if (!brand.equals(orderItem.getBrand())) {
continue;
}
}
orderItemsByWarehouseCode.add(orderItem);
}
dto.setOrderItems(orderItemMapper.toDto(orderItemsByWarehouseCode));
return dto;
}
} else if (!ObjectUtils.isEmpty(orderNo)) {
LiteOrder liteOrder = liteOrderManager.findByOrderNo(orderNo);
if (liteOrder != null) {
OrderDto dto = orderMapper.toDto(liteOrder);
dto.setOrderItems(orderItemMapper.toDto(liteOrder.getOrderItems()));
List<LiteOrderItem> orderItemsByWarehouseCode = new ArrayList<>();
List<LiteOrderItem> orderItems = liteOrder.getOrderItems();
for (LiteOrderItem orderItem : orderItems) {
if (StringUtils.isNotBlank(warehouseCode)) {
if (!warehouseCode.equals(orderItem.getWarehouseCode())) {
continue;
}
}
if (StringUtils.isNotBlank(brand)) {
if (!brand.equals(orderItem.getBrand())) {
continue;
}
}
orderItemsByWarehouseCode.add(orderItem);
}
dto.setOrderItems(orderItemMapper.toDto(orderItemsByWarehouseCode));
return dto;
}
}
......
......@@ -5,6 +5,8 @@ import lombok.Getter;
import lombok.Setter;
import org.springframework.data.annotation.Transient;
import java.util.Date;
@Getter
@Setter
public class OrderItemDto {
......@@ -51,4 +53,61 @@ public class OrderItemDto {
@Transient
private int inventoryNum = 0;
@ApiModelProperty("厂别")
private String plantCode;
@ApiModelProperty("全部已出数量")
private int totalOutNum;
@ApiModelProperty("工单号")
private String so;
@ApiModelProperty("线别")
private String line;
@ApiModelProperty("批次号")
private String batchCode;
@ApiModelProperty("全部已出盘数")
private String totalOutReelCount;
@ApiModelProperty("厂商")
private String brand;
@ApiModelProperty("库别")
private String warehouseCode;
@ApiModelProperty("超发数量")
private int excessOutNum =0;
@ApiModelProperty("超发卷数")
private int excessOutReel =0;
@ApiModelProperty("工单号")
private String mo;
@ApiModelProperty("缺失数量")
private int lackNum = 0;
@ApiModelProperty("缺失盘数")
private int lackReel = 0;
@ApiModelProperty("创建时间")
private Date createDate = new Date();
@ApiModelProperty("优先级")
private int priority = 0;
@ApiModelProperty("点位")
private String subSlot;
@ApiModelProperty("站位")
private String slot;
@ApiModelProperty("机器名称")
private String machineName;
@ApiModelProperty("是否缺料")
private boolean isLack = false;
}
......@@ -43,7 +43,7 @@ public class LiteOrderItemManagerImpl implements ILiteOrderItemManager {
@Override
public void delete(LiteOrderItem object) throws ValidateException {
liteOrderItemDao.removeOneById(object.getId());
}
@Override
......
......@@ -112,6 +112,17 @@ public class LiteOrder extends BasePo implements Serializable {
*/
private String boxNumber;
/**
* 工单优先级
*/
private int priority = 0;
/**
* 是否超发
*/
private String isExcess;
public void setClosed(boolean value){
this.closed=value;
if(value){
......
package com.neotel.smfcore.core.order.service.po;
import com.neotel.smfcore.common.base.BasePo;
import com.neotel.smfcore.core.barcode.service.po.Barcode;
import lombok.Data;
import org.springframework.data.annotation.Transient;
import org.springframework.data.mongodb.core.mapping.Document;
import java.io.Serializable;
import java.util.List;
@Data
@Document
public class LiteOrderItem extends BasePo implements Serializable ,Comparable<LiteOrderItem> {
......@@ -26,24 +29,30 @@ public class LiteOrderItem extends BasePo implements Serializable ,Comparable<Li
private int needNum = 0;
/**
* 总需求料盘数
* 当前任务已出数量
*/
private int needReelCount = 0;
private int outNum = 0;
/**
* 当前任务已出数量
* 累计已出数量
*/
private int outNum = 0;
private int totalOutNum = 0;
/**
* 当前任务已出盘数
* 当前已出数量卷数总和
*/
private int outReelCount = 0;
private int totalReelCountByOutNum = 0;
/**
* 累计已出数量
* 总需求料盘数
*/
private int totalOutNum = 0;
private int needReelCount = 0;
/**
* 当前任务已出盘数
*/
private int outReelCount = 0;
/**
* 累计已出盘数
......@@ -86,6 +95,80 @@ public class LiteOrderItem extends BasePo implements Serializable ,Comparable<Li
*/
private String posName;
/**
* 厂商
*/
private String brand;
/**
* 批次号
*/
private String batchCode;
/**
* 库别
*/
private String warehouseCode;
/**
* 操作人
*/
private String operator;
/**
* 任务单号
*/
private String mo;
/**
* 缺料预警id
*/
private String warningItemId;
/**
* 点位
*/
private String subSlot;
/**
* 站位
*/
private String slot;
/**
* 工单号
*/
private String orderNo;
/**
* 线别
*/
private String line;
/**
* 厂别
*/
private String plantCode;
/**
* 机器名称
*/
private String machineName;
/**
* 优先级
*/
private int priority = 0;
/**
* 是否缺料
*/
private boolean isLack = false;
/**
* 出库是否满足要求,已出库数量大于需求数量
*/
......
......@@ -10,7 +10,7 @@ import java.util.Date;
@Data
public class ReportQuery implements Serializable {
@DateTimeFormat(pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private BetweenData<Date> updateDate;
private String pn;
}
......@@ -283,7 +283,7 @@ public class MaterialController {
}
log.info("出库料仓【" + storage.getName() + "_" + storage.getCid() + "】位置仓位【" + pos.getPosName() + "】");
String outResult = taskService.checkout(storage, pos, true, SecurityUtils.getCurrentUsername());
String outResult = taskService.checkout(storage, pos, true, SecurityUtils.getCurrentUsername(),"");
if (!Strings.isNullOrEmpty(outResult)) {
throw new ValidateException("smfcore.error", outResult);
}
......@@ -306,7 +306,7 @@ public class MaterialController {
}
log.info("出库料仓【" + storage.getName() + "_" + storage.getCid() + "】位置仓位【" + pos.getPosName() + "】");
String outResult = taskService.checkout(storage, pos, true, SecurityUtils.getCurrentUsername());
String outResult = taskService.checkout(storage, pos, true, SecurityUtils.getCurrentUsername(),"");
if (!Strings.isNullOrEmpty(outResult)) {
throw new ValidateException("smfcore.error", outResult);
}
......
......@@ -10,12 +10,16 @@ import com.neotel.smfcore.common.exception.ValidateException;
import com.neotel.smfcore.common.utils.FileUtil;
import com.neotel.smfcore.common.utils.QueryHelp;
import com.neotel.smfcore.common.utils.SecurityUtils;
import com.neotel.smfcore.common.utils.StringUtils;
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.dto.CodeDto;
import com.neotel.smfcore.core.barcode.rest.bean.mapstruct.CodeMapper;
import com.neotel.smfcore.core.barcode.service.manager.IBarcodeManager;
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.language.util.MessageUtils;
import com.neotel.smfcore.core.message.util.DeviceMessageUtil;
......@@ -29,8 +33,10 @@ import com.neotel.smfcore.core.storage.rest.query.StoragePosQueryCriteria;
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.service.po.DataLog;
import com.neotel.smfcore.core.system.util.TaskService;
import com.neotel.smfcore.custom.siemens.SiemensApi;
import com.neotel.smfcore.security.annotation.AnonymousAccess;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
......@@ -76,6 +82,9 @@ public class StoragePosController {
@Autowired
private CodeMapper codeMapper;
@Autowired
private IBarcodeManager barcodeManager;
@ApiOperation("查询库位")
@GetMapping
......@@ -195,7 +204,7 @@ public class StoragePosController {
// QisdaApi.ClearStockBy(storagePos.getPosName());
Barcode barcode = storagePos.getBarcode();
if (barcode != null) {
barcode = barcodeManager.get(barcode.getId());
log.info("清理库位[" + storagePos.getPosName() + "]中的库存" + barcode.getBarcode());
String opUser = SecurityUtils.getCurrentUsername();
log.info(opUser + "清理库位[" + storagePos.getPosName() + "]中的库存" + barcode.getBarcode());
......@@ -288,6 +297,25 @@ public class StoragePosController {
if (ObjectUtil.isNotEmpty(criteria.getStorageId()) && criteria.getStorageId().equals("0")) {
criteria.setStorageId(null);
}
if (ObjectUtil.isNotEmpty(criteria.getBatch())){
String batch = criteria.getBatch();
criteria.setBatchList(Arrays.asList(batch.split(",")));
criteria.setBatch(null);
}
if (ObjectUtil.isNotEmpty(criteria.getDateCode())){
String dateCode = criteria.getDateCode();
criteria.setDateCodeList(Arrays.asList(dateCode.split(",")));
criteria.setDateCode(null);
}
if (ObjectUtil.isNotEmpty(criteria.getPartNumber())){
String partNumber = criteria.getPartNumber();
criteria.setPartNumberList(Arrays.asList(partNumber.split(",")));
criteria.setPartNumber(null);
}
Query query = QueryHelp.getQuery(criteria);
Criteria baseCriteria = Criteria.where("used").is(true);
......@@ -327,6 +355,136 @@ public class StoragePosController {
return new PageData(StoragePosDtos, pages.getTotalElements());
}
@ApiOperation("根据条件查找出库")
@GetMapping("/out")
@AnonymousAccess
public ResultBean storagePosFind(StoragePosFindCriteria criteria) {
//判断查询条件是否为空
String provider = criteria.getProvider();
String batch = criteria.getBatch();
String dateCode = criteria.getDateCode();
String stationName = criteria.getStationName();
String warehouseCode = criteria.getWarehouseCode();
String box = criteria.getBox();
String partNumber = criteria.getPartNumber();
if (StringUtils.isBlank(stationName)) {
return ResultBean.newErrorResult(-1, "", "请选择对应的工位");
}
if (StringUtils.isBlank(partNumber) && StringUtils.isBlank(provider) && StringUtils.isBlank(batch) && StringUtils.isBlank(dateCode) && StringUtils.isBlank(warehouseCode)) {
return ResultBean.newErrorResult(-1, "", "请核实查询条件是否为空");
}
Query query = getPosFindCriteria(criteria);
List<StoragePos> storagePoss = storagePosManager.findByQuery(query);
if (storagePoss != null && !storagePoss.isEmpty()) {
String selectMsg = getSelectMsg(partNumber, provider, batch, dateCode);
for (StoragePos pos : storagePoss) {
//先把里边的物料进行标识
Barcode pidBarcode = pos.getBarcode();
if (StringUtils.isNotBlank(box)) {
if (!box.equals(pidBarcode.getBarcode())) {
continue;
}
}
//排除正在执行的库位
Collection<String> excludePosIds = taskService.excludePosIds();
if (excludePosIds != null && !excludePosIds.isEmpty() && excludePosIds.contains(pos.getId())) {
log.info("库位:" + pos.getPosName() + "正在执行,跳过");
continue;
}
//判断是否有出库任务
boolean hasOutReel = false;
List<Barcode> subCodeList = pidBarcode.getSubCodeList();
for (Barcode barcode : subCodeList) {
if (barcode.isOut()){
continue;
}
List<String> partNumberList = criteria.getPartNumberList();
if (partNumberList != null && !partNumberList.isEmpty()) {
if (!partNumberList.contains(barcode.getPartNumber())) {
continue;
}
}
if (StringUtils.isNotBlank(provider)) {
if (!barcode.getProvider().equals(provider)) {
continue;
}
}
List<String> batchList = criteria.getBatchList();
if (batchList != null && !batchList.isEmpty()) {
if (!batchList.contains(barcode.getBatch())) {
continue;
}
}
List<String> dateCodeList = criteria.getDateCodeList();
if (dateCodeList != null && !dateCodeList.isEmpty()) {
if (!dateCodeList.contains(barcode.getDateCode())) {
continue;
}
}
if (StringUtils.isNotBlank(warehouseCode)) {
if (!warehouseCode.equals(barcode.getWarehouseCode())) {
continue;
}
}
barcode.setOut(true);
barcode.setSelectMsg(selectMsg);
//保存信息
barcode = barcodeManager.save(barcode);
pidBarcode.UpdateSubCode(barcode);
barcodeManager.saveBarcode(pidBarcode);
hasOutReel = true;
}
if (hasOutReel) {
DataLog task = new DataLog(dataCache.getStorageById(pos.getStorageId()), pos.getBarcode(), pos);
task.setType(OP.CHECKOUT);
task.setPutInDate(pos.getBarcode().getPutInDate());
task.setStatus(OP_STATUS.WAIT.name());
task.setSingleOut(false);
task.setOperator(SecurityUtils.getCurrentUsername());
task.setStorageId(pos.getStorageId());
if (StringUtils.isNotBlank(stationName)) {
task.setLoc(stationName);
}
task.setBoxPosName(pos.getPosName());
taskService.addTaskToExecute(task);
}
}
return ResultBean.newOkResult("");
}
return ResultBean.newErrorResult(-1, "", "未找到可以出库的物料");
}
private String getSelectMsg(String partNumber, String provider, String batch, String dateCode) {
String selectMsg = "";
if (StringUtils.isNotBlank(partNumber)) {
selectMsg = selectMsg + "料号:" + partNumber;
}
if (StringUtils.isNotBlank(provider)) {
if (StringUtils.isNotBlank(selectMsg)) {
selectMsg = selectMsg + ",";
}
selectMsg = selectMsg + "供应商:" + provider;
}
if (StringUtils.isNotBlank(batch)) {
if (StringUtils.isNotBlank(selectMsg)) {
selectMsg = selectMsg + ",";
}
selectMsg = selectMsg + "批次:" + batch;
}
if (StringUtils.isNotBlank(dateCode)) {
if (StringUtils.isNotBlank(selectMsg)) {
selectMsg = selectMsg + ",";
}
selectMsg = selectMsg + "dateCode:" + dateCode;
}
return selectMsg;
}
@ApiOperation("导出查找出库列表")
@GetMapping(value = "/find/download")
@PreAuthorize("@el.check('checkOut')")
......@@ -415,7 +573,7 @@ public class StoragePosController {
// }
log.info("出库料仓【" + storage.getName() + "_" + storage.getCid() + "】位置仓位【" + pos.getPosName() + "】");
String outResult = taskService.checkout(storage, pos, isSingleOut,SecurityUtils.getCurrentUsername());
String outResult = taskService.checkout(storage, pos, isSingleOut,SecurityUtils.getCurrentUsername(),null);
if (!Strings.isNullOrEmpty(outResult)) {
throw new ValidateException("smfcore.error", outResult);
}
......
......@@ -56,22 +56,52 @@ public class StoragePosFindCriteria {
@QueryCondition(blurry = "barcode.providerNumber" )
private String providerNumber;
@QueryCondition(blurry = "barcode.partNumber")
private String partNumber;
@QueryCondition(type = QueryCondition.Type.IN,propName = "barcode.subCodeList.partNumber")
private List<String> partNumberList;
@QueryCondition(blurry = "barcode.memo")
private String memo;
@QueryCondition(propName = "barcode.lockId")
private String lockId;
@QueryCondition(blurry = "barcode.batch")
@QueryCondition(blurry = "barcode.batch,barcode.subCodeList.batch")
private String batch;
@QueryCondition(blurry = "barcode.provider")
@QueryCondition(type = QueryCondition.Type.IN,propName = "barcode.subCodeList.batch")
@ApiModelProperty("批次列表")
private List<String> batchList;
@QueryCondition(blurry = "barcode.provider,barcode.subCodeList.provider")
@ApiModelProperty("供应商")
private String provider;
@QueryCondition(propName = "barcode.msl")
@ApiModelProperty("等级")
private String msl;
@QueryCondition(propName = "barcode.subCodeList.dateCode")
@ApiModelProperty("日期代码")
private String dateCode;
@QueryCondition(type = QueryCondition.Type.IN,propName = "barcode.subCodeList.dateCode")
@ApiModelProperty("批次列表")
private List<String> dateCodeList;
@ApiModelProperty("工位名称")
private String stationName;
@QueryCondition(propName = "barcode.subCodeList.warehouseCode")
@ApiModelProperty("库别")
private String warehouseCode;
@ApiModelProperty("料箱号")
private String box;
public int getComponentType(){
int componentType = getType();
if (componentType != -1) {
......
......@@ -67,5 +67,7 @@ public interface IStoragePosManager extends IBaseManager<StoragePos> {
List<StoragePos> getSameSizeContinuityEmptyPosList(Storage storage, Barcode barcode) throws ValidateException;
StoragePos findByQueryOne(Query query);
StoragePos getEmptyPosByStorage(Storage storage, Barcode barcode, Collection<String> excludePosIds, String lastPosId,String logo) throws ValidateException;
StoragePos findPartNumberInStorages(List<String> availableStorageIds, String pn, Collection<String> excludePosIds, CHECKOUT_TYPE checkoutType, String warehouseCode, String brand);
}
......@@ -7,6 +7,7 @@ import com.google.common.collect.Maps;
import com.neotel.smfcore.common.bean.PageData;
import com.neotel.smfcore.common.exception.ValidateException;
import com.neotel.smfcore.common.utils.PointUtil;
import com.neotel.smfcore.common.utils.StringUtils;
import com.neotel.smfcore.core.barcode.bean.PlateSizeBean;
import com.neotel.smfcore.core.barcode.service.po.Barcode;
import com.neotel.smfcore.core.storage.bean.InventoryItem;
......@@ -30,6 +31,7 @@ import org.springframework.stereotype.Service;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.regex.Pattern;
@Service
@Slf4j
......@@ -275,6 +277,36 @@ public class StoragePosManagerImpl implements IStoragePosManager {
return pos;
}
@Override
public StoragePos findPartNumberInStorages(List<String> storageIdList, String pn, Collection<String> excludePosIds, CHECKOUT_TYPE checkOutType, String warehouseCode, String brand) {
Criteria c = Criteria.where("id").nin(excludePosIds)
.and("enabled").is(true)//可用
.and("barcode.lockId").is(null);//没有被锁定的仓位;
if (storageIdList != null) {
c = c.and("storageId").in(storageIdList);
}
if (ObjectUtil.isNotEmpty(warehouseCode)) {
c.and("barcode.subCodeList.warehouseCode").is(warehouseCode);
}
if (ObjectUtil.isNotEmpty(brand)) {
c.and("barcode.subCodeList.provider").is(brand);
}
if (ObjectUtil.isNotEmpty(pn)) {
c.and("barcode.subCodeList.partNumber").is(pn);
}
Sort sort = getSortByCheckOutType(checkOutType);
Query q = new Query(c);
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;
}
/**
* 根据出库方式获取不同的 Sort
*/
......@@ -562,10 +594,54 @@ public class StoragePosManagerImpl implements IStoragePosManager {
}
@Override
public StoragePos findByQueryOne(Query query) {
return storagePosDao.findOne(query);
public StoragePos getEmptyPosByStorage(Storage storage, Barcode barcode, Collection<String> excludePosIds, String lastPosId, String logo) throws ValidateException {
Criteria c = Criteria.where("storageId").is(storage.getId());
COMPATIBLE_TYPE compatibleType = storage.getCompatibleType();
if (compatibleType == COMPATIBLE_TYPE.EXACT_MATCH) {//完全匹配
c = c.and("w").is(barcode.getPlateSize()).and("h").is(barcode.getHeight());
} else if (compatibleType == COMPATIBLE_TYPE.FULLY_COMPATIBLE) {//同厚度兼容
c = c.and("w").gte(barcode.getPlateSize()).and("h").gte(barcode.getHeight());//除7寸外,完全兼容
} else if (compatibleType == COMPATIBLE_TYPE.SIZE_COMPATIBLE) {//同尺寸兼容
c = c.and("w").is(barcode.getPlateSize()).and("h").gte(barcode.getHeight());//宽度等于料盘宽度,高度大于等于料盘高度
}
c = c.and("enabled").is(true)//可用
.and("used").is(false);//未使用
//去除的仓位
if (excludePosIds != null && !excludePosIds.isEmpty()) {
c = c.and("id").nin(excludePosIds);
}
if (StringUtils.isNotBlank(logo)){
Pattern pattern=Pattern.compile("^.*"+logo+".*$", Pattern.CASE_INSENSITIVE);
c.and("posName").regex(pattern);
}
Query query = new Query(c);
String msg = "";
// if (lastPosId == null || lastPosId.equals("")) {
//优先放入最合适的位置(根据尺寸),相同尺寸按优先级排序
query.with(Sort.by(Sort.Direction.ASC, "w").and(Sort.by(Sort.Direction.ASC, "h")).and(Sort.by(Sort.Direction.DESC, "priority")));
// } else {
// Point point = PointUtil.getPosPoint(lastPosId, false);
// query.addCriteria(Criteria.where("coordinate").nearSphere(point));
// msg += "getEmptyPosByStorage 根据就近坐标查询[" + lastPosId + "][" + point.getX() + "," + point.getY() + "]";
// }
StoragePos pos = storagePosDao.findOne(query);
if ((!ObjectUtil.isNotEmpty(msg) )&& (pos != null)) {
Point targetP = PointUtil.getPosPoint(lastPosId, false);
log.info(msg + "结果:[" + pos.getPosName() + "][" + targetP.getX() + "," + targetP.getY() + "]");
}
return pos;
}
/**
* 获取下一库位的库位名(后缀数字+1)
*/
......@@ -589,4 +665,5 @@ public class StoragePosManagerImpl implements IStoragePosManager {
return prefixStr +String.format("%0"+posIndexStr.length()+"d",nextPosIndex);
}
}
......@@ -36,9 +36,9 @@ public class DataLogDaoImpl extends AbstractBaseDao implements IDataLogDao {
}
private List<ChartItem> chart(Date fromTime, Date toTime, int type, String partNumber){
Date addOneDayToTime = DateUtil.addOneDayNoTime(toTime);
//Date addOneDayToTime = DateUtil.addOneDayNoTime(toTime);
Criteria c = new Criteria().andOperator(Criteria.where("updateDate").gte(fromTime),
Criteria.where("updateDate").lt(addOneDayToTime)).and("type").is(type);
Criteria.where("updateDate").lt(toTime)).and("type").is(type);
c.and("status").in(OP_STATUS.END.name(),OP_STATUS.FINISHED.name());
if(Strings.isNotBlank(partNumber)){
c.and("partNumber").is(partNumber);
......
......@@ -211,6 +211,71 @@ public class DataLog extends BasePo implements Serializable {
private String loc = "";
/**
* 线别(楼层)
*/
private String line;
/**
* 需求单号(挑料单号)
*/
private String orderNo;
/**
* 工单号
*/
private String mo;
/**
* 面别(线别)
*/
private String side;
/**
* 库别
*/
private String warehouseCode;
/**
* 厂别
*/
private String plantCode;
/**
* D/C
*/
private String dateCode;
/**
* 供应商
*/
private String provider;
/**
* 供应商代码
*/
private String providerNumber;
/**
* keeperCode
*/
private String keeperCode;
/**
* 物料储位
*/
private String reelPosName;
/**
* 料箱储位
*/
private String boxPosName;
/**
* 隔口数量
*/
private int partitionCount = 0;
/**
* MSD附加信息
*/
private MSDAppendInfo msdAppendInfo;
......@@ -252,6 +317,9 @@ public class DataLog extends BasePo implements Serializable {
return OP_STATUS.WAIT.name().equals(status);
}
public boolean isToBox(){
return OP_STATUS.TO_BOX.name().equals(status);
}
public boolean isEnd(){
return OP_STATUS.END.name().equals(status);
......
......@@ -8,6 +8,7 @@ import com.neotel.smfcore.common.exception.ValidateException;
import com.neotel.smfcore.common.utils.Constants;
import com.neotel.smfcore.common.utils.ReelLockPosUtil;
import com.neotel.smfcore.common.utils.SecurityUtils;
import com.neotel.smfcore.common.utils.StringUtils;
import com.neotel.smfcore.core.api.SmfApi;
import com.neotel.smfcore.core.barcode.enums.COMPONENT_TYPE;
import com.neotel.smfcore.core.barcode.service.manager.IBarcodeManager;
......@@ -19,6 +20,7 @@ import com.neotel.smfcore.core.device.util.DataCache;
import com.neotel.smfcore.core.order.LiteOrderCache;
import com.neotel.smfcore.core.order.service.po.LiteOrder;
import com.neotel.smfcore.core.storage.enums.CHECKOUT_TYPE;
import com.neotel.smfcore.core.storage.enums.DeviceType;
import com.neotel.smfcore.core.storage.rest.dto.TacticsOutDto;
import com.neotel.smfcore.core.storage.service.manager.IStoragePosManager;
import com.neotel.smfcore.core.storage.service.po.Storage;
......@@ -64,6 +66,8 @@ public class TaskService {
*/
private static Map<String, DataLog> theFinishedTaskMap = Maps.newConcurrentMap();
private static String posLogo = "";
// public TaskService(List<ITaskListener> listenerList){
// for (ITaskListener taskListener: listenerList) {
// taskListenerList.add(taskListener);
......@@ -103,7 +107,7 @@ public class TaskService {
* @return
* @throws ValidateException
*/
public synchronized String checkout(Storage storage, StoragePos pos, boolean isSingleOut, String opUserName) throws ValidateException {
public synchronized String checkout(Storage storage, StoragePos pos, boolean isSingleOut, String opUserName,String stationName) throws ValidateException {
if (pos.getBarcode() == null) {
String msg = "库位[" + pos.getPosName() + "]中已无物料,忽略";
log.info(msg);
......@@ -135,6 +139,10 @@ public class TaskService {
task.setSingleOut(isSingleOut);
task.setOperator(opUserName);
task.setStorageId(storage.getId());
if (StringUtils.isNotBlank(stationName)){
task.setLoc(stationName);
}
task.setBoxPosName(pos.getPosName());
addTaskToExecute(task);
return "";
}
......@@ -213,13 +221,16 @@ public class TaskService {
* 获取所有任务
*/
public List<DataLog> getAllTasksByCid(String cid) {
List<DataLog> dataLogs = new ArrayList<>();
List<DataLog> allTasks = getAllTasks();
for (DataLog task : allTasks) {
if(task.getCid().equals(cid)){
allTasks.add(task);
if (allTasks != null && !allTasks.isEmpty()) {
for (DataLog task : allTasks) {
if (cid.equals(task.getCid())) {
dataLogs.add(task);
}
}
}
return allTasks;
return dataLogs;
}
/**
......@@ -402,7 +413,7 @@ public class TaskService {
}
String cid = storage.getCid();
//有入库任务的料仓不分配出库任务
if (!hasExecutingTask(cid, OP.PUT_IN)) {
//if (!hasExecutingTask(cid, OP.PUT_IN)) {
DataLog task = findCheckoutBoxTask(storage);
if (task != null) {
......@@ -433,7 +444,7 @@ public class TaskService {
statusBean.addPosInfo(task.getBarcode(), posName, plateW, plateH, isSingleOut);
log.info("出库" + storage.getName() + "[" + posName + "]物料[" + task.getBarcode() + "]" + isSingleOut + "发送到客户端" + cid);
}
}
// }
String posId = statusBean.getData().get("posId");
if (!Strings.isNullOrEmpty(posId)) {
log.info("SEQ:" + statusBean.getSeq() + "出库库位信息:[" + posId + "]发送到客户端");
......@@ -578,10 +589,12 @@ public class TaskService {
//如果有正在执行的任务,把库位发过去
Collection<DataLog> allTasks = taskMap.values();
for (DataLog task : allTasks) {
if (barcode.getBarcode().equals(task.getBarcode())) {
String posId = task.getPosId();
log.info(barcode.getBarcode() + " 已有任务,返回任务中的库位:" + task.getPosName());
return storagePosManager.get(posId);
if (task.isPutInTask() && !task.isFinished() && !task.isCancel()) {
if (barcode.getBarcode().equals(task.getBarcode())) {
String posId = task.getPosId();
log.info(barcode.getBarcode() + " 已有任务,返回任务中的库位:" + task.getPosName());
return storagePosManager.get(posId);
}
}
String storageId = task.getStorageId();
......@@ -660,7 +673,29 @@ public class TaskService {
try {
Collection<String> operatingPosIds = excludePosIds();
log.debug("尝试从[" + storage.getCid() + "]中为[" + barcode.getBarcode() + "]查找空位");
StoragePos pos = storagePosManager.getEmptyPosByStorage(storage, barcode, operatingPosIds, lastPosId);
StoragePos pos = null;
if (storage.isType(new DeviceType[]{DeviceType.SMD_XLR})) {
if (StringUtils.isNotBlank(posLogo)) {
if ("AA".equals(posLogo)) {
posLogo = "BB";
} else {
posLogo = "AA";
}
} else {
posLogo = "AA";
}
pos = storagePosManager.getEmptyPosByStorage(storage, barcode, operatingPosIds, lastPosId, posLogo);
if (pos == null) {
if ("AA".equals(posLogo)) {
posLogo = "BB";
} else {
posLogo = "AA";
}
pos = storagePosManager.getEmptyPosByStorage(storage, barcode, operatingPosIds, lastPosId, posLogo);
}
} else {
pos = storagePosManager.getEmptyPosByStorage(storage, barcode, operatingPosIds, lastPosId);
}
if (pos != null) {
return pos;
}
......@@ -700,8 +735,10 @@ public class TaskService {
} else {
pos = storagePosManager.getByBarcodeId(barcodeSave.getId());
if (barcodeSave.getAmount() <= 0) {
throw new ValidateException("smfcore.error.barcode.wrongQty", "条码[{0}]对应的数量<=0为: {1}", new String[]{barcodeSave.getBarcode(), barcodeSave.getAmount() + ""});
if (!barcodeSave.getBarcode().startsWith("CS") && !barcodeSave.getBarcode().startsWith("CB") && !barcodeSave.getBarcode().startsWith("CM")) {
if (barcodeSave.getAmount() <= 0) {
throw new ValidateException("smfcore.error.barcode.wrongQty", "条码[{0}]对应的数量<=0为: {1}", new String[]{barcodeSave.getBarcode(), barcodeSave.getAmount() + ""});
}
}
}
......@@ -709,7 +746,7 @@ public class TaskService {
//如果已在库位中,那么自动将该库位的物料出库
log.info("出库已在库位中的物料[" + barcodeSave.getBarcode() + "]");
Storage storage = dataCache.getStorageById(pos.getStorageId());
checkout(storage, pos, true, "");
checkout(storage, pos, true, "","");
throw new ValidateException("smfcore.error.barcode.exist", "[{0}}]已在{1}}[{2}}]中", new String[]{barcodeSave.getBarcode(), storage.getName(), pos.getPosName()});
}
......@@ -745,7 +782,7 @@ public class TaskService {
Collection<DataLog> allTasks = taskMap.values();
if (pos.getBarcode() != null) {
barcode = pos.getBarcode();
//barcode = pos.getBarcode();
for (DataLog task : allTasks) {
if (task.isCheckOutTask()) {
String executeBarcode = task.getBarcode();
......@@ -801,7 +838,7 @@ public class TaskService {
//dataCache.updateStorage(task.getCid());
} else {
barcode = pos.getBarcode();
//barcode = pos.getBarcode();
log.info(opUser + "将【" + barcode.getBarcode() + "】从【" + pos.getPosName() + "】出库");
task.setType(OP.CHECKOUT);
barcode.setUsed(true);
......
......@@ -138,7 +138,7 @@ public class WebSocketServer {
}
/**
* 群发自定义消息
* 群发自定义消息ma
* */
private static void sendInfo(SocketMsg socketMsg,@PathParam("sid") String sid){
String message = JSONObject.toJSONString(socketMsg);
......
......@@ -392,11 +392,6 @@ public class AdvantechApi extends BaseSmfApiListener {
}
@Override
public Barcode barcodeInfo(String barcodeInfoUrl, Barcode barcode) {
return null;
}
@Override
public boolean isForThisApi(String apiName) {
return apiName != null && apiName.equalsIgnoreCase("Advantech");
}
......
......@@ -26,11 +26,6 @@ public class HellaApiHandler extends BaseSmfApiListener {
}
@Override
public Barcode barcodeInfo(String barcodeInfoUrl, Barcode barcode) {
return null;
}
@Override
public boolean isForThisApi(String apiName) {
return apiName != null && apiName.equalsIgnoreCase("Hella");
}
......
......@@ -213,7 +213,7 @@ public class HellaServiceHandler extends BaseSmfApiListener implements IoHandler
}else{
Storage storage = dataCache.getStorageById(storagePos.getStorageId());
try{
taskService.checkout(storage,storagePos,false,"");
taskService.checkout(storage,storagePos,false,"","");
}catch(ValidateException ve){
resultCode = "-3";
resultMsg = ve.getMessage();
......@@ -578,12 +578,6 @@ public class HellaServiceHandler extends BaseSmfApiListener implements IoHandler
}
@Override
public Barcode barcodeInfo(String barcodeInfoUrl, Barcode barcode) {
return null;
}
@Override
public void exceptionCaught(IoSession session, Throwable cause) throws Exception {
log.error("连接发生异常:" + cause.getMessage());
}
......
package com.neotel.smfcore.custom.lizhen;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.neotel.smfcore.common.exception.ApiException;
import com.neotel.smfcore.common.exception.ValidateException;
......@@ -8,10 +10,13 @@ import com.neotel.smfcore.common.utils.JsonUtil;
import com.neotel.smfcore.common.utils.StringUtils;
import com.neotel.smfcore.core.api.listener.BaseSmfApiListener;
import com.neotel.smfcore.core.api.listener.DefaultSmfApiListener;
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.LiteOrderCache;
import com.neotel.smfcore.core.order.service.po.LiteOrder;
import com.neotel.smfcore.core.system.service.po.DataLog;
import com.neotel.smfcore.custom.lizhen.agvBox.bean.GrLabel;
import com.neotel.smfcore.custom.lizhen.innerBox.bean.PreWarningItem;
import com.neotel.smfcore.custom.lizhen.innerBox.util.PreWarningItemCache;
import lombok.extern.slf4j.Slf4j;
......@@ -19,6 +24,7 @@ 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.text.SimpleDateFormat;
import java.util.*;
......@@ -27,39 +33,118 @@ import java.util.*;
public class LizhenApi extends DefaultSmfApiListener {
@Autowired
private LiteOrderCache liteOrderCache;
private IBarcodeManager barcodeManager;
@Autowired
private DataCache dataCache;
@Value("${api.fetchGRUrl}")
private String fetchGRUrl;
@Value("${api.brandQtyUrl}")
private String brandQtyUrl;
@Value("${api.plant}")
private String plant;
@Value("${api.barcodeInfoUrl}")
private String barcodeInfoUrl;
@Value("${api.werks}")
private String werks;
@PostConstruct
public void init(){
fetchGRUrl = dataCache.getConfigCache("fetchGRUrl",fetchGRUrl);
brandQtyUrl = dataCache.getConfigCache("brandQtyUrl",brandQtyUrl);
plant = dataCache.getConfigCache("plant",plant);
barcodeInfoUrl = dataCache.getConfigCache("barcodeInfoUrl",barcodeInfoUrl);
werks = dataCache.getConfigCache("werks",werks);
}
/**
* 获取gr标签的料卷数
* @param barcode
* 根据partnumber和brand获取满卷数
*
* @param partnumber
* @param brand
* @return
*/
public int fetchGR(Barcode barcode) {
public Map<String,Object> brandQty(String partnumber, String brand) {
log.info("brandQty--material_code:" + partnumber + ",brand:" + brand);
int qty = 0;
Map<String, Object> paramMap = new HashMap<>();
paramMap.put("plant", plant);
paramMap.put("gr_code", barcode.getBarcode());
paramMap.put("gr_item", barcode.getMemo());
paramMap.put("partNumber", barcode.getPartNumber());
log.info("gr标签入参为:" + JsonUtil.toJsonStr(paramMap));
paramMap.put("material_code", partnumber);
paramMap.put("brand", brand);
Map<String, Object> resultMap = new HashMap<>();
try {
String result = HttpHelper.postJson(brandQtyUrl, paramMap);
log.info("brandQty-" + partnumber + ":请求结果为:" + result);
JSONObject jsonObject = JsonUtil.toObj(result, JSONObject.class);
String msgtx = jsonObject.getString("MSGTX");
if ("S".equals(msgtx)) {
JSONObject dataObject = jsonObject.getJSONObject("DATA");
if (dataObject != null) {
if (dataObject.getInteger("qty") != null) {
qty = dataObject.getInteger("qty");
resultMap.put("qty", qty);
}
String reelSize = dataObject.getString("reel_size");
if (StringUtils.isNotBlank(reelSize)) {
resultMap.put("reelSize", reelSize);
}
}
}
} catch (ApiException e) {
e.printStackTrace();
log.info("brandQty--" + partnumber + ":异常:" + e.getMessage());
}
return resultMap;
}
/**
* 获取gr标签
*
* @param grLabel
* @return
*/
public Map<String, String> fetchGR(GrLabel grLabel) {
Map<String, Object> paramMap = new HashMap<>();
paramMap.put("plant_code", plant);
paramMap.put("gr_code", grLabel.getLabelId());
paramMap.put("gr_item", grLabel.getLabelItem());
paramMap.put("material_code", grLabel.getPartNumber());
log.info("gr标签入参为:" + JsonUtil.toJsonStr(paramMap));
Map<String, String> resultMap = new HashMap<>();
try {
String result = HttpHelper.postJson(fetchGRUrl, paramMap);
log.info("gr标签出参为:" + result);
JSONObject resultObject = JsonUtil.toObj(result, JSONObject.class);
if ("S".equals(resultObject.getString("MSGTX"))) {
JSONArray dataArrray = resultObject.getJSONArray("DATA");
if (dataArrray != null && !dataArrray.isEmpty()) {
JSONObject dataObject = dataArrray.getJSONObject(0);
String brand = dataObject.getString("brand");
resultMap.put("brand", brand);
resultMap.put("keeperCode",dataObject.getString("keeper_code"));
resultMap.put("warehouseCode",dataObject.getString("warehouse_code"));
}
}
} catch (ApiException e) {
e.printStackTrace();
log.error(grLabel.getLabelId() + "fetchGr异常:" + e.getMessage());
}
return 0;
return resultMap;
}
@Override
public Barcode barcodeInfo(String barcodeInfoUrl, Barcode barcode) {
/**
* 获取mes数量
*
* @param barcode
* @return
*/
public Barcode barcodeInfo(Barcode barcode) {
log.info("获取MES物料数量入参为:" + barcode.getBarcode());
try {
String result = HttpHelper.postJson(barcodeInfoUrl, barcode.getBarcode());
......@@ -77,7 +162,7 @@ public class LizhenApi extends DefaultSmfApiListener {
String vendorNum = dataJson.get("vendorNum") == null ? "" : dataJson.get("vendorNum").toString();
String dataCode = dataJson.get("dataCode") == null ? "" : dataJson.get("dataCode").toString();
String lotCode = dataJson.get("lotCode") == null ? "" : dataJson.get("lotCode").toString();
if (StringUtils.isBlank(reelID)){
if (StringUtils.isBlank(reelID)) {
return null;
}
barcode.setBarcode(reelID);
......@@ -87,6 +172,7 @@ public class LizhenApi extends DefaultSmfApiListener {
barcode.setProviderNumber(vendorNum);
barcode.setDateCode(dataCode);
barcode.setBatch(lotCode);
barcode.setDescribe(partSpec);
return barcode;
}
}
......@@ -98,6 +184,7 @@ public class LizhenApi extends DefaultSmfApiListener {
/**
* 入库验证
*
* @param inCheckUrl
* @param barcode
* @return
......@@ -118,7 +205,7 @@ public class LizhenApi extends DefaultSmfApiListener {
try {
String result = HttpHelper.postJson(inCheckUrl, paramMap);
log.info(barcode.getBarcode() + "禁用料接口wmsCheckReelfob出参为:" + result);
JSONObject resultJson = JsonUtil.toObj(result,JSONObject.class);
JSONObject resultJson = JsonUtil.toObj(result, JSONObject.class);
if (resultJson != null) {
if (resultJson.getString("data") != null) {
JSONObject dataJson = resultJson.getJSONObject("data");
......@@ -132,9 +219,19 @@ public class LizhenApi extends DefaultSmfApiListener {
//log.info("禁用料接口wmsCheckReelfob出参为:" + result);
} catch (ApiException e) {
e.printStackTrace();
resultStr = e.getMessage();
log.info(barcode.getBarcode() + "wmsCheckReelfob异常:" + e.getMessage());
}
//保存禁用料记录
Barcode barcodeOri = barcodeManager.findByBarcode(barcode.getBarcode());
if (barcodeOri != null){
barcodeOri.setDisableMsg(resultStr);
barcodeManager.save(barcodeOri);
}
if (StringUtils.isNotBlank(resultStr)) {
throw new ValidateException("smfcore.mesApi.inCheck.ng", "MES验证失败:" + barcode.getBarcode() + "验证失败:"+resultStr);
throw new ValidateException("smfcore.mesApi.inCheck.ng", "MES验证失败:" + barcode.getBarcode() + "验证失败:" + resultStr);
}
return barcode;
}
......@@ -142,21 +239,14 @@ public class LizhenApi extends DefaultSmfApiListener {
/**
* 保存物料接口
*
* @param inNotifyUrl
* @param task
*/
@Override
public void inTaskStatusChange(String inNotifyUrl, DataLog task) {
Map<String, Object> paramMap = new HashMap<>();
Map<String, Object> dataMap = new HashMap<>();
String sourceId = task.getSourceId();
dataMap.put("pickingid", "");
LiteOrder liteOrder = liteOrderCache.getOrderSortItems(sourceId);
if (liteOrder != null) {
dataMap.put("pickingid", liteOrder.getOrderNo());
}
//dataMap.put("pickingid", "20220214162216");
dataMap.put("wo", "");
dataMap.put("reelno", task.getBarcode());
dataMap.put("ipn", task.getPartNumber());
......@@ -169,33 +259,36 @@ public class LizhenApi extends DefaultSmfApiListener {
dataMap.put("vendor", barcode.getProvider());
dataMap.put("batch", "");
}
paramMap.put("data", Arrays.asList(dataMap));
String param = JsonUtil.toJsonStr(paramMap);
log.info("IMES提供接收发料明细接口入参为:" + param);
dataMap.put("werks",werks);
dataMap.put("reelid","");
String param = JsonUtil.toJsonStr(Arrays.asList(dataMap));
log.info("保存物料入参为:" + param);
try {
String result = HttpHelper.postJson(inNotifyUrl, paramMap);
log.info("IMES提供接收发料明细接口出参为:" + result);
String result = HttpHelper.postJson(inNotifyUrl, Arrays.asList(dataMap));
log.info("保存物料出参为:" + result);
} catch (ApiException e) {
e.printStackTrace();
log.info(barcode.getBarcode()+"保存物料异常:"+e.getMessage());
}
}
/**
* 保存物料接口
*
* @param outNotifyUrl
* @param task
*/
@Override
public void outTaskStatusChange(String outNotifyUrl, DataLog task) {
Map<String, Object> paramMap = new HashMap<>();
if (task.getBarcode().startsWith("CS")
|| task.getBarcode().startsWith("CM")
|| task.getBarcode().startsWith("CB")) {
return;
}
Map<String, Object> dataMap = new HashMap<>();
String sourceId = task.getSourceId();
dataMap.put("pickingid", "");
LiteOrder liteOrder = liteOrderCache.getOrderSortItems(sourceId);
if (liteOrder != null) {
dataMap.put("pickingid", liteOrder.getSo());
}
dataMap.put("wo", "");
dataMap.put("reelno", task.getBarcode());
dataMap.put("ipn", task.getPartNumber());
......@@ -208,19 +301,22 @@ public class LizhenApi extends DefaultSmfApiListener {
dataMap.put("vendor", barcode.getProvider());
dataMap.put("batch", "");
}
paramMap.put("data", Arrays.asList(dataMap));
String param = JsonUtil.toJsonStr(paramMap);
log.info("IMES提供接收发料明细接口入参为:" + param);
dataMap.put("werks",werks);
dataMap.put("reelid","");
String param = JsonUtil.toJsonStr(Arrays.asList(dataMap));
log.info("保存物料入参为:" + param);
try {
String result = HttpHelper.postJson(outNotifyUrl, paramMap);
log.info("IMES提供接收发料明细接口出参为:" + result);
String result = HttpHelper.postJson(outNotifyUrl, Arrays.asList(dataMap));
log.info("保存物料出参为:" + result);
} catch (ApiException e) {
e.printStackTrace();
log.info(barcode.getBarcode()+"保存物料异常:"+e.getMessage());
}
}
/**
* 获取到需求单数据
*
* @param fetchOrderUrl
* @param orderNumber
* @param username
......@@ -255,7 +351,7 @@ public class LizhenApi extends DefaultSmfApiListener {
}
}
if (items != null && !items.isEmpty()) {
return PreWarningItemCache.createAndExecuteLiteOrder(items);
return PreWarningItemCache.createAndExecuteLiteOrder(items,2);
}
}
return null;
......
package com.neotel.smfcore.custom.lizhen;
import com.alibaba.fastjson.JSONObject;
import com.neotel.smfcore.common.bean.ResultBean;
import com.neotel.smfcore.common.exception.ApiException;
import com.neotel.smfcore.common.utils.Constants;
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.barcode.service.po.Barcode;
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.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.manager.IStoragePosManager;
import com.neotel.smfcore.core.storage.service.po.StoragePos;
import com.neotel.smfcore.custom.lizhen.innerBox.bean.PreWarningItem;
import com.neotel.smfcore.custom.lizhen.innerBox.util.PreWarningItemCache;
import com.neotel.smfcore.custom.lizhen.innerBox.util.service.PreWarningItemManager;
import com.neotel.smfcore.security.annotation.AnonymousAccess;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
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.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.PostConstruct;
import java.util.*;
@Slf4j
......@@ -40,44 +40,85 @@ public class LizhenController {
private LiteOrderCache liteOrderCache;
@Autowired
private IStoragePosManager storagePosManager;
private DataCache dataCache;
@Autowired
private PreWarningItemManager preWarningItemManager;
/**
* 发料明细
*
* @param params
* @return
*/
@Value("${lizhen.F2.line}")
private String F2Line;
@Value("${lizhen.F2.url}")
private String F2Url;
@Value("${lizhen.F3.line}")
private String F3Line;
@Value("${lizhen.F3.url}")
private String F3Url;
@Value("${lizhen.F5.line}")
private String F5Line;
@Value("${lizhen.F5.url}")
private String F5Url;
private static Map<String, String> lineUrlMap = new HashMap<>();
//初始化加载需要配送的地址
@PostConstruct
public void init() {
F2Line = dataCache.getConfigCache("F2Line", F2Line);
F2Url = dataCache.getConfigCache("F2Url", F2Url);
F3Line = dataCache.getConfigCache("F3Line", F3Line);
F3Url = dataCache.getConfigCache("F3Url", F3Url);
F5Line = dataCache.getConfigCache("F5Line", F5Line);
F5Url = dataCache.getConfigCache("F5Url", F5Url);
lineUrlMap.put(F2Line, F2Url);
lineUrlMap.put(F3Line, F3Url);
lineUrlMap.put(F5Line, F5Url);
}
@ApiOperation("外仓:发料明细")
@PostMapping("/EPickingList")
@AnonymousAccess
public ResultBean EPickingList(@RequestBody List<Map<String, Object>> params) {
log.info("发料明细数据--" + JsonUtil.toJsonStr(params));
for (Map<String, Object> param : params) {
//任务单号
String orderNo = param.get("picking_id") == null ? "" : param.get("picking_id").toString();
if (StringUtils.isBlank(orderNo)) {
return ResultBean.newErrorResult(-1, "", "picking_id不能为空");
//pickingId
String pickingId = param.get("picking_id") == null ? "" : param.get("picking_id").toString();
if (StringUtils.isBlank(pickingId)) {
return ResultBean.newErrorResult(-1, "smfcore.valueCanotNull", "{0}不能为空", new String[]{"picking_id"});
}
//厂区
String plantCode = param.get("plant_code") == null ? "" : param.get("plant_code").toString();
if (StringUtils.isBlank(plantCode)) {
return ResultBean.newErrorResult(-1, "smfcore.valueCanotNull", "{0}不能为空", new String[]{"plant_code"});
}
//线别
String line = param.get("line") == null ? "" : param.get("line").toString();
if (StringUtils.isBlank(line)) {
return ResultBean.newErrorResult(-1, "", "line不能为空");
return ResultBean.newErrorResult(-1, "smfcore.valueCanotNull", "{0}不能为空", new String[]{"line"});
}
//判断是否已经生成过pickingId
LiteOrder liteOrderPic = liteOrderManager.findByOrderNo(pickingId);
if (liteOrderPic != null) {
return ResultBean.newErrorResult(-1, "", pickingId + "已经生成,请确认");
}
LiteOrder liteOrder = new LiteOrder();
liteOrder.setOrderNo(preWarningItemManager.getNextId("L" + PreWarningItemCache.class.getName()));
liteOrder.setSo(orderNo);
liteOrder.setOrderNo(pickingId);
liteOrder.setLine(line);
liteOrder.setType(2);
liteOrder.setType(1);
liteOrder.setSource(LITEORDER_SOURCE.OUTTER.name());
//liteOrderItem
List<LiteOrderItem> orderItems = new ArrayList<>();
String itemStr = param.get("ITEM") == null ? "" : param.get("ITEM").toString();
if (StringUtils.isBlank(itemStr)) {
return ResultBean.newErrorResult(-1, "", "ITEM不能为空");
return ResultBean.newErrorResult(-1, "smfcore.valueCanotNull", "{0}不能为空", new String[]{"ITEM"});
}
int taskBarcodeCount = 0;
int allReelCount = 0;
List<Map> items = JsonUtil.toList(itemStr, Map.class);
for (Map item : items) {
String face = item.get("face") == null ? "" : item.get("face").toString();
......@@ -89,25 +130,29 @@ public class LizhenController {
int reqReel = item.get("req_reel") == null ? 0 : Integer.valueOf(item.get("req_reel").toString());
String warehouse = item.get("warehouse") == null ? "" : item.get("warehouse").toString();
List<Barcode> barcodes = getBarcodesBypn(materialCode, reqQty);
if (barcodes != null && !barcodes.isEmpty()){
for (Barcode barcode : barcodes) {
LiteOrderItem orderItem = new LiteOrderItem();
orderItem.setSide(face);
orderItem.setPn(materialCode);
orderItem.setRi(barcode.getBarcode());
orderItem.setNeedNum(barcode.getAmount());
orderItem.setPosName(barcode.getPosName());
orderItems.add(orderItem);
}
}
allReelCount = allReelCount + reqReel;
taskBarcodeCount = taskBarcodeCount + reqQty;
LiteOrderItem orderItem = new LiteOrderItem();
orderItem.setSide(face);
orderItem.setPn(materialCode);
orderItem.setBrand(brand);
orderItem.setBatchCode(batchCode);
orderItem.setWarehouseCode(warehouse);
orderItem.setNeedNum(reqQty);
orderItem.setNeedReelCount(reqReel);
orderItem.setMo(mo);
orderItem.setOrderNo(pickingId);
orderItem.setLine(line);
orderItem.setPlantCode(plantCode);
orderItems.add(orderItem);
}
if (orderItems != null && !orderItems.isEmpty()) {
liteOrder.setTaskReelCount(orderItems.size());
liteOrder.setTotalTaskReelCount(orderItems.size());
liteOrder.setTaskReelCount(allReelCount);
//liteOrder.setTotalTaskReelCount(allReelCount);
liteOrder.setOrderItems(orderItems);
liteOrder = liteOrderManager.createWithItems(liteOrder);
log.info("新增加订单:" + liteOrder.getOrderNo() + "[" + liteOrder.getId() + "],共" + orderItems.size() + "条工单详情");
liteOrderManager.createWithItems(liteOrder);
liteOrderCache.addOrderToMap(liteOrder);
}
}
......@@ -115,60 +160,70 @@ public class LizhenController {
}
@ApiOperation("5.缺料预警")
@ApiOperation("内仓:机台叫料")
@PostMapping("/mPickingList")
@AnonymousAccess
public ResultBean mPickingList(@RequestBody List<Map<String, String>> params) {
if (params == null || params.isEmpty()) {
return ResultBean.newErrorResult(-1, "", "数据不能为空");
return ResultBean.newErrorResult(-1, "smfcore.valueCanotNull", "{0}不能为空", new String[]{"参数"});
}
List<PreWarningItem> items = new ArrayList<>();
for (Map<String, String> data : params) {
PreWarningItem item = new PreWarningItem();
item.setMachinename(data.get("MACHINENAME"));
item.setStation(data.get("STATION"));
item.setSide(data.get("SIDE"));
item.setSlot(data.get("SLOT"));
item.setSubslot(data.get("SUBSLOT"));
item.setPartnumber(data.get("PARTNUMBER"));
item.setLine(data.get("LINE"));
items.add(item);
for (Map<String, String> param : params) {
String line = param.get("LINE");
String forwardUrl = getForwardUrl(line);
if (StringUtils.isBlank(forwardUrl)){
log.info(line+"没有对应的地址,跳过");
continue;
}
log.info("Mes缺料预警---" + JSONObject.toJSONString(param) + ",地址为:" + forwardUrl);
String id = param.get("ID");
try {
String result = HttpHelper.postJson(forwardUrl, param);
log.info(id + "机台叫料结果为--" + result);
} catch (ApiException e) {
e.printStackTrace();
log.info(id + "机台叫料转发失败---" + e.getMessage());
}
}
if (items != null && !items.isEmpty()) {
PreWarningItemCache.addItems(items);
return ResultBean.newOkResult("");
}
//机台叫料转发的地址
@PostMapping("/machineCallMaterial")
@AnonymousAccess
public ResultBean machineCallMaterial(@RequestBody Map<String, String> data) {
boolean startJob = dataCache.getCache(Constants.CACHE_StartJob);
if (!startJob){
return ResultBean.newErrorResult(-1,"","定时任务未开启");
}
log.info("Mes缺料预警---" + JSONObject.toJSONString(data));
PreWarningItem item = new PreWarningItem();
item.setMachinename(data.get("MACHINENAME"));
item.setStation(data.get("STATION"));
item.setSide(data.get("SIDE"));
item.setSlot(data.get("SLOT"));
item.setSubslot(data.get("SUBSLOT"));
item.setPartnumber(data.get("PARTNUMBER"));
item.setLine(data.get("LINE"));
item.setId(data.get("ID"));
item.setPriority(Integer.valueOf(data.get("PRIORITY")));
PreWarningItemCache.addItems(Arrays.asList(item));
return ResultBean.newOkResult("");
}
private List<Barcode> getBarcodesBypn(String partNumber, int reqQty) {
Query q = new Query();
Criteria c = Criteria.where("barcode.subCodeList.partNumber").is(partNumber); //料箱中parnumber的物料
c.and("barcode").exists(true).and("enabled").is(true);
Collection<String> barcodeIds = liteOrderCache.excludeBarcodeIds();
Sort sort = Sort.by(Sort.Direction.ASC, "canCheckOutTime", "barcode.usedCount");
List<StoragePos> storagePoss = storagePosManager.findByQuery(q.addCriteria(c).with(sort));
List<Barcode> barcodes = new ArrayList<>();
int amount = 0;
if (storagePoss != null && !storagePoss.isEmpty()) {
for (StoragePos pos : storagePoss) {
List<Barcode> subCodeList = pos.getBarcode().getSubCodeList();
for (Barcode barcode : subCodeList) {
if (barcode.getPartNumber().equals(partNumber)) {
if (barcodeIds != null && !barcodeIds.isEmpty()){
if (barcodeIds.contains(barcode.getBarcode())){
continue;
}
}
barcodes.add(barcode);
amount = amount + barcode.getAmount();
if (amount >= reqQty) {
break;
}
}
private String getForwardUrl(String line) {
String url = "";
for (Map.Entry<String, String> lineUrlEntry : lineUrlMap.entrySet()) {
String lineStr = lineUrlEntry.getKey();
String lineUrl = lineUrlEntry.getValue();
if (StringUtils.isNotBlank(lineStr) && StringUtils.isNotBlank(lineUrl) && StringUtils.isNotBlank(line)) {
if (lineStr.contains(line)) {
url = lineUrl;
break;
}
}
}
return barcodes;
return url;
}
}
package com.neotel.smfcore.custom.lizhen.agvBox.bean;
import com.neotel.smfcore.common.base.BasePo;
import com.neotel.smfcore.core.barcode.bean.BarcodeRule;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class GrLabel extends BasePo {
/**
* 标签id
*/
private String labelId;
/**
* 行号
*/
private String labelItem;
/**
* 标签总数量
*/
private int amount = 0;
/**
* 剩余数量
*/
private int remainingAmount = 0;
/**
* 厂商
*/
private String provider;
/**
* pn
*/
private String partNumber;
/**
* keeperCode
*/
private String keeperCode;
/**
* 库别
*/
private String warehouseCode;
/**
* 完整二维码信息
*/
private String fullCode;
}
......@@ -4,6 +4,8 @@ import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
/**
* @author sunke
* @date 2022/9/22 4:32 PM
......@@ -54,11 +56,42 @@ public class Station {
*/
private int height;
/**
* GR标签
* gr标签
*/
private String grLabel;
/**
* gr行
*/
private String labelItem;
/**
* 上一个隔扣码
*/
private String lastScanBoxCode = "";
/**
* 是否已经入库
*/
private boolean isPutIn = true;
/**
* 料箱隔口数量
*/
private List<Integer> boxPartitionCounts;
/**
* 提示信息
*/
//private String msg;
/**
* 库别
*/
private String warehouseCode;
}
package com.neotel.smfcore.custom.lizhen.agvBox.bean;
import com.neotel.smfcore.common.base.BasePo;
import lombok.Getter;
import lombok.Setter;
import java.io.Serializable;
@Setter
@Getter
public class WareHouseCode extends BasePo implements Serializable {
/**
* 厂区
*/
private String plant;
/**
* 库别
*/
private String wareHouseCode;
/**
* 描述
*/
private String description;
/**
* 创建人
*/
private String createBy;
/**
* 修改人
*/
private String updateBy;
}
package com.neotel.smfcore.custom.lizhen.agvBox.bean.dto;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.annotations.ApiOperation;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import java.io.Serializable;
@Getter
@Setter
@ToString
public class WareHouseCodeDto implements Serializable {
@ApiModelProperty("ID")
private String id;
@ApiModelProperty("厂别")
private String plant;
@ApiModelProperty("库别")
private String wareHouseCode;
@ApiModelProperty("描述")
private String description;
}
package com.neotel.smfcore.custom.lizhen.agvBox.bean.mapstruct;
import com.neotel.smfcore.common.base.BaseMapper;
import com.neotel.smfcore.custom.lizhen.agvBox.bean.WareHouseCode;
import com.neotel.smfcore.custom.lizhen.agvBox.bean.dto.WareHouseCodeDto;
import org.mapstruct.Mapper;
import org.mapstruct.ReportingPolicy;
@Mapper(componentModel = "spring" ,unmappedTargetPolicy = ReportingPolicy.IGNORE)
public interface WareHouseCodeMapper extends BaseMapper<WareHouseCodeDto, WareHouseCode> {
}
package com.neotel.smfcore.custom.lizhen.agvBox.bean.query;
import com.neotel.smfcore.common.annotation.QueryCondition;
import lombok.Data;
@Data
public class WareHouseCodeQueryCriteria {
@QueryCondition(blurry = "plant,wareHouseCode,description,createBy,updateBy")
private String blurry;
}
......@@ -14,6 +14,9 @@ import com.neotel.smfcore.core.storage.service.po.StoragePos;
import com.neotel.smfcore.core.system.service.dao.IDataLogDao;
import com.neotel.smfcore.core.system.service.po.DataLog;
import com.neotel.smfcore.core.system.util.TaskService;
import com.neotel.smfcore.core.system.websocket.MsgType;
import com.neotel.smfcore.core.system.websocket.SocketMsg;
import com.neotel.smfcore.core.system.websocket.WebSocketServer;
import com.neotel.smfcore.custom.lizhen.agvBox.bean.Station;
import com.neotel.smfcore.custom.lizhen.agvBox.util.StationCacheUtil;
import com.neotel.smfcore.security.annotation.AnonymousAccess;
......@@ -70,6 +73,20 @@ public class AgvBoxDeviceClientController {
String stationName = "s" + i;
String rfid = request.getParameter(stationName);
StationCacheUtil.updateCurrentRfid(stationName, rfid);
//判断当前工位箱子是否有正在执行出库工作的任务
/*List<DataLog> allTasks = taskService.getAllTasks();
for (DataLog task : allTasks) {
if (task.isCheckOutTask() && !task.isCancel() && !task.isFinished()) {
if (rfid.startsWith(task.getBarcode())) {
log.info(task.getBarcode() + ":需要更新为状态已完成");
task.setStatus(OP_STATUS.FINISHED.name());
lockRfidTarget.remove(task.getBarcode());
//已完成,从完成缓存中清除
taskService.removeFinishedTask(task);
}
}
}*/
}
//"needInStation": ["s1","s2"]//需要线体升起阻挡进行入库的工位
List<String> needInStationList = new ArrayList<>();
......@@ -120,6 +137,10 @@ public class AgvBoxDeviceClientController {
Collection<DataLog> queueTasks = taskService.getQueueTasks();
List<Map<String, String>> taskToSend = new ArrayList<>();
for (DataLog queueTask : queueTasks) {
//小车限制,默认一次生成200个任务
if (taskToSend != null && taskToSend.size() >= 200) {
break;
}
if (queueTask.isCheckOutTask()) {
if (queueTask.isWait() || queueTask.isExecuting()) {
Storage storage = dataCache.getStorageById(queueTask.getStorageId());
......@@ -163,7 +184,7 @@ public class AgvBoxDeviceClientController {
}
}
}
String target = "0";
String target = "s0";
String barcode = "";
//"target": "1",//0=工位已有箱子;s1=工位1;s2=工位2;s3=工位3;s4=工位4;s5=工位5;其他值表示入库的目标库位
if (opTask != null) {
......@@ -200,6 +221,21 @@ public class AgvBoxDeviceClientController {
target = station.getName();
break;
}
/*Collection<String> names = lockRfidTarget.values();
if (names != null && !names.isEmpty()){
if (!names.contains(station.getName())) {
//工位未分配过库位
log.info("分配料箱[" + opTask.getBarcode() + "]到" + station.getName());
lockRfidTarget.put(opTask.getBarcode(), station.getName());
target = station.getName();
break;
}
} else {
log.info("分配料箱[" + opTask.getBarcode() + "]到" + station.getName());
lockRfidTarget.put(opTask.getBarcode(), station.getName());
target = station.getName();
break;
}*/
}
}
......@@ -230,6 +266,7 @@ public class AgvBoxDeviceClientController {
public synchronized ResultBean updateLocInfo(HttpServletRequest request) {
String rfid = request.getParameter("barcode");
String statusStr = request.getParameter("status");
String loc = request.getParameter("loc"); //工位
log.debug("收到料盘[" + rfid + "]更新位置指令[" + statusStr + "]");
if (statusStr == null) {
return ResultBean.newErrorResult(301, "smfcore.updateLoc.status.empty", "状态不能为空");
......@@ -273,12 +310,19 @@ public class AgvBoxDeviceClientController {
* FINISHED=任务完成(入库时AGV将料箱放入库位;出库时料箱到达工位)
*/
if (updateStatus != null) {
String statusOri = opTask.getStatus(); //任务的上一个状态
opTask.setStatus(statusStr);
if (opTask.isCheckOutTask()) {
if (OP_STATUS.EXECUTING.name().equals(statusStr)) {
//在执行队列中
taskService.updateQueueTask(opTask);
} else {
} else if (OP_STATUS.NEED_AWAY.name().equals(statusStr)){
//判断当前任务是否需要取走状态,如果已经是
if (!OP_STATUS.NEED_AWAY.name().equals(statusOri)) {
WebSocketServer.sendMsg(new SocketMsg(Arrays.asList(loc), rfid + "需出库到工位:" + loc + "上", MsgType.INFO, "", null));
}
}
else {
taskService.moveTaskToFinished(opTask);
if (OP_STATUS.OUT_ON_AGV.name().equals(statusStr)) {
......@@ -407,4 +451,9 @@ public class AgvBoxDeviceClientController {
}
public static void main(String[] args) {
Arrays.asList(null);
}
}
package com.neotel.smfcore.custom.lizhen.agvBox.rest;
import com.google.common.collect.Lists;
import com.neotel.smfcore.common.bean.ReelLockPosInfo;
import com.neotel.smfcore.common.bean.ResultBean;
import com.neotel.smfcore.common.exception.ValidateException;
import com.neotel.smfcore.common.utils.*;
import com.neotel.smfcore.core.api.SmfApi;
import com.neotel.smfcore.core.barcode.bean.BarcodeRule;
import com.neotel.smfcore.core.barcode.bean.CodeBean;
import com.neotel.smfcore.core.barcode.service.manager.IBarcodeManager;
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.service.manager.ILiteOrderItemManager;
import com.neotel.smfcore.core.order.service.manager.ILiteOrderManager;
import com.neotel.smfcore.core.order.service.po.LiteOrder;
import com.neotel.smfcore.core.order.service.po.LiteOrderItem;
import com.neotel.smfcore.core.storage.enums.DeviceType;
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.service.po.DataLog;
import com.neotel.smfcore.core.system.util.TaskService;
import com.neotel.smfcore.custom.lizhen.LizhenApi;
import com.neotel.smfcore.custom.lizhen.agvBox.bean.GrLabel;
import com.neotel.smfcore.custom.lizhen.agvBox.bean.Station;
import com.neotel.smfcore.custom.lizhen.agvBox.service.manager.GrLabelManager;
import com.neotel.smfcore.custom.lizhen.agvBox.util.StationCacheUtil;
import com.neotel.smfcore.security.annotation.AnonymousAccess;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.factory.annotation.Autowired;
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.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
/**
* 外仓操作
*/
@Slf4j
@RestController
public class OutWarehouseController {
@Autowired
private IBarcodeManager barcodeManager;
@Autowired
private CodeResolve codeResolve;
@Autowired
private IStoragePosManager storagePosManager;
@Autowired
private TaskService taskService;
@Autowired
private DataCache dataCache;
@Autowired
private LizhenApi lizhenApi;
@Autowired
private GrLabelManager grLabelManager;
@Autowired
private SmfApi smfApi;
@Autowired
private ILiteOrderManager liteOrderManager;
@Autowired
private ILiteOrderItemManager liteOrderItemManager;
@Autowired
private LiteOrderCache liteOrderCache;
private static Map<String, Integer> boxCount = new ConcurrentHashMap<>();
@ApiOperation("选择物料")
@RequestMapping("/chooseReel")
@AnonymousAccess
public ResultBean chooseReel(@RequestBody Map<String, String> paramMap) {
String name = paramMap.get("name"); //工位名称
String size = paramMap.get("size"); //尺寸 "7X8"
String num = paramMap.get("num"); //数量
String grLabelStr = paramMap.get("grLabel"); //GR标签
String warehouseCode = paramMap.get("warehouseCode"); //库别
//验证gr标签
log.info("{}:收到选择物料信息,尺寸为:{},数量为:{},gr:{}", name, size, num, grLabelStr);
//查询当前工位信息
Station station = StationCacheUtil.getStation(name);
if (station == null) {
station = new Station();
}
//如果gr标签不为空的,直接用gr的,否则,取手输的
if (StringUtils.isNotBlank(grLabelStr)) {
GrLabel grLabel = codeResolve.resolveGrLable(grLabelStr); //解析出gr标签
if (grLabel == null) {
return ResultBean.newErrorResult(-1, "", grLabelStr + "解析失败");
}
//判断数据库是否有barcode数据,如果有用数据库的
GrLabel label = grLabelManager.findLabelBylabelId(grLabel.getLabelId(), grLabel.getLabelItem());
if (label != null) {
grLabel = label;
}
//判断是否已经失效
if (grLabel.getRemainingAmount() <= 0) {
return ResultBean.newErrorResult(-1, "", "Gr:" + grLabel.getLabelId() + "已经失效");
}
//得到料卷总数量与尺寸
Map<String, Object> barandMap = lizhenApi.brandQty(grLabel.getPartNumber(), grLabel.getProvider());
if (barandMap.get("qty") == null) {
return ResultBean.newErrorResult(-1, "", grLabel.getPartNumber() + "MES未返回料卷数量,未找到对应的料卷数量");
}
num = (grLabel.getRemainingAmount() / Integer.valueOf(barandMap.get("qty").toString())) + "";
//校验尺寸,如果没有返回也没有手输,返回错误
if (barandMap.get("reelSize") == null) {
if (StringUtils.isBlank(size)) {
return ResultBean.newErrorResult(-1, "", grLabel.getPartNumber() + "MES未返回物料规格,请选择对应的物料规格");
}
} else {
String reelSize = barandMap.get("reelSize").toString();
if ("7".equals(reelSize)) {
size = "7X8";
} else if ("13".equals(reelSize)) {
size = "13X24";
} else if ("15".equals(reelSize)) {
size = "15X32";
}
}
//得到对应的库别
Map<String, String> fetchGrMap = lizhenApi.fetchGR(grLabel);
if (fetchGrMap.get("warehouseCode") == null) {
if (StringUtils.isBlank(warehouseCode)) {
return ResultBean.newErrorResult(-1, "", grLabel.getLabelId() + "MES未返回库别,请选择对应的库别");
}
} else {
warehouseCode = fetchGrMap.get("warehouseCode");
}
String keeperCode = fetchGrMap.get("keeperCode");
grLabel.setWarehouseCode(warehouseCode);
grLabel.setKeeperCode(keeperCode);
grLabelManager.save(grLabel);
station.setGrLabel(grLabel.getLabelId());
station.setLabelItem(grLabel.getLabelItem());
}
if (StringUtils.isBlank(num)) {
return ResultBean.newErrorResult(-1, "", "请核实输入数量是否为空");
}
if (StringUtils.isBlank(size)) {
return ResultBean.newErrorResult(-1, "", "请选择对应的物料规格");
}
if (StringUtils.isBlank(warehouseCode)) {
return ResultBean.newErrorResult(-1, "", "请选择对应的库别");
}
int platsize = getPlatsizeOrHeight(size, 0);
int height = getPlatsizeOrHeight(size, 1);
//更新工位信息
station.setWarehouseCode(warehouseCode);
updateStation(station, platsize, height, name, Integer.valueOf(num), 0, 0, null, false, null, warehouseCode);
return ResultBean.newOkResult("");
}
@ApiOperation("呼叫空箱")
@RequestMapping("/callEmptyBox")
@AnonymousAccess
public ResultBean callEmptyBox(@RequestBody Map<String, String> paramMap) {
String platsize = paramMap.get("size"); //尺寸
String name = paramMap.get("name"); //工位名称
log.info("{}:收到呼叫空箱信息,尺寸为:{}", name, platsize);
if (StringUtils.isBlank(platsize)) {
return ResultBean.newErrorResult(-1, "", "尺寸不能为空");
}
//判断是否已经呼叫过空箱
Collection<DataLog> queueTasks = taskService.getQueueTasks();
for (DataLog queueTask : queueTasks) {
if (name.equals(queueTask.getLoc()) && !queueTask.isFinished() && !queueTask.isCancel() && queueTask.isCheckOutTask()){
return ResultBean.newErrorResult(-1,"","当前工位:"+name+",已经呼叫空箱,等任务完成后,再进行呼叫");
}
}
StoragePos pos = getEmptyBoxPos(platsize);
if (pos == null) {
return ResultBean.newErrorResult(-1, "", "未找到可用料箱");
}
generateTask(dataCache.getStorageById(pos.getStorageId()), pos.getBarcode(), pos, OP.CHECKOUT, OP_STATUS.WAIT.name(), name);
return ResultBean.newOkResult("");
}
@ApiOperation("获取工位详情")
@RequestMapping("/getStation")
@AnonymousAccess
public ResultBean getStation(@RequestBody Map<String, String> paramMap) {
String name = paramMap.get("name");
Station station = StationCacheUtil.getStation(name);
if (station == null) {
return ResultBean.newErrorResult(-1, "", name + "工位不存在", new String[]{});
}
return ResultBean.newOkResult(station);
}
@ApiOperation("验证是否强制入库")
@RequestMapping("/verifyPutIn")
@AnonymousAccess
public ResultBean verifyPutIn(@RequestBody Map<String, String> paramMap) {
String barcodeStr = paramMap.get("barcode");
String name = paramMap.get("name");
log.info("收到物料信息,条码为:{},工位为:{}", barcodeStr, name);
//料箱直接成功
if (barcodeStr.startsWith("CS") || barcodeStr.startsWith("CM") || barcodeStr.startsWith("CB")) {
return ResultBean.newOkResult("");
}
//开始解析物料
Station station = StationCacheUtil.getStation(name);
if (station == null) {
return ResultBean.newErrorResult(-1, "", name + "工位不存在", new String[]{});
}
String newCodeStr = "=" + station.getPlatsize() + "x" + station.getHeight() + "=" + barcodeStr;
CodeBean codeBean = codeResolve.resolveSingleCode(newCodeStr);
Barcode barcode = codeBean.getBarcode();
try {
smfApi.canPutInAfterResolve(barcode);
} catch (ValidateException e) {
e.printStackTrace();
return ResultBean.newErrorResult(-2, "", e.getMessage());
}
return ResultBean.newOkResult("");
}
@ApiOperation("扫码入库")
@RequestMapping(value = "/operatePos")
@AnonymousAccess
//先扫条码 再扫料箱
public ResultBean operatePos(@RequestBody Map<String, String> paramMap) throws InterruptedException {
String name = paramMap.get("name"); //工位名称
String code = paramMap.get("code"); //条码
log.info("收到物料信息,条码为:{},工位为:{}", code, name);
//Thread.sleep(100000);
Station station = StationCacheUtil.getStation(name);
if (station == null) {
return ResultBean.newErrorResult(-1, "", name + "工位信息未上传成功,请重试", new String[]{});
}
//当前料箱的信息
String currentRfid = station.getCurrentRfid();
if (StringUtils.isBlank(currentRfid)) {
return ResultBean.newErrorResult(-1, "", name + "当前工位料箱信息未上传成功,请重试", new String[]{});
}
//解析出具体的料箱信息
String boxStr = getBoxInfoByRfid(currentRfid);
//判断当前料箱与入库的尺寸信息是否一致
int platsize = station.getPlatsize();
if (platsize == 7) {
if (!boxStr.startsWith("CS")) {
return ResultBean.newErrorResult(-1, "", "物料规格为7寸与当前工位上的料箱:" + boxStr + "不匹配");
}
} else if (platsize == 13) {
if (!boxStr.startsWith("CM")) {
return ResultBean.newErrorResult(-1, "", "物料规格为13寸与当前工位上的料箱:" + boxStr + "不匹配");
}
} else if (platsize == 15) {
if (!boxStr.startsWith("CB")) {
return ResultBean.newErrorResult(-1, "", "物料规格为15寸与当前工位上的料箱:" + boxStr + "不匹配");
}
}
//先判断是否料盒
String newCodeStr = "=" + station.getPlatsize() + "x" + station.getHeight() + "=" + code;
CodeBean codeBean = codeResolve.resolveSingleCode(newCodeStr);
if (!codeBean.isValid()) {
return ResultBean.newErrorResult(-1, "", code + "解析条码失败", new String[]{});
}
Barcode barcode = codeBean.getBarcode();
String partNumber = barcode.getPartNumber();
//如果是箱子的话 则取下边的
if (isBox(partNumber)) {
station.setLastScanBoxCode(code);
if (!currentRfid.startsWith(barcode.getBarcode())) {
return ResultBean.newErrorResult(-1, "", "料箱:" + boxStr + "与料箱隔口码:" + code + "不一致", new String[]{});
}
//Gr标签,卡控库别
String grLabel = station.getGrLabel();
String labelItem = station.getLabelItem();
GrLabel label = grLabelManager.findLabelBylabelId(grLabel, labelItem);
if (label != null){
List<Barcode> barcodes = barcode.getSubCodeList();
if (barcodes != null && !barcodes.isEmpty()){
for (Barcode barcodePos : barcodes) {
if (!code.equals(barcodePos.getPosName())) {
continue;
}
if (!barcodePos.getWarehouseCode().equals(label.getWarehouseCode())) {
return ResultBean.newErrorResult(-1, "", "隔口中库别:" + barcodePos.getWarehouseCode() + "与Gr标签中库别:" + label.getWarehouseCode() + "不一致");
}
}
}
}
//判断当前是否有正在执行的任务
DataLog dataLog = getExecuteTask(boxStr);
if (dataLog != null) {
if (dataLog.isPutInTask()) {
//已有入库任务
return ResultBean.newErrorResult(-1, "", "物料:" + dataLog.getBarcode() + "已有入库任务,需继续执行入库动作", new String[]{});
} else if (dataLog.isCheckOutTask()) {
//已有出库任务
return ResultBean.newErrorResult(-1, "", "物料:" + dataLog.getBarcode() + "已有出库任务,需继续执行出库动作", new String[]{});
}
}
//判断料箱是否在库位中
StoragePos pos = storagePosManager.getByBarcode(boxStr);
if (pos != null) {
return ResultBean.newErrorResult(-1, "", "料箱:" + boxStr + "已存在库位:" + pos.getPosName());
}
//设置操作人
barcode.setCreator(SecurityUtils.getCurrentUsername());
barcodeManager.save(barcode);
} else {
if (barcode.getBarcode().length() < 17 || barcode.getBarcode().length() > 22) {
return ResultBean.newErrorResult(-1, "", barcode.getBarcode() + "请核实唯一码长度是否为17至22位");
}
String lastScanBoxCode = station.getLastScanBoxCode();
if (Strings.isBlank(lastScanBoxCode)) {
//提示要先扫料箱
return ResultBean.newErrorResult(-1, "", "请先扫描料箱隔口码,再扫描物料二维码");
}
//判断是否存在其他料箱中
if (StringUtils.isNotBlank(barcode.getPosName())) {
return ResultBean.newErrorResult(-1, "", "物料" + barcode.getBarcode() + "已存在料箱:" + barcode.getPosName());
}
//判断隔口中厂商,料号,gr标签是否一致
String grLabel = station.getGrLabel();
GrLabel label = null;
if (StringUtils.isNotBlank(grLabel)) {
label = grLabelManager.findLabelBylabelId(grLabel, station.getLabelItem());
if (label != null) {
barcode.setGrLabel(grLabel);
barcode.setWarehouseCode(label.getWarehouseCode());
barcode.setKeeperCode(label.getKeeperCode());
}
} else {
barcode.setWarehouseCode(station.getWarehouseCode());
}
int barcodeCount = 0;
Barcode pidBarcode = barcodeManager.findByBarcode(boxStr);
List<Barcode> subCodes = pidBarcode.getSubCodeList();
if (subCodes != null && !subCodes.isEmpty()) {
for (Barcode subCode : subCodes) {
if (!lastScanBoxCode.equals(subCode.getPosName())){
continue;
}
//判断是否与隔口中的条件是否一致
if (!subCode.getProvider().equals(barcode.getProvider()) || !subCode.getPartNumber().equals(barcode.getPartNumber()) || !subCode.getWarehouseCode().equals(barcode.getWarehouseCode())) {
return ResultBean.newErrorResult(-1, "", "厂商:" + barcode.getProvider() + ",料号:" + barcode.getPartNumber() + "库别:" + barcode.getWarehouseCode() + "与隔口中:" + lastScanBoxCode + "厂商:" + subCode.getProvider() + ",料号:" + subCode.getPartNumber() + "库别:" + subCode.getWarehouseCode() + "不一致");
}
//校验是否属于同一个gr
if (StringUtils.isNotBlank(grLabel)) {
if (!grLabel.equals(subCode.getGrLabel())) {
return ResultBean.newErrorResult(-1, "", grLabel + "与隔口中Gr标签不一致:" + subCode.getGrLabel());
}
}
if (lastScanBoxCode.equals(subCode.getPosName())) {
barcodeCount++;
}
}
}
//7寸箱子最多放10盘
if (lastScanBoxCode.startsWith("CS")) {
if (barcodeCount >= 10) {
return ResultBean.newErrorResult(-1, "", "7寸物料每个隔口最多只允许放10盘");
}
}
//更新gr标签数量
if (label != null) {
int remainingAmount = label.getRemainingAmount();
if (remainingAmount <= 0) {
return ResultBean.newErrorResult(-1, "", "Gr已达到最大数量:" + label.getAmount());
}
//校验厂商与pn是否与gr一致
if (!label.getPartNumber().equals(barcode.getPartNumber()) || !label.getProvider().equals(barcode.getProvider())) {
return ResultBean.newErrorResult(-1, "", "物料PN:" + barcode.getPartNumber() + ",厂商:" + barcode.getProvider() + "与GR-" + "PN:" + label.getPartNumber() + ",厂商:" + label.getProvider() + "不一致");
}
label.setRemainingAmount(remainingAmount - barcode.getAmount());
grLabelManager.save(label);
}
//当前已扫描的料卷数量+1
int reelCurrentNum = station.getReelCurrentNum();
station.setReelCurrentNum(reelCurrentNum + 1);
//开始生成任务,并处理
barcode.setHostBarcodeId(pidBarcode.getId());
barcode.setReelAmount(1); //设置卷数为1
barcode.setPutInTime(System.currentTimeMillis());
barcode.setCreator(SecurityUtils.getCurrentUsername());
barcode = barcodeManager.save(barcode);
finishTask(pidBarcode, OP.PUT_IN, null, barcode, barcode.getAmount(),OP_STATUS.FINISHED.name(),lastScanBoxCode);
log.info("生成入库任务:" + barcode.getBarcode() + "隔口号位:" + lastScanBoxCode);
}
StationCacheUtil.updateStation(station);
return ResultBean.newOkResult("");
}
@ApiOperation("完成装箱并入库")
@RequestMapping("/finishBoxPutIn")
@AnonymousAccess
public ResultBean finishBoxPutIn(@RequestBody Map<String, String> paramMap) {
String code = paramMap.get("barcode"); //料箱条码
String name = paramMap.get("name"); //工位名称
String cids = paramMap.get("cids");
for (Storage storage : dataCache.getAllStorage().values()) {
if (storage.isType(new DeviceType[]{DeviceType.AGV_BOX})) {
cids = storage.getCid();
break;
}
}
log.info("完成装箱并入库,条码为:{},工位为:{}", code, name);
Station station = StationCacheUtil.getStation(name);
if (station == null) {
return ResultBean.newErrorResult(-1, "", name + "工位信息未上传成功,请重试");
}
//先找可用料仓
if (StringUtils.isBlank(cids)) {
return ResultBean.newErrorResult(-1, "", "没有可以入库的料仓");
}
//得到箱子号
String boxStr = getBoxInfoByRfid(code);
//校验rfid是否一致
String currentRfid = station.getCurrentRfid();
if (StringUtils.isBlank(currentRfid)) {
return ResultBean.newErrorResult(-1, "", name + "当前工位料箱信息未上传成功,请重试", new String[]{});
} else if (!currentRfid.startsWith(boxStr)) {
return ResultBean.newErrorResult(-1, "", "当前工位料箱" + currentRfid + "与" + "要入库的料箱:" + boxStr + "不一致", new String[]{});
}
List<Storage> storageList = Lists.newArrayList();
List<String> cidList = Lists.newArrayList();
for (String cid : cids.split(",")) {
String notIntoCids = dataCache.getSettings().getNotIntoCids();
if (notIntoCids != null) {
if (notIntoCids.contains(cid)) {
log.info("料仓[" + cid + "]已被屏蔽入库");
continue;
}
}
Storage storage = dataCache.getStorage(cid);
if (storage != null) {
storageList.add(storage);
cidList.add(cid);
}
}
if (storageList.isEmpty()) {
return ResultBean.newErrorResult(-1, "", "没有可以入库的料仓", new String[]{});
}
DataLog dataLog = getExecuteTask(boxStr);
if (dataLog != null) {
if (dataLog.isPutInTask()) {
//已有入库任务
return ResultBean.newErrorResult(-1, "", "物料[" + dataLog.getBarcode() + "]已有入库任务,需继续执行入库动作", new String[]{});
} else if (dataLog.isCheckOutTask()) {
//已有出库任务
return ResultBean.newErrorResult(-1, "", "物料[" + dataLog.getBarcode() + "]已有出库任务,需继续执行出库动作", new String[]{});
}
}
//开始寻找空库位
Barcode boxBarcode = barcodeManager.findByBarcode(boxStr);
StoragePos pos = taskService.findEmptyPosForPutIn(storageList, boxBarcode, "", "");
if (pos == null) {
throw new ValidateException("", "[" + boxBarcode.getBarcode() + "]未找到可用的[" + boxBarcode.getPlateSize() + "x" + boxBarcode.getHeight() + "]仓位", null);
}
if (pos != null) {
Storage theStorage = dataCache.getStorageById(pos.getStorageId());
ReelLockPosInfo oldLockInfo = ReelLockPosUtil.getLockPosInfoByCode(boxBarcode.getBarcode());
if (oldLockInfo != null) {
if (!oldLockInfo.getBarcode().equals(boxBarcode.getBarcode())) {
ReelLockPosUtil.removeReelLockPosInfo(oldLockInfo.getBarcode());
log.info("清理锁定库位:库位号[" + oldLockInfo.getLockPosName() + "]上物料[" + oldLockInfo.getBarcode() + "]锁定的库位");
}
}
ReelLockPosInfo reelLocInfo = new ReelLockPosInfo();
reelLocInfo.setBarcode(boxBarcode.getBarcode());
reelLocInfo.setCid(theStorage.getCid());
reelLocInfo.setLockPosName(pos.getPosName());
reelLocInfo.setLockPosId(pos.getId());
reelLocInfo = ReelLockPosUtil.addReelLockPosInfo(reelLocInfo, cidList);
if (reelLocInfo == null) {
return ResultBean.newErrorResult(-1, "", "[" + boxBarcode.getBarcode() + "]库位[" + reelLocInfo.getLockPosName() + "]已被锁定,暂停入库", new String[]{});
}
}
//生成任务
generateTask(dataCache.getStorageById(pos.getStorageId()), boxBarcode, pos, OP.PUT_IN, OP_STATUS.WAIT.name(), null);
//同时清空lastScanBoxCode
station.setLastScanBoxCode(null);
if (station.getReelNum() > station.getReelCurrentNum()) {
station.setPutIn(false);
} else {
station.setGrLabel(null);
station.setLabelItem(null);
station.setWarehouseCode(null);
station.setLastScanBoxCode(null);
station.setPutIn(true);
}
//station.setMsg(currentRfid + "需执行入库操作");
StationCacheUtil.saveBoxToBoxCode(station);
//判断是否有要出库的任务,给取消掉
Barcode barcode = barcodeManager.findByBarcode(boxStr);
List<Barcode> subCodes = barcode.getSubCodeList();
if (subCodes != null && !subCodes.isEmpty()) {
for (Barcode subCode : subCodes) {
if (!subCode.isOut()) {
continue;
}
finishTask(barcode,OP.CHECKOUT,null,subCode,subCode.getAmount(),OP_STATUS.CANCEL.name(),null);
}
}
boxCount.remove(boxStr);
return ResultBean.newOkResult(station);
}
@ApiOperation("出库页面展示")
@RequestMapping("/outIndex")
@AnonymousAccess
public ResultBean outIndex(@RequestBody Map<String, String> paramMap) {
String name = paramMap.get("name"); //工位名称
String barcodeStr = paramMap.get("barcode"); //物料条码
Station station = StationCacheUtil.getStation(name);
if (station == null) {
return ResultBean.newErrorResult(-1, "", name + "工位信息未上传成功,请重试");
}
//判断当前工位是否有料箱
String currentRfid = station.getCurrentRfid();
if (StringUtils.isBlank(currentRfid)) {
return ResultBean.newErrorResult(-1, "", name + "当前工位料箱信息未上传成功,请重试", new String[]{});
}
//获取料箱中的物料信息
String boxStr = getBoxInfoByRfid(currentRfid);
Barcode pidBarcode = barcodeManager.findByBarcode(boxStr);
ResultBean resultBean = null;
boolean hasBrand = false;
if (isBox(barcodeStr) && (barcodeStr.endsWith("A") || barcodeStr.endsWith("B"))) {
resultBean = outByBox(boxStr, pidBarcode, hasBrand);
} else if (isBox(barcodeStr) && barcodeStr.indexOf("-") != -1) {
resultBean = outByPartition(barcodeStr, pidBarcode, hasBrand);
} else {
resultBean = outByReel(barcodeStr, boxStr, pidBarcode, hasBrand);
}
return resultBean;
}
@ApiOperation("料箱中的数量")
@RequestMapping("/getBoxNum")
@AnonymousAccess
public ResultBean getBoxNum(@RequestBody Map<String, String> paramMap) {
String name = paramMap.get("name");
Station station = StationCacheUtil.getStation(name);
if (station == null) {
return ResultBean.newErrorResult(-1, "", name + "工位信息未上传成功,请重试");
}
//判断当前工位是否有料箱
String currentRfid = station.getCurrentRfid();
if (StringUtils.isBlank(currentRfid)) {
return ResultBean.newErrorResult(-1, "", name + "当前工位料箱信息未上传成功,请重试", new String[]{});
}
//获取料箱中的物料信息
String boxStr = getBoxInfoByRfid(currentRfid);
//需要出库的数量
Map<String, Integer> needOutCountMap = new HashMap<>();
needOutCountMap.put(boxStr + "-1", 0);
needOutCountMap.put(boxStr + "-2", 0);
needOutCountMap.put(boxStr + "-3", 0);
needOutCountMap.put(boxStr + "-4", 0);
needOutCountMap.put(boxStr + "-5", 0);
needOutCountMap.put(boxStr + "-6", 0);
needOutCountMap.put(boxStr + "-7", 0);
needOutCountMap.put(boxStr + "-8", 0);
Barcode barcode = barcodeManager.findByBarcode(boxStr);
List<Barcode> barcodes = new ArrayList<>();
if (barcode != null){
barcodes = barcode.getSubCodeList();
}
//料箱总数量
if (barcodes == null || barcodes.isEmpty()) {
boxCount.put(boxStr, 0);
} else {
if (boxCount.get(boxStr) == null) {
boxCount.put(boxStr, barcodes.size());
}
}
//料箱所有数量按库位分组
Map<String, Long> allCountMap = new HashMap<>();
if (barcodes != null && !barcodes.isEmpty()) {
allCountMap = barcodes.stream().collect(Collectors.groupingBy(Barcode::getPosName, Collectors.counting()));
//得到需要出库的数量
List<Barcode> outSubCodeList = barcodes.stream().filter(s -> s.isOut()).collect(Collectors.toList());
//需要出库的数量
Map<String, Long> needOutCount = outSubCodeList.stream().collect(Collectors.groupingBy(Barcode::getPosName, Collectors.counting()));
for (Map.Entry<String, Long> needOutEntry : needOutCount.entrySet()) {
needOutCountMap.put(needOutEntry.getKey(), needOutEntry.getValue().intValue());
}
}
List<Integer> boxPartitionCount1 = new ArrayList<>();
boxPartitionCount1.add(needOutCountMap.get(boxStr + "-1"));
int partition1 = allCountMap.get(boxStr + "-1") == null ? 0 : allCountMap.get(boxStr + "-1").intValue();
boxPartitionCount1.add(partition1);
List<Integer> boxPartitionCount2 = new ArrayList<>();
boxPartitionCount2.add(needOutCountMap.get(boxStr + "-2"));
int partition2 = allCountMap.get(boxStr + "-2") == null ? 0 : allCountMap.get(boxStr + "-2").intValue();
boxPartitionCount2.add(partition2);
List<Integer> boxPartitionCount3 = new ArrayList<>();
boxPartitionCount3.add(needOutCountMap.get(boxStr + "-3"));
int partition3 = allCountMap.get(boxStr + "-3") == null ? 0 : allCountMap.get(boxStr + "-3").intValue();
boxPartitionCount3.add(partition3);
List<Integer> boxPartitionCount4 = new ArrayList<>();
boxPartitionCount4.add(needOutCountMap.get(boxStr + "-4"));
int partition4 = allCountMap.get(boxStr + "-4") == null ? 0 : allCountMap.get(boxStr + "-4").intValue();
boxPartitionCount4.add(partition4);
List<Integer> boxPartitionCount5 = new ArrayList<>();
boxPartitionCount5.add(needOutCountMap.get(boxStr + "-5"));
int partition5 = allCountMap.get(boxStr + "-5") == null ? 0 : allCountMap.get(boxStr + "-5").intValue();
boxPartitionCount5.add(partition5);
List<Integer> boxPartitionCount6 = new ArrayList<>();
boxPartitionCount6.add(needOutCountMap.get(boxStr + "-6"));
int partition6 = allCountMap.get(boxStr + "-6") == null ? 0 : allCountMap.get(boxStr + "-6").intValue();
boxPartitionCount6.add(partition6);
List<Integer> boxPartitionCount7 = new ArrayList<>();
boxPartitionCount7.add(needOutCountMap.get(boxStr + "-7"));
int partition7 = allCountMap.get(boxStr + "-7") == null ? 0 : allCountMap.get(boxStr + "-7").intValue();
boxPartitionCount7.add(partition7);
List<Integer> boxPartitionCount8 = new ArrayList<>();
boxPartitionCount8.add(needOutCountMap.get(boxStr + "-8"));
int partition8 = allCountMap.get(boxStr + "-8") == null ? 0 : allCountMap.get(boxStr + "-8").intValue();
boxPartitionCount8.add(partition8);
List<Integer> inBoxPartitionCounts = new ArrayList<>(); //入库需要展示的数量
List<List<Integer>> boxPartitionCounts = new ArrayList<>(); //出库需要展示的数量
if (currentRfid.endsWith("A")) {
if (currentRfid.startsWith("CS")) {
inBoxPartitionCounts.add(partition8);
inBoxPartitionCounts.add(partition7);
inBoxPartitionCounts.add(partition6);
inBoxPartitionCounts.add(partition5);
inBoxPartitionCounts.add(partition1);
inBoxPartitionCounts.add(partition2);
inBoxPartitionCounts.add(partition3);
inBoxPartitionCounts.add(partition4);
boxPartitionCounts.add(boxPartitionCount8);
boxPartitionCounts.add(boxPartitionCount7);
boxPartitionCounts.add(boxPartitionCount6);
boxPartitionCounts.add(boxPartitionCount5);
boxPartitionCounts.add(boxPartitionCount1);
boxPartitionCounts.add(boxPartitionCount2);
boxPartitionCounts.add(boxPartitionCount3);
boxPartitionCounts.add(boxPartitionCount4);
} else if (currentRfid.startsWith("CM")) {
inBoxPartitionCounts.add(partition1);
inBoxPartitionCounts.add(partition2);
inBoxPartitionCounts.add(partition3);
boxPartitionCounts.add(boxPartitionCount1);
boxPartitionCounts.add(boxPartitionCount2);
boxPartitionCounts.add(boxPartitionCount3);
} else if (currentRfid.startsWith("CB")) {
inBoxPartitionCounts.add(partition2);
inBoxPartitionCounts.add(partition1);
boxPartitionCounts.add(boxPartitionCount2);
boxPartitionCounts.add(boxPartitionCount1);
}
} else if (currentRfid.endsWith("B")) {
if (currentRfid.startsWith("CS")) {
inBoxPartitionCounts.add(partition4);
inBoxPartitionCounts.add(partition3);
inBoxPartitionCounts.add(partition2);
inBoxPartitionCounts.add(partition1);
inBoxPartitionCounts.add(partition5);
inBoxPartitionCounts.add(partition6);
inBoxPartitionCounts.add(partition7);
inBoxPartitionCounts.add(partition8);
boxPartitionCounts.add(boxPartitionCount4);
boxPartitionCounts.add(boxPartitionCount3);
boxPartitionCounts.add(boxPartitionCount2);
boxPartitionCounts.add(boxPartitionCount1);
boxPartitionCounts.add(boxPartitionCount5);
boxPartitionCounts.add(boxPartitionCount6);
boxPartitionCounts.add(boxPartitionCount7);
boxPartitionCounts.add(boxPartitionCount8);
} else if (currentRfid.startsWith("CM")) {
inBoxPartitionCounts.add(partition3);
inBoxPartitionCounts.add(partition2);
inBoxPartitionCounts.add(partition1);
boxPartitionCounts.add(boxPartitionCount3);
boxPartitionCounts.add(boxPartitionCount2);
boxPartitionCounts.add(boxPartitionCount1);
} else if (currentRfid.startsWith("CB")) {
inBoxPartitionCounts.add(partition1);
inBoxPartitionCounts.add(partition2);
boxPartitionCounts.add(boxPartitionCount1);
boxPartitionCounts.add(boxPartitionCount2);
}
}
Map<String, Object> resultMap = new HashMap<>();
resultMap.put("boxPartitionCounts", boxPartitionCounts); //展示数量
resultMap.put("boxAllCount", boxCount.get(boxStr)); //料箱总数量
if (barcodes == null || barcodes.isEmpty()) {
resultMap.put("boxRemainingCount", 0); //剩余数量
} else {
resultMap.put("boxRemainingCount", barcodes.size()); //剩余数量
}
resultMap.put("currentRfid", currentRfid);//箱子号
resultMap.put("box", currentRfid);
resultMap.put("reelCurrentNum", station.getReelCurrentNum());//当前扫描数量
resultMap.put("reelNum", station.getReelNum());//总数量
resultMap.put("msg", "");//提示信息
Collection<DataLog> queueTasks = taskService.getQueueTasks();
for (DataLog queueTask : queueTasks) {
if (boxStr.equals(queueTask.getBarcode())) {
if (queueTask.isCheckOutTask()) {
resultMap.put("msg", boxStr + "需执行出库操作");//提示信息
} else {
resultMap.put("msg", boxStr + "需执行入库操作");//提示信息
}
break;
}
}
resultMap.put("boxCurrentNum", station.getBoxCurrentNum());
resultMap.put("platsize", station.getPlatsize());
resultMap.put("lastScanBoxCode", station.getLastScanBoxCode());
resultMap.put("inBoxPartitionCounts", inBoxPartitionCounts);
resultMap.put("boxNum", station.getBoxNum());
return ResultBean.newOkResult(resultMap);
}
@ApiOperation("已全部完成装箱")
@RequestMapping("/finishPutIn")
public ResultBean finishPutIn(@RequestBody Map<String, String> paramMap) {
String name = paramMap.get("name");
Station station = StationCacheUtil.getStation(name);
if (station == null) {
return ResultBean.newErrorResult(-1, "", name + "工位不存在", new String[]{});
}
//station.setMsg("请核实当前工位的料箱是否已经全部入库");
station.setReelCurrentNum(0);
station.setLastScanBoxCode(null);
station.setBoxCurrentNum(0);
station.setCurrentRfid(null);
station.setReelNum(0);
station.setBoxNum(0);
station.setGrLabel(null);
station.setPutIn(true);
station.setWarehouseCode(null);
StationCacheUtil.updateStation(station);
return ResultBean.newOkResult(station);
}
@RequestMapping("/testBarcode")
@AnonymousAccess
public void testBarcode(){
List<Barcode> barcodes = barcodeManager.findByQuery(new Query());
for (Barcode barcode : barcodes) {
List<Barcode> subCodes = barcode.getSubCodeList();
if (subCodes != null && !subCodes.isEmpty()) {
for (Barcode subCode : subCodes) {
barcodeManager.save(subCode);
}
}
}
}
/**
* 生成任务
*
* @param storage
* @param barcode
* @param pos
* @param type
* @param status
* @param loc
*/
private void generateTask(Storage storage, Barcode barcode, StoragePos pos, int type, String status, String loc) {
//开始入库任务
DataLog task = new DataLog(storage, barcode, pos);
task.setType(type);
task.setStatus(status);
task.setLoc(loc);
task.setOperator(SecurityUtils.getCurrentUsername());
task.setBoxPosName(pos.getPosName());
taskService.updateQueueTask(task);
}
/**
* 完成出入库任务
*
* @param pidBarcode 料箱
* @param currentTask 当前任务
* @param subBarcode 箱内物料
* @param opQty 数量
* @throws ValidateException
*/
private synchronized void finishTask(Barcode pidBarcode, int opType, DataLog currentTask, Barcode subBarcode, int opQty,String opStatus,String lastScanBoxCode) throws ValidateException {
String orderItemId = subBarcode.getOrderItemId();
if (opType == OP.CHECKOUT && OP_STATUS.CANCEL.name().equals(opStatus)) {
log.info(subBarcode.getBarcode() + "任务取消---" + orderItemId);
subBarcode.setOut(false);
subBarcode.setSelectMsg(null);
subBarcode.setOrderItemId(null);
subBarcode = barcodeManager.save(subBarcode);
}
if (StringUtils.isNotBlank(lastScanBoxCode)) {
subBarcode.setPosName(lastScanBoxCode);
subBarcode = barcodeManager.save(subBarcode);
}
//更新barcode缓存
pidBarcode.UpdateSubCode(subBarcode);
if (opType == OP.CHECKOUT && OP_STATUS.FINISHED.name().equals(opStatus)) {
pidBarcode.setAmount(pidBarcode.getAmount() - opQty);
pidBarcode.setReelAmount(pidBarcode.getReelAmount() - subBarcode.getReelAmount()); //出库卷数-1
//数量为0直接删除
if (subBarcode.getAmount() <= 0) {
barcodeManager.delete(subBarcode);
log.info(subBarcode.getBarcode() + "数量为0,删除--" + pidBarcode.getBarcode());
}
}
if (opType == OP.PUT_IN && OP_STATUS.FINISHED.name().equals(opStatus)) {
pidBarcode.setAmount(pidBarcode.getAmount() + opQty);
pidBarcode.setReelAmount(pidBarcode.getReelAmount() + subBarcode.getReelAmount()); //入库卷数+1
}
pidBarcode = barcodeManager.saveBarcode(pidBarcode);
DataLog task = null;
//先查看是否有相同类型且库位相同的任务
if (currentTask != null) {
Collection<DataLog> queueTasks = taskService.getQueueTasks();
for (DataLog queueTask : queueTasks) {
if (queueTask.getType() == currentTask.getType()) {
if (queueTask.getPosName().equals(pidBarcode.getBarcode())) {
task = queueTask;
break;
}
}
}
}
if (task == null) {
task = new DataLog();
}
task.setStatus(opStatus);
task.setPartNumber(subBarcode.getPartNumber());
task.setBarcode(subBarcode.getBarcode());
task.setNum(opQty);
task.setType(opType);
task.setPosName(subBarcode.getPosName());
//task.setOperator(SecurityUtils.getCurrentUsername());
task.setDateCode(subBarcode.getDateCode());
task.setBatchInfo(subBarcode.getBatch());
task.setProvider(subBarcode.getProvider());
task.setProviderNumber(subBarcode.getProviderNumber());
task.setKeeperCode(subBarcode.getKeeperCode());
task.setReelPosName(subBarcode.getPosName());
task.setSubSourceId(orderItemId);
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.setWarehouseCode(orderItem.getWarehouseCode());
task.setPlantCode(orderItem.getPlantCode());
task.setOrderNo(orderItem.getOrderNo());
}
}
taskService.updateFinishedTask(task);
}
/**
* 解析尺寸信息
*
* @param size
* @param index
* @return
*/
private int getPlatsizeOrHeight(String size, int index) {
return Integer.valueOf(size.split("X")[index]);
}
/**
* 根据尺寸获取空料箱
*
* @param platsize
* @return
*/
private StoragePos getEmptyBoxPos(String platsize) {
//得到料盒类型
String boxSuffix = "";
if ("7".equals(platsize)) {
boxSuffix = "CS";
} else if ("13".equals(platsize)) {
boxSuffix = "CM";
} else if ("15".equals(platsize)) {
boxSuffix = "CB";
}
//料仓类型是agv的
String storageId = "";
Collection<Storage> storages = dataCache.getAllStorage().values();
for (Storage storage : storages) {
if (storage.isType(new DeviceType[]{DeviceType.AGV_BOX})) {
storageId = storage.getId();
}
}
Criteria c = Criteria.where("barcode").exists(true)
.and("enabled").is(true);//可用
//排除掉正在执行的仓位
Collection<String> excludePosIds = taskService.excludePosIds();
log.info("excludePosIds--" + JsonUtil.toJsonStr(excludePosIds));
if (excludePosIds != null && !excludePosIds.isEmpty()) {
c.and("id").nin(excludePosIds);
}
if (StringUtils.isNotBlank(storageId)) {
c.and("storageId").is(storageId);
}
if (StringUtils.isNotBlank(boxSuffix)) {
Pattern pattern = Pattern.compile(QueryHelp.escapeExprSpecialWord(boxSuffix), Pattern.CASE_INSENSITIVE);
c.and("barcode.barcode").regex(pattern);
}
Query q = new Query(c).with(Sort.by(Sort.Direction.ASC, "barcode.amount")).limit(1);
List<StoragePos> storagePoss = storagePosManager.findByQuery(q);
if (storagePoss != null && !storagePoss.isEmpty()) {
return storagePoss.get(0);
}
return null;
}
/**
* 获取正在执行的任务
*
* @param barcode
* @return
*/
private DataLog getExecuteTask(String barcode) {
List<DataLog> allTasks = taskService.getAllTasks();
for (DataLog dataLog : allTasks) {
if (dataLog.getBarcode().equals(barcode)) {
if (!dataLog.isCancel() && !dataLog.isFinished()) {
return dataLog;
}
}
}
return null;
}
/**
* 根据库位获取物料信息
*
* @param posName
* @param isOut
* @return
*/
private List<Barcode> getBarcodesByPosName(String posName, boolean isOut) {
Query q = new Query();
Criteria c = Criteria.where("posName").is(posName);
if (isOut) {
c.and("isOut").exists(true);
}
q.addCriteria(c);
return barcodeManager.findByQuery(q);
}
/**
* 根据物料出库
*
* @param barcodeStr
* @param boxStr
* @param pidBarcode
* @return
*/
public synchronized ResultBean outByReel(String barcodeStr, String boxStr, Barcode pidBarcode, boolean hasBrand) {
ResultBean bean = ResultBean.newOkResult("");
if (StringUtils.isNotBlank(barcodeStr)) {
CodeBean codeBean = codeResolve.resolveSingleCode(barcodeStr);
if (!codeBean.isValid()) {
return ResultBean.newErrorResult(-1, "", barcodeStr + "解析失败");
}
Barcode barcode = barcodeManager.findByBarcode(codeBean.getBarcode().getBarcode());
if (barcode == null || StringUtils.isBlank(barcode.getPosName())) {
return ResultBean.newErrorResult(-1, "", barcode.getBarcode() + "不在料箱:" + boxStr + "请核实是否已经出库");
}
//判断与隔口是否一致
if (!barcode.getPosName().startsWith(boxStr)) {
return ResultBean.newErrorResult(-1, "", barcode.getBarcode() + "所在的料箱为:" + barcode.getPosName() + ",与当前工位料箱:" + boxStr + "不一致");
}
String selectMsg = "";
List<Barcode> barcodes = getBarcodesByPosName(barcode.getPosName(), true);
for (Barcode barcodePos : barcodes) {
if (StringUtils.isNotBlank(barcodePos.getSelectMsg())) {
selectMsg = barcodePos.getSelectMsg();
break;
}
}
//判断查询条件是否一致
if (StringUtils.isNotBlank(selectMsg)) {
if (StringUtils.isBlank(barcode.getSelectMsg())) {
return ResultBean.newErrorResult(-1, "", "请核实与查询条件:" + selectMsg + "是否一致");
}
}
//判断当前隔口是否有要出的任务
boolean isOut = false;
if (barcode.isOut()) {
isOut = true;
String orderItemId = barcode.getOrderItemId();
if (StringUtils.isNotBlank(orderItemId)) {
LiteOrderItem orderItem = liteOrderItemManager.get(orderItemId);
if (orderItem != null) {
if (StringUtils.isNotBlank(orderItem.getBrand())) {
hasBrand = true;
}
}
}
int amount = barcode.getAmount();
barcode.setAmount(0);
barcode = barcodeManager.save(barcode);
finishTask(pidBarcode, OP.CHECKOUT, null, barcode, amount,OP_STATUS.FINISHED.name(),null);
} else {
if (barcodes != null && !barcodes.isEmpty()) {
//获取到需要出库的物料,进行更改
Barcode barcodeByOut = null;
for (Barcode barcodeByPosName : barcodes) {
if (barcodeByPosName.isOut() && StringUtils.isNotBlank(barcodeByPosName.getOrderItemId())) {
barcodeByOut = barcodeByPosName;
break;
}
}
if (barcodeByOut != null) {
String orderItemId = barcodeByOut.getOrderItemId();
barcodeByOut.setOut(false);
barcodeByOut.setOrderItemId(null);
barcodeByOut = barcodeManager.save(barcodeByOut);
pidBarcode.UpdateSubCode(barcodeByOut);
pidBarcode = barcodeManager.saveBarcode(pidBarcode);
//互换,要出的和隔口中的数据
int amount = barcode.getAmount();
barcode.setAmount(0);
barcode.setOrderItemId(orderItemId);
barcode = barcodeManager.save(barcode);
finishTask(pidBarcode, OP.CHECKOUT, null, barcode, amount,OP_STATUS.FINISHED.name(),null);
isOut = true;
log.info(barcode.getBarcode()+"不是出库任务,"+barcodeByOut.getBarcode()+"需更改out为false");
}
}
}
if (!isOut) {
return ResultBean.newErrorResult(-1, "", barcode.getBarcode() + "不需要出库");
}
} else {
bean = ResultBean.newErrorResult(-1, "smfcore.valueCanotNull", "{0}不能为空", new String[]{"条码编号"});
}
if (hasBrand) {
log.info("hasBrand--" + hasBrand);
bean.setCode(3);
}
return bean;
}
/**
* 根据料箱出库
*
* @param pidBarcode
* @return
*/
private ResultBean outByBox(String boxStr, Barcode pidBarcode, boolean hasBrand) {
//根据料箱获取到全部的物料
//List<Barcode> barcodes = getBarcodesByBoxStr(boxStr);
List<Barcode> barcodes = pidBarcode.getSubCodeList();
if (barcodes == null || barcodes.isEmpty()) {
return ResultBean.newErrorResult(-1, "", "料箱:" + pidBarcode.getBarcode() + ",没有可出库的物料");
}
//判断是否全部出库
for (Barcode barcode : barcodes) {
if (!barcode.isOut()) {
return ResultBean.newErrorResult(-1, "", pidBarcode.getBarcode() + "不允许全部取出,请核实");
}
}
//开始循环,生成任务
for (int index = 0; index < barcodes.size();/*; index++*/) {
Barcode barcode = barcodes.get(index);
String orderItemId = barcode.getOrderItemId();
if (StringUtils.isNotBlank(orderItemId)) {
LiteOrderItem orderItem = liteOrderItemManager.get(orderItemId);
if (orderItem != null) {
if (StringUtils.isNotBlank(orderItem.getBrand())) {
hasBrand = true;
}
}
}
int amount = barcode.getAmount();
barcode.setAmount(0);
barcode = barcodeManager.save(barcode);
finishTask(pidBarcode, OP.CHECKOUT, null, barcode, amount,OP_STATUS.FINISHED.name(),null);
}
ResultBean bean = ResultBean.newOkResult("");
if (hasBrand) {
log.info("hasBrand--" + hasBrand);
bean.setCode(3);
}
return bean;
}
/**
* 根据隔扣出库
*
* @param barcodeStr
* @param pidBarcode
* @return
*/
private ResultBean outByPartition(String barcodeStr, Barcode pidBarcode, boolean hasBrand) {
List<Barcode> barcodes = getBarcodesByPosName(barcodeStr, false);
if (barcodes == null || barcodes.isEmpty()) {
return ResultBean.newErrorResult(-1, "", "料箱隔口:" + barcodeStr + "扫描错误");
}
//判断是否全部出库
for (Barcode barcode : barcodes) {
if (!barcode.isOut()) {
return ResultBean.newErrorResult(-1, "", barcodeStr + "不允许全部出库,请核实");
}
}
for (int i = 0; i < barcodes.size(); i++) {
Barcode barcode = barcodes.get(i);
String orderItemId = barcode.getOrderItemId();
if (StringUtils.isNotBlank(orderItemId)) {
LiteOrderItem orderItem = liteOrderItemManager.get(orderItemId);
if (orderItem != null) {
if (StringUtils.isNotBlank(orderItem.getBrand())) {
hasBrand = true;
}
}
}
int amount = barcode.getAmount();
barcode.setAmount(0);
barcode = barcodeManager.save(barcode);
finishTask(pidBarcode, OP.CHECKOUT, null, barcode, amount,OP_STATUS.FINISHED.name(),null);
}
ResultBean bean = ResultBean.newOkResult("");
if (hasBrand) {
log.info("hasBrand--" + hasBrand);
bean.setCode(3);
}
return bean;
}
private boolean isBox(String boxStr) {
return boxStr.startsWith("CS") || boxStr.startsWith("CM") || boxStr.startsWith("CB");
}
public Station updateStation(Station station, int platsize, int height, String name, int num, int reelcurrentNum, int boxCurrentNum, String lastScanBoxCode, boolean putIn, String msg, String warehouseCode) {
station.setPlatsize(platsize);
station.setHeight(height);
station.setName(name);
station.setReelNum(num);
station.setReelCurrentNum(reelcurrentNum);
station.setLastScanBoxCode(lastScanBoxCode);
station.setBoxCurrentNum(boxCurrentNum);
station.setPutIn(putIn);
//station.setMsg(msg);
StationCacheUtil.updateStation(station);
return station;
}
/**
* 解析rfid为料箱号
*
* @param rfid
* @return
*/
private String getBoxInfoByRfid(String rfid) {
if (rfid.endsWith("B") || rfid.endsWith("A")) {
rfid = rfid.substring(0, rfid.length() - 1);
} else if (rfid.indexOf("-") != -1) {
rfid = rfid.substring(0, rfid.indexOf("-"));
}
return rfid;
}
private List<Barcode> getBarcodesByBoxStr(String boxStr){
Pattern pattern = Pattern.compile(QueryHelp.escapeExprSpecialWord(boxStr), Pattern.CASE_INSENSITIVE);
return barcodeManager.findByQuery(new Query(Criteria.where("posName").regex(pattern)));
}
}
package com.neotel.smfcore.custom.lizhen.agvBox.rest;
import com.neotel.smfcore.common.bean.PageData;
import com.neotel.smfcore.common.bean.ResultBean;
import com.neotel.smfcore.common.exception.ValidateException;
import com.neotel.smfcore.common.utils.JsonUtil;
import com.neotel.smfcore.common.utils.QueryHelp;
import com.neotel.smfcore.common.utils.SecurityUtils;
import com.neotel.smfcore.common.utils.StringUtils;
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.custom.lizhen.agvBox.bean.WareHouseCode;
import com.neotel.smfcore.custom.lizhen.agvBox.bean.dto.WareHouseCodeDto;
import com.neotel.smfcore.custom.lizhen.agvBox.bean.mapstruct.WareHouseCodeMapper;
import com.neotel.smfcore.custom.lizhen.agvBox.bean.query.WareHouseCodeQueryCriteria;
import com.neotel.smfcore.custom.lizhen.agvBox.service.manager.WareHouseCodeManager;
import com.neotel.smfcore.security.annotation.AnonymousAccess;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;
@ApiOperation("库别维护页面")
@Slf4j
@RestController
@RequestMapping("/api/wareHouseCode")
public class WareHouseCodeController {
@Autowired
private WareHouseCodeManager codeManager;
@Autowired
private WareHouseCodeMapper codeMapper;
@Autowired
private ILiteOrderManager liteOrderManager;
@Autowired
private ILiteOrderItemManager liteOrderItemManager;
/*@ApiOperation("根据id查找库别信息")
@RequestMapping("/getById")
@AnonymousAccess
public ResultBean getWareHouseCodeById(String id) {
WareHouseCode wareHouseCode = codeManager.get(id);
return ResultBean.newOkResult(codeMapper.toDto(wareHouseCode));
}*/
@ApiOperation("保存库别信息")
@PostMapping
@AnonymousAccess
public ResultBean saveWareHouseCode(@RequestBody WareHouseCodeDto wareHouseCodeDto) {
WareHouseCode wareHouseCode = codeMapper.toEntity(wareHouseCodeDto);
wareHouseCode.setCreateBy(SecurityUtils.getCurrentUsername());
codeManager.save(wareHouseCode);
return ResultBean.newOkResult("");
}
@ApiOperation("修改库别信息")
@PutMapping
@AnonymousAccess
private ResultBean updateWareHouseCode(@RequestBody WareHouseCodeDto wareHouseCodeDto){
if (wareHouseCodeDto.getId() == null) {
return ResultBean.newErrorResult(-1,"smfcore.valueCanotNull","{0}不能为空",new String[]{"id"} );
}
WareHouseCode wareHouseCode = codeMapper.toEntity(wareHouseCodeDto);
wareHouseCode.setId(wareHouseCodeDto.getId());
wareHouseCode.setUpdateBy(SecurityUtils.getCurrentUsername());
wareHouseCode.setUpdateDate(new Date());
codeManager.save(wareHouseCode);
return ResultBean.newOkResult("");
}
@ApiOperation("删除库别信息")
@DeleteMapping
@AnonymousAccess
private ResultBean deleteWareHouseCodeById(@RequestBody Set<String> ids){
List<WareHouseCode> codes = new ArrayList<>();
for (String id : ids) {
if (id == null) {
return ResultBean.newErrorResult(-1,"smfcore.valueCanotNull","{0}不能为空",new String[]{"ID"} );
}
WareHouseCode wareHouseCode = codeManager.get(id);
if (wareHouseCode == null){
return ResultBean.newErrorResult(-1,"smfcore.valueNotExist","{0}[{1}]不存在",new String[]{"id",id});
}
codes.add(wareHouseCode);
}
for (WareHouseCode code : codes) {
log.info(SecurityUtils.getCurrentUsername()+"删除的信息为:"+ JsonUtil.toJsonStr(code));
codeManager.delete(code);
}
return ResultBean.newOkResult("");
}
@ApiOperation("库别列表")
@GetMapping("/list")
@AnonymousAccess
private PageData getWareHouseCodeList(WareHouseCodeQueryCriteria criteria, Pageable pageable){
Query query = QueryHelp.getQuery(criteria);
PageData<WareHouseCode> codePageData = codeManager.findByPage(query, pageable);
List<WareHouseCodeDto> codeDtos = new ArrayList<>();
List<WareHouseCode> codes = codePageData.getContent();
for (WareHouseCode code : codes) {
WareHouseCodeDto codeDto = codeMapper.toDto(code);
codeDto.setId(code.getId());
codeDtos.add(codeDto);
}
return new PageData(codeDtos,codePageData.getTotalElements());
}
@ApiOperation("获取库别列表下拉")
@RequestMapping("/pullDown")
@AnonymousAccess
private List<String> getWareHouseCodePullDown(String orderNo){
List<WareHouseCode> wareHouseCodes = codeManager.findAll();
List<String> pullDowns = new ArrayList<>();
List<String> warehouseCodes = new ArrayList<>();
if (StringUtils.isNotBlank(orderNo)){
LiteOrder liteOrder = liteOrderManager.findByOrderNo(orderNo);
if (liteOrder != null){
List<LiteOrderItem> orderItems = liteOrderItemManager.findOrderItems(liteOrder.getId());
for (LiteOrderItem orderItem : orderItems) {
if (StringUtils.isNotBlank(orderItem.getWarehouseCode())){
if (!warehouseCodes.contains(orderItem.getWarehouseCode())) {
warehouseCodes.add(orderItem.getWarehouseCode());
}
}
}
}
}
for (WareHouseCode wareHouseCode : wareHouseCodes) {
String code = wareHouseCode.getWareHouseCode();
if (warehouseCodes != null && !warehouseCodes.isEmpty()){
if (warehouseCodes.contains(code)) {
pullDowns.add(code);
}
} else {
pullDowns.add(code);
}
}
return pullDowns;
}
}
package com.neotel.smfcore.custom.lizhen.agvBox.rest;
import com.google.common.collect.Lists;
import com.neotel.smfcore.common.bean.ReelLockPosInfo;
import com.neotel.smfcore.common.bean.ResultBean;
import com.neotel.smfcore.common.exception.ValidateException;
import com.neotel.smfcore.common.utils.JsonUtil;
import com.neotel.smfcore.common.utils.ReelLockPosUtil;
import com.neotel.smfcore.common.utils.SecurityUtils;
import com.neotel.smfcore.common.utils.StringUtils;
import com.neotel.smfcore.core.api.SmfApi;
import com.neotel.smfcore.core.barcode.bean.CodeBean;
import com.neotel.smfcore.core.barcode.service.manager.IBarcodeManager;
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.service.manager.ILiteOrderItemManager;
import com.neotel.smfcore.core.order.service.manager.ILiteOrderManager;
import com.neotel.smfcore.core.order.service.po.LiteOrder;
import com.neotel.smfcore.core.order.service.po.LiteOrderItem;
import com.neotel.smfcore.core.storage.enums.DeviceType;
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.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.LizhenApi;
import com.neotel.smfcore.custom.lizhen.agvBox.bean.Station;
import com.neotel.smfcore.custom.lizhen.agvBox.util.StationCacheUtil;
import com.neotel.smfcore.security.annotation.AnonymousAccess;
import com.sun.org.apache.regexp.internal.RE;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.factory.annotation.Autowired;
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.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
/**
* 外仓操作
*/
@Slf4j
@RestController
public class WarehouseController {
@Autowired
private IBarcodeManager barcodeManager;
@Autowired
private CodeResolve codeResolve;
@Autowired
private IStoragePosManager storagePosManager;
@Autowired
private TaskService taskService;
@Autowired
private IDataLogManager dataLogManager;
@Autowired
private DataCache dataCache;
@Autowired
private LizhenApi lizhenApi;
@Autowired
private SmfApi smfApi;
@Autowired
private LiteOrderCache liteOrderCache;
@Autowired
private ILiteOrderManager liteOrderManager;
@Autowired
private ILiteOrderItemManager liteOrderItemManager;
private static Map<String,Map<String,Integer>> boxALlCountMap = new ConcurrentHashMap<>();
private static Map<String,Integer> boxCount = new ConcurrentHashMap<>();
@ApiOperation("选择物料")
@RequestMapping("/chooseReel")
@AnonymousAccess
public ResultBean chooseReel(@RequestBody Map<String, String> paramMap) {
String size = paramMap.get("size"); //尺寸 "7X8"
String num = paramMap.get("num"); //数量
String name = paramMap.get("name"); //工位名称
log.info("{}:收到选择物料信息,尺寸为:{},数量为:{}", name, size, num);
if (StringUtils.isBlank(size) || StringUtils.isBlank(num) || StringUtils.isBlank(name)) {
return ResultBean.newErrorResult(-1, "", "请核实尺寸,数量,工位名称是否为空", new String[]{});
}
String grLabel = paramMap.get("grLabel"); //GR标签
if (StringUtils.isNotBlank(grLabel)) {
CodeBean codeBean = codeResolve.resolveSingleCode(grLabel);
if (codeBean.isValid()) {
int grNum = lizhenApi.fetchGR(codeBean.getBarcode());
}
}
int platsize = getPlatsizeOrHeight(size, 0);
int height = getPlatsizeOrHeight(size, 1);
Station station = StationCacheUtil.getStation(name);
if (station == null) {
station = new Station();
}
station.setPlatsize(platsize);
station.setHeight(height);
station.setName(name);
station.setGrLabel(grLabel);
station.setReelNum(Integer.valueOf(num));
station.setReelCurrentNum(0);
station.setLastScanBoxCode(null);
station.setBoxCurrentNum(0);
StationCacheUtil.updateStation(station);
return ResultBean.newOkResult("");
}
@ApiOperation("呼叫空箱")
@RequestMapping("/callEmptyBox")
@AnonymousAccess
public ResultBean callEmptyBox(@RequestBody Map<String, String> paramMap) {
String platsize = paramMap.get("size"); //尺寸
String name = paramMap.get("name"); //工位名称
log.info("{}:收到呼叫空箱信息,尺寸为:{}", name, platsize);
if (StringUtils.isBlank(platsize)) {
return ResultBean.newErrorResult(-1, "", "尺寸不能为空", new String[]{});
}
StoragePos pos = getEmptyBoxPos(platsize);
if (pos == null) {
return ResultBean.newErrorResult(-1, "", "未找到可用料箱", new String[]{});
}
generateTask(dataCache.getStorageById(pos.getStorageId()), pos.getBarcode(), pos, OP.CHECKOUT, OP_STATUS.WAIT.name(), name);
return ResultBean.newOkResult("");
}
@ApiOperation("获取工位详情")
@RequestMapping("/getStation")
@AnonymousAccess
public ResultBean getStation(@RequestBody Map<String, String> paramMap) {
String name = paramMap.get("name");
Station station = StationCacheUtil.getStation(name);
if (station == null) {
return ResultBean.newErrorResult(-1, "", name + "工位不存在", new String[]{});
}
return ResultBean.newOkResult(station);
}
@ApiOperation("扫码入库")
@RequestMapping(value = "/operatePos")
@AnonymousAccess
//先扫条码 再扫料箱
public ResultBean operatePos(@RequestBody Map<String, String> paramMap) {
String name = paramMap.get("name"); //工位名称
String code = paramMap.get("code"); //条码
Station station = StationCacheUtil.getStation(name);
if (station == null) {
return ResultBean.newErrorResult(-1, "", name + "工位不存在", new String[]{});
}
//条码信息
String barcodeStr = "";
if (code.startsWith("C") && code.indexOf("-") != -1) {
station.setLastScanBoxCode(code); //设置扫描的隔口信息
barcodeStr = code.substring(0, code.indexOf("-"));
} else {
barcodeStr = code;
}
log.info("收到物料信息,条码为:{},工位为:{}", code, name);
String currentRfid = station.getCurrentRfid(); //当前料箱的信息
if (StringUtils.isBlank(currentRfid)) {
return ResultBean.newErrorResult(-1, "", "料箱不存在", new String[]{});
}
//先判断是否料盒
String newCodeStr = "=" + station.getPlatsize() + "x" + station.getHeight() + "=" + barcodeStr;
CodeBean codeBean = codeResolve.resolveSingleCode(newCodeStr);
if (!codeBean.isValid()) {
return ResultBean.newErrorResult(-1, "", code + "解析条码失败", new String[]{});
}
Barcode barcode = codeBean.getBarcode();
String partNumber = barcode.getPartNumber();
//如果是箱子的话 则取下边的
if (partNumber.equals("CS") || partNumber.equals("CM") || partNumber.equals("CB")) {
if (!currentRfid.startsWith(barcode.getBarcode())) {
return ResultBean.newErrorResult(-1, "", "料箱" + currentRfid + "与料箱隔口码" + barcode.getBarcode() + "不一致", new String[]{});
}
//判断当前是否有正在执行的任务
DataLog dataLog = getExecuteTask(barcode.getBarcode());
if (dataLog != null) {
if (dataLog.isPutInTask()) {
//已有入库任务
return ResultBean.newErrorResult(-1, "", "物料[" + dataLog.getBarcode() + "]已有入库任务,需继续执行入库动作", new String[]{});
} else if (dataLog.isCheckOutTask()) {
//已有出库任务
return ResultBean.newErrorResult(-1, "", "物料[" + dataLog.getBarcode() + "]已有出库任务,需继续执行出库动作", new String[]{});
}
}
//判断料箱是否在库位中
StoragePos pos = storagePosManager.getByBarcode(barcode.getBarcode());
if (pos != null) {
return ResultBean.newErrorResult(-1, "", "料箱" + barcode.getBarcode() + "已存在库位" + pos.getPosName());
}
barcodeManager.save(barcode);
} else {
String lastScanBoxCode = station.getLastScanBoxCode();
if (Strings.isBlank(lastScanBoxCode)) {
//提示要先扫料箱
return ResultBean.newErrorResult(-1, "", "请先扫描料箱,再扫描条码");
}
Barcode barcodeApi = smfApi.barcodeInfo(barcode);
if (barcodeApi != null) {
barcode = barcodeApi;
}
//判断是否已经在其他料箱中
Query q = new Query();
q.addCriteria(Criteria.where("subCodeList.barcode").is(barcode.getBarcode()));
List<Barcode> barcodes = barcodeManager.findByQuery(q);
if (barcodes != null && !barcodes.isEmpty()) {
return ResultBean.newErrorResult(-1, "", "物料" + barcode.getBarcode() + "已存在料箱:" + barcodes.get(0).getBarcode());
}
int reelCurrentNum = station.getReelCurrentNum();
station.setReelCurrentNum(reelCurrentNum + 1);
String boxBarcode = lastScanBoxCode.substring(0, lastScanBoxCode.indexOf("-")); //获取到料箱条码
Barcode pidBarcode = barcodeManager.findByBarcode(boxBarcode);
barcode.setHostBarcodeId(pidBarcode.getId());
barcode.setPosName(lastScanBoxCode);
barcodeManager.save(barcode);
finishTask(pidBarcode, 1, null, barcode, 1);
}
StationCacheUtil.updateStation(station);
return ResultBean.newOkResult(StationCacheUtil.getStation(name));
}
@ApiOperation("完成装箱并入库")
@RequestMapping("/finishBoxPutIn")
@AnonymousAccess
public ResultBean finishBoxPutIn(@RequestBody Map<String, String> paramMap) {
String code = paramMap.get("barcode"); //料箱条码
String name = paramMap.get("name"); //工位名称
String cids = paramMap.get("cids"); //料仓cid
cids = "so1131";
log.info("完成装箱并入库,条码为:{},工位为:{}", code, name);
//校验是否存在
code = code.replace("A", "").replace("B", "");
Barcode barcode = barcodeManager.findByBarcode(code);
if (barcode == null) {
return ResultBean.newErrorResult(-1, "", code + "料箱不存在", null);
}
Station station = StationCacheUtil.getStation(name);
if (station == null) {
return ResultBean.newErrorResult(-1, "", name + "工位不存在", new String[]{});
}
//校验rfid是否一致
String currentRfid = station.getCurrentRfid();
if (StringUtils.isBlank(currentRfid)) {
return ResultBean.newErrorResult(-1, "", "料箱不存在", new String[]{});
} else if (!currentRfid.startsWith(barcode.getBarcode())) {
return ResultBean.newErrorResult(-1, "", "料箱" + currentRfid + "与" + barcode.getBarcode() + "不一致", new String[]{});
}
//先找可用料仓
if (StringUtils.isBlank(cids)) {
return ResultBean.newErrorResult(-1, "", "料仓不存在", new String[]{});
}
List<Storage> storageList = Lists.newArrayList();
List<String> cidList = Lists.newArrayList();
for (String cid : cids.split(",")) {
String notIntoCids = dataCache.getSettings().getNotIntoCids();
if (notIntoCids != null) {
if (notIntoCids.contains(cid)) {
log.info("料仓[" + cid + "]已被屏蔽入库");
continue;
}
}
Storage storage = dataCache.getStorage(cid);
if (storage != null) {
storageList.add(storage);
cidList.add(cid);
}
}
if (storageList.isEmpty()) {
return ResultBean.newErrorResult(-1, "", "料仓不存在", new String[]{});
}
DataLog dataLog = getExecuteTask(barcode.getBarcode());
if (dataLog != null) {
if (dataLog.isPutInTask()) {
//已有入库任务
return ResultBean.newErrorResult(-1, "", "物料[" + dataLog.getBarcode() + "]已有入库任务,需继续执行入库动作", new String[]{});
} else if (dataLog.isCheckOutTask()) {
//已有出库任务
return ResultBean.newErrorResult(-1, "", "物料[" + dataLog.getBarcode() + "]已有出库任务,需继续执行出库动作", new String[]{});
}
}
//开始寻找空箱
StoragePos pos = taskService.findEmptyPosForPutIn(storageList, barcode, "", "");
if (pos == null) {
throw new ValidateException("", "[" + barcode.getBarcode() + "]未找到可用的[" + barcode.getPlateSize() + "x" + barcode.getHeight() + "]仓位", null);
}
if (pos != null) {
Storage theStorage = dataCache.getStorageById(pos.getStorageId());
ReelLockPosInfo oldLockInfo = ReelLockPosUtil.getLockPosInfoByCode(barcode.getBarcode());
if (oldLockInfo != null) {
if (!oldLockInfo.getBarcode().equals(barcode.getBarcode())) {
ReelLockPosUtil.removeReelLockPosInfo(oldLockInfo.getBarcode());
log.info("清理锁定库位:库位号[" + oldLockInfo.getLockPosName() + "]上物料[" + oldLockInfo.getBarcode() + "]锁定的库位");
}
}
ReelLockPosInfo reelLocInfo = new ReelLockPosInfo();
reelLocInfo.setBarcode(barcode.getBarcode());
reelLocInfo.setCid(theStorage.getCid());
reelLocInfo.setLockPosName(pos.getPosName());
reelLocInfo.setLockPosId(pos.getId());
reelLocInfo = ReelLockPosUtil.addReelLockPosInfo(reelLocInfo, cidList);
if (reelLocInfo == null) {
return ResultBean.newErrorResult(-1, "", "[" + barcode.getBarcode() + "]库位[" + reelLocInfo.getLockPosName() + "]已被锁定,暂停入库", new String[]{});
}
}
//生成任务
generateTask(dataCache.getStorageById(pos.getStorageId()), barcode, pos, OP.PUT_IN, OP_STATUS.WAIT.name(), null);
//同时清空lastScanBoxCode
station.setLastScanBoxCode(null);
StationCacheUtil.saveBoxToBoxCode(station);
String boxStr = currentRfid.replaceAll("A","").replaceAll("B","");
if (boxALlCountMap.get(boxStr) != null){
boxALlCountMap.remove(boxStr);
}
if (boxCount.get(boxStr) != null){
boxCount.remove(boxStr);
}
return ResultBean.newOkResult(station);
}
@ApiOperation("出库页面展示")
@RequestMapping("/outIndex")
@AnonymousAccess
public ResultBean outIndex(@RequestBody Map<String, String> paramMap) {
String name = paramMap.get("name"); //工位名称
String barcodeStr = paramMap.get("barcode"); //隔扣码
Station station = StationCacheUtil.getStation(name);
if (station == null) {
return ResultBean.newErrorResult(-1, "", name + "工位不存在", new String[]{});
}
//判断当前工位是否有料箱
String currentRfid = station.getCurrentRfid();
if (StringUtils.isBlank(currentRfid)) {
return ResultBean.newErrorResult(-1, "", "料箱不存在", new String[]{});
}
String boxStr = currentRfid.replaceAll("A","").replaceAll("B","");
//处理要出库的物料
if (StringUtils.isNotBlank(barcodeStr)) {
CodeBean codeBean = codeResolve.resolveSingleCode(barcodeStr);
if (!codeBean.isValid()) {
return ResultBean.newErrorResult(-1, "", barcodeStr + "解析条码失败", new String[]{});
}
String code = codeBean.getBarcode().getBarcode();
if (code.startsWith("CS") || code.startsWith("CM") || code.startsWith("CB")) {
return ResultBean.newErrorResult(-1, "", "请扫描物料条码");
}
Barcode barcode = barcodeManager.findByBarcode(codeBean.getBarcode().getBarcode());
if (barcode == null) {
return ResultBean.newErrorResult(-1, "", barcodeStr + "未找到对应得物料");
}
Barcode barcodeApi = smfApi.canPutInAfterResolve(barcode);
if (barcodeApi != null) {
barcode = barcodeApi;
}
//判断扫描的料号与正在执行的是否一致
Collection<String> executePartNumbers = liteOrderCache.executePartNumber();
if (executePartNumbers != null && !executePartNumbers.isEmpty()) {
if (!executePartNumbers.contains(barcode.getPartNumber())) {
return ResultBean.newErrorResult(-1, "", "当前物料不在允许出库");
}
}
String posName = barcode.getPosName();
Map<String, Integer> boxCountMap = boxALlCountMap.get(boxStr);
if (boxCountMap == null) {
return ResultBean.newErrorResult(-1, "", "当前料箱没有要出库的物料");
}
if (StringUtils.isBlank(posName) || !posName.startsWith(boxStr)){
return ResultBean.newErrorResult(-1,"",barcode.getBarcode()+"不在料箱"+boxStr);
}
int count = boxCountMap.get(posName);
if (count == 0) {
return ResultBean.newErrorResult(-1, "", posName + "没有出库任务");
}
//得到正在执行的工单
String orderId = null;
Collection<LiteOrderItem> items = liteOrderCache.executeItems();
for (LiteOrderItem item : items) {
String pn = item.getPn();
if (pn.equals(barcode.getPartNumber()) && posName.equals(item.getPosName())) {
DataLog executeTask = getExecuteTask(item.getRi());
if (executeTask == null) {
if (item.getTotalOutNum() != item.getNeedNum()) {
item.setRi(barcode.getBarcode());
orderId = item.getOrderId();
liteOrderItemManager.save(item);
break;
}
}
}
}
if (StringUtils.isNotBlank(orderId)){
LiteOrder liteOrder = liteOrderManager.get(orderId);
List<LiteOrderItem> orderItems = liteOrderItemManager.findOrderItems(orderId);
liteOrder.setOrderItems(orderItems);
liteOrder = liteOrderManager.createWithItems(liteOrder);
liteOrderCache.addOrderToMap(liteOrder);
}
//生成出库任务
Barcode pidBarcode = barcodeManager.findByBarcode(boxStr);
finishTask(pidBarcode, OP.CHECKOUT, null, barcode, 1);
}
//获取料箱中的物料信息
Barcode pidBarcode = barcodeManager.findByBarcode(boxStr);
if (pidBarcode == null){
return ResultBean.newErrorResult(-1,"",boxStr+"未找到物料信息");
}
List<Barcode> subCodeList = pidBarcode.getSubCodeList();
//需要出库的数量
Map<String,Integer> boxCountMap = new HashMap<>();
boxCountMap.put(boxStr+"-1",0);
boxCountMap.put(boxStr+"-2",0);
boxCountMap.put(boxStr+"-3",0);
boxCountMap.put(boxStr+"-4",0);
boxCountMap.put(boxStr+"-5",0);
boxCountMap.put(boxStr+"-6",0);
boxCountMap.put(boxStr+"-7",0);
boxCountMap.put(boxStr+"-8",0);
//得到正在执行的工单数据
List<LiteOrderItem> orderItems = new ArrayList<>();
Collection<LiteOrderItem> liteOrderItems = liteOrderCache.executeItems();
for (LiteOrderItem liteOrderItem : liteOrderItems) {
if (liteOrderItem.getNeedNum() != liteOrderItem.getTotalOutNum()){
orderItems.add(liteOrderItem);
}
}
if (orderItems != null && !orderItems.isEmpty()){
Map<String, Long> boxCount = orderItems.stream().collect(Collectors.groupingBy(LiteOrderItem::getPosName, Collectors.counting()));
for (Map.Entry<String, Long> countEntry : boxCount.entrySet()) {
if (countEntry.getValue() != null) {
boxCountMap.put(countEntry.getKey(),countEntry.getValue().intValue());
}
}
}
if (boxALlCountMap.get(boxStr) != null){
boxALlCountMap.remove(boxStr);
}
boxALlCountMap.put(boxStr,boxCountMap);
//料箱总数量
if (boxCount.get(boxStr) == null) {
boxCount.put(boxStr, subCodeList.size());
}
//判断是否全部出库
Map<String, Long> subCountMap = subCodeList.stream().collect(Collectors.groupingBy(Barcode::getPosName, Collectors.counting()));
for (Map.Entry<String, Long> countMap : subCountMap.entrySet()) {
String posName = countMap.getKey();
int count = boxCountMap.get(posName);
if (count != 0 && count == countMap.getValue()) {
boxCountMap.put(posName, -1);
}
}
List<Integer> boxPartitionCounts = new ArrayList<>();
if (currentRfid.endsWith("A")) {
boxPartitionCounts.add(boxCountMap.get(boxStr + "-8"));
boxPartitionCounts.add(boxCountMap.get(boxStr + "-7"));
boxPartitionCounts.add(boxCountMap.get(boxStr + "-6"));
boxPartitionCounts.add(boxCountMap.get(boxStr + "-5"));
boxPartitionCounts.add(boxCountMap.get(boxStr + "-1"));
boxPartitionCounts.add(boxCountMap.get(boxStr + "-2"));
boxPartitionCounts.add(boxCountMap.get(boxStr + "-3"));
boxPartitionCounts.add(boxCountMap.get(boxStr + "-4"));
} else if (currentRfid.endsWith("B")) {
boxPartitionCounts.add(boxCountMap.get(boxStr + "-4"));
boxPartitionCounts.add(boxCountMap.get(boxStr + "-3"));
boxPartitionCounts.add(boxCountMap.get(boxStr + "-2"));
boxPartitionCounts.add(boxCountMap.get(boxStr + "-1"));
boxPartitionCounts.add(boxCountMap.get(boxStr + "-5"));
boxPartitionCounts.add(boxCountMap.get(boxStr + "-6"));
boxPartitionCounts.add(boxCountMap.get(boxStr + "-7"));
boxPartitionCounts.add(boxCountMap.get(boxStr + "-8"));
}
Map<String,Object> resultMap = new HashMap<>();
resultMap.put("boxPartitionCounts",boxPartitionCounts); //展示数量
resultMap.put("boxAllCount", boxCount.get(boxStr)); //料箱总数量
resultMap.put("boxRemainingCount", subCodeList.size()); //剩余数量
resultMap.put("box", currentRfid);//箱子号
return ResultBean.newOkResult(resultMap);
/*String currentRfid = station.getCurrentRfid();
if (barcodeStr.startsWith("CS") || barcodeStr.startsWith("CB") || barcodeStr.startsWith("CM")) {
if (barcodeStr.indexOf("-") != -1) {
station.setLastScanBoxCode(barcodeStr);
barcodeStr = barcodeStr.substring(0, barcodeStr.indexOf("-"));
}
if (StringUtils.isBlank(currentRfid)) {
return ResultBean.newErrorResult(-1, "", "料箱不存在", new String[]{});
} else if (!currentRfid.startsWith(barcodeStr)) {
return ResultBean.newErrorResult(-1, "", "料箱" + currentRfid + "与" + barcodeStr + "不一致", new String[]{});
}
} else {
String lastScanBoxCode = station.getLastScanBoxCode();
if (Strings.isBlank(lastScanBoxCode)) {
//提示要先扫料箱
return ResultBean.newErrorResult(-1, "", "请先扫描料箱,再扫描条码");
}
CodeBean codeBean = codeResolve.resolveSingleCode(barcodeStr);
if (!codeBean.isValid()) {
return ResultBean.newErrorResult(-1, "", barcodeStr + "解析条码失败", new String[]{});
}
Barcode barcode = barcodeManager.findByBarcode(codeBean.getBarcode().getBarcode());
if (barcode == null) {
return ResultBean.newErrorResult(-1, "", barcodeStr + "未找到对应得物料");
}
Barcode barcodeApi = smfApi.canPutInAfterResolve(barcode);
if (barcodeApi != null){
barcode = barcodeApi;
}
if (!lastScanBoxCode.equals(barcode.getPosName())) {
return ResultBean.newErrorResult(-1, "", barcodeStr + "存在库位:" + barcode.getPosName());
}
//生成出库任务
Barcode pidBarcode = barcodeManager.findByBarcode(lastScanBoxCode.substring(0, lastScanBoxCode.indexOf("-")));
barcode.setAmount(0);
finishTask(pidBarcode, OP.CHECKOUT, null, barcode, 1);
}
String boxStr = currentRfid.replaceAll("A", "").replaceAll("B", "");
Barcode pidBarcode = barcodeManager.findByBarcode(boxStr);
//获取到箱子里物料信息
List<Barcode> subCodeList = pidBarcode.getSubCodeList();
Map<String, Object> resultMap = new HashMap<>();
resultMap.put(boxStr + "-1", 0l);
resultMap.put(boxStr + "-2", 0l);
resultMap.put(boxStr + "-3", 0l);
resultMap.put(boxStr + "-4", 0l);
resultMap.put(boxStr + "-5", 0l);
resultMap.put(boxStr + "-6", 0l);
resultMap.put(boxStr + "-7", 0l);
resultMap.put(boxStr + "-8", 0l);
resultMap.put("boxAllCount", 0);
resultMap.put("boxRemainingCount", 0);
resultMap.put("box", currentRfid);
Collection<String> excludeBarcodes = liteOrderCache.excludeBarcodeIds();
for (Barcode subBarcode : subCodeList) {
if (excludeBarcodes != null && !excludeBarcodes.isEmpty()) {
boolean contains = excludeBarcodes.contains(subBarcode.getBarcode());
if (contains) {
DataLog task = null;
List<DataLog> allTasks = taskService.getAllTasks();
for (DataLog dataLog : allTasks) {
if (dataLog.getBarcode().equals(subBarcode.getBarcode())) {
task = dataLog;
break;
}
}
if (task == null) {
long count = (long) resultMap.get(subBarcode.getPosName());
if (count != 0) {
resultMap.put(subBarcode.getPosName(), count + 1);
} else {
resultMap.put(subBarcode.getPosName(), 1l);
}
}
}
}
}
if (subCodeList != null && !subCodeList.isEmpty()) {
if (boxCount.get(boxStr) == null) {
boxCount.put(boxStr, subCodeList.size());
}
resultMap.put("boxAllCount", boxCount.get(boxStr)); //料箱总数量
resultMap.put("boxRemainingCount", subCodeList.size()); //剩余数量
Map<String, Long> subCountMap = subCodeList.stream().collect(Collectors.groupingBy(Barcode::getPosName, Collectors.counting()));
for (Map.Entry<String, Long> countMap : subCountMap.entrySet()) {
String posName = countMap.getKey();
long count = (long) resultMap.get(posName);
if (count != 0 && count == countMap.getValue()) {
resultMap.put(posName, -1);
}
}
}
List<Object> boxPartitionCounts = new ArrayList<>();
if (currentRfid.endsWith("A")) {
boxPartitionCounts.add(resultMap.get(boxStr + "-8"));
boxPartitionCounts.add(resultMap.get(boxStr + "-7"));
boxPartitionCounts.add(resultMap.get(boxStr + "-6"));
boxPartitionCounts.add(resultMap.get(boxStr + "-5"));
boxPartitionCounts.add(resultMap.get(boxStr + "-1"));
boxPartitionCounts.add(resultMap.get(boxStr + "-2"));
boxPartitionCounts.add(resultMap.get(boxStr + "-3"));
boxPartitionCounts.add(resultMap.get(boxStr + "-4"));
} else if (currentRfid.endsWith("B")) {
boxPartitionCounts.add(resultMap.get(boxStr + "-4"));
boxPartitionCounts.add(resultMap.get(boxStr + "-3"));
boxPartitionCounts.add(resultMap.get(boxStr + "-2"));
boxPartitionCounts.add(resultMap.get(boxStr + "-1"));
boxPartitionCounts.add(resultMap.get(boxStr + "-5"));
boxPartitionCounts.add(resultMap.get(boxStr + "-6"));
boxPartitionCounts.add(resultMap.get(boxStr + "-7"));
boxPartitionCounts.add(resultMap.get(boxStr + "-8"));
}
resultMap.put("boxPartitionCounts",boxPartitionCounts);
return ResultBean.newOkResult(resultMap);*/
}
@ApiOperation("已全部完成装箱")
@RequestMapping("/finishPutIn")
public ResultBean finishPutIn(@RequestBody Map<String, String> paramMap) {
String name = paramMap.get("name");
Station station = StationCacheUtil.getStation(name);
if (station == null) {
return ResultBean.newErrorResult(-1, "", name + "工位不存在", new String[]{});
}
station.setReelCurrentNum(0);
station.setLastScanBoxCode(null);
station.setBoxCurrentNum(0);
station.setCurrentRfid(null);
station.setReelNum(0);
station.setBoxNum(0);
StationCacheUtil.updateStation(station);
return ResultBean.newOkResult(station);
}
private void generateTask(Storage storage, Barcode barcode, StoragePos pos, int type, String status, String loc) {
//开始入库任务
DataLog task = new DataLog(storage, barcode, pos);
task.setType(type);
task.setStatus(status);
task.setLoc(loc);
taskService.updateQueueTask(task);
}
/**
* 完成出入库任务
*
* @param pidBarcode 料箱
* @param currentTask 当前任务
* @param subBarcode 箱内物料
* @param opQty 数量
* @throws ValidateException
*/
private void finishTask(Barcode pidBarcode, int opType, DataLog currentTask, Barcode subBarcode, int opQty) throws ValidateException {
int subAmout = subBarcode.getAmount();
//更新pidBarcode的数量
int amount = pidBarcode.getAmount();
if (opType == OP.PUT_IN) {
pidBarcode.setAmount(amount + opQty);
} else {
pidBarcode.setAmount(amount - opQty);
subBarcode.setAmount(0);
}
//更新barcode缓存
pidBarcode.UpdateSubCode(subBarcode);
barcodeManager.saveBarcode(pidBarcode);
DataLog task = null;
//先查看是否有相同类型且库位相同的任务
if (currentTask != null) {
Collection<DataLog> queueTasks = taskService.getQueueTasks();
for (DataLog queueTask : queueTasks) {
if (queueTask.getType() == currentTask.getType()) {
if (queueTask.getPosName().equals(pidBarcode.getBarcode())) {
task = queueTask;
break;
}
}
}
}
if (task == null) {
task = new DataLog();
}
task.setStatus(OP_STATUS.FINISHED.name());
task.setPartNumber(subBarcode.getPartNumber());
task.setBarcode(subBarcode.getBarcode());
task.setNum(subAmout);
task.setType(opType);
task.setPosName(pidBarcode.getBarcode());
task.setOperator(SecurityUtils.getLoginUsername());
String orderNo = liteOrderCache.executeOrderByBarcode(subBarcode.getBarcode());
if (StringUtils.isNotBlank(orderNo)){
task.setSourceName(orderNo);
LiteOrder liteOrder = liteOrderCache.getOrderSortItems(orderNo);
for (LiteOrderItem orderItem : liteOrder.getOrderItems()) {
if (orderItem.getRi().equals(subBarcode.getBarcode())){
if (!orderItem.isOutFinished()){
task.setSubSourceId(orderItem.getId());
break;
}
}
}
}
task = dataLogManager.save(task);
taskService.updateFinishedTask(task);
if (opType == OP.CHECKOUT && subBarcode.getAmount() <= 0) {
//数量为0直接删除
barcodeManager.delete(subBarcode);
}
}
private int getPlatsizeOrHeight(String size, int index) {
return Integer.valueOf(size.split("X")[index]);
}
private StoragePos getEmptyBoxPos(String platsize) {
//得到料盒类型
String boxCode = "";
if ("7".equals(platsize)) {
boxCode = "CS";
} else if ("13".equals(platsize)) {
boxCode = "CM";
} else if ("15".equals(platsize)) {
boxCode = "CB";
}
//料仓类型是agv的
String storageId = "";
Collection<Storage> storages = dataCache.getAllStorage().values();
for (Storage storage : storages) {
if (storage.isType(new DeviceType[]{DeviceType.AGV_BOX})) {
storageId = storage.getId();
}
}
Criteria c = Criteria.where("barcode").exists(true)
.and("enabled").is(true);//可用
//排除掉正在执行的仓位
Collection<String> excludePosIds = taskService.excludePosIds();
log.info("excludePosIds--" + JsonUtil.toJsonStr(excludePosIds));
if (excludePosIds != null && !excludePosIds.isEmpty()) {
c.and("id").nin(excludePosIds);
}
if (StringUtils.isNotBlank(storageId)) {
c.and("storageId").is(storageId);
}
if (StringUtils.isNotBlank(boxCode)) {
Pattern pattern = Pattern.compile("^.*" + boxCode + ".*$", Pattern.CASE_INSENSITIVE);
c.and("barcode.barcode").regex(pattern);
}
Query q = new Query(c).with(Sort.by(Sort.Direction.ASC, "barcode.amount")).limit(1);
List<StoragePos> storagePoss = storagePosManager.findByQuery(q);
if (storagePoss != null && !storagePoss.isEmpty()) {
return storagePoss.get(0);
}
return null;
}
private DataLog getExecuteTask(String barcode) {
List<DataLog> allTasks = taskService.getAllTasks();
for (DataLog dataLog : allTasks) {
if (dataLog.getBarcode().equals(barcode)) {
if (!dataLog.isCancel() && !dataLog.isFinished()) {
return dataLog;
}
}
}
return null;
}
/**
* 根据料箱编号获取到所有物料
*
* @param boxBarcode
* @return
*/
private List<Barcode> getAllBarcodeByBox(String boxBarcode) {
Query query = new Query();
Pattern pattern = Pattern.compile("^" + boxBarcode + ".*$", Pattern.CASE_INSENSITIVE);
Criteria criteria = Criteria.where("posName").regex(pattern);
return barcodeManager.findByQuery(query.addCriteria(criteria));
}
}
package com.neotel.smfcore.custom.lizhen.agvBox.service.dao;
import com.neotel.smfcore.common.base.IBaseDao;
public interface GrLabelDao extends IBaseDao {
}
package com.neotel.smfcore.custom.lizhen.agvBox.service.dao;
import com.neotel.smfcore.common.base.IBaseDao;
public interface WareHouseCodeDao extends IBaseDao {
}
package com.neotel.smfcore.custom.lizhen.agvBox.service.dao.impl;
import com.neotel.smfcore.common.base.AbstractBaseDao;
import com.neotel.smfcore.custom.lizhen.agvBox.bean.GrLabel;
import com.neotel.smfcore.custom.lizhen.agvBox.service.dao.GrLabelDao;
import org.springframework.stereotype.Service;
@Service
public class GrLabelDaoImpl extends AbstractBaseDao implements GrLabelDao {
@Override
public Class getEntityClass() {
return GrLabel.class;
}
}
package com.neotel.smfcore.custom.lizhen.agvBox.service.dao.impl;
import com.neotel.smfcore.common.base.AbstractBaseDao;
import com.neotel.smfcore.custom.lizhen.agvBox.bean.GrLabel;
import com.neotel.smfcore.custom.lizhen.agvBox.bean.WareHouseCode;
import com.neotel.smfcore.custom.lizhen.agvBox.service.dao.GrLabelDao;
import com.neotel.smfcore.custom.lizhen.agvBox.service.dao.WareHouseCodeDao;
import org.springframework.stereotype.Service;
@Service
public class WareHouseCodeDaoImpl extends AbstractBaseDao implements WareHouseCodeDao {
@Override
public Class getEntityClass() {
return WareHouseCode.class;
}
}
package com.neotel.smfcore.custom.lizhen.agvBox.service.manager;
import com.neotel.smfcore.common.base.IBaseManager;
import com.neotel.smfcore.core.barcode.service.po.Barcode;
import com.neotel.smfcore.custom.lizhen.agvBox.bean.GrLabel;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
import java.util.Set;
public interface GrLabelManager extends IBaseManager<GrLabel> {
GrLabel findLabelBylabelId(String labelId,String labelItem);
}
package com.neotel.smfcore.custom.lizhen.agvBox.service.manager;
import com.neotel.smfcore.common.base.IBaseManager;
import com.neotel.smfcore.core.equipment.service.po.Equipment;
import com.neotel.smfcore.custom.lizhen.agvBox.bean.WareHouseCode;
import java.util.List;
public interface WareHouseCodeManager extends IBaseManager<WareHouseCode> {
List<WareHouseCode> findAll();
}
package com.neotel.smfcore.custom.lizhen.agvBox.service.manager.impl;
import com.google.common.base.Strings;
import com.neotel.smfcore.common.bean.PageData;
import com.neotel.smfcore.common.exception.ValidateException;
import com.neotel.smfcore.common.utils.DateUtil;
import com.neotel.smfcore.common.utils.FileUtil;
import com.neotel.smfcore.core.barcode.service.dao.IBarcodeDao;
import com.neotel.smfcore.core.barcode.service.manager.IBarcodeManager;
import com.neotel.smfcore.core.barcode.service.manager.IComponentManager;
import com.neotel.smfcore.core.barcode.service.po.Barcode;
import com.neotel.smfcore.core.barcode.service.po.Component;
import com.neotel.smfcore.custom.lizhen.agvBox.bean.GrLabel;
import com.neotel.smfcore.custom.lizhen.agvBox.service.dao.GrLabelDao;
import com.neotel.smfcore.custom.lizhen.agvBox.service.manager.GrLabelManager;
import lombok.extern.slf4j.Slf4j;
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 javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;
@Slf4j
@Service
public class GrLabelManagerImpl implements GrLabelManager {
@Autowired
private GrLabelDao grLabelDao;
@Override
public GrLabel get(String id) {
return null;
}
@Override
public GrLabel save(GrLabel object) throws ValidateException {
return grLabelDao.save(object);
}
@Override
public void delete(GrLabel object) throws ValidateException {
}
@Override
public PageData<GrLabel> findByPage(Query query, Pageable pageable) {
return null;
}
@Override
public List<GrLabel> findByQuery(Query query) {
return null;
}
public GrLabel findLabelBylabelId(String labelId,String labelItem){
return grLabelDao.findOne(new Query(Criteria.where("labelId").is(labelId).and("labelItem").is(labelItem)));
}
}
package com.neotel.smfcore.custom.lizhen.agvBox.service.manager.impl;
import com.neotel.smfcore.common.bean.PageData;
import com.neotel.smfcore.common.exception.ValidateException;
import com.neotel.smfcore.core.barcode.service.po.Barcode;
import com.neotel.smfcore.custom.lizhen.agvBox.bean.WareHouseCode;
import com.neotel.smfcore.custom.lizhen.agvBox.service.dao.WareHouseCodeDao;
import com.neotel.smfcore.custom.lizhen.agvBox.service.manager.WareHouseCodeManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class WareHouseCodeManagerImpl implements WareHouseCodeManager {
@Autowired
private WareHouseCodeDao codeDao;
@Override
public WareHouseCode get(String id) {
return codeDao.findOneById(id);
}
@Override
public WareHouseCode save(WareHouseCode object) throws ValidateException {
return codeDao.save(object);
}
@Override
public void delete(WareHouseCode object) throws ValidateException {
codeDao.removeOne(object);
}
@Override
public PageData<WareHouseCode> findByPage(Query query, Pageable pageable) {
int totalCount = codeDao.countByQuery(query);
List<WareHouseCode> wareHouseCodes= codeDao.findByQuery(query,pageable);
return new PageData(wareHouseCodes,totalCount);
}
@Override
public List<WareHouseCode> findByQuery(Query query) {
return null;
}
@Override
public List<WareHouseCode> findAll() {
return codeDao.findAll();
}
}
package com.neotel.smfcore.custom.lizhen.innerBox.bean;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@Getter
@Setter
@NoArgsConstructor
public class OutLotInfo {
/**
* 出口位置
*/
private String outlet = "";
/**
* 料仓cid
*/
private String cid = "";
/**
* 当前料箱号
*/
private String rfid = "";
/**
* 靠近rfid已放数量
*/
private int boxTCount = 0;
/**
* 不靠近rfid已放数量
*/
private int boxBCount = 0;
/**
* 工单序号
*/
private String hSerial = "";
/**
* 目的地(线体)
*/
private String line = "";
/**
* 当前料仓剩余未出的需求单数量
*/
private int remainTaskCount = 0;
/**
* 所属需求单剩余料架任务数
*/
private int rackTaskCount = 0;
}
......@@ -26,6 +26,12 @@ public class PreWarningItem {
private String slot;
private String subslot;
private String partnumber;
private String id;
/**
* 优先级,1:人工 0:机器
*/
private int priority = 0;
/**
* 接收时间
......
package com.neotel.smfcore.custom.lizhen.innerBox.rest;
import com.neotel.smfcore.common.bean.ResultBean;
import com.neotel.smfcore.common.utils.JsonUtil;
import com.neotel.smfcore.common.utils.QueryHelp;
import com.neotel.smfcore.common.utils.ReelLockPosUtil;
import com.neotel.smfcore.common.utils.StringUtils;
import com.neotel.smfcore.core.barcode.bean.CodeBean;
import com.neotel.smfcore.core.barcode.service.manager.IBarcodeManager;
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;
......@@ -11,17 +17,24 @@ import com.neotel.smfcore.core.order.service.manager.ILiteOrderItemManager;
import com.neotel.smfcore.core.order.service.manager.ILiteOrderManager;
import com.neotel.smfcore.core.order.service.po.LiteOrder;
import com.neotel.smfcore.core.order.service.po.LiteOrderItem;
import com.neotel.smfcore.core.storage.enums.DeviceType;
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.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.OutLotInfo;
import com.neotel.smfcore.custom.lizhen.innerBox.util.OutLotInfoCache;
import com.neotel.smfcore.security.annotation.AnonymousAccess;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
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.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
......@@ -60,7 +73,17 @@ public class InnerBoxRestController {
@Autowired
private LiteOrderCache liteOrderCache;
private static List<String> finishPrint = new ArrayList<>();
@Autowired
private CodeResolve codeResolve;
@Autowired
private IDataLogManager dataLogManager;
//料架缓存id
private static String labelOrderItemId;
//人工发料id
private static String manualOrderItemId;
@ApiOperation("IA 出库更新任务状态")
@RequestMapping("/updateLocInfo")
......@@ -70,16 +93,21 @@ public class InnerBoxRestController {
String status = request.getParameter("status");
String loc = request.getParameter("loc");
String cid = request.getParameter("cid");
log.info("IA 出库更新任务状态--barcode:{},status:{},loc:{}", code, status, loc);
String hSerial = request.getParameter("hSerial"); //工单序号
String outlet = request.getParameter("outlet"); //出口位置
String boxSide = request.getParameter("boxSide"); //料箱隔口
log.info("IA 出库更新任务状态--barcode:{},status:{},loc:{},hSerial:{},outlet:{},boxSide:{}", code, status, loc, hSerial, outlet, boxSide);
//获取到当前执行的任务
DataLog opTask = null;
Collection<DataLog> allTasks = taskService.getAllTasks();
//log.info("所有任务为:"+ JSON.toJSONString(allTasks));
for (DataLog task : allTasks) {
if (code.startsWith(task.getBarcode())) {
if (!task.isCancel()) {
if (!task.isCancel() && !task.isFinished()) {
opTask = task;
break;
}
break;
}
}
if (opTask == null) {
......@@ -111,23 +139,68 @@ public class InnerBoxRestController {
//已完成,从完成缓存中清除
taskService.removeFinishedTask(opTask);
//移除打印的标签
finishPrint.remove(code);
//清理锁定库位
ReelLockPosUtil.removeReelLockPosInfo(code);
//物料与箱子绑定
Barcode barcode = barcodeManager.findByBarcode(code);
if (barcode != null) {
barcode.setPosName(loc);
barcodeManager.save(barcode);
}
//料箱与需求单进行绑定
String boxNumber = loc.replaceAll("A","").replaceAll("B","");
LiteOrder liteOrder = liteOrderManager.get(opTask.getSourceId());
if (liteOrder != null) {
liteOrder.setBoxNumber(boxNumber);
liteOrderManager.save(liteOrder);
liteOrderCache.addOrderToMap(liteOrder);
//如果工单号不为空时,则修改出口状态缓存
if (StringUtils.isNotBlank(hSerial)) {
List<OutLotInfo> outLotInfos = OutLotInfoCache.getOutLotInfoByCid(cid);
List<OutLotInfo> newOutLotInfos = new ArrayList<>();
boolean hasOutLot = false;
if (outLotInfos != null && !outLotInfos.isEmpty()) {
for (OutLotInfo outLotInfo : outLotInfos) {
if (outLotInfo.getOutlet().equals(outlet)) {
hasOutLot = true;
if (outLotInfo.getRfid().startsWith(loc)) {
if ("T".equals(boxSide)) {
int boxTCount = outLotInfo.getBoxTCount();
outLotInfo.setBoxTCount(boxTCount + 1);
} else if ("B".equals(boxSide)) {
int boxBCount = outLotInfo.getBoxBCount();
outLotInfo.setBoxBCount(boxBCount + 1);
}
} else {
outLotInfo = new OutLotInfo();
if (liteOrder != null) {
outLotInfo.setLine(liteOrder.getLine());
outLotInfo.setOutlet(outlet);
outLotInfo.setCid(cid);
if ("T".equals(boxSide)) {
int boxTCount = outLotInfo.getBoxTCount();
outLotInfo.setBoxTCount(boxTCount + 1);
} else if ("B".equals(boxSide)) {
int boxBCount = outLotInfo.getBoxBCount();
outLotInfo.setBoxBCount(boxBCount + 1);
}
outLotInfo.setHSerial(hSerial);
outLotInfo.setRfid(loc);
}
}
}
newOutLotInfos.add(outLotInfo);
}
}
if (!hasOutLot) {
OutLotInfo outLotInfo = new OutLotInfo();
if (liteOrder != null) {
outLotInfo.setLine(liteOrder.getLine());
outLotInfo.setOutlet(outlet);
outLotInfo.setCid(cid);
if ("T".equals(boxSide)) {
int boxTCount = outLotInfo.getBoxTCount();
outLotInfo.setBoxTCount(boxTCount + 1);
} else if ("B".equals(boxSide)) {
int boxBCount = outLotInfo.getBoxBCount();
outLotInfo.setBoxBCount(boxBCount + 1);
}
outLotInfo.setHSerial(hSerial);
outLotInfo.setRfid(loc);
}
newOutLotInfos.add(outLotInfo);
}
OutLotInfoCache.updateOutLotInfo(cid, newOutLotInfos);
}
}
}
......@@ -137,8 +210,16 @@ public class InnerBoxRestController {
}
//得到当前料箱状态
Map<String, Object> resultMap = getBoxStatusByBoxNumber(loc, cid);
return ResultBean.newOkResult(resultMap);
OutLotInfo outLotInfo = null;
try {
if (StringUtils.isNotBlank(loc)) {
outLotInfo = getOutLotInfoByRfid(loc, cid);
}
} catch (Exception e) {
log.error(loc + "异常");
e.printStackTrace();
}
return ResultBean.newOkResult(outLotInfo);
}
......@@ -149,57 +230,34 @@ public class InnerBoxRestController {
String rfid = request.getParameter("rfid"); //料箱RFID
String cid = request.getParameter("cid");
//得到当前料箱状态
Map<String, Object> resultMap = getBoxStatusByBoxNumber(rfid, cid);
Map<String, Object> resultMap = new HashMap<>();
try {
rfid = rfid.replaceAll("A", "").replaceAll("B", "");
resultMap = getBoxStatusByBoxNumber(rfid, cid);
} catch (Exception e) {
log.error(rfid + "异常");
e.printStackTrace();
}
return ResultBean.newOkResult(resultMap);
}
@ApiOperation("IC 获取料架标签打印信息")
@ApiOperation("IC 获取料架标签打印信息 或者 补打印信息")
@RequestMapping("/rack/getPrintInfo")
@AnonymousAccess
public List<Map<String, String>> getPrintLabel(HttpServletRequest request) {
Collection<DataLog> dataLogs = taskService.getAllTasks();
List<Map<String, String>> results = new ArrayList<>();
for (DataLog dataLog : dataLogs) {
String barcode = dataLog.getBarcode();
if (finishPrint != null && !finishPrint.isEmpty()) {
if (finishPrint.contains(barcode)) {
continue;
}
}
if (!dataLog.isFinished() && !dataLog.isCancel()) {
String orderId = dataLog.getSourceId();
LiteOrder liteOrder = liteOrderManager.get(orderId);
if (liteOrder != null) {
String orderItemId = dataLog.getSubSourceId();
LiteOrderItem liteOrderItem = liteOrderItemManager.get(orderItemId);
if (liteOrderItem != null) {
Map<String, String> resultMap = new HashMap<>();
resultMap.put("barcode", dataLog.getBarcode());
resultMap.put("pn", dataLog.getPartNumber());
resultMap.put("station", liteOrderItem.getTableNo());
resultMap.put("side", liteOrderItem.getSide());
resultMap.put("hSerial", liteOrder.getOrderNo());
results.add(resultMap);
}
}
}
public ResultBean rackPrintLabel(HttpServletRequest request) {
Map<String, String> resultMap = getPrintLabel(labelOrderItemId);
if (resultMap.isEmpty()) {
return ResultBean.newErrorResult(-1, "", "未找到需要打印的标签信息");
}
return results;
return ResultBean.newOkResult(resultMap);
}
@ApiOperation("ID 料架标签打印完成通知")
@ApiOperation("ID 料架标签打印完成通知 或 补打印完成通知")
@RequestMapping("/rack/finishPrint")
@AnonymousAccess
public ResultBean finishPrintLabel(HttpServletRequest request) {
String barcode = request.getParameter("barcode");
Collection<DataLog> dataLogs = taskService.getQueueTasks();
for (DataLog dataLog : dataLogs) {
if (!dataLog.isCancel() && !dataLog.isFinished()) {
if (dataLog.getBarcode().equals(barcode)) {
finishPrint.add(barcode);
}
}
}
log.info("移除打印标签");
setLabelOrderItemId(null);
return ResultBean.newOkResult("");
}
......@@ -221,6 +279,9 @@ public class InnerBoxRestController {
resultMap.put("station", liteOrderItem.getTableNo());
resultMap.put("side", liteOrderItem.getSide());
resultMap.put("hSerial", liteOrder.getOrderNo());
resultMap.put("line", liteOrder.getLine());
resultMap.put("slot", liteOrderItem.getSlot());
resultMap.put("subSlot", liteOrderItem.getSubSlot());
}
break;
}
......@@ -235,7 +296,8 @@ public class InnerBoxRestController {
public ResultBean boxTakeAway(HttpServletRequest request) {
String rfid = request.getParameter("rfid");
rfid = rfid.replaceAll("A", "").replaceAll("B", "");
Pattern pattern = Pattern.compile("^" + rfid + ".*$", Pattern.CASE_INSENSITIVE);
log.info(rfid + "小车已经拉走");
Pattern pattern = Pattern.compile(QueryHelp.escapeExprSpecialWord(rfid), Pattern.CASE_INSENSITIVE);
List<LiteOrder> liteOrders = liteOrderManager.findByQuery(new Query(Criteria.where("boxNumber").regex(pattern)));
if (liteOrders != null && !liteOrders.isEmpty()) {
for (LiteOrder liteOrder : liteOrders) {
......@@ -244,9 +306,241 @@ public class InnerBoxRestController {
liteOrderCache.addOrderToMap(liteOrder);
}
}
//同时清除物料与料箱的信息
List<Barcode> barcodes = barcodeManager.findByQuery(new Query(Criteria.where("posName").regex(pattern)));
if (barcodes != null && !barcodes.isEmpty()) {
for (Barcode barcode : barcodes) {
barcode.setPosName(null);
barcodeManager.save(barcode);
}
}
return ResultBean.newOkResult("");
}
@ApiOperation("获取当前执行的工单,是否全部都是料架信息")
@RequestMapping("/getNlOutInfo")
@AnonymousAccess
public ResultBean getNlOutInfo() {
//获取到当前正在执行的工单
Collection<DataLog> queueTasks = taskService.getQueueTasks();
boolean isAllNlOut = false;
DataLog dataLog = null;
Map<String, Object> resultMap = new HashMap<>();
for (DataLog task : queueTasks) {
String orderId = task.getSubSourceId();
if (!task.isCancel() && !task.isFinished() && task.isCheckOutTask() && StringUtils.isNotBlank(orderId)) {
String cid = task.getCid();
Storage storage = dataCache.getStorage(cid);
if (storage.isType(new DeviceType[]{DeviceType.SMD_XLR})) {
isAllNlOut = true;
break;
} else {
dataLog = task;
}
}
}
if (dataLog == null) {
return ResultBean.newErrorResult(-1, "", "没有要出的料架任务");
}
if (!isAllNlOut && dataLog != null) {
String orderId = dataLog.getSourceId();
LiteOrder liteOrder = liteOrderManager.get(orderId);
resultMap.put("line", liteOrder.getLine());
}
//如果没有产线,则返回错误
if (resultMap.get("line") == null) {
return ResultBean.newErrorResult(-1, "", "料仓与料架都有出库任务");
}
return ResultBean.newOkResult(resultMap);
}
@ApiOperation("根据料仓编号获取料仓两个出料口料箱信息")
@RequestMapping("/getOutStateInfo")
@AnonymousAccess
public ResultBean getOutStateInfo(HttpServletRequest request) {
String cid = request.getParameter("cid");
if (StringUtils.isBlank(cid)) {
return ResultBean.newErrorResult(-1, "smfcore.valueCanotNull", "{0}不能为空", new String[]{"cid"});
}
List<OutLotInfo> outLotInfos = OutLotInfoCache.getOutLotInfoByCid(cid);
log.info(cid + "--出料口信息为:" + JsonUtil.toJsonStr(outLotInfos));
return ResultBean.newOkResult(outLotInfos);
}
//料箱送上AGV后,调用此接口,服务器将料口状态信息另存, 把当前料口状态置空
@ApiOperation("料箱送上AGV")
@RequestMapping("/boxToAgv")
@AnonymousAccess
public ResultBean boxToAgv(HttpServletRequest request) {
String outlet = request.getParameter("outlet");
String rfid = request.getParameter("rfid");
String AGVName = request.getParameter("AGVName");
log.info("料箱送上AGV---出口位置为:" + outlet + ",rfid为:" + rfid + ",AGV为:" + AGVName);
OutLotInfoCache.outLotInfoMapToOutInfos(outlet, rfid);
return ResultBean.newOkResult("");
}
@ApiOperation("获取AGV目的地")
@RequestMapping("/getAgvLineInfo")
@AnonymousAccess
public ResultBean getAgvLineInfo(HttpServletRequest request) {
String rfid = request.getParameter("rfid");
OutLotInfo outLotInfo = OutLotInfoCache.getOutLotInfoByRfid(rfid);
log.info("获取AGV目的地---rfid为:" + rfid + ",outLotInfo为:" + JsonUtil.toJsonStr(outLotInfo));
int rackTaskCount = 0;
List<DataLog> allTasks = taskService.getAllTasks();
for (DataLog dataLog : allTasks) {
Storage storage = dataCache.getStorage(dataLog.getCid());
if (storage != null && storage.isNLShelf()) {
if (StringUtils.isNotBlank(dataLog.getSourceName())) {
if (dataLog.getSourceName().equals(outLotInfo.getHSerial())) {
rackTaskCount++;
}
}
}
}
outLotInfo.setRackTaskCount(rackTaskCount);
log.info(rfid + "--AGV目的信息为:" + JsonUtil.toJsonStr(outLotInfo));
return ResultBean.newOkResult(outLotInfo);
}
@ApiOperation("清理料箱信息")
@RequestMapping("/clearRfidInfo")
@AnonymousAccess
public ResultBean clearRfidInfo(HttpServletRequest request) {
String rfid = request.getParameter("rfid");
String source = request.getParameter("source");
log.info("清理料箱信息---rfid为:" + rfid + ",source为:" + source);
OutLotInfoCache.clearRfidInfo(rfid);
return ResultBean.newOkResult("");
}
@ApiOperation("补打印标签信息")
@PostMapping("/fillPrint")
@AnonymousAccess
public ResultBean fillPrint(@RequestBody Map<String, String> paramMap) {
String barcodestr = paramMap.get("barcode");
log.info("补打印标签信息:" + barcodestr);
CodeBean codeBean = codeResolve.resolveSingleCode(barcodestr);
if (!codeBean.isValid()) {
return ResultBean.newErrorResult(-1, "smfcore.error.barcode.invalid", "{0}不是有效的条码", new String[]{barcodestr});
}
//根据唯一码,获取到最近一条出库记录
Barcode barcode = codeBean.getBarcode();
String reelId = barcode.getBarcode();
Query query = new Query();
Criteria criteria = Criteria.where("barcode").is(reelId).and("subSourceId").exists(true).and("type").is(OP.CHECKOUT).and("status").is("FINISHED");
Sort sort = Sort.by(Sort.Direction.DESC, "createDate");//按创建时间排序
List<DataLog> dataLogs = dataLogManager.findByQuery(query.addCriteria(criteria).with(sort).limit(1));
if (dataLogs == null || dataLogs.isEmpty()) {
return ResultBean.newErrorResult(-1, "smfcore.valueNotFind", "未找到{0}{1}", new String[]{reelId,"补打印信息,请核实是否已经有出库任务"});
}
for (DataLog dataLog : dataLogs) {
setLabelOrderItemId(dataLog.getSubSourceId());
break;
}
return ResultBean.newOkResult("");
}
@ApiOperation("手动发料")
@PostMapping("/manualFeeding")
@AnonymousAccess
public ResultBean manualFeeding(@RequestBody Map<String, String> paramMap) {
/*if (StringUtils.isNotBlank(getManualOrderItemId())) {
return ResultBean.newErrorResult(-1,"","上一个物料标签请打印完成后再进行手动发料操作");
}*/
String barcodestr = paramMap.get("barcodestr");
String orderItemId = paramMap.get("orderItemId");
log.info("人工发料--ItemId:"+orderItemId+",barcodestr:"+barcodestr);
if (StringUtils.isBlank(orderItemId)) {
return ResultBean.newErrorResult(-1, "smfcore.valueCanotNull", "{0}不能为空", new String[]{"itemId"});
}
CodeBean codeBean = codeResolve.resolveSingleCode(barcodestr);
if (!codeBean.isValid()) {
return ResultBean.newErrorResult(-1, "smfcore.error.barcode.invalid", "{0}不是有效的条码", new String[]{barcodestr});
}
//判断当前是否已经有出库任务
List<DataLog> allTasks = taskService.getAllTasks();
for (DataLog dataLog : allTasks) {
if (orderItemId.equals(dataLog.getSubSourceId())) {
if (dataLog.isCheckOutTask() && !dataLog.isCancel() && !dataLog.isFinished()) {
return ResultBean.newErrorResult(-1,"smfcore.valueAlreadyExist","{0}[{1}]已存在",new String[]{"出库任务",orderItemId});
}
}
}
LiteOrderItem orderItem = liteOrderItemManager.get(orderItemId);
if (orderItem == null){
return ResultBean.newErrorResult(-1,"smfcore.valueNotExist","{0}[{1}]不存在",new String[]{"工单信息",orderItemId});
}
//判断料号是否一致
String partNumber = codeBean.getBarcode().getPartNumber();
if (!orderItem.getPn().equals(partNumber)) {
return ResultBean.newErrorResult(-1,"","请核实手动补料的料号:"+partNumber+"与工单需求料号:"+orderItem.getPn()+"是否一致");
}
LiteOrder liteOrder = liteOrderManager.get(orderItem.getOrderId());
if (liteOrder == null){
return ResultBean.newErrorResult(-1,"smfcore.valueNotExist","{0}[{1}]不存在",new String[]{"工单信息",orderItemId});
}
//生成一条出库任务
Barcode barcode = codeBean.getBarcode();
DataLog dataLog = new DataLog();
dataLog.setStatus(OP_STATUS.FINISHED.name());
dataLog.setBarcode(barcode.getBarcode());
dataLog.setSourceName(liteOrder.getOrderNo());
dataLog.setSourceId(liteOrder.getId());
dataLog.setSubSourceId(orderItemId);
dataLog.setPartNumber(barcode.getPartNumber());
dataLog.setProviderNumber(barcode.getProviderNumber());
dataLog.setNum(barcode.getAmount());
dataLog.setType(OP.CHECKOUT);
dataLog.setPosName("人工");
taskService.updateFinishedTask(dataLog);
setManualOrderItemId(orderItemId);
return ResultBean.newOkResult("");
}
@ApiOperation("手动补料打印信息")
@RequestMapping("/manual/getPrintInfo")
@AnonymousAccess
public ResultBean manualPrintLabel(HttpServletRequest request) {
Map<String, String> resultMap = getPrintLabel(manualOrderItemId);
if (resultMap.isEmpty()) {
return ResultBean.newErrorResult(-1, "", "未找到需要打印的标签信息");
}
return ResultBean.newOkResult(resultMap);
}
@ApiOperation("手动发料打印完成通知")
@RequestMapping("/manual/finishPrint")
@AnonymousAccess
public ResultBean finishManualPrintLabel(HttpServletRequest request) {
log.info("移除打印标签");
setManualOrderItemId(null);
return ResultBean.newOkResult("");
}
public String getLabelOrderItemId() {
return labelOrderItemId;
}
public void setLabelOrderItemId(String orderItemId) {
labelOrderItemId = orderItemId;
}
/**
* 物料取出
......@@ -285,18 +579,49 @@ public class InnerBoxRestController {
dataCache.updateInventory(storagePos, barcode);
}
private OutLotInfo getOutLotInfoByRfid(String rfid, String cid) {
if (rfid.endsWith("A") || rfid.endsWith("B")) {
rfid = rfid.substring(0, rfid.length() - 1);
}
OutLotInfo outLotInfo = null;
List<OutLotInfo> outLotInfos = OutLotInfoCache.getOutLotInfoByCid(cid);
for (OutLotInfo lotInfo : outLotInfos) {
if (lotInfo.getRfid().contains(rfid)) {
outLotInfo = lotInfo;
break;
}
}
int remainTaskCount = 0;
int rackTaskCount = 0;
if (outLotInfo != null) {
String hSerial = outLotInfo.getHSerial();
List<DataLog> allTasks = taskService.getAllTasks();
for (DataLog dataLog : allTasks) {
Storage storage = dataCache.getStorage(dataLog.getCid());
if (!dataLog.isFinished() && !dataLog.isCancel() && hSerial.equals(dataLog.getSourceName()) && cid.equals(dataLog.getCid()) && !storage.isNLShelf()) {
remainTaskCount++;
} else if (storage != null && storage.isNLShelf()) {
rackTaskCount++;
}
}
outLotInfo.setRemainTaskCount(remainTaskCount);
outLotInfo.setRackTaskCount(rackTaskCount);
}
return outLotInfo;
}
private Map<String, Object> getBoxStatusByBoxNumber(String boxNumber, String cid) {
if (boxNumber.indexOf("-") != -1) {
/*if (boxNumber.indexOf("-") != -1) {
boxNumber = boxNumber.substring(0, boxNumber.indexOf("-"));
}
boxNumber = boxNumber.replaceAll("A", "").replaceAll("B", "");
}*/
//boxNumber = boxNumber.replaceAll("A", "").replaceAll("B", "");
Map<String, Object> resultMap = new HashMap<>();
int remainTaskCount = 0; //所属需求单剩余当前料仓未完成任务数
int rackTaskCount = 0; //所属需求单剩余料架任务数
//当前料箱的隔口数量
resultMap.put("inCount",0);
resultMap.put("outCount",0);
Pattern pattern = Pattern.compile("^" + boxNumber + ".*$", Pattern.CASE_INSENSITIVE);
resultMap.put("inCount", 0);
resultMap.put("outCount", 0);
Pattern pattern = Pattern.compile(QueryHelp.escapeExprSpecialWord(boxNumber), Pattern.CASE_INSENSITIVE);
List<Barcode> barcodes = barcodeManager.findByQuery(new Query(Criteria.where("posName").regex(pattern)));
if (barcodes != null && !barcodes.isEmpty()) {
Map<String, Long> posCountMap = barcodes.stream().collect(Collectors.groupingBy(Barcode::getPosName, Collectors.counting()));
......@@ -311,12 +636,14 @@ public class InnerBoxRestController {
}
//获取当前工单数据
LiteOrder liteOrder = null;
List<LiteOrder> liteOrders = liteOrderManager.findByQuery(new Query(Criteria.where("boxNumber").regex(pattern)));
Criteria c = Criteria.where("boxNumber").is(boxNumber);
Query query = new Query(c);
List<LiteOrder> liteOrders = liteOrderManager.findByQuery(query);
if (liteOrders != null && !liteOrders.isEmpty()) {
liteOrder = liteOrders.get(0);
}
resultMap.put("hSerial","");
resultMap.put("line","");
resultMap.put("hSerial", "");
resultMap.put("line", "");
if (liteOrder != null) {
String line = liteOrder.getLine();
String orderNo = liteOrder.getOrderNo();
......@@ -330,7 +657,7 @@ public class InnerBoxRestController {
if (dataLog.isFinished() || dataLog.isCancel()) {
continue;
}
if (orderItem.getRi().equals(dataLog.getBarcode())) {
if (orderItem.getId().equals(dataLog.getSubSourceId())) {
if (dataLog.getCid().equals(cid)) {
remainTaskCount++;
} else {
......@@ -350,4 +677,31 @@ public class InnerBoxRestController {
return resultMap;
}
public static String getManualOrderItemId() {
return manualOrderItemId;
}
public static void setManualOrderItemId(String orderItemId) {
manualOrderItemId = orderItemId;
}
public Map<String,String> getPrintLabel(String orderItemId){
Map<String, String> resultMap = new HashMap<>();
LiteOrderItem liteOrderItem = liteOrderItemManager.get(labelOrderItemId);
if (liteOrderItem != null) {
String orderId = liteOrderItem.getOrderId();
LiteOrder liteOrder = liteOrderManager.get(orderId);
if (liteOrder != null) {
//resultMap.put("barcode", dataLog.getBarcode());
resultMap.put("pn", liteOrderItem.getPn());
resultMap.put("station", liteOrderItem.getTableNo());
resultMap.put("side", liteOrderItem.getSide());
resultMap.put("hSerial", liteOrder.getOrderNo());
resultMap.put("line", liteOrder.getLine());
resultMap.put("slot", liteOrderItem.getSlot());
resultMap.put("subSlot", liteOrderItem.getSubSlot());
}
}
return resultMap;
}
}
package com.neotel.smfcore.custom.lizhen.innerBox.util;
import com.neotel.smfcore.common.utils.Constants;
import com.neotel.smfcore.common.utils.SecurityUtils;
import com.neotel.smfcore.common.utils.StringUtils;
import com.neotel.smfcore.core.device.util.DataCache;
import com.neotel.smfcore.custom.lizhen.innerBox.bean.OutLotInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
@Slf4j
@Service
public class OutLotInfoCache {
private static DataCache dataCache;
//保存的料口信息缓存
private static Map<String, List<OutLotInfo>> outLotInfoMap = new ConcurrentHashMap<>();
//agv上箱子信息
private static List<OutLotInfo> outLotInfos = new CopyOnWriteArrayList<>();
@PostConstruct
public void getOutLotInfoMap(){
log.info("加载料口信息");
Object lotInfoMap = dataCache.getCache(Constants.CACHE_outLotInfoMap);
if (lotInfoMap != null) {
outLotInfoMap = (Map<String, List<OutLotInfo>>) lotInfoMap;
}
Object lotInfos = dataCache.getCache(Constants.CACHE_outLotInfos);
if (lotInfos != null){
List<OutLotInfo> newOutLotInfos = new ArrayList<>();
outLotInfos = (List<OutLotInfo>) lotInfos;
if (outLotInfos != null && !outLotInfos.isEmpty()){
for (OutLotInfo outLotInfo : outLotInfos) {
if (outLotInfo != null){
newOutLotInfos.add(outLotInfo);
}
}
outLotInfos = newOutLotInfos;
dataCache.updateCache(Constants.CACHE_outLotInfos,outLotInfos);
}
}
}
/**
* 根据cid获取料口状态信息
*
* @param cid
* @return
*/
public static List<OutLotInfo> getOutLotInfoByCid(String cid) {
List<OutLotInfo> outLotInfos = outLotInfoMap.get(cid);
if (outLotInfos == null) {
outLotInfos = new ArrayList<>();
}
return outLotInfos;
}
/**
* 修改缓存信息
* @param cid
* @param outLotInfos
*/
public static synchronized void updateOutLotInfo(String cid, List<OutLotInfo> outLotInfos) {
/* List<OutLotInfo> outLotInfos = outLotInfoMap.get(cid);
List<OutLotInfo> newOutLotInfos = new ArrayList<>();
boolean hasOutLot = false;
if (outLotInfos != null && !outLotInfos.isEmpty()) {
for (OutLotInfo lotInfo : outLotInfos) {
if (outLotInfo.getOutlet().equals(lotInfo.getOutlet())) {
lotInfo = outLotInfo;
hasOutLot = true;
}
newOutLotInfos.add(lotInfo);
}
}
if (!hasOutLot) {
newOutLotInfos.add(outLotInfo);
}*/
outLotInfoMap.put(cid, outLotInfos);
dataCache.updateCache(Constants.CACHE_outLotInfoMap, outLotInfoMap);
}
public static void clearRfidInfo(String rfid) {
if (outLotInfos != null && !outLotInfos.isEmpty()) {
for (OutLotInfo outLotInfo : outLotInfos) {
if (outLotInfo == null){
continue;
}
String lotInfoRfid = outLotInfo.getRfid();
if (StringUtils.isNotBlank(lotInfoRfid)) {
if (lotInfoRfid.startsWith(rfid)) {
outLotInfos.remove(outLotInfo);
break;
}
}
}
}
dataCache.updateCache(Constants.CACHE_outLotInfos,outLotInfos);
}
public static OutLotInfo getOutLotInfoByRfid(String rfid) {
OutLotInfo outLotInfo = new OutLotInfo();
if (outLotInfos != null && !outLotInfos.isEmpty()) {
for (OutLotInfo lotInfo : outLotInfos) {
if (lotInfo == null){
continue;
}
String lotInfoRfid = lotInfo.getRfid();
if (StringUtils.isNotBlank(lotInfoRfid)) {
if (lotInfo.getRfid().startsWith(rfid)) {
outLotInfo = lotInfo;
break;
}
}
}
}
return outLotInfo;
}
public static void outLotInfoMapToOutInfos(String outlet, String rfid) {
OutLotInfo outLotInfo = null;
for (Map.Entry<String, List<OutLotInfo>> outLotInfoEntry : outLotInfoMap.entrySet()) {
List<OutLotInfo> newOutLotInfos = new ArrayList<>();
List<OutLotInfo> outLotInfoValues = outLotInfoEntry.getValue();
for (OutLotInfo outLotInfoValue : outLotInfoValues) {
if (outLotInfoValue.getRfid().startsWith(rfid) /*&& outLotInfoValue.getOutlet().equals(outlet)*/) {
outLotInfo = outLotInfoValue;
} else {
newOutLotInfos.add(outLotInfoValue);
}
}
updateOutLotInfo(outLotInfoEntry.getKey(),newOutLotInfos);
}
boolean hasOutLotInfo = false;
for (OutLotInfo lotInfo : outLotInfos) {
if (lotInfo.getRfid().startsWith(rfid)) {
hasOutLotInfo = true;
break;
}
}
if (!hasOutLotInfo && outLotInfo != null) {
outLotInfos.add(outLotInfo);
}
dataCache.updateCache(Constants.CACHE_outLotInfos,outLotInfos);
}
@Autowired
public void setDataCache(DataCache dataCache){
OutLotInfoCache.dataCache = dataCache;
}
}
......@@ -8,6 +8,7 @@ import com.neotel.smfcore.core.api.SmfApi;
import com.neotel.smfcore.core.barcode.service.po.Barcode;
import com.neotel.smfcore.core.device.util.DataCache;
import com.neotel.smfcore.core.order.LiteOrderCache;
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;
......@@ -46,7 +47,7 @@ import java.util.stream.Collectors;
*/
@Slf4j
@Service
public class PreWarningItemCache {
public class PreWarningItemCache {
/**
* 预警列表缓存
......@@ -65,7 +66,9 @@ public class PreWarningItemCache {
private static SmfApi smfApi;
private static PreWarningItemManager preWarningItemManager;
private static PreWarningItemManager preWarningItemManager;
private static ILiteOrderItemManager liteOrderItemManager;
/**
* 添加到预警列表缓存中
......@@ -78,10 +81,10 @@ public class PreWarningItemCache {
/**
* 从缓存列表中取出预警Item生成工单并执行
*/
private static void generateTask() {
boolean hasIdleBox = false;
private static void generateTask(int priority) {
boolean hasIdleBox = true;
//有料仓空闲下来就需要生成任务,保证料仓不空闲,提高节拍
Collection<Storage> boxList = dataCache.getAllStorage().values();
/*Collection<Storage> boxList = dataCache.getAllStorage().values();
for (Storage storage : boxList) {
if (storage.isStorage(DeviceType.SMD_XLR)) {
Collection<DataLog> boxQueueTasks = taskService.getQueueTasks(storage.getCid());
......@@ -91,7 +94,7 @@ public class PreWarningItemCache {
break;
}
}
}
}*/
if (hasIdleBox) {
//最早的一条预警时间
......@@ -99,6 +102,8 @@ public class PreWarningItemCache {
String firstItemLine = "";
//每次最多出多少盘
int maxReelCount = 30;
int TReelCount = 0;
int BReelCount = 0;
//如果取不到,从数据库中取
if (queueItemList == null || queueItemList.isEmpty()) {
queueItemList = dataCache.getCache(Constants.CACHE_preWarningItem);
......@@ -111,6 +116,8 @@ public class PreWarningItemCache {
if (Strings.isNotBlank(itemLine)) {
if (firstItemLine.isEmpty()) {
firstItemLine = itemLine;
//System.out.println(System.currentTimeMillis());
//System.out.println(preWarningItem.getReceiveDate().getTime());
if (System.currentTimeMillis() - preWarningItem.getReceiveDate().getTime() < 1 * 60 * 1000) {
//不到1分钟,暂不执行
return;
......@@ -120,15 +127,13 @@ public class PreWarningItemCache {
if (itemLine.equals(firstItemLine)) {
lineItems.add(preWarningItem);
}
if (lineItems.size() > maxReelCount) {
if (lineItems.size() >= maxReelCount) {
break;
}
}
}
if (!lineItems.isEmpty()) {
createAndExecuteLiteOrder(lineItems);
//工单生成后,从缓存中清除
updateItem(lineItems, true);
createAndExecuteLiteOrder(lineItems,priority);
}
}
}
......@@ -139,102 +144,37 @@ public class PreWarningItemCache {
*
* @param lineItems
*/
public static LiteOrder createAndExecuteLiteOrder(List<PreWarningItem> lineItems) {
List<String> noPossPosIds = new ArrayList<>();
List<String> outPosIds = new ArrayList<>();
//得到料仓id
String storageId = "";
Collection<Storage> storages = dataCache.getAllStorage().values();
for (Storage storage : storages) {
if (storage.isType(new DeviceType[]{DeviceType.SMD_XLR})) {
storageId = storage.getId();
break;
}
}
//处理线别需求单
public static synchronized LiteOrder createAndExecuteLiteOrder(List<PreWarningItem> lineItems,int priority) {
//1.得到优先级比较高的
LiteOrder liteOrder = new LiteOrder();
liteOrder.setType(2);
//List<PreWarningItem> itemsPri = new ArrayList<>();
if (priority == 1){
lineItems = lineItems.stream().filter(t -> 1 == t.getPriority()).collect(Collectors.toList());
liteOrder.setPriority(1);
} else if (priority == 2){
lineItems = lineItems.stream().filter(t -> 1 != t.getPriority()).collect(Collectors.toList());
liteOrder.setPriority(0);
}
liteOrder.setOrderNo(getSeq());
//liteOrder.setSo(getSeq(2));
//2 如果优先级不为空,则优先生成优先级高的工单
List<LiteOrderItem> orderItems = new ArrayList<>();
for (PreWarningItem item : lineItems) {
liteOrder.setLine(item.getLine());
//创建工单
LiteOrderItem orderItem = new LiteOrderItem();
boolean flag = true;
while (flag) {
String partnumber = item.getPartnumber();
Query q = new Query();
//库位有数据
Criteria c = Criteria.where("barcode").exists(true).and("enabled").is(true);
//相同partNumber
c.and("barcode.partNumber").is(partnumber);
//得到库位
if (StringUtils.isNotBlank(storageId)) {
c.and("storageId").is(storageId);
}
List<String> posIds = new ArrayList<>();
//排除已经执行过的物料barcode
if (outPosIds != null && !outPosIds.isEmpty()) {
posIds.addAll(outPosIds);
}
//排除校验没通过的
if (noPossPosIds != null && !noPossPosIds.isEmpty()) {
posIds.addAll(noPossPosIds);
}
//排除正在执行出库的工位
Collection<String> excludePosIds = taskService.excludePosIds();
if (excludePosIds != null && !excludePosIds.isEmpty()) {
posIds.addAll(excludePosIds);
}
if (posIds != null && !posIds.isEmpty()) {
c.and("id").not().in(posIds);
}
//排除正在执行的工单物料
Collection<String> excludeBarcodeIds = liteOrderCache.excludeBarcodeIds();
if (excludeBarcodeIds != null && !excludeBarcodeIds.isEmpty()) {
c.and("barcode.barcode").nin(excludeBarcodeIds);
}
//然后最早入库的
q.addCriteria(c);
q.with(Sort.by(Sort.Direction.ASC, "canCheckOutTime", "barcode.subCodeList.usedCount")).limit(5);
// log.info(q.toString());
List<StoragePos> storagePoss = storagePosManager.findByQuery(q);
orderItem.setPn(item.getPartnumber());
orderItem.setSide(item.getSide());
orderItem.setFeederInfo(item.getSlot());
if (lineItems != null && !lineItems.isEmpty()) {
for (PreWarningItem item : lineItems) {
liteOrder.setLine(item.getLine());
LiteOrderItem orderItem = new LiteOrderItem();
orderItem.setLine(item.getLine());
orderItem.setWarningItemId(item.getId());
orderItem.setNeedReelCount(1); //需要出库数量是1
orderItem.setNeedNum(1);//设置出库任务为1盘
orderItem.setPn(item.getPartnumber()); //设置pn
orderItem.setSide(item.getSide()); //设置面别
orderItem.setSlot(item.getSlot()); //站位
orderItem.setSubSlot(item.getSubslot());
orderItem.setTableNo(item.getStation());
if (storagePoss == null || storagePoss.isEmpty()) {
orderItem.setRi(item.getPartnumber());
orderItem.setNeedNum(0);
orderItems.add(orderItem);
flag = false;
break;
} else {
for (StoragePos pos : storagePoss) {
Barcode barcode = pos.getBarcode();
try {
Barcode barcodeApi = smfApi.canPutInAfterResolve(barcode);
//String checkResult = ""; //立臻校验时,需要切换
if (barcodeApi != null) {
outPosIds.add(pos.getId()); //防止其他地方出库
orderItem.setRi(barcode.getBarcode());
orderItem.setNeedNum(1);
orderItems.add(orderItem);
flag = false;
break;
} else {
log.info("partNumber:{}校验失败:{}", barcode.getPartNumber());
noPossPosIds.add(pos.getId());
continue;
}
} catch (ValidateException e) {
e.printStackTrace();
}
}
}
orderItem.setOrderNo(liteOrder.getOrderNo());
orderItem.setPriority(item.getPriority());
orderItem.setMachineName(item.getMachinename());
orderItems.add(orderItem);
}
}
if (orderItems != null && !orderItems.isEmpty()) {
......@@ -243,6 +183,8 @@ public class PreWarningItemCache {
liteOrder = liteOrderManager.createWithItems(liteOrder);
liteOrderCache.addOrderToMap(liteOrder);
}
//工单生成后,从缓存中清除
updateItem(lineItems, true);
return liteOrder;
}
......@@ -252,7 +194,43 @@ public class PreWarningItemCache {
queueItemList.remove(item);
}
} else {
queueItemList.addAll(items);
//判断是否已经生成
List<PreWarningItem> newItems = new ArrayList<>();
newItems.addAll(items);
for (int i = 0; i < items.size(); i++) {
PreWarningItem preWarningItem = items.get(i);
if (queueItemList != null && !queueItemList.isEmpty()) {
for (PreWarningItem item : queueItemList) {
if (item.getId().equals(preWarningItem.getId())) {
newItems = newItems.stream().filter(t -> !t.getId().equals(item.getId())).collect(Collectors.toList());
log.info("Mes缺料预警重复物料:" + item.getId() + "PN为:" + item.getPartnumber());
break;
}
}
}
}
//判断工单是否已经出过
for (int i = 0; i < items.size(); i++) {
PreWarningItem item = items.get(i);
Query q = new Query();
Criteria c = Criteria.where("pn").is(item.getPartnumber()).and("warningItemId").is(item.getId());
List<LiteOrderItem> orderItems = liteOrderItemManager.findByQuery(q.addCriteria(c));
/*for (LiteOrderItem orderItem : orderItems) {
if (orderItem.getOutNum() >= orderItem.getNeedNum() || orderItem.getOutReelCount() >= orderItem.getNeedReelCount() || !orderItem.getRi().equals(orderItem.getPn())) {
newItems = newItems.stream().filter(t -> !t.getId().equals(orderItem.getWarningItemId())).collect(Collectors.toList());
log.info("Mes缺料预警已经生成工单:" + item.getId() + "PN为:" + item.getPartnumber());
}
}*/
if (orderItems != null && !orderItems.isEmpty()){
newItems = newItems.stream().filter(t -> !t.getId().equals(item.getId())).collect(Collectors.toList());
log.info("Mes缺料预警已经生成工单:" + item.getId() + "PN为:" + item.getPartnumber());
}
}
if (queueItemList == null || queueItemList.isEmpty()){
queueItemList = newItems;
} else {
queueItemList.addAll(newItems);
}
}
dataCache.updateCache(Constants.CACHE_preWarningItem, queueItemList);
}
......@@ -262,13 +240,13 @@ public class PreWarningItemCache {
/**
* 定时执行,从缓存列表中取出预警Item生成工单并执行
*/
public static void runTimer() {
public static void runTimer(int priority) {
if (processing) {
return;
}
processing = true;
try {
generateTask();
generateTask(priority);
} catch (Exception e) {
log.error("预警缓存定时器出错", e);
} finally {
......@@ -308,11 +286,16 @@ public class PreWarningItemCache {
}
@Autowired
public void setPreWarningItemManager(PreWarningItemManager itemManager){
public void setPreWarningItemManager(PreWarningItemManager itemManager) {
PreWarningItemCache.preWarningItemManager = itemManager;
}
private static String getSeq() {
@Autowired
public void setLiteOrderItemManager(ILiteOrderItemManager itemManager) {
PreWarningItemCache.liteOrderItemManager = itemManager;
}
private synchronized static String getSeq() {
return "H" + preWarningItemManager.getNextId(PreWarningItemCache.class.getName());
}
}
package com.neotel.smfcore.custom.lizhen.report.bean.query;
import com.neotel.smfcore.common.annotation.QueryCondition;
import com.neotel.smfcore.common.bean.BetweenData;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
import java.util.List;
@Data
@ApiModel("查询条件")
public class ReportQueryCondition {
@QueryCondition(blurry = "pn,partNumber")
@ApiModelProperty("料号")
private String pn;
@QueryCondition(propName = "orderNo")
@ApiModelProperty("挑料单号")
private String orderNo;
@QueryCondition(propName = "mo")
@ApiModelProperty("工单号")
private String mo;
@QueryCondition(type = QueryCondition.Type.BETWEEN, propName = "updateDate")
@DateTimeFormat(pattern = "yyyy-MM-dd")
private BetweenData<Date> updateDate;
@QueryCondition
@ApiModelProperty("厂别")
private String plantCode;
@QueryCondition
@ApiModelProperty("库别")
private String warehouse;
@QueryCondition
@ApiModelProperty("唯一码")
private String barcode;
@QueryCondition
@ApiModelProperty("库位")
private String posName;
@QueryCondition
@ApiModelProperty("批次")
private String batch;
@ApiModelProperty("线别")
@QueryCondition(propName = "line")
private String line;
}
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.QueryHelp;
import com.neotel.smfcore.core.device.util.DataCache;
import com.neotel.smfcore.core.order.enums.LITEORDER_STATUS;
import com.neotel.smfcore.core.order.rest.bean.mapstruct.OrderItemMapper;
import com.neotel.smfcore.core.order.rest.bean.mapstruct.OrderMapper;
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.system.util.TaskService;
import com.neotel.smfcore.custom.lizhen.report.bean.query.ReportQueryCondition;
import com.neotel.smfcore.security.annotation.AnonymousAccess;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
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.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.*;
import java.util.stream.Collectors;
@Slf4j
@ApiOperation("内仓报表")
@RequestMapping("/inner/report")
@RestController
public class InnerReportController {
@Autowired
private ILiteOrderManager liteOrderManager;
@Autowired
private ILiteOrderItemManager liteOrderItemManager;
@Autowired
private OrderItemMapper orderItemMapper;
@Autowired
private OrderMapper orderMapper;
@Autowired
private TaskService taskService;
@Autowired
private DataCache dataCache;
@ApiOperation("喂料")
@RequestMapping("/feeding")
@AnonymousAccess
public PageData feeding(ReportQueryCondition queryCondition, Pageable pageable) {
Query q = QueryHelp.getQuery(queryCondition);
//查询不是关闭状态的订单,新建的,尾料已完成的
List<Criteria> orCriterias = new ArrayList<>();
orCriterias.add(Criteria.where("status").is(LITEORDER_STATUS.NEW));
orCriterias.add(Criteria.where("status").is(LITEORDER_STATUS.TAILS_FINISHED));
Criteria c = Criteria.where("closed").is(false).orOperator(orCriterias);
PageData<LiteOrder> pageData = liteOrderManager.findByPage(q.addCriteria(c), pageable);
List<LiteOrder> liteOrders = pageData.getContent();
liteOrders = liteOrders.stream().sorted(Comparator.comparing(LiteOrder :: getPriority).reversed().thenComparing(LiteOrder :: getCreateDate)).collect(Collectors.toList());
PageData resultPageData = new PageData();
resultPageData.setTotalElements(pageData.getTotalElements());
resultPageData.setContent(liteOrders);
return resultPageData;
}
@ApiOperation("根据工单id获取工单详情")
@RequestMapping("/getItemsByOrderId")
@AnonymousAccess
public ResultBean getItemsByOrderId(String orderId){
LiteOrder liteOrder = liteOrderManager.get(orderId);
List<LiteOrderItem> orderItems = liteOrderItemManager.findOrderItems(orderId);
if (LITEORDER_STATUS.TAILS_FINISHED == liteOrder.getStatus()){
List<LiteOrderItem> newOrderItems = new ArrayList<>();
for (LiteOrderItem orderItem : orderItems) {
if (orderItem.getOutNum() == 0) {
orderItem.setLack(true);
newOrderItems.add(orderItem);
}
}
orderItems = newOrderItems;
}
//根据缺料排序
orderItems = orderItems.stream().sorted(Comparator.comparing(LiteOrderItem :: isLack).reversed()).collect(Collectors.toList());
return ResultBean.newOkResult(orderItemMapper.toDto(orderItems));
}
@ApiOperation("线别下拉")
@RequestMapping("linePullDown")
@AnonymousAccess
public ResultBean linePullDown() {
//得到每一个楼层的线体
String f2Line = dataCache.getCache("F2Line").toString();
String f3Line = dataCache.getCache("F3Line").toString();
String f5Line = dataCache.getCache("F5Line").toString();
Map<String, String> resultMap = new LinkedHashMap<>();
for (String line : f2Line.split(",")) {
resultMap.put(line,line);
}
for (String line : f3Line.split(",")) {
resultMap.put(line,line);
}
for (String line : f5Line.split(",")) {
resultMap.put(line,line);
}
return ResultBean.newOkResult(resultMap);
}
}
package com.neotel.smfcore.custom.lizhen.report.outer;
import com.google.common.collect.Lists;
import com.neotel.smfcore.common.bean.PageData;
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.core.barcode.rest.bean.dto.BarcodeDto;
import com.neotel.smfcore.core.barcode.service.manager.IBarcodeManager;
import com.neotel.smfcore.core.barcode.service.po.Barcode;
import com.neotel.smfcore.core.order.rest.bean.dto.OrderItemDto;
import com.neotel.smfcore.core.order.rest.bean.mapstruct.OrderItemMapper;
import com.neotel.smfcore.core.order.service.manager.ILiteOrderItemManager;
import com.neotel.smfcore.core.order.service.po.LiteOrderItem;
import com.neotel.smfcore.core.storage.rest.dto.StoragePosDto;
import com.neotel.smfcore.core.storage.rest.mapstruct.StoragePosMapper;
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.core.system.service.po.DataLog;
import com.neotel.smfcore.custom.lizhen.report.bean.query.ReportQueryCondition;
import com.neotel.smfcore.security.annotation.AnonymousAccess;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.bson.Document;
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.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;
@Slf4j
@ApiOperation("报表")
@RestController
@RequestMapping("/outer/report")
public class OuterReportController {
@Autowired
private ILiteOrderItemManager liteOrderItemManager;
@Autowired
private OrderItemMapper orderItemMapper;
@Autowired
private IDataLogManager dataLogManager;
@Autowired
private IBarcodeManager barcodeManager;
@Autowired
private IStoragePosManager storagePosManager;
@Autowired
private StoragePosMapper storagePosMapper;
@ApiOperation("发料明细")
@RequestMapping("/pickingDetail")
@AnonymousAccess
public PageData pickingDetail(ReportQueryCondition queryCondition, Pageable pageable) {
Query query = QueryHelp.getQuery(queryCondition);
//subSourceId存的是itemId
Criteria criteria = Criteria.where("subSourceId").exists(true);
PageData<DataLog> pageData = new PageData<>();
if (pageable != null) {
pageData = dataLogManager.findByPage(query.addCriteria(criteria), pageable);
} else {
int totalElements = 0;
List<DataLog> dataLogs = dataLogManager.findByQuery(query.addCriteria(criteria));
if (dataLogs != null && !dataLogs.isEmpty()) {
totalElements = dataLogs.size();
}
pageData.setTotalElements(totalElements);
pageData.setContent(dataLogs);
}
return pageData;
}
@ApiOperation("发料明细导出")
@RequestMapping("/pickingDetail/download")
@AnonymousAccess
public void pickingDetailDownLoad(ReportQueryCondition queryCondition, Pageable pageable, HttpServletResponse response) {
PageData pageData = pickingDetail(queryCondition, null);
List<DataLog> contents = pageData.getContent();
if (contents != null && !contents.isEmpty()) {
List<Map<String, Object>> results = new ArrayList<>();
for (DataLog dataLog : contents) {
Map<String, Object> resultMap = new LinkedHashMap<>();
resultMap.put("楼层", dataLog.getLine());
resultMap.put("挑料单号", dataLog.getOrderNo());
resultMap.put("工单号", dataLog.getMo());
resultMap.put("料号", dataLog.getPartNumber());
resultMap.put("物料描述", "");
resultMap.put("储位", dataLog.getPosName());
resultMap.put("段别", dataLog.getSide());
resultMap.put("数量", dataLog.getNum());
resultMap.put("库别", dataLog.getWarehouseCode());
resultMap.put("储位厂区", dataLog.getPlantCode());
resultMap.put("异动类型", dataLog.getSourceName());
resultMap.put("姓名", dataLog.getOperator());
resultMap.put("时间", dataLog.getCreateDate());
resultMap.put("ID No", dataLog.getBarcode());
resultMap.put("D/C", dataLog.getDateCode());
resultMap.put("L/C", dataLog.getBatchInfo());
resultMap.put("厂商代码", dataLog.getProviderNumber());
resultMap.put("厂商", dataLog.getProvider());
results.add(resultMap);
}
try {
FileUtil.downloadExcel(results, response);
} catch (IOException e) {
e.printStackTrace();
log.info("发料明细导出失败--" + e.getMessage());
}
}
}
@ApiOperation("缺料")
@RequestMapping("/lackPicking")
@AnonymousAccess
public PageData lackPicking(ReportQueryCondition queryCondition, Pageable pageable) {
Query query = QueryHelp.getQuery(queryCondition);
//缺失数量条件
Criteria lackNumCri = new Criteria() {
@Override
public Document getCriteriaObject() {
Document document = new Document();
document.put("$where", "this.outNum < this.needNum");
return document;
}
};
//缺失料盘条件
Criteria lackReelCri = new Criteria() {
@Override
public Document getCriteriaObject() {
Document document = new Document();
document.put("$where", "this.outReelCount < this.needReelCount");
return document;
}
};
List<Criteria> orCriterialList = Lists.newArrayList();
orCriterialList.add(lackNumCri);
orCriterialList.add(lackReelCri);
query.addCriteria(new Criteria().orOperator(orCriterialList));
int totalElements = 0;
List<LiteOrderItem> orderItemList = liteOrderItemManager.findByQuery(query);
if (orderItemList != null && !orderItemList.isEmpty()) {
totalElements = orderItemList.size();
}
if (pageable != null) {
query.with(pageable);
}
List<LiteOrderItem> orderItems = liteOrderItemManager.findByQuery(query);
List<OrderItemDto> itemDtos = new ArrayList<>();
if (orderItems != null && !orderItems.isEmpty()) {
for (LiteOrderItem orderItem : orderItems) {
OrderItemDto itemDto = orderItemMapper.toDto(orderItem);
itemDto.setLackNum(itemDto.getNeedNum() - itemDto.getOutNum());
itemDto.setLackReel(itemDto.getNeedReelCount() - itemDto.getOutReelCount());
itemDtos.add(itemDto);
}
}
PageData pageData = new PageData();
pageData.setContent(itemDtos);
pageData.setTotalElements(totalElements);
return pageData;
}
@ApiOperation("缺料导出")
@RequestMapping("/lackPicking/download")
@AnonymousAccess
public void lackPickingDownload(ReportQueryCondition queryCondition, Pageable pageable,HttpServletResponse response) {
PageData pageData = lackPicking(queryCondition, null);
List<OrderItemDto> orderItemDtos = pageData.getContent();
if (orderItemDtos != null && !orderItemDtos.isEmpty()) {
List<Map<String, Object>> results = new ArrayList<>();
for (OrderItemDto orderItemDto : orderItemDtos) {
Map<String, Object> resultMap = new LinkedHashMap<>();
resultMap.put("厂别", orderItemDto.getPlantCode());
resultMap.put("楼层", orderItemDto.getLine());
resultMap.put("Picking ID", orderItemDto.getOrderNo());
resultMap.put("工单号", orderItemDto.getMo());
resultMap.put("料号", orderItemDto.getPn());
resultMap.put("物料描述", "");
resultMap.put("库别", orderItemDto.getWarehouseCode());
resultMap.put("需求数", orderItemDto.getNeedNum());
resultMap.put("发料数", orderItemDto.getOutNum());
resultMap.put("需求卷", orderItemDto.getNeedReelCount());
resultMap.put("实发卷", orderItemDto.getOutReelCount());
resultMap.put("实发卷", orderItemDto.getOutReelCount());
resultMap.put("实发卷", orderItemDto.getOutReelCount());
resultMap.put("累计实发数", orderItemDto.getTotalOutNum());
resultMap.put("累计实发卷数", orderItemDto.getTotalOutReelCount());
resultMap.put("缺料数量", orderItemDto.getLackNum());
resultMap.put("缺料卷数", orderItemDto.getLackReel());
results.add(resultMap);
}
try {
FileUtil.downloadExcel(results, response);
} catch (IOException e) {
e.printStackTrace();
log.info("缺料明细导出失败--" + e.getMessage());
}
}
}
@ApiOperation("备料清单")
@RequestMapping("/preparePicking")
@AnonymousAccess
public PageData preparePicking(ReportQueryCondition queryCondition, Pageable pageable) {
Query query = QueryHelp.getQuery(queryCondition);
PageData pageData = new PageData();
if (pageable != null) {
pageData = liteOrderItemManager.findByPage(query, pageable);
} else {
int totalElements = 0;
List<LiteOrderItem> orderItems = liteOrderItemManager.findByQuery(query);
if (orderItems != null && !orderItems.isEmpty()){
totalElements = orderItems.size();
}
pageData.setTotalElements(totalElements);
pageData.setContent(orderItems);
}
List<OrderItemDto> dtos = new ArrayList<>();
List<LiteOrderItem> orderItems = pageData.getContent();
if (orderItems != null && !orderItems.isEmpty()) {
for (LiteOrderItem orderItem : orderItems) {
OrderItemDto orderItemDto = orderItemMapper.toDto(orderItem);
int excessOutNum = getExcessOutNum(orderItem); //超发数量
int excessOutReel = getExcessOutReel(orderItem); //超发卷数
orderItemDto.setExcessOutNum(excessOutNum);
orderItemDto.setExcessOutReel(excessOutReel);
dtos.add(orderItemDto);
}
}
PageData resultPageData = new PageData();
resultPageData.setTotalElements(pageData.getTotalElements());
resultPageData.setContent(dtos);
return resultPageData;
}
@ApiOperation("备料清单导出")
@RequestMapping("/preparePicking/download")
@AnonymousAccess
public void preparePickingDownload(ReportQueryCondition queryCondition, Pageable pageable, HttpServletResponse response) {
PageData pageData = preparePicking(queryCondition, null);
List<OrderItemDto> orderItemDtos = pageData.getContent();
if (orderItemDtos != null && !orderItemDtos.isEmpty()) {
List<Map<String, Object>> results = new ArrayList<>();
for (OrderItemDto orderItemDto : orderItemDtos) {
Map<String, Object> resultMap = new LinkedHashMap<>();
resultMap.put("楼层",orderItemDto.getLine());
resultMap.put("挑料单号",orderItemDto.getOrderNo());
resultMap.put("工单号",orderItemDto.getMo());
resultMap.put("料号",orderItemDto.getPn());
resultMap.put("描述","");
resultMap.put("储位","");
resultMap.put("库别",orderItemDto.getWarehouseCode());
resultMap.put("需求数",orderItemDto.getNeedNum());
resultMap.put("需求卷",orderItemDto.getNeedReelCount());
resultMap.put("实发数",orderItemDto.getOutNum());
resultMap.put("实发卷",orderItemDto.getOutReelCount());
resultMap.put("累计实发数",orderItemDto.getTotalOutNum());
resultMap.put("累计实发卷数",orderItemDto.getTotalOutReelCount());
resultMap.put("段别",orderItemDto.getSide());
resultMap.put("超发数量",orderItemDto.getExcessOutNum());
resultMap.put("超发卷数",orderItemDto.getExcessOutReel());
results.add(resultMap);
}
try {
FileUtil.downloadExcel(results, response);
} catch (IOException e) {
e.printStackTrace();
log.info("备料清单导出失败--" + e.getMessage());
}
}
}
@ApiOperation("PK查询")
@RequestMapping("/pickingSearch")
@AnonymousAccess
public PageData pickingSearch(ReportQueryCondition queryCondition,Pageable pageable){
Query query = QueryHelp.getQuery(queryCondition);
if (pageable != null) {
query.with(pageable);
}
List<LiteOrderItem> orderItems = liteOrderItemManager.findByQuery(query);
int totalElements = 0;
if (orderItems != null && !orderItems.isEmpty()){
totalElements = orderItems.size();
}
PageData pageData = new PageData();
pageData.setTotalElements(totalElements);
pageData.setContent(orderItemMapper.toDto(orderItems));
return pageData;
}
@ApiOperation("PK查询导出")
@RequestMapping("/pickingSearch/download")
@AnonymousAccess
public void pickingSearchDownload(ReportQueryCondition queryCondition, Pageable pageable, HttpServletResponse response) {
PageData pageData = pickingSearch(queryCondition, null);
List<OrderItemDto> orderItemDtos = pageData.getContent();
if (orderItemDtos != null && !orderItemDtos.isEmpty()) {
List<Map<String, Object>> results = new ArrayList<>();
for (OrderItemDto orderItemDto : orderItemDtos) {
Map<String, Object> resultMap = new LinkedHashMap<>();
resultMap.put("厂别",orderItemDto.getPlantCode());
resultMap.put("楼层",orderItemDto.getLine());
resultMap.put("PK ID",orderItemDto.getOrderNo());
resultMap.put("工单号",orderItemDto.getMo());
resultMap.put("料号",orderItemDto.getPn());
resultMap.put("套数",orderItemDto.getNeedReelCount());
results.add(resultMap);
}
try {
FileUtil.downloadExcel(results, response);
} catch (IOException e) {
e.printStackTrace();
log.info("PK查询导出失败--" + e.getMessage());
}
}
}
@ApiOperation("异动")
@RequestMapping("/change")
@AnonymousAccess
public PageData change(ReportQueryCondition queryCondition, Pageable pageable) {
Query query = QueryHelp.getQuery(queryCondition);
PageData<DataLog> pageData = new PageData<>();
if (pageable != null){
pageData = dataLogManager.findByPage(query, pageable);
} else {
int totalElements = 0;
List<DataLog> dataLogs = dataLogManager.findByQuery(query);
if (dataLogs != null && !dataLogs.isEmpty()){
totalElements = dataLogs.size();
}
pageData.setTotalElements(totalElements);
pageData.setContent(dataLogs);
}
//单独对隔口数量进行
List<DataLog> dataLogs = pageData.getContent();
if (dataLogs != null && !dataLogs.isEmpty()) {
List<String> posNames = dataLogs.stream().filter(dataLog -> StringUtils.isNotBlank(dataLog.getPosName())).map(DataLog::getPosName).collect(Collectors.toList());
List<Barcode> barcodes = barcodeManager.findByQuery(new Query(Criteria.where("posName").in(posNames)));
if (barcodes != null && !barcodes.isEmpty()) {
Map<String, Long> countMap = barcodes.stream().collect(Collectors.groupingBy(Barcode::getPosName, Collectors.counting()));
for (DataLog dataLog : dataLogs) {
String posName = dataLog.getPosName();
if (StringUtils.isNotBlank(posName) && countMap.get(posName) != null){
dataLog.setPartitionCount(countMap.get(posName).intValue());
}
}
}
}
pageData.setContent(dataLogs);
return pageData;
}
@ApiOperation("异动导出")
@RequestMapping("/change/download")
@AnonymousAccess
public void changeDownload(ReportQueryCondition queryCondition, Pageable pageable, HttpServletResponse response) {
PageData pageData = change(queryCondition, null);
List<DataLog> dataLogs = pageData.getContent();
if (dataLogs != null && !dataLogs.isEmpty()) {
List<Map<String, Object>> results = new ArrayList<>();
for (DataLog dataLog : dataLogs) {
Map<String, Object> resultMap = new LinkedHashMap<>();
resultMap.put("料号", dataLog.getPartNumber());
resultMap.put("物料描述", "");
resultMap.put("隔口码", dataLog.getReelPosName());
resultMap.put("隔口数量", dataLog.getPartitionCount());
resultMap.put("储位", dataLog.getBoxPosName());
resultMap.put("异动类型", dataLog.getSourceName());
resultMap.put("ID NO", dataLog.getBarcode());
resultMap.put("LOT", dataLog.getBatchInfo());
resultMap.put("D/C", dataLog.getDateCode());
resultMap.put("厂商", dataLog.getProvider());
resultMap.put("Keeper", dataLog.getKeeperCode());
resultMap.put("原始库别", dataLog.getWarehouseCode());
resultMap.put("目的库别", "");
resultMap.put("供应商代码", dataLog.getProviderNumber());
resultMap.put("事务日期", dataLog.getCreateDate());
resultMap.put("姓名", dataLog.getOperator());
results.add(resultMap);
}
try {
FileUtil.downloadExcel(results, response);
} catch (IOException e) {
e.printStackTrace();
log.info("异动导出失败--" + e.getMessage());
}
}
}
@ApiOperation("库存")
@RequestMapping("/inventory")
@AnonymousAccess
public PageData inventory(ReportQueryCondition queryCondition, Pageable pageable) {
Query query = QueryHelp.getQuery(queryCondition);
query.addCriteria(Criteria.where("used").is(true));
PageData<StoragePos> pages = storagePosManager.findByPage(query, pageable);
//处理隔口数量
List<StoragePosDto> storagePosDtos = storagePosMapper.toDto(pages.getContent());
if (storagePosDtos != null && !storagePosDtos.isEmpty()) {
for (StoragePosDto storagePosDto : storagePosDtos) {
BarcodeDto barcode = storagePosDto.getBarcode();
if (barcode == null){
continue;
}
List<BarcodeDto> subCodeList = barcode.getSubCodeList();
if (subCodeList != null && !subCodeList.isEmpty()){
List<String> posNames = subCodeList.stream().filter(barcodeDto -> StringUtils.isNotBlank(barcodeDto.getPosName())).map(BarcodeDto::getPosName).collect(Collectors.toList());
Map<String, Long> countMap = getPartitionCountMap(posNames);
for (BarcodeDto barcodeDto : subCodeList) {
String posName = barcodeDto.getPosName();
if (StringUtils.isNotBlank(posName) && countMap.get(posName) != null){
barcodeDto.setPartitionCount(countMap.get(posName).intValue());
}
}
}
}
}
return new PageData(storagePosDtos, pages.getTotalElements());
}
public Map<String, Long> getPartitionCountMap(List<String> posNames) {
Map<String, Long> countMap = new HashMap<>();
List<Barcode> barcodes = barcodeManager.findByQuery(new Query(Criteria.where("posName").in(posNames)));
if (barcodes != null && !barcodes.isEmpty()) {
countMap = barcodes.stream().collect(Collectors.groupingBy(Barcode::getPosName, Collectors.counting()));
}
return countMap;
}
private int getExcessOutReel(LiteOrderItem orderItem) {
int differenceReelCount = orderItem.getTotalOutReelCount() - orderItem.getNeedReelCount() - orderItem.getTotalReelCountByOutNum();
return differenceReelCount > 0 ? differenceReelCount : 0;
}
private int getExcessOutNum(LiteOrderItem orderItem) {
int differenceNum = orderItem.getOutNum() - orderItem.getNeedNum();
return differenceNum > 0 ? differenceNum : 0;
}
}
......@@ -427,11 +427,6 @@ public class PanaApiController extends BaseSmfApiListener {
}
@Override
public Barcode barcodeInfo(String barcodeInfoUrl, Barcode barcode) {
return null;
}
@Override
public void inTaskStatusChange(String inNotifyUrl, DataLog task) {
if(task.isFinished()){
if(task.isPutInTask()){
......
......@@ -190,11 +190,6 @@ public class SiemensApi extends BaseSmfApiListener {
}
}
@Override
public Barcode barcodeInfo(String barcodeInfoUrl, Barcode barcode) {
return null;
}
public static LotCheckInfo lotCheckIn(String lot, String url,String deviceId) {
if (ObjectUtil.isEmpty(url)) {
log.info("没有配置Siemens,无需验证");
......
支持 Markdown 格式
你添加了 0 到此讨论。请谨慎行事。
Finish editing this message first!