EdcStartAction.java

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

import com.fa.sesa.exception.Assert;
import com.fa.sesa.exception.Errors;
import com.fa.sesa.exception.SystemIllegalArgumentException;
import com.fa.sesa.threadlocal.LocalContext;
import com.mycim.framework.utils.beans.BeanUtils;
import com.mycim.framework.utils.beans.PropertyUtils;
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.framework.utils.lang.math.NumberUtils;
import com.mycim.framework.utils.lang.time.DateUtils;
import com.mycim.framework.utils.msg.JsonUtils;
import com.mycim.framework.workflow.engine.costs.ParameterNames;
import com.mycim.utils.WflLinkContextSetupAttributeUtil;
import com.mycim.valueobject.MessageIdList;
import com.mycim.valueobject.ObjectList;
import com.mycim.valueobject.consts.CollectionLevel;
import com.mycim.valueobject.consts.EDCConst;
import com.mycim.valueobject.consts.MultiPathCheckType;
import com.mycim.valueobject.consts.SessionNames;
import com.mycim.valueobject.edcspc.*;
import com.mycim.valueobject.edcspc.rule.CollectionRule;
import com.mycim.valueobject.ems.Equipment;
import com.mycim.valueobject.prp.EdcLotContextValue;
import com.mycim.valueobject.prp.Operation;
import com.mycim.valueobject.spc.SpcResult;
import com.mycim.valueobject.wip.*;
import com.mycim.webapp.Constants;
import com.mycim.webapp.TemplateLocation;
import com.mycim.webapp.WebUtils;
import com.mycim.webapp.actions.WipSetupAction;
import com.mycim.webapp.forms.DataCollectionInfoForm;
import com.mycim.workflow.valueobject.*;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbookFactory;
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.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.text.SimpleDateFormat;
import java.util.*;

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

    @Override
    public ActionForward perform(ActionMapping mapping, ActionForm form, HttpServletRequest request,
                                 HttpServletResponse response) throws Exception {
        //需求41250 在此处调用下载模板的方法
        if (StringUtils.equalsIgnoreCase(request.getParameter("action"), "downloadTemplate")) {
            return downloadTemplate(form,request, response);
        }
        DataCollectionInfoForm theform = (DataCollectionInfoForm) form;
        initCache(theform, request);

        Map parameters = (Map) request.getAttribute(SessionNames.PARAMETERSINFO_KEY);
        parameters.put(SessionNames.RUNSTEP_FLAG, "0");

        boolean existEdc = existEdc(request);

        if (existEdc && StringUtils.isNotBlank(request.getParameter("edcNextPage"))) {
            return edcNextPage(mapping, form, request, response, parameters);
        } else if (existEdc && StringUtils.isNotBlank(request.getParameter("edcSave"))) {
            return saveDataCollection(mapping, form, request, response);
        } else if (request.getParameter(Constants.CANCEL_KEY) != null) {
            return cancelToLotInfo(mapping, form, request, response);
        } else if (existEdc) {
            if (dataHasBeenCollected(request)) {//检查是否已经被收过值
                request.getRequestDispatcher(mapping.findForward("workflow").getPath()).forward(request, response);
                return null;
            }
            return initEdc(mapping, form, request, response, parameters);
        }

        long jobRrn = MapUtils.getLongValue(parameters, "jobRrn");
        Assert.isFalse(jobRrn <= 0, Errors.create().content("Parameters are not enough!").build());
        //检查是否配置了multiPath的edc规则,但流程没有配置edc
        boolean holdFlag = lotService.handleRunningHoldWithMultiPath(jobRrn, MultiPathCheckType.EDC_PLAN);
        if (holdFlag) {
            return super.showRunningHoldInfoDetail(mapping, request, jobRrn);
        }

        request.getRequestDispatcher(mapping.findForward("workflow").getPath()).forward(request, response);
        return null;
    }

    public ActionForward initEdc(ActionMapping mapping, ActionForm form, HttpServletRequest request,
                                 HttpServletResponse response, Map parametersMap) throws Exception {
        DataCollectionInfoForm theform = (DataCollectionInfoForm) form;
        List<Map> lots = (List) request.getAttribute(SessionNames.COLLECTION_KEY);
        String equipmentId = (String) request.getParameter("eqptId");
        Job job = (Job) request.getAttribute(SessionNames.JOB_KEY);

        Lot lot = new Lot();
        List<Map> collection = new ArrayList();
        for (Map lotMap : lots) {
            List<Map> parameterInfos = new ArrayList<>();

            String actionPoint = MapUtils.getString(parametersMap, "actionPoint");
            Equipment equipment = new Equipment(equipmentId,
                                                getNamedSpace(ObjectList.ENTITY_KEY, LocalContext.getFacilityRrn()),
                                                ObjectList.ENTITY_KEY);
            equipment = emsService.getEquipment(equipment);

            lot = lotQueryService.getLot(Long.valueOf((String) lotMap.get("lotRrn")));

            EdcLotContextValue contextValue = ctxExecService.getEdcLotContextValue(lot, equipment, actionPoint);

            Assert.isFalse(contextValue == null, Errors.create().key(MessageIdList.ERROR_EDC_CONTEXTVALUE_NOT_FOUND)
                                                       .content("未找到EDC ContextValue").build());
            Long parameterSetRrn = contextValue.getParameterSetRrn();

            List<ParameterSetVersion> parameterSetVersions = new ArrayList<>();
            //1.获取parameter
            if (parameterSetRrn == null || parameterSetRrn == 0) {
            } else {
                parameterSetVersions = edcService.getActiveParameterSetVersion(parameterSetRrn);
            }


            if (CollectionUtils.isNotEmpty(parameterSetVersions)) {
                for (ParameterSetVersion parameterSetVersion : parameterSetVersions) {
                    List<Unit> unitList = wipQueryService.getUnitList(lot.getLotRrn());

                    List<Parameter> parameters = (List<Parameter>) parameterSetVersion.getParameters();

                    for (Parameter parameter : parameters) {
                        HashMap map = new HashMap();

                        //因为关系表DATA_COLLECTION_RULE中,分别存了参数、规则(此时PARAMETER_SET_RRN、PARAMETER_SET_VERSION都为定值0)
                        //和参数集、参数、规则两种关系。因为参数界面和参数集界面都是以第一种关系展示,
                        // 故这里也使用第一种关系,即PARAMETER_SET_RRN、PARAMETER_SET_VERSION都为0

                        //此方法为使用old rule的选片规则
                        // CollectionRule collectionRule = wipQueryService.getAvailableDataCollectionRule
                        // (unitList, parameter.getInstanceRrn());

                        //此方法为使用new rule的选片规则
                        CollectionRule collectionRule = wipQueryService.getAvailableDataCollectionRule(lot, unitList,
                                                                                                       parameter.getInstanceRrn());

                        String dataCollectionRuleInfo = "NONE";
                        //这个是关于edc暂停的代码,目前先注释,后面有需求在继续开发
                        /*//当批次为7片,选片为Bottom+2,Top-4时,会有重复的位置,导致collectionRule为null
                        if(collectionRule==null){
                            collectionRule = wipQueryService.getDataCollectionRule(unitList,
                            parameterSetVersion.getInstanceRrn(),parameterSetVersion.getInstanceVersion(),
                            parameter.getInstanceRrn());
                            parameter.setDataCollectionRule(collectionRule.getAvailableDataCollectionRule());
                            parameter.setSelectedUnitIds(collectionRule.getSelectedUnitIds());
                            parameter.setSelectedUnitPositions(collectionRule.getSelectedUnitPositions());
                            dataCollectionRuleInfo = parameterSetVersion.getRuleType() != null
                                                     ? parameterSetVersion.getRuleType()
                                                     : dataCollectionRuleInfo;
                        }else {*/

                        if (collectionRule != null) {
                            parameter.setDataCollectionRule(collectionRule.getAvailableDataCollectionRule());
                            parameter.setSelectedUnitIds(collectionRule.getSelectedUnitIds());
                            parameter.setSelectedUnitPositions(collectionRule.getSelectedUnitPositions());
                        } else {
                            parameter.setDataCollectionRule(null);
                            parameter.setSelectedUnitIds(null);
                            parameter.setSelectedUnitPositions(null);
                        }

                        DataCollectionRule dataCollectionRule = parameter.getDataCollectionRule();
                        if (dataCollectionRule == null) {
                            dataCollectionRuleInfo = parameterSetVersion.getRuleType() !=
                                    null ? parameterSetVersion.getRuleType() : dataCollectionRuleInfo;
                        } else {
                            dataCollectionRuleInfo = dataCollectionRule.toString();
                        }
                        /* }*/

                        map.put("dataCollectionRuleInfo", dataCollectionRuleInfo);
                        map.put("parameterSetVersion", parameterSetVersion);
                        map.put("lot", lot);
                        map.put("parameter", parameter);

                        parameterInfos.add(map);
                    }
                }
            }

            HashMap parameterInfoMap = new HashMap();
            parameterInfoMap.put("sourceLot", lot);
            parameterInfoMap.put("parameterInfo", parameterInfos);
            parameterInfoMap.put("parameterSetVersions", parameterSetVersions);
            collection.add(parameterInfoMap);
        }

        copySourceLotInfo(lot, theform);
        theform.setCacheCollection(WebUtils.getCacheObj2String(collection));
        theform.setCacheParametersInfo(WebUtils.getCacheObj2String(parametersMap));
        theform.setCacheLots(WebUtils.getCacheObj2String(lots));
        theform.setCacheJob(WebUtils.getCacheObj2String(job));

        String automoveout = (String) request.getAttribute("automoveout");
        if (StringUtils.isNotBlank(automoveout)) {
            request.setAttribute("automoveout", automoveout);
        }
        request.setAttribute("edcDataInfo", collection);
        request.setAttribute("dcolFlag", "ROUTINE");
        request.setAttribute("mapvalue", "contextInfo");

        request.getRequestDispatcher(mapping.findForward("edcvariable").getPath()).forward(request, response);
        return null;
    }

    //需求41250 下载模板的方法
    public ActionForward downloadTemplate(ActionForm form,HttpServletRequest request, HttpServletResponse response) {

        String sitesStr = request.getParameter("sitesArr");
        String fileName = "EDCPlan_receive_data_template.xls";
        if (StringUtils.isBlank(sitesStr)) {
            return null;
        }
        List<Object> sitesList = JsonUtils.toList(sitesStr, Object.class);

        if (CollectionUtils.isEmpty(sitesList)) {
            return null;
        }
        //chartId 即sheetName
        Set<String> chartIdSet = new LinkedHashSet<>();

        sitesList.forEach(e->{
            if(e instanceof Map) {
                chartIdSet.add(MapUtils.getString((Map)e,"chartId",""));
            }
        });

        Workbook workbook = null;
        try(InputStream inputStream= WebUtils.class.getClassLoader().getResourceAsStream(TemplateLocation.EDC_RECEIVE_DATA_TEMPLATE)){
            workbook = XSSFWorkbookFactory.create(inputStream);
        } catch (IOException e) {
            throw new SystemIllegalArgumentException(Errors.create().key(MessageIdList.SYSTEM_UNKNOWN_EXCEPTION)
                                                           .content("An unknown exception occurs,please contact an IT engineer!").build());
        }

        //创建excel工作表
        workbook.setSheetName(0, "模板说明");
        //sheet的index
        int sheetNumber = 1;
        for (String e : chartIdSet) {
            //生成表头数据
            Set<String> waferIdSet = new LinkedHashSet<>();
            //使第一个单元格为空
            waferIdSet.add(null);
            String siteNumberStr = null;
            //取出对应siteNumber和waferId
            for (Object em : sitesList) {
                if(em instanceof Map){
                    if (StringUtils.equalsIgnoreCase(MapUtils.getString((Map) em,"chartId"),e)) {
                        siteNumberStr = MapUtils.getString((Map)em, "maxSite", null);
                        waferIdSet.add(MapUtils.getString((Map)em, "waferId", null));
                    }
                }
            }
            List<List<String>> dataList = new ArrayList();
            //根据最大siteNumber,生成行数据
            if (StringUtils.isNotEmpty(siteNumberStr) && NumberUtils.isParsable(siteNumberStr)) {
                int siteNumber = Integer.parseInt(siteNumberStr);
                for (int i = 0; i < siteNumber; i++) {
                    List rowDate = new ArrayList();
                    rowDate.add(String.valueOf(i + 1));
                    //给数据的单元格填充null,使其添加边框
                    waferIdSet.forEach(w->{
                        if(rowDate.size() < waferIdSet.size()){
                            rowDate.add(null);
                        }
                    });
                    dataList.add(rowDate);
                }
                //当数据点数小于一时,默认生成一行数
                if (siteNumber < 1) {
                    List rowDate = new ArrayList();
                    rowDate.add("1");
                    dataList.add(rowDate);
                }
            }
            //根据数据为工作表生成sheet
            WebUtils.buildSheetsForWorkbook(workbook, sheetNumber++, e, new ArrayList<String>(waferIdSet), dataList,true);
        }
        //将模板说明移动到最后一页
        workbook.setSheetOrder("模板说明",workbook.getNumberOfSheets()-1);
        //设置打开文件时焦点为第一页
        workbook.setActiveSheet(0);

        //输出工作表
        try {
            WebUtils.exportExcel(workbook, response, fileName);
        } catch (IOException e) {
            throw new SystemIllegalArgumentException(Errors.create().key(MessageIdList.SYSTEM_UNKNOWN_EXCEPTION)
                                                           .content("An unknown exception occurs,please contact an IT engineer!").build());
        }

        return null;
    }

    public ActionForward edcNextPage(ActionMapping mapping, ActionForm form, HttpServletRequest request,
                                     HttpServletResponse response, Map parametersMap) throws Exception {
        DataCollectionInfoForm theform = (DataCollectionInfoForm) form;
        moveNextPage(theform, request);
        request.getRequestDispatcher(mapping.findForward("edccommit").getPath()).forward(request, response);
        return null;
    }

    public ActionForward saveDataCollection(ActionMapping mapping, ActionForm form, HttpServletRequest request,
                                            HttpServletResponse response) throws Exception {
        String userId = LocalContext.getUserId();
        DataCollectionInfoForm theform = (DataCollectionInfoForm) form;
        List<Map> dcolStepInfos = (List<Map>) WebUtils.getCacheString2Obj(theform.getCacheDcolStepInfos());

        //-------校验edc规则是否匹配--------Start------------
        //Map<Long, List<ParameterSetVersion>> unavailableParameterSetVersion = (Map<Long,
        // List<ParameterSetVersion>>) request.getAttribute("unavailableParameterSetVersion");
       /* Map<Long, List<ParameterSetVersion>> unavailableParameterSetVersion = (Map<Long,
       List<ParameterSetVersion>>)WebUtils.getCacheString2Obj(theform.getCacheParametersetversions());
        List<EdcRuleCheckResult> edcRuleCheckResults = new ArrayList<EdcRuleCheckResult>();
        for (Map dcolStepInfo : dcolStepInfos) {
            DcolStepInfo         dcolInfo        = (DcolStepInfo) dcolStepInfo.get("dcolstepinfo");
            Lot lot = lotQueryService.getLot(dcolInfo.getLotRrn());
            if (unavailableParameterSetVersion != null && unavailableParameterSetVersion.get(lot.getLotRrn
            ()) != null) {
                List<EdcRuleCheckResult> tmp = recordEdcRuleCheckRuleInfo(userId, lot,
                                                                          unavailableParameterSetVersion);
                edcRuleCheckResults.addAll(tmp);
            }
        }
        request.setAttribute("edcRuleCheckResults", edcRuleCheckResults);// 为了hold 批次使用*/
        //-------校验edc规则是否匹配--------End------------
        // List<Lot> lockLots = new ArrayList<>();
        // for (Map dcolStepInfo : dcolStepInfos) {
        // List<DcolStepInfo> dcolInfoList = (List) dcolStepInfo.get("dcolstepinfo");
        // if (CollectionUtils.isNotEmpty(dcolInfoList)) {//数据来源于buildDcolStepInfo方法,取lotrrn,list中值始终一样,直接取第一个即可
        // DcolStepInfo dcolInfo = dcolInfoList.get(0);
        // Lot lot = lotQueryService.getLot(dcolInfo.getLotRrn());
        //添加判断,如果有锁直接返回到批次加工页面
        // boolean checkFlag = checkLotLock(lot.getLotRrn());
        // if (checkFlag) {
        //     request.getRequestDispatcher(
        //             mapping.findForward("jobmanagement4lot").getPath() + "&lotId=" + lot.getLotId())
        //            .forward(request, response);
        //     return null;
        // } else {
        //     lockLots.add(lot);
        // }
        // }
        // }
        // checkAndCreateLotsTransLock(LocalContext.getUserRrn(), TransactionNames.LOCK_MOVEOUT, lockLots,
        //                             "EDC2SPC commit in EdcStartAction by: " + userId);

        Map parameters = (Map) request.getAttribute(SessionNames.PARAMETERSINFO_KEY);
        long jobRrn = MapUtils.getLongValue(parameters, "jobRrn");

        //check是否重复提交data collection
        checkRepeatSave(dcolStepInfos, jobRrn, parameters);

        edcService.saveDataCollection(dcolStepInfos, "ROUTINE");
        // removeLotLockWhenTransError(LocalContext.getUserRrn(), lockLots, TransactionNames.LOCK_MOVEOUT,
        //                             "EDC2SPC commit in EdcStartAction by: " + userId);

        //hold超出multiPath中edc上下限
        Assert.isFalse(jobRrn <= 0, Errors.create().content("Parameters are not enough!").build());
        boolean holdFlag = lotService.handleRunningHoldWithMultiPath(jobRrn, MultiPathCheckType.EDC_RANGE);
        if (holdFlag) {
            return super.showRunningHoldInfoDetail(mapping, request, jobRrn);
        }
        //move out 时判断是否为byManual设置的multipath,如果是将路径传递下去
        List<Lot> lotsByJobRrn = lotQueryService.getLotsByJobRrn(jobRrn);
        boolean byManualFlag = wipCheckService.checkMultipathByManual(lotsByJobRrn);
        if (byManualFlag) {
            Assert.isTrue(NumberUtils.INTEGER_ONE.equals(lotsByJobRrn.size()),
                          Errors.create().key(MessageIdList.MULTIPATH_BY_MANUAL_CHECK_LOT)
                                .content("has a multipath set by manual.lot quantity can only be 1!").build());
            Lot multipathLot = lotQueryService.getLot(lotsByJobRrn.get(0).getLotRrn());
            List<Map<String, Object>> wflPathOperation = super.getWflPathoperation(multipathLot);
            List<Map<String, Object>> wflPathRoute = super.getWflPathRoute(multipathLot);
            if (wflPathOperation.size() > 1) {
                request.setAttribute(WflLinkContextSetupAttributeUtil.MANUAL_OPERATION, wflPathOperation);
                request.setAttribute("byManualStepFlag", "true");
            }
            if (wflPathRoute.size() > 1 &&
                    wipCheckService.checkOperationIsLastOperationInRoute(multipathLot.getWflStepPath(),
                                                                         multipathLot.getProcessRrn(),
                                                                         multipathLot.getProcessVersion())) {
                request.setAttribute(WflLinkContextSetupAttributeUtil.MANUAL_ROUTE, wflPathRoute);
                request.setAttribute("byManualRouteFlag", "true");
            }
        }

        parameters.put("dcolStepInfos", dcolStepInfos);

        request.getRequestDispatcher(mapping.findForward("workflow").getPath()).forward(request, response);
        return null;
    }

    private void checkRepeatSave(List<Map> dcolStepInfos, long jobRrn, Map parameters) {
        //check status
        List<String> lotRrns = new ArrayList<>();
        List<String> status = new ArrayList<>();
        for (Map dcolStepInfo : dcolStepInfos) {
            List<DcolStepInfo> dcolInfos = (List<DcolStepInfo>) dcolStepInfo.get("dcolstepinfo");
            if (CollectionUtils.isNotEmpty(dcolInfos)) {
                for (DcolStepInfo dcolInfo : dcolInfos) {
                    String lotRrnStr = String.valueOf(dcolInfo.getLotRrn());
                    if (!lotRrns.contains(lotRrnStr)) {
                        lotRrns.add(lotRrnStr);
                    }
                }
            }
        }
        status.add(LotStatus.RUNNING);
        lotQueryService.checkLotStatus(lotRrns, status);

        //check job
        Job job = wipQueryService.getJob(jobRrn);
        Assert.isFalse(job == null, Errors.create().key(MessageIdList.JOB_NOT_EXIST_OR_MOVE_NEXT_ALREADY)
                                          .content("Job  Not Exist or Move next Already!").build());

        //check taskId
        Long wflExecRrn = MapUtils.getLong(parameters, ParameterNames.MAP_WFL_EXEC_RRN);
        WorkflowInstanceModel instanceModel = workflowEngineService.selectWorkflowInstance(wflExecRrn);
        long wflRrn = instanceModel.getWflRrn();
        WorkflowPath workflowPath = instanceModel.getWorkflowPath();
        int rootWorkflowVersion = workflowPath.getRootWorkflowVersion();
        Workflow workflow = wipWorkflowQueryService.getWorkflow(wflRrn, true, workflowPath);
        WorkflowTemplate workflowTemplate = workflow.findTemplate(rootWorkflowVersion);
        WorkflowTask currentTask = workflowTemplate.getCurrentTask(workflowPath);

        String currentMethodId = currentTask.getModel().getMethodId();
        String requestMetohd = MapUtils.getString(parameters, ParameterNames.MAP_RUNTASKMETHOD);
        Assert.isFalse(StringUtils.isNotBlank(currentMethodId) && StringUtils.isNotBlank(requestMetohd) &&
                               !StringUtils.equalsIgnoreCase(requestMetohd, currentMethodId),
                       Errors.create().key("task.current_task_not_match")
                             .content("The current task does not match the requested task, Please try again later!")
                             .build());
    }

    /**
     * 获取参数集下参数的显示信息
     *
     * @param parameterSetVersion
     * @param parameter
     * @return e.g: THK (None<=None<=None Ω)(2/3): WAFER(1,5), SLOT(1,5),MANUAL(2)<br> 参数名(下限<=目标值<=上限
     * 单位)(样点数/样本数): 规则
     */
    public String getParameterSetVersionShowInfo(ParameterSetVersion parameterSetVersion, Parameter parameter) {
        StringBuilder info = new StringBuilder();
        Collection samplePrompts = parameterSetVersion.getSamplePrompts();
        Collection readingPrompts = parameterSetVersion.getReadingPrompts();

        String defaultVal = "None";
        String target = parameterSetVersion.getTargetValue() == null ? defaultVal : StringUtils.toString(
                parameterSetVersion.getTargetValue());
        String lower = parameterSetVersion.getLowerSpecificationLimit() == null ? defaultVal : StringUtils.toString(
                parameterSetVersion.getLowerSpecificationLimit());
        String upper = parameterSetVersion.getUpperSpecificationLimit() == null ? defaultVal : StringUtils.toString(
                parameterSetVersion.getUpperSpecificationLimit());
        if (samplePrompts == null || samplePrompts.isEmpty()) {
            samplePrompts = edcService.getSamplePrompts(parameterSetVersion);
        }
        if (readingPrompts == null || readingPrompts.isEmpty()) {
            readingPrompts = edcService.getReadingPrompts(parameterSetVersion);
        }

        int sampleSize = samplePrompts.size();
        int readingSize = readingPrompts.size();

        String unit = parameter.getParameterUnit() == null ? "" : parameter.getParameterUnit();

        info.append(parameter.getInstanceId()).append(" ");
        info.append("(").append(lower).append("<=").append(target).append("<=").append(upper);
        info.append(" ").append(unit).append(")");
        // info.append("(").append(sampleSize).append("/").append(readingSize).append("): ");
        info.append("(").append(readingSize).append("): ");

        info.append(
                getCollectionRulesString(parameterSetVersion.getInstanceRrn(), parameterSetVersion.getInstanceVersion(),
                                         parameterSetVersion.getParameterRrn()));

        return info.toString();
    }

    /**
     * 获取参数集下参数的规则显示信息
     *
     * @param parameterSetRrn
     * @param parameterSetVersion
     * @param parameterRrn
     * @return
     */
    public String getCollectionRulesString(Long parameterSetRrn, Integer parameterSetVersion, Long parameterRrn) {
        StringBuilder rules = new StringBuilder();

        List<DataCollectionRule> collectionRules = edcService.getDataCollectionRules(parameterSetRrn,
                                                                                     parameterSetVersion, parameterRrn);

        for (Iterator<DataCollectionRule> iterator = collectionRules.iterator(); iterator.hasNext(); ) {
            DataCollectionRule dataCollectionRule = iterator.next();

            rules.append(dataCollectionRule.toString());
            if (iterator.hasNext()) {
                rules.append(",");
            }
        }

        return rules.toString();
    }

    // public boolean checkLotLock(Long lotRrn) {
    //     LotTransLock lotTransLock = new LotTransLock();
    //     lotTransLock.setLotRrn(lotRrn);
    //     lotTransLock.setUserRrn(LocalContext.getUserRrn());
    //     return lotService.checkLotsTransLock(lotTransLock);
    // }

    private void copySourceLotInfo(Lot lot, DataCollectionInfoForm theform) throws Exception {
        lot.setRecipeId(getInstanceId(lot.getRecipeLogicalRrn()));
        lot.setReticleRrn(lot.getRecipeRrn());
        theform.setLotId(lot.getLotId());
        theform.setSourceEquipmentId(this.getInstanceId(lot.getEqptRrn().longValue()));
        theform.setSourceProductId(lot.getProductId());
        theform.setSourceRouteId(this.getInstanceId(parseRouteRrn(lot.getProcessStepVersion())));
        theform.setSourceTechnologyId(lot.getProcessId());
        if (StringUtils.isNotBlank(lot.getRecipePhysicalId())) {
            theform.setSourceRecipeId(lot.getRecipePhysicalId());
        } else {
            String recipeId = recipeService.buildRecipePhysicalId(lot.getRecipeId(), BeanUtils.copyBeanToMap(lot));
            theform.setSourceRecipeId(recipeId);
        }
        theform.setTargetTechnologyId(lot.getProcessId());
        theform.setSourceOperationId(lot.getOperationId());
        theform.setTargetProductId(lot.getProductId());
    }

    private void moveNextPage(DataCollectionInfoForm theform, HttpServletRequest request) throws Exception {
        List<Map> collection = (List<Map>) WebUtils.getCacheString2Obj(theform.getCacheCollection());

        List<Map> dcolStepInfos = new ArrayList();
        Map<Long, List<ParameterSetVersion>> unavailableParameterSetVersion = new HashMap<>();
        Map readingPromptsMap = new HashMap();

        for (Map map : collection) {
            List<Lot> lockLots = new ArrayList<>();
            Lot sourceLot = (Lot) map.get("sourceLot");
            List<Map> parameterInfos = (List) map.get("parameterInfo");
            List<ParameterSetVersion> parameterSetVersions = (List) map.get("parameterSetVersions");
            List dataCollections = new ArrayList();
            for (ParameterSetVersion parameterSetVersion : parameterSetVersions) {
                Parameter parameter = (Parameter) parameterSetVersion.getParameters().iterator().next();
                String dataCollectionRuleInfo = request.getParameter(
                        sourceLot.getLotId() + "|" + parameter.getInstanceId() + "|RULE");

                if (StringUtils.isEmpty(dataCollectionRuleInfo) || isUnavailableParameterSet(dataCollectionRuleInfo)) {
                    List<ParameterSetVersion> unavailable = unavailableParameterSetVersion.get(sourceLot.getLotRrn());
                    unavailable = unavailable == null ? new ArrayList<ParameterSetVersion>() : unavailable;
                    unavailable.add(parameterSetVersion);
                    unavailableParameterSetVersion.put(sourceLot.getLotRrn(), unavailable);
                    continue;
                }

                this.validateSample(sourceLot, parameterSetVersion, request);

                //准备数据 for edcSave
                DataCollection dataCollection = buildDataCollection(LocalContext.getUserId(), parameterSetVersion);
                dataCollection.setLotRrn(sourceLot.getLotRrn());

                Collection sampleList = this.buildSampleList(sourceLot, parameterSetVersion, request);

                if (sampleList.size() > 0) {
                    dataCollection.setSamples(sampleList);
                    dataCollections.add(dataCollection);

                }
            }

            for (Map parameterInfo : parameterInfos) {
                Parameter parameter = (Parameter) MapUtils.getObject(parameterInfo, "parameter");
                String tempLotId = sourceLot.getLotId();
                //jsp bean:write 标签 的property 属性不可以含有小数点,否则报错,这里仅为了显示而处理 增加 tempLotId
                if (tempLotId.indexOf(".") > 0) {
                    String[] split = tempLotId.split("\\.");
                    tempLotId = split[0] + "_" + split[1];
                }
                parameterInfo.put("tempLotId", tempLotId);

                //前台显示数据
                String[] selectedUnitIds = parameter.getSelectedUnitIds();
                List<Prompt> readingPrompts = (List) parameter.getReadingPrompts();
                for (int i = 0; i < (selectedUnitIds == null ? 0 : selectedUnitIds.length); i++) {//by mingcz 自测发现空指针
                    for (Prompt readingPrompt : readingPrompts) {
                        String readingPromptId =
                                parameter.getInstanceId() + "|" + sourceLot.getLotId() + "|sample|" + i + "|reading|" +
                                        readingPrompt.getPromptId();
                        String readingValue = request.getParameter(readingPromptId);
                        readingPromptsMap.put(readingPromptId, readingValue);

                        //处理小数点问题,仅为了展示页面使用tempLotId
                        readingPromptId = parameter.getInstanceId() + "|" + tempLotId + "|sample|" + i + "|reading|" +
                                readingPrompt.getPromptId();
                        readingPromptsMap.put(readingPromptId, readingValue);

                        //参数ID含有特殊字符,导致前端报错,故改用rrn
                        String readingPromptByRrn =
                                parameter.getInstanceRrn() + "|" + tempLotId + "|sample|" + i + "|reading|" +
                                        readingPrompt.getPromptId();
                        readingPromptsMap.put(readingPromptByRrn, readingValue);
                    }
                }
            }


            //ALRAM 不处理
            //                if (!parameter.getFileCollectionFlag().equals("1")) {
            //                    checkAlarm(sampleList, parameterSetVersion);
            //                }


            List<DcolStepInfo> infos = buildDcolStepInfo(sourceLot);
            Map dcolInfo = new HashMap();
            if (CollectionUtils.isNotEmpty(dataCollections)) {
                dcolInfo.put("datacollections", dataCollections);
                dcolInfo.put("dcolstepinfo", infos);
                dcolStepInfos.add(dcolInfo);
            }
            lockLots.add(sourceLot);
            //            checkAndCreateLotsTransLock(LocalContext.getUserRrn(), TransactionNames
            //            .LOCK_MOVEOUT,
            //                                        lockLots, "EDC2SPC next in EdcStartAction by:" +
            //                                        LocalContext.getUserId());
        }

        request.setAttribute("unavailableParameterSetVersion", unavailableParameterSetVersion);

        theform.setCacheCollection(WebUtils.getCacheObj2String(collection));
        theform.setCacheDcolStepInfos(WebUtils.getCacheObj2String(dcolStepInfos));
        //theform.setCacheParametersetversions(WebUtils.getCacheObj2String(unavailableParameterSetVersion));
        request.setAttribute("collection", collection);
        request.setAttribute("readingPromptsMap", readingPromptsMap);
        String automoveout = request.getParameter("automoveout");
        if (StringUtils.isNotBlank(automoveout)) {
            request.setAttribute("automoveout", automoveout);
        }
    }

    private boolean isUnavailableParameterSet(String dataCollectionRuleInfo) {
        for (EDCConst.CollectionRuleTypeEnum type : EDCConst.CollectionRuleTypeEnum.values()) {
            if (type.toString().equals(dataCollectionRuleInfo)) {
                return true;
            }
        }
        return false;
    }

    private List<DcolStepInfo> buildDcolStepInfo(Lot lot) throws Exception {
        List<DcolStepInfo> infos = new ArrayList<>();

        Operation operation = prpService.getOperation(lot.getOperationRrn());
        operation.setObjectType(lotQueryService.getOperationType(lot));
        String pStepType = prpService.getPOperationByMOperation(operation);
        List<LotProcessInfo> lotProcessInfos = lotQueryService.getLotProcessInfo(lot.getLotRrn(), pStepType);
      /*  List<LotStepHistory> stepHistories = lotProcessInfos.stream().map(lotProcessInfo -> {
            LotStepHistory lotStepHistory = lotQueryService
                    .getLotStepHistory(lotProcessInfo.getLotRrn(), lotProcessInfo.getStepSequence());
            return lotStepHistory;
        }).collect(Collectors.toList());*/

        if (CollectionUtils.isNotEmpty(lotProcessInfos)) {
            //for (LotStepHistory lotstephistoryinfo : stepHistories) {
            LotProcessInfo lotProcessInfo = lotProcessInfos.get(0);
            LotStepHistory lotstephistoryinfo = lotQueryService.getLotStepHistory(lotProcessInfo.getLotRrn(),
                                                                                  lotProcessInfo.getStepSequence());
            DcolStepInfo info = new DcolStepInfo();
            if (lotstephistoryinfo != null) {
                info.setLotRrn(lot.getLotRrn());
                info.setMetrologicalEqptRrn(lot.getEqptRrn());
                info.setMetrologicalOperRrn(lot.getOperationRrn());
                info.setMetrologicalOperVersion(new Long(lot.getOperationVersion().intValue()));

                info.setMetrologicalRunRrn(lot.getJobRrn());
                info.setMetrologicalStepSequence(lot.getStepSequence());
                info.setMetrologicalStep(lot.getProcessStepIdVersion());
                info.setMetrologicalStepVersion(lot.getProcessStepVersion());

                if (lotstephistoryinfo.getEqptRrn() != null) {
                    info.setManufacturingEqptRrn(new Long("" + lotstephistoryinfo.getEqptRrn()));
                } else {
                    info.setManufacturingEqptRrn(new Long(0));
                }

                info.setManufacturingOperRrn(new Long("" + lotstephistoryinfo.getOperationRrn()));

                if (lotstephistoryinfo.getOperationVersion() != null) {
                    info.setManufacturingOperVersion(new Long("" + lotstephistoryinfo.getOperationVersion()));
                }

                info.setManufacturingRunRrn(null);

                info.setManufacturingStepSequence(Long.parseLong("" + lotstephistoryinfo.getStepSequence()));

                info.setManufacturingStep((String) lotstephistoryinfo.getProcessStepIdVersion());
                info.setManufacturingStepVersion((String) lotstephistoryinfo.getProcessStepVersion());
                info.setProcessRrn(lot.getProcessRrn());
                info.setProcessVersion(lot.getProcessVersion());
                info.setProdcutRrn(lot.getProductRrn());

                infos.add(info);
            }

            // }
        } else {
            DcolStepInfo info = new DcolStepInfo();
            info.setLotRrn(lot.getLotRrn());
            info.setMetrologicalEqptRrn(lot.getEqptRrn());
            info.setMetrologicalOperRrn(lot.getOperationRrn());
            info.setMetrologicalOperVersion(new Long(lot.getOperationVersion().intValue()));

            info.setMetrologicalRunRrn(lot.getJobRrn());
            info.setMetrologicalStepSequence(lot.getStepSequence());
            info.setMetrologicalStep(lot.getProcessStepIdVersion());
            info.setMetrologicalStepVersion(lot.getProcessStepVersion());

            info.setProcessRrn(lot.getProcessRrn());
            info.setProcessVersion(lot.getProcessVersion());
            info.setProdcutRrn(lot.getProductRrn());

            infos.add(info);
        }

        return infos;
    }

    private DataCollection buildDataCollection(String userID, ParameterSetVersion parameterSetVersion) {
        DataCollection dataCollection = new DataCollection();

        Parameter parameter = (Parameter) parameterSetVersion.getParameters().iterator().next();

        dataCollection.setParameterRrn(new Long(parameter.getInstanceRrn()));

        dataCollection.setTransPerformedby(userID);

        dataCollection.setTransId(Constants.CREATE_KEY);

        dataCollection.setParameterSetRrn(new Long(parameterSetVersion.getInstanceRrn()));

        dataCollection.setParameterSetVersion(new Integer(parameterSetVersion.getInstanceVersion()));

        dataCollection.setTargetValue(parameterSetVersion.getTargetValue());

        dataCollection.setUpperSpecificationLimit(parameterSetVersion.getUpperSpecificationLimit());

        dataCollection.setLowerSpecificationLimit(parameterSetVersion.getLowerSpecificationLimit());

        dataCollection.setNumberOfSamples(
                new Long(parameter.getSelectedUnitIds() == null ? 0 : parameter.getSelectedUnitIds().length));

        return dataCollection;
    }

    private Collection buildSampleList(Lot lot, ParameterSetVersion parameterSetVersion,
                                       HttpServletRequest request) throws Exception {
        Job job = (Job) request.getAttribute("job");
        Collection sampleList = new ArrayList();

        Parameter parameter = (Parameter) parameterSetVersion.getParameters().iterator().next();
        String collectionLevel = parameterSetVersion.getCollectionLevel();
        String unitRrn;
        String parameterName;

        parameter.setSelectedUnitIds(
                parameter.getSelectedUnitIds() == null ? new String[]{} : parameter.getSelectedUnitIds());
        if (CollectionLevel.UNIT.toString().equals(collectionLevel)) {
            String dcolFlag =
                    request.getAttribute("dcolFlag") != null ? (String) request.getAttribute("dcolFlag") : null;
            //            List<Unit> units = getUnitListByDcolFlag(lot, dcolFlag);
            //            for (Unit unit : units) {
            //                unitRrn = StringUtils.toString(unit.getUnitRrn());
            //                parameterName = buildRequestParameterNameForBase(parameter.getInstanceId(),
            //                lot.getLotId(),
            //                                                                 unit.getUnitId());
            //                buildSampleList(request, parameter, sampleList, unitRrn, parameterName);
            //        }
        } else {
            unitRrn = CollectionLevel.LOT.toString().equals(collectionLevel) ? String.valueOf(
                    lot.getLotRrn()) : String.valueOf(job.getRunRrn());
            parameterName = parameter.getInstanceId() + "|" + lot.getLotId();

            buildSampleList(request, parameter, sampleList, unitRrn, parameterName);
        }

        return sampleList;
    }

    private void buildSampleList(HttpServletRequest request, Parameter parameter, Collection sampleList, String unitRrn,
                                 String parameterName) throws Exception {
        String dataType = parameter.getDataType();
        if (EDCConst.ParameterDataType.VARIABLE.toString().equals(dataType)) {
            buildSampleListForVariable(request, parameter, sampleList, unitRrn, parameterName);
        } else if (EDCConst.ParameterDataType.ATTRIBUTE.toString().equals(dataType)) {
            //            buildSampleListForAttribute(request, parameter, sampleList,
            //            unitRrn unitRrn, parameterName);
        }
    }

    private void buildSampleListForVariable(HttpServletRequest request, Parameter parameter, Collection sampleList,
                                            String unitRrn, String parameterName) throws Exception {

        for (int i = 1; i <= parameter.getSelectedUnitIds().length; i++) {

            String sampleName = parameterName + "|sample|" + (i - 1);

            Collection readingList = new ArrayList();
            String readingName;
            int reSeq = 0;
            for (Iterator iterator2 = parameter.getReadingPrompts().iterator(); iterator2.hasNext(); ) {
                Prompt readingPrompt = (Prompt) iterator2.next();

                readingName = sampleName + "|reading|" + readingPrompt.getPromptId();

                String readingId = edcService.getReadingId(request.getParameter("readingId" + readingName));
                String readingValue = request.getParameter(readingName);
                if (readingValue == null || readingValue.trim().length() < 1) {
                    continue;
                }

                Reading reading = buildReading(i, ++reSeq, readingId, readingValue);

                readingList.add(reading);
            }

            if (!readingList.isEmpty()) {
                String sampleId = request.getParameter(sampleName);
                sampleId = StringUtils.isNotEmpty(sampleId) ? sampleId : "LOT_LEVEL";

                String recipeId = request.getParameter(sampleName + "recipes");

                Sample sample = buildSample(i, sampleId, null, recipeId, unitRrn, readingList);

                sampleList.add(sample);
            }
        }
    }

    private Sample buildSample(Integer seq, String sampleId, String sampleValue, String recipeId, String unitRrn,
                               Collection readingList) throws Exception {
        Sample sample = new Sample();

        sample.setSampleSequence(seq);
        sample.setRecipeId(recipeId);
        this.SetObjPropertyVlaue(sample, sampleId, "sampleId");
        if (StringUtils.isNotEmpty(sampleValue) && NumberUtils.isNumber(sampleValue)) {
            this.SetObjPropertyVlaue(sample, sampleValue, "sampleValue");
        }
        this.SetObjPropertyVlaue(sample, unitRrn, "unitRrn");
        sample.setReadings(readingList);

        return sample;
    }

    private Reading buildReading(Integer sampleSeq, Integer readingSeq, String readingId,
                                 String readingValue) throws Exception {
        Reading reading = new Reading();

        reading.setSampleSequence(sampleSeq);
        reading.setReadingSequence(readingSeq);
        reading.setReadingId(readingId);
        this.SetObjPropertyVlaue(reading, readingValue, "dataValue");

        SimpleDateFormat formatter = new SimpleDateFormat(DateUtils.DATE_FORMAT);
        Date time = new Date(System.currentTimeMillis());
        reading.setCollectionTimestamp(formatter.format(time));

        return reading;
    }

    private void SetObjPropertyVlaue(Object bean, String value, String propertyName) throws Exception {

        Class propertyType = PropertyUtils.getPropertyType(bean, propertyName);
        Constructor ctor = propertyType.getConstructor(new Class[]{String.class});

        Object obj = ctor.newInstance(new Object[]{value});
        PropertyUtils.setSimpleProperty(bean, propertyName, obj);
    }

    private void validateSample(Lot lot, ParameterSetVersion parameterSetVersion,
                                HttpServletRequest request) throws Exception {
        Parameter parameter = (Parameter) parameterSetVersion.getParameters().iterator().next();
        if (EDCConst.ParameterDataType.VARIABLE.toString().equals(parameter.getDataType())) {
            this.validateSample4Variable(lot, parameterSetVersion, request);
        } else if (EDCConst.ParameterDataType.ATTRIBUTE.toString().equals(parameter.getDataType())) {
            //            this.validateSample4Attribute(lot, parameterSetVersion, request);
        }
    }

    private void validateSample4Variable(Lot lot, ParameterSetVersion parameterSetVersion, HttpServletRequest request) {
        if (!StringUtils.equals(CollectionLevel.UNIT.toString(), parameterSetVersion.getCollectionLevel())) {
            String collectionLevel = parameterSetVersion.getCollectionLevel();

            Parameter parameter = (Parameter) parameterSetVersion.getParameters().iterator().next();
            String[] selectUnitIs = parameter.getSelectedUnitIds();

            Collection samplePrompts = parameter.getSamplePrompts();
            Collection readingPrompts = parameter.getReadingPrompts();
            if (readingPrompts == null) {
                readingPrompts = new ArrayList();
                Iterator rit = readingPrompts.iterator();

                if (samplePrompts == null) {
                    samplePrompts = new ArrayList();
                }
                Iterator it = samplePrompts.iterator();

                if (selectUnitIs != null) {
                    for (int i = 0; i < selectUnitIs.length; i++) {

                        while (selectUnitIs != null && selectUnitIs.length > 0 && rit.hasNext()) {
                            String txtName = parameter.getInstanceId() + "|" + lot.getLotId() + "|sample|" + i;

                            Prompt readingPrompt = (Prompt) rit.next();
                            String readingName =
                                    parameter.getInstanceId() + "|" + lot.getLotId() + "|sample|" + i + "|reading|" +
                                            readingPrompt.getPromptId();

                            if (parameterSetVersion != null && parameterSetVersion.getOptionalFlag() != null &&
                                    !parameterSetVersion.getOptionalFlag().equals("1")) {
                                Assert.isFalse(request.getParameter(readingName) == null ||
                                                       request.getParameter(readingName).trim().equals(""),
                                               Errors.create().key(MessageIdList.ERROR_EDC_CONTEXTVALUE_NOT_FOUND)
                                                     .content("No collection parameters" + " {}!")
                                                     .args(parameter.getInstanceId()).build());
                            }
                        }
                    }
                }

            }

        }
    }

    private boolean existEdc(HttpServletRequest request) {
        List<Map> lots = (List) request.getAttribute(SessionNames.COLLECTION_KEY);
        Map parametersMap = (Map) request.getAttribute(SessionNames.PARAMETERSINFO_KEY);
        String equipmentId = (String) request.getParameter("eqptId");
        String actionPoint = MapUtils.getString(parametersMap, "actionPoint");
        Equipment equipment = new Equipment(equipmentId,
                                            getNamedSpace(ObjectList.ENTITY_KEY, LocalContext.getFacilityRrn()),
                                            ObjectList.ENTITY_KEY);
        for (Map lotMap : lots) {
            Lot lot = lotQueryService.getLot(MapUtils.getLong(lotMap, "lotRrn"));
            EdcLotContextValue contextValue = ctxExecService.getEdcLotContextValue(lot, equipment, actionPoint);
            if (contextValue != null && contextValue.getParameterSetRrn() != null &&
                    contextValue.getParameterSetRrn() > 0) {
                return true;
            }
        }
        return false;
    }

    private boolean dataHasBeenCollected(HttpServletRequest request) {
        List<Map> lots = (List) request.getAttribute(SessionNames.COLLECTION_KEY);

        if (CollectionUtils.isNotEmpty(lots)) {
            for (Map lotMap : lots) {
                Lot lot = lotQueryService.getLot(MapUtils.getLong(lotMap, "lotRrn"));
                try {
                    wipQueryService.checkActiveInlineOcapId(lot.getLotRrn());
                } catch (Exception e) {
                    return false;
                }
                LotStepHistory stepHistory = lotQueryService.getLotStepHistory(lot.getLotRrn(), lot.getStepSequence());
                Long dcolRrn = stepHistory.getMoveOutDcolRrn();
                if (dcolRrn != null && dcolRrn > 0) {
                    SpcResult flag = lotQueryService.getSpcJobResultInfo(lot.getLotRrn(), lot.getStepSequence(),
                                                                         dcolRrn);
                    if (flag != null) {
                        //已经收过值的批次,直接跳过收值Task
                        return true;
                    }
                }
            }
        }
        return false;
    }

    private void initCache(DataCollectionInfoForm theform, HttpServletRequest request) throws Exception {
        List<Map> lots = (List) request.getAttribute(SessionNames.COLLECTION_KEY);
        if (lots == null) {
            lots = (List<Map>) WebUtils.getCacheString2Obj(theform.getCacheLots());
            request.setAttribute(SessionNames.COLLECTION_KEY, lots);
        }

        Map parametersMap = (Map) request.getAttribute(SessionNames.PARAMETERSINFO_KEY);

        if (parametersMap == null) {
            parametersMap = (Map) WebUtils.getCacheString2Obj(theform.getCacheParametersInfo());
            request.setAttribute(SessionNames.PARAMETERSINFO_KEY, parametersMap);
        }

        String dcolFlag = (String) request.getAttribute("dcolFlag");
        if (StringUtils.isEmpty(dcolFlag)) {
            dcolFlag = theform.getCacheDcolFlag();
            request.setAttribute("dcolFlag", dcolFlag);
        }

        Job job = (Job) request.getAttribute(SessionNames.JOB_KEY);
        if (job == null) {
            job = (Job) WebUtils.getCacheString2Obj(theform.getCacheJob());
            request.setAttribute(SessionNames.JOB_KEY, job);
        }

        Assert.isFalse(job != null && wipQueryService.getJob(job.getJobRrn()) == null,
                       Errors.create().key(MessageIdList.JOB_MISSING).content(
                               "Job does " + "not " + "exist! " + "Please " + "close " + "the " + "current" + " tab " +
                                       "page " + "and " + "recreate " + "it!").build());

    }

    private List<EdcRuleCheckResult> recordEdcRuleCheckRuleInfo(String userId, Lot lot,
                                                                Map<Long, List<ParameterSetVersion>> unavailableParameterSetVersion) throws Exception {
        EdcRuleCheckResult edcRuleCheckResult;
        ParameterSetVersion parameterSetVersion;
        Parameter parameter;
        long resultSequence = 0;

        List<EdcRuleCheckResult> edcRuleCheckResults = new ArrayList<EdcRuleCheckResult>();

        List<ParameterSetVersion> unavailable = unavailableParameterSetVersion.get(lot.getLotRrn());
        for (Iterator iterator = unavailable.iterator(); iterator.hasNext(); ) {
            parameterSetVersion = (ParameterSetVersion) iterator.next();
            parameter = (Parameter) parameterSetVersion.getParameters().iterator().next();

            edcRuleCheckResult = new EdcRuleCheckResult();
            edcRuleCheckResult.setResultSequence(++resultSequence);
            edcRuleCheckResult.setLotRrn(lot.getLotRrn());
            edcRuleCheckResult.setProductRrn(lot.getProductRrn());
            edcRuleCheckResult.setProcessRrn(lot.getProcessRrn());
            edcRuleCheckResult.setRouteRrn(
                    NumberUtils.toLong(getRouteInfoFromProcessStepVersion(lot.getProcessStepVersion())));
            edcRuleCheckResult.setOperationRrn(lot.getOperationRrn());
            edcRuleCheckResult.setStepSequence(lot.getStepSequence());
            edcRuleCheckResult.setPerformedBy(userId);
            edcRuleCheckResult.setCollectionLevel(parameterSetVersion.getCollectionLevel());

            StringBuilder reasonCode = new StringBuilder();
            reasonCode.append("The EDC parameter selection rules of MES are not satisfied:");
            reasonCode.append(getParameterSetVersionShowInfo(parameterSetVersion, parameter));
            edcRuleCheckResult.setReasonCode(reasonCode.toString());

            if (LotStatus.HOLD.equals(parameterSetVersion.getRuleType())) {
                edcRuleCheckResult.setIsHold("true");
            } else {
                edcRuleCheckResult.setIsHold("false");
            }
            edcRuleCheckResult.setErrorCode("0000");
            edcRuleCheckResult.setErrorMessage("OK: Success");
            edcRuleCheckResult.setHoldType("BYLOT");
            edcRuleCheckResult.setEdcType("FLOW");
            edcRuleCheckResult.setAlarmId(null);

            edcRuleCheckResults.add(edcRuleCheckResult);
            edcService.insertEdcRuleCheckResult(edcRuleCheckResult);
        }

        return edcRuleCheckResults;
    }

    private ActionForward cancelToLotInfo(ActionMapping mapping, ActionForm form, HttpServletRequest request,
                                          HttpServletResponse response) throws Exception {
        List<Map> lots = (List) request.getAttribute(SessionNames.COLLECTION_KEY);
        String lotId = "";
        if (lots != null && (lots.size() > 0)) {
            for (Map lotMap : lots) {
                lotId = MapUtils.getString(lotMap, "lotId");
            }
        }
        request.getRequestDispatcher(mapping.findForward("jobmanagement4lot").getPath() + "&lotId=" + lotId)
               .forward(request, response);
        return null;
    }

    protected String getRouteInfoFromProcessStepVersion(String processStepVersion) {
        String temp = processStepVersion;
        String route = "";

        if (temp != null) {
            int i = 0;
            int j = 0;
            i = temp.indexOf("|");

            // find first '|'
            if (i != -1) {
                j = temp.indexOf("|", i + 1);
                // find se '|'
                // string is aaa|bbb|cccc
                if (j > 0) {
                    route = temp.substring(i + 1, j);
                } else if (i > 0) { // aaa|bbb
                    route = temp.substring(0, i);
                }
            }
        }
        route = route.replace(',', '.');
        route = route.substring(0, route.indexOf("."));
        return route;
    }

}