NpwSetupAction.java

package com.mycim.webapp.actions;

import com.fa.sesa.exception.Assert;
import com.fa.sesa.exception.Errors;
import com.fa.sesa.threadlocal.LocalContext;
import com.mycim.framework.context.spring.SpringContext;
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.msg.JsonUtils;
import com.mycim.quartz.service.QuartzOperateService;
import com.mycim.server.asm.service.AsmService;
import com.mycim.server.asm.service.WarehouseService;
import com.mycim.server.carrier.service.CarrierService;
import com.mycim.server.constrain.service.ConstrainService;
import com.mycim.server.ctx.exec.service.CtxExecService;
import com.mycim.server.ecn.service.EcnService;
import com.mycim.server.edc.service.EdcService;
import com.mycim.server.ems.service.EmsService;
import com.mycim.server.npw.service.EqpMonitorLotService;
import com.mycim.server.npw.service.EqpMonitorService;
import com.mycim.server.prp.service.PrpService;
import com.mycim.server.rcp.service.RecipeService;
import com.mycim.server.wip.service.*;
import com.mycim.utils.WipUtils;
import com.mycim.valueobject.MessageIdList;
import com.mycim.valueobject.ObjectList;
import com.mycim.valueobject.bas.NamedObject;
import com.mycim.valueobject.bas.ObjectVersion;
import com.mycim.valueobject.consts.ContextNames;
import com.mycim.valueobject.consts.HoldCodeNames;
import com.mycim.valueobject.prp.*;
import com.mycim.valueobject.security.User;
import com.mycim.valueobject.wip.*;

import java.lang.Override;
import java.util.*;


/**
 * @author shijie.deng
 * @version 6.0.0
 * @date 2019/11/8
 **/
public class NpwSetupAction extends AbstractAction {

    public static final String MONITOR = "MONITOR";

    public static final String DMMROUTE_SUFFIX = "-R";

    public static final String PROCESS_JOB_CLASS = "com.mycim.quartz.jobs.ProcessScheduleJob";

    protected static final String TRUE = "1";

    protected static final String FALSE = "0";

    protected static final String PROCESS_RRN_KEY = "PROCESSRRN";

    protected static final String DATA_PERMISSION_KEY = "dataPermissionFlag";

    protected PrpService prpService = SpringContext.getBean(PrpService.class);

    protected LotService lotService = SpringContext.getBean(LotService.class);

    protected WarehouseService warehouseService = SpringContext.getBean(WarehouseService.class);

    protected CarrierService carrierService = SpringContext.getBean(CarrierService.class);

    protected WipWorkflowQueryService wipWorkflowQueryService = SpringContext.getBean(WipWorkflowQueryService.class);

    protected LotQueryService lotQueryService = SpringContext.getBean(LotQueryService.class);

    protected WipQueryService wipQueryService = SpringContext.getBean(WipQueryService.class);

    protected EqpMonitorService dmmService = SpringContext.getBean(EqpMonitorService.class);

    protected RecipeService recipeService = SpringContext.getBean(RecipeService.class);

    protected EcnService ecnService = SpringContext.getBean(EcnService.class);

    protected ConstrainService constrainService = SpringContext.getBean(ConstrainService.class);

    protected EqpMonitorLotService dmmLotService = SpringContext.getBean(EqpMonitorLotService.class);

    protected EmsService emsService = SpringContext.getBean(EmsService.class);

    protected QuartzOperateService quartzOperateService = SpringContext.getBean(QuartzOperateService.class);

    protected CtxExecService ctxExecService = SpringContext.getBean(CtxExecService.class);

    protected AsmService asmService = SpringContext.getBean(AsmService.class);

    protected EdcService edcService = SpringContext.getBean(EdcService.class);

    protected WipService wipService = SpringContext.getBean(WipService.class);

    public String getDefaultOptionValue(List<Map<String, String>> lotTypeOptions) {
        String result = StringUtils.EMPTY;
        for (Map<String, String> each : lotTypeOptions) {
            if (StringUtils.equals("true", each.get("selected"))) {
                result = each.get("value");
                break;
            }
        }
        return result;
    }

    @Override
    public NamedObject getInstance(NamedObject instance) {

        NamedObject _instance = null;
        if (instance instanceof Item) {
            _instance = prpService.getItem((Item) instance);
        } else if (instance instanceof ProcessPlanning) {
            _instance = prpService.getProcessPlanning((ProcessPlanning) instance);
        }
        if (_instance != null) {
            instance = _instance;
        }

        return instance;
    }

    private Collection myParseString(String tempString, String index) {
        int pos0 = -1;
        int pos1 = 0;
        int pos2 = 0;
        String key;
        String _tempString;
        Collection _keys = new ArrayList();
        if (tempString != null) {
            while (tempString.indexOf("$") > 0) {
                pos1 = tempString.indexOf("$");
                _tempString = tempString.substring(pos0 + 1, pos1);

                if (_tempString.indexOf("|") > 0) {
                    pos2 = _tempString.indexOf("|");

                    if (index.equals("1")) {
                        key = StringUtils.trimToUpperCase(_tempString.substring(pos0 + 1, pos2));
                    } else {
                        key = StringUtils.trimToUpperCase(_tempString.substring(pos2 + 1, pos1));
                    }

                    _keys.add(key);
                    tempString = tempString.substring(pos1 + 1, tempString.length());
                }
            }
        }

        return _keys;
    }

    protected String getLimitString(Long lowerLimit, Long upperLimit) {
        String limit = "";
        if (lowerLimit != null && upperLimit != null) {
            limit = upperLimit + "+&nbsp;-" + lowerLimit;
        } else if (lowerLimit != null && upperLimit == null) {
            limit = ">&nbsp;" + lowerLimit;
        } else if (lowerLimit == null && upperLimit != null) {
            limit = "<&nbsp;" + upperLimit;
        }
        return limit;
    }

    protected Map<String, String> getLotInfo(Lot lot, EqpMonitorLotSpecialStep lotSpecialStep) {
        Map<String, String> lotInfo = new HashMap<String, String>();
        lotInfo.put("carrierId", lot.getCarrierId());
        lotInfo.put("lotId", lot.getLotId());
        lotInfo.put("productId", lot.getProductId());
        lotInfo.put("processId", lot.getProcessId());
        lotInfo.put("lotStatus", lot.getLotStatus());
        lotInfo.put("qty1", lot.getInt_qty1() + "");

        if (lotSpecialStep != null) {
            lotInfo.put("seq", lotSpecialStep.getStepSequence() + "");
            lotInfo.put("eqptGroupId", lotSpecialStep.getEntityGroupId());
            lotInfo.put("eqptGroupRrn", lotSpecialStep.getEntityGroupRrn() + "");
            lotInfo.put("slot", lotSpecialStep.getSlot());
            lotInfo.put("recipe", lotSpecialStep.getRecipeStr());
            lotInfo.put("parameterId", lotSpecialStep.getParameterId());
            lotInfo.put("formula", lotSpecialStep.getFormula());
            lotInfo.put("limit", getLimitString(lotSpecialStep.getLowerLimit(), lotSpecialStep.getUpperLimit()));
            lotInfo.put("lotStepSeq", lotSpecialStep.getLotStepSeq() + "");
            lotInfo.put("lotRrn", lotSpecialStep.getLotRrn() + "");
            lotInfo.put("lotSpecialStepRrn", lotSpecialStep.getLotSpecialStepRrn() + "");
            lotInfo.put("parameterSetId", lotSpecialStep.getParameterSetId());
            lotInfo.put("stepId", lotSpecialStep.getStepId());
            lotInfo.put("stepDesc", lotSpecialStep.getStepDesc());
            lotInfo.put("processLocation", lotSpecialStep.getProcessLocation());
            lotInfo.put("stepSeq", lotSpecialStep.getStepSeq());
            lotInfo.put("waferNum", lotSpecialStep.getWaferNum());
            lotInfo.put("stageId", lotSpecialStep.getStageId());
            lotInfo.put("measurationFlag", new Integer(1).equals(lotSpecialStep.getMeasurationFlag()) ? "Y" : "N");
            lotInfo.put("pollutionLevel", lotSpecialStep.getPollutionLevel());
            if (StringUtils.equals("DMM-NO-ACCOUNT-PROCESS", lotSpecialStep.getProcessId())) {
                lotInfo.put("noAccount", "1");
                lotInfo.put("eqptId", lotSpecialStep.getEquipmentId());
                lotInfo.put("eqptRrn", lotSpecialStep.getEquipmentRrn() + "");
            }
        }

        if (StringUtils.isNotBlank(lot.getRecipePhysicalId())) {
            lotInfo.put("recipeId", lot.getRecipePhysicalId());
            lotInfo.put("eqptId", lot.getEqptID());
            if (StringUtils.isEmpty(MapUtils.getString(lotInfo, "recipe"))) {
                lotInfo.put("recipe", lot.getRecipePhysicalId());
            }
        }
        return lotInfo;
    }

    protected boolean checkVersionEditEnable(List versionObjects) {
        if (CollectionUtils.isNotEmpty(versionObjects)) {
            for (Object version : versionObjects) {
                ObjectVersion versionObject = (ObjectVersion) version;
                if ((versionObject.getVersionStatus() == null) ||
                        versionObject.getVersionStatus().equalsIgnoreCase("UNFROZEN") ||
                        versionObject.getVersionStatus().equalsIgnoreCase("FROZEN")) {
                    return true;
                }
            }
        }
        return false;
    }

    protected boolean checkVersionEditEnable(ObjectVersion objectVersion) {
        boolean checked = false;

        if ((objectVersion.getVersionStatus() == null) ||
                objectVersion.getVersionStatus().equalsIgnoreCase("UNFROZEN")) {
            checked = true;
        }

        return checked;
    }

    protected String checkObjectDeleteEnable(List<? extends ObjectVersion> versionObjects) {
        String checked = "true";

        if (CollectionUtils.isNotEmpty(versionObjects)) {
            checked = "false";
        }

        return checked;
    }

    protected void validateProcessPlan(List list) {
        ObjectVersion objectVersions;
        for (Object o : list) {
            objectVersions = (ObjectVersion) o;
            long objectRrn = objectVersions.getInstanceRrn();
            int objectVersion = objectVersions.getInstanceVersion();
            String object = objectVersions.getObject();

            NamedObject wflObject = null;

            if ("WFL".equalsIgnoreCase(object)) {
                boolean validateFlag = false;
                wflObject = baseService.getNamedObject(objectRrn);
                Assert.notNull(wflObject,
                               Errors.create().key(MessageIdList.NAMEDOBJECT_NOT_EXIST).content("{} Does not exist.")
                                     .args(objectVersions.getInstanceId()).build());
                validateFlag = prpService.validateWfl(objectRrn, objectVersion);

                if (!validateFlag) {
                    Assert.isFalse("PROCESS".equals(wflObject.getObjectSubtype()),
                                   Errors.create().content("Please Save in " + "ProcessEditor").build());
                }
            }
        }
    }

    protected String getDMMRouteId(String DMMProcessId) {
        return DMMProcessId + DMMROUTE_SUFFIX;
    }

    protected PlanLot getPlanLot(PlanLot planLot) throws Exception {
        // temp object to store the value object retrived from database
        PlanLot _planLot = lotService.getPlanLot(planLot);

        if (_planLot != null) {
            planLot = _planLot;
        }
        return planLot;
    }

    protected Integer getProcessVersion(long processRrn) throws Exception {
        NamedObject object = new NamedObject(processRrn);
        object = baseService.isExisted(processRrn);
        ObjectVersion version = baseService.getMostActiveVersion(object);

        return new Integer(version.getInstanceVersion());
    }

    protected Map getStepsInfoByLot(Lot lot, Long processRrn, Integer processVer, String stepPath) throws Exception {
        Map matchingRules = new HashMap();
        matchingRules.put("productRrn", String.valueOf(lot.getProductRrn()));
        matchingRules.put("processRrn", processRrn);
        matchingRules.put("lotRrn", lot.getLotRrn() + "");
        Map stepsInfo = wipWorkflowQueryService.getStepsInfoByVersion(processRrn, processVer, stepPath, matchingRules);
        return stepsInfo;
    }

    protected void handlePreFutureHoldByPilot(Lot currentLot, User systemUser, Long facilityRrn) throws Exception {
        PilotContextValue contextValue = getPilotLotContextValue(currentLot);

        if (contextValue != null) {
            Map holdMap = new HashMap();
            holdMap.put("lotRrn", new Long(currentLot.getLotRrn()));
            holdMap.put("transPerformedBy", systemUser.getInstanceId());
            holdMap.put("holdBy", String.valueOf(systemUser.getInstanceRrn()));
            holdMap.put("holdPassword", "");
            holdMap.put("transComments", "");

            TransReason transReason = new TransReason();
            transReason.setReasonCategory(HoldCodeNames.PILOTHOLD_KEY);
            transReason.setReasonCode(HoldCodeNames.PILOTHOLD_KEY);
            String reasonCodeDesc = sysService
                    .getRefFileValue("$HOLD_CODE", contextValue.getHoldCode(), "DATA_1_VALUE");
            transReason.setReason("(FH)" + contextValue.getHoldDepart() + " " + reasonCodeDesc);
            transReason.setResponsibility(systemUser.getInstanceId());
            transReason.setTransQty1(currentLot.getQty1());
            holdMap.put("transReason", transReason);

            lotService.holdLot4Pilot(contextValue, holdMap);
        }
    }

    protected PilotContextValue getPilotLotContextValue(Lot lot) throws Exception {
        PilotContextValue contextValue = null;
        long contextRrn = baseService.getNamedObjectRrn(ContextNames.PILOT_LOT_CONTEXT_KEY, baseService
                .getNamedSpace(lot.getFacilityRrn().longValue(), "CONTEXT"), "CONTEXT");
        if (contextRrn > 0) {
            contextValue = new PilotContextValue(contextRrn);
            contextValue.setProductRrn(lot.getProductRrn());
            contextValue.setProcessRrn(lot.getProcessRrn());
            contextValue.setRouteRrn(lot.getRouteRrn());
            contextValue.setOperationRrn(lot.getOperationRrn());
            contextValue.setRecipeRrn(lot.getRecipeRrn());
            contextValue.setLotRrn(new Long(lot.getLotRrn()));
            contextValue = lotService.getPilotLotContextValue(contextValue);
        }
        return contextValue;
    }

    protected String connectMesSystem(Map objectInfo, long facilityRrn, String user) {
        // todo 接口相关的待完成
        return null;
    }

    protected Boolean isNPWLot(String lotId) {
        Map<String, String> queryInfo = new HashMap<String, String>();
        queryInfo.put("lotId", lotId);
        List<NpwBank> npwLots = dmmLotService.getNPWBankLot(queryInfo);
        return CollectionUtils.isNotEmpty(npwLots);
    }

    /**
     * @param unitList
     * @return String
     * @Description 将集合对象转换成json字符串(包含空位置信息的json, 一般用于前台ext的展示)
     * @author Aiden
     */
    protected String parseToJsonString(List<Map> unitList) {
        List<Map> newUnits = new ArrayList<Map>(unitList);
        Collections.sort(newUnits, new Comparator<Map>() {

            // 将wafer重新排序
            @Override
            public int compare(Map map1, Map map2) {
                int position1 = MapUtils.getIntValue(map1, "position");
                int position2 = MapUtils.getIntValue(map2, "position");
                if (position1 > position2) {
                    return 1;
                } else if (position1 < position2) {
                    return -1;
                } else {
                    return 0;
                }
            }
        });
        Iterator it = newUnits.iterator();
        Map unit = new HashMap();
        int number = 1;// 指wafer位置从1开始
        int seq = 1;
        List<Map> units = new ArrayList<Map>();
        while (it.hasNext()) {
            Map<String, Object> unitMap = null;
            unit = (HashMap) it.next();
            seq = MapUtils.getIntValue(unit, "position");
            while ((number < seq)) {
                unitMap = new HashMap();
                unitMap.put("position", number + "");
                unitMap.put("unitId", "");
                unitMap.put("unitRrn", "");
                unitMap.put("lotid", "");
                unitMap.put("chooseFlag", "");
                units.add(unitMap);
                number++;
            }
            unitMap = new HashMap();
            unitMap.put("position", number + "");
            unitMap.put("unitId", unit.get("unitId"));
            unitMap.put("unitRrn", unit.get("unitRrn"));
            unitMap.put("lotid", unit.get("lotid"));
            unitMap.put("chooseFlag", unit.get("chooseFlag"));
            units.add(unitMap);
            number++;
        }
        int listSize = units.size();// 已有
        for (int i = listSize + 1; i <= 25; i++) {
            Map<String, Object> unitMap = new HashMap();
            unitMap.put("position", i + "");
            unitMap.put("unitId", "");
            unitMap.put("unitRrn", "");
            unitMap.put("lotid", "");
            unitMap.put("chooseFlag", "");
            units.add(unitMap);
        }
        return JsonUtils.toString(units);
    }

    protected String initEmptyCarrier() {
        List<Map<String, Object>> emptyUnits = new ArrayList<Map<String, Object>>();
        int number = 25;// 默认槽位25片
        for (int i = 1; i <= number; i++) {
            Map<String, Object> unitMap = new HashMap<String, Object>();
            unitMap.put("position", i + "");
            unitMap.put("unitId", "");
            unitMap.put("unitRrn", "");
            unitMap.put("lotid", "");
            emptyUnits.add(unitMap);

        }
        String jsonStr = JsonUtils.toString(emptyUnits).toString();
        return jsonStr;
    }

    /**
     * @param jsonStr
     * @return List<Map < String, Object>>
     * @Description 获得移除空位后的wafer信息
     */
    protected List<Map<String, Object>> parseJsonStrAndRemoveIdlePostion(String jsonStr) {
        List<Map<String, Object>> unitList = new ArrayList<Map<String, Object>>();
        List list = JsonUtils.toObject(jsonStr, List.class);
        List<Map<String, Object>> tempUnits = (List) list;
        for (Map<String, Object> unitMap : tempUnits) {
            String unitId = MapUtils.getString(unitMap, "unitId");
            String unitRrn = MapUtils.getString(unitMap, "unitRrn");
            String lotid = MapUtils.getString(unitMap, "lotid");
            if (StringUtils.isNotBlank(unitId) && StringUtils.isNotBlank(unitRrn) && StringUtils.isNotBlank(lotid)) {
                unitList.add(unitMap);
            }
        }
        return unitList;
    }

    protected void activateWithProcessScheduler(Long ecnRrn, boolean isRoute) {
        String userId = LocalContext.getUserId();
        //        ecnService.activateEcn(ecnRrn, userId);
        if (isRoute) {
            ObjectVersion objectVersion = new ObjectVersion();
            objectVersion.setEcnRrn(ecnRrn);
            prpService.activeteEcnByRouteVersion(objectVersion, userId);
        } else {
            ProcessVersion pv = new ProcessVersion();
            pv.setEcnRrn(ecnRrn);
            prpService.activeteEcnByProcessVersion(pv, userId);
        }
        Date date = new Date();
        String jobName = "ECN" + date.getTime();
        Map jobData = new HashMap();
        jobData.put("ECN_RRN", ecnRrn + "");
        quartzOperateService.addJob(jobName, PROCESS_JOB_CLASS, "DEFAULT", new Date(date.getTime() + 1), 0, 0, jobData);
    }

    protected boolean isValidUnitId(String customerWaferId, Long facilityRrn) {
        List unitIds = (List) myParseString(customerWaferId, "1");
        for (int i = 0; i < unitIds.size(); i++) {
            Unit unit = wipQueryService.getUnit(facilityRrn, (String) unitIds.get(i));
            if (unit != null && StringUtils.isNotBlank(unit.getUnitId())) {
                return true;
            }
        }
        return false;
    }

    protected boolean isProductProcessBined(Long productRrn, long processRrn) {
        List<Long> processRrns = prpService.getProcessRrnsByProductRrn(productRrn);
        return processRrns.contains(processRrn);
    }

    protected Map getStepsInfoByVersion(Lot lot, Long processRrn, Integer processVer, String stepPath) {
        Map matchingRules = new HashMap();
        matchingRules.put("productRrn", String.valueOf(lot.getProductRrn()));
        matchingRules.put("processRrn", lot.getProcessRrn());
        matchingRules.put("lotRrn", lot.getLotRrn() + "");

        Map stepsInfo = wipWorkflowQueryService.getStepsInfoByVersion(processRrn, processVer, stepPath, matchingRules);

        return stepsInfo;
    }

    protected boolean checkOperationInFacility(Long operationRrn, Long facilityRrn) {

        boolean inSameFab = false;

        NamedObject object = baseService.getNamedObject(new NamedObject(operationRrn.longValue()));

        if (object != null && object.getNamedSpace() != null) {

            String _temp = getNamedSpace(ObjectList.OPERATION_KEY, facilityRrn);

            if (object.getNamedSpace().equalsIgnoreCase(_temp)) {

                inSameFab = true;
            }

        }
        return inSameFab;
    }

    protected long parseRouteRrn(String processStepVersion) {
        long routeRrn = 0;
        if (StringUtils.isNotBlank(processStepVersion)) {

            int firstSep = 0;
            int secondSep = 0;

            firstSep = processStepVersion.indexOf("|");

            secondSep = processStepVersion.indexOf("|", firstSep + 1);
            if (secondSep >= 0) {
                routeRrn = Long.parseLong(processStepVersion.substring(processStepVersion.indexOf("|", 1) + 1,
                                                                       processStepVersion.indexOf(",",
                                                                                                  processStepVersion
                                                                                                          .indexOf("|",
                                                                                                                   1))));
            } else {
                routeRrn = Long.parseLong(processStepVersion.substring(0, processStepVersion.indexOf(",")));
            }
        }

        return routeRrn;

    }

    protected String getNextStepDesc(Lot lot) {
        long facilityRrn = LocalContext.getFacilityRrn();
        Map conditionM = new HashMap();
        conditionM.put("facilityRrn", facilityRrn);
        conditionM.put("productRrn", lot.getProductRrn());
        conditionM.put("processRrn", lot.getProcessRrn());
        conditionM.put("processVersion", lot.getProcessVersion());
        conditionM.put("routeRrn", WipUtils.getRouteRrnByProcessStep(lot.getNextStepVersion1()));
        conditionM.put("operationRrn", lot.getNextOperationRrn1());

        String nextOperationDesc1 = ctxExecService.getOperationDescByProcessInfo(conditionM);
        return nextOperationDesc1;
    }

    protected String getHotflagSplicingPriority(Lot lot) {
        return wipQueryService.getHotflagSplicingPriority(NumberUtils.toInt(lot.getHotFlag()), lot.getPriority(),
                                                          LocalContext.getFacilityRrn());
    }

    protected String getRecipePhysicalId(Lot lot) {
        String recipePhysicalId = "";
        RecipeVersion recipeVersion = recipeService.getLotRecipe(lot);
        if (recipeVersion != null) {
            recipePhysicalId = recipeVersion.getPpid();
        }
        return recipePhysicalId;
    }

    protected void checkProcessPermission(String processId) {
        String dataPermissionFlag = LocalContext.get(DATA_PERMISSION_KEY);
        if (StringUtils.equals(dataPermissionFlag, "1") && StringUtils.isNotBlank(processId)) {
            ProcessPlanning processPlanning = new ProcessPlanning(
                    processId, getNamedSpace(ObjectList.WFL_KEY, LocalContext.getFacilityRrn()), ObjectList.WFL_KEY);
            ProcessPlanning newProcessPlanning = prpService.getProcessPlanning(processPlanning);
            if (null != newProcessPlanning) {
                String processRrnStr = securityService.getProcessRrnWithPermission(LocalContext.getUserRrn());
                Assert.isTrue(processRrnStr.contains(Long.toString(newProcessPlanning.getInstanceRrn())),
                              Errors.create().key(MessageIdList.SYSTEM_OPERATION_NOT_PERMISSION)
                                    .content("No permission to view the process!").build());
            }
        }
    }

    /**
     * 检查当前用户是否有权限操作该流程
     *
     * @param processRrn 流程rrn
     */
    protected void checkPermissionForOperateProcess(long processRrn) {
        String processRrns = securityService.getProcessRrnWithPermission(LocalContext.getUserRrn());
        String dataPermissionFlag = LocalContext.get(DATA_PERMISSION_KEY);
        Assert.isFalse(
                StringUtils.equals(dataPermissionFlag, "1") && !StringUtils.contains(processRrns, processRrn + ""),
                Errors.create().key(MessageIdList.SYSTEM_OPERATION_NOT_PERMISSION)
                      .content("No permission to view the process!").build());
    }

}