Commit 102dbabe LN

单盘入库功能

1 个父辈 4b0cdeb3
......@@ -49,71 +49,71 @@ public class NLPShelfHandler extends BaseDeviceHandler{
super(apiList);
}
/**
* 扫码
*/
@ApiOperation("扫码入库")
@PostMapping("/api/sensorShelf/codeIn")
@PreAuthorize("@el.check('sensorShelf:putIn')")
public ResultBean codeIn( @RequestBody Map<String, String> mapValues,HttpServletRequest request) {
String code = mapValues.get("code");
String groupId = mapValues.get("group");
String storageId=mapValues.get("storageId");
String sourceId=mapValues.get("sourceId");
String token = tokenProvider.getToken(request);
if(ObjectUtils.isEmpty(code)){
throw new ValidateException("smfcore.valueCanotNull", "{0}不能为空", new String[]{"code"});
}
if(groupId==null&&storageId==null){
throw new ValidateException("smfcore.valueCanotNull", "{0}不能为空", new String[]{"group"});
}
if(groupId==null&&storageId!=null){
Storage storage=dataCache.getStorageById(storageId);
if(storage!=null){
groupId=storage.getGroupId();
}
}
if(groupId!=null&&groupId.equals("-1")){
groupId="";
}
// WebSocketServer.sendMsg("", new SocketMsg("{0}未找到库位:{1}"+code, MsgType.INFO,"smfclient.nlp.cannotFindPos",new String[]{"消息测试","库位号"}));
String loginUser = SecurityUtils.getLoginUsername();
Collection<DataLog> queueTasks = taskService.getQueueTasks();
ResultBean resultBean = null;
for (DataLog queueTask : queueTasks) {
if (queueTask.isPutInTask() && queueTask.isWait()) {
if (!Strings.isNullOrEmpty(groupId) && queueTask.getGroupId().equals(groupId)) {
log.info("codeIn [" + code + "][" + groupId + "]入库失败:条码[" + queueTask.getBarcode() + "]的任务还未结束 ");
throw new ValidateException("smfcore.unfinished", "the task of [{0}] is unfinished", new String[]{queueTask.getBarcode()});
}
if (!Strings.isNullOrEmpty(storageId) && queueTask.getStorageId().equals(storageId)) {
log.info("codeIn [" + code + "][" + storageId + "]入库失败:条码[" + queueTask.getBarcode() + "]的任务还未结束 ");
throw new ValidateException("smfcore.unfinished", "the task of [{0}] is unfinished", new String[]{queueTask.getBarcode()});
}
}
}
Barcode barcodeSave = resolveBarcodeFromApiForShelf(new CodeValidateParam( loginUser,groupId,storageId,code,token));
if(barcodeSave == null){
barcodeSave = codeResolve.resolveOneValideBarcode("=1x1="+code);
}
Date expireDate = barcodeSave.getExpireDate();
if (expireDate != null) {
if (System.currentTimeMillis() > expireDate.getTime()) {
throw new ValidateException("smfcore.error.barcode.expired", "物料已过期,无法入库.");
}
}
//从API验证
Barcode verResult = verifyPutInFromApi(barcodeSave);
if(verResult==null){
return testPutIn(loginUser,groupId,storageId, barcodeSave,token);
}
// resultBean = hellaServiceHandler.checkMaterial(loginUser, groupId, code);
return ResultBean.newOkResult("");
}
// /**
// * 扫码
// */
// @ApiOperation("扫码入库")
// @PostMapping("/api/sensorShelf/codeIn")
// @PreAuthorize("@el.check('sensorShelf:putIn')")
// public ResultBean codeIn( @RequestBody Map<String, String> mapValues,HttpServletRequest request) {
// String code = mapValues.get("code");
// String groupId = mapValues.get("group");
// String storageId=mapValues.get("storageId");
// String sourceId=mapValues.get("sourceId");
// String token = tokenProvider.getToken(request);
// if(ObjectUtils.isEmpty(code)){
// throw new ValidateException("smfcore.valueCanotNull", "{0}不能为空", new String[]{"code"});
// }
// if(groupId==null&&storageId==null){
// throw new ValidateException("smfcore.valueCanotNull", "{0}不能为空", new String[]{"group"});
// }
// if(groupId==null&&storageId!=null){
// Storage storage=dataCache.getStorageById(storageId);
// if(storage!=null){
// groupId=storage.getGroupId();
// }
// }
// if(groupId!=null&&groupId.equals("-1")){
// groupId="";
// }
// // WebSocketServer.sendMsg("", new SocketMsg("{0}未找到库位:{1}"+code, MsgType.INFO,"smfclient.nlp.cannotFindPos",new String[]{"消息测试","库位号"}));
// String loginUser = SecurityUtils.getLoginUsername();
// Collection<DataLog> queueTasks = taskService.getQueueTasks();
// ResultBean resultBean = null;
// for (DataLog queueTask : queueTasks) {
// if (queueTask.isPutInTask() && queueTask.isWait()) {
// if (!Strings.isNullOrEmpty(groupId) && queueTask.getGroupId().equals(groupId)) {
// log.info("codeIn [" + code + "][" + groupId + "]入库失败:条码[" + queueTask.getBarcode() + "]的任务还未结束 ");
// throw new ValidateException("smfcore.unfinished", "the task of [{0}] is unfinished", new String[]{queueTask.getBarcode()});
// }
// if (!Strings.isNullOrEmpty(storageId) && queueTask.getStorageId().equals(storageId)) {
// log.info("codeIn [" + code + "][" + storageId + "]入库失败:条码[" + queueTask.getBarcode() + "]的任务还未结束 ");
// throw new ValidateException("smfcore.unfinished", "the task of [{0}] is unfinished", new String[]{queueTask.getBarcode()});
// }
// }
// }
//
// Barcode barcodeSave = resolveBarcodeFromApiForShelf(new CodeValidateParam( loginUser,groupId,storageId,code,token));
// if(barcodeSave == null){
// barcodeSave = codeResolve.resolveOneValideBarcode("=1x1="+code);
// }
//
// Date expireDate = barcodeSave.getExpireDate();
// if (expireDate != null) {
// if (System.currentTimeMillis() > expireDate.getTime()) {
// throw new ValidateException("smfcore.error.barcode.expired", "物料已过期,无法入库.");
// }
// }
//
// //从API验证
// Barcode verResult = verifyPutInFromApi(barcodeSave);
//
// if(verResult==null){
// return testPutIn(loginUser,groupId,storageId, barcodeSave,token);
// }
//// resultBean = hellaServiceHandler.checkMaterial(loginUser, groupId, code);
// return ResultBean.newOkResult("");
// }
private ResultBean testPutIn(String loginUser, String groupId,String storageId,Barcode barcode,String token) {
......
package com.neotel.smfcore.core.hik.bean;
import com.neotel.smfcore.core.order.service.po.LiteOrderItem;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import java.io.Serializable;
@Getter
@Setter
public class ShelfPosInfo implements Serializable ,Comparable<ShelfPosInfo> {
@ApiModelProperty("料架ID")
private String id;
@ApiModelProperty("名称")
private String name;
@ApiModelProperty("料仓CID")
private String cid;
@ApiModelProperty("指定库位的宽度")
private int posWidth;
@ApiModelProperty("指定库位的高度")
private int posHeight;
@ApiModelProperty("指定库位总库位数")
private int posTotalSlots;
@ApiModelProperty("指定库位空库位数")
private int posEmptySlots;
@Override
public int compareTo(ShelfPosInfo o) {
if (this.getPosEmptySlots() != o.getPosEmptySlots()) {
return this.posEmptySlots - o.getPosEmptySlots();
}
return this.getId().compareTo(o.getId());
}
// @ApiModelProperty("总库位数")
// private int totalSlots;
// @ApiModelProperty("空库位数")
// private int emptySlots;
// @ApiModelProperty("使用情况")
// private Map<String, UsageItem> usageMap = new ConcurrentHashMap<>();
}
package com.neotel.smfcore.core.hik.rest;
import cn.hutool.core.util.ObjectUtil;
import com.google.common.base.Strings;
import com.neotel.smfcore.common.bean.ResultBean;
import com.neotel.smfcore.common.exception.ValidateException;
import com.neotel.smfcore.common.utils.Constants;
import com.neotel.smfcore.common.utils.SecurityUtils;
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.hik.bean.ShelfPosInfo;
import com.neotel.smfcore.core.kanban.rest.bean.dto.BoxStatusDto;
import com.neotel.smfcore.core.kanban.rest.bean.dto.GroupStatusDto;
import com.neotel.smfcore.core.storage.bean.UsageItem;
import com.neotel.smfcore.core.storage.service.manager.IStorageManager;
import com.neotel.smfcore.core.storage.service.po.Storage;
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.security.TokenProvider;
import com.neotel.smfcore.security.service.manager.IUserManager;
import com.neotel.smfcore.security.service.po.Group;
import com.neotel.smfcore.security.service.po.User;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.util.*;
@Slf4j
@RestController
@RequiredArgsConstructor
@Api(tags = "HIK单盘入库功能")
@RequestMapping("api/singleIn")
public class SingleInController {
@Autowired
protected CodeResolve codeResolve;
@Autowired
private final IStorageManager storageManager;
@Autowired
private final IBarcodeManager barcodeManager;
@Autowired
private final DataCache dataCache;
@Autowired
private TokenProvider tokenProvider;
@Autowired
protected TaskService taskService;
@Autowired
private final IUserManager userManager;
@ApiOperation("输入二维码后根据尺寸获取料架列表")
@GetMapping("/shelfPosList")
public List<ShelfPosInfo> codeIn(@RequestParam Map<String,String> paramsMap) {
String code = paramsMap.get("code");
if (ObjectUtils.isEmpty(code)) {
throw new ValidateException("smfcore.valueCanotNull", "{0}不能为空", new String[]{"code"});
}
Barcode barcode = resolveBarcode(code);
List<ShelfPosInfo> shelfPosInfos = new ArrayList<>();
int width = barcode.getPlateSize();
int height = barcode.getHeight();
//获取对应尺寸的空位列表
//TODO 增加用户权限判断
String userId = SecurityUtils.getCurrentUserId();
User user = userManager.get(userId);
Set<String> mygroups = user.getGroups();
if(user.getUsername().equals(Constants.SUPER_USERNAME)){
mygroups.add("");
}
for (String groupid : mygroups) {
List<BoxStatusDto> boxStatusDtos = new ArrayList<>();
List<String> cidList =dataCache. getCidsByGroupId(groupid, false);
for (String cid :
cidList) {
Storage storage = dataCache.getStorage(cid);
ShelfPosInfo shelfPosInfo = new ShelfPosInfo();
shelfPosInfo.setId(storage.getId());
shelfPosInfo.setCid(storage.getCid());
shelfPosInfo.setName(storage.getName());
int posTotalCount = 0;
int posUsedCount = 0;
//
for (UsageItem item :
storage.getUsageMap().values()) {
if (item.getH() == height && item.getW() == width) {
posTotalCount += item.getTotalCount();
posUsedCount = item.getUsedCount();
}
}
int emptyCount = posTotalCount - posUsedCount;
shelfPosInfo.setPosHeight(height);
shelfPosInfo.setPosWidth(width);
shelfPosInfo.setPosTotalSlots(posTotalCount);
shelfPosInfo.setPosEmptySlots(emptyCount);
if (emptyCount > 0) {
shelfPosInfos.add(shelfPosInfo);
}
}
}
// List<Storage> storageList = storageManager.findAll();
// for (Storage storage : storageList
// ) {
// }
//根据空位数排序
Collections.sort(shelfPosInfos);
return shelfPosInfos;
}
@ApiOperation("扫码入库")
@PostMapping("/codeIn")
public ResultBean codeIn( @RequestBody Map<String, String> mapValues,HttpServletRequest request) {
//参数:code:条形码,storageId:料架ID,inType:入库类型(1=普通入库,2=并盘入库,3=截料入库,4=退料入库)
String token = tokenProvider.getToken(request);
String code = mapValues.get("code");
String storageId = mapValues.get("storageId");
Integer inType = Integer.parseInt(mapValues.get("inType"));//1=普通入库,2=并盘入库,3=截料入库,4=退料入库
if (ObjectUtils.isEmpty(code)) {
throw new ValidateException("smfcore.valueCanotNull", "{0}不能为空", new String[]{"code"});
}
Storage storage = storageManager.get(storageId);
if (storage == null) {
return ResultBean.newErrorResult(-1, "smfcore.shelfNotExist", "{0}对应的料架不存在", new String[]{storageId});
}
// WebSocketServer.sendMsg("", new SocketMsg("{0}未找到库位:{1}"+code, MsgType.INFO,"smfclient.nlp.cannotFindPos",new String[]{"消息测试","库位号"}));
String loginUser = SecurityUtils.getLoginUsername();
Collection<DataLog> queueTasks = taskService.getQueueTasks();
ResultBean resultBean = null;
for (DataLog queueTask : queueTasks) {
if (queueTask.isPutInTask() && queueTask.isWait()) {
if (!Strings.isNullOrEmpty(storageId) && queueTask.getStorageId().equals(storageId)) {
log.info("codeIn [" + code + "][" + storageId + "]入库失败:条码[" + queueTask.getBarcode() + "]的任务还未结束 ");
throw new ValidateException("smfcore.unfinished", "the task of [{0}] is unfinished", new String[]{queueTask.getBarcode()});
}
}
}
Barcode barcode = resolveBarcode(code);
String pn = barcode.getPartNumber();
String reelId = barcode.getBarcode();
String num = barcode.getAmount() + "";
Integer qty = barcode.getAmount();
String msl = barcode.getMsl();
try {
//需要模拟一个库位
DataLog dataLog = new DataLog();
dataLog.setBarcode(reelId);
dataLog.setPartNumber(pn);
dataLog.setType(OP.PUT_IN);
dataLog.setInType(inType);
barcode.setPutInTime(System.currentTimeMillis());
barcode.updateSluggishTime(dataCache.getPNsluggishDay(barcode.getPartNumber()));
barcodeManager.saveBarcode(barcode);
dataLog.setNum(barcode.getAmount());
dataLog.setStatus(OP_STATUS.WAIT.name());
dataLog.setGroupId(storage.getGroupId());
dataLog.setStorageId(storageId);
dataLog.setMemo(barcode.getMemo());
dataLog.setOperator(loginUser);
if (ObjectUtil.isNotEmpty(storageId)) {
if (storage != null) {
dataLog.setCid(storage.getCid());
dataLog.setStorageName(storage.getName());
}
}
log.info("用户["+loginUser+"]创建料架["+storage.getName()+"]的入库任务:barcode["+barcode.getBarcode()+"],cid["+storage.getCid()+"],inType["+inType+"]");
try {
taskService.addTaskToExecute(dataLog);
} catch (Exception e) {
WebSocketServer.sendMsg(token, new SocketMsg(e.getMessage(), MsgType.INFO, "smfclient.nlp.error", new String[]{e.getMessage()}));
}
} catch (ValidateException e) {
log.error(e.toString());
return ResultBean.newErrorResult(1, e.getMsgKey(), e.getDefaultMsg());
}
return ResultBean.newOkResult("");
}
private Barcode resolveBarcode(String code) {
Barcode barcode = codeResolve.resolveOneValideBarcode(code);
if (barcode == null) {
throw new ValidateException("smfcore.error.barcode.invalid", "{0}不是有效的条码", new String[]{code});
}
Date expireDate = barcode.getExpireDate();
if (expireDate != null) {
if (System.currentTimeMillis() > expireDate.getTime()) {
throw new ValidateException("smfcore.error.barcode.expired", "物料已过期,无法入库.");
}
}
if (barcode.getPlateSize() <= 1) {
//长宽为1的需要弹框设置尺寸
throw new ValidateException("smfcore.error.barcode.errorSize", "条码未设置尺寸");
}
return barcode;
}
}
......@@ -204,6 +204,10 @@ public class DataLog extends BasePo implements Serializable {
* 如果是出库任务,需要记录入库时间
*/
private Date putInDate;
/**
* 入库类型:1=普通入库,2=并盘入库,3=截料入库,4=退料入库
*/
private int inType;
/**
* MSD附加信息
......
package com.neotel.smfcore.hikvision;
import cn.hutool.core.util.ObjectUtil;
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.LiteOrderCache;
import com.neotel.smfcore.core.order.enums.LITEORDER_STATUS;
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.hikvision.bean.HikOutInfo;
import com.neotel.smfcore.panacim.PanaMaterial;
import com.neotel.smfcore.security.annotation.AnonymousAccess;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
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.ResponseBody;
import java.util.Date;
import java.util.List;
import java.util.Map;
@Slf4j
@Controller
@RequestMapping("/rest/api")
@Api(tags = "海康API")
public class HikvisionApiController {
@Autowired
private IBarcodeManager barcodeManager;
@Autowired
private LiteOrderCache liteOrderCache;
@Autowired
private ILiteOrderItemManager liteOrderItemManager;
@Autowired
private ILiteOrderManager liteOrderManager;
@ApiOperation("1创建出库单:创建出库需求单,可一次性传入多个")
@RequestMapping(value = "/outInfo")
@ResponseBody
@AnonymousAccess
public ResultBean outInfo(@RequestParam List<HikOutInfo> outInfos) {
// 6.1创建出库单
// 接口功能
// 创建出库需求单,可一次性传入多个
// 接口地址
// http://IP/smfcore/rest/api/outInfo
// 请求方式
// POST
// 接口使用
// 本接口由SMF端提供,由MES/ERP系统调用。
// 请求参数
// 参数名称 类型 是否必须 描述
// jobNo String true 工单号/合单号[]
// replenishmentNo String false 补料单号,如果有值表示此单为补料单[合并唯一]
// station String true 站位号
// baseCode String true 基地编号
// lgort String true 库位
// workLine String true 产线
// startDate String true 开工时间
// endDate String true 完工时间
// materialNo String true 物料号[详情]
// qty Integer true 需求数量
// overFlag Integer true 超发标识[贵重物料](1是不允许超发,0是允许超发)
// increment Integer true 发料增量
// wemng Integer true 排程数量
// reason String false 移动原因
// 返回参数
//
// 参数名称 类型 描述
// code string 状态码。0为正常,其他为异常。
// msg string 提示消息
// data 返回数据
if (outInfos != null && outInfos.size() > 0) {
for (HikOutInfo outInfo :
outInfos) {
//查找工单是否存在
String orderNo = outInfo.getJobNo();
if (ObjectUtil.isNotEmpty(outInfo.getReplenishmentNo())) {
orderNo += "-" + outInfo.getReplenishmentNo();
}
LiteOrder order = liteOrderCache.findOrderByNo(orderNo);
if (order == null) {
//创建工单
order = new LiteOrder();
order.setOrderNo(orderNo);
order.UpdateOutInfo(outInfo);
LiteOrderItem item = outInfo.crateOrderItem(orderNo);
order.addOrderItems(item);
liteOrderManager.createWithItems(order);
liteOrderCache.addOrderToMap(order);
} else {
if (order.getStatus() > LITEORDER_STATUS.NEW) {
log.info("工单[" + orderNo + "]已存在,且状态为[" + order.getStatus() + "],不能修改工单信息:" + outInfo.toString());
continue;
}
order.UpdateOutInfo(outInfo);
LiteOrderItem item = outInfo.crateOrderItem(orderNo);
item = liteOrderItemManager.save(item);
List<LiteOrderItem> items = order.getOrderItems();
items.add(item);
order.setOrderItems(items);
liteOrderManager.save(order);
liteOrderCache.addOrderToMap(order);
}
}
}
return ResultBean.newOkResult("");
}
@ApiOperation("对湿敏过期物料进行冻结")
@RequestMapping(value = "/lockMsl")
@ResponseBody
@AnonymousAccess
public ResultBean lockMsl(@RequestBody Map<String, Object> paramsMap) {
// 接口功能
// 对湿敏过期物料进行冻结
// 接口地址
// http://IP/smfcore/rest/api/lockMsl
// 请求方式
// POST
// 接口使用
// 本接口由SMF端提供,由MES/ERP系统调用。
// 请求参数
// 参数名称 类型 是否必须 描述
// reelIds array true 要冻结湿敏物料唯一码数组
//
// 返回参数
//
// 参数名称 类型 描述
// code string 状态码。0为正常,其他为异常。
// msg string 提示消息
// data 返回数据
List<String> reelIds = (List<String>) paramsMap.get("reelIds");
String msg = "";
if (reelIds != null && reelIds.size() > 0) {
for (String reelId :
reelIds) {
if (ObjectUtil.isEmpty(reelId)) {
continue;
}
Barcode barcode = barcodeManager.findByBarcode(reelId);
if (barcode != null) {
barcode.setLockMsl(true);
barcodeManager.saveBarcode(barcode);
msg += reelId + ",";
} else {
log.info("lockMsl:未找到reelID:" + reelId);
}
}
}
if (ObjectUtil.isNotEmpty(msg)) {
log.info("lockMsl:对湿敏过期物料进行冻结 " + reelIds);
}
return ResultBean.newOkResult("");
}
}
支持 Markdown 格式
你添加了 0 到此讨论。请谨慎行事。
Finish editing this message first!