LotsDeBondedAction.java

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

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.BeanUtils;
import com.mycim.framework.utils.lang.StringUtils;
import com.mycim.framework.utils.lang.collections.CollectionUtils;
import com.mycim.framework.utils.lang.collections.MapUtils;
import com.mycim.framework.utils.lang.math.NumberUtils;
import com.mycim.utils.WipUtils;
import com.mycim.valueobject.ObjectList;
import com.mycim.valueobject.bas.NamedObject;
import com.mycim.valueobject.bas.Relation;
import com.mycim.valueobject.consts.LinkTypeList;
import com.mycim.valueobject.consts.SessionNames;
import com.mycim.valueobject.ems.Carrier;
import com.mycim.valueobject.wip.*;
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.*;

public class LotsDeBondedAction extends WipSetupAction {

    @Override
    public ActionForward init(ActionMapping mapping, ActionForm form, HttpServletRequest request,
                              HttpServletResponse response) throws Exception {
        LbrdLotInfoForm theform = (LbrdLotInfoForm) form;
        Job job = (Job) request.getAttribute(SessionNames.JOB_KEY);
        if (job == null && theform.getCacheJob() != null) {
            job = (Job) WebUtils.getCacheString2Obj(theform.getCacheJob());
            request.setAttribute(SessionNames.JOB_KEY, job);
        }
        Collection lots = (Collection) request.getAttribute(SessionNames.COLLECTION_KEY);
        if (lots == null && theform.getCacheCollection() != null) {
            lots = (Collection) WebUtils.getCacheString2Obj(theform.getCacheCollection());
            request.setAttribute(SessionNames.COLLECTION_KEY, lots);
        }
        HashMap parameters = (HashMap) request.getAttribute(SessionNames.PARAMETERSINFO_KEY);
        if (parameters == null && theform.getCacheParametersInfo() != null) {
            parameters = (HashMap) WebUtils.getCacheString2Obj(theform.getCacheParametersInfo());
            request.setAttribute(SessionNames.PARAMETERSINFO_KEY, parameters);
        }

        List lotsinfoList = new ArrayList();
        for (Iterator it = lots.iterator(); it.hasNext(); ) {// 只有一个批次
            Map lotMap = (HashMap) it.next();
            long targetLotRrn = MapUtils.getLongValue(lotMap, "lotRrn");
            Lot lot = lotQueryService.getLot(targetLotRrn);
            List bondedLots = buildBondingLots(lot);
            if (bondedLots.isEmpty()) {
                parameters.put(SessionNames.RUNSTEP_FLAG, "0");
                request.getRequestDispatcher(mapping.findForward("workflow").getPath() + "?action=init")
                       .forward(request, response);
                return null;
                //return mapping.findForward("workflow");
            }
            Map lotinfo = new HashMap();
            lotinfo.put("targetLotId", lot.getLotId());
            lotinfo.put("targetLotRrn", targetLotRrn);
            lotinfo.put("bondedLots", bondedLots);
            lotsinfoList.add(lotinfo);
        }
        request.setAttribute("lotsinfoList", lotsinfoList);
        setCache4WFL(request, form);
        return mapping.getInputForward();
    }


    public ActionForward lotsDeBonded(ActionMapping mapping, ActionForm form, HttpServletRequest request,
                                      HttpServletResponse response) throws Exception {
        LbrdLotInfoForm theform = (LbrdLotInfoForm) form;
        // Collection lots = (Collection) session.getAttribute(SessionNames.COLLECTION_KEY);
        Collection lots = (Collection) WebUtils.getCacheString2Obj(theform.getCacheCollection());
        request.setAttribute(SessionNames.COLLECTION_KEY, lots);
        Long facilityRrn = LocalContext.getFacilityRrn();
        String userId = LocalContext.getUserId();
        // HashMap parameters = (HashMap) session.getAttribute(SessionNames.PARAMETERSINFO_KEY);
        HashMap parameters = (HashMap) WebUtils.getCacheString2Obj(theform.getCacheParametersInfo());
        request.setAttribute(SessionNames.PARAMETERSINFO_KEY, parameters);
        Job job = (Job) WebUtils.getCacheString2Obj(theform.getCacheJob());
        request.setAttribute(SessionNames.JOB_KEY, job);
        List jobLots = new ArrayList();
        List<Map> sourceLotInfo = new ArrayList();
        int i = 0;
        boolean haveBondLotFlag = false;
        Set<Long> sourceLotRrns = new HashSet<Long>();
        List<String> carrierIds = new ArrayList<String>();

        for (Iterator it = lots.iterator(); it.hasNext(); ) {
            i = 0;

            Map lotMap = (HashMap) it.next();
            Lot lot = lotQueryService.getLot(MapUtils.getLongValue(lotMap, "lotRrn"));
            Collection units = wipQueryService.getUnits(new Long(lot.getLotRrn()));
            List<Map> bondedLots = buildBondingLots(lot);
            if (CollectionUtils.isEmpty(bondedLots)) {// 是否bond过
                continue;
            } else {
                haveBondLotFlag = true;
            }
            if (CollectionUtils.isEmpty(units)) {// 批次没有圆片信息
                continue;
            }

            for (Map lotInfo : bondedLots) {
                i++;
                Lot sourceLot = lotQueryService.getLot(MapUtils.getLongValue(lotInfo, "sourceLotRrn"));
                sourceLotRrns.add(sourceLot.getLotRrn());

                Long sourceDebondoperationRrn = getSourceDebondStep(lot, sourceLot);

                Assert.isFalse(sourceDebondoperationRrn == 0,
                               Errors.create().content("Product debond info setup is not corrrect").build());

                Map nodeMap = wipQueryService.getNodeInfoByWflTree(sourceLot, sourceDebondoperationRrn, false);

                String routeId = MapUtils.getString(nodeMap, "routeId");
                sourceLot.setRouteId(routeId);

                long routeRrn = MapUtils.getLongValue(nodeMap, "routeRrn");
                sourceLot.setRouteRrn(new Long(routeRrn));

                String operationId = MapUtils.getString(nodeMap, "operationId");
                sourceLot.setOperationId(operationId);

                long operationRrn = MapUtils.getLongValue(nodeMap, "operationRrn");
                sourceLot.setOperationRrn(new Long(operationRrn));
                String stepPath = MapUtils.getString(nodeMap, "stepInfo");

                Map tempInfo = getStepsInfoByLot(sourceLot, sourceLot.getProcessRrn(), stepPath);

                sourceLot.setProcessStepVersion(MapUtils.getString(tempInfo, "processStepVersion"));
                // 验证晶舟信息
                String carrierId = WebUtils.getParameterUpperCase("carrierId" + lot.getLotId() + i, request);
                Assert.isFalse(carrierIds.contains(carrierId),
                               Errors.create().content("Cassette cannot repeat").build());
                Long carrrierRrn = carrierService.getCarrierRrnForLot(facilityRrn, sourceLot, carrierId);

                Carrier carrier = carrierService.getCarrier(carrrierRrn);

                carrierIds.add(carrierId);

                // 重构待解绑批次信息
                Map sourceLotMap = builDebondLot(facilityRrn, userId, sourceLot, stepPath);
                sourceLotMap.put("carrier", carrier);
                sourceLotMap.put("lot", lot);
                sourceLotInfo.add(sourceLotMap);
                jobLots.add(new Long(lot.getLotRrn()));
                jobLots.add(new Long(sourceLot.getLotRrn()));
            }
        }
        if (haveBondLotFlag && CollectionUtils.isNotEmpty(sourceLotRrns)) {
            buildIdenticalLot4DeBond(sourceLotInfo);

            for (Long sourceLotRrn : sourceLotRrns) {
                Lot sourceLot = lotQueryService.getLot(sourceLotRrn);
                updateProductSapphireInfo(sourceLot);
                lotService.handlePreFutureHold(new HandleLot(sourceLot, "", null));
            }
        }
        parameters.put(SessionNames.RUNSTEP_FLAG, "0");
        request.getRequestDispatcher(mapping.findForward("workflow").getPath() + "?action=init")
               .forward(request, response);
        return null;
        //return mapping.findForward("workflow");
    }

    @Override
    public void setCache4WFL(HttpServletRequest request, ActionForm form) {
        LbrdLotInfoForm theform = (LbrdLotInfoForm) form;
        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)));
    }

    private void buildIdenticalLot4DeBond(List<Map> sourceUnits) {
        wipService.buildIdenticalLot4DeBond(sourceUnits);
    }

    /**
     * 功能 #8856 Bonding批次move out 解绑的时候算一次数。当前次数需要加一 ,判断最大使用时间,跟次数。没有最大时间的话就不判断。 超过。则需要把批次hold住。
     *
     * @param sappLot
     */
    private void updateProductSapphireInfo(Lot sappLot) {
        String language = I18nUtils.getCurrentLanguage().toString();
        NamedObject object = baseService.getNamedObject(sappLot.getProductRrn());
        // 如果是Bonding类型
        if (StringUtils.equals(object.getObjectType(), ObjectList.SAPPHIRE)) {
            LotSapphreInfo lotSapphreInfo = lotQueryService.getLotSapphreInfo(sappLot.getLotRrn());
            // 当前次数
            Long actualCount = lotSapphreInfo.getActualCount() + 1;
            // 最大使用次数
            Long targetCount = lotSapphreInfo.getTargetCount();
            // 最大使用时间
            Long expiredDatelot = lotSapphreInfo.getExpiredDate();
            // 批次是否超过设定时间(当前时间-创建时间<设定时间)
            boolean outTime =
                    System.currentTimeMillis() - sappLot.getCreatedTimestamp().getTime() >= expiredDatelot * 1000;
            // 批次是否超过次数
            boolean outCount = targetCount <= actualCount;
            HashMap holdInfo = new HashMap();
            holdInfo.put("lotRrn", new Long(sappLot.getLotRrn()).toString());
            holdInfo.put("lotId", sappLot.getLotId());
            holdInfo.put("lotStatus", sappLot.getLotStatus());
            holdInfo.put("transPerformedBy", "SYSTEM");
            holdInfo.put("holdBy", "0");
            holdInfo.put("holdPassword", "");
            holdInfo.put("transComments", "");
            holdInfo.put("operation", sappLot.getOperationId());
            holdInfo.put("holdcode", TransReason.reasonCode.BONDERROR.name());
            TransReason transReason = new TransReason();
            transReason.setReasonCategory(TransReason.reasonCode.BONDERROR.name());
            transReason.setReasonCode(TransReason.reasonCode.BONDERROR.name());

            if (StringUtils.equalsIgnoreCase("CN", language)) {
                transReason.setReason("批次超过最大使用时间或者最大使用次数");
            } else {
                transReason.setReason("Lots exceed maximum usage time or maximum usage times.");
            }
            // 没有超过则次数加1
            lotSapphreInfo.setActualCount(actualCount);
            if (lotSapphreInfo.getLotRrn() > 0) {
                lotService.updateLotSapphreInfo(lotSapphreInfo);
            }
            if (expiredDatelot > 0 && outTime) {
                String errorMsg = "";
                if (StringUtils.equalsIgnoreCase("CN", language)) {
                    errorMsg = "批次超过最大使用时间";
                } else {
                    errorMsg = "Lots exceed maximum usage time or maximum usage times.";
                }
                transReason.setReason(errorMsg);
                holdInfo.put("transReason", transReason);
                lotService.holdLot(holdInfo);
                throw new SystemIllegalArgumentException(Errors.create().content(errorMsg).build());
            } else if ((targetCount > 0 && outCount)) {// 超过则hold住 为空则不判断
                String errorMsg = "";
                if (StringUtils.equalsIgnoreCase("CN", language)) {
                    errorMsg = "批次超过最大使用次数";
                } else {
                    errorMsg = "Lots exceed maximum usage time or maximum usage frequency.";
                }
                transReason.setReason(errorMsg);
                holdInfo.put("transReason", transReason);
                lotService.holdLot(holdInfo);
                throw new SystemIllegalArgumentException(Errors.create().content(errorMsg).build());
            }
        }
    }

    private List buildBondingLots(Lot lot) {
        List<Bonding> bondingLots;
        List bondingInfo = new ArrayList();
        bondingLots = wipService.getBondingsForDebond(lot.getLotRrn());

        Map map;
        Lot sourceLot;
        if (bondingLots != null) {
            Iterator it = bondingLots.iterator();
            Bonding bonding;
            while (it.hasNext()) {
                bonding = (Bonding) it.next();
                sourceLot = lotQueryService.getLot(bonding.getSourceLotRrn());

                Long sourceDebondoperationRrn = getSourceDebondStep(lot, sourceLot);

                Assert.isFalse(sourceDebondoperationRrn == 0,
                               Errors.create().content("Product debond info setup is not corrrect").build());

                Map nodeMap = wipQueryService.getNodeInfoByWflTree(sourceLot, sourceDebondoperationRrn, false);

                String routeId = MapUtils.getString(nodeMap, "routeId");
                sourceLot.setRouteId(routeId);

                long routeRrn = MapUtils.getLongValue(nodeMap, "routeRrn");
                sourceLot.setRouteRrn(new Long(routeRrn));

                String operationId = MapUtils.getString(nodeMap, "operationId");
                sourceLot.setOperationId(operationId);

                long operationRrn = MapUtils.getLongValue(nodeMap, "operationRrn");
                sourceLot.setOperationRrn(new Long(operationRrn));
                String stepPath = MapUtils.getString(nodeMap, "stepInfo");

                Map tempInfo = getStepsInfoByLot(sourceLot, sourceLot.getProcessRrn(), stepPath);

                sourceLot.setProcessStepVersion(MapUtils.getString(tempInfo, "processStepVersion"));

                map = BeanUtils.copyBeanToMap(bonding);
                map.put("lotCategory", sourceLot.getCreateCategory());
                map.put("carrierType", carrierService.getTargetCarrierTypeByStatus(sourceLot));
                bondingInfo.add(map);
            }
        }
        return bondingInfo;
    }

    private Long getSourceDebondStep(Lot targetLot, Lot sourceLot) {
        Relation relation = new Relation();
        relation.setFromRrn(targetLot.getProductRrn());
        relation.setToRrn(sourceLot.getProductRrn());
        relation.setLinkType(LinkTypeList.PRODUCT_TO_DEBOND);
        relation.setAttributedata1(StringUtils.toString(targetLot.getOperationRrn()));
        relation.setAttributedata2(StringUtils.toString(targetLot.getProcessRrn()));

        Collection<Relation> relations = sysService.getFullRelations(relation);

        if (relations == null || relations.isEmpty()) {
            return 0L;
        }

        for (Relation tmp : relations) {// 只有一条数据
            return NumberUtils.toLong(tmp.getAttributedata3(), 0L);
        }
        return 0L;
    }

}