SplitLotAction.java

package com.mycim.webapp.actions.lot.split;

import com.fa.sesa.exception.Assert;
import com.fa.sesa.exception.Errors;
import com.fa.sesa.threadlocal.LocalContext;
import com.mycim.framework.utils.beans.BeanUtils;
import com.mycim.framework.utils.beans.PropertyUtils;
import com.mycim.framework.utils.lang.ObjectUtils;
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.valueobject.LocationNames;
import com.mycim.valueobject.MessageIdList;
import com.mycim.valueobject.ObjectList;
import com.mycim.valueobject.consts.PcdStatus;
import com.mycim.valueobject.consts.SessionNames;
import com.mycim.valueobject.ems.Carrier;
import com.mycim.valueobject.ems.pilot.PiLotView;
import com.mycim.valueobject.wip.Lot;
import com.mycim.valueobject.wip.TransReason;
import com.mycim.webapp.Constants;
import com.mycim.webapp.WebUtils;
import com.mycim.webapp.actions.lot.ManualAndSortCheckAction;
import com.mycim.webapp.forms.lot.LotInfoForm;
import com.mycim.webapp.forms.lot.SplitMergeInfoForm;
import org.apache.commons.compress.utils.Sets;
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 shijie.deng
 * @version 6.0.0
 * @date 2019/9/28
 **/
public class SplitLotAction extends ManualAndSortCheckAction {
    protected static final String ACTION_URL_KEY = "splitActionUrl";

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

        // redirect to the login page if there is no session
        long facilityRrn = LocalContext.getFacilityRrn();
        if (form == null) {
            form = new SplitMergeInfoForm();
        }

        SplitMergeInfoForm theform = (SplitMergeInfoForm) form;

        theform.setPages(1);

        // Populate the new valid format id
        String lotId = theform.getLotId();

        Assert.isFalse((lotId == null) || lotId.trim().equalsIgnoreCase(""),
                       Errors.create().key(MessageIdList.LOT_ID_EMPTY).content("The lot Id is empty!").build());

        lotId = lotId.trim().toUpperCase();

        if (StringUtils.isNotBlank((String) request.getAttribute("target"))) {
            theform.setCacheTarget((String) request.getAttribute("target"));
        }

        Lot lot = lotQueryService.getLot(lotId, facilityRrn);

        super.checkCstRemoved(Sets.newHashSet(lot.getLotRrn()));

        checkLotForSplit(lot, theform.getSplitType());

        if (isTrackUnitFlag(lot)) {
            lot.setTrackUnitFlag(TRUE);

        } else {
            lot.setTrackUnitFlag(FALSE);
        } // end of if


        //check sortJob
        checkWaitJobs(lot.getCarrierRrn(), 0L, 0L, null);

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

        wipQueryService.checkActiveInlineOcapId(lot.getLotRrn());

        // Copy value object properties to form bean.
        LotInfoForm lotInfoForm = new LotInfoForm();

        PropertyUtils.copyProperties(lotInfoForm, lot);
        Map conditionMap = BeanUtils.copyBeanToMap(lot);
        String recipePhysicalId = getRecipePhysicalId(lot);
        lotInfoForm.setRecipePhysicalId(recipePhysicalId);
        lot.setRecipePhysicalId(recipePhysicalId);    //防止进入分批操作页面后返回分批信息页面,recipePhysicalId丢失
        Assert.nonNull(lot.getQty1(),
                       Errors.create().key(MessageIdList.LOT_QTY_NULL).content("This Lot's qty1 is null").build());
        initLotBaseInfoForJsp(request, true, null, null);
        theform.setSourceListValues(parseToJsonString(wipQueryService.getUnitListByLot(lot.getLotRrn())));
        lotInfoForm.setSourceListValues(theform.getSourceListValues());// holly add 20080711
        request.setAttribute(SessionNames.COLLECTION2_KEY, parseToSimplifyCollection(theform.getSourceListValues()));

        lotInfoForm.setRemainQty(lot.getQty1());

        theform.setLotInfoForm(lotInfoForm);
        theform.setLotId(null);

        theform.setCacheLot(WebUtils.getCacheObj2String(lot));

        request.setAttribute(SessionNames.COLLECTION_KEY, new ArrayList());
        theform.setCacheChildLots(WebUtils.getCacheObj2String(new ArrayList()));
        theform.setTransId(Constants.MODIFY_KEY);
        request.setAttribute(SessionNames.LOT_INFO_FORM_KEY, lotInfoForm);
        theform.setCacheLotInfo(WebUtils.getCacheObj2String(lotInfoForm));

        setActionUrl(request);
        return mapping.findForward(Constants.INIT_KEY);
    }

    public ActionForward initAddChildLot(ActionMapping mapping, SplitMergeInfoForm theform,
                                         HttpServletRequest request) {
        String userId = LocalContext.getUserId();
        long facilityRrn = LocalContext.getFacilityRrn();
        LotInfoForm lotInfoForm = (LotInfoForm) WebUtils.getCacheString2Obj(theform.getCacheLotInfo());
        Collection childLots = (Collection) WebUtils.getCacheString2Obj(theform.getCacheChildLots());
        Lot lot = (Lot) WebUtils.getCacheString2Obj(theform.getCacheLot());

        lot.setTransPerformedby(userId);
        // 设置优先级信息
        lotInfoForm.setHotFlagPriorityStr(wipQueryService.getHotflagSplicingPriority(
                NumberUtils.parseNumber(lotInfoForm.getHotFlag(), Integer.class).intValue(), lotInfoForm.getPriority(),
                facilityRrn));

        lotInfoForm.setTargetListValues(initEmptyCarrier());
        theform.setTargetListValues(initEmptyCarrier());
        lotInfoForm.setSplitType(theform.getSplitType());
        Carrier parentCarrier = carrierService.getCarrier(lot.getCarrierRrn());
        request.setAttribute("parentCSTslotCount", parentCarrier.getSlotCount());
        request.setAttribute("parentCarrierCategory", parentCarrier.getFlagType());

        // increment child lot id
        int i = (theform.getCacheChildLotId() == null) ? 1 : theform.getCacheChildLotId().intValue();


        theform.setCacheChildLotId(i + 1);

        String lotId = lotInfoForm.getLotId();

        //已下沉到Manage层
        String childLotId = lotService.buildChildLotId(lotId, childLots);

        theform.setLotId(childLotId);
        theform.setBaseCarrierType(parentCarrier.getObjectSubtype());
        theform.setCarrierId(null);
        theform.setRouteId(null);
        theform.setQty1(null);
        theform.setOperationId(null);
        theform.setTransId(Constants.CREATE_KEY);
        theform.setLotInfoForm(lotInfoForm);// childLotId
        String subSplitType = theform.getSubSplitType();
        if (StringUtils.isEqual(Constants.PILOT_KEY, subSplitType)) {
            //TODO :先行片逻辑
            childPiLotInfo(theform, lot);
        }
        theform.setCacheLotInfo(WebUtils.getCacheObj2String(lotInfoForm));

        lotInfoForm.setPriorityText(lotQueryService.getPriorityText(lot.getPriority()));
        request.setAttribute(SessionNames.COLLECTION_KEY, childLots);
        request.setAttribute(SessionNames.LOT_INFO_FORM_KEY, lotInfoForm);
        theform.setCacheChildLots(WebUtils.getCacheObj2String(childLots));
        theform.setCacheLotInfo(WebUtils.getCacheObj2String(lotInfoForm));
        theform.setCacheLot(WebUtils.getCacheObj2String(lot));

        setActionUrl(request);
        return mapping.findForward("initAddChildLot");
    }

    public ActionForward addChildLot(ActionMapping mapping, SplitMergeInfoForm theform, HttpServletRequest request) {
        theform.setPages(1);
        theform.setLotId(StringUtils.trimToUpperCase(theform.getLotId()));
        LotInfoForm lotInfoForm = (LotInfoForm) WebUtils.getCacheString2Obj(theform.getCacheLotInfo());
        List<Map> childLots = (List<Map>) WebUtils.getCacheString2Obj(theform.getCacheChildLots());
        Lot lot = (Lot) WebUtils.getCacheString2Obj(theform.getCacheLot());
        isDeleteValidation(request, theform, lotInfoForm);

        verifyChildLot(theform.getLotId(), theform.getCarrierId().toUpperCase(), childLots);
        verifyChildLotId(theform, childLots);
        validateLotId(theform.getLotId());// 检查ChildLot和得carrierRrn值
        Assert.isFalse(theform.getLotId().indexOf(",") > 0,
                       Errors.create().content("Invalid Lot ID! Lot ID can not contain comma.").build());
        Map item = new HashMap();

        builditemChidLotInfo(request, theform, lotInfoForm, lot, item);

        if (theform.getSplitType().equals(LocationNames.PERMANENT_UP) ||
                theform.getSplitType().equals(LocationNames.PERMANENT)) {
            item = validatePermanentSplit(theform, item);
        }
        childLots.add(item);
        if (StringUtils.isNotEmptyTrim(WebUtils.getParameter("sourceListValues", request))) {
            lotInfoForm.setSourceListValues(request.getParameter("sourceListValues"));
        }
        Assert.isFalse(lotInfoForm.getRemainQty() - theform.getQty1() <= 0,
                       Errors.create().key(MessageIdList.LOT_AT_LEAST_1_WAFER).content("Parent lot at least 1 wafer!")
                             .build());
        lotInfoForm.setRemainQty(lotInfoForm.getRemainQty() - theform.getQty1());

        copyLotForm(theform, lotInfoForm, lot);
        String changeProcessFlag = request.getParameter("changeProcessFlag");
        request.setAttribute(SessionNames.COLLECTION_KEY, childLots);
        request.setAttribute(SessionNames.LOT_INFO_FORM_KEY, lotInfoForm);
        request.setAttribute("changeProcessFlag", changeProcessFlag);
        initLotBaseInfoJspForSplit(request, lotInfoForm);
        theform.setCacheChildLots(WebUtils.getCacheObj2String(childLots));
        theform.setCacheLotInfo(WebUtils.getCacheObj2String(lotInfoForm));
        theform.setCacheLot(WebUtils.getCacheObj2String(lot));

        setActionUrl(request);
        return (mapping.findForward("init"));

    }

    public ActionForward modifyChildLotInit(ActionMapping mapping, SplitMergeInfoForm theform,
                                            HttpServletRequest request) {
        LotInfoForm lotInfoForm = (LotInfoForm) WebUtils.getCacheString2Obj(theform.getCacheLotInfo());
        List<Map> childLots = (List<Map>) WebUtils.getCacheString2Obj(theform.getCacheChildLots());
        Lot lot = (Lot) WebUtils.getCacheString2Obj(theform.getCacheLot());
        Iterator it = childLots.iterator();
        String record = request.getParameter(Constants.ITEM_KEY);
        // TODO : fix MapUtils
        for (Map childLot : childLots) {
            String childLotId = MapUtils.getString(childLot, "childLotId");
            if (childLotId.equals(record)) {
                theform.setLotId(childLotId);
                theform.setCarrierId((String) childLot.get("carrierId"));
                theform.setQty1((Double) childLot.get("splitQty"));
                theform.setRouteId((String) childLot.get("routeId4Show"));

                theform.setOperationId((String) childLot.get("operationId"));
                theform.setNewProductId((String) childLot.get("newProductId"));
                theform.setNewTechnologyId((String) childLot.get("newTechnologyId"));
                theform.setChangeProcessFlag(StringUtils.equalsIgnoreCase("TRUE", MapUtils.getString(childLot,
                                                                                                     "changeProcessFlag")) ? "1" : "0");
                theform.setStepNumber(MapUtils.getString(childLot, "wflStepPath"));
                lotInfoForm.setSplitType(theform.getSplitType());
                lotInfoForm.setTargetListValues((String) childLot.get("unitList"));
                theform.setTransId(Constants.MODIFY_KEY);

                Carrier parentCarrier = carrierService.getCarrier(lot.getCarrierRrn());
                request.setAttribute("parentCarrierCategory", parentCarrier.getFlagType());
                theform.setBaseCarrierType(parentCarrier.getObjectSubtype());
                break;
            } // end of if
        }
        theform.setLotInfoForm(lotInfoForm);
        request.setAttribute(SessionNames.COLLECTION_KEY, childLots);
        request.setAttribute(SessionNames.LOT_INFO_FORM_KEY, lotInfoForm);
        theform.setCacheChildLots(WebUtils.getCacheObj2String(childLots));
        theform.setCacheLotInfo(WebUtils.getCacheObj2String(lotInfoForm));
        theform.setCacheLot(WebUtils.getCacheObj2String(lot));

        setActionUrl(request);
        return (mapping.findForward("initAddChildLot"));
    }

    public ActionForward modifyChildLot(ActionMapping mapping, SplitMergeInfoForm theform, HttpServletRequest request) {

        LotInfoForm lotInfoForm = (LotInfoForm) WebUtils.getCacheString2Obj(theform.getCacheLotInfo());
        List childLots = (List) WebUtils.getCacheString2Obj(theform.getCacheChildLots());
        Lot lot = (Lot) WebUtils.getCacheString2Obj(theform.getCacheLot());
        isDeleteValidation(request, theform, lotInfoForm);
        Map item = null;
        for (Iterator it = childLots.iterator(); it.hasNext(); ) {
            item = (HashMap) it.next();
            String childLotId = (String) item.get("childLotId");
            if (childLotId.equals(theform.getLotId())) {
                validateLotId(childLotId);

                lotInfoForm.setSourceListValues(request.getParameter("sourceListValues"));
                lotInfoForm.setTargetListValues(null);
                Assert.isFalse(lotInfoForm.getRemainQty().doubleValue() - theform.getQty1().doubleValue() +
                                       MapUtils.getDoubleValue(item, "splitQty", 0) <= 0,
                               Errors.create().key(MessageIdList.LOT_AT_LEAST_1_WAFER)
                                     .content("Parent lot at least 1 wafer!").build());
                lotInfoForm.setRemainQty(new Double(
                        lotInfoForm.getRemainQty().doubleValue() - theform.getQty1().doubleValue() +
                                ((Double) item.get("splitQty")).doubleValue()));
                builditemChidLotInfo(request, theform, lotInfoForm, lot, item);

                if (theform.getSplitType().equals("permanent")) {
                    item = validatePermanentSplit(theform, item);
                }
                break;
            }
        }
        copyLotForm(theform, lotInfoForm, lot);
        request.setAttribute(SessionNames.COLLECTION_KEY, childLots);
        request.setAttribute(SessionNames.LOT_INFO_FORM_KEY, lotInfoForm);
        theform.setCacheChildLots(WebUtils.getCacheObj2String(childLots));
        theform.setCacheLotInfo(WebUtils.getCacheObj2String(lotInfoForm));
        theform.setCacheLot(WebUtils.getCacheObj2String(lot));
        initLotBaseInfoJspForSplit(request, lotInfoForm);

        setActionUrl(request);
        return (mapping.findForward(Constants.INIT_KEY));
    }

    public ActionForward delChildLot(ActionMapping mapping, SplitMergeInfoForm theform, HttpServletRequest request) {
        LotInfoForm lotInfoForm = (LotInfoForm) WebUtils.getCacheString2Obj(theform.getCacheLotInfo());
        List<Map> childLots = (List<Map>) WebUtils.getCacheString2Obj(theform.getCacheChildLots());
        Lot lot = (Lot) WebUtils.getCacheString2Obj(theform.getCacheLot());

        Map item = null;
        for (Iterator it = childLots.iterator(); it.hasNext(); ) {
            item = (HashMap) it.next();
            String childLotId = (String) item.get("childLotId");
            if (childLotId.equals(theform.getLotId())) {
                childLots.remove(item);
                lotInfoForm.setSourceListValues(
                        transUnit((String) item.get("unitList"), lotInfoForm.getSourceListValues()));
                lotInfoForm.setTargetListValues(null);
                lotInfoForm.setRemainQty(new Double(
                        lotInfoForm.getRemainQty().doubleValue() + ((Double) item.get("splitQty")).doubleValue()));
                break;
            }
        }
        copyLotForm(theform, lotInfoForm, lot);
        request.setAttribute(SessionNames.COLLECTION_KEY, childLots);
        request.setAttribute(SessionNames.LOT_INFO_FORM_KEY, lotInfoForm);
        theform.setCacheChildLots(WebUtils.getCacheObj2String(childLots));
        theform.setCacheLotInfo(WebUtils.getCacheObj2String(lotInfoForm));
        theform.setCacheLot(WebUtils.getCacheObj2String(lot));
        initLotBaseInfoJspForSplit(request, lotInfoForm);

        setActionUrl(request);
        return (mapping.findForward("init"));
    }

    public ActionForward saveSplitLots(ActionMapping mapping, SplitMergeInfoForm theform, HttpServletRequest request) {
        String userId = LocalContext.getUserId();
        long facilityRrn = LocalContext.getFacilityRrn();
        long userRrn = LocalContext.getUserRrn();
        String changeProcessFlag = request.getParameter("changeProcessFlag");

        LotInfoForm lotInfoForm = (LotInfoForm) WebUtils.getCacheString2Obj(theform.getCacheLotInfo());
        List<Map> childLots = (List<Map>) WebUtils.getCacheString2Obj(theform.getCacheChildLots());
        Lot lot = (Lot) WebUtils.getCacheString2Obj(theform.getCacheLot());
        lot.setTransPerformedby(userId);
        // 如果分批的数量<=0
        Assert.isFalse(childLots.isEmpty(), Errors.create().key(MessageIdList.SPLITLOT_NO_CHILD_LOT_SPECIFIED)
                                                  .content("No child lot specified!").build());
        Collection unitsOfParentLot = null;// 母批
        //如果缓存的剩余数量和传递过来的剩余数量不同时 用传过来的数量
        if (theform.getRemainQty().doubleValue() != lotInfoForm.getRemainQty().doubleValue()) {
            theform.setRemainQty(lotInfoForm.getRemainQty());
        }
        String splitType = theform.getSplitType();// 分批类型
        Double remainQty = theform.getRemainQty();// 保持数量

        Assert.isFalse(remainQty < 1,
                       Errors.create().key(MessageIdList.LOT_AT_LEAST_1_WAFER).content("Parent lot at least 1 wafer!")
                             .build());

        for (Map childLotMap : childLots) {
            String childCarrierId = MapUtils.getString(childLotMap, "carrierId");
            Carrier childCarrier = carrierService.getCarrier(LocalContext.getFacilityRrn(), childCarrierId);
            String pcdFlag = sysService.getRefFileValue("$CARRIER_TYPE", childCarrier.getObjectSubtype(),
                                                        "DATA_2_VALUE");
            String allowedStatus = StringUtils.equalsIgnoreCase("1",
                                                                pcdFlag) ? PcdStatus.ASSEMBLY_KEY : PcdStatus.FREE_KEY;
            String status = emsService.getEntityCurrentStatus(
                    baseService.getNamedObjectRrn(childCarrierId, "MYCIM2", "ENTITY"));
            Assert.isTrue(StringUtils.equalsIgnoreCase(status, allowedStatus),
                          Errors.create().key(MessageIdList.CARRIER_CASSETTE_IN_USED).content("晶舟被使用").build());
            Assert.state(!lotAutoMonitorInqService.checkMonitorCarrierUsed(childCarrier.getInstanceRrn()),
                         Errors.create().key(MessageIdList.AUTOMONITOR_CARRIER_INUSED).build());

            //check sortJob
            checkWaitJobs(childCarrier.getInstanceRrn(), 0L, 0L, null);
        }

        if (StringUtils.containsIgnoreCase("WAITING", lotInfoForm.getLotStatus()) ||
                StringUtils.containsIgnoreCase("HOLD", lotInfoForm.getLotStatus())) {
            double childQty = 0.0;
            for (Map map : childLots) {
                childQty += (Double) map.get("splitQty");
            }
            Assert.isFalse(lotInfoForm.getQty1() - childQty <= 0,
                           Errors.create().key(MessageIdList.SPLITLOT_SPLIT_LOT_EXCEPTION)
                                 .content("LotId:{}operate exception,please " + "Re-operation!")
                                 .args(lotInfoForm.getLotId()).build());
        }
        Assert.isFalse(remainQty < 0, Errors.create().content("The Rremain Qty < 0!").build());
        if (isTrackUnitFlag(lot)) {
            Iterator it = childLots.iterator();

            while (it.hasNext()) {
                Map item = (Map) it.next();
                String unitList = (String) item.get("unitList");// Wafer信息.
                List units = this.parseJsonStrAndRemoveIdlePostion(unitList);
                item.put("units", units);
            }

            if (StringUtils.isEmpty(theform.getSourceListValues())) {
                Map unitsOfParentLotMap = WebUtils.getCacheString2Obj(theform.getCacheUnitsOfParentLot()) ==
                        null ? new HashMap() : ((Map) WebUtils.getCacheString2Obj(theform.getCacheUnitsOfParentLot()));

                String unitsOfParentLotSession = MapUtils.getString(unitsOfParentLotMap,
                                                                    lot.getLotId() + "unitsOfParentLot");
                theform.setSourceListValues(unitsOfParentLotSession);
            }
            unitsOfParentLot = this.parseJsonStrAndRemoveIdlePostion(theform.getSourceListValues());
        }
        HashMap valueMap = new HashMap();
        valueMap.put("changeProcessFlag", changeProcessFlag);
        valueMap.put("lot", lot);
        valueMap.put("childLots", childLots);
        valueMap.put("splitType", splitType);
        valueMap.put("subSplitType", theform.getSubSplitType());
        valueMap.put("unitOfParent", unitsOfParentLot);
        valueMap.put("comment", theform.getComment());
        valueMap.put("facilityRrn", facilityRrn);
        valueMap.put("user", userId);

        HashMap map = null;
        if (remainQty == 0) {
            map = new HashMap();
            map.put("lotRrn", new Long(lot.getLotRrn()));
            map.put("transId", "TERMINATE");
            map.put("user", userId);

            TransReason transReason = new TransReason();
            transReason.setReasonCategory("TERM");
            transReason.setReason("NOQTY");
            transReason.setReasonCode("SPLIT");
            transReason.setResponsibility(userId);
            transReason.setTransQty1(lot.getQty1());
            transReason.setTransQty2(lot.getQty2());

            map.put("transReason", transReason);
            map.put("comments", "");
        }
        valueMap.put("terminateMap", map);
        // add for FMI reason Code
        String userName = securityService.getUser(userRrn).getUserName();

        String reason = theform.getReasonCode() + " " + theform.getDeptExt().trim().toUpperCase() + " " +
                userName.toUpperCase() + " " + theform.getReason();

        // 区分Split 和 PILOT Split  #41886
        if (StringUtils.equalsIgnoreCase(theform.getSubSplitType(),"pilot")){
            PiLotView piLotView = wipQueryService.getPiLotViewIdByLotRrn(lot.getLotRrn(),lot.getBasedLotRrn());
            if (ObjectUtils.isNotEmpty(piLotView)) {
                reason = reason + " " + "PILot Number:" + piLotView.getViewId();
            }
        }

        TransReason transReason = new TransReason();
        transReason.setReasonCode(theform.getReasonCode());
        transReason.setReason(reason);
        transReason.setResponsibility(userId);
        // add by yao
        transReason.setTransQty1(remainQty);
        // end add by yao
        valueMap.put("transReason", transReason);
        valueMap.put("lotRrn", String.valueOf(lot.getLotRrn()));
        // end
        Assert.isFalse(checkSplitLotBeforeUpdateDB(valueMap),
                       Errors.create().content("Split Lot info is error!").build());
        lotBeforeIntoServiceCheck(lot, "SO");
        // List<Lot> lockLots = new ArrayList<Lot>();
        // lockLots.add(lot);
        // checkAndCreateLotsTransLock(LocalContext.getUserRrn(), TransactionNames.LOCK_SPLIT, lockLots,
        //                             "split lot, in SplitLotAction by " + userId);
        lotService.splitLotWithTerminate(valueMap);
        //TODO:    old order programer
        //        this.changeLotOrderInfo(lot, childLots, splitType, theform, facilityRrn);

        //TODO: bondding
        //        lotService.antoUpdateChildSapphire(lot, childLots);
        request.setAttribute(SessionNames.COLLECTION_KEY, childLots);
        request.setAttribute(SessionNames.LOT_INFO_FORM_KEY, lotInfoForm);
        theform.setCacheChildLots(WebUtils.getCacheObj2String(childLots));
        theform.setCacheLotInfo(WebUtils.getCacheObj2String(lotInfoForm));
        theform.setCacheLot(WebUtils.getCacheObj2String(lot));

        List<Map> collection = childLots.stream().map(childLot -> {
            String lotId = (String) childLot.get("childLotId");
            return buildLotBaseInfo(lotQueryService.getLot(lotId, LocalContext.getFacilityRrn()));
        }).collect(Collectors.toList());
        request.setAttribute("lotId", lot.getLotId());
        request.setAttribute("collection", collection);

        setActionUrl(request);
        return (mapping.findForward("childlotinfo"));// childlotinfo.jsp
        //        return mapping.findForward(Constants.LOTLOCATION_KEY);
    }

    public ActionForward cancelAddChildLot(ActionMapping mapping, SplitMergeInfoForm theform,
                                           HttpServletRequest request) {
        List childLots = (List) WebUtils.getCacheString2Obj(theform.getCacheChildLots());
        LotInfoForm lotInfoForm = (LotInfoForm) WebUtils.getCacheString2Obj(theform.getCacheLotInfo());
        Lot lot = (Lot) WebUtils.getCacheString2Obj(theform.getCacheLot());
        PropertyUtils.copyProperties(lotInfoForm, lot);
        request.setAttribute(SessionNames.COLLECTION_KEY, childLots);
        request.setAttribute(SessionNames.LOT_INFO_FORM_KEY, lotInfoForm);
        theform.setCacheChildLots(WebUtils.getCacheObj2String(childLots));
        theform.setCacheLotInfo(WebUtils.getCacheObj2String(lotInfoForm));
        theform.setCacheLot(WebUtils.getCacheObj2String(lot));
        initLotBaseInfoJspForSplit(request, lotInfoForm);

        setActionUrl(request);
        return (mapping.findForward("init"));
    }

    private Map validatePermanentSplit(SplitMergeInfoForm theform, Map item) {
        long facilityRrn = LocalContext.getFacilityRrn();
        if (theform.getChangeProcessFlag().equals("1")) {
            Assert.isFalse((theform.getNewProductId() == null) || theform.getNewProductId().trim().equals(""),
                           Errors.create().content("product is required when changeprocess is needed").build());
            if (theform.getOrder_flg().equalsIgnoreCase("1")) {
                item.put("changeAcutl", "1");
            } else if (theform.getOrder_flg().equalsIgnoreCase("0")) {
                item.put("changeAcutl", "0");
            }
            item.put("changeProcessFlag", "TRUE");
            item.put("newProductId", theform.getNewProductId().trim().toUpperCase());
            item.put("productRrn", new Long(getInstanceRrn(theform.getNewProductId().trim().toUpperCase(),
                                                           getNamedSpace(ObjectList.PRODUCT_KEY, facilityRrn),
                                                           ObjectList.PRODUCT_KEY)));

            if ((theform.getNewTechnologyId() == null) || theform.getNewTechnologyId().trim().equals("")) {
                item.put("technologyRrn", getDefaultTechnology((Long) item.get("productRrn")));

                Assert.isFalse(((Long) item.get("technologyRrn")).compareTo(new Long(0)) <= 0,
                               Errors.create().content("No default technology defined").build());
            } else {
                item.put("technologyRrn", new Long(
                        getInstanceRrn(theform.getNewTechnologyId(), getNamedSpace(ObjectList.WFL_KEY, facilityRrn),
                                       ObjectList.WFL_KEY)));

                // check if technology is valid for product specified
                Assert.isTrue(isProductProcessBined(MapUtils.getLongValue(item, "productRrn"),
                                                    MapUtils.getLongValue(item, "technologyRrn")),
                              Errors.create().content("Invalid technology").build());
            }

            item.put("newTechnologyId", theform.getNewTechnologyId());
            // add for check
            Assert.isFalse(theform.getRouteId() == null || theform.getRouteId().trim().equalsIgnoreCase(""),
                           Errors.create().content("SubPlan ID can not be null").build());
            item.put("newRouteId", theform.getRouteId());
            item.put("newOperationId", theform.getOperationId());
            long opRrn = getInstanceRrn(theform.getOperationId(), facilityRrn, ObjectList.OPERATION_KEY);
            item.put("newOperationDesc", getInstanceDesc(opRrn));
            // FMI Code, delete, yunsong 2014-10-12
            // item.put("actulFlg", theform.getOrder_flg().toString());
            // item.put("orderId", theform.getOrder_Id().toString());
            item.put("actulFlg", "");
            item.put("orderId", "");
        } else {
            item.put("changeProcessFlag", "FALSE");
            item.put("changeAcutl", "-1");
        }

        return item;
    }

    private void isDeleteValidation(HttpServletRequest request, SplitMergeInfoForm theform, LotInfoForm lotInfoForm) {
        Assert.isFalse(theform.getLotId().equals(lotInfoForm.getLotId()),
                       Errors.create().key(MessageIdList.CHILD_LOT_ID_EXISTS).content("The Child Lot ID already existed!").build());

        // pilot 母批数量不足 #42071
        PiLotView piLotView = wipQueryService.getPiLotViewIdByLotRrn(lotInfoForm.getLotRrn(),lotInfoForm.getBasedLotRrn());
        if (ObjectUtils.isNotEmpty(piLotView) && theform.getQty1() >= theform.getRemainQty()){
            Assert.isFalse((request.getParameter("targetListValues") != null) && (theform.getQty1() != null) &&
                                   (this.parseJsonStrAndRemoveIdlePostion(request.getParameter("targetListValues"))
                                        .size() != theform.getRemainQty().doubleValue() - 1) &&
                                   lotInfoForm.getTrackUnitFlag().equalsIgnoreCase("1"),
                           Errors.create().key(MessageIdList.LOT_AT_LEAST_1_WAFER)
                                 .content("Parent lot at least 1 wafer!").build());
            theform.setQty1(theform.getRemainQty().doubleValue() - 1);
        } else {
            Assert.isFalse((request.getParameter("targetListValues") != null) && (theform.getQty1() != null) &&
                                   (this.parseJsonStrAndRemoveIdlePostion(request.getParameter("targetListValues"))
                                        .size() != theform.getQty1().doubleValue()) &&
                                   lotInfoForm.getTrackUnitFlag().equalsIgnoreCase("1"),
                           Errors.create().key(MessageIdList.SPLITLOT_SELECTED_QUANTITY_NOT_EQUAL)
                                 .content("The Quantity selected not equal to input!").build());
        }

        if (!(lotInfoForm.getSplitType().equals(LocationNames.PERMANENT) ||
                lotInfoForm.getSplitType().equals(LocationNames.PERMANENT_UP))) {
            Assert.isFalse(theform.getRouteId() == null || theform.getRouteId().trim().equals(""),
                           Errors.create().content("SubPlan ID is required when Temporary Split Lot!").build());
        }
        if (lotInfoForm.getSplitType().equals(LocationNames.PERMANENT) ||
                lotInfoForm.getSplitType().equals(LocationNames.PERMANENT_UP)) {
            if (theform.getChangeProcessFlag().equals(TRUE)) {
                Assert.isFalse((theform.getNewProductId() == null) || theform.getNewProductId().trim().equals(""),
                               Errors.create().content("product is required when change process is needed").build());
                theform.setNewProductId(getValidateId(theform.getNewProductId(), ObjectList.PRODUCT_KEY));
                theform.setNewTechnologyId(getValidateId(theform.getNewTechnologyId(), ObjectList.WFL_KEY));
                if (StringUtils.isNotEmptyTrim(request.getParameter("routeId"))) {
                    theform.setRouteId(request.getParameter("routeId"));
                }
                theform.setOperationId(getValidateId(theform.getOperationId(), ObjectList.OPERATION_KEY));
            }
        } else {
            if (StringUtils.isNotEmptyTrim(request.getParameter("routeId"))) {
                theform.setRouteId(request.getParameter("routeId"));
            }
            theform.setOperationId(getValidateId(theform.getOperationId(), ObjectList.OPERATION_KEY));
        }
    }

    private void initLotBaseInfoJspForSplit(HttpServletRequest request, LotInfoForm lotInfoForm) {
        long facilityRrn = LocalContext.getFacilityRrn();
        request.setAttribute(LOT_SEARCH_TYPE_KEY, LOT_DEFAULT_SEARCH_TYPE);
        request.setAttribute(CARRIER_SEARCH_TYPE_KEY, CARRIER_DEFAULT_SEARCH_TYPE);
        request.setAttribute(LOT_READONLY_KEY, true);
        String lotId = lotInfoForm.getLotId();
        Map lotBaseInfo = buildLotBaseInfo(lotQueryService.getLot(lotId, facilityRrn));
        request.setAttribute("lotBaseInfo", lotBaseInfo);
    }

    private boolean checkSplitLotBeforeUpdateDB(HashMap valueMap) {
        //TODO :  fix   not use Collection
        boolean errorFlag = false;
        Lot _lot = (Lot) valueMap.get("lot");
        Lot lot = lotQueryService.getLot(_lot.getLotRrn());
        Collection childLots = (Collection) valueMap.get("childLots");
        Collection _unitsOfParentLot = (Collection) valueMap.get("unitOfParent");
        Collection pLotUnitsOfDB = wipQueryService.getUnitListByLot(lot.getLotRrn());
        Collection unitsOfParentLot = new ArrayList();
        unitsOfParentLot.addAll(_unitsOfParentLot);
        Iterator cLots = childLots.iterator();
        while (cLots.hasNext()) {
            Map cLot = (Map) cLots.next();
            Collection cunits = (Collection) cLot.get("units");
            Double cSplitQty = (Double) cLot.get("splitQty");
            if (cunits.size() != cSplitQty.intValue()) {// 子批分批数量和实际的晶圆数量不符
                return true;
            } else {
                unitsOfParentLot.addAll(cunits);
            }
        }
        if (unitsOfParentLot.size() != pLotUnitsOfDB.size()) {// 分批后子批晶圆数量+分批后母批晶圆数量 不等于 分批前母批总晶圆数量
            return true;
        } else {
            // 1.检查子批,母批片号是否与数据库一致 ;
            // 2.检查合批位置是否正确
            Iterator dbIts = pLotUnitsOfDB.iterator();
            while (dbIts.hasNext()) {
                Map dbUnit = (Map) dbIts.next();
                Long dbUnitRrn = MapUtils.getLong(dbUnit, "unitRrn");
                String dbUnitId = MapUtils.getString(dbUnit, "unitId");
                boolean isHasUnit = false;
                Iterator its = unitsOfParentLot.iterator();
                while (its.hasNext()) {
                    Map unit = (Map) its.next();
                    Long unitRrn = MapUtils.getLong(unit, "unitRrn");
                    String unitId = MapUtils.getString(unit, "unitId");
                    if (dbUnitRrn.longValue() == unitRrn.longValue() && StringUtils.equals(dbUnitId, unitId)) {
                        isHasUnit = true;
                    }
                }
                // 没有匹配到相应的unit
                if (!isHasUnit) {
                    return true;
                }
            }
        }

        return errorFlag;
    }

    protected void setActionUrl(HttpServletRequest request) {
        request.setAttribute(ACTION_URL_KEY, "splitLot.do");
    }

    protected void childPiLotInfo(SplitMergeInfoForm theform, Lot lot) {

    }

}