ChamberRecipeListAction.java

package com.mycim.webapp.actions.equipment.recipe;

import com.fa.sesa.exception.Assert;
import com.fa.sesa.exception.Errors;
import com.fa.sesa.threadlocal.LocalContext;
import com.mycim.framework.utils.lang.BooleanUtils;
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.framework.utils.lang.time.DateUtils;
import com.mycim.valueobject.MessageIdList;
import com.mycim.valueobject.ObjectList;
import com.mycim.valueobject.SystemConstant;
import com.mycim.valueobject.bas.Relation;
import com.mycim.valueobject.consts.LinkTypeList;
import com.mycim.valueobject.consts.TransactionNames;
import com.mycim.valueobject.ems.Entity;
import com.mycim.valueobject.prp.Recipe;
import com.mycim.valueobject.prp.RecipeStatus;
import com.mycim.valueobject.prp.RecipeVersion;
import com.mycim.webapp.Constants;
import com.mycim.webapp.WebUtils;
import com.mycim.webapp.actions.EmsSetupAction;
import com.mycim.webapp.forms.EntityInfoForm;
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 pinyan.song
 * @version 6.0.0
 * @date 2019-9-8 21:51
 **/

public class ChamberRecipeListAction extends EmsSetupAction {
    private static final String SUB_RECIPE_SEPARATOR = "-";

    private static final String PARALLEL_MODE = "PARALLEL";

    private static final String SERIAL_MODE = "SERIAL";

    private static final String FLAG = "1";

    @Override
    public ActionForward init(ActionMapping mapping, ActionForm form, HttpServletRequest request,
                              HttpServletResponse response) throws Exception {
        EntityInfoForm theform = (EntityInfoForm) form;
        Entity theEntity = getEntity(theform, request);

        String searchId = StringUtils.trimToUpperCase(theform.getSearchRecipeId());
        String chamberMode=theEntity.getChamberMode();
        List<Map<String, Object>> recipeList =recipeService
                .getRecipesByEquipmentForShow(theEntity.getInstanceRrn(), searchId, chamberMode);

        //当chamber mode = Parallel的机台 EQP setup 界面的 reciplist 界面按照 recipeID 正序排序
        if (StringUtils.equalsIgnoreCase(chamberMode, SystemConstant.Str.PARALLEL)){
            if(CollectionUtils.isNotEmpty(recipeList)){
                Collections.sort(recipeList, (o1, o2) -> {
                    String id1=MapUtils.getString(o1,"recipeId");
                    String id2=MapUtils.getString(o2,"recipeId");
                    if (StringUtils.isNotEmpty(id1) && StringUtils.isNotEmpty(id2)){
                        return id1.compareTo(id2);
                    }
                    return 0;
                });
            }
        }

        request.setAttribute("recipeList",recipeList);

        request.setAttribute("recipeHistoryList",
                             recipeService.getDeleteRelationHistoryByEntityForRecipe(theEntity.getInstanceRrn()));

        request.setAttribute("hasEditPermisstion", securityService
                .hasRelationEditPermission(LocalContext.getFacilityRrn(), LocalContext.getUserRrn(),
                                           theEntity.getMaintenanceEngineerRrn()));
        theform.setSearchRecipeId(searchId);
        theform.setChamberMode(theEntity.getChamberMode());
        theform.setTransId(Constants.MODIFY_KEY);
        theform.setRecipeId("");

        return mapping.getInputForward();
    }


    public ActionForward batchUpdateMembers(ActionMapping mapping, ActionForm form, HttpServletRequest request,
                                            HttpServletResponse response) throws Exception {
        EntityInfoForm theform = (EntityInfoForm) form;
        Entity entity = getEntity(theform, request);

        String[] selectUpdateRecipeRrns = request.getParameterValues("selectUpdateStatus");
        String status = request.getParameter("changeStatus");
        String comments = WebUtils.getParameter("reason", request);

        Assert.isFalse(selectUpdateRecipeRrns == null || selectUpdateRecipeRrns.length == 0,
                       Errors.create().key(MessageIdList.RECIPE_MISSING_RECIPE).content("No recipe selected!").build());

        List<Long> recipeRrns = new ArrayList<>();
        for (String selectUpdateRecipeRrn : selectUpdateRecipeRrns) {
            long recipeRrn = NumberUtils.toLong(selectUpdateRecipeRrn);
            checkRecipeIsInUse(entity.getInstanceRrn(), recipeRrn);
            recipeRrns.add(recipeRrn);
        }

        /* 串行模式也能多个ON
        if (CollectionUtils.isNotEmpty(recipeRrns)) {
            if (RecipeStatus.isAvailable(status) && SERIAL_MODE.equals(entity.getChamberMode())) {
                checkOnStatusSubRecipeInSerialMode(entity.getInstanceRrn(), recipeRrns);
            }
        }
        */

        Relation relation = new Relation();

        relation.setLinkType(LinkTypeList.ENTITY_TO_RECIPE);
        relation.setFromRrn(entity.getInstanceRrn());
        relation.setLastUpdatedUser(LocalContext.getUserRrn());

        recipeService.updateRecipesStatus(LocalContext.getUserId(), RecipeStatus.getContrary(status), status, relation,
                                          recipeRrns, comments);

        WebUtils.setSuccessMsg(request);
        return init(mapping, theform, request, response);
    }

    public ActionForward history(ActionMapping mapping, ActionForm form, HttpServletRequest request) {
        EntityInfoForm theform = (EntityInfoForm) form;
        if (StringUtils.isNotBlank(request.getParameter("flag"))) {
            request.setAttribute("flag", FLAG);
        }
        return mapping.findForward(Constants.HISTORY_KEY);
    }

    public ActionForward deleteMembers(ActionMapping mapping, ActionForm form, HttpServletRequest request,
                                       HttpServletResponse response) throws Exception {
        EntityInfoForm theform = (EntityInfoForm) form;
        Entity entity = getEntity(theform, request);

        long recipeRrn = WebUtils.getParameterLong(Constants.ITEM_KEY, request);

        checkRecipeIsInUse(entity.getInstanceRrn(), recipeRrn);

        Relation relation = baseService.getRelation(entity.getInstanceRrn(), recipeRrn, LinkTypeList.ENTITY_TO_RECIPE);

        relation.setLastUpdatedUser(LocalContext.getUserRrn());
        relation.setTransPerformedby(LocalContext.getUserId());
        relation.setTransId(TransactionNames.DELETE_KEY);
        emsService.deleteRelation4RecipeToEntity(relation,theform.getReason());

        WebUtils.setSuccessMsg(request);
        return init(mapping, theform, request, response);
    }

    public ActionForward deleteHistory(ActionMapping mapping, ActionForm form, HttpServletRequest request,
                                       HttpServletResponse response) throws Exception {
        EntityInfoForm theform = (EntityInfoForm) form;
        Entity entity = getEntity(theform, request);

        long transRrn = WebUtils.getParameterLong("transRrn", request);
        int transSequence = WebUtils.getParameterInt("transSequence", request);

        baseService.updateDeleteRelationHistory(transRrn, transSequence);
        WebUtils.setSuccessMsg(request);
        return init(mapping, theform, request, response);
    }


    public ActionForward add(ActionMapping mapping, ActionForm form, HttpServletRequest request,
                             HttpServletResponse response) throws Exception {
        EntityInfoForm theform = (EntityInfoForm) form;
        Entity entity = getEntity(theform, request);

        String recipeId = StringUtils.trimToUpperCase(theform.getRecipeId());
        Assert.isFalse(StringUtils.isBlank(recipeId),
                       Errors.create().key(MessageIdList.RECIPE_INVALID_ID).content("Recipe cannot be empty!").build());

        long equipmentRrn = entity.getInstanceRrn();
        String chamberMode = entity.getChamberMode();

        boolean isDefaultAvailableStatus = true;
        boolean isSingleChamber = true;
        Recipe recipe;
        long parentRecipeRrn;

        List<Long> addRecipeRrns = new ArrayList<>();

        String parentRecipeId = StringUtils.substringBeforeLast(recipeId, SUB_RECIPE_SEPARATOR);
        String chamberId = StringUtils.substringAfterLast(recipeId, SUB_RECIPE_SEPARATOR);

        checkInputRecipeIdCanBeCreated(equipmentRrn, chamberId);

        recipe = recipeService.getRecipe(parentRecipeId, LocalContext.getFacilityRrn());

        Assert.isFalse(recipe == null || recipe.getInstanceRrn() <= 0,
                       Errors.create().key(MessageIdList.RECIPE_MISSING).content("The Recipe {} does not " + "exist!")
                             .args(parentRecipeId).build());

        parentRecipeRrn = recipe.getInstanceRrn();
        addRecipeRrns.add(parentRecipeRrn);

        if (StringUtils.equalsIgnoreCase(chamberMode, SERIAL_MODE) || StringUtils.isEmpty(chamberMode)) {
            isDefaultAvailableStatus = false;
            isSingleChamber = chamberId.length() == 1;

            addRecipeRrns.add(createSubRecipeWithIsExisted(recipe, recipeId));
        } else {
            Assert.isFalse(chamberId.length() != 1, Errors.create().key(MessageIdList.EQUIPMENT_IS_PARALLEL_ONLY_ONE)
                                                          .content(
                                                                  "This Equipment is parallel mode, please only" + " " +
                                                                          "input one chamber's recipe.").build());
            addRecipeRrns.addAll(buildAddRecipeRrnsForParallelMode(equipmentRrn, recipe, chamberId));
        }
        // int maxSize = baseService.getRelationsUseFromRrn(equipmentRrn, LinkTypeList.ENTITY_TO_RECIPE).size();
        int maxSeqNumber = 0;
        //在串联模式下,防止生成sequence number重复的问题
        if (StringUtils.equalsIgnoreCase(chamberMode, SERIAL_MODE)) {
            maxSeqNumber = baseService.getMaxSeqOfRelation(new Relation(equipmentRrn,null,LinkTypeList.ENTITY_TO_RECIPE));
        }else{
            maxSeqNumber = baseService.getRelationsUseFromRrn(equipmentRrn, LinkTypeList.ENTITY_TO_RECIPE).size();
        }
        String currentTimestampString = DateUtils.formatDate(new Date());
        String status;

        List<Relation> addRelations = new ArrayList<>();
        for (Long recipeRrn : addRecipeRrns) {
            if (!isExistedInRelation(equipmentRrn, recipeRrn)) {
                Relation relation = new Relation(equipmentRrn, recipeRrn, LinkTypeList.ENTITY_TO_RECIPE);

                relation.setSequenceNumber(++maxSeqNumber);

                boolean isParentRecipe = recipeRrn == parentRecipeRrn;
                boolean isAvailableStatus = isParentRecipe || isDefaultAvailableStatus;
                status = StringUtils.trimToUpperCase(BooleanUtils.toStringOnOff(isAvailableStatus));

                String parentRecipeRrnStr = isParentRecipe ? null : StringUtils.toString(parentRecipeRrn);
                String isSingleChamberStr = isParentRecipe ? null : StringUtils
                        .upperCase(BooleanUtils.toStringYesNo(isSingleChamber));

                relation.setStatus(status);

                relation.setAttributedata1(status);
                relation.setAttributedata2(StringUtils.toString(LocalContext.getUserRrn()));
                relation.setAttributedata3(currentTimestampString);
                relation.setAttributedata4(parentRecipeRrnStr);
                relation.setAttributedata5(recipe.getAttributeData2());
                relation.setAttributedata6(isSingleChamberStr);
                relation.setAttributedata7(chamberMode);

                relation.setTransPerformedby(LocalContext.getUserId());
                relation.setTransId(TransactionNames.CREATE_KEY);

                addRelations.add(relation);
            }
        }

        Assert.isFalse(CollectionUtils.isEmpty(addRelations), Errors.create().key(MessageIdList.RECIPE_HAS_EQP_RELATION)
                                                                    .content(
                                                                            "Recipe has a relationship with " + "this" +
                                                                                    " equipment!").build());

        if (CollectionUtils.isNotEmpty(addRelations)) {
            // baseService.insertRelation(addRelations);
            emsService.insertRelation4RecipeToEntity(addRelations,theform.getReason());
        }

        WebUtils.setSuccessMsg(request);
        return init(mapping, theform, request, response);
    }

    public ActionForward updateRelationSequence(ActionMapping mapping, ActionForm form, HttpServletRequest request,
                                                   HttpServletResponse response) throws Exception {
        EntityInfoForm theform = (EntityInfoForm) form;
        Entity entity = getEntity(theform, request);

        Long recipeRrn = WebUtils.getParameterLong("recipeRrn", request);
        Long replaceRecipeRrn = WebUtils.getParameterLong("replaceRecipeRrn", request);
        int seq = WebUtils.getParameterInt("seq", request);
        int replaceSeq = WebUtils.getParameterInt("replaceSeq", request);

        Assert.isFalse(replaceRecipeRrn == null || replaceRecipeRrn.longValue() == 0,
                       Errors.create().content("The relation sequence is already the minimum or maximum!").build());

        Relation relation1 = baseService.getRelation(entity.getInstanceRrn(), recipeRrn, LinkTypeList.ENTITY_TO_RECIPE);
        Relation relation2 = baseService
                .getRelation(entity.getInstanceRrn(), replaceRecipeRrn, LinkTypeList.ENTITY_TO_RECIPE);
        Assert.isFalse(relation1 == null || relation2 == null,
                       Errors.create().key(MessageIdList.RECIPE_NOT_EXIST).content("Recipe relation is not existed!")
                             .build());

        String comments =
                "Exchange serial NO: " + getInstanceId(recipeRrn) + " from " + seq + " to " + replaceSeq + ";" +
                        getInstanceId(replaceRecipeRrn) + " from " + replaceSeq + " to " + seq;
        emsService.exchangeRelationSequence(relation1, relation2, comments);

        WebUtils.setSuccessMsg(request);
        return init(mapping, theform, request, response);
    }

    private void checkOnStatusSubRecipeInSerialMode(long equipmentRrn, List<Long> recipeRrns) {
        Map<Long, Integer> selectedMap = new HashMap<>();
        for (Long selectedRecipeRrn : recipeRrns) {
            Relation relation = baseService.getRelation(equipmentRrn, selectedRecipeRrn);
            if (relation == null) {
                continue;
            }

            Long parentRecipeRrn = NumberUtils.toLong(relation.getAttributedata4(), 0L);
            if (parentRecipeRrn > 0) {
                int onStatusSize = recipeService.getOpenRecipesByEquipmentForSerialMode(equipmentRrn, parentRecipeRrn)
                                                .size();

                Integer selectedSize = MapUtils.getIntValue(selectedMap, parentRecipeRrn) + 1;
                selectedMap.put(parentRecipeRrn, selectedSize);

                Assert.isFalse(selectedSize > 1 || onStatusSize >= 1,
                               Errors.create().key(MessageIdList.EQUIPMENT_SERIAL_MODE_ONLY_ONE_SUB_RECIPE)
                                     .content("recipe串行改ON").build());
            }
        }
    }

    private void checkRecipeIsInUse(long entityRrn, Long recipeRrn) {
        Assert.isFalse(wipQueryService.checkLotStatus(recipeRrn, entityRrn),
                       Errors.create().key(MessageIdList.RECIPE_CANT_OPERATION_HAS_RUN_LOT).content(
                               "a lot runing on the" + " " + "EQP by the " + "recipe,this " + "operation cannot " +
                                       "be performed!").build());
    }

    private boolean isExistedInRelation(long equipmentRrn, Long recipeRrn) {
        return baseService.getRelation(new Relation(equipmentRrn, recipeRrn, LinkTypeList.ENTITY_TO_RECIPE)) != null;
    }

    private List<Long> buildAddRecipeRrnsForParallelMode(long equipmentRrn, Recipe parentRecipe, String chamberId) {
        List<Long> addRecipeRrns = new ArrayList<>();
        Set<String> willCreateChamberIds = new HashSet<>();
        willCreateChamberIds.add(chamberId);
        buildCreatedSingleChamberId(willCreateChamberIds, equipmentRrn, parentRecipe.getInstanceId());

        for (String combinationId : getAvailableSubRecipeChamberIds(willCreateChamberIds)) {
            if (!combinationId.contains(chamberId)) {
                continue;
            }
            long subRecipeRrn = createSubRecipeWithIsExistedByChamberId(parentRecipe, combinationId);
            if (combinationId.length() == 1) {
                addRecipeRrns.add(subRecipeRrn);
            }
        }
        return addRecipeRrns;
    }

    private long createSubRecipeWithIsExistedByChamberId(Recipe parentRecipe, String combinationId) {
        return createSubRecipeWithIsExisted(parentRecipe, StringUtils
                .trimToUpperCase(parentRecipe.getInstanceId() + SUB_RECIPE_SEPARATOR + combinationId));
    }

    private List<String> getAvailableSubRecipeChamberIds(Collection<String> chamberTypes) {
        if (CollectionUtils.isEmpty(chamberTypes)) {
            return Collections.emptyList();
        } else {
            List<String> list = buildNoRepeatChamberTypes(chamberTypes);
            return StringUtils.combinationStrings(list.toArray(new String[0]));
        }
    }

    private List<String> buildNoRepeatChamberTypes(Collection<String> chamberTypes) {
        Set<String> set = new HashSet<>();
        for (String string : chamberTypes) {
            if (StringUtils.isNotEmpty(string)) {
                set.add(string);
            }
        }
        List<String> list = new ArrayList<>(set);
        Collections.sort(list);
        return list;
    }


    private void buildCreatedSingleChamberId(Set<String> willCreateChamberIds, long equipmentRrn,
                                             String parentRecipeId) {
        String queryRecipeId = parentRecipeId + "-*";
        for (Map<String, Object> map : recipeService
                .getRecipesByEquipmentForParallelMode(equipmentRrn, queryRecipeId)) {
            willCreateChamberIds
                    .add(StringUtils.substringAfterLast((MapUtils.getString(map, "recipeId")), SUB_RECIPE_SEPARATOR));
        }
    }

    private Long createSubRecipeWithIsExisted(Recipe parentRecipe, String subRecipeId) {
        long subRecipeRrn = getInstanceRrn(subRecipeId, LocalContext.getFacilityRrn(), ObjectList.RECIPE_KEY);
        if (subRecipeRrn <= 0) {
            subRecipeRrn = createSubRecipeWithActiveVersion(parentRecipe, subRecipeId);
        }
        checkSubRecipeVersionInfo(subRecipeId, subRecipeRrn);

        Relation relation = new Relation(parentRecipe.getInstanceRrn(), subRecipeRrn,
                                         LinkTypeList.RECIPEFAMILY_TO_RECIPE);
        if (baseService.getRelation(relation) == null) {
            relation.setTransId(TransactionNames.CREATE_KEY);
            recipeService.insertRelation4RecipeFamilyToRecipe(relation);
        }

        return subRecipeRrn;
    }

    private void checkSubRecipeVersionInfo(String subRecipeId, long subRecipeRrn) {
        List<String> recipeChambers = getRecipeChambers(subRecipeRrn);
        Assert.isFalse(CollectionUtils.isEmpty(recipeChambers),
                       Errors.create().key(MessageIdList.RECIPE_NOT_CHAMBER_IS_VERSION)
                             .content("This recipe {} has not any required " + "chamber in active version!")
                             .args(subRecipeId).build());

        String chamberIds = StringUtils.substringAfterLast(subRecipeId, SUB_RECIPE_SEPARATOR);
        boolean isSameNum = chamberIds.length() == recipeChambers.size();
        for (String requiredChamberId : recipeChambers) {
            Assert.isFalse(!isSameNum || !chamberIds.contains(requiredChamberId),
                           Errors.create().key(MessageIdList.RECIPE_CHAMBER_IN_VERSION).content(
                                   "This recipe {}" + " " + "required " + "chamber in " + "active " + "version is " +
                                           "not mapped " + "subrecipe id!").args(subRecipeId).build());
        }


    }

    private List<String> getRecipeChambers(long subRecipeRrn) {
        RecipeVersion subRecipeVersion = recipeService.getNowActiveRecipeVersion(subRecipeRrn);
        boolean isAvailableRecipe = subRecipeVersion != null && subRecipeVersion.getInstanceRrn() > 0 &&
                subRecipeVersion.getInstanceVersion() > 0;
        String[] chambers = null;
        if (isAvailableRecipe) {
            chambers = StringUtils.split(StringUtils.substringBefore(subRecipeVersion.getChamberTypes(), ";"),
                                         StringUtils.COMMA_SIGN);
        }

        List<String> result;
        if (chambers != null) {
            result = Arrays.asList(chambers);
        } else {
            result = Collections.emptyList();
        }

        return result;
    }

    private long createSubRecipeWithActiveVersion(Recipe parentRecipe, String subRecipeId) {
        Recipe recipe = new Recipe(StringUtils.trimToUpperCase(subRecipeId), parentRecipe.getNamedSpace(),
                                   ObjectList.RECIPE_KEY);

        recipe.setObjectType(ObjectList.RECIPE_KEY);
        recipe.setAttributeData1(parentRecipe.getAttributeData1());
        recipe.setAttributeData2(parentRecipe.getAttributeData2());
        recipe.setAttributeData3(parentRecipe.getAttributeData3());

        recipe.setTransPerformedby(LocalContext.getUserId());
        recipe.setTransId(TransactionNames.CREATE_KEY);
        long subRecipeRrn = recipeService.insertRecipe(setDefaultParam(recipe));
        recipe.setInstanceRrn(subRecipeRrn);

        recipe = recipeService.getRecipe(recipe.getInstanceRrn());

        baseService.updateNamedObjectSystemUesd(recipe.getInstanceRrn(), "1");

        createActiveSubRecipeVersion(recipe, StringUtils.substringAfterLast(subRecipeId, SUB_RECIPE_SEPARATOR));

        return subRecipeRrn;
    }

    private void createActiveSubRecipeVersion(Recipe subRecipe, String chamberIds) {
        RecipeVersion recipeVersion = new RecipeVersion();

        recipeVersion.copyNamedObject(subRecipe);

        int newVersionId = subRecipe.getCurrentVersion() == null ? 1 : subRecipe.getCurrentVersion() + 1;

        recipeVersion.setInstanceVersion(newVersionId);
        recipeVersion.setVersionId(Integer.toString(newVersionId));
        recipeVersion.setVersionDesc("Automatic schema generation");

        recipeVersion.setChamberTypes(buildChamberTypesForRecipeVersion(chamberIds.toCharArray()));

        recipeVersion.setTransId(TransactionNames.CREATE_KEY);
        recipeVersion.setTransPerformedby(LocalContext.getUserId());

        recipeService.createRecipeVersion(recipeVersion);

        recipeVersion = recipeService.getRecipeVersion(recipeVersion);

        ecnService.activateEcn(recipeVersion.getEcnRrn());
    }

    private String buildChamberTypesForRecipeVersion(char[] chamberIds) {
        int lastChar = chamberIds.length - 1;
        StringBuilder result = new StringBuilder();
        for (int i = 0; i < chamberIds.length; i++) {
            result.append(chamberIds[i]);
            result.append(i == lastChar ? ";" : StringUtils.COMMA_SIGN);
        }
        return result.toString();
    }


    private void checkInputRecipeIdCanBeCreated(long equipmentRrn, String chamberId) {
        Assert.isFalse(StringUtils.isEmpty(chamberId), Errors.create().key(MessageIdList.RECIPE_ID_IS_ERROR).content(
                "Recipe ID must use a Recipe ID with a '-' and " + "cannot end with a '-'!").build());

        List<String> canBeCreatedChamberIds = emsService.getChildChamberEquipmentType(equipmentRrn);
        Assert.isFalse(CollectionUtils.isEmpty(canBeCreatedChamberIds),
                       Errors.create().key(MessageIdList.EQUIPMENT_NOT_HAVE_CHAMBER)
                             .content("This Equipment does not have " + "any chamber!").build());

        char[] chars = chamberId.toCharArray();
        for (char c : chars) {
            Assert.isTrue(canBeCreatedChamberIds.contains(StringUtils.toString(c)),
                          Errors.create().key(MessageIdList.EQUIPMENT_NOT_HAVE_CHAMBER_2)
                                .content("This Equipment " + "does not " + "have this " + "chamber: " + "{}!").args(c)
                                .build());
        }
    }

    private Entity getEntity(EntityInfoForm theform, HttpServletRequest request) {
        Entity theEntity = new Entity(theform.getInstanceId(),
                                      getNamedSpace(ObjectList.ENTITY_KEY, LocalContext.getFacilityRrn()),
                                      ObjectList.ENTITY_KEY);

        theEntity = (Entity) getInstance(theEntity);
        emsService.checkEquipmentRecipeInvalid(theEntity.getInstanceRrn());
        if (StringUtils.isNotBlank(WebUtils.getParameter("equipmentReadOnlyFlag", request))) {
            request.setAttribute("equipmentReadOnlyFlag", 1);
        }

        return theEntity;
    }

}