LbrdLotAction.java

/*
 *        @ Copyright 2001 FA Software;
 *        All right reserved. No part of this program may be reproduced or
 *        transmitted in any form or by any means, electronic or
 *        mechanical, including photocopying, recording, or by any
 *        information storage or retrieval system without written
 *        permission from FA Software, except for inclusion of brief
 *        quotations in a review.
 */
package com.mycim.webapp.actions.operation.lbrd;

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.MiscUtils;
import com.mycim.framework.utils.beans.PropertyUtils;
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.framework.utils.lang.math.NumberUtils;
import com.mycim.valueobject.MessageIdList;
import com.mycim.valueobject.ObjectList;
import com.mycim.valueobject.consts.*;
import com.mycim.valueobject.ems.Carrier;
import com.mycim.valueobject.prp.*;
import com.mycim.valueobject.security.User;
import com.mycim.valueobject.sorter.SortJobCacheBean;
import com.mycim.valueobject.wip.*;
import com.mycim.webapp.Constants;
import com.mycim.webapp.WebUtils;
import com.mycim.webapp.actions.WipSetupAction;
import com.mycim.webapp.forms.LbrdLotInfoForm;
import com.mycim.webapp.forms.lot.LotInfoForm;
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.lang.Override;
import java.util.*;

/**
 * LbrdLotAction
 *
 * @author pinyan.song
 * @version 6.0.0
 * @date 2019-10-12 15:01
 **/
public class LbrdLotAction extends WipSetupAction {

    @Override
    public ActionForward init(ActionMapping mapping, ActionForm form, HttpServletRequest request,
                              HttpServletResponse response) throws Exception {
        Long facilityRrn = LocalContext.getFacilityRrn();
        LbrdLotInfoForm theform = (LbrdLotInfoForm) form;
        Map parameters = (Map) request.getAttribute(SessionNames.PARAMETERSINFO_KEY);
        if (parameters == null) {
            parameters = (HashMap) WebUtils.getCacheString2Obj(theform.getCacheParametersInfo());
            request.setAttribute(SessionNames.PARAMETERSINFO_KEY, parameters);
        }

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

        List lots = (List) request.getAttribute(SessionNames.COLLECTION_KEY);
        if (lots == null) {
            lots = (List) WebUtils.getCacheString2Obj(theform.getCacheCollection());
            request.setAttribute(SessionNames.COLLECTION_KEY, lots);
            request.setAttribute("currentlots", lots);
        }

        SortJobCacheBean sjcb = (SortJobCacheBean) request.getAttribute(SessionNames.SORTER_JOB);
        if (sjcb == null){
            sjcb = (SortJobCacheBean) WebUtils.getCacheString2Obj(theform.getCacheSorterJob());
            request.setAttribute(SessionNames.SORTER_JOB, sjcb);
        }

        String automoveout = request.getParameter("automoveout");
        request.setAttribute("automoveout", automoveout);

        request.setAttribute("moveOutQty", request.getAttribute("moveOutQty"));

        request.setAttribute("moveOutQty2", request.getAttribute("moveOutQty2"));

        Assert.isFalse(job == null || parameters == null || lots == null,
                       Errors.create().content("Parameters are not enough!").build());
        LotInfoForm[] lotInfoForms = new LotInfoForm[lots.size()];
        int i = 0;
        Lot[] _lots = new Lot[lots.size()];
        Collection[] parametergroups = new Collection[lots.size()];
        Operation operation = new Operation();
        boolean bondFlag = false;
        String sourceCarrierType = StringUtils.EMPTY;
        String sourceCarrierCategory = StringUtils.EMPTY;
        for (Object o : lots) {
            HashMap _lot = (HashMap) o;
            LotInfoForm lotInfoForm = new LotInfoForm();
            Lot lot = new Lot();
            lot.setLotRrn(Long.parseLong((String) _lot.get("lotRrn")));

            lot = lotQueryService.getLot(lot.getLotRrn());

            Assert.isFalse(lot == null,
                           Errors.create().key(MessageIdList.SYSTEM_INSTANCE_NOT_FOUND).content("{} 没有找到对象!").args(lot)
                                 .build());

            String result = getObjectValue(lot.getProductRrn(), "FLD_BONDING");
            if (StringUtils.equals(result, Unit.BONDED_TYPE_KEY)) {
                result = "D";
            } else if (StringUtils.equals(result, Unit.BY_BONDED_TYPE_KEY)) {
                result = "H";
            } else {
                result = "";
            }
            lot.setLotTypeBonded(result);

            request.setAttribute("lot" + i, lot);
            _lots[i] = lot;

            PropertyUtils.copyProperties(lotInfoForm, lot);
            if (isBondedLot(lots, lot)) {
                lotInfoForm.setIsSapphire("yes");
                bondFlag = true;

            }else if (lots.size() > 1) {
                String carrierId = lotInfoForm.getCarrierId();
                Carrier carrier = carrierService.getCarrier(LocalContext.getFacilityRrn(), carrierId);
                sourceCarrierType = carrier.getObjectSubtype();
                sourceCarrierCategory = carrier.getFlagType();
            }

            if (bondFlag) {
                request.setAttribute("sourceCarrierType", sourceCarrierType);
                request.setAttribute("sourceCarrierCategory", sourceCarrierCategory);
            }

            if (StringUtils.isNotBlank(lotInfoForm.getPriority() + "")) {
                lotInfoForm.setPriorityText(wipQueryService.getHotflagSplicingPriority(
                        NumberUtils.toInt(lotInfoForm.getHotFlag()), lotInfoForm.getPriority(), facilityRrn));
            }

            //get lot flow seq
            Map<String, Object> paramMap = new HashMap<String, Object>();
            paramMap.put("facilityRrn", facilityRrn);
            paramMap.put("productRrn", _lot.get("productRrn"));
            paramMap.put("processRrn", _lot.get("processRrn"));
            String _routeInfo = (String) _lot.get("routeRrn");
            if (_routeInfo != null && _routeInfo.contains("|")) {
                _routeInfo = _routeInfo.substring(0, _routeInfo.indexOf(","));
            }
            paramMap.put("routeRrn", _routeInfo);
            paramMap.put("operationRrn", _lot.get("operationRrn"));
            paramMap.put("processVersion", _lot.get("processVersion"));
            String flowSeq = ctxExecService.getFlowSeqByProcessInfo(paramMap);
            if (StringUtils.isNotBlank(flowSeq)) {
                lotInfoForm.setFlowSeq(flowSeq);
            }

            if (StringUtils.isNotBlank(lotInfoForm.getOperationId())) {
                Operation lotOperation = prpService.getOperation(lotInfoForm.getOperationId(), facilityRrn);
                String workArea = "";
                if (lotOperation != null) {
                    workArea = lotQueryService.getWorkArea(lot);
                }
                lotInfoForm.setWorkArea(workArea);
            }


            lotInfoForms[i] = lotInfoForm;

            // get default lbrd reference table from operation
            operation.setInstanceId(this.getInstanceId(MiscUtils.parseSQL(lot.getOperationRrn())));
            operation.setNamedSpace(getNamedSpace(ObjectList.OPERATION_KEY, facilityRrn));
            operation.setObject(ObjectList.OPERATION_KEY);

            operation = prpService.getOperation(operation.getInstanceId(), operation.getNamedSpace());


            request.setAttribute("lossCode" + i, sysService.getRefFileValues(operation.getLossTableId(), facilityRrn));
            request.setAttribute("bonusCode" + i,
                                 sysService.getRefFileValues(operation.getBonusTableId(), facilityRrn));
            request.setAttribute("reworkCode" + i,
                                 sysService.getRefFileValues(operation.getReworkTableId(), facilityRrn));
            request.setAttribute("defectCode" + i,
                                 sysService.getRefFileValues(operation.getDefectTableId(), facilityRrn));

            Collection parametergroup = new ArrayList();

            parametergroup = this.getParameterForLot(lot, facilityRrn);
            if (parametergroup != null && parametergroup.size() > 0) {
                Double parameterValue = lotQueryService.getParameterValueForLot(lot);
                request.setAttribute("parameterValue", parameterValue);
            }
            request.setAttribute(SessionNames.PARAMETER_GROUP_FLAG_KEY + i, parametergroup);
            parametergroups[i] = parametergroup;

            i++;
        }
        theform.setDeptExt(null);
        theform.setCacheLots(WebUtils.getCacheObj2String(_lots));
        theform.setCacheParametergroup(WebUtils.getCacheObj2String(parametergroups));
        theform.setCacheJob(WebUtils.getCacheObj2String(job));
        theform.setLotsInfo(lotInfoForms);
        request.setAttribute("lotNum", lotInfoForms.length);

        // add by steven for fmi
        Map operationExtMap = new HashMap();
        operationExtMap = prpService.getOperationExtInfo(job.getOperationRrn());

        ContextValue contextValue = null;
        Collection routeRework = new ArrayList();

        long contextRrn = baseService
                .getNamedObjectRrn(ContextNames.REWORK_ROUTE_CONTEXT, getNamedSpace("CONTEXT", facilityRrn), "CONTEXT");
        contextValue = new PilotContextValue(contextRrn);
        for (LotInfoForm lotInfoFormsValue : lotInfoForms) {
            contextValue.setContextKey2(lotInfoFormsValue.getProcessId());
            contextValue.setContextKey3(lotInfoFormsValue.getRouteId());
            contextValue.setContextKey4(lotInfoFormsValue.getOperationId());
            contextValue.setContextKey8(lotInfoFormsValue.getProcessVersion() + "");
            routeRework = ctxService.simulateFilterContextValues(contextValue, facilityRrn);
            if (routeRework.size() > 0) {
                break;
            }
        }

        if (routeRework.size() > 0) {
            request.setAttribute("reworkFlag", "on");

        }

        // end

        theform.setTrackUnitFlag(getTrackUnitFlag(job));

        theform.setMultipathFlag(operation.getMultipathFlag());

        for (Object o : lots) {
            HashMap _lot = (HashMap) o;
            LotInfoForm lotInfoForm = new LotInfoForm();
            Lot lot = new Lot();
            lot.setLotRrn(Long.parseLong((String) _lot.get("lotRrn")));

            lot = lotQueryService.getLot(lot.getLotRrn());
            if (StringUtils.equals(theform.getMultipathFlag(), "on")) {
                Collection lotNext = wipWorkflowQueryService.getNextMultiStepInfoByDao(lot.getExecutionRrn(), 1);

                if (lotNext != null && !lotNext.isEmpty()) {
                    Map next = (Map) lotNext.iterator().next();
                    String routeRrn = MapUtils.getString(next, "Route");
                    Collection wfl = new ArrayList();
                    if (StringUtils.equals(routeRrn, lot.getRouteRrn() + "")) {
                        wfl = getWflPathoperation(lot);
                        theform.setIsRouteOrStepWflPath("step");
                    } else {
                        wfl = getWflPathRoute(lot);
                        theform.setIsRouteOrStepWflPath("route");
                    }
                    request.setAttribute("wflPaths", wfl);
                }
            }
        }

        this.setCache4WFL(request, theform);
        return mapping.findForward("lotinfo");
    }

    @Override
    public ActionForward cancel(ActionMapping mapping, ActionForm form, HttpServletRequest request,
                                HttpServletResponse response) throws Exception {
        if (StringUtils.isNotBlank(request.getParameter("runcardLotId"))) {
            String runcardLotId = request.getParameter("runcardLotId");
            request.getRequestDispatcher("splitRunCardLotInfo.do?action=showLot&lotId=" + runcardLotId)
                   .forward(request, response);
            return null;
        }
        return mapping.findForward("cancel");
    }

    public boolean checkReworkInfo(Map params) {
        return true;
    }

    public ActionForward modify(ActionMapping mapping, ActionForm form, HttpServletRequest request,
                                HttpServletResponse response) throws Exception {
        Long facilityRrn = LocalContext.getFacilityRrn();

        LbrdLotInfoForm theform = (LbrdLotInfoForm) form;

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

        SortJobCacheBean sjcb = (SortJobCacheBean) request.getAttribute(SessionNames.SORTER_JOB);
        if (sjcb == null){
            sjcb = (SortJobCacheBean) WebUtils.getCacheString2Obj(theform.getCacheSorterJob());
            request.setAttribute(SessionNames.SORTER_JOB, sjcb);
        }

        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());

        List lots = (List) request.getAttribute(SessionNames.COLLECTION_KEY);
        if (lots == null) {
            lots = (List) WebUtils.getCacheString2Obj(theform.getCacheCollection());
            request.setAttribute(SessionNames.COLLECTION_KEY, lots);
            request.setAttribute("currentlots", lots);
        }

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

        validateTask(parameters, "moveout");

        String tempMoveOutQty = request.getParameter("moveOutQty");
        Assert.isFalse(StringUtils.isBlankCheckNull(tempMoveOutQty),
                       Errors.create().content("MoveOut Qty An error occurred!").build());

        String[] moveOutQty = StringUtils.split(tempMoveOutQty, ",");
        Assert.isFalse(lots == null || parameters == null || moveOutQty == null,
                       Errors.create().content("Parameters are not " + "enough!").build());

        List<Map> transInfos = new ArrayList();
        double lossQty1 = 0.0;
        double lossQty2 = 0.0;
        double bonusQty1 = 0.0;
        double bonusQty2 = 0.0;
        double internalreworkQty1 = 0.0;
        double internalreworkQty2 = 0.0;
        double defectQty1 = 0.0;
        double defectQty2 = 0.0;
        double transQty = 0.0;
        String[] type = null;
        String[] units = null;
        String[] reasonCodes = null;
        String[] reasons = null;
        String[] responsibilitys = null;
        String[] transQty1s = null;
        String[] transQty2s = null;
        List<Map> transReasons = null;

        Lot[] _lots = (Lot[]) WebUtils.getCacheString2Obj(theform.getCacheLots());
        Collection[] parametergroups = (Collection[]) WebUtils.getCacheString2Obj(theform.getCacheParametergroup());

        //check lot lock
        List<Lot> lockLots = new ArrayList<Lot>();
        Collections.addAll(lockLots, _lots);
        //        checkAndCreateLotsTransLock(LocalContext.getUserRrn(), TransactionNames.LOCK_MOVEOUT,
        //        lockLots,
        //                                    "moveOut of LbrdLotAction by:" + LocalContext.getUserId());

        Lot lot = null;
        int j = 0;
        for (Object o : lots) {
            //lot = (Lot) session.getAttribute("lot" + j);
            lot = _lots[j];

            Assert.isFalse(lot == null, Errors.create().content("Parameters are not enough!").build());
            if (StringUtils.isNotEmpty(theform.getIsRouteOrStepWflPath())) {
                wflContext(lot, theform.getWflPath(), theform.getIsRouteOrStepWflPath());
            } else {
                Collection wflPath = getWflPathoperation(lot);
                for (Iterator iterator = wflPath.iterator(); iterator.hasNext(); ) {
                    Map path = (Map) iterator.next();
                    deleteWflContext(lot, MapUtils.getString(path, "pathId"));
                }
            }

            transReasons = new ArrayList();

            lossQty1 = 0.0;
            lossQty2 = 0.0;
            bonusQty1 = 0.0;
            bonusQty2 = 0.0;
            internalreworkQty1 = 0.0;
            internalreworkQty2 = 0.0;
            defectQty1 = 0.0;
            defectQty2 = 0.0;
            transQty = 0.0;

            type = request.getParameterValues("type" + j);
            units = request.getParameterValues("unitList" + j);

            reasonCodes = request.getParameterValues("reasonCode" + j);
            reasons = request.getParameterValues("reason" + j);
            responsibilitys = request.getParameterValues("responsibility" + j);
            transQty1s = request.getParameterValues("transQty1" + j);
            transQty2s = request.getParameterValues("transQty2" + j);

            // for updating loss/bonus qty if units l/b in multipul reason
            Collection lossUnits = new ArrayList();
            Collection bonusUnits = new ArrayList();

            if (transQty1s == null) {
                transQty1s = new String[0];
            }

            // avoid null pointer exception
            if (units == null) {
                units = new String[transQty1s.length];
            }

            for (int i = 0; i < transQty1s.length; i++) {
                if ((transQty1s[i] != null) && !transQty1s[i].equals("")) {

                    if ((type[i] != null) && type[i].equals(Constants.LOSS_KEY)) {
                        lossQty1 += Double.parseDouble(transQty1s[i]);
                        lossQty2 += Double.parseDouble((transQty2s == null || transQty2s[i] == null ||
                                transQty2s[i].equals("")) ? "0.0" : transQty2s[i]);
                        lossUnits.addAll(parseStringToCollection(units[i]));
                    }

                    if ((type[i] != null) && type[i].equals(Constants.BONUS_KEY)) {
                        bonusQty1 += Double.parseDouble(transQty1s[i]);
                        bonusQty2 += Double.parseDouble((transQty2s == null || transQty2s[i] == null ||
                                transQty2s[i].equals("")) ? "0.0" : transQty2s[i]);
                        bonusUnits.addAll(parseStringToCollection(units[i]));
                    }

                    if ((type[i] != null) && type[i].equals(Constants.INTERNALREWORK_KEY)) {
                        internalreworkQty1 += Double.parseDouble(transQty1s[i]);
                        internalreworkQty2 += Double.parseDouble((transQty2s == null || transQty2s[i] == null ||
                                transQty2s[i].equals("")) ? "0.0" : transQty2s[i]);
                    }

                    if ((type[i] != null) && type[i].equals(Constants.DEFECT_KEY)) {
                        defectQty1 += Double.parseDouble(transQty1s[i]);
                        defectQty2 += Double.parseDouble((transQty2s == null || transQty2s[i] == null ||
                                transQty2s[i].equals("")) ? "0.0" : transQty2s[i]);
                    }

                    transQty += Double.parseDouble(transQty1s[i]);

                    Map transReason = new HashMap();
                    transReason.put("reasonCode", reasonCodes[i]);
                    transReason.put("reason", reasons[i]);
                    transReason.put("type", type[i]);

                    // transReason.put("reasonCategory",theform.getTransId().toUpperCase());
                    transReason.put("transQty1", new Double(transQty1s[i]));
                    transReason.put("transQty2", new Double((transQty2s == null || transQty2s[i] == null ||
                            transQty2s[i].equals("")) ? "0.0" : transQty2s[i]));
                    transReason.put("responsibility", responsibilitys[i]);

                    if ((units != null) && (units[i] != null)) {
                        transReason.put("unitList", units[i]);
                    }

                    transReasons.add(transReason);
                }
            }

            // update loss/bonus/defect/rework qty if the same unit with
            // different reason
            int duplicatLossQty = 0;
            int duplicatBonusQty = 0;
            String unitRrn = null;
            Collection uniqueBonusUnits = bonusUnits;

            for (Iterator _it = lossUnits.iterator(); _it.hasNext(); ) {
                unitRrn = (String) _it.next();
                _it.remove();

                if (lossUnits.contains(unitRrn)) {
                    duplicatLossQty++;
                }
            }


            for (Iterator _it1 = bonusUnits.iterator(); _it1.hasNext(); ) {
                unitRrn = (String) _it1.next();
                _it1.remove();

                if (bonusUnits.contains(unitRrn)) {
                    duplicatBonusQty++;
                }
            }
            lossQty1 = lossQty1 - duplicatLossQty;
            bonusQty1 = bonusQty1 - duplicatBonusQty;

            // prepare the parameters for transaction
            Map transInfo = new HashMap();
            transInfo.put("lotComments", theform.getLotComments());
            transInfo.put("lot", lot);
            transInfo.put("transPerformedBy", LocalContext.getUserId());
            transInfo.put("transReasons", transReasons);
            transInfo.put("transQty", new Double(transQty));
            transInfo.put("lossQty1", new Double(lossQty1));
            transInfo.put("bonusQty1", new Double(bonusQty1));
            transInfo.put("defectQty1", new Double(defectQty1));
            transInfo.put("internalreworkQty1", new Double(internalreworkQty1));
            transInfo.put("lossQty2", new Double(lossQty2));
            transInfo.put("bonusQty2", new Double(bonusQty2));
            transInfo.put("defectQty2", new Double(defectQty2));
            transInfo.put("internalreworkQty2", new Double(internalreworkQty2));
            /*
             * if(transQty<=0.0){ request.setAttribute(ErrorDef.MYCIM_ERR_KEY,new
             * ValidateFailureException("No value for lot("+ lot.getLotId()+") is really specified,
             * transaction
             * is not needed!")); return (mapping.findForward("error")); }
             */

            String UOM1 = lot.getUOM1();

            if (lot.getUOM1() == null) {
                UOM1 = this.getUOM1(lot.getOperationRrn());
            }

            if (UOM1 != null && UOM1.trim().equalsIgnoreCase(UOM_WAFER)) {
                Assert.isFalse(getCarrierSlotCount(lot.getCarrierRrn()) <
                                       (MiscUtils.parseSQL(lot.getQty1()) - lossQty1 + bonusQty1),
                               Errors.create().content("More wafters than permitted!").build());
            }
            Assert.isFalse(lot.getQty1().compareTo(lossQty1) < 0,
                           Errors.create().content("Loss Quantity should not be " + "larger than " + "lot quantity.")
                                 .build());

            if (Double.parseDouble(moveOutQty[j]) != (MiscUtils.parseSQL(lot.getQty1()) - lossQty1 + bonusQty1)) {
                throw new SystemIllegalArgumentException(Errors.create().content(
                        "More Or Less wafters in lot ( {} )than " + "permitted!The numbers should" + " be " + "{}!")
                                                               .args(lot.getLotId(),
                                                                     (MiscUtils.parseSQL(lot.getQty1()) -
                                                                             Double.parseDouble(moveOutQty[j])))
                                                               .build());
            }

            List parametergroup = (List) parametergroups[j];
            Map<String, String> parameterList = new HashMap<String, String>();
            String collectionFlag = "";
            if (parametergroup != null && !parametergroup.isEmpty()) {
                int size = parametergroup.size();
                for (int x = 0; x < size; x++) {
                    String[] parameterValue = request.getParameterValues(lot.getLotId() + "parameterValue");
                    if (parameterValue != null) {
                        for (int tem = 0; tem < parameterValue.length; tem++) {
                            if (StringUtils.isNotBlank(parameterValue[tem])) {
                                parameterList.put("parameter", StringUtils.toString(
                                        getInstanceRrn((String) parametergroup.get(tem), LocalContext.getFacilityRrn(),
                                                       ObjectList.PARAMETER_KEY)));

                                parameterList.put("parameterValue", parameterValue[tem]);
                                collectionFlag = "TRUE";
                            }
                        }
                    } else {
                        collectionFlag = "FALSE";
                    }
                }
            } else {
                collectionFlag = "FALSE";
            }
            transInfo.put("collectionFlag", collectionFlag);
            transInfo.put("parameterList", parameterList);

            j++;
            transInfos.add(transInfo);

            // 记录lotComments
            if (StringUtils.isNotEmpty(theform.getLotComments())) {
                lotService.addLotStepHistoryComment(String.valueOf(lot.getLotRrn()),
                                                    String.valueOf(lot.getStepSequence()), theform.getLotComments(), "",
                                                    LocalContext.getUserId(), LocalContext.getFacilityRrn());
            }
        }
        Collection splitLotList = new ArrayList();
        if (StringUtils.equals(WebUtils.getParameter("bonded", request), "true")) {
            // TODO: 2019-10-13 分批
            splitLotList = lotService.lbrdBondedLot(transInfos);
        } else {
            // TODO: 2019-10-14
            lotService.lbrdLot(transInfos);
        }
        if (StringUtils.isNotBlank(request.getParameter("runcardLotId"))) {
            String runcardLotId = request.getParameter("runcardLotId");
            request.setAttribute("runcardLotId", runcardLotId);
        }
        request.setAttribute("splitLotList", splitLotList);
        if (StringUtils.isNotBlank(request.getParameter("bondFlag"))) {
            String targetCarrierId = request.getParameter("targetCarrierId");
            String sourceCarrierId = request.getParameter("sourceCarrierId");
            Assert.isFalse(StringUtils.isBlank(targetCarrierId) || StringUtils.isBlank(sourceCarrierId),
                           Errors.create().key(MessageIdList.BOND_CARRIER_NOT_FOUND).content("targetCarrier is empty").build());
            if (!StringUtils.equals(targetCarrierId, sourceCarrierId)) {
                //还需check carrier是否可用
                Carrier targetCarrier = carrierService.getCarrier(LocalContext.getFacilityRrn(), targetCarrierId);
                Carrier sourceCarrier = carrierService.getCarrier(LocalContext.getFacilityRrn(), sourceCarrierId);

                String targetCarrierCategory = targetCarrier.getFlagType();
                String sourceCarrierCategory = sourceCarrier.getFlagType();

                String targetCarrierType = targetCarrier.getObjectSubtype();
                String sourceCarrierType = sourceCarrier.getObjectSubtype();

                Assert.isFalse(!StringUtils.equalsIgnoreCase(sourceCarrierType, targetCarrierType),
                               Errors.create().key(MessageIdList.BOND_CARRIER_TYPE_MIS_MATCH).
                                       content(" Top carrier and target carrier type mismatch!").build());

                Assert.isFalse(!StringUtils.equalsIgnoreCase(targetCarrierCategory, sourceCarrierCategory),
                               Errors.create().key(MessageIdList.BOND_CARRIER_CATEGORY_MIS_MATCH).
                                       content(" Top carrier and target carrier Category mismatch!").build());

            }
            request.setAttribute("targetCarrierId", targetCarrierId);
        }
        return buildHandleLotInfo(mapping, theform, request, response, parameters, job, lots, splitLotList);

    }

    @Override
    public void setCache4WFL(HttpServletRequest request, ActionForm form) {
        LbrdLotInfoForm theform = (LbrdLotInfoForm) form;
        theform.setCacheJob(WebUtils.getCacheObj2String(request.getAttribute(SessionNames.JOB_KEY)));
        theform.setCacheParametersInfo(
                WebUtils.getCacheObj2String(request.getAttribute(SessionNames.PARAMETERSINFO_KEY)));
        theform.setCacheCollection(WebUtils.getCacheObj2String(request.getAttribute(SessionNames.COLLECTION_KEY)));
        request.setAttribute(SessionNames.RUNCARD_LOT_ID, request.getAttribute(SessionNames.RUNCARD_LOT_ID));
    }

    private String getTrackUnitFlag(Job job) {
        boolean flag = isTrackUnitFlag(job);
        return String.valueOf(BooleanUtils.toInteger(flag));
    }

    private boolean isTrackUnitFlag(Job job) {
        Map map = prpService.getOperationInfo(job.getOperationRrn(), null);
        String flag = (String) map.get("trackUnitFlag");

        return flag.equals(TRUE);
    }

    private void deleteWflContext(Lot lot, String stepLinkId) {
        ContextValue contextValue = new ContextValue();
        contextValue.setContextRrn(
                getInstanceRrn(ContextNames.WFL_LINK_CONTEXT, LocalContext.getFacilityRrn(), ObjectList.CONTEXT_KEY));
        contextValue = buildRouteWflContextForm(contextValue, lot, stepLinkId);
        contextValue.setStatus("ACTIVE");
        ctxService.removeContextValue(contextValue, LocalContext.getFacilityRrn(), LocalContext.getUserRrn());

        contextValue = new ContextValue();
        contextValue.setContextRrn(
                getInstanceRrn(ContextNames.WFL_LINK_CONTEXT, LocalContext.getFacilityRrn(), ObjectList.CONTEXT_KEY));
        contextValue = buildPorcessWflContextForm(contextValue, lot, stepLinkId);
        contextValue.setStatus("ACTIVE");
        ctxService.removeContextValue(contextValue, LocalContext.getFacilityRrn(), LocalContext.getUserRrn());
    }

    private void wflContext(Lot lot, String stepLinkId, String isRouteOrStepWflPath) {
        ContextValue contextValue = new ContextValue();
        contextValue.setContextRrn(
                getInstanceRrn(ContextNames.WFL_LINK_CONTEXT, LocalContext.getFacilityRrn(), ObjectList.CONTEXT_KEY));
        if (StringUtils.equals(isRouteOrStepWflPath, "step")) {
            contextValue = buildRouteWflContextForm(contextValue, lot, stepLinkId);
        } else if (StringUtils.equals(isRouteOrStepWflPath, "route")) {
            contextValue = buildPorcessWflContextForm(contextValue, lot, stepLinkId);
        }
        contextValue.setStatus("ACTIVE");
        ctxService.removeContextValue(contextValue, LocalContext.getFacilityRrn(), LocalContext.getUserRrn());

        ctxService.createContextValueWithActivatedEcn(LocalContext.getFacilityRrn(), LocalContext.getUserRrn(),
                                                      LocalContext.getUserId(), contextValue);
    }

    private ContextValue buildPorcessWflContextForm(ContextValue contextValue, Lot lot, String wflPath) {
        String productId = lot.getProductId();
        String processId = lot.getProcessId();
        String routeId = lot.getRouteId();
        String operationId = lot.getOperationId();
        String lotId = lot.getLotId();
        String lotRrn = lot.getLotRrn() + "";
        String routeSeq = lot.getRouteSeq();
        int processVersion = lot.getProcessVersion();

        if (productId != null && !"".equals(productId)) {
            contextValue.setContextKey1(productId);
        }
        if (processId != null && !"".equals(processId)) {
            contextValue.setContextKey2(processId);
        }
        if (routeId != null && !"".equals(routeId)) {
            contextValue.setContextKey3(routeId);
        }

        if (lotRrn != null && !"".equals(lotRrn)) {
            contextValue.setContextKey5(lotRrn);
        }

        if (processVersion > 0) {
            contextValue.setContextKey14(String.valueOf(processVersion));
        }
        /*
         * if (routeSeq != null && !"".equals(routeSeq)) { theform.setContextKey7(routeSeq); }
         */
        contextValue.setResultValue1(wflPath);
        return contextValue;
    }

    private ContextValue buildRouteWflContextForm(ContextValue contextValue, Lot lot, String wflPath) {
        String productId = lot.getProductId();
        String processId = lot.getProcessId();
        String routeId = lot.getRouteId();
        String operationId = lot.getOperationId();
        String lotId = lot.getLotId();
        String lotRrn = lot.getLotRrn() + "";
        String operationSeq = lot.getOperationSeq();
        String routeSeq = lot.getRouteSeq();
        int processVersion = lot.getProcessVersion();

        if (productId != null && !"".equals(productId)) {
            contextValue.setContextKey1(productId);
        }
        if (processId != null && !"".equals(processId)) {
            contextValue.setContextKey2(processId);
        }
        if (routeId != null && !"".equals(routeId)) {
            contextValue.setContextKey3(routeId);
        }
        if (operationId != null && !"".equals(operationId)) {
            contextValue.setContextKey4(operationId);
        }
        if (lotRrn != null && !"".equals(lotRrn)) {
            contextValue.setContextKey5(lotRrn);
        }
        if (processVersion > 0) {
            contextValue.setContextKey14(String.valueOf(processVersion));
        }
        contextValue.setResultValue1(wflPath);
        return contextValue;
    }

    private ActionForward buildHandleLotInfo(ActionMapping mapping, LbrdLotInfoForm theform, HttpServletRequest request,
                                             HttpServletResponse response, Map parameters, Job job, List lots,
                                             Collection splitLotList) throws Exception {
        String user = LocalContext.getUserId();
        Long facilityRrn = LocalContext.getFacilityRrn();

        request.setAttribute(SessionNames.HANDLE_LOT_INFO_KEY, new ArrayList());

        Collection splitLots = new ArrayList();

        Collection handleLotInfos = new ArrayList();

        Collection allLotListShow = new ArrayList();

        List holdInfos = new ArrayList<>();

        List <String>lotRrns=new ArrayList<>();
        int index = 0;
        for (Object value : lots) {
            Map lotMap = (Map) value;
            Lot currentLot = lotQueryService
                    .getLot(org.apache.commons.collections.MapUtils.getLongValue(lotMap, "lotRrn"));


            Map handleInfo = new HashMap();

            String processFlag = request.getParameter("processFlag_" + index);
            if (StringUtils.equals(WebUtils.getParameter("bonded", request), "true")) {
                processFlag = ProcessSwitchTypeNames.PROCESS_MOVE_NEXT;
            }
            Assert.isFalse(processFlag == null,
                           Errors.create().content("Please choose Lot:{} next operation!").args(currentLot.getLotId())
                                 .build());
            //String qTimeMaxTimeHoldReason = wipCheckService
            // .getLotQueueTimeisOverForMaxTimeAtTrackOutHoldReason(currentLot);

			/*if (StringUtils.equals(processFlag, ProcessSwitchTypeNames.PROCESS_MOVE_NEXT)
			    && StringUtils.isNotEmpty(qTimeMaxTimeHoldReason)) {
			    buildTrackOutHoldInfoForQTime(user, handleInfo, qTimeMaxTimeHoldReason, index);
			    processFlag = ProcessSwitchTypeNames.PROCESS_TRACK_OUT_HOLD;
			} else */
            if (StringUtils.equals(processFlag, ProcessSwitchTypeNames.PROCESS_TRACK_OUT_HOLD)) {
                buildTrackOutHoldInfo(theform, index, handleInfo);
            } else if (StringUtils.equals(processFlag, ProcessSwitchTypeNames.PROCESS_ALL_REWORK)) {
                buildReworkInfo(theform, index, handleInfo, user);
                boolean isReworkFlag = checkLotRework(facilityRrn, currentLot);
                if (!isReworkFlag) {
                    processFlag = ProcessSwitchTypeNames.PROCESS_TRACK_OUT_HOLD;
                    handleInfo.put("holdReasonCode", "REWORK");
                    handleInfo.put("reason", "(TR) Exceed max rework times, hold by system");
                }
            } else if (StringUtils.equals(processFlag, ProcessSwitchTypeNames.PROCESS_LITTLE_REWORK)) {
                buildReworkInfo(theform, index, handleInfo, user);
                boolean isReworkFlag = checkLotRework(facilityRrn, currentLot);
                if (!isReworkFlag) {
                    handleInfo = new HashMap();
                    processFlag = ProcessSwitchTypeNames.PROCESS_TRACK_OUT_HOLD;
                    handleInfo.put("holdReasonCode", "REWORK");
                    handleInfo.put("reason", "(TR) Exceed max rework times, hold by system");
                } else {
                    Map splitLot = new HashMap();
                    splitLot.put("needSplitFlag", "1");
                    splitLot.put("lotId", currentLot.getLotId());
                    splitLot.put("facilityRrn", currentLot.getFacilityRrn());
                    splitLot.put("qty", currentLot.getQty1());
                    splitLot.put("lotRrn", String.valueOf(currentLot.getLotRrn()));
                    splitLot.put("moveOutQty", "0.0");
                    splitLot.put("moveOutQty2", "0.0");
                    splitLot.put("REWORK_TRANS_INFO_FOR_PARTIAL_REWORK", handleInfo);
                    splitLots.add(splitLot);
                }
            } else if (StringUtils.equals(processFlag, ProcessSwitchTypeNames.PROCESS_AUTO_TERMINATE)) {
                processFlag = ProcessSwitchTypeNames.PROCESS_AUTO_TERMINATE;
                handleInfo = buildTerminateInfo(request, index, currentLot);
            }
            Map handleLotInfo = new HashMap();
            handleLotInfo.put("Lot", currentLot);
            handleLotInfo.put("processFlag", processFlag);
            handleLotInfo.put("handleInfo", handleInfo);
            handleLotInfos.add(handleLotInfo);
            index++;
            if (splitLotList.size() > 0) {
                allLotListShow.add(buildProcessLotInfo(currentLot));
            }

            Map<String, Object> holdLot = lotService.buildFutureReassignForTrackOutAutoReassign(currentLot);
            if (holdLot != null) {
                holdInfos.add(holdLot);
                lotRrns.add(StringUtils.toString(currentLot.getLotRrn()));
            }
        }
        // lotService.holdRunningLot(holdInfos,lotRrns);
        if(CollectionUtils.isNotEmpty(holdInfos)){
            lotService.holdRunningLot(holdInfos,lotRrns);
        }

        holdInfos = new ArrayList<>();

        Collection<?> joblots = wipQueryService.getJobList(job.getJobRrn(), ObjectList.JOB_KEY);

        for (Object joblot : joblots) {
            Map<?, ?> lotMap = (Map<?, ?>) joblot;
            Lot lot = lotQueryService.getLot(MapUtils.getLongValue(lotMap, "lotRrn"));

            if (StringUtils.equalsIgnoreCase(lot.getLotStatus(), LotStatus.RUNNINGHOLD)) {
                holdInfos.addAll(lotQueryService.getHoldReasons(lot.getLotRrn()));
                // removeLotLock(LocalContext.getUserRrn(), lot, TransactionNames.LOCK_MOVEOUT,
                //               "The lot runninghold, in LbrdLotAction by: " + user);
            }
        }

        if (!holdInfos.isEmpty()) {
            request.setAttribute("holdInfo", holdInfos);
            request.setAttribute(SessionNames.COLLECTION_KEY, joblots);
            return mapping.findForward("runningHold");
        }

        for (Object o : splitLotList) {
            String lotId = (String) o;
            long lotRrn = lotQueryService.getLotRrn(lotId);
            Lot currentLot = lotQueryService.getLot(lotRrn);
            Map handleLotInfo = new HashMap();
            handleLotInfo.put("Lot", currentLot);
            handleLotInfo.put("processFlag", ProcessSwitchTypeNames.PROCESS_NONE);
            handleLotInfos.add(handleLotInfo);
            allLotListShow.add(buildProcessLotInfo(currentLot));
        }
        //session.setAttribute("allLotListShow", allLotListShow);
        request.setAttribute("allLotListShow", allLotListShow);
        //session.setAttribute(SessionNames.HANDLE_LOT_INFO_KEY, handleLotInfos);
        request.setAttribute(SessionNames.HANDLE_LOT_INFO_KEY, handleLotInfos);
        if (!splitLots.isEmpty()) {
            //session.setAttribute(SessionNames.COLLECTION_KEY, splitLots);
            request.setAttribute(SessionNames.COLLECTION_KEY, splitLots);
            parameters.put(SessionNames.RUNSTEP_FLAG, "0");
            ActionForward workflowPara = mapping.findForward("workflow");
            //session.setAttribute("workflowPara", workflowPara);
            request.setAttribute("workflowPara", workflowPara);
            //session.setAttribute("workflowFlag", "true");
            request.setAttribute("workflowFlag", "true");
            return mapping.findForward("pathrework");
        }
        request.getRequestDispatcher(mapping.getInput()).forward(request, response);
        return null;
    }

    private ContextValue getRewrkContextValue(Long facilityRrn, Lot lot) {
        ReworkRouteContextValue contextValue = new ReworkRouteContextValue();
        contextValue.setContextRrn(getInstanceRrn(contextValue.getContextId(), facilityRrn, ObjectList.CONTEXT_KEY));
        contextValue.setProductRrn(lot.getProductRrn());
        contextValue.setProcessRrn(lot.getProcessRrn());
        contextValue.setRouteRrn(lot.getRouteRrn());
        contextValue.setOperationRrn(lot.getOperationRrn());
        contextValue.setEntityRrn(lot.getEqptRrn());
        contextValue.setLotRrn(lot.getLotRrn());
        contextValue.setProcessVersion(lot.getProcessVersion());

        ContextValue actionCondition = ctxService.simulateContextValue(contextValue);

        Assert.isFalse(actionCondition == null || StringUtils.isBlank(actionCondition.getResultValue1()),
                       Errors.create().content("Rework layer can not find!").build());
        return actionCondition;
    }

    private boolean checkLotRework(Long facilityRrn, Lot lot) {
        ContextValue actionCondition = getRewrkContextValue(facilityRrn, lot);
        String maxReworkTimes = (actionCondition.getResultValue4() == null) ? "0" : actionCondition.getResultValue4();
        String reworkRouteRrn = actionCondition.getResultValue1();
        long reworkedTimes = lotQueryService.getReworkSeq(new Long(lot.getLotRrn()), reworkRouteRrn);
        boolean isReworkFlag = reworkedTimes < Integer.valueOf(maxReworkTimes).longValue();
        return isReworkFlag;
    }

    private Map buildTerminateInfo(HttpServletRequest request, int index, Lot currentLot) throws Exception {

        Map handleInfo = new HashMap();

        String[] reasonCodes = request.getParameterValues("reasonCode");
        String[] hiddenUserRrns = request.getParameterValues("hiddenUserId");
        String[] deptExts = request.getParameterValues("deptExt");
        String[] reasons = request.getParameterValues("reason");

        String hiddenUserRrn = StringUtils.EMPTY;
        String deptExt = StringUtils.EMPTY;
        String reason = StringUtils.EMPTY;
        String reasonCode = StringUtils.EMPTY;

        if (reasonCodes != null && reasonCodes.length >= index) {
            reasonCode = reasonCodes[index];
        }

        if (hiddenUserRrns != null && hiddenUserRrns.length >= index) {
            hiddenUserRrn = hiddenUserRrns[index];
        }
        if (deptExts != null && deptExts.length >= index) {
            deptExt = deptExts[index];
        }

        if (reasons != null && reasons.length >= index) {
            reason = reasons[index];
        }

        Assert.isFalse(StringUtils.isEmpty(reasonCode), Errors.create().content("Dept ID cannot be empty!").build());
        Assert.isFalse(StringUtils.isEmpty(hiddenUserRrn),
                       Errors.create().content("Responsibility cannot be empty!").build());
        Assert.isFalse(StringUtils.isEmpty(reason), Errors.create().content("Reason cannot be empty!").build());

        User user = new User();
        user.setInstanceRrn(NumberUtils.toLong(hiddenUserRrn, 0));
        user = securityService.getUser(user);
        String transReasons = reasonCode + " " + user.getInstanceId() + " " + deptExt + " " + " " + reason;
        TransReason transReason = new TransReason();
        transReason.setReasonCode(StringUtils.EMPTY);
        transReason.setReasonCategory(TransactionNames.TERMINATELOT_KEY);
        transReason.setReason(transReasons);
        transReason.setTransQty1(currentLot.getQty1());
        transReason.setTransQty2(currentLot.getQty2());

        transReason.setResponsibility(user.getInstanceId() + " " + user.getUserName());
        handleInfo.put("transReason", transReason);
        return handleInfo;
    }

    private void buildTrackOutHoldInfo(LbrdLotInfoForm theform, int index, Map handleInfo) {
        Assert.isFalse(theform.getHoldReasonCode()[index] == null || "".equals(theform.getHoldReasonCode()[index]),
                       Errors.create().content("Please choose hold code!").build());
        Assert.isFalse(theform.getHoldDept()[index] == null || "".equals(theform.getHoldDept()[index]),
                       Errors.create().content("Please choose Department!").build());
        // if ("".equals(theform.getUserId()[index])) {
        // throw new ValidateFailureException("请选择责任人!");
        // }
        // String userName =
        // getJobManager().getUserName(org.apache.commons.lang.math.NumberUtils.toLong(theform.getUserId()
        // [index]));
        User user = securityService.getUser(NumberUtils.toLong(theform.getUserId()[index]));
        String userName = user.getInstanceId() + " " + user.getUserName();
        String reason = "(TR)" + theform.getHoldDept()[index] + " Reason:" + theform.getHoldReason()[index];
        handleInfo.put("userName" + index, userName);
        handleInfo.put("reason" + index, reason);
        handleInfo.put("holdReasonCode" + index, theform.getHoldReasonCode()[index]);
    }

    private void buildTrackOutHoldInfoForQTime(String user, Map handleInfo, String qTimeMaxTimeHoldReason, int index) {
        String reason = "(TR) Exceeded Maximum Waiting Time. Reason: Hold Time Limit Id: " + qTimeMaxTimeHoldReason;
        handleInfo.put("reason" + index, reason);
        handleInfo.put("holdReasonCode" + index, HoldCodeNames.QTIMEHOLD_KEY);
        handleInfo.put("transComments" + index, "SYSTEM QTIME WHEN MOVE OUT");
        handleInfo.put("transPerformedBy" + index, "SYSTEM");
        handleInfo.put("qTimeMaxTimeFlag" + index, 1);
    }

    private void buildReworkInfo(LbrdLotInfoForm theform, int index, Map handleInfo, String user) throws Exception {
        Assert.isFalse(theform.getDepartment() == null || theform.getDepartment().length == 0 ||
                               StringUtils.isEmpty(theform.getDepartment()[0]),
                       Errors.create().content("Please choose Department!").build());

        Assert.isFalse(theform.getReworkCode() == null || theform.getReworkCode().length == 0 ||
                               StringUtils.isEmpty(theform.getReworkCode()[index]),
                       Errors.create().content("Please choose rework code!").build());

        String reworkCode = theform.getReworkCode()[index];

        String reason = "[" + StringUtils.trimToUpperCase(theform.getReworkCode()[index]) + "]" + sysService
                .referenceDetailExchange("$$REWORK_CODE", StringUtils.trimToUpperCase(theform.getDepartment()[index]),
                                         StringUtils.trimToUpperCase(theform.getReworkCode()[index]), "data_1_value");
        handleInfo.put("reasonCode", reworkCode);
        handleInfo.put("reason", reason);
        handleInfo.put("transComments", "SYSTEM REWORK WHEN MOVE OUT");
        handleInfo.put("transPerformedBy", user);
    }

    private long getCarrierSlotCount(Long carrierRrn) {
        Carrier carrier = new Carrier();
        carrier = carrierService.getCarrier(carrierRrn);
        return MiscUtils.parseSQL(carrier.getSlotCount());
    }

    private Collection parseStringToCollection(String tempString) {
        int pos0 = -1;
        int pos1 = 0;
        String key;
        String _tempString;
        Collection keys = new ArrayList();

        if (tempString != null) {
            while (tempString.indexOf("|") > 0) {
                pos1 = tempString.indexOf("|");
                key = tempString.substring(pos0 + 1, pos1);
                keys.add(key);
                tempString = tempString.substring(pos1 + 1, tempString.length());
            }

            keys.add(tempString);
        }

        return keys;
    }

    /**
     * bond 的副产品或者消耗的主产品并且要生成newLot时返回true
     *
     * @param lot
     * @return
     * @throws Exception
     */
    private Boolean isBondedLot(Collection lots, Lot lot) throws Exception {

        Operation operation = new Operation(lot.getOperationRrn());

        operation = getOperation(operation);
        Boolean isBondOpe = StringUtils.equalsIgnoreCase("MOVEOUT_AUTOBONDED_STD", operation.getMvouWflId());

        // 两个批次 bond 时,辅产品只能正常move out
        if (lots.size() == 2) {
            return isBondOpe && !lotService.isTargetLot4Bond(lot);
        }
        // 1个批次 消耗 时,主产品并且需要生成new Lot 时,只能正常move out
        if (lots.size() == 1) {
            return isBondOpe && lotService.isTargetLot4Consume(lot) && lotService.isNewLotNeededByTargetLot(lot);
        }

        return false;
    }

    private Collection getParameterForLot(Lot lot, Long facilityRrn) throws Exception {
        WflLinkContextValue ctx = new WflLinkContextValue();
        ctx.setContextRrn(getInstanceRrn(ContextNames.WFL_LINK_CONTEXT, facilityRrn, ObjectList.CONTEXT_KEY));
        ctx.setProductRrn(lot.getProductRrn());
        ctx.setProcessRrn(lot.getProcessRrn());
        ctx.setRouteRrn(lot.getRouteRrn());
        ctx.setOperationRrn(lot.getOperationRrn());
        ctx.setProcessVersion(lot.getProcessVersion());

        List parameters = new ArrayList();

        String wfl = lot.getWflStepPath();
        String stepRrn = StringUtils.substring(wfl, wfl.lastIndexOf(".") + 1);

         //Boolean isRouteLastStep = prpService.isRouteLastStep(lot.getRouteRrn(), NumberUtils.toLong(stepRrn, 0));
        Boolean isRouteLastStep = wipCheckService.checkOperationIsLastOperationInRoute(lot.getWflStepPath(), lot.getProcessRrn(), lot.getProcessVersion());
        Collection tempParameters = ctxExecService.getParameterForLot(ctx, null);
        if (tempParameters != null && !tempParameters.isEmpty()) {
            parameters.addAll(tempParameters);
        }
        if (isRouteLastStep) {
            ctx.setContextKey4(" ");
            tempParameters = ctxExecService.getParameterForLot(ctx, parameters);
            if (tempParameters != null && !tempParameters.isEmpty()) {
                parameters.addAll(tempParameters);
            }
        }

        return parameters;
    }

}