ReworkLotConfigurationAction.java

/*
 *        @ Copyright 2001 FA Software;
 *        All right reserved. No part of this program may be reproduced or
 *        transmitted in any form or by any means, electronic or
 *        mechanical, including photocopying, recording, or by any
 *        information storage or retrieval system without written
 *        permission from FA Software, except for inclusion of brief
 *        quotations in a review.
 */
package com.mycim.webapp.actions.lot.rework;

import com.fa.sesa.exception.Assert;
import com.fa.sesa.exception.Errors;
import com.fa.sesa.i18n.I18nUtils;
import com.fa.sesa.threadlocal.LocalContext;
import com.mycim.framework.utils.MiscUtils;
import com.mycim.framework.utils.beans.PropertyUtils;
import com.mycim.framework.utils.lang.StringUtils;
import com.mycim.framework.utils.lang.math.NumberUtils;
import com.mycim.utils.WipUtils;
import com.mycim.valueobject.MessageIdList;
import com.mycim.valueobject.ObjectList;
import com.mycim.valueobject.consts.SessionNames;
import com.mycim.valueobject.prp.Context;
import com.mycim.valueobject.prp.ContextValue;
import com.mycim.valueobject.prp.Operation;
import com.mycim.valueobject.wip.HandleLot;
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.lot.LotInfoForm;
import com.mycim.webapp.forms.lot.ReworkLotInfoForm;
import org.apache.commons.collections.MapUtils;
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.HashMap;
import java.util.List;
import java.util.Map;

public class ReworkLotConfigurationAction extends WipSetupAction {

    @Override
    public ActionForward init(ActionMapping mapping, ActionForm form, HttpServletRequest request,
                              HttpServletResponse response) throws Exception {
        ReworkLotInfoForm theform = new ReworkLotInfoForm();
        initLotBaseInfoForJsp(request, false, "HOLD", null);
        Map<String, Object> cachePageInfo = (Map<String, Object>) WebUtils
                .getCacheString2Obj(theform.getCachePageInfo());
        if (cachePageInfo == null) {
            cachePageInfo = new HashMap<String, Object>();
        }
        cachePageInfo.put(SessionNames.CONTEXT_KEY, new Context());
        this.setTheFormSession(theform, request, new Lot(), new LotInfoForm(), cachePageInfo);
        if (StringUtils.isNotBlank(WebUtils.getParameter("initSuccessFlag", request))) {
            WebUtils.setSuccessMsg(request);
        }
        return new ActionForward(mapping.getInput());
    }

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

        initLotBaseInfoForJsp(request, false, "HOLD", null);
        ReworkLotInfoForm theform = (ReworkLotInfoForm) form;

        if (StringUtils.isNotBlank((String) request.getAttribute("target"))) {
            theform.setCacheTarget((String) request.getAttribute("target"));
        }
        Map<String, Object> cachePageInfo = (Map<String, Object>) WebUtils
                .getCacheString2Obj(theform.getCachePageInfo());
        if (cachePageInfo == null) {
            cachePageInfo = new HashMap<String, Object>();
        }

        if (WebUtils.getParameterBoolean(Constants.NAV_KEY, request)) {
            cachePageInfo.put(SessionNames.CONTEXT_KEY, new Context());
            this.setTheFormSession(theform, request, new Lot(), new LotInfoForm(), cachePageInfo);
            return new ActionForward(mapping.getInput());
        }

        // Populate the new valid format planlot/product
        String id = getLotIdFromRequest(request, "byCarrierId");

        // construct lot value object for later use facilityRrn
        Lot lot = lotQueryService.getLot(id, LocalContext.getFacilityRrn());

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

        String msg = "";
        if (StringUtils.equalsIgnoreCase("CN", I18nUtils.getCurrentLanguage().toString())) {
            msg = WebUtils.getParameter("byCarrierId", request) != null ? "晶舟号" : "批次号";
        } else {
            msg = WebUtils.getParameter("byCarrierId", request) != null ? "Cassette Id" : "lot Id";
        }
        Assert.isFalse((lot == null) || (lot.getLotRrn() <= 0),
                       Errors.create().key(MessageIdList.LOT_LOTID_OR_CARRIERID_INCORRECT).content("批次号或晶舟号不正确!")
                             .build());

        Assert.isFalse((lot.getLotStatus() != null) && !lot.getLotStatus().equals(LotStatus.HOLD),
                       Errors.create().key(MessageIdList.LOT_LOT_STATUS_MUSTBE_HOLD).content("批次必须为暂停状态!").build());

        boolean isSingleLot = true;
        List lots = wipQueryService.getLotsByEqpt(" WHERE CARRIER_RRN = ", MiscUtils.parseSQL(lot.getCarrierRrn()));
        if ((lots != null) && (lots.size() > 1)) {
            isSingleLot = false;
        }
        Assert.isTrue(isSingleLot,
                      Errors.create().key(MessageIdList.REWORK_SAME_CARRIER_FOR_LOTS).content("该晶舟被多个批次使用。请先分批!")
                            .build());
        // Copy value object properties to form bean.
        LotInfoForm lotInfo = new LotInfoForm();

        PropertyUtils.copyProperties(lotInfo, lot);
        lotInfo.setRecipePhysicalId(getRecipePhysicalId(lot));
        theform.setLotInfo(lotInfo);

        // get default rework route id
        Operation operation;

        // get default lbrd reference table from operation
        operation = prpService.getOperation(lot.getOperationRrn());
        theform.setReworkRouteId(operation.getExternalReworkWflId());

        String lotReworkFlag = "";

        if (lot.getReworkCategory() == null) {
            lotReworkFlag = "1";
        } else {
            lotReworkFlag = "2";
        }
        request.setAttribute(SessionNames.LOT_INFO_FORM_KEY, lotInfo);

        cachePageInfo.put(SessionNames.LOT_REWORK_FLAG_KEY, lotReworkFlag);
        this.setTheFormSession(theform, request, lot, lotInfo, cachePageInfo);

        // for search "return route id" in next page
        request.setAttribute("stepNumber", lot.getStepNumberInProcess());
        request.setAttribute("lotRrn", new Long(lot.getLotRrn()));
        return new ActionForward(mapping.getInput());
    }

    public ActionForward reworkLotConfiguration(ActionMapping mapping, ActionForm form, HttpServletRequest request,
                                                HttpServletResponse response) {
        Long facilityRrn = LocalContext.getFacilityRrn();
        initLotBaseInfoForJsp(request, true, null, null);

        String id = getLotIdFromRequest(request, "byCarrierId");
        Lot lot = lotQueryService.getLot(id, LocalContext.getFacilityRrn());
        //判断数据库中实际lot是否存在。
        Assert.notNull(lot,
                       Errors.create().key(MessageIdList.REWORK_INVALID_PARAMETERS_LOT_NOT_EXIST).content("无效参数!批次不存在!")
                             .build());
        //判断数据库中 lot 是否为hold 状态
        Assert.isTrue(LotStatus.isHold(lot.getLotStatus()),Errors.create().key(MessageIdList.LOT_LOT_STATUS_MUSTBE_HOLD).content("lot status must be hold !").build());

        //获取情景值 检查是否进行双次rework 并检查是否到达返工最大次数
        ContextValue contextValue =   ctxExecService.getReworkRouteContextValueByLot(lot);
        Assert.notNull(contextValue, Errors.create().key(MessageIdList.REWORK_NO_REWORK_MARK).content(
                "No rework mark or rework path is set on step, Lot cannot" + " " + "be reworked!").build());
        //判断返工次数
        int maxReworkTimes = NumberUtils.toInt(contextValue.getResultValue4());
        String countWay = contextValue.getResultValue6();
        lotQueryService.checkLotUnitReworkSeq(lot,countWay,maxReworkTimes);

        ReworkLotInfoForm theform = (ReworkLotInfoForm) form;
        // ----------------------------------------------------------------action
        // handling
        // if user click the Cancel button
        if (request.getParameter(Constants.CANCEL_KEY) != null) {

            return new ActionForward(mapping.getInput());
        }

        Long returnExecutionRrn = null;
        Long executionRrn = null;
        Long operationRrn = null;
        Integer operationVer = null;
        String processStepVersion = null;
        String returnProcessStepVersion = null;
        String processStepIdVersion = null;
        String trackUnitFlag = null;
        String keepUnitHistoryFlag = null;
        String stageId = null;
        String layerId = null;
        Long borRrn = null;
        String recipeString = null;

        // get rework route info
        long reworkWflRrn = getInstanceRrn(WebUtils.getParameter("reworkRouteId", request),
                                           getNamedSpace(ObjectList.WFL_KEY, facilityRrn), ObjectList.WFL_KEY);

        String stepNumber = request.getParameter("stepNumber");
        Assert.isFalse(StringUtils.isEmpty(stepNumber),
                       Errors.create().key(MessageIdList.REWORK_PLEASE_SELECT_REWORK_STEP_NUMBER).content("请选择返步骤骤号!")
                             .build());
        HashMap tempInfo = (HashMap) this.getStepsInfoByLot(lot, new Long(reworkWflRrn), stepNumber);
        executionRrn = (Long) tempInfo.get("executionRrn");
        operationRrn = (Long) tempInfo.get("operationRrn");

        Assert.isTrue(checkOperationInFacility(operationRrn, facilityRrn),
                      Errors.create().key(MessageIdList.REWORK_IS_NOT_CURRENT_FACILITY).content("新路径/步骤 不在当前车间!")
                            .build());

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

        tempInfo = (HashMap) prpService.getOperationInfo(operationRrn, operationVer);

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

        tempInfo = new HashMap();
        tempInfo.put("operationRrn", operationRrn);
        tempInfo.put("productRrn", lot.getProductRrn());
        tempInfo.put("routeRrn", WipUtils.parseRouteRrn(processStepVersion) + "");
        tempInfo.put("technologyRrn", lot.getProcessRrn());
        tempInfo.put("recipeRrn", null);
        tempInfo.put("lotRrn", new Long(lot.getLotRrn()));
        tempInfo.put("facilityRrn", facilityRrn);

        borRrn = ctxExecService.getBomRrn(tempInfo);

        recipeString = ctxExecService.getRecipeString(tempInfo);
        returnProcessStepVersion = theform.getReturnStepNumber();

        if (lot.getReworkCategory() != null) {
            if (returnProcessStepVersion.indexOf("|") > 0) {
                returnProcessStepVersion = returnProcessStepVersion
                        .substring(returnProcessStepVersion.indexOf("|") + 1);
            }
        }

        Assert.isFalse(returnProcessStepVersion == null ||
                               returnProcessStepVersion != null && returnProcessStepVersion.equals(""),
                       Errors.create().key(MessageIdList.REWORK_PLEASE_SELECT_RETURN_STEP_NUMBER).content("请选择返回步骤号!")
                             .build());
        Map transInfo = new HashMap();
        transInfo.put("reworkWflRrn", new Long(reworkWflRrn));
        transInfo.put("stepNumber", request.getParameter("stepNumber"));
        transInfo.put("lotRrn", new Long(lot.getLotRrn()));
        transInfo.put("lotId", lot.getLotId());
        transInfo.put("productRrn", lot.getProductRrn());
        transInfo.put("processRrn", lot.getProcessRrn());
        transInfo.put("processVersion", lot.getProcessVersion());

        // qty
        transInfo.put("qty", "" + lot.getQty1());

        // toRouteID,returnRouteId

        transInfo.put("executionRrn", executionRrn);
        // transInfo.put("returnExecutionRrn", executionRrn);
        transInfo.put("fromOperation", lot.getOperationId());
        transInfo.put("operationRrn", operationRrn);

        // toOperation
        transInfo.put("operationId", this.getInstanceId(operationRrn.longValue()));

        String returnOperation = request.getParameter("returnOperationId");
        transInfo.put("returnOperationId", returnOperation);
        transInfo.put("operationVer", operationVer);
        transInfo.put("processStepVersion", processStepVersion);
        String routeId = getRouteString(processStepVersion);
        transInfo.put("routeId", routeId);

        transInfo.put("processStepIdVersion", processStepIdVersion);
        transInfo.put("trackUnitFlag", trackUnitFlag);
        transInfo.put("keepUnitHistoryFlag", keepUnitHistoryFlag);
        transInfo.put("stageId", stageId);
        transInfo.put("layerId", layerId);
        transInfo.put("recipeString", recipeString);
        transInfo.put("borRrn", borRrn);

        Map returnMap = this.getStepsInfoByLot(lot, lot.getProcessRrn(), returnProcessStepVersion);
        returnExecutionRrn = (Long) returnMap.get("executionRrn");

        if ((returnProcessStepVersion != null) && !returnProcessStepVersion.equals("")) {
            Map routeMap = new HashMap();
            routeMap.put("Process", lot.getProcessRrn());
            routeMap.put("Route", new Long(
                    getInstanceRrn(theform.getReturnRouteId(), getNamedSpace(ObjectList.WFL_KEY, facilityRrn),
                                   ObjectList.WFL_KEY)));
            routeMap.put("Operation", new Long(
                    getInstanceRrn(theform.getReturnOperationId(), getNamedSpace(ObjectList.OPERATION_KEY, facilityRrn),
                                   ObjectList.OPERATION_KEY)));
            transInfo.put("returnProcessStepVersion",
                          wipWorkflowQueryService.reconstructRouteMap(returnProcessStepVersion, routeMap));
        } else {
            transInfo.put("returnProcessStepVersion", lot.getProcessStepVersion());
        }

        transInfo.put("returnProcessStepVersion4wfl", returnProcessStepVersion);
        String returnRouteId = getRouteString((String) transInfo.get("returnProcessStepVersion"));
        transInfo.put("returnRouteId", returnRouteId);
        transInfo.put("returnExecutionRrn", returnExecutionRrn);

        // transInfo.put("returnProcessStepVersion",returnProcessStepVersion);
        // transInfo.put("returnStepNumber",theform.getReturnStepNumber());
        // transInfo.put("reworkWFLRrn",theform.getReworkWFLRrn());
        transInfo.put("reworkCategory", theform.getReworkCategory());
        transInfo.put("transPerformedBy", LocalContext.getUserId());

        Assert.isFalse(theform.getReworkCode() == null || theform.getReworkCode().trim().length() == 0,
                       Errors.create().key(MessageIdList.REWORK_PLEASE_SELECT_REWORK_CODE).content("请选择返工代码!").build());
        transInfo.put("reasonCode", theform.getReworkCode());
        String reworkCode = StringUtils.isBlank(theform.getReworkCode()) ? "" : theform.getReworkCode();
        String reason = "[" + reworkCode + "]" + sysService
                .referenceDetailExchange("$$REWORK_CODE", theform.getDepartment().trim().toUpperCase(), reworkCode,
                                         "data_1_value");
        transInfo.put("reason", reason);
        transInfo.put("transComments", theform.getLotComments());
        transInfo.put("reworkWflStepPath", lot.getWflStepPath());
        transInfo.put("reworkOperationRrn", lot.getOperationRrn() + "");
        transInfo.put("CHANGE_LOT_STATUS", false + "");
        transInfo.put("reworkProcessStepIdVersion", lot.getProcessStepIdVersion());
        transInfo.put("reworkProcessStepVersion", lot.getProcessStepVersion());
        lotService.reworkLot(transInfo);
        lot = lotQueryService.getLot(lot.getLotId(), LocalContext.getFacilityRrn());
        lotService.handlePreFutureHold(new HandleLot(lot, "", null));

        request.setAttribute("initSuccessFlag", "true");
        WebUtils.setSuccessMsg(request);
        return mapping.findForward("initReworklotselect");
    }

    public String getLotIdFromRequest(HttpServletRequest request, String byCarrierFlag) {
        Long facilityRrn = LocalContext.getFacilityRrn();
        String result = null;
        boolean carrierFlag = request.getParameter(byCarrierFlag) != null;
        String carrierId = carrierFlag ? request.getParameter("carrierId") : StringUtils.EMPTY;
        carrierId = carrierId != null ? carrierId.trim().toUpperCase() : StringUtils.EMPTY;
        Assert.isFalse(carrierFlag == true && carrierId.length() < 1,
                       Errors.create().key(MessageIdList.CARRIER_CASSETTE_ID_MISSING).content("晶舟号不存在!").build());
        if (carrierFlag == true) {
            Long carrierRrn = this.getInstanceRrn(carrierId, facilityRrn, ObjectList.ENTITY_KEY);
            if (carrierRrn > 0L) {
                List<String> lotIds = carrierService.getInUseCarrierLotIdList(carrierRrn);
                Assert.isFalse(lotIds == null || lotIds.size() != 1,
                               Errors.create().key(MessageIdList.CARRIER_CASSETTE_HAVE_SOME_LOTS).content("该晶舟内有批次")
                                     .args(lotIds == null ? 0 : lotIds.size()).build());
                result = lotIds.get(0);
            }
        } else {
            result = request.getParameter("lotId") == null ? request.getParameter("instanceId") : request
                    .getParameter("lotId");
        }
        return result != null ? result.trim().toUpperCase() : StringUtils.EMPTY;
    }

    private void setTheFormSession(ReworkLotInfoForm theform, HttpServletRequest request, Lot lot, LotInfoForm lotInfo,
                                   Map<String, Object> cachePageInfo) {
        if (lot == null) {
            theform.setCacheLot(theform.getCacheLot());
            request.setAttribute(SessionNames.LOT_KEY, WebUtils.getCacheString2Obj(theform.getCacheLot()));
        } else {
            theform.setCacheLot(WebUtils.getCacheObj2String(lot));
            request.setAttribute(SessionNames.LOT_KEY, lot);
        }

        if (lotInfo == null) {
            theform.setCacheLotInfo(theform.getCacheLotInfo());
            request.setAttribute(SessionNames.LOT_INFO_FORM_KEY,
                                 WebUtils.getCacheString2Obj(theform.getCacheLotInfo()));
        } else {
            request.setAttribute(SessionNames.LOT_INFO_FORM_KEY, lotInfo);
            theform.setCacheLotInfo(WebUtils.getCacheObj2String(lotInfo));
        }

        if (cachePageInfo == null) {
            cachePageInfo = (Map<String, Object>) WebUtils.getCacheString2Obj(theform.getCachePageInfo());
        }
        if (cachePageInfo == null) {
            cachePageInfo = new HashMap<String, Object>();
        }
        theform.setCachePageInfo(WebUtils.getCacheObj2String(cachePageInfo));
        for (String key : cachePageInfo.keySet()) {
            request.setAttribute(key, MapUtils.getObject(cachePageInfo, key));
        }
    }

    protected String getRouteString(String processStepVersion) {
        String temp = processStepVersion;
        String route = "";

        if (temp != null) {
            int i = 0;
            int j = 0;
            i = temp.indexOf("|");

            // find first '|'
            if (i != -1) {
                j = temp.indexOf("|", i + 1);
                // find se '|'
                // string is aaa|bbb|cccc
                if (j > 0) {
                    route = temp.substring(i + 1, j);
                } else if (i > 0) { // aaa|bbb
                    route = temp.substring(0, i);
                }
            }
        }
        route = route.replace(',', '.');
        return route;
    }

}

/*
 * Modification Log Log No : Name : Modified Date: Description :
 */