EquipmentConstrainPairAction.java
package com.mycim.webapp.actions.constrain;
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.lang.StringUtils;
import com.mycim.framework.utils.lang.collections.MapUtils;
import com.mycim.valueobject.MessageIdList;
import com.mycim.valueobject.ObjectList;
import com.mycim.valueobject.bas.ErrorMsg;
import com.mycim.valueobject.bas.Relation;
import com.mycim.valueobject.consts.EquipmentConstrainPairConstants;
import com.mycim.valueobject.ems.Equipment;
import com.mycim.valueobject.ems.EquipmentConstrainPair;
import com.mycim.valueobject.ems.EquipmentConstrainPairDetail;
import com.mycim.valueobject.prp.Operation;
import com.mycim.valueobject.prp.ProcessPlanning;
import com.mycim.valueobject.prp.ProcessVersion;
import com.mycim.valueobject.wip.Lot;
import com.mycim.webapp.actions.PrpSetupAction;
import com.mycim.webapp.forms.EquipmentConstrainPairForm;
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 shijie.deng
* @version 6.0.0
* @date 2019/9/9
**/
public class EquipmentConstrainPairAction extends PrpSetupAction {
@Override
public ActionForward init(ActionMapping mapping, ActionForm form, HttpServletRequest request,
HttpServletResponse response) {
return mapping.getInputForward();
}
public Map<String, Object> getConstrain(EquipmentConstrainPairForm theform) {
long facilityRrn = LocalContext.getFacilityRrn();
Map<String, Object> dataMap = new HashMap();
String processId = StringUtils.trimToUpperCase(theform.getProcessId());
String productId = StringUtils.trimToUpperCase(theform.getProductId());
String lotId = StringUtils.trimToUpperCase(theform.getLotId());
long processRrn = getInstanceRrn(processId, facilityRrn, ObjectList.WFL_KEY);
long productRrn = getInstanceRrn(productId, facilityRrn, ObjectList.PRODUCT_KEY);
Lot lot = lotQueryService.getLot(lotId, facilityRrn);
EquipmentConstrainPair constrainPair = null;
if (StringUtils.isBlank(lotId)) {
if (0 == productRrn) {
dataMap.put("success", false);
dataMap.put("message", I18nUtils.getMessage("PRODUCT.PRODUCT_MISSING", "Product is not exist!"));
return dataMap;
}
if (0 == processRrn) {
dataMap.put("success", false);
dataMap.put("message", I18nUtils.getMessage("PROCESS.PROCESS_MISSING", "Process is not exist!"));
return dataMap;
}
} else if (lot.getLotRrn() == 0) {
dataMap.put("success", false);
dataMap.put("message", I18nUtils.getMessage("unshipLot.lot_not_exists", "This lot does not exist!"));
return dataMap;
}
if (processRrn > 0 && productRrn > 0) {
if (!isRightProcess(productRrn, processRrn)) {
dataMap.put("success", false);
dataMap.put("message", I18nUtils.getMessage("process.cant_get_process_info",
"The process information is not checked, please" + " " +
"check whether the " + "input is correct."));
return dataMap;
}
dataMap.put("processRrn", processRrn);
dataMap.put("productRrn", productRrn);
constrainPair = constrainService.getConstrainPairByProductAndProcess(productRrn, processRrn);
} else if (lot.getLotRrn() > 0) {
dataMap.put("lotRrn", lot.getLotRrn());
constrainPair = constrainService.getConstrainPairByLotRrn(lot.getLotRrn());
}
if (constrainPair != null) {
String status = constrainPair.getStatus();
Long constrainPairRrn = constrainPair.getConstrainPairRrn();
dataMap.put("status", status);
dataMap.put("constrainRrn", constrainPairRrn);
}
dataMap.put("success", true);
return dataMap;
}
public Map<String, Object> getProcessInfo(EquipmentConstrainPairForm theform) {
long facilityRrn = LocalContext.getFacilityRrn();
long lotRrn = theform.getLotRrn();
Long constrainRrn = theform.getConstrainRrn();
String onlyReticle = theform.getOnlyReticle();
long processRrn = theform.getProcessRrn();
long productRrn = theform.getProductRrn();
List<Map<String, Object>> viewProcessInfo = new ArrayList();
Map<String, Object> dataMap = new HashMap();
if (processRrn > 0 && productRrn > 0) {
// 获取工艺流程
Integer processNowActiveVersion = getProcessNowActiveVersion(processRrn);
// TODO : 后面改为调用存储过程的方法
viewProcessInfo = prpService
.getProcessAllStepInfo(processRrn, processNowActiveVersion, null, null, new Long(99999), null, null,
0);
} else if (lotRrn > 0) {
Lot lot = lotQueryService.getLot(lotRrn);
processRrn = lot.getProcessRrn();
productRrn = lot.getProductRrn();
Integer productVersion = lot.getProductVersion();
Integer processVersion = lot.getProcessVersion();
// TODO : 后面改为调用存储过程的方法
viewProcessInfo = prpService
.getProcessAllStepInfo(processRrn, processVersion, null, null, new Long(99999), null,
productVersion, 0);
}
// 查询返工工步信息并置入流程内
Integer processVersion = getProcessNowActiveVersion(processRrn);
buildReworkRouteInfo(viewProcessInfo, processRrn, productRrn, facilityRrn, processVersion.toString());
// 如果一条都没查出来则表示信息错误
Assert.isFalse(viewProcessInfo.size() < 1, Errors.create().key(MessageIdList.PROCESS_CANT_GET_PROCESS_INFO)
.content(
"The process information is not checked, " + "please" +
" check whether the input " + "is correct!")
.build());
// 如果不为空,则加入相关设置信息
if (constrainRrn != null && constrainRrn > 0) {
List<EquipmentConstrainPairDetail> details = constrainService
.getConstrainPairDetailsByConstrainRrn(constrainRrn);
// 匹配已设置的机限 进行加工
buildConstrainInfo(viewProcessInfo, details, onlyReticle, facilityRrn, productRrn);
} else {
// 未设置 机限 也要 对流程信息进行加工
buildProcessInfoToSetBenchMark(viewProcessInfo, onlyReticle, facilityRrn, productRrn);
}
dataMap.put("dataLists", viewProcessInfo);
return dataMap;
}
public List<Map<String, Object>> getEquipments(EquipmentConstrainPairForm theform) {
long facilityRrn = LocalContext.getFacilityRrn();
String operationId = theform.getOperationId();
String choosedEquipments = theform.getChoosedEquipments();
String routeId = theform.getRouteId();
String processId = theform.getProcessId().toUpperCase();
String productId = theform.getProductId().toUpperCase();
String lotId = theform.getLotId().toUpperCase();
// 有lotId时,processId和productId必定为空,所以这时从lot里面取
if (StringUtils.isNotBlank(lotId)) {
Lot lot = lotQueryService.getLot(lotId, facilityRrn);
processId = lot.getProcessId();
productId = lot.getProductId();
}
String[] choosedEquipmentArry = {};
if (StringUtils.isNotBlank(choosedEquipments)) {
choosedEquipmentArry = choosedEquipments.split(",");
}
Operation operation = prpService.getOperation(operationId, facilityRrn);
long entityGroupRrn = operation.getEntityGroupRrn();
List<Relation> entitygroup = emsService.getAllEntities(entityGroupRrn);
List<Map<String, Object>> entitymaps = new ArrayList<Map<String, Object>>();
for (Relation relation : entitygroup) {
String instanceId = relation.getInstanceId();
long instanceRrn = relation.getInstanceRrn();
String instanceDesc = relation.getInstanceDesc();
// 判断设备是否设置了工艺限制
// 1.构建lot
Lot buildLot = new Lot();
buildLot.setLotId(lotId);
buildLot.setProcessId(processId);
buildLot.setProductId(productId);
buildLot.setOperationId(operationId);
buildLot.setRouteId(routeId);
// 2.构建equipment
Equipment equipment = new Equipment();
equipment.setInstanceId(instanceId);
equipment.setInstanceRrn(instanceRrn);
Boolean isSetLotConstrain = constrainService.isSetLotConstrain(equipment, buildLot);
if (isSetLotConstrain) {
// 如果设置了工艺限制,不做后续操作,继续下一次循环
continue;
}
Map<String, Object> entitymap = new HashMap<String, Object>();
entitymap.put("instanceId", instanceId);
entitymap.put("instanceDesc", instanceDesc);
if (choosedEquipmentArry.length > 0) {
Boolean isChoose = false;
for (String choosedEquipment : choosedEquipmentArry) {
if (choosedEquipment.equals(instanceId)) {
isChoose = true;
break;
}
}
entitymap.put("checkboxInput", isChoose);
} else {
entitymap.put("checkboxInput", false);
}
entitymaps.add(entitymap);
}
return entitymaps;
}
public Map<String, Object> saveConfiguration(EquipmentConstrainPairForm theform) {
long facilityRrn = LocalContext.getFacilityRrn();
String userId = LocalContext.getUserId();
Map<String, Object> map = new HashMap();
String lotId = theform.getLotId();
Long lotRrn = theform.getLotRrn();
String processId = theform.getProcessId();
Long processRrn = theform.getProcessRrn();
String productId = theform.getProductId();
Long productRrn = theform.getProductRrn();
Long constrainRrn = theform.getConstrainRrn();
String type = theform.getType();
List<Map<String, Object>> changeRecords = theform.getChangeRecords();
Long constrainRrnL = 0L;
if (constrainRrn != null) {
constrainRrnL = constrainRrn;
}
ErrorMsg errorMsg = validateBenchmark(changeRecords, constrainRrnL);
// 检查数据正确性不通过
Assert.isFalse(errorMsg.getError(), Errors.create().content(errorMsg.getErrorMsg()).build());
Map<String, Object> transInfo = new HashMap<String, Object>();
transInfo.put("processRrn", processRrn);
transInfo.put("productRrn", productRrn);
transInfo.put("productId", productId);
transInfo.put("lotRrn", lotRrn);
transInfo.put("lotId", lotId);
transInfo.put("processId", processId);
transInfo.put("constrainRrn", constrainRrn);
transInfo.put("facilityRrn", facilityRrn);
transInfo.put("user", userId);
transInfo.put("type", type);
transInfo.put("changeRecords", changeRecords);
constrainRrnL = constrainService.saveConstrainPair(transInfo);
map.put("success", true);
map.put("constrainRrn", constrainRrnL);
return map;
}
public String disableOrEnable(EquipmentConstrainPairForm theform) {
long facilityRrn = LocalContext.getFacilityRrn();
String userId = LocalContext.getUserId();
Map<String, Object> dataMap = new HashMap<String, Object>();
Long constrainRrn = theform.getConstrainRrn();
String changeStatus = theform.getChangeStatus();
String status;
if (EquipmentConstrainPairConstants.STATUS_DISABLE.equals(StringUtils.trimToUpperCase(changeStatus))) {
status = EquipmentConstrainPairConstants.STATUS_DISABLE;
} else {
status = EquipmentConstrainPairConstants.STATUS_ENABLE;
}
constrainService.changeConstrianStatus(constrainRrn, userId, status, facilityRrn);
return I18nUtils.getMessage("system.operate_successfully", "operate successfully!");
}
private void buildConstrainInfo(List<Map<String, Object>> processInfos, List<EquipmentConstrainPairDetail> details,
String onlyReticleStr, Long facilityRrn, Long productRrn) {
Boolean onlyReticle = false;
if (onlyReticleStr != null) {
onlyReticle = new Boolean(onlyReticleStr);
}
// 需要移除的非光刻工步
List<Map<String, Object>> noReticles = new ArrayList<>();
for (Map<String, Object> processInfo : processInfos) {
long processRrn = MapUtils.getLongValue(processInfo, "processRrn");
int processVersion = MapUtils.getIntValue(processInfo, "processVersion");
Integer productVersion = MapUtils.getInteger(processInfo, "productVersion");
long routeRrn = MapUtils.getLongValue(processInfo, "routeRrn");
long operationRrn = MapUtils.getLongValue(processInfo, "operationRrn");
long reticleFamilyRrn = ctxExecService
.getReticleFamilyRrn(productRrn, productVersion, processRrn, processVersion, routeRrn,
operationRrn);
if (onlyReticle && reticleFamilyRrn < 1) {
// 需要过滤不是光刻工步
noReticles.add(processInfo);
continue;
}
if (reticleFamilyRrn > 0) {
processInfo.put("reticlefamilyId", getInstanceId(reticleFamilyRrn));
}
// 对流程进行处理
initProcessInfo(facilityRrn, processInfo);
// 准备比较数据
Long routeRrnP = MapUtils.getLong(processInfo, "routeRrn");
Long operationRrnP = MapUtils.getLong(processInfo, "operationRrn");
String routeProcessSeqP = MapUtils.getString(processInfo, "routeProcessSeq");
String operationRouteSeqP = MapUtils.getString(processInfo, "operationRouteSeq");
String layerIdP = MapUtils.getString(processInfo, "layerId");
String reticlefamilyIdP = MapUtils.getString(processInfo, "reticlefamilyId");
Map<String, Object> processMap = new HashMap<String, Object>();
processMap.put("routeRrn", routeRrnP);
processMap.put("operationRrn", operationRrnP);
if (StringUtils.isNotBlank(routeProcessSeqP)) {
processMap.put("routeSeq", routeProcessSeqP);
}
if (StringUtils.isNotBlank(operationRouteSeqP)) {
processMap.put("operationSeq", operationRouteSeqP);
}
if (StringUtils.isNotBlank(reticlefamilyIdP)) {
processMap.put("reticlefamilyId", reticlefamilyIdP);
}
if (StringUtils.isNotBlank(layerIdP)) {
processMap.put("layerId", layerIdP);
}
for (EquipmentConstrainPairDetail detail : details) {
Long routeRrnD = detail.getRouteRrn();
Long operationRrnD = detail.getOperationRrn();
String routeSeq = detail.getRouteSeq();
String operationSeq = detail.getOperationSeq();
String reticlefamilyId = detail.getReticlefamilyId();
String layerId = detail.getLayerId();
Map<String, Object> detailMap = new HashMap<String, Object>();
detailMap.put("routeRrn", routeRrnD);
detailMap.put("operationRrn", operationRrnD);
if (StringUtils.isNotBlank(routeSeq)) {
detailMap.put("routeSeq", routeSeq);
}
if (StringUtils.isNotBlank(operationSeq)) {
detailMap.put("operationSeq", operationSeq);
}
if (StringUtils.isNotBlank(reticlefamilyId)) {
detailMap.put("reticlefamilyId", reticlefamilyId);
}
if (StringUtils.isNotBlank(layerId)) {
detailMap.put("layerId", layerId);
}
// 匹配成功 放入 设置信息
if (detailMap.equals(processMap)) {
processInfo.put("isBenchmark", detail.getIsBenchmark());
processInfo.put("detailRrn", detail.getConstrainDetailRrn());
processInfo.put("PlanA", StringUtils.isNotBlank(detail.getPlanA()) ? detail.getPlanA() : "");
processInfo.put("PlanB", StringUtils.isNotBlank(detail.getPlanB()) ? detail.getPlanB() : "");
processInfo.put("PlanC", StringUtils.isNotBlank(detail.getPlanC()) ? detail.getPlanC() : "");
processInfo.put("PlanD", StringUtils.isNotBlank(detail.getPlanD()) ? detail.getPlanD() : "");
processInfo.put("PlanE", StringUtils.isNotBlank(detail.getPlanE()) ? detail.getPlanE() : "");
break;
}
}
}
processInfos.removeAll(noReticles);
}
private void buildProcessInfoToSetBenchMark(List<Map<String, Object>> processInfos, String onlyReticleStr,
Long facilityRrn, Long productRrn) {
Boolean onlyReticle = false;
if (onlyReticleStr != null) {
onlyReticle = new Boolean(onlyReticleStr);
}
// 需要移除的非光刻工步
List<Map<String, Object>> noReticles = new ArrayList<>();
for (Map<String, Object> processInfo : processInfos) {
long processRrn = MapUtils.getLongValue(processInfo, "processRrn");
int processVersion = MapUtils.getIntValue(processInfo, "processVersion");
Integer productVersion = MapUtils.getInteger(processInfo, "productVersion");
long routeRrn = MapUtils.getLongValue(processInfo, "routeRrn");
long operationRrn = MapUtils.getLongValue(processInfo, "operationRrn");
long reticleFamilyRrn = ctxExecService
.getReticleFamilyRrn(productRrn, productVersion, processRrn, processVersion, routeRrn,
operationRrn);
if (onlyReticle && reticleFamilyRrn < 1) {
// 需要过滤不是光刻工步
noReticles.add(processInfo);
continue;
}
if (reticleFamilyRrn > 0) {
processInfo.put("reticlefamilyId", getInstanceId(reticleFamilyRrn));
}
processInfo.put("facilityRrn", facilityRrn);
initProcessInfo(facilityRrn, processInfo);
}
processInfos.removeAll(noReticles);
}
private void initProcessInfo(Long facilityRrn, Map<String, Object> processInfo) {
processInfo.put("isBenchmark", "false");
processInfo.put("PlanA", "");
processInfo.put("PlanB", "");
processInfo.put("PlanC", "");
processInfo.put("PlanD", "");
processInfo.put("PlanE", "");
String layerId = MapUtils.getString(processInfo, "layerId");
if (layerId == null) {
// 必须设置... 不然ext会提交"null"字符串到后台
processInfo.put("layerId", "");
}
long productRrn = MapUtils.getLongValue(processInfo, "productRrn");
long processRrn = MapUtils.getLongValue(processInfo, "processRrn");
int processVersion = MapUtils.getIntValue(processInfo, "processVersion");
Integer productVersion = MapUtils.getInteger(processInfo, "productVersion");
long routeRrn = MapUtils.getLongValue(processInfo, "routeRrn");
long operationRrn = MapUtils.getLongValue(processInfo, "operationRrn");
long reticleFamilyRrn = ctxExecService
.getReticleFamilyRrn(productRrn, productVersion, processRrn, processVersion, routeRrn, operationRrn);
String reticleFamilyId = reticleFamilyRrn > 0 ? getInstanceId(reticleFamilyRrn) : StringUtils.EMPTY;
processInfo.put("reticlefamilyId", reticleFamilyId);
// 是否需要光刻板
String routeProcessSeq = MapUtils.getString(processInfo, "routeProcessSeq");
if (routeProcessSeq == null) {
processInfo.put("routeProcessSeq", "");
}
// 是否是返工工步
Boolean isRework = MapUtils.getBoolean(processInfo, "isRework");
if (isRework == null || !isRework) {
processInfo.put("isRework", false);
}
}
private ErrorMsg validateBenchmark(List<Map<String, Object>> changeRecords, Long constrainRrn) {
ErrorMsg errorMsg = new ErrorMsg();
errorMsg.setError(false);
// 1.第一次保存是验证必须选择基准层
boolean haveBenchmark = false;
for (Map<String, Object> map : changeRecords) {
boolean isBenchmark = MapUtils.getBooleanValue(map, "isBenchmark");
if (isBenchmark) {
haveBenchmark = true;
List<String> plan = new ArrayList<String>();
String PlanA = MapUtils.getString(map, "PlanA");
plan.add(PlanA);
String PlanB = MapUtils.getString(map, "PlanB");
plan.add(PlanB);
String PlanC = MapUtils.getString(map, "PlanC");
plan.add(PlanC);
String PlanD = MapUtils.getString(map, "PlanD");
plan.add(PlanD);
String PlanE = MapUtils.getString(map, "PlanE");
plan.add(PlanE);
// 2.验证基准层设备无交集且至少有一个计划设置了设备
if (!validateEquipment(plan)) {
errorMsg.setError(true);
errorMsg.setErrorMsg(I18nUtils.getMessage("constrain.save_failed_benchmark_epq_duplication",
"Save failed, the benchmark layer 'uninstalled EQP' or " +
"'planned EQP duplication'"));
}
}
}
// 初次保存
if ((constrainRrn == null || constrainRrn < 1) && !haveBenchmark) {
errorMsg.setError(true);
errorMsg.setErrorMsg(I18nUtils.getMessage("constrain.save_failed_benchmark_not_set",
"Save failed,No baseline layer is set."));
}
return errorMsg;
}
private Boolean validateEquipment(List<String> plan) {
Boolean isPass = true;
Boolean isSetEqpt = false;
List<String> equipmentList = new ArrayList<String>();
for (String str : plan) {// 遍历计划
if (StringUtils.isNotBlank(str)) {
isSetEqpt = true;
}
String[] equipmentArry = str.split(",");// 分隔成设备数组
for (String equipment : equipmentArry) {// 将所有计划的设备加入list
if (StringUtils.isNotBlank(equipment)) {
equipmentList.add(equipment);
}
}
}
// 再来遍历List 看每个设备在list里面的数量
for (int i = 0; i < equipmentList.size() - 1; i++) {
for (int j = i + 1; j < equipmentList.size(); j++) {
if (equipmentList.get(i).equals(equipmentList.get(j))) {
isPass = false;// 重复了
break;
}
}
}
return (isPass && isSetEqpt);
}
private Integer getProcessNowActiveVersion(Long processRrn) {
ProcessPlanning processPlanning = new ProcessPlanning();
processPlanning.setInstanceRrn(processRrn);
Collection processVersions = prpService.getProcessVersions(processPlanning);
Integer nowVersion = 1;
for (Iterator iterator = processVersions.iterator(); iterator.hasNext(); ) {
ProcessVersion processVersion = (ProcessVersion) iterator.next();
String tempProcessStatus = processVersion.getVersionStatus();
if (tempProcessStatus.trim().equalsIgnoreCase("ACTIVE")) {
nowVersion = processVersion.getInstanceVersion();
break;
}
}
return nowVersion;
}
private boolean isRightProcess(Long productRrn, Long processRrn) {
boolean isRight = false;
List<Map> productTechnologys = prpService.getProductTechnologys(productRrn);
for (Map map : productTechnologys) {
Long rightProcessRrn = MapUtils.getLong(map, "instancerrn");
if (processRrn.equals(rightProcessRrn)) {
isRight = true;
}
}
return isRight;
}
private void buildReworkRouteInfo(List<Map<String, Object>> viewProcessInfo, Long processRrn, Long productRrn,
Long facilityRrn, String processVersion) {
List<String> reworkRoutes = new ArrayList<String>();
for (Map<String, Object> processInfo : viewProcessInfo) {
// 查询流程中的返工工步
long processReworkRouteRrn = ctxExecService.getProcessReworkRouteRrn(processInfo);
if (processReworkRouteRrn > 0) {
reworkRoutes.add(processReworkRouteRrn + "");
}
}
// 获得返工工序详情
Map<String, Object> reworkCondition = new HashMap<String, Object>();
reworkCondition.put("PRODUCT_RRN", productRrn + "");
reworkCondition.put("PROCESS_RRN", processRrn + "");
reworkCondition.put("PROCESS_VERSION", processVersion);
reworkCondition.put("ROUTE_RRN_ARRAY", reworkRoutes.toArray());
reworkCondition.put("PROCESS_STATUS", "ACTIVE");
// TODO : 等待流程树查询
// List<Map<String, Object>> viewReworkRouteInfo = (List<Map<String, Object>>)
// getPrpSetupManager().viewReworkRouteInfo(
// reworkCondition);
// if (viewReworkRouteInfo != null) {
// for (Map<String, Object> reworkRouteInfo : viewReworkRouteInfo) {
// reworkRouteInfo.put("isRework", true);
// }
// // 加入流程中
// viewProcessInfo.addAll(viewReworkRouteInfo);
// }
}
}