SplitRunCardAction.java

package com.mycim.webapp.actions.splitruncard;

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.ObjectUtils;
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.server.runcard.service.SplitRunCardService;
import com.mycim.utils.FieldValidateUtils;
import com.mycim.valueobject.MessageIdList;
import com.mycim.valueobject.ObjectList;
import com.mycim.valueobject.bas.NamedObject;
import com.mycim.valueobject.bas.Relation;
import com.mycim.valueobject.ems.EntityGroup;
import com.mycim.valueobject.prp.AutoSplitMergeInfo;
import com.mycim.valueobject.wip.*;
import com.mycim.webapp.actions.RunCardAction;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;

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

/**
 * @author pinyan.song
 * @version 6.0.0
 * @date 2020-1-7 10:56
 **/
public class SplitRunCardAction extends RunCardAction {
    protected SplitRunCardService splitRunCardService = SpringContext.getBean(SplitRunCardService.class);

    /**
     * Action 方法: init
     */
    @Override
    public ActionForward init(ActionMapping mapping, ActionForm form, HttpServletRequest request,
                              HttpServletResponse response) {
        String[] types = new String[]{"RC_E1_MANAGER", "RELATED_MODULE_GROUP", "SORTERFLIPTYPE"};
        registerOptionType(LocalContext.getFacilityRrn(), Arrays.asList(types), request);
        return mapping.getInputForward();
    }

    /**
     * Action 方法: queryList
     */
    public Map<String, Object> queryList(Map<String, Object> params) {
        int pageSize = MapUtils.getIntValue(params, "limit");
        int pageNo = MapUtils.getIntValue(params, "page");
        String sortJsonString = MapUtils.getString(params, "sort");

        params.put("orderBy", buildOrderBy(sortJsonString));

        // RC Search 界面
        if (!MapUtils.getBooleanValue(params, "isReview") && !MapUtils.getBooleanValue(params, "isSettings")) {
            //选择runCardStatus ALL 时,RRC 查询会将状态为DRAFT的隐藏。
            String[] tempStringArray;
            Object runCardStatus = params.get("runCardStatus");
            if (runCardStatus instanceof List) {
                List<String> tempStringList = (List<String>) runCardStatus;
                tempStringArray = tempStringList.toArray(new String[0]);
            } else {
                tempStringArray = (String[]) runCardStatus;
            }
            if (!(tempStringArray != null && tempStringArray.length > 0 &&
                    StringUtils.isNotEmpty(tempStringArray[0]))) {
                params.put("srcSpecialNeeds", true);
            }
        }

        return splitRunCardService.queryRunCardPage(pageSize, pageNo, params);
    }

    /**
     * Action 方法: addRunCard
     */
    public Map<String, Object> addRunCard() {
        return splitRunCardService.addRunCard();
    }

    /**
     * Action 方法: runCardDetail
     */
    public ActionForward runCardDetail(ActionMapping mapping, HttpServletRequest request) {
        String[] types = new String[]{"RELATED_MODULE_GROUP", "RELATED_MODULE_MANAGER", "POLLUTIONLEVEL",
                                      "WORKAREATYPE", "$LOT_CREATE_CATEGORY", "PROCESSLOCATION", "SRCHOLDCODE",
                                      "RC_E1_MANAGER", "STAGEID", "RC_SUPERVISOR", "RC_MFG_MANAGER", "holdGroup",
                                      "SORTERFLIPTYPE"};
        setForwardParametersToRequest(request, types);
        return mapping.findForward("runCardSettings");
    }

    /**
     * Action 方法: viewRunCardDetail
     */
    public ActionForward viewRunCardDetail(ActionMapping mapping, HttpServletRequest request) {
        String[] types = new String[]{"RELATED_MODULE_GROUP", "RELATED_MODULE_MANAGER", "POLLUTIONLEVEL",
                                      "WORKAREATYPE", "$LOT_CREATE_CATEGORY", "PROCESSLOCATION", "SRCHOLDCODE",
                                      "RC_E1_MANAGER", "RC_SUPERVISOR", "RC_MFG_MANAGER", "SORTERFLIPTYPE"};
        setForwardParametersToRequest(request, types);
        return mapping.findForward("runCardView");
    }

    /**
     * Action 方法: viewRunCard
     */
    public Map<String, Object> viewRunCard(Map<String, Object> params) {
        Long scrRrn = MapUtils.getLong(params, "runCardRrn");
        Integer queueSequence = MapUtils.getInteger(params, "queueSequence");
        Assert.isFalse(scrRrn == null || scrRrn <= 0,
                       Errors.create().content("The parameter is missing. Please login again.").build());

        return splitRunCardService.viewRunCard(scrRrn, queueSequence);
    }

    /**
     * Action 方法: modifyRunCard
     */
    public Map<String, Object> modifyRunCard(Map<String, Object> params) {
        Long scrRrn = MapUtils.getLong(params, "runCardRrn");
        Assert.isFalse(scrRrn == null || scrRrn <= 0,
                       Errors.create().content("The parameter is missing. Please login again.").build());
        return splitRunCardService.getLotRunCardInfo(scrRrn);
    }

    /**
     * Action 方法: copyRunCard
     */
    public Map<String, Object> copyRunCard(Map<String, Object> params) {
        String scrId = MapUtils.getString(params, "runCardId");
        Assert.isFalse(StringUtils.isEmpty(scrId),
                       Errors.create().content("Please enter the Run Card ID to copy!").build());
        scrId = scrId.toUpperCase();

        long scrRrn = getInstanceRrn(scrId, LocalContext.getFacilityRrn(), ObjectList.ECN_KEY);

        Assert.isFalse(scrRrn <= 0, Errors.create().content("Run Card ID: {} does not exist!").args(scrId).build());

        return splitRunCardService.getLotRunCardInfo(scrRrn);
    }

    /**
     * Action 方法: saveSplitRunCard
     */
    public void saveSplitRunCard(Map<String, Object> params) {
        //自动分合批不能和SRC嵌套
        Long lotRrn = MapUtils.getLong(params, "lotRrn");
        Assert.isFalse(lotRrn == null || lotRrn <= 0,
                       Errors.create().key(MessageIdList.LOT_LOTRRN_NOT_FOUND).content("Cannot Find Lot!").build());

        //卡控post future hold被hold住的lot
        checkPostFutureHold(lotRrn);

        Long productRrn = MapUtils.getLong(params, "productRrn");
        if (productRrn != null && productRrn > 0) {
            List<AutoSplitMergeInfo> autoSplitMergeInfo = prpService.getAutoSplitMergeInfoByProduct(productRrn);
            Long splitFlowSeq = getLong4FlowSeq(MapUtils.getString(params, "splitFlowSeq"));
            Long mergeFlowSeq = getLong4FlowSeq(MapUtils.getString(params, "mergeFlowSeq"));
            for (AutoSplitMergeInfo splitMergeInfo : autoSplitMergeInfo) {
                long existSplitSeq = getLong4FlowSeq(splitMergeInfo.getSplitFlowSeq());
                long existMergeSeq = getLong4FlowSeq(splitMergeInfo.getMergeFlowSeq());
                Assert.isFalse(splitFlowSeq != null && existSplitSeq <= splitFlowSeq && splitFlowSeq <= existMergeSeq,
                               Errors.create().content("Please check Step No. nested in Auto Split Merge!").build());
                Assert.isFalse(mergeFlowSeq != null && existSplitSeq <= mergeFlowSeq && mergeFlowSeq <= existMergeSeq,
                               Errors.create().content("Please check Step No. nested in Auto Split Merge!").build());
            }
        }
        checkRecipeForRuncardStep(params);
        splitRunCardService.saveSplitRunCard(params);
    }

    private void checkRecipeForRuncardStep(Map<String,Object> params){
        if(MapUtils.isEmpty(params)){
            return;
        }
        //检查recipe 规则
        //可能是一个 也可能是多个
        Object recipeIds  = MapUtils.getObject(params,"runStepRecipeId");
        if(ObjectUtils.isEmpty(recipeIds)){
            return;
        }
        Set<String> recipeIdSet = new HashSet<>();
        if(recipeIds instanceof  String){
            recipeIdSet.add((String)recipeIds);
        }
        if(recipeIds instanceof  ArrayList){
            recipeIdSet.addAll((ArrayList)recipeIds);
        }
        for(String recipeId : recipeIdSet){
            String msg =  FieldValidateUtils.validateRecipeIdFor536(recipeId);
            Assert.state(StringUtils.isEmpty(msg),Errors.key(MessageIdList.RECIPE_ID_REGEXP_MSG_536));
        }
    }


    /**
     * Action 方法: getLotWithUnitInfo
     */
    public Map<String, Object> getLotWithUnitInfo(Map<String, Object> params) {
        String lotId = MapUtils.getString(params, "lotId");
        Assert.isFalse(StringUtils.isEmpty(lotId),
                       Errors.create().content("The parameter is missing. Please login again.").build());

        Lot lot = lotQueryService.getLot(lotId);
        Assert.isFalse(lot == null,
                       Errors.create().key(MessageIdList.LOT_MISSING_ID).content("The lot is missing.").build());

        //卡控post future hold被hold住的lot
        checkPostFutureHold(lot.getLotRrn());

        verifyLotInfo(lot);

        AutoSplitMergeLot autoSplitMergeLot4Split = prpService.getAutoSplitMergeLot4Split(lot.getLotRrn());
        Assert.isFalse(autoSplitMergeLot4Split != null && autoSplitMergeLot4Split.getTransRrn() > 0L,
                       Errors.create().key(MessageIdList.LOT_AUTOSPLITMERGEEXIST).content("lot in auto split merge")
                             .build());

        return splitRunCardService.getLotWithUnitInfo(lot);
    }

    /**
     * Action 方法: deleteRunCard
     */
    public void deleteRunCard(Map<String, Object> params) {
        deleteRunCardHandle(params);
    }

    /**
     * Action 方法: frozenRunCard
     */
    public void frozenRunCard(Map<String, Object> params) {
        Long runCardRrn = MapUtils.getLong(params, "runCardRrn");
        Assert.isFalse(runCardRrn == null || runCardRrn <= 0,
                       Errors.create().content("The parameter is missing. Please login again.").build());
        LotRunCard lotRunCard = lotRunCardQueryService.getLotRunCard(runCardRrn);
        Assert.isTrue(hasPermissionToWithdraw(lotRunCard),
                      Errors.create().content("Permission denied! The user is not the creator of this SRC!").build());
        splitRunCardService.frozenRunCard(lotRunCard);
    }

    /**
     * Action 方法: rejectRunCard
     */
    public void rejectRunCard(Map<String, Object> params) {
        splitRunCardService.rejectRunCard(params, "Auto Change Hold by SRC Review Reject");
    }

    /**
     * Action 方法: getRunCardTransHistory
     */
    public Map<String, Object> getRunCardTransHistory(Map<String, Object> params) {
        int pageSize = MapUtils.getIntValue(params, "limit");
        int pageNo = MapUtils.getIntValue(params, "page");
        Long scrRrn = MapUtils.getLong(params, "runCardRrn");
        Assert.isFalse(scrRrn == null || scrRrn <= 0,
                       Errors.create().content("The parameter is missing. Please login again.").build());
        return splitRunCardService.getRunCardTransHistory(pageSize, pageNo, scrRrn);
    }

    /**
     * Action 方法: approveRunCard
     */
    public void approveRunCard(Map<String, Object> params) {
        splitRunCardService.approveRunCard(params);
    }

    /**
     * Action 方法: withdrawRunCard
     */
    public void withdrawRunCard(Map<String, Object> params) {
        splitRunCardService.withdrawRunCard(params, "Auto Change Hold by SRC Withdraw");
    }

    /**
     * ajax 方法: getUserGroup 根据UserGroupId获取下面所有用户的信息
     */
    public Map getUserGroup(Map<String, Object> params) {
        Map resul = new HashMap();
        List resultList = new ArrayList();
        String userGroupIdStr = MapUtils.getString(params, "userGroupId");
        if (StringUtils.isNotBlank(userGroupIdStr)) {
            if (userGroupIdStr.length() > 0 && userGroupIdStr.indexOf("[") == 0 &&
                    userGroupIdStr.indexOf("]") == userGroupIdStr.length() - 1) {
                userGroupIdStr = userGroupIdStr.substring(1, userGroupIdStr.length() - 1);
            }
            String[] userGroupIdArr = userGroupIdStr.split(",");
            for (String userGroupId : userGroupIdArr) {
                Long userGroupRrn = getInstanceRrn(userGroupId.trim(), LocalContext.getFacilityRrn(),
                                                   ObjectList.USERGROUP_KEY);
                List<Map> userGroupGrantUserList = securityService.getHasGrantUserAll(userGroupRrn, null);
                resultList.addAll(userGroupGrantUserList);
            }
            resultList = (List) resultList.stream().distinct().collect(Collectors.toList());
        }
        resul.put("data", resultList);
        return resul;
    }

    public List<Map<String, Object>> getFutureStep4Preview(Map<String, Object> params) {
        Map<String, Object> map = (Map<String, Object>) MapUtils.getObject(params, "params");
        Long lotRrn = MapUtils.getLong(map, "lotRrn");
        if (lotRrn == null || lotRrn == 0) {
            return new ArrayList<>();
        }
        List<Map<String, Object>> list = buildStepInfos(map);
        List<LotRunCardSplit> futureSteps = splitRunCardService.getFutureStep4Preview(lotRrn, list);
        return getStepDetails(futureSteps, list);
    }

    public List<Map<String, Object>> getFutureStep4View(Map<String, Object> params) {
        if (params.get("steps") != null) {
            List<Map<String, Object>> list = (List) params.get("steps");
            Long lotRrn = MapUtils.getLong(params, "lotRrn");
            if (CollectionUtils.isNotEmpty(list)) {
                List<LotRunCardSplit> futureSteps = splitRunCardService.getFutureStep4View(list);
                return getStepDetails(futureSteps, list);
            }
        }
        return new ArrayList<>();
    }

    public Map<String, Object> copyRunCardWithAutoCreateNew(Map<String, Object> params) {
        String runCardId = MapUtils.getString(params, "runCardId");

        Long runCardRrn = baseService.getNamedObjectRrn(runCardId,
                                                        baseService.getNamedSpace(LocalContext.getFacilityRrn(),
                                                                                  ObjectList.ECN_KEY),
                                                        ObjectList.ECN_KEY);

        Assert.isFalse((runCardRrn == null || runCardRrn <= 0),
                       Errors.create().content("The parameter is missing. Please login again.").build());

        return lotRunCardService.copyRunCard(runCardRrn);
    }

    public ActionForward printViewRunCardDetail(ActionMapping mapping, HttpServletRequest request) {
        String[] types = new String[]{"RELATED_MODULE_GROUP", "RELATED_MODULE_MANAGER", "POLLUTIONLEVEL",
                                      "WORKAREATYPE", "$LOT_CREATE_CATEGORY", "PROCESSLOCATION", "SRCHOLDCODE",
                                      "RC_E1_MANAGER", "RC_SUPERVISOR", "RC_MFG_MANAGER"};
        setForwardParametersToRequest(request, types);
        return mapping.findForward("runCardViewPrint");
    }

    private List<Map<String, Object>> getStepDetails(List<LotRunCardSplit> futureSteps,
                                                     List<Map<String, Object>> stepList) {
        if (CollectionUtils.isEmpty(futureSteps)) {
            return new ArrayList<>();
        }

        List<Map<String, Object>> result = new ArrayList<>();
        for (LotRunCardSplit futureStep : futureSteps) {
            if (StringUtils.isNotBlank(futureStep.getStepSerials())) {
                String[] chars = StringUtils.split(futureStep.getStepSerials(), ",");
                for (String aChar : chars) {
                    Map<String, Object> temp = new HashMap<>(11);
                    temp.put("waferList", futureStep.getUnitRrns());
                    temp.put("serialNo", aChar);

                    //Map<String, Object> stepMap = stepList.get(NumberUtils.toInt(aChar) - 1);
                    Map<String, Object> stepMap = stepList.stream().filter(step -> StringUtils.equalsIgnoreCase(
                            MapUtils.getString(step, "stepSerialNo"), aChar)).findAny().orElse(null);
                    Assert.notNull(stepMap,
                                   Errors.create().content("Step Serial No {} was not found!").args(aChar).build());

                    temp.put("step", MapUtils.getString(stepMap, "operationId"));
                    temp.put("area", MapUtils.getString(stepMap, "areaId"));
                    temp.put("recipe", MapUtils.getString(stepMap, "recipeId"));

                    if (StringUtils.isNotBlank(MapUtils.getString(stepMap, "equipmentId"))) {
                        temp.put("eqpId", MapUtils.getString(stepMap, "equipmentId"));
                    } else if (StringUtils.isNotBlank(MapUtils.getString(stepMap, "equipmentGroupId"))) {
                        String runStepEquipmentGroupId = MapUtils.getString(stepMap, "equipmentGroupId");

                        EntityGroup entityGroup = new EntityGroup(runStepEquipmentGroupId,
                                                                  getNamedSpace(ObjectList.ENTITYGROUP_KEY,
                                                                                LocalContext.getFacilityRrn()),
                                                                  ObjectList.ENTITYGROUP_KEY);

                        NamedObject namedObject = baseService.getNamedObject(entityGroup);
                        if (namedObject != null && namedObject.getInstanceRrn() > 0) {
                            List<Relation> allEntities = emsService.getAllEntities(namedObject.getInstanceRrn());
                            String eqpIds = allEntities.stream().map(Relation::getInstanceId)
                                                       .collect(Collectors.joining(","));
                            temp.put("eqpId", eqpIds);
                        }
                    }

                    temp.put("contamination", MapUtils.getString(stepMap, "contamination"));
                    temp.put("measurementWafer", MapUtils.getString(stepMap, "measurementSlotRrns"));
                    temp.put("chart", MapUtils.getString(stepMap, "chart"));
                    //如果是RC_TOOD和RC_Search界面,参数存放在stepMap的parameters中
                    if (stepMap.get("parameters") != null) {
                        List list = (List) ((Map) MapUtils.getObject(stepMap, "parameters")).get("parameterId");
                        if (CollectionUtils.isNotEmpty(list)) {
                            temp.put("chart", StringUtils.join(list.toArray(), ","));
                        }
                    }
                    result.add(temp);
                }
            }
        }
        return result;
    }

    private List<Map<String, Object>> buildStepInfos(Map<String, Object> params) {
        List<Map<String, Object>> steps = new ArrayList<>();

        List<String> runStepSerialNos = getSubParamByKeyList(params, "runStepSerialNo");
        List<String> runStepOperationIds = getSubParamByKeyList(params, "runStepOperationId");
        List<String> runStepAreaIds = getSubParamByKeyList(params, "runStepAreaId");
        List<String> runStepEquipmentIds = getSubParamByKeyList(params, "runStepEquipmentId");
        List<String> runStepEquipmentGroupIds = getSubParamByKeyList(params, "runStepEquipmentGroupId");
        List<String> runStepRecipeIds = getSubParamByKeyList(params, "runStepRecipeId");
        List<String> runStepUnitRrns = getSubParamByKeyList(params, "runStepUnitRrns");
        List<String> runStepUnitIds = getSubParamByKeyList(params, "runStepUnitIds");
        List<String> runStepMeasurementSlotRrns = getSubParamByKeyList(params, "runStepMeasurementSlotRrns");
        List<String> runStepContaminations = getSubParamByKeyList(params, "runStepContamination");
        List<String> startOfMainQtimeFlags = getSubParamByKeyList(params, "startOfMainQtimeFlag");
        List<String> endOfMainQtimeFlags = getSubParamByKeyList(params, "endOfMainQtimeFlag");
        List<String> startOfRcQtimeFlags = getSubParamByKeyList(params, "startOfRcQtimeFlag");
        List<String> endOfRcQtimeFlags = getSubParamByKeyList(params, "endOfRcQtimeFlag");
        List<String> runStepRouteRrns = getSubParamByKeyList(params, "runStepRouteRrn");
        List<String> timeLimits = getSubParamByKeyList(params, "timeLimit");


        if (CollectionUtils.isNotEmpty(runStepSerialNos)) {
            for (int i = 0; i < runStepSerialNos.size(); i++) {
                Map<String, Object> stepMap = new HashMap<>();

                String serialNo = runStepSerialNos.get(i);
                stepMap.put("stepSerialNo", serialNo);
                stepMap.put("operationId", StringUtils.trimToUpperCase(runStepOperationIds.get(i)));
                stepMap.put("areaId", runStepAreaIds.get(i));
                stepMap.put("equipmentId", StringUtils.trimToUpperCase(runStepEquipmentIds.get(i)));
                stepMap.put("equipmentGroupId", StringUtils.trimToUpperCase(runStepEquipmentGroupIds.get(i)));
                stepMap.put("recipeId", StringUtils.trimToUpperCase(runStepRecipeIds.get(i)));
                stepMap.put("unitRrns", runStepUnitRrns.get(i));
                stepMap.put("runStepUnitIds", getUnitIdAsList(runStepUnitIds.get(i)));
                stepMap.put("measurementSlotRrns", runStepMeasurementSlotRrns.get(i));
                stepMap.put("contamination", runStepContaminations.get(i));
                stepMap.put("startOfMainQtime", startOfMainQtimeFlags.get(i));
                stepMap.put("endOfMainQtime", endOfMainQtimeFlags.get(i));
                stepMap.put("startOfRcQtime", startOfRcQtimeFlags.get(i));
                stepMap.put("endOfRcQtime", endOfRcQtimeFlags.get(i));
                stepMap.put("runStepRouteRrn", runStepRouteRrns.get(i));
                stepMap.put("timeLimit", timeLimits.get(i));

                String charts = "";
                Object parameterIds = MapUtils.getObject(params, "parameterId" + (i + 1));
                if (parameterIds != null) {
                    // 单个参数是String类型,多个参数是ArrayList类型
                    if (parameterIds instanceof String) {
                        charts = (String) MapUtils.getObject(params, "parameterId" + (i + 1));
                    } else if (parameterIds instanceof List) {
                        List<String> list = (List<String>) MapUtils.getObject(params, "parameterId" + (i + 1));
                        charts = StringUtils.join(list, ",");
                    }
                }
                stepMap.put("chart", charts);
                steps.add(stepMap);
            }
        }

        return steps;
    }

    private List<String> getUnitIdAsList(String unitIds) {
        String[] unitArray = StringUtils.split(unitIds, ',');
        return Arrays.asList(unitArray);
    }

    private List<String> getSubParamByKeyList(Map<String, Object> params, String key) {
        List<String> ret = new ArrayList<>();
        if (params.get(key) == null) {
            return ret;
        } else if ((params.get(key)) instanceof ArrayList) {
            ret.addAll((Collection<? extends String>) params.get(key));
        } else {
            String kVal = MapUtils.getString(params, key);
            ret.add(StringUtils.trim(kVal));
        }
        return ret;
    }

    private Long getLong4FlowSeq(String flowSeq) {
        if (StringUtils.isBlank(flowSeq)) {
            return null;
        } else {
            if (flowSeq.contains(".")) {
                String[] flowSeqArray = flowSeq.split("\\.");
                return Long.parseLong(flowSeqArray[0] + flowSeqArray[1]);
            }
        }
        return Long.parseLong(flowSeq);
    }

    private boolean isAvailableSetLot(String lotStatus) {
        boolean isOutStatus = isCurrentAvailableSetLot(lotStatus);
        return isOutStatus || LotStatus.RUNNING.equalsIgnoreCase(lotStatus) ||
                LotStatus.RUNNINGHOLD.equalsIgnoreCase(lotStatus) || LotStatus.PROCESSED.equalsIgnoreCase(lotStatus);
    }

    private boolean isCurrentAvailableSetLot(String lotStatus) {
        return LotStatus.WAITING.equalsIgnoreCase(lotStatus) || LotStatus.HOLD.equalsIgnoreCase(lotStatus);
    }

    @Override
    protected Boolean hasPermissionToWithdraw(LotRunCard lotRunCard) {
        return splitRunCardService.hasPermissionToWithdraw(lotRunCard);
    }

    @Override
    protected void verifyLotInfo(Lot lot) {
        Assert.isFalse(StringUtils.isNotEmpty(lot.getReworkCategory()) ||
                               (lot.getReworkTransRrn() != null && lot.getReworkTransRrn() > 0),
                       Errors.create().content("Lot is in rework!").build());
        Assert.isTrue(isAvailableSetLot(lot.getLotStatus()),
                      Errors.create().content("Lot status must be WAITING or HOLD!").build());
        wipCheckService.checkPiLotNormalFunction(lot.getLotRrn(),lot.getBasedLotRrn());
    }

}