Commit 21bb19f4 zshaohui

立臻项目提交

1 个父辈 3e8bc470
正在显示 78 个修改的文件 包含 5849 行增加915 行删除
......@@ -233,5 +233,4 @@ public abstract class AbstractBaseDao implements IBaseDao {
public void setMongoTemplate(MongoTemplate mongoTemplate) {
this.mongoTemplate = mongoTemplate;
}
}
......@@ -58,6 +58,4 @@ public interface IBaseDao {
void updateFirst(Query query, Update update);
MongoTemplate getMongoTemplate();
}
package com.neotel.smfcore.common.bean;
import com.neotel.smfcore.common.base.BasePo;
import lombok.Data;
import java.util.Date;
@Data
public class ReelLockPosInfo {
public class ReelLockPosInfo extends BasePo{
/**
* 条码信息
*/
......
......@@ -60,6 +60,7 @@ public class DataInitManager {
private InListCache inListCache;
@Autowired
private IMessageManager messageManager;
/**
* 当前版本
*/
......@@ -211,6 +212,7 @@ public class DataInitManager {
//报表:出入库、库存
Menu pMenuReport = Menu.CreatePMenu("报表", 7, "report", 2, "inOutData",null);
addNewFunctionMenu(71, pMenuReport, "inOutData", "出入库", "inOutData", "neolight/inOutData/index", "outPut",functionMenuMap);
addNewFunctionMenu(72, pMenuReport, "innerOutData", "内仓出入库", "innerOutData", "neolight/innerOutData/index", "outPut",functionMenuMap);
addNewFunctionMenu(72, pMenuReport,"inventory", "库存", "inventory", "neolight/inventory/index", "inventory",functionMenuMap);
addNewFunctionMenu(73, pMenuReport,"materialIssueDetailsList", "发料", "materialIssueDetailsList", "neolight/materialIssueDetailsList/index", "mIDList",functionMenuMap);
addNewFunctionMenu(74, pMenuReport,"overdueDelayReport", "过期延期", "overdueDelayReport", "neolight/overdueDelayReport/index", "oDReport",functionMenuMap);
......@@ -222,8 +224,17 @@ public class DataInitManager {
addNewFunctionMenu(80, pMenuReport,"inventoryReport", "库存", "inventoryReport", "neolight/inventoryReport/index", "BOM",functionMenuMap);
addNewFunctionMenu(81, pMenuReport,"materialShortageReport", "缺料", "materialShortageReport", "neolight/materialShortageReport/index", "mShortageReport",functionMenuMap);
addNewFunctionMenu(82,pMenuReport,"pkSearch","PK查询","pkSearch","neolight/pkSearch/index","findOut",functionMenuMap);
//addNewFunctionMenu(83,pMenuReport,"lackPicking","内仓缺料","lackPicking","neolight/lackPicking/index","mShortageReport",functionMenuMap);
addNewFunctionMenu(83,pMenuReport,"feeding","喂料","feeding","neolight/feeding/index","mShortageReport",functionMenuMap);
//内仓
addNewFunctionMenu(84,pMenuReport,"feeding","喂料","feeding","neolight/feeding/index","feeding",functionMenuMap);
addNewFunctionMenu(85,pMenuReport,"innerInventory","库存","innerInventory","innerWarehouse/inventory/index","inventory",functionMenuMap);
addNewFunctionMenu(86,pMenuReport,"innerMaterial","备料清单","innerMaterial","innerWarehouse/materialPreList/index","mPreListReport",functionMenuMap);
addNewFunctionMenu(87,pMenuReport,"innerChangeReport","异动","innerChangeReport","innerWarehouse/changeReport/index","chageReport",functionMenuMap);
addNewFunctionMenu(88,pMenuReport,"innerIssueReport","发料","innerIssueReport","innerWarehouse/issueReport/index","IssueRe",functionMenuMap);
addNewFunctionMenu(89,pMenuReport,"innerMaShortReport","缺料","innerMaShortReport","innerWarehouse/maShortReport/index","maShort",functionMenuMap);
addNewFunctionMenu(90,pMenuReport,"innerProLimitReport","禁限用","innerProLimitReport","innerWarehouse/proLimitReport/index","proLimit",functionMenuMap);
//可观测性:物料追踪
Menu guanceMenu = Menu.CreatePMenu("可观测性", 8, "observability", 2, "scanKey",null);
......@@ -276,6 +287,14 @@ public class DataInitManager {
addNewFunctionMenu(130, s5, "outerWarehouse/s5", "入库扫码装箱","outerWarehouse/s5", "outers/outerWarehouse/index","index",functionMenuMap);
addNewFunctionMenu(131, s5, "outOperation/s5", "出库作业","outOperation/s5", "outers/outOperation/index","index",functionMenuMap);
//线外入库
//Menu outPage = Menu.CreatePMenu("线外入库", 17, "", 1, "index", null);
addNewFunctionMenu(132,null,"outPage","线外入库","outPage","outers/outPage/index","index",functionMenuMap);
addNewFunctionMenu(133,null,"outVir","虚拟仓出库","outVir","outers/outVir/index","index",functionMenuMap);
//内仓线外入库
addNewFunctionMenu(134,null,"virWarehous","虚拟仓","virWarehous","virWarehous/virWarehous/index","feeding",functionMenuMap);
return functionMenuMap;
}
......
......@@ -183,7 +183,16 @@ public class DateUtil {
return date0.after(date1)? date0 : date1;
}
public static Date initDate(Date date, String aMask) {
SimpleDateFormat sf = new SimpleDateFormat(aMask);
String dateStr = sf.format(date);
try {
date = toDate(dateStr,aMask);
} catch (ParseException e) {
e.printStackTrace();
}
return date;
}
public static class Req{
private String seq;
......
......@@ -238,12 +238,16 @@ public class FileUtil extends cn.hutool.core.io.FileUtil {
// 这里注意 如果同一个sheet只要创建一次
WriteSheet writeSheet = EasyExcel.writerSheet("Sheet1").build();
// 去调用写入,这里我调用了五次,实际使用时根据数据库分页的总的页数来
PageRequest page = PageRequest.ofSize(10000);
PageRequest page = PageRequest.ofSize(20000);
if(pageable != null){
page.withSort(pageable.getSort());
}
int count = 0;
while (true){
count ++;
log.info("查询次数:"+count);
List<List<Object>> data = excelDownLoad.getPageData(query,page);
log.info("查找完成");
if(data == null || data.isEmpty()){
break;
}
......
......@@ -58,6 +58,9 @@ public class SmfApi {
@Value("${api.barcodeInfoUrl:}")
protected String barcodeInfoUrl = "";
@Value("${api.importUrl}")
protected String importUrl;
@PostConstruct
public void init(){
apiName = dataCache.getConfigCache("api.name",apiName);
......@@ -69,6 +72,7 @@ public class SmfApi {
fetchInListUrl = dataCache.getConfigCache("api.fetchInListUrl",fetchInListUrl);
fetchOrderUrl = dataCache.getConfigCache("api.fetchOrderUrl",fetchOrderUrl);
barcodeInfoUrl = dataCache.getConfigCache("api.barcodeInfoUrl",barcodeInfoUrl);
importUrl = dataCache.getConfigCache("api.importUrl",importUrl);
}
/**
......
......@@ -858,6 +858,9 @@ 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]";
BarcodeRule br = BarcodeRule.newRule(rule);
Barcode b = br.toCodeBean(codeStr).getBarcode();
if(b != null){
......
......@@ -103,6 +103,9 @@ public class BarcodeDto implements Serializable {
@ApiModelProperty("库位信息")
private String posName;
@ApiModelProperty("隔扣码数量")
private String posNameCount;
/**
* 只能单盘出库
*/
......@@ -265,4 +268,16 @@ public class BarcodeDto implements Serializable {
@ApiModelProperty("创建人")
private String creator;
@ApiModelProperty("厂别")
private String plant;
@ApiModelProperty("厂区")
private String factory;
@ApiModelProperty("储位")
private String storagePosName;
@ApiModelProperty("Keeper")
private String keeperCode;
}
......@@ -2,6 +2,8 @@ package com.neotel.smfcore.core.barcode.service.manager;
import com.neotel.smfcore.common.base.IBaseManager;
import com.neotel.smfcore.core.barcode.service.po.Barcode;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
......@@ -17,4 +19,10 @@ public interface IBarcodeManager extends IBaseManager<Barcode> {
void download(List<Barcode> list, HttpServletResponse response) throws IOException;
void deleteBarcodes(Set<String> ids);
Barcode findOne(Query query);
void updateBarcode(Query query, Update update);
List<Barcode> findByPosName(String barcodeStr);
}
......@@ -5,6 +5,7 @@ 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.common.utils.QueryHelp;
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;
......@@ -15,12 +16,14 @@ 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.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;
import java.util.regex.Pattern;
@Slf4j
@Service
......@@ -96,6 +99,11 @@ public class BarcodeManagerImpl implements IBarcodeManager {
}
@Override
public Barcode findOne(Query query) {
return barcodeDao.findOne(query);
}
@Override
public Barcode saveBarcode(Barcode resources) {
validateSave(resources);
......@@ -169,6 +177,19 @@ public class BarcodeManagerImpl implements IBarcodeManager {
return barcodeDao.save(resources);
}
public void updateBarcode(Query query, Update update){
barcodeDao.updateMulti(query,update);
}
@Override
public List<Barcode> findByPosName(String posName) {
Query q = new Query();
Pattern p = Pattern.compile(QueryHelp.escapeExprSpecialWord(posName), Pattern.CASE_INSENSITIVE);
q.addCriteria(Criteria.where("posName").regex(p));
return barcodeDao.findByQuery(q);
}
protected boolean validateComponent(Barcode barcode) {
return componentManager.findOneByPN(barcode.getPartNumber()) != null;
}
......
......@@ -108,6 +108,11 @@ public class Barcode extends BasePo implements Serializable {
private String posName;
/**
* 库位信息(料箱的库位)
*/
private String storagePosName;
/**
* 只能单盘出库
*/
private boolean onlySingleOut = false;
......@@ -528,4 +533,19 @@ public class Barcode extends BasePo implements Serializable {
}
}
}
public void updateSubCodes(Barcode subCode) {
if (subCodeList == null) {
subCodeList = new ArrayList<>();
}
if (subCodeList == null || subCodeList.isEmpty()) {
subCodeList.add(subCode);
} else {
//移除
subCodeList.removeIf(t -> t.getBarcode().equals(subCode.getBarcode()));
if (subCode.getAmount() > 0){
subCodeList.add(subCode);
}
}
}
}
......@@ -491,7 +491,6 @@ public class BaseDeviceHandler implements IDeviceHandler {
updatePosExecuteTime(posName,executeTime);
}
log.info(task.getBarcode() + "入仓位[" + task.getPosName() + "]完成,执行时间["+executeTime+"]秒");
ReelLockPosUtil.removeReelLockPosInfo(task.getBarcode());
DataLog cancelTask = taskService.findFinishedTask(cid, posName);
if (cancelTask != null && cancelTask.isCancel()) {
//将相同库位已经取消的任务从完成队列里删除
......@@ -499,6 +498,7 @@ public class BaseDeviceHandler implements IDeviceHandler {
log.info("从已完成的任务列表中删除之前取消的任务:" + cancelTask.getPosName() + " ReelId:" + cancelTask.getBarcode());
}
updatePutInData(task);
ReelLockPosUtil.removeReelLockPosInfo(task.getBarcode());
} else {
//从已完成列表中找,如果还找不到就忽略
task = taskService.findFinishedTask(cid, posName);
......
......@@ -23,6 +23,8 @@ import com.neotel.smfcore.core.system.bean.OrderSetting;
import com.neotel.smfcore.core.system.service.po.DataLog;
import com.neotel.smfcore.core.system.util.DevicesStatusUtil;
import com.neotel.smfcore.core.system.util.TaskService;
import com.neotel.smfcore.custom.lizhen.LizhenApi;
import com.neotel.smfcore.custom.lizhen.innerBox.enums.ExtendType;
import com.neotel.smfcore.custom.lizhen.innerBox.rest.InnerBoxRestController;
import com.neotel.smfcore.security.TokenProvider;
import com.neotel.smfcore.security.annotation.AnonymousAccess;
......@@ -52,12 +54,15 @@ public class NLShelfHandler extends BaseDeviceHandler {
@Autowired
private TokenProvider tokenProvider;
@Autowired
private ILiteOrderManager liteOrderManager;
@Autowired
private InListCache inListCache;
@Autowired
private LizhenApi lizhenApi;
String putInColor = "green";
int delayCloseTime = 30000;
......@@ -137,7 +142,6 @@ public class NLShelfHandler extends BaseDeviceHandler {
}
log.info("料架亮灯:" + task.getPosName() + "=" + color.name());
statusBean.addData("open", task.getPosName() + "=" + color.name());
log.info(JsonUtil.toJsonStr(statusBean.getData()));
}
return statusBean;
}
......@@ -306,6 +310,7 @@ public class NLShelfHandler extends BaseDeviceHandler {
pos=storagePosManager.getByPosName(posNameStr);
}
}
if (pos != null) {
//扫描的为库位条码,先关掉上一个库位灯, 当前库位中没有物料的话点亮库位灯
closeLastPos(token);
......@@ -382,8 +387,26 @@ public class NLShelfHandler extends BaseDeviceHandler {
return ResultBean.newOkResult( "smfcore.shelf.msg.outConfirm", "出库完成, 库位[{0}]灭灯", new String[]{inPos.getPosName()} );
}
}
//判断是不是虚拟仓的,如果是则直接完成
Storage storage = dataCache.getStorageById(inPos.getStorageId());
if (storage.isVirtual()) {
DataLog dataLog = new DataLog(storage, barcode, inPos);
dataLog.setStatus(OP_STATUS.FINISHED.name());
dataLog.setExtendType(ExtendType.VIRTUAL_CHECKOUT); //虚拟出库
taskService.updateFinishedTask(dataLog);
taskService.removeFinishedTask(dataLog);
log.info("料架入库,虚拟仓出库:" + barcode.getBarcode() + ",库位名称为:" + inPos.getPosName());
inPos.setBarcode(null);
//dataCache.updateInventory(storagePos, barcode);
barcode.setPosName(null);
barcode = barcodeManager.save(barcode);
//进行库位更改
inPos.setUsed(false);
storagePosManager.save(inPos);
} else {
return ResultBean.newErrorResult(1, "smfcore.shelf.msg.noTask", "操作失败,已在库位[{0}]中,未找到对应的出库任务", new String[]{inPos.getPosName()});
}
}
return null;
}
......@@ -401,6 +424,12 @@ public class NLShelfHandler extends BaseDeviceHandler {
if(barcode == null){
throw new ValidateException("smfcore.error.barcode.invalid", "{0}不是有效的条码",new String[]{code});
}
Barcode barcodeApi = lizhenApi.barcodeInfo(barcode);
if (barcodeApi != null){
barcode = barcodeApi;
}
Date expireDate = barcode.getExpireDate();
if (expireDate != null) {
if (System.currentTimeMillis() > expireDate.getTime()) {
......@@ -467,6 +496,52 @@ public class NLShelfHandler extends BaseDeviceHandler {
return ResultBean.newOkResult(posList);
}
/**
* 库位亮灯(1:使用库位亮灯,2:空库位亮灯,3:一键灭灯)
*
* @param request
* @return
*/
@RequestMapping("/service/store/nlShelf/posOnOrOffLights")
@AnonymousAccess
public ResultBean posOnOrOffLights(HttpServletRequest request) {
String cid = request.getParameter("cid");
String type = request.getParameter("type");
//获取设备信息
Storage storage = null;
for (Storage stor : dataCache.getAllStorage().values()) {
if (stor.getCid().equals(cid)) {
storage = stor;
break;
}
}
//查询符合条件的料仓
List<StoragePos> storagePosList = new ArrayList<>();
if ("1".equals(type)) {
storagePosList = storagePosManager.findNotEmptyByStorageId(storage.getId());
} else if ("2".equals(type)) {
storagePosList = storagePosManager.findEmptyByStorageId(storage.getId());
} else if ("3".equals(type)) {
storagePosList = storagePosManager.findByStorage(storage.getId());
}
if (storagePosList == null || storagePosList.isEmpty()) {
return ResultBean.newErrorResult(-1, "smfcore.shelf.msg.noPos", "未找到符合条件的库位");
}
if ("1".equals(type) || "2".equals(type)) {
for (StoragePos pos : storagePosList) {
opPosLight("open", pos, ORDER_COLOR.INDIANRED.name());
}
} else if ("3".equals(type)) {
for (StoragePos pos : storagePosList) {
opPosLight("close", pos, "");
}
}
return ResultBean.newOkResult(null);
}
@Override
public DeviceType getDeviceType() {
return DeviceType.NL;
......
......@@ -12,9 +12,11 @@ import com.neotel.smfcore.common.utils.Constants;
import com.neotel.smfcore.common.utils.ReelLockPosUtil;
import com.neotel.smfcore.core.api.SmfApi;
import com.neotel.smfcore.core.api.listener.ISmfApiListener;
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.bean.PosInfo;
import com.neotel.smfcore.core.device.enums.OP_STATUS;
import com.neotel.smfcore.core.message.util.DeviceMessageUtil;
import com.neotel.smfcore.core.storage.service.manager.IStoragePosManager;
import com.neotel.smfcore.core.storage.service.po.StoragePos;
......@@ -24,6 +26,7 @@ import com.neotel.smfcore.core.system.service.po.DataLog;
import com.neotel.smfcore.core.system.util.DevicesStatusUtil;
import com.neotel.smfcore.core.system.util.TaskService;
import com.neotel.smfcore.custom.lizhen.LizhenApi;
import com.neotel.smfcore.custom.lizhen.innerBox.enums.ExtendType;
import com.neotel.smfcore.security.annotation.AnonymousAccess;
import com.neotel.smfcore.core.storage.enums.DeviceType;
import com.neotel.smfcore.core.device.handler.IDeviceHandler;
......@@ -66,6 +69,9 @@ public class DeviceController {
@Autowired
private LizhenApi lizhenApi;
@Autowired
private IBarcodeManager barcodeManager;
private Map<String, IDeviceHandler> handlerMap = new HashMap<>();
public DeviceController(List<IDeviceHandler> deviceHandlerList) {
......@@ -164,11 +170,29 @@ public class DeviceController {
try {
Barcode barcode = codeResolve.resolveOneValideBarcode(code);
if(barcode==null) {
throw new ValidateException("smfcore.error.barcode.invalid", "{0}不是有效的条码", new String[]{code});
}
//判断虚拟仓有没有存在,如果有,把虚拟仓库位置空
StoragePos storagePos = storagePosManager.getByBarcode(barcode.getBarcode());
if (storagePos != null) {
Storage storage = dataCache.getStorageById(storagePos.getStorageId());
DataLog dataLog = new DataLog(storage, barcode, storagePos);
dataLog.setStatus(OP_STATUS.FINISHED.name());
dataLog.setExtendType(ExtendType.VIRTUAL_CHECKOUT); //虚拟出库
taskService.updateFinishedTask(dataLog);
taskService.removeFinishedTask(dataLog);
log.info("智能仓储入库,虚拟仓出库:" + barcode.getBarcode() + ",库位名称为:" + storagePos.getPosName());
storagePos.setBarcode(null);
//dataCache.updateInventory(storagePos, barcode);
barcode.setPosName(null);
barcode = barcodeManager.save(barcode);
//进行库位更改
storagePos.setUsed(false);
storagePosManager.save(storagePos);
}
Barcode barcodeCanPutIn = smfApi.canPutInAfterResolve(barcode);
if (barcodeCanPutIn != null){
barcode = barcodeCanPutIn;
......
......@@ -16,6 +16,7 @@ import com.neotel.smfcore.core.language.util.MessageUtils;
import com.neotel.smfcore.core.storage.bean.InventoryItem;
import com.neotel.smfcore.core.storage.enums.CHECKOUT_TYPE;
import com.neotel.smfcore.core.storage.enums.COMPATIBLE_TYPE;
import com.neotel.smfcore.core.storage.enums.DeviceType;
import com.neotel.smfcore.core.storage.service.po.StoragePos;
import com.neotel.smfcore.core.system.bean.OrderSetting;
import com.neotel.smfcore.core.system.service.dao.ICacheItemDao;
......@@ -401,7 +402,7 @@ public class DataCache {
posNameList = new ArrayList<>();
if(storage != null){
log.info("加载["+cid+"]所有已使用库位到缓存");
List<StoragePos> allPos = storagePosManager.findNotEmptyByStorageId(storage.getId());
List<StoragePos> allPos = storagePosManager.findNotEmptyPosNameByStorageId(storage.getId());
for (StoragePos pos : allPos) {
posNameList.add(pos.getPosName());
}
......@@ -452,14 +453,16 @@ public class DataCache {
List<Storage> storages = Lists.newArrayList();
for (Storage storage : allStorages.values()) {
if (storageIds == null || storageIds.contains(storage.getId())) {
if (!storage.isVirtual()) {
storages.add(storage);
}
}
}
Map<String, InventoryItem> map = getInventory(storages);
Map<String, InventoryItem> resultMap = new HashMap<>();
for (InventoryItem item : map.values()) {
if (ObjectUtil.isNotEmpty(blurry)) {
if(item.getPartNumber().contains(blurry)){
if (item.getPartNumber().contains(blurry)) {
resultMap.put(item.getPartNumber(), item);
}
} else {
......@@ -469,6 +472,7 @@ public class DataCache {
return resultMap;
}
/**
* 获取某些料仓的库存信息
*/
......
......@@ -30,11 +30,13 @@ import com.neotel.smfcore.core.storage.service.po.Storage;
import com.neotel.smfcore.core.storage.service.po.StoragePos;
import com.neotel.smfcore.core.system.service.po.DataLog;
import com.neotel.smfcore.core.system.util.TaskService;
import com.neotel.smfcore.custom.lizhen.innerBox.enums.ExtendType;
import com.sun.org.apache.regexp.internal.RE;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;
import springfox.documentation.spring.web.json.Json;
......@@ -211,7 +213,7 @@ public class LiteOrderCache {
}
liteOrder.setTaskReelCount(taskReelCount);
liteOrder.setTotalTaskReelCount(liteOrder.getTotalTaskReelCount()+taskReelCount);
//liteOrder.setTotalTaskReelCount(liteOrder.getTotalTaskReelCount()+taskReelCount);
liteOrder.setStatus(LITEORDER_STATUS.TAILS);
log.info("工单[" + liteOrder.getOrderNo() + "]任务分配结束,任务数[" + taskReelCount + "]");
smfApi.onOrderStatusChange(liteOrder);
......@@ -281,22 +283,23 @@ public class LiteOrderCache {
//任务是取消的,需要将总待出库数量-1
if (task.isCancel()) {
order.setTaskReelCount(order.getTaskReelCount() - 1);
order.setTotalTaskReelCount(order.getTotalTaskReelCount()-1);
//order.setTotalTaskReelCount(order.getTotalTaskReelCount()-1);
log.info("工单[" + orderNo + "]的任务" + task.getPartNumber() + "[" + task.getBarcode() + "]已取消,任务数-1=" + order.getFinishedReelCount() + "/" + order.getTaskReelCount());
}
else if (task.isFinished()) {
order.setFinishedReelCount(order.getFinishedReelCount() + 1);
order.setTotalFinishedReelCount(order.getTotalFinishedReelCount() + 1);
order.setFinishedReelCount(order.getFinishedReelCount() + 1);
String orderItemId = task.getSubSourceId();
List<LiteOrderItem> orderItems = order.getOrderItems();
List<LiteOrderItem> liteOrderItems = new ArrayList<>();
if (LITEORDER_SOURCE.OUTTER.name().equals(order.getSource())) {
order.setTotalFinishedReelCount(order.getTotalFinishedReelCount() + 1);
log.info("更新任务盘数:"+order.getTaskReelCount()+",已完成的数量:"+order.getFinishedReelCount());
if (orderItems != null && !orderItems.isEmpty()) {
for (LiteOrderItem liteOrderItem : orderItems) {
if (liteOrderItem.getId().equals(orderItemId)) {
//判断是否超发,如果是超发,则赋值
if (StringUtils.isNotBlank(order.getIsExcess()) && "true".equals(order.getIsExcess())){
if (order.isExcess()){
if (!liteOrderItem.isOutFinished()) {
liteOrderItem.setOutNum(liteOrderItem.getOutNum() + task.getNum());
liteOrderItem.setTotalReelCountByOutNum(liteOrderItem.getTotalReelCountByOutNum() + 1);
......@@ -340,7 +343,7 @@ public class LiteOrderCache {
//工单未关闭的话,检查状态,全部都出完进行关闭
boolean closed = true;
for (LiteOrderItem liteOrderItem : order.getOrderItems()) {
if (StringUtils.isNotBlank(order.getIsExcess()) && "true".equals(order.getIsExcess())){
if (order.isExcess()){
if (liteOrderItem.getOutNum() < liteOrderItem.getNeedNum() || liteOrderItem.getOutReelCount() < liteOrderItem.getNeedReelCount()){
closed = false;
break;
......@@ -430,6 +433,20 @@ public class LiteOrderCache {
return orderNo + "前面已有出库任务,执行完继续执行";
}
//判断当前工单的任务数,是否大于2
int executingCount = 0;
if (liteOrderMap != null){
for (LiteOrder order : liteOrderMap.values()) {
if (order.isOutTails()){
executingCount ++;
}
}
}
if (executingCount >= 2){
return "正在执行的工单超过2个,跳过";
}
LiteOrder cacheOrder = liteOrderMap.get(orderNo);
if (cacheOrder == null) {
cacheOrder = liteOrderManager.findByOrderNo(orderNo);
......@@ -472,8 +489,12 @@ public class LiteOrderCache {
//liteOrderMap.put(cacheOrder.getOrderNo(), cacheOrder);
int taskReelCount = 0;
CHECKOUT_TYPE checkoutType = dataCache.getCheckOutType();
List<String> availableStorageIds = dataCache.getAvailableStorageIds();
List<String> availableStorageIds = new ArrayList<>();
for (Storage storage : dataCache.getAllStorage().values()) {
if (!storage.isVirtual()){
availableStorageIds.add(storage.getId());
}
}
//其他出库模式一次性全部生成任务
//List<LiteOrderItem> orderItems = liteOrderItemManager.findOrderItems(cacheOrder.getId());
......@@ -540,15 +561,26 @@ public class LiteOrderCache {
taskReelCount = taskReelCount + 1;
log.info("工单[" + orderNo + "],任务数[" + taskReelCount + "]出库位置仓位【" + pos.getPosName() + "】RI=[" + pos.getBarcode().getBarcode() + "] PN=[" + partNumber + "] num:" + pos.getBarcode().getAmount());
DataLog task = newTask(pos);
task.setSourceId(cacheOrder.getId());
task.setSourceName(cacheOrder.getOrderNo());
task.setSubSourceId(orderItem.getId());
task.setSubSourceInfo(orderItem.getFeederInfo());
task.setType(OP.CHECKOUT);
task.setExtendType(ExtendType.STORAGE_CHECKOUT); //智能仓储出库
task.setLightColor(nextColor.getRgb());
task.setStatus(OP_STATUS.WAIT.name());
task.setPartNumber(pos.getBarcode().getPartNumber());
task.setPartNumber(pos.getBarcode().getPartNumber()); //料号
task.setLine(orderItem.getLine()); //线别
task.setMachineName(orderItem.getMachineName()); //机器名称
task.setSlot(orderItem.getSlot()); //站位
task.setSubSlot(orderItem.getSubSlot()); //点位
task.setSide(orderItem.getSide()); //面别
task.setNum(pos.getBarcode().getAmount()); //数量
task.setDateCode(pos.getBarcode().getDateCode()); // D/C
task.setBatchInfo(pos.getBarcode().getBatch()); //L/C
task.setProviderNumber(pos.getBarcode().getProviderNumber()); //厂商代码
task.setProvider(pos.getBarcode().getProvider()); //厂商
task.setTableNo(orderItem.getTableNo());
// task = dataLogDao.save(task);
taskService.addTaskToExecute(task);
}
......@@ -560,7 +592,7 @@ public class LiteOrderCache {
}
}
cacheOrder.setTaskReelCount(taskReelCount);
cacheOrder.setTotalTaskReelCount(cacheOrder.getTotalTaskReelCount()+taskReelCount);
//cacheOrder.setTotalTaskReelCount(cacheOrder.getTotalTaskReelCount()+taskReelCount);
log.info("工单[" + orderNo + "]任务分配结束,任务数[" + taskReelCount + "]");
smfApi.onOrderStatusChange(cacheOrder);
//有需要出库的
......@@ -726,7 +758,7 @@ public class LiteOrderCache {
}
public synchronized String checkOutLiteOrderOut(String orderNo, boolean outBom,List<String> orderItemIds,String isExcess) {
public synchronized String checkOutLiteOrderOut(String orderNo, boolean outBom,List<String> orderItemIds) {
LiteOrder cacheOrder = liteOrderMap.get(orderNo);
if (cacheOrder == null) {
cacheOrder = liteOrderManager.findByOrderNo(orderNo);
......@@ -753,8 +785,32 @@ public class LiteOrderCache {
return "smfcore.order.out.maxOrder";
}
//判断是否已经确认过超发
if (!cacheOrder.isConfirmExcess()) {
return "smfcore.order.confirmExcess";
}
//限制当前执行的工单只有一个
if (liteOrderMap != null) {
for (LiteOrder liteOrder : liteOrderMap.values()) {
if (liteOrder.isOutTails()) {
return "smfcore.order.executing";
}
}
}
//料仓信息
List<String> availableStorageIds = dataCache.getAvailableStorageIds();
List<String> availableStorageIds = new ArrayList<>();
String virtualId = "";
for (Storage storage : dataCache.getAllStorage().values()) {
if (storage.isVirtual()) {
virtualId = storage.getId();
} else {
availableStorageIds.add(storage.getId());
}
}
//出库方式
CHECKOUT_TYPE checkoutType = dataCache.getCheckOutType();
......@@ -764,11 +820,6 @@ public class LiteOrderCache {
cacheOrder.setFinishedReelCount(0);
cacheOrder.setStatus(LITEORDER_STATUS.TAILS);
//判断是否属于超发,如果为空,则取工单上的
if (StringUtils.isBlank(isExcess)){
isExcess = cacheOrder.getIsExcess();
}
List<StoragePos> needOutPoss = new ArrayList<>();
int orderTaskReelCount = 0;
//开始循环处理工单详情
......@@ -776,16 +827,21 @@ public class LiteOrderCache {
//排除的仓位信息
Collection<String> excludePosIds = taskService.excludePosIds();
List<String> excludeIds = new ArrayList<>();
for (String excludePosId : excludePosIds) {
excludeIds.add(excludePosId);
}
//判断是否包含需要出库的
if (orderItemIds != null && !orderItemIds.isEmpty()){
if (!orderItemIds.contains(orderItem.getId())){
if (orderItemIds != null && !orderItemIds.isEmpty()) {
if (!orderItemIds.contains(orderItem.getId())) {
continue;
}
}
int outReelCount = 0;
int outNumCount = 0;
//如果是超发情况
if (StringUtils.isNotBlank(isExcess) && "true".equals(isExcess)) {
if (cacheOrder.isExcess()) {
if (orderItem.getOutNum() >= orderItem.getNeedNum() && orderItem.getOutReelCount() >= orderItem.getNeedReelCount()) {
continue;
}
......@@ -807,7 +863,15 @@ public class LiteOrderCache {
String warehouseCode = orderItem.getWarehouseCode(); //厂别
String brand = orderItem.getBrand(); //供应商
String pn = orderItem.getPn(); //料号
StoragePos pos = storagePosManager.findPartNumberInStorages(availableStorageIds, pn, excludePosIds, checkoutType, warehouseCode, brand);
log.info("查询库位时间开始");
StoragePos pos = storagePosManager.findPartNumberInStorages(Arrays.asList(virtualId),pn, excludeIds, checkoutType, warehouseCode, brand,false);
if (pos == null){
pos = storagePosManager.findPartNumberInStorages(availableStorageIds, pn, excludeIds, checkoutType, warehouseCode, brand,true);
}
if (pos == null){
pos = storagePosManager.findPartNumberInStorages(availableStorageIds, pn, excludeIds, checkoutType, warehouseCode, brand,false);
}
log.info("查询库位时间结束");
if (pos == null) {
log.info(orderItem.getOrderId() + "厂商:" + warehouseCode + ",供应商:" + brand + ",料号:" + pn + "未找到存在库位,跳过");
break;
......@@ -817,6 +881,7 @@ public class LiteOrderCache {
List<Barcode> subCodeList = barcode.getSubCodeList();
//进行排序
subCodeList = subCodeList.stream().sorted(Comparator.comparing(Barcode::getPosName)).collect(Collectors.toList());
List<String> subCodeIds = new ArrayList<>();
for (Barcode subCode : subCodeList) {
if (outReelCount >= orderItem.getNeedReelCount() && outNumCount >= orderItem.getNeedNum()) {
break;
......@@ -852,14 +917,13 @@ public class LiteOrderCache {
}
subCode.setOut(true);
subCode.setOrderItemId(orderItem.getId());
subCode = barcodeManager.save(subCode);
barcode.UpdateSubCode(subCode);
barcodeManager.saveBarcode(barcode);
orderTaskReelCount ++;
log.info(subCode.getBarcode()+"---"+orderTaskReelCount);
subCodeIds.add(subCode.getId());
orderTaskReelCount++;
log.info(subCode.getBarcode() + "---" + orderTaskReelCount);
hasOutReel = true;
//判断是否超发,如果超发,先判断是否满足数量.再判断是否满足卷数
if (StringUtils.isNotBlank(isExcess) && "true".equals(isExcess)) {
if (cacheOrder.isExcess()) {
if (outNumCount >= orderItem.getNeedNum()) {
outReelCount++;
} else {
......@@ -872,15 +936,25 @@ public class LiteOrderCache {
outNumCount = outNumCount + subCode.getAmount();
}
}
excludePosIds.add(pos.getId());
log.info("保存barcode时间开始--"+barcode.getBarcode());
if (subCodeIds != null && !subCodeIds.isEmpty()) {
Query query = new Query(Criteria.where("id").in(subCodeIds));
Update update = new Update().set("isOut", true).set("orderItemId", orderItem.getId());
barcodeManager.updateBarcode(query, update);
}
barcodeManager.save(barcode);
log.info("保存barcode时间结束");
excludeIds.add(pos.getId());
if (hasOutReel) {
needOutPoss.add(pos);
pos.setBarcode(barcode);
log.info("库位保存开始");
storagePosManager.save(pos);
log.info("库位保存结束");
}
}
}
if (needOutPoss != null && !needOutPoss.isEmpty()){
if (needOutPoss != null && !needOutPoss.isEmpty()) {
for (StoragePos pos : needOutPoss) {
Barcode barcode = pos.getBarcode();
DataLog task = new DataLog(dataCache.getStorageById(pos.getStorageId()), barcode, pos);
......@@ -892,13 +966,15 @@ public class LiteOrderCache {
//task.setCreator(SecurityUtils.getCurrentUsername());
task.setStatus(OP_STATUS.WAIT.name());
try {
log.info("生成任务开始");
taskService.addTaskToExecute(task);
}catch (Exception e){
log.info("生成任务结束");
} catch (Exception e) {
e.getMessage();
}
}
}
cacheOrder.setIsExcess(isExcess);
//cacheOrder.setIsExcess(isExcess);
cacheOrder.setTaskReelCount(orderTaskReelCount);
cacheOrder.setTotalTaskReelCount(cacheOrder.getTotalTaskReelCount() + orderTaskReelCount);
log.info("工单[" + orderNo + "]任务分配结束,任务数[" + orderTaskReelCount + "]");
......@@ -915,4 +991,68 @@ public class LiteOrderCache {
}
return "";
}
public synchronized void pauseOrder(String orderNo) {
LiteOrder liteOrder = liteOrderMap.get(orderNo);
//缓存里没有
if (liteOrder == null) {
log.info("缓存里没有找到该工单,从数据库中查询:" + orderNo);
liteOrder = liteOrderManager.findByOrderNo(orderNo);
}
//记录原来的工单状态
liteOrder.setLastStatus(liteOrder.getStatus());
//工单状态改为暂停
liteOrder.setStatus(LITEORDER_STATUS.PAUSE);
liteOrderManager.save(liteOrder);
liteOrderMap.put(orderNo, liteOrder);
}
public synchronized void restoreOrder(String orderNo) {
LiteOrder liteOrder = liteOrderMap.get(orderNo);
//缓存里没有
if (liteOrder == null) {
log.info("缓存里没有找到该工单,从数据库中查询:" + orderNo);
liteOrder = liteOrderManager.findByOrderNo(orderNo);
}
//工单状态改为暂停
liteOrder.setStatus(liteOrder.getLastStatus());
liteOrderManager.save(liteOrder);
liteOrderMap.put(orderNo, liteOrder);
}
public synchronized String excessOrder(String orderNo,boolean excess) {
LiteOrder liteOrder = liteOrderMap.get(orderNo);
//缓存里没有
if (liteOrder == null) {
log.info("缓存里没有找到该工单,从数据库中查询:" + orderNo);
liteOrder = liteOrderManager.findByOrderNo(orderNo);
}
//判断是否已经超发过
if (liteOrder.isConfirmExcess()){
return "smfcore.order.excessSuccess";
}
liteOrder.setExcess(excess);
liteOrder.setConfirmExcess(true);
//再判断orderitem是否为空
List<LiteOrderItem> orderItems = liteOrder.getOrderItems();
if (orderItems != null && !orderItems.isEmpty()) {
for (LiteOrderItem orderItem : orderItems) {
orderItem.setExcess(excess);
liteOrderItemManager.save(orderItem);
}
}
liteOrder.setOrderItems(orderItems);
liteOrderManager.save(liteOrder);
liteOrderMap.put(orderNo, liteOrder);
return "";
}
/**
* 获取所有liteOrder
* @return
*/
public synchronized Collection<LiteOrder> getAllLiteOrder() {
return liteOrderMap.values();
}
}
......@@ -23,6 +23,11 @@ public class LITEORDER_STATUS {
/**工单已关闭*/
public static int CLOSED=7;
/**
* 工单暂停
*/
public static int PAUSE = 8;
/**
* 工单状态
* 0=新建的工单
......@@ -33,5 +38,6 @@ public class LITEORDER_STATUS {
* 5=正在补料
* 6=补料已完成
* 7=工单已关闭
* 8=工单暂停
*/
}
......@@ -171,7 +171,7 @@ public class OrderController {
@ApiOperation("工单出库")
@PostMapping(value = "/out")
@PreAuthorize("@el.check('workOrder')")
public ResultBean checkOut(@RequestBody Map<String, String> mapValues) {
public synchronized ResultBean checkOut(@RequestBody Map<String, String> mapValues) {
String orderNo = mapValues.get("orderNo");
if (orderNo == null) {
throw new ValidateException("smfcore.valueCanotNull", "{0}不能为空", new String[]{"orderNo"});
......@@ -182,9 +182,8 @@ public class OrderController {
}
String result = "";
String isExcess = mapValues.get("isExcess");
if (LITEORDER_SOURCE.OUTTER.name().equals(liteOrder.getSource())) {
result = liteOrderCache.checkOutLiteOrderOut(liteOrder.getOrderNo(),false,null,isExcess);
result = liteOrderCache.checkOutLiteOrderOut(liteOrder.getOrderNo(),false,null);
} else {
result = liteOrderCache.checkOutLiteOrder(liteOrder.getOrderNo(), false);
}
......@@ -210,8 +209,8 @@ public class OrderController {
}
String result = "";
if ("out".equals(""/*liteO"rder.getLogo()*/)) {
result = liteOrderCache.checkOutLiteOrderOut(liteOrder.getOrderNo(),true,null,"");
if (LITEORDER_SOURCE.OUTTER.equals(liteOrder.getSource())) {
result = liteOrderCache.checkOutLiteOrderOut(liteOrder.getOrderNo(),true,null);
} else {
result = liteOrderCache.checkOutLiteOrder(liteOrder.getOrderNo(), true);
}
......@@ -226,7 +225,7 @@ public class OrderController {
@ApiOperation("尾料出库")
@PostMapping(value = "/outTails")
@PreAuthorize("@el.check('workOrder')")
public ResultBean outTails(@RequestBody Map<String, String> mapValues) {
public synchronized ResultBean outTails(@RequestBody Map<String, String> mapValues) {
String orderNo = mapValues.get("orderNo");
String orderItemId = mapValues.get("orderItemId");
List<String> orderItemIds = new ArrayList<>();
......@@ -243,7 +242,7 @@ public class OrderController {
}
String result = "";
if (LITEORDER_SOURCE.OUTTER.name().equals(liteOrder.getSource())) {
result = liteOrderCache.checkOutLiteOrderOut(liteOrder.getOrderNo(),false,orderItemIds,"");
result = liteOrderCache.checkOutLiteOrderOut(liteOrder.getOrderNo(),false,orderItemIds);
} else {
result = liteOrderCache.checkOutLiteOrder(liteOrder.getOrderNo(), false);
}
......@@ -527,6 +526,65 @@ public class OrderController {
return ResultBean.newOkResult("");
}
@ApiOperation("暂停工单")
@RequestMapping("/pauseOrder")
public ResultBean pauseOrder(@RequestBody Map<String, String> paramMap) {
String orderNo = paramMap.get("orderNo");
//根据orderNo得到正在执行的任务
Collection<DataLog> queueTasks = taskService.getQueueTasks();
if (queueTasks != null && !queueTasks.isEmpty()) {
for (DataLog queueTask : queueTasks) {
if (queueTask.isWait()) {
if (orderNo.equals(queueTask.getSourceName())) {
queueTask.setStatus(OP_STATUS.PAUSE.name());
taskService.updateQueueTask(queueTask);
}
}
}
}
//同时更改工单状态为暂停
liteOrderCache.pauseOrder(orderNo);
return ResultBean.newOkResult("");
}
@ApiOperation("工单恢复")
@RequestMapping("/restoreOrder")
public ResultBean restoreOrder(@RequestBody Map<String,String> paramMap) {
String orderNo = paramMap.get("orderNo");
//根据orderNo得到正在执行的任务
Collection<DataLog> queueTasks = taskService.getQueueTasks();
if (queueTasks != null && !queueTasks.isEmpty()) {
for (DataLog queueTask : queueTasks) {
if (queueTask.isPause()) {
if (orderNo.equals(queueTask.getSourceName())) {
queueTask.setStatus(OP_STATUS.WAIT.name());
taskService.updateQueueTask(queueTask);
}
}
}
}
liteOrderCache.restoreOrder(orderNo);
return ResultBean.newOkResult("");
}
@ApiOperation("工单超发")
@RequestMapping("/excessOrder")
public ResultBean excessOrder(@RequestBody Map<String, String> paramMap) {
boolean excess = false;
String orderNo = paramMap.get("orderNo");
String isExcess = paramMap.get("isExcess");
if (StringUtils.isNotBlank(isExcess)) {
excess = Boolean.valueOf(isExcess);
}
String result = liteOrderCache.excessOrder(orderNo, excess);
if (StringUtils.isNotBlank(result)) {
return ResultBean.newErrorResult(-1, result, null);
}
return ResultBean.newOkResult("");
}
public void addVirtualOutToFinished( LiteOrder liteOrder, Barcode barcode,Integer num, String opUser) {
try {
DataLog dataLog = new DataLog();
......
......@@ -92,4 +92,10 @@ public class OrderDto implements Serializable {
@ApiModelProperty("工单优先级")
private int priority = 0;
@ApiModelProperty("是否确认超发")
private boolean confirmExcess = false;
@ApiModelProperty("是否超发")
private boolean isExcess = false;
}
......@@ -70,7 +70,7 @@ public class OrderItemDto {
private String batchCode;
@ApiModelProperty("全部已出盘数")
private String totalOutReelCount;
private int totalOutReelCount;
@ApiModelProperty("厂商")
private String brand;
......@@ -110,4 +110,10 @@ public class OrderItemDto {
@ApiModelProperty("是否缺料")
private boolean isLack = false;
@ApiModelProperty("是否超发")
private boolean isExcess = false;
@ApiModelProperty("厂区")
private String factory;
}
......@@ -2,6 +2,7 @@ package com.neotel.smfcore.core.order.service.manager;
import com.neotel.smfcore.common.base.IBaseManager;
import com.neotel.smfcore.core.order.service.po.LiteOrderItem;
import org.springframework.data.mongodb.core.query.Query;
import java.util.List;
......@@ -9,4 +10,6 @@ public interface ILiteOrderItemManager extends IBaseManager<LiteOrderItem> {
List<LiteOrderItem> findOrderItems(String orderId);
LiteOrderItem getOrderItemByBarcode(String barcode);
int countByQuery(Query q);
}
......@@ -4,6 +4,7 @@ import com.neotel.smfcore.common.base.IBaseManager;
import com.neotel.smfcore.common.exception.ValidateException;
import com.neotel.smfcore.core.barcode.service.po.Barcode;
import com.neotel.smfcore.core.order.service.po.LiteOrder;
import org.springframework.data.mongodb.core.query.Query;
import java.util.List;
......@@ -14,4 +15,6 @@ public interface ILiteOrderManager extends IBaseManager<LiteOrder> {
List<LiteOrder> findUnEndOrdersList();
LiteOrder findBySource(String source);
List<LiteOrder> findByQueryAndPartNumber(Query q, String partNumber);
}
......@@ -32,6 +32,11 @@ public class LiteOrderItemManagerImpl implements ILiteOrderItemManager {
}
@Override
public int countByQuery(Query q) {
return liteOrderItemDao.countByQuery(q);
}
@Override
public LiteOrderItem get(String id) {
return liteOrderItemDao.findOneById(id);
}
......
......@@ -20,6 +20,7 @@ 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.Date;
import java.util.List;
......@@ -108,6 +109,34 @@ public class LiteOrderManagerImpl implements ILiteOrderManager {
}
@Override
public List<LiteOrder> findByQueryAndPartNumber(Query q, String partNumber) {
List<LiteOrder> resultOrders = new ArrayList<>();
List<LiteOrder> orders = findByQuery(q);
if (orders != null && !orders.isEmpty()) {
for (LiteOrder order : orders) {
List<LiteOrderItem> resultItems = new ArrayList<>();
List<LiteOrderItem> items = liteOrderItemManager.findOrderItems(order.getId());
if (StringUtils.isNotBlank(partNumber)) {
if (items != null && !items.isEmpty()) {
for (LiteOrderItem item : items) {
if (partNumber.equals(item.getPn())) {
resultItems.add(item);
}
}
}
} else {
resultItems = items;
}
if (resultItems != null && !resultItems.isEmpty()) {
order.setOrderItems(resultItems);
resultOrders.add(order);
}
}
}
return resultOrders;
}
@Override
public PageData<LiteOrder> findByPage(Query query, Pageable pageable) {
int totalCount = liteOrderDao.countByQuery(query);
List<LiteOrder> list = liteOrderDao.findByQuery(query, pageable);
......
......@@ -67,6 +67,12 @@ public class LiteOrder extends BasePo implements Serializable {
*/
private int status = LITEORDER_STATUS.NEW;
/**
* 上一次工单状态
*/
private int lastStatus = LITEORDER_STATUS.NEW;
private boolean closed = false;
......@@ -121,7 +127,12 @@ public class LiteOrder extends BasePo implements Serializable {
/**
* 是否超发
*/
private String isExcess;
private boolean isExcess = false;
/**
* 是否已经确认超发
*/
private boolean confirmExcess = false;
public void setClosed(boolean value){
this.closed=value;
......
......@@ -2,6 +2,7 @@ package com.neotel.smfcore.core.order.service.po;
import com.neotel.smfcore.common.base.BasePo;
import com.neotel.smfcore.core.barcode.service.po.Barcode;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.data.annotation.Transient;
import org.springframework.data.mongodb.core.mapping.Document;
......@@ -169,6 +170,27 @@ public class LiteOrderItem extends BasePo implements Serializable ,Comparable<Li
*/
private boolean isLack = false;
/**
* 缺失数量
*/
private int lackNum = 0;
/**
* 缺失盘数
*/
private int lackReel = 0;
/**
* 是否超发
*/
private boolean isExcess = false;
/**
* 厂区
*/
private String factory;
/**
* 出库是否满足要求,已出库数量大于需求数量
*/
......
......@@ -93,7 +93,6 @@ public class ReportController {
@GetMapping(value = "/inventory")
@PreAuthorize("@el.check('inventory')")
public List<InventoryGroupDto> inventory() {
String userId = SecurityUtils.getCurrentUserId();
User user = userManager.get(userId);
Set<String> mygroups = user.getGroups();
......@@ -145,20 +144,20 @@ public class ReportController {
date = initDate(date, initFormat, format, dayStartTime);
//得到白班的开始与结束时间
Date dayStartDate = DateUtil.addHours(date, -8);
Date dayStartDate = DateUtil.addHours(date, 0);
Date dayEndDate = DateUtil.addHours(dayStartDate, 12);
//得到白班的入库数据
int dayInCount = dataLogManager.getInOutDate(dayStartDate,dayEndDate, OP.PUT_IN,query.getPn());
int dayInCount = dataLogManager.getInOutData(dayStartDate,dayEndDate, OP.PUT_IN,query.getPn(),-1,"");
//得到白班的出库库数据
int dayOutCount = dataLogManager.getInOutDate(dayStartDate,dayEndDate, OP.CHECKOUT,query.getPn());
int dayOutCount = dataLogManager.getInOutData(dayStartDate,dayEndDate, OP.CHECKOUT,query.getPn(),-1,"");
//得到夜班的开始与结束时间
Date nightStartDate = dayEndDate;
Date nightEndDate = DateUtil.addHours(nightStartDate, 12);
//得到夜班班的入库数据
int nightInCount = dataLogManager.getInOutDate(nightStartDate,nightEndDate, OP.PUT_IN,query.getPn());
int nightInCount = dataLogManager.getInOutData(nightStartDate,nightEndDate, OP.PUT_IN,query.getPn(),-1,"");
//得到白班的出库库数据
int nightOutCount = dataLogManager.getInOutDate(nightStartDate,nightEndDate, OP.CHECKOUT,query.getPn());
int nightOutCount = dataLogManager.getInOutData(nightStartDate,nightEndDate, OP.CHECKOUT,query.getPn(),-1,"");
//构造返回数据
List<String> labelList = new ArrayList<>();
......
......@@ -10,7 +10,7 @@ import java.util.Date;
@Data
public class ReportQuery implements Serializable {
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern = "yyyy-MM-dd")
private BetweenData<Date> updateDate;
private String pn;
}
......@@ -54,6 +54,12 @@ public class InventoryItem {
*/
private String storageName ;
/**
* 绑定数量
*/
private int bindReel = 0;
public String getPartNumber() {
return partNumber;
}
......
......@@ -324,15 +324,105 @@ public class StorageController {
// 验证文件上传的格式
String image = "csv";
String fileType = FileUtil.getExtensionName(uploadFile.getOriginalFilename());
if(fileType != null && !image.contains(fileType)){
throw new ValidateException("smfcore.feleFormatError","文件格式错误!, 仅支持{0}格式",new String[]{image});
if (fileType != null && !image.contains(fileType)) {
throw new ValidateException("smfcore.feleFormatError", "文件格式错误!, 仅支持{0}格式", new String[]{image});
}
File folder = new File(properties.getPath(),"pos");
File folder = new File(properties.getPath(), "pos");
File file = FileUtil.upload(uploadFile, folder.getAbsolutePath());
String resultMsg = handleStoragePos(file.getAbsolutePath(),storageId);
String resultMsg = "";
Storage storage = dataCache.getStorageById(storageId);
if (!storage.isVirtual()) {
resultMsg = handleStoragePos(file.getAbsolutePath(), storageId);
} else {
//单独处理虚拟仓的
resultMsg = handleVirtualStoragePos(file.getAbsolutePath(),storageId);
}
return ResultBean.newOkResult(resultMsg);
}
private String handleVirtualStoragePos(String fileURL, String storageId) throws IOException {
log.info("开始更新料仓【" + storageId + "】的位置信息");
if (Strings.isNullOrEmpty(storageId)) {
log.error("Storage id is null");
throw new ValidateException("smfcore.valueCanotNull", "{0}不能为空", new String[]{"storageId"});
}
Storage storage = storageManager.get(storageId);
if (storage == null) {
log.error("Storage id is not exist");
throw new ValidateException("smfcore.storage.error.notExist", "未找到料仓{0}", new String[]{storageId});
}
CsvReader csvRead = CsvReader.newReader(fileURL, "位置", "pos");
int posIndex = csvRead.getCsvIndex("位置", "pos");
//int priIndex = csvRead.getCsvIndex("优先级", "pri");
//int hIndex = csvRead.getCsvIndex("高度", "h");
//int wIndex = csvRead.getCsvIndex("宽度", "w");
int pnIndex = csvRead.getCsvIndex("料号", "pn");
int row = 1;
int newRowCount = 0;
int existRowCount = 0;
int updateRowCount = 0;
List<StoragePos> storagePosList = storagePosManager.findByStorage(storage.getId());
List<StoragePos> newList = new ArrayList<>();
while (csvRead.readRecord()) {
row++;
String[] lineValues = csvRead.getValues();
String posName = lineValues[posIndex];
Integer priority = 0;
Integer height = 0;
Integer width = 0;
String partNumber = "";
try {
//priority = Integer.parseInt(lineValues[priIndex]);
//height = Integer.parseInt(lineValues[hIndex]);
//width = Integer.parseInt(lineValues[wIndex]);
partNumber = String.valueOf(lineValues[pnIndex]);
} catch (Exception ex) {
log.warn("第" + row + "行中有空白内容,此行忽略");
continue;
}
if (posName.isEmpty()) {
log.warn("第" + row + "行中有空白内容,此行忽略");
continue;
}
// StoragePos posInfo = storagePosManager.getByPosName(posName);
StoragePos posInfo = findFormList(storagePosList, posName);
if (posInfo == null) {
posInfo = new StoragePos(storageId, posName, height, width, priority);
posInfo.setPartNumber(partNumber);
posInfo.setShowStatus(0 + "");
newRowCount++;
newList.add(posInfo);
} else {
//boolean needUpdate = posInfo.updatePosInfo(storageId, posName, height, width, priority);
boolean needUpdate = false;
if (!partNumber.equals(posInfo.getPartNumber())) {
posInfo.setPartNumber(partNumber);
needUpdate = true;
}
if (needUpdate) {
updateRowCount++;
posInfo.setShowStatus(0 + "");
storagePosManager.save(posInfo);
} else {
existRowCount++;
}
}
}
if (newList.size() > 0) {
storagePosManager.insertAll(newList);
}
dataCache.reloadStorage(storage, "");
String msg = "读取到[" + row + "]行数据:新增【" + newRowCount + "】,已存在【" + existRowCount + "】,更新【" + updateRowCount + "】";
log.info(msg);
return msg;
}
@ApiOperation("下载库位模板")
@GetMapping(value = "/downloadPosModel")
......@@ -354,6 +444,7 @@ public class StorageController {
titles.add("pri");
titles.add(("h"));
titles.add("w");
titles.add("pn");
for(int i=1;i<=10;i++) {
Map<String, Object> map = new LinkedHashMap<>();
......@@ -362,6 +453,7 @@ public class StorageController {
map.put("pri", i);
map.put("h", 8);
map.put("w", 7);
map.put("pn","虚拟仓填写料号");
maps.add(map);
}
......
......@@ -107,8 +107,8 @@ public class StoragePosController {
blurry = blurry.substring(blurry.indexOf("-")+1);
criteria.setBlurry(blurry);
}
Query query = QueryHelp.getQuery(criteria);
//query.addCriteria(Criteria.where("showStatus").ne("0").exists(false));
PageData<StoragePos> pages = storagePosManager.findByPage(query, pageable);
List<StoragePosDto> StoragePosDtos = storagePosMapper.toDto(pages.getContent());
......@@ -359,7 +359,7 @@ public class StoragePosController {
@ApiOperation("根据条件查找出库")
@GetMapping("/out")
@AnonymousAccess
public ResultBean storagePosFind(StoragePosFindCriteria criteria) {
public synchronized ResultBean storagePosFind(StoragePosFindCriteria criteria) {
//判断查询条件是否为空
String provider = criteria.getProvider();
String batch = criteria.getBatch();
......@@ -382,6 +382,8 @@ public class StoragePosController {
Query query = getPosFindCriteria(criteria);
List<StoragePos> storagePoss = storagePosManager.findByQuery(query);
//判断是否有出库任务
boolean hasOutReel = false;
if (storagePoss != null && !storagePoss.isEmpty()) {
String selectMsg = getSelectMsg(partNumber, provider, batch, dateCode);
for (StoragePos pos : storagePoss) {
......@@ -398,16 +400,23 @@ public class StoragePosController {
log.info("库位:" + pos.getPosName() + "正在执行,跳过");
continue;
}
//判断是否有出库任务
boolean hasOutReel = false;
hasOutReel = true;
List<Barcode> subCodeList = pidBarcode.getSubCodeList();
if (subCodeList != null && !subCodeList.isEmpty()) {
for (Barcode barcode : subCodeList) {
if (barcode.isOut()){
if (barcode.isOut()) {
continue;
}
List<String> partNumberList = criteria.getPartNumberList();
if (partNumberList != null && !partNumberList.isEmpty()) {
if (!partNumberList.contains(barcode.getPartNumber())) {
boolean hasCont = false;
for (String pn : partNumberList) {
if (barcode.getPartNumber().startsWith(pn)){
hasCont = true;
break;
}
}
if (!hasCont){
continue;
}
}
......@@ -439,7 +448,7 @@ public class StoragePosController {
barcode = barcodeManager.save(barcode);
pidBarcode.UpdateSubCode(barcode);
barcodeManager.saveBarcode(pidBarcode);
hasOutReel = true;
}
}
if (hasOutReel) {
......@@ -454,11 +463,14 @@ public class StoragePosController {
task.setLoc(stationName);
}
task.setBoxPosName(pos.getPosName());
taskService.addTaskToExecute(task);
//task.setPosId(pos.getId());
taskService.updateQueueTask(task);
}
}
if (hasOutReel) {
return ResultBean.newOkResult("");
}
}
return ResultBean.newErrorResult(-1, "", "未找到可以出库的物料");
}
......
......@@ -69,5 +69,17 @@ public interface IStoragePosManager extends IBaseManager<StoragePos> {
StoragePos getEmptyPosByStorage(Storage storage, Barcode barcode, Collection<String> excludePosIds, String lastPosId,String logo) throws ValidateException;
StoragePos findPartNumberInStorages(List<String> availableStorageIds, String pn, Collection<String> excludePosIds, CHECKOUT_TYPE checkoutType, String warehouseCode, String brand);
StoragePos findPartNumberInStorages(List<String> availableStorageIds, String pn, Collection<String> excludePosIds, CHECKOUT_TYPE checkoutType, String warehouseCode, String brand,boolean isOut);
StoragePos findOne(Query query);
List<StoragePos> findNotEmptyPosNameByStorageId(String storageId);
StoragePos findOneEmptyPosNameByStorageId(String storageId,String posName);
List<StoragePos> findEmptyByStorageId(String storageId);
List<StoragePos> findNotEmptyPosName();
StoragePos getPosNameByPnAndStrId(String partNumber,String storageId);
}
......@@ -81,16 +81,16 @@ public class StorageManagerImpl implements IStorageManager {
*/
@Override
public List<ChartItem> getRunStatusData(Date fromDate, Date toDate, String partNumber){
if(fromDate == null || toDate == null){
/*if(fromDate == null || toDate == null){
return new ArrayList<>();
}
LinkedHashMap<String,ChartItem> inOutDataMap = new LinkedHashMap<>();
Date startDay = DateUtil.getMinDate(fromDate, toDate);
Date endDay = DateUtil.getMaxDate(fromDate,toDate);
/**
*//**
* 结束时间+1天,包含结束那一天
*/
*//*
long endTime = endDay.getTime();
Calendar c = Calendar.getInstance();
c.setTime(startDay);
......@@ -121,7 +121,7 @@ public class StorageManagerImpl implements IStorageManager {
if(item != null){
item.setCheckOutValue(checkOutItem.getValue());
}
}
}*/
// List<ChartItem> alarmData = alarmInfoDao.alarmChart(startDay, endDay);
// for (ChartItem alarmItem : alarmData){
......@@ -143,6 +143,6 @@ public class StorageManagerImpl implements IStorageManager {
// }
//alarmInfoDao.alarmChartByType(startDay,endDay);
//alarmInfoDao.alarmChartByBox(startDay,endDay);
return new ArrayList<>(inOutDataMap.values());
return new ArrayList<>(/*inOutDataMap.values()*/);
}
}
......@@ -41,6 +41,9 @@ public class StoragePosManagerImpl implements IStoragePosManager {
@Autowired
private IStoragePosDao storagePosDao;
/*@Autowired
private DataCache dataCache;
*/
@Override
public List<PlateSizeBean> getStoragePosUsage(String storageId){
Aggregation agg = Aggregation.newAggregation(
......@@ -128,10 +131,60 @@ public class StoragePosManagerImpl implements IStoragePosManager {
inventoryMap.put(partNumber,inventoryItem);
}
//获取agv类型的库存
Map<String,InventoryItem> agvInventory = getAgvBoxInventory(storageIds);
if (agvInventory != null && agvInventory.size() >0){
inventoryMap.putAll(agvInventory);
}
return inventoryMap;
}
/**
* 得到agvBox存储信息
* @param storageIds
* @return
*/
private Map<String, InventoryItem> getAgvBoxInventory(String...storageIds) {
Map<String, InventoryItem> resultMap = new HashMap<>();
for (String storageId : storageIds) {
/*Storage storage = dataCache.getStorageById(storageId);
if (!storage.isType(new DeviceType[]{DeviceType.AGV_BOX})) {
continue;
}*/
List<StoragePos> storagePoss = findNotEmptyByStorageId(storageId);
//开始循环处理
if (storagePoss != null && !storagePoss.isEmpty()) {
for (StoragePos pos : storagePoss) {
List<Barcode> subCodeList = pos.getBarcode().getSubCodeList();
if (subCodeList != null && !subCodeList.isEmpty()) {
for (Barcode barcode : subCodeList) {
InventoryItem item = resultMap.get(barcode.getPartNumber());
if (item != null) {
item.setStockReel(item.getStockReel() + 1);
item.setStockCount(item.getStockCount() + barcode.getAmount());
} else {
item = new InventoryItem();
item.setPartNumber(barcode.getPartNumber());
item.setStockCount(barcode.getAmount());
item.setStockReel(1);
}
resultMap.put(barcode.getPartNumber(), item);
}
}
}
}
}
return resultMap;
}
/**
* 统计多少个小时内即将过期的物料(inHours 为0表示截止到目前已经过期的,为1表示1个小时后过期,但现在还没过期的)
* @param storageIds
......@@ -240,10 +293,11 @@ public class StoragePosManagerImpl implements IStoragePosManager {
c = c.and("storageId").is(storageId);
}
Query query = new Query(c);
query.with(Sort.by(Sort.Direction.ASC, "updateDate"));
//query.with(Sort.by(Sort.Direction.ASC, "updateDate"));
return storagePosDao.findByQuery(query);
}
@Override
public List<StoragePos> findLockPos(String lockId) {
Criteria c = Criteria.where("barcode.lockId").is(lockId);
......@@ -280,10 +334,9 @@ public class StoragePosManagerImpl implements IStoragePosManager {
@Override
public StoragePos findPartNumberInStorages(List<String> storageIdList, String pn, Collection<String> excludePosIds, CHECKOUT_TYPE checkOutType, String warehouseCode, String brand) {
Criteria c = Criteria.where("id").nin(excludePosIds)
.and("enabled").is(true)//可用
.and("barcode.lockId").is(null);//没有被锁定的仓位;
public StoragePos findPartNumberInStorages(List<String> storageIdList, String pn, Collection<String> excludePosIds, CHECKOUT_TYPE checkOutType, String warehouseCode, String brand, boolean isOut) {
Criteria c = Criteria.where("id").nin(excludePosIds);
// .and("enabled").is(true)//可用//.and("barcode.lockId").is(null);//没有被锁定的仓位;
if (storageIdList != null) {
c = c.and("storageId").in(storageIdList);
}
......@@ -296,6 +349,9 @@ public class StoragePosManagerImpl implements IStoragePosManager {
if (ObjectUtil.isNotEmpty(pn)) {
c.and("barcode.subCodeList.partNumber").is(pn);
}
if (isOut){
c.and("barcode.subCodeList.isOut").is(isOut);
}
Sort sort = getSortByCheckOutType(checkOutType);
Query q = new Query(c);
q.with(sort);
......@@ -308,6 +364,52 @@ public class StoragePosManagerImpl implements IStoragePosManager {
return pos;
}
@Override
public StoragePos findOne(Query query) {
return storagePosDao.findOne(query);
}
@Override
public List<StoragePos> findNotEmptyPosNameByStorageId(String storageId) {
Criteria c = Criteria.where("barcode").exists(true)
.and("enabled").is(true);//可用;
if(!Strings.isNullOrEmpty(storageId)){
c = c.and("storageId").is(storageId);
}
Query query = new Query(c);
query.fields().include("posName").exclude("id");
return storagePosDao.findByQuery(query);
}
@Override
public StoragePos findOneEmptyPosNameByStorageId(String storageId,String posName) {
Criteria c = Criteria.where("barcode").exists(false)
.and("enabled").is(true);//可用;
if (!Strings.isNullOrEmpty(storageId)) {
c = c.and("storageId").is(storageId);
}
if (!Strings.isNullOrEmpty(posName)) {
Pattern pattern = Pattern.compile(QueryHelp.escapeExprSpecialWord(posName), Pattern.CASE_INSENSITIVE);
c = c.and("posName").regex(pattern);
}
c.and("partNumber").exists(false);
Query query = new Query(c);
return storagePosDao.findOne(query);
}
@Override
public List<StoragePos> findEmptyByStorageId(String storageId){
Criteria c = Criteria.where("barcode").exists(false)
.and("enabled").is(true);//可用;
if(!Strings.isNullOrEmpty(storageId)){
c = c.and("storageId").is(storageId);
}
Query query = new Query(c);
//query.with(Sort.by(Sort.Direction.ASC, "updateDate"));
return storagePosDao.findByQuery(query);
}
/**
* 根据出库方式获取不同的 Sort
*/
......@@ -666,5 +768,16 @@ public class StoragePosManagerImpl implements IStoragePosManager {
return prefixStr +String.format("%0"+posIndexStr.length()+"d",nextPosIndex);
}
public List<StoragePos> findNotEmptyPosName(){
Criteria c = Criteria.where("barcode").exists(true)
.and("enabled").is(true);//可用;
Query query = new Query(c);
query.fields().include("posName").include("storageId").include("barcode.barcode").include("barcode.subCodeList.posName");
return storagePosDao.findByQuery(query);
}
@Override
public StoragePos getPosNameByPnAndStrId(String partNumber,String storageId) {
return storagePosDao.findOne(new Query(Criteria.where("partNumber").is(partNumber).and("storageId").is(storageId)));
}
}
......@@ -117,6 +117,17 @@ public class StoragePos extends BasePo implements Serializable {
private List<String> mergePosList;
/**
* 1:展示 0:不展示
*/
private String showStatus;
/**
* 虚拟仓对应料号
*/
private String partNumber;
public String getLabelStr(){
String posNameLabel = posName;
int index = posNameLabel.lastIndexOf(":");
......
......@@ -15,6 +15,7 @@ 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.Date;
import java.util.List;
......@@ -36,7 +37,7 @@ public class DataLogDaoImpl extends AbstractBaseDao implements IDataLogDao {
}
private List<ChartItem> chart(Date fromTime, Date toTime, int type, String partNumber){
Date addOneDayToTime = DateUtil.addOneDayNoTime(toTime);
/* Date addOneDayToTime = DateUtil.addOneDayNoTime(toTime);
Criteria c = new Criteria().andOperator(Criteria.where("updateDate").gte(fromTime),
Criteria.where("updateDate").lt(addOneDayToTime)).and("type").is(type);
c.and("status").in(OP_STATUS.END.name(),OP_STATUS.FINISHED.name());
......@@ -50,7 +51,8 @@ public class DataLogDaoImpl extends AbstractBaseDao implements IDataLogDao {
Aggregation.project("value").and("label").previousOperation()
);
AggregationResults<ChartItem> results = getMongoTemplate().aggregate(agg, getEntityClass(), ChartItem.class);
return results.getMappedResults();
return results.getMappedResults();*/
return new ArrayList<>();
}
@Override
......
......@@ -2,6 +2,7 @@ package com.neotel.smfcore.core.system.service.manager;
import com.neotel.smfcore.common.base.IBaseManager;
import com.neotel.smfcore.core.system.service.po.DataLog;
import org.springframework.data.domain.Pageable;
import java.util.Date;
import java.util.List;
......@@ -9,5 +10,9 @@ import java.util.List;
public interface IDataLogManager extends IBaseManager<DataLog> {
List<DataLog> findUnFinishedTasks();
int getInOutDate(Date startDate, Date endDate, int type, String partNumber);
int getInOutData(Date startDate, Date endDate, int type, String partNumber,int extendType,String storageId);
List<DataLog> getDatalogs(String orderNo, String line, Pageable pageable);
int getInOutData(Date startDate, Date endDate, int type,String stationName);
}
......@@ -2,10 +2,14 @@ package com.neotel.smfcore.core.system.service.manager.impl;
import com.neotel.smfcore.common.bean.PageData;
import com.neotel.smfcore.common.exception.ValidateException;
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.device.enums.OP_STATUS;
import com.neotel.smfcore.core.system.service.dao.IDataLogDao;
import com.neotel.smfcore.core.system.service.manager.IDataLogManager;
import com.neotel.smfcore.core.system.service.po.DataLog;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
......@@ -17,7 +21,9 @@ import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.regex.Pattern;
@Slf4j
@Service
public class DataLogManagerImpl implements IDataLogManager {
......@@ -54,7 +60,7 @@ public class DataLogManagerImpl implements IDataLogManager {
@Override
public List<DataLog> findUnFinishedTasks( ) {
Criteria c = Criteria.where("status").nin(OP_STATUS.FINISHED.name(),OP_STATUS.CANCEL.name());
//只查找近12个小时未完成的任务
//只查找近48个小时未完成的任务
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.HOUR_OF_DAY,-48);
c.and("updateDate").gte(calendar.getTime());
......@@ -67,7 +73,7 @@ public class DataLogManagerImpl implements IDataLogManager {
}
@Override
public int getInOutDate(Date startDate, Date endDate, int type, String partNumber) {
public int getInOutData(Date startDate, Date endDate, int type, String partNumber,int extendType,String storageId) {
Query query = new Query();
Criteria criteria = new Criteria().andOperator(Criteria.where("updateDate").gte(startDate),
Criteria.where("updateDate").lt(endDate)).and("type").is(type);
......@@ -75,6 +81,39 @@ public class DataLogManagerImpl implements IDataLogManager {
if (Strings.isNotBlank(partNumber)) {
criteria.and("partNumber").is(partNumber);
}
if (-1 != extendType){
criteria.and("extendType").is(extendType);
}
if (Strings.isNotBlank(storageId)){
criteria.and("storageId").is(storageId);
}
return dataLogDao.countByQuery(query.addCriteria(criteria));
}
@Override
public List<DataLog> getDatalogs(String orderNo, String line, Pageable pageable) {
Criteria c = new Criteria();
if (StringUtils.isNotBlank(orderNo)) {
c.and("orderNo").is(orderNo);
}
if (StringUtils.isNotBlank(line)) {
Pattern p = Pattern.compile(QueryHelp.escapeExprSpecialWord(line), Pattern.CASE_INSENSITIVE);
c.and("line").regex(p);
}
PageData<DataLog> data = findByPage(new Query(c), pageable);
//log.info("orderNo:"+orderNo+",line:"+line+",数量为:"+data.getTotalElements());
return data.getContent();
}
@Override
public int getInOutData(Date startDate, Date endDate, int type, String stationName) {
Query query = new Query();
Criteria criteria = new Criteria().andOperator(Criteria.where("updateDate").gte(startDate),
Criteria.where("updateDate").lt(endDate)).and("type").is(type);
criteria.and("status").in(OP_STATUS.END.name(), OP_STATUS.FINISHED.name());
if (Strings.isNotBlank(stationName)) {
criteria.and("stationName").is(stationName);
}
return dataLogDao.countByQuery(query.addCriteria(criteria));
}
}
......@@ -235,6 +235,7 @@ public class DataLog extends BasePo implements Serializable {
*/
private String warehouseCode;
/**
* 厂别
*/
......@@ -270,16 +271,57 @@ public class DataLog extends BasePo implements Serializable {
*/
private String boxPosName;
/**
* 机器名称
*/
private String machineName;
/**
* 段别
*/
private String slot;
/**
* 站别
*/
private String subSlot;
/**
* 台车号
*/
private String tableNo = "";
/**
* 隔口数量
* 异动类型
*/
private int partitionCount = 0;
private String changeType;
/**
* 厂区
*/
private String factory;
/**
* 储位
*/
private String storagePosName;
/**
* 工位名称
*/
private String stationName;
/**
* MSD附加信息
*/
private MSDAppendInfo msdAppendInfo;
/**
* 出库类型(手动喂料,清空库位,智能仓储出库,手动出库,虚拟仓入库,虚拟仓出库,智能仓储入库)
*/
private int extendType;
public String getBarcode() {
if(barcode == null){
return "";
......@@ -325,6 +367,10 @@ public class DataLog extends BasePo implements Serializable {
return OP_STATUS.END.name().equals(status);
}
public boolean isPause(){
return OP_STATUS.PAUSE.name().equals(status);
}
public boolean isTaskInStatus(OP_STATUS taskStatus){
return taskStatus.name().equals(status);
}
......
......@@ -29,6 +29,7 @@ import com.neotel.smfcore.core.storage.service.po.StoragePos;
import com.neotel.smfcore.core.system.bean.MSDAppendInfo;
import com.neotel.smfcore.core.system.service.dao.IDataLogDao;
import com.neotel.smfcore.core.system.service.po.DataLog;
import com.neotel.smfcore.custom.lizhen.innerBox.enums.ExtendType;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
......@@ -67,7 +68,10 @@ public class TaskService {
*/
private static Map<String, DataLog> theFinishedTaskMap = Maps.newConcurrentMap();
private static String posLogo = "";
/**
* key为料仓cid,value为A/B面
*/
private static Map<String,String> posSideMap = Maps.newConcurrentMap();
// public TaskService(List<ITaskListener> listenerList){
// for (ITaskListener taskListener: listenerList) {
......@@ -83,7 +87,7 @@ public class TaskService {
DataLog task = new DataLog(storage, barcode, storagePos);
task.setType(OP.PUT_IN);
task.setStatus(OP_STATUS.EXECUTING.name());
task.setExtendType(ExtendType.STORAGE_PUTIN); //智能仓储入库
if(barcode!=null){
barcode.setPutInTime(System.currentTimeMillis());
barcode.updateSluggishTime(dataCache.getPNsluggishDay(barcode.getPartNumber()));
......@@ -133,10 +137,10 @@ public class TaskService {
// return "";
}
Barcode barcode = pos.getBarcode();
DataLog task = new DataLog(storage, pos.getBarcode(), pos);
task.setType(OP.CHECKOUT);
task.setPutInDate(pos.getBarcode().getPutInDate());
task.setStatus(OP_STATUS.WAIT.name());
task.setPutInDate(barcode.getPutInDate());
task.setSingleOut(isSingleOut);
task.setOperator(opUserName);
task.setStorageId(storage.getId());
......@@ -144,7 +148,13 @@ public class TaskService {
task.setLoc(stationName);
}
task.setBoxPosName(pos.getPosName());
/*if (barcode.getBarcode().startsWith("CS") || barcode.getBarcode().startsWith("CM") || barcode.getBarcode().startsWith("CB")){
task.setStatus(OP_STATUS.FINISHED.name());
addTaskToFinished(pos,barcode,SecurityUtils.getCurrentUsername());
} else {*/
task.setStatus(OP_STATUS.WAIT.name());
addTaskToExecute(task);
//}
return "";
}
......@@ -688,27 +698,33 @@ public class TaskService {
for (Storage storage : availbleStorageList) {
try {
String posSide = "";
Collection<String> operatingPosIds = excludePosIds();
log.debug("尝试从[" + storage.getCid() + "]中为[" + barcode.getBarcode() + "]查找空位");
StoragePos pos = null;
if (storage.isType(new DeviceType[]{DeviceType.SMD_XLR})) {
if (StringUtils.isNotBlank(posLogo)) {
if ("AA".equals(posLogo)) {
posLogo = "BB";
//根据cid获取下一个放入的面别
String side = posSideMap.get(storage.getCid());
if (side != null) {
if ("AA".equals(side)) {
posSide = "BB";
} else {
posLogo = "AA";
posSide = "AA";
}
posSideMap.put(storage.getCid(),posSide);
} else {
posLogo = "AA";
posSide = "AA";
posSideMap.put(storage.getCid(),posSide);
}
pos = storagePosManager.getEmptyPosByStorage(storage, barcode, operatingPosIds, lastPosId, posLogo);
pos = storagePosManager.getEmptyPosByStorage(storage, barcode, operatingPosIds, lastPosId, posSide);
if (pos == null) {
if ("AA".equals(posLogo)) {
posLogo = "BB";
if ("AA".equals(posSide)) {
posSide = "BB";
} else {
posLogo = "AA";
posSide = "AA";
}
pos = storagePosManager.getEmptyPosByStorage(storage, barcode, operatingPosIds, lastPosId, posLogo);
posSideMap.put(storage.getCid(),posSide);
pos = storagePosManager.getEmptyPosByStorage(storage, barcode, operatingPosIds, lastPosId, posSide);
}
} else {
pos = storagePosManager.getEmptyPosByStorage(storage, barcode, operatingPosIds, lastPosId);
......@@ -801,6 +817,9 @@ public class TaskService {
if (pos.getBarcode() != null) {
//barcode = pos.getBarcode();
barcode = barcodeManager.findByBarcode(pos.getBarcode().getBarcode());
if (barcode == null){
barcode = pos.getBarcode();
}
for (DataLog task : allTasks) {
if (task.isCheckOutTask()) {
String executeBarcode = task.getBarcode();
......@@ -858,6 +877,9 @@ public class TaskService {
} else {
//barcode = pos.getBarcode();
barcode = barcodeManager.findByBarcode(pos.getBarcode().getBarcode());
if (barcode == null){
barcode = pos.getBarcode();
}
log.info(opUser + "将【" + barcode.getBarcode() + "】从【" + pos.getPosName() + "】出库");
task.setType(OP.CHECKOUT);
barcode.setUsed(true);
......@@ -877,7 +899,7 @@ public class TaskService {
task.setOperator(opUser);
task.setStatus(OP_STATUS.FINISHED.name());
task.setExtendType(ExtendType.CLEAR_POS); //手动清空库位
updateFinishedTask(task);
} catch (Exception e) {
......@@ -968,7 +990,13 @@ public class TaskService {
public synchronized void tacticsCheckOut(Set<TacticsOutDto> tacticsOutDtos) {
CHECKOUT_TYPE checkoutType = dataCache.getCheckOutType();
List<String> availableStorageIds = dataCache.getAvailableStorageIds();
//List<String> availableStorageIds = dataCache.getAvailableStorageIds();
List<String> availableStorageIds = new ArrayList<>();
for (Storage storage : dataCache.getAllStorage().values()) {
if (!storage.isVirtual()) {
availableStorageIds.add(storage.getId());
}
}
//其他出库模式一次性全部生成任务
......@@ -993,6 +1021,7 @@ public class TaskService {
log.info("策略出库,PN[" + item.getPartNumber() + "]第[" + i + "]盘, 出库位置仓位【" + pos.getPosName() + "】RI=[" + pos.getBarcode().getBarcode() + "] PN=[" + partNumber + "] num:" + pos.getBarcode().getAmount());
DataLog task = newTask(pos);
task.setType(OP.CHECKOUT);
task.setExtendType(ExtendType.MANUAL_CHECKOUT); //手动出库
task.setOperator(SecurityUtils.getCurrentUsername());
task.setSingleOut(true);
task.setSourceId(null);
......
......@@ -15,6 +15,8 @@ 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.po.Storage;
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;
......@@ -53,6 +55,9 @@ public class LizhenApi extends DefaultSmfApiListener {
@Value("${api.werks}")
private String werks;
@Value("${api.outNotifyUrlPK}")
private String outNotifyUrlPK = "";
@PostConstruct
public void init(){
......@@ -61,6 +66,7 @@ public class LizhenApi extends DefaultSmfApiListener {
plant = dataCache.getConfigCache("plant",plant);
barcodeInfoUrl = dataCache.getConfigCache("barcodeInfoUrl",barcodeInfoUrl);
werks = dataCache.getConfigCache("werks",werks);
outNotifyUrlPK = dataCache.getConfigCache("api.outNotifyUrlPK",outNotifyUrlPK);
}
/**
......@@ -145,6 +151,9 @@ public class LizhenApi extends DefaultSmfApiListener {
* @return
*/
public Barcode barcodeInfo(Barcode barcode) {
if (barcodeInfoUrl == null){
return null;
}
log.info("获取MES物料数量入参为:" + barcode.getBarcode());
try {
String result = HttpHelper.postJson(barcodeInfoUrl, barcode.getBarcode());
......@@ -231,7 +240,7 @@ public class LizhenApi extends DefaultSmfApiListener {
}
if (StringUtils.isNotBlank(resultStr)) {
throw new ValidateException("smfcore.mesApi.inCheck.ng", "MES验证失败:" + barcode.getBarcode() + "验证失败:" + resultStr);
throw new ValidateException("smfcore.mesApi.inCheck.ng", /*"MES验证失败:" + */barcode.getBarcode() + "验证失败:" + resultStr);
}
return barcode;
}
......@@ -245,6 +254,9 @@ 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", "");
......@@ -258,6 +270,7 @@ public class LizhenApi extends DefaultSmfApiListener {
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","");
......@@ -287,30 +300,57 @@ public class LizhenApi extends DefaultSmfApiListener {
return;
}
if (!task.isFinished()) {
return;
}
Map<String, Object> dataMap = new HashMap<>();
dataMap.put("pickingid", "");
if (StringUtils.isNotBlank(task.getSourceName())) {
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());
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", "");
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(barcode.getBarcode() + "保存物料异常:" + e.getMessage());
}
dataMap.put("werks",werks);
dataMap.put("reelid","");
} else {
String param = JsonUtil.toJsonStr(Arrays.asList(dataMap));
log.info("保存物料入参为:" + param);
log.info("保存物料入参为:" + param + "地址为:" + outNotifyUrl);
try {
String result = HttpHelper.postJson(outNotifyUrl, Arrays.asList(dataMap));
log.info("保存物料出参为:" + result);
} catch (ApiException e) {
e.printStackTrace();
log.info(barcode.getBarcode()+"保存物料异常:"+e.getMessage());
log.info(barcode.getBarcode() + "保存物料异常:" + e.getMessage());
}
}
}
......
......@@ -205,7 +205,7 @@ public class LizhenController {
item.setSubslot(data.get("SUBSLOT"));
item.setPartnumber(data.get("PARTNUMBER"));
item.setLine(data.get("LINE"));
item.setId(data.get("ID"));
item.setItemId(data.get("ID"));
item.setPriority(Integer.valueOf(data.get("PRIORITY")));
PreWarningItemCache.addItems(Arrays.asList(item));
return ResultBean.newOkResult("");
......
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.enums;
/**
* 异动类型
*/
public enum CHANGE_TYPE {
PICKING_DETAIL("PK发料"),
GR_PUTIN("GR入库"),
MANUAL_PUTIN("手动入库"),
MANUAL_CHECKOUT("手动出库"),
TASK_CANNEL("任务取消"),
VIRTUAL_PICKING_DETAIL("虚拟仓PK发料"),
VIRTUAL_CHECKOUT("虚拟仓出库");
private final String name;
CHANGE_TYPE(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
package com.neotel.smfcore.custom.lizhen.agvBox.enums;
/*
出入库类型
*/
public enum INOUT_TYPE {
/**
* 单盘入库
*/
IN_ONE,
/**
* 整箱入库
*/
IN_BOX,
/**
* 单盘出库
*/
OUT_ONE,
/**
* 隔口出库
*/
OUT_PARTITION,
/**
* 整箱出库
*/
OUT_BOX,
/**
* 单盘取消
*/
CANCEL_ONE
}
......@@ -3,6 +3,7 @@ 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;
......@@ -31,6 +32,7 @@ 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;
/**
......@@ -135,14 +137,17 @@ public class AgvBoxDeviceClientController {
@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) {
//小车限制,默认一次生成200个任务
if (taskToSend != null && taskToSend.size() >= 200) {
//小车限制,默认一次生成8个任务
if (taskToSend != null && taskToSend.size() >= 8) {
break;
}
if (queueTask.isCheckOutTask()) {
if (queueTask.isWait() || queueTask.isExecuting()) {
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<>();
......@@ -154,6 +159,28 @@ public class AgvBoxDeviceClientController {
}
}
}
}
//出手动的
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);
}
......@@ -214,14 +241,14 @@ public class AgvBoxDeviceClientController {
String stationRfid = station.getCurrentRfid();
if(Strings.isBlank(stationRfid)){
//该工位目前无料箱
if (lockRfidTarget.get(station.getName()) == null) {
/*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();
}*/
Collection<String> names = lockRfidTarget.values();
if (names != null && !names.isEmpty()){
if (!names.contains(station.getName())) {
//工位未分配过库位
......@@ -235,9 +262,32 @@ public class AgvBoxDeviceClientController {
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);
}
}
}
......@@ -267,7 +317,7 @@ public class AgvBoxDeviceClientController {
String rfid = request.getParameter("barcode");
String statusStr = request.getParameter("status");
String loc = request.getParameter("loc"); //工位
log.debug("收到料盘[" + rfid + "]更新位置指令[" + statusStr + "]");
log.info("收到料盘[" + rfid + "]更新位置指令[" + statusStr + "]");
if (statusStr == null) {
return ResultBean.newErrorResult(301, "smfcore.updateLoc.status.empty", "状态不能为空");
}
......@@ -295,11 +345,16 @@ public class AgvBoxDeviceClientController {
}
statusStr = statusStr.toUpperCase();
log.info("更新料箱[" + rfid + "]的任务状态[" + opTask.getStatus() + "]为[" + statusStr + "]");
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
......@@ -316,13 +371,14 @@ public class AgvBoxDeviceClientController {
if (OP_STATUS.EXECUTING.name().equals(statusStr)) {
//在执行队列中
taskService.updateQueueTask(opTask);
} else if (OP_STATUS.NEED_AWAY.name().equals(statusStr)){
} /*else if (OP_STATUS.NEED_AWAY.name().equals(statusStr)) {
//判断当前任务是否需要取走状态,如果已经是
if (!OP_STATUS.NEED_AWAY.name().equals(statusOri)) {
*//*if (!OP_STATUS.NEED_AWAY.name().equals(statusOri)) {
WebSocketServer.sendMsg(new SocketMsg(Arrays.asList(loc), rfid + "需出库到工位:" + loc + "上", MsgType.INFO, "", null));
}
}
else {
}*//*
opTask.setLoc(loc);
taskService.updateFinishedTask(opTask);
}*/ else {
taskService.moveTaskToFinished(opTask);
if (OP_STATUS.OUT_ON_AGV.name().equals(statusStr)) {
......@@ -347,7 +403,8 @@ public class AgvBoxDeviceClientController {
lockRfidTarget.remove(opTask.getBarcode());
intoPos(opTask);
//清理锁定库位
ReelLockPosUtil.removeReelLockPosInfo(rfid.replace("A","").replace("B",""));
//rfid = rfid.substring(0,rfid.length()-1);
ReelLockPosUtil.removeReelLockPosInfo(rfid);
} else {
taskService.updateQueueTask(opTask);
}
......@@ -359,6 +416,32 @@ public class AgvBoxDeviceClientController {
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 {
results.add(queueTask.getBarcode() + "需要出库");
}
}
}
}
return ResultBean.newOkResult(results);
}
/**
* 料箱从仓位中取出
*/
......@@ -387,7 +470,13 @@ public class AgvBoxDeviceClientController {
if (barcode != null) {
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());
}
}
}
//更新缓存中的库存信息
opTask.setStatus(OP_STATUS.FINISHED.name());
......@@ -430,6 +519,14 @@ public class AgvBoxDeviceClientController {
//更新缓存中的库存信息
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());
}
}
}
/**
......
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.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.StationCacheUtil;
import com.neotel.smfcore.security.annotation.AnonymousAccess;
import com.sun.org.apache.regexp.internal.RE;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.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.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
@Slf4j
@RestController
@RequestMapping("/outLine")
public class OutLineStorageController {
@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;
/*
* 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[]{"条码编号"});
}
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())) {
//如果是隔口,获取到料箱号
boxStr = barcode.getBarcode();
//判断尺寸与箱子是否一致
if (platSize == 7) {
if (!code.startsWith("CS")) {
return ResultBean.newErrorResult(-1, "", "物料规格为7寸与当前工位上的料箱:" + boxStr + "不匹配");
}
} /*else if (platSize == 13) {
if (!code.startsWith("CM")) {
return ResultBean.newErrorResult(-1, "", "物料规格为13寸与当前工位上的料箱:" + boxStr + "不匹配");
}
}*/ else if (platSize == 15) {
if (!code.startsWith("CB") && !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());
}
}
barcode.setReelAmount(1);
barcode.setWarehouseCode(warehouseCode);
barcode.setPosName(boxPartition);
String result = finishTask(boxStr, OP.PUT_IN, barcode, barcode.getAmount(), OP_STATUS.FINISHED.name());
if (StringUtils.isNotBlank(result)) {
return ResultBean.newErrorResult(-1, "", result);
}
}
return ResultBean.newOkResult(getBoxPartitionNum(boxStr, boxSideStr, boxPartition));
}
@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");
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()});
}
//如果不是虚拟仓的
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);
} 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);
taskService.moveTaskToFinished(task);
taskService.updateFinishedTask(task);
taskService.removeFinishedTask(task);
}
return ResultBean.newOkResult("");
}
@ApiOperation("线外扫码出库")
@RequestMapping("/checkOut")
//@AnonymousAccess
public ResultBean checkOut(@RequestBody Map<String, String> paramMap) {
String code = paramMap.get("code");
//判断是否整箱出库
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() + "不允许全部取出,请核实");
}
}
//开始循环,生成任务
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);
subCode = barcodeManager.save(subCode);
pidBarcode.UpdateSubCode(subCode);
pidBarcode.setReelAmount(pidBarcode.getReelAmount() - 1);
pidBarcode.setAmount(pidBarcode.getAmount() - amount);
pidBarcode = barcodeManager.save(pidBarcode);
generateTask(subCode, opStatus, amount, opType, orderItemId);
log.info("整箱出库,生成出库任务,barcode:" + subCode.getBarcode() + ",料箱号为:" + pidBarcode.getBarcode());
if (subCode.getAmount() <= 0) {
barcodeManager.delete(subCode);
}
}
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 + "不允许全部出库,请核实");
}
}
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);
subCode = barcodeManager.save(subCode);
pidBarcode.UpdateSubCode(subCode);
pidBarcode.setReelAmount(pidBarcode.getReelAmount() - 1);
pidBarcode.setAmount(pidBarcode.getAmount() - amount);
pidBarcode = barcodeManager.save(pidBarcode);
generateTask(subCode, opStatus, amount, opType, orderItemId);
log.info("隔口出库,生成出库任务,barcode:" + subCode.getBarcode() + ",料箱号为:" + subCode.getPosName());
log.info("箱子数量为:" + pidBarcode.getAmount() + ",物料数量为:" + pidBarcode.getReelAmount() + "箱号为:" + pidBarcode.getBarcode());
if (subCode.getAmount() <= 0) {
barcodeManager.delete(subCode);
}
//}
}
resultBean.setData(getBoxInfo(boxStr));
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 + "是否一致");
}
}
//判断当前隔口是否有要出的任务
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);
barcode = barcodeManager.save(barcode);
pidBarcode.UpdateSubCode(barcode);
pidBarcode.setReelAmount(pidBarcode.getReelAmount() - 1);
pidBarcode.setAmount(pidBarcode.getAmount() - amount);
pidBarcode = barcodeManager.save(pidBarcode);
generateTask(barcode, opStatus, amount, opType, orderItemId);
log.info("物料出库,生成出库任务,barcode:" + barcode.getBarcode() + ",隔口号为:" + barcode.getPosName());
if (barcode.getAmount() <= 0) {
barcodeManager.delete(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);
generateTask(barcode, opStatus, amount, opType, orderItemId);
log.info(barcode.getBarcode() + "不是出库任务," + barcodeByOut.getBarcode() + "需更改out为false");
log.info("物料出库,生成出库任务,barcode:" + barcode.getBarcode() + ",隔口号为:" + barcode.getPosName());
if (barcode.getAmount() <= 0) {
barcodeManager.delete(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)) {
//根据箱子号 找到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);
log.info("点击完成扫码并入库,任务取消,barcode:" + subCode.getBarcode() + ",OrderItemId为:" + orderItemId);
}
}
}
}
return resultBean;
}
private void generateTask(Barcode barcode, String opStatus, int opQty, int opType, String orderItemId) {
//生成任务
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());
//如果是入库任务
if (task.isPutInTask()) {
if (StringUtils.isNotBlank(barcode.getGrLabel())) {
task.setChangeType(CHANGE_TYPE.GR_PUTIN.getName());
} else {
task.setChangeType(CHANGE_TYPE.MANUAL_PUTIN.getName());
}
}
//如果是出库任务
if (task.isCheckOutTask()) {
task.setChangeType(CHANGE_TYPE.MANUAL_CHECKOUT.getName());
}
//任务取消
if (task.isCancel()) {
task.setChangeType(CHANGE_TYPE.TASK_CANNEL.getName());
}
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());
//如果是出库任务,则更新为发料
if (task.isCheckOutTask()) {
task.setChangeType(CHANGE_TYPE.VIRTUAL_CHECKOUT.getName());
} else if (task.isCancel()) {
task.setChangeType(CHANGE_TYPE.TASK_CANNEL.getName());
}
}
}
taskService.updateFinishedTask(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);
//判断是否有出库任务,如果有就完成
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) {
log.info("虚拟仓出库,已有出库任务,直接完成:" + task.getBarcode());
task.setStatus(OP_STATUS.FINISHED.name());
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);
}
}
Map<String, Object> resultMap = getBoxInfo(code);
return ResultBean.newOkResult(resultMap);
}
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 = storagePosManager.save(pos);
posName = posName + "-" + pos.getId();
}
barcode.setPosName(posName);
barcode.setPutInDate(new Date());
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")) {
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("CB") || 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")) {
resultMap.put("platsize", 7);
} /*else if (boxStr.startsWith("CM")) {
resultMap.put("platsize", 13);
}*/ else if (boxStr.startsWith("CB") || 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")) {
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 + "-1"));
inBoxPartitionCounts.add(boxPartitionNumMap.get(boxStr + "-2"));
inBoxPartitionCounts.add(boxPartitionNumMap.get(boxStr + "-3"));
} else {
inBoxPartitionCounts.add(boxPartitionNumMap.get(boxStr + "-3"));
inBoxPartitionCounts.add(boxPartitionNumMap.get(boxStr + "-2"));
inBoxPartitionCounts.add(boxPartitionNumMap.get(boxStr + "-1"));
}
}*/ else if (boxStr.startsWith("CB") || 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) {
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")) {
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());
taskService.updateFinishedTask(task);
return "";
}
private DataLog generateTask(Storage storage, Barcode barcode, StoragePos pos, int type, String status, String loc) {
//开始入库任务
DataLog task = new DataLog(storage, barcode, pos);
task.setType(type);
task.setStatus(status);
task.setLoc(loc);
task.setOperator(SecurityUtils.getCurrentUsername());
task.setBoxPosName(pos.getPosName());
taskService.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 com.google.common.collect.Lists;
import com.lowagie.text.Anchor;
import com.neotel.smfcore.common.bean.ReelLockPosInfo;
import com.neotel.smfcore.common.bean.ResultBean;
import com.neotel.smfcore.common.exception.ValidateException;
......@@ -28,6 +29,8 @@ 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.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.StationCacheUtil;
import com.neotel.smfcore.security.annotation.AnonymousAccess;
......@@ -38,10 +41,12 @@ 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.http.HttpRequest;
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;
......@@ -54,7 +59,6 @@ import java.util.stream.Collectors;
@RestController
public class OutWarehouseController {
@Autowired
private IBarcodeManager barcodeManager;
......@@ -67,14 +71,12 @@ public class OutWarehouseController {
@Autowired
private TaskService taskService;
@Autowired
private DataCache dataCache;
@Autowired
private LizhenApi lizhenApi;
@Autowired
private GrLabelManager grLabelManager;
......@@ -82,61 +84,47 @@ public class OutWarehouseController {
private SmfApi smfApi;
@Autowired
private ILiteOrderManager liteOrderManager;
@Autowired
private ILiteOrderItemManager liteOrderItemManager;
@Autowired
private LiteOrderCache liteOrderCache;
private static Map<String, Integer> boxCount = new ConcurrentHashMap<>();
@ApiOperation("选择物料")
@RequestMapping("/chooseReel")
@AnonymousAccess
//@AnonymousAccess
public ResultBean chooseReel(@RequestBody Map<String, String> paramMap) {
String name = paramMap.get("name"); //工位名称
String size = paramMap.get("size"); //尺寸 "7X8"
String num = paramMap.get("num"); //数量
String grLabelStr = paramMap.get("grLabel"); //GR标签
String warehouseCode = paramMap.get("warehouseCode"); //库别
//验证gr标签
log.info("{}:收到选择物料信息,尺寸为:{},数量为:{},gr:{}", name, size, num, grLabelStr);
//查询当前工位信息
//查询当前工位信息,如果当前工位为空,则新创建
Station station = StationCacheUtil.getStation(name);
if (station == null) {
station = new Station();
}
//如果gr标签不为空的,直接用gr的,否则,取手输的
if (StringUtils.isNotBlank(grLabelStr)) {
GrLabel grLabel = codeResolve.resolveGrLable(grLabelStr); //解析出gr标签
if (grLabel == null) {
return ResultBean.newErrorResult(-1, "", grLabelStr + "解析失败");
}
//判断数据库是否有barcode数据,如果有用数据库的
//判断数据库是否有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)) {
......@@ -146,13 +134,12 @@ public class OutWarehouseController {
String reelSize = barandMap.get("reelSize").toString();
if ("7".equals(reelSize)) {
size = "7X8";
} else if ("13".equals(reelSize)) {
} /*else if ("13".equals(reelSize)) {
size = "13X24";
} else if ("15".equals(reelSize)) {
} */else if ("15".equals(reelSize)) {
size = "15X32";
}
}
//得到对应的库别
Map<String, String> fetchGrMap = lizhenApi.fetchGR(grLabel);
if (fetchGrMap.get("warehouseCode") == null) {
......@@ -166,7 +153,6 @@ public class OutWarehouseController {
grLabel.setWarehouseCode(warehouseCode);
grLabel.setKeeperCode(keeperCode);
grLabelManager.save(grLabel);
station.setGrLabel(grLabel.getLabelId());
station.setLabelItem(grLabel.getLabelItem());
}
......@@ -181,10 +167,8 @@ public class OutWarehouseController {
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);
......@@ -194,33 +178,45 @@ public class OutWarehouseController {
@ApiOperation("呼叫空箱")
@RequestMapping("/callEmptyBox")
@AnonymousAccess
//@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()){
return ResultBean.newErrorResult(-1,"","当前工位:"+name+",已经呼叫空箱,等任务完成后,再进行呼叫");
if (name.equals(queueTask.getLoc()) && !queueTask.isFinished() && !queueTask.isCancel() && queueTask.isCheckOutTask()) {
callCount++;
}
}
StoragePos pos = getEmptyBoxPos(platsize);
if (pos == null) {
if (callCount >= 2) {
return ResultBean.newErrorResult(-1, "", "当前工位:" + name + ",已经呼叫空箱,等任务完成后,再进行呼叫");
}
DataLog dataLog = getCallEmptyBoxTask(platsize, name);
if (dataLog == null) {
return ResultBean.newErrorResult(-1, "", "未找到可用料箱");
}
generateTask(dataCache.getStorageById(pos.getStorageId()), pos.getBarcode(), pos, OP.CHECKOUT, OP_STATUS.WAIT.name(), name);
log.info(name + "呼叫的空箱为:" + dataLog.getBarcode());
return ResultBean.newOkResult("");
}
@ApiOperation("获取工位详情")
@RequestMapping("/getStation")
@AnonymousAccess
//@AnonymousAccess
public ResultBean getStation(@RequestBody Map<String, String> paramMap) {
String name = paramMap.get("name");
Station station = StationCacheUtil.getStation(name);
......@@ -233,7 +229,7 @@ public class OutWarehouseController {
@ApiOperation("验证是否强制入库")
@RequestMapping("/verifyPutIn")
@AnonymousAccess
//@AnonymousAccess
public ResultBean verifyPutIn(@RequestBody Map<String, String> paramMap) {
String barcodeStr = paramMap.get("barcode");
String name = paramMap.get("name");
......@@ -262,57 +258,62 @@ public class OutWarehouseController {
@ApiOperation("扫码入库")
@RequestMapping(value = "/operatePos")
@AnonymousAccess
//@AnonymousAccess
//先扫条码 再扫料箱
public ResultBean operatePos(@RequestBody Map<String, String> paramMap) throws InterruptedException {
String name = paramMap.get("name"); //工位名称
String code = paramMap.get("code"); //条码
log.info("收到物料信息,条码为:{},工位为:{}", code, name);
//Thread.sleep(100000);
//判断工位信息是否为空
Station station = StationCacheUtil.getStation(name);
if (station == null) {
return ResultBean.newErrorResult(-1, "", name + "工位信息未上传成功,请重试", new String[]{});
}
//当前料箱的信息
String currentRfid = station.getCurrentRfid();
if (StringUtils.isBlank(currentRfid)) {
return ResultBean.newErrorResult(-1, "", name + "当前工位料箱信息未上传成功,请重试", new String[]{});
}
//解析出具体的料箱信息
String boxStr = getBoxInfoByRfid(currentRfid);
//判断当前料箱与入库的尺寸信息是否一致
int platsize = station.getPlatsize();
if (platsize == 7) {
if (!boxStr.startsWith("CS")) {
return ResultBean.newErrorResult(-1, "", "物料规格为7寸与当前工位上的料箱:" + boxStr + "不匹配");
}
} else if (platsize == 13) {
} /*else if (platsize == 13) {
if (!boxStr.startsWith("CM")) {
return ResultBean.newErrorResult(-1, "", "物料规格为13寸与当前工位上的料箱:" + boxStr + "不匹配");
}
} else if (platsize == 15) {
if (!boxStr.startsWith("CB")) {
}*/ else if (platsize == 15) {
if (!boxStr.startsWith("CB") && !boxStr.startsWith("CM")) {
return ResultBean.newErrorResult(-1, "", "物料规格为15寸与当前工位上的料箱:" + boxStr + "不匹配");
}
}
//先判断是否料盒
String newCodeStr = "=" + station.getPlatsize() + "x" + station.getHeight() + "=" + code;
CodeBean codeBean = codeResolve.resolveSingleCode(newCodeStr);
if (!codeBean.isValid()) {
return ResultBean.newErrorResult(-1, "", code + "解析条码失败", new String[]{});
return ResultBean.newErrorResult(-1, "smfcore.error.barcode.noValidCode", "无效的条码");
}
Barcode barcode = codeBean.getBarcode();
String partNumber = barcode.getPartNumber();
//如果是箱子的话 则取下边的
ResultBean resultBean = ResultBean.newOkResult("");
//判断是否是料箱隔口码
if (isBox(partNumber)) {
station.setLastScanBoxCode(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[]{});
}
......@@ -320,10 +321,11 @@ public class OutWarehouseController {
String grLabel = station.getGrLabel();
String labelItem = station.getLabelItem();
GrLabel label = grLabelManager.findLabelBylabelId(grLabel, labelItem);
if (label != null){
List<Barcode> barcodes = barcode.getSubCodeList();
if (barcodes != null && !barcodes.isEmpty()){
for (Barcode barcodePos : barcodes) {
if (label != null) {
//根据隔口码找到当前料箱对应的物料信息
List<Barcode> barcodesByPosName = getBarcodesByPosName(code, false);
if (barcodesByPosName != null && !barcodesByPosName.isEmpty()) {
for (Barcode barcodePos : barcodesByPosName) {
if (!code.equals(barcodePos.getPosName())) {
continue;
}
......@@ -333,17 +335,6 @@ public class OutWarehouseController {
}
}
}
//判断当前是否有正在执行的任务
DataLog dataLog = getExecuteTask(boxStr);
if (dataLog != null) {
if (dataLog.isPutInTask()) {
//已有入库任务
return ResultBean.newErrorResult(-1, "", "物料:" + dataLog.getBarcode() + "已有入库任务,需继续执行入库动作", new String[]{});
} else if (dataLog.isCheckOutTask()) {
//已有出库任务
return ResultBean.newErrorResult(-1, "", "物料:" + dataLog.getBarcode() + "已有出库任务,需继续执行出库动作", new String[]{});
}
}
//判断料箱是否在库位中
StoragePos pos = storagePosManager.getByBarcode(boxStr);
if (pos != null) {
......@@ -352,68 +343,51 @@ public class OutWarehouseController {
//设置操作人
barcode.setCreator(SecurityUtils.getCurrentUsername());
barcodeManager.save(barcode);
station.setLastScanBoxCode(code);
} else {
if (barcode.getBarcode().length() < 17 || barcode.getBarcode().length() > 22) {
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 grLabel = station.getGrLabel();
String grLabelStr = station.getGrLabel();
GrLabel label = null;
if (StringUtils.isNotBlank(grLabel)) {
label = grLabelManager.findLabelBylabelId(grLabel, station.getLabelItem());
if (StringUtils.isNotBlank(grLabelStr)) {
label = grLabelManager.findLabelBylabelId(grLabelStr, station.getLabelItem());
if (label != null) {
barcode.setGrLabel(grLabel);
barcode.setGrLabel(grLabelStr);
barcode.setWarehouseCode(label.getWarehouseCode());
barcode.setKeeperCode(label.getKeeperCode());
}
} else {
barcode.setWarehouseCode(station.getWarehouseCode());
}
int barcodeCount = 0;
Barcode pidBarcode = barcodeManager.findByBarcode(boxStr);
List<Barcode> subCodes = pidBarcode.getSubCodeList();
if (subCodes != null && !subCodes.isEmpty()) {
for (Barcode subCode : subCodes) {
if (!lastScanBoxCode.equals(subCode.getPosName())){
continue;
}
//判断是否与隔口中的条件是否一致
if (!subCode.getProvider().equals(barcode.getProvider()) || !subCode.getPartNumber().equals(barcode.getPartNumber()) || !subCode.getWarehouseCode().equals(barcode.getWarehouseCode())) {
return ResultBean.newErrorResult(-1, "", "厂商:" + barcode.getProvider() + ",料号:" + barcode.getPartNumber() + "库别:" + barcode.getWarehouseCode() + "与隔口中:" + lastScanBoxCode + "厂商:" + subCode.getProvider() + ",料号:" + subCode.getPartNumber() + "库别:" + subCode.getWarehouseCode() + "不一致");
}
//校验是否属于同一个gr
if (StringUtils.isNotBlank(grLabel)) {
if (!grLabel.equals(subCode.getGrLabel())) {
return ResultBean.newErrorResult(-1, "", grLabel + "与隔口中Gr标签不一致:" + subCode.getGrLabel());
}
}
if (lastScanBoxCode.equals(subCode.getPosName())) {
barcodeCount++;
}
}
}
//7寸箱子最多放10盘
if (lastScanBoxCode.startsWith("CS")) {
if (barcodeCount >= 10) {
return ResultBean.newErrorResult(-1, "", "7寸物料每个隔口最多只允许放10盘");
}
}
//更新gr标签数量
if (label != null) {
int remainingAmount = label.getRemainingAmount();
......@@ -427,30 +401,20 @@ public class OutWarehouseController {
label.setRemainingAmount(remainingAmount - barcode.getAmount());
grLabelManager.save(label);
}
//当前已扫描的料卷数量+1
int reelCurrentNum = station.getReelCurrentNum();
station.setReelCurrentNum(reelCurrentNum + 1);
//开始生成任务,并处理
barcode.setHostBarcodeId(pidBarcode.getId());
barcode.setReelAmount(1); //设置卷数为1
barcode.setPutInTime(System.currentTimeMillis());
barcode.setCreator(SecurityUtils.getCurrentUsername());
barcode = barcodeManager.save(barcode);
finishTask(pidBarcode, OP.PUT_IN, null, barcode, barcode.getAmount(),OP_STATUS.FINISHED.name(),lastScanBoxCode);
log.info("生成入库任务:" + barcode.getBarcode() + "隔口号位:" + lastScanBoxCode);
resultBean = finishTask(boxStr, OP.PUT_IN, barcode, OP_STATUS.FINISHED.name(), INOUT_TYPE.IN_ONE.name(), lastScanBoxCode, grLabelStr,name);
}
StationCacheUtil.updateStation(station);
return ResultBean.newOkResult("");
return resultBean;
}
@ApiOperation("完成装箱并入库")
@RequestMapping("/finishBoxPutIn")
@AnonymousAccess
//@AnonymousAccess
public ResultBean finishBoxPutIn(@RequestBody Map<String, String> paramMap) {
String code = paramMap.get("barcode"); //料箱条码
String name = paramMap.get("name"); //工位名称
String cids = paramMap.get("cids");
......@@ -461,17 +425,14 @@ public class OutWarehouseController {
}
}
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是否一致
......@@ -481,8 +442,6 @@ public class OutWarehouseController {
} 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(",")) {
......@@ -502,8 +461,7 @@ public class OutWarehouseController {
if (storageList.isEmpty()) {
return ResultBean.newErrorResult(-1, "", "没有可以入库的料仓", new String[]{});
}
DataLog dataLog = getExecuteTask(boxStr);
DataLog dataLog = getExecutingTask(boxStr);
if (dataLog != null) {
if (dataLog.isPutInTask()) {
//已有入库任务
......@@ -513,15 +471,12 @@ public class OutWarehouseController {
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());
......@@ -531,7 +486,6 @@ public class OutWarehouseController {
log.info("清理锁定库位:库位号[" + oldLockInfo.getLockPosName() + "]上物料[" + oldLockInfo.getBarcode() + "]锁定的库位");
}
}
ReelLockPosInfo reelLocInfo = new ReelLockPosInfo();
reelLocInfo.setBarcode(boxBarcode.getBarcode());
reelLocInfo.setCid(theStorage.getCid());
......@@ -542,9 +496,6 @@ public class OutWarehouseController {
return ResultBean.newErrorResult(-1, "", "[" + boxBarcode.getBarcode() + "]库位[" + reelLocInfo.getLockPosName() + "]已被锁定,暂停入库", new String[]{});
}
}
//生成任务
generateTask(dataCache.getStorageById(pos.getStorageId()), boxBarcode, pos, OP.PUT_IN, OP_STATUS.WAIT.name(), null);
//同时清空lastScanBoxCode
station.setLastScanBoxCode(null);
if (station.getReelNum() > station.getReelCurrentNum()) {
......@@ -558,19 +509,10 @@ public class OutWarehouseController {
}
//station.setMsg(currentRfid + "需执行入库操作");
StationCacheUtil.saveBoxToBoxCode(station);
//判断是否有要出库的任务,给取消掉
Barcode barcode = barcodeManager.findByBarcode(boxStr);
List<Barcode> subCodes = barcode.getSubCodeList();
if (subCodes != null && !subCodes.isEmpty()) {
for (Barcode subCode : subCodes) {
if (!subCode.isOut()) {
continue;
}
finishTask(barcode,OP.CHECKOUT,null,subCode,subCode.getAmount(),OP_STATUS.CANCEL.name(),null);
}
}
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);
return ResultBean.newOkResult(station);
}
......@@ -585,25 +527,21 @@ public class OutWarehouseController {
if (station == null) {
return ResultBean.newErrorResult(-1, "", name + "工位信息未上传成功,请重试");
}
//判断当前工位是否有料箱
String currentRfid = station.getCurrentRfid();
if (StringUtils.isBlank(currentRfid)) {
return ResultBean.newErrorResult(-1, "", name + "当前工位料箱信息未上传成功,请重试", new String[]{});
}
//获取料箱中的物料信息
String boxStr = getBoxInfoByRfid(currentRfid);
Barcode pidBarcode = barcodeManager.findByBarcode(boxStr);
ResultBean resultBean = null;
boolean hasBrand = false;
String result = "";
ResultBean resultBean = ResultBean.newOkResult("");
if (isBox(barcodeStr) && (barcodeStr.endsWith("A") || barcodeStr.endsWith("B"))) {
resultBean = outByBox(boxStr, pidBarcode, hasBrand);
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 = outByPartition(barcodeStr, pidBarcode, hasBrand);
resultBean = finishTask(boxStr, OP.CHECKOUT, null, OP_STATUS.FINISHED.name(), INOUT_TYPE.OUT_PARTITION.name(), barcodeStr, null,name);
} else {
resultBean = outByReel(barcodeStr, boxStr, pidBarcode, hasBrand);
resultBean = finishTask(boxStr, OP.CHECKOUT, null, OP_STATUS.FINISHED.name(), INOUT_TYPE.OUT_ONE.name(), barcodeStr, null,name);
}
return resultBean;
}
......@@ -611,7 +549,7 @@ public class OutWarehouseController {
@ApiOperation("料箱中的数量")
@RequestMapping("/getBoxNum")
@AnonymousAccess
//@AnonymousAccess
public ResultBean getBoxNum(@RequestBody Map<String, String> paramMap) {
String name = paramMap.get("name");
Station station = StationCacheUtil.getStation(name);
......@@ -630,18 +568,13 @@ public class OutWarehouseController {
//需要出库的数量
Map<String, Integer> needOutCountMap = new HashMap<>();
needOutCountMap.put(boxStr + "-1", 0);
needOutCountMap.put(boxStr + "-2", 0);
needOutCountMap.put(boxStr + "-3", 0);
needOutCountMap.put(boxStr + "-4", 0);
needOutCountMap.put(boxStr + "-5", 0);
needOutCountMap.put(boxStr + "-6", 0);
needOutCountMap.put(boxStr + "-7", 0);
needOutCountMap.put(boxStr + "-8", 0);
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){
if (barcode != null) {
barcodes = barcode.getSubCodeList();
}
//料箱总数量
......@@ -728,7 +661,7 @@ public class OutWarehouseController {
boxPartitionCounts.add(boxPartitionCount2);
boxPartitionCounts.add(boxPartitionCount3);
boxPartitionCounts.add(boxPartitionCount4);
} else if (currentRfid.startsWith("CM")) {
} /*else if (currentRfid.startsWith("CM")) {
inBoxPartitionCounts.add(partition1);
inBoxPartitionCounts.add(partition2);
inBoxPartitionCounts.add(partition3);
......@@ -736,7 +669,7 @@ public class OutWarehouseController {
boxPartitionCounts.add(boxPartitionCount1);
boxPartitionCounts.add(boxPartitionCount2);
boxPartitionCounts.add(boxPartitionCount3);
} else if (currentRfid.startsWith("CB")) {
}*/ else if (currentRfid.startsWith("CB") || currentRfid.startsWith("CM")) {
inBoxPartitionCounts.add(partition2);
inBoxPartitionCounts.add(partition1);
......@@ -763,7 +696,7 @@ public class OutWarehouseController {
boxPartitionCounts.add(boxPartitionCount6);
boxPartitionCounts.add(boxPartitionCount7);
boxPartitionCounts.add(boxPartitionCount8);
} else if (currentRfid.startsWith("CM")) {
} /*else if (currentRfid.startsWith("CM")) {
inBoxPartitionCounts.add(partition3);
inBoxPartitionCounts.add(partition2);
inBoxPartitionCounts.add(partition1);
......@@ -771,7 +704,7 @@ public class OutWarehouseController {
boxPartitionCounts.add(boxPartitionCount3);
boxPartitionCounts.add(boxPartitionCount2);
boxPartitionCounts.add(boxPartitionCount1);
} else if (currentRfid.startsWith("CB")) {
}*/ else if (currentRfid.startsWith("CB") || currentRfid.startsWith("CM")) {
inBoxPartitionCounts.add(partition1);
inBoxPartitionCounts.add(partition2);
......@@ -836,19 +769,41 @@ public class OutWarehouseController {
}
@RequestMapping("/testBarcode")
@ApiOperation("重置料箱信息")
@RequestMapping("/resetBoxInfo")
@AnonymousAccess
public void testBarcode(){
List<Barcode> barcodes = barcodeManager.findByQuery(new Query());
for (Barcode barcode : barcodes) {
List<Barcode> subCodes = barcode.getSubCodeList();
if (subCodes != null && !subCodes.isEmpty()) {
for (Barcode subCode : subCodes) {
barcodeManager.save(subCode);
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);
}
/**
......@@ -861,7 +816,7 @@ public class OutWarehouseController {
* @param status
* @param loc
*/
private void generateTask(Storage storage, Barcode barcode, StoragePos pos, int type, String status, String loc) {
private DataLog generateTask(Storage storage, Barcode barcode, StoragePos pos, int type, String status, String loc) {
//开始入库任务
DataLog task = new DataLog(storage, barcode, pos);
task.setType(type);
......@@ -869,234 +824,271 @@ public class OutWarehouseController {
task.setLoc(loc);
task.setOperator(SecurityUtils.getCurrentUsername());
task.setBoxPosName(pos.getPosName());
taskService.updateQueueTask(task);
taskService.addTaskToExecute(task);
return task;
}
/**
* 完成出入库任务
*
* @param pidBarcode 料箱
* @param currentTask 当前任务
* @param subBarcode 箱内物料
* @param opQty 数量
* @throws ValidateException
* @param boxStr 箱子号
* @param opType 出入库 1,2
* @param barcode barcode
* @param opStatus 出入库状态
* @param inoutType 出入库类型 单个,隔口,整箱 出入库
* @param lastScanBoxCode 上一个隔口码
* @param grLabelStr gr标签
* @return
*/
private synchronized void finishTask(Barcode pidBarcode, int opType, DataLog currentTask, Barcode subBarcode, int opQty,String opStatus,String lastScanBoxCode) throws ValidateException {
String orderItemId = subBarcode.getOrderItemId();
if (opType == OP.CHECKOUT && OP_STATUS.CANCEL.name().equals(opStatus)) {
log.info(subBarcode.getBarcode() + "任务取消---" + orderItemId);
subBarcode.setOut(false);
subBarcode.setSelectMsg(null);
subBarcode.setOrderItemId(null);
subBarcode = barcodeManager.save(subBarcode);
}
if (StringUtils.isNotBlank(lastScanBoxCode)) {
subBarcode.setPosName(lastScanBoxCode);
subBarcode = barcodeManager.save(subBarcode);
}
//更新barcode缓存
log.info(subBarcode.getBarcode()+"的数量为:"+subBarcode.getAmount());
pidBarcode.UpdateSubCode(subBarcode);
if (opType == OP.CHECKOUT && OP_STATUS.FINISHED.name().equals(opStatus)) {
pidBarcode.setAmount(pidBarcode.getAmount() - opQty);
pidBarcode.setReelAmount(pidBarcode.getReelAmount() - subBarcode.getReelAmount()); //出库卷数-1
//数量为0直接删除
if (subBarcode.getAmount() <= 0) {
barcodeManager.delete(subBarcode);
log.info(subBarcode.getBarcode() + "数量为0,删除--" + pidBarcode.getBarcode());
}
}
if (opType == OP.PUT_IN && OP_STATUS.FINISHED.name().equals(opStatus)) {
pidBarcode.setAmount(pidBarcode.getAmount() + opQty);
pidBarcode.setReelAmount(pidBarcode.getReelAmount() + subBarcode.getReelAmount()); //入库卷数+1
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")) {
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);
//生成入库任务
pidBarcode = barcodeManager.save(pidBarcode);
generateTask(barcode, opStatus, barcode.getAmount(), opType, barcode.getOrderItemId(),name);
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);
DataLog task = null;
//先查看是否有相同类型且库位相同的任务
if (currentTask != null) {
Collection<DataLog> queueTasks = taskService.getQueueTasks();
for (DataLog queueTask : queueTasks) {
if (queueTask.getType() == currentTask.getType()) {
if (queueTask.getPosName().equals(pidBarcode.getBarcode())) {
task = queueTask;
break;
generateTask(subCode, opStatus, subCode.getAmount(), opType, orderItemId,name);
log.info("点击完成扫码并入库,任务取消,barcode:" + subCode.getBarcode() + ",OrderItemId为:" + orderItemId);
}
}
}
}
if (task == null) {
task = new DataLog();
//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() + ",没有可出库的物料");
}
task.setStatus(opStatus);
task.setPartNumber(subBarcode.getPartNumber());
task.setBarcode(subBarcode.getBarcode());
task.setNum(opQty);
task.setType(opType);
task.setPosName(subBarcode.getPosName());
//task.setOperator(SecurityUtils.getCurrentUsername());
task.setDateCode(subBarcode.getDateCode());
task.setBatchInfo(subBarcode.getBatch());
task.setProvider(subBarcode.getProvider());
task.setProviderNumber(subBarcode.getProviderNumber());
task.setKeeperCode(subBarcode.getKeeperCode());
task.setReelPosName(subBarcode.getPosName());
task.setSubSourceId(orderItemId);
//判断是否全部出库
for (Barcode subCode : subCodes) {
if (!subCode.isOut()) {
return ResultBean.newErrorResult(-1, "", pidBarcode.getBarcode() + "不允许全部取出,请核实");
}
}
//开始循环,生成任务
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) {
task.setSourceName(orderItem.getOrderNo());
task.setLine(orderItem.getLine());
task.setMo(orderItem.getMo());
task.setSide(orderItem.getSide());
task.setWarehouseCode(orderItem.getWarehouseCode());
task.setPlantCode(orderItem.getPlantCode());
task.setOrderNo(orderItem.getOrderNo());
if (StringUtils.isNotBlank(orderItem.getBrand())) {
hasBrand = true;
}
if (StringUtils.isNotBlank(orderItem.getOrderNo())) {
if (!orderItem.getOrderNo().equals(orderItemIdStr)) {
orderItemIdStr = orderItem.getOrderNo();
}
taskService.updateFinishedTask(task);
}
/**
* 解析尺寸信息
*
* @param size
* @param index
* @return
*/
private int getPlatsizeOrHeight(String size, int index) {
return Integer.valueOf(size.split("X")[index]);
}
/**
* 根据尺寸获取空料箱
*
* @param platsize
* @return
*/
private StoragePos getEmptyBoxPos(String platsize) {
//得到料盒类型
String boxSuffix = "";
if ("7".equals(platsize)) {
boxSuffix = "CS";
} else if ("13".equals(platsize)) {
boxSuffix = "CM";
} else if ("15".equals(platsize)) {
boxSuffix = "CB";
}
//料仓类型是agv的
String storageId = "";
Collection<Storage> storages = dataCache.getAllStorage().values();
for (Storage storage : storages) {
if (storage.isType(new DeviceType[]{DeviceType.AGV_BOX})) {
storageId = storage.getId();
//生成任务
int amount = subCode.getAmount();
subCode.setAmount(0);
subCode = barcodeManager.save(subCode);
pidBarcode.UpdateSubCode(subCode);
pidBarcode.setReelAmount(pidBarcode.getReelAmount() - 1);
pidBarcode.setAmount(pidBarcode.getAmount() - amount);
pidBarcode = barcodeManager.save(pidBarcode);
generateTask(subCode, opStatus, amount, opType, orderItemId,name);
log.info("整箱出库,生成出库任务,barcode:" + subCode.getBarcode() + ",料箱号为:" + pidBarcode.getBarcode());
if (subCode.getAmount() <= 0) {
barcodeManager.delete(subCode);
}
}
Criteria c = Criteria.where("barcode").exists(true)
.and("enabled").is(true);//可用
//排除掉正在执行的仓位
Collection<String> excludePosIds = taskService.excludePosIds();
log.info("excludePosIds--" + JsonUtil.toJsonStr(excludePosIds));
if (excludePosIds != null && !excludePosIds.isEmpty()) {
c.and("id").nin(excludePosIds);
if (hasBrand) {
ResultBean resultBean = ResultBean.newOkResult("");
resultBean.setCode(3);
return resultBean;
}
if (StringUtils.isNotBlank(storageId)) {
c.and("storageId").is(storageId);
if (StringUtils.isNotBlank(orderItemIdStr)) {
return ResultBean.newOkResult("", "工单号为:" + orderItemIdStr, "");
}
if (StringUtils.isNotBlank(boxSuffix)) {
Pattern pattern = Pattern.compile(QueryHelp.escapeExprSpecialWord(boxSuffix), Pattern.CASE_INSENSITIVE);
c.and("barcode.barcode").regex(pattern);
}
Query q = new Query(c).with(Sort.by(Sort.Direction.ASC, "barcode.amount")).limit(1);
List<StoragePos> storagePoss = storagePosManager.findByQuery(q);
if (storagePoss != null && !storagePoss.isEmpty()) {
return storagePoss.get(0);
//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);
}
return null;
}
/**
* 获取正在执行的任务
*
* @param barcode
* @return
*/
private DataLog getExecuteTask(String barcode) {
List<DataLog> allTasks = taskService.getAllTasks();
for (DataLog dataLog : allTasks) {
if (dataLog.getBarcode().equals(barcode)) {
if (!dataLog.isCancel() && !dataLog.isFinished()) {
return dataLog;
}
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 + "不允许全部出库,请核实");
}
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);
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;
}
q.addCriteria(c);
return barcodeManager.findByQuery(q);
if (StringUtils.isNotBlank(orderItem.getOrderNo())) {
if (!orderItem.getOrderNo().equals(orderItemIdStr)) {
orderItemIdStr = orderItem.getOrderNo();
}
/**
* 根据物料出库
*
* @param barcodeStr
* @param boxStr
* @param pidBarcode
* @return
*/
public synchronized ResultBean outByReel(String barcodeStr, String boxStr, Barcode pidBarcode, boolean hasBrand) {
ResultBean bean = ResultBean.newOkResult("");
if (StringUtils.isNotBlank(barcodeStr)) {
CodeBean codeBean = codeResolve.resolveSingleCode(barcodeStr);
}
}
}
int amount = subCode.getAmount();
subCode.setAmount(0);
subCode = barcodeManager.save(subCode);
pidBarcode.UpdateSubCode(subCode);
pidBarcode.setReelAmount(pidBarcode.getReelAmount() - 1);
pidBarcode.setAmount(pidBarcode.getAmount() - amount);
pidBarcode = barcodeManager.save(pidBarcode);
generateTask(subCode, opStatus, amount, opType, orderItemId,name);
log.info("隔口出库,生成出库任务,barcode:" + subCode.getBarcode() + ",料箱号为:" + subCode.getPosName());
log.info("箱子数量为:" + pidBarcode.getAmount() + ",物料数量为:" + pidBarcode.getReelAmount() + "箱号为:" + pidBarcode.getBarcode());
if (subCode.getAmount() <= 0) {
barcodeManager.delete(subCode);
}
//}
}
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, "", barcodeStr + "解析失败");
return ResultBean.newErrorResult(-1, "", codeStr + "解析失败");
}
Barcode barcode = barcodeManager.findByBarcode(codeBean.getBarcode().getBarcode());
if (barcode == null || StringUtils.isBlank(barcode.getPosName())) {
return ResultBean.newErrorResult(-1, "", barcode.getBarcode() + "不在料箱:" + boxStr + "请核实是否已经出库");
try {
smfApi.canPutInAfterResolve(codeBean.getBarcode());
} catch (ValidateException e) {
e.printStackTrace();
return ResultBean.newErrorResult(-1, "", e.getMessage());
}
//判断与隔口是否一致
if (!barcode.getPosName().startsWith(boxStr)) {
return ResultBean.newErrorResult(-1, "", barcode.getBarcode() + "所在的料箱为:" + barcode.getPosName() + ",与当前工位料箱:" + boxStr + "不一致");
List<Barcode> subCodes = pidBarcode.getSubCodeList();
if (subCodes == null || subCodes.isEmpty()) {
return ResultBean.newErrorResult(-1, "", "料箱:" + boxStr + ",没有可出库的物料");
}
//判断当前料箱是否包含此物料
boolean hasBarcode = false;
String selectMsg = "";
List<Barcode> barcodes = getBarcodesByPosName(barcode.getPosName(), true);
for (Barcode barcodePos : barcodes) {
if (StringUtils.isNotBlank(barcodePos.getSelectMsg())) {
selectMsg = barcodePos.getSelectMsg();
break;
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()) {
......@@ -1108,27 +1100,43 @@ public class OutWarehouseController {
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);
barcode = barcodeManager.save(barcode);
finishTask(pidBarcode, OP.CHECKOUT, null, barcode, amount,OP_STATUS.FINISHED.name(),null);
pidBarcode.UpdateSubCode(barcode);
pidBarcode.setReelAmount(pidBarcode.getReelAmount() - 1);
pidBarcode.setAmount(pidBarcode.getAmount() - amount);
pidBarcode = barcodeManager.save(pidBarcode);
generateTask(barcode, opStatus, amount, opType, orderItemId,name);
log.info("物料出库,生成出库任务,barcode:" + barcode.getBarcode() + ",隔口号为:" + barcode.getPosName());
if (barcode.getAmount() <= 0) {
barcodeManager.delete(barcode);
}
} else {
if (barcodes != null && !barcodes.isEmpty()) {
if (subCodes != null && !subCodes.isEmpty()) {
//获取到需要出库的物料,进行更改
Barcode barcodeByOut = null;
for (Barcode barcodeByPosName : barcodes) {
if (barcodeByPosName.isOut() && StringUtils.isNotBlank(barcodeByPosName.getOrderItemId())) {
barcodeByOut = barcodeByPosName;
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);
......@@ -1138,116 +1146,262 @@ public class OutWarehouseController {
barcode.setAmount(0);
barcode.setOrderItemId(orderItemId);
barcode = barcodeManager.save(barcode);
finishTask(pidBarcode, OP.CHECKOUT, null, barcode, amount,OP_STATUS.FINISHED.name(),null);
pidBarcode.setReelAmount(pidBarcode.getReelAmount() - 1);
pidBarcode.setAmount(pidBarcode.getAmount() - amount);
pidBarcode.UpdateSubCode(barcode);
pidBarcode = barcodeManager.save(pidBarcode);
generateTask(barcode, opStatus, amount, opType, orderItemId,name);
log.info(barcode.getBarcode() + "不是出库任务," + barcodeByOut.getBarcode() + "需更改out为false");
log.info("物料出库,生成出库任务,barcode:" + barcode.getBarcode() + ",隔口号为:" + barcode.getPosName());
if (barcode.getAmount() <= 0) {
barcodeManager.delete(barcode);
}
isOut = true;
log.info(barcode.getBarcode()+"不是出库任务,"+barcodeByOut.getBarcode()+"需更改out为false");
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 {
bean = ResultBean.newErrorResult(-1, "smfcore.valueCanotNull", "{0}不能为空", new String[]{"条码编号"});
return ResultBean.newErrorResult(-1, "", "条码编号不能为空");
}
if (hasBrand) {
log.info("hasBrand--" + hasBrand);
bean.setCode(3);
ResultBean resultBean = ResultBean.newOkResult("");
resultBean.setCode(3);
return resultBean;
}
return bean;
if (StringUtils.isNotBlank(orderItemIdStr)) {
return ResultBean.newOkResult("", "工单号为:" + orderItemIdStr, "");
}
}
return ResultBean.newOkResult("");
}
/**
* 根据料箱出库
*
* @param pidBarcode
* @return
*/
private ResultBean outByBox(String boxStr, Barcode pidBarcode, boolean hasBrand) {
//根据料箱获取到全部的物料
//List<Barcode> barcodes = getBarcodesByBoxStr(boxStr);
List<Barcode> barcodes = pidBarcode.getSubCodeList();
if (barcodes == null || barcodes.isEmpty()) {
return ResultBean.newErrorResult(-1, "", "料箱:" + pidBarcode.getBarcode() + ",没有可出库的物料");
private void generateTask(Barcode barcode, String opStatus, int opQty, int opType, String orderItemId,String name) {
//生成任务
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);
//如果是入库任务
if (task.isPutInTask()) {
if (StringUtils.isNotBlank(barcode.getGrLabel())) {
task.setChangeType(CHANGE_TYPE.GR_PUTIN.getName());
} else {
task.setChangeType(CHANGE_TYPE.MANUAL_PUTIN.getName());
}
//判断是否全部出库
for (Barcode barcode : barcodes) {
if (!barcode.isOut()) {
return ResultBean.newErrorResult(-1, "", pidBarcode.getBarcode() + "不允许全部取出,请核实");
}
//如果是出库任务
if (task.isCheckOutTask()) {
task.setChangeType(CHANGE_TYPE.MANUAL_CHECKOUT.getName());
}
//任务取消
if (task.isCancel()) {
task.setChangeType(CHANGE_TYPE.TASK_CANNEL.getName());
}
//开始循环,生成任务
for (int index = 0; index < barcodes.size();/*; index++*/) {
Barcode barcode = barcodes.get(index);
String orderItemId = barcode.getOrderItemId();
if (StringUtils.isNotBlank(orderItemId)) {
LiteOrderItem orderItem = liteOrderItemManager.get(orderItemId);
if (orderItem != null) {
if (StringUtils.isNotBlank(orderItem.getBrand())) {
hasBrand = true;
}
}
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());
//如果是出库任务,则更新为发料
if (task.isCheckOutTask()) {
task.setChangeType(CHANGE_TYPE.PICKING_DETAIL.getName());
} else if (task.isCancel()) {
task.setChangeType(CHANGE_TYPE.TASK_CANNEL.getName());
}
int amount = barcode.getAmount();
barcode.setAmount(0);
barcode = barcodeManager.save(barcode);
finishTask(pidBarcode, OP.CHECKOUT, null, barcode, amount,OP_STATUS.FINISHED.name(),null);
}
ResultBean bean = ResultBean.newOkResult("");
if (hasBrand) {
log.info("hasBrand--" + hasBrand);
bean.setCode(3);
}
return bean;
taskService.updateFinishedTask(task);
}
/**
* 根据隔扣出库
* 解析尺寸信息
*
* @param barcodeStr
* @param pidBarcode
* @param size
* @param index
* @return
*/
private ResultBean outByPartition(String barcodeStr, Barcode pidBarcode, boolean hasBrand) {
List<Barcode> barcodes = getBarcodesByPosName(barcodeStr, false);
if (barcodes == null || barcodes.isEmpty()) {
return ResultBean.newErrorResult(-1, "", "料箱隔口:" + barcodeStr + "扫描错误");
private int getPlatsizeOrHeight(String size, int index) {
return Integer.valueOf(size.split("X")[index]);
}
//判断是否全部出库
for (Barcode barcode : barcodes) {
if (!barcode.isOut()) {
return ResultBean.newErrorResult(-1, "", barcodeStr + "不允许全部出库,请核实");
@AnonymousAccess
@RequestMapping("/getCallEmptyBoxTask")
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();
}
}
for (int i = 0; i < barcodes.size(); i++) {
Barcode barcode = barcodes.get(i);
String orderItemId = barcode.getOrderItemId();
if (StringUtils.isNotBlank(orderItemId)) {
LiteOrderItem orderItem = liteOrderItemManager.get(orderItemId);
if (orderItem != null) {
if (StringUtils.isNotBlank(orderItem.getBrand())) {
hasBrand = true;
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);
}
//料仓类型
/*if (StringUtils.isNotBlank(boxSuffix)) {
List<Criteria> orCriteriaList = new ArrayList<>();
String[] sufixS = boxSuffix.split(",");
for (String sufix : sufixS) {
Pattern pattern = Pattern.compile(QueryHelp.escapeExprSpecialWord(sufix), Pattern.CASE_INSENSITIVE);
orCriteriaList.add(Criteria.where("barcode.partNumber").regex(pattern));
}
c.andOperator(orCriteriaList);
}*/
//料盘数量小于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("CB"), Pattern.CASE_INSENSITIVE))));
if (poss == null || poss.isEmpty()){
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()) {
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 ("13".equals(platsize)) {
for (int par = 1; par < 4; 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;
}
int amount = barcode.getAmount();
barcode.setAmount(0);
barcode = barcodeManager.save(barcode);
finishTask(pidBarcode, OP.CHECKOUT, null, barcode, amount,OP_STATUS.FINISHED.name(),null);
}
ResultBean bean = ResultBean.newOkResult("");
if (hasBrand) {
log.info("hasBrand--" + hasBrand);
bean.setCode(3);
}
return bean;
}
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);
}
return task;
}
private boolean isBox(String boxStr) {
return boxStr.startsWith("CS") || boxStr.startsWith("CM") || boxStr.startsWith("CB");
/**
* 获取正在执行的任务
*
* @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) {
return barcodeStr.startsWith("CS") || barcodeStr.startsWith("CM") || barcodeStr.startsWith("CB");
}
public Station updateStation(Station station, int platsize, int height, String name, int num, int reelcurrentNum, int boxCurrentNum, String lastScanBoxCode, boolean putIn, String msg, String warehouseCode) {
......@@ -1259,7 +1413,6 @@ public class OutWarehouseController {
station.setLastScanBoxCode(lastScanBoxCode);
station.setBoxCurrentNum(boxCurrentNum);
station.setPutIn(putIn);
//station.setMsg(msg);
StationCacheUtil.updateStation(station);
return station;
}
......@@ -1279,11 +1432,6 @@ public class OutWarehouseController {
return rfid;
}
private List<Barcode> getBarcodesByBoxStr(String boxStr){
Pattern pattern = Pattern.compile(QueryHelp.escapeExprSpecialWord(boxStr), Pattern.CASE_INSENSITIVE);
return barcodeManager.findByQuery(new Query(Criteria.where("posName").regex(pattern)));
}
private String getPosNameBySubcode(String barcodeStr) {
String posName = "";
......@@ -1304,4 +1452,9 @@ public class OutWarehouseController {
}
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 com.neotel.smfcore.core.system.service.manager.IDataLogManager;
import com.neotel.smfcore.core.system.service.po.DataLog;
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;
/**
* 外仓外部接口控制类
*/
@RestController
@RequestMapping("/ext")
public class OutWarehouseExtController {
@Autowired
private IDataLogManager dataLogManager;
@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.rest;
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.system.service.manager.IDataLogManager;
......@@ -11,14 +15,18 @@ import com.neotel.smfcore.core.system.util.TaskService;
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.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Map;
import javax.annotation.PostConstruct;
import java.util.*;
@RestController
@Slf4j
@RequestMapping("/task")
public class TaskRestController {
@Autowired
......@@ -33,6 +41,65 @@ public class TaskRestController {
@Autowired
private IStoragePosManager storagePosManager;
@Autowired
private ILiteOrderItemManager liteOrderItemManager;
@Autowired
private IBarcodeManager barcodeManager;
/**
* 初始化putInDate
*/
@PostConstruct
public void initPutInDate() {
Criteria c = Criteria.where("putInTime").is(-1);
List<Barcode> barcodeList = barcodeManager.findByQuery(new Query(c));
for (Barcode barcode : barcodeList) {
Date date = new Date();
barcode.setPutInTime(date.getTime());
barcode.setPutInDate(date);
barcodeManager.save(barcode);
}
}
@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("/test")
@AnonymousAccess
public List<DataLog> getDataLogs(@RequestBody Map<String,String> paramMap){
String barcodeStr = paramMap.get("barcodeStr");
dataLogManager.findByQuery(new Query(Criteria.where("").is()))
}
*/
@RequestMapping("/putIn")
@AnonymousAccess
......
package com.neotel.smfcore.custom.lizhen.innerBox.bean;
import com.neotel.smfcore.common.base.BasePo;
import lombok.Data;
import java.util.Date;
......@@ -10,7 +11,7 @@ import java.util.Date;
* @date 2022/10/9 3:21 PM
*/
@Data
public class PreWarningItem {
public class PreWarningItem extends BasePo {
//{"id":"7527248","workorderno":"030000113197","line":"A05-5FARF-06","machinename":"NPM1",
// "station":"3_2","side":"B","slot":"5","subslot":"L","partnumber":"128S00105",
......@@ -26,7 +27,7 @@ public class PreWarningItem {
private String slot;
private String subslot;
private String partnumber;
private String id;
private String itemId;
/**
* 优先级,1:人工 0:机器
......
package com.neotel.smfcore.custom.lizhen.innerBox.enums;
/**
* 出库类型
*/
public class ExtendType {
/**
* 智能仓储入库
*/
public final static int STORAGE_PUTIN = 0;
/**
* 智能仓储出库
*/
public final static int STORAGE_CHECKOUT = 1;
/**
* 虚拟仓入库
*/
public final static int VIRTUAL_PUTIN = 2;
/**
* 虚拟仓出库
*/
public final static int VIRTUAL_CHECKOUT = 3;
/**
* 手动出库
*/
public final static int MANUAL_CHECKOUT = 4;
/**
* 手动喂料
*/
public final static int MANUAL_FEEDING = 5;
/**
* 清空库位
*/
public final static int CLEAR_POS = 6;
}
package com.neotel.smfcore.custom.lizhen.innerBox.rest;
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.ReelLockPosUtil;
......@@ -25,6 +26,7 @@ import com.neotel.smfcore.core.system.service.manager.IDataLogManager;
import com.neotel.smfcore.core.system.service.po.DataLog;
import com.neotel.smfcore.core.system.util.TaskService;
import com.neotel.smfcore.custom.lizhen.innerBox.bean.OutLotInfo;
import com.neotel.smfcore.custom.lizhen.innerBox.enums.ExtendType;
import com.neotel.smfcore.custom.lizhen.innerBox.util.OutLotInfoCache;
import com.neotel.smfcore.security.annotation.AnonymousAccess;
import io.swagger.annotations.ApiOperation;
......@@ -247,7 +249,7 @@ public class InnerBoxRestController {
public ResultBean rackPrintLabel(HttpServletRequest request) {
Map<String, String> resultMap = getPrintLabel(labelOrderItemId);
if (resultMap.isEmpty()) {
return ResultBean.newErrorResult(-1, "", "未找到需要打印的标签信息");
return ResultBean.newErrorResult(-1, "", "未找到需要打印的标签信息",null,false);
}
return ResultBean.newOkResult(resultMap);
}
......@@ -426,7 +428,8 @@ public class InnerBoxRestController {
public ResultBean fillPrint(@RequestBody Map<String, String> paramMap) {
String barcodestr = paramMap.get("barcode");
log.info("补打印标签信息:" + barcodestr);
CodeBean codeBean = codeResolve.resolveSingleCode(barcodestr);
String newCodeStr = "=" + 7 + "x" + 8 + "=" + barcodestr;
CodeBean codeBean = codeResolve.resolveSingleCode(newCodeStr);
if (!codeBean.isValid()) {
return ResultBean.newErrorResult(-1, "smfcore.error.barcode.invalid", "{0}不是有效的条码", new String[]{barcodestr});
}
......@@ -458,45 +461,45 @@ public class InnerBoxRestController {
String barcodestr = paramMap.get("barcodestr");
String orderItemId = paramMap.get("orderItemId");
log.info("人工发料--ItemId:"+orderItemId+",barcodestr:"+barcodestr);
log.info("人工发料--ItemId:" + orderItemId + ",barcodestr:" + barcodestr);
if (StringUtils.isBlank(orderItemId)) {
return ResultBean.newErrorResult(-1, "smfcore.valueCanotNull", "{0}不能为空", new String[]{"itemId"});
}
CodeBean codeBean = codeResolve.resolveSingleCode(barcodestr);
if (!codeBean.isValid()) {
/*if (!codeBean.isValid()) {
return ResultBean.newErrorResult(-1, "smfcore.error.barcode.invalid", "{0}不是有效的条码", new String[]{barcodestr});
}
}*/
//判断当前是否已经有出库任务
List<DataLog> allTasks = taskService.getAllTasks();
for (DataLog dataLog : allTasks) {
if (orderItemId.equals(dataLog.getSubSourceId())) {
if (dataLog.isCheckOutTask() && !dataLog.isCancel() && !dataLog.isFinished()) {
return ResultBean.newErrorResult(-1,"smfcore.valueAlreadyExist","{0}[{1}]已存在",new String[]{"出库任务",orderItemId});
return ResultBean.newErrorResult(-1, "smfcore.valueAlreadyExist", "{0}[{1}]已存在", new String[]{"出库任务", orderItemId});
}
}
}
LiteOrderItem orderItem = liteOrderItemManager.get(orderItemId);
if (orderItem == null){
return ResultBean.newErrorResult(-1,"smfcore.valueNotExist","{0}[{1}]不存在",new String[]{"工单信息",orderItemId});
if (orderItem == null) {
return ResultBean.newErrorResult(-1, "smfcore.valueNotExist", "{0}[{1}]不存在", new String[]{"工单信息", orderItemId});
}
//判断是否已经补过料
if (orderItem.getOutNum() > 0){
return ResultBean.newErrorResult(-1,"smfcore.task.hasEnd","任务已完成");
if (orderItem.getOutNum() > 0) {
return ResultBean.newErrorResult(-1, "smfcore.task.hasEnd", "任务已完成");
}
//判断料号是否一致
String partNumber = codeBean.getBarcode().getPartNumber();
if (!orderItem.getPn().equals(partNumber)) {
return ResultBean.newErrorResult(-1,"","请核实手动补料的料号:"+partNumber+"与工单需求料号:"+orderItem.getPn()+"是否一致");
return ResultBean.newErrorResult(-1, "", "请核实手动补料的料号:" + partNumber + "与工单需求料号:" + orderItem.getPn() + "是否一致");
}
LiteOrder liteOrder = liteOrderManager.get(orderItem.getOrderId());
if (liteOrder == null){
return ResultBean.newErrorResult(-1,"smfcore.valueNotExist","{0}[{1}]不存在",new String[]{"工单信息",orderItemId});
if (liteOrder == null) {
return ResultBean.newErrorResult(-1, "smfcore.valueNotExist", "{0}[{1}]不存在", new String[]{"工单信息", orderItemId});
}
//生成一条出库任务
......@@ -511,11 +514,29 @@ public class InnerBoxRestController {
dataLog.setProviderNumber(barcode.getProviderNumber());
dataLog.setNum(barcode.getAmount());
dataLog.setType(OP.CHECKOUT);
dataLog.setPosName("人工");
dataLog.setExtendType(ExtendType.MANUAL_FEEDING); //手动喂料
//dataLog.setPosName("人工");
//判断虚拟仓有没有,如果有,则删除库位
StoragePos storagePos = storagePosManager.getByBarcode(barcode.getBarcode());
if (storagePos != null) {
dataLog.setPosName(storagePos.getPosName());
Storage storage = dataCache.getStorageById(storagePos.getStorageId());
dataLog.setCid(storage.getCid());
if (storage.isVirtual()) {
dataLog.setCid(storage.getCid());
storagePos.setBarcode(null);
//dataCache.updateInventory(storagePos, barcode);
//进行库位更改
storagePos.setBarcode(null);
storagePos.setUsed(false);
storagePosManager.save(storagePos);
barcodeManager.delete(barcode);
}
}
taskService.updateFinishedTask(dataLog);
taskService.removeFinishedTask(dataLog);
setManualOrderItemId(orderItemId);
return ResultBean.newOkResult("");
}
......@@ -525,7 +546,7 @@ public class InnerBoxRestController {
public ResultBean manualPrintLabel(HttpServletRequest request) {
Map<String, String> resultMap = getPrintLabel(manualOrderItemId);
if (resultMap.isEmpty()) {
return ResultBean.newErrorResult(-1, "", "未找到需要打印的标签信息");
return ResultBean.newErrorResult(-1, "", "未找到需要打印的标签信息",null,false);
}
return ResultBean.newOkResult(resultMap);
}
......@@ -539,6 +560,71 @@ public class InnerBoxRestController {
return ResultBean.newOkResult("");
}
@ApiOperation("扫描物料信息直接喂料")
@RequestMapping("/manualFeedingByBarcode")
@AnonymousAccess
public ResultBean manualFeedingByBarcode(@RequestBody Map<String, String> paramMap) {
String orderNo = paramMap.get("orderNo");
String barcodeStr = paramMap.get("barcode");
//解析条码
CodeBean codeBean = codeResolve.resolveSingleCode(barcodeStr);
Barcode barcode = codeBean.getBarcode();
if (barcode == null) {
return ResultBean.newErrorResult(-1, "smfcore.error.barcode.invalid", "{0}不是有效的条码", new String[]{barcodeStr});
}
LiteOrder order = liteOrderManager.findByOrderNo(orderNo);
if (order == null) {
return ResultBean.newErrorResult(-1, "smfcore.order.out.notFound", "工单未找到");
}
boolean hasItem = false;
for (LiteOrderItem orderItem : order.getOrderItems()) {
if (orderItem.getOutNum() > 0){
continue;
}
if (barcode.getPartNumber().equals(orderItem.getPn())) {
hasItem = true;
DataLog dataLog = new DataLog();
dataLog.setStatus(OP_STATUS.FINISHED.name());
dataLog.setBarcode(barcode.getBarcode());
dataLog.setSourceName(order.getOrderNo());
dataLog.setSourceId(order.getId());
dataLog.setSubSourceId(orderItem.getId());
dataLog.setPartNumber(barcode.getPartNumber());
dataLog.setProviderNumber(barcode.getProviderNumber());
dataLog.setNum(barcode.getAmount());
dataLog.setType(OP.CHECKOUT);
dataLog.setExtendType(ExtendType.MANUAL_FEEDING); //手动喂料
//dataLog.setPosName("人工");
//判断虚拟仓有没有,如果有,则删除库位
StoragePos storagePos = storagePosManager.getByBarcode(barcode.getBarcode());
if (storagePos != null) {
dataLog.setPosName(storagePos.getPosName());
Storage storage = dataCache.getStorageById(storagePos.getStorageId());
dataLog.setCid(storage.getCid());
if (storage.isVirtual()) {
dataLog.setCid(storage.getCid());
storagePos.setBarcode(null);
//dataCache.updateInventory(storagePos, barcode);
//进行库位更改
storagePos.setUsed(false);
storagePosManager.save(storagePos);
barcodeManager.delete(barcode);
}
}
taskService.updateFinishedTask(dataLog);
taskService.removeFinishedTask(dataLog);
setManualOrderItemId(orderItem.getId());
break;
}
}
if (!hasItem) {
return ResultBean.newErrorResult(-1, "smfcore.order.supplementOutFail", "未找到可以出库的补料");
}
return ResultBean.newOkResult("");
}
public String getLabelOrderItemId() {
return labelOrderItemId;
}
......@@ -692,7 +778,7 @@ public class InnerBoxRestController {
public Map<String,String> getPrintLabel(String orderItemId){
Map<String, String> resultMap = new HashMap<>();
LiteOrderItem liteOrderItem = liteOrderItemManager.get(labelOrderItemId);
LiteOrderItem liteOrderItem = liteOrderItemManager.get(orderItemId);
if (liteOrderItem != null) {
String orderId = liteOrderItem.getOrderId();
LiteOrder liteOrder = liteOrderManager.get(orderId);
......
package com.neotel.smfcore.custom.lizhen.innerBox.rest;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.neotel.smfcore.common.bean.ResultBean;
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.LiteOrderCache;
import com.neotel.smfcore.core.order.rest.bean.mapstruct.OrderItemMapper;
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.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.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.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.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.*;
import java.util.regex.Pattern;
/**
* 虚拟仓页面
*/
@Slf4j
@RestController
public class VirtualRestController {
@Autowired
private CodeResolve codeResolve;
@Autowired
private IStoragePosManager storagePosManager;
@Autowired
private DataCache dataCache;
@Autowired
private IBarcodeManager barcodeManager;
@Autowired
private TaskService taskService;
@Autowired
private LizhenApi lizhenApi;
@Autowired
private SmfApi smfApi;
@Autowired
private LiteOrderCache liteOrderCache;
@Autowired
private OrderItemMapper orderItemMapper;
@ApiOperation("虚拟入库")
@RequestMapping("/virtual/putIn")
public ResultBean putIn(@RequestBody Map<String, String> paramMap) {
String posName = paramMap.get("posName");
String code = paramMap.get("code");
String newCode = code.toUpperCase();
//开始解析code
CodeBean codeBean = codeResolve.resolveSingleCode("=1x1=" + newCode);
if (!codeBean.isValid()) {
return ResultBean.newErrorResult(-1, "smfcore.error.barcode.noValidCode", "无效的条码");
}
//处理散料盘
Barcode barcode = codeBean.getBarcode();
//如果不为空,则使用扫描的,否则从数据库中查
if (StringUtils.isBlank(posName)){
Storage storage = null;
for (Storage stor : dataCache.getAllStorage().values()) {
if (stor.isVirtual()){
storage = stor;
break;
}
}
StoragePos pos = storagePosManager.getPosNameByPnAndStrId(barcode.getPartNumber(),storage.getId());
if (pos != null){
posName = pos.getPosName();
}
}
if (StringUtils.isBlank(posName)) {
return ResultBean.newErrorResult(-1, "smfcore.valueCanotNull", "{0}不能为空", new String[]{"库位"});
}
Barcode barcodeInfo = lizhenApi.barcodeInfo(barcode);
if (barcodeInfo != null){
barcode = barcodeInfo;
}
//判断是否为禁用料
try {
smfApi.canPutInAfterResolve(barcode);
} catch (Exception e){
return ResultBean.newErrorResult(-1,"",e.getMessage());
}
//判断是否已经存在库位
StoragePos pos = storagePosManager.getByBarcode(barcode.getBarcode());
if (pos != null) {
return ResultBean.newErrorResult(-1, "smfcore.storagePos.existBarcode", "{}已存在库位{}中", new String[]{barcode.getBarcode(), pos.getPosName()});
}
//判断库位中是否已经存在3种料号
List<String> pnList = getExistPnByPosName(posName);
if (pnList != null && !pnList.isEmpty()) {
if (!pnList.contains(barcode.getPartNumber())){
if (pnList.size() >= 3){
return ResultBean.newErrorResult(-1,"",posName+"已经存在3种料号,请更换库位");
}
}
}
//放入虚拟仓
intoVirtualPos(posName,barcode);
return ResultBean.newOkResult(barcode.getBarcode()+"已经放入库位中:"+posName);
}
@ApiOperation("执行过的工单信息")
@RequestMapping("/getNoFinishedOrder")
@AnonymousAccess
private ResultBean getNoFinishedOrder() {
List<LiteOrderItem> results = new ArrayList<>();
for (LiteOrder liteOrder : liteOrderCache.getAllLiteOrder()) {
if (liteOrder.isTaskFinished()) {
List<LiteOrderItem> orderItems = liteOrder.getOrderItems();
if (orderItems != null && !orderItems.isEmpty()) {
for (LiteOrderItem orderItem : orderItems) {
if (orderItem.getNeedReelCount() > orderItem.getOutReelCount()){
results.add(orderItem);
}
}
}
}
}
return ResultBean.newOkResult(orderItemMapper.toDto(results));
}
@ApiOperation("手动出库")
@RequestMapping("/vitual/checkout")
private ResultBean checkout(@RequestBody Map<String,String> paramMap) {
String code = paramMap.get("code");
String newCode = code.toUpperCase();
//开始解析code
CodeBean codeBean = codeResolve.resolveSingleCode("=1x1=" + newCode);
if (!codeBean.isValid()) {
return ResultBean.newErrorResult(-1, "smfcore.error.barcode.noValidCode", "无效的条码");
}
Barcode barcode = codeBean.getBarcode();
//判断是否为虚拟仓
String barcodeStr = barcode.getBarcode();
StoragePos pos = storagePosManager.getByBarcode(barcodeStr);
if (pos != null) {
Storage storage = dataCache.getStorageById(pos.getStorageId());
DataLog dataLog = new DataLog(storage, barcode, pos);
dataLog.setStatus(OP_STATUS.FINISHED.name());
dataLog.setType(OP.CHECKOUT);
if (storage.isVirtual()) {
dataLog.setExtendType(ExtendType.VIRTUAL_CHECKOUT); //虚拟出库
} else {
dataLog.setExtendType(ExtendType.STORAGE_CHECKOUT); //手动出库
}
//dataCache.updateInventoryAmount(storage.getCid(),barcode.getPartNumber(),-barcode.getAmount());
barcodeManager.delete(barcode);
taskService.updateFinishedTask(dataLog);
taskService.removeFinishedTask(dataLog);
pos.setBarcode(null);
pos.setUsed(false);
storagePosManager.save(pos);
} else {
DataLog dataLog = new DataLog();
dataLog.setStatus(OP_STATUS.FINISHED.name());
dataLog.setBarcode(barcode.getBarcode());
dataLog.setPartNumber(barcode.getPartNumber());
dataLog.setProviderNumber(barcode.getProviderNumber());
dataLog.setNum(barcode.getAmount());
dataLog.setType(OP.CHECKOUT);
//dataLog.setPosName("人工");
dataLog.setExtendType(ExtendType.MANUAL_CHECKOUT); //手动出库
taskService.updateFinishedTask(dataLog);
taskService.removeFinishedTask(dataLog);
}
return ResultBean.newOkResult("");
}
@ApiOperation("一键导入")
@RequestMapping("/virtual/import")
@AnonymousAccess
public ResultBean virImport(String floor, String orderNo) {
if (StringUtils.isBlank(floor)) {
return ResultBean.newErrorResult(-1, "smfcore.valueCanotNull", "{0}不能为空", new String[]{"楼层"});
}
if (StringUtils.isBlank(orderNo)) {
return ResultBean.newErrorResult(-1, "smfcore.valueCanotNull", "{0}不能为空", new String[]{"PickingId"});
}
int page = 0;
final int size = 1000;
boolean hasDataLog = true;
while (hasDataLog) {
String url = dataCache.getCache("api.importUrl");
url = url + "?orderNo=" + orderNo + "&line=" + floor + "&page=" + page + "&size=" + size;
String result = HttpHelper.sendGet(url);
if (StringUtils.isNotBlank(result)) {
List<DataLog> dataLogs = JSONArray.parseArray(result, DataLog.class);
if (dataLogs == null || dataLogs.isEmpty()) {
hasDataLog = false;
} else {
for (DataLog dataLog : dataLogs) {
String barcodeStr = dataLog.getBarcode();
//先判断有没有存在,如果有,就跳过
StoragePos pos = storagePosManager.getByBarcode(barcodeStr);
if (pos != null) {
log.info("barcode:" + barcodeStr + "已经存在库位:" + pos.getPosName() + ",跳过");
continue;
}
Barcode barcode = new Barcode();
/**
* 从配置取
*/
Storage storage = null;
for (Storage stor : dataCache.getAllStorage().values()) {
if (stor.isVirtual()){
storage = stor;
break;
}
}
String posName = "";
StoragePos storagePos = storagePosManager.getPosNameByPnAndStrId(dataLog.getPartNumber(),storage.getId());
if (storagePos != null){
posName = storagePos.getPosName();
}
barcode.setBarcode(barcodeStr);
barcode.setAmount(dataLog.getNum());
barcode.setDateCode(dataLog.getDateCode());
barcode.setPartNumber(dataLog.getPartNumber());
barcode.setBatch(dataLog.getBatchInfo());
barcode.setProvider(dataLog.getProvider());
barcode.setProviderNumber(dataLog.getProviderNumber());
barcode = barcodeManager.save(barcode);
intoVirtualPos(posName, barcode);
}
page++;
}
} else {
hasDataLog = false;
}
if (!hasDataLog) {
break;
}
}
return ResultBean.newOkResult(null);
}
private synchronized void intoVirtualPos(String posName, Barcode barcode) {
//判断有没有空库位
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 = storagePosManager.save(pos);
posName = posName + "-" + pos.getId();
}
barcode.setPosName(posName);
barcode.setPutInDate(new Date());
barcode = barcodeManager.save(barcode);
pos.setPosName(posName);
pos.setBarcode(barcode);
pos.setEnabled(true);
pos.setUsed(true);
pos.setUpdateDate(new Date());
pos.setStorageId(storage.getId());
pos = storagePosManager.save(pos);
DataLog dataLog = generateTask(storage, barcode, pos, OP.PUT_IN, OP_STATUS.FINISHED.name(), null);
dataLog.setExtendType(ExtendType.VIRTUAL_PUTIN); //虚拟入库
taskService.moveTaskToFinished(dataLog);
taskService.removeFinishedTask(dataLog);
//更改缓存信息
//dataCache.updateInventory(pos, barcode);
}
private DataLog generateTask(Storage storage, Barcode barcode, StoragePos pos, int type, String status, String loc) {
//开始入库任务
DataLog task = new DataLog(storage, barcode, pos);
task.setType(type);
task.setStatus(status);
task.setLoc(loc);
//task.setOperator(SecurityUtils.getCurrentUsername());
task.setBoxPosName(pos.getPosName());
taskService.addTaskToExecute(task);
return task;
}
private List<String> getExistPnByPosName(String posName) {
//int count = 0;
String stoageId = "";
for (Storage storage : dataCache.getAllStorage().values()) {
if (storage.isVirtual()){
stoageId = storage.getId();
break;
}
}
List<String> pnList = new ArrayList<>();
Query query = new Query();
Pattern pattern = Pattern.compile(QueryHelp.escapeExprSpecialWord(posName+"-"), Pattern.CASE_INSENSITIVE);
query.addCriteria(Criteria.where("used").is(true).and("posName").regex(pattern).and("storageId").is(stoageId));
List<StoragePos> posList = storagePosManager.findByQuery(query);
if (posList != null && !posList.isEmpty()) {
for (StoragePos pos : posList) {
Barcode barcode = pos.getBarcode();
if (barcode != null) {
if (pnList == null || pnList.isEmpty()) {
pnList.add(barcode.getPartNumber());
//count++;
} else {
if (!pnList.contains(barcode.getPartNumber())) {
pnList.add(barcode.getPartNumber());
//count++;
}
}
}
}
}
return pnList;
}
}
package com.neotel.smfcore.custom.lizhen.innerBox.service.dao;
import com.neotel.smfcore.common.base.IBaseDao;
import com.neotel.smfcore.custom.lizhen.innerBox.bean.PreWarningItem;
public interface IPreWarningItemDao extends IBaseDao {
}
package com.neotel.smfcore.custom.lizhen.innerBox.service.dao.impl;
import com.neotel.smfcore.common.base.AbstractBaseDao;
import com.neotel.smfcore.core.order.service.dao.ILiteOrderDao;
import com.neotel.smfcore.custom.lizhen.innerBox.bean.PreWarningItem;
import com.neotel.smfcore.custom.lizhen.innerBox.service.dao.IPreWarningItemDao;
import org.springframework.stereotype.Service;
@Service
public class PreWarningItemDaoImpl extends AbstractBaseDao implements IPreWarningItemDao {
@Override
public Class getEntityClass() {
return PreWarningItem.class;
}
}
package com.neotel.smfcore.custom.lizhen.innerBox.service.manager;
import com.neotel.smfcore.common.base.IBaseManager;
import com.neotel.smfcore.custom.lizhen.innerBox.bean.PreWarningItem;
import java.util.List;
public interface IPreWarningItemManager extends IBaseManager<PreWarningItem> {
List<PreWarningItem> findAll();
}
package com.neotel.smfcore.custom.lizhen.innerBox.service.manager.impl;
import com.neotel.smfcore.common.bean.PageData;
import com.neotel.smfcore.common.exception.ValidateException;
import com.neotel.smfcore.custom.lizhen.innerBox.bean.PreWarningItem;
import com.neotel.smfcore.custom.lizhen.innerBox.service.dao.IPreWarningItemDao;
import com.neotel.smfcore.custom.lizhen.innerBox.service.manager.IPreWarningItemManager;
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.stereotype.Service;
import java.util.List;
@Slf4j
@Service
public class PreWarningItemManagerImpl implements IPreWarningItemManager {
@Autowired
private IPreWarningItemDao preWarningItemDao;
@Override
public PreWarningItem get(String id) {
return null;
}
@Override
public PreWarningItem save(PreWarningItem item) throws ValidateException {
return preWarningItemDao.save(item);
}
@Override
public void delete(PreWarningItem item) throws ValidateException {
preWarningItemDao.removeOneById(item.getId());
}
@Override
public PageData<PreWarningItem> findByPage(Query query, Pageable pageable) {
return null;
}
@Override
public List<PreWarningItem> findByQuery(Query query) {
return null;
}
@Override
public List<PreWarningItem> findAll() {
return preWarningItemDao.findAll();
}
}
package com.neotel.smfcore.custom.lizhen.innerBox.util;
import com.neotel.smfcore.common.base.AbstractBaseDao;
import com.neotel.smfcore.common.exception.ValidateException;
import com.neotel.smfcore.common.utils.Constants;
import com.neotel.smfcore.common.utils.StringUtils;
import com.neotel.smfcore.core.api.SmfApi;
import com.neotel.smfcore.core.barcode.service.po.Barcode;
import com.neotel.smfcore.core.device.util.DataCache;
import com.neotel.smfcore.core.order.LiteOrderCache;
import com.neotel.smfcore.core.order.service.manager.ILiteOrderItemManager;
import com.neotel.smfcore.core.order.service.manager.ILiteOrderManager;
import com.neotel.smfcore.core.order.service.po.LiteOrder;
import com.neotel.smfcore.core.order.service.po.LiteOrderItem;
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.innerBox.bean.PreWarningItem;
import com.neotel.smfcore.custom.lizhen.innerBox.util.service.PreWarningItemManager;
import com.neotel.smfcore.security.annotation.AnonymousAccess;
import jdk.nashorn.internal.runtime.arrays.ArrayIndex;
import com.neotel.smfcore.custom.lizhen.innerBox.service.manager.IPreWarningItemManager;
import com.neotel.smfcore.custom.lizhen.innerBox.util.service.PreWarningItemCacheManager;
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.stereotype.Service;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.*;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import java.util.stream.Collectors;
/**
......@@ -56,20 +39,16 @@ public class PreWarningItemCache {
private static LiteOrderCache liteOrderCache;
private static TaskService taskService;
private static DataCache dataCache;
private static ILiteOrderManager liteOrderManager;
private static IStoragePosManager storagePosManager;
private static SmfApi smfApi;
private static PreWarningItemManager preWarningItemManager;
private static PreWarningItemCacheManager preWarningItemCacheManager;
private static ILiteOrderItemManager liteOrderItemManager;
private static IPreWarningItemManager preWarningItemManager;
/**
* 添加到预警列表缓存中
*/
......@@ -83,18 +62,6 @@ public class PreWarningItemCache {
*/
private static void generateTask(int priority) {
boolean hasIdleBox = true;
//有料仓空闲下来就需要生成任务,保证料仓不空闲,提高节拍
/*Collection<Storage> boxList = dataCache.getAllStorage().values();
for (Storage storage : boxList) {
if (storage.isStorage(DeviceType.SMD_XLR)) {
Collection<DataLog> boxQueueTasks = taskService.getQueueTasks(storage.getCid());
if (boxQueueTasks.isEmpty()) {
//料仓空闲,没有待执行的任务
hasIdleBox = true;
break;
}
}
}*/
if (hasIdleBox) {
//最早的一条预警时间
......@@ -102,11 +69,9 @@ public class PreWarningItemCache {
String firstItemLine = "";
//每次最多出多少盘
int maxReelCount = 30;
int TReelCount = 0;
int BReelCount = 0;
//如果取不到,从数据库中取
if (queueItemList == null || queueItemList.isEmpty()) {
queueItemList = dataCache.getCache(Constants.CACHE_preWarningItem);
queueItemList = preWarningItemManager.findAll();
}
if (queueItemList == null || queueItemList.isEmpty()) {
return;
......@@ -155,15 +120,15 @@ public class PreWarningItemCache {
lineItems = lineItems.stream().filter(t -> 1 != t.getPriority()).collect(Collectors.toList());
liteOrder.setPriority(0);
}
liteOrder.setOrderNo(getSeq());
//2 如果优先级不为空,则优先生成优先级高的工单
List<LiteOrderItem> orderItems = new ArrayList<>();
if (lineItems != null && !lineItems.isEmpty()) {
liteOrder.setOrderNo(getSeq());
for (PreWarningItem item : lineItems) {
liteOrder.setLine(item.getLine());
LiteOrderItem orderItem = new LiteOrderItem();
orderItem.setLine(item.getLine());
orderItem.setWarningItemId(item.getId());
orderItem.setWarningItemId(item.getItemId());
orderItem.setNeedReelCount(1); //需要出库数量是1
orderItem.setNeedNum(1);//设置出库任务为1盘
orderItem.setPn(item.getPartnumber()); //设置pn
......@@ -179,6 +144,7 @@ public class PreWarningItemCache {
}
if (orderItems != null && !orderItems.isEmpty()) {
liteOrder.setOrderItems(orderItems);
liteOrder.setTotalTaskReelCount(orderItems.size());
liteOrder.setTaskReelCount(orderItems.size());
liteOrder = liteOrderManager.createWithItems(liteOrder);
liteOrderCache.addOrderToMap(liteOrder);
......@@ -192,6 +158,7 @@ public class PreWarningItemCache {
if (remove) {
for (PreWarningItem item : items) {
queueItemList.remove(item);
preWarningItemManager.delete(item);
}
} else {
//判断是否已经生成
......@@ -201,9 +168,9 @@ public class PreWarningItemCache {
PreWarningItem preWarningItem = items.get(i);
if (queueItemList != null && !queueItemList.isEmpty()) {
for (PreWarningItem item : queueItemList) {
if (item.getId().equals(preWarningItem.getId())) {
newItems = newItems.stream().filter(t -> !t.getId().equals(item.getId())).collect(Collectors.toList());
log.info("Mes缺料预警重复物料:" + item.getId() + "PN为:" + item.getPartnumber());
if (preWarningItem.getItemId().equals(item.getItemId())) {
newItems = newItems.stream().filter(t -> !t.getItemId().equals(item.getItemId())).collect(Collectors.toList());
log.info("Mes缺料预警重复物料:" + item.getItemId() + "PN为:" + item.getPartnumber());
break;
}
}
......@@ -213,26 +180,23 @@ public class PreWarningItemCache {
for (int i = 0; i < items.size(); i++) {
PreWarningItem item = items.get(i);
Query q = new Query();
Criteria c = Criteria.where("pn").is(item.getPartnumber()).and("warningItemId").is(item.getId());
Criteria c = Criteria.where("pn").is(item.getPartnumber()).and("warningItemId").is(item.getItemId());
List<LiteOrderItem> orderItems = liteOrderItemManager.findByQuery(q.addCriteria(c));
/*for (LiteOrderItem orderItem : orderItems) {
if (orderItem.getOutNum() >= orderItem.getNeedNum() || orderItem.getOutReelCount() >= orderItem.getNeedReelCount() || !orderItem.getRi().equals(orderItem.getPn())) {
newItems = newItems.stream().filter(t -> !t.getId().equals(orderItem.getWarningItemId())).collect(Collectors.toList());
log.info("Mes缺料预警已经生成工单:" + item.getId() + "PN为:" + item.getPartnumber());
}
}*/
if (orderItems != null && !orderItems.isEmpty()){
newItems = newItems.stream().filter(t -> !t.getId().equals(item.getId())).collect(Collectors.toList());
log.info("Mes缺料预警已经生成工单:" + item.getId() + "PN为:" + item.getPartnumber());
if (orderItems != null && !orderItems.isEmpty()) {
newItems = newItems.stream().filter(t -> !t.getItemId().equals(item.getItemId())).collect(Collectors.toList());
log.info("Mes缺料预警已经生成工单:" + item.getItemId() + "PN为:" + item.getPartnumber());
}
}
if (queueItemList == null || queueItemList.isEmpty()){
if (queueItemList == null || queueItemList.isEmpty()) {
queueItemList = newItems;
} else {
queueItemList.addAll(newItems);
}
for (PreWarningItem item : newItems) {
preWarningItemManager.save(item);
}
dataCache.updateCache(Constants.CACHE_preWarningItem, queueItemList);
}
//dataCache.updateCache(Constants.CACHE_preWarningItem, queueItemList);
}
private static boolean processing = false;
......@@ -254,12 +218,6 @@ public class PreWarningItemCache {
}
}
@Autowired
public void setTaskService(TaskService taskService) {
PreWarningItemCache.taskService = taskService;
}
@Autowired
public void setLiteOrderCache(LiteOrderCache liteOrderCache) {
PreWarningItemCache.liteOrderCache = liteOrderCache;
......@@ -276,26 +234,22 @@ public class PreWarningItemCache {
}
@Autowired
public void setIStoragePosManager(IStoragePosManager storagePosManager) {
PreWarningItemCache.storagePosManager = storagePosManager;
public void setPreWarningItemManager(PreWarningItemCacheManager itemManager) {
PreWarningItemCache.preWarningItemCacheManager = itemManager;
}
@Autowired
public void setSmfApi(SmfApi smfApi) {
PreWarningItemCache.smfApi = smfApi;
public void setLiteOrderItemManager(ILiteOrderItemManager itemManager) {
PreWarningItemCache.liteOrderItemManager = itemManager;
}
@Autowired
public void setPreWarningItemManager(PreWarningItemManager itemManager) {
PreWarningItemCache.preWarningItemManager = itemManager;
public void setPreWarningItemManager(IPreWarningItemManager preWarningItemManager){
PreWarningItemCache.preWarningItemManager = preWarningItemManager;
}
@Autowired
public void setLiteOrderItemManager(ILiteOrderItemManager itemManager) {
PreWarningItemCache.liteOrderItemManager = itemManager;
}
private synchronized static String getSeq() {
return "H" + preWarningItemManager.getNextId(PreWarningItemCache.class.getName());
return "H" + preWarningItemCacheManager.getNextId(PreWarningItemCache.class.getName());
}
}
......@@ -5,7 +5,7 @@ import com.neotel.smfcore.custom.lizhen.innerBox.util.PreWarningItemCache;
import org.springframework.stereotype.Service;
@Service
public class PreWarningItemManager extends AbstractBaseDao {
public class PreWarningItemCacheManager extends AbstractBaseDao {
@Override
public Class getEntityClass() {
return PreWarningItemCache.class;
......
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 org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RestController;
import java.util.*;
@RestController
public class KanbanUtils {
private static String F2;
private static String F3;
private static String F5;
private static IDataLogManager dataLogManager;
private static IStoragePosManager storagePosManager;
private static DataCache dataCache;
/**
* 得到当日的出入库完成统计
*
* @return
*/
public static Map<String, Integer> getTodayInAndOutAmount() {
Map<String, Integer> resultMap = new HashMap<>();
resultMap.put("in", 0);
resultMap.put("out", 0);
//得到当前日期与结束日期
Date startDate = getCurrentDate();
Date endDate = DateUtil.addDays(startDate, 1);
//得到出入库数据
int inCount = dataLogManager.getInOutData(startDate, endDate, OP.PUT_IN, "",-1,"");
int outCount = dataLogManager.getInOutData(startDate, endDate, OP.CHECKOUT, "",-1,"");
resultMap.put("in", inCount);
resultMap.put("out", outCount);
return resultMap;
}
/**
* 得到近7天的出入库数量
*
* @return
*/
public static InOutDataDto getSevenDaysInAndOutAmount() {
InOutDataDto dataDto = new InOutDataDto();
List<String> labelList = new ArrayList<>();
List<Integer> putInValueList = new ArrayList<>();
List<Integer> checkOutValueList = new ArrayList<>();
Date currentDate = getCurrentDate(); //当前时间
Date startDate = DateUtil.addDays(currentDate, -6); //开始时间(与当前时间相差7天)
for (int day = 1; day < 8; 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.setLabelList(labelList);
dataDto.setPutInValueList(putInValueList);
dataDto.setCheckOutValueList(checkOutValueList);
return dataDto;
}
/**
* 得到当前日期
*
* @return
*/
public static Date getCurrentDate() {
Date date = new Date();
return DateUtil.initDate(date, "yyyy-MM-dd");
}
/**
* 根据楼层得到线体
*
* @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();
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(",")));
}
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;
}
@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;
}
}
package com.neotel.smfcore.custom.lizhen.kanban.common.bean.dto;
import lombok.Data;
import lombok.Setter;
import java.util.ArrayList;
import java.util.List;
@Data
public class InOutDataDto {
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;
}
package com.neotel.smfcore.custom.lizhen.kanban.inner;
import com.neotel.smfcore.common.bean.ResultBean;
import com.neotel.smfcore.common.utils.DateUtil;
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.po.Storage;
import com.neotel.smfcore.core.system.service.manager.IDataLogManager;
import com.neotel.smfcore.core.system.util.DevicesStatusUtil;
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 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.util.*;
@RestController
@RequestMapping("/innerKanban")
public class InnerKanbanController {
@Autowired
private DataCache dataCache;
@Autowired
private ILiteOrderItemManager liteOrderItemManager;
@Autowired
private IDataLogManager dataLogManager;
/**
* 获取近7天出入库统计
* @return
*/
@RequestMapping("/getSevenDaysInAndOutAmount")
@AnonymousAccess
public ResultBean getSevenDaysInAndOutAmount(){
InOutDataDto dto = KanbanUtils.getSevenDaysInAndOutAmount();
return ResultBean.newOkResult(dto);
}
/**
* 获取当天出入库统计
* @return
*/
@RequestMapping("/getTodayInAndOutAmount")
@AnonymousAccess
public ResultBean getTodayInAndOutAmount(){
Map<String, Integer> map = KanbanUtils.getTodayInAndOutAmount();
return ResultBean.newOkResult(map);
}
/**
* 获取线体缺料预警信息
*
* @param floor 楼层
* @return
*/
@RequestMapping("/getLineInfo")
@AnonymousAccess
public ResultBean getLineLackPickingInfo(String floor) {
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));
resultList.add(dto);
}
return ResultBean.newOkResult(resultList);
}
/**
* 获取设备状态信息
*
* @return
*/
@RequestMapping("/getDevicesStatus")
@AnonymousAccess
public ResultBean getDevicesStatus() {
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.setStauts(status);
if (storage.isNLShelf()){
dto.setType(0);
} else {
dto.setType(1);
}
resultList.add(dto);
}
}
return ResultBean.newOkResult(resultList);
}
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) {
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));
}
}
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 stauts;
/**
* 所有库位
*/
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;
}
package com.neotel.smfcore.custom.lizhen.kanban.outer;
import com.neotel.smfcore.common.bean.ResultBean;
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.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.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.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
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;
/**
* 获取近7天出入库统计
*
* @return
*/
@RequestMapping("/getSevenDaysInAndOutAmount")
@AnonymousAccess
public ResultBean getSevenDaysInAndOutAmount() {
InOutDataDto dto = KanbanUtils.getSevenDaysInAndOutAmount();
return ResultBean.newOkResult(dto);
}
/**
* 获取当天出入库统计
*
* @return
*/
@RequestMapping("/getTodayInAndOutAmount")
@AnonymousAccess
public ResultBean getTodayInAndOutAmount() {
Map<String, Integer> map = KanbanUtils.getTodayInAndOutAmount();
return ResultBean.newOkResult(map);
}
/**
* 获取工位的出入库统计数据
*
* @return
*/
@RequestMapping("/getStationInAndOutAmout")
@AnonymousAccess
public ResultBean getStationInAndOutAmout() {
List<StationInOutDto> resultList = new ArrayList<>();
Date currentDate = KanbanUtils.getCurrentDate();
//currentDate = DateUtil.addDays(currentDate,-1);
Date endDate = DateUtil.addDays(currentDate, 1);
for (int i = 1; i < 6; i++) {
StationInOutDto dto = new StationInOutDto();
String stationName = "s" + i;
dto.setName(stationName);
int inCount = dataLogManager.getInOutData(currentDate, endDate, OP.PUT_IN, stationName);
dto.setInCount(inCount);
int outCount = dataLogManager.getInOutData(currentDate, endDate, OP.CHECKOUT, stationName);
dto.setOutCount(outCount);
resultList.add(dto);
}
return ResultBean.newOkResult(resultList);
}
/**
* 获取库位使用率
*/
@RequestMapping("/getPosUsage")
@AnonymousAccess
public ResultBean getPosUsage() {
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); //库位使用率
return ResultBean.newOkResult(usage);
}
/**
* 获取picking进度信息
*/
@RequestMapping("/getPickingProgress")
@AnonymousAccess
public ResultBean getPickingProgress() {
LiteOrder liteOrder = new LiteOrder();
for (LiteOrder order : liteOrderCache.getAllLiteOrder()) {
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);
}
return ResultBean.newOkResult(dto);
}
/**
* 获取出入库记录
*/
@RequestMapping("/getQueueTask")
@AnonymousAccess
public ResultBean getQueueTask() {
Collection<DataLog> queueTasks = taskService.getQueueTasks();
return ResultBean.newOkResult(queueTasks);
}
}
package com.neotel.smfcore.custom.lizhen.kanban.outer.bean.dto;
import lombok.Data;
@Data
public class PickingProgressDto {
/**
* pickingId
*/
private String pickingId = "";
/**
* 进度
*/
private int progress;
}
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.utils;
import com.neotel.smfcore.common.bean.ResultBean;
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) {
agvInfoCacheList = 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();
agvInfo.setLocCn(Location.getLoc(loc));
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;
}
package com.neotel.smfcore.custom.lizhen.kanban.utils.enums;
/**
* 点位 AGV
*/
public enum Location {
//外仓点位
WAREHOUSE("仓库", 2),
TAKE("取料点", 2),
PUT("取料点", 2),
//内外仓,通用点位
STANDBY("待机点", 0),
CHARGE("充电点", 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.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;
}
......@@ -14,14 +14,22 @@ import java.util.List;
@Data
@ApiModel("查询条件")
public class ReportQueryCondition {
@QueryCondition(blurry = "pn,partNumber")
@QueryCondition(blurry = "pn,partNumber,barcode.partNumber")
@ApiModelProperty("料号")
private String pn;
@QueryCondition(propName = "orderNo")
@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;
......@@ -30,6 +38,9 @@ public class ReportQueryCondition {
@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("厂别")
......@@ -39,19 +50,41 @@ public class ReportQueryCondition {
@ApiModelProperty("库别")
private String warehouse;
@QueryCondition
@ApiModelProperty("唯一码")
@QueryCondition(blurry = "barcode.barcode,barcode")
private String barcode;
@QueryCondition
@QueryCondition(blurry = "posName")
@ApiModelProperty("库位")
private String posName;
@QueryCondition
@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;
}
......@@ -2,16 +2,38 @@ package com.neotel.smfcore.custom.lizhen.report.inner;
import com.neotel.smfcore.common.bean.PageData;
import com.neotel.smfcore.common.bean.ResultBean;
import com.neotel.smfcore.common.utils.DateUtil;
import com.neotel.smfcore.common.utils.FileUtil;
import com.neotel.smfcore.common.utils.QueryHelp;
import com.neotel.smfcore.common.utils.StringUtils;
import com.neotel.smfcore.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.enums.OP_STATUS;
import com.neotel.smfcore.core.device.util.DataCache;
import com.neotel.smfcore.core.order.LiteOrderCache;
import com.neotel.smfcore.core.order.enums.LITEORDER_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.core.system.util.TaskService;
import com.neotel.smfcore.custom.lizhen.innerBox.enums.ExtendType;
import com.neotel.smfcore.custom.lizhen.report.bean.query.ReportQueryCondition;
import com.neotel.smfcore.security.annotation.AnonymousAccess;
import io.swagger.annotations.ApiOperation;
......@@ -24,7 +46,10 @@ 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
......@@ -57,29 +82,71 @@ public class InnerReportController {
@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;
@ApiOperation("喂料")
@RequestMapping("/feeding")
//@AnonymousAccess
@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);
PageData<LiteOrder> pageData = liteOrderManager.findByPage(q.addCriteria(c), pageable);
List<LiteOrder> liteOrders = pageData.getContent();
liteOrders = liteOrders.stream().sorted(Comparator.comparing(LiteOrder :: getPriority).reversed()).collect(Collectors.toList());
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(pageData.getTotalElements());
resultPageData.setContent(orderMapper.toDto(liteOrders));
resultPageData.setTotalElements(resultLiteOrders.size());
resultPageData.setContent(orderMapper.toDto(resultLiteOrders));
return resultPageData;
}
@ApiOperation("根据工单id获取工单详情")
@RequestMapping("/getItemsByOrderId")
//@AnonymousAccess
public ResultBean getItemsByOrderId(String orderId) {
public ResultBean getItemsByOrderId(String orderId,String partNumber) {
LiteOrder liteOrder = liteOrderManager.get(orderId);
List<LiteOrderItem> orderItems = liteOrderItemManager.findOrderItems(orderId);
List<LiteOrderItem> newOrderItems = new ArrayList<>();
......@@ -88,9 +155,15 @@ public class InnerReportController {
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());
......@@ -101,11 +174,11 @@ public class InnerReportController {
@ApiOperation("楼层下拉")
@RequestMapping("floorPullDown")
@AnonymousAccess
public ResultBean floorPullDown(){
Map<String,String> resultMap = new LinkedHashMap<>();
resultMap.put(F2,F2);
resultMap.put(F3,F3);
resultMap.put(F5,F5);
public ResultBean floorPullDown() {
Map<String, String> resultMap = new LinkedHashMap<>();
resultMap.put(F2, F2);
resultMap.put(F3, F3);
resultMap.put(F5, F5);
return ResultBean.newOkResult(resultMap);
}
......@@ -133,5 +206,473 @@ public class InnerReportController {
}
return ResultBean.newOkResult(resultMap);
}
@ApiOperation("内仓库存")
@RequestMapping("/inventory")
@AnonymousAccess
public PageData inventory(ReportQueryCondition queryCondition, Pageable pageable) {
Query query = QueryHelp.getQuery(queryCondition);
query.addCriteria(Criteria.where("used").is(true));
PageData resultData = new PageData();
if (pageable != null) {
PageData<StoragePos> page = storagePosManager.findByPage(query, pageable);
resultData.setTotalElements(page.getTotalElements());
resultData.setContent(storagePosMapper.toDto(page.getContent()));
} else {
List<StoragePos> storagePosList = storagePosManager.findByQuery(query);
if (storagePosList != null && !storagePosList.isEmpty()) {
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());
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) {
Collection<LiteOrder> liteOrders = liteOrderCache.getAllLiteOrder();
PageData resultData = new PageData();
if (liteOrders != null && !liteOrders.isEmpty()) {
//先按创建时间进行升序
liteOrders = liteOrders.stream().sorted(Comparator.comparing(LiteOrder::getCreateDate)).collect(Collectors.toList());
//再按优先级进行降序
liteOrders = liteOrders.stream().sorted(Comparator.comparing(LiteOrder::getPriority).reversed()).collect(Collectors.toList());
List<LiteOrderItem> orderItems = getLackItems(liteOrders, queryCondition);
if (orderItems != null && !orderItems.isEmpty()) {
resultData.setTotalElements(orderItems.size());
resultData.setContent(orderItemMapper.toDto(orderItems));
}
}
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();
List<Map<String, Object>> results = new ArrayList<>();
if (dtos != null && !dtos.isEmpty()) {
for (OrderItemDto dto : dtos) {
Map<String, Object> resultMap = new LinkedHashMap<>();
resultMap.put("线别", dto.getLine());
resultMap.put("工单号", dto.getOrderNo());
resultMap.put("料号", dto.getPn());
resultMap.put("机器", dto.getMachineName());
resultMap.put("站点", dto.getTableNo());
resultMap.put("站位", dto.getSlot());
resultMap.put("点位", dto.getSubSlot());
resultMap.put("面别", dto.getSide());
resultMap.put("需求卷", dto.getNeedReelCount());
results.add(resultMap);
}
}
try {
FileUtil.downloadExcel(results, response);
} catch (IOException e) {
e.printStackTrace();
log.info("内仓缺料导出导出失败--" + e.getMessage());
}
}
@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));
}
}
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();
/*resultMap.put("inCount", 0);
resultMap.put("outCount", 0);
resultMap.put("storageInCount",0);
resultMap.put("storageOutCount",0);
resultMap.put("virtualInCount",0);
resultMap.put("virtualOutCount",0);
resultMap.put("clearCount",0);
resultMap.put("feedingCount",0);
resultMap.put("manualCheckOutCount",0);*/
//开始时间
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);
//resultMap.put("inCount", inCount);
//全部出库
int outCount = dataLogManager.getInOutData(startDate, endDate, OP.CHECKOUT, queryCondition.getPartNumber(), -1,"");
countList.add(outCount);
//resultMap.put("outCount", outCount);
//智能仓入库
int storageInCount = dataLogManager.getInOutData(startDate, endDate, OP.PUT_IN, queryCondition.getPartNumber(), ExtendType.STORAGE_PUTIN,"");
countList.add(storageInCount);
//resultMap.put("storageInCount",storageInCount);
//智能仓出库
int storageOutCount = dataLogManager.getInOutData(startDate, endDate, OP.CHECKOUT, queryCondition.getPartNumber(), ExtendType.STORAGE_CHECKOUT,"");
countList.add(storageOutCount);
// resultMap.put("storageOutCount",storageOutCount);
//虚拟仓入库
int virtualInCount = dataLogManager.getInOutData(startDate, endDate, OP.PUT_IN, queryCondition.getPartNumber(), ExtendType.VIRTUAL_PUTIN,"");
countList.add(virtualInCount);
//resultMap.put("virtualInCount",virtualInCount);
//虚拟仓出库
int virtualOutCount = dataLogManager.getInOutData(startDate, endDate, OP.CHECKOUT, queryCondition.getPartNumber(), ExtendType.VIRTUAL_CHECKOUT,"");
countList.add(virtualOutCount);
//resultMap.put("virtualOutCount",virtualOutCount);
//手动清空库位
int clearCount = dataLogManager.getInOutData(startDate, endDate, OP.CHECKOUT, queryCondition.getPartNumber(), ExtendType.CLEAR_POS,"");
countList.add(clearCount);
//resultMap.put("clearCount",clearCount);
//手动喂料
int feedingCount = dataLogManager.getInOutData(startDate, endDate, OP.CHECKOUT, queryCondition.getPartNumber(), ExtendType.MANUAL_FEEDING,"");
countList.add(feedingCount);
//resultMap.put("feedingCount",feedingCount);
//手动出库
int manualCheckOutCount = dataLogManager.getInOutData(startDate, endDate, OP.CHECKOUT, queryCondition.getPartNumber(), ExtendType.MANUAL_CHECKOUT,"");
countList.add(manualCheckOutCount);
//resultMap.put("manualCheckOutCount",manualCheckOutCount);
resultMap.put("title",titleList);
resultMap.put("count",countList);
return ResultBean.newOkResult(resultMap);
}
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);
}
}
}
}
}
}
return lackItems;
}
private Object getData(Object data) {
return data == null ? "" : data;
}
}
package com.neotel.smfcore.custom.lizhen.report.outer;
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.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.rest.bean.mapstruct.OrderMapper;
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.rest.dto.StoragePosDto;
import com.neotel.smfcore.core.storage.bean.InventoryItem;
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.report.bean.dto.InventoryDto;
import com.neotel.smfcore.custom.lizhen.report.bean.query.ReportQueryCondition;
import com.neotel.smfcore.security.annotation.AnonymousAccess;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.bson.Document;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.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.data.mongodb.core.query.Update;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
......@@ -60,26 +73,61 @@ public class OuterReportController {
@Autowired
private StoragePosMapper storagePosMapper;
@Autowired
private LiteOrderCache liteOrderCache;
@Autowired
private OrderMapper orderMapper;
@Autowired
private DataCache dataCache;
@Autowired
private BarcodeMapper barcodeMapper;
@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);
Criteria criteria = Criteria.where("subSourceId").exists(true).and("type").is(OP.CHECKOUT);
PageData<DataLog> pageData = new PageData<>();
if (pageable != null) {
pageData = dataLogManager.findByPage(query.addCriteria(criteria), pageable);
} else {
int totalElements = 0;
List<DataLog> dataLogs = dataLogManager.findByQuery(query.addCriteria(criteria));
if (dataLogs != null && !dataLogs.isEmpty()) {
totalElements = dataLogs.size();
}
pageData.setTotalElements(totalElements);
pageData.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);
}
}
return pageData;
}
......@@ -95,24 +143,26 @@ public class OuterReportController {
List<Map<String, Object>> results = new ArrayList<>();
for (DataLog dataLog : contents) {
Map<String, Object> resultMap = new LinkedHashMap<>();
resultMap.put("楼层", dataLog.getLine());
resultMap.put("挑料单号", dataLog.getOrderNo());
resultMap.put("工单号", dataLog.getMo());
resultMap.put("料号", dataLog.getPartNumber());
resultMap.put("物料描述", "");
resultMap.put("储位", dataLog.getPosName());
resultMap.put("段别", dataLog.getSide());
resultMap.put("数量", dataLog.getNum());
resultMap.put("库别", dataLog.getWarehouseCode());
resultMap.put("储位厂区", dataLog.getPlantCode());
resultMap.put("异动类型", dataLog.getSourceName());
resultMap.put("姓名", dataLog.getOperator());
resultMap.put("时间", dataLog.getCreateDate());
resultMap.put("ID No", dataLog.getBarcode());
resultMap.put("D/C", dataLog.getDateCode());
resultMap.put("L/C", dataLog.getBatchInfo());
resultMap.put("厂商代码", dataLog.getProviderNumber());
resultMap.put("厂商", dataLog.getProvider());
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(null));
resultMap.put("储位", getData(dataLog.getPosName()));
resultMap.put("段别", getData(dataLog.getSide()));
resultMap.put("数量", getData(dataLog.getNum()));
resultMap.put("异动类型", getData(dataLog.getChangeType()));
resultMap.put("工号", getData(null));
resultMap.put("姓名", getData(dataLog.getCreator()));
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 {
......@@ -129,133 +179,93 @@ public class OuterReportController {
@RequestMapping("/lackPicking")
@AnonymousAccess
public PageData lackPicking(ReportQueryCondition queryCondition, Pageable pageable) {
Query query = QueryHelp.getQuery(queryCondition);
//缺失数量条件
Criteria lackNumCri = new Criteria() {
@Override
public Document getCriteriaObject() {
Document document = new Document();
document.put("$where", "this.outNum < this.needNum");
return document;
}
};
//缺失料盘条件
Criteria lackReelCri = new Criteria() {
@Override
public Document getCriteriaObject() {
Document document = new Document();
document.put("$where", "this.outReelCount < this.needReelCount");
return document;
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.setFactory(factory);
}
};
List<Criteria> orCriterialList = Lists.newArrayList();
orCriterialList.add(lackNumCri);
orCriterialList.add(lackReelCri);
query.addCriteria(new Criteria().orOperator(orCriterialList));
int totalElements = 0;
List<LiteOrderItem> orderItemList = liteOrderItemManager.findByQuery(query);
if (orderItemList != null && !orderItemList.isEmpty()) {
totalElements = orderItemList.size();
}
if (pageable != null) {
query.with(pageable);
}
List<LiteOrderItem> orderItems = liteOrderItemManager.findByQuery(query);
List<OrderItemDto> itemDtos = new ArrayList<>();
if (orderItems != null && !orderItems.isEmpty()) {
for (LiteOrderItem orderItem : orderItems) {
OrderItemDto itemDto = orderItemMapper.toDto(orderItem);
itemDto.setLackNum(itemDto.getNeedNum() - itemDto.getOutNum());
itemDto.setLackReel(itemDto.getNeedReelCount() - itemDto.getOutReelCount());
itemDtos.add(itemDto);
resultData.setContent(orderItemMapper.toDto(lackItems));
resultData.setTotalElements(lackItems.size());
}
return resultData;
}
PageData pageData = new PageData();
pageData.setContent(itemDtos);
pageData.setTotalElements(totalElements);
return pageData;
}
@ApiOperation("缺料导出")
@RequestMapping("/lackPicking/download")
@AnonymousAccess
public void lackPickingDownload(ReportQueryCondition queryCondition, Pageable pageable,HttpServletResponse response) {
PageData pageData = lackPicking(queryCondition, null);
List<OrderItemDto> orderItemDtos = pageData.getContent();
if (orderItemDtos != null && !orderItemDtos.isEmpty()) {
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 orderItemDto : orderItemDtos) {
for (OrderItemDto dto : dtos) {
Map<String, Object> resultMap = new LinkedHashMap<>();
resultMap.put("厂别", orderItemDto.getPlantCode());
resultMap.put("楼层", orderItemDto.getLine());
resultMap.put("Picking ID", orderItemDto.getOrderNo());
resultMap.put("工单号", orderItemDto.getMo());
resultMap.put("料号", orderItemDto.getPn());
resultMap.put("物料描述", "");
resultMap.put("库别", orderItemDto.getWarehouseCode());
resultMap.put("需求数", orderItemDto.getNeedNum());
resultMap.put("发料数", orderItemDto.getOutNum());
resultMap.put("需求卷", orderItemDto.getNeedReelCount());
resultMap.put("实发卷", orderItemDto.getOutReelCount());
resultMap.put("实发卷", orderItemDto.getOutReelCount());
resultMap.put("实发卷", orderItemDto.getOutReelCount());
resultMap.put("累计实发数", orderItemDto.getTotalOutNum());
resultMap.put("累计实发卷数", orderItemDto.getTotalOutReelCount());
resultMap.put("缺料数量", orderItemDto.getLackNum());
resultMap.put("缺料卷数", orderItemDto.getLackReel());
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());
log.info("缺料清单导出失败--" + e.getMessage());
}
}
}
@ApiOperation("备料清单")
@RequestMapping("/preparePicking")
@AnonymousAccess
public PageData preparePicking(ReportQueryCondition queryCondition, Pageable pageable) {
Query query = QueryHelp.getQuery(queryCondition);
PageData pageData = new PageData();
PageData resultData = new PageData();
if (pageable != null) {
pageData = liteOrderItemManager.findByPage(query, pageable);
PageData<LiteOrderItem> data = liteOrderItemManager.findByPage(query, pageable);
resultData.setTotalElements(data.getTotalElements());
resultData.setContent(orderItemMapper.toDto(data.getContent()));
} else {
int totalElements = 0;
List<LiteOrderItem> orderItems = liteOrderItemManager.findByQuery(query);
if (orderItems != null && !orderItems.isEmpty()){
totalElements = orderItems.size();
}
pageData.setTotalElements(totalElements);
pageData.setContent(orderItems);
}
List<OrderItemDto> dtos = new ArrayList<>();
List<LiteOrderItem> orderItems = pageData.getContent();
if (orderItems != null && !orderItems.isEmpty()) {
for (LiteOrderItem orderItem : orderItems) {
OrderItemDto orderItemDto = orderItemMapper.toDto(orderItem);
int excessOutNum = getExcessOutNum(orderItem); //超发数量
int excessOutReel = getExcessOutReel(orderItem); //超发卷数
orderItemDto.setExcessOutNum(excessOutNum);
orderItemDto.setExcessOutReel(excessOutReel);
dtos.add(orderItemDto);
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()) {
dto.setExcessOutReel(dto.getOutReelCount() - dto.getNeedReelCount());
dto.setExcessOutNum(dto.getOutNum() - dto.getNeedNum());
dto.setTotalOutNum(dto.getNeedNum());
dto.setTotalOutReelCount(dto.getTotalOutReelCount());
} else {
dto.setExcessOutReel(dto.getTotalOutReelCount() - dto.getNeedReelCount());
dto.setExcessOutNum(dto.getTotalOutNum() - dto.getNeedNum());
}
}
PageData resultPageData = new PageData();
resultPageData.setTotalElements(pageData.getTotalElements());
resultPageData.setContent(dtos);
return resultPageData;
return resultData;
}
@ApiOperation("备料清单导出")
......@@ -266,24 +276,24 @@ public class OuterReportController {
List<OrderItemDto> orderItemDtos = pageData.getContent();
if (orderItemDtos != null && !orderItemDtos.isEmpty()) {
List<Map<String, Object>> results = new ArrayList<>();
for (OrderItemDto orderItemDto : orderItemDtos) {
for (OrderItemDto dto : orderItemDtos) {
Map<String, Object> resultMap = new LinkedHashMap<>();
resultMap.put("楼层",orderItemDto.getLine());
resultMap.put("挑料单号",orderItemDto.getOrderNo());
resultMap.put("工单号",orderItemDto.getMo());
resultMap.put("料号",orderItemDto.getPn());
resultMap.put("描述","");
resultMap.put("储位","");
resultMap.put("库别",orderItemDto.getWarehouseCode());
resultMap.put("需求数",orderItemDto.getNeedNum());
resultMap.put("需求卷",orderItemDto.getNeedReelCount());
resultMap.put("实发数",orderItemDto.getOutNum());
resultMap.put("实发卷",orderItemDto.getOutReelCount());
resultMap.put("累计实发数",orderItemDto.getTotalOutNum());
resultMap.put("累计实发卷数",orderItemDto.getTotalOutReelCount());
resultMap.put("段别",orderItemDto.getSide());
resultMap.put("超发数量",orderItemDto.getExcessOutNum());
resultMap.put("超发卷数",orderItemDto.getExcessOutReel());
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 {
......@@ -299,21 +309,31 @@ public class OuterReportController {
@ApiOperation("PK查询")
@RequestMapping("/pickingSearch")
@AnonymousAccess
public PageData pickingSearch(ReportQueryCondition queryCondition,Pageable pageable){
public PageData pickingSearch(ReportQueryCondition queryCondition, Pageable pageable) {
Query query = QueryHelp.getQuery(queryCondition);
PageData resultData = new PageData();
if (pageable != null) {
query.with(pageable);
}
PageData<LiteOrderItem> data = liteOrderItemManager.findByPage(query, pageable);
resultData.setTotalElements(data.getTotalElements());
resultData.setContent(orderItemMapper.toDto(data.getContent()));
} else {
List<LiteOrderItem> orderItems = liteOrderItemManager.findByQuery(query);
int totalElements = 0;
if (orderItems != null && !orderItems.isEmpty()){
totalElements = orderItems.size();
if (orderItems != null && !orderItems.isEmpty()) {
resultData.setTotalElements(orderItems.size());
resultData.setContent(orderItemMapper.toDto(orderItems));
}
PageData pageData = new PageData();
pageData.setTotalElements(totalElements);
pageData.setContent(orderItemMapper.toDto(orderItems));
return pageData;
}
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;
}
......@@ -327,12 +347,14 @@ public class OuterReportController {
List<Map<String, Object>> results = new ArrayList<>();
for (OrderItemDto orderItemDto : orderItemDtos) {
Map<String, Object> resultMap = new LinkedHashMap<>();
resultMap.put("厂别",orderItemDto.getPlantCode());
resultMap.put("楼层",orderItemDto.getLine());
resultMap.put("PK ID",orderItemDto.getOrderNo());
resultMap.put("工单号",orderItemDto.getMo());
resultMap.put("料号",orderItemDto.getPn());
resultMap.put("套数",orderItemDto.getNeedReelCount());
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 {
......@@ -349,38 +371,33 @@ public class OuterReportController {
@AnonymousAccess
public PageData change(ReportQueryCondition queryCondition, Pageable pageable) {
Query query = QueryHelp.getQuery(queryCondition);
PageData<DataLog> pageData = new PageData<>();
if (pageable != null){
pageData = dataLogManager.findByPage(query, pageable);
PageData resultData = new PageData();
if (pageable != null) {
PageData<DataLog> data = dataLogManager.findByPage(query, pageable);
resultData.setTotalElements(data.getTotalElements());
resultData.setContent(data.getContent());
} else {
int totalElements = 0;
List<DataLog> dataLogs = dataLogManager.findByQuery(query);
if (dataLogs != null && !dataLogs.isEmpty()){
totalElements = dataLogs.size();
List<DataLog> logs = dataLogManager.findByQuery(query);
if (logs != null && !logs.isEmpty()) {
resultData.setTotalElements(logs.size());
resultData.setContent(logs);
}
pageData.setTotalElements(totalElements);
pageData.setContent(dataLogs);
}
//单独对隔口数量进行
List<DataLog> dataLogs = pageData.getContent();
if (dataLogs != null && !dataLogs.isEmpty()) {
List<String> posNames = dataLogs.stream().filter(dataLog -> StringUtils.isNotBlank(dataLog.getPosName())).map(DataLog::getPosName).collect(Collectors.toList());
List<Barcode> barcodes = barcodeManager.findByQuery(new Query(Criteria.where("posName").in(posNames)));
if (barcodes != null && !barcodes.isEmpty()) {
Map<String, Long> countMap = barcodes.stream().collect(Collectors.groupingBy(Barcode::getPosName, Collectors.counting()));
for (DataLog dataLog : dataLogs) {
String posName = dataLog.getPosName();
if (StringUtils.isNotBlank(posName) && countMap.get(posName) != null){
dataLog.setPartitionCount(countMap.get(posName).intValue());
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);
}
}
}
pageData.setContent(dataLogs);
return pageData;
return resultData;
}
@ApiOperation("异动导出")
......@@ -393,22 +410,25 @@ public class OuterReportController {
List<Map<String, Object>> results = new ArrayList<>();
for (DataLog dataLog : dataLogs) {
Map<String, Object> resultMap = new LinkedHashMap<>();
resultMap.put("料号", dataLog.getPartNumber());
resultMap.put("物料描述", "");
resultMap.put("隔口码", dataLog.getReelPosName());
resultMap.put("隔口数量", dataLog.getPartitionCount());
resultMap.put("储位", dataLog.getBoxPosName());
resultMap.put("异动类型", dataLog.getSourceName());
resultMap.put("ID NO", dataLog.getBarcode());
resultMap.put("LOT", dataLog.getBatchInfo());
resultMap.put("D/C", dataLog.getDateCode());
resultMap.put("厂商", dataLog.getProvider());
resultMap.put("Keeper", dataLog.getKeeperCode());
resultMap.put("原始库别", dataLog.getWarehouseCode());
resultMap.put("目的库别", "");
resultMap.put("供应商代码", dataLog.getProviderNumber());
resultMap.put("事务日期", dataLog.getCreateDate());
resultMap.put("姓名", dataLog.getOperator());
resultMap.put("厂别", getData(dataLog.getPlantCode()));
resultMap.put("厂区", getData(dataLog.getFactory()));
resultMap.put("料号", getData(dataLog.getPartNumber()));
resultMap.put("物料描述", getData(null));
resultMap.put("隔口码", getData(dataLog.getPosName()));
resultMap.put("异动数量", getData(dataLog.getNum()));
resultMap.put("储位", getData(dataLog.getStoragePosName()));
resultMap.put("异动类型", getData(dataLog.getChangeType()));
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.getCreator()));
resultMap.put("工号", getData(null));
resultMap.put("姓名", getData(dataLog.getOperator()));
results.add(resultMap);
}
try {
......@@ -420,55 +440,377 @@ public class OuterReportController {
}
}
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, Pageable pageable) {
Query query = QueryHelp.getQuery(queryCondition);
query.addCriteria(Criteria.where("used").is(true));
PageData<StoragePos> pages = storagePosManager.findByPage(query, pageable);
//处理隔口数量
List<StoragePosDto> storagePosDtos = storagePosMapper.toDto(pages.getContent());
if (storagePosDtos != null && !storagePosDtos.isEmpty()) {
for (StoragePosDto storagePosDto : storagePosDtos) {
BarcodeDto barcode = storagePosDto.getBarcode();
if (barcode == null){
continue;
public PageData inventory(ReportQueryCondition queryCondition, Query query, Pageable pageable) {
posMap.clear();
countMap.clear();
if (queryCondition != null) {
query = QueryHelp.getQuery(queryCondition);
query.addCriteria(Criteria.where("posName").exists(true).ne("").and("partNumber").nin(Arrays.asList("CS", "CM", "CB")));
} else {
if (posMap == null || posMap.isEmpty()) {
List<StoragePos> storagePosList = storagePosManager.findNotEmptyPosName();
for (StoragePos pos : storagePosList) {
Barcode barcode = pos.getBarcode();
posMap.put(barcode.getBarcode(), pos);
}
List<BarcodeDto> subCodeList = barcode.getSubCodeList();
if (subCodeList != null && !subCodeList.isEmpty()){
List<String> posNames = subCodeList.stream().filter(barcodeDto -> StringUtils.isNotBlank(barcodeDto.getPosName())).map(BarcodeDto::getPosName).collect(Collectors.toList());
Map<String, Long> countMap = getPartitionCountMap(posNames);
for (BarcodeDto barcodeDto : subCodeList) {
String posName = barcodeDto.getPosName();
if (StringUtils.isNotBlank(posName) && countMap.get(posName) != null){
barcodeDto.setPartitionCount(countMap.get(posName).intValue());
}
}
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 = 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) {
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);
}
}
return new PageData(storagePosDtos, pages.getTotalElements());
}
public Map<String, Long> getPartitionCountMap(List<String> posNames) {
Map<String, Long> countMap = new HashMap<>();
List<Barcode> barcodes = barcodeManager.findByQuery(new Query(Criteria.where("posName").in(posNames)));
//库位名称
if (pos != null && StringUtils.isNotBlank(pos.getPosName())) {
dto.setStoragePosName(pos.getPosName());
Storage storage = dataCache.getStorageById(pos.getStorageId());
if(storage != null) {
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("");
result.add(dto.getCreator());
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()) {
countMap = barcodes.stream().collect(Collectors.groupingBy(Barcode::getPosName, Collectors.counting()));
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(null));
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());
}
return countMap;
}
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) {
String pn = orderItem.getPn();
//1 先判断是否有库存
InventoryItem inventoryItem = inventory.get(pn);
if (inventoryItem == null) {
orderItem.setLackNum(orderItem.getNeedNum());
orderItem.setLackReel(orderItem.getNeedReelCount());
items.add(orderItem);
continue;
}
//2 计算每一个partNumber的数量
int pnAmount = 0;
if (partNumberAmount.get(pn) == null) {
pnAmount = getAmountByPartNumber(pn);
partNumberAmount.put(pn, pnAmount);
} else {
pnAmount = partNumberAmount.get(pn);
}
//3 处理不是超发
if (!liteOrder.isExcess()) {
int needNum = orderItem.getNeedNum() - orderItem.getTotalOutNum();
int needNumReel = needNum / pnAmount;
if (needNumReel <= (orderItem.getTotalOutReelCount() - orderItem.getNeedReelCount())) {
needNumReel = orderItem.getNeedReelCount();
}
//判断是否全部已出数量大于需要出库的数量,如果有,则跳过
if (orderItem.getTotalOutReelCount() >= needNumReel) {
continue;
}
int avaiReel = inventoryItem.getStockReel() - inventoryItem.getLockReel() - inventoryItem.getBindReel(); //可用盘数
avaiReel = avaiReel < 0 ? 0 : avaiReel;
if (avaiReel - needNumReel < 0) {
int lackReel = orderItem.getNeedReelCount() - (avaiReel - (avaiReel - needNumReel));
int lackNum = orderItem.getNeedNum() - (avaiReel - (avaiReel - needNumReel)) * pnAmount;
orderItem.setLackReel(lackReel);
orderItem.setLackNum(lackNum);
items.add(orderItem);
} else {
inventoryItem.setBindReel(inventoryItem.getBindReel() + needNumReel);
inventory.put(pn, inventoryItem);
}
}
//4 超发情况
else {
int needNum = orderItem.getNeedNum() - orderItem.getOutNum();
int needNumReel = needNum / pnAmount;
int needReel = orderItem.getNeedReelCount() - orderItem.getOutReelCount();
//先判断是否满足数量
if (needNumReel <= 0 && needReel <= 0) {
continue;
} else {
//判断可用需求数量
if (needNumReel > 0) {
int avaiReel = inventoryItem.getStockReel() - inventoryItem.getLockReel() - inventoryItem.getBindReel(); //可用盘数
avaiReel = avaiReel < 0 ? 0 : avaiReel;
if (avaiReel - needNumReel < 0) {
//int lackReel = orderItem.getNeedReelCount() - (avaiReel - (avaiReel - needNumReel));
int lackNum = orderItem.getNeedNum() - (avaiReel - (avaiReel - needNumReel)) * pnAmount;
orderItem.setLackReel(orderItem.getNeedReelCount());
orderItem.setLackNum(lackNum);
items.add(orderItem);
continue;
} else {
inventoryItem.setBindReel(inventoryItem.getBindReel() + needNumReel);
inventory.put(pn, inventoryItem);
}
}
//判断需求盘数
if (needReel > 0) {
int avaiReel = inventoryItem.getStockReel() - inventoryItem.getLockReel() - inventoryItem.getBindReel(); //可用盘数
avaiReel = avaiReel < 0 ? 0 : avaiReel;
if (avaiReel - needReel < 0) {
orderItem.setLackReel(-(avaiReel - needReel));
items.add(orderItem);
} else {
inventoryItem.setBindReel(inventoryItem.getBindReel() + needNumReel);
inventory.put(pn, inventoryItem);
}
}
}
}
}
}
}
}
return items;
}
private int getExcessOutReel(LiteOrderItem orderItem) {
int differenceReelCount = orderItem.getTotalOutReelCount() - orderItem.getNeedReelCount() - orderItem.getTotalReelCountByOutNum();
return differenceReelCount > 0 ? differenceReelCount : 0;
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 int getExcessOutNum(LiteOrderItem orderItem) {
int differenceNum = orderItem.getOutNum() - orderItem.getNeedNum();
return differenceNum > 0 ? differenceNum : 0;
private Object getData(Object data) {
return data == null ? "" : data;
}
}
......@@ -6,10 +6,10 @@
</Properties>
<appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss} %-5level [%file:%line] - %msg%n"/>
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss:SSS} %-5level [%file:%line] - %msg%n"/>
</Console>
<RollingFile name="log" fileName="${LOG_HOME}/${LOG_NAME}" filePattern="${LOG_HOME}/%d{yyyy-MM-dd}.${LOG_NAME}" append="true">
<PatternLayout charset="GB18030" pattern="%d{yyyy-MM-dd HH:mm:ss} %-5level [%file:%line] - %msg%n" />
<PatternLayout charset="GB18030" pattern="%d{yyyy-MM-dd HH:mm:ss:SSS} %-5level [%file:%line] - %msg%n" />
<Policies>
<TimeBasedTriggeringPolicy modulate="true" interval="1" />
</Policies>
......
......@@ -100,6 +100,7 @@ smfcore.order.out.noTask=\u5DE5\u5355\u65E0\u53EF\u6267\u884C\u7684\u4EFB\u52A1
smfcore.cannotUpdateOrderNum=\u5DE5\u5355\u5DF2\u51FA\u5E93\uFF0C\u4E0D\u80FD\u4FEE\u6539\u6570\u91CF
smfcore.order.close.success=\u5DE5\u5355\u5173\u95ED\u6210\u529F
smfcore.order.close.taskNotEnd=\u5DE5\u5355\u8FD8\u6709\u672A\u5B8C\u6210\u7684\u4EFB\u52A1
smfcore.order.executing=\u5DF2\u7ECF\u6709\u6B63\u5728\u6267\u884C\u7684\u5DE5\u5355,\u8BF7\u6838\u5B9E
smfcore.manualOut=\u624B\u52A8\u51FA\u5E93
smfcore.error.barcode.noRules=\u89E3\u6790\u89C4\u5219\u672A\u5B9A\u4E49
smfcore.error.barcode.wrongLength=\u6761\u7801[{0}]\u957F\u5EA6\u9519\u8BEF
......@@ -115,6 +116,8 @@ smfcore.order.uploadOK=\u5DE5\u5355\u4E0A\u4F20\u6210\u529F
smfcore.order.ameExists=\u5DE5\u5355\u540D\u79F0[{0}]\u5DF2\u5B58\u5728
smfcore.order.hasClose=\u5DE5\u5355\u5DF2\u5173\u95ED
smfcore.order.supplementOutFail=\u672A\u627E\u5230\u53EF\u4EE5\u51FA\u5E93\u7684\u8865\u6599
smfcore.order.confirmExcess=\u8BF7\u9009\u62E9\u5DE5\u5355\u662F\u5426\u8D85\u53D1\uFF0C\u518D\u8FDB\u884C\u51FA\u5E93\u4F5C\u4E1A
smfcore.order.excessSuccess=\u5DE5\u5355\u5DF2\u7ECF\u8D85\u53D1
smfcore.materialBox.quantityshort=\u7269\u6599\u6570\u91CF\u4E0D\u8DB3
smfcore.materialBox.invalid=\u672A\u627E\u5230\u6599\u76D2\u4FE1\u606F{0}
smfcore.materialBox.noReel=\u6599\u76D2\u4E2D\u672A\u627E\u5230\u5BF9\u5E94\u7269\u6599
......@@ -151,6 +154,7 @@ smfcore.solderPasteSetting=\u8BBE\u7F6E
smfcore.orderSetting=\u5171\u4EAB\u6587\u4EF6\u5939
smfcore.enterCorrectFolder=\u8BF7\u8F93\u5165\u6B63\u786E\u7684\u6587\u4EF6\u5939
smfcore.taskHasEnd=\u4EFB\u52A1{0}\u5DF2\u53D6\u6D88\u6216\u5DF2\u7ED3\u675F
smfcore.taskStatusHasUpdate=\u4EFB\u52A1{0}\u5DF2\u7ECF\u4FEE\u6539\u72B6\u6001
smfcore.virtual.notFound=\u672A\u627E\u5230\u865A\u62DF\u4ED3
smfcore.virtual.pos.notInStorage=\u865A\u62DF\u4ED3[{0}]\u4E2D\u672A\u627E\u5230\u5E93\u4F4D[{1}]
smfcore.virtual.msg.outConfirm=[{0}]\u51FA\u5E93\u5B8C\u6210
......@@ -186,6 +190,7 @@ smfcore.storagePos.lockName=\u5DE5\u5355\u53F7
smfcore.storagePos.amount=\u6570\u91CF
smfcore.storagePos.putInTime=\u9996\u6B21\u5165\u5E93\u65F6\u95F4
smfcore.storagePos.putInDate=\u5165\u5E93\u65F6\u95F4
smfcore.storagePos.existBarcode={0}\u5DF2\u5B58\u5728\u5E93\u4F4D{1}\u4E2D
smfcore.inventory.partNumber=\u7269\u6599\u7F16\u53F7
smfcore.inventory.count=\u6570\u91CF
smfcore.inventory.lockReel=\u9501\u5B9A
......@@ -240,6 +245,7 @@ smfcore.error.barcode.errorSize=\u6761\u7801\u672A\u8BBE\u7F6E\u5C3A\u5BF8
smfcore.shelf.msg.alreadyInPos=\u8BE5\u7269\u6599\u5DF2\u5728\u5E93\u4F4D[{0}]\u4E2D
smfcore.shelf.msg.inMergeOk=\u64CD\u4F5C\u6210\u529F,\u8BF7\u5408\u5E76\u5E93\u4F4D[{0}]\u5E76\u653E\u5165\u6599\u76D8
smfcore.shelf.msg.inError=\u672A\u627E\u5230\u9002\u5408[{0}]\u7684\u5E93\u4F4D
smfcore.shelf.msg.noPos=\u672A\u627E\u5230\u7B26\u5408\u6761\u4EF6\u7684\u5E93\u4F4D
smfcore.dumpWarehousing=\u8F6C\u50A8\u5165\u5E93
smfcore.singleDiskWarehousing=\u5355\u76D8\u5165\u5E93
smfcore.sluggishMaterials=\u5446\u6EDE\u7269\u6599
......
支持 Markdown 格式
你添加了 0 到此讨论。请谨慎行事。
Finish editing this message first!