Commit dc411eff sunke

设置线体后再进行绑定

Fix:有手动出库任务时工单执行出错
出入库日志条码查询转义特殊字符
自动任务开启时不允许手动出库
需求单查询增加线体
1 个父辈 600b3464
......@@ -310,6 +310,9 @@ public class AppendInfo {
}
public boolean isPnAction(){
if(action == null){
return false;
}
return getAction().contains("PN");
}
......
......@@ -32,9 +32,6 @@ public class OutInfo extends BaseMongoBean {
this.taskNeedOutDate = needOutDate;
this.mdate = outItem.getMdate();
this.endOutInfo = outItem.isTheEndOutInfo();
if(outItem.isPnAction()){
this.endOutInfo = true;
}
}
/**
......
......@@ -72,6 +72,8 @@ public interface IStoragePosDao extends IMongoDao {
List<StoragePos> findBindList(String hSerial);
int countBind(String hSerial);
List<StoragePos> findBindList(String hSerial, String outItemId);
/**
......
......@@ -395,6 +395,13 @@ public class StoragePosDaoImpl extends AbstractMongoDao implements IStoragePosDa
return findByQuery(q);
}
@Override
public int countBind(String hSerial){
Criteria c = Criteria.where("barcode.appendInfo.hSerial").is(hSerial);
Query q = new Query(c);
return countByQuery(q);
}
/**
* 获取工单的所有绑定料盘
*/
......
......@@ -26,6 +26,8 @@ public interface IOutInfoDao extends IMongoDao {
void updateTaskFinishNum(String hSerail, int taskFinishNum);
void updateBindNum(String hSerail, int taskFinishNum);
void updateOutReelNum(String hSerial, int outReelNum);
void updateExecuteTime(String hSerial, long firstExecuteTime);
......
......@@ -112,6 +112,11 @@ public class OutInfoDaoImpl extends AbstractMongoDao implements IOutInfoDao {
}
@Override
public void updateBindNum(String hSerail, int taskFinishNum) {
update(hSerail, "totalBindNum", taskFinishNum);
}
@Override
public void updateOutReelNum(String hSerial, int outReelNum){
update(hSerial, "outReelNum", outReelNum);
}
......
......@@ -43,26 +43,38 @@ public class OutInfoSearchController extends BaseSearchController {
@RequestMapping("/outInfoSearch*")
public String onSubmit(@ModelAttribute("searchCriteria") BaseSearchCriteria searchCriteria, HttpServletRequest request) {
boolean stopOut = dataCache.getSettings().isStopOut();
request.setAttribute("stopOut",stopOut);
boolean stopJob = dataCache.getSettings().isStopJob();
request.setAttribute("stopJob",stopJob);
Query query = new Query();
Criteria criteria = new Criteria();
addLikeParam(request,criteria,"so");
String reelId = request.getParameter("reelId");
if(Strings.isNotBlank(reelId)){
Pattern pattern = Pattern.compile(reelId, Pattern.CASE_INSENSITIVE);
Criteria c = Criteria.where("reelID").regex(pattern);
String lineStr = request.getParameter("line");
if(lineStr == null){
lineStr = "NONE";
}
request.setAttribute("line",lineStr);
if(Strings.isNotBlank(lineStr)){
String line = lineStr;
if(lineStr.equals("NONE")){
line = null;
}
criteria.and("line").is(line);
}
String pn = request.getParameter("pn");
if(Strings.isNotBlank(pn)){
Pattern pattern = Pattern.compile(pn, Pattern.CASE_INSENSITIVE);
Criteria c = Criteria.where("pn").regex(pattern);
List<OutItem> itemList = outItemDao.findByQuery(new Query(c));
List<String> hSerialList = new ArrayList<>();
for (OutItem outItem : itemList) {
hSerialList.add(outItem.gethSerial());
}
criteria.and("hSerial").in(hSerialList);
request.setAttribute("reelId",reelId);
request.setAttribute("pn",pn);
}else{
addLikeParam(request,criteria,"hSerial");
}
......
......@@ -77,6 +77,7 @@ public class OutInfoCache {
if(!isProcessTimer){
isProcessTimer = true;
try {
closeOutInfos();
if(!dataCache.getSettings().isStopJob()){
updateMustExeOutInfo();
executeBindTask();
......@@ -90,15 +91,16 @@ public class OutInfoCache {
}
}
public void executeOutTask(){
/**
* 关闭已完成的需求单
*/
public void closeOutInfos(){
Date now = new Date();
List<OutInfo> cachedOutInfos = getCachedOutInfos();
for (OutInfo unEndOutInfo : cachedOutInfos) {
if(!unEndOutInfo.isClosed() && unEndOutInfo.isTaskEnd() && !unEndOutInfo.isReelCutAction()){
long lastEndTime = unEndOutInfo.getTaskEndTime();
if(now.getTime() - lastEndTime >= 5 * 60 * 1000){
long taskEndTime = unEndOutInfo.getTaskEndTime();
if(taskEndTime>0 && now.getTime() - taskEndTime >= 5 * 60 * 1000){
//任务已结束5分钟
if(unEndOutInfo.isEndOutInfo()){
log.info("需求单["+unEndOutInfo.gethSerial()+"]已执行过,且是工单的最后一个需求单,关闭工单"+unEndOutInfo.getSo()+"["+unEndOutInfo.getSoseq()+"]");
......@@ -110,6 +112,19 @@ public class OutInfoCache {
}
}
if(unEndOutInfo.getFirstExecuteTime()<=0 && unEndOutInfo.getTotalBindNum() <=0 ){
//未执行过,且未绑定的,更新绑定数量
int bindCount = storagePosDao.countBind(unEndOutInfo.gethSerial());
updateBindNum(unEndOutInfo.gethSerial(),bindCount);
}
}
}
public void executeOutTask(){
Date now = new Date();
List<OutInfo> cachedOutInfos = getCachedOutInfos();
for (OutInfo unEndOutInfo : cachedOutInfos) {
if(unEndOutInfo.isReelCutAction() || unEndOutInfo.isUrgentAction() || unEndOutInfo.isCheckAction()){
//单独出库,分盘料或盘点料,不按时间可直接执行,距离上次任务完成5分钟后才可再次执行
if(unEndOutInfo.isTaskEnd() || unEndOutInfo.isNew()){
......@@ -630,6 +645,16 @@ public class OutInfoCache {
return outInfoList;
}
public void updateBindNum(String hSerial, int bindNum){
OutInfo outInfo = getOutInfoFromCache(hSerial);
if(outInfo != null && outInfo.getFirstExecuteTime() <=0) {
//未执行过,更新
outInfo.setTotalBindNum(bindNum);
outInfoDao.updateBindNum(hSerial, bindNum);
outInfoMap.put(hSerial, outInfo);
}
}
/**
* 任务开始时,初始化出库任务数
* @param hSerial
......@@ -821,8 +846,17 @@ public class OutInfoCache {
public void updateOutInfo(OutInfo outInfo){
//已经执行过的不能更新
outInfoDao.updateOutInfo(outInfo);
if(outInfo.isPnAction() && Strings.isNotBlank(outInfo.getLine())){
qisdaBindService.bindPnOutInfo(outInfo);
List<StoragePos> bindPosList = storagePosDao.findBindList(outInfo.gethSerial());
int bindReelNum = bindPosList.size();
outInfo.setTotalBindNum(bindReelNum);
log.info("PN需求单["+outInfo.gethSerial()+"]绑定料盘数量为:" + bindReelNum);
outInfoDao.save(outInfo);
}
outInfoMap.put(outInfo.gethSerial(),outInfo);
log.info("更新需求单["+outInfo.gethSerial()+"]的建议时间为:"+outInfo.getSdate() + " 必须时间为:" + outInfo.getMdate());
log.info("更新需求单["+outInfo.gethSerial()+"]的建议时间为:"+outInfo.getSdate() + " 必须时间为:" + outInfo.getMdate() +" 目的地为:"+ outInfo.getLine());
}
......@@ -881,9 +915,6 @@ public class OutInfoCache {
* @return
*/
private ResultBean checkOutInfoCanOut(OutInfo outInfo){
if(dataCache.getSettings().isStopOut()){
return ResultBean.newErrorResult(100, "系统更新中,暂停出库,请稍后再试",false);
}
if(outInfo == null){
return ResultBean.newErrorResult(1001,"未找到需求单",false);
......@@ -974,6 +1005,11 @@ public class OutInfoCache {
private static AtomicBoolean outProcessing = new AtomicBoolean(false);
public synchronized ResultBean checkOutOutItems(String hSerial){
if(dataCache.getSettings().isStopOut()){
return ResultBean.newErrorResult(1001, "系统更新中,暂停出入库,请稍后再试",false);
}
boolean canProcess = outProcessing.compareAndSet(false, true);
try{
if(canProcess){
......@@ -990,7 +1026,7 @@ public class OutInfoCache {
}
}
public synchronized ResultBean executeOutItems(String hSerial){
private synchronized ResultBean executeOutItems(String hSerial){
//OutInfo outInfo = outInfoDao.findByHSerial(hSerial);
OutInfo outInfoToExecute = getOutInfoFromCache(hSerial);
......
......@@ -82,13 +82,13 @@ public class DataLogSearchController extends BaseSearchController {
String barcode = searchCriteria.getBarcode();
if(!Strings.isNullOrEmpty(barcode)){
Pattern pattern = Pattern.compile(barcode, Pattern.CASE_INSENSITIVE);
Pattern pattern = Pattern.compile(escapeExprSpecialWord(barcode), Pattern.CASE_INSENSITIVE);
criteria.and("barcode").regex(pattern);
}
String partNumber = searchCriteria.getPartNumber();
if (!Strings.isNullOrEmpty(partNumber)) {
Pattern pattern = Pattern.compile(partNumber, Pattern.CASE_INSENSITIVE);
Pattern pattern = Pattern.compile(escapeExprSpecialWord(partNumber), Pattern.CASE_INSENSITIVE);
criteria.and("partNumber").regex(pattern);
}
......@@ -129,6 +129,18 @@ public class DataLogSearchController extends BaseSearchController {
return SUCCESS_VIEW;
}
private String escapeExprSpecialWord(String keyword) {
if (!Strings.isNullOrEmpty(keyword)) {
String[] fbsArr = { "\\", "$", "(", ")", "*", "+", ".", "[", "]", "?", "^", "{", "}", "|" };
for (String key : fbsArr) {
if (keyword.contains(key)) {
keyword = keyword.replace(key, "\\" + key);
}
}
}
return keyword;
}
@Override
protected BaseSearchCriteria getNewSearchCriteria() {
......
......@@ -144,8 +144,14 @@ public class QisdaApiController extends BaseController {
String hSerial = request.getParameter("hSerial");
//OutInfo outInfo = outInfoCache.getOutInfoFromCache(hSerial);
//qisdaBindService.realBindOutInfo(outInfo);
ResultBean resultBean = null;
if(!dataCache.getSettings().isStopJob()){
resultBean = ResultBean.newErrorResult(1001, "自动任务开启时,不允许手动出库",false);
}else{
log.info("手动执行需求单["+hSerial+"]出库");
ResultBean resultBean = outInfoCache.checkOutOutItems(hSerial);
resultBean = outInfoCache.checkOutOutItems(hSerial);
}
return resultBean.getMsg();
}
......@@ -530,46 +536,6 @@ public class QisdaApiController extends BaseController {
outItem = outItemDao.save(outItem);
if(outItem.isPnAction()){
int needNum = outItem.getQty() - outItem.getSendQty() - outItem.getRealLockQty();
log.info("将预绑定转为真实绑定结束,所需数量("+needNum+")=需求单数量("+outItem.getQty()+")-已发料数量("+ outItem.getSendQty()+")-真实绑定数量"+ outItem.getRealLockQty() +")");
if(needNum >= 0){
log.info("预绑定数量不足,查找未绑定料盘进行真实绑定结束,当前数量:"+outItem.getSendQty()+"+"+ outItem.getRealLockQty() +"/" + outItem.getQty());
while(needNum >= 0){
StoragePos pos = storagePosDao.findNoBindMinQty(outItem.getPn(), outItem.getFacility());
if(pos != null){
Barcode barcode = pos.getBarcode();
AppendInfo appendInfo = barcode.getAppendInfo();
//未真实绑定过,可以出库,绑定
appendInfo.sethSerial(outItem.gethSerial());
appendInfo.setRefno(outItem.getRefno());
appendInfo.setSo("HSerial-" + outItem.gethSerial());
appendInfo.setSoseq("HSerial-" + outItem.gethSerial());
appendInfo.setSlotStr(outItem.getSlotStr());
appendInfo.setOutItemId(outItem.getId());
appendInfo.setBindSlot("1");
appendInfo.setSlotIndex(1);
barcode.setAppendInfo(appendInfo);
pos.setBarcode(barcode);
storagePosDao.save(pos);
int totalLockQty = outItem.getLockQty() + barcode.getAmount();
outItem.setLockQty(totalLockQty);
outItem.setRealLockQty(totalLockQty);
}else{
break;
}
if(outItem.getRealLockQty() > outItem.getQty()){
//已经满足需求了,直接跳出
break;
}
}
}
outItem = outItemDao.save(outItem);
outInfo.updateItem(outItem);
outInfoMap.put(hSerial, outInfo);
}else if(outItem.isUrgentAction()){
......
......@@ -90,6 +90,55 @@ public class QisdaBindService {
}
}
/**
* 绑定PN需求单
*/
public void bindPnOutInfo(OutInfo pnOutInfo){
log.info("Pn需求单["+pnOutInfo.gethSerial()+"]线别["+pnOutInfo.getLine()+"]开始进行绑定");
for (OutItem outItem : pnOutInfo.getOutItems()) {
int needNum = outItem.getQty() - outItem.getSendQty() - outItem.getRealLockQty();
//log.info("开始绑定,所需数量("+needNum+")=需求单数量("+outItem.getQty()+")-已发料数量("+ outItem.getSendQty()+")-真实绑定数量"+ outItem.getRealLockQty() +")");
if(needNum >= 0){
log.info("查找未绑定料盘进行真实绑定结束,当前数量:"+outItem.getSendQty()+"+"+ outItem.getRealLockQty() +"/" + outItem.getQty());
while(needNum >= 0){
StoragePos pos = storagePosDao.findNoBindMinQty(outItem.getPn(), outItem.getFacility());
if(pos != null){
Barcode barcode = pos.getBarcode();
AppendInfo appendInfo = barcode.getAppendInfo();
//未真实绑定过,可以出库,绑定
appendInfo.sethSerial(outItem.gethSerial());
appendInfo.setRefno(outItem.getRefno());
appendInfo.setSo("HSerial-" + outItem.gethSerial());
appendInfo.setSoseq("HSerial-" + outItem.gethSerial());
appendInfo.setSlotStr(outItem.getSlotStr());
appendInfo.setOutItemId(outItem.getId());
appendInfo.setBindSlot("1");
appendInfo.setSlotIndex(1);
barcode.setAppendInfo(appendInfo);
pos.setBarcode(barcode);
storagePosDao.save(pos);
int totalLockQty = outItem.getLockQty() + barcode.getAmount();
outItem.setLockQty(totalLockQty);
outItem.setRealLockQty(totalLockQty);
log.info("绑定料盘"+barcode.getBarcode()+"["+barcode.getPartNumber()+"]到PN需求单["+outItem.gethSerial()+"]");
}else{
break;
}
if(outItem.getRealLockQty() > outItem.getQty()){
//已经满足需求了,直接跳出
break;
}
}
}
outItem = outItemDao.save(outItem);
pnOutInfo.updateItem(outItem);
}
}
/******************************** 以下是 Private 方法*******************************************/
......@@ -360,6 +409,9 @@ public class QisdaBindService {
bindItem.setLockQty(totalLockQty);
bindItem.setRealLockQty(totalLockQty);
outItemDao.updateLockQty(bindItem.getId(), totalLockQty, totalLockQty);
int bindCount = storagePosDao.countBind(bindItem.gethSerial());
outInfoCache.updateBindNum(bindItem.gethSerial(),bindCount);
outInfoCache.updateOutItem(bindItem.getId());
log.info("绑定料盘["+barcode.getBarcode()+"]到需求单["+bindItem.gethSerial()+"]完成");
}
......@@ -467,6 +519,7 @@ public class QisdaBindService {
List<OutInfo> cacheOutInfoList = outInfoCache.getCachedOutInfos();
List<String> lessHSerialList = new ArrayList<>();
for (OutInfo unEndOutInfo : cacheOutInfoList) {
if(Strings.isNotBlank(unEndOutInfo.getLine())){
if(!unEndOutInfo.isClosed() && !unEndOutInfo.isRealBindOk()){
if(unEndOutInfo.isPnAction()){
lessHSerialList.add(unEndOutInfo.gethSerial());
......@@ -474,7 +527,7 @@ public class QisdaBindService {
lessHSerialList.add(unEndOutInfo.gethSerial());
}
}
}
}
String pn = barcode.getPartNumber();
......@@ -494,6 +547,7 @@ public class QisdaBindService {
OutInfo outInfo = outInfoCache.getOutInfoFromCache(outItem.gethSerial());
if(outInfo != null){
//只对有目的地并且缺料的进行绑定
if(outInfo.isPnAction() || outInfo.isReelCutAction()){
//真实绑定缺料
if(outItem.realBindLessQty() > 0){
......
......@@ -8,6 +8,7 @@ import com.google.common.collect.Sets;
import com.myproject.bean.CodeBean;
import com.myproject.bean.json.*;
import com.myproject.bean.qisda.ReelLockPosInfo;
import com.myproject.bean.qisda.ResultBean;
import com.myproject.bean.search.PageList;
import com.myproject.bean.update.*;
import com.myproject.bean.utils.BoxStatusBean;
......@@ -251,6 +252,10 @@ public class StorageDataController extends BaseController {
@ResponseBody
public String checkPos(HttpServletRequest request) {
if(dataCache.getSettings().isStopOut()){
return "系统更新中,暂停出入库,请稍后再试";
}
String cid = request.getParameter("cid");
String partnumber = request.getParameter("pn");
if(partnumber != null){
......
......@@ -22,7 +22,7 @@
socket-timeout="${mongo.socketTimeout}" slave-ok="${mongo.slaveOk}"
write-number="1" write-timeout="0" write-fsync="true" />
</mongo:mongo>
<mongo:db-factory dbname="qisda" username="${mongo.username}"
<mongo:db-factory dbname="gree" username="${mongo.username}"
password="${mongo.password}" mongo-ref="mongo" />
<bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
<constructor-arg name="mongoDbFactory" ref="mongoDbFactory" />
......
......@@ -209,15 +209,15 @@
<%--<display:column titleKey="barcode.expireDate" sortProperty="barcode.expireDate" sortable="true">--%>
<%--<fmt:formatDate value="${pos.barcode.expireDate}" pattern="yyyy-MM-dd"/>--%>
<%--</display:column>--%>
<%--<security:authorize ifAnyGranted="ROLE_MANAGE_STACK_OUT, ROLE_MANAGE_FEEDER">--%>
<%--<display:column titleKey="checkOut.operate" media="html">--%>
<security:authorize ifAnyGranted="ROLE_MANAGE_STACK_OUT, ROLE_MANAGE_FEEDER">
<display:column titleKey="checkOut.operate" media="html">
<%--<c:if test="${!limitCheckOut}">--%>
<%--<button class="btn yellow limit${pos.barcode.inFixture}" id="btn${pos.id}"--%>
<%--onclick="checkoutStorage('${pos.id}')">--%>
<%--<i class="fa fa-sign-out"></i><fmt:message key="button.checkout"/></button>--%>
<button class="btn yellow limit${pos.barcode.inFixture}" id="btn${pos.id}"
onclick="checkoutStorage('${pos.id}')">
<i class="fa fa-sign-out"></i><fmt:message key="button.checkout"/></button>
<%--</c:if>--%>
<%--</display:column>--%>
<%--</security:authorize>--%>
</display:column>
</security:authorize>
<c:if test="${limitCheckOut}">
<c:set var="limitCodes" value="${pos.barcode.inFixture},${limitCodes}"/>
</c:if>
......
......@@ -17,12 +17,6 @@
</style>
<c:if test="${stopOut}">
系统更新中,暂停出库,请稍后再试
</c:if>
<c:if test="${!stopOut}">
<!-- BEGIN PAGE HEADER-->
<h3 class="page-title">
<fmt:message key="需求单"/>
......@@ -59,15 +53,27 @@
</div>
</div>
<label class="control-label col-md-1"><fmt:message key="ReelId"/></label>
<label class="control-label col-md-1"><fmt:message key="线别"/></label>
<div class="col-md-1">
<select class="form-control" name="line">
<option value="">所有</option>
<option value="NONE" <c:if test='${line=="NONE"}'>selected</c:if>>未定义</option>
<c:forEach begin="1" end="20" var="lineStr">
<c:set var="lineValue" value="SMT${lineStr}"/>
<option value="${lineValue}" <c:if test='${line == lineValue}'>selected</c:if>>${lineValue}</option>
</c:forEach>
</select>
</div>
<label class="control-label col-md-1"><fmt:message key="PN"/></label>
<div class="col-md-2">
<div style="text-align:left" class="input-group">
<input type="text" name="reelId" class="form-control" value="${reelId}"/>
<input type="text" name="reelId" class="form-control" value="${pn}"/>
</div>
</div>
<div class="col-md-2">
<div class="col-md-1">
<button class="btn purple" type="submit"><i class="fa fa-search"></i>
<fmt:message key="button.search"/>
</button>
......@@ -106,12 +112,12 @@
<fmt:formatDate value="${outInfo.mdate}" pattern="yyyy-MM-dd HH:mm"/>
</display:column>
<display:column titleKey="任务" sortable="true" sortProperty="mdate">
<display:column titleKey="任务" sortable="true" sortProperty="taskNum">
${outInfo.taskFinishNum}/${outInfo.taskNum}
</display:column>
<display:column titleKey="累计任务" sortable="true" sortProperty="totalTaskNum">
${outInfo.totalTaskNum}/${outInfo.totalBindNum}
<display:column titleKey="绑定数量" sortable="true" sortProperty="totalBindNum">
${outInfo.totalBindNum}
</display:column>
<display:column titleKey="创建时间" sortable="true" sortProperty="createDate">
......@@ -126,7 +132,7 @@
</display:column>
<display:column titleKey="checkOut.operate" media="html" sortProperty="sendStatus" sortable="true">
<c:if test="${!outInfo.executing}">
<c:if test="${!outInfo.executing && stopJob}">
<c:if test="${(outInfo.urgentAction && outInfo.taskFinishNum != outInfo.taskNum) || (!outInfo.sendEnd && !outInfo.closed)}">
<button class="btn yellow" id="btn${outInfo.hSerial}" onclick="executeOut('${outInfo.hSerial}')">
<i class="fa fa-sign-out"></i><fmt:message key="button.checkout"/>
......@@ -147,7 +153,6 @@
<!-- END EXAMPLE TABLE PORTLET-->
</div>
</div>
</c:if>
<div id="detail" class="modal fade" tabindex="-1" data-backdrop="static" data-keyboard="false">
<div class="modal-dialog" style="margin-top: 10%;width:80%;margin-left:10%;">
......@@ -221,7 +226,12 @@
<label class="control-label col-md-2"><fmt:message key="线别:"/></label>
<div class="input-group">
<input type="hidden" id="hSerialToModify" value=""/>
<input type="text" class="form-control" id="lineToModify" />
<select class="form-control" id="lineToModify">
<option value="">--</option>
<c:forEach begin="1" end="20" var="line">
<option value="SMT${line}">SMT${line}</option>
</c:forEach>
</select>
</div>
<h4>
<span id="lineErrorMsg" style="font-weight: 500;color:red;"></span>
......
......@@ -239,7 +239,7 @@
<div class="page-footer-inner">
2016&copy; <a href="${ctx}/updateHistory.html">SMD BOX</a>
</div>
<span class="right" style="color: #a3a3a3;">Version: 1.4.26</span>
<span class="right" style="color: #a3a3a3;">Version: 1.5.2118</span>
<div class="scroll-to-top">
<i class="icon-arrow-up"></i>
</div>
......
支持 Markdown 格式
你添加了 0 到此讨论。请谨慎行事。
Finish editing this message first!