MonitorLotPlanAction.java

package com.mycim.webapp.actions.dmmlotplan;

import com.fa.sesa.exception.Assert;
import com.fa.sesa.exception.Errors;
import com.fa.sesa.exception.SystemIllegalArgumentException;
import com.fa.sesa.i18n.I18nUtils;
import com.fa.sesa.threadlocal.LocalContext;
import com.mycim.framework.utils.beans.PropertyUtils;
import com.mycim.framework.utils.lang.StringUtils;
import com.mycim.framework.utils.lang.collections.MapUtils;
import com.mycim.framework.utils.lang.math.NumberUtils;
import com.mycim.framework.utils.lang.time.DateUtils;
import com.mycim.valueobject.MessageIdList;
import com.mycim.valueobject.ObjectList;
import com.mycim.valueobject.bas.NamedObject;
import com.mycim.valueobject.consts.ReferenceDetailNames;
import com.mycim.valueobject.consts.ReferenceFileConst;
import com.mycim.valueobject.consts.SessionNames;
import com.mycim.valueobject.prp.Item;
import com.mycim.valueobject.sys.ReferenceFileDetail;
import com.mycim.valueobject.wip.Lot;
import com.mycim.valueobject.wip.LotStatus;
import com.mycim.webapp.Constants;
import com.mycim.webapp.WebUtils;
import com.mycim.webapp.actions.NpwSetupAction;
import com.mycim.webapp.forms.MonitorLotInfoForm;
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.sql.Timestamp;
import java.util.*;

/**
 * @author sandy
 * @version 6.0.0
 * @date 2019/9/1
 **/

public class MonitorLotPlanAction extends NpwSetupAction {

    private static String DEFAULT_WAFER_BANK = "WAFER_BANK";

    private static String SEPARATOR_LOT_ID = "#$#";

    private static String WAITING_KEY = "WAITING";

    private static String DUMMY_KEY = "DUMMY";

    private static String Material_prefix = "allMaterial";

    private static String DUMMY_OPERATION_TYPE = "D";


    @Override
    public ActionForward init(ActionMapping mapping, ActionForm form, HttpServletRequest request,
                              HttpServletResponse response) {

        MonitorLotInfoForm theform = (MonitorLotInfoForm) form;
        String reqCode = WebUtils.getParameter("reqCode", request);
        String lotPlanType = WebUtils.getParameter("type", request);

        // 进入投片页面
        theform.setLotPlanType(lotPlanType);
        theform.setPlanStartDateS(DateUtils.formatDate(new Date(), DateUtils.DATE_FORMAT4DAY));
        String categoryOwner = WebUtils.getParameter("owner", request);
        if (StringUtils.isNotBlank(categoryOwner)) {
            theform.setCategoryOwner(categoryOwner);
        }
        request.removeAttribute(SessionNames.LOTS_LIST_KEY);
        request.removeAttribute(SessionNames.LOT_KEY);
        request.removeAttribute("lotIds");

        String lotTypeRef = WebUtils.getParameter("lotTypeRef", request);

        if (StringUtils.isNotBlank(lotPlanType) && StringUtils.isNotBlank(lotTypeRef)) {
            return handleDefault(mapping, request, theform, LocalContext.getFacilityRrn(), lotPlanType);
        }
        return mapping.findForward("lotPlanStart");
    }

    public Map getProductInfo(Map mapData, HttpServletRequest request, HttpServletResponse response,
                              MonitorLotInfoForm theform) throws Exception {

        Long facilityRrn = LocalContext.getFacilityRrn();
        String language = I18nUtils.getCurrentLanguage().toString();

        Map map = new HashMap();
        String productId = MapUtils.getString(mapData, "productId");
        Item item = new Item(productId, getNamedSpace(ObjectList.PRODUCT_KEY, facilityRrn), ObjectList.PRODUCT_KEY);
        item = (Item) getInstance(item);
        Assert.isFalse(item == null || item.getInstanceRrn() < 1,
                       Errors.create().key(MessageIdList.PRODUCT_PRODUCT_MISSING).content("Product is not exist!")
                             .build());
        Assert.isTrue(StringUtils.equalsIgnoreCase(item.getAttribute3(), Constants.NPW_TYPE),
                      Errors.create().key(MessageIdList.LOT_PRODUCT_TYPE_NOT_MATCH_PLAN)
                            .content("Product type does not match plan type!").build());
        Collection technologys = new ArrayList();
        technologys = prpService.getProductTechnologys(item.getInstanceRrn());
        if (StringUtils.isNotBlank(item.getItemOwner())) {
            map.put("productOwnerId", getInstanceId(new Long(item.getItemOwner())));
        } else {
            map.put("productOwnerId", "");
        }
        map.put("processs", technologys);
        map.put("productEngineerId", item.getProductEngineerId());
        map.put("productEngineerRrn", item.getProductEngineerRrn());
        map.put("productOwnerRrn", item.getItemOwner());

        Iterator it = technologys.iterator();
        Long processRrn = 0l;
        boolean firstProcess = true;
        while (it.hasNext()) {
            Map<String, Object> processMap = (Map<String, Object>) it.next();
            if (processMap != null) {
                if (StringUtils.isNotBlank(MapUtils.getJsonString(processMap, "default")) &&
                        StringUtils.equalsIgnoreCase("y", MapUtils.getJsonString(processMap, "default"))) {
                    // 获取默认流程
                    processRrn = MapUtils.getLong(processMap, "instancerrn");
                    break;
                } else {
                    // 获取第一个流程
                    if (firstProcess) {
                        firstProcess = false;
                        processRrn = MapUtils.getLong(processMap, "instancerrn");
                    }
                }
            }
        }

        int processVersion = prpService.getLastAvaliableProcessVersion(item.getInstanceRrn(), processRrn);
        Assert.isFalse(processVersion == 0, Errors.create().key(MessageIdList.PRODUCT_HAVA_NOT_AVALIABLE_VERSION)
                                                  .content("Have not avaliable process version, please check!")
                                                  .build());
        Long maxLotQty = this.getMaxLotQtyByPorductAndProcess(facilityRrn, item.getInstanceRrn(), processRrn);
        map.put("maxLotQty", maxLotQty);
        //map.put("allMaterial", this.getMaterials4lot(facilityRrn, language, item.getInstanceRrn()));

        return map;
    }

    public ActionForward batchCreateLotPlan(ActionMapping mapping, HttpServletRequest request,
                                            HttpServletResponse response, MonitorLotInfoForm theform) throws Exception {

        String user = LocalContext.getUserId();
        Long facilityRrn = LocalContext.getFacilityRrn();
        String language = I18nUtils.getCurrentLanguage().toString();
        Lot lot = new Lot();


        String createCategory = sysService
                .referenceDetailExchangeByKey2(ReferenceDetailNames.LOT_NAMING_RULE, theform.getLotType(),
                                               ReferenceFileConst.KEY_1_VALUE);
        theform.setCreateCategory(createCategory);
        Assert.isFalse(StringUtils.isNotBlank(theform.getCustomerWaferId()) &&
                               isValidUnitId(theform.getCustomerWaferId(), facilityRrn),
                       Errors.create().key(MessageIdList.LOTPLAN_CUSTOMER_NUMBER_EXISTED)
                             .content("Customer number has already existed, " + "please change customer batch number!")
                             .build());
        // check lotType
        if (StringUtils.isNotBlank(theform.getLotPlanType()) && StringUtils.isNotBlank(theform.getLotTypeRef())) {
            // List<String> lotTypes = sysService.getRefData1Values(theform.getLotTypeRef());
            // Assert.isFalse(lotTypes == null || lotTypes.size() == 0,
            //                Errors.create().key(MessageIdList.REFERENCE_PLEASE_ADD_VALUE)
            //                      .content("Please set reference file: " + "{}").args(theform.getLotTypeRef())
            //                      .build());
            //
            // Assert.isTrue(lotTypes.contains(theform.getLotType()),
            //               Errors.create().key(MessageIdList.LOT_LOT_TYPE_ERROR).content("Lot Type can not be : {}")
            //                     .args(theform.getLotType()).build());
        }

        //校验lotId有效性
        String lotIds = theform.getLotIds();
        Assert.isFalse(StringUtils.isEmpty(lotIds), Errors.create().key(MessageIdList.LOTPALAN_DATA_LOSS_TRY_AGAIN)
                                                          .content("The data loss, please try again!").build());
        String[] lotArr = StringUtils.split(lotIds, SEPARATOR_LOT_ID);
        for (String lotId : lotArr) {
            Assert.isFalse(lotId.indexOf(",") > 0, Errors.create().key(MessageIdList.LOT_LOTID_ERROR_CANT_CONTAIN_COMMA)
                                                         .content("Invalid Lot ID! Lot ID can not contain ','")
                                                         .build());
        }

        Assert.isFalse(StringUtils.isBlank(theform.getLotOwner()),
                       Errors.create().key(MessageIdList.LOT_OWNER_REQUIRE).content("Lot Owner is require").build());
        theform.setLotOwner(StringUtils.trimToUpperCase(theform.getLotOwner()));

        Assert.isFalse((theform.getQty1() != null) && (theform.getQty1().compareTo(new Double(0)) <= 0),
                       Errors.create().key(MessageIdList.LOT_QUANTITY_MUST_LARGER_0)
                             .content("LOT Quantity must be larger than 0!").build());

        Assert.isFalse(StringUtils.isBlank(theform.getProductId()),
                       Errors.create().key(MessageIdList.PRODUCT_EMPTY_ID).content("Product Id cannot be empty!")
                             .build());

        // 根据lot plan type check the product type
        theform.setProductId(StringUtils.trimToUpperCase(theform.getProductId()));
        NamedObject obj = new NamedObject(theform.getProductId(), getNamedSpace(ObjectList.PRODUCT_KEY, facilityRrn),
                                          ObjectList.PRODUCT_KEY);
        obj = baseService.getNamedObject(obj);

        Assert.isFalse(obj != null, Errors.create().key(MessageIdList.SUBTECHNOLOGY_ENTER_CORRECT)
                                          .content("Please enter the correct product id!").build());
        String lotPlanType = theform.getLotPlanType();
        boolean matchFlag = true;
        // new lot和GLASS是同一产品
        if (StringUtils.isNotBlank(lotPlanType)) {
            if (!StringUtils.equalsIgnoreCase(lotPlanType, ObjectList.NEW_LOT) &&
                    !StringUtils.equals(obj.getObjectType(), lotPlanType)) {
                matchFlag = false;
            }
        } else {
            // 如果lot type是空,则表示普通的lot plan,产品类型不能是类表值$$SPECIAL_LOT_PLAN_TYPE设置的类型
            List<String> specialTypes = sysService
                    .getRefFileKey(ReferenceDetailNames.SPECIAL_LOT_PLAN_TYPE, StringUtils.EMPTY);
            if (specialTypes != null && specialTypes.contains(obj.getObjectType())) {
                matchFlag = false;
            }
        }

        Assert.isTrue(matchFlag, Errors.create().key(MessageIdList.LOT_PRODUCT_TYPE_NOT_MATCH_PLAN)
                                       .content("Product type does not match plan type!").build());


        Assert.isFalse(StringUtils.isBlank(theform.getProcessId()),
                       Errors.create().key(MessageIdList.PROCESS_EMPTY_ID).content("Process cannot be empty!").build());

        theform.setProcessId(StringUtils.trimToUpperCase(theform.getProcessId()));
        Long processRrn = new Long(
                getInstanceRrn(theform.getProcessId(), getNamedSpace(ObjectList.WFL_KEY, facilityRrn),
                               ObjectList.WFL_KEY));

        Assert.isFalse(processRrn <= 0, Errors.create().key(MessageIdList.DMMLOTPLAN_PROCESSID_NOT_CORRECT)
                                              .content("Process id input error!").build());

        boolean isProductProcessBined;
        int processVersion = 0;

        isProductProcessBined = isProductProcessBined(obj.getInstanceRrn(), processRrn);
        processVersion = prpService.getLastAvaliableProcessVersion(obj.getInstanceRrn(), processRrn);
        Assert.isFalse(processVersion == 0, Errors.create().key(MessageIdList.PRODUCT_HAVA_NOT_AVALIABLE_VERSION)
                                                  .content("Have not avaliable process version, please check!")
                                                  .build());

        Assert.isTrue(isProductProcessBined,
                      Errors.create().key(MessageIdList.PRODUCT_PRODUCT_PROCESS_NOT_BOUND).content("产品流程未绑定!").build());
        theform.setProcessRrn(processRrn);
        theform.setLotOwner(StringUtils.trimToUpperCase(theform.getLotOwner()));

        long lotOwnerRrn = this
                .getInstanceRrn(theform.getLotOwner(), this.getNamedSpace(ObjectList.USER_KEY, facilityRrn),
                                ObjectList.USER_KEY);
        Assert.isFalse(lotOwnerRrn == 0,
                       Errors.create().key(MessageIdList.LOT_INVALIDA_LOT_OWNER).content("Invalida Lot Owner id!")
                             .build());

        lot = new Lot();

        PropertyUtils.copyProperties(lot, theform);


        lot.setLotPlanType(StringUtils.isBlank(lot.getLotPlanType()) ? obj.getObjectType() : lot.getLotPlanType());
        lot.setFacilityRrn(facilityRrn);
        //			lot.setLotId(StringUtils.trimToUpperCase(lot.getLotId()));
        //			theform.setLotId(lot.getLotId());
        lot.setQty1(theform.getQty1());
        lot.setProcessRrn(theform.getProcessRrn());
        lot.setStepSequence(new Long(TRUE));
        lot.setLotStatus(WAITING_KEY);
        if (lot.getHotFlag() == null || lot.getHotFlag().trim().equals("")) {
            lot.setHotFlag(FALSE);
        }
        lot.setQueueTimestamp(new Timestamp(System.currentTimeMillis()));


        if (theform.getDueDateS() != null && !theform.getDueDateS().trim().equalsIgnoreCase("")) {

            long nowTime = System.currentTimeMillis();

            Timestamp dueDate = DateUtils.stringToTimestamp(theform.getDueDateS() + " 00:00:00");

            Assert.notNull(dueDate, Errors.create().key(MessageIdList.DATE_DATE_FORMAT_INCORRECT)
                                          .content("Incorrect date format!").build());
            Assert.isFalse(dueDate.getTime() < nowTime,
                           Errors.create().content("dueDate must after the current date").build());

            lot.setDueDate(DateUtils.stringToTimestamp(theform.getDueDateS() + " 00:00:00"));

        }

        //handle plandate
        if (StringUtils.isEmpty(theform.getPlanStartDateS())) {
            theform.setPlanStartDateS(DateUtils.formatDate(new Date(), DateUtils.DATE_FORMAT4DAY));
        }
        Timestamp planDate = DateUtils.stringToTimestamp(theform.getPlanStartDateS() + " 00:00:00");
        Assert.notNull(planDate,
                       Errors.create().key(MessageIdList.DATE_DATE_FORMAT_INCORRECT).content("Incorrect date format!")
                             .build());
        lot.setPlanStartDate(DateUtils.stringToTimestamp(theform.getPlanStartDateS() + " 00:00:00"));
        //handle plantDate end

        lot.setProductRrn(obj.getInstanceRrn());
        if (theform.getCarrierId() != null && !theform.getCarrierId().trim().equals("")) {
            lot.setCarrierRrn(new Long(
                    getInstanceRrn(lot.getCarrierId(), getNamedSpace(ObjectList.ENTITY_KEY, facilityRrn),
                                   ObjectList.ENTITY_KEY)));

            Assert.isFalse(lot.getCarrierRrn().compareTo(new Long(0)) < 0,
                           Errors.create().content("Carrier not found!").build());
        }
        lot.setProcessVersion(processVersion);
        if ((theform.getCreateCategory() != null) && theform.getCreateCategory().equals(DUMMY_KEY)) {
            lot.setDummyFlag(TRUE);
        } else {
            lot.setDummyFlag(FALSE);
        }

        lot.setTransPerformedby(user);
        //处理批次流程信息
        List<Lot> lotList = new ArrayList<Lot>();
        lotArr = StringUtils.split(lotIds, SEPARATOR_LOT_ID);
        Lot _lot = null;
        String allMaterial = StringUtils.EMPTY;
        if (lot != null && lotArr != null && lotArr.length >= 1) {
            for (String lotId : lotArr) {
                _lot = (Lot) lot.clone();
                _lot.setLotId(lotId);
                buildLotProcessStepinfo(theform, request, facilityRrn, _lot);
                allMaterial = WebUtils.getParameterUpperCase(Material_prefix + lotId, request);
                if (StringUtils.isNotEmpty(allMaterial)) {
                    _lot.setMaterialinfo(allMaterial);
                }
                lotList.add(_lot);
            }
        }

        theform.setPages(new Integer(1));

        request.setAttribute(SessionNames.COLLECTION_KEY, new ArrayList());
        StringBuffer lotIdSb = new StringBuffer();
        StringBuffer existLotIdSb = new StringBuffer();
        for (String lotId : lotArr) {
            long lotRrn = lotQueryService.getLot(lotId, facilityRrn).getLotRrn();
            Lot lotTemp = lotService.getLotPlan(lotId);
            if (lotTemp != null && (lotTemp.getLotRrn() > 0 && lotTemp.getLotRrn() != theform.getLotRrn()) ||
                    lotRrn > 0) {
                existLotIdSb.append(lotId).append(",");
            } else {
                lotIdSb.append(lotId).append(",");
            }
        }


        if (existLotIdSb != null && existLotIdSb.length() > 0) {
            throw new SystemIllegalArgumentException(Errors.create().content("Lot:{} existed!")
                                                           .args(existLotIdSb.substring(0, existLotIdSb.length() - 1)
                                                                             .toString()).build());
        }

        lot.setTransPerformedby(user);
        lotService.insertBatchLotPlan(lotList);

        request.setAttribute("createFlag", "1");
        request.setAttribute("sucLotId", lotIdSb.substring(0, lotIdSb.length() - 1).toString());
        return mapping.findForward("lotPlanStart");

    }

    public ActionForward createLotInit(ActionMapping mapping, HttpServletRequest request, MonitorLotInfoForm theform) {
        Map lotInfo = new HashMap();
        lotInfo.put("lotPlanTypeMenu", theform.getLotPlanType());
        request.setAttribute("_lotInfo", lotInfo);
        return mapping.getInputForward();
    }

    private void buildLotProcessStepinfo(MonitorLotInfoForm theform, HttpServletRequest request, Long facilityRrn,
                                         Lot lot) throws Exception {
        String trackUnitFlag = "0";
        String keepUnitHistoryFlag = "0";
        String totalProcessTime = StringUtils.EMPTY;
        String stageId = "";
        String layerId = "";
        Long borRrn = new Long(0);
        Long operationRrn = new Long(0);
        Integer operationVer = new Integer(0);
        Long executionRrn = new Long(0);
        String processStepVersion = null;
        String processStepIdVersion = null;
        String processStepVersion4wfl = null;


        String stepNumber = request.getParameter("stepNumber");
        Map tempInfo = getStepsInfoByVersion(lot, lot.getProcessRrn(), lot.getProcessVersion(), stepNumber);

        executionRrn = (Long) tempInfo.get("executionRrn");
        operationRrn = (Long) tempInfo.get("operationRrn");

        /*NamedObject operation = baseService.getNamedObject(new NamedObject(operationRrn.longValue()));
        if (!StringUtils.startsWith(operation.getObjectType(), DUMMY_OPERATION_TYPE)) {
            throw new WebException("流程第一步不是材料开始步骤 !");
        }*/

        Assert.isTrue(checkOperationInFacility(operationRrn, facilityRrn),
                      Errors.create().content("The Lot's first step is not" + " in current " + "facility!").build());
        if (theform.getCarrierId() != null && !theform.getCarrierId().trim().equals("")) {
            List lotsInSameCarrier = new ArrayList();
            Lot item = null;

            for (Iterator it = lotsInSameCarrier.iterator(); it.hasNext(); ) {
                item = (Lot) it.next();

                Assert.isFalse((item.getLotStatus() == null) || !item.getLotStatus().equals(LotStatus.WAITING),
                               Errors.create().content("Carrier selected is in used, please select other carriers.")
                                     .build());

                Assert.isFalse(item.getOperationRrn().compareTo(operationRrn) != 0, Errors.create().content(
                        "Carrier " + "should not" + " be used" + " " + "for Lot" + "({}) in " + "this " + "carrier is" +
                                " in " + "different " + "operation").args(item.getLotId()).build());
            }

        }
        operationVer = (Integer) tempInfo.get("operationVer");
        stageId = (String) tempInfo.get("stageId");
        layerId = (String) tempInfo.get("layerId");
        processStepVersion = (String) tempInfo.get("processStepVersion");
        processStepIdVersion = (String) tempInfo.get("processStepIdVersion");
        processStepVersion4wfl = (String) tempInfo.get("processStepVersion4wfl");

        lot.setNextOperationRrn1((Long) tempInfo.get("nextoperationRrn1"));

        if ((lot.getNextOperationRrn1() != null) && (lot.getNextOperationRrn1().compareTo(new Long(0)) > 0)) {
            lot.setNextOperationId1(getInstanceId(lot.getNextOperationRrn1().longValue()));
        }

        lot.setNextStepVersion1((String) tempInfo.get("nextprocessStepVersion1"));
        lot.setNextStepIdVersion1((String) tempInfo.get("nextprocessStepIdVersion1"));

        lot.setNextOperationRrn2((Long) tempInfo.get("nextoperationRrn2"));

        if ((lot.getNextOperationRrn2() != null) && (lot.getNextOperationRrn2().compareTo(new Long(0)) > 0)) {
            lot.setNextOperationId2(getInstanceId(lot.getNextOperationRrn2().longValue()));
        }

        lot.setNextStepVersion2((String) tempInfo.get("nextprocessStepVersion2"));
        lot.setNextStepIdVersion2((String) tempInfo.get("nextprocessStepIdVersion2"));

        trackUnitFlag = (String) tempInfo.get("trackUnitFlag");
        keepUnitHistoryFlag = (String) tempInfo.get("keepUnitHistoryFlag");

        tempInfo = new HashMap();
        tempInfo.put("operationRrn", operationRrn);
        tempInfo.put("productRrn", lot.getProductRrn());
        tempInfo.put("technologyRrn", lot.getProcessRrn());
        tempInfo.put("recipeRrn", null);
        tempInfo.put("lotRrn", null);

        if ((lot.getScheduleDueDate() != null) && (lot.getDueDate() != null) &&
                lot.getScheduleDueDate().after(lot.getDueDate())) {
            lot.setLastScheduleFlag(TRUE);
        }

        lot.setProcessStepVersion(processStepVersion.toString());
        lot.setProcessStepIdVersion(processStepIdVersion.toString());
        lot.setWflStepPath(processStepVersion4wfl);
        lot.setExecutionRrn(executionRrn);
        lot.setOperationRrn(operationRrn);
        lot.setOperationVersion(operationVer);
        lot.setOperationId(this.getInstanceId(operationRrn.longValue()));
        lot.setStageId(stageId);
        lot.setLayerId(layerId);
        lot.setBorRrn(borRrn);
        lot.setBeforeStatus("");
        lot.setInputQty1(theform.getQty1());
        lot.setInputQty2(theform.getQty2());
        lot.setStartedFlag(TRUE);
        lot.setReticleGroupRrn(theform.getReticleGroupRrn());
        theform.setTrackUnitFlag(trackUnitFlag);
        theform.setKeepUnitHistoryFlag(keepUnitHistoryFlag);

    }

    private ActionForward handleDefault(ActionMapping mapping, HttpServletRequest request, MonitorLotInfoForm theform,
                                        Long facilityRrn, String lotPlanType) {
        // 得到lot plan type对应的批次类型类表值
        String lotTypeRef = WebUtils.getParameter("lotTypeRef", request);
        theform.setLotTypeRef(lotTypeRef);

        if (!StringUtils.equalsIgnoreCase(lotPlanType, ObjectList.NEW_LOT)) {
            // 默认lot type
            // List<String> lotTypes = sysService.getRefData1Values(lotTypeRef);
            List<String> lotTypes = new ArrayList<>();
            if (lotTypes == null || lotTypes.size() == 0) {
                request.setAttribute("confimLotIdFlag", "0");
                //request.setAttribute(ErrorDef.MYCIM_ERR_KEY, "Please set reference file: " + lotTypeRef);
                return mapping.findForward("lotPlanStart");
            }
            theform.setLotType(lotTypes.get(0));// 任意默认一个

            // 默认lot ID和create category
            String createCategory = sysService
                    .referenceDetailExchangeByKey2(ReferenceDetailNames.LOT_NAMING_RULE, lotTypes.get(0),
                                                   ReferenceFileConst.KEY_1_VALUE);
            // check 默认的createCategory的权限是否是菜单携带的owner权限一致
            String categoryOwner = theform.getCategoryOwner();
            if (StringUtils.isNotBlank(categoryOwner)) {
                List<String> refKeys = sysService
                        .getRefFileKeysByDataValue(ReferenceDetailNames.LOT_CREATE_CATEGORY, categoryOwner,
                                                   "DATA_3_VALUE");
                if (!refKeys.contains(createCategory)) {
                    request.setAttribute("confimLotIdFlag", "0");
                    return mapping.findForward("lotPlanStart");
                }
            }
            ReferenceFileDetail referenceFileDetail = getReferenceFileDetail(ReferenceDetailNames.LOT_NAMING_RULE,
                                                                             createCategory, lotTypes.get(0),
                                                                             facilityRrn);
            String lotId = baseService.generateLotId(theform.getLotType(), theform.getLotType()).toUpperCase();
            theform.setCreateCategory(createCategory);
            theform.setLotId(lotId);
        }
        return mapping.findForward("lotPlanStart");
    }

    /**
     * 根据产品rrn和流程rrn获取流程上设置的第一个工步的process location,然后通过匹配获取晶舟的槽位数作为批次的最大晶圆数量
     *
     * @param facilityRrn 车间rrn
     * @param productRrr  产品rrn
     * @param processRrn  流程rrn
     * @return 批次的最大晶圆数量
     */
    private Long getMaxLotQtyByPorductAndProcess(Long facilityRrn, Long productRrr, Long processRrn) throws Exception {
        Long defaultMaxLotQty = 25l;
        if (productRrr != null && productRrr > 0 && processRrn != null && processRrn > 0) {
            // 获取流程树
            Map<String, Object> matchingRules = new HashMap<String, Object>();
            matchingRules.put("productRrn", productRrr);
            matchingRules.put("processRrn", processRrn);
            List wflTree = new ArrayList();
            int processVersion = this.getProcessVersion(processRrn);
            wflTree = prpService.getWorkFlowTree(processRrn, matchingRules);


            Map<String, Object> contextValueInfoMap = new HashMap<String, Object>();
            if (wflTree != null && wflTree.size() > 0) {
                contextValueInfoMap.putAll(matchingRules);
                String[] treeRouteNodes = (String[]) wflTree.get(0);
                String[] treeOperNodes = (String[]) wflTree.get(1);

                contextValueInfoMap.put("routeRrn", NumberUtils.createLong(treeRouteNodes[4]));
                contextValueInfoMap.put("operationRrn", NumberUtils.createLong(treeOperNodes[4]));
                contextValueInfoMap.put("processVersion", processVersion);

                String processLocation = ctxExecService.getProcessLocation(contextValueInfoMap);
                if (StringUtils.isNotBlank(processLocation)) {
                    // 根据porcesslocation获取对应cst类型的槽位数,设置为$carrier_type类表值的default value 栏位
                    List refColl = sysService.getRefFileValues("$CARRIER_TYPE", facilityRrn);
                    if (!refColl.isEmpty()) {
                        Iterator it = refColl.iterator();
                        while (it.hasNext()) {
                            ReferenceFileDetail detail = (ReferenceFileDetail) it.next();
                            if (StringUtils.equalsIgnoreCase(detail.getData1Value(), processLocation)) {
                                String maxLotQtyStr = detail.getData4Value();
                                if (StringUtils.isNotBlank(maxLotQtyStr) && NumberUtils.isNumber(maxLotQtyStr)) {
                                    return Long.parseLong(maxLotQtyStr);
                                }
                            }
                        }
                    }
                }
            }
        }

        return defaultMaxLotQty;
    }


    /*private boolean isValidUnitId(String customerWaferId, Long facilityRrn) {

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

        return false;
    }*/

    /**
     * lot--customerwaferId字符串 格式 aaaa|0$aaaa|0$aaaa|0$aaaa|0$ 转换为 [aaaa,aaaa,aaaa]
     */
   /* 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;
    }*/

}