RecipeControlAction.java

package com.mycim.webapp.actions.recipeControl;

import com.fa.sesa.exception.Assert;
import com.fa.sesa.exception.Errors;
import com.fa.sesa.threadlocal.LocalContext;
import com.mycim.framework.jdbc.Page;
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.msg.JsonUtils;
import com.mycim.valueobject.MessageIdList;
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.TransactionNames;
import com.mycim.valueobject.ems.Entity;
import com.mycim.valueobject.prp.RecipeGroup;
import com.mycim.valueobject.prp.RecipeStatus;
import com.mycim.valueobject.sys.ReferenceFileDetail;
import com.mycim.webapp.WebUtils;
import com.mycim.webapp.actions.EmsSetupAction;
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.Map.Entry;

public class RecipeControlAction extends EmsSetupAction {

    private static final String SUB_RECIPE_SEPARATOR = "-";

    private static final String PARALLEL_MODE = "PARALLEL";

    private static final String SERIAL_MODE = "SERIAL";

    @Override
    public ActionForward init(ActionMapping mapping, ActionForm form, HttpServletRequest request,
                              HttpServletResponse response) throws Exception {
        return mapping.findForward("init");
    }

    /**
     * 获取RecipeGroup列表
     *
     * @param reqMap
     * @return
     */
    public List<RecipeGroup> getAllRecipeGroup(Map<String, Object> reqMap) {
        String recipeGroupId = MapUtils.getString(reqMap, "searchGroupId");
        String namedSpace = getNamedSpace(ObjectList.RECIPE_KEY, LocalContext.getFacilityRrn());
        String object = ObjectList.RECIPE_GROUP_KEY;
        RecipeGroup condition = new RecipeGroup(recipeGroupId, namedSpace, object);
        List<RecipeGroup> list = recipeService.getRecipeGroupList(condition);
        return list;
    }

    /**
     * 添加RecipeGroup
     *
     * @param reqMap
     * @return
     */
    public long addRecipeGroup(Map<String, Object> reqMap) {
        String recipeGroupId = MapUtils.getString(reqMap, "recipeGroupId");
        Assert.isFalse(StringUtils.isEmpty(recipeGroupId),
                       Errors.create().key(MessageIdList.RECIPEGROUP_RECIPEGROUPEMPTY).content("Recipe group empty")
                             .build());

        RecipeGroup recipeGroup = new RecipeGroup(StringUtils.trimToUpperCase(recipeGroupId),
                                                  getNamedSpace(ObjectList.RECIPE_KEY, LocalContext.getFacilityRrn()),
                                                  ObjectList.RECIPE_GROUP_KEY);
        recipeGroup.setTransPerformedby(LocalContext.getUserId());
        recipeGroup.setTransId(TransactionNames.CREATE_KEY);
        long instanceRrn = recipeService.insertRecipeGroup(recipeGroup);
        return instanceRrn;
    }

    public void deleteRecipeGroup(Map<String, Object> reqMap) {
        long recipeGroupRrn = MapUtils.getLongValue(reqMap, "recipeGroupRrn", 0L);
        Assert.isFalse(recipeGroupRrn == 0L,
                       Errors.create().key(MessageIdList.RECIPEGROUP_RECIPEGROUPEMPTY).content("Recipe group empty")
                             .build());

        List<NamedObject> recipeFamilyByGroup = recipeService.getRecipeFamilyByGroup(recipeGroupRrn);
        Assert.isFalse(CollectionUtils.isNotEmpty(recipeFamilyByGroup),
                       Errors.create().key(MessageIdList.RECIPEGROUP_REMOVERECIPEFROMGROUP)
                             .content("Remove ecipe from group " + "first").build());

        RecipeGroup recipeGroup = new RecipeGroup(recipeGroupRrn);
        recipeGroup.setTransPerformedby(LocalContext.getUserId());
        recipeGroup.setTransId(TransactionNames.DELETE_KEY);
        recipeService.deleteRecipeGroup(recipeGroup);
    }


    /**
     * 获取group中recipe
     *
     * @param reqMap
     * @return
     */
    public Page getRecipeByGroup(Map<String, Object> reqMap) {
        long recipeGroupRrn = MapUtils.getLongValue(reqMap, "recipeGroupRrn");
        Assert.isFalse(recipeGroupRrn == 0L,
                       Errors.create().key(MessageIdList.RECIPEGROUP_RECIPEGROUPEMPTY).content("Recipe group empty")
                             .build());

        Page page = new Page(MapUtils.getIntValue(reqMap, "page"), MapUtils.getIntValue(reqMap, "limit"));
        Page selectPage = recipeService.getRecipeFamilyByGroupByPage(page, recipeGroupRrn);
        return selectPage;
    }

    /**
     * 获取所有未在组内的recipyFamily(非子ricipe)
     *
     * @param reqMap
     * @return
     */
    public Page getInGroupAndAll(Map<String, Object> reqMap) {
        long recipeGroupRrn = MapUtils.getLongValue(reqMap, "recipeGroupRrn");
        String recipeIdLike = StringUtils.replace(MapUtils.getString(reqMap, "recipeIdLike"), "*", "%");
        Assert.isFalse(recipeGroupRrn == 0L,
                       Errors.create().key(MessageIdList.RECIPEGROUP_RECIPEGROUPEMPTY).content("Recipe group empty")
                             .build());

        Page page = new Page(MapUtils.getIntValue(reqMap, "page"), MapUtils.getIntValue(reqMap, "limit"));
        // 获取所有非子recipy
        // Page selectPage = recipeService.getAllRecipeFamily(page);
        Page selectPage = recipeService.getAllRecipeFamilyNotInGroup(page, recipeGroupRrn, recipeIdLike);

		/*List<NamedObject> results = (List<NamedObject>) selectPage.getResults();
		if(CollectionUtils.isNotEmpty(results)) {
			Set<Long> collect = results.stream().map(nobj->nobj.getInstanceRrn()).collect(Collectors.toSet
			());
			List<NamedObject> areadyIn = recipeService.getrecipeAreadyInGroup(recipeGroupRrn,new
			ArrayList<Long>(collect));
			Set<Long> areadyInList = areadyIn.stream().map(nobj->nobj.getInstanceRrn()).collect(Collectors
			.toSet());
			//用attribute1标识是否默认勾选
			for (NamedObject nobj : results) {
				if(areadyInList.contains(nobj.getInstanceRrn())) {
					nobj.setAttribute1("true");
				}
			}
		}*/
        return selectPage;
    }

    public void addRecipeToGroup(Map<String, Object> reqMap) {
        List<Long> rrns = JsonUtils.toList(MapUtils.getString(reqMap, "instanceRrns"), Long.class);
        Long groupRrn = MapUtils.getLongValue(reqMap, "recipeGroupRrn");
        List<Relation> relations = new ArrayList<Relation>();
        int index = 0;

        for (Long recipeRrn : rrns) {
            index++;
            Relation relation = new Relation(groupRrn, recipeRrn, LinkTypeList.RECIPEGROUP_TO_RECIPEFAMILY);
            relation.setSequenceNumber(index);
            relations.add(relation);
        }
        baseService.insertRelation(relations);
    }

    public void deleteRecipeToGroup(Map<String, Object> reqMap) {
        Long groupRrn = MapUtils.getLongValue(reqMap, "groupRrn");
        Long recipeRrn = MapUtils.getLongValue(reqMap, "recipeRrn");
        List<Relation> relations = new ArrayList<Relation>();
        Relation relation = new Relation(groupRrn, recipeRrn, LinkTypeList.RECIPEGROUP_TO_RECIPEFAMILY);
        baseService.deleteRelation(relation);
    }

    /**
     * 获取并行下的列表
     *
     * @param reqMap
     * @return
     */
    public Page getParallelList(Map<String, Object> reqMap) {
        Page page = new Page(MapUtils.getIntValue(reqMap, "page"), MapUtils.getIntValue(reqMap, "limit"));
        Page selectPage = recipeService.getParalleProtallList(page, reqMap);
        return selectPage;
    }

    /**
     * 获取OFF/Serial下的列表
     *
     * @param reqMap
     * @return
     */
    public Page getUnParallelList(Map<String, Object> reqMap) {
        Page page = new Page(MapUtils.getIntValue(reqMap, "page"), MapUtils.getIntValue(reqMap, "limit"));
        Page selectPage = recipeService.getUnParalleProtallList(page, reqMap);
        return selectPage;
    }


    /**
     * 页面查询区域下拉
     */
    public List<Map> getEqptLocations(Map<String, Object> reqMap) {
        List<ReferenceFileDetail> refFileValues = sysService
                .getRefFileValues("$EQPT_LOCATION", LocalContext.getFacilityRrn());
        List<String> processVersionIds = new ArrayList<String>();
        for (ReferenceFileDetail detail : refFileValues) {
            processVersionIds.add(detail.getKey1Value());
        }
        List<Map> maps = WebUtils.analyticalComboData(processVersionIds);
        return maps;
    }

    /**
     * recipe ON/OFF
     */
    public void turnRecipeStatus(Map<String, Object> reqMap) {
        Map<Long, Set<Long>> recips = new HashMap<Long, Set<Long>>();
        List<HashMap> selectArr = JsonUtils.toList(MapUtils.getString(reqMap, "selectArr"), HashMap.class);
        for (HashMap selected : selectArr) {
            long entityRrn = MapUtils.getLongValue(selected, "entityRrn", 0);
            long recipeRrn = MapUtils.getLongValue(selected, "recipeRrn", 0);
            if (recips.containsKey(entityRrn)) {
                recips.get(entityRrn).add(recipeRrn);
            } else {
                HashSet<Long> hashSet = new HashSet<Long>();
                hashSet.add(recipeRrn);
                recips.put(entityRrn, hashSet);
            }
        }

        String status = StringUtils.upperCase(MapUtils.getString(reqMap, "status"));
        String comments = MapUtils.getString(reqMap, "comments");

        for (Entry<Long, Set<Long>> entry : recips.entrySet()) {
            Long entityRrn = entry.getKey();
            Entity entity = getEntity(entityRrn);
            Set<Long> recipRrns = entry.getValue();
            for (Long recipeRrn : recipRrns) {
                checkRecipeIsInUse(entityRrn, recipeRrn);
            }
            if (CollectionUtils.isNotEmpty(recipRrns)) {
                if (RecipeStatus.isAvailable(status) && SERIAL_MODE.equals(entity.getChamberMode())) {
                    checkOnStatusSubRecipeInSerialMode(entity.getInstanceRrn(), new ArrayList<Long>(recipRrns));
                }
            }

            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,
                                         new ArrayList<Long>(recipRrns), comments);
        }

    }

    private Entity getEntity(Long entityRrn) {
        Entity theEntity = new Entity(entityRrn);
        theEntity = (Entity) getInstance(theEntity);
        emsService.checkEquipmentRecipeInvalid(theEntity.getInstanceRrn());
        return theEntity;
    }

    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().
                        content("Serial Mode can only " + "have one sub recipe " + "is ON status in parent recipe at " +
                                        "most! recipeID:{}").args(baseService.getNamedObject(selectedRecipeRrn) !=
                                                                          null ? baseService
                        .getNamedObject(selectedRecipeRrn).getInstanceId() : "").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! " + "recipeID:{}")
                             .args(baseService.getNamedObject(recipeRrn) != null ? baseService.getNamedObject(recipeRrn)
                                                                                              .getInstanceId() : "")
                             .build());
    }

}