Commit c9cde554 sunke

分盘料会多绑定一盘的问题

1 个父辈 6a3dc070
......@@ -61,7 +61,7 @@ public class AppendInfo {
private String preBindSlot;
/**
* 站位信息(预绑定时,不放入slot信息,只有当实际绑定准备出库时再放入slot值)
* 真实绑定站位信息(预绑定时,不放入slot信息,只有当实际绑定准备出库时再放入slot值)
*/
private String bindSlot;
......
......@@ -3,6 +3,7 @@ package com.myproject.bean.update;
import com.google.common.collect.Lists;
import com.myproject.bean.BaseMongoBean;
import com.myproject.bean.qisda.AppendInfo;
import com.myproject.bean.update.qisda.OutItem;
import com.myproject.util.DateUtil;
import com.myproject.util.StorageConstants;
import org.springframework.data.annotation.Transient;
......@@ -550,10 +551,43 @@ public class Barcode extends BaseMongoBean {
}
public void preBindItem(OutItem outItem){
boolean realBind = false;
addBindInfoToBarcode(outItem, realBind);
}
public void realBindItem(OutItem outItem){
boolean realBind = true;
addBindInfoToBarcode(outItem, realBind);
}
private void addBindInfoToBarcode(OutItem outItem, boolean realBind){
AppendInfo appendInfo = getAppendInfo();
appendInfo.sethSerial(outItem.gethSerial());
appendInfo.setRefno(outItem.getRefno());
appendInfo.setSo(outItem.getSo());
appendInfo.setSoseq(outItem.getSoseq());
appendInfo.setSlotStr(outItem.getSlotStr());
appendInfo.setPreBindSlot(outItem.getSlotlocation()+"");
if(realBind){
appendInfo.setBindSlot(outItem.getSlotlocation()+"");
}else{
appendInfo.setBindSlot("");
}
appendInfo.setSlotIndex(outItem.getSlotlocation());
setAppendInfo(appendInfo);
}
/**
* 分盘,返回母盘上的剩余数量,返回值小于0时,需要分另一盘
*/
public int cutCount(String soseq, String so, int slotlocation, String slot, String hSerial, int cutCount){
public int cutCount(OutItem cutItem){
String soseq = cutItem.getSoseq();
String so = cutItem.getSo();
int slotlocation = cutItem.getSlotlocation();
String slot = cutItem.getSlotStr();
String hSerial = cutItem.gethSerial();
if(appendInfo == null){
appendInfo = new AppendInfo();
}
......@@ -562,6 +596,10 @@ public class Barcode extends BaseMongoBean {
cutMap = new HashMap<>();
}
int lockQty = cutItem.getLockQty();
int cutCount = cutItem.getQty() - lockQty;
//flag:子盘或母盘(L:子盘,M:母盘,其他‘’)
//母盘剩余数量
int remainQty = amount - cutCount;
......
......@@ -9,7 +9,7 @@ public interface IOutItemDao extends IMongoDao {
List<OutItem> findByHSerial(String hSerial);
List<OutItem> findCutItemList(List<String> soseqList, String pn, String facility);
List<OutItem> findCutItemList(List<String> cutHserialList, String pn, String facility);
OutItem findItem(String hSerial, int slotSeq);
......
......@@ -24,10 +24,10 @@ public class OutItemDaoImpl extends AbstractMongoDao implements IOutItemDao {
}
@Override
public List<OutItem> findCutItemList(List<String> soseqList, String pn, String facility){
public List<OutItem> findCutItemList(List<String> cutHserialList, String pn, String facility){
Criteria c = new Criteria();
c.and("hSerial").in(cutHserialList);
c.and("action").is("分盘");
c.and("soseq").in(soseqList);
c.and("pn").is(pn);
c.and("facility").is(facility);
Query query = new Query(c);
......
......@@ -82,11 +82,66 @@ public class OutInfoCache {
* 绑定入库料盘
*/
public Barcode bindPutInReel(Barcode barcode){
OutItem bindItem = findNeedBindItem(barcode);
if(bindItem != null){
log.info("绑定入库料盘["+barcode.getBarcode()+"]到 "+bindItem.getSourceName());
barcode = qisdaBindService.addBindInfoToBarcode(barcode, bindItem);
boolean isCutReelIn = false;
String bindSoseq = barcode.getAppendInfo().getSoseq();
String bindSlot = barcode.getAppendInfo().getBindSlot();
OutItem cutItem = soseqCache.getCutOutItem(bindSoseq, Integer.valueOf(bindSlot));
if(Strings.isBlank(bindSoseq)){
//未绑定
cutItem = findNeedBindItem(barcode);
}else{
//料盘分盘过后入库(已经预绑定过)
isCutReelIn = true;
}
if(cutItem != null){
//分盘料
if(cutItem.isCutMaterial()){
int preBindQty = cutItem.getLockQty();
if(!isCutReelIn){
preBindQty = cutItem.getLockQty() + barcode.getAmount();
}
if(preBindQty >= cutItem.getQty()){
int reelRemainNum = barcode.cutCount(cutItem);
if(reelRemainNum > 0){
//母盘还有剩余,说明该需求slot已经满足
preBindQty = cutItem.getQty();
}else {
//母盘正好用完或全部用完也达不到需求量,此母盘绑定slot后,需要继续寻找其他盘进行绑定
preBindQty = preBindQty + barcode.getAmount();
}
}
cutItem.setLockQty(preBindQty);
soseqCache.udpateTotalPreLockQty(cutItem,preBindQty);
log.info("\t分盘料["+barcode.getBarcode()+"]绑定到Soseq=["+cutItem.getSoseq()+"]So=["+cutItem.getSo()+"]的["+cutItem.getSlotlocation()+"] 数量:" + preBindQty +"/" + cutItem.getQty());
if(!barcode.hasCutInfo()){
//没有分盘信息,可以直接绑定
barcode.realBindItem(cutItem);
int realBindQty = cutItem.getRealLockQty() + barcode.getAmount();
cutItem.setRealLockQty(realBindQty);
soseqCache.updateTotalRealLockQty(cutItem,realBindQty);
}else{
AppendInfo appendInfo = barcode.getAppendInfo();
appendInfo.setSlotIndex(cutItem.getSlotlocation());
appendInfo.setSo(cutItem.getSo());
appendInfo.setSoseq(cutItem.getSoseq());
barcode.setAppendInfo(appendInfo);
log.info("分盘料["+barcode.getBarcode()+"]分盘信息:" + barcode.getAppendInfo().getCutMap());
}
}else{
//绑定
barcode.realBindItem(cutItem);
int realBindQty = cutItem.getRealLockQty() + barcode.getAmount();
cutItem.setRealLockQty(realBindQty);
soseqCache.updateTotalRealLockQty(cutItem,realBindQty);
log.info(barcode.getBarcode() + "入库完成,工单so=["+cutItem.getSo()+"] soseq=["+cutItem.getSoseq()+"]slotSeq=["+cutItem.getSlotlocation()+"]绑定数量增加"+barcode.getAmount()+"="+ realBindQty);
}
qisdaBindService.unbindSurplusReel(cutItem);
}
return barcode;
}
......@@ -138,19 +193,19 @@ public class OutInfoCache {
* 入库完成时,查找需要绑定的需求单
*/
private OutItem findNeedBindItem(Barcode barcode){
List<String> soseqList = new ArrayList<>();
List<String> cutHserialList = new ArrayList<>();
for (OutInfo unEndOutInfo : outInfoMap.values()) {
//查找执行过缺料和即将执行的,进行绑定
if(unEndOutInfo.isReelCutAction() && !unEndOutInfo.isClosed()){
if(unEndOutInfo.isSendLess() || unEndOutInfo.isPriority()){
soseqList.add(unEndOutInfo.getSoseq());
if(unEndOutInfo.isSendLess()){
cutHserialList.add(unEndOutInfo.gethSerial());
}
}
}
String pn = barcode.getPartNumber();
String facility = barcode.getAppendInfo().getFacility();
List<OutItem> cutItemList = outItemDao.findCutItemList(soseqList, pn, facility);
List<OutItem> cutItemList = outItemDao.findCutItemList(cutHserialList, pn, facility);
//优先绑定执行过的工单,如果没有,则绑定优先执行的工单
OutItem executedItem = null;
......@@ -159,6 +214,7 @@ public class OutInfoCache {
OutItem priorityItem = null;
OutInfo priorityOutInfo = null;
for (OutItem outItem : cutItemList) {
if(!outItem.isBindOk()){
OutInfo outInfo = getOutInfoFromCache(outItem.gethSerial());
if(outInfo != null){
//真实绑定缺料
......@@ -190,7 +246,7 @@ public class OutInfoCache {
}
}
}
}
if(executedItem != null){
return executedItem;
......@@ -310,11 +366,30 @@ public class OutInfoCache {
/**
* 手动调整优先级
* @param hSerialList
*/
public void changePriority(List<String> hSerialList) {
long sortOrder = - System.currentTimeMillis();
for (String hSerial : hSerialList) {
if(Strings.isBlank(hSerial)){
continue;
}
OutInfo outInfo = getOutInfoFromCache(hSerial);
if(outInfo != null){
updateExecuteTime(outInfo, sortOrder);
sortOrder = sortOrder - 1;
}
}
}
/**
* 获取缓存的需求单信息
*/
public List<OutInfo> getCachedOutInfos(){
List<OutInfo> outInfoList = Lists.newArrayList(outInfoMap.values());
//未执行过的,并且达到了必须出库时间,取出来放到优先执行中
//执行过按执行时间先后排序, 未执行过的放在最后
outInfoList.sort(new Comparator<OutInfo>() {
@Override
public int compare(OutInfo o1, OutInfo o2) {
......@@ -323,9 +398,14 @@ public class OutInfoCache {
long executeTime2 = o2.getFirstExecuteTime();
if(executeTime1 != executeTime2){
//手动更改优先级的,排在最前面
long result = executeTime1 - executeTime2;
return result > 0 ? 1 : -1;
if(executeTime1 == 0){
return 1;
}
if(executeTime2 == 0){
return -1;
}
Long abs = Math.abs(executeTime1) - Math.abs(executeTime2);
return abs.intValue();
}
//都为0即未执行过的,到这里的,理论上都是未达到必须出库时间(达到必须出库时间的,已经修改过优先级)
Date sdate1 = o1.getSdate();
......@@ -501,19 +581,6 @@ public class OutInfoCache {
public void changePriority(List<String> hSerialList) {
long sortOrder = - System.currentTimeMillis();
for (String hSerial : hSerialList) {
if(Strings.isBlank(hSerial)){
continue;
}
OutInfo outInfo = getOutInfoFromCache(hSerial);
if(outInfo != null){
updateExecuteTime(outInfo, sortOrder);
sortOrder = sortOrder - 1;
}
}
}
private OutInfo updateExecuteTime(OutInfo outInfo,long executeTime){
boolean updateResult = outInfo.updateExecuteTime(executeTime);
......
......@@ -111,8 +111,8 @@ public class QisdaApiController extends BaseController {
@ResponseBody
public String executeOut(HttpServletRequest request){
String hSerial = request.getParameter("hSerial");
OutInfo outInfo = outInfoCache.getOutInfoFromCache(hSerial);
qisdaBindService.realBindOutInfo(outInfo);
//OutInfo outInfo = outInfoCache.getOutInfoFromCache(hSerial);
//qisdaBindService.realBindOutInfo(outInfo);
ResultBean resultBean = outInfoCache.checkOutOutItems(hSerial);
return resultBean.getMsg();
}
......
......@@ -84,6 +84,7 @@ public class QisdaCache {
rfidDnMap = new ConcurrentHashMap<>();
}else{
rfidDnMap = (Map<String, DNInfo>) cacheInfo.getCacheValue();
log.info("当前收料绑定:" + rfidDnMap);
}
}
}
......@@ -127,7 +128,6 @@ public class QisdaCache {
}
public static void bindRfidDnInfo(String rfid, DNInfo dnInfo){
rfidDnMap.put(rfid, dnInfo);
saveRfidDnMap();
}
......
......@@ -560,20 +560,19 @@ public class QisdaDeviceController extends BaseController {
public ResultBean cancelPutInTask(HttpServletRequest request) {
String codeStr = request.getParameter("barcode");
try{
Barcode barcode = dataCache.resolveOneValideBarcode(codeStr);
Collection<DataLog> queueTasks = taskService.getQueueTasks();
for (DataLog queueTask : queueTasks) {
if(queueTask.isPutInTask() && queueTask.getBarcode().equals(barcode)){
if(queueTask.isPutInTask() && codeStr.contains(queueTask.getBarcode())){
//只能取消入库任务
boolean cancelResult = taskService.cancelTask(queueTask.getId());
log.info("客户端取消["+barcode+"]的入库任务结果:" + cancelResult);
log.info("客户端取消["+codeStr+"]的入库任务结果:" + cancelResult);
return ResultBean.newOkResult(cancelResult);
}
}
}catch (Exception e){
return ResultBean.newErrorResult(2002, "任务["+codeStr+"]取消失败:" + e.getMessage());
return ResultBean.newErrorResult(2002, "客户端取消任务["+codeStr+"]失败:" + e.getMessage());
}
return ResultBean.newErrorResult(2003, "任务["+codeStr+"]取消失败");
return ResultBean.newErrorResult(2003, "客户端取消任务["+codeStr+"]失败");
}
/**
......
......@@ -554,7 +554,7 @@ public class StorageDataController extends BaseController {
if(dataCache.getSettings().isStopOut()){
lineMsg = "系统更新中,暂停出入库";
resultMap.put("result","100");
resultMap.put("result"," ");
resultMap.put("msg",lineMsg);
return resultMap;
}
......
......@@ -444,11 +444,6 @@ public class TaskService implements ITaskService {
if(result != null){
barcodeSave = result;
}
String bindSoseq = barcodeSave.getAppendInfo().getSoseq();
if(Strings.isNullOrEmpty(bindSoseq)){
//未绑定(不是分盘入库)
barcodeSave = outInfoCache.bindPutInReel(barcodeSave);
}
barcodeSave = barcodeManager.save(barcodeSave);
return barcodeSave;
......@@ -1653,26 +1648,26 @@ public class TaskService implements ITaskService {
}
}
log.info("二维码:[" + barcode.getBarcode() + "]任务["+storagePos.getPosName()+"]开始加入队列");
DataLog dataLog = new DataLog();
dataLog.setStorageId(storage.getId());
dataLog.setStorageName(storage.getName());
dataLog.setBarcode(barcode.getBarcode());
dataLog.setAppendInfo(barcode.getAppendInfo());
dataLog.setRelationCodes(barcode.getRelationCodes());
//dataLog.setRelationCodes(barcode.getRelationCodes());
dataLog.setType(StorageConstants.OP.PUT_IN);
dataLog.setNum(barcode.getAmount());
dataLog.setCid(storage.getCid());
String loginUser = StorageDataController.getLoginUsername();
dataLog.setOperator(loginUser);
//String loginUser = StorageDataController.getLoginUsername();
//dataLog.setOperator(loginUser);
dataLog.setPartNumber(barcode.getPartNumber());
dataLog.setPosId(storagePos.getId());
dataLog.setPosName(storagePos.getPosName());
dataLog.setStatus(StorageConstants.OP_STATUS.EXECUTING.name());
dataLog.setSourceName(barcode.getAppendInfo().getDnNo());
dataLogDao.save(dataLog);
......@@ -1696,8 +1691,8 @@ public class TaskService implements ITaskService {
barcode.setPosName(task.getPosName());
barcode.setInitialAmount(barcode.getAmount());
//TODO: 进行绑定或者预绑定
//入库更新绑定数量
barcode = outInfoCache.bindPutInReel(barcode);
barcodeManager.save(barcode);
......@@ -1764,20 +1759,6 @@ public class TaskService implements ITaskService {
dNItemDao.save(dnItem);
}
//入库更新绑定数量
String soseq = appendInfo.getSoseq();
if(soseq != null && !soseq.isEmpty()){
int slotIndex = appendInfo.getSlotIndex();
OutItem cutItem = outItemDao.findCutItem(soseq, slotIndex);
if(cutItem != null){
int realBindQty = cutItem.getRealLockQty() + barcode.getAmount();
log.info(barcode.getBarcode() + "纯入库完成,分盘需求单soseq=["+soseq+"]slotSeq=["+slotIndex+"]绑定数量增加"+barcode.getAmount()+"="+ realBindQty);
cutItem.setRealLockQty(realBindQty);
soseqCache.updateTotalRealLockQty(cutItem,realBindQty);
}
}
//通知VMI入库完成
QisdaApiController.PutInFinished(barcode, task);
}
......
......@@ -7,6 +7,9 @@
.icon-cursor-move{
margin-right:10px;
}
.portlet-body {
min-height:60px;
}
.panel-body {
position: relative;
......@@ -24,6 +27,7 @@
margin-bottom: 10px;
}
</style>
<link href="${ctx}/scripts/lobibox/css/lobibox.min.css?id=2" rel="stylesheet" type="text/css"/>
......@@ -173,6 +177,8 @@
});
}
flushOutInfos();
var moving = false;
setInterval(function(){
if(!moving){
......
支持 Markdown 格式
你添加了 0 到此讨论。请谨慎行事。
Finish editing this message first!