ExchangePCDAction.java

package com.mycim.webapp.actions.operation.run;

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.lang.StringUtils;
import com.mycim.framework.utils.lang.collections.MapUtils;
import com.mycim.utils.WipUtils;
import com.mycim.valueobject.MessageIdList;
import com.mycim.valueobject.ObjectList;
import com.mycim.valueobject.consts.*;
import com.mycim.valueobject.ems.Carrier;
import com.mycim.valueobject.sorter.SortJobBean;
import com.mycim.valueobject.sys.ReferenceFileDetail;
import com.mycim.valueobject.wip.Job;
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.WipSetupAction;
import com.mycim.webapp.forms.LbrdLotInfoForm;
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.*;

/**
 * @author Johnson.Wang
 * @version 6.0.0
 * @date 2019/10/9
 **/
public class ExchangePCDAction extends WipSetupAction {

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

        LbrdLotInfoForm theform = (LbrdLotInfoForm) form;
        Map parameters = (Map) request.getAttribute(SessionNames.PARAMETERSINFO_KEY);
        if (MapUtils.isEmpty(parameters)) {
            parameters = (HashMap) WebUtils.getCacheString2Obj(theform.getCacheParametersInfo());
        }
        Assert.isFalse(MapUtils.isEmpty(parameters), Errors.create().content("Parameters are not enough!").build());

        String cacheJob = theform.getCacheJob();
        String cacheCollection = theform.getCacheCollection();
        if (StringUtils.isEmpty(cacheJob)) {
            cacheJob = WebUtils.getCacheObj2String(request.getAttribute(SessionNames.JOB_KEY));
            theform.setCacheJob(cacheJob);
        }
        if (StringUtils.isEmpty(cacheCollection)) {
            cacheCollection = WebUtils.getCacheObj2String(request.getAttribute(SessionNames.COLLECTION_KEY));
            theform.setCacheCollection(cacheCollection);
        }

        Job job = (Job) WebUtils.getCacheString2Obj(cacheJob);
        Collection lots = (Collection) WebUtils.getCacheString2Obj(cacheCollection);

        Assert.isFalse(job == null || lots == null, Errors.create().content("Parameters are not enough!").build());

        if (StringUtils.isNotEmpty(WebUtils.getParameter("exchangePCD", request))) {
            return exchangePCD(mapping, form, request, response);
        } else if (StringUtils.isNotEmpty(WebUtils.getParameter("modify", request))) {
            return buildUnitInfo(mapping, (LbrdLotInfoForm) form, request);
        } else {
            return handleExchange(mapping, form, request, response);
        }
    }

    private ActionForward handleExchange(ActionMapping mapping, ActionForm form, HttpServletRequest request,
                                         HttpServletResponse response) throws Exception {
        List<Map> lots = (List<Map>) request.getAttribute(SessionNames.COLLECTION_KEY);
        HashMap parameters = (HashMap) request.getAttribute(SessionNames.PARAMETERSINFO_KEY);

        List lotsinfoList = new ArrayList();

        for (Map lotMap : lots) {

            long lotRrn = MapUtils.getLongValue(lotMap, "lotRrn");
            Lot lot = lotQueryService.getLot(lotRrn);

            if (StringUtils.equals(LotStatus.PROCESSED, lot.getLotStatus())) {
                parameters.put(SessionNames.RUNSTEP_FLAG, "0");
                return mapping.findForward("workflow");
            }

            Carrier carrier = carrierService.getCarrier(lot.getCarrierRrn());
            Map lotInfo = new HashMap();
            BeanUtils.copyBeanToMap(lotInfo, lot);
            lotInfo.put("flowSeq", ctxExecService.getFlowSeqByProcessInfo(lotInfo));
            lotInfo.putAll(lotMap);

            String targetCSTType = lotQueryService.getToCarrierTypeForChange(lot);

            SortJobBean sortJobBean = sorterQueryService.getSortJobListByCarrierRrn(carrier.getInstanceRrn());
            if (sortJobBean != null && sortJobBean.getMainJobRrn() > 0 &&
                    StringUtils.equalsIgnoreCase(SorterEnum.Constant.EXCHANGE, sortJobBean.getJobType())) {
                //跳过传统交换
                continue;
            }

            String processLocation = specService
                    .getProcessLocation(lot.getProcessRrn(), lot.getProcessVersion(), lot.getRouteRrn(),
                                        lot.getRouteVersion(), lot.getOperationRrn());

            // 检查是否自动切换cassette type #42535
            if (carrierService.checkSwitchCarrierType(processLocation)) {
                carrierService.autoExchangePCDType(lot.getCarrierRrn());
                continue;
            }

            if (StringUtils.equalsIgnoreCase(targetCSTType, carrier.getObjectSubtype()) ||
                    lot.getAutoSplitMergFlag() == 1) {//
                // 不需要交换的cassette 不交换
                continue;
            }
            lotInfo.put("targetCSTType", targetCSTType);
            lotInfo.put("currentCSTType", carrier.getObjectSubtype());
            lotInfo.put("currentProcessLocation",
                        ctxExecService.getCurrentProcessLocation(LocalContext.getFacilityRrn(), lot));
            lotsinfoList.add(lotInfo);
        }

        if (lotsinfoList.isEmpty()) {// 没有需要交换的cassette 直接到下一步
            parameters.put(SessionNames.RUNSTEP_FLAG, "0");
            request.getRequestDispatcher(mapping.findForward("workflow").getPath()).forward(request, response);
            return null;
        }
        request.setAttribute("lotsinfoList", lotsinfoList);
        setCache4WFL1(request, form);
        return mapping.getInputForward();
    }

    private ActionForward buildUnitInfo(ActionMapping mapping, LbrdLotInfoForm form,
                                        HttpServletRequest request) throws Exception {
        List<Map> lots = (List<Map>) WebUtils.getCacheString2Obj(form.getCacheCollection());
        HashMap parameters = (HashMap) WebUtils.getCacheString2Obj(form.getCacheParametersInfo());
        List<String> carrierIds = new ArrayList<String>();

        List<Map> transInfo = new ArrayList<Map>();

        Map transMap;
        List<Lot> lockLots = new ArrayList<Lot>();
        for (Map lotMap : lots) {
            transMap = new HashMap();

            Lot lot = lotQueryService.getLot(MapUtils.getLongValue(lotMap, "lotRrn"));

            String carrierId = WebUtils.getParameterUpperCase("carrierId" + lot.getLotId(), request);

            // 如果目标晶周与当前晶周类型以及category 一致,可以不做交换

            Carrier currentCarrier = carrierService.getCarrier(lot.getCarrierRrn());

            String targetCSTType = lotQueryService.getToCarrierTypeForChange(lot);

            Boolean ignoreChangePCD = StringUtils.equalsIgnoreCase(targetCSTType, currentCarrier.getObjectSubtype());

            if (ignoreChangePCD) {
                continue;
            }

            Assert.isFalse(StringUtils.isEmpty(carrierId),
                           Errors.create().key(MessageIdList.CASSETTE_EMPTY).content("Cassette cannot be empty")
                                 .build());

            Assert.isFalse(carrierIds.contains(carrierId),
                           Errors.create().key(MessageIdList.CASSETTE_CANNOT_REPEAT).content("Cassette cannot repeat")
                                 .build());

            Long carrrierRrn = carrierService.getCarrierRrnForLot(LocalContext.getFacilityRrn(), lot, carrierId);

            Carrier carrier = carrierService.getCarrier(carrrierRrn);

            carrierIds.add(carrierId);

            transMap = BeanUtils.copyBeanToMap(lot);

            transMap.put("sourceListValue",
                         parseToJsonString(wipQueryService.getUnitListByCarrier(currentCarrier.getInstanceRrn())));

            transMap.put("targetListValue", parseToJsonString(wipQueryService.getUnitListByCarrier(carrrierRrn)));

            transMap.put("targetCarrierRrn", carrier.getInstanceRrn());
            transMap.put("targetCarrierId", carrierId);
            transMap.put("currentCarrierId", currentCarrier.getInstanceId());
            transMap.put("maxSize", currentCarrier.getSlotCount());
            transMap.put("targetMaxSize", carrier.getSlotCount());
            transMap.put("currentProcessLocation",
                         ctxExecService.getCurrentProcessLocation(LocalContext.getFacilityRrn(), lot));

            transMap.put("toDefaultPosition",
                         currentCarrier.getSlotCount() == 13 && carrier.getSlotCount() == 25);// cst
            // 13
            // 换到cst25
            // 要回到尾标位置
            /*
             * Boolean canDropTarget = StringUtils.equalsIgnoreCase(currentCarrier.getObjectSubtype(),
             * CarrierType.CST25.toString()) && StringUtils.equalsIgnoreCase(carrier.getObjectSubtype(),
             * CarrierType.CST13.toString());
             */// csrt25
            // 换到cst13需要可以拖动

            // 换到cst25
            // 要回到尾标位置
            Boolean canDropTarget = currentCarrier.getSlotCount() == 25 && carrier.getSlotCount() == 13;// csrt25
            transMap.put("canDropTarget", canDropTarget);// CST25 与cst13 交换时可以拖拽
            lockLots.add(lot);
            transInfo.add(transMap);
        }
        //        checkAndCreateLotsTransLock(LocalContext.getUserRrn(), TransactionNames.LOCK_MOVEOUT,
        //        lockLots,
        //                                    "moveOut-buildUnitInfo in ExchangePCDAction by: "
        //                                    + LocalContext.getUserId());
        request.setAttribute("transInfo", transInfo);
        return mapping.findForward(Constants.MODIFY_KEY);
    }

    private ActionForward exchangePCD(ActionMapping mapping, ActionForm form, HttpServletRequest request,
                                      HttpServletResponse response) throws Exception {
        LbrdLotInfoForm theform = (LbrdLotInfoForm) form;
        List<Map<String, Object>> lots = (List<Map<String, Object>>) WebUtils
                .getCacheString2Obj(theform.getCacheCollection());
        HashMap parameters = (HashMap) WebUtils.getCacheString2Obj(theform.getCacheParametersInfo());
        List<String> carrierIds = new ArrayList<String>();

        List<Map> transInfo = new ArrayList<Map>();

        Map transMap;

        String[] targetListValuesParameters = request.getParameterValues("targetListValues");

        // List<Lot> lockLots = new ArrayList<Lot>();
        int i = 0;

        for (Map lotMap : lots) {
            transMap = new HashMap();

            Lot lot = lotQueryService.getLot(MapUtils.getLongValue(lotMap, "lotRrn"));

            String carrierId = WebUtils.getParameterUpperCase("carrierId" + lot.getLotId(), request);
            Carrier targetcarrier1 = carrierService.getCarrier(LocalContext.getFacilityRrn(), carrierId);

            // 如果目标晶周与当前晶周类型以及category 一致,可以不做交换

            Carrier currentCarrier = carrierService.getCarrier(lot.getCarrierRrn());

            String targetCSTType = lotQueryService.getToCarrierTypeForChange(lot);

            Boolean ignoreChangePCD = StringUtils.equalsIgnoreCase(targetCSTType, currentCarrier.getObjectSubtype());
            Assert.isFalse(targetcarrier1.getInstanceRrn() == lot.getCarrierRrn(),
                           Errors.create().key(MessageIdList.CARRIER_CARRIER_IS_NOT_CONSISTENT)
                                 .content("批次实际晶舟与操作不符," + "请回到批次作业界面重试!").build());

            if (ignoreChangePCD) {
                continue;
            }

            Assert.isFalse(StringUtils.isEmpty(carrierId),
                           Errors.create().key(MessageIdList.CASSETTE_EMPTY).content("Cassette cannot be empty")
                                 .build());

            Assert.isFalse(carrierIds.contains(carrierId),
                           Errors.create().key(MessageIdList.CASSETTE_CANNOT_REPEAT).content("Cassette cannot repeat")
                                 .build());

            Long carrrierRrn = carrierService.getCarrierRrnForLot(LocalContext.getFacilityRrn(), lot, carrierId);

            Carrier carrier = carrierService.getCarrier(carrrierRrn);
            //check sortJob
            checkWaitJobs(carrrierRrn, 0L, 0L, null);
            carrierIds.add(carrierId);
            lot.setLotComments("Exchange carrier, initial carrier: " + currentCarrier.getInstanceId());
            lot.setTransPerformedby(LocalContext.getUserId());
            lot.setTransId(TransactionNames.EXCHANGE_KEY);
            transMap.put("lot", lot);
            List<Map<String, Object>> targetListValues = parseJsonStrAndRemoveIdlePostion(
                    targetListValuesParameters[i]);
            transMap.put("unitsList", targetListValues);
            transMap.put("targetCarrierRrn", carrier.getInstanceRrn());
            transMap.put("facilityRrn", LocalContext.getFacilityRrn());
            transMap.put("user", LocalContext.getUserId());
            transInfo.add(transMap);
            // lockLots.add(lot);
            i++;
        }
        // checkAndCreateLotsTransLock(LocalContext.getUserRrn(), TransactionNames.LOCK_EXCHANGE_PCD, lockLots,
        //                             "exchangePCD in ExchangePCDAction by: " + LocalContext.getUserId());
        carrierService.exchangePCD(transInfo);
        // removeLotLockWhenTransError(LocalContext.getUserRrn(), lockLots, TransactionNames.LOCK_EXCHANGE_PCD,
        //                             "exchangePCD Over in ExchangePCDAction by: " + LocalContext.getUserId());


        parameters.put(SessionNames.RUNSTEP_FLAG, "0");
        if (StringUtils.isNotEmpty(theform.getCacheCurrentlots())) {
            request.setAttribute("currentlots", WebUtils.getCacheString2Obj(theform.getCacheCurrentlots()));
        } else {
            request.setAttribute("currentlots", request.getAttribute("currentlots"));
        }
        request.setAttribute(SessionNames.JOB_KEY, WebUtils.getCacheString2Obj(theform.getCacheJob()));
        request.setAttribute(SessionNames.PARAMETERSINFO_KEY, parameters);
        request.setAttribute(SessionNames.COLLECTION_KEY, lots);
        request.getRequestDispatcher(mapping.findForward("workflow").getPath()).forward(request, response);
        return null;
    }

    private void setCache4WFL1(HttpServletRequest request, ActionForm form) {
        LbrdLotInfoForm theform = (LbrdLotInfoForm) form;
        theform.setCacheCurrentlots(WebUtils.getCacheObj2String(request.getAttribute("currentlots")));
        theform.setCacheJob(WebUtils.getCacheObj2String(request.getAttribute(SessionNames.JOB_KEY)));
        theform.setCacheParametersInfo(
                WebUtils.getCacheObj2String(request.getAttribute(SessionNames.PARAMETERSINFO_KEY)));
        theform.setCacheCollection(WebUtils.getCacheObj2String(request.getAttribute(SessionNames.COLLECTION_KEY)));
        String runcardLotId = WebUtils.getParameter("runcardLotId", request);
        if (StringUtils.isNotBlank(runcardLotId)) {
            request.setAttribute("runcardLotId", runcardLotId);
        }
    }

}