ProcessSwitchAction.java

package com.mycim.webapp.actions.operation.run;

import com.fa.sesa.exception.Assert;
import com.fa.sesa.exception.Errors;
import com.fa.sesa.threadlocal.LocalContext;
import com.mycim.framework.cache.utils.CacheUtils;
import com.mycim.framework.utils.lang.BooleanUtils;
import com.mycim.framework.utils.lang.StringUtils;
import com.mycim.framework.utils.lang.collections.CollectionUtils;
import com.mycim.framework.utils.lang.collections.MapUtils;
import com.mycim.valueobject.LotConstants;
import com.mycim.valueobject.MessageIdList;
import com.mycim.valueobject.consts.SessionNames;
import com.mycim.valueobject.wip.HandleLot;
import com.mycim.valueobject.wip.Job;
import com.mycim.valueobject.wip.Lot;
import com.mycim.valueobject.wip.LotStatus;
import com.mycim.webapp.Constants;
import com.mycim.webapp.actions.WipSetupAction;
import com.mycim.webapp.forms.BaseTaskForm;
import com.mycim.webapp.forms.ProcessSwitchForm;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author Johnson.Wang
 * @version 6.0.0
 * @date 2019/10/6
 **/
public class ProcessSwitchAction extends WipSetupAction {

    @Override
    public ActionForward perform(ActionMapping mapping, ActionForm form, HttpServletRequest request,
                                 HttpServletResponse response) throws Exception {
        ProcessSwitchForm theform = (ProcessSwitchForm) form;
        Map parameters = (HashMap) request.getAttribute(SessionNames.PARAMETERSINFO_KEY);
        if (request.getParameter(Constants.CANCEL_KEY) != null) {
            if (request.getAttribute(SessionNames.OPERATION_KEY) != null) {
                return mapping.findForward("jobmanagement4operation");
            } else {
                    return mapping.findForward("jobmanagement");
            }
        }

        Job job = (Job) request.getAttribute(SessionNames.JOB_KEY);

        Assert.isFalse(MapUtils.isEmpty(parameters), Errors.create().content("Parameters are not enough!").build());

        validateTask(parameters, "movenext");

        job = wipQueryService.getJob(job.getJobRrn());
        Assert.isFalse(job == null, Errors.create().key(MessageIdList.JOB_NOT_EXIST_OR_MOVE_NEXT_ALREADY)
                                              .content("Job  Not Exist or Move next Already!").build());
        List<Map> handleLotInfos = (List<Map>) request.getAttribute(SessionNames.HANDLE_LOT_INFO_KEY);

        //如果job中没有 lots,这个job 有脏数据问题
        List<String> lotRrns = new ArrayList<>();
        if (StringUtils.isBlank(MapUtils.getString(parameters,"lotRrn"))) {
            List<Lot> lots = lotQueryService.getLotsByJobRrn(job.getJobRrn());
            Assert.isFalse(CollectionUtils.isEmpty(lots), Errors.create().key(MessageIdList.LOT_ID_EMPTY)
                                                                .content("Job  Can not Query Lots!").build());
            lotRrns = lots.stream().map(Lot::getLotRrn).map(StringUtils::toString).collect(Collectors.toList());
        }else {
            lotRrns.add(MapUtils.getString(parameters,"lotRrn"));
        }

        //这里严格控制 parameter 中传入的lotRrn数据,通过 jobRrn 查询可能已经 丢失lot信息  issue  #41242
        String lotRrnsStr = MapUtils.getStringCheckNull(parameters,"lotRrns");
        if(StringUtils.isNotEmpty(lotRrnsStr)){
            List<String> lotRrnsList= StringUtils.splitAsList(lotRrnsStr, LotConstants.DEFAULY_SEPARATOR);
            if(CollectionUtils.isNotEmpty(lotRrnsList)&&lotRrnsList.size()!=lotRrns.size()){ //说明通过job 查询丢失了某些lot
                for(String lotRrnStr:lotRrnsList){
                    if(lotRrns.contains(lotRrnsStr)){
                        continue;// 这里跳过job查询到的lot
                    }
                    //能到这里说明jobrrn 查询 lot, 丢失了某些lot信息,比如 bonded 状态的,lot表中 eqptrrn字段没有被清空
                    //因此导致issue #41242 辅材在与主产品做完bond之后出站后,辅材的lot 当前加工设备在lot 表还存在
                    long lotRrn =  Long.parseLong(lotRrnStr);
                    if(lotRrn<=0){
                        continue;
                    }
                    String lotState = lotQueryService.getLotStatus(lotRrn);
                    if(StringUtils.equalsIgnoreCase(LotStatus.BONDED,lotState)){ //issue 中只描述了 bonded
                        lotService.clearLotEqptRrn(lotRrn);
                    }
                }
            }
        }

        String reasonCode = theform.getReasonCode();
        List<HandleLot> handleLots = lotService.moveNext(job.getJobRrn(), handleLotInfos, parameters, reasonCode,lotRrns);

        //判断在moveNext操作之前该lot是否已经触发PostFutureHold且未释放
        for (HandleLot handleLot : handleLots) {
            if(BooleanUtils.toBoolean(handleLot.getPostFutureHoldFlag())){
                request.getRequestDispatcher(mapping.findForward("jobmanagement4lot").getPath() + "&lotId=" + handleLot.getLot().getLotId())
                       .forward(request, response);
                return null;
            }
        }

        // finish processed lots
        addProcessedLots(theform, handleLots);
        // update the cacheHelper after movenext
        updateCacheHelper(handleLots, LocalContext.getUserRrn());


        Collection moveNextLotsInfoAll = theform.getProcessedLots();
        request.setAttribute(SessionNames.PROCESS_NEXT_STEP_INFO_KEY, moveNextLotsInfoAll);

        Collection autoSplitLots = theform.getAutoSplitLots();
        if (CollectionUtils.isNotEmpty(autoSplitLots)) {
            Collection splitLots = new ArrayList<>();
            Map lot = null;
            boolean flag = false;

            for (Iterator iter = autoSplitLots.iterator(); iter.hasNext(); ) {
                String splitStr = (String) iter.next();

                if (!splitStr.trim().equals("")) {
                    long splitRrn = Long.parseLong(splitStr);
                    lot = lotQueryService.getLotInfoasMap(LocalContext.getFacilityRrn(),
                                                          lotQueryService.getLot(splitRrn).getLotId());
                    lot.put("needSplitFlag", "1");
                    lot.put("lotRrn", lot.get("lotRrn") + "");
                    lot.put("moveOutQty", "0.0");
                    lot.put("moveOutQty2", "0.0");
                    splitLots.add(lot);
                } else {
                    flag = true;
                }
            }
            if (flag) {
                for (Iterator _it = moveNextLotsInfoAll.iterator(); _it.hasNext(); ) {
                    Map _lot = (Map) _it.next();
                    _lot.put("needSplitFlag", "1");
                    _lot.put("lotRrn", _lot.get("lotRrn") + "");
                    _lot.put("moveOutQty", "0.0");
                    _lot.put("moveOutQty2", "0.0");
                    splitLots.add(_lot);
                }
            }
            request.setAttribute(SessionNames.COLLECTION_KEY, splitLots);

            parameters.put("flag", "1");
            parameters.put(SessionNames.RUNSTEP_FLAG, "0");

            ActionForward workflowPara = mapping.findForward("workflow");
            request.setAttribute("workflowPara", workflowPara);
            request.setAttribute("workflowFlag", "true");
            request.getRequestDispatcher(mapping.findForward("split").getPath()).forward(request, response);
            return null;
        }

        parameters.put(SessionNames.RUNSTEP_FLAG, "0");
        request.getRequestDispatcher(mapping.findForward("workflow").getPath()).forward(request, response);
        return null;
    }

    public void addProcessedLots(BaseTaskForm theform, List<HandleLot> handleLot) {
        for (HandleLot lot : handleLot) {
            addProcessedLots(theform, lot);
        }
    }

    public void addProcessedLots(BaseTaskForm theform, HandleLot handleLot) {
        Lot lot = lotQueryService.getLot(handleLot.getLot().getLotRrn());
        Map lotInfo = buildProcessLotInfo(lot);
        lotInfo.put("holdInfoList", handleLot.getMoveNextHoldLots());
        lotInfo.put("trackOutHoldInfoList", handleLot.getTrackOutHoldLots());
        lotInfo.put("spcHoldInfoList", handleLot.getSpcHoldLots());
        lotInfo.put("edcSpecHoldInfoList", handleLot.getEdcSpecHoldLots());
        theform.getProcessedLots().add(lotInfo);
    }

    private void updateCacheHelper(List<HandleLot> handleLots, Long userRrn) {
        for (HandleLot handleLot : handleLots) {
            updateCacheHelper(lotQueryService.getLot(handleLot.getLot().getLotRrn()), userRrn);
        }
    }

    private void updateCacheHelper(Lot currentLot, Long userRrn) {
        ArrayList availableEquipmentInfos = (ArrayList) buildAvailableEquipInfosForLot(currentLot, userRrn);
        for (Iterator iter = availableEquipmentInfos.iterator(); iter.hasNext(); ) {
            Map availableEquipment = (HashMap) iter.next();
            String eqptRrn = org.apache.commons.collections.MapUtils.getString(availableEquipment, "equipmentRrn");
            List cacheLotStatus = (List<String>) CacheUtils.get(eqptRrn);
            if (cacheLotStatus != null && (!StringUtils.equals(currentLot.getLotStatus(), LotStatus.FINISH))) {
                cacheLotStatus.add(currentLot.getLotStatus());
            }
            CacheUtils.put(eqptRrn + "", cacheLotStatus);
        }
    }

}