Commit 97b4d19f zshaohui

1.盘点功能提交

1 个父辈 f85456ab
正在显示 28 个修改的文件 包含 1018 行增加62 行删除
......@@ -559,7 +559,7 @@ public class BarcodeRule {
if(batch_item.hasThisField()){
String batch = batch_item.getStrValue(codeArr);
if (batch.indexOf("-") != -1){
batch = batch.substring(0,batch.indexOf("-"));
batch = batch.substring(0,batch.lastIndexOf("-"));
}
b.setBatch(batch);
}
......@@ -613,7 +613,7 @@ public class BarcodeRule {
if (dateCode_item.hasThisField()){
String dateCode = dateCode_item.getStrValue(codeArr);
if (dateCode.indexOf("-") != -1){
dateCode = dateCode.substring(dateCode.indexOf("-")+1,dateCode.length());
dateCode = dateCode.substring(dateCode.lastIndexOf("-")+1);
}
b.setDateCode(dateCode);
}
......@@ -621,7 +621,7 @@ public class BarcodeRule {
if (providerNumber_item.hasThisField()){
String providerNumber = providerNumber_item.getStrValue(codeArr);
if (providerNumber.indexOf("-") != -1){
providerNumber = providerNumber.substring(providerNumber.lastIndexOf("-")+1,providerNumber.length());
providerNumber = providerNumber.substring(providerNumber.lastIndexOf("-")+1);
}
b.setProviderNumber(providerNumber);
}
......@@ -858,8 +858,8 @@ public class BarcodeRule {
codeStr = "=1x1=806-33328-1000015|220812A-220812|6000|M8010000153322U50F|EVERWIN";
rule = "RI[0:6:2]PN[-1:2:-1]";
codeStr = "CS0001-1";
rule = "RI[-1:6:-1]PN[-1:2:-1]";
codeStr = "353S03035-620140|F10-9FHLF6-2302|15000|M35620140022302AF|QORVO|";
rule = "PN[-1:50:-1]PROVIDERNUMBER[-1:50:-1]|BATCH[-1:50:-1]DATECODE[-1:50:-1]|QTY|RI|SP|6";
BarcodeRule br = BarcodeRule.newRule(rule);
Barcode b = br.toCodeBean(codeStr).getBarcode();
......
......@@ -36,10 +36,12 @@ import com.neotel.smfcore.core.storage.service.po.Storage;
import io.swagger.annotations.Api;
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.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.beans.Beans;
import java.util.*;
......@@ -131,13 +133,18 @@ public class DeviceController {
lineMsg = "";
log.info("流水线[" + cids + "]获取[" + rfid + "][" + code + "]的入库库位");
//判断锁定库位,是否超过5分钟,如果超过,则解绑
/*Collection<ReelLockPosInfo> allReelLockPosInfo = ReelLockPosUtil.getAllReelLockPosInfo();
//判断锁定库位,是否超过1小时,如果超过,则解绑
Collection<ReelLockPosInfo> copyList = new ArrayList<>();
Collection<ReelLockPosInfo> allReelLockPosInfo = ReelLockPosUtil.getAllReelLockPosInfo();
for (ReelLockPosInfo lockPosInfo : allReelLockPosInfo) {
if (new Date().getTime() - lockPosInfo.getCreateDate().getTime() >= 1000 * 60 * 5) {
copyList.add(lockPosInfo);
}
for (ReelLockPosInfo lockPosInfo : copyList) {
if (System.currentTimeMillis() - lockPosInfo.getCreateDate().getTime() >= 1000 * 60 * 60) {
ReelLockPosUtil.removeReelLockPosInfo(lockPosInfo.getBarcode());
}
}*/
}
Map<String, Object> resultMap = Maps.newHashMap();
......
......@@ -306,10 +306,11 @@ public class OrderController {
PageData<OrderDto> resultList = orderMapper.toDto(orderList);
return resultList;
} else {
Query query = QueryHelp.getQuery(criteria);
PageData<OrderDto> resultList = new PageData<>();
resultList.setContent(new ArrayList<>());
resultList.setTotalElements(0);
LiteOrderItem item = liteOrderItemManager.findOne(new Query(Criteria.where("warningItemId").is(criteria.getWarningItemId())));
LiteOrderItem item = liteOrderItemManager.findOne(query);
if (item != null){
String orderId = item.getOrderId();
LiteOrder liteOrder = liteOrderManager.get(orderId);
......
......@@ -119,4 +119,7 @@ public class OrderItemDto {
@ApiModelProperty("缺料预警ID")
private String warningItemId;
@ApiModelProperty("缺料预警物料")
private String reel;
}
......@@ -26,6 +26,7 @@ public class OrderQueryCondition {
private Integer status;
//缺料预警id
@QueryCondition(blurry = "warningItemId,reel")
private String warningItemId;
//
// @QueryCondition(type=QueryCondition.Type.IN,propName = "status")
......
......@@ -191,6 +191,12 @@ public class LiteOrderItem extends BasePo implements Serializable ,Comparable<Li
* 厂区
*/
private String factory;
/**
* 物料信息
*/
private String reel;
/**
* 出库是否满足要求,已出库数量大于需求数量
*/
......
......@@ -78,5 +78,6 @@ public class StoragePosDto implements Serializable {
@ApiModelProperty("组名称")
private String groupName = "";
@ApiModelProperty("盘点状态")
private String inventoryStatus = "";
}
......@@ -82,4 +82,6 @@ public interface IStoragePosManager extends IBaseManager<StoragePos> {
List<StoragePos> findNotEmptyPosName();
StoragePos getPosNameByPnAndStrId(String partNumber,String storageId);
int countByQuery(Query query);
}
......@@ -783,4 +783,9 @@ public class StoragePosManagerImpl implements IStoragePosManager {
public StoragePos getPosNameByPnAndStrId(String partNumber,String storageId) {
return storagePosDao.findOne(new Query(Criteria.where("partNumber").is(partNumber).and("storageId").is(storageId)));
}
@Override
public int countByQuery(Query query) {
return storagePosDao.countByQuery(query);
}
}
......@@ -132,6 +132,11 @@ public class StoragePos extends BasePo implements Serializable {
*/
private String msg;
/**
* 盘点状态
*/
private String inventoryStatus = "";
public String getLabelStr(){
String posNameLabel = posName;
int index = posNameLabel.lastIndexOf(":");
......
......@@ -207,6 +207,7 @@ public class LizhenController {
item.setLine(data.get("LINE"));
item.setItemId(data.get("ID"));
item.setPriority(Integer.valueOf(data.get("PRIORITY")));
item.setReel(data.get("REEL"));
PreWarningItemCache.addItems(Arrays.asList(item));
return ResultBean.newOkResult("");
}
......
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 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 Long inventoryBatch;
/**
* 盘点的barcode集合
*/
private List<Barcode> barcodeList;
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<>();
}
package com.neotel.smfcore.custom.lizhen.agvBox.bean.dto;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@Data
public class InventoryDto {
@ApiModelProperty("箱子尺寸")
private int platsize;
@ApiModelProperty("提示信息")
private String msg;
@ApiModelProperty("当前箱子号")
private String currentRfid;
@ApiModelProperty("pn和数量")
private List<Map<String, Integer>> pnCountList = new ArrayList<>();
}
package com.neotel.smfcore.custom.lizhen.agvBox.bean.enums;
/**
* 盘点出库状态
*/
public enum InventoryStatus {
/**
* 新建
*/
NEW,
/**
* 正在执行中
*/
EXECUTING,
/**
* 完成
*/
FINISHED
}
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.QueryHelp;
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.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;
......@@ -15,23 +23,35 @@ 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.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.dto.InventoryDto;
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.agvBox.util.StationCacheUtil;
import com.neotel.smfcore.custom.lizhen.innerBox.enums.ExtendType;
import com.neotel.smfcore.security.annotation.AnonymousAccess;
import com.sun.org.apache.regexp.internal.RE;
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.RestController;
import javax.swing.*;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
/**
* 盘点
*/
@Slf4j
@RestController
@RequestMapping("/inventory")
public class InventoryController {
......@@ -51,14 +71,110 @@ public class InventoryController {
@Autowired
private TaskService taskService;
@Autowired
private InventoryDataManager inventoryDataManager;
@Autowired
private CodeResolve codeResolve;
/**
* 盘点数据key
*/
private static final String INVENTORY_DATA = "barcode.inventory.data";
/**
* 获取盘点信息
*
* @return
*/
@RequestMapping("/getInventoryInfo")
@AnonymousAccess
public ResultBean getInventoryInfo() {
Map<String, Object> resultMap = new HashMap<>();
int inventoryCount = 0;
int count = storagePosManager.countByQuery(new Query());
Long inventoryBatch = dataCache.getCache(INVENTORY_DATA);
if (inventoryBatch != null) {
inventoryCount = inventoryDataManager.countByQuery(new Query(Criteria.where("inventoryBatch").is(inventoryBatch).and("status").is(InventoryStatus.FINISHED.name())));
}
resultMap.put("inventoryCount", inventoryCount);
resultMap.put("count", count);
return ResultBean.newOkResult(resultMap);
}
/**
* 开始盘点
*
* @return
*/
@RequestMapping("/inventoryStart")
@AnonymousAccess
public ResultBean inventoryStart() {
Long inventoryBatch = dataCache.getCache(INVENTORY_DATA);
if (inventoryBatch == null) {
inventoryBatch = System.currentTimeMillis();
dataCache.updateCache(INVENTORY_DATA, inventoryBatch);
}
return ResultBean.newOkResult("盘点批次为:" + inventoryBatch);
}
/**
* 结束盘点
*
* @param type 默认是0,强制是1
* @return
*/
@RequestMapping("/inventoryEnd")
@AnonymousAccess
public ResultBean inventoryEnd(int type) {
Long inventoryBatch = dataCache.getCache(INVENTORY_DATA);
if (inventoryBatch == null) {
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, null);
return ResultBean.newOkResult("");
}
/**
* 获取盘点数据
* 获取料箱信息
*
* @return
*/
@RequestMapping("/getInventoryData")
@RequestMapping("/getStoragePosData")
@AnonymousAccess
public Map<String, List<StoragePosDto>> getInventoryData() {
public Map<String, List<StoragePosDto>> getStoragePosData(String posName) {
Map<String, List<StoragePosDto>> resultMap = new HashMap<>();
List<Storage> storageList = new ArrayList<>();
for (Storage storage : dataCache.getAllStorage().values()) {
......@@ -66,9 +182,28 @@ public class InventoryController {
storageList.add(storage);
}
}
Long inventoryBatch = dataCache.getCache(INVENTORY_DATA);
//获取所有库位信息
for (Storage storage : storageList) {
List<StoragePos> storagePosList = storagePosManager.findByQuery(inventoryQuery(storage.getId(), null));
List<StoragePos> storagePosList = storagePosManager.findByQuery(inventoryQuery(posName, storage.getId(), null));
if (inventoryBatch != null) {
for (StoragePos pos : storagePosList) {
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());
}
}
}
}
resultMap.put(storage.getName(), storagePosMapper.toDto(storagePosList));
}
return resultMap;
......@@ -88,7 +223,7 @@ public class InventoryController {
return ResultBean.newErrorResult(-1, "smfcore.valueCanotNull", "{0}不能为空", new String[]{"ID"});
}
if (storagePosIdList != null && !storagePosIdList.isEmpty()) {
List<StoragePos> storagePosList = storagePosManager.findByQuery(inventoryQuery(null, storagePosIdList));
List<StoragePos> storagePosList = storagePosManager.findByQuery(inventoryQuery(null, null, storagePosIdList));
if (storagePosList == null || storagePosList.isEmpty()) {
return ResultBean.newErrorResult(-1, "smfcore.label.noReel", "未找到可出库的物料");
}
......@@ -97,13 +232,15 @@ public class InventoryController {
if (barcode != null) {
Storage storage = dataCache.getStorageById(pos.getStorageId());
barcode.setInventory(true);
barcodeManager.save(barcode);
barcode = barcodeManager.save(barcode);
//生成出库任务
DataLog dataLog = new DataLog(storage, barcode, pos);
dataLog.setType(OP.CHECKOUT);
dataLog.setCreator(SecurityUtils.getCurrentUsername());
//dataLog.setCreator(SecurityUtils.getCurrentUsername());
dataLog.setExtendType(ExtendType.INVENTORY_CHECKOUT); //盘点出库
taskService.updateQueueTask(dataLog);
taskService.addTaskToExecute(dataLog);
//生成盘点数据
generateInventoryData(barcode, pos);
}
}
}
......@@ -112,15 +249,15 @@ public class InventoryController {
/**
* 获取工位上料箱信息
* 料箱信息
*
* @param name
* @return
*/
@RequestMapping("/getInventoryBoxInfo")
@RequestMapping("/inventoryBoxInfo")
@AnonymousAccess
public ResultBean getInventoryBoxInfo(String name) {
//判断工位信息是否为空
public ResultBean inventoryBoxInfo(String name) {
//根据名称获取当前工位上的箱子
Station station = StationCacheUtil.getStation(name);
if (station == null) {
return ResultBean.newErrorResult(-1, "", name + "工位信息未上传成功,请重试", new String[]{});
......@@ -130,28 +267,307 @@ public class InventoryController {
if (StringUtils.isBlank(currentRfid)) {
return ResultBean.newErrorResult(-1, "", name + "当前工位料箱信息未上传成功,请重试", new String[]{});
}
//返回结果
String boxStr = currentRfid.substring(0, currentRfid.length() - 1);
InventoryDto dto = new InventoryDto();
dto.setCurrentRfid(currentRfid);
dto.setPlatsize(currentRfid.startsWith("CS") ? 7 : 15);
//获取料箱信息
String boxStr = BoxUtil.getBoxStr(currentRfid);
//查找barcode
Barcode barcode = barcodeManager.findByBarcode(boxStr);
//
List<PartitionInfo> partitionInfoList = BoxUtil.getPartitionInfo(currentRfid, barcode);
//盘点批次
Long inventoryBatch = dataCache.getCache(INVENTORY_DATA);
if(inventoryBatch == null) {
inventoryBatch = -1l;
}
//获取需要盘点的信息
List<InventoryData> dataList = inventoryDataManager.findByQuery(new Query(Criteria.where("inventoryBatch").is(inventoryBatch).and("box").is(boxStr)));
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())) {
item.setInventory(true);
item.setInventoryReelCount(inventoryData.getInventoryReelCount());
item.setInventoryAmount(inventoryData.getInventoryAmout());
item.setBarcodeList(inventoryData.getBarcodeList());
}
return item;
}).collect(Collectors.toList());
}
}
}
return ResultBean.newOkResult(partitionInfoList);
}
return ResultBean.newOkResult(dto);
/**
* 料盘开始盘点
*
* @param paramMap
* @return
*/
@RequestMapping("/inventoryReel")
@AnonymousAccess
public ResultBean inventoryReel(@RequestBody Map<String, String> paramMap) {
String name = paramMap.get("name");
String bacodeStr = paramMap.get("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);
StoragePos pos = taskService.findEmptyPosForPutIn(storageList, boxBarcode, "", "");
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("");
}
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());
taskService.addTaskToExecute(task);
}
private Query inventoryQuery(String storageId, List<String> storageIdList) {
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 + "不一致";
}
//开始查询盘点数据
//盘点批次
Long inventoryBatch = dataCache.getCache(INVENTORY_DATA);
if(inventoryBatch == null) {
inventoryBatch = -1l;
}
InventoryData data = inventoryDataManager.findOne(new Query(Criteria.where("inventoryBatch").is(inventoryBatch).and("boxPartition").is(posName)));
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.setInventoryReelCount(data.getInventoryReelCount() + 1);
data.setInventoryAmout(data.getInventoryAmout() + barcode.getAmount());
data.updateBarcodeList(barcode);
//判断是否完成
if (data.getReelCount() == data.getInventoryReelCount() && data.getInventoryAmout() == data.getAmout()) {
data.setStatus(InventoryStatus.FINISHED.name());
data.setMatch(true);
} else {
data.setStatus(InventoryStatus.EXECUTING.name());
}
inventoryDataManager.save(data);
return errorMsg;
}
/**
* 生成盘点数据
*
* @param barcode
* @param pos
*/
private void generateInventoryData(Barcode barcode, StoragePos pos) {
//判断盘点批次是否存在
Long inventoryBatch = dataCache.getCache(INVENTORY_DATA);
if (inventoryBatch == null) {
inventoryBatch = System.currentTimeMillis();
dataCache.updateCache(INVENTORY_DATA, inventoryBatch);
}
//开始处理数据
List<Barcode> subCodeList = barcode.getSubCodeList();
if (subCodeList != null && !subCodeList.isEmpty()) {
InventoryData data = new InventoryData();
//料箱号
data.setBox(barcode.getBarcode());
//隔口码
String partition = getInventoryPartition(subCodeList);
data.setBoxPartition(partition);
//料号
String partNumber = BoxUtil.getPartitionPartNumber(partition, subCodeList);
data.setPartNumber(partNumber);
//物料描述
data.setDescribe("");
//储位
data.setPosName(pos.getPosName());
//卷数
int partitionCount = BoxUtil.getPartitionCount(partition, subCodeList);
data.setReelCount(partitionCount);
//数量
int partitionNum = BoxUtil.getPartitionNum(partition, subCodeList);
data.setAmout(partitionNum);
//创建人
//data.setCreator(SecurityUtils.getCurrentUsername());
//盘点批次
data.setInventoryBatch(inventoryBatch);
inventoryDataManager.save(data);
}
}
/**
* 随机获取一个隔扣码进行返回
*
* @param subCodeList
* @return
*/
private String getInventoryPartition(List<Barcode> subCodeList) {
int index = new Random().nextInt(subCodeList.size());
return subCodeList.get(index).getPosName();
}
private Query inventoryQuery(String posName, String storageId, List<String> storagePosIdList) {
Query query = new Query();
if (storageIdList != null && !storageIdList.isEmpty()) {
query.addCriteria(Criteria.where("id").in(storageIdList));
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));
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.barcode", "barcode.amount", "barcode.posName", "barcode.reelAmount", "updateDate");
//query.fields().include("barcode", "updateDate", "storageId","posName");
return query;
}
}
......@@ -25,6 +25,7 @@ import com.neotel.smfcore.custom.lizhen.LizhenApi;
import com.neotel.smfcore.custom.lizhen.agvBox.bean.Station;
import com.neotel.smfcore.custom.lizhen.agvBox.enums.CHANGE_TYPE;
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.agvBox.util.StationCacheUtil;
import com.neotel.smfcore.security.annotation.AnonymousAccess;
import com.sun.org.apache.regexp.internal.RE;
......@@ -309,6 +310,13 @@ public class OutLineController {
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 = barcodeManager.save(boxBarcode);
//如果不是虚拟仓的
if (!isVirtual) {
StoragePos pos = taskService.findEmptyPosForPutIn(storageList, boxBarcode, "", "");
......
......@@ -27,6 +27,7 @@ import com.neotel.smfcore.custom.lizhen.agvBox.bean.Station;
import com.neotel.smfcore.custom.lizhen.agvBox.enums.CHANGE_TYPE;
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.security.annotation.AnonymousAccess;
import io.swagger.annotations.ApiOperation;
......@@ -498,6 +499,14 @@ public class WarehouseController {
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()) {
......
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.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.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.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.util;
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 (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) {
int num = subCodeList.stream().filter(item -> partition.equals(item.getPosName())).mapToInt(Barcode::getAmount).sum();
return num;
}
/**
* 获取隔口料号
*
* @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) {
int partitionCount = (int) subCodeList.stream().filter(item -> partition.equals(item.getPosName())).count();
return partitionCount;
}
/**
* 获取隔口的信息
*
* @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")) {
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")) {
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) {
Long inventoryBatch = dataCache.getCache(INVENTORY_DATA);
if (inventoryBatch == null) {
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;
}
}
......@@ -28,6 +28,7 @@ public class PreWarningItem extends BasePo {
private String subslot;
private String partnumber;
private String itemId;
private String reel;
/**
* 优先级,1:人工 0:机器
......
......@@ -53,4 +53,9 @@ public class ExtendType {
* 盘点出库
*/
public final static int INVENTORY_CHECKOUT = 9;
/**
* 盘点入库
*/
public final static int INVENTORY_PUTIN = 9;
}
......@@ -139,6 +139,7 @@ public class PreWarningItemCache {
orderItem.setOrderNo(liteOrder.getOrderNo());
orderItem.setPriority(item.getPriority());
orderItem.setMachineName(item.getMachinename());
orderItem.setReel(item.getReel());
orderItems.add(orderItem);
}
}
......
......@@ -43,9 +43,11 @@ public class AgvStatusCache {
AgvInfo agvInfo = infoList.get(0);
boolean hasAgvInfo = false;
if (agvInfoCacheList != null && !agvInfoCacheList.isEmpty()) {
for (AgvInfo info : agvInfoCacheList) {
for (int i = 0; i < agvInfoCacheList.size(); i++) {
AgvInfo info = agvInfoCacheList.get(i);
if (info.getName().equals(agvInfo.getName())) {
info = agvInfo;
agvInfoCacheList.remove(i);
agvInfoCacheList.add(i,agvInfo);
hasAgvInfo = true;
}
}
......
......@@ -26,6 +26,8 @@ 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.service.manager.InventoryDataManager;
import com.neotel.smfcore.custom.lizhen.report.bean.dto.InventoryDto;
import com.neotel.smfcore.custom.lizhen.report.bean.query.ReportQueryCondition;
import com.neotel.smfcore.security.annotation.AnonymousAccess;
......@@ -85,6 +87,9 @@ public class OuterReportController {
@Autowired
private BarcodeMapper barcodeMapper;
@Autowired
private InventoryDataManager inventoryDataManager;
@Value("${api.plant}")
private String plant; //厂别
......@@ -703,6 +708,58 @@ public class OuterReportController {
}
}
@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.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("盘点状态", data.getStatus());
map.put("盘点批次", data.getInventoryBatch());
results.add(map);
}
try {
FileUtil.downloadExcel(results,response);
} catch (IOException e) {
e.printStackTrace();
log.error("盘点报表导出失败");
}
}
}
private List<LiteOrderItem> getLackItems(Collection<LiteOrder> liteOrders, ReportQueryCondition queryCondition) {
List<LiteOrderItem> items = new ArrayList<>();
//开始比较库存
......
支持 Markdown 格式
你添加了 0 到此讨论。请谨慎行事。
Finish editing this message first!