Commit 313eb402 zshaohui

原料仓和半成品仓功能提交

1 个父辈 5281733a
正在显示 39 个修改的文件 包含 1783 行增加235 行删除
......@@ -246,6 +246,26 @@
<groupId>org.springframework.kafka</groupId>
<artifactId>spring-kafka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-commons</artifactId>
<version>2.7.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot</artifactId>
<version>2.7.1</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.21</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-jul</artifactId>
<version>2.17.0</version>
</dependency>
</dependencies>
......
......@@ -905,6 +905,8 @@ public class BarcodeRule {
codeStr = "B0700001A";
rule = "RI[0:8:1]PN[0:3:6]";
//codeStr = "B0700001A";
//rule = "RI[0:8:1]PN[0:3:6]";
......
......@@ -282,4 +282,7 @@ public class BarcodeDto implements Serializable {
@ApiModelProperty("Keeper")
private String keeperCode;
@ApiModelProperty("栈板id")
private String palletId;
}
......@@ -275,6 +275,8 @@ public class Barcode extends BasePo implements Serializable {
private String barSource;
private String odn;
/**
* 是否是锡膏
*/
......@@ -374,6 +376,13 @@ public class Barcode extends BasePo implements Serializable {
//记录序列号
private int seq = 0;
private Map<String,Integer> heightMap = new HashMap<>();
public void updateHeightMap(String key,Integer value){
heightMap.put(key,value);
}
/**
* 添加相关联条码
*
......
......@@ -70,5 +70,8 @@ public enum OP_STATUS {
OUT_POS,
//出料口
ON_SLIDE
ON_SLIDE,
//物料放入料格
REEL_TO_BOX
}
......@@ -9,6 +9,7 @@ import com.neotel.smfcore.common.utils.Constants;
import com.neotel.smfcore.common.utils.SecurityUtils;
import com.neotel.smfcore.common.utils.StringUtils;
import com.neotel.smfcore.core.api.SmfApi;
import com.neotel.smfcore.core.barcode.enums.BARCODE_STATUS;
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;
......@@ -34,6 +35,7 @@ import com.neotel.smfcore.custom.lizhen.innerBox.bean.StorageExport;
import com.neotel.smfcore.custom.lizhen.innerBox.enums.ExtendType;
import com.neotel.smfcore.custom.lizhen.innerBox.util.StorageExportUtil;
import com.neotel.smfcore.custom.lizhen.third.maicheng.api.MaiZhengApi;
import com.neotel.smfcore.custom.luxsan.factory_c.util.CacheNameUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.query.Criteria;
......@@ -384,7 +386,7 @@ public class LiteOrderCache {
//工单未关闭的话,检查状态,全部都出完进行关闭
boolean closed = true;
for (LiteOrderItem liteOrderItem : order.getOrderItems()) {
if (!liteOrderItem.isOutFinished()) {
if (!liteOrderItem.isOutNumFinished()) {
closed = false;
break;
}
......@@ -697,6 +699,7 @@ public class LiteOrderCache {
log.info("关闭工单[" + orderNo + "]成功");
liteOrder.setClosed(true);
liteOrderManager.save(liteOrder);
liteOrderMap.remove(orderNo);
smfApi.onOrderStatusChange(liteOrder);
return "smfcore.order.close.success";
}
......@@ -844,16 +847,16 @@ public class LiteOrderCache {
}
public boolean hasExecutingOrder() {
public String hasExecutingOrder() {
Collection<LiteOrder> liteOrders = getAllLiteOrder();
if (liteOrders != null && !liteOrders.isEmpty()) {
for (LiteOrder liteOrder : liteOrders) {
if (liteOrder.isOutTails()) {
return true;
if (!liteOrder.isTaskFinished() && !liteOrder.isNew() && !liteOrder.isClosed()) {
return liteOrder.getOrderNo();
}
}
}
return false;
return "";
}
......@@ -885,6 +888,11 @@ public class LiteOrderCache {
return "smfcore.order.out.executing";
}
List<String> storageIdList = new ArrayList<>();
for (Storage storage : dataCache.getAllStorage().values()) {
storageIdList.add(storage.getId());
}
//3.设置工单其他信息
liteOrder.setStartDate(new Date());
liteOrder.setTaskReelCount(0);
......@@ -894,19 +902,32 @@ public class LiteOrderCache {
liteOrderMap.put(liteOrder.getOrderNo(), liteOrder);
//4.获取partNumber所在的库位信息
List<String> partNumberList = liteOrder.getOrderItems().stream().map(item -> item.getPn()).collect(Collectors.toList());
List<StoragePos> allStoragePosList = storagePosManager.findStoragePosByPartNumber(partNumberList);
//List<String> partNumberList = liteOrder.getOrderItems().stream().map(item -> item.getPn()).collect(Collectors.toList());
//List<StoragePos> allStoragePosList = storagePosManager.findStoragePosByPartNumber(partNumberList);
//5.开始处理工单详情
List<StoragePos> needOutPosList = new ArrayList<>();
int orderTaskReelCount = 0;
for (LiteOrderItem orderItem : liteOrder.getOrderItems()){
//6.排除的仓位信息
List<String> excludeIdList = new ArrayList<>();
Collection<String> excludePosIds = taskService.excludePosIds();
for (String excludePosId : excludePosIds) {
excludeIdList.add(excludePosId);
Collection excludeIdList = excludeOutPosIds();
//判断有没有正在执行的料箱入库信息
/*Map<String,String> cacheMap = dataCache.getCache(CacheNameUtil.CHCHE_EXECUTINGPUTIN_BOX);
if (cacheMap == null){
cacheMap = new HashMap<>();
}
Set<String> keySet = cacheMap.keySet();
if (keySet != null && !keySet.isEmpty()){
for (String boxStr : keySet) {
log.info(boxStr+"正在执行入库任务,先不允许出库");
StoragePos pos = storagePosManager.getByBarcode(boxStr);
if (pos != null){
excludeIdList.add(pos.getId());
}
}
}*/
//7.判断是否指定的itemId
if (orderItemIds != null && !orderItemIds.isEmpty()) {
......@@ -941,7 +962,10 @@ public class LiteOrderCache {
String warehouseCode = orderItem.getWarehouseCode(); //厂别
String brand = orderItem.getBrand(); //供应商
String pn = orderItem.getPn(); //料号
StoragePos pos = getStoragePosByPartNumberAndBrand(allStoragePosList,pn,excludeIdList);
StoragePos pos = storagePosManager.findPartNumberInStorages(storageIdList,pn,excludeIdList,dataCache.getCheckOutType(),warehouseCode,brand,true);
if (pos == null) {
pos = storagePosManager.findPartNumberInStorages(storageIdList, pn, excludeIdList, dataCache.getCheckOutType(), warehouseCode, brand, false);
}
if (pos == null) {
log.info(orderItem.getOrderId() + "厂商:" + warehouseCode + ",供应商:" + brand + ",料号:" + pn + "未找到存在库位,跳过");
break;
......@@ -1019,20 +1043,23 @@ public class LiteOrderCache {
log.info("开始生成料箱出库任务");
for (StoragePos pos : needOutPosList) {
Barcode barcode = pos.getBarcode();
Storage storage = dataCache.getStorageById(pos.getStorageId());
log.info(pos.getPosName()+"出库,料箱号为:"+barcode.getBarcode());
DataLog task = new DataLog(storage, barcode, pos);
task.setSourceId(liteOrder.getId());
task.setSourceName(liteOrder.getOrderNo());
task.setSubSourceId(barcode.getLockName());
task.setSubSourceInfo(barcode.getLockName());
task.setType(OP.CHECKOUT);
task.setCreator(SecurityUtils.getCurrentUsername());
task.setStatus(OP_STATUS.WAIT.name());
try {
taskService.addTaskToExecute(task);
} catch (Exception e) {
e.getMessage();
log.info("barcode:"+barcode.getBarcode()+",状态为:"+barcode.getStatus());
if (barcode.getStatus() == BARCODE_STATUS.IN_STORE) {
Storage storage = dataCache.getStorageById(pos.getStorageId());
log.info(pos.getPosName() + "出库,料箱号为:" + barcode.getBarcode());
DataLog task = new DataLog(storage, barcode, pos);
task.setSourceId(liteOrder.getId());
task.setSourceName(liteOrder.getOrderNo());
task.setSubSourceId(barcode.getLockName());
task.setSubSourceInfo(barcode.getLockName());
task.setType(OP.CHECKOUT);
task.setCreator(SecurityUtils.getCurrentUsername());
task.setStatus(OP_STATUS.WAIT.name());
try {
taskService.addTaskToExecute(task);
} catch (Exception e) {
e.getMessage();
}
}
}
}
......@@ -1091,7 +1118,7 @@ public class LiteOrderCache {
//按排序找到最先过期入库的partNumber
if (barcodeList != null && !barcodeList.isEmpty()) {
List<String> posNameList = barcodeList.stream().sorted(Comparator.comparing(Barcode::getExpireDate, Comparator.nullsFirst(Date::compareTo)).reversed()).map(item -> item.getPosName()).distinct().collect(Collectors.toList());
List<String> posNameList = barcodeList.stream().sorted(Comparator.comparing(Barcode::getCreateDate, Comparator.nullsFirst(Date::compareTo)).reversed()).map(item -> item.getPosName()).distinct().collect(Collectors.toList());
for (String posName : posNameList) {
for (StoragePos pos : storagePosList) {
if (StringUtils.isNotBlank(posName)) {
......@@ -1239,4 +1266,85 @@ public class LiteOrderCache {
}
return resultList;
}
public synchronized void wipTicketOut(String orderNo) {
LiteOrder cacheOrder = liteOrderMap.get(orderNo);
if (cacheOrder == null) {
cacheOrder = liteOrderManager.findByOrderNo(orderNo);
}
if (cacheOrder == null) {
log.info("未找到工单:" + orderNo + "的信息");
throw new ValidateException("smfcore.order.out.notFound", "未找到工单");
}
if (cacheOrder.isClosed()) {
log.info("工单:" + orderNo + "已经关闭");
throw new ValidateException("smfcore.order.hasClose", "工单已关闭");
}
if (!cacheOrder.isTaskFinished() && !cacheOrder.isNew()) {
log.info("工单:" + orderNo + "正在执行中");
throw new ValidateException("smfcore.order.out.executing", "工单正在执行");
}
log.info("开始执行工单:" + orderNo);
cacheOrder.setTaskReelCount(0);
cacheOrder.setFinishedReelCount(0);
cacheOrder.setStatus(LITEORDER_STATUS.TAILS);
CHECKOUT_TYPE checkoutType = dataCache.getCheckOutType();
List<String> storageIdList = new ArrayList<>();
for (Storage storage : dataCache.getAllStorage().values()) {
storageIdList.add(storage.getId());
}
int taskReelCount = 0;
for (LiteOrderItem orderItem : cacheOrder.getOrderItems()) {
String partNumber = orderItem.getPn();
int taskNum = 0;
int remainNum = orderItem.getNeedNum() - orderItem.getTotalOutNum();
while (taskNum < remainNum) {
Collection<String> excludePosIds = excludeOutPosIds();
StoragePos pos = storagePosManager.findPartNumberInStorages(storageIdList, partNumber, excludePosIds, checkoutType, orderItem.getBrand());
if (pos == null) {
break;
} else {
Barcode barcode = pos.getBarcode();
log.info(barcode.getBarcode() + "需要生成出库任务,工单号为:" + orderNo);
taskNum = taskNum + barcode.getAmount();
taskReelCount = taskReelCount + 1;
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.setStatus(OP_STATUS.WAIT.name());
taskService.addTaskToExecute(task);
}
}
}
if (taskReelCount <= 0) {
log.info("工单:" + orderNo + "没有找到对应的任务");
finishedOrderTasks(cacheOrder);
throw new ValidateException("smfcore.order.out.noTask", "工单无可执行的任务");
}
cacheOrder.setTaskReelCount(taskReelCount);
liteOrderManager.save(cacheOrder);
liteOrderMap.put(cacheOrder.getOrderNo(), cacheOrder);
log.info("生成工单" + orderNo + "任务结束,数量为:" + taskReelCount);
}
public synchronized void rawTicketOut(String orderNo) {
}
}
......@@ -593,6 +593,7 @@ public class OrderController {
@RequestMapping("/pauseOrder")
public ResultBean pauseOrder(@RequestBody Map<String, String> paramMap) {
String orderNo = paramMap.get("orderNo");
boolean hasOutBox = false;
//根据orderNo得到正在执行的任务
Collection<DataLog> queueTasks = taskService.getQueueTasks();
if (queueTasks != null && !queueTasks.isEmpty()) {
......@@ -601,10 +602,14 @@ public class OrderController {
if (orderNo.equals(queueTask.getSourceName())) {
queueTask.setStatus(OP_STATUS.PAUSE.name());
taskService.updateQueueTask(queueTask);
hasOutBox = true;
}
}
}
}
if (!hasOutBox){
return ResultBean.newErrorResult(-1,"","没有出库状态为等待中箱子任务,请检查");
}
//同时更改工单状态为暂停
liteOrderCache.pauseOrder(orderNo);
return ResultBean.newOkResult("");
......@@ -613,9 +618,9 @@ public class OrderController {
@ApiOperation("工单恢复")
@RequestMapping("/restoreOrder")
public ResultBean restoreOrder(@RequestBody Map<String, String> paramMap) {
if (liteOrderCache.hasExecutingOrder()) {
if (StringUtils.isNotEmpty(liteOrderCache.hasExecutingOrder())) {
//throw new ValidateException("","有正在执行的工单,不允许恢复");
return ResultBean.newErrorResult(-1, "", "有正在执行的工单,不允许恢复");
return ResultBean.newErrorResult(-1, "", "有正在执行的工单"+liteOrderCache.hasExecutingOrder()+",不允许恢复");
}
String orderNo = paramMap.get("orderNo");
//根据orderNo得到正在执行的任务
......
......@@ -387,6 +387,20 @@ public class LiteOrderItem extends BasePo implements Serializable ,Comparable<Li
private String shipTo;
private String srcPlant;
private String dstPlant;
private String srcWarehouse;
private String dstWarehouse;
private String srcBatch;
private String dstBatch;
private String moveType;
public void setOutReelList(String reel) {
if (outReelList == null){
outReelList = new ArrayList<>();
......@@ -408,6 +422,13 @@ public class LiteOrderItem extends BasePo implements Serializable ,Comparable<Li
return totalOutReelCount - needReelCount >=0;
}
/**
* 出库是否满足要求,已出库数量大于需求数量
*/
public boolean isOutNumFinished(){
return totalOutNum - needNum >=0;
}
@Override
public int compareTo(LiteOrderItem o) {
if(this.getOutNum()!=o.getOutNum()){
......
......@@ -279,6 +279,16 @@ public class StoragePosController {
throw new ValidateException("smfcore.valueNotFind", "未找到{0}[{1}]", new String[]{"PosId", saveDto.getId()});
// throw new ValidateException("未找到库位 ");
}
//判断是否为禁用库位
if (!saveDto.isEnabled()){
//判断库位是否有料
if (pos.getBarcode() != null){
throw new ValidateException("",pos.getPosName()+"先清空库位后,再禁用库位");
}
}
pos.setPosName(saveDto.getPosName());
pos.setPriority(saveDto.getPriority());
pos.setH(saveDto.getH());
......
......@@ -10,6 +10,7 @@ import com.neotel.smfcore.common.utils.PointUtil;
import com.neotel.smfcore.common.utils.QueryHelp;
import com.neotel.smfcore.common.utils.StringUtils;
import com.neotel.smfcore.core.barcode.bean.PlateSizeBean;
import com.neotel.smfcore.core.barcode.enums.BARCODE_STATUS;
import com.neotel.smfcore.core.barcode.service.po.Barcode;
import com.neotel.smfcore.core.storage.bean.InventoryItem;
import com.neotel.smfcore.core.storage.enums.CHECKOUT_TYPE;
......@@ -401,6 +402,7 @@ public class StoragePosManagerImpl implements IStoragePosManager {
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);
c.and("enabled").is(true);//可用//.and("barcode.lockId").is(null);//没有被锁定的仓位;
c.and("barcode.status").is(BARCODE_STATUS.IN_STORE);
if (storageIdList != null) {
c = c.and("storageId").in(storageIdList);
}
......@@ -417,7 +419,7 @@ public class StoragePosManagerImpl implements IStoragePosManager {
c.and("barcode.subCodeList.isOut").is(isOut);
}
//Sort sort = getSortByCheckOutType(checkOutType);
Sort sort = Sort.by(Sort.Direction.ASC, "barcode.subCodeList.amount","barcode.subCodeList.createDate"/*,"canCheckOutTime", "barcode.usedCount"*/);
Sort sort = Sort.by(Sort.Direction.ASC, "barcode.subCodeList.createDate","barcode.subCodeList.amount"/*,"canCheckOutTime", "barcode.usedCount"*/);
Query q = new Query(c);
q.with(sort);
StoragePos pos = storagePosDao.findOne(q);
......
......@@ -370,6 +370,9 @@ public class DataLog extends BasePo implements Serializable {
*/
private String export = "";
//任务是否正常
private boolean normal = true;
public String getBarcode() {
if(barcode == null){
return "";
......
......@@ -125,7 +125,7 @@ public class TaskService {
task.setProvider(barcode.getProvider());
task.setProviderNumber(barcode.getProviderNumber());
task.setKeeperCode(barcode.getKeeperCode());
//task.setNum(barcode.getAmount());
task.setNum(barcode.getAmount());
barcode.setPutInTime(System.currentTimeMillis());
barcode.updateSluggishTime(dataCache.getPNsluggishDay(barcode.getPartNumber()));
barcodeManager.saveBarcode(barcode);
......@@ -329,17 +329,17 @@ public class TaskService {
StoragePos storagePos = storagePosManager.getByPosName(posName);
//如果是入库任务,直接屏蔽库位
if (task.isPutInTask()) {
disablePos(task.getBarcode(),storagePos);
//disablePos(task.getBarcode(),storagePos);
}
//如果是出库任务,判断当前任务的barcode和库位中的师傅一致
else if (task.isCheckOutTask()) {
Barcode barcode = storagePos.getBarcode();
if (barcode == null) {
disablePos(task.getBarcode(),storagePos);
//disablePos(task.getBarcode(),storagePos);
} else if (barcode != null && task.getBarcode().equals(barcode.getBarcode())) {
barcode = clearOut(barcode);
storagePos.setBarcode(barcode);
disablePos(task.getBarcode(),storagePos);
//disablePos(task.getBarcode(),storagePos);
}
}
ReelLockPosUtil.removeReelLockPosInfo(task.getBarcode());
......
......@@ -517,6 +517,7 @@ public class LuxsanApi extends DefaultSmfApiListener {
try {
log.info("fetchMoveTicket接口请求参数为:" + JSONObject.toJSONString(request));
String resultStr = HttpHelper.postJson(fetchMoveTicketUrl, request);
log.info("fetchMoveTicket接口请求结果为:" + resultStr);
LuxsanApiResult apiResult = JSONObject.parseObject(resultStr, LuxsanApiResult.class);
if (LuxsanApiEnum.ERROR.equals(apiResult.getMSGTY())) {
throw new ValidateException("smfcore.api.error", "接口请求失败[{0}]", new String[]{apiResult.getMSGTX()});
......@@ -931,7 +932,7 @@ public class LuxsanApi extends DefaultSmfApiListener {
}
//保存禁用料记录
Barcode barcodeOri = barcodeManager.findByBarcode(barcode.getBarcode());
/*Barcode barcodeOri = barcodeManager.findByBarcode(barcode.getBarcode());
if (barcodeOri != null){
barcodeOri.setDisableMsg(resultStr);
barcode = barcodeManager.save(barcodeOri);
......@@ -940,7 +941,7 @@ public class LuxsanApi extends DefaultSmfApiListener {
storagePos.setBarcode(barcode);
storagePosManager.save(storagePos);
}
}
}*/
if (StringUtils.isNotBlank(resultStr)) {
throw new ValidateException("smfcore.mesApi.inCheck.ng", /*"MES验证失败:" + */barcode.getBarcode() + "验证失败:" + resultStr);
......@@ -949,6 +950,23 @@ public class LuxsanApi extends DefaultSmfApiListener {
return barcode;
}
public static void shipCancelUpshelf(ShipCancelUpshelfRequest request) {
log.info("shipCancelUpshelf接口请求参数为:" + JSON.toJSONString(request));
try {
String resultStr = HttpHelper.postJson(shipCancelUpshelfUrl, request);
log.info("shipCancelUpshelf接口返回为:" + resultStr);
LuxsanApiResult apiResult = JSONObject.parseObject(resultStr, LuxsanApiResult.class);
if (LuxsanApiEnum.ERROR.equals(apiResult.getMSGTY())) {
throw new ValidateException("smfcore.api.error", "接口请求失败[{0}]", new String[]{apiResult.getMSGTX()});
}
} catch (ApiException e) {
e.printStackTrace();
throw new ValidateException("smfcore.api.error", "接口请求失败[{0}]", new String[]{e.getMessage()});
}
}
@Override
public void outTaskStatusChange(String outNotifyUrl, DataLog task) {
//pickingIssue(new PickingIssueRequest());
......@@ -956,7 +974,7 @@ public class LuxsanApi extends DefaultSmfApiListener {
@Override
public boolean isForThisApi(String apiName) {
return "Luxsan".equals(apiName);
return "luxsan".equals(apiName);
}
......@@ -1201,4 +1219,17 @@ public class LuxsanApi extends DefaultSmfApiListener {
LuxsanApi.binMoveUrl = url;
}
public static String shipCancelUpshelfUrl;
@Value("${api.shipCancelUpshelf}")
public void setShipCancelUpshelfUrl(String url) {
LuxsanApi.shipCancelUpshelfUrl = url;
}
public static String cancelOdnUrl;
@Value("${api.cancelOdn}")
public void setCancelOdnUrl(String url){
LuxsanApi.cancelOdnUrl = url;
}
}
package com.neotel.smfcore.custom.luxsan.api.bean.request;
import lombok.AllArgsConstructor;
import lombok.Data;
import java.util.List;
......
package com.neotel.smfcore.custom.luxsan.api.bean.request;
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
public class ShipCancelUpshelfRequest {
//工厂代码
private String PLANT_CODE;
//ODN单号
private String TICKET_CODE;
//标签码
private String PALLET_ID;
}
......@@ -2,6 +2,8 @@ package com.neotel.smfcore.custom.luxsan.api.bean.result;
import lombok.Data;
import java.util.Date;
/**
* 查询挑料单列表
*/
......@@ -38,5 +40,24 @@ public class QueryPickingResult {
private String UPDATE_NAME;
private boolean checkOut = false;
//出库按钮是否置灰
private boolean checkOut = true;
//工单状态
private int orderStatus;
//当前任务盘数
private int taskReelCount = 0;
//当前任务已完成盘数
private int finishedReelCount = 0;
//工单开始时间
private Date startDate;
//工单结束时间
private Date endDate;
//工单完成时间
private Date finishDate;
}
package com.neotel.smfcore.custom.luxsan.factory_c.common.controller;
import com.alibaba.fastjson.JSON;
import com.neotel.smfcore.common.exception.ApiException;
import com.neotel.smfcore.common.utils.HttpHelper;
import com.neotel.smfcore.custom.luxsan.api.LuxsanApi;
import com.neotel.smfcore.custom.luxsan.factory_c.common.bean.request.SendTicketInfo;
import com.neotel.smfcore.custom.luxsan.factory_c.common.bean.result.WcsResult;
import com.neotel.smfcore.security.annotation.AnonymousAccess;
......@@ -11,6 +14,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
import java.util.Map;
@Slf4j
@RequestMapping("/wcs")
......@@ -30,4 +34,29 @@ public class WcsController {
wcsResult.setMSGTY("接收成功");
return wcsResult;
}
@ApiOperation("砍单通知自动仓")
@RequestMapping("/cancelOdn")
@AnonymousAccess
public WcsResult cancelOdn(@RequestBody Map<String, String> paramMap) {
String plantCode = paramMap.get("PLANT_CODE");
String ticketCode = paramMap.get("TICKET_CODE");
log.info("wms砍单通知自动仓,工厂代码为:" + plantCode + ",出货单为:" + ticketCode);
String msgtx = "S";
String msgty = "";
try {
String resultStr = HttpHelper.postJson(LuxsanApi.cancelOdnUrl, paramMap);
log.info("wms砍单通知自动仓,转发结果为:" + resultStr);
} catch (ApiException e) {
e.printStackTrace();
msgtx = "E";
msgty = e.getMessage();
}
WcsResult wcsResult = new WcsResult();
wcsResult.setMSGTX(msgtx);
wcsResult.setMSGTY(msgty);
return wcsResult;
}
}
package com.neotel.smfcore.custom.luxsan.factory_c.rawstor.bean;
import lombok.Data;
import java.util.Map;
@Data
public class CtuStatus {
//ctu Id
private String ctuId;
//key为抽屉号, value为
private Map<String,String> usageMap;
}
......@@ -4,6 +4,7 @@ import com.neotel.smfcore.custom.luxsan.api.bean.result.QueryPickingResult;
import lombok.Data;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
@Data
......@@ -38,8 +39,26 @@ public class QueryPickingDto {
// 更新姓名
private String updateName;
//出库按钮是否置灰
private boolean checkOut = true;
private boolean checkOut = false;
//工单状态
private int orderStatus;
//当前任务盘数
private int taskReelCount = 0;
//当前任务已完成盘数
private int finishedReelCount = 0;
//工单开始时间
private Date startDate;
//工单结束时间
private Date endDate;
//工单完成时间
private Date finishDate;
public static QueryPickingDto convertQueryPickingResultDto(QueryPickingResult result){
QueryPickingDto queryPickingResultDto = new QueryPickingDto();
......@@ -53,6 +72,12 @@ public class QueryPickingDto {
queryPickingResultDto.setUpdateAt(result.getUPDATE_AT());
queryPickingResultDto.setUpdateBy(result.getUPDATE_BY());
queryPickingResultDto.setUpdateName(result.getUPDATE_NAME());
queryPickingResultDto.setOrderStatus(result.getOrderStatus());
queryPickingResultDto.setTaskReelCount(result.getTaskReelCount());
queryPickingResultDto.setFinishedReelCount(result.getFinishedReelCount());
queryPickingResultDto.setStartDate(result.getStartDate());
queryPickingResultDto.setEndDate(result.getEndDate());
queryPickingResultDto.setFinishDate(result.getFinishDate());
queryPickingResultDto.setCheckOut(result.isCheckOut());
return queryPickingResultDto;
}
......
......@@ -41,9 +41,11 @@ import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.util.Strings;
import org.ehcache.impl.internal.concurrent.ConcurrentHashMap;
import org.springframework.beans.factory.annotation.Autowired;
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.*;
......@@ -196,9 +198,11 @@ public class CDeviceController {
barcode.setPosName(binCodeStr);
barcode.setWarehouseCode(warhouseCode);
barcode.setBarSource(soucre);
barcode.setSeq(BoxHandleUtil.getSeq(boxBarcode,binCodeStr)+1);
barcode.setPutInTime(System.currentTimeMillis());
barcode = barcodeManager.save(barcode);
generatePutInTask(barcode, boxBarcode);
generatePutInTask(barcode, boxBarcode,OP_STATUS.FINISHED.name());
boxBarcode.updateSubCodes(barcode);
boxBarcode.setAmount(boxBarcode.getAmount()+barcode.getAmount());
barcodeManager.save(boxBarcode);
......@@ -207,6 +211,15 @@ public class CDeviceController {
inPos.setBarcode(boxBarcode);
storagePosManager.save(inPos);
}
//把当前料箱设置成正在入库的料箱
Map<String,String> cacheMap = dataCache.getCache(CacheNameUtil.CHCHE_EXECUTINGPUTIN_BOX);
if (cacheMap == null){
cacheMap = new HashMap<>();
}
cacheMap.put(boxBarcode.getBarcode(),boxBarcode.getBarcode());
dataCache.updateCache(CacheNameUtil.CHCHE_EXECUTINGPUTIN_BOX,cacheMap);
return ResultBean.newOkResult("");
}
}
......@@ -229,6 +242,12 @@ public class CDeviceController {
//该料格有出库时, 需要清理此字段
boxBarcode.updateExtraData(binCodeStr,"FULL");
barcodeManager.saveBarcode(boxBarcode);
StoragePos inPos = storagePosManager.getByBarcode(boxBarcode.getBarcode());
if (inPos != null){
inPos.setBarcode(boxBarcode);
storagePosManager.save(inPos);
}
return ResultBean.newOkResult("");
}
......@@ -287,6 +306,14 @@ public class CDeviceController {
Storage storage = dataCache.getStorageById(pos.getStorageId());
DataLog dataLog = taskService.addPutInTaskToExecute(storage, boxBarcode, pos, boxLoc);
Map<String,String> cacheMap = dataCache.getCache(CacheNameUtil.CHCHE_EXECUTINGPUTIN_BOX);
if (cacheMap == null){
cacheMap = new HashMap<>();
}
cacheMap.remove(boxBarcode.getBarcode());
dataCache.updateCache(CacheNameUtil.CHCHE_EXECUTINGPUTIN_BOX,cacheMap);
return ResultBean.newOkResult(dataLog);
}
......@@ -367,7 +394,8 @@ public class CDeviceController {
@ApiOperation("料格中的物料开始出库")
@RequestMapping("/reelCheckOut")
@AnonymousAccess
public synchronized ResultBean reelCheckOut(String boxStr) {
public synchronized ResultBean reelCheckOut(@RequestParam("boxStr") String boxStr,
@RequestParam("isNormal") boolean isNormal) {
//1.解析条码内容
//Barcode binCode = codeResolve.resolveOneValideBarcode(boxStr);
......@@ -383,77 +411,119 @@ public class CDeviceController {
}
List<Barcode> subCodeList = boxBarcode.getSubCodeList();
//2.获取要出库的code
int seq = BoxHandleUtil.getSeq(boxBarcode, boxStr);
Barcode barcode = null;
for (Barcode subCode : subCodeList) {
if (boxStr.equals(subCode.getPosName()) && subCode.isOut()){
//第一个该格口的就是要出的, 生成出库任务
//4.开始生成出库任务
log.info(subCode.getBarcode() + "从" + boxStr + "出库");
DataLog dataLog = new DataLog(new Storage(), subCode, new StoragePos());
String orderItemId = subCode.getOrderItemId();
LiteOrderItem orderItem = null;
if (StringUtils.isNotEmpty(orderItemId)) {
orderItem = liteOrderItemManager.get(orderItemId);
}
String orderNo = "";
String orderId = "";
int checkType = -1;
String pkItemId = "";
String face = "";
String brand = "";
String batchCode = "";
if(orderItem != null){
orderNo = orderItem.getOrderNo();
orderId = orderItem.getOrderId();
pkItemId = orderItem.getItemId();
face = orderItem.getFace();
brand = orderItem.getBrand();
if (!"N/A".equals(orderItem.getBatchCode())){
batchCode = orderItem.getBatchCode();
}
LiteOrder order = liteOrderManager.get(orderItem.getOrderId());
if (order != null){
checkType = order.getCheckType();
}
}
if (seq == subCode.getSeq() && boxStr.equals(subCode.getPosName())) {
barcode = subCode;
break;
}
}
dataLog.setSubSourceId(orderItemId);
//3.判断barcode是否为空
if (barcode == null) {
return ResultBean.newErrorResult(-1, "", "未找到可以出库的物料");
}
dataLog.setSourceId(orderId);
dataLog.setSourceName(orderNo);
dataLog.setType(OP.CHECKOUT);
dataLog.setStatus(OP_STATUS.FINISHED.name());
dataLog.setPosName(boxStr);
taskService.updateFinishedTask(dataLog);
List<Barcode> barcodeList = new ArrayList<>();
for (Barcode subCode : subCodeList) {
if (boxStr.equals(subCode.getPosName())){
barcodeList.add(subCode);
}
}
//有出库,此料格就去除满格标志
boxBarcode.updateExtraData(subCode.getPosName(),null);
boxBarcode.removeFromSubCodes(subCode);
barcodeManager.save(boxBarcode);
if(inPos != null){
//为保证数据一致性, pos中的box barcode也需要更新
inPos.setBarcode(boxBarcode);
storagePosManager.save(inPos);
//判断barcode是否为需要出库的
if (!barcode.isOut()){
log.info(barcode.getBarcode()+"不是要出库的料盘");
Barcode needOutBarcode = null;
for (Barcode subCode : barcodeList) {
if (subCode.isOut()){
needOutBarcode = subCode;
break;
}
}
if (needOutBarcode != null){
String orderItemId = needOutBarcode.getOrderItemId();
needOutBarcode.setOrderItemId("");
needOutBarcode.setOut(false);
log.info(needOutBarcode.getBarcode()+"需要改成不需要出库");
barcodeManager.save(needOutBarcode);
boxBarcode.updateSubCodes(needOutBarcode);
barcode.setOut(true);
barcode.setOrderItemId(orderItemId);
log.info(barcode.getBarcode()+"改成要出库,orderItemId为:"+orderItemId);
}
}
//清理条码档案信息
subCode.setPosName("");
subCode.setOut(false);
subCode.setOrderId("");
subCode.setOrderItemId("");
subCode.setBarSource("");
barcodeManager.saveBarcode(subCode);
//通知WMS
if (checkType == LiteorderCheckType.PICKING_CHECKOUT){
LuxsanApi.pickingIssue(new PickingIssueRequest(CommonUtil.plantCode,orderNo,pkItemId,subCode.getPartNumber()
,subCode.getWarehouseCode(),brand,face,batchCode,Arrays.asList(subCode.getBarcode())));
}
break;
//4.开始生成出库任务
log.info(barcode.getBarcode() + "从" + boxStr + "出库,序列号为:" + seq);
DataLog dataLog = new DataLog(new Storage(), barcode, new StoragePos());
String orderItemId = barcode.getOrderItemId();
LiteOrderItem orderItem = null;
if (StringUtils.isNotEmpty(orderItemId)) {
orderItem = liteOrderItemManager.get(orderItemId);
}
String orderNo = "";
String orderId = "";
int checkType = -1;
String pkItemId = "";
String face = "";
String brand = "";
String batchCode = "";
if(orderItem != null){
orderNo = orderItem.getOrderNo();
orderId = orderItem.getOrderId();
pkItemId = orderItem.getItemId();
face = orderItem.getFace();
brand = orderItem.getBrand();
if (!"N/A".equals(orderItem.getBatchCode())){
batchCode = orderItem.getBatchCode();
}
LiteOrder order = liteOrderManager.get(orderItem.getOrderId());
if (order != null){
checkType = order.getCheckType();
}
}
dataLog.setSubSourceId(orderItemId);
dataLog.setSourceId(orderId);
dataLog.setSourceName(orderNo);
dataLog.setType(OP.CHECKOUT);
dataLog.setStatus(OP_STATUS.FINISHED.name());
dataLog.setPosName(boxStr);
dataLog.setNormal(isNormal);
taskService.updateFinishedTask(dataLog);
//有出库,此料格就去除满格标志
boxBarcode.updateExtraData(barcode.getPosName(),null);
boxBarcode.removeFromSubCodes(barcode);
barcodeManager.save(boxBarcode);
if(inPos != null){
//为保证数据一致性, pos中的box barcode也需要更新
inPos.setBarcode(boxBarcode);
storagePosManager.save(inPos);
}
//清理条码档案信息
barcode.setPosName("");
barcode.setOut(false);
barcode.setOrderId("");
barcode.setOrderItemId("");
barcode.setBarSource("");
barcodeManager.saveBarcode(barcode);
//通知WMS
if (checkType == LiteorderCheckType.PICKING_CHECKOUT){
LuxsanApi.pickingIssue(new PickingIssueRequest(CommonUtil.plantCode,orderNo,pkItemId,barcode.getPartNumber()
,barcode.getWarehouseCode(),brand,face,batchCode,Arrays.asList(barcode.getBarcode())));
}
return ResultBean.newOkResult("");
}
//
......@@ -516,55 +586,6 @@ public class CDeviceController {
}
@ApiOperation("原材料CTU获取线体到架子的入库任务(入满箱或出库后回库)")
@RequestMapping("/lineToShelfTasks")
@AnonymousAccess
public ResultBean lineToShelfTasks(){
List<DataLog> allTasks = taskService.getAllTasks();
List<CtuTask> lineToShelfTaskList = new ArrayList<>();
for (DataLog dataLog : allTasks) {
if (dataLog.isPutInTask() && dataLog.isWait()){
CtuTask ctuTask = new CtuTask();
ctuTask.setId(dataLog.getId());
ctuTask.setBoxCode(dataLog.getBarcode());
ctuTask.setTaskType(dataLog.getType());
//起始点为线体传入的boxLoc值
ctuTask.setFromLoc(dataLog.getLoc());
//目的地都为库位
ctuTask.setToLoc(dataLog.getPosName());
ctuTask.setCreateDate(dataLog.getCreateDate());
lineToShelfTaskList.add(ctuTask);
}
}
return ResultBean.newOkResult(lineToShelfTaskList);
}
@ApiOperation("原材料CTU获取架子到线体的出库任务(出空箱到入料机构或出库到出料机构)")
@RequestMapping("/shelfToLineTasks")
@AnonymousAccess
public ResultBean shelfToLineTasks(){
List<DataLog> allTasks = taskService.getAllTasks();
List<CtuTask> shelfToLineTaskList = new ArrayList<>();
for (DataLog dataLog : allTasks) {
if (dataLog.isCheckOutTask() && dataLog.isWait()){
CtuTask ctuTask = new CtuTask();
ctuTask.setId(dataLog.getId());
ctuTask.setBoxCode(dataLog.getBarcode());
ctuTask.setTaskType(dataLog.getType());
ctuTask.setFromLoc(dataLog.getPosName());
//手动出空箱的目的地已经设置为In_FeedingInlet, 所以其他出库的未设置目的地的设置为Out_FeedingInlet
String toLoc = dataLog.getLoc();
if(Strings.isBlank(toLoc)){
toLoc = "Out_FeedingInlet";
}
ctuTask.setToLoc(toLoc);
ctuTask.setCreateDate(dataLog.getCreateDate());
shelfToLineTaskList.add(ctuTask);
}
}
return ResultBean.newOkResult(shelfToLineTaskList);
}
@ApiOperation("根据料箱获取目的地")
@RequestMapping("/getTargetByBox")
@AnonymousAccess
......@@ -629,6 +650,262 @@ public class CDeviceController {
return ResultBean.newOkResult(dataMap);
}
@ApiOperation("呼叫空箱")
@RequestMapping("/callEmptyBox")
@AnonymousAccess
public ResultBean callEmptyBox(String size,String outLet){
log.info("开始呼叫空箱,尺寸为:"+size+",出口位置为:"+outLet);
String resultStr = BoxHandleUtil.callEmptyBox(size,outLet);
if (StringUtils.isEmpty(resultStr)){
return ResultBean.newErrorResult(-1,"","未找到可用料箱");
}
return ResultBean.newOkResult(resultStr);
}
@ApiOperation("物料放入料格,生成入库任务")
@RequestMapping("/reelToBox")
@AnonymousAccess
public ResultBean reelToBox(@RequestBody Map<String, String> paramMap) {
String binCodeStr = paramMap.get("binCode"); //料格
String codeStr = paramMap.get("codeStr"); //物料条码
String materialStr = paramMap.get("materialStr"); //料串信息
//判断入参是否为空
if (StringUtils.isEmpty(binCodeStr)) {
return ResultBean.newErrorResult(-1, "smfcore.valueCanotNull", "{0}不能为空", new String[]{"料格信息"});
}
if (StringUtils.isEmpty(codeStr)) {
return ResultBean.newErrorResult(-1, "smfcore.valueCanotNull", "{0}不能为空", new String[]{"物料信息"});
}
if (StringUtils.isEmpty(materialStr)) {
return ResultBean.newErrorResult(-1, "smfcore.valueCanotNull", "{0}不能为空", new String[]{"料串信息"});
}
//判断条码是否正常
Barcode barcode = null;
try {
barcode = codeResolve.resolveOneValideBarcode(codeStr);
} catch (ValidateException ve) {
return ResultBean.newErrorResult(-1, ve.getMsgKey(), ve.getDefaultMsg());
}
log.info("料串[" + materialStr + "]上的物料[" + barcode.getBarcode() + "] 准备放入料格[" + binCodeStr + "]");
//判断是否存在料箱中
/*if (StringUtils.isNotEmpty(barcode.getPosName())) {
log.info(barcode.getBarcode() + "已经存在料格" + barcode.getPosName());
ResultBean resultBean = ResultBean.newErrorResult(101, "", barcode.getBarcode() + "已经存在料格" + barcode.getPosName());
resultBean.setData(barcode.getPosName());
return resultBean;
}*/
//判断是否绑定其他料串
if (!MaterialUtil.bindInfo(materialStr)) {
return ResultBean.newErrorResult(-1, "", materialStr + "没有任何绑定信息");
}
//调用禁用料信息
barcode = smfApi.canPutInAfterResolve(barcode);
//获取库别
String warhouseCode = MaterialUtil.getWarhouseCode(materialStr);
//判断料格是否正常
Barcode boxBarcode = null;
try {
String boxStr = BoxHandleUtil.getBoxStr(binCodeStr);
boxBarcode = codeResolve.resolveOneValideBarcode(boxStr);
} catch (ValidateException ve) {
return ResultBean.newErrorResult(-1, ve.getMsgKey(), "料格条码不正确:" + binCodeStr);
}
if (boxBarcode != null) {
//判断隔口是否可以放入
if (BinCacheUtil.canPutInBinCode(binCodeStr, warhouseCode)) {
//把当前料箱设置成正在入库的料箱
Map<String, String> cacheMap = dataCache.getCache(CacheNameUtil.CHCHE_EXECUTINGPUTIN_BOX);
if (cacheMap == null) {
cacheMap = new HashMap<>();
}
cacheMap.put(boxBarcode.getBarcode(), boxBarcode.getBarcode());
dataCache.updateCache(CacheNameUtil.CHCHE_EXECUTINGPUTIN_BOX, cacheMap);
return ResultBean.newOkResult("");
}
}
return ResultBean.newErrorResult(-1, "", barcode.getBarcode() + "不可以放到料格:" + binCodeStr);
}
@ApiOperation("物料放入料格,完成入库任务")
@RequestMapping("/finishedReelToBox")
@AnonymousAccess
public ResultBean finishedReelToBox(@RequestBody Map<String, String> paramMap) {
String binCodeStr = paramMap.get("binCode"); //料格
String codeStr = paramMap.get("codeStr"); //物料条码
String materialStr = paramMap.get("materialStr"); //料串信息
//判断入参是否为空
if (StringUtils.isEmpty(binCodeStr)) {
return ResultBean.newErrorResult(-1, "smfcore.valueCanotNull", "{0}不能为空", new String[]{"料格信息"});
}
if (StringUtils.isEmpty(codeStr)) {
return ResultBean.newErrorResult(-1, "smfcore.valueCanotNull", "{0}不能为空", new String[]{"物料信息"});
}
if (StringUtils.isEmpty(materialStr)) {
return ResultBean.newErrorResult(-1, "smfcore.valueCanotNull", "{0}不能为空", new String[]{"料串信息"});
}
//判断条码是否正常
Barcode barcode = null;
try {
barcode = codeResolve.resolveOneValideBarcode(codeStr);
} catch (ValidateException ve) {
return ResultBean.newErrorResult(-1, ve.getMsgKey(), ve.getDefaultMsg());
}
log.info("料串["+materialStr+"]上的物料["+barcode.getBarcode()+"] 放入料格完成["+binCodeStr+"]");
//判断料格是否正常
Barcode boxBarcode = null;
StoragePos inPos = null;
try {
String boxStr = BoxHandleUtil.getBoxStr(binCodeStr);
boxBarcode = codeResolve.resolveOneValideBarcode(boxStr);
inPos = storagePosManager.getByBarcode(boxBarcode.getBarcode());
if (inPos != null) {
boxBarcode = inPos.getBarcode();
//log.error("流程异常:料箱["+boxStr+"]在库位["+inPos.getPosName()+"],但物料["+barcode.getBarcode()+"]放入了料格中");
}
} catch (ValidateException ve) {
return ResultBean.newErrorResult(-1, ve.getMsgKey(), "料格条码不正确:" + binCodeStr);
}
DataLog task = null;
Collection<DataLog> queueTasks = taskService.getQueueTasks();
for (DataLog queueTask : queueTasks) {
if (barcode.getBarcode().equals(queueTask.getBarcode())) {
if (queueTask.isPutInTask()) {
task = queueTask;
break;
}
}
}
if (task != null) {
if (!binCodeStr.equals(task.getPosName())){
return ResultBean.newErrorResult(-1,"",binCodeStr+"与当前任务的料格"+task.getPosName()+"不匹配");
}
barcode.setPosName(task.getPosName());
barcode.setSeq(BoxHandleUtil.getSeq(boxBarcode,binCodeStr)+1);
barcode.setPutInTime(System.currentTimeMillis());
boxBarcode.updateSubCodes(barcode);
boxBarcode.setAmount(boxBarcode.getAmount() + barcode.getAmount());
boxBarcode.setReelAmount(boxBarcode.getReelAmount() + 1);
barcodeManager.save(barcode);
barcodeManager.save(boxBarcode);
if (inPos != null) {
//流程异常时,为保证数据一致性, pos中的box barcode也需要更新
inPos.setBarcode(boxBarcode);
storagePosManager.save(inPos);
}
task.setStatus(OP_STATUS.FINISHED.name());
taskService.removeQueueTask(task);
taskService.updateFinishedTask(task);
return ResultBean.newOkResult("");
}
return ResultBean.newErrorResult(-1, "", codeStr + "未找到对应的任务");
}
@ApiOperation("修改料格已用高度")
@RequestMapping("/updateBinCodeHeigt")
@AnonymousAccess
public ResultBean updateBinCodeHeigt(@RequestBody Map<String, Integer> paramMap) {
Barcode boxBarcode = null;
for (String binCode : paramMap.keySet()) {
if (boxBarcode == null) {
String boxStr = BoxHandleUtil.getBoxStr(binCode);
boxBarcode = codeResolve.resolveOneValideBarcode(boxStr);
}
boxBarcode.updateHeightMap(binCode, paramMap.get(binCode));
}
barcodeManager.saveBarcode(boxBarcode);
StoragePos inPos = storagePosManager.getByBarcode(boxBarcode.getBarcode());
if (inPos != null) {
inPos.setBarcode(boxBarcode);
storagePosManager.save(inPos);
}
return ResultBean.newOkResult("");
}
@ApiOperation("获取料格已用高度")
@RequestMapping("/getBinCodeHeigt")
@AnonymousAccess
public ResultBean updateBinCodeHeigt(String boxStr) {
Barcode boxBarcode = codeResolve.resolveOneValideBarcode(boxStr);
return ResultBean.newOkResult(boxBarcode.getHeightMap());
}
@ApiOperation("更新入料机构缓存")
@RequestMapping("updateMaterPutInCache")
@AnonymousAccess
public ResultBean updateMaterPutInCache(@RequestParam("number") String number,
@RequestParam("boxStr") String boxStr,
@RequestParam("loc") String loc) {
Map<String, Map<String, String>> cacheMap = dataCache.getCache(CacheNameUtil.CHCHE_MATERIAL_PUTIN_CACHE);
if (cacheMap == null) {
cacheMap = new ConcurrentHashMap<>();
}
Map<String, String> usageMap = cacheMap.get(number);
if (usageMap == null) {
usageMap = new ConcurrentHashMap<>();
}
usageMap.put(boxStr, loc);
cacheMap.put(number, usageMap);
dataCache.updateCache(CacheNameUtil.CHCHE_MATERIAL_PUTIN_CACHE, cacheMap);
return ResultBean.newOkResult("");
}
@ApiOperation("移除入料机构缓存")
@RequestMapping("removeMaterPutInCache")
@AnonymousAccess
public ResultBean removeMaterPutInCache(@RequestParam("number") String number,
@RequestParam("boxStr") String boxStr) {
Map<String, Map<String, String>> cacheMap = dataCache.getCache(CacheNameUtil.CHCHE_MATERIAL_PUTIN_CACHE);
if (cacheMap == null) {
cacheMap = new ConcurrentHashMap<>();
}
Map<String, String> usageMap = cacheMap.get(number);
if (usageMap == null) {
usageMap = new ConcurrentHashMap<>();
}
usageMap.remove(boxStr);
cacheMap.put(number, usageMap);
dataCache.updateCache(CacheNameUtil.CHCHE_MATERIAL_PUTIN_CACHE, cacheMap);
return ResultBean.newOkResult("");
}
/**
* 验证物料是否可以放入料格:
* 1 料格未满 2 料格中若有物料,必须料号,供应商,库别,过账日期一致才可放入
......@@ -638,6 +915,7 @@ public class CDeviceController {
String isBinFull = boxBarcode.getExtraData(binId);
if(isBinFull != null){
//该料格已放满, 不可以再放料
log.info("料格["+binId+"]已满,不可放入物料["+reelBarcode.getBarcode()+"]");
return "料格["+binId+"]已满,不可放入物料["+reelBarcode.getBarcode()+"]";
}
if (!BinCacheUtil.canPutInBinCode(binId, reelBarcode.getWarehouseCode())) {
......@@ -666,7 +944,7 @@ public class CDeviceController {
return "";
}
private void generatePutInTask(Barcode barcode, Barcode boxBarcode) {
private void generatePutInTask(Barcode barcode, Barcode boxBarcode,String status) {
DataLog dataLog = new DataLog();
dataLog.setPosId(boxBarcode.getId());
......@@ -677,10 +955,10 @@ public class CDeviceController {
dataLog.setPartNumber(barcode.getPartNumber());
dataLog.setNum(barcode.getAmount());
dataLog.setType(OP.PUT_IN);
dataLog.setStatus(OP_STATUS.FINISHED.name());
dataLog.setStatus(status);
dataLog.setBatchInfo(barcode.getBatch());
dataLog.setSourceName(barcode.getBarSource());
dataLog.setWarehouseCode(barcode.getWarehouseCode());
taskService.updateFinishedTask(dataLog);
taskService.updateQueueTask(dataLog);
}
}
package com.neotel.smfcore.custom.luxsan.factory_c.rawstor.controller;
import com.alibaba.fastjson.JSON;
import com.neotel.smfcore.common.bean.ResultBean;
import com.neotel.smfcore.core.device.util.DataCache;
import com.neotel.smfcore.core.system.service.po.DataLog;
import com.neotel.smfcore.core.system.util.TaskService;
import com.neotel.smfcore.custom.luxsan.factory_c.rawstor.bean.CtuStatus;
import com.neotel.smfcore.custom.luxsan.factory_c.rawstor.bean.dto.CtuTask;
import com.neotel.smfcore.custom.luxsan.factory_c.util.CacheNameUtil;
import com.neotel.smfcore.security.annotation.AnonymousAccess;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@Api(tags = "Ctu对接接口")
@Slf4j
@RestController
@RequestMapping("/cdevice")
public class CtuDeviceController {
@Autowired
private TaskService taskService;
@Autowired
private DataCache dataCache;
@ApiOperation("原材料CTU获取线体到架子的入库任务(入满箱或出库后回库)")
@RequestMapping("/lineToShelfTasks")
@AnonymousAccess
public ResultBean lineToShelfTasks() {
List<DataLog> allTasks = taskService.getAllTasks();
List<CtuTask> lineToShelfTaskList = new ArrayList<>();
for (DataLog dataLog : allTasks) {
if (dataLog.isPutInTask()) {
if (dataLog.isWait() || dataLog.isExecuting()) {
CtuTask ctuTask = new CtuTask();
ctuTask.setId(dataLog.getId());
ctuTask.setBoxCode(dataLog.getBarcode());
ctuTask.setTaskType(dataLog.getType());
//起始点为线体传入的boxLoc值
ctuTask.setFromLoc(dataLog.getLoc());
//目的地都为库位
ctuTask.setToLoc(dataLog.getPosName());
ctuTask.setCreateDate(dataLog.getCreateDate());
lineToShelfTaskList.add(ctuTask);
}
}
}
return ResultBean.newOkResult(lineToShelfTaskList);
}
@ApiOperation("原材料CTU获取架子到线体的出库任务(出空箱到入料机构或出库到出料机构)")
@RequestMapping("/shelfToLineTasks")
@AnonymousAccess
public ResultBean shelfToLineTasks() {
List<DataLog> allTasks = taskService.getAllTasks();
allTasks = allTasks.stream().sorted(Comparator.comparing(DataLog::getCreateDate)).collect(Collectors.toList());
List<CtuTask> shelfToLineTaskList = new ArrayList<>();
for (DataLog dataLog : allTasks) {
if (shelfToLineTaskList != null && shelfToLineTaskList.size() >= 6) {
break;
}
if (dataLog.isCheckOutTask()) {
if (dataLog.isWait() || dataLog.isExecuting()) {
CtuTask ctuTask = new CtuTask();
ctuTask.setId(dataLog.getId());
ctuTask.setBoxCode(dataLog.getBarcode());
ctuTask.setTaskType(dataLog.getType());
ctuTask.setFromLoc(dataLog.getPosName());
//手动出空箱的目的地已经设置为In_FeedingInlet, 所以其他出库的未设置目的地的设置为Out_FeedingInlet
String toLoc = dataLog.getLoc();
if (Strings.isBlank(toLoc)) {
toLoc = "Out_FeedingInlet";
}
ctuTask.setToLoc(toLoc);
ctuTask.setCreateDate(dataLog.getCreateDate());
shelfToLineTaskList.add(ctuTask);
}
}
}
return ResultBean.newOkResult(shelfToLineTaskList);
}
}
......@@ -157,6 +157,10 @@ public class GrPutInController {
return ResultBean.newErrorResult(-1, "smfcore.valueCanotNull", "{0}不能为空", new String[]{"料串信息"});
}
if (!materialStr.startsWith("B00")){
return ResultBean.newErrorResult(-1,"","料串信息:"+materialStr+"不是有效的");
}
//判断是不是已过账状态
log.info(info.getGrCode()+"状态为:"+info.getStatus());
if (!info.getStatus().equalsIgnoreCase(QueryGrStatusEnum.getStatusName(QueryGrStatusEnum.postIn))) {
......
......@@ -4,6 +4,7 @@ import cn.hutool.core.date.DateUtil;
import com.neotel.smfcore.common.bean.ResultBean;
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.language.util.MessageUtils;
import com.neotel.smfcore.core.order.LiteOrderCache;
import com.neotel.smfcore.core.order.enums.LITEORDER_SOURCE;
......@@ -11,6 +12,8 @@ import com.neotel.smfcore.core.order.rest.bean.mapstruct.OrderMapper;
import com.neotel.smfcore.core.order.service.manager.ILiteOrderManager;
import com.neotel.smfcore.core.order.service.po.LiteOrder;
import com.neotel.smfcore.core.order.service.po.LiteOrderItem;
import com.neotel.smfcore.core.system.service.po.DataLog;
import com.neotel.smfcore.core.system.util.TaskService;
import com.neotel.smfcore.custom.luxsan.api.LuxsanApi;
import com.neotel.smfcore.custom.luxsan.api.bean.request.GetPickingItemsRequest;
import com.neotel.smfcore.custom.luxsan.api.bean.request.QueryPickingRequest;
......@@ -24,6 +27,7 @@ import com.neotel.smfcore.custom.luxsan.factory_c.util.CommonUtil;
import com.neotel.smfcore.security.annotation.AnonymousAccess;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
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;
......@@ -43,10 +47,13 @@ public class PkCheckOutController {
@Autowired
private OrderMapper orderMapper;
@Autowired
private TaskService taskService;
@ApiOperation("出库目的地")
@RequestMapping("/checkLoc")
@AnonymousAccess
//@AnonymousAccess
public ResultBean checkOutLoc() {
Map<String, String> resultMap = new HashMap<>();
resultMap.put(CheckOutUtil.loc_1F,CheckOutUtil.loc_1F);
......@@ -58,26 +65,34 @@ public class PkCheckOutController {
@ApiOperation("查询pk列表")
@RequestMapping("/queryPicking")
@AnonymousAccess
//@AnonymousAccess
public ResultBean queryPicking() {
List<QueryPickingResult> pickingResultList = LuxsanApi.queryPicking(new QueryPickingRequest(CommonUtil.plantCode));
/*for (QueryPickingResult queryPickingResult : pickingResultList) {
for (QueryPickingResult queryPickingResult : pickingResultList) {
String pickingId = queryPickingResult.getPICKING_ID();
LiteOrder liteOrder = liteOrderCache.getLiteOrder(pickingId);
if (liteOrder == null) {
liteOrder = liteOrderManager.findByOrderNo(pickingId);
}
if (liteOrder != null && !liteOrder.isNew()){
queryPickingResult.setCheckOut(true);
if (liteOrder != null){
queryPickingResult.setOrderStatus(liteOrder.getStatus());
queryPickingResult.setTaskReelCount(liteOrder.getTaskReelCount());
queryPickingResult.setFinishedReelCount(liteOrder.getFinishedReelCount());
queryPickingResult.setStartDate(liteOrder.getStartDate());
queryPickingResult.setEndDate(liteOrder.getEndDate());
queryPickingResult.setFinishDate(liteOrder.getFinishDate());
if (!liteOrder.isTaskFinished() || liteOrder.isClosed()){
queryPickingResult.setCheckOut(false);
}
}
}*/
}
return ResultBean.newOkResult(QueryPickingDto.convertQueryPickingResultDto(pickingResultList));
}
@ApiOperation("查询pk详情")
@RequestMapping("/getPickingItems")
@AnonymousAccess
//@AnonymousAccess
public ResultBean getPickingItems(@RequestParam("pickingId") String pickingId) {
if (StringUtils.isEmpty(pickingId)) {
return ResultBean.newErrorResult(-1, "smfcore.valueCanotNull", "{0}不能为空", new String[]{"pickingId"});
......@@ -93,6 +108,13 @@ public class PkCheckOutController {
@RequestParam("confirmExcess") boolean confirmExcess,
@RequestParam("loc") String loc) {
String resultStr = liteOrderCache.hasExecutingOrder();
if (StringUtils.isNotEmpty(resultStr)) {
//throw new ValidateException("","有正在执行的工单,不允许恢复");
return ResultBean.newErrorResult(-1, "", "有正在执行的工单"+resultStr+",不允许出库");
}
List<QueryPickingResult> resultList = LuxsanApi.queryPicking(new QueryPickingRequest(CommonUtil.plantCode));
for (QueryPickingResult result : resultList) {
if (result.getPICKING_ID().equals(pickingId)){
......@@ -111,63 +133,63 @@ public class PkCheckOutController {
if (!liteOrder.isTaskFinished() && !liteOrder.isNew()) {
return ResultBean.newErrorResult(-1, "", pickingId + "正在执行中,不允许出库");
}
//2.如果存在,改个名字
liteOrder.setOrderNo(liteOrder.getOrderNo() + DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss"));
liteOrderManager.createWithItems(liteOrder);
/*liteOrder.setOrderNo(liteOrder.getOrderNo() + DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss"));
liteOrderManager.createWithItems(liteOrder);*/
}
//3.获取pk详情
GetPickingItemsRequest request = new GetPickingItemsRequest(CommonUtil.plantCode, pickingId);
List<GetPickingItemsResult> pickingItemList = LuxsanApi.getPickingItems(request);
//4.循环新建工单
List<LiteOrderItem> itemList = new ArrayList<>();
for (GetPickingItemsResult pkItem : pickingItemList) {
LiteOrderItem item = new LiteOrderItem();
item.setPlantCode(pkItem.getPLANT_CODE());
item.setItemId(pkItem.getITEM_ID());
item.setPickingId(pkItem.getPICKING_ID());
item.setMaterialCode(pkItem.getMATERIAL_CODE());
item.setPn(pkItem.getMATERIAL_CODE());
item.setWarehouse(pkItem.getWAREHOUSE());
item.setWarehouseCode(pkItem.getWAREHOUSE());
item.setReqQty(pkItem.getREQ_QTY());
item.setReqReel(pkItem.getREQ_REEL());
item.setCpQty(pkItem.getCP_QTY());
item.setCpReel(pkItem.getCP_REEL());
item.setIssuedQty(pkItem.getISSUED_QTY());
item.setIssuedReel(pkItem.getISSUED_REEL());
item.setRetQty(pkItem.getRET_QTY());
item.setFace(pkItem.getFACE());
item.setBatchCode(pkItem.getBATCH_CODE());
item.setBrand(pkItem.getBRAND());
item.setCreateAt(pkItem.getCREATE_AT());
item.setUpdateAt(pkItem.getUPDATE_AT());
item.setMo(pkItem.getMO());
item.setBinCode(pkItem.getBIN_CODE());
//需要发料的数量
int needNum = pkItem.getREQ_QTY() - pkItem.getCP_QTY() - pkItem.getISSUED_QTY() + pkItem.getRET_QTY();
item.setNeedNum(needNum);
//需要发料的卷数
int needReelCount = pkItem.getREQ_REEL() - pkItem.getISSUED_REEL() - pkItem.getCP_REEL() + (pkItem.getRET_QTY() > 0 ? 1 : 0);
item.setNeedReelCount(needReelCount);
itemList.add(item);
}
if(liteOrder == null) {
//3.获取pk详情
GetPickingItemsRequest request = new GetPickingItemsRequest(CommonUtil.plantCode, pickingId);
List<GetPickingItemsResult> pickingItemList = LuxsanApi.getPickingItems(request);
List<LiteOrderItem> itemList = new ArrayList<>();
for (GetPickingItemsResult pkItem : pickingItemList) {
LiteOrderItem item = new LiteOrderItem();
item.setPlantCode(pkItem.getPLANT_CODE());
item.setItemId(pkItem.getITEM_ID());
item.setPickingId(pkItem.getPICKING_ID());
item.setMaterialCode(pkItem.getMATERIAL_CODE());
item.setPn(pkItem.getMATERIAL_CODE());
item.setWarehouse(pkItem.getWAREHOUSE());
item.setWarehouseCode(pkItem.getWAREHOUSE());
item.setReqQty(pkItem.getREQ_QTY());
item.setReqReel(pkItem.getREQ_REEL());
item.setCpQty(pkItem.getCP_QTY());
item.setCpReel(pkItem.getCP_REEL());
item.setIssuedQty(pkItem.getISSUED_QTY());
item.setIssuedReel(pkItem.getISSUED_REEL());
item.setRetQty(pkItem.getRET_QTY());
item.setFace(pkItem.getFACE());
item.setBatchCode(pkItem.getBATCH_CODE());
item.setBrand(pkItem.getBRAND());
item.setCreateAt(pkItem.getCREATE_AT());
item.setUpdateAt(pkItem.getUPDATE_AT());
item.setMo(pkItem.getMO());
item.setBinCode(pkItem.getBIN_CODE());
//需要发料的数量
int needNum = pkItem.getREQ_QTY() - pkItem.getCP_QTY() - pkItem.getISSUED_QTY() + pkItem.getRET_QTY();
item.setNeedNum(needNum);
//需要发料的卷数
int needReelCount = pkItem.getREQ_REEL() - pkItem.getISSUED_REEL() - pkItem.getCP_REEL() + (pkItem.getRET_QTY() > 0 ? 1 : 0);
item.setNeedReelCount(needReelCount);
itemList.add(item);
}
//5.创建工单
LiteOrder newOrder = new LiteOrder();
newOrder.setOrderNo(pickingId);
newOrder.setSource(LITEORDER_SOURCE.OUTTER.name());
newOrder.setConfirmExcess(confirmExcess);
newOrder.setOrderItems(itemList);
newOrder.setLoc(loc);
newOrder.setCheckType(LiteorderCheckType.PICKING_CHECKOUT);
newOrder = liteOrderManager.createWithItems(newOrder);
liteOrderCache.addOrderToMap(newOrder);
//5.创建工单
LiteOrder newOrder = new LiteOrder();
newOrder.setOrderNo(pickingId);
newOrder.setSource(LITEORDER_SOURCE.OUTTER.name());
newOrder.setConfirmExcess(confirmExcess);
newOrder.setOrderItems(itemList);
newOrder.setLoc(loc);
newOrder.setCheckType(LiteorderCheckType.PICKING_CHECKOUT);
newOrder = liteOrderManager.createWithItems(newOrder);
liteOrderCache.addOrderToMap(newOrder);
}
//6.执行工单出库
String result = liteOrderCache.checkOutLiteOrderOut(pickingId, false, null);
......@@ -176,5 +198,4 @@ public class PkCheckOutController {
}
return ResultBean.newOkResult("");
}
}
......@@ -3,7 +3,15 @@ package com.neotel.smfcore.custom.luxsan.factory_c.rawstor.controller;
import com.alibaba.fastjson.JSONObject;
import com.neotel.smfcore.common.bean.PageData;
import com.neotel.smfcore.common.bean.ResultBean;
import com.neotel.smfcore.common.exception.ValidateException;
import com.neotel.smfcore.common.utils.SecurityUtils;
import com.neotel.smfcore.common.utils.StringUtils;
import com.neotel.smfcore.core.device.util.DataCache;
import com.neotel.smfcore.core.language.util.MessageUtils;
import com.neotel.smfcore.core.order.LiteOrderCache;
import com.neotel.smfcore.core.order.service.manager.ILiteOrderManager;
import com.neotel.smfcore.core.order.service.po.LiteOrder;
import com.neotel.smfcore.core.order.service.po.LiteOrderItem;
import com.neotel.smfcore.custom.luxsan.api.LuxsanApi;
import com.neotel.smfcore.custom.luxsan.api.bean.request.FetchMoveTicketRequest;
import com.neotel.smfcore.custom.luxsan.api.bean.result.FetchMoveTicketResult;
......@@ -33,6 +41,11 @@ public class TicketController {
@Autowired
private DataCache dataCache;
@Autowired
private LiteOrderCache liteOrderCache;
@Autowired
private ILiteOrderManager liteOrderManager;
@ApiOperation("拉取单据信息")
@RequestMapping("/fetchTicket")
......@@ -46,8 +59,49 @@ public class TicketController {
@ApiOperation("单据领料")
@RequestMapping("/checkOut")
@AnonymousAccess
public ResultBean checkOut(String ticket) {
public synchronized ResultBean checkOut(String ticket) {
String resultStr = liteOrderCache.hasExecutingOrder();
if (StringUtils.isNotEmpty(resultStr)) {
//throw new ValidateException("","有正在执行的工单,不允许恢复");
return ResultBean.newErrorResult(-1, "", "有正在执行的工单"+resultStr+",不允许出库");
}
if (StringUtils.isEmpty(ticket)) {
return ResultBean.newErrorResult(-1, "smfcore.valueCanotNull", "{0}不能为空", new String[]{"单据号"});
}
//判断单据号是否存在
LiteOrder liteOrder = liteOrderCache.getLiteOrder(ticket);
if (liteOrder == null) {
liteOrder = liteOrderManager.findByOrderNo(ticket);
}
if (liteOrder != null) {
if (!liteOrder.isTaskFinished() && !liteOrder.isNew()) {
return ResultBean.newErrorResult(-1, "", "单据号" + ticket + "有正在执行的任务");
}
} else {
liteOrder = new LiteOrder();
liteOrder.setOrderNo(ticket);
List<LiteOrderItem> itemList = new ArrayList<>();
List<FetchMoveTicketResult> ticketList = LuxsanApi.fetchMoveTicket(new FetchMoveTicketRequest(CommonUtil.plantCode, ticket));
for (FetchMoveTicketResult result : ticketList) {
LiteOrderItem item = new LiteOrderItem();
item.setNeedNum(result.getQTY());
item.setWarehouseCode(result.getSRC_WAREHOUSE());
item.setPn(result.getMATERIAL_CODE());
itemList.add(item);
}
liteOrder.setOrderItems(itemList);
liteOrder = liteOrderManager.createWithItems(liteOrder);
liteOrderCache.addOrderToMap(liteOrder);
}
String result = liteOrderCache.checkOutLiteOrderOut(ticket, false, null);
if (StringUtils.isNotEmpty(result)){
return ResultBean.newErrorResult(-1,"", MessageUtils.getText(result,new Locale(SecurityUtils.getCurrentUserLanguage()),result));
}
return ResultBean.newOkResult("");
}
......
......@@ -3,5 +3,4 @@ package com.neotel.smfcore.custom.luxsan.factory_c.rawstor.enums;
public class LiteorderCheckType {
public static final int PICKING_CHECKOUT = 1;
}
......@@ -52,13 +52,13 @@ public class BinCacheUtil {
if (code.equals(warehouseCode)) {
//binCodeUpdateTime = System.currentTimeMillis();
return true;
} else {
}/* else {
LuxsanApi.updateBin(new UpdateBinRequest(CommonUtil.plantCode, binCode, warehouseCode, BinEnum.STORAGE_TYPE_C));
cacheMap.put(binCode, warehouseCode);
dataCache.updateCache(CacheNameUtil.CHCHE_QUERY_BIN, cacheMap);
binCodeUpdateTime = System.currentTimeMillis();
return true;
}
}*/
}
return false;
}
......
package com.neotel.smfcore.custom.luxsan.factory_c.rawstor.util;
import com.neotel.smfcore.common.utils.QueryHelp;
import com.neotel.smfcore.common.utils.SecurityUtils;
import com.neotel.smfcore.common.utils.StringUtils;
import com.neotel.smfcore.core.barcode.enums.BARCODE_STATUS;
import com.neotel.smfcore.core.barcode.service.manager.IBarcodeManager;
import com.neotel.smfcore.core.barcode.service.po.Barcode;
import com.neotel.smfcore.core.device.enums.OP;
import com.neotel.smfcore.core.device.enums.OP_STATUS;
import com.neotel.smfcore.core.device.util.DataCache;
import com.neotel.smfcore.core.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.innerBox.enums.ExtendType;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
@Slf4j
@Service
......@@ -22,7 +36,7 @@ public class BoxHandleUtil {
private static IBarcodeManager barcodeManager;
@Autowired
public void setBarcodeManager(IBarcodeManager manager) {
public void setBarcodeManager(IBarcodeManager manager) {
BoxHandleUtil.barcodeManager = manager;
}
......@@ -30,21 +44,21 @@ public class BoxHandleUtil {
private static IStoragePosManager storagePosManager;
@Autowired
public void setStoragePosManager(IStoragePosManager manager) {
public void setStoragePosManager(IStoragePosManager manager) {
BoxHandleUtil.storagePosManager = manager;
}
private static DataCache dataCache;
@Autowired
public void setDataCache(DataCache cache) {
public void setDataCache(DataCache cache) {
BoxHandleUtil.dataCache = cache;
}
private static TaskService taskService;
@Autowired
public void setTaskService(TaskService service) {
public void setTaskService(TaskService service) {
BoxHandleUtil.taskService = service;
}
......@@ -60,6 +74,7 @@ public class BoxHandleUtil {
barcode.setInOpor("");
barcode.setCheckOutDate(null, "");
barcode.setPosName(opTask.getPosName());
barcode.setStatus(BARCODE_STATUS.IN_STORE);
barcode = barcodeManager.save(barcode);
}
storagePos.setBarcode(barcode);
......@@ -68,6 +83,23 @@ public class BoxHandleUtil {
storagePosManager.save(storagePos);
taskService.moveTaskToFinished(opTask);
taskService.updateFinishedTask(opTask);
List<Barcode> subCodeList = barcode.getSubCodeList();
if (subCodeList != null && !subCodeList.isEmpty()){
for (Barcode subCode : subCodeList) {
if (subCode.isOut()){
log.info(barcode.getBarcode()+"有要出库的任务,需要重新出库");
Storage storage = dataCache.getStorageById(storagePos.getStorageId());
DataLog dataLog = new DataLog(storage, barcode, storagePos);
dataLog.setType(OP.CHECKOUT);
dataLog.setStatus(OP_STATUS.WAIT.name());
dataLog.setLoc("Out_FeedingInlet");
taskService.addTaskToExecute(dataLog);
break;
}
}
}
}
public static void outFromPos(DataLog opTask) {
......@@ -98,7 +130,7 @@ public class BoxHandleUtil {
barcodeManager.save(barcode);
}
//storagePos.setBarcode(null);
storagePos.setBarcode(barcode);
//storagePos.setUsed(false);
storagePosManager.save(storagePos);
......@@ -107,9 +139,104 @@ public class BoxHandleUtil {
}
public static String callEmptyBox(String size,String outLet) {
String box = "";
if ("7".equals(size)) {
box = "C07";
} else if ("13".equals(size)) {
box = "C13";
} else if ("15".equals(size)) {
box = "C15";
}
//排除掉正在使用的仓位
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);
}
c.and("barcode.partNumber").regex(Pattern.compile(QueryHelp.escapeExprSpecialWord(box), Pattern.CASE_INSENSITIVE));
c.and("barcode.status").is(BARCODE_STATUS.IN_STORE);
List<StoragePos> storagePosList = storagePosManager.findByQuery(new Query(c).with(Sort.by(Sort.Direction.ASC, "barcode.amount")));
StoragePos storagePos = null;
//隔口数量
int num = 0;
if (storagePosList != null && !storagePosList.isEmpty()) {
for (StoragePos pos : storagePosList) {
Barcode barcode = pos.getBarcode();
List<Barcode> subCodeList = barcode.getSubCodeList();
if (subCodeList == null || subCodeList.isEmpty()) {
storagePos = pos;
break;
} else {
Map<String, Long> countMap = subCodeList.stream().collect(Collectors.groupingBy(Barcode::getPosName, Collectors.counting()));
if ("7".equals(size)) {
int noReelNum = 0;
for (int par = 1; par < 7; par++) {
//箱子+隔口号
String binCode = barcode.getBarcode() + "-0" + par;
if (countMap.get(binCode) == null || countMap.get(binCode) == 0) {
noReelNum = noReelNum + 1;
}
}
if (num < noReelNum) {
num = noReelNum;
storagePos = pos;
}
} else if ("13".equals(size) || "15".equals(size)) {
String binCode = barcode.getBarcode() + "-01";
if (countMap.get(binCode) == null || countMap.get(binCode) == 0){
storagePos = pos;
break;
}
}
}
}
}
if (storagePos != null) {
Storage storage = dataCache.getStorageById(storagePos.getStorageId());
String toLoc = "In_FeedingInlet";
if (StringUtils.isNotEmpty(outLet)){
if ("1".equals(outLet)){
toLoc = "In1_FeedingInlet";
} else if ("2".equals(outLet)){
toLoc = "In2_FeedingInlet";
}
}
generateTask(storage, storagePos.getBarcode(), storagePos, OP.CHECKOUT, OP_STATUS.WAIT.name(), toLoc, ExtendType.STORAGE_CHECKOUT);
return storagePos.getPosName();
}
return "";
}
private static DataLog generateTask(Storage storage, Barcode barcode, StoragePos pos, int type, String status, String loc, int extendType) {
//开始入库任务
DataLog task = new DataLog(storage, barcode, pos);
task.setType(type);
task.setStatus(status);
task.setLoc(loc);
task.setOperator(SecurityUtils.getLoginUsername());
task.setBoxPosName(pos.getPosName());
task.setExtendType(extendType);
if (barcode.getPutInTime() != -1) {
task.setFristPutInDate(new Date(barcode.getPutInTime()));
} else {
task.setFristPutInDate(barcode.getPutInDate());
}
task.setDescribe(barcode.getDescribe());
taskService.addTaskToExecute(task);
return task;
}
public static String getBoxStr(String code) {
......@@ -123,4 +250,26 @@ public class BoxHandleUtil {
}
return code;
}
/**
* 获取序列号
* @param boxBarcode
* @param binCode
* @return
*/
public static int getSeq(Barcode boxBarcode,String binCode) {
int seq = 0;
List<Barcode> subCodeList = boxBarcode.getSubCodeList();
if (subCodeList != null && !subCodeList.isEmpty()){
for (Barcode barcode : subCodeList) {
if (binCode.equals(barcode.getPosName())){
if (seq < barcode.getSeq()){
seq = barcode.getSeq();
}
}
}
}
return seq;
}
}
package com.neotel.smfcore.custom.luxsan.third.controller;
package com.neotel.smfcore.custom.luxsan.factory_c.third;
import com.neotel.smfcore.common.bean.ResultBean;
import com.neotel.smfcore.core.device.util.DataCache;
......
package com.neotel.smfcore.custom.luxsan.factory_c.third;
import com.neotel.smfcore.common.bean.ResultBean;
import com.neotel.smfcore.common.exception.ValidateException;
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.security.annotation.AnonymousAccess;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
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.Map;
@Slf4j
@RestController
@RequestMapping("/thirdBarcode")
public class ThirdBarcodeController {
@Autowired
private IBarcodeManager barcodeManager;
@Autowired
private CodeResolve codeResolve;
@RequestMapping("/getBarcode")
@AnonymousAccess
public ResultBean getBarcode(@RequestBody Map<String,String> paramMap) {
String codeStr = paramMap.get("codeStr");
Barcode barcode = null;
try {
barcode = codeResolve.resolveOneValideBarcode(codeStr);
} catch (ValidateException e) {
log.error(e.getMessage());
return ResultBean.newErrorResult(-1,e.getMsgKey(),e.getMessage());
}
return ResultBean.newOkResult(barcode);
}
}
......@@ -15,4 +15,16 @@ public class CacheNameUtil {
public static final String CHCHE_UPLOAD_CARPALLINFO = "CHCHE_UPLOAD_CARPALLINFO";
public static final String CHCHE_MANUALWORK_PUTIN = "CHCHE_MANUALWORK_PUTIN";
public static final String CHCHE_EXECUTINGPUTIN_BOX = "CHCHE_EXECUTINGPUTIN_BOX";
public static final String CHCHE_SHIPCANCELUPSHELF = "CHCHE_SHIPCANCELUPSHELF";
public static final String CHCHE_RESTOREREPLACE = "CHCHE_RESTOREREPLACE";
//CTU使用信息
public static final String CHCHE_CTUUSEINFO = "CHCHE_CTUUSEINFO";
//入料机构缓存
public static final String CHCHE_MATERIAL_PUTIN_CACHE = "CHCHE_MATERIAL_PUTIN_CACHE";
}
package com.neotel.smfcore.custom.luxsan.factory_c.wipstor.controller;
import com.google.common.collect.Lists;
import com.neotel.smfcore.common.bean.ResultBean;
import com.neotel.smfcore.common.utils.ReelLockPosUtil;
import com.neotel.smfcore.common.utils.StringUtils;
import com.neotel.smfcore.core.barcode.service.manager.IBarcodeManager;
import com.neotel.smfcore.core.barcode.service.po.Barcode;
import com.neotel.smfcore.core.device.enums.OP_STATUS;
import com.neotel.smfcore.core.storage.service.manager.IStoragePosManager;
import com.neotel.smfcore.core.storage.service.po.StoragePos;
import com.neotel.smfcore.core.system.service.manager.IDataLogManager;
import com.neotel.smfcore.core.system.service.po.DataLog;
import com.neotel.smfcore.core.system.util.TaskService;
import com.neotel.smfcore.custom.luxsan.factory_c.rawstor.util.BoxHandleUtil;
import com.neotel.smfcore.custom.luxsan.api.LuxsanApi;
import com.neotel.smfcore.custom.luxsan.api.bean.request.PalletUpdateRequest;
import com.neotel.smfcore.custom.luxsan.factory_c.util.CommonUtil;
import com.neotel.smfcore.custom.luxsan.factory_c.wipstor.util.TaskLocUtil;
import com.neotel.smfcore.custom.luxsan.factory_c.wipstor.util.WipBoxHandleUtil;
import com.neotel.smfcore.security.annotation.AnonymousAccess;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
......@@ -14,9 +25,7 @@ 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.Map;
import java.util.*;
@Slf4j
@ApiOperation("AGV设备端")
......@@ -27,6 +36,15 @@ public class AgvDeviceController {
@Autowired
private TaskService taskService;
@Autowired
private IBarcodeManager barcodeManager;
@Autowired
private IStoragePosManager storagePosManager;
@Autowired
private IDataLogManager dataLogManager;
@ApiOperation("获取入库任务")
@RequestMapping("/getPutInTask")
@AnonymousAccess
......@@ -46,7 +64,13 @@ public class AgvDeviceController {
public List<DataLog> getCheckOutTask() {
List<DataLog> dataLogList = new ArrayList<>();
for (DataLog dataLog : taskService.getAllTasks()) {
if (dataLogList != null && dataLogList.size() > 6){
break;
}
if (dataLog.isCheckOutTask() && dataLog.isWait()) {
if (StringUtils.isEmpty(dataLog.getLoc())){
dataLog.setLoc(TaskLocUtil.OUT);
}
dataLogList.add(dataLog);
}
}
......@@ -88,7 +112,10 @@ public class AgvDeviceController {
//3.判断是出库,还是入库任务
if (task.isPutInTask()) {
if (OP_STATUS.FINISHED.name().equals(statusStr)) {
BoxHandleUtil.intoPos(task);
finishedPutInTask(task);
//WipBoxHandleUtil.intoPos(task);
ReelLockPosUtil.removeReelLockPosInfo(task.getBarcode());
} else {
taskService.updateQueueTask(task);
......@@ -99,7 +126,8 @@ public class AgvDeviceController {
taskService.updateQueueTask(task);
} else {
if (!task.isOutFromPos()) {
BoxHandleUtil.outFromPos(task);
finishedOutTask(task);
//WipBoxHandleUtil.outFromPos(task);
task.setOutFromPos(true);
}
taskService.updateFinishedTask(task);
......@@ -107,4 +135,99 @@ public class AgvDeviceController {
}
return ResultBean.newOkResult("");
}
@ApiOperation("出库任务获取目的地")
@RequestMapping("/getLoc")
@AnonymousAccess
public ResultBean getLoc(String boxStr) {
List<DataLog> allTasks = taskService.getAllTasks();
for (DataLog dataLog : allTasks) {
if (dataLog.isCheckOutTask()) {
if (boxStr.startsWith(dataLog.getBarcode())) {
if (StringUtils.isEmpty(dataLog.getLoc())) {
dataLog.setLoc(TaskLocUtil.OUT);
}
return ResultBean.newOkResult(dataLog.getLoc());
}
}
}
return ResultBean.newErrorResult(-1, "", "未找到料箱:" + boxStr + "的任务");
}
private void finishedOutTask(DataLog queueTask){
Barcode barcode = barcodeManager.findByBarcode(queueTask.getBarcode());
//通知WMS
PalletUpdateRequest palletUpdateRequest = new PalletUpdateRequest();
palletUpdateRequest.setREQUEST_ID(System.currentTimeMillis()+"");
palletUpdateRequest.setPALLET_LIST(Lists.newArrayList(barcode.getPalletId()));
//上架是SWC, 下架是SWCT
palletUpdateRequest.setBIN_CODE("SWCT");
palletUpdateRequest.setBIZ_TYPE("M");
palletUpdateRequest.setPLANT_CODE(CommonUtil.plantCode);
LuxsanApi.palletUpdate(palletUpdateRequest);
//已完成,从库存中清除,并且从完成队列中清除
StoragePos storagePos = storagePosManager.get(queueTask.getPosId());
if (barcode != null) {
//二维码状态
barcode.setUsed(true);
barcode.setUsedDate(new Date());
//仓位状态
barcode.setCheckOutDate(new Date(), "");
//barcode.setPosName("");
barcode.setOrderItemId("");
barcode.setOrderId("");
barcode.setLockName("");
barcode.setLockId("");
barcodeManager.save(barcode);
}
storagePos.setBarcode(null);
storagePos.setUsed(false);
storagePosManager.save(storagePos);
queueTask.setStatus(OP_STATUS.FINISHED.name());
taskService.moveTaskToFinished(queueTask);
}
private void finishedPutInTask(DataLog queueTask){
Barcode barcode = barcodeManager.findByBarcode(queueTask.getBarcode());
//通知WMS
PalletUpdateRequest palletUpdateRequest = new PalletUpdateRequest();
palletUpdateRequest.setREQUEST_ID(System.currentTimeMillis()+"");
palletUpdateRequest.setPALLET_LIST(Lists.newArrayList(barcode.getPalletId()));
//上架是SWC, 下架是SWCT
palletUpdateRequest.setBIN_CODE("SWC");
palletUpdateRequest.setBIZ_TYPE("M");
palletUpdateRequest.setPLANT_CODE(CommonUtil.plantCode);
LuxsanApi.palletUpdate(palletUpdateRequest);
//已完成,加入库存,并且从完成队列中清除
StoragePos storagePos = storagePosManager.get(queueTask.getPosId());
if (barcode != null) {
barcode.setUsedCount(barcode.getUsedCount() + 1);
barcode.setPutInTime(System.currentTimeMillis());
barcode.setInOpor("");
barcode.setCheckOutDate(null, "");
barcode.setPosName(queueTask.getPosName());
barcode = barcodeManager.save(barcode);
}
storagePos.setBarcode(barcode);
storagePos.setUsed(true);
storagePos.setCanCheckOutTime(System.currentTimeMillis());
storagePosManager.save(storagePos);
queueTask.setStatus(OP_STATUS.FINISHED.name());
taskService.moveTaskToFinished(queueTask);
dataLogManager.save(queueTask);
}
}
package com.neotel.smfcore.custom.luxsan.factory_c.wipstor.controller;
import com.neotel.smfcore.common.bean.ResultBean;
import com.neotel.smfcore.common.exception.ValidateException;
import com.neotel.smfcore.common.utils.StringUtils;
import com.neotel.smfcore.core.barcode.service.po.Barcode;
import com.neotel.smfcore.core.barcode.utils.CodeResolve;
import com.neotel.smfcore.core.device.util.DataCache;
import com.neotel.smfcore.core.system.service.po.DataLog;
import com.neotel.smfcore.core.system.util.TaskService;
import com.neotel.smfcore.custom.luxsan.api.LuxsanApi;
import com.neotel.smfcore.custom.luxsan.api.bean.request.ShipCancelUpshelfRequest;
import com.neotel.smfcore.custom.luxsan.factory_c.util.CacheNameUtil;
import com.neotel.smfcore.custom.luxsan.factory_c.util.CommonUtil;
import com.neotel.smfcore.custom.luxsan.factory_c.wipstor.util.TaskLocUtil;
import com.neotel.smfcore.security.annotation.AnonymousAccess;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Slf4j
@Api(tags = "砍单回库")
@RequestMapping("/cancelRestock")
@RestController
public class CancelRestockController {
@Autowired
private CodeResolve codeResolve;
@Autowired
private DataCache dataCache;
@Autowired
private TaskService taskService;
@ApiOperation("砍单通知自动仓")
@RequestMapping("/cancelOdn")
@AnonymousAccess
public ResultBean cancelOdn(@RequestBody Map<String, String> paramMap) {
String plantCode = paramMap.get("PLANT_CODE");
String ticketCode = paramMap.get("TICKET_CODE");
log.info("wms砍单通知自动仓,工厂代码为:" + plantCode + ",出货单为:" + ticketCode);
//查找对应的任务,只把等待中的给取消
List<DataLog> dataLogList = taskService.getAllTasks();
for (DataLog dataLog : dataLogList) {
if (ticketCode.equals(dataLog.getSourceName())) {
if (dataLog.isWait()) {
boolean cancelTask = taskService.cancelTask(dataLog.getId());
log.info(dataLog.getBarcode() + "取消任务,结果为:" + cancelTask + ",odn为:" + ticketCode);
} else {
dataLog.setLoc(TaskLocUtil.NG);
if (dataLog.isOutFromPos()) {
taskService.updateFinishedTask(dataLog);
}
taskService.updateQueueTask(dataLog);
}
}
}
return ResultBean.newOkResult("");
}
@ApiOperation("砍单回库")
@RequestMapping("/shipCancelUpshelf")
@AnonymousAccess
public ResultBean shipCancelUpshelf(String boxStr) {
if (StringUtils.isEmpty(boxStr)) {
throw new ValidateException("smfcore.valueCanotNull", "{0}不能为空", new String[]{"料箱信息"});
}
log.info("砍单回库,料箱号为:" + boxStr);
//1.解析条码
Barcode barcode = codeResolve.resolveOneValideBarcode("=2x2=" + boxStr);
if (barcode == null) {
throw new ValidateException("smfcore.error.barcode.invalid", "条码无效");
}
//2.判断栈板号和odn是否存在
String palletId = barcode.getPalletId();
if (StringUtils.isEmpty(palletId)) {
throw new ValidateException("smfcore.valueNotFind", "未找到{0}[{1}]", new String[]{"料箱", "标签码"});
}
String odn = barcode.getOdn();
if (StringUtils.isEmpty(odn)) {
throw new ValidateException("smfcore.valueNotFind", "未找到{0}[{1}]", new String[]{"料箱", "odn"});
}
//3.调用接口,判断是否可以回库
LuxsanApi.shipCancelUpshelf(new ShipCancelUpshelfRequest(CommonUtil.plantCode, odn, palletId));
//4.加入缓存,后续不用扫码,直接上架
Map<String, String> cacheMap = dataCache.getCache(CacheNameUtil.CHCHE_SHIPCANCELUPSHELF);
if (cacheMap == null) {
cacheMap = new HashMap<>();
}
cacheMap.put(barcode.getBarcode(), barcode.getBarcode());
dataCache.updateCache(CacheNameUtil.CHCHE_SHIPCANCELUPSHELF, cacheMap);
return ResultBean.newOkResult("");
}
}
......@@ -29,6 +29,7 @@ import com.neotel.smfcore.custom.luxsan.api.enums.PalletEnum;
import com.neotel.smfcore.custom.luxsan.factory_c.util.CacheNameUtil;
import com.neotel.smfcore.custom.luxsan.factory_c.util.CommonUtil;
import com.neotel.smfcore.custom.luxsan.factory_c.wipstor.util.ManualWorkUtil;
import com.neotel.smfcore.custom.luxsan.factory_c.wipstor.util.TaskLocUtil;
import com.neotel.smfcore.security.annotation.AnonymousAccess;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
......@@ -160,11 +161,13 @@ public class LineController {
barcode.setWarehouseCode(fetchPalletInfo.getWAREHOUSE_CODE());
barcode.setHold(fetchPalletInfo.getHOLD());
barcode.setQty(fetchPalletInfo.getQTY());
barcode.setAmount(fetchPalletInfo.getQTY());
//barcode.setFullQty(fetchPalletInfo.getFULL_QTY());
barcode.setPackType(fetchPalletInfo.getPACK_TYPE());
barcode.setCreateAt(fetchPalletInfo.getCREATED_TIME());
//barcode.setRegion(fetchPalletInfo.getREGION());
barcode.setStatus(fetchPalletInfo.getSTATUS());
barcode.setBatch(fetchPalletInfo.getBATCH_CODE());
barcode = barcodeManager.save(barcode);
}
......@@ -204,7 +207,7 @@ public class LineController {
//4.生成入库任务
String boxLoc = "semiFinished_In";
String boxLoc = TaskLocUtil.IN;
taskService.addPutInTaskToExecute(storage, barcode, pos,boxLoc);
return ResultBean.newOkResult("");
......@@ -239,6 +242,11 @@ public class LineController {
resultMap.put("odn", sourceId);
resultMap.put("qty", qty);
resultMap.put("palletId", "");
Barcode barcode = barcodeManager.findByBarcode(boxId);
if (barcode != null){
resultMap.put("palletId", barcode.getPalletId());
}
return ResultBean.newOkResult(resultMap);
}
}
......@@ -392,6 +400,7 @@ public class LineController {
queueTask.setStatus(OP_STATUS.FINISHED.name());
taskService.moveTaskToFinished(queueTask);
dataLogManager.save(queueTask);
}
......
package com.neotel.smfcore.custom.luxsan.factory_c.wipstor.controller;
import com.neotel.smfcore.common.bean.ResultBean;
import com.neotel.smfcore.common.exception.ValidateException;
import com.neotel.smfcore.common.utils.StringUtils;
import com.neotel.smfcore.core.barcode.service.po.Barcode;
import com.neotel.smfcore.core.barcode.utils.CodeResolve;
import com.neotel.smfcore.core.order.LiteOrderCache;
import com.neotel.smfcore.core.storage.service.dao.IStoragePosDao;
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 io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@Slf4j
@Api(tags = "odn还原补箱")
@RestController
@RequestMapping("/restoreReplace")
public class RestoreReplaceController {
@Autowired
private CodeResolve codeResolve;
@Autowired
private IStoragePosManager storagePosManager;
@Autowired
private LiteOrderCache liteOrderCache;
@Autowired
private IStoragePosDao storagePosDao;
@ApiOperation("还原补箱")
@RequestMapping("/scanBox")
@AnonymousAccess
public ResultBean scanBox(String boxStr) {
if (StringUtils.isEmpty(boxStr)) {
throw new ValidateException("smfcore.valueCanotNull", "{0}不能为空", new String[]{"料箱信息"});
}
log.info("还原补箱,料箱号为:" + boxStr);
//1.解析条码
Barcode barcode = codeResolve.resolveOneValideBarcode("=2x2=" + boxStr);
if (barcode == null) {
throw new ValidateException("smfcore.error.barcode.invalid", "条码无效");
}
//2.找一个料号相同,数量相同的箱子
String partNumber = barcode.getPartNumber();
int amount = barcode.getAmount();
Criteria c = Criteria.where("barcode.partNumber").is(partNumber)
.and("id").nin(liteOrderCache.excludeOutPosIds())
.and("enabled").is(true)
.and("barcode.lockId").is(null)
.and("barcode.amount").gte(amount);
Sort s = Sort.by(Sort.Direction.ASC, "barcode.amount", "barcode.putInDate");
StoragePos pos = storagePosDao.findOne(new Query(c).with(s));
if (pos == null) {
return ResultBean.newErrorResult(-1, "", "未找到对应的料箱");
}
//3.生成出库任务,到流水线
return ResultBean.newOkResult("");
}
}
package com.neotel.smfcore.custom.luxsan.factory_c.wipstor.controller;
import com.neotel.smfcore.common.bean.ResultBean;
import com.neotel.smfcore.common.exception.ValidateException;
import com.neotel.smfcore.common.utils.StringUtils;
import com.neotel.smfcore.core.order.LiteOrderCache;
import com.neotel.smfcore.core.order.service.manager.ILiteOrderManager;
import com.neotel.smfcore.core.order.service.po.LiteOrder;
import com.neotel.smfcore.core.order.service.po.LiteOrderItem;
import com.neotel.smfcore.custom.luxsan.api.LuxsanApi;
import com.neotel.smfcore.custom.luxsan.api.bean.request.FetchMoveTicketRequest;
import com.neotel.smfcore.custom.luxsan.api.bean.result.FetchMoveTicketResult;
import com.neotel.smfcore.custom.luxsan.factory_c.rawstor.bean.dto.FetchMoveTicketDto;
import com.neotel.smfcore.custom.luxsan.factory_c.util.CommonUtil;
import com.neotel.smfcore.security.annotation.AnonymousAccess;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
import java.util.List;
@Slf4j
@Api(tags = "261&931领用")
@RequestMapping("/takeOut")
@RestController
public class TakeOutController {
@Autowired
private LiteOrderCache liteOrderCache;
@Autowired
private ILiteOrderManager liteOrderManager;
@ApiOperation("拉取单据信息")
@RequestMapping("/fetchTicket")
@AnonymousAccess
public ResultBean fetchTicket(String ticket) {
if (StringUtils.isEmpty(ticket)) {
throw new ValidateException("smfcore.valueCanotNull", "{0}不能为空", new String[]{"单据号"});
}
List<FetchMoveTicketResult> ticketList = LuxsanApi.fetchMoveTicket(new FetchMoveTicketRequest(CommonUtil.plantCode, ticket));
return ResultBean.newOkResult(FetchMoveTicketDto.convertFetchMoveTicketDto(ticketList));
}
@ApiOperation("单据出库")
@RequestMapping("/ticketOut")
@AnonymousAccess
public ResultBean ticketOut(String ticket) {
log.info("半成品仓单据出库:" + ticket);
if (StringUtils.isEmpty(ticket)) {
throw new ValidateException("smfcore.valueCanotNull", "{0}不能为空", new String[]{"单据号"});
}
//1.判断单据是否存在
LiteOrder liteOrder = liteOrderCache.getOrderSortItems(ticket);
if (liteOrder == null) {
List<FetchMoveTicketResult> ticketList = LuxsanApi.fetchMoveTicket(new FetchMoveTicketRequest(CommonUtil.plantCode, ticket));
ticketToLiteOrder(ticket,ticketList);
}
liteOrderCache.wipTicketOut(ticket);
return ResultBean.newOkResult("");
}
public LiteOrder ticketToLiteOrder(String ticket, List<FetchMoveTicketResult> ticketList) {
LiteOrder liteOrder = new LiteOrder();
liteOrder.setOrderNo(ticket);
List<LiteOrderItem> itemList = new ArrayList<>();
for (FetchMoveTicketResult ticketResult : ticketList) {
LiteOrderItem item = new LiteOrderItem();
item.setTicketItem(ticketResult.getTICKET_ITEM());
item.setPn(ticketResult.getMATERIAL_CODE());
item.setSrcPlant(ticketResult.getSRC_PLANT());
item.setDstPlant(ticketResult.getDST_PLANT());
item.setSrcWarehouse(ticketResult.getSRC_WAREHOUSE());
item.setDstWarehouse(ticketResult.getDST_WAREHOUSE());
item.setSrcBatch(ticketResult.getSRC_BATCH());
item.setDstBatch(ticketResult.getDST_BATCH());
item.setNeedNum(ticketResult.getQTY());
item.setMoveType(ticketResult.getMOVE_TYPE());
itemList.add(item);
}
liteOrder.setOrderItems(itemList);
liteOrder = liteOrderManager.createWithItems(liteOrder);
liteOrderCache.addOrderToMap(liteOrder);
return liteOrder;
}
}
package com.neotel.smfcore.custom.luxsan.factory_c.wipstor.util;
public class TaskLocUtil {
public static final String IN = "semiFinished_In";
public static final String OUT = "semiFinished_Out";
public static final String NG = "semiFinished_ng";
public static final String RR = "semiFinished_rr"; //还原补箱 restoreReplace
}
package com.neotel.smfcore.custom.luxsan.factory_c.wipstor.util;
import com.neotel.smfcore.common.utils.SecurityUtils;
import com.neotel.smfcore.core.barcode.service.manager.IBarcodeManager;
import com.neotel.smfcore.core.barcode.service.po.Barcode;
import com.neotel.smfcore.core.device.util.DataCache;
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 lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Date;
@Slf4j
@Service
public class WipBoxHandleUtil {
private static IBarcodeManager barcodeManager;
@Autowired
public void setBarcodeManager(IBarcodeManager manager) {
WipBoxHandleUtil.barcodeManager = manager;
}
private static IStoragePosManager storagePosManager;
@Autowired
public void setStoragePosManager(IStoragePosManager manager) {
WipBoxHandleUtil.storagePosManager = manager;
}
private static DataCache dataCache;
@Autowired
public void setDataCache(DataCache cache) {
WipBoxHandleUtil.dataCache = cache;
}
private static TaskService taskService;
@Autowired
public void setTaskService(TaskService service) {
WipBoxHandleUtil.taskService = service;
}
public static void intoPos(DataLog opTask) {
//已完成,加入库存,并且从完成队列中清除
StoragePos storagePos = storagePosManager.get(opTask.getPosId());
//二维码状态
Barcode barcode = barcodeManager.findByBarcode(opTask.getBarcode());
if (barcode != null) {
barcode.setUsedCount(barcode.getUsedCount() + 1);
barcode.setPutInTime(System.currentTimeMillis());
barcode.setInOpor("");
barcode.setCheckOutDate(null, "");
barcode.setPosName(opTask.getPosName());
barcode = barcodeManager.save(barcode);
}
storagePos.setBarcode(barcode);
storagePos.setUsed(true);
storagePos.setCanCheckOutTime(System.currentTimeMillis());
storagePosManager.save(storagePos);
taskService.moveTaskToFinished(opTask);
taskService.updateFinishedTask(opTask);
}
public static void outFromPos(DataLog opTask) {
//从队列里面移除操作
taskService.removeQueueTask(opTask);
StoragePos storagePos = storagePosManager.get(opTask.getPosId());
Barcode barcode = storagePos.getBarcode();
if (barcode == null) {
log.warn("任务:" + opTask.getId() + " 仓位:" + opTask.getPosName() + " 的 Barcode 为null, 之前可能处理过,结束任务后直接返回");
return;
}
barcode = barcodeManager.get(barcode.getId());
if (barcode != null) {
//二维码状态
barcode.setUsed(true);
barcode.setUsedDate(new Date());
//仓位状态
barcode.setCheckOutDate(new Date(), "");
barcode.setPosName("");
barcode.setOrderItemId("");
barcode.setOrderId("");
barcode.setLockName("");
barcode.setLockId("");
barcodeManager.save(barcode);
}
storagePos.setBarcode(null);
storagePos.setUsed(false);
storagePosManager.save(storagePos);
log.info("出库完成,清空仓位: " + storagePos.getId() + "[" + storagePos.getPosName() + "]");
taskService.moveTaskToFinished(opTask);
}
private static DataLog generateTask(Storage storage, Barcode barcode, StoragePos pos, int type, String status, String loc, int extendType) {
//开始入库任务
DataLog task = new DataLog(storage, barcode, pos);
task.setType(type);
task.setStatus(status);
task.setLoc(loc);
task.setOperator(SecurityUtils.getLoginUsername());
task.setBoxPosName(pos.getPosName());
task.setExtendType(extendType);
if (barcode.getPutInTime() != -1) {
task.setFristPutInDate(new Date(barcode.getPutInTime()));
} else {
task.setFristPutInDate(barcode.getPutInDate());
}
task.setDescribe(barcode.getDescribe());
taskService.addTaskToExecute(task);
return task;
}
}
......@@ -6,6 +6,9 @@ luxsan:
api:
name: luxsan
#todo 后续需要改成半成品仓地址
cancelOdn: http://10.68.27.86/smf-core/cancelRestock/cancelOdn
#禁用料
inCheckUrl: http://10.190.25.124:8001/Npm/WmsCheckReelfob
......@@ -151,4 +154,7 @@ api:
fetchShipmentInfo: http://10.68.30.22:8082/api/FetchShipment
#储位转移
binMove: http://10.68.30.22:8082/api/mlb/BinMove
\ No newline at end of file
binMove: http://10.68.30.22:8082/api/mlb/BinMove
#砍单回库
shipCancelUpshelf: http://10.68.30.22:8082/api/mlb/ShipCancelUpshelf
\ No newline at end of file
......@@ -6,6 +6,8 @@ luxsan:
api:
name: luxsan
cancelOdn: http://10.68.27.86/smf-core/cancelRestock/cancelOdn
#禁用料
inCheckUrl: http://10.68.21.21:8001/Npm/WmsCheckReelfob
......@@ -152,4 +154,7 @@ api:
fetchShipmentInfo: http://10.42.220.171:8082/api/FetchShipment
#储位转移
binMove: http://10.42.220.171:8082/api/mlb/BinMove
\ No newline at end of file
binMove: http://10.42.220.171:8082/api/mlb/BinMove
#砍单回库
shipCancelUpshelf: http://10.42.220.171:8082/api/mlb/ShipCancelUpshelf
\ No newline at end of file
支持 Markdown 格式
你添加了 0 到此讨论。请谨慎行事。
Finish editing this message first!