Commit 92eebe0a zshaohui

3f逻辑修改

1 个父辈 ea01bade
正在显示 81 个修改的文件 包含 112 行增加11359 行删除
......@@ -4,7 +4,6 @@ import com.google.common.base.Strings;
import com.neotel.smfcore.common.utils.DateUtil;
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 com.neotel.smfcore.custom.lizhen.setting.util.ExpireDateUtil;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
......@@ -683,75 +682,6 @@ public class BarcodeRule {
}
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
......
......@@ -5,7 +5,6 @@ import com.google.common.collect.Lists;
import com.neotel.smfcore.common.exception.ValidateException;
import com.neotel.smfcore.common.utils.DateUtil;
import com.neotel.smfcore.common.utils.StringUtils;
import com.neotel.smfcore.core.api.SmfApi;
import com.neotel.smfcore.core.barcode.bean.BarcodeRule;
import com.neotel.smfcore.core.barcode.bean.CodeBean;
import com.neotel.smfcore.core.barcode.enums.COMPONENT_TYPE;
......@@ -13,16 +12,14 @@ 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.LizhenApi;
import com.neotel.smfcore.custom.lizhen.agvBox.bean.GrLabel;
import com.neotel.smfcore.custom.lizhen.setting.bean.ExpiredSetting;
import com.neotel.smfcore.custom.lizhen.setting.service.manager.ExpiredSettingManager;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.yaml.snakeyaml.comments.CommentType;
import java.util.*;
import java.util.Collection;
import java.util.Date;
import java.util.List;
/**
* Created by sunke on 2021/7/13.
......@@ -434,15 +431,4 @@ 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;
}
}
......@@ -596,6 +596,7 @@ public class LiteOrderCache {
task.setDescribe(pos.getBarcode().getDescribe());
task.setKeeperCode(pos.getBarcode().getKeeperCode());
task.setExport(exportStr);
task.setPickingId(orderItem.getPickingId());
// task = dataLogDao.save(task);
taskService.addTaskToExecute(task);
}
......
......@@ -241,6 +241,9 @@ public class LiteOrderItem extends BasePo implements Serializable ,Comparable<Li
private List<String> positionList;
private String pickingId;
public void setOutReelList(String reel) {
if (outReelList == null){
outReelList = new ArrayList<>();
......
......@@ -368,6 +368,11 @@ public class DataLog extends BasePo implements Serializable {
*/
private String export = "";
/**
* 出库pickingId
*/
private String pickingId;
public String getBarcode() {
if(barcode == null){
return "";
......
package com.neotel.smfcore.custom.lizhen;
import cn.hutool.json.JSONUtil;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
......@@ -9,31 +9,24 @@ import com.neotel.smfcore.common.exception.ValidateException;
import com.neotel.smfcore.common.utils.HttpHelper;
import com.neotel.smfcore.common.utils.JsonUtil;
import com.neotel.smfcore.common.utils.StringUtils;
import com.neotel.smfcore.core.api.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.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.custom.lizhen.agvBox.bean.GrLabel;
import com.neotel.smfcore.custom.lizhen.innerBox.bean.PreWarningItem;
import com.neotel.smfcore.custom.lizhen.innerBox.util.CommonUtil;
import com.neotel.smfcore.custom.lizhen.innerBox.util.PreWarningItemCache;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;
@Slf4j
@Component
......@@ -81,7 +74,6 @@ public class LizhenApi extends DefaultSmfApiListener {
werks = dataCache.getConfigCache("werks",werks);
outNotifyUrlPK = dataCache.getConfigCache("api.outNotifyUrlPK",outNotifyUrlPK);
batchCheckUrl = dataCache.getConfigCache("api.batchCheckUrl",batchCheckUrl);
//checkReelMeasureUrl = dataCache.getConfigCache("api.checkReelMeasure",checkReelMeasureUrl);
}
/**
......@@ -130,41 +122,6 @@ public class LizhenApi extends DefaultSmfApiListener {
/**
* 获取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 resultMap;
}
/**
* 获取mes数量
*
* @param barcode
......@@ -290,6 +247,7 @@ public class LizhenApi extends DefaultSmfApiListener {
if (StringUtils.isNotBlank(resultStr)) {
throw new ValidateException("smfcore.mesApi.inCheck.ng", /*"MES验证失败:" + */barcode.getBarcode() + "验证失败:" + resultStr);
}
return barcode;
}
......@@ -302,34 +260,21 @@ public class LizhenApi extends DefaultSmfApiListener {
*/
@Override
public void inTaskStatusChange(String inNotifyUrl, DataLog task) {
if (!task.isFinished()){
return;
}
Map<String, Object> dataMap = new HashMap<>();
dataMap.put("pickingid", "");
dataMap.put("wo", "");
dataMap.put("reelno", task.getBarcode());
dataMap.put("ipn", task.getPartNumber());
Barcode barcode = barcodeManager.findByBarcode(task.getBarcode());
if (barcode != null) {
dataMap.put("qty", barcode.getAmount());
dataMap.put("datecode", barcode.getDateCode());
dataMap.put("lot", barcode.getBatch());
dataMap.put("vendor", barcode.getProvider());
dataMap.put("batch", "");
dataMap.put("vendorcode",barcode.getProviderNumber());
}
dataMap.put("werks",werks);
dataMap.put("reelid","");
String param = JsonUtil.toJsonStr(Arrays.asList(dataMap));
log.info("保存物料入参为:" + param);
if (task.isFinished()){
Map<String,Object> paramMap = new HashMap<>();
paramMap.put("PLANT_CODE", CommonUtil.plantCode);
paramMap.put("RETURN_TYPE", "return_tower"); //退回大库: return 退回料塔: return_tower
paramMap.put("BIN_CODE", task.getPosName());
paramMap.put("REEL_LIST", Arrays.asList(task.getBarcode()));
log.info(task.getBarcode()+"入库通知,调用电子料入退库,请求参数为:"+JSON.toJSONString(paramMap));
try {
String result = HttpHelper.postJson(inNotifyUrl, Arrays.asList(dataMap));
log.info("保存物料出参为:" + result);
String resultStr = HttpHelper.postJson(inNotifyUrl, paramMap);
log.info(task.getBarcode()+"入库通知,调用电子料入退库,结果为:"+resultStr);
} catch (ApiException e) {
e.printStackTrace();
log.info(barcode.getBarcode()+"保存物料异常:"+e.getMessage());
log.info(task.getBarcode()+"入库通知,调用电子料入退库,异常为:"+e.getMessage());
}
}
}
......@@ -341,59 +286,23 @@ public class LizhenApi extends DefaultSmfApiListener {
*/
@Override
public void outTaskStatusChange(String outNotifyUrl, DataLog task) {
if (task.getBarcode().startsWith("CS")
|| task.getBarcode().startsWith("CM")
|| task.getBarcode().startsWith("CB")) {
return;
}
if (!task.isFinished()) {
return;
}
if (task.isBoxOut()){
return;
}
Map<String, Object> dataMap = new HashMap<>();
dataMap.put("pickingid", "");
if (StringUtils.isNotBlank(task.getSourceName()) && StringUtils.isNotBlank(task.getLine()) && !task.isManualUpload()) {
dataMap.put("pickingid", task.getSourceName());
outNotifyUrl = outNotifyUrlPK;
log.info("出库pk不为空:"+outNotifyUrl);
}
dataMap.put("wo", "");
dataMap.put("reelno", task.getBarcode());
dataMap.put("ipn", task.getPartNumber());
dataMap.put("qty", task.getNum());
dataMap.put("datecode", task.getDateCode());
dataMap.put("lot", task.getBatchInfo());
dataMap.put("vendor", task.getProvider());
dataMap.put("batch", "");
dataMap.put("vendorcode", task.getProviderNumber());
dataMap.put("werks", werks);
dataMap.put("reelid", "");
if (outNotifyUrl == outNotifyUrlPK) {
List<Map<String, Object>> paramList = new ArrayList();
paramList.add(dataMap);
JSONObject jsonObject = new JSONObject();
jsonObject.put("data",paramList);
String param = JsonUtil.toJsonStr(jsonObject);
log.info("保存物料入参为:" + param + "地址为:" + outNotifyUrl);
try {
String result = HttpHelper.postJson(outNotifyUrl, jsonObject);
log.info("保存物料出参为:" + result);
} catch (ApiException e) {
e.printStackTrace();
log.info(task.getBarcode() + "保存物料异常:" + e.getMessage());
}
} else {
String param = JsonUtil.toJsonStr(Arrays.asList(dataMap));
log.info("保存物料入参为:" + param + "地址为:" + outNotifyUrl);
if (task.isFinished()) {
Map<String, Object> paramMap = new HashMap<>();
paramMap.put("PLANT_CODE", CommonUtil.plantCode);
paramMap.put("PICKING_ID", task.getPickingId());
paramMap.put("MATERIAL_CODE", task.getPartNumber());
paramMap.put("WAREHOUSE_CODE", task.getWarehouseCode());
paramMap.put("BRAND", task.getProvider());
paramMap.put("FACE", task.getSide());
paramMap.put("BATCH_CODE", task.getBatchInfo());
paramMap.put("REEL_LIST", Arrays.asList(task.getBarcode()));
log.info(task.getBarcode() + "出库通知,调用Tower发料,请求参数为:" + JSON.toJSONString(paramMap));
try {
String result = HttpHelper.postJson(outNotifyUrl, Arrays.asList(dataMap));
log.info("保存物料出参为:" + result);
String resultStr = HttpHelper.postJson(outNotifyUrl, paramMap);
log.info(task.getBarcode() + "出库通知,调用Tower发料,结果为:" + resultStr);
} catch (ApiException e) {
e.printStackTrace();
log.info(task.getBarcode() + "保存物料异常:" + e.getMessage());
log.info(task.getBarcode() + "出库通知,调用Tower发料,异常为:" + e.getMessage());
}
}
}
......@@ -406,77 +315,7 @@ public class LizhenApi extends DefaultSmfApiListener {
* @param taskList
*/
public void outTaskStatusChange(String outNotifyUrl, List<DataLog> taskList) {
List<DataLog> resultList = new ArrayList<>();
for (DataLog task : taskList) {
if (task.getBarcode().startsWith("CS")
|| task.getBarcode().startsWith("CM")
|| task.getBarcode().startsWith("CB")) {
continue;
}
if (!task.isFinished()) {
continue;
}
resultList.add(task);
}
//构造入参
List<Map<String, Object>> paramList = new ArrayList();
for (DataLog task : resultList) {
Map<String, Object> dataMap = new HashMap<>();
dataMap.put("pickingid", "");
if (StringUtils.isNotBlank(task.getSourceName()) && StringUtils.isNotBlank(task.getLine()) && !task.isManualUpload()) {
dataMap.put("pickingid", task.getSourceName());
}
dataMap.put("wo", "");
dataMap.put("reelno", task.getBarcode());
dataMap.put("ipn", task.getPartNumber());
dataMap.put("qty", task.getNum());
dataMap.put("datecode", task.getDateCode());
dataMap.put("lot", task.getBatchInfo());
dataMap.put("vendor", task.getProvider());
dataMap.put("batch", "");
dataMap.put("vendorcode", task.getProviderNumber());
dataMap.put("werks", werks);
dataMap.put("reelid", "");
paramList.add(dataMap);
}
//有pickingid的任务
List<Map<String, Object>> hasPickingidList = paramList.stream().filter(item -> {
String pickingid = (String) item.get("pickingid");
return StringUtils.isNotBlank(pickingid);
}).collect(Collectors.toList());
if (hasPickingidList != null && !hasPickingidList.isEmpty()) {
JSONObject jsonObject = new JSONObject();
jsonObject.put("data", paramList);
String param = JsonUtil.toJsonStr(jsonObject);
log.info("保存物料入参为:" + param + "地址为:" + outNotifyUrlPK);
try {
String result = HttpHelper.postJson(outNotifyUrlPK, jsonObject);
log.info("保存物料出参为:" + result);
} catch (ApiException e) {
e.printStackTrace();
log.info("保存物料异常:" + e.getMessage());
}
}
//无picking的任务
List<Map<String, Object>> noPickingidList = paramList.stream().filter(item -> {
String pickingid = (String) item.get("pickingid");
return StringUtils.isBlank(pickingid);
}).collect(Collectors.toList());
if (noPickingidList != null && !noPickingidList.isEmpty()){
String param = JsonUtil.toJsonStr(paramList);
log.info("保存物料入参为:" + param + "地址为:" + outNotifyUrl);
try {
String result = HttpHelper.postJson(outNotifyUrl, paramList);
log.info("保存物料出参为:" + result);
} catch (ApiException e) {
e.printStackTrace();
log.info("保存物料异常:" + e.getMessage());
}
}
}
......
......@@ -42,7 +42,7 @@ import java.util.concurrent.TimeUnit;
@Slf4j
@RestController
@RequestMapping("/api/Mes")
@RequestMapping("wcs")
public class LizhenController {
@Autowired
......@@ -107,89 +107,6 @@ public class LizhenController {
}
@ApiOperation("外仓:发料明细")
@PostMapping("/EPickingList")
@AnonymousAccess
public ResultBean EPickingList(@RequestBody List<Map<String, Object>> params) {
log.info("发料明细数据--" + JsonUtil.toJsonStr(params));
for (Map<String, Object> param : params) {
//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, "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(pickingId);
liteOrder.setLine(line);
liteOrder.setType(1);
liteOrder.setSource(LITEORDER_SOURCE.OUTTER.name());
List<LiteOrderItem> orderItems = new ArrayList<>();
String itemStr = param.get("ITEM") == null ? "" : param.get("ITEM").toString();
if (StringUtils.isBlank(itemStr)) {
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();
String mo = item.get("mo") == null ? "" : item.get("mo").toString();
String materialCode = item.get("material_code") == null ? "" : item.get("material_code").toString();
String brand = item.get("brand") == null ? "" : item.get("brand").toString();
String batchCode = item.get("batch_code") == null ? "" : item.get("batch_code").toString();
int reqQty = item.get("req_qty") == null ? 0 : Integer.valueOf(item.get("req_qty").toString());
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();
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(allReelCount);
//liteOrder.setTotalTaskReelCount(allReelCount);
liteOrder.setOrderItems(orderItems);
liteOrderManager.createWithItems(liteOrder);
liteOrderCache.addOrderToMap(liteOrder);
}
}
return ResultBean.newOkResult("");
}
ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(1);
@PostConstruct
......@@ -234,12 +151,15 @@ public class LizhenController {
@ApiOperation("内仓:机台叫料")
@PostMapping("/mPickingList")
@PostMapping("/ReelWarningInfo")
@AnonymousAccess
public ResultBean mPickingList(@RequestBody List<Map<String, String>> params) {
if (params == null || params.isEmpty()) {
return ResultBean.newErrorResult(-1, "smfcore.valueCanotNull", "{0}不能为空", new String[]{"参数"});
}
log.info("收到缺料预警信息为:"+ JSONObject.toJSONString(params));
for (Map<String, String> param : params) {
String line = param.get("LINE");
String forwardUrl = getForwardUrl(line);
......@@ -277,6 +197,7 @@ public class LizhenController {
item.setPartnumber(data.get("PARTNUMBER"));
item.setLine(data.get("LINE"));
item.setItemId(data.get("ID"));
item.setPickingId(data.get("PICKING_ID"));
try {
item.setPriority(Integer.valueOf(data.get("PRIORITY")));
} catch (NumberFormatException e) {
......
package com.neotel.smfcore.custom.lizhen;
import com.neotel.smfcore.common.bean.ResultBean;
import com.neotel.smfcore.core.barcode.service.manager.IBarcodeManager;
import com.neotel.smfcore.core.barcode.service.po.Barcode;
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.security.annotation.AnonymousAccess;
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.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RequestMapping("/exp")
@RestController
public class OrderExpRestController {
@Autowired
private IBarcodeManager barcodeManager;
@Autowired
private ILiteOrderManager orderManager;
@Autowired
private IStoragePosManager storagePosManager;
@RequestMapping("/orderExp")
@AnonymousAccess
public ResultBean order(String orderNo) {
LiteOrder liteOrder = orderManager.findByOrderNo(orderNo);
List<LiteOrderItem> orderItems = liteOrder.getOrderItems();
//开始处理数据
for (LiteOrderItem orderItem : orderItems) {
//根据工单查找item
Query query = new Query(Criteria.where("orderItemId").is(orderItem.getId()));
List<Barcode> barcodes = barcodeManager.findByQuery(query);
int count = 0;
if (barcodes != null && !barcodes.isEmpty()) {
for (Barcode barcode : barcodes) {
barcode.setOut(false);
barcode.setOrderItemId(null);
barcode.setSelectMsg(null);
barcodeManager.save(barcode);
count++;
System.out.println("修改barcode数量为:" + count);
}
}
}
//开始处理料箱数据
for (LiteOrderItem orderItem : orderItems) {
Query query = new Query(Criteria.where("subCodeList.orderItemId").is(orderItem.getId()));
List<Barcode> barcodes = barcodeManager.findByQuery(query);
int count = 0;
for (Barcode barcode : barcodes) {
List<Barcode> subCodeList = barcode.getSubCodeList();
for (Barcode subCode : subCodeList) {
subCode.setOut(false);
subCode.setOrderItemId(null);
subCode.setSelectMsg(null);
}
barcode.setSubCodeList(subCodeList);
barcodeManager.save(barcode);
count++;
System.out.println("修改barcode数量为:" + count);
}
}
//开始处理料cang
for (LiteOrderItem orderItem : orderItems) {
Query query = new Query(Criteria.where("barcode.subCodeList.orderItemId").is(orderItem.getId()));
List<StoragePos> storagePosList = storagePosManager.findByQuery(query);
int count = 0;
for (StoragePos storagePos : storagePosList) {
Barcode barcode = storagePos.getBarcode();
List<Barcode> subCodeList = barcode.getSubCodeList();
for (Barcode subCode : subCodeList) {
subCode.setOut(false);
subCode.setOrderItemId(null);
subCode.setSelectMsg(null);
}
barcode.setSubCodeList(subCodeList);
storagePos.setBarcode(barcode);
storagePosManager.save(storagePos);
count++;
System.out.println("修改库位数量为:" + count);
}
}
//再补一刀
List<Barcode> barcodeList = barcodeManager.findByQuery(new Query(Criteria.where("isOut").is(true)));
if (barcodeList != null && !barcodeList.isEmpty()){
for (Barcode barcode : barcodeList) {
barcode.setOut(false);
barcode.setOrderItemId(null);
barcode.setSelectMsg(null);
barcodeManager.save(barcode);
}
}
return ResultBean.newOkResult("");
}
}
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;
}
package com.neotel.smfcore.custom.lizhen.agvBox.bean;
import com.neotel.smfcore.common.base.BasePo;
import com.neotel.smfcore.core.barcode.service.po.Barcode;
import com.neotel.smfcore.custom.lizhen.agvBox.bean.enums.InventoryStatus;
import lombok.Data;
import java.util.ArrayList;
import java.util.List;
/**
* 盘点数据
*/
@Data
public class InventoryData extends BasePo {
/**
* 原始库位
*/
private String oriPosName;
/**
* 料箱号
*/
private String box;
/**
* 隔口码
*/
private String boxPartition;
/**
* 料号
*/
private String partNumber;
/**
* 物料描述
*/
private String describe;
/**
* 储位
*/
private String posName = "";
/**
* 卷数
*/
private int reelCount = 0;
/**
* 数量
*/
private int amout = 0;
/**
* 已盘点卷数
*/
private int inventoryReelCount = 0;
/**
* 已盘点数量
*/
private int inventoryAmout = 0;
/**
* 是否匹配
*/
private boolean isMatch = false;
/**
* 创建人
*/
private String creator;
/**
* 状态
*/
private String status = InventoryStatus.NEW.name();
/**
* 盘点批次
*/
private String inventoryBatch;
/**
* 盘点的barcode集合
*/
private List<Barcode> barcodeList;
/**
* 是否需要盘点,默认false
*/
private boolean needInventory = false;
public synchronized void updateBarcodeList(Barcode barcode) {
if (barcodeList == null) {
barcodeList = new ArrayList<>();
}
int index = -1;
for (int i = 0; i < barcodeList.size(); i++) {
if (barcodeList.get(i).getBarcode().equals(barcode.getBarcode())) {
index = i;
break;
}
}
if (index >= 0){
barcodeList.set(index,barcode);
} else {
barcodeList.add(barcode);
}
}
}
package com.neotel.smfcore.custom.lizhen.agvBox.bean;
import com.neotel.smfcore.core.barcode.service.po.Barcode;
import lombok.Data;
import java.util.ArrayList;
import java.util.List;
/**
* 盘点箱子信息
*/
@Data
public class PartitionInfo {
/**
* 隔口信息
*/
private String partition;
/**
* 盘数
*/
private int reelCount = 0;
/**
* 是否盘点
*/
private boolean isInventory = false;
/**
* 料号
*/
private String partNumber;
/**
* 数量
*/
private int num = 0;
/**
* 盘点盘数
*/
private int inventoryReelCount = 0;
/**
* 盘点数量
*/
private int inventoryAmount = 0;
/**
* 盘点物料信息
*/
private List<Barcode> barcodeList = new ArrayList<>();
private int status = 0;
}
package com.neotel.smfcore.custom.lizhen.agvBox.bean;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
/**
* @author sunke
* @date 2022/9/22 4:32 PM
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Station {
/**
* 工位名称
*/
private String name;
/**
* 当前料箱的RFID
*/
private String currentRfid = "";
/**
* 物料当前扫描数量
*/
private int reelCurrentNum = 0;
/**
* 物料总数量
*/
private int reelNum;
/**
* 料箱当前数量
*/
private int boxCurrentNum = 0;
/**
* 料箱数量
*/
private int boxNum;
/**
* 宽
*/
private int platsize;
/**
* 高
*/
private int height;
/**
* 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.enums;
/**
* 盘点出库状态
*/
public enum InventoryStatus {
/**
* 新建
*/
NEW("新建"),
/**
* 正在执行中
*/
EXECUTING("正在执行"),
/**
* 完成
*/
FINISHED("已完成");
private String value;
InventoryStatus(String value) {
this.value = value;
}
public static String getValue(String name){
for (InventoryStatus status : InventoryStatus.values()) {
if (name.equals(status.name())){
return status.value;
}
}
return "";
}
}
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 com.neotel.smfcore.common.bean.BetweenData;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
@Data
public class InventoryQuery {
@QueryCondition(type = QueryCondition.Type.BETWEEN, propName = "createDate")
@DateTimeFormat(pattern = "yyyy-MM-dd")
private BetweenData<Date> createDate;
private String type;
}
package com.neotel.smfcore.custom.lizhen.agvBox.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;
}
package com.neotel.smfcore.custom.lizhen.agvBox.enums;
/*
出入库类型
*/
public enum INOUT_TYPE {
/**
* 单盘入库
*/
IN_ONE,
/**
* 整箱入库
*/
IN_BOX,
/**
* 单盘出库
*/
OUT_ONE,
/**
* 隔口出库
*/
OUT_PARTITION,
/**
* 整箱出库
*/
OUT_BOX,
/**
* 单盘取消
*/
CANCEL_ONE
}
package com.neotel.smfcore.custom.lizhen.agvBox.rest;
import com.neotel.smfcore.common.bean.ResultBean;
import com.neotel.smfcore.common.utils.JsonUtil;
import com.neotel.smfcore.common.utils.ReelLockPosUtil;
import com.neotel.smfcore.common.utils.StringUtils;
import com.neotel.smfcore.core.barcode.service.manager.IBarcodeManager;
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.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.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.custom.lizhen.innerBox.enums.ExtendType;
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.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
/**
* 设备通信(AGV料仓)
*/
@Slf4j
@RestController
public class AgvBoxDeviceClientController {
@Autowired
private DataCache dataCache;
@Autowired
private TaskService taskService;
@Autowired
private IBarcodeManager barcodeManager;
@Autowired
private IStoragePosManager storagePosManager;
@Autowired
private IDataLogDao dataLogDao;
/**
* 料箱锁定的目的地
*/
private Map<String, String> lockRfidTarget = new ConcurrentHashMap<>();
/**
* 工位状态定时上报
*/
@ApiOperation("工位状态定时上报")
@RequestMapping(value = "/service/store/agvBox/stationInfo")
@ResponseBody
@AnonymousAccess
public ResultBean stationInfo(HttpServletRequest request) {
for (int i = 1; i <= 5; i++) {
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<>();
Collection<DataLog> queueTasks = taskService.getQueueTasks();
for (DataLog queueTask : queueTasks) {
if (queueTask.isPutInTask() && queueTask.isWait()) {
Storage storage = dataCache.getStorageById(queueTask.getStorageId());
if (storage.isStorage(DeviceType.AGV_BOX)) {
String barcode = queueTask.getBarcode();
String station = getStationByRfid(barcode);
//任务的条码与工位的箱号一致,需要线体升起阻挡进行入库
if (!station.isEmpty()) {
needInStationList.add(station);
}
}
}
}
Map<String, List<String>> dataMap = new HashMap<>();
dataMap.put("needInStation", needInStationList);
return ResultBean.newOkResult(dataMap);
}
/**
* 根据料箱RFID获取工位信息
*/
private String getStationByRfid(String rfid) {
//String prefixRfid = rfid + "-";
for (Station station : StationCacheUtil.getAllStations()) {
String stationRfid = station.getCurrentRfid();
if (stationRfid.startsWith(rfid)) {
return station.getName();
}
}
return "";
}
/**
* 定时获取出库库位列表
*
* @param request
* @return
*/
@RequestMapping(value = "/service/store/agvBox/getOutTask")
@ResponseBody
@AnonymousAccess
public ResultBean getOutTask(HttpServletRequest request) {
Collection<DataLog> queueTasks = taskService.getQueueTasks();
queueTasks = queueTasks.stream().sorted(Comparator.comparing(DataLog::getPosName)).collect(Collectors.toList());
//queueTasks = queueTasks.stream().sorted(Comparator.comparing(DataLog :: getLoc).reversed()).collect(Collectors.toList());
List<Map<String, String>> taskToSend = new ArrayList<>();
for (DataLog queueTask : queueTasks) {
//小车限制,默认一次生成8个任务
if (taskToSend != null && taskToSend.size() >= 8) {
break;
}
if (queueTask.isCheckOutTask()) {
if (queueTask.isWait() /*|| queueTask.isExecuting()*/) {
if (StringUtils.isNotBlank(queueTask.getLoc())) {
Storage storage = dataCache.getStorageById(queueTask.getStorageId());
if (storage.isStorage(DeviceType.AGV_BOX)) {
Map<String, String> taskData = new HashMap<>();
taskData.put("barcode", queueTask.getBarcode());
taskData.put("slotCode", queueTask.getPosName());
taskData.put("status", queueTask.getStatus());
taskToSend.add(taskData);
}
}
}
}
}
//出手动的
for (DataLog queueTask : queueTasks) {
if (taskToSend != null && taskToSend.size() >= 8) {
break;
}
if (queueTask.isCheckOutTask()) {
if (queueTask.isWait()) {
if (StringUtils.isBlank(queueTask.getLoc())) {
Storage storage = dataCache.getStorageById(queueTask.getStorageId());
if (storage.isStorage(DeviceType.AGV_BOX)) {
Map<String, String> taskData = new HashMap<>();
taskData.put("barcode", queueTask.getBarcode());
taskData.put("slotCode", queueTask.getPosName());
taskData.put("status", queueTask.getStatus());
taskToSend.add(taskData);
}
}
}
}
}
return ResultBean.newOkResult(taskToSend);
}
/**
* 根据料箱条码获取目的地信息
*
* @param request
* @return
*/
@RequestMapping(value = "/service/store/agvBox/getTarget")
@ResponseBody
@AnonymousAccess
public ResultBean getTarget(HttpServletRequest request) {
String rfid = request.getParameter("barcode");
try {
//"barcode": "CS001"
DataLog opTask = null;
Collection<DataLog> tasks = taskService.getAllTasks();
for (DataLog task : tasks) {
if (!task.isFinished() && !task.isCancel()) {
Storage storage = dataCache.getStorageById(task.getStorageId());
if (storage.isStorage(DeviceType.AGV_BOX)) {
if (isSameBarcodeTask(rfid, task)) {
opTask = task;
break;
}
}
}
}
String target = "s0";
String barcode = "";
//"target": "1",//0=工位已有箱子;s1=工位1;s2=工位2;s3=工位3;s4=工位4;s5=工位5;其他值表示入库的目标库位
if (opTask != null) {
barcode = opTask.getBarcode();
if (opTask.isPutInTask()) {
target = opTask.getPosName();
} else {
String loc = lockRfidTarget.get(opTask.getBarcode());
if (loc != null) {
target = loc;
} else {
loc = opTask.getLoc();
if(Strings.isNotBlank(loc)){
//出空箱子时已经指定了工位,先判断该工位是否有料箱
Station station = StationCacheUtil.getStation(loc);
if(station != null){
String stationRfid = station.getCurrentRfid();
if(Strings.isBlank(stationRfid)){
//该工位无料箱, 把空箱子分配到该工位
lockRfidTarget.put(opTask.getBarcode(),station.getName());
log.info("分配用于入库物料的料箱[" + opTask.getBarcode() + "]到" + station.getName());
target = station.getName();
}
}
}else{
for (Station station : StationCacheUtil.getAllStations()) {
String stationRfid = station.getCurrentRfid();
if(Strings.isBlank(stationRfid)){
//该工位目前无料箱
/*if (lockRfidTarget.get(station.getName()) == null) {
//工位未分配过库位
log.info("分配料箱[" + opTask.getBarcode() + "]到" + station.getName());
lockRfidTarget.put(opTask.getBarcode(), station.getName());
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;
}
}
}
//如果工位上都是忙碌,则均分
if ("s0".equals(target)){
Map<String,Integer> nameCountMap = new HashMap<>();
for (int i = 1; i < 6; i++) {
nameCountMap.put("s"+i,0);
}
Collection<String> names = lockRfidTarget.values();
for (String name : names) {
Integer count = nameCountMap.get(name);
count ++;
nameCountMap.put(name,count);
}
target = "s5";
int count = nameCountMap.get("s5");
for (Map.Entry<String, Integer> entry : nameCountMap.entrySet()) {
String name = entry.getKey();
Integer nameCount = entry.getValue();
if (count > nameCount){
count = nameCount;
target = name;
}
}
lockRfidTarget.put(opTask.getBarcode(),target);
}
}
}
}
}
Map<String, String> taskData = new HashMap<>();
taskData.put("barcode", barcode);
taskData.put("slotCode", target);
return ResultBean.newOkResult(taskData);
} catch (Exception e) {
return ResultBean.newErrorResult(2004, "smfcore.agvBox.getTarget.fail", "获取" + rfid + "目的地失败");
}
}
/**
* 更新任务状态
* EXECUTING=已发送到AGV
* INLINE=料箱放上线体(入库时人员推上线体, 出库时指AGV放上线体),
* INAGV=料箱放上AGV(入库时AGV从线体上抓起料箱;出库时AGV从库位取走料箱),
* FINISHED=任务完成(入库时AGV将料箱放入库位;出库时料箱到达工位)
*/
@RequestMapping(value = "/service/store/agvBox/updateLocInfo")
@ResponseBody
@AnonymousAccess
public synchronized ResultBean updateLocInfo(HttpServletRequest request) {
String rfid = request.getParameter("barcode");
String statusStr = request.getParameter("status");
String loc = request.getParameter("loc"); //工位
log.info("收到料盘[" + rfid + "]更新位置指令[" + statusStr + "]");
if (statusStr == null) {
return ResultBean.newErrorResult(301, "smfcore.updateLoc.status.empty", "状态不能为空");
}
if (rfid == null) {
return ResultBean.newErrorResult(302, "smfcore.updateLoc.barcode.empty", "条码不能为空");
}
DataLog opTask = null;
List<DataLog> allTasks = taskService.getAllTasks();
for (DataLog task : allTasks) {
if (rfid.startsWith(task.getBarcode())) {
if (!task.isCancel() && !task.isFinished()) {
opTask = task;
break;
}
}
}
if (opTask == null) {
return ResultBean.newErrorResult(303, "smfcore.task.notExist", "任务不存在");
}
if (opTask.isFinished()) {
return ResultBean.newErrorResult(304, "smfcore.task.hasEnd", "任务已完成");
}
statusStr = statusStr.toUpperCase();
log.info("更新料箱[" + rfid + "]的任务状态[" + opTask.getStatus() + "]为[" + statusStr + "]"+"目的地信息为:"+loc);
OP_STATUS oldStatus = OP_STATUS.valueOf(opTask.getStatus());
OP_STATUS updateStatus = OP_STATUS.valueOf(statusStr);
//如果是相同状态,则不执行
if (statusStr.equals(opTask.getStatus())){
return ResultBean.newErrorResult(-1,"smfcore.taskStatusHasUpdate","任务{0}已经修改状态",new String[]{opTask.getBarcode()});
}
/**
* 任务状态
* EXECUTING=已发送到AGV
* IN_ON_LINE=入库时人员将料箱推上线体,
* IN_ON_AGV=入库时AGV从线体上抓起料箱
* OUT_ON_LINE=出库时AGV将料箱放上线体,
* OUT_ON_AGV=出库时AGV将料箱从库位中取出
* 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 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));
}*//*
opTask.setLoc(loc);
taskService.updateFinishedTask(opTask);
}*/ else {
taskService.moveTaskToFinished(opTask);
if (OP_STATUS.OUT_ON_AGV.name().equals(statusStr)) {
//从库位中取出,需要移到完成队列中,并且清理库存
outFromPos(opTask);
}
taskService.updateFinishedTask(opTask);
if (OP_STATUS.FINISHED.name().equals(statusStr)) {
lockRfidTarget.remove(opTask.getBarcode());
//已完成,从完成缓存中清除
taskService.removeFinishedTask(opTask);
taskService.addBoxPosName(opTask);
}
}
} else {
opTask.setStatus(statusStr);
//入库任务
if (OP_STATUS.FINISHED.name().equals(statusStr)) {
taskService.moveTaskToFinished(opTask);
lockRfidTarget.remove(opTask.getBarcode());
intoPos(opTask);
//清理锁定库位
//rfid = rfid.substring(0,rfid.length()-1);
ReelLockPosUtil.removeReelLockPosInfo(rfid);
} else {
taskService.updateQueueTask(opTask);
}
}
} else {
log.info(rfid + "更新状态时未找到状态:" + statusStr + "");
}
return ResultBean.newOkResult("");
}
@RequestMapping("/needAwayBox")
//@ResponseBody
@AnonymousAccess
public ResultBean needAwayBox() {
List<String> results = new ArrayList<>();
Collection<DataLog> queueTasks = taskService.getAllTasks();
if (queueTasks != null && !queueTasks.isEmpty()) {
for (DataLog queueTask : queueTasks) {
if (results != null && !results.isEmpty()) {
if (results.size() >= 8) {
break;
}
}
if (queueTask.isCheckOutTask() && !queueTask.isFinished() && !queueTask.isCancel() && !queueTask.isWait() && !queueTask.isPause()) {
if (StringUtils.isNotBlank(queueTask.getLoc())) {
results.add(queueTask.getBarcode() + "需要出库到工位:" + queueTask.getLoc());
} else {
if (queueTask.getExtendType() == ExtendType.INVENTORY_CHECKOUT) {
results.add(queueTask.getBarcode() + "需要盘点");
} else {
results.add(queueTask.getBarcode() + "需要出库");
}
}
}
}
}
return ResultBean.newOkResult(results);
}
/**
* 料箱从仓位中取出
*/
private void intoPos(DataLog opTask) {
//已完成,加入库存,并且从完成队列中清除
StoragePos storagePos = storagePosManager.get(opTask.getPosId());
//二维码状态
Barcode barcode = barcodeManager.findByBarcode(opTask.getBarcode());
if (barcode != null) {
barcode.setUsedCount(barcode.getUsedCount() + 1);
barcode.setPutInTime(System.currentTimeMillis());
barcode.setInOpor("");
barcode.setCheckOutDate(null, "");
barcode.setPosName(opTask.getPosName());
storagePos.setBarcode(barcode);
dataCache.updateInventory(storagePos, barcode);
//需要更新料箱中物料的库存
List<Barcode> subCodes = barcode.getSubCodeList();
if (subCodes != null && !subCodes.isEmpty()) {
Storage storage = dataCache.getStorageById(storagePos.getStorageId());
for (Barcode subCode : subCodes) {
subCode.setStorageId(storage.getId());
barcodeManager.save(subCode);
dataCache.updateInventoryAmount(storage.getCid(), subCode.getPartNumber(), subCode.getAmount());
}
}
barcode.setSubCodeList(subCodes);
barcode = barcodeManager.save(barcode);
}
/**
* 仓位状态
*/
storagePos.setBarcode(barcode);
storagePos.setUsed(true);
storagePos.setCanCheckOutTime(System.currentTimeMillis());
storagePosManager.save(storagePos);
//更新缓存中的库存信息
opTask.setStatus(OP_STATUS.FINISHED.name());
taskService.updateFinishedTask(opTask);
taskService.removeFinishedTask(opTask);
}
/**
* 料箱放入仓位
*/
private void outFromPos(DataLog opTask) {
//从队列里面移除操作
taskService.removeQueueTask(opTask);
StoragePos storagePos = storagePosManager.get(opTask.getPosId());
Barcode barcode = storagePos.getBarcode();
if (barcode == null) {
log.warn("任务:" + opTask.getId() + " 仓位:" + opTask.getPosId() + " 的 Barcode 为null, 之前可能处理过,结束任务后直接返回");
return;
}
barcode = barcodeManager.get(barcode.getId());
if (barcode != null) {
//二维码状态
barcode.setUsed(true);
barcode.setUsedDate(new Date());
//仓位状态
barcode.setCheckOutDate(new Date(), "");
barcode.setPosName("");
barcodeManager.save(barcode);
}
storagePos.setBarcode(null);
storagePos.setUsed(false);
storagePosManager.save(storagePos);
log.info("出库完成,清空仓位: " + storagePos.getId() + "[" + storagePos.getPosName() + "]");
//更新缓存中的库存信息
dataCache.updateInventory(storagePos, barcode);
//需要更新料箱中物料的库存
List<Barcode> subCodes = barcode.getSubCodeList();
if (subCodes != null && !subCodes.isEmpty()) {
Storage storage = dataCache.getStorageById(storagePos.getStorageId());
for (Barcode subCode : subCodes) {
dataCache.updateInventoryAmount(storage.getCid(), subCode.getPartNumber(), -subCode.getAmount());
}
}
}
/**
* 是否是同一个箱子的任务
*
* @param rfid 客户端上传的RFID,值为CS001-A或CS001-B这种形式,只需要验证前缀是否相同
* @param task 任务
* @return
*/
private boolean isSameBarcodeTask(String rfid, DataLog task) {
if (rfid == null) {
return false;
}
String taskBarcode = task.getBarcode();
if (rfid.startsWith(taskBarcode)) {
return true;
}
return false;
}
public static void main(String[] args) {
Arrays.asList(null);
}
}
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 CodeController {
@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 cn.hutool.core.date.DateTime;
import com.google.common.collect.Lists;
import com.neotel.smfcore.common.bean.BetweenData;
import com.neotel.smfcore.common.bean.ReelLockPosInfo;
import com.neotel.smfcore.common.bean.ResultBean;
import com.neotel.smfcore.common.utils.*;
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.storage.enums.DeviceType;
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.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.InventoryData;
import com.neotel.smfcore.custom.lizhen.agvBox.bean.PartitionInfo;
import com.neotel.smfcore.custom.lizhen.agvBox.bean.Station;
import com.neotel.smfcore.custom.lizhen.agvBox.bean.enums.InventoryStatus;
import com.neotel.smfcore.custom.lizhen.agvBox.bean.query.InventoryQuery;
import com.neotel.smfcore.custom.lizhen.agvBox.service.manager.InventoryDataManager;
import com.neotel.smfcore.custom.lizhen.agvBox.util.BoxUtil;
import com.neotel.smfcore.custom.lizhen.agvBox.util.StationCacheUtil;
import com.neotel.smfcore.custom.lizhen.innerBox.enums.ExtendType;
import com.neotel.smfcore.security.annotation.AnonymousAccess;
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.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.*;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
/**
* 盘点
*/
@Slf4j
@RestController
@RequestMapping("/inventory")
public class InventoryController {
@Autowired
private IStoragePosManager storagePosManager;
@Autowired
private StoragePosMapper storagePosMapper;
@Autowired
private DataCache dataCache;
@Autowired
private IBarcodeManager barcodeManager;
@Autowired
private TaskService taskService;
@Autowired
private InventoryDataManager inventoryDataManager;
@Autowired
private CodeResolve codeResolve;
@Autowired
private LizhenApi lizhenApi;
/**
* 盘点数据key
*/
private static final String INVENTORY_DATA = "barcode.inventory.data";
/**
* 获取盘点状态
* @return
*/
@RequestMapping("/getInventoryStatus")
//@AnonymousAccess
public Map<String, String> getInventoryStatus() {
Map<String, String> resultMap = new LinkedHashMap<>();
for (InventoryStatus status : InventoryStatus.values()) {
resultMap.put(status.getValue(status.name()), status.name());
}
return resultMap;
}
/**
* 获取盘点信息
*
* @return
*/
@RequestMapping("/getInventoryInfo")
//@AnonymousAccess
public ResultBean getInventoryInfo() {
Map<String, Object> resultMap = new HashMap<>();
int inventoryCount = 0;
List<String> finishInventory = new ArrayList<>();
String storageId = "";
for (Storage storage : dataCache.getAllStorage().values()) {
if (!storage.isVirtual()) {
storageId = storage.getId();
break;
}
}
int count = storagePosManager.countByQuery(new Query(Criteria.where("storageId").is(storageId)));
String inventoryBatch = dataCache.getCache(INVENTORY_DATA) + "";
if (StringUtils.isNotBlank(inventoryBatch) && !"-1".equals(inventoryBatch)) {
List<InventoryData> dataList = inventoryDataManager.findByQuery(new Query(Criteria.where("inventoryBatch").is(inventoryBatch)/*.and("status").is(InventoryStatus.FINISHED.name())*/));
if (dataList != null && !dataList.isEmpty()) {
List<String> posNameList = new ArrayList<>();
for (InventoryData data : dataList) {
boolean isFinished = isInventoryDataFinshed(data.getPosName(),dataList);
if (isFinished) {
if (posNameList.isEmpty()) {
posNameList.add(data.getPosName());
} else {
if (!posNameList.contains(data.getPosName())) {
posNameList.add(data.getPosName());
}
}
}
}
inventoryCount = posNameList.size();
}
finishInventory = getFinishInventoryPosName(inventoryBatch,dataList);
}
resultMap.put("inventoryCount", inventoryCount);
resultMap.put("count", count);
resultMap.put("inventoryBatch", StringUtils.isBlank(inventoryBatch) || "-1".equals(inventoryBatch) ? "" : inventoryBatch);
resultMap.put("finishInventory", finishInventory);
return ResultBean.newOkResult(resultMap);
}
private boolean isInventoryDataFinshed(String posName, List<InventoryData> dataList) {
boolean isFinished = true;
for (InventoryData data : dataList) {
if (posName.equals(data.getPosName())){
if (!data.getStatus().equals(InventoryStatus.FINISHED.name())){
isFinished = false;
break;
}
}
}
return isFinished;
}
/**
* 开始盘点
*
* @return
*/
@RequestMapping("/inventoryStart")
//@AnonymousAccess
public ResultBean inventoryStart() {
String inventoryBatch = dataCache.getCache(INVENTORY_DATA) + "";
if (StringUtils.isBlank(inventoryBatch) || "-1".equals(inventoryBatch)) {
inventoryBatch = com.neotel.smfcore.common.utils.DateUtil.toDateString(System.currentTimeMillis(), "yyyyMMddHHmmssSSS");
dataCache.updateCache(INVENTORY_DATA, inventoryBatch);
}
log.info(SecurityUtils.getCurrentUsername() + "开始盘点,批次为:" + inventoryBatch);
return ResultBean.newOkResult("盘点批次为:" + inventoryBatch);
}
/**
* 结束盘点
*
* @param type 默认是0,强制是1
* @return
*/
@RequestMapping("/inventoryEnd")
//@AnonymousAccess
public ResultBean inventoryEnd(int type) {
log.info(SecurityUtils.getCurrentUsername() + "盘点结束,type为:" + type);
String inventoryBatch = dataCache.getCache(INVENTORY_DATA) + "";
if (StringUtils.isBlank(inventoryBatch) || "-1".equals(inventoryBatch)) {
return ResultBean.newErrorResult(-1, "", "当前没有要盘点的批次");
}
//根据批次查询所有的盘点数据
List<InventoryData> inventoryDataList = inventoryDataManager.findByQuery(new Query(Criteria.where("inventoryBatch").is(inventoryBatch)));
//判断是否要强制结束
if (type == 1) {
for (InventoryData data : inventoryDataList) {
if (!data.getStatus().equals(InventoryStatus.FINISHED.name())) {
data.setStatus(InventoryStatus.FINISHED.name());
inventoryDataManager.save(data);
}
String box = data.getBox();
Barcode barcode = barcodeManager.findByBarcode(box);
if (barcode != null) {
if (barcode.isInventory()) {
barcode.setInventory(false);
barcodeManager.save(barcode);
}
}
}
} else {
if (inventoryDataList != null && !inventoryDataList.isEmpty()) {
for (InventoryData data : inventoryDataList) {
if (!data.getStatus().equals(InventoryStatus.FINISHED.name())) {
return ResultBean.newErrorResult(-2, "", inventoryBatch + "盘点未完成,是否强制结束");
}
}
}
}
dataCache.updateCache(INVENTORY_DATA, "");
return ResultBean.newOkResult("");
}
/**
* 获取料箱信息
*
* @return
*/
@RequestMapping("/getStoragePosData")
//@AnonymousAccess
public List<StoragePosDto> getStoragePosData(String posName) {
List<Storage> storageList = new ArrayList<>();
for (Storage storage : dataCache.getAllStorage().values()) {
if (!storage.isVirtual()) {
storageList.add(storage);
}
}
String inventoryBatch = dataCache.getCache(INVENTORY_DATA) + "";
//获取所有库位信息
for (Storage storage : storageList) {
List<StoragePos> storagePosList = storagePosManager.findByQuery(inventoryQuery(posName, storage.getId(), null));
List<StoragePosDto> storagePosDtos = storagePosMapper.toDto(storagePosList);
if (inventoryBatch != null) {
for (StoragePosDto pos : storagePosDtos) {
List<InventoryData> dataList = inventoryDataManager.findByQuery(new Query(Criteria.where("inventoryBatch").is(inventoryBatch).and("posName").is(pos.getPosName())));
if (dataList != null && !dataList.isEmpty()) {
List<String> statusList = new ArrayList<>();
for (InventoryData data : dataList) {
statusList.add(data.getStatus());
}
if (statusList.contains(InventoryStatus.NEW.name())) {
pos.setInventoryStatus(InventoryStatus.NEW.name());
} else if (!statusList.contains(InventoryStatus.NEW.name()) && statusList.contains(InventoryStatus.EXECUTING.name())) {
pos.setInventoryStatus(InventoryStatus.EXECUTING.name());
} else if (!statusList.contains(InventoryStatus.NEW.name()) && !statusList.contains(InventoryStatus.EXECUTING.name())) {
pos.setInventoryStatus(InventoryStatus.FINISHED.name());
}
}
}
}
storagePosDtos = storagePosDtos.stream().sorted(Comparator.comparing(StoragePosDto :: getPosName).reversed()).collect(Collectors.toList());
return storagePosDtos;
}
return new ArrayList<>();
}
/**
* 盘点数据出库
*
* @param storagePosIdList
* @return
*/
@RequestMapping("/inventoryOut")
//@AnonymousAccess
public synchronized ResultBean inventoryOut(@RequestBody List<String> storagePosIdList) {
String msg = "";
String inventoryBatch = dataCache.getCache(INVENTORY_DATA) + "";
if (StringUtils.isBlank(inventoryBatch) || "-1".equals(inventoryBatch)) {
return ResultBean.newErrorResult(-1, "", "请点击开始盘点");
}
if (storagePosIdList == null || storagePosIdList.isEmpty()) {
return ResultBean.newErrorResult(-1, "smfcore.valueCanotNull", "{0}不能为空", new String[]{"库位"});
}
if (storagePosIdList != null && !storagePosIdList.isEmpty()) {
List<StoragePos> storagePosList = storagePosManager.findByQuery(inventoryQuery(null, null, storagePosIdList));
if (storagePosList == null || storagePosList.isEmpty()) {
return ResultBean.newErrorResult(-1, "smfcore.label.noReel", "未找到可出库的物料");
}
//核验是否已经盘点出库
List<String> posNameList = storagePosList.stream().map(StoragePos::getPosName).collect(Collectors.toList());
List<InventoryData> dataList = inventoryDataManager.findByQuery(new Query(Criteria.where("inventoryBatch").is(inventoryBatch).and("posName").in(posNameList)));
if (dataList != null && !dataList.isEmpty()) {
List<String> dataPosNameList = dataList.stream().map(InventoryData::getPosName).collect(Collectors.toList());
dataPosNameList = dataPosNameList.stream().distinct().collect(Collectors.toList());
return ResultBean.newErrorResult(-1, "", JsonUtil.toJsonStr(dataPosNameList) + "已经进行过盘点出库,请核实");
}
for (StoragePos pos : storagePosList) {
log.info("盘点出库的库位为:" + pos.getPosName());
Barcode barcode = pos.getBarcode();
if (barcode != null) {
log.info("盘点出库的物料为:" + barcode.getBarcode());
Storage storage = dataCache.getStorageById(pos.getStorageId());
barcode.setInventory(true);
barcode = barcodeManager.save(barcode);
//生成出库任务
DataLog dataLog = new DataLog(storage, barcode, pos);
dataLog.setType(OP.CHECKOUT);
dataLog.setCreator(SecurityUtils.getCurrentUsername());
dataLog.setExtendType(ExtendType.INVENTORY_CHECKOUT); //盘点出库
dataLog.setInventoryBatch(dataCache.getCache(INVENTORY_DATA));
try {
taskService.addTaskToExecute(dataLog);
} catch (Exception e) {
log.error("盘点出库失败:" + e.getMessage());
msg = StringUtils.isBlank(msg) ? dataLog.getBarcode() : msg + "," + dataLog.getBarcode();
continue;
}
}
//生成盘点数据
generateInventoryData(barcode, pos);
}
}
if (StringUtils.isNotBlank(msg)){
msg = msg +"已经有出入库任务请核实";
return ResultBean.newOkResult("","",msg);
}
return ResultBean.newOkResult("");
}
/**
* 批量盘点出库
* @param posName
* @return
*/
@RequestMapping("/batchInventoryOut")
public ResultBean batchInventoryOut(String posName) {
Pattern pattern = Pattern.compile(QueryHelp.escapeExprSpecialWord(posName), Pattern.CASE_INSENSITIVE);
List<StoragePos> storagePosList = storagePosManager.findByQuery(new Query(Criteria.where("posName").regex(pattern)));
List<String> storagePosIdList = storagePosList.stream().map(item -> item.getId()).collect(Collectors.toList());
return inventoryOut(storagePosIdList);
}
/**
* 料箱信息
*
* @param name
* @return
*/
@RequestMapping("/inventoryBoxInfo")
//@AnonymousAccess
public ResultBean inventoryBoxInfo(String name) {
//根据名称获取当前工位上的箱子
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 = BoxUtil.getBoxStr(currentRfid);
//查找barcode
Barcode barcode = barcodeManager.findByBarcode(boxStr);
List<PartitionInfo> partitionInfoList = BoxUtil.getPartitionInfo(currentRfid, barcode);
//盘点批次
String inventoryBatch = dataCache.getCache(INVENTORY_DATA) + "";
if (StringUtils.isNotBlank(inventoryBatch) && !"-1".equals(inventoryBatch)) {
//获取需要盘点的信息
List<InventoryData> dataList = inventoryDataManager.findByQuery(new Query(Criteria.where("inventoryBatch").is(inventoryBatch).and("box").is(boxStr).and("needInventory").is(true)));
if (dataList != null && !dataList.isEmpty()) {
if (partitionInfoList != null && !partitionInfoList.isEmpty()) {
for (InventoryData inventoryData : dataList) {
partitionInfoList = partitionInfoList.stream().map(item -> {
if (inventoryData.getBoxPartition().equals(item.getPartition())) {
//判断是否展示
if (inventoryData.getInventoryReelCount() < inventoryData.getReelCount()) {
item.setStatus(1);
}
item.setInventory(true);
item.setInventoryReelCount(inventoryData.getInventoryReelCount());
item.setInventoryAmount(inventoryData.getInventoryAmout());
item.setBarcodeList(inventoryData.getBarcodeList());
}
return item;
}).collect(Collectors.toList());
}
}
}
}
return ResultBean.newOkResult(partitionInfoList);
}
/**
* 料盘开始盘点
*
* @param paramMap
* @return
*/
@RequestMapping("/inventoryReel")
//@AnonymousAccess
public synchronized ResultBean inventoryReel(@RequestBody Map<String, String> paramMap) {
String name = paramMap.get("name");
String bacodeStr = paramMap.get("bacodeStr");
log.info("盘点人:" + SecurityUtils.getCurrentUsername() + ",工位为:" + name + ",物料编码为:" + bacodeStr);
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 errorMsg = inventoryReel(currentRfid, bacodeStr);
if (StringUtils.isNotBlank(errorMsg)) {
return ResultBean.newErrorResult(-1, "", "盘点失败:" + errorMsg);
}
return ResultBean.newOkResult("");
}
/**
* 盘点完成并入库
* @param paramMap
* @return
*/
@RequestMapping("/inventoryFinished")
//@AnonymousAccess
public ResultBean inventoryFinished(@RequestBody Map<String, String> paramMap) {
String code = paramMap.get("barcode"); //料箱条码
String name = paramMap.get("name"); //工位名称
List<Storage> storageList = new ArrayList<>();
List<String> cidList = Lists.newArrayList();
for (Storage storage : dataCache.getAllStorage().values()) {
if (storage.isType(new DeviceType[]{DeviceType.AGV_BOX})) {
storageList.add(storage);
cidList.add(storage.getCid());
break;
}
}
log.info("盘点完成并入库,条码为:{},工位为:{}", code, name);
Station station = StationCacheUtil.getStation(name);
if (station == null) {
return ResultBean.newErrorResult(-1, "", name + "工位信息未上传成功,请重试");
}
//先找可用料仓
if (storageList == null || storageList.isEmpty()) {
return ResultBean.newErrorResult(-1, "", "没有可以入库的料仓");
}
//得到箱子号
String boxStr = BoxUtil.getBoxStr(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[]{});
}
//判断是否盘点完成
boolean finished = BoxUtil.isInventoryFinished(boxStr);
if (!finished) {
return ResultBean.newErrorResult(-1, "", boxStr + "盘点未完成,请继续盘点");
}
//判断是否正在进行出入库任务
for (DataLog dataLog : taskService.getAllTasks()) {
if (dataLog.getBarcode().equals(boxStr)) {
if (!dataLog.isFinished()) {
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);
//如果盘点批次为空的话,则查找新的库位,否则用原来的库位
String inventoryBatch = dataCache.getCache(INVENTORY_DATA);
StoragePos pos = null;
if (StringUtils.isBlank(inventoryBatch) || "-1".equals(inventoryBatch)) {
pos = taskService.findEmptyPosForPutIn(storageList, boxBarcode, "", "");
} else {
InventoryData data = inventoryDataManager.findOne(
new Query(Criteria.where("inventoryBatch").is(inventoryBatch).and("box").is(boxStr))
.with(Sort.by(Sort.Direction.DESC, "createDate")));
String posName = data.getPosName();
pos = storagePosManager.getByPosName(posName);
}
if (pos == null) {
return ResultBean.newErrorResult(-1, "", boxStr + "未找到可用库位");
}
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[]{});
}
//生成入库任务
boxBarcode.setInventory(false);
barcodeManager.save(boxBarcode);
generateTask(dataCache.getStorageById(pos.getStorageId()), boxBarcode, pos, OP.PUT_IN, OP_STATUS.WAIT.name(), ExtendType.INVENTORY_PUTIN);
}
return ResultBean.newOkResult("");
}
/**
* 未盘点出库的箱子进行出库
*/
@RequestMapping("/noInventoryOut")
@AnonymousAccess
public ResultBean noInventoryOut(InventoryQuery query) {
//判断时间是否为空
BetweenData<Date> createDateBetween = query.getCreateDate();
if (createDateBetween == null || createDateBetween.isEmpty()) {
return ResultBean.newErrorResult(-1, "", "所选时间为空");
}
if (createDateBetween.getFrom().getTime() == createDateBetween.getTo().getTime()) {
createDateBetween.set(1, DateUtil.addDays(createDateBetween.getTo(),1));
query.setCreateDate(createDateBetween);
}
//判断批次是否为空
String inventoryBatch = dataCache.getCache(INVENTORY_DATA) + "";
if (StringUtils.isNotBlank(inventoryBatch)) {
return ResultBean.newErrorResult(-1, "", "请结束上一次盘点,再进行操作");
}
List<InventoryData> inventoryDataList = inventoryDataManager.findByQuery(QueryHelp.getQuery(query));
if (inventoryDataList == null || inventoryDataList.isEmpty()) {
return ResultBean.newErrorResult(-1, "", "所选时间内没有盘点过的料箱,请核实");
}
List<String> inventoryBoxList = inventoryDataList.stream().map(item -> item.getBox()).distinct().collect(Collectors.toList());
//2.得到agv料箱
Storage storage = null;
for (Storage stor : dataCache.getAllStorage().values()) {
if (stor.isStorage(DeviceType.AGV_BOX)) {
storage = stor;
break;
}
}
List<StoragePos> storagePosList = storagePosManager.findNotEmptyByStorageId(storage.getId());
List<String> storagePosIdList = storagePosList.stream().filter(item -> {
String barcode = item.getBarcode().getBarcode();
if (!inventoryBoxList.contains(barcode)) {
return true;
}
return false;
}).map(item -> item.getId()).collect(Collectors.toList());
//如果type == 1时,提醒要出库的物料
if ("1".equals(query.getType())) {
return ResultBean.newErrorResult(1, "", "当前需要盘点的料箱数量为:" + (storagePosIdList == null ? 0 : storagePosIdList.size()));
}
synchronized (this) {
//判断批次是否为空
String newBatch = dataCache.getCache(INVENTORY_DATA) + "";
if (StringUtils.isNotBlank(newBatch)) {
return ResultBean.newErrorResult(-1, "", "当前正在进行盘点出库,请核实");
}
dataCache.updateCache(INVENTORY_DATA, com.neotel.smfcore.common.utils.DateUtil.toDateString(System.currentTimeMillis(), "yyyyMMddHHmmssSSS"));
}
return inventoryOut(storagePosIdList);
}
private void generateTask(Storage storage, Barcode barcode, StoragePos pos, int type, String status,int extendType) {
//开始入库任务
DataLog task = new DataLog(storage, barcode, pos);
task.setType(type);
task.setStatus(status);
task.setOperator(SecurityUtils.getCurrentUsername());
task.setExtendType(extendType);
task.setBoxPosName(pos.getPosName());
task.setInventoryBatch(dataCache.getCache(INVENTORY_DATA));
taskService.addTaskToExecute(task);
}
private synchronized String inventoryReel(String currentRfid, String bacodeStr) {
String errorMsg = "";
//解析当前物料
CodeBean codeBean = codeResolve.resolveSingleCode(bacodeStr);
if (!codeBean.isValid()) {
return bacodeStr + "解析失败";
}
//当前料箱号
String boxStr = BoxUtil.getBoxStr(currentRfid);
//判断当前料箱是否为要盘点的料箱
Barcode boxBarcode = barcodeManager.findByBarcode(boxStr);
if (boxBarcode == null || !boxBarcode.isInventory()) {
return boxStr + "不是要盘点的料箱";
}
Barcode barcode = codeBean.getBarcode();
//判断是否在料箱中
String posName = barcode.getPosName();
if (StringUtils.isBlank(posName)) {
return barcode.getBarcode() + "不在料箱中,请核实";
}
//判断所在料箱与当前工位上的料箱是否一致
if (!posName.startsWith(boxStr)) {
return barcode.getBarcode() + "存在料箱中:" + barcode.getPosName() + "与当前工位上的料箱:" + boxStr + "不一致";
}
//判断料号是否正确
Map<String, Object> barandMap = lizhenApi.brandQty(barcode.getPartNumber(), barcode.getProvider());
if (barandMap.get("qty") == null) {
return barcode.getPartNumber() + "MES未返回料卷数量,未找到对应的料卷数量";
}
log.info(barcode.getBarcode() + "隔口信息:" + barcode.getPosName());
//开始查询盘点数据
//盘点批次
String inventoryBatch = dataCache.getCache(INVENTORY_DATA) + "";
if (StringUtils.isBlank(inventoryBatch) || "-1".equals(inventoryBatch)) {
return "当前没有要盘点的批次";
}
InventoryData data = inventoryDataManager.findOne(
new Query(Criteria.where("inventoryBatch").is(inventoryBatch).and("boxPartition").is(posName))
.with(Sort.by(Sort.Direction.DESC, "createDate")));
if (data != null) {
List<Barcode> barcodeList = data.getBarcodeList();
if (barcodeList != null && !barcodeList.isEmpty()) {
boolean hasBarocde = false;
for (Barcode bar : barcodeList) {
if (bar.getBarcode().equals(barcode.getBarcode())) {
hasBarocde = true;
break;
}
}
if (hasBarocde) {
return barcode.getBarcode() + "已经进行过盘点,请核实";
}
}
} else {
data = new InventoryData();
data.setBox(boxStr);
data.setBoxPartition(posName);
data.setPartNumber(barcode.getPartNumber());
data.setDescribe("");
InventoryData lastData = inventoryDataManager.findOne(new Query(Criteria.where("inventoryBatch").is(inventoryBatch).and("box").is(boxStr)).with(Sort.by(Sort.Direction.DESC, "createDate")));
if (lastData != null) {
data.setPosName(lastData.getPosName());
}
data.setReelCount(BoxUtil.getPartitionCount(posName, boxBarcode.getSubCodeList()));
data.setAmout(BoxUtil.getPartitionNum(posName, boxBarcode.getSubCodeList()));
data.setInventoryBatch(inventoryBatch + "");
data.setCreator(SecurityUtils.getCurrentUsername());
}
data.setInventoryReelCount(data.getInventoryReelCount() + 1);
data.setInventoryAmout(data.getInventoryAmout() + barcode.getAmount());
data.updateBarcodeList(barcode);
//判断是否完成
if (data.getInventoryReelCount() >= data.getReelCount() && data.getInventoryAmout() >= data.getAmout()) {
data.setStatus(InventoryStatus.FINISHED.name());
data.setMatch(true);
} else {
data.setStatus(InventoryStatus.EXECUTING.name());
}
//判断data是否需要盘点,如果不是,则改成需要盘点
if (!data.isNeedInventory()) {
data.setNeedInventory(true);
}
//设置创建人为当前盘点人
data.setCreator(SecurityUtils.getCurrentUsername());
inventoryDataManager.save(data);
//同时,把当前料箱的盘点人,都改成当前登录人
List<InventoryData> inventoryDataList = inventoryDataManager.findByQuery(new Query(Criteria.where("inventoryBatch").is(inventoryBatch).and("box").is(boxStr).and("oriPosName").is(data.getOriPosName())));
if (inventoryDataList != null && !inventoryDataList.isEmpty()){
for (InventoryData inventoryData : inventoryDataList) {
inventoryData.setCreator(SecurityUtils.getCurrentUsername());
inventoryDataManager.save(inventoryData);
}
}
return errorMsg;
}
/**
* 生成盘点数据
*
* @param barcode
* @param pos
*/
private synchronized void generateInventoryData(Barcode barcode, StoragePos pos) {
//判断盘点批次是否存在
String inventoryBatch = dataCache.getCache(INVENTORY_DATA);
//获取原始库位
String posName = pos.getPosName();
String oriPosName = posName.substring(0, posName.lastIndexOf("-"));
//开始处理数据
if (barcode == null) {
InventoryData data = new InventoryData();
data.setMatch(true);
data.setStatus(InventoryStatus.FINISHED.name());
data.setNeedInventory(false);
data.setCreator(SecurityUtils.getCurrentUsername());
data.setInventoryBatch(inventoryBatch);
data.setOriPosName(oriPosName);
data.setPosName(pos.getPosName());
inventoryDataManager.save(data);
} else {
List<Barcode> subCodeList = barcode.getSubCodeList();
String partition = getInventoryPartition(subCodeList);
String boxStr = barcode.getBarcode();
int count = boxStr.startsWith("CS") || boxStr.startsWith("CB") ? 8 : 2; //CS开头的8个隔口,其他是2个
for (int i = 1; i <= count; i++) {
String priPartition = boxStr + "-" + i;
InventoryData data = new InventoryData();
data.setBox(boxStr);
data.setBoxPartition(priPartition);
//料号
String partNumber = BoxUtil.getPartitionPartNumber(priPartition, subCodeList);
data.setPartNumber(partNumber);
//物料描述
data.setDescribe("");
//储位
data.setPosName(pos.getPosName());
//卷数
int partitionCount = BoxUtil.getPartitionCount(priPartition, subCodeList);
data.setReelCount(partitionCount);
//数量
int partitionNum = BoxUtil.getPartitionNum(priPartition, subCodeList);
data.setAmout(partitionNum);
data.setInventoryBatch(inventoryBatch);
data.setOriPosName(oriPosName);
if (partition.equals(boxStr + "-" + i)) {
data.setNeedInventory(true);
} else {
data.setNeedInventory(false);
data.setStatus(InventoryStatus.FINISHED.name());
}
if(subCodeList == null || subCodeList.isEmpty()){
data.setMatch(true);
}
inventoryDataManager.save(data);
}
}
}
/**
* 随机获取一个隔扣码进行返回
*
* @param subCodeList
* @return
*/
private String getInventoryPartition(List<Barcode> subCodeList) {
if (subCodeList != null && !subCodeList.isEmpty()) {
int index = new Random().nextInt(subCodeList.size());
return subCodeList.get(index).getPosName();
} else {
return "";
}
}
private Query inventoryQuery(String posName, String storageId, List<String> storagePosIdList) {
Query query = new Query();
if (storagePosIdList != null && !storagePosIdList.isEmpty()) {
query.addCriteria(Criteria.where("id").in(storagePosIdList));
}
if (StringUtils.isNotBlank(storageId)) {
query.addCriteria(Criteria.where("storageId").is(storageId)/*.and("used").is(true)*/);
}
if (StringUtils.isNotBlank(posName)) {
Pattern pattern = Pattern.compile(QueryHelp.escapeExprSpecialWord(posName), Pattern.CASE_INSENSITIVE);
query.addCriteria(Criteria.where("posName").regex(pattern));
}
//query.fields().include("barcode", "updateDate", "storageId","posName");
return query;
}
private List<String> getFinishInventoryPosName(String inventoryBatch,List<InventoryData> dataList) {
List<String> finishPosName = new ArrayList<>();
//List<InventoryData> dataList = inventoryDataManager.findByQuery(new Query(Criteria.where("inventoryBatch").is(inventoryBatch)));
//获取原始库位
List<String> oriPosNameList = dataList.stream().map(InventoryData::getOriPosName).collect(Collectors.toList());
oriPosNameList = oriPosNameList.stream().distinct().collect(Collectors.toList());
for (String oriPosName : oriPosNameList) {
boolean isFinished = true;
for (InventoryData data : dataList) {
if (data.getOriPosName().equals(oriPosName)){
if (!data.getStatus().equals(InventoryStatus.FINISHED.name())){
isFinished = false;
break;
}
}
}
if (isFinished) {
finishPosName.add(oriPosName);
}
}
return finishPosName;
}
}
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.service.manager.ILiteOrderItemManager;
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.enums.INOUT_TYPE;
import com.neotel.smfcore.custom.lizhen.agvBox.util.BoxUtil;
import com.neotel.smfcore.custom.lizhen.innerBox.enums.ExtendType;
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.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.stream.Collectors;
@Slf4j
@RestController
@RequestMapping("/outLine")
public class OutLineController {
@Autowired
private SmfApi smfApi;
@Autowired
private CodeResolve codeResolve;
@Autowired
private TaskService taskService;
@Autowired
private IStoragePosManager storagePosManager;
@Autowired
private IBarcodeManager barcodeManager;
@Autowired
private DataCache dataCache;
@Autowired
private ILiteOrderItemManager liteOrderItemManager;
@Autowired
private LizhenApi lizhenApi;
/*
* key为工位信息,value为上一个隔口信息
*/
private Map<String, String> lastBoxPartitionMap = new ConcurrentHashMap<>();
/**
* key 为料箱号
* value 为数量
*/
private static Map<String, Integer> boxAllCountMap = new ConcurrentHashMap<>();
/**
* key为箱号
* value为A、B面
*/
private static Map<String,String> boxSideMap = new ConcurrentHashMap<>();
//扫码入库
@ApiOperation("线外扫码入库")
@RequestMapping("/operatePos")
@AnonymousAccess
public ResultBean operatePos(@RequestBody Map<String, String> paramMap) {
String name = paramMap.get("name"); //当前工位名称
String code = paramMap.get("code"); //传入的物料信息
String size = paramMap.get("size"); //尺寸信息
String warehouseCode = paramMap.get("warehouseCode");//库别
String force = paramMap.get("force"); //强制入库
String boxSideStr = paramMap.get("boxSide"); //箱子面
if (StringUtils.isBlank(name)) {
return ResultBean.newErrorResult(-1, "smfcore.valueCanotNull", "{0}不能为空", new String[]{"工位信息"});
}
if (StringUtils.isBlank(code)) {
return ResultBean.newErrorResult(-1, "smfcore.valueCanotNull", "{0}不能为空", new String[]{"条码编号"});
}
code = code.toUpperCase();
if (StringUtils.isBlank(warehouseCode)) {
return ResultBean.newErrorResult(-1, "smfcore.valueCanotNull", "{0}不能为空", new String[]{"库别"});
}
if (StringUtils.isBlank(size)) {
return ResultBean.newErrorResult(-1, "smfcore.valueCanotNull", "{0}不能为空", new String[]{"尺寸"});
}
if (StringUtils.isBlank(boxSideStr)) {
return ResultBean.newErrorResult(-1, "smfcore.valueCanotNull", "{0}不能为空", new String[]{"箱子面"});
}
if ("7".equals(size)) {
size = "7X8";
} else if ("13".equals(size)) {
size = "13X24";
} else if ("15".equals(size)) {
size = "15X32";
}
//解析条码
int platSize = getPlatsizeOrHeight(size, 0);
int height = getPlatsizeOrHeight(size, 1);
String codeStr = "=" + platSize + "x" + height + "=" + code;
CodeBean codeBean = codeResolve.resolveSingleCode(codeStr);
if (!codeBean.isValid()) {
return ResultBean.newErrorResult(-1, "smfcore.error.barcode.noValidCode", "条码无效");
}
Barcode barcode = codeBean.getBarcode();
String boxStr = "";
String boxPartition = "";
//判断是否隔口或者是物料
if (isBoxPartition(barcode.getPartNumber())) {
boolean canPutIn = BoxUtil.isCanPutIn(code);
if (!canPutIn){
return ResultBean.newErrorResult(-1,"","无效的隔口码:"+code);
}
//如果是隔口,获取到料箱号
boxStr = barcode.getBarcode();
//判断尺寸与箱子是否一致
if (platSize == 7) {
if (!code.startsWith("CS") && !code.startsWith("CB")) {
return ResultBean.newErrorResult(-1, "", "物料规格为7寸与当前工位上的料箱:" + boxStr + "不匹配");
}
} else if (platSize == 15) {
if (!code.startsWith("CM")) {
return ResultBean.newErrorResult(-1, "", "物料规格为15寸与当前工位上的料箱:" + boxStr + "不匹配");
}
}
boxPartition = code;
lastBoxPartitionMap.put(name, code);
//判断当前是否有正在执行的任务
DataLog dataLog = getExecutingTaskByBarcode(barcode.getBarcode());
if (dataLog != null) {
if (dataLog.isPutInTask()) {
//已有入库任务
return ResultBean.newErrorResult(-1, "", "物料:" + dataLog.getBarcode() + "已有入库任务,需继续执行入库动作");
} else if (dataLog.isCheckOutTask()) {
//已有出库任务
return ResultBean.newErrorResult(-1, "", "物料:" + dataLog.getBarcode() + "已有出库任务,需继续执行出库动作");
}
}
//判断是否存在库位中
/*StoragePos pos = storagePosManager.getByBarcode(barcode.getBarcode());
if (pos != null) {
return ResultBean.newErrorResult(-1, "smfcore.shelf.msg.alreadyInPos", "该物料已在库位[{0}]中", new String[]{pos.getPosName()});
}*/
//设置操作人
//barcode.setCreator(SecurityUtils.getCurrentUsername());
barcodeManager.save(barcode);
} else {
//判断物料的长度
String barcodeStr = barcode.getBarcode();
if (barcodeStr.length() < 16 || barcodeStr.length() > 22) {
return ResultBean.newErrorResult(-1, "smfcore.error.barcode.wrongLength", "条码[{0}]长度错误", new String[]{barcodeStr});
}
if (StringUtils.isNotBlank(barcode.getBatch())) {
int batchLength = barcode.getBatch().length();
if (batchLength > 36) {
return ResultBean.newErrorResult(-1, "", barcode.getBatch() + "请核实L/C长度是否小于36位");
}
}
if (StringUtils.isNotBlank(barcode.getDateCode())) {
int dateLength = barcode.getDateCode().length();
if (dateLength > 36) {
return ResultBean.newErrorResult(-1, "", barcode.getDateCode() + "请核实D/C长度是否小于36位");
}
}
//判断是否已经扫描隔口工位
boxPartition = lastBoxPartitionMap.get(name);
if (StringUtils.isBlank(boxPartition)) {
return ResultBean.newErrorResult(-1, "smfcore.valueNotExist", "{0}[{1}]不存在", new String[]{"隔口信息"});
}
//获取料箱号,得到
boxStr = getBoxStrbyBoxPartition(boxPartition);
if (!boxPartition.startsWith(boxStr)) {
return ResultBean.newErrorResult(-1, "", "请先扫描料箱隔口码,再扫描物料二维码");
}
//判断是否存在其他料箱中
String posName = getPosNameBySubcode(barcode.getBarcode());
if (StringUtils.isNotBlank(posName)) {
return ResultBean.newErrorResult(-1, "", "物料" + barcode.getBarcode() + "已存在料箱:" + barcode.getPosName());
}
//判断是否强制入库,为1时验证,否则不验证
if ("0".equals(force)) {
try {
smfApi.canPutInAfterResolve(barcode);
} catch (ValidateException e) {
e.printStackTrace();
return ResultBean.newErrorResult(-2, "", e.getMessage());
}
}
//判断物料是否过期
Date expireDate = barcode.getExpireDate();
if (expireDate != null) {
if (System.currentTimeMillis() > expireDate.getTime()) {
return ResultBean.newErrorResult(-1,"smfcore.error.barcode.expired", "物料已过期,无法入库.");
}
}
//校验是否可以入库
Map<String, Object> brandQty = lizhenApi.brandQty(barcode.getPartNumber(), barcode.getProvider());
if (brandQty == null || brandQty.isEmpty()) {
return ResultBean.newErrorResult(-1, "smfcore.error.barcode.partNumber.invalid", "{0}不是有效的料号", new String[]{barcode.getPartNumber()});
}
//获取mes数量
Barcode barcodeApi = lizhenApi.barcodeInfo(barcode);
//如果是L开头的去量测
if (barcode.getBarcode().startsWith("L") || barcode.getBarcode().startsWith("l")) {
boolean check = lizhenApi.checkReelMeasure(barcode);
if (!check) {
return ResultBean.newErrorResult(-1, "", barcode.getBarcode() + "散料未量测");
}
} else {
if (barcodeApi != null) {
//判断返回过来的物料数量与标签上的是否一致,如果不一致,则调用散料量测接口
if (barcodeApi.getAmount() != barcode.getLabelAmount()) {
boolean check = lizhenApi.checkReelMeasure(barcode);
if (!check) {
return ResultBean.newErrorResult(-1, "", barcode.getBarcode() + "散料未量测");
}
}
}
}
if (barcodeApi != null){
barcode = barcodeApi;
}
barcode.setReelAmount(1);
barcode.setWarehouseCode(warehouseCode);
barcode.setPosName(boxPartition);
Date date = new Date();
barcode.setPutInTime(date.getTime());
barcode.setPutInDate(date);
barcode.setCreator(SecurityUtils.getCurrentUsername());
String result = finishTask(boxStr, OP.PUT_IN, barcode, barcode.getAmount(), OP_STATUS.FINISHED.name(), ExtendType.MANUAL_PUTIN);
if (StringUtils.isNotBlank(result)) {
return ResultBean.newErrorResult(-1, "", result);
}
}
return ResultBean.newOkResult(getBoxPartitionNum(boxStr, boxSideStr, boxPartition));
}
@ApiOperation("完成装箱并入库")
@RequestMapping("/finishBoxPutIn")
@AnonymousAccess
public synchronized ResultBean finishBoxPutIn(@RequestBody Map<String, String> paramMap) {
String code = paramMap.get("barcode"); //料箱条码
String name = paramMap.get("name"); //工位名称
String cids = paramMap.get("cids");
boolean isVirtual = StringUtils.isNotBlank(paramMap.get("isVirtual")) ? Boolean.valueOf(paramMap.get("isVirtual")) : false;
String posName = paramMap.get("posName"); //库位
for (Storage storage : dataCache.getAllStorage().values()) {
if (storage.isType(new DeviceType[]{DeviceType.AGV_BOX})) {
cids = storage.getCid();
break;
}
}
log.info("线外入库完成装箱并入库,条码为:{},工位为:{}", code, name);
//得到箱子号
String boxStr = getBoxStrbyBoxPartition(code);
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) {
if (!storage.isVirtual()) {
storageList.add(storage);
cidList.add(cid);
}
}
}
if (storageList.isEmpty()) {
return ResultBean.newErrorResult(-1, "", "没有可以入库的料仓", new String[]{});
}
DataLog dataLog = getExecutingTaskByBarcode(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);
//校验是否已经存在库位
/*if (StringUtils.isNotBlank(boxBarcode.getPosName())) {
return ResultBean.newErrorResult(-1, "smfcore.storagePos.existBarcode", "{}已存在库位{}中", new String[]{boxBarcode.getBarcode(), boxBarcode.getPosName()});
}*/
StoragePos storagePos = storagePosManager.getByBarcode(boxBarcode.getBarcode());
if (storagePos != null){
return ResultBean.newErrorResult(-1, "smfcore.storagePos.existBarcode", "{}已存在库位{}中", new String[]{boxBarcode.getBarcode(), storagePos.getPosName()});
}
//判断是否盘点完成
boolean finished = BoxUtil.isInventoryFinished(boxStr);
if (!finished) {
return ResultBean.newErrorResult(-1, "", boxStr + "盘点未完成,请继续盘点");
}
boxBarcode.setInventory(false);
boxBarcode.setCreator(SecurityUtils.getCurrentUsername());
boxBarcode = barcodeManager.save(boxBarcode);
//如果不是虚拟仓的
if (!isVirtual) {
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[]{});
}
}
//生成任务
finishTask(boxStr, OP.CHECKOUT, null, OP_STATUS.CANCEL.name(), INOUT_TYPE.CANCEL_ONE.name());
boxAllCountMap.remove(boxStr);
generateTask(dataCache.getStorageById(pos.getStorageId()), boxBarcode, pos, OP.PUT_IN, OP_STATUS.WAIT.name(), null,ExtendType.STORAGE_PUTIN);
taskService.removePosName(boxStr);
} else { //入虚拟仓
finishTask(boxStr, OP.CHECKOUT, null, OP_STATUS.CANCEL.name(), INOUT_TYPE.CANCEL_ONE.name());
boxAllCountMap.remove(boxStr);
boxSideMap.remove(boxStr);
boxBarcode = barcodeManager.findByBarcode(boxStr);
StoragePos pos = intoVirtualPos(boxBarcode,posName);
DataLog task = generateTask(dataCache.getStorageById(pos.getStorageId()), boxBarcode, pos, OP.PUT_IN, OP_STATUS.FINISHED.name(), null,ExtendType.VIRTUAL_PUTIN);
taskService.moveTaskToFinished(task);
taskService.updateFinishedTask(task);
taskService.removeFinishedTask(task);
taskService.removePosName(boxStr);
}
return ResultBean.newOkResult("");
}
@ApiOperation("线外扫码出库")
@RequestMapping("/checkOut")
//@AnonymousAccess
public ResultBean checkOut(@RequestBody Map<String, String> paramMap) {
String code = paramMap.get("code");
code = code.toUpperCase();
//判断是否整箱出库
if (isBoxPartition(code) && (code.endsWith("A") || code.endsWith("B"))) {
return finishTask(code, OP.CHECKOUT, null, OP_STATUS.FINISHED.name(), INOUT_TYPE.OUT_BOX.name());
}
//判断是否隔口出库
else if (isBoxPartition(code) && code.indexOf("-") != -1) {
return finishTask(code, OP.CHECKOUT, null, OP_STATUS.FINISHED.name(), INOUT_TYPE.OUT_PARTITION.name());
}
//判断是否属于料盘出库
else {
return finishTask(code, OP.CHECKOUT, null, OP_STATUS.FINISHED.name(), INOUT_TYPE.OUT_ONE.name());
}
}
private synchronized ResultBean finishTask(String boxStr, int opType,
Barcode barcode, String opStatus,
String inoutType) {
ResultBean resultBean = ResultBean.newOkResult("");
//判断是否为整箱出库
if (INOUT_TYPE.OUT_BOX.name().equals(inoutType)) {
//根据箱子号 找到barcode
boxStr = getBoxStrbyBoxPartition(boxStr);
Barcode pidBarcode = barcodeManager.findByBarcode(boxStr);
boolean hasBrand = false;
String orderItemIdStr = "";
//根据料箱获取到全部的物料
List<Barcode> subCodes = pidBarcode.getSubCodeList();
if (subCodes == null || subCodes.isEmpty()) {
return ResultBean.newErrorResult(-1, "", "料箱:" + pidBarcode.getBarcode() + ",没有可出库的物料");
}
//判断是否全部出库
for (Barcode subCode : subCodes) {
if (!subCode.isOut()) {
return ResultBean.newErrorResult(-1, "", pidBarcode.getBarcode() + "不允许全部取出,请核实");
}
}
finishVirtualTask(boxStr);
List<DataLog> dataLogList = new ArrayList<>();
//开始循环,生成任务
for (int index = 0; index < subCodes.size();/*; index++*/) {
Barcode subCode = subCodes.get(index);
String orderItemId = subCode.getOrderItemId();
//判断是否管控厂商
if (StringUtils.isNotBlank(orderItemId)) {
LiteOrderItem orderItem = liteOrderItemManager.get(orderItemId);
if (orderItem != null) {
if (StringUtils.isNotBlank(orderItem.getBrand())) {
hasBrand = true;
}
if (StringUtils.isNotBlank(orderItem.getOrderNo())) {
if (!orderItem.getOrderNo().equals(orderItemIdStr)) {
orderItemIdStr = orderItem.getOrderNo();
}
}
}
}
//生成任务
int amount = subCode.getAmount();
subCode.setAmount(0);
pidBarcode.UpdateSubCode(subCode);
pidBarcode.setReelAmount(pidBarcode.getReelAmount() - 1);
pidBarcode.setAmount(pidBarcode.getAmount() - amount);
pidBarcode = barcodeManager.save(pidBarcode);
int extendType = StringUtils.isNotBlank(subCode.getOrderItemId()) ? ExtendType.VIRTUAL_PICKING_DETAIL : ExtendType.VIRTUAL_CHECKOUT;
DataLog dataLog = generateTask(subCode, opStatus, amount, opType, orderItemId, extendType, true);
dataLogList.add(dataLog);
log.info("整箱出库,生成出库任务,barcode:" + subCode.getBarcode() + ",料箱号为:" + pidBarcode.getBarcode());
if (subCode.getAmount() <= 0) {
subCode.setAmount(amount);
subCode.setSelectMsg(null);
subCode.setOut(false);
subCode.setOrderItemId(null);
subCode.setPosName(null);
subCode.setHostBarcodeId(null);
subCode.setStorageId(null);
barcodeManager.save(subCode);
}
}
if (dataLogList != null && !dataLogList.isEmpty()) {
taskService.outTaskStatusChange(dataLogList);
}
resultBean.setData(getBoxInfo(boxStr));
if (hasBrand) {
resultBean.setCode(3);
return resultBean;
}
if (StringUtils.isNotBlank(orderItemIdStr)) {
resultBean.setMsg("工单号为:" + orderItemIdStr);
}
}
//判断是否隔口出库
else if (INOUT_TYPE.OUT_PARTITION.name().equals(inoutType)) {
//根据箱子号 找到barcode
String newboxStr = boxStr.substring(0, boxStr.indexOf("-"));
Barcode pidBarcode = barcodeManager.findByBarcode(newboxStr);
boolean hasBrand = false;
String orderItemIdStr = "";
List<Barcode> needOutBarcodes = new ArrayList<>();
List<Barcode> subCodes = pidBarcode.getSubCodeList();
if (subCodes != null && !subCodes.isEmpty()) {
for (Barcode subCode : subCodes) {
if (boxStr.equals(subCode.getPosName())) {
needOutBarcodes.add(subCode);
}
}
}
if (needOutBarcodes == null || needOutBarcodes.isEmpty()) {
return ResultBean.newErrorResult(-1, "", "料箱隔口:" + boxStr + "扫描错误");
}
//判断是否全部出库
for (Barcode subCode : needOutBarcodes) {
if (!subCode.isOut()) {
return ResultBean.newErrorResult(-1, "", boxStr + "不允许全部出库,请核实");
}
}
finishVirtualTask(boxStr);
List<DataLog> dataLogList = new ArrayList<>();
for (int index = 0; index < needOutBarcodes.size(); index++) {
Barcode subCode = needOutBarcodes.get(index);
String orderItemId = subCode.getOrderItemId();
if (StringUtils.isNotBlank(orderItemId)) {
LiteOrderItem orderItem = liteOrderItemManager.get(orderItemId);
if (orderItem != null) {
if (StringUtils.isNotBlank(orderItem.getBrand())) {
hasBrand = true;
}
if (StringUtils.isNotBlank(orderItem.getOrderNo())) {
if (!orderItem.getOrderNo().equals(orderItemIdStr)) {
orderItemIdStr = orderItem.getOrderNo();
}
}
}
}
int amount = subCode.getAmount();
subCode.setAmount(0);
pidBarcode.UpdateSubCode(subCode);
pidBarcode.setReelAmount(pidBarcode.getReelAmount() - 1);
pidBarcode.setAmount(pidBarcode.getAmount() - amount);
pidBarcode = barcodeManager.save(pidBarcode);
int extendType = StringUtils.isNotBlank(subCode.getOrderItemId()) ? ExtendType.VIRTUAL_PICKING_DETAIL : ExtendType.VIRTUAL_CHECKOUT;
DataLog dataLog = generateTask(subCode, opStatus, amount, opType, orderItemId, extendType, true);
dataLogList.add(dataLog);
log.info("隔口出库,生成出库任务,barcode:" + subCode.getBarcode() + ",料箱号为:" + subCode.getPosName());
log.info("箱子数量为:" + pidBarcode.getAmount() + ",物料数量为:" + pidBarcode.getReelAmount() + "箱号为:" + pidBarcode.getBarcode());
if (subCode.getAmount() <= 0) {
subCode.setAmount(amount);
subCode.setSelectMsg(null);
subCode.setOut(false);
subCode.setOrderItemId(null);
subCode.setPosName(null);
subCode.setHostBarcodeId(null);
subCode.setStorageId(null);
barcodeManager.save(subCode);
}
//}
}
if (dataLogList != null && !dataLogList.isEmpty()){
taskService.outTaskStatusChange(dataLogList);
}
resultBean.setData(getBoxInfo(newboxStr));
if (hasBrand) {
resultBean.setCode(3);
return resultBean;
}
if (StringUtils.isNotBlank(orderItemIdStr)) {
resultBean.setMsg("工单号为:" + orderItemIdStr);
}
}
//判断是否为单盘出库
else if (INOUT_TYPE.OUT_ONE.name().equals(inoutType)) {
CodeBean code = codeResolve.resolveSingleCode(boxStr);
if (!code.isValid()) {
return ResultBean.newErrorResult(-1, "smfcore.error.barcode.noValidCode", "条码无效");
}
barcode = code.getBarcode();
boxStr = barcode.getPosName();
if (StringUtils.isBlank(boxStr)) {
return ResultBean.newErrorResult(-1, "", barcode.getBarcode() + "不存在此料箱中");
}
boxStr = boxStr.substring(0, boxStr.indexOf("-"));
//根据箱子号 找到barcode
Barcode pidBarcode = barcodeManager.findByBarcode(boxStr);
boolean hasBrand = false; //是否提示管控厂商
/*try {
smfApi.canPutInAfterResolve(barcode);
} catch (ValidateException e) {
e.printStackTrace();
return ResultBean.newErrorResult(-1, "", e.getMessage());
}*/
List<Barcode> subCodes = pidBarcode.getSubCodeList();
if (subCodes == null || subCodes.isEmpty()) {
return ResultBean.newErrorResult(-1, "", "料箱:" + boxStr + ",没有可出库的物料");
}
//判断当前料箱是否包含此物料
boolean hasBarcode = false;
String orderItemIdStr = "";
String selectMsg = "";
String barcodeStr = barcode.getBarcode();
for (Barcode subCode : subCodes) {
if (barcodeStr.equals(subCode.getBarcode())) {
hasBarcode = true;
}
if (StringUtils.isNotBlank(barcode.getSelectMsg())) {
selectMsg = barcode.getSelectMsg();
}
if (barcode.getBarcode().equals(subCode.getBarcode())) {
barcode = subCode;
}
}
if (!hasBarcode) {
return ResultBean.newErrorResult(-1, "", barcodeStr + "不在料箱:" + boxStr + "请核实是否已经出库");
}
//判断查询条件是否一致
if (StringUtils.isNotBlank(selectMsg)) {
if (StringUtils.isBlank(barcode.getSelectMsg())) {
return ResultBean.newErrorResult(-1, "", "请核实与查询条件:" + selectMsg + "是否一致");
}
}
finishVirtualTask(boxStr);
//判断当前隔口是否有要出的任务
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;
}
if (StringUtils.isNotBlank(orderItem.getOrderNo())) {
if (!orderItem.getOrderNo().equals(orderItemIdStr)) {
orderItemIdStr = orderItem.getOrderNo();
}
}
}
}
int amount = barcode.getAmount();
barcode.setAmount(0);
pidBarcode.UpdateSubCode(barcode);
pidBarcode.setReelAmount(pidBarcode.getReelAmount() - 1);
pidBarcode.setAmount(pidBarcode.getAmount() - amount);
pidBarcode = barcodeManager.save(pidBarcode);
int extendType = StringUtils.isNotBlank(barcode.getOrderItemId()) ? ExtendType.VIRTUAL_PICKING_DETAIL : ExtendType.VIRTUAL_CHECKOUT;
generateTask(barcode, opStatus, amount, opType, orderItemId,extendType,false);
log.info("物料出库,生成出库任务,barcode:" + barcode.getBarcode() + ",隔口号为:" + barcode.getPosName());
if (barcode.getAmount() <= 0) {
barcode.setAmount(amount);
barcode.setSelectMsg(null);
barcode.setOut(false);
barcode.setOrderItemId(null);
barcode.setPosName(null);
barcode.setHostBarcodeId(null);
barcode.setStorageId(null);
barcodeManager.save(barcode);
}
} else {
if (subCodes != null && !subCodes.isEmpty()) {
//获取到需要出库的物料,进行更改
Barcode barcodeByOut = null;
for (Barcode subCode : subCodes) {
//判断料箱隔口是否一致
if (subCode.getPosName().equals(barcode.getPosName())) {
if (subCode.isOut() && StringUtils.isNotBlank(subCode.getOrderItemId())) {
barcodeByOut = subCode;
break;
}
}
}
if (barcodeByOut != null) {
String orderItemId = barcodeByOut.getOrderItemId();
barcodeByOut.setOut(false);
barcodeByOut.setOrderItemId(null);
barcodeByOut.setSelectMsg(null);
barcodeByOut = barcodeManager.save(barcodeByOut);
pidBarcode.UpdateSubCode(barcodeByOut);
pidBarcode = barcodeManager.save(pidBarcode);
//互换,要出的和隔口中的数据
int amount = barcode.getAmount();
barcode.setAmount(0);
barcode.setOrderItemId(orderItemId);
pidBarcode.setReelAmount(pidBarcode.getReelAmount() - 1);
pidBarcode.setAmount(pidBarcode.getAmount() - amount);
pidBarcode.UpdateSubCode(barcode);
pidBarcode = barcodeManager.save(pidBarcode);
int extendType = StringUtils.isNotBlank(barcode.getOrderItemId()) ? ExtendType.VIRTUAL_PICKING_DETAIL : ExtendType.VIRTUAL_CHECKOUT;
generateTask(barcode, opStatus, amount, opType, orderItemId,extendType,false);
log.info(barcode.getBarcode() + "不是出库任务," + barcodeByOut.getBarcode() + "需更改out为false");
log.info("物料出库,生成出库任务,barcode:" + barcode.getBarcode() + ",隔口号为:" + barcode.getPosName());
if (barcode.getAmount() <= 0) {
barcode.setAmount(amount);
barcode.setSelectMsg(null);
barcode.setOut(false);
barcode.setOrderItemId(null);
barcode.setPosName(null);
barcode.setHostBarcodeId(null);
barcode.setStorageId(null);
barcodeManager.save(barcode);
}
isOut = true;
if (StringUtils.isNotBlank(orderItemId)) {
LiteOrderItem orderItem = liteOrderItemManager.get(orderItemId);
if (orderItem != null) {
if (StringUtils.isNotBlank(orderItem.getBrand())) {
hasBrand = true;
}
if (StringUtils.isNotBlank(orderItem.getOrderNo())) {
if (!orderItem.getOrderNo().equals(orderItemIdStr)) {
orderItemIdStr = orderItem.getOrderNo();
}
}
}
}
}
}
}
if (!isOut) {
return ResultBean.newErrorResult(-1, "", barcode.getBarcode() + "不需要出库");
}
resultBean.setData(getBoxInfo(boxStr));
if (hasBrand) {
log.info("hasBrand--" + hasBrand);
resultBean.setCode(3);
return resultBean;
}
if (StringUtils.isNotBlank(orderItemIdStr)) {
resultBean.setMsgKey(null);
resultBean.setMsg("工单号为:" + orderItemIdStr);
}
}
//任务取消
else if (INOUT_TYPE.CANCEL_ONE.name().equals(inoutType)) {
finishVirtualTask(boxStr);
//根据箱子号 找到barcode
Barcode pidBarcode = barcodeManager.findByBarcode(boxStr);
//判断是否有要出库的任务,给取消掉
List<Barcode> subCodes = pidBarcode.getSubCodeList();
if (subCodes != null && !subCodes.isEmpty()) {
for (Barcode subCode : subCodes) {
if (subCode.isOut()) {
String orderItemId = subCode.getOrderItemId();
subCode.setOut(false);
subCode.setSelectMsg(null);
subCode.setOrderItemId(null);
subCode = barcodeManager.save(subCode);
pidBarcode.UpdateSubCode(subCode);
pidBarcode = barcodeManager.save(pidBarcode);
generateTask(subCode, opStatus, subCode.getAmount(), opType, orderItemId,ExtendType.TASK_CANNEL,false);
log.info("点击完成扫码并入库,任务取消,barcode:" + subCode.getBarcode() + ",OrderItemId为:" + orderItemId);
}
}
}
}
return resultBean;
}
private DataLog generateTask(Barcode barcode, String opStatus, int opQty, int opType, String orderItemId,int extendType,boolean isBoxOut) {
//生成任务
DataLog task = new DataLog();
task.setStatus(opStatus);
task.setPartNumber(barcode.getPartNumber());
task.setBarcode(barcode.getBarcode());
task.setNum(opQty);
task.setType(opType);
task.setPosName(barcode.getPosName());
task.setOperator(SecurityUtils.getCurrentUsername());
task.setDateCode(barcode.getDateCode());
task.setBatchInfo(barcode.getBatch());
task.setProvider(barcode.getProvider());
task.setProviderNumber(barcode.getProviderNumber());
task.setKeeperCode(barcode.getKeeperCode());
//task.setReelPosName(barcode.getPosName());
task.setSubSourceId(orderItemId);
task.setWarehouseCode(barcode.getWarehouseCode());
task.setExtendType(extendType);
if (StringUtils.isNotBlank(orderItemId)) {
LiteOrderItem orderItem = liteOrderItemManager.get(orderItemId);
if (orderItem != null) {
task.setSourceName(orderItem.getOrderNo());
task.setLine(orderItem.getLine());
task.setMo(orderItem.getMo());
task.setSide(orderItem.getSide());
task.setPlantCode(orderItem.getPlantCode());
task.setOrderNo(orderItem.getOrderNo());
task.setManualUpload(orderItem.isManualUpload());
}
}
String boxStr = BoxUtil.getBoxStr(barcode.getPosName());
if (StringUtils.isNotBlank(boxStr)){
String posName = taskService.getPosName(boxStr);
if (StringUtils.isNotBlank(posName)){
task.setStoragePosName(posName);
}
}
task.setBoxOut(isBoxOut);
if (barcode.getPutInTime() != -1){
task.setFristPutInDate(new Date(barcode.getPutInTime()));
} else {
task.setFristPutInDate(barcode.getPutInDate());
}
task.setDescribe(barcode.getDescribe());
taskService.updateFinishedTask(task);
return task;
}
@ApiOperation("获取虚拟仓正在出库的列表")
@RequestMapping("/getVirtualOutTask")
@AnonymousAccess
public ResultBean getVirtualOutTask(@RequestBody Map<String, String> paramMap) {
String orderNo = paramMap.get("orderNo");
List<DataLog> tasks = getVirtualOutTask(orderNo);
return ResultBean.newOkResult(tasks);
}
@ApiOperation("料箱中的数量")
@RequestMapping("/getOutBoxNum")
@AnonymousAccess
public ResultBean getOutBoxNum(@RequestBody Map<String, String> paramMap) {
String code = paramMap.get("code");
//code = getBoxStrbyBoxPartition(code);
//判断是否有出库任务,如果有就完成
Map<String, Object> resultMap = getBoxInfo(code);
return ResultBean.newOkResult(resultMap);
}
/**
* 虚拟仓任务完成
* @param code
*/
private void finishVirtualTask(String code) {
DataLog task = null;
Collection<DataLog> queueTasks = taskService.getQueueTasks();
for (DataLog queueTask : queueTasks) {
if (code.startsWith(queueTask.getBarcode()) && queueTask.isCheckOutTask()) {
task = queueTask;
break;
}
}
if (task != null) {
taskService.addBoxPosName(task);
log.info("虚拟仓出库,已有出库任务,直接完成:" + task.getBarcode());
task.setStatus(OP_STATUS.FINISHED.name());
if (task.getExtendType() == -1){
task.setExtendType(ExtendType.VIRTUAL_CHECKOUT);
}
//task.setExtendType(ExtendType.VIRTUAL_CHECKOUT);
taskService.moveTaskToFinished(task);
taskService.updateFinishedTask(task);
StoragePos pos = storagePosManager.getByBarcode(task.getBarcode());
if (pos != null) {
Barcode barcode = barcodeManager.findByBarcode(task.getBarcode());
barcode.setPosName(null);
barcodeManager.save(barcode);
pos.setBarcode(null);
pos.setUsed(false);
storagePosManager.save(pos);
dataCache.updateInventory(pos, barcode);
List<Barcode> subCodeList = barcode.getSubCodeList();
if (subCodeList != null && !subCodeList.isEmpty()) {
for (Barcode subCode : subCodeList) {
dataCache.updateInventoryAmount(dataCache.getStorageById(pos.getStorageId()).getCid(), subCode.getPartNumber(), -subCode.getAmount());
}
}
}
}
}
private StoragePos intoVirtualPos(Barcode barcode, String posName) {
//判断有没有空库位
Storage storage = null;
Collection<Storage> storages = dataCache.getAllStorage().values();
for (Storage stor : storages) {
if (stor.isVirtual()) {
storage = stor;
break;
}
}
StoragePos pos = storagePosManager.findOneEmptyPosNameByStorageId(storage.getId(), posName);
if (pos != null) {
posName = posName + "-" + pos.getId();
} else {
pos = new StoragePos();
pos.setStorageId(storage.getId());
pos = storagePosManager.save(pos);
posName = posName + "-" + pos.getId();
}
barcode.setPosName(posName);
Date date = new Date();
barcode.setPutInTime(date.getTime());
barcode.setPutInDate(date);
//同时,更改虚拟仓缓存
dataCache.updateInventory(pos, barcode);
List<Barcode> subCodeList = barcode.getSubCodeList();
if (subCodeList != null && !subCodeList.isEmpty()) {
for (Barcode subCode : subCodeList) {
subCode.setStorageId(storage.getId());
barcodeManager.save(subCode);
dataCache.updateInventoryAmount(storage.getCid(), subCode.getPartNumber(), subCode.getAmount());
}
}
barcode.setSubCodeList(subCodeList);
barcode = barcodeManager.save(barcode);
pos.setStorageId(storage.getId());
pos.setPosName(posName);
pos.setBarcode(barcode);
pos.setUsed(true);
pos.setUpdateDate(new Date());
pos = storagePosManager.save(pos);
return pos;
}
private Map<String, Object> getBoxInfo(String code) {
Map<String, Object> resultMap = new HashMap<>();
String platsize = "";
int boxAllCount = 0;
int boxRemainingCount = 0;
String boxStr = "";
String msg = "";
List<List<Integer>> boxPartitionCounts = new ArrayList<>();
if (StringUtils.isNotBlank(code)) {
if (code.startsWith("CS") || code.startsWith("CM") || code.startsWith("CB")) {
String endStr = code.substring(code.length() - 1); //得到是A、B面
boxStr = getBoxStrbyBoxPartition(code);
if (boxSideMap.get(boxStr) != null) {
endStr = boxSideMap.get(boxStr);
} else {
boxSideMap.put(boxStr,endStr);
}
//1、获取料箱的
Barcode barcode = barcodeManager.findByBarcode(boxStr);
if (barcode != null) {
List<Barcode> subCodeList = barcode.getSubCodeList();
if (subCodeList != null && !subCodeList.isEmpty()) {
if (boxAllCountMap.get(boxStr) == null) {
boxAllCountMap.put(boxStr, subCodeList.size());
}
//进行库位分组
Map<String, Long> allCountMap = subCodeList.stream().collect(Collectors.groupingBy(Barcode::getPosName, Collectors.counting()));
//得到需要出库的数量
Map<String, Long> needOutCountMap = new HashMap<>();
List<Barcode> outSubCodeList = subCodeList.stream().filter(s -> s.isOut()).collect(Collectors.toList());
if (outSubCodeList != null && !outSubCodeList.isEmpty()) {
needOutCountMap = outSubCodeList.stream().collect(Collectors.groupingBy(Barcode::getPosName, Collectors.counting()));
}
List<Integer> partition1 = new ArrayList<>();
partition1.add(getCountByPartition(needOutCountMap, boxStr + "-1"));
partition1.add(getCountByPartition(allCountMap, boxStr + "-1"));
List<Integer> partition2 = new ArrayList<>();
partition2.add(getCountByPartition(needOutCountMap, boxStr + "-2"));
partition2.add(getCountByPartition(allCountMap, boxStr + "-2"));
List<Integer> partition3 = new ArrayList<>();
partition3.add(getCountByPartition(needOutCountMap, boxStr + "-3"));
partition3.add(getCountByPartition(allCountMap, boxStr + "-3"));
List<Integer> partition4 = new ArrayList<>();
partition4.add(getCountByPartition(needOutCountMap, boxStr + "-4"));
partition4.add(getCountByPartition(allCountMap, boxStr + "-4"));
List<Integer> partition5 = new ArrayList<>();
partition5.add(getCountByPartition(needOutCountMap, boxStr + "-5"));
partition5.add(getCountByPartition(allCountMap, boxStr + "-5"));
List<Integer> partition6 = new ArrayList<>();
partition6.add(getCountByPartition(needOutCountMap, boxStr + "-6"));
partition6.add(getCountByPartition(allCountMap, boxStr + "-6"));
List<Integer> partition7 = new ArrayList<>();
partition7.add(getCountByPartition(needOutCountMap, boxStr + "-7"));
partition7.add(getCountByPartition(allCountMap, boxStr + "-7"));
List<Integer> partition8 = new ArrayList<>();
partition8.add(getCountByPartition(needOutCountMap, boxStr + "-8"));
partition8.add(getCountByPartition(allCountMap, boxStr + "-8"));
//根据箱子面展示不同的隔扣
if (boxStr.startsWith("CS") || boxStr.startsWith("CB")) {
platsize = "7";
if ("A".equals(endStr)) {
boxPartitionCounts.add(partition8);
boxPartitionCounts.add(partition7);
boxPartitionCounts.add(partition6);
boxPartitionCounts.add(partition5);
boxPartitionCounts.add(partition1);
boxPartitionCounts.add(partition2);
boxPartitionCounts.add(partition3);
boxPartitionCounts.add(partition4);
} else {
boxPartitionCounts.add(partition4);
boxPartitionCounts.add(partition3);
boxPartitionCounts.add(partition2);
boxPartitionCounts.add(partition1);
boxPartitionCounts.add(partition5);
boxPartitionCounts.add(partition6);
boxPartitionCounts.add(partition7);
boxPartitionCounts.add(partition8);
}
} else if (boxStr.startsWith("CM")) {
platsize = "15";
if ("A".equals(endStr)) {
boxPartitionCounts.add(partition2);
boxPartitionCounts.add(partition1);
} else {
boxPartitionCounts.add(partition1);
boxPartitionCounts.add(partition2);
}
}
boxAllCount = boxAllCountMap.get(boxStr) == null ? 0 : boxAllCountMap.get(boxStr);
boxRemainingCount = subCodeList.size();
}
}
}
}
resultMap.put("platsize", platsize);
resultMap.put("boxPartitionCounts", boxPartitionCounts);
resultMap.put("boxAllCount", boxAllCount);
resultMap.put("boxRemainingCount", boxRemainingCount);
resultMap.put("currentRfid", boxStr);
resultMap.put("box", boxStr);
Collection<DataLog> queueTasks = taskService.getQueueTasks();
for (DataLog queueTask : queueTasks) {
if (queueTask.getBarcode().equals(boxStr)) {
if (queueTask.isCheckOutTask()) {
msg = boxStr + "需执行出库操作";//提示信息
} else {
msg = boxStr + "需执行入库操作";//提示信息
}
}
}
resultMap.put("msg", msg);
return resultMap;
}
private int getCountByPartition(Map<String, Long> paramMap, String partition) {
return paramMap.get(partition) == null ? 0 : paramMap.get(partition).intValue();
}
private List<DataLog> getVirtualOutTask(String orderNo) {
List<DataLog> tasks = new ArrayList<>();
for (Storage storage : dataCache.getAllStorage().values()) {
if (storage.isVirtual()) {
Collection<DataLog> queueTasks = taskService.getQueueTasks(storage.getCid());
for (DataLog queueTask : queueTasks) {
if (queueTask.isCheckOutTask()) {
if (StringUtils.isNotBlank(orderNo)) {
if (orderNo.equals(queueTask.getSourceName())) {
tasks.add(queueTask);
}
} else {
tasks.add(queueTask);
}
}
}
}
}
if (tasks != null && tasks.isEmpty()){
tasks = tasks.stream().sorted(Comparator.comparing(DataLog :: getPosName)).collect(Collectors.toList());
}
return tasks;
}
public Map<String, Object> getBoxPartitionNum(String boxStr, String boxSideStr, String boxPartition) {
//箱子号
Map<String, Object> resultMap = new HashMap<>();
resultMap.put("boxStr", boxStr);
resultMap.put("boxSideStr", boxSideStr);
resultMap.put("boxPartition", boxPartition);
if (boxStr.startsWith("CS") || boxStr.startsWith("CB")) {
resultMap.put("platsize", 7);
} else if (boxStr.startsWith("CM")) {
resultMap.put("platsize", 15);
}
Map<String, Long> boxPartitionNumMap = new HashMap<>();
for (int i = 1; i < 9; i++) {
boxPartitionNumMap.put(boxStr + "-" + i, 0l);
}
//根据箱子号,查询信息
Barcode barcode = barcodeManager.findByBarcode(boxStr);
if (barcode != null) {
List<Barcode> subCodes = barcode.getSubCodeList();
if (subCodes != null && !subCodes.isEmpty()) {
//根据posName进行分组
Map<String, Long> countByPosName = subCodes.stream().collect(Collectors.groupingBy(t -> t.getPosName(), Collectors.counting()));
//开始覆盖原有的集合
for (Map.Entry<String, Long> countByPosNameEntry : countByPosName.entrySet()) {
boxPartitionNumMap.put(countByPosNameEntry.getKey(), countByPosNameEntry.getValue());
}
}
}
//返回信息
List<Long> inBoxPartitionCounts = getInBoxPartitionCounts(boxStr, boxSideStr, boxPartitionNumMap);
resultMap.put("inBoxPartitionCounts", inBoxPartitionCounts);
//resultMap.putAll(boxPartitionNumMap);
return resultMap;
}
private List<Long> getInBoxPartitionCounts(String boxStr, String boxSideStr, Map<String, Long> boxPartitionNumMap) {
List<Long> inBoxPartitionCounts = new ArrayList<>();
if (boxStr.startsWith("CS") || boxStr.startsWith("CB")) {
if ("A".equals(boxSideStr)) {
inBoxPartitionCounts.add(boxPartitionNumMap.get(boxStr + "-8"));
inBoxPartitionCounts.add(boxPartitionNumMap.get(boxStr + "-7"));
inBoxPartitionCounts.add(boxPartitionNumMap.get(boxStr + "-6"));
inBoxPartitionCounts.add(boxPartitionNumMap.get(boxStr + "-5"));
inBoxPartitionCounts.add(boxPartitionNumMap.get(boxStr + "-1"));
inBoxPartitionCounts.add(boxPartitionNumMap.get(boxStr + "-2"));
inBoxPartitionCounts.add(boxPartitionNumMap.get(boxStr + "-3"));
inBoxPartitionCounts.add(boxPartitionNumMap.get(boxStr + "-4"));
} else {
inBoxPartitionCounts.add(boxPartitionNumMap.get(boxStr + "-4"));
inBoxPartitionCounts.add(boxPartitionNumMap.get(boxStr + "-3"));
inBoxPartitionCounts.add(boxPartitionNumMap.get(boxStr + "-2"));
inBoxPartitionCounts.add(boxPartitionNumMap.get(boxStr + "-1"));
inBoxPartitionCounts.add(boxPartitionNumMap.get(boxStr + "-5"));
inBoxPartitionCounts.add(boxPartitionNumMap.get(boxStr + "-6"));
inBoxPartitionCounts.add(boxPartitionNumMap.get(boxStr + "-7"));
inBoxPartitionCounts.add(boxPartitionNumMap.get(boxStr + "-8"));
}
} else if (boxStr.startsWith("CM")) {
if ("A".equals(boxSideStr)) {
inBoxPartitionCounts.add(boxPartitionNumMap.get(boxStr + "-2"));
inBoxPartitionCounts.add(boxPartitionNumMap.get(boxStr + "-1"));
} else {
inBoxPartitionCounts.add(boxPartitionNumMap.get(boxStr + "-1"));
inBoxPartitionCounts.add(boxPartitionNumMap.get(boxStr + "-2"));
}
}
return inBoxPartitionCounts;
}
private synchronized String finishTask(String boxStr, int opType, Barcode barcode, int opQty, String opStatus,int extendType) {
Barcode pidBarcode = barcodeManager.findByBarcode(boxStr);
int partitionCount = 0;
//判断隔口中的厂商,料号,库别是否一致
List<Barcode> subCodeList = pidBarcode.getSubCodeList();
if (subCodeList != null && !subCodeList.isEmpty()) {
for (Barcode subCode : subCodeList) {
if (barcode.getPosName().equals(subCode.getPosName())) {
//判断是否与隔口中的条件是否一致
if (!subCode.getProvider().equals(barcode.getProvider()) || !subCode.getPartNumber().equals(barcode.getPartNumber()) || !subCode.getWarehouseCode().equals(barcode.getWarehouseCode())) {
return "厂商:" + barcode.getProvider() + ",料号:" + barcode.getPartNumber() + "库别:" + barcode.getWarehouseCode() + "与隔口中:" + subCode.getPosName() + "厂商:" + subCode.getProvider() + ",料号:" + subCode.getPartNumber() + "库别:" + subCode.getWarehouseCode() + "不一致";
}
partitionCount++;
}
}
}
//如果是7寸箱子,最多只能放10盘
if (boxStr.startsWith("CS") || boxStr.startsWith("CB")) {
if (partitionCount >= 10) {
return "7寸物料每个隔口最多只允许放10盘";
}
}
barcode = barcodeManager.save(barcode);
//更新barcode缓存
log.info(barcode.getBarcode() + "的数量为:" + barcode.getAmount());
pidBarcode.updateSubCodes(barcode);
if (opType == OP.PUT_IN && OP_STATUS.FINISHED.name().equals(opStatus)) {
pidBarcode.setAmount(pidBarcode.getAmount() + opQty);
pidBarcode.setReelAmount(pidBarcode.getReelAmount() + 1); //入库卷数+1
}
pidBarcode = barcodeManager.save(pidBarcode);
//判断料箱中有没有该料箱,如果有,则更新
StoragePos pos = storagePosManager.getByBarcode(pidBarcode.getBarcode());
//log.info(pidBarcode.getBarcode() +"查询的库位信息为:"+ JsonUtil.toJsonStr(pos));
if (pos != null){
pos.setBarcode(pidBarcode);
pos = storagePosManager.save(pos);
}
DataLog task = new DataLog();
task.setStatus(opStatus);
task.setPartNumber(barcode.getPartNumber());
task.setBarcode(barcode.getBarcode());
task.setNum(opQty);
task.setType(opType);
task.setPosName(barcode.getPosName());
task.setOperator(SecurityUtils.getCurrentUsername());
task.setDateCode(barcode.getDateCode());
task.setBatchInfo(barcode.getBatch());
task.setProvider(barcode.getProvider());
task.setProviderNumber(barcode.getProviderNumber());
task.setKeeperCode(barcode.getKeeperCode());
task.setReelPosName(barcode.getPosName());
task.setExtendType(extendType);
task.setWarehouseCode(barcode.getWarehouseCode());
//增加首次入库时间和物料描述
if(barcode.getPutInTime() != -1){
task.setFristPutInDate(new Date(barcode.getPutInTime()));
} else {
task.setFristPutInDate(barcode.getPutInDate());
}
task.setDescribe(barcode.getDescribe());
taskService.updateFinishedTask(task);
return "";
}
private DataLog generateTask(Storage storage, Barcode barcode, StoragePos pos, int type, String status, String loc,int extendType) {
//开始入库任务
DataLog task = new DataLog(storage, barcode, pos);
task.setType(type);
task.setStatus(status);
task.setLoc(loc);
task.setOperator(SecurityUtils.getCurrentUsername());
task.setBoxPosName(pos.getPosName());
task.setExtendType(extendType);
task.setWarehouseCode(barcode.getWarehouseCode());
if (barcode.getPutInTime() != -1) {
task.setFristPutInDate(new Date(barcode.getPutInTime()));
} else {
task.setFristPutInDate(barcode.getPutInDate());
}
task.setDescribe(barcode.getDescribe());
taskService.addTaskToExecute(task);
return task;
}
private String getBoxStrbyBoxPartition(String boxPartition) {
String boxStr = "";
if (boxPartition.endsWith("A") || boxPartition.endsWith("B")) {
boxStr = boxPartition.substring(0, boxPartition.length() - 1);
}
if (boxPartition.indexOf("-") != -1) {
boxStr = boxPartition.substring(0, boxPartition.indexOf("-"));
}
if (StringUtils.isBlank(boxStr)) {
boxStr = boxPartition;
}
return boxStr;
}
private DataLog getExecutingTaskByBarcode(String barcode) {
DataLog task = null;
List<DataLog> allTasks = taskService.getAllTasks();
for (DataLog dataLog : allTasks) {
if (!dataLog.isCancel() && !dataLog.isFinished() && barcode.equals(dataLog.getBarcode())) {
task = dataLog;
break;
}
}
return task;
}
private boolean isBoxPartition(String code) {
boolean flag = false;
if (code.startsWith("CS") || code.startsWith("CM") || code.startsWith("CB")) {
flag = true;
}
return flag;
}
private int getPlatsizeOrHeight(String size, int index) {
return Integer.valueOf(size.split("X")[index]);
}
private String getPosNameBySubcode(String barcodeStr) {
String posName = "";
Criteria c = Criteria.where("subCodeList.barcode").is(barcodeStr);
List<Barcode> barcodes = barcodeManager.findByQuery(new Query(c));
if (barcodes != null && !barcodes.isEmpty()) {
for (Barcode barcode : barcodes) {
for (Barcode subCode : barcode.getSubCodeList()) {
if (barcodeStr.equals(subCode.getBarcode())) {
posName = subCode.getPosName();
break;
}
}
if (StringUtils.isNotBlank(posName)) {
break;
}
}
}
return posName;
}
}
package com.neotel.smfcore.custom.lizhen.agvBox.rest;
import cn.hutool.core.date.DateUtil;
import com.neotel.smfcore.common.bean.ResultBean;
import com.neotel.smfcore.core.barcode.service.manager.IBarcodeManager;
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.service.manager.ILiteOrderItemManager;
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.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.setting.util.ExpireDateUtil;
import com.neotel.smfcore.security.annotation.AnonymousAccess;
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.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.*;
@RestController
@Slf4j
@RequestMapping("/task")
public class TaskRestController {
@Autowired
private IDataLogManager dataLogManager;
@Autowired
private DataCache dataCache;
@Autowired
private TaskService taskService;
@Autowired
private IStoragePosManager storagePosManager;
@Autowired
private ILiteOrderItemManager liteOrderItemManager;
@Autowired
private IBarcodeManager barcodeManager;
@AnonymousAccess
@RequestMapping("/getOutBarcodeByPkId")
public ResultBean getOutBarcodeByPkId(String pkId) {
List<Map<String, String>> results = new ArrayList<>();
List<LiteOrderItem> orderItems = liteOrderItemManager.findByQuery(new Query(Criteria.where("orderNo").is(pkId)));
if (orderItems != null && !orderItems.isEmpty()) {
List<String> itemIds = new ArrayList<>();
for (LiteOrderItem orderItem : orderItems) {
itemIds.add(orderItem.getId());
}
Query query = new Query(Criteria.where("isOut").is(true).and("orderItemId").in(itemIds));
List<Barcode> barcodes = barcodeManager.findByQuery(query);
for (Barcode barcode : barcodes) {
Map<String, String> resultMap = new HashMap<>();
resultMap.put("唯一码", barcode.getBarcode());
resultMap.put("隔口码", barcode.getPosName());
results.add(resultMap);
}
}
return ResultBean.newOkResult(results);
}
@RequestMapping("/putIn")
@AnonymousAccess
public ResultBean putIn(@RequestBody Map<String, String> paramMap) {
String barcode = paramMap.get("barcode");
String posName = paramMap.get("posName");
String cid = paramMap.get("cid");
Storage storage = dataCache.getStorage(cid);
DataLog dataLog = new DataLog();
dataLog.setStorageId(storage.getId());
dataLog.setPosName(posName);
dataLog.setPosId(storagePosManager.getByPosName(posName).getId());
dataLog.setCid(cid);
dataLog.setBarcode(barcode);
dataLog.setPartNumber(barcode);
dataLog.setType(1);
dataLog.setStatus(OP_STATUS.WAIT.name());
taskService.addTaskToExecute(dataLog);
return ResultBean.newOkResult("");
}
@RequestMapping("/outIn")
@AnonymousAccess
public ResultBean outIn(@RequestBody Map<String, String> paramMap) {
String barcode = paramMap.get("barcode");
String posName = paramMap.get("posName");
String cid = paramMap.get("cid");
String name = paramMap.get("name");
Storage storage = dataCache.getStorage(cid);
DataLog dataLog = new DataLog();
dataLog.setStorageId(storage.getId());
dataLog.setPosName(posName);
dataLog.setPosId(storagePosManager.getByPosName(posName).getId());
dataLog.setCid(cid);
dataLog.setBarcode(barcode);
dataLog.setPartNumber(barcode);
dataLog.setType(2);
dataLog.setStatus(OP_STATUS.WAIT.name());
dataLog.setLoc(name);
log.info("工位信息--" + name);
taskService.addTaskToExecute(dataLog);
return ResultBean.newOkResult("");
}
/**
* 初始化,刷新过期时间
*/
@GetMapping("/flushExpireData")
@AnonymousAccess
public void flushExpireData() {
List<StoragePos> storagePosList = storagePosManager.findNotEmpty();
if (storagePosList != null && !storagePosList.isEmpty()) {
for (StoragePos storagePos : storagePosList) {
Barcode barcode = storagePos.getBarcode();
List<Barcode> subCodeList = barcode.getSubCodeList();
if (subCodeList != null && !subCodeList.isEmpty()) {
for (Barcode subCode : subCodeList) {
if (subCode.getExpireDate() == null) {
String provider = subCode.getProvider();
String dateCode = subCode.getDateCode();
Date produceDate = ExpireDateUtil.getExpireDate(dateCode, provider);
if (produceDate != null) {
subCode.setProduceDate(produceDate);
subCode.setExpireDate(DateUtil.offsetMonth(produceDate, 12));
barcodeManager.save(subCode);
}
}
}
barcode.setSubCodeList(subCodeList);
barcodeManager.save(barcode);
storagePos.setBarcode(barcode);
storagePosManager.save(storagePos);
}
}
}
}
/**
* 初始化内仓,过期时间
*/
@GetMapping("/flushInnerExpireData")
@AnonymousAccess
public void flushInnerExpireData() {
List<StoragePos> storagePosList = storagePosManager.findNotEmpty();
if (storagePosList != null && !storagePosList.isEmpty()) {
for (StoragePos storagePos : storagePosList) {
Barcode barcode = storagePos.getBarcode();
// if (barcode.getExpireDate() == null) {
String provider = barcode.getProvider();
String dateCode = barcode.getDateCode();
Date produceDate = ExpireDateUtil.getExpireDate(dateCode, provider);
if (produceDate != null) {
barcode.setProduceDate(produceDate);
barcode.setExpireDate(DateUtil.offsetMonth(produceDate, 12));
barcodeManager.save(barcode);
}
// }
storagePos.setBarcode(barcode);
storagePosManager.save(storagePos);
}
}
}
}
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.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.service.manager.ILiteOrderItemManager;
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.enums.INOUT_TYPE;
import com.neotel.smfcore.custom.lizhen.agvBox.service.manager.GrLabelManager;
import com.neotel.smfcore.custom.lizhen.agvBox.util.BoxUtil;
import com.neotel.smfcore.custom.lizhen.agvBox.util.StationCacheUtil;
import com.neotel.smfcore.custom.lizhen.innerBox.enums.ExtendType;
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 javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
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 DataCache dataCache;
@Autowired
private LizhenApi lizhenApi;
@Autowired
private GrLabelManager grLabelManager;
@Autowired
private SmfApi smfApi;
@Autowired
private ILiteOrderItemManager liteOrderItemManager;
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 + "解析失败");
}
//判断数据库是否有Gr数据,如果有用数据库的
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)) {
Station station = StationCacheUtil.getStation(name);
if (station != null) {
platsize = station.getPlatsize() + "";
}
}
if (StringUtils.isBlank(platsize)) {
return ResultBean.newErrorResult(-1, "", "尺寸不能为空");
}
//判断是否已经呼叫过空箱
int callCount = 0;
Collection<DataLog> queueTasks = taskService.getQueueTasks();
for (DataLog queueTask : queueTasks) {
if (name.equals(queueTask.getLoc()) && !queueTask.isFinished() && !queueTask.isCancel() && queueTask.isCheckOutTask()) {
callCount++;
}
}
if (callCount >= 2) {
return ResultBean.newErrorResult(-1, "", "当前工位:" + name + ",已经呼叫空箱,等任务完成后,再进行呼叫");
}
DataLog dataLog = getCallEmptyBoxTask(platsize, name);
if (dataLog == null) {
return ResultBean.newErrorResult(-1, "", "未找到可用料箱");
}
log.info(name + "呼叫的空箱为:" + dataLog.getBarcode());
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);
//判断工位信息是否为空
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") && !boxStr.startsWith("CB")) {
return ResultBean.newErrorResult(-1, "", "物料规格为7寸与当前工位上的料箱:" + boxStr + "不匹配");
}
} else if (platsize == 15) {
if (!boxStr.startsWith("CM")) {
return ResultBean.newErrorResult(-1, "", "物料规格为15寸与当前工位上的料箱:" + boxStr + "不匹配");
}
}
code = code.toUpperCase();
//先判断是否料盒
String newCodeStr = "=" + station.getPlatsize() + "x" + station.getHeight() + "=" + code;
CodeBean codeBean = codeResolve.resolveSingleCode(newCodeStr);
if (!codeBean.isValid()) {
return ResultBean.newErrorResult(-1, "smfcore.error.barcode.noValidCode", "无效的条码");
}
Barcode barcode = codeBean.getBarcode();
String partNumber = barcode.getPartNumber();
ResultBean resultBean = ResultBean.newOkResult("");
//判断是否是料箱隔口码
if (isBox(partNumber)) {
boolean canPutIn = BoxUtil.isCanPutIn(code);
if (!canPutIn){
return ResultBean.newErrorResult(-1,"","无效的隔口码:"+code);
}
//判断当前是否有正在执行的任务
DataLog dataLog = getExecutingTask(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[]{});
}
}
//判断当前工位上的料箱
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> barcodesByPosName = getBarcodesByPosName(code, false);
if (barcodesByPosName != null && !barcodesByPosName.isEmpty()) {
for (Barcode barcodePos : barcodesByPosName) {
if (!code.equals(barcodePos.getPosName())) {
continue;
}
if (!barcodePos.getWarehouseCode().equals(label.getWarehouseCode())) {
return ResultBean.newErrorResult(-1, "", "隔口中库别:" + barcodePos.getWarehouseCode() + "与Gr标签中库别:" + label.getWarehouseCode() + "不一致");
}
}
}
}
//判断料箱是否在库位中
StoragePos pos = storagePosManager.getByBarcode(boxStr);
if (pos != null) {
return ResultBean.newErrorResult(-1, "", "料箱:" + boxStr + "已存在库位:" + pos.getPosName());
}
//设置操作人
barcode.setCreator(SecurityUtils.getCurrentUsername());
barcodeManager.save(barcode);
station.setLastScanBoxCode(code);
} else {
int barcodeLength = barcode.getBarcode().length();
if (barcodeLength < 16 || barcodeLength > 22) {
return ResultBean.newErrorResult(-1, "", barcode.getBarcode() + "请核实唯一码长度是否为17至22位");
}
if (StringUtils.isNotBlank(barcode.getBatch())) {
int batchLength = barcode.getBatch().length();
if (batchLength > 36) {
return ResultBean.newErrorResult(-1, "", barcode.getBatch() + "请核实L/C长度是否小于36位");
}
}
if (StringUtils.isNotBlank(barcode.getDateCode())) {
int dateLength = barcode.getDateCode().length();
if (dateLength > 36) {
return ResultBean.newErrorResult(-1, "", barcode.getDateCode() + "请核实D/C长度是否小于36位");
}
}
String lastScanBoxCode = station.getLastScanBoxCode();
if (Strings.isBlank(lastScanBoxCode)) {
//提示要先扫料箱
return ResultBean.newErrorResult(-1, "", "请先扫描料箱隔口码,再扫描物料二维码");
} else if (!lastScanBoxCode.startsWith(boxStr)) {
return ResultBean.newErrorResult(-1, "", "请先扫描料箱隔口码,再扫描物料二维码");
}
//判断是否存在其他料箱中
String posName = getPosNameBySubcode(barcode.getBarcode());
if (StringUtils.isNotBlank(posName)) {
return ResultBean.newErrorResult(-1, "", "物料" + barcode.getBarcode() + "已存在料箱:" + barcode.getPosName());
}
//判断隔口中厂商,料号,gr标签是否一致
String grLabelStr = station.getGrLabel();
GrLabel label = null;
if (StringUtils.isNotBlank(grLabelStr)) {
label = grLabelManager.findLabelBylabelId(grLabelStr, station.getLabelItem());
if (label != null) {
barcode.setGrLabel(grLabelStr);
barcode.setWarehouseCode(label.getWarehouseCode());
barcode.setKeeperCode(label.getKeeperCode());
}
} else {
barcode.setWarehouseCode(station.getWarehouseCode());
}
//更新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);
}
//判断物料是否过期
Date expireDate = barcode.getExpireDate();
if (expireDate != null) {
if (System.currentTimeMillis() > expireDate.getTime()) {
return ResultBean.newErrorResult(-1, "smfcore.error.barcode.expired", "物料已过期,无法入库.");
}
}
//校验是否可以入库
Map<String, Object> brandQty = lizhenApi.brandQty(barcode.getPartNumber(), barcode.getProvider());
if (brandQty == null || brandQty.isEmpty()) {
return ResultBean.newErrorResult(-1,"smfcore.error.barcode.partNumber.invalid", "{0}不是有效的料号", new String[]{barcode.getPartNumber()});
}
//获取mes数量
Barcode barcodeApi = lizhenApi.barcodeInfo(barcode);
//如果是L开头的去量测
if (barcode.getBarcode().startsWith("L") || barcode.getBarcode().startsWith("l")) {
boolean check = lizhenApi.checkReelMeasure(barcode);
if (!check) {
return ResultBean.newErrorResult(-1, "", barcode.getBarcode() + "散料未量测");
}
} else {
if (barcodeApi != null) {
//判断返回过来的物料数量与标签上的是否一致,如果不一致,则调用散料量测接口
if (barcodeApi.getAmount() != barcode.getLabelAmount()) {
boolean check = lizhenApi.checkReelMeasure(barcode);
if (!check) {
return ResultBean.newErrorResult(-1, "", barcode.getBarcode() + "散料未量测");
}
}
}
}
if (barcodeApi != null){
barcode = barcodeApi;
}
//当前已扫描的料卷数量+1
int reelCurrentNum = station.getReelCurrentNum();
station.setReelCurrentNum(reelCurrentNum + 1);
Date date = new Date();
//barcode.setPutInDate(new Date());
barcode.setPutInTime(date.getTime());
resultBean = finishTask(boxStr, OP.PUT_IN, barcode, OP_STATUS.FINISHED.name(), INOUT_TYPE.IN_ONE.name(), lastScanBoxCode, grLabelStr,name);
}
StationCacheUtil.updateStation(station);
return resultBean;
}
@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 = getExecutingTask(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[]{});
}
}
//判断是否盘点完成
boolean finished = BoxUtil.isInventoryFinished(boxStr);
if (!finished) {
return ResultBean.newErrorResult(-1, "", boxStr + "盘点未完成,请继续盘点");
}
boxBarcode.setInventory(false);
boxBarcode = barcodeManager.save(boxBarcode);
//同时清空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);
finishTask(boxStr, OP.CHECKOUT, null, OP_STATUS.CANCEL.name(), INOUT_TYPE.CANCEL_ONE.name(), null, null,name);
boxCount.remove(boxStr);
//生成任务
generateTask(dataCache.getStorageById(pos.getStorageId()), boxBarcode, pos, OP.PUT_IN, OP_STATUS.WAIT.name(), null,ExtendType.STORAGE_PUTIN);
taskService.removePosName(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[]{});
}
barcodeStr = barcodeStr.toUpperCase();
//获取料箱中的物料信息
String boxStr = getBoxInfoByRfid(currentRfid);
String result = "";
ResultBean resultBean = ResultBean.newOkResult("");
if (isBox(barcodeStr) && (barcodeStr.endsWith("A") || barcodeStr.endsWith("B"))) {
resultBean = finishTask(boxStr, OP.CHECKOUT, null, OP_STATUS.FINISHED.name(), INOUT_TYPE.OUT_BOX.name(), null, null,name);
} else if (isBox(barcodeStr) && barcodeStr.indexOf("-") != -1) {
resultBean = finishTask(boxStr, OP.CHECKOUT, null, OP_STATUS.FINISHED.name(), INOUT_TYPE.OUT_PARTITION.name(), barcodeStr, null,name);
} else {
resultBean = finishTask(boxStr, OP.CHECKOUT, null, OP_STATUS.FINISHED.name(), INOUT_TYPE.OUT_ONE.name(), barcodeStr, null,name);
}
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<>();
for (int i = 1; i < 9; i++) {
needOutCountMap.put(boxStr + "-" + i, 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") || currentRfid.startsWith("CB") ) {
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(partition2);
inBoxPartitionCounts.add(partition1);
boxPartitionCounts.add(boxPartitionCount2);
boxPartitionCounts.add(boxPartitionCount1);
}
} else if (currentRfid.endsWith("B")) {
if (currentRfid.startsWith("CS") || currentRfid.startsWith("CB") ) {
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(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());
resultMap.put("warehouseCode",station.getWarehouseCode());
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);
}
@ApiOperation("重置料箱信息")
@RequestMapping("/resetBoxInfo")
@AnonymousAccess
public ResultBean resetBoxInfo(HttpServletRequest request) {
String barcodeStr = request.getParameter("barcode");
//log.info(SecurityUtils.getCurrentUsername() + "重置料箱信息:" + barcodeStr);
if (StringUtils.isBlank(barcodeStr)) {
return ResultBean.newErrorResult(-1, "smfcore.valueCanotNull", "{0}不能为空", new String[]{"料箱号"});
}
Barcode barcode = barcodeManager.findByBarcode(barcodeStr);
if (barcode == null) {
return ResultBean.newErrorResult(-1, "smfcore.valueNotExist", "{0}[{1}]不存在", new String[]{"料箱信息", barcodeStr});
}
//删除料箱信息
barcodeManager.delete(barcode);
//删除物料信息
List<Barcode> barcodeList = barcodeManager.findByPosName(barcodeStr);
if (barcodeList != null && !barcodeList.isEmpty()) {
for (Barcode subCode : barcodeList) {
log.info("重置物料信息:" + subCode.getBarcode());
barcodeManager.delete(subCode);
}
}
//判断库位中有没有
StoragePos pos = storagePosManager.getByBarcode(barcodeStr);
if (pos != null) {
log.info("重置库位信息:" + pos.getPosName());
pos.setBarcode(null);
pos.setUsed(false);
storagePosManager.save(pos);
}
return ResultBean.newOkResult(null);
}
/**
* 生成任务
*
* @param storage
* @param barcode
* @param pos
* @param type
* @param status
* @param loc
*/
private DataLog generateTask(Storage storage, Barcode barcode, StoragePos pos, int type, String status, String loc,int extendType) {
//开始入库任务
DataLog task = new DataLog(storage, barcode, pos);
task.setType(type);
task.setStatus(status);
task.setLoc(loc);
task.setOperator(SecurityUtils.getCurrentUsername());
task.setBoxPosName(pos.getPosName());
task.setExtendType(extendType);
if (barcode.getPutInTime() != -1) {
task.setFristPutInDate(new Date(barcode.getPutInTime()));
} else {
task.setFristPutInDate(barcode.getPutInDate());
}
task.setDescribe(barcode.getDescribe());
taskService.addTaskToExecute(task);
return task;
}
/**
* 完成出入库任务
*
* @param boxStr 箱子号
* @param opType 出入库 1,2
* @param barcode barcode
* @param opStatus 出入库状态
* @param inoutType 出入库类型 单个,隔口,整箱 出入库
* @param lastScanBoxCode 上一个隔口码
* @param grLabelStr gr标签
* @return
*/
private synchronized ResultBean finishTask(String boxStr, int opType,
Barcode barcode, String opStatus,
String inoutType, String lastScanBoxCode,
String grLabelStr, String name) {
String orderItemIdStr = "";
//1.单盘入库
if (INOUT_TYPE.IN_ONE.name().equals(inoutType)) {
//判断是否存在其他料箱中
String posName = getPosNameBySubcode(barcode.getBarcode());
if (StringUtils.isNotBlank(posName)) {
return ResultBean.newErrorResult(-1, "", "物料" + barcode.getBarcode() + "已存在料箱:" + barcode.getPosName());
}
//根据箱子号 找到barcode
Barcode pidBarcode = barcodeManager.findByBarcode(boxStr);
//校验隔口中是否可以放入
int barcodeCount = 0;
List<Barcode> subCodes = pidBarcode.getSubCodeList();
if (subCodes != null && !subCodes.isEmpty()) {
for (Barcode subCode : subCodes) {
if (lastScanBoxCode.equals(subCode.getPosName())) {
//判断是否与隔口中的条件是否一致
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(grLabelStr)) {
if (!grLabelStr.equals(subCode.getGrLabel())) {
return ResultBean.newErrorResult(-1, "", grLabelStr + "与隔口中Gr标签不一致:" + subCode.getGrLabel());
}
}
barcodeCount++;
}
}
}
//7寸箱子最多放10盘
if (lastScanBoxCode.startsWith("CS") || lastScanBoxCode.startsWith("CB")) {
if (barcodeCount >= 10) {
return ResultBean.newErrorResult(-1, "", "7寸物料每个隔口最多只允许放10盘");
}
}
log.info("单盘入库:" + barcode.getBarcode() + ",箱子号:" + boxStr + ",隔口号:" + lastScanBoxCode);
//开始生成任务,并处理
barcode.setHostBarcodeId(pidBarcode.getId());
barcode.setReelAmount(1); //设置卷数为1
barcode.setPutInTime(System.currentTimeMillis());
barcode.setCreator(SecurityUtils.getCurrentUsername());
barcode.setPosName(lastScanBoxCode);
barcode = barcodeManager.save(barcode);
pidBarcode.UpdateSubCode(barcode);
pidBarcode.setAmount(pidBarcode.getAmount() + barcode.getAmount());
pidBarcode.setReelAmount(pidBarcode.getReelAmount() + 1);
//生成入库任务
barcodeManager.save(pidBarcode);
//判断是gr入库还是手动入库
int extendType = StringUtils.isNotBlank(barcode.getGrLabel()) ? ExtendType.GR_PUTIN : ExtendType.MANUAL_PUTIN;
generateTask(barcode, opStatus, barcode.getAmount(), opType, barcode.getOrderItemId(), name, extendType,false);
log.info("单盘出库生成入库信息,barcode:" + barcode.getBarcode() + "隔口信息为:" + barcode.getPosName());
}
//2.任务取消状态
else if (INOUT_TYPE.CANCEL_ONE.name().equals(inoutType)) {
//根据箱子号 找到barcode
Barcode pidBarcode = barcodeManager.findByBarcode(boxStr);
//判断是否有要出库的任务,给取消掉
List<Barcode> subCodes = pidBarcode.getSubCodeList();
if (subCodes != null && !subCodes.isEmpty()) {
for (Barcode subCode : subCodes) {
if (subCode.isOut()) {
String orderItemId = subCode.getOrderItemId();
subCode.setOut(false);
subCode.setSelectMsg(null);
subCode.setOrderItemId(null);
subCode = barcodeManager.save(subCode);
pidBarcode.UpdateSubCode(subCode);
pidBarcode = barcodeManager.save(pidBarcode);
generateTask(subCode, opStatus, subCode.getAmount(), opType, orderItemId, name, ExtendType.TASK_CANNEL,false);
log.info("点击完成扫码并入库,任务取消,barcode:" + subCode.getBarcode() + ",OrderItemId为:" + orderItemId);
}
}
}
}
//3.整箱出库状态
else if (INOUT_TYPE.OUT_BOX.name().equals(inoutType)) {
//根据箱子号 找到barcode
Barcode pidBarcode = barcodeManager.findByBarcode(boxStr);
boolean hasBrand = false;
//根据料箱获取到全部的物料
List<Barcode> subCodes = pidBarcode.getSubCodeList();
if (subCodes == null || subCodes.isEmpty()) {
return ResultBean.newErrorResult(-1, "", "料箱:" + pidBarcode.getBarcode() + ",没有可出库的物料");
}
//判断是否全部出库
for (Barcode subCode : subCodes) {
if (!subCode.isOut()) {
return ResultBean.newErrorResult(-1, "", pidBarcode.getBarcode() + "不允许全部取出,请核实");
}
}
//开始循环,生成任务
List<DataLog> dataLogList = new ArrayList<>();
for (int index = 0; index < subCodes.size();/*; index++*/) {
Barcode subCode = subCodes.get(index);
String orderItemId = subCode.getOrderItemId();
//判断是否管控厂商
if (StringUtils.isNotBlank(orderItemId)) {
LiteOrderItem orderItem = liteOrderItemManager.get(orderItemId);
if (orderItem != null) {
if (StringUtils.isNotBlank(orderItem.getBrand())) {
hasBrand = true;
}
if (StringUtils.isNotBlank(orderItem.getOrderNo())) {
if (!orderItem.getOrderNo().equals(orderItemIdStr)) {
orderItemIdStr = orderItem.getOrderNo();
}
}
}
}
//生成任务
int amount = subCode.getAmount();
subCode.setAmount(0);
pidBarcode.UpdateSubCode(subCode);
pidBarcode.setReelAmount(pidBarcode.getReelAmount() - 1);
pidBarcode.setAmount(pidBarcode.getAmount() - amount);
pidBarcode = barcodeManager.save(pidBarcode);
//判断是手动出库,还是pk出库
int extendType = StringUtils.isNotBlank(subCode.getOrderItemId()) ? ExtendType.PICKING_DETAIL : ExtendType.MANUAL_CHECKOUT;
DataLog dataLog = generateTask(subCode, opStatus, amount, opType, orderItemId, name, extendType, true);
dataLogList.add(dataLog);
log.info("整箱出库,生成出库任务,barcode:" + subCode.getBarcode() + ",料箱号为:" + pidBarcode.getBarcode());
if (subCode.getAmount() <= 0) {
subCode.setAmount(amount);
subCode.setSelectMsg(null);
subCode.setOut(false);
subCode.setOrderItemId(null);
subCode.setPosName(null);
subCode.setHostBarcodeId(null);
subCode.setStorageId(null);
barcodeManager.save(subCode);
}
}
if (dataLogList != null && !dataLogList.isEmpty()) {
taskService.outTaskStatusChange(dataLogList);
}
if (hasBrand) {
ResultBean resultBean = ResultBean.newOkResult("");
resultBean.setCode(3);
return resultBean;
}
if (StringUtils.isNotBlank(orderItemIdStr)) {
return ResultBean.newOkResult("", "工单号为:" + orderItemIdStr, "");
}
}
//4.隔口出库
else if (INOUT_TYPE.OUT_PARTITION.name().equals(inoutType)) {
//根据箱子号 找到barcode
Barcode pidBarcode = barcodeManager.findByBarcode(boxStr);
boolean hasBrand = false;
List<Barcode> needOutBarcodes = new ArrayList<>();
List<Barcode> subCodes = pidBarcode.getSubCodeList();
if (subCodes != null && !subCodes.isEmpty()) {
for (Barcode subCode : subCodes) {
if (lastScanBoxCode.equals(subCode.getPosName())) {
needOutBarcodes.add(subCode);
}
}
}
if (needOutBarcodes == null || needOutBarcodes.isEmpty()) {
return ResultBean.newErrorResult(-1, "", "料箱隔口:" + lastScanBoxCode + "扫描错误");
}
//判断是否全部出库
for (Barcode subCode : needOutBarcodes) {
//if (lastScanBoxCode.equals(subCode.getPosName())) {
if (!subCode.isOut()) {
return ResultBean.newErrorResult(-1, "", lastScanBoxCode + "不允许全部出库,请核实");
}
//}
}
List<DataLog> dataLogList = new ArrayList<>();
for (int index = 0; index < needOutBarcodes.size(); index++) {
Barcode subCode = needOutBarcodes.get(index);
//if (lastScanBoxCode.equals(subCode.getPosName())) {
String orderItemId = subCode.getOrderItemId();
if (StringUtils.isNotBlank(orderItemId)) {
LiteOrderItem orderItem = liteOrderItemManager.get(orderItemId);
if (orderItem != null) {
if (StringUtils.isNotBlank(orderItem.getBrand())) {
hasBrand = true;
}
if (StringUtils.isNotBlank(orderItem.getOrderNo())) {
if (!orderItem.getOrderNo().equals(orderItemIdStr)) {
orderItemIdStr = orderItem.getOrderNo();
}
}
}
}
int amount = subCode.getAmount();
subCode.setAmount(0);
pidBarcode.UpdateSubCode(subCode);
pidBarcode.setReelAmount(pidBarcode.getReelAmount() - 1);
pidBarcode.setAmount(pidBarcode.getAmount() - amount);
pidBarcode = barcodeManager.save(pidBarcode);
int extendType = StringUtils.isNotBlank(subCode.getOrderItemId()) ? ExtendType.PICKING_DETAIL : ExtendType.MANUAL_CHECKOUT;
DataLog dataLog = generateTask(subCode, opStatus, amount, opType, orderItemId, name, extendType, true);
dataLogList.add(dataLog);
log.info("隔口出库,生成出库任务,barcode:" + subCode.getBarcode() + ",料箱号为:" + subCode.getPosName());
log.info("箱子数量为:" + pidBarcode.getAmount() + ",物料数量为:" + pidBarcode.getReelAmount() + "箱号为:" + pidBarcode.getBarcode());
if (subCode.getAmount() <= 0) {
subCode.setAmount(amount);
subCode.setSelectMsg(null);
subCode.setOut(false);
subCode.setOrderItemId(null);
subCode.setPosName(null);
subCode.setHostBarcodeId(null);
subCode.setStorageId(null);
barcodeManager.save(subCode);
}
//}
}
if (dataLogList != null && !dataLogList.isEmpty()){
taskService.outTaskStatusChange(dataLogList);
}
if (hasBrand) {
ResultBean resultBean = ResultBean.newOkResult("");
resultBean.setCode(3);
return resultBean;
}
if (StringUtils.isNotBlank(orderItemIdStr)) {
return ResultBean.newOkResult("", "工单号为:" + orderItemIdStr, "");
}
}
//5.物料出库
else if (INOUT_TYPE.OUT_ONE.name().equals(inoutType)) {
//根据箱子号 找到barcode
Barcode pidBarcode = barcodeManager.findByBarcode(boxStr);
boolean hasBrand = false; //是否提示管控厂商
String codeStr = lastScanBoxCode; //物料条码
if (StringUtils.isNotBlank(codeStr)) {
CodeBean codeBean = codeResolve.resolveSingleCode(codeStr);
if (!codeBean.isValid()) {
return ResultBean.newErrorResult(-1, "", codeStr + "解析失败");
}
try {
smfApi.canPutInAfterResolve(codeBean.getBarcode());
} catch (ValidateException e) {
e.printStackTrace();
return ResultBean.newErrorResult(-1, "", e.getMessage());
}
List<Barcode> subCodes = pidBarcode.getSubCodeList();
if (subCodes == null || subCodes.isEmpty()) {
return ResultBean.newErrorResult(-1, "", "料箱:" + boxStr + ",没有可出库的物料");
}
//判断当前料箱是否包含此物料
boolean hasBarcode = false;
String selectMsg = "";
barcode = codeBean.getBarcode();
String barcodeStr = barcode.getBarcode();
for (Barcode subCode : subCodes) {
if (barcodeStr.equals(subCode.getBarcode())) {
hasBarcode = true;
}
if (StringUtils.isNotBlank(barcode.getSelectMsg())) {
selectMsg = barcode.getSelectMsg();
}
if (barcode.getBarcode().equals(subCode.getBarcode())) {
barcode = subCode;
}
}
if (!hasBarcode) {
return ResultBean.newErrorResult(-1, "", barcodeStr + "不在料箱:" + boxStr + "请核实是否已经出库");
}
//判断查询条件是否一致
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;
}
if (StringUtils.isNotBlank(orderItem.getOrderNo())) {
if (!orderItem.getOrderNo().equals(orderItemIdStr)) {
orderItemIdStr = orderItem.getOrderNo();
}
}
}
}
int amount = barcode.getAmount();
barcode.setAmount(0);
pidBarcode.UpdateSubCode(barcode);
pidBarcode.setReelAmount(pidBarcode.getReelAmount() - 1);
pidBarcode.setAmount(pidBarcode.getAmount() - amount);
pidBarcode = barcodeManager.save(pidBarcode);
int extendType = StringUtils.isNotBlank(barcode.getOrderItemId()) ? ExtendType.PICKING_DETAIL : ExtendType.MANUAL_CHECKOUT;
generateTask(barcode, opStatus, amount, opType, orderItemId,name,extendType,false);
log.info("物料出库,生成出库任务,barcode:" + barcode.getBarcode() + ",隔口号为:" + barcode.getPosName());
if (barcode.getAmount() <= 0) {
barcode.setAmount(amount);
barcode.setSelectMsg(null);
barcode.setOut(false);
barcode.setOrderItemId(null);
barcode.setPosName(null);
barcode.setHostBarcodeId(null);
barcode.setStorageId(null);
barcodeManager.save(barcode);
}
} else {
if (subCodes != null && !subCodes.isEmpty()) {
//获取到需要出库的物料,进行更改
Barcode barcodeByOut = null;
for (Barcode subCode : subCodes) {
//判断料箱隔口是否一致
if (subCode.getPosName().equals(barcode.getPosName())) {
if (subCode.isOut() && StringUtils.isNotBlank(subCode.getOrderItemId())) {
barcodeByOut = subCode;
break;
}
}
}
if (barcodeByOut != null) {
String orderItemId = barcodeByOut.getOrderItemId();
barcodeByOut.setOut(false);
barcodeByOut.setOrderItemId(null);
barcodeByOut.setSelectMsg(null);
barcodeByOut = barcodeManager.save(barcodeByOut);
pidBarcode.UpdateSubCode(barcodeByOut);
pidBarcode = barcodeManager.save(pidBarcode);
//互换,要出的和隔口中的数据
int amount = barcode.getAmount();
barcode.setAmount(0);
barcode.setOrderItemId(orderItemId);
//barcode = barcodeManager.save(barcode);
pidBarcode.setReelAmount(pidBarcode.getReelAmount() - 1);
pidBarcode.setAmount(pidBarcode.getAmount() - amount);
pidBarcode.UpdateSubCode(barcode);
pidBarcode = barcodeManager.save(pidBarcode);
int extendType = StringUtils.isNotBlank(barcode.getOrderItemId()) ? ExtendType.PICKING_DETAIL : ExtendType.MANUAL_CHECKOUT;
generateTask(barcode, opStatus, amount, opType, orderItemId,name,extendType,false);
log.info(barcode.getBarcode() + "不是出库任务," + barcodeByOut.getBarcode() + "需更改out为false");
log.info("物料出库,生成出库任务,barcode:" + barcode.getBarcode() + ",隔口号为:" + barcode.getPosName());
if (barcode.getAmount() <= 0) {
barcode.setAmount(amount);
barcode.setSelectMsg(null);
barcode.setOut(false);
barcode.setOrderItemId(null);
barcode.setPosName(null);
barcode.setHostBarcodeId(null);
barcode.setStorageId(null);
barcodeManager.save(barcode);
}
isOut = true;
if (StringUtils.isNotBlank(orderItemId)) {
LiteOrderItem orderItem = liteOrderItemManager.get(orderItemId);
if (orderItem != null) {
if (StringUtils.isNotBlank(orderItem.getBrand())) {
hasBrand = true;
}
if (StringUtils.isNotBlank(orderItem.getOrderNo())) {
if (!orderItem.getOrderNo().equals(orderItemIdStr)) {
orderItemIdStr = orderItem.getOrderNo();
}
}
}
}
}
}
}
if (!isOut) {
return ResultBean.newErrorResult(-1, "", barcode.getBarcode() + "不需要出库");
}
} else {
return ResultBean.newErrorResult(-1, "", "条码编号不能为空");
}
if (hasBrand) {
log.info("hasBrand--" + hasBrand);
ResultBean resultBean = ResultBean.newOkResult("");
resultBean.setCode(3);
return resultBean;
}
if (StringUtils.isNotBlank(orderItemIdStr)) {
return ResultBean.newOkResult("", "工单号为:" + orderItemIdStr, "");
}
}
return ResultBean.newOkResult("");
}
private DataLog generateTask(Barcode barcode, String opStatus, int opQty, int opType, String orderItemId,String name,int extendType,boolean isBoxOut) {
//生成任务
DataLog task = new DataLog();
task.setStatus(opStatus);
task.setPartNumber(barcode.getPartNumber());
task.setBarcode(barcode.getBarcode());
task.setNum(opQty);
task.setType(opType);
task.setPosName(barcode.getPosName());
task.setOperator(SecurityUtils.getCurrentUsername());
task.setDateCode(barcode.getDateCode());
task.setBatchInfo(barcode.getBatch());
task.setProvider(barcode.getProvider());
task.setProviderNumber(barcode.getProviderNumber());
task.setKeeperCode(barcode.getKeeperCode());
//task.setReelPosName(barcode.getPosName());
task.setSubSourceId(orderItemId);
task.setWarehouseCode(barcode.getWarehouseCode());
task.setStationName(name);
task.setExtendType(extendType);
if (StringUtils.isNotBlank(orderItemId)) {
LiteOrderItem orderItem = liteOrderItemManager.get(orderItemId);
if (orderItem != null) {
task.setSourceName(orderItem.getOrderNo());
task.setLine(orderItem.getLine());
task.setMo(orderItem.getMo());
task.setSide(orderItem.getSide());
task.setPlantCode(orderItem.getPlantCode());
task.setOrderNo(orderItem.getOrderNo());
task.setSubSourceId(orderItem.getId());
task.setManualUpload(orderItem.isManualUpload());
}
}
//如果是出库任务,增加库位
if (task.isCheckOutTask()) {
String boxStr = BoxUtil.getBoxStr(barcode.getPosName());
String posName = taskService.getPosName(boxStr);
if (StringUtils.isNotBlank(posName)) {
task.setStoragePosName(posName);
}
}
task.setBoxOut(isBoxOut);
if (barcode.getPutInTime() != -1) {
task.setFristPutInDate(new Date(barcode.getPutInTime()));
} else {
task.setFristPutInDate(barcode.getPutInDate());
}
task.setDescribe(barcode.getDescribe());
taskService.updateFinishedTask(task);
return task;
}
/**
* 解析尺寸信息
*
* @param size
* @param index
* @return
*/
private int getPlatsizeOrHeight(String size, int index) {
return Integer.valueOf(size.split("X")[index]);
}
private synchronized DataLog getCallEmptyBoxTask(String platsize, String name) {
//获取料箱id
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();
if (excludePosIds != null && !excludePosIds.isEmpty()) {
c.and("id").nin(excludePosIds);
}
//料仓id
if (StringUtils.isNotBlank(storageId)) {
c.and("storageId").is(storageId);
}
//料盘数量小于70盘
c.and("barcode.reelAmount").lte(70);
//进行排序方式
Query q = new Query(c).with(Sort.by(Sort.Direction.ASC, "barcode.amount"));
StoragePos pos = null;
List<StoragePos> poss = new ArrayList<>();
if ("15".equals(platsize)) {
poss = storagePosManager.findByQuery(q.addCriteria(Criteria.where("barcode.partNumber").regex(Pattern.compile(QueryHelp.escapeExprSpecialWord("CM"), Pattern.CASE_INSENSITIVE))));
} else {
poss = storagePosManager.findByQuery(q.addCriteria(Criteria.where("barcode.partNumber").regex(Pattern.compile(QueryHelp.escapeExprSpecialWord("CS"), Pattern.CASE_INSENSITIVE))));
if (poss == null || poss.isEmpty()) {
poss = storagePosManager.findByQuery(q.addCriteria(Criteria.where("barcode.partNumber").regex(Pattern.compile(QueryHelp.escapeExprSpecialWord("CB"), Pattern.CASE_INSENSITIVE))));
}
}
//找隔口中 没有物料的箱子
if (poss != null && !poss.isEmpty()) {
for (StoragePos storagePos : poss) {
Barcode barcode = storagePos.getBarcode();
List<Barcode> subCodeList = barcode.getSubCodeList();
if (subCodeList == null || subCodeList.isEmpty()) {
pos = storagePos;
break;
} else {
boolean hasBarcode = true;
//分组求每个隔口的数量
Map<String, Long> countMap = subCodeList.stream().collect(Collectors.groupingBy(Barcode::getPosName, Collectors.counting()));
if ("7".equals(platsize)) {
for (int par = 1; par < 9; par++) {
//箱子+隔口号
if (countMap.get(barcode.getBarcode() + "-" + par) == null || countMap.get(barcode.getBarcode() + "-" + par) == 0) {
hasBarcode = false;
break;
}
}
} else if ("15".equals(platsize)) {
for (int par = 1; par < 3; par++) {
//箱子+隔口号
if (countMap.get(barcode.getBarcode() + "-" + par) == null || countMap.get(barcode.getBarcode() + "-" + par) == 0) {
hasBarcode = false;
break;
}
}
}
if (!hasBarcode) {
pos = storagePos;
break;
}
}
}
}
log.info("工位:" + name + "呼叫尺寸类型:" + platsize + "得到空箱为:" + JsonUtil.toJsonStr(pos));
//如果料箱不为空的话,生成出库任务
DataLog task = null;
if (pos != null) {
Storage storage = dataCache.getStorageById(pos.getStorageId());
task = generateTask(storage, pos.getBarcode(), pos, OP.CHECKOUT, OP_STATUS.WAIT.name(), name,ExtendType.STORAGE_CHECKOUT);
}
return task;
}
/**
* 获取正在执行的任务
*
* @param barcode
* @return
*/
private DataLog getExecutingTask(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);
}
private boolean isBox(String barcodeStr) {
if (barcodeStr.startsWith("CS") || barcodeStr.startsWith("CM") || barcodeStr.startsWith("CB")) {
//如果大于10位,就任务不是料箱
if (barcodeStr.length() <= 10) {
return true;
}
}
return false;
}
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);
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 String getPosNameBySubcode(String barcodeStr) {
String posName = "";
Criteria c = Criteria.where("subCodeList.barcode").is(barcodeStr);
List<Barcode> barcodes = barcodeManager.findByQuery(new Query(c));
if (barcodes != null && !barcodes.isEmpty()) {
for (Barcode barcode : barcodes) {
for (Barcode subCode : barcode.getSubCodeList()) {
if (barcodeStr.equals(subCode.getBarcode())) {
posName = subCode.getPosName();
break;
}
}
if (StringUtils.isNotBlank(posName)) {
break;
}
}
}
return posName;
}
public int getCount(Map<String, Long> map, String key) {
return map.get(key) != null ? map.get(key).intValue() : 0;
}
}
package com.neotel.smfcore.custom.lizhen.agvBox.rest;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSONArray;
import com.neotel.smfcore.common.utils.HttpHelper;
import com.neotel.smfcore.common.utils.JsonUtil;
import com.neotel.smfcore.common.utils.StringUtils;
import com.neotel.smfcore.core.system.service.manager.IDataLogManager;
import com.neotel.smfcore.core.system.service.po.DataLog;
import com.neotel.smfcore.custom.lizhen.report.merge.utils.FloorUtils;
import com.neotel.smfcore.security.annotation.AnonymousAccess;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
import java.util.Map;
/**
* 外仓外部接口控制类
*/
@RestController
@RequestMapping("/ext")
public class WarehouseExtController {
@Autowired
private IDataLogManager dataLogManager;
@Autowired
private FloorUtils floorUtils;
@RequestMapping("/forward/getDataLogs")
@AnonymousAccess
public List<DataLog> forwardGetDataLogs(String orderNo, String line, Pageable pageable){
String url = "";
Map<String, String> allFloor = floorUtils.getAllFloor(2);
for (String floor : allFloor.values()) {
if (floorUtils.isB15(floor)){
url = floorUtils.getUrlByFloor(floor);
break;
}
}
if (StringUtils.isNotBlank(url)){
url = url + "/ext/getDatalogs"+"?orderNo=" + orderNo + "&line=" + line + "&page=" + pageable.getPageNumber() + "&size=" + pageable.getPageSize();
String result = HttpUtil.get(url);
if (StringUtils.isNotBlank(result)){
return JSONArray.parseArray(result,DataLog.class);
}
}
return null;
}
@RequestMapping("/getDatalogs")
@AnonymousAccess
public List<DataLog> getDatalogs(String orderNo, String line, Pageable pageable) {
List<DataLog> dataLogs = dataLogManager.getDatalogs(orderNo, line, pageable);
return dataLogs;
}
}
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 InventoryDataDao 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.InventoryData;
import com.neotel.smfcore.custom.lizhen.agvBox.service.dao.InventoryDataDao;
import org.springframework.stereotype.Service;
@Service
public class InventoryDataDaoImpl extends AbstractBaseDao implements InventoryDataDao {
@Override
public Class getEntityClass() {
return InventoryData.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.custom.lizhen.agvBox.bean.InventoryData;
import org.springframework.data.mongodb.core.query.Query;
public interface InventoryDataManager extends IBaseManager<InventoryData> {
InventoryData findOne(Query query);
int countByQuery(Query query);
}
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.custom.lizhen.agvBox.bean.InventoryData;
import com.neotel.smfcore.custom.lizhen.agvBox.service.dao.InventoryDataDao;
import com.neotel.smfcore.custom.lizhen.agvBox.service.manager.InventoryDataManager;
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 InventoryDataManagerImpl implements InventoryDataManager {
@Autowired
private InventoryDataDao inventoryDataDao;
@Override
public InventoryData get(String id) {
return null;
}
@Override
public InventoryData save(InventoryData object) throws ValidateException {
return inventoryDataDao.save(object);
}
@Override
public void delete(InventoryData object) throws ValidateException {
}
@Override
public PageData<InventoryData> findByPage(Query query, Pageable pageable) {
int count = inventoryDataDao.countByQuery(query);
List list = inventoryDataDao.findByQuery(query, pageable);
return new PageData<InventoryData>(list, count);
}
@Override
public List<InventoryData> findByQuery(Query query) {
return inventoryDataDao.findByQuery(query);
}
@Override
public InventoryData findOne(Query query) {
return inventoryDataDao.findOne(query);
}
@Override
public int countByQuery(Query query) {
return inventoryDataDao.countByQuery(query);
}
}
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.agvBox.util;
import com.neotel.smfcore.common.utils.StringUtils;
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.custom.lizhen.agvBox.bean.InventoryData;
import com.neotel.smfcore.custom.lizhen.agvBox.bean.PartitionInfo;
import com.neotel.smfcore.custom.lizhen.agvBox.bean.enums.InventoryStatus;
import com.neotel.smfcore.custom.lizhen.agvBox.service.manager.InventoryDataManager;
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 java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Service
public class BoxUtil {
private static DataCache dataCache;
@Autowired
private void setDataCache(DataCache cache) {
this.dataCache = cache;
}
private static InventoryDataManager inventoryDataManager;
@Autowired
private void setInventoryDataManager(InventoryDataManager manager) {
this.inventoryDataManager = manager;
}
/**
* 盘点数据key
*/
private static final String INVENTORY_DATA = "barcode.inventory.data";
/**
* 解析料箱信息
*
* @param str
* @return
*/
public static String getBoxStr(String str) {
String boxStr = "";
if (StringUtils.isNotBlank(str)) {
if (str.startsWith("CS") || str.startsWith("CM") || str.startsWith("CB")) {
if (str.endsWith("A") || str.endsWith("B")) {
boxStr = str.substring(0, str.length() - 1);
} else if (str.indexOf("-") != -1) {
boxStr = str.substring(0, str.indexOf("-"));
} else {
boxStr = str;
}
}
}
return boxStr;
}
/**
* 隔口数量
*
* @param partition
* @param subCodeList
* @return
*/
public static int getPartitionNum(String partition, List<Barcode> subCodeList) {
if (subCodeList != null && !subCodeList.isEmpty()) {
int num = subCodeList.stream().filter(item -> partition.equals(item.getPosName())).mapToInt(Barcode::getAmount).sum();
return num;
}
return 0;
}
/**
* 获取隔口料号
*
* @param partition
* @param subCodeList
* @return
*/
public static String getPartitionPartNumber(String partition, List<Barcode> subCodeList) {
String partNumber = "";
for (Barcode subCode : subCodeList) {
if (partition.equals(subCode.getPosName())) {
partNumber = subCode.getPartNumber();
break;
}
}
return partNumber;
}
/**
* 获取隔口数量
*
* @param partition
* @param subCodeList
* @return
*/
public static int getPartitionCount(String partition, List<Barcode> subCodeList) {
if (subCodeList != null && !subCodeList.isEmpty()) {
int partitionCount = (int) subCodeList.stream().filter(item -> partition.equals(item.getPosName())).count();
return partitionCount;
}
return 0;
}
/**
* 获取隔口的信息
*
* @param boxSideStr
* @param barcode
* @return
*/
public static List<PartitionInfo> getPartitionInfo(String boxSideStr, Barcode barcode) {
List<PartitionInfo> infoList = new ArrayList<>();
List<Barcode> subCodeList = barcode.getSubCodeList();
if (subCodeList != null && !subCodeList.isEmpty()) {
Map<String, PartitionInfo> infoMap = new HashMap<>();
String boxStr = getBoxStr(boxSideStr);
for (int i = 1; i < 9; i++) {
String partition = boxStr + "-" + i;
PartitionInfo info = new PartitionInfo();
info.setPartition(partition);
info.setReelCount(getPartitionCount(partition, subCodeList));
info.setPartNumber(getPartitionPartNumber(partition, subCodeList));
info.setNum(getPartitionNum(partition, subCodeList));
infoMap.put(partition, info);
}
if (boxSideStr.endsWith("A")) {
if (boxSideStr.startsWith("CS") || boxSideStr.startsWith("CB")) {
for (int i = 8; i > 4; i--) {
String partition = boxStr + "-" + i;
infoList.add(infoMap.get(partition));
}
for (int i = 1; i < 5; i++) {
String partition = boxStr + "-" + i;
infoList.add(infoMap.get(partition));
}
} else {
for (int i = 2; i > 0; i--) {
String partition = boxStr + "-" + i;
infoList.add(infoMap.get(partition));
}
}
} else if (boxSideStr.endsWith("B")) {
if (boxSideStr.startsWith("CS") || boxSideStr.startsWith("CB")) {
for (int i = 4; i > 0; i--) {
String partition = boxStr + "-" + i;
infoList.add(infoMap.get(partition));
}
for (int i = 5; i < 9; i++) {
String partition = boxStr + "-" + i;
infoList.add(infoMap.get(partition));
}
} else {
for (int i = 1; i < 3; i++) {
String partition = boxStr + "-" + i;
infoList.add(infoMap.get(partition));
}
}
}
}
return infoList;
}
/**
* 判断是否盘点完成
* @param boxStr
* @return
*/
public static boolean isInventoryFinished(String boxStr) {
String inventoryBatch = dataCache.getCache(INVENTORY_DATA) +"";
if (StringUtils.isBlank(inventoryBatch) || "-1".equals(inventoryBatch)) {
return true;
}
List<InventoryData> dataList = inventoryDataManager.findByQuery(new Query(Criteria.where("inventoryBatch").is(inventoryBatch).and("box").is(boxStr)));
if (dataList != null && !dataList.isEmpty()) {
for (InventoryData data : dataList) {
if (!data.getStatus().equals(InventoryStatus.FINISHED.name())) {
return false;
}
}
}
return true;
}
/**
* 判断是否可以入库
* @param partitionStr
* @return
*/
public static boolean isCanPutIn(String partitionStr) {
List<String> partitionList = new ArrayList<>();
String boxStr = getBoxStr(partitionStr);
if (partitionStr.startsWith("CS") || partitionStr.startsWith("CB")) {
for (int i = 1; i < 9; i++) {
partitionList.add(boxStr+"-"+i);
}
} else {
for (int i = 1; i < 3; i++) {
partitionList.add(boxStr+"-"+i);
}
}
if (partitionList != null && !partitionList.isEmpty()){
if (partitionList.contains(partitionStr)){
return true;
}
}
return false;
}
}
package com.neotel.smfcore.custom.lizhen.agvBox.util;
import com.neotel.smfcore.core.device.util.DataCache;
import com.neotel.smfcore.custom.lizhen.agvBox.bean.Station;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import java.util.Collection;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@Service
@Slf4j
public class StationCacheUtil {
private static DataCache dataCache;
/**
* 工位缓存信息
*/
private static Map<String, Station> stationMap = new ConcurrentHashMap<>();
public static void saveBoxToBoxCode(Station station){
int boxCurrentNum = station.getBoxCurrentNum();
boxCurrentNum ++;
station.setBoxCurrentNum(boxCurrentNum);
StationCacheUtil.updateStation(station);
}
public static void saveReelToBoxCode(Station station) {
int reelCurrentNum = station.getReelCurrentNum();
reelCurrentNum++;
station.setReelCurrentNum(reelCurrentNum);
StationCacheUtil.updateStation(station);
}
@PostConstruct
public void init() {
log.info("开始工位缓存信息");
for (int i = 1; i <= 5; i++) {
String stationName = "s" + i;
Station station = dataCache.getCache(stationName);
if(station == null){
station = new Station();
station.setName(stationName);
}
stationMap.put(stationName,station);
dataCache.updateCache(stationName, station);
}
}
public static synchronized void updateStation(Station station){
stationMap.put(station.getName(),station);
dataCache.updateCache(station.getName(), station);
}
/**
* 更新工位当前的RFID信息
* @param stationName 工位名称
* @param rfid 料箱RFID信息
*/
public static void updateCurrentRfid(String stationName, String rfid){
if(rfid == null){
rfid = "";
}
Station station = getStation(stationName);
if(station != null){
String oldRfid = station.getCurrentRfid();
if (!rfid.equals(oldRfid)) {
log.info("工位" + stationName + " 切换料箱,当前料箱:" + rfid + ",上一料箱:" + oldRfid);
station.setCurrentRfid(rfid);
updateStation(station);
}
} else {
station = new Station();
station.setName(stationName);
station.setCurrentRfid(rfid);
updateStation(station);
}
}
/**
* 获取所有工位的缓存信息
*/
public static Collection<Station> getAllStations(){
return stationMap.values();
}
/**
* 获取工位信息
* @param stationName 工位名称
* @return
*/
public static Station getStation(String stationName){
return stationMap.get(stationName);
}
@Autowired
public void setDataCache(DataCache dataCache) {
StationCacheUtil.dataCache = dataCache;
}
}
......@@ -39,4 +39,6 @@ public class PreWarningItem extends BasePo {
* 接收时间
*/
private Date receiveDate = new Date();
private String pickingId;
}
package com.neotel.smfcore.custom.lizhen.innerBox.util;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class CommonUtil {
public static String plantCode;
@Value("${api.plantCode}")
private void setPlantCode(String code){
CommonUtil.plantCode = code;
}
}
package com.neotel.smfcore.custom.lizhen.innerBox.util;
import com.alibaba.fastjson.JSON;
import com.mks.api.response.Item;
import com.neotel.smfcore.common.utils.Constants;
import com.neotel.smfcore.common.utils.StringUtils;
import com.neotel.smfcore.core.device.util.DataCache;
import com.neotel.smfcore.core.order.LiteOrderCache;
import com.neotel.smfcore.core.order.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.rest.bean.LineConfig;
import com.neotel.smfcore.custom.lizhen.innerBox.bean.PreWarningItem;
import com.neotel.smfcore.custom.lizhen.innerBox.service.manager.IPreWarningItemManager;
import com.neotel.smfcore.custom.lizhen.innerBox.util.service.PreWarningItemCacheManager;
import com.neotel.smfcore.custom.lizhen.third.maicheng.bean.StationStatus;
import com.neotel.smfcore.custom.lizhen.third.maicheng.util.StationStatusCache;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
......@@ -75,70 +69,13 @@ public class PreWarningItemCache {
queueItemList = preWarningItemManager.findAll();
}
if (queueItemList != null && !queueItemList.isEmpty()) {
//迈征集合
List<PreWarningItem> maiZhengItemList = new ArrayList<>();
//其他工单集合
List<PreWarningItem> otherItemList = new ArrayList<>();
//挑出迈征和其他工单
Map<String, String> stationStatusMap = StationStatusCache.getStationStatusMap();
for (PreWarningItem item : queueItemList) {
/*String station = item.getStation();
String partnumber = item.getPartnumber();
String slot = item.getSlot();
String line = item.getLine();
String side = item.getSide();
String key = station + "_" + partnumber + "_" + slot + "_" + line+"_"+side;
String value = stationStatusMap.get(key);
if (StringUtils.isNotBlank(value)) {
maiZhengItemList.add(item);
} else {
otherItemList.add(item);
}*/
otherItemList.add(item);
}
//处理迈征工单信息
/*if (maiZhengItemList != null && !maiZhengItemList.isEmpty()) {
maiZhengItemList = maiZhengItemList.stream().sorted(Comparator.comparing(PreWarningItem::getReceiveDate)).collect(Collectors.toList());
int minute = dataCache.getCache(Constants.CACHE_maiZhengMinute);
if (minute == 0) {
minute = 20;
}
//如果第一条接受的时间和当前时间相差超过设定时间
PreWarningItem firstItem = maiZhengItemList.get(0);
if (System.currentTimeMillis() - firstItem.getReceiveDate().getTime() > 1000 * 60 * minute) {
//获取迈征的线体
List<String> lineList = StationStatusCache.getStationStatusLineList();
if (lineList != null && !lineList.isEmpty()) {
for (String cacheLine : lineList) {
List<PreWarningItem> itemList = new ArrayList<>();
for (PreWarningItem item : maiZhengItemList) {
String line = item.getLine();
String station = item.getStation();
String side = item.getSide();
String trackNumber = "";
if (StringUtils.isNotBlank(station)) {
trackNumber = station.substring(station.length() - 1);
}
line = line + "_" + side + "_" + trackNumber;
if (line.equals(cacheLine)) {
itemList.add(item);
}
}
if (itemList != null && !itemList.isEmpty()) {
createAndExecuteLiteOrder(itemList, true);
}
}
}
}
}*/
//处理其他工单信息
if (otherItemList != null && !otherItemList.isEmpty()) {
Map<String, List<PreWarningItem>> otherItemGroupMap = otherItemList.stream().collect(Collectors.groupingBy(PreWarningItem::getLine));
......@@ -174,14 +111,6 @@ public class PreWarningItemCache {
public static synchronized LiteOrder createAndExecuteLiteOrder(List<PreWarningItem> lineItems, boolean maiZheng) {
//1.得到优先级比较高的
LiteOrder liteOrder = new LiteOrder();
//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);
}*/
//2 如果优先级不为空,则优先生成优先级高的工单
List<LiteOrderItem> orderItems = new ArrayList<>();
if (lineItems != null && !lineItems.isEmpty()) {
......@@ -204,6 +133,7 @@ public class PreWarningItemCache {
orderItem.setReel(item.getReel());
orderItem.setBrand(item.getBrand());
orderItem.setReceiveDate(item.getReceiveDate());
orderItem.setPickingId(item.getPickingId());
orderItems.add(orderItem);
}
}
......
......@@ -58,7 +58,7 @@ public class KafkaService {
/**
* 设备状态发送
*/
@Scheduled(fixedRate = 1000 * 60 * 1)
//@Scheduled(fixedRate = 1000 * 60 * 1)
public void setMachineStatus() {
log.info("发送设备状态开始");
Collection<Storage> storages = dataCache.getAllStorage().values();
......@@ -158,7 +158,7 @@ public class KafkaService {
/**
* 心跳数据发送
*/
@Scheduled(fixedRate = 1000 * 60 * 5)
//@Scheduled(fixedRate = 1000 * 60 * 5)
public void setHeartbeat() {
log.info("发送心跳开始");
//根据machineId,找到设备状态,是否正常
......@@ -203,7 +203,7 @@ public class KafkaService {
/**
* 设备状态发送
*/
@Scheduled(fixedRate = 1000 * 60 * 1)
//@Scheduled(fixedRate = 1000 * 60 * 1)
public void setStorageExportStatus() {
log.info("发送出料口信息开始");
......@@ -272,7 +272,7 @@ public class KafkaService {
/**
* 发送出料口心跳
*/
@Scheduled(fixedRate = 1000 * 60 * 5)
//@Scheduled(fixedRate = 1000 * 60 * 5)
public void setStorageHeartbeat() {
log.info("发送出料口心跳开始");
EquipStatusBean statusBean = EquipStatusUtil.getStatusBean(KafkaConfig.LINE_CID);
......@@ -308,7 +308,7 @@ public class KafkaService {
/**
* MachineParameter发送
*/
@Scheduled(fixedRate = 1000 * 60 * 5)
//@Scheduled(fixedRate = 1000 * 60 * 5)
public void setMachineParameter() {
log.info("MachineParameter开始发送");
List<String> machineIdList = getMachineIdList();
......
package com.neotel.smfcore.custom.lizhen.kanban.bacheng;
import com.google.common.collect.Maps;
import com.neotel.smfcore.common.bean.ResultBean;
import com.neotel.smfcore.common.utils.DateUtil;
import com.neotel.smfcore.common.utils.StringUtils;
import com.neotel.smfcore.core.device.bean.BoxStatusBean;
import com.neotel.smfcore.core.device.bean.StatusBean;
import com.neotel.smfcore.core.device.enums.BOX_STATUS;
import com.neotel.smfcore.core.device.util.DataCache;
import com.neotel.smfcore.core.order.service.manager.ILiteOrderItemManager;
import com.neotel.smfcore.core.storage.service.manager.IStoragePosManager;
import com.neotel.smfcore.core.storage.service.po.Storage;
import com.neotel.smfcore.core.system.util.DevicesStatusUtil;
import com.neotel.smfcore.custom.lizhen.innerBox.bean.StorageExport;
import com.neotel.smfcore.custom.lizhen.innerBox.util.StorageExportUtil;
import com.neotel.smfcore.custom.lizhen.kanban.bacheng.bean.Status;
import com.neotel.smfcore.custom.lizhen.kanban.bacheng.bean.dto.BcStationDto;
import com.neotel.smfcore.custom.lizhen.kanban.bacheng.bean.dto.BcStorageDto;
import com.neotel.smfcore.custom.lizhen.kanban.common.KanbanUtils;
import com.neotel.smfcore.custom.lizhen.kanban.common.bean.dto.InOutDataDto;
import com.neotel.smfcore.custom.lizhen.kanban.inner.bean.dto.LackPickingDto;
import com.neotel.smfcore.security.annotation.AnonymousAccess;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
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.text.ParseException;
import java.util.*;
import java.util.stream.Collectors;
/**
* 巴城看板
*/
@RestController
@RequestMapping("/bcKanban")
public class BcKanbanController {
@Autowired
private IStoragePosManager storagePosManager;
@Autowired
private DataCache dataCache;
@Autowired
private ILiteOrderItemManager liteOrderItemManager;
/*@Value("${disable.export}")
private String disableExport;*/
private static Map<String, Long> expireMap = Maps.newConcurrentMap();
private static Map<String,LackPickingDto> pickingDtoMap = Maps.newConcurrentMap();
/**
* 获取近7天出入库统计
*
* @return
*/
@RequestMapping("/getSevenDaysInAndOutAmount")
@AnonymousAccess
public ResultBean getSevenDaysInAndOutAmount() throws ParseException {
InOutDataDto dto = KanbanUtils.getSevenDaysInAndOutAmount();
return ResultBean.newOkResult(dto);
}
/**
* 获取当天出入库统计
*
* @return
*/
@RequestMapping("/getTodayInAndOutAmount")
@AnonymousAccess
public ResultBean getTodayInAndOutAmount() throws ParseException {
Map<String, Integer> map = KanbanUtils.getTodayInAndOutAmount();
return ResultBean.newOkResult(map);
}
/**
* 过期时间信息
*
* @return
*/
@RequestMapping("/getExpireInfo")
@AnonymousAccess
public ResultBean getExpireInfo() throws ParseException {
Long lastSaveTime = expireMap.get("lastSaveTime");
if (lastSaveTime == null || System.currentTimeMillis() - lastSaveTime >= 1000 * 60 * 10) {
expireMap.put("noExpire", getNoExpireCount());
expireMap.put("zeroToServen", getZeroToServenExpireCount());
expireMap.put("servenToThirty", getServenToThrityExpireCount());
expireMap.put("expire", getExpireCount());
expireMap.put("lastSaveTime", System.currentTimeMillis());
}
return ResultBean.newOkResult(expireMap);
}
/**
* 获取设备详情
*
* @return
*/
@RequestMapping("/getStorageInfo")
@AnonymousAccess
public ResultBean getStorageInfo() {
List<String> cidList = new ArrayList<>();
for (Storage storage : dataCache.getAllStorage().values()) {
cidList.add(storage.getCid().substring(0, storage.getCid().length() - 1));
}
cidList = cidList.stream().distinct().collect(Collectors.toList());
cidList = cidList.stream().sorted().collect(Collectors.toList());
List<BcStorageDto> dtoList = new ArrayList<>();
for (String cid : cidList) {
dtoList.add(getBcStorage(cid, dataCache.getAllStorage().values()));
}
return ResultBean.newOkResult(dtoList);
}
/**
* 获取线体缺料预警信息
*
* @return
* @throws ParseException
*/
@RequestMapping("/getLineInfo")
@AnonymousAccess
public ResultBean getLineLackPickingInfo() throws ParseException {
List<String> lineList = KanbanUtils.getLineByFloor("4F");
List<LackPickingDto> resultList = new ArrayList<>();
for (String line : lineList) {
LackPickingDto lackPickingDto = pickingDtoMap.get(line);
if (lackPickingDto != null && System.currentTimeMillis() - lackPickingDto.getLastTime() < 1000 * 60 * 5){
resultList.add(lackPickingDto);
} else {
LackPickingDto dto = new LackPickingDto();
dto.setLine(line);
//统计缺料数量
dto.setTotalNeedCount(getLackPickingCount(0, line));
//统计已发数量
dto.setTotalOutCount(getLackPickingCount(-1, line));
//待出数量
dto.setReadyOutCount(dto.getTotalNeedCount() - dto.getTotalOutCount());
//上一次查询时间
dto.setLastTime(System.currentTimeMillis());
pickingDtoMap.put(line, dto);
resultList.add(dto);
}
}
return ResultBean.newOkResult(resultList);
}
/**
* 获取出料口信息
*
* @return
*/
@RequestMapping("/getExportInfo")
@AnonymousAccess
public ResultBean getExportInfo() {
List<BcStationDto> stationDtoList = new ArrayList<>();
for (Map.Entry<String, StorageExport> exportEntry : StorageExportUtil.exportMap.entrySet()) {
if (exportEntry.getKey().contains(StorageExportUtil.OUT_STATION)) {
continue;
}
BcStationDto dto = new BcStationDto();
dto.setName(exportEntry.getKey());
dto.setStatus(Status.idle);
StorageExport export = exportEntry.getValue();
if (export.isDisable()) {
dto.setStatus(Status.fault);
} else {
if (StringUtils.isNotBlank(export.getHSerial())) {
dto.setStatus(Status.performTask);
}
}
stationDtoList.add(dto);
}
stationDtoList = stationDtoList.stream().sorted(Comparator.comparing(BcStationDto::getName)).collect(Collectors.toList());
return ResultBean.newOkResult(stationDtoList);
}
private BcStorageDto getBcStorage(String cid, Collection<Storage> storages) {
BcStorageDto dto = new BcStorageDto();
//获取cid开头的所有设备
List<StatusBean> statusBeanList = new ArrayList<>();
List<Storage> storageList = new ArrayList<>();
for (Storage storage : storages) {
if (storage.getCid().startsWith(cid)) {
storageList.add(storage);
StatusBean statusBean = DevicesStatusUtil.getStatusBean(storage.getCid());
if (statusBean != null) {
statusBeanList.add(statusBean);
}
}
}
int totalSlots = storageList.stream().mapToInt(Storage::getTotalSlots).sum();
int emptySlots = storageList.stream().mapToInt(Storage::getEmptySlots).sum();
int useSlots = totalSlots - emptySlots;
dto.setCid(cid);
dto.setNoUse(emptySlots);
dto.setUse(useSlots);
dto.setTotal(totalSlots);
if (statusBeanList == null || statusBeanList.isEmpty()) {
dto.setStatus(Status.fault);
} else {
List<Integer> statusList = new ArrayList<>();
for (StatusBean bean : statusBeanList) {
for (BoxStatusBean statusBean : bean.getBoxStatus().values()) {
statusList.add(statusBean.getStatus());
}
}
if (statusList == null || statusList.isEmpty()) {
dto.setStatus(Status.fault);
} else {
//先判断有没有故障
dto.setStatus(Status.idle);
if (statusList.contains(BOX_STATUS.PUTIN) || statusList.contains(BOX_STATUS.CHECKOUT)) {
dto.setStatus(Status.performTask);
}
if (statusList.contains(BOX_STATUS.EMERGENCY) || statusList.contains(BOX_STATUS.PROBLEM)) {
dto.setStatus(Status.fault);
}
}
}
return dto;
}
private int getLackPickingCount(int num, String line) throws ParseException {
Query q = new Query();
Criteria c = Criteria.where("line").is(line);
if (num == 0) {
c.and("needReelCount").gt(0);
} else if (num == -1) {
c.and("outReelCount").gt(0);
}
//默认是当天时间
Date currentDate = KanbanUtils.getCurrentDate();
//currentDate = DateUtil.addDays(currentDate,-2);
c.andOperator(Criteria.where("updateDate").gte(currentDate), Criteria.where("updateDate").lt(DateUtil.addDays(currentDate, 1)));
return liteOrderItemManager.countByQuery(q.addCriteria(c));
}
private long getExpireCount() {
Query query = new Query().addCriteria(Criteria.where("barcode").exists(true).and("barcode.expireDate").lte(new Date()));
return storagePosManager.countByQuery(query);
}
private long getNoExpireCount() {
List<Criteria> orCriList = new ArrayList<>();
orCriList.add(Criteria.where("barcode").exists(true).and("barcode.expireDate").gt(new Date()));
orCriList.add(Criteria.where("barcode").exists(true).and("barcode.expireDate").exists(false));
return storagePosManager.countByQuery(new Query(new Criteria().orOperator(orCriList)));
}
private long getZeroToServenExpireCount() {
Date startDate = new Date();
Date endDate = DateUtil.addDays(startDate, 7);
Query query = new Query().addCriteria(Criteria.where("barcode").exists(true).and("barcode.expireDate").gte(startDate).lt(endDate));
return storagePosManager.countByQuery(query);
}
private long getServenToThrityExpireCount() {
Date date = new Date();
Date startDate = DateUtil.addDays(date, 7);
Date endDate = DateUtil.addDays(date, 30);
Query query = new Query().addCriteria(Criteria.where("barcode").exists(true).and("barcode.expireDate").gte(startDate).lt(endDate));
return storagePosManager.countByQuery(query);
}
}
package com.neotel.smfcore.custom.lizhen.kanban.bacheng.bean;
import lombok.Data;
@Data
public class Status {
/**
* 空闲
*/
public static final int idle = 1;
/**
* 执行任务
*/
public static final int performTask = 2;
/**
* 故障
*/
public static final int fault = 3;
}
package com.neotel.smfcore.custom.lizhen.kanban.bacheng.bean.dto;
import lombok.Data;
@Data
public class BcStationDto {
private String name;
private int status;
}
package com.neotel.smfcore.custom.lizhen.kanban.bacheng.bean.dto;
import lombok.Data;
@Data
public class BcStorageDto {
private String cid;
private int status;
private int total;
private int use;
private int noUse;
}
package com.neotel.smfcore.custom.lizhen.kanban.common;
import com.neotel.smfcore.common.utils.DateUtil;
import com.neotel.smfcore.core.device.enums.OP;
import com.neotel.smfcore.core.device.util.DataCache;
import com.neotel.smfcore.core.storage.service.manager.IStoragePosManager;
import com.neotel.smfcore.core.system.service.manager.IDataLogManager;
import com.neotel.smfcore.custom.lizhen.kanban.common.bean.dto.InOutDataDto;
import com.neotel.smfcore.custom.lizhen.kanban.service.manager.InOutDataDtoManager;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RestController;
import java.text.ParseException;
import java.util.*;
@RestController
@Slf4j
public class KanbanUtils {
private static String F2;
private static String F3;
private static String F5;
private static String F4;
private static IDataLogManager dataLogManager;
private static IStoragePosManager storagePosManager;
private static DataCache dataCache;
private static InOutDataDtoManager inOutDataManager;
/**
* 今日出入库缓存
*/
private static InOutDataDto todayInOutDto = null;
/**
* 得到当日的出入库完成统计
*
* @return
*/
public static Map<String, Integer> getTodayInAndOutAmount() throws ParseException {
Map<String, Integer> resultMap = new HashMap<>();
int inCount = 0;
int outCount = 0;
if (todayInOutDto == null || System.currentTimeMillis() - todayInOutDto.getCreateDate().getTime() >= 1000 * 60 * 1) {
todayInOutDto = new InOutDataDto();
//得到当前日期与结束日期
Date startDate = getCurrentDate();
Date endDate = DateUtil.addDays(startDate, 1);
//得到出入库数据
inCount = dataLogManager.getInOutData(startDate, endDate, OP.PUT_IN, "", -1, "");
outCount = dataLogManager.getInOutData(startDate, endDate, OP.CHECKOUT, "", -1, "");
todayInOutDto.setInValue(inCount);
todayInOutDto.setOutValue(outCount);
todayInOutDto.setCreateDate(new Date());
} else {
inCount = todayInOutDto.getInValue();
outCount = todayInOutDto.getOutValue();
}
resultMap.put("in", inCount);
resultMap.put("out", outCount);
return resultMap;
}
/**
* 得到近7天的出入库数量
*
* @return
*/
public static InOutDataDto getSevenDaysInAndOutAmount() throws ParseException {
InOutDataDto dataDto = getSixDaysAgoData();
Date currentDate = getCurrentDate(); //当前时间
//增加当天出入库记录
List<String> labelList = dataDto.getLabelList();
labelList.add(DateUtil.toDateString(currentDate, "MM/dd"));
dataDto.setLabelList(labelList);
Map<String, Integer> todayInAndOutAmount = getTodayInAndOutAmount();
Integer inValue = todayInAndOutAmount.get("in");
Integer outValue = todayInAndOutAmount.get("out");
List<Integer> putInValueList = dataDto.getPutInValueList();
putInValueList.add(inValue);
dataDto.setPutInValueList(putInValueList);
List<Integer> checkOutValueList = dataDto.getCheckOutValueList();
checkOutValueList.add(outValue);
dataDto.setCheckOutValueList(checkOutValueList);
return dataDto;
}
private static InOutDataDto getSixDaysAgoData() throws ParseException {
Date currentDate = getCurrentDate();
InOutDataDto dataDto = inOutDataManager.getSixDaysAgoData(currentDate);
if (dataDto == null) {
dataDto = new InOutDataDto();
List<String> labelList = new ArrayList<>();
List<Integer> putInValueList = new ArrayList<>();
List<Integer> checkOutValueList = new ArrayList<>();
Date startDate = DateUtil.addDays(currentDate, -6); //开始时间(与当前时间相差7天)
for (int day = 1; day < 7; day++) {
Date endDate = DateUtil.addDays(startDate, 1);
int inData = dataLogManager.getInOutData(startDate, endDate, OP.PUT_IN, "", -1, "");
int outData = dataLogManager.getInOutData(startDate, endDate, OP.CHECKOUT, "", -1, "");
labelList.add(DateUtil.toDateString(startDate, "MM/dd"));
putInValueList.add(inData);
checkOutValueList.add(outData);
startDate = endDate;
}
dataDto.setCheckOutValueList(checkOutValueList);
dataDto.setPutInValueList(putInValueList);
dataDto.setLabelList(labelList);
inOutDataManager.save(dataDto);
}
return dataDto;
}
/**
* 得到当前日期
*
* @return
*/
public static Date getCurrentDate() throws ParseException {
Date date = new Date();
//获取当天的7点时间
String currentDayStr = DateUtil.toDateString(date, "yyyy-MM-dd");
currentDayStr += " 07:00:00";
Date currentDay = DateUtil.toDate(currentDayStr, "yyyy-MM-dd HH:mm:ss");
//获取第二天时间
Date lastDay = DateUtil.addDays(currentDay, -1);
if (date.getTime() > currentDay.getTime()) {
return currentDay;
} else {
return lastDay;
}
}
/**
* 根据楼层得到线体
*
* @param floor
* @return
*/
public static List<String> getLineByFloor(String floor) {
List<String> lineList = new ArrayList<>();
//得到每一个楼层的线体
String f2Line = dataCache.getCache("F2Line").toString();
String f3Line = dataCache.getCache("F3Line").toString();
String f5Line = dataCache.getCache("F5Line").toString();
String f4Line = dataCache.getCache("F4Line").toString();
if (F2.equals(floor)) {
lineList = new ArrayList<>(Arrays.asList(f2Line.split(",")));
} else if (F3.equals(floor)) {
lineList = new ArrayList<>(Arrays.asList(f3Line.split(",")));
} else if (F5.equals(floor)) {
lineList = new ArrayList<>(Arrays.asList(f5Line.split(",")));
} else if (F4.equals(floor)) {
lineList = new ArrayList<>(Arrays.asList(f4Line.split(",")));
}
return lineList;
}
@Autowired
private void setDataLogManager(IDataLogManager dataLogManager) {
this.dataLogManager = dataLogManager;
}
@Autowired
private void setStoragePosManager(IStoragePosManager storagePosManager) {
this.storagePosManager = storagePosManager;
}
@Autowired
private void setDataCache(DataCache dataCache) {
this.dataCache = dataCache;
}
@Autowired
private void setInOutDataManager(InOutDataDtoManager manager) {
this.inOutDataManager = manager;
}
@Value("${lizhen.F2.name}")
private void setF2Floor(String floor) {
F2 = floor;
}
@Value("${lizhen.F3.name}")
private void setF3Floor(String floor) {
F3 = floor;
}
@Value("${lizhen.F5.name}")
private void setF5Floor(String floor) {
F5 = floor;
}
@Value("${lizhen.F4.name}")
private void setF4Floor(String floor) {
F4 = floor;
}
}
package com.neotel.smfcore.custom.lizhen.kanban.common.bean.dto;
import com.neotel.smfcore.common.base.BasePo;
import lombok.Data;
import lombok.Setter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
@Data
public class InOutDataDto extends BasePo {
public InOutDataDto() {
this.labelList = new ArrayList<>();
this.putInValueList = new ArrayList<>();
this.checkOutValueList = new ArrayList<>();
}
/**
* 日期
*/
private List<String> labelList;
/**
* 入库量
*/
private List<Integer> putInValueList;
/**
* 出库量
*/
private List<Integer> checkOutValueList;
/**
* 当前时间
*/
private String dateStr;
/**
* 入库量
*/
private int inValue;
/**
* 出库量
*/
private int outValue;
}
package com.neotel.smfcore.custom.lizhen.kanban.inner;
import cn.hutool.core.date.DateUnit;
import com.google.common.collect.Maps;
import com.neotel.smfcore.common.bean.ResultBean;
import com.neotel.smfcore.common.utils.DateUtil;
import com.neotel.smfcore.core.barcode.service.po.Barcode;
import com.neotel.smfcore.core.device.bean.StatusBean;
import com.neotel.smfcore.core.device.enums.OP;
import com.neotel.smfcore.core.device.util.DataCache;
import com.neotel.smfcore.core.order.service.manager.ILiteOrderItemManager;
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.DevicesStatusUtil;
import com.neotel.smfcore.core.system.util.TaskService;
import com.neotel.smfcore.custom.lizhen.kanban.common.KanbanUtils;
import com.neotel.smfcore.custom.lizhen.kanban.common.bean.dto.InOutDataDto;
import com.neotel.smfcore.custom.lizhen.kanban.inner.bean.dto.DevicesStatusDto;
import com.neotel.smfcore.custom.lizhen.kanban.inner.bean.dto.LackPickingDto;
import com.neotel.smfcore.security.annotation.AnonymousAccess;
import io.swagger.models.auth.In;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
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.text.ParseException;
import java.util.*;
@RestController
@RequestMapping("/innerKanban")
public class InnerKanbanController {
@Autowired
private DataCache dataCache;
@Autowired
private ILiteOrderItemManager liteOrderItemManager;
@Autowired
private IDataLogManager dataLogManager;
@Autowired
private IStoragePosManager storagePosManager;
@Autowired
private TaskService taskService;
public static final Map<String,Long> expireMap = Maps.newConcurrentMap();
/**
* 获取近7天出入库统计
* @return
*/
@RequestMapping("/getSevenDaysInAndOutAmount")
@AnonymousAccess
public ResultBean getSevenDaysInAndOutAmount() throws ParseException {
InOutDataDto dto = KanbanUtils.getSevenDaysInAndOutAmount();
return ResultBean.newOkResult(dto);
}
/**
* 获取当天出入库统计
* @return
*/
@RequestMapping("/getTodayInAndOutAmount")
@AnonymousAccess
public ResultBean getTodayInAndOutAmount() throws ParseException {
Map<String, Integer> map = KanbanUtils.getTodayInAndOutAmount();
return ResultBean.newOkResult(map);
}
/**
* 获取线体缺料预警信息
*
* @param floor 楼层
* @return
*/
@RequestMapping("/getLineInfo")
@AnonymousAccess
public ResultBean getLineLackPickingInfo(String floor) throws ParseException {
List<String> lineList = KanbanUtils.getLineByFloor(floor);
List<LackPickingDto> resultList = new ArrayList<>();
for (String line : lineList) {
LackPickingDto dto = new LackPickingDto();
dto.setLine(line);
//统计缺料数量
dto.setTotalNeedCount(getLackPickingCount(0, line));
//统计已发数量
dto.setTotalOutCount(getLackPickingCount(-1, line));
//待出数量
dto.setReadyOutCount(dto.getTotalNeedCount() - dto.getTotalOutCount());
resultList.add(dto);
}
return ResultBean.newOkResult(resultList);
}
/**
* 获取设备状态信息
*
* @return
*/
@RequestMapping("/getDevicesStatus")
@AnonymousAccess
public ResultBean getDevicesStatus() throws ParseException {
List<DevicesStatusDto> resultList = new ArrayList<>();
//开始时间与结束时间
Date currentDate = KanbanUtils.getCurrentDate();
currentDate = DateUtil.addDays(currentDate, -2);
Date endDate = DateUtil.addDays(currentDate, 1);
for (Storage storage : dataCache.getAllStorage().values()) {
//排除虚拟仓的
if (!storage.isVirtual()) {
int emptySlots = storage.getEmptySlots(); //空库位
int totalSlots = storage.getTotalSlots(); //所有库位
int useSlots = totalSlots - emptySlots; //使用库位
String name = storage.getName(); //库位名称
int usage = (int) (((double) useSlots / totalSlots) * 100); //库位使用率
//获取设备状态
int status = 0;
StatusBean bean = DevicesStatusUtil.getStatusBean(storage.getCid());
if (bean != null){
status = bean.getStatus();
}
//出入库数据
//int inCount = dataLogManager.getInOutData(currentDate, endDate, OP.PUT_IN, "", -1, storage.getId());
//int outCount = dataLogManager.getInOutData(currentDate, endDate, OP.CHECKOUT, "", -1, storage.getId());
DevicesStatusDto dto = new DevicesStatusDto();
dto.setName(name);
dto.setPosUseCount(useSlots);
dto.setPosAllCount(totalSlots);
//dto.setInCount(inCount);
//dto.setOutCount(outCount);
dto.setUsage(usage);
dto.setStatus(status);
if (storage.isNLShelf()){
dto.setType(0);
} else {
dto.setType(1);
}
resultList.add(dto);
}
}
return ResultBean.newOkResult(resultList);
}
/**
* 所有设备库位使率汇总
* @return
*/
@RequestMapping("/getAllUsage")
@AnonymousAccess
public ResultBean getAllUsage(){
int usage = 0;
int total = 0;
int use = 0;
List<Storage> resultList = new ArrayList<>();
Collection<Storage> collection = dataCache.getAllStorage().values();
for (Storage storage : collection) {
if (!storage.isVirtual()){
resultList.add(storage);
}
}
if (resultList != null && !resultList.isEmpty()){
int totalSlots = resultList.stream().mapToInt(Storage::getTotalSlots).sum();
int emptySlots = resultList.stream().mapToInt(Storage::getEmptySlots).sum();
usage = (int) (((double) (totalSlots - emptySlots) / totalSlots) * 100); //库位使用率
total = totalSlots;
use = totalSlots - emptySlots;
}
Map<String,Integer> resultMap = new HashMap<>();
resultMap.put("usage",usage);
resultMap.put("total",total);
resultMap.put("use",use);
return ResultBean.newOkResult(resultMap);
}
/**
* 过期时间信息
*
* @return
*/
@RequestMapping("/getExpireInfo")
@AnonymousAccess
public ResultBean getExpireInfo() throws ParseException {
Long lastSaveTime = expireMap.get("lastSaveTime");
if (lastSaveTime == null || System.currentTimeMillis() - lastSaveTime >= 1000 * 60 * 10) {
expireMap.put("noExpire", getNoExpireCount());
expireMap.put("zeroToServen", getZeroToServenExpireCount());
expireMap.put("servenToThirty", getServenToThrityExpireCount());
expireMap.put("expire", getExpireCount());
expireMap.put("lastSaveTime", System.currentTimeMillis());
}
return ResultBean.newOkResult(expireMap);
}
public static void main(String[] args) {
int i = (int) (((double) (99 - 88) / 99) * 100);
System.out.println(i);
}
private int getLackPickingCount(int num, String line) throws ParseException {
Query q = new Query();
Criteria c = Criteria.where("line").is(line);
if (num == 0) {
c.and("needReelCount").gt(0);
} else if (num == -1) {
c.and("outReelCount").gt(0);
}
//默认是当天时间
Date currentDate = KanbanUtils.getCurrentDate();
//currentDate = DateUtil.addDays(currentDate,-2);
c.andOperator(Criteria.where("updateDate").gte(currentDate), Criteria.where("updateDate").lt(DateUtil.addDays(currentDate, 1)));
return liteOrderItemManager.countByQuery(q.addCriteria(c));
}
private long getExpireCount() {
Query query = new Query().addCriteria(Criteria.where("barcode").exists(true).and("barcode.expireDate").lte(new Date()));
return storagePosManager.countByQuery(query);
}
private long getNoExpireCount() {
List<Criteria> orCriList = new ArrayList<>();
orCriList.add(Criteria.where("barcode").exists(true).and("barcode.expireDate").gt(new Date()));
orCriList.add(Criteria.where("barcode").exists(true).and("barcode.expireDate").exists(false));
return storagePosManager.countByQuery(new Query(new Criteria().orOperator(orCriList)));
}
private long getZeroToServenExpireCount() {
Date startDate = new Date();
Date endDate = DateUtil.addDays(startDate, 7);
Query query = new Query().addCriteria(Criteria.where("barcode").exists(true).and("barcode.expireDate").gte(startDate).lt(endDate));
return storagePosManager.countByQuery(query);
}
private long getServenToThrityExpireCount() {
Date date = new Date();
Date startDate = DateUtil.addDays(date, 7);
Date endDate = DateUtil.addDays(date, 30);
Query query = new Query().addCriteria(Criteria.where("barcode").exists(true).and("barcode.expireDate").gte(startDate).lt(endDate));
return storagePosManager.countByQuery(query);
}
}
package com.neotel.smfcore.custom.lizhen.kanban.inner.bean.dto;
import lombok.Data;
/**
* 设备状态信息
*/
@Data
public class DevicesStatusDto {
/**
* 设备名称
*/
private String name;
/**
* 库位使用率
*/
private int usage;
/**
* 入库数据
*/
private int inCount;
/**
* 出库数据
*/
private int outCount;
/**
* 设备状态
*/
private int status;
/**
* 所有库位
*/
private int posAllCount;
/**
* 已使用库位
*/
private int posUseCount;
/**
* 0是料仓 1是料架
*/
private int type;
}
package com.neotel.smfcore.custom.lizhen.kanban.inner.bean.dto;
import lombok.Data;
/**
* 缺料信息(内仓)
*/
@Data
public class LackPickingDto {
/**
* 线体信息
*/
private String line;
/**
* 需要出库的数量
*/
private int totalNeedCount;
/**
* 已经出库的数量
*/
private int totalOutCount;
/**
* 待出数量
*/
private int readyOutCount;
/**
* 上一次保存时间
*/
private Long lastTime;
}
package com.neotel.smfcore.custom.lizhen.kanban.outer;
import cn.hutool.core.date.DateUnit;
import com.google.common.collect.Maps;
import com.neotel.smfcore.common.bean.ResultBean;
import com.neotel.smfcore.common.utils.DateUtil;
import com.neotel.smfcore.core.barcode.service.manager.IBarcodeManager;
import com.neotel.smfcore.core.barcode.service.po.Barcode;
import com.neotel.smfcore.core.device.enums.OP;
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.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.kanban.common.KanbanUtils;
import com.neotel.smfcore.custom.lizhen.kanban.common.bean.dto.InOutDataDto;
import com.neotel.smfcore.custom.lizhen.kanban.outer.bean.dto.PickingProgressDto;
import com.neotel.smfcore.custom.lizhen.kanban.outer.bean.dto.StationInOutDto;
import com.neotel.smfcore.security.annotation.AnonymousAccess;
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.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.text.ParseException;
import java.util.*;
@RestController
@RequestMapping("/outer")
public class OuterKanbanController {
@Autowired
private IDataLogManager dataLogManager;
@Autowired
private DataCache dataCache;
@Autowired
private LiteOrderCache liteOrderCache;
@Autowired
private TaskService taskService;
@Autowired
private IBarcodeManager barcodeManager;
public static Map<String,Long> expireMap = Maps.newConcurrentMap();
public static Long stationInOutTime = null;
public static List<StationInOutDto> dtoList = new ArrayList<>();
/**
* 获取近7天出入库统计
*
* @return
*/
@RequestMapping("/getSevenDaysInAndOutAmount")
@AnonymousAccess
public ResultBean getSevenDaysInAndOutAmount() throws ParseException {
InOutDataDto dto = KanbanUtils.getSevenDaysInAndOutAmount();
return ResultBean.newOkResult(dto);
}
/**
* 获取当天出入库统计
*
* @return
*/
@RequestMapping("/getTodayInAndOutAmount")
@AnonymousAccess
public ResultBean getTodayInAndOutAmount() throws ParseException {
Map<String, Integer> map = KanbanUtils.getTodayInAndOutAmount();
return ResultBean.newOkResult(map);
}
/**
* 获取工位的出入库统计数据
*
* @return
*/
@RequestMapping("/getStationInAndOutAmout")
@AnonymousAccess
public ResultBean getStationInAndOutAmout() throws ParseException {
if (stationInOutTime == null || System.currentTimeMillis() - stationInOutTime >= 1000 * 60 * 5) {
//先把缓存清空
dtoList.clear();
//开始统计值
Date currentDate = KanbanUtils.getCurrentDate();
Date endDate = DateUtil.addDays(currentDate, 1);
for (int i = 1; i < 6; i++) {
StationInOutDto dto = new StationInOutDto();
String stationName = "s" + i;
int inCount = dataLogManager.getInOutData(currentDate, endDate, OP.PUT_IN, stationName);
int outCount = dataLogManager.getInOutData(currentDate, endDate, OP.CHECKOUT, stationName);
dto.setName(stationName.toUpperCase(Locale.ROOT));
dto.setInCount(inCount);
dto.setOutCount(outCount);
dtoList.add(dto);
}
stationInOutTime = System.currentTimeMillis();
}
return ResultBean.newOkResult(dtoList);
}
/**
* 获取库位使用率
*/
@RequestMapping("/getPosUsage")
@AnonymousAccess
public ResultBean getPosUsage() {
Map<String, Object> resultMap = new HashMap<>();
Storage storage = null;
for (Storage stor : dataCache.getAllStorage().values()) {
if (!stor.isVirtual()) {
storage = stor;
break;
}
}
int totalSlots = storage.getTotalSlots(); //全部库位
int emptySlots = storage.getEmptySlots(); //空库位
int usage = (int) (((double) (totalSlots - emptySlots) / totalSlots) * 100); //库位使用率
resultMap.put("usage", usage);
resultMap.put("noUsage", 100 - usage);
resultMap.put("use", (totalSlots - emptySlots));
resultMap.put("noUse", emptySlots);
return ResultBean.newOkResult(resultMap);
}
/**
* 获取picking进度信息
*/
@RequestMapping("/getPickingProgress")
@AnonymousAccess
public ResultBean getPickingProgress() {
LiteOrder liteOrder = new LiteOrder();
Collection<LiteOrder> liteOrders = liteOrderCache.getAllLiteOrder();
for (LiteOrder order : liteOrders) {
if (order.isOutTails()) {
liteOrder = order;
break;
}
}
PickingProgressDto dto = new PickingProgressDto();
if (liteOrder != null) {
dto.setPickingId(liteOrder.getOrderNo());
int progress = (int) (((double) (/*liteOrder.getTaskReelCount() -*/ liteOrder.getFinishedReelCount()) / liteOrder.getTaskReelCount()) * 100); //库位使用率
dto.setProgress(progress);
dto.setOut(liteOrder.getFinishedReelCount());
dto.setTotal(liteOrder.getTaskReelCount());
}
return ResultBean.newOkResult(dto);
}
/**
* 获取出入库记录
*/
@RequestMapping("/getQueueTask")
@AnonymousAccess
public ResultBean getQueueTask() {
List<DataLog> dataLogList = new ArrayList<>();
Collection<DataLog> queueTasks = taskService.getQueueTasks();
for (DataLog queueTask : queueTasks) {
if (!queueTask.isWait()) {
dataLogList.add(queueTask);
}
}
return ResultBean.newOkResult(dataLogList);
}
/**
* 过期时间信息
*
* @return
*/
@RequestMapping("/getExpireInfo")
@AnonymousAccess
public ResultBean getExpireInfo() throws ParseException {
Long lastSaveTime = expireMap.get("lastSaveTime");
if (lastSaveTime == null || System.currentTimeMillis() - lastSaveTime >= 1000 * 60 * 10) {
expireMap.put("noExpire", getNoExpireCount());
expireMap.put("zeroToServen", getZeroToServenExpireCount());
expireMap.put("servenToThirty", getServenToThrityExpireCount());
expireMap.put("expire", getExpireCount());
expireMap.put("lastSaveTime", System.currentTimeMillis());
}
return ResultBean.newOkResult(expireMap);
}
private long getExpireCount() {
Query query = new Query().addCriteria(Criteria.where("posName").exists(true).ne("").and("expireDate").lt(new Date()));
return barcodeManager.countByQuery(query);
}
private long getNoExpireCount() {
List<Criteria> orCriList = new ArrayList<>();
orCriList.add(Criteria.where("expireDate").gt(new Date()).and("posName").exists(true).ne("").and("partNumber").nin(Arrays.asList("CS", "CM", "CB")));
orCriList.add(Criteria.where("expireDate").exists(false).and("posName").exists(true).ne("").and("partNumber").nin(Arrays.asList("CS", "CM", "CB")));
return barcodeManager.countByQuery(new Query(new Criteria().orOperator(orCriList)));
}
private long getZeroToServenExpireCount() {
Date startDate = new Date();
Date endDate = DateUtil.addDays(startDate, 7);
Query query = new Query().addCriteria(Criteria.where("posName").exists(true).ne("").and("expireDate").gte(startDate).lt(endDate));
return barcodeManager.countByQuery(query);
}
private long getServenToThrityExpireCount() {
Date date = new Date();
Date startDate = DateUtil.addDays(date, 7);
Date endDate = DateUtil.addDays(date, 30);
Query query = new Query().addCriteria(Criteria.where("posName").exists(true).ne("").and("expireDate").gte(startDate).lt(endDate));
return barcodeManager.countByQuery(query);
}
}
package com.neotel.smfcore.custom.lizhen.kanban.outer.bean.dto;
import lombok.Data;
@Data
public class PickingProgressDto {
/**
* pickingId
*/
private String pickingId = "";
/**
* 进度
*/
private int progress;
private int out;
private int total;
}
package com.neotel.smfcore.custom.lizhen.kanban.outer.bean.dto;
import lombok.Data;
/**
* 工位出入库数据
*/
@Data
public class StationInOutDto {
/**
* 工位名称
*/
private String name;
/**
* 入库数量
*/
private int inCount;
/**
* 出库数量
*/
private int outCount;
/**
* 状态
*/
private String status = "正常";
}
package com.neotel.smfcore.custom.lizhen.kanban.service.dao;
import com.neotel.smfcore.common.base.IBaseDao;
import com.neotel.smfcore.custom.lizhen.kanban.common.bean.dto.InOutDataDto;
import java.util.Date;
public interface InOutDataDtoDao extends IBaseDao {
}
package com.neotel.smfcore.custom.lizhen.kanban.service.dao.impl;
import com.neotel.smfcore.common.base.AbstractBaseDao;
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.kanban.common.bean.dto.InOutDataDto;
import com.neotel.smfcore.custom.lizhen.kanban.service.dao.InOutDataDtoDao;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;
import java.util.Date;
@Service
public class InOutDataDtoImpl extends AbstractBaseDao implements InOutDataDtoDao {
@Override
public Class getEntityClass() {
return InOutDataDto.class;
}
}
package com.neotel.smfcore.custom.lizhen.kanban.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 com.neotel.smfcore.custom.lizhen.kanban.common.bean.dto.InOutDataDto;
import java.util.Date;
import java.util.List;
public interface InOutDataDtoManager extends IBaseManager<InOutDataDto> {
InOutDataDto getSixDaysAgoData(Date currentDate);
}
package com.neotel.smfcore.custom.lizhen.kanban.service.manager.impl;
import com.neotel.smfcore.common.bean.PageData;
import com.neotel.smfcore.common.exception.ValidateException;
import com.neotel.smfcore.custom.lizhen.kanban.common.bean.dto.InOutDataDto;
import com.neotel.smfcore.custom.lizhen.kanban.service.dao.InOutDataDtoDao;
import com.neotel.smfcore.custom.lizhen.kanban.service.manager.InOutDataDtoManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;
import java.util.Date;
import java.util.List;
@Service
public class InOutDataDtoManagerImpl implements InOutDataDtoManager {
@Autowired
private InOutDataDtoDao inOutDataDtoDao;
@Override
public InOutDataDto get(String id) {
return null;
}
@Override
public InOutDataDto save(InOutDataDto object) throws ValidateException {
return inOutDataDtoDao.save(object);
}
@Override
public void delete(InOutDataDto object) throws ValidateException {
}
@Override
public PageData<InOutDataDto> findByPage(Query query, Pageable pageable) {
return null;
}
@Override
public List<InOutDataDto> findByQuery(Query query) {
return null;
}
@Override
public InOutDataDto getSixDaysAgoData(Date currentDate) {
Query query = Query.query(Criteria.where("createDate").gte(currentDate));
return inOutDataDtoDao.findOne(query);
}
}
package com.neotel.smfcore.custom.lizhen.kanban.utils;
import com.neotel.smfcore.common.bean.ResultBean;
import com.neotel.smfcore.common.utils.StringUtils;
import com.neotel.smfcore.custom.lizhen.kanban.common.KanbanUtils;
import com.neotel.smfcore.custom.lizhen.kanban.utils.bean.AgvInfo;
import com.neotel.smfcore.custom.lizhen.kanban.utils.enums.Location;
import com.neotel.smfcore.security.annotation.AnonymousAccess;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
/**
* agv小车状态信息缓存
*/
@RestController
public class AgvStatusCache {
@Value("${lizhen.F2.name}")
private String F2;
@Value("${lizhen.F3.name}")
private String F3;
@Value("${lizhen.F5.name}")
private String F5;
private static List<AgvInfo> agvInfoCacheList = new CopyOnWriteArrayList<>();
/**
* agv状态信息上报
*
* @param infoList
* @return
*/
@RequestMapping("/service/store/agvStatus/agvInfo")
@AnonymousAccess
public ResultBean agvInfo(@RequestBody List<AgvInfo> infoList) {
AgvInfo agvInfo = infoList.get(0);
boolean hasAgvInfo = false;
if (agvInfoCacheList != null && !agvInfoCacheList.isEmpty()) {
for (int i = 0; i < agvInfoCacheList.size(); i++) {
AgvInfo info = agvInfoCacheList.get(i);
if (info.getName().equals(agvInfo.getName())) {
agvInfoCacheList.remove(i);
agvInfoCacheList.add(i,agvInfo);
hasAgvInfo = true;
}
}
} else {
agvInfoCacheList = infoList;
hasAgvInfo = true;
}
if (!hasAgvInfo){
agvInfoCacheList.addAll(infoList);
}
return ResultBean.newOkResult(null);
}
/**
* 获取agv状态信息
*
* @param floor
* @return
*/
@RequestMapping("/agvStatus/getAgvInfoBySource")
@AnonymousAccess
public ResultBean getAgvInfoBySource(String floor) {
List<String> locList = new ArrayList<>();
List<String> locCnList = new ArrayList<>();
if (F2.equals(floor) || F3.equals(floor) || F5.equals(floor)) {
locList = KanbanUtils.getLineByFloor(floor);
locList.addAll(getLocByType(0));
locCnList = KanbanUtils.getLineByFloor(floor);
locCnList.addAll(getLocCnByType(0));
} else {
locList.addAll(getLocByType(2));
locCnList.addAll(getLocCnByType(2));
}
for (AgvInfo agvInfo : agvInfoCacheList) {
String loc = agvInfo.getLoc();
if (StringUtils.isNotBlank(Location.getLoc(loc))) {
agvInfo.setLocCn(Location.getLoc(loc));
} else {
agvInfo.setLocCn(agvInfo.getLoc());
}
agvInfo.setLocList(locList);
agvInfo.setLocCnList(locCnList);
}
return ResultBean.newOkResult(agvInfoCacheList);
}
private List<String> getLocByType(int type) {
List<String> locList = new ArrayList<>();
for (Location loc : Location.values()) {
int locType = Location.getType(loc.name());
if (locType == 0 || locType == type) {
locList.add(loc.name());
}
}
return locList;
}
private List<String> getLocCnByType(int type) {
List<String> locList = new ArrayList<>();
for (Location loc : Location.values()) {
int locType = Location.getType(loc.name());
if (locType == 0 || locType == type) {
locList.add(Location.getLoc(loc.name()));
}
}
return locList;
}
}
package com.neotel.smfcore.custom.lizhen.kanban.utils.bean;
import lombok.Data;
import java.util.List;
@Data
public class AgvInfo {
/**
* 小车名称
*/
private String name;
/**
* 小车电量
*/
private String elec;
/**
* 小车位置
*/
private String loc;
/**
* 小车位置 中文
*/
private String locCn;
/**
* 位置集合
*/
private List<String> locList;
/**
* 位置集合 中文
*/
private List<String> locCnList;
int type = 0;
}
package com.neotel.smfcore.custom.lizhen.kanban.utils.enums;
/**
* 点位 AGV
*/
public enum Location {
//外仓点位
WAREHOUSE("仓库", 2),
PUT("放料点", 2),
//内外仓,通用点位
STANDBY("待机点", 0),
CHARGE("充电点", 0),
TAKE("取料点", 0);
private String loc;
private int type;
Location(String loc, int type) {
this.loc = loc;
this.type = type;
}
/**
* 根据名称获取位置
*
* @param name
* @return
*/
public static String getLoc(String name) {
for (Location location : Location.values()) {
if (location.name().equals(name)) {
return location.loc;
}
}
return null;
}
/**
* 根据名称获取类别
*
* @param name
* @return
*/
public static int getType(String name) {
for (Location location : Location.values()) {
if (location.name().equals(name)) {
return location.type;
}
}
return -1;
}
}
package com.neotel.smfcore.custom.lizhen.report.bacheng;
import com.google.common.collect.Lists;
import com.neotel.smfcore.common.base.IExcelDownLoad;
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.core.barcode.service.po.Barcode;
import com.neotel.smfcore.core.device.util.DataCache;
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.innerBox.enums.ExtendType;
import com.neotel.smfcore.custom.lizhen.report.bacheng.bean.dto.BCChange;
import com.neotel.smfcore.custom.lizhen.report.bacheng.bean.dto.BCExpire;
import com.neotel.smfcore.custom.lizhen.report.bacheng.bean.dto.BCInventory;
import com.neotel.smfcore.custom.lizhen.report.bacheng.bean.query.BcQuery;
import com.neotel.smfcore.custom.lizhen.setting.util.ExpireDateUtil;
import com.neotel.smfcore.security.annotation.AnonymousAccess;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
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
@RestController
@RequestMapping("/bcReport")
public class BCReportController {
//厂别
@Value("${bc.plant}")
private String BCPlant;
//厂区
@Value("${bc.factory}")
private String BCFactory;
@Autowired
private IStoragePosManager storagePosManager;
@Autowired
private IDataLogManager dataLogManager;
@Autowired
private DataCache dataCache;
/**
* 库位报表
*
* @param query
* @param pageable
* @return
*/
@RequestMapping("/getInventory")
@AnonymousAccess
public PageData getInventory(BcQuery query, Pageable pageable) {
Query q = QueryHelp.getQuery(query);
q.addCriteria(Criteria.where("barcode").exists(true));
PageData<StoragePos> pageData = storagePosManager.findByPage(q, pageable);
List<BCInventory> inventoryList = getBCInventory(pageData.getContent());
return new PageData(inventoryList, pageData.getTotalElements());
}
/**
* 库存导出
* @param query
*/
@RequestMapping("/getInventory/download")
@AnonymousAccess
public void getInventoryDownload(BcQuery query, Pageable pageable, HttpServletResponse response) {
Query q = QueryHelp.getQuery(query);
q.addCriteria(Criteria.where("barcode").exists(true));
try {
FileUtil.downloadExcel(q, pageable, response, new IExcelDownLoad() {
@Override
public List<List<String>> getHeader() {
List<List<String>> headerList = new ArrayList<>();
headerList.add(Lists.newArrayList("厂别"));
headerList.add(Lists.newArrayList("厂区"));
headerList.add(Lists.newArrayList("库别"));
headerList.add(Lists.newArrayList("料号"));
headerList.add(Lists.newArrayList("物料描述"));
headerList.add(Lists.newArrayList("ID NO"));
headerList.add(Lists.newArrayList("储位"));
headerList.add(Lists.newArrayList("数量"));
headerList.add(Lists.newArrayList("卷数"));
headerList.add(Lists.newArrayList("厂商"));
headerList.add(Lists.newArrayList("LOT"));
headerList.add(Lists.newArrayList("D/C"));
headerList.add(Lists.newArrayList("keeper"));
headerList.add(Lists.newArrayList("禁用信息"));
headerList.add(Lists.newArrayList("入库时间"));
headerList.add(Lists.newArrayList("工号"));
return headerList;
}
@Override
public List<List<Object>> getPageData(Query query, Pageable pageable) {
List<List<Object>> dataList = new ArrayList<>();
List<StoragePos> storagePosList = storagePosManager.findByQuery(query, pageable);
List<BCInventory> inventoryList = getBCInventory(storagePosList);
for (BCInventory bcInventory : inventoryList) {
List<Object> result = new ArrayList<>();
result.add(bcInventory.getPlant());
result.add(bcInventory.getFactory());
result.add(bcInventory.getWarehouseCode());
result.add(bcInventory.getPartNumber());
result.add(bcInventory.getDescribe());
result.add(bcInventory.getBarcode());
result.add(bcInventory.getPosName());
result.add(bcInventory.getAmount());
result.add(bcInventory.getReelAmount());
result.add(bcInventory.getProvider());
result.add(bcInventory.getBatch());
result.add(bcInventory.getDateCode());
result.add(bcInventory.getKeeperCode());
result.add(bcInventory.getDisableMsg());
result.add(bcInventory.getPutInDate());
result.add(bcInventory.getCreator());
dataList.add(result);
}
return dataList;
}
});
} catch (IOException e) {
e.printStackTrace();
log.error("库存导出失败", e);
}
}
/**
* 过期报表
*
* @param query
* @param pageable
* @return
*/
@RequestMapping("/getExpire")
@AnonymousAccess
public PageData getExpire(BcQuery query, Pageable pageable) {
Query q = QueryHelp.getQuery(query);
q.addCriteria(Criteria.where("barcode").exists(true)/*.and("barcode.expireDate").lt(new Date())*/);
PageData<StoragePos> pageData = storagePosManager.findByPage(q, pageable);
List<BCExpire> expireList = getBCExpire(pageData.getContent());
return new PageData(expireList, pageData.getTotalElements());
}
/**
* 过期报表导出
* @param query
* @param pageable
* @param response
*/
@RequestMapping("/getExpire/download")
@AnonymousAccess
public void expireDownload(BcQuery query, Pageable pageable, HttpServletResponse response){
Query q = QueryHelp.getQuery(query);
q.addCriteria(Criteria.where("barcode").exists(true)/*.and("barcode.expireDate").lt(new Date())*/);
try {
FileUtil.downloadExcel(q, pageable, response, new IExcelDownLoad() {
@Override
public List<List<String>> getHeader() {
List<List<String>> headerList = new ArrayList<>();
headerList.add(Lists.newArrayList("厂别"));
headerList.add(Lists.newArrayList("厂区"));
headerList.add(Lists.newArrayList("库别"));
headerList.add(Lists.newArrayList("料号"));
headerList.add(Lists.newArrayList("物料描述"));
headerList.add(Lists.newArrayList("数量"));
headerList.add(Lists.newArrayList("储位"));
headerList.add(Lists.newArrayList("keeper"));
headerList.add(Lists.newArrayList("ID NO"));
headerList.add(Lists.newArrayList("LOT"));
headerList.add(Lists.newArrayList("D/C"));
headerList.add(Lists.newArrayList("增加物料保质期"));
headerList.add(Lists.newArrayList("过期天数"));
headerList.add(Lists.newArrayList("过期日期"));
headerList.add(Lists.newArrayList("备注"));
return headerList;
}
@Override
public List<List<Object>> getPageData(Query query, Pageable pageable) {
List<List<Object>> dataList = new ArrayList<>();
List<StoragePos> storagePosList = storagePosManager.findByQuery(query, pageable);
List<BCExpire> bcExpireList = getBCExpire(storagePosList);
for (BCExpire expire : bcExpireList) {
List<Object> result = new ArrayList<>();
result.add(expire.getPlant());
result.add(expire.getFactory());
result.add(expire.getWarehouseCode());
result.add(expire.getPartNumber());
result.add(expire.getDescribe());
result.add(expire.getAmount());
result.add(expire.getPosName());
result.add(expire.getKeeperCode());
result.add(expire.getBarcode());
result.add(expire.getBatch());
result.add(expire.getDateCode());
result.add(expire.getExpireYear());
result.add(expire.getExpireDays());
result.add(expire.getExpireDate());
result.add(expire.getRemark());
dataList.add(result);
}
return dataList;
}
});
} catch (IOException e) {
e.printStackTrace();
log.error("过期报表导出失败",e);
}
}
/**
* 事务报表
*
* @param query
* @param pageable
* @return
*/
@RequestMapping("/change")
@AnonymousAccess
public PageData change(BcQuery query, Pageable pageable) {
Query q = QueryHelp.getQuery(query);
PageData<DataLog> pageData = dataLogManager.findByPage(q, pageable);
return new PageData(getChange(pageData.getContent()), pageData.getTotalElements());
}
/**
* 异动导出
*
* @param
* @return
*/
@RequestMapping("/change/download")
@AnonymousAccess
public void changeDownload(BcQuery query, Pageable pageable, HttpServletResponse response) {
Query q = QueryHelp.getQuery(query);
try {
FileUtil.downloadExcel(q, pageable, response, new IExcelDownLoad() {
@Override
public List<List<String>> getHeader() {
List<List<String>> headerList = new ArrayList<>();
headerList.add(Lists.newArrayList("厂别"));
headerList.add(Lists.newArrayList("厂区"));
headerList.add(Lists.newArrayList("库别"));
headerList.add(Lists.newArrayList("料号"));
headerList.add(Lists.newArrayList("物料描述"));
headerList.add(Lists.newArrayList("异动数量"));
headerList.add(Lists.newArrayList("卷数"));
headerList.add(Lists.newArrayList("储位"));
headerList.add(Lists.newArrayList("异动类型"));
headerList.add(Lists.newArrayList("ID NO"));
headerList.add(Lists.newArrayList("LOT"));
headerList.add(Lists.newArrayList("D/C"));
headerList.add(Lists.newArrayList("厂商"));
headerList.add(Lists.newArrayList("厂商代码"));
headerList.add(Lists.newArrayList("keeper"));
headerList.add(Lists.newArrayList("事务日期"));
headerList.add(Lists.newArrayList("工号"));
return headerList;
}
@Override
public List<List<Object>> getPageData(Query query, Pageable pageable) {
List<List<Object>> resultList = new ArrayList<>();
PageData<DataLog> pageData = dataLogManager.findByPage(query, pageable);
List<DataLog> dataLogList = pageData.getContent();
List<BCChange> changeList = getChange(dataLogList);
for (BCChange bcChange : changeList) {
List<Object> dataList = new ArrayList<>();
dataList.add(bcChange.getPlant());
dataList.add(bcChange.getFactory());
dataList.add(bcChange.getWarehouseCode());
dataList.add(bcChange.getPartNumber());
dataList.add(bcChange.getDescribe());
dataList.add(bcChange.getNum());
dataList.add(bcChange.getReelAmount());
dataList.add(bcChange.getPosName());
dataList.add(bcChange.getType());
dataList.add(bcChange.getBarcode());
dataList.add(bcChange.getBatch());
dataList.add(bcChange.getDateCode());
dataList.add(bcChange.getProvider());
dataList.add(bcChange.getProviderNumber());
dataList.add(bcChange.getKeeperCode());
dataList.add(bcChange.getCreateDate());
dataList.add(bcChange.getCreator());
resultList.add(dataList);
}
return resultList;
}
});
} catch (IOException e) {
e.printStackTrace();
log.error("异动导出失败");
}
}
/**
* 分组
*
* @param type 0是按厂商 其他按料号
* @return
*/
@RequestMapping("/group")
@AnonymousAccess
public PageData group(String type) {
Map<String, Long> resultMap = new HashMap<>();
List<StoragePos> storagePosList = storagePosManager.findNotEmpty();
List<Barcode> barcodeList = storagePosList.stream().map(item -> item.getBarcode()).collect(Collectors.toList());
if ("1".equals(type)) {
resultMap = barcodeList.stream().collect(Collectors.groupingBy(Barcode::getProvider, Collectors.counting()));
} else if ("2".equals(type)) {
resultMap = barcodeList.stream().collect(Collectors.groupingBy(Barcode::getPartNumber, Collectors.counting()));
}
List<Map<String, Object>> resultList = new ArrayList<>();
for (Map.Entry<String, Long> entry : resultMap.entrySet()) {
Map<String, Object> paramMap = new HashMap<>();
paramMap.put("pn", entry.getKey());
paramMap.put("amount", entry.getValue());
resultList.add(paramMap);
}
return new PageData(resultList, resultList.size());
}
private List<BCChange> getChange(List<DataLog> dataLogList) {
List<BCChange> changeList = new ArrayList<>();
for (DataLog dataLog : dataLogList) {
BCChange bcChange = new BCChange();
BeanUtils.copyProperties(dataLog,bcChange);
bcChange.setPlant(BCPlant);
bcChange.setFactory(BCFactory);
bcChange.setReelAmount(1);
bcChange.setPosName(dataLog.getPosStr());
//TODO 要修改
bcChange.setType(ExtendType.getName(dataLog.getExtendType()));
bcChange.setBatch(dataLog.getBatchInfo());
bcChange.setProviderNumber(dataLog.getProviderNumber());
bcChange.setNum(dataLog.getNum());
changeList.add(bcChange);
}
return changeList;
}
private List<BCExpire> getBCExpire(List<StoragePos> storagePosList) {
List<BCExpire> expireList = new ArrayList<>();
for (StoragePos storagePos : storagePosList) {
BCExpire expire = new BCExpire();
BeanUtils.copyProperties(storagePos, expire);
Barcode barcode = storagePos.getBarcode();
BeanUtils.copyProperties(barcode, expire);
expire.setPlant(BCPlant);
expire.setFactory(BCFactory);
if (expire.getExpireDate() != null) {
expire.setExpireDays(ExpireDateUtil.getExpireDays(expire.getExpireDate()));
}
expire.setReelAmount(1);
expire.setPosName(dataCache.getStorageById(storagePos.getStorageId()).getName() + "[" + storagePos.getPosName() + "]");
expireList.add(expire);
}
return expireList;
}
private List<BCInventory> getBCInventory(List<StoragePos> storagePosList) {
List<BCInventory> inventoryList = new ArrayList<>();
for (StoragePos storagePos : storagePosList) {
BCInventory bcInventory = new BCInventory();
BeanUtils.copyProperties(storagePos, bcInventory);
Barcode barcode = storagePos.getBarcode();
BeanUtils.copyProperties(barcode, bcInventory);
bcInventory.setPlant(BCPlant);
bcInventory.setFactory(BCFactory);
bcInventory.setReelAmount(1);
bcInventory.setPosName(dataCache.getStorageById(storagePos.getStorageId()).getName() + "[" + storagePos.getPosName() + "]");
inventoryList.add(bcInventory);
}
return inventoryList;
}
}
package com.neotel.smfcore.custom.lizhen.report.bacheng.bean.dto;
import lombok.Data;
import java.util.Date;
/**
* 异动报表
*/
@Data
public class BCChange {
//厂别
private String plant;
//厂区
private String factory;
//库别
private String warehouseCode;
//料号
private String partNumber;
//物料描述
private String describe;
//异动数量
private int num;
//卷数
private int reelAmount;
//储位
private String posName;
//异动类型
private String type;
//ID NO
private String barcode;
//LOT
private String batch;
//D/C
private String dateCode;
//厂商
private String provider;
//厂商代码
private String providerNumber;
//Keeper
private String keeperCode;
//事务日期
private Date createDate;
//工号
private String creator;
}
package com.neotel.smfcore.custom.lizhen.report.bacheng.bean.dto;
import lombok.Data;
import java.util.Date;
@Data
public class BCExpire {
/**
* 厂别
*/
private String plant;
/**
* 厂区
*/
private String factory;
/**
* 料号
*/
private String partNumber;
/**
* 描述
*/
private String describe;
/**
* ID NO
*/
private String barcode;
/**
* 储位
*/
private String posName;
/**
* 数量
*/
private int amount;
/**
* 卷数
*/
private int reelAmount = 1;
/**
* 厂商
*/
private String provider;
/**
* lot
*/
private String batch = "";
/**
* d/c
*/
private String dateCode;
/**
* keeper
*/
private String keeperCode;
/**
* 物料保质期(年)
*/
private int expireYear = 1;
/**
* 过期天数
*/
private long expireDays;
/**
* 过期时间
*/
private Date expireDate;
/**
* 备注
*/
private String remark;
/**
* 库别
*/
private String warehouseCode;
}
package com.neotel.smfcore.custom.lizhen.report.bacheng.bean.dto;
import lombok.Data;
import java.util.Date;
@Data
public class BCInventory {
/**
* 厂别
*/
private String plant;
/**
* 厂区
*/
private String factory;
/**
* 库别
*/
private String warehouseCode;
/**
* 料号
*/
private String partNumber;
/**
* 描述
*/
private String describe;
/**
* ID NO
*/
private String barcode;
/**
* 储位
*/
private String posName;
/**
* 数量
*/
private int amount;
/**
* 卷数
*/
private int reelAmount = 1;
/**
* 厂商
*/
private String provider;
/**
* lot
*/
private String batch="";
/**
* d/c
*/
private String dateCode;
/**
* keeper
*/
private String keeperCode;
/**
* 禁用信息
*/
private String disableMsg;
/**
* 入库时间
*/
private Date putInDate;
/**
* 工号
*/
private String creator;
}
package com.neotel.smfcore.custom.lizhen.report.bacheng.bean.query;
import com.neotel.smfcore.common.annotation.QueryCondition;
import com.neotel.smfcore.common.bean.BetweenData;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
@Data
public class BcQuery {
@QueryCondition(blurry = "barcode.partNumber,partNumber")
private String pn;
@QueryCondition(blurry = "barcode.partNumber")
private String partNumber;
@QueryCondition(blurry = "barcode.provider")
private String provider;
@QueryCondition(blurry = "barcode.warehouseCode,warehouseCode")
private String warehouseCode;
@QueryCondition(blurry = "posName")
private String posName;
@QueryCondition(blurry = "barcode.barcode,barcode")
private String barcode;
@QueryCondition(blurry = "barcode.dateCode")
private String dateCode;
@QueryCondition(blurry = "barcode.batch")
private String batch;
@QueryCondition(blurry = "barcode.keeperCode")
private String keeperCode;
@QueryCondition(propName = "extendType",type = QueryCondition.Type.EQ)
private Integer extendType;
@QueryCondition(type = QueryCondition.Type.BETWEEN, propName = "updateDate")
@DateTimeFormat(pattern = "yyyy-MM-dd")
private BetweenData<Date> updateDate;
}
package com.neotel.smfcore.custom.lizhen.report.bean.dto;
import com.neotel.smfcore.core.barcode.service.po.Barcode;
import lombok.Data;
import java.util.Date;
@Data
public class ExpireDto extends Barcode {
/**
* 过期天数
*/
private long expireDays;
/**
* 厂别
*/
private String plant;
/**
* 厂区
*/
private String factory;
/**
* 楼层
*/
private String floor;
/**
* 首次入库时间
*/
private Date firstPutInDate;
/**
* 来源
*/
private String source;
/**
* 隔口数量
*/
private Integer partitionCount;
/**
* 备注
*/
private String remark;
}
package com.neotel.smfcore.custom.lizhen.report.bean.dto;
import lombok.Getter;
import lombok.Setter;
import java.util.Date;
/**
* 外仓库存报表展示
*/
@Getter
@Setter
public class InventoryDto {
/**
* 厂别
*/
private String plant;
/**
* 厂区
*/
private String factory;
/**
* 库别
*/
private String warehouseCode;
/**
* 楼层
*/
private String floor = "1F";
/**
* 料号
*/
private String partNumber;
/**
* 物料隔扣码
*/
private String posName;
/**
* 隔口数量
*/
private long posNameCount;
/**
* 卷数
*/
private int reelCount = 1;
/**
* 厂商
*/
private String provider;
/**
* 厂商代码
*/
private String providerNumber;
/**
* lot
*/
private String batch;
/**
* D/C
*/
private String dateCode;
/**
* keeper
*/
private String keeperCode;
/**
* 储位
*/
private String storagePosName;
/**
* 禁用信息
*/
private String disableMsg;
/**
* 首次入库时间
*/
private Date firstPutInDate;
/**
* 当前入库时间
*/
private Date putInDate;
/**
* 姓名
*/
private String creator;
/**
* 唯一码
*/
private String barcode;
/**
* 每卷数量
*/
private int amount;
/**
* 来源
*/
private String source;
}
package com.neotel.smfcore.custom.lizhen.report.bean.dto;
import lombok.Data;
@Data
public class MergeInventoryDto extends InventoryDto{
}
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,barcode.partNumber")
@ApiModelProperty("料号")
private String pn;
@QueryCondition(blurry = "pn,partNumber,barcode.partNumber")
@ApiModelProperty("料号")
private String partNumber;
@QueryCondition(blurry = "orderNo,sourceName")
@ApiModelProperty("挑料单号")
private String orderNo;
@QueryCondition(type = QueryCondition.Type.IN, propName = "orderNo")
@ApiModelProperty("挑料单号集合")
private List<String> orderNoList;
@QueryCondition(propName = "mo")
@ApiModelProperty("工单号")
private String mo;
@QueryCondition(type = QueryCondition.Type.BETWEEN, propName = "updateDate")
@DateTimeFormat(pattern = "yyyy-MM-dd")
private BetweenData<Date> updateDate;
@QueryCondition(type = QueryCondition.Type.BETWEEN, propName = "updateDate")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm")
private BetweenData<Date> updateDateHHmm;
@QueryCondition
@ApiModelProperty("厂别")
private String plantCode;
@QueryCondition
@ApiModelProperty("库别")
private String warehouse;
@ApiModelProperty("唯一码")
@QueryCondition(blurry = "barcode.barcode,barcode")
private String barcode;
@QueryCondition(blurry = "posName")
@ApiModelProperty("库位")
private String posName;
@QueryCondition(blurry = "batch")
@ApiModelProperty("批次")
private String batch;
@ApiModelProperty("线别")
@QueryCondition(propName = "line")
private String line;
@ApiModelProperty("厂商")
@QueryCondition(blurry = "barcode.provider,provider")
private String provider;
@ApiModelProperty("日期代码")
@QueryCondition(blurry = "dateCode")
private String dateCode;
@ApiModelProperty("料仓id")
@QueryCondition(type = QueryCondition.Type.IN, propName = "storageId")
private List<String> storageIdList;
@ApiModelProperty("库别")
@QueryCondition(blurry = "warehouseCode")
private String warehouseCode;
@ApiModelProperty("储位")
@QueryCondition(blurry = "posName")
private String storagePosName;
@ApiModelProperty("隔口")
@QueryCondition(blurry = "boxPartition")
private String boxPartition;
@ApiModelProperty("是否匹配")
@QueryCondition(type = QueryCondition.Type.EQ, propName = "isMatch")
private Boolean match;
@ApiModelProperty("状态")
@QueryCondition(blurry = "status")
private String status;
@ApiModelProperty("盘点批次")
@QueryCondition(blurry = "inventoryBatch")
private String inventoryBatch;
//楼层
private String floor;
//过期状态
private String expireStatus;
private int page;
private int size;
private String sort;
}
package com.neotel.smfcore.custom.lizhen.report.inner;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import com.google.common.collect.Lists;
import com.neotel.smfcore.common.base.IExcelDownLoad;
import com.neotel.smfcore.common.bean.PageData;
import com.neotel.smfcore.common.bean.ResultBean;
import com.neotel.smfcore.common.utils.*;
import com.neotel.smfcore.core.barcode.bean.CodeBean;
import com.neotel.smfcore.core.barcode.rest.bean.dto.BarcodeDto;
import com.neotel.smfcore.core.barcode.rest.bean.mapstruct.BarcodeMapper;
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.util.DataCache;
import com.neotel.smfcore.core.order.LiteOrderCache;
import com.neotel.smfcore.core.order.enums.LITEORDER_STATUS;
import com.neotel.smfcore.core.order.rest.bean.dto.OrderItemDto;
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.storage.bean.InventoryItem;
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.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.custom.lizhen.innerBox.bean.VirImportLog;
import com.neotel.smfcore.custom.lizhen.innerBox.enums.ExtendType;
import com.neotel.smfcore.custom.lizhen.innerBox.service.manager.IVirImportLogManager;
import com.neotel.smfcore.custom.lizhen.report.bean.dto.ExpireDto;
import com.neotel.smfcore.custom.lizhen.report.bean.query.ReportQueryCondition;
import com.neotel.smfcore.custom.lizhen.setting.util.ExpireDateUtil;
import com.neotel.smfcore.security.annotation.AnonymousAccess;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
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("内仓报表")
@RequestMapping("/inner/report")
@RestController
public class InnerReportController {
@Value("${lizhen.F2.name}")
private String F2;
@Value("${lizhen.F3.name}")
private String F3;
@Value("${lizhen.F5.name}")
private String F5;
@Autowired
private ILiteOrderManager liteOrderManager;
@Autowired
private ILiteOrderItemManager liteOrderItemManager;
@Autowired
private OrderItemMapper orderItemMapper;
@Autowired
private OrderMapper orderMapper;
@Autowired
private DataCache dataCache;
@Autowired
private IStoragePosManager storagePosManager;
@Autowired
private StoragePosMapper storagePosMapper;
@Autowired
private IDataLogManager dataLogManager;
@Autowired
private LiteOrderCache liteOrderCache;
@Autowired
private IBarcodeManager barcodeManager;
@Autowired
private BarcodeMapper barcodeMapper;
@Autowired
private CodeResolve codeResolve;
@Autowired
private IVirImportLogManager virImportLogManager;
@ApiOperation("喂料")
@RequestMapping("/feeding")
@AnonymousAccess
public PageData feeding(ReportQueryCondition queryCondition, Pageable pageable) {
//增加料号解析(这里传入的料号数据,就是物料条码)
String partNumber = queryCondition.getPartNumber();
if (StringUtils.isNotBlank(partNumber)) {
CodeBean codeBean = codeResolve.resolveSingleCode(partNumber);
Barcode barcode = codeBean.getBarcode();
if (barcode != null) {
partNumber = barcode.getPartNumber();
}
}
queryCondition.setPartNumber(null);
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);
List<LiteOrder> liteOrders = liteOrderManager.findByQueryAndPartNumber(q.addCriteria(c), partNumber);
liteOrders = liteOrders.stream().sorted(Comparator.comparing(LiteOrder::getPriority).reversed()).collect(Collectors.toList());
List<LiteOrder> resultLiteOrders = new ArrayList<>();
for (LiteOrder liteOrder : liteOrders) {
List<LiteOrderItem> newOrderItems = new ArrayList<>();
for (LiteOrderItem orderItem : liteOrder.getOrderItems()) {
if (orderItem.getOutNum() == 0) {
newOrderItems.add(orderItem);
}
}
if (newOrderItems != null && !newOrderItems.isEmpty()) {
liteOrder.setOrderItems(newOrderItems);
resultLiteOrders.add(liteOrder);
}
}
PageData resultPageData = new PageData();
resultPageData.setTotalElements(resultLiteOrders.size());
resultPageData.setContent(orderMapper.toDto(resultLiteOrders));
return resultPageData;
}
@ApiOperation("根据工单id获取工单详情")
@RequestMapping("/getItemsByOrderId")
//@AnonymousAccess
public ResultBean getItemsByOrderId(String orderId, String partNumber) {
LiteOrder liteOrder = liteOrderManager.get(orderId);
List<LiteOrderItem> orderItems = liteOrderItemManager.findOrderItems(orderId);
List<LiteOrderItem> newOrderItems = new ArrayList<>();
for (LiteOrderItem orderItem : orderItems) {
if (orderItem.getOutNum() == 0) {
if (LITEORDER_STATUS.TAILS_FINISHED == liteOrder.getStatus()) {
orderItem.setLack(true);
}
if (StringUtils.isNotBlank(partNumber)) {
if (partNumber.equals(orderItem.getPn())) {
newOrderItems.add(orderItem);
}
} else {
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("floorPullDown")
@AnonymousAccess
public ResultBean floorPullDown() {
String floor = dataCache.getCache(Constants.CACHE_floor);
Map<String, String> resultMap = new LinkedHashMap<>();
if (StringUtils.isNotBlank(floor)) {
if (F2.equals(floor)) {
resultMap.put(F2, F2);
} else if (F3.equals(floor)) {
resultMap.put(F3, F3);
} else if (F5.equals(floor)) {
resultMap.put(F5, F5);
}
} else {
resultMap.put(F2, F2);
resultMap.put(F3, F3);
resultMap.put(F5, F5);
}
return ResultBean.newOkResult(resultMap);
}
@ApiOperation("线别下拉")
@RequestMapping("linePullDown")
@AnonymousAccess
public ResultBean linePullDown(String floor) {
//得到每一个楼层的线体
String f2Line = dataCache.getCache("F2Line").toString();
String f3Line = dataCache.getCache("F3Line").toString();
String f5Line = dataCache.getCache("F5Line").toString();
String resultLine = "";
if (F2.equals(floor)) {
resultLine = f2Line;
} else if (F3.equals(floor)) {
resultLine = f3Line;
} else if (F5.equals(floor)) {
resultLine = f5Line;
} else {
resultLine = f2Line + "," + f3Line + "," + f5Line;
}
Map<String, String> resultMap = new LinkedHashMap<>();
for (String line : resultLine.split(",")) {
resultMap.put(line, line);
}
return ResultBean.newOkResult(resultMap);
}
@ApiOperation("内仓库存")
@RequestMapping("/inventory")
@AnonymousAccess
public PageData inventory(ReportQueryCondition queryCondition, Pageable pageable) {
Query query = QueryHelp.getQuery(queryCondition);
query.addCriteria(Criteria.where("barcode").exists(true));
PageData resultData = new PageData();
if (pageable != null) {
PageData<StoragePos> page = storagePosManager.findByPage(query, pageable);
resultData.setTotalElements(page.getTotalElements());
List<StoragePos> storagePosList = page.getContent();
storagePosList.stream().forEach(item -> {
String storageId = item.getStorageId();
Storage storage = dataCache.getStorageById(storageId);
item.setSource(storage.getName());
});
resultData.setContent(storagePosMapper.toDto(storagePosList));
} else {
List<StoragePos> storagePosList = storagePosManager.findByQuery(query);
if (storagePosList != null && !storagePosList.isEmpty()) {
storagePosList.stream().forEach(item -> {
String storageId = item.getStorageId();
Storage storage = dataCache.getStorageById(storageId);
item.setSource(storage.getName());
});
resultData.setContent(storagePosMapper.toDto(storagePosList));
resultData.setTotalElements(storagePosList.size());
}
}
return resultData;
}
@ApiOperation("内仓库存")
@RequestMapping("/inventory/download")
@AnonymousAccess
public void inventoryDownload(ReportQueryCondition queryCondition, Pageable pageable, HttpServletResponse response) {
List<Map<String, Object>> results = new ArrayList<>();
PageData data = inventory(queryCondition, null);
List<StoragePosDto> storagePosList = data.getContent();
if (storagePosList != null && !storagePosList.isEmpty()) {
for (StoragePosDto dto : storagePosList) {
Map<String, Object> resultMap = new LinkedHashMap<>();
BarcodeDto barcode = dto.getBarcode();
resultMap.put("储位", barcode.getPosName());
resultMap.put("料号", barcode.getPartNumber());
resultMap.put("卷数", 1);
resultMap.put("数量", barcode.getAmount());
resultMap.put("厂商", barcode.getProvider());
resultMap.put("厂商代码", barcode.getProviderNumber());
resultMap.put("IDNO", barcode.getBarcode());
resultMap.put("LOT", barcode.getBatch());
resultMap.put("D/C", barcode.getDateCode());
resultMap.put("入库日期", barcode.getPutInDate());
results.add(resultMap);
}
try {
FileUtil.downloadExcel(results, response);
} catch (IOException e) {
e.printStackTrace();
log.info("内仓库存导出失败--" + e.getMessage());
}
}
}
@ApiOperation("内仓备料清单")
@RequestMapping("/materialPreList")
@AnonymousAccess
public PageData materialPreList(ReportQueryCondition queryCondition, Pageable pageable) {
Query query = QueryHelp.getQuery(queryCondition);
PageData resultData = new PageData();
if (pageable != null) {
PageData<LiteOrderItem> data = liteOrderItemManager.findByPage(query, pageable);
resultData.setTotalElements(data.getTotalElements());
resultData.setContent(orderItemMapper.toDto(data.getContent()));
} else {
List<LiteOrderItem> orderItemList = liteOrderItemManager.findByQuery(query);
if (orderItemList != null && !orderItemList.isEmpty()) {
resultData.setTotalElements(orderItemList.size());
resultData.setContent(orderItemMapper.toDto(orderItemList));
}
}
return resultData;
}
@ApiOperation("内仓备料清单")
@RequestMapping("/materialPreList/download")
@AnonymousAccess
public void materialPreListDownload(ReportQueryCondition queryCondition, Pageable pageable, HttpServletResponse response) {
List<Map<String, Object>> results = new ArrayList<>();
PageData data = materialPreList(queryCondition, null);
List<OrderItemDto> orderItemDtoList = data.getContent();
if (orderItemDtoList != null && !orderItemDtoList.isEmpty()) {
for (OrderItemDto dto : orderItemDtoList) {
Map<String, Object> resultMap = new LinkedHashMap<>();
resultMap.put("线别", dto.getLine() == null ? "" : dto.getLine());
resultMap.put("机器", dto.getTableNo() == null ? "" : dto.getTableNo());
resultMap.put("段别", dto.getSlot() == null ? "" : dto.getSlot());
resultMap.put("站别", dto.getSubSlot() == null ? "" : dto.getSubSlot());
resultMap.put("面别", dto.getSide() == null ? "" : dto.getSide());
resultMap.put("工单号", dto.getOrderNo() == null ? "" : dto.getOrderNo());
resultMap.put("料号", dto.getPn() == null ? "" : dto.getPn());
resultMap.put("需求卷", dto.getNeedReelCount());
resultMap.put("实发卷", dto.getOutReelCount());
resultMap.put("创建时间",dto.getCreateDate());
results.add(resultMap);
}
try {
FileUtil.downloadExcel(results, response);
} catch (IOException e) {
e.printStackTrace();
log.info("内仓备料清单导出失败--" + e.getMessage());
}
}
}
@ApiOperation("内仓异动")
@RequestMapping("/change")
@AnonymousAccess
public PageData change(ReportQueryCondition queryCondition, Pageable pageable) {
Query query = QueryHelp.getQuery(queryCondition);
PageData<DataLog> resultData = new PageData<>();
if (pageable != null) {
PageData<DataLog> pageData = dataLogManager.findByPage(query, pageable);
resultData.setTotalElements(pageData.getTotalElements());
resultData.setContent(pageData.getContent());
} else {
List<DataLog> dataLogs = dataLogManager.findByQuery(query);
if (dataLogs != null && !dataLogs.isEmpty()) {
resultData.setContent(dataLogs);
resultData.setTotalElements(dataLogs.size());
}
}
return resultData;
}
@ApiOperation("内仓异动导出")
@RequestMapping("/change/download")
@AnonymousAccess
public void changeDownload(ReportQueryCondition queryCondition, Pageable pageable, HttpServletResponse response) {
List<Map<String, Object>> results = new ArrayList<>();
PageData data = change(queryCondition, null);
List<DataLog> dataLogs = data.getContent();
if (dataLogs != null && !dataLogs.isEmpty()) {
for (DataLog dataLog : dataLogs) {
Map<String, Object> resultMap = new LinkedHashMap<>();
resultMap.put("线别", getData(dataLog.getLine()));
resultMap.put("机器", getData(dataLog.getMachineName()));
resultMap.put("站点", getData(dataLog.getTableNo()));
resultMap.put("站位", getData(dataLog.getSlot()));
resultMap.put("点位", getData(dataLog.getSubSlot()));
resultMap.put("面别", getData(dataLog.getSide()));
resultMap.put("工单号", getData(dataLog.getSourceName()));
resultMap.put("类型", getData(dataLog.getType()));
resultMap.put("料号", getData(dataLog.getPartNumber()));
resultMap.put("储位", getData(dataLog.getPosName()));
resultMap.put("数量", getData(dataLog.getNum()));
resultMap.put("时间", getData(dataLog.getCreateDate()));
resultMap.put("ID NO", getData(dataLog.getBarcode()));
resultMap.put("D/C", getData(dataLog.getDateCode()));
resultMap.put("L/C", getData(dataLog.getBatchInfo()));
resultMap.put("厂商代码", getData(dataLog.getProviderNumber()));
resultMap.put("厂商", getData(dataLog.getProvider()));
resultMap.put("状态", getData(dataLog.getStatus()));
results.add(resultMap);
}
try {
FileUtil.downloadExcel(results, response);
} catch (IOException e) {
e.printStackTrace();
log.info("内仓异动导出导出失败--" + e.getMessage());
}
}
}
@ApiOperation("发料明细")
@RequestMapping("/pickingDetail")
@AnonymousAccess
public PageData pickingDetail(ReportQueryCondition queryCondition, Pageable pageable) {
Query query = QueryHelp.getQuery(queryCondition);
query.addCriteria(Criteria.where("type").is(OP.CHECKOUT));
PageData<DataLog> resultData = new PageData<>();
if (pageable != null) {
PageData<DataLog> data = dataLogManager.findByPage(query, pageable);
resultData.setTotalElements(data.getTotalElements());
resultData.setContent(data.getContent());
} else {
List<DataLog> dataLogs = dataLogManager.findByQuery(query);
if (dataLogs != null && !dataLogs.isEmpty()) {
resultData.setTotalElements(dataLogs.size());
resultData.setContent(dataLogs);
}
}
return resultData;
}
@ApiOperation("发料明细导出")
@RequestMapping("/pickingDetail/download")
@AnonymousAccess
public void pickingDetailDownload(ReportQueryCondition queryCondition, Pageable pageable, HttpServletResponse response) {
PageData<DataLog> data = pickingDetail(queryCondition, null);
List<DataLog> dataLogs = data.getContent();
List<Map<String, Object>> results = new ArrayList<>();
if (dataLogs != null && !dataLogs.isEmpty()) {
for (DataLog dataLog : dataLogs) {
Map<String, Object> resultMap = new LinkedHashMap<>();
resultMap.put("线别", getData(dataLog.getLine()));
resultMap.put("机器", getData(dataLog.getMachineName()));
resultMap.put("站点", getData(dataLog.getTableNo()));
resultMap.put("站位", getData(dataLog.getSlot()));
resultMap.put("点位", getData(dataLog.getSubSlot()));
resultMap.put("面别", getData(dataLog.getSide()));
resultMap.put("工单号", getData(dataLog.getSourceName()));
resultMap.put("类型", getData(dataLog.getType()));
resultMap.put("料号", getData(dataLog.getPartNumber()));
resultMap.put("储位", getData(dataLog.getPosName()));
resultMap.put("数量", getData(dataLog.getNum()));
resultMap.put("时间", getData(dataLog.getCreateDate()));
resultMap.put("ID NO", getData(dataLog.getBarcode()));
resultMap.put("D/C", getData(dataLog.getDateCode()));
resultMap.put("L/C", getData(dataLog.getBatchInfo()));
resultMap.put("厂商代码", getData(dataLog.getProviderNumber()));
resultMap.put("厂商", getData(dataLog.getProvider()));
resultMap.put("状态", getData(dataLog.getStatus()));
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) {
List<OrderItemDto> dtoList = new ArrayList<>();
String floor = dataCache.getCache(Constants.CACHE_floor);
List<LiteOrderItem> lackItems = getLackItems(liteOrderCache.getAllLiteOrder(), queryCondition);
for (LiteOrderItem orderItem : lackItems) {
orderItem.setFloor(floor);
orderItem.setLackReel(1);
orderItem.setLackNum(1);
orderItem.setPreWarningTime(DateUtil.between(orderItem.getCreateDate(), new Date(), DateUnit.MINUTE));
}
dtoList.addAll(orderItemMapper.toDto(lackItems));
return new PageData(dtoList, dtoList.size());
}
@ApiOperation("缺料导出")
@RequestMapping("/lackPicking/download")
@AnonymousAccess
public void lackPickingDownload(ReportQueryCondition queryCondition, Pageable pageable, HttpServletResponse response) throws IOException {
String floor = dataCache.getCache(Constants.CACHE_floor);
List<List<String>> headers = new ArrayList<>();
headers.add(Arrays.asList("楼层"));
headers.add(Arrays.asList("线别"));
headers.add(Arrays.asList("料号"));
headers.add(Arrays.asList("机台"));
headers.add(Arrays.asList("面别"));
headers.add(Arrays.asList("需求站位"));
headers.add(Arrays.asList("需求数量"));
headers.add(Arrays.asList("需求卷数"));
headers.add(Arrays.asList("需求时间"));
headers.add(Arrays.asList("发料数量"));
headers.add(Arrays.asList("发料卷数"));
headers.add(Arrays.asList("发料时间"));
headers.add(Arrays.asList("缺料数量"));
headers.add(Arrays.asList("缺料卷数"));
headers.add(Arrays.asList("累计预警时间(分钟)"));
List<List<Object>> datas = new ArrayList<>();
List<LiteOrderItem> orderItems = getLackItems(liteOrderCache.getAllLiteOrder(), queryCondition);
for (LiteOrderItem orderItem : orderItems) {
List<Object> dataList = new ArrayList<>();
dataList.add(floor);
dataList.add(orderItem.getLine());
dataList.add(orderItem.getPn());
dataList.add(orderItem.getMachineName());
dataList.add(orderItem.getSide());
dataList.add(orderItem.getSlot());
dataList.add(orderItem.getNeedNum());
dataList.add(orderItem.getNeedReelCount());
dataList.add(orderItem.getCreateDate());
dataList.add(0);
dataList.add(0);
dataList.add("");
dataList.add(orderItem.getNeedNum());
dataList.add(orderItem.getNeedReelCount());
dataList.add(DateUtil.between(orderItem.getCreateDate(), new Date(), DateUnit.MINUTE));
datas.add(dataList);
}
FileUtil.downloadExcel(headers, datas, response);
}
@ApiOperation("禁限用")
@RequestMapping("/disable")
@AnonymousAccess
public PageData disable(ReportQueryCondition queryCondition, Pageable pageable) {
Query query = QueryHelp.getQuery(queryCondition);
query.addCriteria(Criteria.where("disableMsg").nin("").exists(true).and("posName").ne("").exists(true));
PageData<BarcodeDto> resultData = new PageData<>();
if (pageable != null) {
PageData<Barcode> data = barcodeManager.findByPage(query, pageable);
resultData.setTotalElements(data.getTotalElements());
resultData.setContent(barcodeMapper.toDto(data.getContent()));
} else {
List<Barcode> barcodes = barcodeManager.findByQuery(query);
if (barcodes != null && !barcodes.isEmpty()) {
resultData.setTotalElements(barcodes.size());
resultData.setContent(barcodeMapper.toDto(barcodes));
}
}
return resultData;
}
@ApiOperation("禁限用导出")
@RequestMapping("/disable/download")
@AnonymousAccess
public void disableDownload(ReportQueryCondition queryCondition, Pageable pageable, HttpServletResponse response) {
PageData data = disable(queryCondition, null);
List<Map<String, Object>> results = new ArrayList<>();
List<BarcodeDto> dtos = data.getContent();
if (dtos != null && !dtos.isEmpty()) {
for (BarcodeDto dto : dtos) {
Map<String, Object> resultMap = new LinkedHashMap<>();
resultMap.put("ID NO", dto.getBarcode());
resultMap.put("料号", dto.getPartNumber());
resultMap.put("D/C", dto.getDateCode());
resultMap.put("L/C", dto.getBatch());
resultMap.put("厂商代码", dto.getProviderNumber());
resultMap.put("厂商", dto.getProvider());
resultMap.put("数量", dto.getAmount());
resultMap.put("禁用信息", dto.getDisableMsg());
results.add(resultMap);
}
}
try {
FileUtil.downloadExcel(results, response);
} catch (IOException e) {
e.printStackTrace();
log.info("内仓禁限用导出导出失败--" + e.getMessage());
}
}
@ApiOperation("获取出入库数据")
@RequestMapping("/getInAndOutCount")
@AnonymousAccess
public ResultBean getInAndOutCount(ReportQueryCondition queryCondition) {
Map<String, Object> resultMap = new HashMap<>();
List<String> titleList = new ArrayList();
String[] title = {"全部入库", "智能仓入库", "虚拟仓入库", "料架入库", "全部出库", "智能仓出库", "虚拟仓出库", "手动清空库位", "手动喂料", "手动出库", "料架出库"};
titleList.addAll(Arrays.asList(title));
List<Integer> countList = new ArrayList();
//开始时间
Date startDate = queryCondition.getUpdateDateHHmm().getFrom();
//结束时间
Date endDate = queryCondition.getUpdateDateHHmm().getTo();
//全部入库
int inCount = dataLogManager.getInOutData(startDate, endDate, OP.PUT_IN, queryCondition.getPartNumber(), -1, "");
countList.add(inCount);
//智能仓入库
int storageInCount = dataLogManager.getInOutData(startDate, endDate, OP.PUT_IN, queryCondition.getPartNumber(), ExtendType.STORAGE_PUTIN, "");
countList.add(storageInCount);
//虚拟仓入库
int virtualInCount = dataLogManager.getInOutData(startDate, endDate, OP.PUT_IN, queryCondition.getPartNumber(), ExtendType.VIRTUAL_PUTIN, "");
countList.add(virtualInCount);
//料架入库
int nlShelfPutInCount = inCount - storageInCount - virtualInCount;
countList.add(nlShelfPutInCount);
//全部出库
int outCount = dataLogManager.getInOutData(startDate, endDate, OP.CHECKOUT, queryCondition.getPartNumber(), -1, "");
countList.add(outCount);
//智能仓出库
int storageOutCount = dataLogManager.getInOutData(startDate, endDate, OP.CHECKOUT, queryCondition.getPartNumber(), ExtendType.STORAGE_CHECKOUT, "");
countList.add(storageOutCount);
//虚拟仓出库
int virtualOutCount = dataLogManager.getInOutData(startDate, endDate, OP.CHECKOUT, queryCondition.getPartNumber(), ExtendType.VIRTUAL_CHECKOUT, "");
countList.add(virtualOutCount);
//手动清空库位
int clearCount = dataLogManager.getInOutData(startDate, endDate, OP.CHECKOUT, queryCondition.getPartNumber(), ExtendType.CLEAR_POS, "");
countList.add(clearCount);
//手动喂料
int feedingCount = dataLogManager.getInOutData(startDate, endDate, OP.CHECKOUT, queryCondition.getPartNumber(), ExtendType.MANUAL_FEEDING, "");
countList.add(feedingCount);
//手动出库
int manualCheckOutCount = dataLogManager.getInOutData(startDate, endDate, OP.CHECKOUT, queryCondition.getPartNumber(), ExtendType.MANUAL_CHECKOUT, "");
countList.add(manualCheckOutCount);
//料架出库
int nlShelfCheckOutCount = outCount - storageOutCount - virtualOutCount - clearCount - feedingCount - manualCheckOutCount;
countList.add(nlShelfCheckOutCount);
resultMap.put("title", titleList);
resultMap.put("count", countList);
return ResultBean.newOkResult(resultMap);
}
@ApiOperation("出入库数据导出")
@RequestMapping("/getInAndOutCount/download")
@AnonymousAccess
public void getInAndOutCountDownload(ReportQueryCondition queryCondition, HttpServletResponse response) {
ResultBean bean = getInAndOutCount(queryCondition);
Map<String, Object> map = (Map<String, Object>) bean.getData();
List<String> titleList = (List<String>) map.get("title");
List<Integer> countList = (List<Integer>) map.get("count");
List<Map<String, Object>> results = new ArrayList<>();
Map<String, Object> resultMap = new LinkedHashMap<>();
for (int i = 0; i < titleList.size(); i++) {
resultMap.put(titleList.get(i), countList.get(i));
}
results.add(resultMap);
try {
FileUtil.downloadExcel(results, response);
} catch (IOException e) {
e.printStackTrace();
log.info("内仓出入库导出导出失败--" + e.getMessage());
}
}
@ApiOperation("一键导入明细")
@RequestMapping("/virImportLog")
@AnonymousAccess
public PageData<VirImportLog> virImportLog(ReportQueryCondition queryCondition, Pageable pageable) {
Query query = QueryHelp.getQuery(queryCondition);
if (pageable != null) {
return virImportLogManager.findByPage(query, pageable);
} else {
List<VirImportLog> virImportLogList = virImportLogManager.findByQuery(query);
if (virImportLogList == null) {
virImportLogList = new ArrayList<>();
}
return new PageData<VirImportLog>(virImportLogList, virImportLogList.size());
}
}
@ApiOperation("一键导入明细导出")
@RequestMapping("/virImportLog/download")
@AnonymousAccess
public void virImportLogDownload(ReportQueryCondition queryCondition, HttpServletResponse response) {
PageData<VirImportLog> pageData = virImportLog(queryCondition, null);
if (pageData.getTotalElements() != 0) {
List<VirImportLog> importLogList = pageData.getContent();
List<Map<String, Object>> results = new ArrayList<>();
if (importLogList != null && !importLogList.isEmpty()) {
for (VirImportLog log : importLogList) {
Map<String, Object> resultMap = new LinkedHashMap<>();
resultMap.put("唯一码",log.getBarcode());
resultMap.put("提示信息",log.getMsg());
resultMap.put("是否成功",log.isSuccess() ? "是" : "否");
resultMap.put("楼层",log.getFloor());
resultMap.put("pickingId",log.getOrderNo());
resultMap.put("创建人",log.getCreator());
resultMap.put("创建时间",log.getCreateDate());
resultMap.put("修改时间",log.getUpdateDate());
results.add(resultMap);
}
}
try {
FileUtil.downloadExcel(results, response);
} catch (IOException e) {
e.printStackTrace();
log.info("内仓禁限用导出导出失败--" + e.getMessage());
}
}
}
@ApiOperation("过期报表")
@RequestMapping("/expire")
@AnonymousAccess
public PageData<ExpireDto> expireInfo(ReportQueryCondition queryCondition, Pageable pageable) {
Query query = QueryHelp.getQuery(queryCondition);
Criteria c = Criteria.where("barcode").exists(true);
//判断传入的类型
String expireStatus = queryCondition.getExpireStatus();
Date startDate,endDate;
if ("0".equals(expireStatus)) {
startDate = new Date();
endDate = DateUtil.offsetDay(startDate, 7);
c.and("barcode.expireDate").gte(startDate).lt(endDate);
} else if ("1".equals(expireStatus)) {
startDate = DateUtil.offsetDay(new Date(), 7);
endDate = DateUtil.offsetDay(new Date(), 30);
c.and("barcode.expireDate").gte(startDate).lt(endDate);
} else if ("2".equals(expireStatus)) {
List<Criteria> orCriList = new ArrayList<>();
orCriList.add(Criteria.where("barcode").exists(true).and("barcode.expireDate").gt(new Date()));
orCriList.add(Criteria.where("barcode").exists(true).and("barcode.expireDate").exists(false));
c.orOperator(orCriList);
} else if ("3".equals(expireStatus)) {
endDate = new Date();
c.and("barcode.expireDate").lt(endDate);
}
query.addCriteria(c);
int count = storagePosManager.countByQuery(query);
List<StoragePos> storagePosList = storagePosManager.findByQuery(query, pageable);
PageData<ExpireDto> data = new PageData<>();
List<ExpireDto> dtoList = new ArrayList<>();
if (storagePosList != null && !storagePosList.isEmpty()) {
for (StoragePos storagePos : storagePosList) {
Barcode barcode = storagePos.getBarcode();
ExpireDto dto = new ExpireDto();
BeanUtils.copyProperties(barcode, dto);
if (dto.getExpireDate() != null){
long days = ExpireDateUtil.getExpireDays(dto.getExpireDate());
dto.setExpireDays(days);
String reelStatus = ExpireDateUtil.getReelStatus(days);
dto.setRemark(reelStatus);
} else {
dto.setExpireDays(0);
dto.setRemark("");
}
//long betweenDay = DateUtil.between(dto.getExpireDate(), new Date(), DateUnit.DAY) + 1;
dto.setFactory("A5");
dto.setPlant("W337");
dto.setFloor(dataCache.getCache(Constants.CACHE_floor));
dto.setFirstPutInDate(new Date(dto.getPutInTime()));
dto.setSource(dataCache.getStorageById(storagePos.getStorageId()).getName());
dto.setStoragePosName(storagePos.getPosName());
dtoList.add(dto);
}
}
data.setContent(dtoList);
data.setTotalElements(count);
return data;
}
@ApiOperation("过期报表导出")
@RequestMapping("/expire/download")
@AnonymousAccess
public void expireInfo(ReportQueryCondition queryCondition, Pageable pageable, HttpServletResponse response) throws IOException {
Query query = QueryHelp.getQuery(queryCondition);
Criteria c = Criteria.where("barcode").exists(true);
//判断传入的类型
String expireStatus = queryCondition.getExpireStatus();
Date startDate,endDate;
if ("0".equals(expireStatus)) {
startDate = new Date();
endDate = DateUtil.offsetDay(startDate, 7);
c.and("barcode.expireDate").gte(startDate).lt(endDate);
} else if ("1".equals(expireStatus)) {
startDate = DateUtil.offsetDay(new Date(), 7);
endDate = DateUtil.offsetDay(new Date(), 30);
c.and("barcode.expireDate").gte(startDate).lt(endDate);
} else if ("2".equals(expireStatus)) {
startDate = DateUtil.offsetDay(new Date(), 30);
c.and("barcode.expireDate").gte(startDate);
} else if ("3".equals(expireStatus)) {
endDate = new Date();
c.and("barcode.expireDate").lt(endDate);
}
query.addCriteria(c);
FileUtil.downloadExcel(query, pageable, response, new IExcelDownLoad() {
@Override
public List<List<String>> getHeader() {
List<List<String>> header = new ArrayList<>();
header.add(Lists.newArrayList("厂别"));
header.add(Lists.newArrayList("厂区"));
header.add(Lists.newArrayList("库别"));
header.add(Lists.newArrayList("楼层"));
header.add(Lists.newArrayList("储位"));
header.add(Lists.newArrayList("料号"));
header.add(Lists.newArrayList("物料描述"));
header.add(Lists.newArrayList("数量"));
header.add(Lists.newArrayList("LOT"));
header.add(Lists.newArrayList("D/C"));
header.add(Lists.newArrayList("ID NO"));
header.add(Lists.newArrayList("厂商"));
header.add(Lists.newArrayList("厂商代码"));
header.add(Lists.newArrayList("keeper"));
header.add(Lists.newArrayList("过期天数"));
header.add(Lists.newArrayList("物料状态"));
header.add(Lists.newArrayList("过期日期"));
header.add(Lists.newArrayList("工号"));
header.add(Lists.newArrayList("首次入库时间"));
header.add(Lists.newArrayList("当前入库时间"));
header.add(Lists.newArrayList("来源"));
return header;
}
@Override
public List<List<Object>> getPageData(Query query, Pageable pageable) {
List<List<Object>> dataList = new ArrayList<>();
List<StoragePos> storagePosList = storagePosManager.findByQuery(query, pageable);
for (StoragePos storagePos : storagePosList) {
List<Object> data = new ArrayList<>();
Barcode barcode = storagePos.getBarcode();
data.add("A5");
data.add("A337");
data.add(barcode.getWarehouseCode());
data.add(dataCache.getCache(Constants.CACHE_floor));
data.add(barcode.getPosName());
data.add(barcode.getPartNumber());
data.add(barcode.getDescribe());
data.add(barcode.getAmount());
data.add(barcode.getBatch());
data.add(barcode.getDateCode());
data.add(barcode.getBarcode());
data.add(barcode.getProvider());
data.add(barcode.getProviderNumber());
data.add(barcode.getKeeperCode());
if (barcode.getExpireDate() != null){
long days = ExpireDateUtil.getExpireDays(barcode.getExpireDate());
data.add(days);
String reelStatus = ExpireDateUtil.getReelStatus(days);
data.add(reelStatus);
} else {
data.add(0);
data.add("");
}
data.add(barcode.getExpireDate());
data.add(barcode.getCreator());
data.add(new Date(barcode.getPutInTime()));
data.add(barcode.getPutInDate());
data.add(dataCache.getStorageById(storagePos.getStorageId()).getName());
dataList.add(data);
}
return dataList;
}
});
}
private List<LiteOrderItem> getLackItems(Collection<LiteOrder> liteOrders, ReportQueryCondition queryCondition) {
List<LiteOrderItem> lackItems = new ArrayList<>();
//排除虚拟仓的
List<String> storageIds = new ArrayList<>();
for (Storage storage : dataCache.getAllStorage().values()) {
//if (!storage.isVirtual()) {
storageIds.add(storage.getId());
//}
}
//得到库存信息
Map<String, InventoryItem> inventoryMap = dataCache.getAllInventory(storageIds, null);
if (inventoryMap != null) {
for (LiteOrder liteOrder : liteOrders) {
//状态是未关闭的,未出库的
if (!liteOrder.isClosed()) {
List<LiteOrderItem> items = liteOrder.getOrderItems();
for (LiteOrderItem orderItem : items) {
if (orderItem.getOutReelCount() < orderItem.getNeedReelCount()) {
//判断线别是否相等
String line = queryCondition.getLine();
if (StringUtils.isNotBlank(line)) {
if (!orderItem.getLine().contains(line)) {
continue;
}
}
//判断工单号是否一致
String orderNo = queryCondition.getOrderNo();
if (StringUtils.isNotBlank(orderNo)) {
if (!orderItem.getOrderNo().contains(orderNo)) {
continue;
}
}
//判断料号是否一致
String pn = queryCondition.getPn();
if (StringUtils.isNotBlank(pn)) {
if (!orderItem.getPn().contains(pn)) {
continue;
}
}
InventoryItem inventoryItem = inventoryMap.get(orderItem.getPn());
if (inventoryItem != null) {
if (inventoryItem.getStockReel() /*- inventoryItem.getLockReel()*/ - inventoryItem.getBindReel() > 0) {
inventoryItem.setBindReel(inventoryItem.getBindReel() + 1);
} else {
lackItems.add(orderItem);
}
inventoryMap.put(orderItem.getPn(), inventoryItem);
} else {
lackItems.add(orderItem);
}
}
}
}
}
}
return lackItems;
}
private Object getData(Object data) {
return data == null ? "" : data;
}
}
package com.neotel.smfcore.custom.lizhen.report.merge;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
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.HttpHelper;
import com.neotel.smfcore.common.utils.StringUtils;
import com.neotel.smfcore.core.barcode.service.po.Barcode;
import com.neotel.smfcore.custom.lizhen.report.bacheng.bean.dto.BCChange;
import com.neotel.smfcore.custom.lizhen.report.bacheng.bean.dto.BCExpire;
import com.neotel.smfcore.custom.lizhen.report.bacheng.bean.dto.BCInventory;
import com.neotel.smfcore.custom.lizhen.report.bean.query.ReportQueryCondition;
import com.neotel.smfcore.custom.lizhen.report.merge.bean.query.MergeBcQuery;
import com.neotel.smfcore.security.annotation.AnonymousAccess;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
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.ArrayList;
import java.util.List;
import java.util.Map;
/**
* 报表合并
*/
@RestController
@Slf4j
@RequestMapping("/reportMerge")
public class ReportMergeController {
@Value("${forward.f4.url}")
private String f4Url;
/**
* 库存
*
* @param query
* @return
*/
@RequestMapping("/getInventory")
@AnonymousAccess
public PageData getInventory(MergeBcQuery query) {
String url = f4Url + "/bcReport/getInventory";
url = url + getQueryStr(query);
String result = HttpHelper.sendGet(url);
PageData pageData = JSON.parseObject(result, PageData.class);
PageData resultPageDate = new PageData();
resultPageDate.setTotalElements(pageData.getTotalElements());
List content = pageData.getContent();
String contentStr = JSON.toJSONString(content);
List<BCInventory> bcInventoryList = JSON.parseArray(contentStr, BCInventory.class);
resultPageDate.setContent(bcInventoryList);
return resultPageDate;
}
/**
* 库存导出
*
* @param bcQuery
* @param response
* @throws IOException
*/
@RequestMapping("/getInventory/download")
@AnonymousAccess
public void getInventoryDownload(MergeBcQuery bcQuery, HttpServletResponse response) throws IOException {
List<List<String>> headerList = new ArrayList<>();
headerList.add(Lists.newArrayList("厂别"));
headerList.add(Lists.newArrayList("厂区"));
headerList.add(Lists.newArrayList("库别"));
headerList.add(Lists.newArrayList("料号"));
headerList.add(Lists.newArrayList("物料描述"));
headerList.add(Lists.newArrayList("ID NO"));
headerList.add(Lists.newArrayList("储位"));
headerList.add(Lists.newArrayList("数量"));
headerList.add(Lists.newArrayList("卷数"));
headerList.add(Lists.newArrayList("厂商"));
headerList.add(Lists.newArrayList("LOT"));
headerList.add(Lists.newArrayList("D/C"));
headerList.add(Lists.newArrayList("keeper"));
headerList.add(Lists.newArrayList("禁用信息"));
headerList.add(Lists.newArrayList("入库时间"));
headerList.add(Lists.newArrayList("工号"));
List<List<Object>> dataList = new ArrayList<>();
int page = 0;
int size = 20000;
while (true) {
bcQuery.setPage(page);
bcQuery.setSize(size);
PageData pageData = getInventory(bcQuery);
List<BCInventory> inventoryList = pageData.getContent();
if (inventoryList == null || inventoryList.isEmpty()) {
break;
}
for (BCInventory bcInventory : inventoryList) {
List<Object> result = new ArrayList<>();
result.add(bcInventory.getPlant());
result.add(bcInventory.getFactory());
result.add(bcInventory.getWarehouseCode());
result.add(bcInventory.getPartNumber());
result.add(bcInventory.getDescribe());
result.add(bcInventory.getBarcode());
result.add(bcInventory.getPosName());
result.add(bcInventory.getAmount());
result.add(bcInventory.getReelAmount());
result.add(bcInventory.getProvider());
result.add(bcInventory.getBatch());
result.add(bcInventory.getDateCode());
result.add(bcInventory.getKeeperCode());
result.add(bcInventory.getDisableMsg());
result.add(bcInventory.getPutInDate());
result.add(bcInventory.getCreator());
dataList.add(result);
}
page++;
}
FileUtil.downloadExcel(headerList, dataList, response);
}
/**
* 过期报表
*
* @param query
* @return
*/
@RequestMapping("/getExpire")
@AnonymousAccess
public PageData getExpire(MergeBcQuery query) {
String url = f4Url + "/bcReport/getExpire";
url = url + getQueryStr(query);
String result = HttpHelper.sendGet(url);
PageData pageData = JSON.parseObject(result, PageData.class);
PageData resultPageDate = new PageData();
resultPageDate.setTotalElements(pageData.getTotalElements());
List content = pageData.getContent();
String contentStr = JSON.toJSONString(content);
List<BCExpire> bcInventoryList = JSON.parseArray(contentStr, BCExpire.class);
resultPageDate.setContent(bcInventoryList);
return resultPageDate;
}
/**
* 过期导出
*
* @param bcQuery
* @param response
* @throws IOException
*/
@RequestMapping("/getExpire/download")
@AnonymousAccess
public void getExpireDownload(MergeBcQuery bcQuery, HttpServletResponse response) throws IOException {
List<List<String>> headerList = new ArrayList<>();
headerList.add(Lists.newArrayList("厂别"));
headerList.add(Lists.newArrayList("厂区"));
headerList.add(Lists.newArrayList("库别"));
headerList.add(Lists.newArrayList("料号"));
headerList.add(Lists.newArrayList("物料描述"));
headerList.add(Lists.newArrayList("数量"));
headerList.add(Lists.newArrayList("储位"));
headerList.add(Lists.newArrayList("keeper"));
headerList.add(Lists.newArrayList("ID NO"));
headerList.add(Lists.newArrayList("LOT"));
headerList.add(Lists.newArrayList("D/C"));
headerList.add(Lists.newArrayList("增加物料保质期"));
headerList.add(Lists.newArrayList("过期天数"));
headerList.add(Lists.newArrayList("过期日期"));
headerList.add(Lists.newArrayList("备注"));
List<List<Object>> dataList = new ArrayList<>();
int page = 0;
int size = 20000;
while (true) {
bcQuery.setPage(page);
bcQuery.setSize(size);
PageData pageData = getExpire(bcQuery);
List<BCExpire> bcExpireList = pageData.getContent();
if (bcExpireList == null || bcExpireList.isEmpty()) {
break;
}
for (BCExpire expire : bcExpireList) {
List<Object> result = new ArrayList<>();
result.add(expire.getPlant());
result.add(expire.getFactory());
result.add(expire.getWarehouseCode());
result.add(expire.getPartNumber());
result.add(expire.getDescribe());
result.add(expire.getAmount());
result.add(expire.getPosName());
result.add(expire.getKeeperCode());
result.add(expire.getBarcode());
result.add(expire.getBatch());
result.add(expire.getDateCode());
result.add(expire.getExpireYear());
result.add(expire.getExpireDays());
result.add(expire.getExpireDate());
result.add(expire.getRemark());
dataList.add(result);
}
page++;
}
FileUtil.downloadExcel(headerList, dataList, response);
}
/**
* 事务
*
* @param query
* @return
*/
@RequestMapping("/change")
@AnonymousAccess
public PageData change(MergeBcQuery query) {
String url = f4Url + "/bcReport/change";
url = url + getQueryStr(query);
String result = HttpHelper.sendGet(url);
PageData pageData = JSON.parseObject(result, PageData.class);
PageData resultPageDate = new PageData();
resultPageDate.setTotalElements(pageData.getTotalElements());
List content = pageData.getContent();
String contentStr = JSON.toJSONString(content);
List<BCChange> bcChangeList = JSON.parseArray(contentStr, BCChange.class);
resultPageDate.setContent(bcChangeList);
return resultPageDate;
}
/**
* 事务导出
*
* @param bcQuery
* @param response
* @throws IOException
*/
@RequestMapping("/change/download")
@AnonymousAccess
public void changeDownload(MergeBcQuery bcQuery, HttpServletResponse response) throws IOException {
List<List<String>> headerList = new ArrayList<>();
headerList.add(Lists.newArrayList("厂别"));
headerList.add(Lists.newArrayList("厂区"));
headerList.add(Lists.newArrayList("库别"));
headerList.add(Lists.newArrayList("料号"));
headerList.add(Lists.newArrayList("物料描述"));
headerList.add(Lists.newArrayList("异动数量"));
headerList.add(Lists.newArrayList("卷数"));
headerList.add(Lists.newArrayList("储位"));
headerList.add(Lists.newArrayList("异动类型"));
headerList.add(Lists.newArrayList("ID NO"));
headerList.add(Lists.newArrayList("LOT"));
headerList.add(Lists.newArrayList("D/C"));
headerList.add(Lists.newArrayList("厂商"));
headerList.add(Lists.newArrayList("厂商代码"));
headerList.add(Lists.newArrayList("keeper"));
headerList.add(Lists.newArrayList("事务日期"));
headerList.add(Lists.newArrayList("工号"));
List<List<Object>> dataList = new ArrayList<>();
int page = 0;
int size = 20000;
while (true) {
bcQuery.setPage(page);
bcQuery.setSize(size);
PageData pageData = change(bcQuery);
List<BCChange> bcChangeList = pageData.getContent();
if (bcChangeList == null || bcChangeList.isEmpty()) {
break;
}
for (BCChange bcChange : bcChangeList) {
List<Object> result = new ArrayList<>();
result.add(bcChange.getPlant());
result.add(bcChange.getFactory());
result.add(bcChange.getWarehouseCode());
result.add(bcChange.getPartNumber());
result.add(bcChange.getDescribe());
result.add(bcChange.getNum());
result.add(bcChange.getReelAmount());
result.add(bcChange.getPosName());
result.add(bcChange.getType());
result.add(bcChange.getBarcode());
result.add(bcChange.getBatch());
result.add(bcChange.getDateCode());
result.add(bcChange.getProvider());
result.add(bcChange.getProviderNumber());
result.add(bcChange.getKeeperCode());
result.add(bcChange.getCreateDate());
result.add(bcChange.getCreator());
dataList.add(result);
}
page++;
}
FileUtil.downloadExcel(headerList, dataList, response);
}
@ApiOperation("禁限用")
@RequestMapping("/disable")
@AnonymousAccess
public PageData disable(ReportQueryCondition queryCondition) {
String url = f4Url + "/inner/report/disable";
url = url + getQueryStr(queryCondition);
String result = HttpHelper.sendGet(url);
PageData pageData = JSON.parseObject(result, PageData.class);
PageData resultPageDate = new PageData();
resultPageDate.setTotalElements(pageData.getTotalElements());
List content = pageData.getContent();
String contentStr = JSON.toJSONString(content);
List<Barcode> bcBarcodeList = JSON.parseArray(contentStr, Barcode.class);
resultPageDate.setContent(bcBarcodeList);
return resultPageDate;
}
/**
* 禁限用
*
* @param bcQuery
* @param response
* @throws IOException
*/
@RequestMapping("/disable/download")
@AnonymousAccess
public void disableDownload(ReportQueryCondition bcQuery, HttpServletResponse response) throws IOException {
List<List<String>> headerList = new ArrayList<>();
headerList.add(Lists.newArrayList("ID NO"));
headerList.add(Lists.newArrayList("料号"));
headerList.add(Lists.newArrayList("D/C"));
headerList.add(Lists.newArrayList("L/C"));
headerList.add(Lists.newArrayList("厂商代码"));
headerList.add(Lists.newArrayList("厂商"));
headerList.add(Lists.newArrayList("数量"));
headerList.add(Lists.newArrayList("禁用信息"));
List<List<Object>> dataList = new ArrayList<>();
int page = 0;
int size = 20000;
while (true) {
bcQuery.setPage(page);
bcQuery.setSize(size);
PageData pageData = disable(bcQuery);
List<Barcode> bcBarcodeList = pageData.getContent();
if (bcBarcodeList == null || bcBarcodeList.isEmpty()) {
break;
}
for (Barcode barcode : bcBarcodeList) {
List<Object> result = new ArrayList<>();
result.add(barcode.getBarcode());
result.add(barcode.getPartNumber());
result.add(barcode.getDateCode());
result.add(barcode.getBatch());
result.add(barcode.getProviderNumber());
result.add(barcode.getProvider());
result.add(barcode.getAmount());
result.add(barcode.getDisableMsg());
dataList.add(result);
}
page++;
}
FileUtil.downloadExcel(headerList, dataList, response);
}
private String getQueryStr(Object obj) {
String str = "";
String queryStr = JSONObject.toJSONString(obj);
JSONObject queryJson = JSONObject.parseObject(queryStr);
for (Map.Entry<String, Object> entry : queryJson.entrySet()) {
Object value = entry.getValue();
if (value != null) {
if (StringUtils.isNotBlank(str)) {
str = str + "&" + entry.getKey() + "=" + entry.getValue();
} else {
str = "?" + entry.getKey() + "=" + entry.getValue();
}
}
}
return str;
}
}
package com.neotel.smfcore.custom.lizhen.report.merge.bean.query;
import com.neotel.smfcore.custom.lizhen.report.bacheng.bean.query.BcQuery;
import lombok.Data;
@Data
public class MergeBcQuery extends BcQuery {
private int page;
private int size;
private String sort;
}
package com.neotel.smfcore.custom.lizhen.report.merge.utils;
import com.neotel.smfcore.core.device.util.DataCache;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* 楼层工具类
*/
@Service
public class FloorUtils {
@Autowired
private DataCache dataCache;
@Value("${forward.f2.name}")
private String forwardF2Name;
@Value("${forward.f2.url}")
private String forwardF2Url;
@Value("${forward.f3.name}")
private String forwardF3Name;
@Value("${forward.f3.url}")
private String forwardF3Url;
@Value("${forward.f5.name}")
private String forwardF5Name;
@Value("${forward.f5.url}")
private String forwardF5Url;
@Value("${forward.b15.name}")
private String forwardB15Name;
@Value("${forward.b15.url}")
private String forwardB15Url;
@PostConstruct
public void init() {
forwardF2Name = dataCache.getConfigCache("forward.f2.name", forwardF2Name);
forwardF2Url = dataCache.getConfigCache("forward.f2.url", forwardF2Url);
forwardF3Name = dataCache.getConfigCache("forward.f3.name", forwardF3Name);
forwardF3Url = dataCache.getConfigCache("forward.f3.url", forwardF3Url);
forwardF5Name = dataCache.getConfigCache("forward.f5.name", forwardF5Name);
forwardF5Url = dataCache.getConfigCache("forward.f5.url", forwardF5Url);
forwardB15Name = dataCache.getConfigCache("forward.b15.name", forwardB15Name);
forwardB15Url = dataCache.getConfigCache("forward.b15.url", forwardB15Url);
}
public Map<String, String> getAllFloor(int type) {
Map<String, String> resultMap = new LinkedHashMap<>();
if (type == 0) {
resultMap.put(forwardF2Name, forwardF2Name);
resultMap.put(forwardF3Name, forwardF3Name);
resultMap.put(forwardF5Name, forwardF5Name);
resultMap.put(forwardB15Name, forwardB15Name);
} else if (type == 1){
resultMap.put(forwardF2Name, forwardF2Name);
resultMap.put(forwardF3Name, forwardF3Name);
resultMap.put(forwardF5Name, forwardF5Name);
} else if (type == 2){
resultMap.put(forwardB15Name, forwardB15Name);
}
return resultMap;
}
public String getUrlByFloor(String floor) {
String url = "";
if (forwardF2Name.equals(floor)) {
url = forwardF2Url;
} else if (forwardF3Name.equals(floor)) {
url = forwardF3Url;
} else if (forwardF5Name.equals(floor)) {
url = forwardF5Url;
} else if (forwardB15Name.equals(floor)) {
url = forwardB15Url;
}
return url;
}
public boolean isB15(String floor){
return floor.equals(forwardB15Name);
}
}
package com.neotel.smfcore.custom.lizhen.report.outer;
import cn.hutool.core.date.DateUtil;
import com.google.common.collect.Lists;
import com.neotel.smfcore.common.base.IExcelDownLoad;
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.rest.bean.mapstruct.BarcodeMapper;
import com.neotel.smfcore.core.barcode.service.manager.IBarcodeManager;
import com.neotel.smfcore.core.barcode.service.po.Barcode;
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.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.LiteOrder;
import com.neotel.smfcore.core.order.service.po.LiteOrderItem;
import com.neotel.smfcore.core.storage.bean.InventoryItem;
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.custom.lizhen.agvBox.bean.InventoryData;
import com.neotel.smfcore.custom.lizhen.agvBox.bean.enums.InventoryStatus;
import com.neotel.smfcore.custom.lizhen.agvBox.service.manager.InventoryDataManager;
import com.neotel.smfcore.custom.lizhen.agvBox.util.BoxUtil;
import com.neotel.smfcore.custom.lizhen.innerBox.enums.ExtendType;
import com.neotel.smfcore.custom.lizhen.report.bean.dto.ExpireDto;
import com.neotel.smfcore.custom.lizhen.report.bean.dto.InventoryDto;
import com.neotel.smfcore.custom.lizhen.report.bean.query.ReportQueryCondition;
import com.neotel.smfcore.custom.lizhen.setting.util.ExpireDateUtil;
import com.neotel.smfcore.security.annotation.AnonymousAccess;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
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 LiteOrderCache liteOrderCache;
@Autowired
private DataCache dataCache;
@Autowired
private BarcodeMapper barcodeMapper;
@Autowired
private InventoryDataManager inventoryDataManager;
@Value("${api.plant}")
private String plant; //厂别
@Value("${api.outerFactory}")
private String factory; //厂区
/**
* key为partNumber
* value为数量
*/
private static Map<String, Integer> partNumberAmount = new ConcurrentHashMap<>();
@ApiOperation("发料明细")
@RequestMapping("/pickingDetail")
@AnonymousAccess
public PageData pickingDetail(ReportQueryCondition queryCondition, Pageable pageable) {
String orderNo = queryCondition.getOrderNo();
if (StringUtils.isNotBlank(orderNo)){
queryCondition.setOrderNoList(new ArrayList<>(Arrays.asList(orderNo.split(","))));
queryCondition.setOrderNo(null);
}
Query query = QueryHelp.getQuery(queryCondition);
//subSourceId存的是itemId
Criteria criteria = Criteria.where("subSourceId").exists(true).and("type").is(OP.CHECKOUT).and("status").is(OP_STATUS.FINISHED.name());
PageData<DataLog> pageData = new PageData<>();
if (pageable != null) {
pageData = dataLogManager.findByPage(query.addCriteria(criteria), pageable);
} else {
List<DataLog> dataLogs = dataLogManager.findByQuery(query.addCriteria(criteria));
if (dataLogs != null && !dataLogs.isEmpty()) {
pageData.setTotalElements(dataLogs.size());
pageData.setContent(dataLogs);
}
}
//开始处理数据
List<DataLog> dataLogs = pageData.getContent();
if (dataLogs != null && !dataLogs.isEmpty()) {
for (DataLog dataLog : dataLogs) {
dataLog.setPlantCode(plant);
dataLog.setFactory(factory);
if (StringUtils.isBlank(dataLog.getChangeType())){
dataLog.setChangeType(ExtendType.getName(dataLog.getExtendType()));
}
}
}
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("厂别", getData(dataLog.getPlantCode()));
resultMap.put("厂区", getData(dataLog.getFactory()));
resultMap.put("库别", getData(dataLog.getWarehouseCode()));
resultMap.put("楼层", getData(dataLog.getLine()));
resultMap.put("挑料单号", getData(dataLog.getOrderNo()));
resultMap.put("工单号", getData(dataLog.getMo()));
resultMap.put("料号", getData(dataLog.getPartNumber()));
resultMap.put("物料描述", getData(dataLog.getDescribe()));
resultMap.put("储位", getData(dataLog.getPosName()));
resultMap.put("段别", getData(dataLog.getSide()));
resultMap.put("数量", getData(dataLog.getNum()));
resultMap.put("异动类型", getData(dataLog.getChangeType()));
resultMap.put("工号", getData(dataLog.getOperator()));
resultMap.put("姓名", getData(null));
resultMap.put("时间", getData(dataLog.getCreateDate()));
resultMap.put("ID NO.", getData(dataLog.getBarcode()));
resultMap.put("LOT", getData(dataLog.getBatchInfo()));
resultMap.put("D/C", getData(dataLog.getDateCode()));
resultMap.put("厂商", getData(dataLog.getProvider()));
resultMap.put("厂商代码", getData(dataLog.getProviderNumber()));
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) {
PageData resultData = new PageData();
Collection<LiteOrder> liteOrders = liteOrderCache.getAllLiteOrder();
if (liteOrders != null && !liteOrders.isEmpty()) {
List<LiteOrderItem> lackItems = getLackItems(liteOrders, queryCondition);
if (lackItems != null && !lackItems.isEmpty()) {
for (LiteOrderItem lackItem : lackItems) {
lackItem.setPlantCode(plant);
lackItem.setFactory(factory);
}
}
resultData.setContent(orderItemMapper.toDto(lackItems));
resultData.setTotalElements(lackItems.size());
}
return resultData;
}
@ApiOperation("缺料导出")
@RequestMapping("/lackPicking/download")
@AnonymousAccess
public void lackPickingDownload(ReportQueryCondition queryCondition, Pageable pageable, HttpServletResponse response) {
PageData data = lackPicking(queryCondition, null);
List<OrderItemDto> dtos = data.getContent();
if (dtos != null && !dtos.isEmpty()) {
List<Map<String, Object>> results = new ArrayList<>();
for (OrderItemDto dto : dtos) {
Map<String, Object> resultMap = new LinkedHashMap<>();
resultMap.put("厂别",getData(dto.getPlantCode()));
resultMap.put("厂区",factory);
resultMap.put("库别",getData(dto.getWarehouseCode()));
resultMap.put("楼层",getData(dto.getLine()));
resultMap.put("Picking ID",getData(dto.getOrderNo()));
resultMap.put("工单号",getData(dto.getMo()));
resultMap.put("55料号",getData(null));
resultMap.put("工单套数",getData(null));
resultMap.put("料号",getData(dto.getPn()));
resultMap.put("描述",getData(null));
resultMap.put("需求站别",getData(dto.getSide()));
resultMap.put("需求数量",getData(dto.getNeedNum()));
resultMap.put("需求卷数",getData(dto.getNeedReelCount()));
resultMap.put("发料数量",getData(dto.getTotalOutNum()));
resultMap.put("发料卷数",getData(dto.getTotalOutReelCount()));
resultMap.put("缺料数量",getData(dto.getLackNum()));
resultMap.put("缺料卷数",getData(dto.getLackReel()));
resultMap.put("是否超发",dto.isExcess() ? "是" : "否");
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 resultData = new PageData();
if (pageable != null) {
PageData<LiteOrderItem> data = liteOrderItemManager.findByPage(query, pageable);
resultData.setTotalElements(data.getTotalElements());
resultData.setContent(orderItemMapper.toDto(data.getContent()));
} else {
List<LiteOrderItem> items = liteOrderItemManager.findByQuery(query);
if (items != null && !items.isEmpty()) {
resultData.setTotalElements(items.size());
resultData.setContent(orderItemMapper.toDto(items));
}
}
//开始处理数据
List<OrderItemDto> dtos = resultData.getContent();
for (OrderItemDto dto : dtos) {
dto.setFactory(factory);
//判断是否超发
if (dto.isExcess()) {
if (dto.getTotalOutNum() - dto.getNeedNum() > 0) {
dto.setExcessOutNum(dto.getTotalOutNum() - dto.getNeedNum());
dto.setExcessOutReel(1 + dto.getOutReelCount());
}
dto.setTotalOutNum(dto.getTotalOutNum());
dto.setTotalOutReelCount(dto.getTotalOutReelCount());
} else {
if (dto.getTotalOutNum() - dto.getNeedNum() > 0) {
if (dto.getTotalOutReelCount() - dto.getNeedReelCount() > 0){
dto.setExcessOutReel(dto.getTotalOutReelCount() - dto.getNeedReelCount());
}
dto.setExcessOutNum(dto.getTotalOutNum() - dto.getNeedNum());
}
}
}
return resultData;
}
@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 dto : orderItemDtos) {
Map<String, Object> resultMap = new LinkedHashMap<>();
resultMap.put("厂别", getData(dto.getPlantCode()));
resultMap.put("厂区", getData(dto.getFactory()));
resultMap.put("库别", getData(dto.getWarehouseCode()));
resultMap.put("楼层", getData(dto.getLine()));
resultMap.put("挑料单号", getData(dto.getOrderNo()));
resultMap.put("工单号", getData(dto.getMo()));
resultMap.put("料号", getData(dto.getPn()));
resultMap.put("物料描述", getData(null));
resultMap.put("需求数", getData(dto.getNeedNum()));
resultMap.put("需求卷", getData(dto.getNeedReelCount()));
resultMap.put("实发数", getData(dto.getTotalOutNum()));
resultMap.put("实发卷", getData(dto.getTotalOutReelCount()));
resultMap.put("段别", getData(dto.getSide()));
resultMap.put("超发数量", getData(dto.getExcessOutNum()));
resultMap.put("超发卷数", getData(dto.getExcessOutReel()));
resultMap.put("是否超发", getData(dto.isExcess() ? "是" : "否"));
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);
PageData resultData = new PageData();
if (pageable != null) {
PageData<LiteOrderItem> data = liteOrderItemManager.findByPage(query, pageable);
resultData.setTotalElements(data.getTotalElements());
resultData.setContent(orderItemMapper.toDto(data.getContent()));
} else {
List<LiteOrderItem> orderItems = liteOrderItemManager.findByQuery(query);
if (orderItems != null && !orderItems.isEmpty()) {
resultData.setTotalElements(orderItems.size());
resultData.setContent(orderItemMapper.toDto(orderItems));
}
}
List<OrderItemDto> orderItems = resultData.getContent();
if (orderItems != null && !orderItems.isEmpty()) {
for (OrderItemDto dto : orderItems) {
String plantCode = dto.getPlantCode();
if (StringUtils.isBlank(plantCode)) {
dto.setPlantCode(plant);
}
dto.setFactory(factory);
}
}
return resultData;
}
@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("厂别", getData(orderItemDto.getPlantCode()));
resultMap.put("厂区", getData(orderItemDto.getFactory()));
resultMap.put("库别", getData(orderItemDto.getWarehouseCode()));
resultMap.put("楼层", getData(orderItemDto.getLine()));
resultMap.put("PK ID", getData(orderItemDto.getOrderNo()));
resultMap.put("工单号", getData(orderItemDto.getMo()));
resultMap.put("板子料号", getData(null));
resultMap.put("套数", getData(null));
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 resultData = new PageData();
if (pageable != null) {
PageData<DataLog> data = dataLogManager.findByPage(query, pageable);
resultData.setTotalElements(data.getTotalElements());
resultData.setContent(data.getContent());
} else {
List<DataLog> logs = dataLogManager.findByQuery(query);
if (logs != null && !logs.isEmpty()) {
resultData.setTotalElements(logs.size());
resultData.setContent(logs);
}
}
List<DataLog> logs = resultData.getContent();
if (logs != null && !logs.isEmpty()) {
for (DataLog dataLog : logs) {
String plantCode = dataLog.getPlantCode();
if (StringUtils.isBlank(plantCode)) {
dataLog.setPlantCode(plant);
}
dataLog.setFactory(factory);
if ("CS".equals(dataLog.getPartNumber()) || "CM".equals(dataLog.getPartNumber()) || "CB".equals(dataLog.getPartNumber())) {
dataLog.setStoragePosName(dataLog.getPosName());
dataLog.setPosName(null);
dataLog.setBox(dataLog.getBarcode());
dataLog.setBarcode("");
}
if (StringUtils.isBlank(dataLog.getChangeType())) {
dataLog.setChangeType(ExtendType.getName(dataLog.getExtendType()));
}
}
}
return resultData;
}
@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("厂别", getData(dataLog.getPlantCode()));
resultMap.put("厂区", getData(dataLog.getFactory()));
resultMap.put("料号", getData(dataLog.getPartNumber()));
resultMap.put("物料描述", getData(dataLog.getDescribe()));
resultMap.put("隔口码", getData(dataLog.getPosName()));
resultMap.put("异动数量", getData(dataLog.getNum()));
resultMap.put("储位", getData(dataLog.getStoragePosName()));
resultMap.put("异动类型", getData(dataLog.getChangeType()));
resultMap.put("PK ID", getData(dataLog.getOrderNo()));
resultMap.put("盘点批次", getData(dataLog.getInventoryBatch()));
resultMap.put("箱号", getData(dataLog.getBox()));
resultMap.put("ID NO", getData(dataLog.getBarcode()));
resultMap.put("LOT", getData(dataLog.getBatchInfo()));
resultMap.put("D/C", getData(dataLog.getDateCode()));
resultMap.put("厂商", getData(dataLog.getProvider()));
resultMap.put("厂商代码", getData(dataLog.getProviderNumber()));
resultMap.put("Keeper", getData(dataLog.getKeeperCode()));
resultMap.put("原始库别", getData(dataLog.getWarehouseCode()));
resultMap.put("目的库别", getData(null));
resultMap.put("首次入库时间", getData(dataLog.getFristPutInDate()));
resultMap.put("事务日期", getData(dataLog.getCreateDate()));
resultMap.put("工号", getData(dataLog.getOperator()));
resultMap.put("姓名", getData(null));
results.add(resultMap);
}
try {
FileUtil.downloadExcel(results, response);
} catch (IOException e) {
e.printStackTrace();
log.info("异动导出失败--" + e.getMessage());
}
}
}
private static Map<String, StoragePos> posMap = new ConcurrentHashMap<>();
private static Map<String, Long> countMap = new ConcurrentHashMap<>();
@ApiOperation("库存")
@RequestMapping("/inventory")
@AnonymousAccess
public PageData inventory(ReportQueryCondition queryCondition, Query query, Pageable pageable) {
posMap.clear();
countMap.clear();
List<StoragePos> storagePosList = storagePosManager.findNotEmptyPosName();
for (StoragePos pos : storagePosList) {
Barcode barcode = pos.getBarcode();
posMap.put(barcode.getBarcode(), pos);
}
if (queryCondition != null) {
query = QueryHelp.getQuery(queryCondition);
query.addCriteria(Criteria.where("posName").exists(true).ne("").and("partNumber").nin(Arrays.asList("CS", "CM", "CB")));
}
PageData<InventoryDto> resultData = new PageData<>();
PageData<Barcode> data = barcodeManager.findByPage(query, pageable);
List<InventoryDto> dtos = new ArrayList<>();
List<Barcode> barcodes = data.getContent();
if (barcodes != null && !barcodes.isEmpty()) {
//int count = 0;
for (Barcode barcode : barcodes) {
//count++;
//log.info("处理数量--" + count);
InventoryDto dto = new InventoryDto();
String posName = barcode.getPosName();
String newPosName = "";
if (posName.indexOf("-") != -1){
newPosName = posName.substring(0, posName.indexOf("-"));
}
//根据posName取库位信息
StoragePos pos = null;
if (posMap.get(newPosName) != null) {
pos = posMap.get(newPosName);
} /*else {
pos = storagePosManager.getByBarcode(newPosName);
if (pos == null) {
pos = new StoragePos();
posMap.put(newPosName, pos);
}
}*/
//获取隔口信息
if (countMap.get(posName) == null) {
if (pos == null){
pos = new StoragePos();
}
Barcode pidBarcode = pos.getBarcode();
if (pidBarcode == null) {
pidBarcode = barcodeManager.findByBarcode(newPosName);
}
if (pidBarcode != null) {
List<Barcode> subCodeList = pidBarcode.getSubCodeList();
if (subCodeList != null && !subCodeList.isEmpty()) {
Map<String, Long> countAllMap = subCodeList.stream().collect(Collectors.groupingBy(t -> t.getPosName(), Collectors.counting()));
countMap.putAll(countAllMap);
}
}
}
//库位名称
if (pos != null && StringUtils.isNotBlank(pos.getPosName())) {
dto.setStoragePosName(pos.getPosName());
Storage storage = dataCache.getStorageById(pos.getStorageId());
if(storage != null) {
if (StringUtils.isBlank(barcode.getStorageId())){
barcode.setStorageId(storage.getId());
barcodeManager.save(barcode);
}
dto.setSource(storage.getName());
}
}
//库位数量
if (countMap.get(posName) != null) {
dto.setPosNameCount(countMap.get(posName));
}
dto.setPartNumber(barcode.getPartNumber());
dto.setPlant(plant);
dto.setFactory(factory);
dto.setWarehouseCode(barcode.getWarehouseCode());
dto.setPosName(barcode.getPosName());
dto.setReelCount(1);
dto.setAmount(barcode.getAmount());
dto.setProvider(barcode.getProvider());
dto.setProviderNumber(barcode.getProviderNumber());
dto.setBatch(barcode.getBatch());
dto.setDateCode(barcode.getDateCode());
dto.setKeeperCode(barcode.getKeeperCode());
dto.setDisableMsg(barcode.getDisableMsg());
dto.setFirstPutInDate(barcode.getFirstPutInDate());
dto.setPutInDate(barcode.getPutInDate());
dto.setCreator(barcode.getCreator());
dto.setBarcode(barcode.getBarcode());
dtos.add(dto);
}
}
resultData.setTotalElements(data.getTotalElements());
resultData.setContent(dtos);
return resultData;
}
@ApiOperation("库存导出")
@RequestMapping("/inventory/download")
@AnonymousAccess
public void inventoryDownload(ReportQueryCondition queryCondition, Pageable pageable, HttpServletResponse response) {
log.info("导出开始:"+new Date());
Query query = QueryHelp.getQuery(queryCondition);
query.addCriteria(Criteria.where("posName").exists(true).ne("").and("partNumber").nin(Arrays.asList("CS","CM","CB")));
try {
FileUtil.downloadExcel(query, pageable, response, new IExcelDownLoad() {
@Override
public List<List<String>> getHeader() {
List<List<String>> header = new ArrayList<>();
header.add(Lists.newArrayList("厂别"));
header.add(Lists.newArrayList("厂区"));
header.add(Lists.newArrayList("库别"));
header.add(Lists.newArrayList("楼层"));
header.add(Lists.newArrayList("隔口码"));
header.add(Lists.newArrayList("唯一码"));
header.add(Lists.newArrayList("料号"));
header.add(Lists.newArrayList("物料描述"));
header.add(Lists.newArrayList("隔口数量"));
header.add(Lists.newArrayList("卷数"));
header.add(Lists.newArrayList("每卷数量"));
header.add(Lists.newArrayList("厂商"));
header.add(Lists.newArrayList("厂商代码"));
header.add(Lists.newArrayList("LOT"));
header.add(Lists.newArrayList("D/C"));
header.add(Lists.newArrayList("批次代码"));
header.add(Lists.newArrayList("keeper"));
header.add(Lists.newArrayList("储位"));
header.add(Lists.newArrayList("禁用信息"));
header.add(Lists.newArrayList("首次入库时间"));
header.add(Lists.newArrayList("当前入库时间"));
header.add(Lists.newArrayList("工号"));
header.add(Lists.newArrayList("姓名"));
header.add(Lists.newArrayList("来源"));
return header;
}
@Override
public List<List<Object>> getPageData(Query query, Pageable pageable) {
List<List<Object>> results = new ArrayList<>();
PageData<InventoryDto> data = inventory(null, query, pageable);
List<InventoryDto> dtos = data.getContent();
if (dtos != null && !dtos.isEmpty()) {
for (InventoryDto dto : dtos) {
List<Object> result = new ArrayList<>();
result.add(dto.getPlant());
result.add(dto.getFactory());
result.add(dto.getWarehouseCode());
result.add(dto.getFloor());
result.add(dto.getPosName());
result.add(dto.getBarcode());
result.add(dto.getPartNumber());
result.add("");
result.add(dto.getPosNameCount());
result.add(dto.getReelCount());
result.add(dto.getAmount());
result.add(dto.getProvider());
result.add(dto.getProviderNumber());
result.add(dto.getBatch());
result.add(dto.getDateCode());
result.add("");
result.add(dto.getKeeperCode());
result.add(dto.getStoragePosName());
result.add(dto.getDisableMsg());
result.add(dto.getFirstPutInDate());
result.add(dto.getPutInDate());
result.add(dto.getCreator());
result.add("");
result.add(dto.getSource());
results.add(result);
}
}
return results;
}
});
} catch (IOException e) {
e.printStackTrace();
log.info("库存导出失败--" + e.getMessage());
}
log.info("导出完成:"+new Date());
}
@ApiOperation("禁限用")
@RequestMapping("/disable")
@AnonymousAccess
public PageData disable(ReportQueryCondition queryCondition, Pageable pageable) {
Query query = QueryHelp.getQuery(queryCondition);
query.addCriteria(Criteria.where("disableMsg").nin("").exists(true));
PageData<BarcodeDto> resultData = new PageData<>();
if (pageable != null) {
PageData<Barcode> data = barcodeManager.findByPage(query, pageable);
resultData.setTotalElements(data.getTotalElements());
resultData.setContent(barcodeMapper.toDto(data.getContent()));
} else {
List<Barcode> barcodes = barcodeManager.findByQuery(query);
if (barcodes != null && !barcodes.isEmpty()) {
resultData.setTotalElements(barcodes.size());
resultData.setContent(barcodeMapper.toDto(barcodes));
}
}
//进行单独处理
List<BarcodeDto> dtos = resultData.getContent();
if (dtos != null && !dtos.isEmpty()) {
for (BarcodeDto dto : dtos) {
dto.setPlant(plant);
dto.setFactory(factory);
String posName = dto.getPosName();
if (StringUtils.isNotBlank(posName)) {
posName = posName.substring(0, posName.indexOf("-"));
StoragePos pos = storagePosManager.getByBarcode(posName);
if (pos != null) {
dto.setStoragePosName(pos.getPosName());
}
}
}
}
return resultData;
}
@ApiOperation("禁限用导出")
@RequestMapping("/disable/download")
@AnonymousAccess
public void disableDownload(ReportQueryCondition queryCondition, Pageable pageable, HttpServletResponse response) {
PageData data = disable(queryCondition, null);
List<Map<String, Object>> results = new ArrayList<>();
List<BarcodeDto> dtos = data.getContent();
if (dtos != null && !dtos.isEmpty()) {
for (BarcodeDto dto : dtos) {
Map<String, Object> resultMap = new LinkedHashMap<>();
resultMap.put("厂别", getData(dto.getPlant()));
resultMap.put("厂区", getData(dto.getFactory()));
resultMap.put("库别", getData(dto.getWarehouseCode()));
resultMap.put("料号", getData(dto.getPartNumber()));
resultMap.put("物料描述", getData(dto.getDescribe()));
resultMap.put("隔口码", getData(dto.getPosName()));
resultMap.put("储位", getData(dto.getStoragePosName()));
resultMap.put("Keeper", getData(dto.getKeeperCode()));
resultMap.put("数量", getData(dto.getAmount()));
resultMap.put("LOT", getData(dto.getBatch()));
resultMap.put("D/C", getData(dto.getDateCode()));
resultMap.put("厂商", getData(dto.getProvider()));
resultMap.put("厂商代码", getData(dto.getProviderNumber()));
resultMap.put("禁用信息", getData(dto.getDisableMsg()));
resultMap.put("入库时间", getData(dto.getPutInDate()));
results.add(resultMap);
}
}
try {
FileUtil.downloadExcel(results, response);
} catch (IOException e) {
e.printStackTrace();
log.info("禁限用导出导出失败--" + e.getMessage());
}
}
@ApiOperation("盘点报表")
@RequestMapping("/inventoryData")
@AnonymousAccess
public PageData inventoryData(ReportQueryCondition queryCondition, Pageable pageable) {
Query query = QueryHelp.getQuery(queryCondition);
if (pageable != null) {
return inventoryDataManager.findByPage(query, pageable);
} else {
PageData pageData = new PageData();
List<InventoryData> dataList = inventoryDataManager.findByQuery(query);
if (dataList != null && !dataList.isEmpty()) {
pageData.setTotalElements(dataList.size());
pageData.setContent(dataList);
}
return pageData;
}
}
@ApiOperation("盘点报表导出")
@RequestMapping("/inventoryData/download")
@AnonymousAccess
public void inventoryDataDownload(ReportQueryCondition queryCondition, Pageable pageable,HttpServletResponse response) {
PageData pageData = inventoryData(queryCondition, null);
if (pageData.getTotalElements() > 0) {
List<Map<String, Object>> results = new ArrayList<>();
List<InventoryData> dataList = pageData.getContent();
for (InventoryData data : dataList) {
Map<String, Object> map = new LinkedHashMap<>();
map.put("料箱", data.getBox());
map.put("隔口", data.getBoxPartition());
map.put("料号", data.getPartNumber());
map.put("描述", "");
//map.put("原储位",data.getOriPosName());
map.put("储位", data.getPosName());
map.put("卷数", data.getReelCount());
map.put("数量", data.getAmout());
map.put("已盘点卷数", data.getInventoryReelCount());
map.put("已盘点数量", data.getInventoryAmout());
map.put("是否匹配", data.isMatch() ? "是" : "否");
map.put("盘点人", data.getCreator());
map.put("盘点状态", InventoryStatus.getValue(data.getStatus()));
map.put("盘点批次", data.getInventoryBatch());
map.put("人工是否确认", data.isNeedInventory() ? "是" : "否");
map.put("创建时间",data.getCreateDate());
results.add(map);
}
try {
FileUtil.downloadExcel(results,response);
} catch (IOException e) {
e.printStackTrace();
log.error("盘点报表导出失败");
}
}
}
@ApiOperation("过期报表")
@RequestMapping("/expire")
@AnonymousAccess
public PageData<ExpireDto> expireInfo(ReportQueryCondition queryCondition, Pageable pageable) {
Query query = QueryHelp.getQuery(queryCondition);
Criteria c = Criteria.where("posName").exists(true).ne("").and("partNumber").nin(Arrays.asList("CS", "CM", "CB"));
//判断传入的类型
String expireStatus = queryCondition.getExpireStatus();
Date startDate,endDate;
if ("0".equals(expireStatus)) {
startDate = new Date();
endDate = DateUtil.offsetDay(startDate, 7);
c.and("expireDate").gte(startDate).lt(endDate);
} else if ("1".equals(expireStatus)) {
startDate = DateUtil.offsetDay(new Date(), 7);
endDate = DateUtil.offsetDay(new Date(), 30);
c.and("expireDate").gte(startDate).lt(endDate);
} else if ("2".equals(expireStatus)) {
List<Criteria> orCriList = new ArrayList<>();
orCriList.add(Criteria.where("expireDate").gt(new Date()).and("posName").exists(true).ne("").and("partNumber").nin(Arrays.asList("CS", "CM", "CB")));
orCriList.add(Criteria.where("expireDate").exists(false).and("posName").exists(true).ne("").and("partNumber").nin(Arrays.asList("CS", "CM", "CB")));
c.orOperator(orCriList);
} else if ("3".equals(expireStatus)) {
endDate = new Date();
c.and("expireDate").lt(endDate);
}
query.addCriteria(c);
int count = barcodeManager.countByQuery(query);
List<Barcode> barcodeList = barcodeManager.findByQuery(query, pageable);
List<ExpireDto> expireDtoList = new ArrayList<>();
if (barcodeList != null && !barcodeList.isEmpty()) {
//提取出来料箱信息
List<String> boxStrList = barcodeList.stream().filter(item -> {
String posName = item.getPosName();
if (posName.startsWith("CS") || posName.startsWith("CM") || posName.startsWith("CB")) {
if (posName.indexOf("-") != -1) {
return true;
}
}
return false;
}).map(item -> {
String posName = item.getPosName();
return posName.substring(0, posName.indexOf("-"));
}).distinct().collect(Collectors.toList());
List<Barcode> pidBarcodeList = barcodeManager.findByQuery(new Query(Criteria.where("barcode").in(boxStrList)));
//开始赋值
for (Barcode barcode : barcodeList) {
List<Barcode> posNameList = pidBarcodeList.stream().filter(item -> {
return barcode.getPosName().startsWith(item.getBarcode());
}).collect(Collectors.toList());
Barcode pidBarcode = (posNameList != null && !posNameList.isEmpty()) ? posNameList.get(0) : null;
ExpireDto dto = new ExpireDto();
BeanUtils.copyProperties(barcode, dto);
dto.setPutInDate(barcode.getPutInDate());
if (dto.getExpireDate() != null) {
long expireDays = ExpireDateUtil.getExpireDays(dto.getExpireDate());
dto.setExpireDays(expireDays);
dto.setRemark(ExpireDateUtil.getReelStatus(expireDays));
} else {
dto.setExpireDays(0);
}
dto.setPlant("W337");
dto.setFactory("B15");
dto.setFloor("1F");
dto.setFirstPutInDate(new Date(barcode.getPutInTime()));
if (StringUtils.isNotBlank(dto.getStorageId())) {
Storage storage = dataCache.getStorageById(dto.getStorageId());
if (storage != null) {
dto.setSource(storage.getName());
}
}
if (pidBarcode != null) {
dto.setPartitionCount(BoxUtil.getPartitionCount(dto.getPosName(),pidBarcode.getSubCodeList()));
dto.setStoragePosName(pidBarcode.getPosName());
}
expireDtoList.add(dto);
}
}
PageData<ExpireDto> pageData = new PageData<>();
pageData.setTotalElements(count);
pageData.setContent(expireDtoList);
return pageData;
}
@ApiOperation("过期报表导出")
@RequestMapping("/expire/download")
@AnonymousAccess
public void expireInfoDownload(ReportQueryCondition queryCondition, Pageable pageable, HttpServletResponse response) throws IOException {
Query query = QueryHelp.getQuery(queryCondition);
Criteria c = Criteria.where("posName").exists(true).ne("").and("partNumber").nin(Arrays.asList("CS", "CM", "CB"));
//判断传入的类型
String expireStatus = queryCondition.getExpireStatus();
Date startDate,endDate;
if ("0".equals(expireStatus)) {
startDate = new Date();
endDate = DateUtil.offsetDay(startDate, 7);
c.and("expireDate").gte(startDate).lt(endDate);
} else if ("1".equals(expireStatus)) {
startDate = DateUtil.offsetDay(new Date(), 7);
endDate = DateUtil.offsetDay(new Date(), 30);
c.and("expireDate").gte(startDate).lt(endDate);
} else if ("2".equals(expireStatus)) {
List<Criteria> orCriList = new ArrayList<>();
orCriList.add(Criteria.where("expireDate").gt(new Date()).and("posName").exists(true).ne("").and("partNumber").nin(Arrays.asList("CS", "CM", "CB")));
orCriList.add(Criteria.where("expireDate").exists(false).and("posName").exists(true).ne("").and("partNumber").nin(Arrays.asList("CS", "CM", "CB")));
c.orOperator(orCriList);
} else if ("3".equals(expireStatus)) {
endDate = new Date();
c.and("expireDate").lt(endDate);
}
query.addCriteria(c);
FileUtil.downloadExcel(query, pageable, response, new IExcelDownLoad() {
@Override
public List<List<String>> getHeader() {
List<List<String>> header = new ArrayList<>();
header.add(Lists.newArrayList("厂别"));
header.add(Lists.newArrayList("厂区"));
header.add(Lists.newArrayList("库别"));
header.add(Lists.newArrayList("楼层"));
header.add(Lists.newArrayList("储位"));
header.add(Lists.newArrayList("隔口码"));
header.add(Lists.newArrayList("隔口数量"));
header.add(Lists.newArrayList("料号"));
header.add(Lists.newArrayList("物料描述"));
header.add(Lists.newArrayList("数量"));
header.add(Lists.newArrayList("LOT"));
header.add(Lists.newArrayList("D/C"));
header.add(Lists.newArrayList("ID NO"));
header.add(Lists.newArrayList("厂商"));
header.add(Lists.newArrayList("厂商代码"));
header.add(Lists.newArrayList("keeper"));
header.add(Lists.newArrayList("过期天数"));
header.add(Lists.newArrayList("过期日期"));
header.add(Lists.newArrayList("工号"));
header.add(Lists.newArrayList("首次入库时间"));
header.add(Lists.newArrayList("当前入库时间"));
header.add(Lists.newArrayList("来源"));
header.add(Lists.newArrayList("物料状态"));
return header;
}
@Override
public List<List<Object>> getPageData(Query query, Pageable pageable) {
List<List<Object>> resultList = new ArrayList<>();
List<Barcode> barcodeList = barcodeManager.findByQuery(query, pageable);
if (barcodeList != null && !barcodeList.isEmpty()) {
//提取出来料箱信息
List<String> boxStrList = barcodeList.stream().filter(item -> {
String posName = item.getPosName();
if (posName.startsWith("CS") || posName.startsWith("CM") || posName.startsWith("CB")) {
if (posName.indexOf("-") != -1) {
return true;
}
}
return false;
}).map(item -> {
String posName = item.getPosName();
return posName.substring(0, posName.indexOf("-"));
}).distinct().collect(Collectors.toList());
List<Barcode> pidBarcodeList = barcodeManager.findByQuery(new Query(Criteria.where("barcode").in(boxStrList)));
for (Barcode barcode : barcodeList) {
List<Barcode> posNameList = pidBarcodeList.stream().filter(item -> {
return barcode.getPosName().startsWith(item.getBarcode());
}).collect(Collectors.toList());
Barcode pidBarcode = (posNameList != null && !posNameList.isEmpty()) ? posNameList.get(0) : null;
ExpireDto dto = new ExpireDto();
List<Object> data = new ArrayList<>();
BeanUtils.copyProperties(barcode, dto);
dto.setPutInDate(barcode.getPutInDate());
if (dto.getExpireDate() != null) {
long expireDays = ExpireDateUtil.getExpireDays(dto.getExpireDate());
dto.setExpireDays(expireDays);
dto.setRemark(ExpireDateUtil.getReelStatus(expireDays));
} else {
dto.setExpireDays(0);
dto.setRemark("");
}
dto.setPlant("W337");
dto.setFactory("B15");
dto.setFloor("1F");
dto.setFirstPutInDate(new Date(barcode.getPutInTime()));
if (StringUtils.isNotBlank(dto.getStorageId())) {
Storage storage = dataCache.getStorageById(dto.getStorageId());
if (storage != null) {
dto.setSource(storage.getName());
}
}
if (pidBarcode != null) {
dto.setPartitionCount(BoxUtil.getPartitionCount(dto.getPosName(), pidBarcode.getSubCodeList()));
dto.setStoragePosName(pidBarcode.getPosName());
}
data.add(dto.getPlant());
data.add(dto.getFactory());
data.add(dto.getWarehouseCode());
data.add(dto.getFloor());
data.add(dto.getStoragePosName());
data.add(dto.getPosName());
data.add(dto.getPartitionCount());
data.add(dto.getPartNumber());
data.add(dto.getDescribe());
data.add(dto.getAmount());
data.add(dto.getBatch());
data.add(dto.getDateCode());
data.add(dto.getBarcode());
data.add(dto.getProvider());
data.add(dto.getProviderNumber());
data.add(dto.getKeeperCode());
data.add(dto.getExpireDays());
data.add(dto.getExpireDate());
data.add(dto.getCreator());
data.add(dto.getFirstPutInDate());
data.add(dto.getPutInDate());
data.add(dto.getSource());
data.add(dto.getRemark());
resultList.add(data);
}
}
return resultList;
}
});
}
private List<LiteOrderItem> getLackItems(Collection<LiteOrder> liteOrders, ReportQueryCondition queryCondition) {
List<LiteOrderItem> items = new ArrayList<>();
//开始比较库存
List<String> storageIds = new ArrayList<>();
for (Storage storage : dataCache.getAllStorage().values()) {
storageIds.add(storage.getId());
}
Map<String, InventoryItem> inventory = dataCache.getAllInventory(storageIds, "");
for (LiteOrder liteOrder : liteOrders) {
List<LiteOrderItem> orderItems = liteOrder.getOrderItems();
if (orderItems != null && !orderItems.isEmpty()) {
if (!liteOrder.isClosed() && liteOrder.isConfirmExcess() && !liteOrder.isOutTails()) {
for (LiteOrderItem orderItem : orderItems) {
orderItem.setExcess(liteOrder.isExcess());
String pn = orderItem.getPn();
//判断料号是否存在
if (StringUtils.isNotBlank(queryCondition.getPn())) {
if (!queryCondition.getPn().equals(pn)) {
continue;
}
}
//判断库别是否存在
if (StringUtils.isNotBlank(queryCondition.getWarehouseCode())) {
if (!queryCondition.getWarehouseCode().equals(orderItem.getWarehouseCode())) {
continue;
}
}
//判断楼层是否存在
if (StringUtils.isNotBlank(queryCondition.getLine())) {
if (!queryCondition.getLine().equals(orderItem.getLine())) {
continue;
}
}
//判断工单号是否存在
if (StringUtils.isNotBlank(queryCondition.getOrderNo())) {
if (!queryCondition.getOrderNo().equals(orderItem.getOrderNo())) {
continue;
}
}
if (StringUtils.isNotBlank(queryCondition.getMo())) {
if (!queryCondition.getMo().equals(orderItem.getMo())) {
continue;
}
}
//1 先判断是否有库存
InventoryItem inventoryItem = inventory.get(pn);
if (inventoryItem == null) {
inventoryItem = new InventoryItem();
}
//2 计算每一个partNumber的数量
int pnAmount = 0;
if (partNumberAmount.get(pn) == null) {
pnAmount = getAmountByPartNumber(pn);
partNumberAmount.put(pn, pnAmount);
} else {
pnAmount = partNumberAmount.get(pn);
}
if (pnAmount == 0 || !liteOrder.isExcess()) {
orderItem.setLackNum(orderItem.getNeedNum() - orderItem.getTotalOutNum());
orderItem.setLackReel(orderItem.getNeedReelCount() - orderItem.getTotalOutReelCount());
if (orderItem.getLackNum() > 0 || orderItem.getLackReel() > 0) {
items.add(orderItem);
}
continue;
}
//判断是不是超发情况
if (liteOrder.isExcess()) {
boolean isLack = false;
//先判断是否满足盘数
int needReelCount = orderItem.getNeedReelCount() - orderItem.getOutReelCount();
if (needReelCount >= 0) {
int avaiReel = inventoryItem.getStockReel() - inventoryItem.getLockReel() - inventoryItem.getBindReel(); //可用盘数
avaiReel = avaiReel < 0 ? 0 : avaiReel;
if (avaiReel - needReelCount < 0) {
isLack = true;
orderItem.setLackReel(needReelCount - avaiReel);
}
inventoryItem.setBindReel(needReelCount);
inventory.put(pn, inventoryItem);
}
//再判断是否满足数量
int needNum = orderItem.getNeedNum() - orderItem.getOutNum();
if (needNum > 0) {
int needNumReel = (int) Math.ceil(needNum / pnAmount);
needNumReel = needNumReel == 0 ? needNumReel + 1 : needNumReel;
int avaiReel = inventoryItem.getStockReel() - inventoryItem.getLockReel() - inventoryItem.getBindReel(); //可用盘数
if (needNumReel - avaiReel > 0) {
isLack = true;
orderItem.setLackNum(needNum - avaiReel * pnAmount);
}
inventoryItem.setBindReel(needNumReel);
inventory.put(pn, inventoryItem);
}
if (isLack){
items.add(orderItem);
}
}
}
}
}
}
return items;
}
public int getAmountByPartNumber(String partNumber) {
Query query = new Query();
query.addCriteria(Criteria.where("partNumber").is(partNumber));
query.with(Sort.by(Sort.Direction.ASC, "amount"));
Barcode barcode = barcodeManager.findOne(query);
if (barcode != null) {
return barcode.getAmount();
}
return 0;
}
private Object getData(Object data) {
return data == null ? "" : data;
}
}
......@@ -31,7 +31,7 @@ public class StationStatusCache {
private static Map<String, String> stationStatusMap = Maps.newConcurrentMap();
@PostConstruct
/*@PostConstruct
public void init() {
try {
List<StationStatus> statusList = maiZhengApi.StationStatus();
......@@ -50,7 +50,7 @@ public class StationStatusCache {
} catch (Exception e) {
e.printStackTrace();
}
}
}*/
public void updateStatusList(List<StationStatus> statusList) {
stationStatusMap.clear();
......
api:
plantCode: W339
name: Lizhen
inCheckUrl: http://10.190.25.124:8001/Npm/WmsCheckReelfob #禁用料接口
outNotifyUrl: http://10.68.30.22:8082/api/mlb/TowerIssue
inNotifyUrl: http://10.68.30.22:8082/api/mlb/BackToWarehouse
\ No newline at end of file
api:
plantCode: W339
name: Lizhen
inCheckUrl: http://10.190.25.124:8001/Npm/WmsCheckReelfob #禁用料接口
outNotifyUrl: http://10.42.220.171:8082/api/mlb/TowerIssue
inNotifyUrl: http://10.42.220.171:8082/api/mlb/BackToWarehouse
\ No newline at end of file
......@@ -3,45 +3,45 @@ server:
api:
name: Lizhen
inCheckUrl: #http://10.190.25.124:8001/Npm/WmsCheckReelfob #禁用料
batchCheckUrl: #http://172.30.60.117:8001/Npm/WmsCheckReelfob_Batch #批量禁用料
outNotifyUrl: #http://172.30.170.148:8082/SmtAutoWH/Save2DReelInfo #保存物料(外仓配置)
outNotifyUrlPK: #http://172.30.170.148:8001/Sct/SaveReelInfo #PK发料保存(外仓配置)
inNotifyUrl: #http://10.190.25.124:8082/SmtAutoWH/Save2DReelInfo #保存物料(内仓配置)
fetchOrderUrl: #http://172.30.170.148:8082/SmtAutoWH/GetWoPickingList #获取工单
barcodeInfoUrl: #http://10.190.25.124:8001/Sct/GetReelInfo #mes数量
fetchGRUrl: #http://10.42.25.199:8082/api/wcs/fetchGR #gr标签
brandQtyUrl: #http://172.30.170.199:8082/api/wcs/brandQty #gr标签满卷数
importUrl: #http://10.42.222.52:8001/smf-core/ext/forward/getDataLogs #内仓导入外仓picking虚拟仓数据
checkReelMeasure: #http://10.190.25.124:8001/Sct/CheckReelMeasure #散料量测接口
plant: 2810
werks: 2810
inCheckUrl:
batchCheckUrl:
outNotifyUrl:
outNotifyUrlPK:
inNotifyUrl:
fetchOrderUrl:
barcodeInfoUrl:
fetchGRUrl:
brandQtyUrl:
importUrl:
checkReelMeasure:
plant:
werks:
outerFactory:
bc:
plant: 2810
factory: B3
plant:
factory:
#缺料预警对应的地址
lizhen:
F2:
name: 2F
line: A05-2FSMT-16S,A05-2FSMT-17S,A05-2FSMT-06S,A05-2FSMT-07S
url: http://172.30.88.19:8001/smf-core/api/Mes/machineCallMaterial
name:
line:
url:
F3:
name: 3F
line: A05-3FSMT-04S,A05-3FSMT-14S,A05-3FSMT-15S,A05-3FSMT-05S
url: http://172.30.97.99:8001/smf-core/api/Mes/machineCallMaterial
line:
url: http://10.68.27.85/smf-core/wcs/ReelWarningInfo
F5:
name: 5F
line: A05-5FSMT-13S,A05-5FSMT-03S,A05-5FSMT-02S,A05-5FSMT-12S #,A05-5FARF-06,A05-5FSMT-01S,A05-5FSMT-11S
url: http://172.30.97.63:8001/smf-core/api/Mes/machineCallMaterial
name:
line:
url:
F4:
name: 4F
line: B03-4FSMT-11,B03-4FSMT-01,B03-4FSMT-13,B03-4FSMT-03,B03-4FSMT-14,B03-4FSMT-04
url: http://172.25.252.12:8001/smf-core/api/Mes/machineCallMaterial
name:
line:
url:
#转发地址
......@@ -80,6 +80,7 @@ spring:
check-template-location: false
profiles:
active: 'prod'
include: 21088test
jackson:
time-zone: GMT+8
data:
......
支持 Markdown 格式
你添加了 0 到此讨论。请谨慎行事。
Finish editing this message first!