SplitRunCardAction.java
package com.mycim.webapp.actions.splitruncard;
import com.fa.sesa.exception.Assert;
import com.fa.sesa.exception.Errors;
import com.fa.sesa.threadlocal.LocalContext;
import com.mycim.framework.context.spring.SpringContext;
import com.mycim.framework.utils.lang.ObjectUtils;
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.server.runcard.service.SplitRunCardService;
import com.mycim.utils.FieldValidateUtils;
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.ems.EntityGroup;
import com.mycim.valueobject.prp.AutoSplitMergeInfo;
import com.mycim.valueobject.wip.*;
import com.mycim.webapp.actions.RunCardAction;
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.stream.Collectors;
/**
* @author pinyan.song
* @version 6.0.0
* @date 2020-1-7 10:56
**/
public class SplitRunCardAction extends RunCardAction {
protected SplitRunCardService splitRunCardService = SpringContext.getBean(SplitRunCardService.class);
/**
* Action 方法: init
*/
@Override
public ActionForward init(ActionMapping mapping, ActionForm form, HttpServletRequest request,
HttpServletResponse response) {
String[] types = new String[]{"RC_E1_MANAGER", "RELATED_MODULE_GROUP", "SORTERFLIPTYPE"};
registerOptionType(LocalContext.getFacilityRrn(), Arrays.asList(types), request);
return mapping.getInputForward();
}
/**
* Action 方法: queryList
*/
public Map<String, Object> queryList(Map<String, Object> params) {
int pageSize = MapUtils.getIntValue(params, "limit");
int pageNo = MapUtils.getIntValue(params, "page");
String sortJsonString = MapUtils.getString(params, "sort");
params.put("orderBy", buildOrderBy(sortJsonString));
// RC Search 界面
if (!MapUtils.getBooleanValue(params, "isReview") && !MapUtils.getBooleanValue(params, "isSettings")) {
//选择runCardStatus ALL 时,RRC 查询会将状态为DRAFT的隐藏。
String[] tempStringArray;
Object runCardStatus = params.get("runCardStatus");
if (runCardStatus instanceof List) {
List<String> tempStringList = (List<String>) runCardStatus;
tempStringArray = tempStringList.toArray(new String[0]);
} else {
tempStringArray = (String[]) runCardStatus;
}
if (!(tempStringArray != null && tempStringArray.length > 0 &&
StringUtils.isNotEmpty(tempStringArray[0]))) {
params.put("srcSpecialNeeds", true);
}
}
return splitRunCardService.queryRunCardPage(pageSize, pageNo, params);
}
/**
* Action 方法: addRunCard
*/
public Map<String, Object> addRunCard() {
return splitRunCardService.addRunCard();
}
/**
* Action 方法: runCardDetail
*/
public ActionForward runCardDetail(ActionMapping mapping, HttpServletRequest request) {
String[] types = new String[]{"RELATED_MODULE_GROUP", "RELATED_MODULE_MANAGER", "POLLUTIONLEVEL",
"WORKAREATYPE", "$LOT_CREATE_CATEGORY", "PROCESSLOCATION", "SRCHOLDCODE",
"RC_E1_MANAGER", "STAGEID", "RC_SUPERVISOR", "RC_MFG_MANAGER", "holdGroup",
"SORTERFLIPTYPE"};
setForwardParametersToRequest(request, types);
return mapping.findForward("runCardSettings");
}
/**
* Action 方法: viewRunCardDetail
*/
public ActionForward viewRunCardDetail(ActionMapping mapping, HttpServletRequest request) {
String[] types = new String[]{"RELATED_MODULE_GROUP", "RELATED_MODULE_MANAGER", "POLLUTIONLEVEL",
"WORKAREATYPE", "$LOT_CREATE_CATEGORY", "PROCESSLOCATION", "SRCHOLDCODE",
"RC_E1_MANAGER", "RC_SUPERVISOR", "RC_MFG_MANAGER", "SORTERFLIPTYPE"};
setForwardParametersToRequest(request, types);
return mapping.findForward("runCardView");
}
/**
* Action 方法: viewRunCard
*/
public Map<String, Object> viewRunCard(Map<String, Object> params) {
Long scrRrn = MapUtils.getLong(params, "runCardRrn");
Integer queueSequence = MapUtils.getInteger(params, "queueSequence");
Assert.isFalse(scrRrn == null || scrRrn <= 0,
Errors.create().content("The parameter is missing. Please login again.").build());
return splitRunCardService.viewRunCard(scrRrn, queueSequence);
}
/**
* Action 方法: modifyRunCard
*/
public Map<String, Object> modifyRunCard(Map<String, Object> params) {
Long scrRrn = MapUtils.getLong(params, "runCardRrn");
Assert.isFalse(scrRrn == null || scrRrn <= 0,
Errors.create().content("The parameter is missing. Please login again.").build());
return splitRunCardService.getLotRunCardInfo(scrRrn);
}
/**
* Action 方法: copyRunCard
*/
public Map<String, Object> copyRunCard(Map<String, Object> params) {
String scrId = MapUtils.getString(params, "runCardId");
Assert.isFalse(StringUtils.isEmpty(scrId),
Errors.create().content("Please enter the Run Card ID to copy!").build());
scrId = scrId.toUpperCase();
long scrRrn = getInstanceRrn(scrId, LocalContext.getFacilityRrn(), ObjectList.ECN_KEY);
Assert.isFalse(scrRrn <= 0, Errors.create().content("Run Card ID: {} does not exist!").args(scrId).build());
return splitRunCardService.getLotRunCardInfo(scrRrn);
}
/**
* Action 方法: saveSplitRunCard
*/
public void saveSplitRunCard(Map<String, Object> params) {
//自动分合批不能和SRC嵌套
Long lotRrn = MapUtils.getLong(params, "lotRrn");
Assert.isFalse(lotRrn == null || lotRrn <= 0,
Errors.create().key(MessageIdList.LOT_LOTRRN_NOT_FOUND).content("Cannot Find Lot!").build());
//卡控post future hold被hold住的lot
checkPostFutureHold(lotRrn);
Long productRrn = MapUtils.getLong(params, "productRrn");
if (productRrn != null && productRrn > 0) {
List<AutoSplitMergeInfo> autoSplitMergeInfo = prpService.getAutoSplitMergeInfoByProduct(productRrn);
Long splitFlowSeq = getLong4FlowSeq(MapUtils.getString(params, "splitFlowSeq"));
Long mergeFlowSeq = getLong4FlowSeq(MapUtils.getString(params, "mergeFlowSeq"));
for (AutoSplitMergeInfo splitMergeInfo : autoSplitMergeInfo) {
long existSplitSeq = getLong4FlowSeq(splitMergeInfo.getSplitFlowSeq());
long existMergeSeq = getLong4FlowSeq(splitMergeInfo.getMergeFlowSeq());
Assert.isFalse(splitFlowSeq != null && existSplitSeq <= splitFlowSeq && splitFlowSeq <= existMergeSeq,
Errors.create().content("Please check Step No. nested in Auto Split Merge!").build());
Assert.isFalse(mergeFlowSeq != null && existSplitSeq <= mergeFlowSeq && mergeFlowSeq <= existMergeSeq,
Errors.create().content("Please check Step No. nested in Auto Split Merge!").build());
}
}
checkRecipeForRuncardStep(params);
splitRunCardService.saveSplitRunCard(params);
}
private void checkRecipeForRuncardStep(Map<String,Object> params){
if(MapUtils.isEmpty(params)){
return;
}
//检查recipe 规则
//可能是一个 也可能是多个
Object recipeIds = MapUtils.getObject(params,"runStepRecipeId");
if(ObjectUtils.isEmpty(recipeIds)){
return;
}
Set<String> recipeIdSet = new HashSet<>();
if(recipeIds instanceof String){
recipeIdSet.add((String)recipeIds);
}
if(recipeIds instanceof ArrayList){
recipeIdSet.addAll((ArrayList)recipeIds);
}
for(String recipeId : recipeIdSet){
String msg = FieldValidateUtils.validateRecipeIdFor536(recipeId);
Assert.state(StringUtils.isEmpty(msg),Errors.key(MessageIdList.RECIPE_ID_REGEXP_MSG_536));
}
}
/**
* Action 方法: getLotWithUnitInfo
*/
public Map<String, Object> getLotWithUnitInfo(Map<String, Object> params) {
String lotId = MapUtils.getString(params, "lotId");
Assert.isFalse(StringUtils.isEmpty(lotId),
Errors.create().content("The parameter is missing. Please login again.").build());
Lot lot = lotQueryService.getLot(lotId);
Assert.isFalse(lot == null,
Errors.create().key(MessageIdList.LOT_MISSING_ID).content("The lot is missing.").build());
//卡控post future hold被hold住的lot
checkPostFutureHold(lot.getLotRrn());
verifyLotInfo(lot);
AutoSplitMergeLot autoSplitMergeLot4Split = prpService.getAutoSplitMergeLot4Split(lot.getLotRrn());
Assert.isFalse(autoSplitMergeLot4Split != null && autoSplitMergeLot4Split.getTransRrn() > 0L,
Errors.create().key(MessageIdList.LOT_AUTOSPLITMERGEEXIST).content("lot in auto split merge")
.build());
return splitRunCardService.getLotWithUnitInfo(lot);
}
/**
* Action 方法: deleteRunCard
*/
public void deleteRunCard(Map<String, Object> params) {
deleteRunCardHandle(params);
}
/**
* Action 方法: frozenRunCard
*/
public void frozenRunCard(Map<String, Object> params) {
Long runCardRrn = MapUtils.getLong(params, "runCardRrn");
Assert.isFalse(runCardRrn == null || runCardRrn <= 0,
Errors.create().content("The parameter is missing. Please login again.").build());
LotRunCard lotRunCard = lotRunCardQueryService.getLotRunCard(runCardRrn);
Assert.isTrue(hasPermissionToWithdraw(lotRunCard),
Errors.create().content("Permission denied! The user is not the creator of this SRC!").build());
splitRunCardService.frozenRunCard(lotRunCard);
}
/**
* Action 方法: rejectRunCard
*/
public void rejectRunCard(Map<String, Object> params) {
splitRunCardService.rejectRunCard(params, "Auto Change Hold by SRC Review Reject");
}
/**
* Action 方法: getRunCardTransHistory
*/
public Map<String, Object> getRunCardTransHistory(Map<String, Object> params) {
int pageSize = MapUtils.getIntValue(params, "limit");
int pageNo = MapUtils.getIntValue(params, "page");
Long scrRrn = MapUtils.getLong(params, "runCardRrn");
Assert.isFalse(scrRrn == null || scrRrn <= 0,
Errors.create().content("The parameter is missing. Please login again.").build());
return splitRunCardService.getRunCardTransHistory(pageSize, pageNo, scrRrn);
}
/**
* Action 方法: approveRunCard
*/
public void approveRunCard(Map<String, Object> params) {
splitRunCardService.approveRunCard(params);
}
/**
* Action 方法: withdrawRunCard
*/
public void withdrawRunCard(Map<String, Object> params) {
splitRunCardService.withdrawRunCard(params, "Auto Change Hold by SRC Withdraw");
}
/**
* ajax 方法: getUserGroup 根据UserGroupId获取下面所有用户的信息
*/
public Map getUserGroup(Map<String, Object> params) {
Map resul = new HashMap();
List resultList = new ArrayList();
String userGroupIdStr = MapUtils.getString(params, "userGroupId");
if (StringUtils.isNotBlank(userGroupIdStr)) {
if (userGroupIdStr.length() > 0 && userGroupIdStr.indexOf("[") == 0 &&
userGroupIdStr.indexOf("]") == userGroupIdStr.length() - 1) {
userGroupIdStr = userGroupIdStr.substring(1, userGroupIdStr.length() - 1);
}
String[] userGroupIdArr = userGroupIdStr.split(",");
for (String userGroupId : userGroupIdArr) {
Long userGroupRrn = getInstanceRrn(userGroupId.trim(), LocalContext.getFacilityRrn(),
ObjectList.USERGROUP_KEY);
List<Map> userGroupGrantUserList = securityService.getHasGrantUserAll(userGroupRrn, null);
resultList.addAll(userGroupGrantUserList);
}
resultList = (List) resultList.stream().distinct().collect(Collectors.toList());
}
resul.put("data", resultList);
return resul;
}
public List<Map<String, Object>> getFutureStep4Preview(Map<String, Object> params) {
Map<String, Object> map = (Map<String, Object>) MapUtils.getObject(params, "params");
Long lotRrn = MapUtils.getLong(map, "lotRrn");
if (lotRrn == null || lotRrn == 0) {
return new ArrayList<>();
}
List<Map<String, Object>> list = buildStepInfos(map);
List<LotRunCardSplit> futureSteps = splitRunCardService.getFutureStep4Preview(lotRrn, list);
return getStepDetails(futureSteps, list);
}
public List<Map<String, Object>> getFutureStep4View(Map<String, Object> params) {
if (params.get("steps") != null) {
List<Map<String, Object>> list = (List) params.get("steps");
Long lotRrn = MapUtils.getLong(params, "lotRrn");
if (CollectionUtils.isNotEmpty(list)) {
List<LotRunCardSplit> futureSteps = splitRunCardService.getFutureStep4View(list);
return getStepDetails(futureSteps, list);
}
}
return new ArrayList<>();
}
public Map<String, Object> copyRunCardWithAutoCreateNew(Map<String, Object> params) {
String runCardId = MapUtils.getString(params, "runCardId");
Long runCardRrn = baseService.getNamedObjectRrn(runCardId,
baseService.getNamedSpace(LocalContext.getFacilityRrn(),
ObjectList.ECN_KEY),
ObjectList.ECN_KEY);
Assert.isFalse((runCardRrn == null || runCardRrn <= 0),
Errors.create().content("The parameter is missing. Please login again.").build());
return lotRunCardService.copyRunCard(runCardRrn);
}
public ActionForward printViewRunCardDetail(ActionMapping mapping, HttpServletRequest request) {
String[] types = new String[]{"RELATED_MODULE_GROUP", "RELATED_MODULE_MANAGER", "POLLUTIONLEVEL",
"WORKAREATYPE", "$LOT_CREATE_CATEGORY", "PROCESSLOCATION", "SRCHOLDCODE",
"RC_E1_MANAGER", "RC_SUPERVISOR", "RC_MFG_MANAGER"};
setForwardParametersToRequest(request, types);
return mapping.findForward("runCardViewPrint");
}
private List<Map<String, Object>> getStepDetails(List<LotRunCardSplit> futureSteps,
List<Map<String, Object>> stepList) {
if (CollectionUtils.isEmpty(futureSteps)) {
return new ArrayList<>();
}
List<Map<String, Object>> result = new ArrayList<>();
for (LotRunCardSplit futureStep : futureSteps) {
if (StringUtils.isNotBlank(futureStep.getStepSerials())) {
String[] chars = StringUtils.split(futureStep.getStepSerials(), ",");
for (String aChar : chars) {
Map<String, Object> temp = new HashMap<>(11);
temp.put("waferList", futureStep.getUnitRrns());
temp.put("serialNo", aChar);
//Map<String, Object> stepMap = stepList.get(NumberUtils.toInt(aChar) - 1);
Map<String, Object> stepMap = stepList.stream().filter(step -> StringUtils.equalsIgnoreCase(
MapUtils.getString(step, "stepSerialNo"), aChar)).findAny().orElse(null);
Assert.notNull(stepMap,
Errors.create().content("Step Serial No {} was not found!").args(aChar).build());
temp.put("step", MapUtils.getString(stepMap, "operationId"));
temp.put("area", MapUtils.getString(stepMap, "areaId"));
temp.put("recipe", MapUtils.getString(stepMap, "recipeId"));
if (StringUtils.isNotBlank(MapUtils.getString(stepMap, "equipmentId"))) {
temp.put("eqpId", MapUtils.getString(stepMap, "equipmentId"));
} else if (StringUtils.isNotBlank(MapUtils.getString(stepMap, "equipmentGroupId"))) {
String runStepEquipmentGroupId = MapUtils.getString(stepMap, "equipmentGroupId");
EntityGroup entityGroup = new EntityGroup(runStepEquipmentGroupId,
getNamedSpace(ObjectList.ENTITYGROUP_KEY,
LocalContext.getFacilityRrn()),
ObjectList.ENTITYGROUP_KEY);
NamedObject namedObject = baseService.getNamedObject(entityGroup);
if (namedObject != null && namedObject.getInstanceRrn() > 0) {
List<Relation> allEntities = emsService.getAllEntities(namedObject.getInstanceRrn());
String eqpIds = allEntities.stream().map(Relation::getInstanceId)
.collect(Collectors.joining(","));
temp.put("eqpId", eqpIds);
}
}
temp.put("contamination", MapUtils.getString(stepMap, "contamination"));
temp.put("measurementWafer", MapUtils.getString(stepMap, "measurementSlotRrns"));
temp.put("chart", MapUtils.getString(stepMap, "chart"));
//如果是RC_TOOD和RC_Search界面,参数存放在stepMap的parameters中
if (stepMap.get("parameters") != null) {
List list = (List) ((Map) MapUtils.getObject(stepMap, "parameters")).get("parameterId");
if (CollectionUtils.isNotEmpty(list)) {
temp.put("chart", StringUtils.join(list.toArray(), ","));
}
}
result.add(temp);
}
}
}
return result;
}
private List<Map<String, Object>> buildStepInfos(Map<String, Object> params) {
List<Map<String, Object>> steps = new ArrayList<>();
List<String> runStepSerialNos = getSubParamByKeyList(params, "runStepSerialNo");
List<String> runStepOperationIds = getSubParamByKeyList(params, "runStepOperationId");
List<String> runStepAreaIds = getSubParamByKeyList(params, "runStepAreaId");
List<String> runStepEquipmentIds = getSubParamByKeyList(params, "runStepEquipmentId");
List<String> runStepEquipmentGroupIds = getSubParamByKeyList(params, "runStepEquipmentGroupId");
List<String> runStepRecipeIds = getSubParamByKeyList(params, "runStepRecipeId");
List<String> runStepUnitRrns = getSubParamByKeyList(params, "runStepUnitRrns");
List<String> runStepUnitIds = getSubParamByKeyList(params, "runStepUnitIds");
List<String> runStepMeasurementSlotRrns = getSubParamByKeyList(params, "runStepMeasurementSlotRrns");
List<String> runStepContaminations = getSubParamByKeyList(params, "runStepContamination");
List<String> startOfMainQtimeFlags = getSubParamByKeyList(params, "startOfMainQtimeFlag");
List<String> endOfMainQtimeFlags = getSubParamByKeyList(params, "endOfMainQtimeFlag");
List<String> startOfRcQtimeFlags = getSubParamByKeyList(params, "startOfRcQtimeFlag");
List<String> endOfRcQtimeFlags = getSubParamByKeyList(params, "endOfRcQtimeFlag");
List<String> runStepRouteRrns = getSubParamByKeyList(params, "runStepRouteRrn");
List<String> timeLimits = getSubParamByKeyList(params, "timeLimit");
if (CollectionUtils.isNotEmpty(runStepSerialNos)) {
for (int i = 0; i < runStepSerialNos.size(); i++) {
Map<String, Object> stepMap = new HashMap<>();
String serialNo = runStepSerialNos.get(i);
stepMap.put("stepSerialNo", serialNo);
stepMap.put("operationId", StringUtils.trimToUpperCase(runStepOperationIds.get(i)));
stepMap.put("areaId", runStepAreaIds.get(i));
stepMap.put("equipmentId", StringUtils.trimToUpperCase(runStepEquipmentIds.get(i)));
stepMap.put("equipmentGroupId", StringUtils.trimToUpperCase(runStepEquipmentGroupIds.get(i)));
stepMap.put("recipeId", StringUtils.trimToUpperCase(runStepRecipeIds.get(i)));
stepMap.put("unitRrns", runStepUnitRrns.get(i));
stepMap.put("runStepUnitIds", getUnitIdAsList(runStepUnitIds.get(i)));
stepMap.put("measurementSlotRrns", runStepMeasurementSlotRrns.get(i));
stepMap.put("contamination", runStepContaminations.get(i));
stepMap.put("startOfMainQtime", startOfMainQtimeFlags.get(i));
stepMap.put("endOfMainQtime", endOfMainQtimeFlags.get(i));
stepMap.put("startOfRcQtime", startOfRcQtimeFlags.get(i));
stepMap.put("endOfRcQtime", endOfRcQtimeFlags.get(i));
stepMap.put("runStepRouteRrn", runStepRouteRrns.get(i));
stepMap.put("timeLimit", timeLimits.get(i));
String charts = "";
Object parameterIds = MapUtils.getObject(params, "parameterId" + (i + 1));
if (parameterIds != null) {
// 单个参数是String类型,多个参数是ArrayList类型
if (parameterIds instanceof String) {
charts = (String) MapUtils.getObject(params, "parameterId" + (i + 1));
} else if (parameterIds instanceof List) {
List<String> list = (List<String>) MapUtils.getObject(params, "parameterId" + (i + 1));
charts = StringUtils.join(list, ",");
}
}
stepMap.put("chart", charts);
steps.add(stepMap);
}
}
return steps;
}
private List<String> getUnitIdAsList(String unitIds) {
String[] unitArray = StringUtils.split(unitIds, ',');
return Arrays.asList(unitArray);
}
private List<String> getSubParamByKeyList(Map<String, Object> params, String key) {
List<String> ret = new ArrayList<>();
if (params.get(key) == null) {
return ret;
} else if ((params.get(key)) instanceof ArrayList) {
ret.addAll((Collection<? extends String>) params.get(key));
} else {
String kVal = MapUtils.getString(params, key);
ret.add(StringUtils.trim(kVal));
}
return ret;
}
private Long getLong4FlowSeq(String flowSeq) {
if (StringUtils.isBlank(flowSeq)) {
return null;
} else {
if (flowSeq.contains(".")) {
String[] flowSeqArray = flowSeq.split("\\.");
return Long.parseLong(flowSeqArray[0] + flowSeqArray[1]);
}
}
return Long.parseLong(flowSeq);
}
private boolean isAvailableSetLot(String lotStatus) {
boolean isOutStatus = isCurrentAvailableSetLot(lotStatus);
return isOutStatus || LotStatus.RUNNING.equalsIgnoreCase(lotStatus) ||
LotStatus.RUNNINGHOLD.equalsIgnoreCase(lotStatus) || LotStatus.PROCESSED.equalsIgnoreCase(lotStatus);
}
private boolean isCurrentAvailableSetLot(String lotStatus) {
return LotStatus.WAITING.equalsIgnoreCase(lotStatus) || LotStatus.HOLD.equalsIgnoreCase(lotStatus);
}
@Override
protected Boolean hasPermissionToWithdraw(LotRunCard lotRunCard) {
return splitRunCardService.hasPermissionToWithdraw(lotRunCard);
}
@Override
protected void verifyLotInfo(Lot lot) {
Assert.isFalse(StringUtils.isNotEmpty(lot.getReworkCategory()) ||
(lot.getReworkTransRrn() != null && lot.getReworkTransRrn() > 0),
Errors.create().content("Lot is in rework!").build());
Assert.isTrue(isAvailableSetLot(lot.getLotStatus()),
Errors.create().content("Lot status must be WAITING or HOLD!").build());
wipCheckService.checkPiLotNormalFunction(lot.getLotRrn(),lot.getBasedLotRrn());
}
}