RebuildLotAction.java
package com.mycim.webapp.actions.dmmbuildlot;
import com.fa.sesa.exception.Assert;
import com.fa.sesa.exception.Errors;
import com.fa.sesa.exception.SystemIllegalArgumentException;
import com.fa.sesa.threadlocal.LocalContext;
import com.mycim.framework.utils.lang.StringUtils;
import com.mycim.framework.utils.lang.collections.MapUtils;
import com.mycim.framework.utils.lang.math.NumberUtils;
import com.mycim.valueobject.MessageIdList;
import com.mycim.valueobject.ObjectList;
import com.mycim.valueobject.bas.ErrorMsg;
import com.mycim.valueobject.consts.ReferenceDetailNames;
import com.mycim.valueobject.consts.ReferenceFileConst;
import com.mycim.valueobject.consts.TransactionNames;
import com.mycim.valueobject.ems.Equipment;
import com.mycim.valueobject.prp.*;
import com.mycim.valueobject.sys.ReferenceFileDetail;
import com.mycim.valueobject.wip.Lot;
import com.mycim.valueobject.wip.LotExt;
import com.mycim.webapp.actions.NpwSetupAction;
import com.mycim.webapp.forms.RebuildLotForm;
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.lang.Override;
import java.util.*;
import java.util.regex.Pattern;
/**
* DMM分批
*
* @author yanbing.chen
* @date 2019/11/15
* @since 1.8
**/
public class RebuildLotAction extends NpwSetupAction {
protected static String TRUE = "1";
private static List<Map> targetEditLotUnits;
@Override
public ActionForward init(ActionMapping mapping, ActionForm form, HttpServletRequest request,
HttpServletResponse response) throws Exception {
targetEditLotUnits = new ArrayList<>();
for (int i = 0; i < 25; i++) {
Map map = new HashMap();
map.put("postionInCarrier", (i + 1) + "");
targetEditLotUnits.add(map);
}
String[] types = new String[]{"EQUIPMENTLOCATION", "TESTTYPE"};
registerOptionType(LocalContext.getFacilityRrn(), Arrays.asList(types), request);
return mapping.findForward("buildLotDetail");
}
public Map queryUnits(Map transMap) throws Exception {
String _lotRrns = MapUtils.getString(transMap, "lotRrn");
List<Map> list = null;
if (StringUtils.isNotBlank(_lotRrns)) {
String[] lotRrns = _lotRrns.split("#");
list = wipQueryService.getUnits(new Long(lotRrns[0]));
for (int i = 1; i < lotRrns.length; i++) {
list.addAll(wipQueryService.getUnits(new Long(lotRrns[i])));
}
}
if (list == null) {
list = new ArrayList();
}
Map result = new HashMap();
result.put("results", list.size());
result.put("rows", list);
return result;
}
public Map viewLotList(Map transMap) {
Long facilityRrn = LocalContext.getFacilityRrn();
List<Map> lots = new ArrayList();
String eqptId = MapUtils.getString(transMap, "eqptId");
String dmmProcess = MapUtils.getString(transMap, "dmmProcess");
Long dmmProcessRrn = getInstanceRrn(dmmProcess, getNamedSpace("WFL", facilityRrn), "WFL");
Long objectRrn = getInstanceRrn(eqptId, getNamedSpace("ENTITY", facilityRrn), "ENTITY");
String lotStatus = MapUtils.getString(transMap, "lotStatus");
Map map = new HashMap();
map.put("entityRrn", objectRrn);
map.put("dmmProcessRrn", dmmProcessRrn);
List list = new ArrayList();
Map resultMap = null;
List eqptMs = dmmService.getDMMRelationByMap(map);
if (eqptMs.size() > 0) {
String sourceProcess = "";
for (int i = 0; i < eqptMs.size(); i++) {
EqpMonitorEntityRelation rel = (EqpMonitorEntityRelation) eqptMs.get(i);
if (!StringUtils.contains(sourceProcess, rel.getSourceProcessRrn() + "")) {
lots.addAll(dmmLotService.getAvailableLotListNpwAutoBankin(rel.getSourceProcessRrn()));
sourceProcess += (rel.getSourceProcessRrn() + ",");
}
}
} else {
Map result = new HashMap();
result.put("results", list.size());
result.put("rows", list);
return result;
}
for (Map lot : lots) {
if (StringUtils.isBlank((String) lot.get("carrierId"))) {
continue;
}
resultMap = new HashMap();
resultMap.put("LotRRN", lot.get("lotRrn"));// 批次RRN
resultMap.put("LotID", lot.get("lotId"));// 批次号
resultMap.put("CarrierID", lot.get("carrierId"));// 晶舟号
resultMap.put("LotCategory", lot.get("lotType"));// 批次类型
ReferenceFileDetail detail = getReferenceFileDetail("$$LOT_PRIORITY", MapUtils.getString(lot, "priority"),
facilityRrn);
resultMap.put("LotPiority", detail.getData1Value());// 优先级
resultMap.put("Qty1", lot.get("qty1"));// 数量
resultMap.put("processId", lot.get("processId"));// 流程id
resultMap.put("processRrn", lot.get("processRrn"));// 流程Rrn
resultMap.put("ProductID", lot.get("productId"));// 产品号
resultMap.put("StageID", lot.get("stageId"));// 路径段号
resultMap.put("RouteID", lot.get("routeId"));// 路径号
String routeDesc = baseService.getInstanceDesc(MapUtils.getLongValue(lot, "routeRrn"));
resultMap.put("RouteDesc", routeDesc);// 路径描述
resultMap.put("OperationID", lot.get("operationId"));// 步骤号
resultMap.put("operationDesc", lot.get("operationDesc"));// 步骤描述
/*resultMap.put("RecipeID", lot.get("recipeId"));// 工艺菜单号
resultMap.put("physicalRecipeID",
recipeService.buildRecipePhysicalId(MapUtils.getString(lot, "recipeId"), lot));
resultMap.put("RecipePara", lot.get("recipeParam"));// 工艺规格*/
resultMap.put("QueueTime", lot.get("queueTimestamp"));// 等待时间
resultMap.put("equipRRN", lot.get("equipmentRrn"));
resultMap.put("pollutionLevel", lot.get("pollutionLevel"));// 污染等级
Operation operation = prpService.getOperation((String) lot.get("operationId"), facilityRrn);
resultMap.put("jobRrn",
(lot.get("jobRrn") == null || "0".equals(String.valueOf(lot.get("jobRrn")))) ? null : lot
.get("jobRrn"));
resultMap.put("LotStatus", "IN_USE");
// get operation seq.
Map condtion = new HashMap();
condtion.put("facilityRrn", facilityRrn);
condtion.put("operationRrn", lot.get("operationRrn") + "");
condtion.put("routeRrn", lot.get("routeRrn") + "");
condtion.put("processRrn", lot.get("processRrn") + "");
condtion.put("productRrn", org.apache.commons.collections.MapUtils.getString(lot, "productRrn"));
Lot curLot = lotQueryService.getLot(Long.parseLong(lot.get("lotRrn").toString()));
String wflStepPath = curLot.getWflStepPath();
String operationSeq = "";
String routeSeq = "";
if (wflStepPath.indexOf("|") > 0) {
operationSeq = prpService
.getWflSeq(wflStepPath.substring(wflStepPath.indexOf("|") + 1, wflStepPath.length()), "1");
routeSeq = prpService.getWflSeq(wflStepPath.substring(0, wflStepPath.indexOf("|")), "0");
}
if (operationSeq == null) {
operationSeq = "";
}
if (routeSeq == null) {
routeSeq = "";
}
resultMap.put("routeSeq", routeSeq);
resultMap.put("operationSeq", operationSeq);
resultMap.put("operationRrn", lot.get("operationRrn"));
resultMap.put("flowSeq", lot.get("flowSeq"));
// get work area
addWorkArea(resultMap);
// start: 检查批次在当前设备是否有constrain
String constrainFlag = "NO";
String constrainMsg = "";
if (MapUtils.getString(transMap, "objectRrn") != null) {
Pattern pattern = Pattern.compile("[0-9]*");
if (pattern.matcher(MapUtils.getString(transMap, "objectRrn")).matches()) {
Equipment equipment = new Equipment();
equipment.setInstanceRrn(Long.parseLong(MapUtils.getString(transMap, "objectRrn")));
long tLotRrn = Long.parseLong(String.valueOf(lot.get("lotRrn")));
Lot sLot = lotQueryService.getLot(tLotRrn);
ErrorMsg errorMsg = constrainService.checkLotConstrain(equipment, sLot);
if (errorMsg.getError()) {
constrainFlag = "YES";
constrainMsg = errorMsg.getErrorMsg();
}
}
}
resultMap.put("constrainFlag", constrainFlag);
resultMap.put("constrainMsg", constrainMsg);
// end: 检查批次在当前设备是否有constrain
resultMap.put("hotFlag", lot.get("hotFlag"));
LotExt lotExt = new LotExt();
lotExt.setLotRrn(NumberUtils.toLong(lot.get("lotRrn").toString()));
lotExt = lotQueryService.getLotExt(lotExt);
if (StringUtils.isNotEmpty(lotExt.getAttributeData3())) {
resultMap.put("pilot", "Y");
} else {
resultMap.put("pilot", "N");
}
list.add(resultMap);
}
Map result = new HashMap();
result.put("results", list.size());
result.put("rows", list);
return result;
}
//查询selectUnit结果集的
public Map changeUnits(Map transMap) {
String flag = MapUtils.getString(transMap, "flag");
// 选择一个晶圆
if (StringUtils.equalsIgnoreCase("select", flag)) {
int blankIndex = -1;
for (int i = 24; i >= 0; i--) {
Map _map = targetEditLotUnits.get(i);
if (StringUtils.isBlank((String) _map.get("unitId"))) {
blankIndex = i;
}
if (StringUtils.equalsIgnoreCase(MapUtils.getString(transMap, "unitId"), (String) _map.get("unitId"))) {
Map result = new HashMap();
result.put("results", targetEditLotUnits.size());
result.put("rows", targetEditLotUnits);
return result;
}
}
// 注释掉的是按照晶圆原先的位置插入到新晶舟的同样位置
Integer position = Integer.parseInt(MapUtils.getString(transMap, "postionInCarrier"));
// Map map = (Map) list.get(position - 1);
// if (StringUtils.isBlank((String) map.get("unitId"))) {// &&StringUtils.equalsIgnoreCase(
// (String)
// // map.get("unitId"), request.getParameter("unitId"))
// map.put("oldPostionInCarrier", position);
// builtMap4Unit(request, map);
// } else {
// if (blankIndex != -1) {
// map = (Map) list.get(blankIndex);
// map.put("oldPostionInCarrier", position);
// builtMap4Unit(request, map);
// }
// }
if (blankIndex != -1) {
Map map = targetEditLotUnits.get(blankIndex);
map.put("oldPostionInCarrier", position);
transMap.remove("postionInCarrier");
map.putAll(transMap);
}
} else if (StringUtils.equalsIgnoreCase("drop", flag)) {
// 拖拽一个晶圆,调整在新晶舟中的位置
// 插入位置
int afterPosition = Integer.parseInt(MapUtils.getString(transMap, "insertPosition"));
int beforePosition = Integer.parseInt(MapUtils.getString(transMap, "dragBeforePosition"));
/*
* Map map = new HashMap(); if (StringUtils.isNotBlank(unitId)) { map.put
("oldPostionInCarrier",
* request.getParameter("oldPostionInCarrier"));// 原所在批次晶舟中的位置 builtMap4Unit(request,
map); }
*/
beforePosition--;
// Map beforeMap = (Map) list.remove(beforePosition);
// Map afeterMap = (Map) list.remove(--afterPosition);
// if (StringUtils.equalsIgnoreCase("before", dropPosition)) {
// list.add(--afterPosition, map);
// Map beforeMap = (Map) list.remove(beforePosition);// 7
// Map afeterMap = (Map) list.remove(--afterPosition);// 3
HashMap beforeMap = (HashMap) targetEditLotUnits.get(beforePosition);
HashMap afeterMap = (HashMap) targetEditLotUnits.get(--afterPosition);
HashMap temp = (HashMap) beforeMap.clone();
targetEditLotUnits.set(beforePosition, afeterMap);
targetEditLotUnits.set(afterPosition, temp);
// list.add(afterPosition, beforeMap);// 3
// list.add(beforePosition, afeterMap);// 7
// } else {
// list.add(--afterPosition, map);
// Map afeterMap = (Map) list.remove(--afterPosition);
// Map beforeMap = (Map) list.remove(beforePosition);
// list.add(beforePosition, afeterMap);
// list.add(afterPosition, beforeMap);
// }
int pf = 1;
for (int i = 0; i < 25; i++) {
Map map = (Map) targetEditLotUnits.get(i);
map.put("postionInCarrier", (pf++) + "");
}
} else if (StringUtils.equalsIgnoreCase("deselect", flag)) {
// 去掉选择的一个晶圆
for (int i = targetEditLotUnits.size() - 1; i >= 0; i--) {
Map map = (Map) targetEditLotUnits.get(i);
if (StringUtils.equals(MapUtils.getString(map, "unitId"), MapUtils.getString(transMap, "unitId"))) {
clearMap4Unit(map);
}
}
} else if (StringUtils.equalsIgnoreCase("clearSUnits", flag)) {
// 清空选择的晶圆
for (int i = 0; i < targetEditLotUnits.size(); i++) {
Map map = (Map) targetEditLotUnits.get(i);
clearMap4Unit(map);
}
}
Map result = new HashMap();
result.put("results", targetEditLotUnits.size());
result.put("rows", targetEditLotUnits);
return result;
}
public String buildLot(RebuildLotForm theform) throws Exception {
long facilityRrn = LocalContext.getFacilityRrn();
long userRrn = LocalContext.getUserRrn();
String userId = LocalContext.getUserId();
List<Map> selectedUnits = selectedUnits(targetEditLotUnits);
Assert.isFalse(selectedUnits.isEmpty(), Errors.create().key(MessageIdList.WAFER_INFORMATION_ERRO).content(
"The wafer information is wrong, please pick it " + "again!").build());
String eqptId = StringUtils.trim(theform.getEqptId());
List<Lot> lots = getLots(selectedUnits);
for (Iterator iterator = lots.iterator(); iterator.hasNext(); ) {
Lot lot = (Lot) iterator.next();
List unitInfos = lot.getUnitsInfo();
Assert.isFalse(unitInfos.size() == selectedUnits.size() && lots.size() == 1,
Errors.create().content("单批无法全部分为子批").build());
}
String childLotId = dmmLotService.generateMonitorSplitLotId(eqptId).toUpperCase();
String carrierId = StringUtils.trimToUpperCase(theform.getParentCarrierId());
Lot __lot = lotQueryService.getLotByCarrierId(carrierId, facilityRrn);
Assert.isFalse(__lot != null && __lot.getLotRrn() > 0,
Errors.create().key(MessageIdList.CARRIER_CARRIER_UNAVAILABLE)
.content("Carrier is not available!").build());
long carrierRrn = getInstanceRrn(carrierId, getNamedSpace(ObjectList.ENTITY_KEY, facilityRrn),
ObjectList.ENTITY_KEY, ObjectList.CARRIER_KEY);
Assert.isFalse(carrierRrn <= 0,
Errors.create().key(MessageIdList.UNFINISHLOT_NOT_FIND_CARRIER).content("Cannot Find carrier!")
.build());
Lot lot = lotQueryService.getLot(childLotId);
if (lot.getLotRrn() <= 0) {
String maxLotToUnit = "";
Collection maxLotUnitList = new ArrayList();
for (Iterator iterator = lots.iterator(); iterator.hasNext(); ) {
Lot selectedLot = (Lot) iterator.next();
if (maxLotUnitList.size() < selectedLot.getSelectedUnitsInfo().size()) {
maxLotUnitList = selectedLot.getSelectedUnitsInfo();
maxLotToUnit = selectedLot.getLotId();
}
}
Lot parentLot = lotQueryService.getLot(maxLotToUnit);
if (parentLot.getOperationRrn() > 0) {
parentLot.setOperationDesc(baseService.getInstanceDesc(parentLot.getOperationRrn()));
}
Lot childLot = (Lot) parentLot.clone();
childLot.setLotId(childLotId);
childLot.setBasedLotRrn(parentLot.getLotRrn());
childLot.setCarrierRrn(carrierRrn);
childLot.setCarrierId(carrierId);
childLot.setCarrierMapRrn(null);
childLot.setEqptRrn(baseService.getNamedObjectRrn(eqptId, baseService
.getNamedSpace(facilityRrn, ObjectList.ENTITY_KEY), ObjectList.ENTITY_KEY));
childLot.setEqptID(eqptId);
childLot.setQty1(NumberUtils.toDouble(selectedUnits.size() + ""));
childLot.setQty2(0d);
childLot.setInputQty1(NumberUtils.toDouble(selectedUnits.size() + ""));
childLot.setInputQty1(0d);
childLot.setTransId(TransactionNames.NPW_LOT_KEY);
childLot.setRecipeString("");
Map transInfo = new HashMap();
transInfo.put("childLot", childLot);
transInfo.put("unitsInfo", selectedUnits);
transInfo.put("parentLotList", lots);
transInfo.put("lotAndwafers", selectedUnits);
transInfo.put("facilityRrn", facilityRrn);
transInfo.put("userId", userId);
transInfo.put("selectedUnitAll", selectedUnits);
transInfo.put("rebuildlot", TransactionNames.NPW_LOT_KEY);
transInfo.put("transId", TransactionNames.NPW_LOT_KEY);
Map bankIn = new HashMap();
bankIn.put("lotId", childLot.getLotId());
bankIn.put("userRrn", userRrn);
bankIn.put("carrierRrn", childLot.getCarrierRrn());
bankIn.put("carrierId", childLot.getCarrierId());
bankIn.put("plotRrn", parentLot.getLotRrn());
transInfo.put("bankIn", bankIn);
List<EqpMonitorLotBonDing> bondingList = dmmLotService.getDmmLotBonding(childLot.getLotRrn());
Assert.isFalse(bondingList.size() > 0, Errors.create().key(MessageIdList.LOT_USED_COMPANION_LOT).content(
"The lot has been used as a companion lot and " + "cannot be registered.").build());
String processId = StringUtils.trimToUpperCase(theform.getDmmProcessId());
long eqptRrn = getInstanceRrn(eqptId, facilityRrn, ObjectList.ENTITY_KEY);
Assert.isFalse(eqptRrn < 0, Errors.create().key(MessageIdList.EQUIPMENT_ID_NOT_EXIST)
.content("Equipment ID does not exist!").build());
long processRrn = getInstanceRrn(processId, facilityRrn, ObjectList.WFL_KEY);
Assert.isFalse(processRrn <= 0, Errors.create().key(MessageIdList.PROCESS_PROCESS_NOT_SELECTED)
.content("Process not selected!").build());
checkPermissionForOperateProcess(processRrn);
validateRegisted(childLot);
Long modelRrn = NumberUtils.toLong(StringUtils.trimToUpperCase(theform.getModelRrn()));
EqpMonitorModel dmmModel = dmmService.getDMMModelByRrn(modelRrn);
int version = dmmModel.getWorkflowVersion();
Map<Long, EqpMonitorStep> stepMap = new HashMap<Long, EqpMonitorStep>();
List<EqpMonitorStep> stepList = dmmService.getDmmModelStepsInfo(modelRrn);
for (EqpMonitorStep step : stepList) {
stepMap.put(step.getWorkflowStepRrn(), step);
}
Map<String, Object> condition = new HashMap<String, Object>();
condition.put("user", LocalContext.getUserId());
condition.put("userRrn", userRrn);
condition.put("facilityRrn", facilityRrn);
condition.put("eqptId", eqptId);
condition.put("stepMap", stepMap);
dmmLotService.dmmCreateLotAndRegister(transInfo, childLot, processRrn, version, condition);
return childLotId;
} else {
throw new SystemIllegalArgumentException(
Errors.create().key(MessageIdList.LOT_LOTID_REPEAT).content("Lot id is repeat!").build());
}
}
public Map getWaferNum(EqpMonitorModel dmmModel) {
dmmModel = dmmService.getDMMModelByRrn(dmmModel.getModelRrn());
String processLocation = dmmService.getFirstLocation(dmmModel.getModelRrn());
String location = "";
if (StringUtils.isNotBlank(processLocation)) {
location = sysService.getRefFileValue(ReferenceDetailNames.PROCESS_LOCARION_CARRIER_TYPE, processLocation,
ReferenceFileConst.DATA_1_VALUE);
}
Map map = new HashMap();
map.put("waferNum", dmmModel.getWaferNum());
map.put("location", location);
return map;
}
private void clearMap4Unit(Map map) {
map.remove("unitId");
map.remove("unitRrn");
map.remove("lotId");
map.remove("lotRrn");
map.remove("sumLoopCount");
map.remove("loopCount");
map.remove("oldPostionInCarrier");
}
private void addWorkArea(Map map) {
long operationRrn = MapUtils.getLong(map, ("operationRrn"));
map.remove("operationRrn");
Operation operation = prpService.getOperation(operationRrn);
if (operation != null && StringUtils.isNotEmpty(operation.getWorkArea())) {
String workArea = sysService
.referenceDetailExchangeNull("$$WORK_AREA", operation.getWorkArea(), "DATA_1_VALUE");
map.put("workArea", workArea);
}
}
/**
* 查询所有选中的的unit
*/
private List<Map> selectedUnits(List targetEditLotUnits) {
List<Map> units = new ArrayList();
if (targetEditLotUnits != null) {
for (int i = 0; i < targetEditLotUnits.size(); i++) {
Map map = (Map) targetEditLotUnits.get(i);
if (StringUtils.isNotBlank(MapUtils.getString(map, "unitId"))) {
int loopCount = MapUtils.getIntValue(map, "loopCount");
int sumLoopCount = MapUtils.getIntValue(map, "sumLoopCount");
Assert.isFalse(loopCount >= sumLoopCount,
Errors.create().key(MessageIdList.LOT_NOT_ENOUGH_TO_REGISTER)
.content("Not enough times to register").build());
map.put("position", map.get("postionInCarrier"));
units.add(map);
}
}
}
return units;
}
private List<Lot> getLots(List<Map> selectedUnits) {
List<Lot> lots = new ArrayList<Lot>();
List<String> lotIds = new ArrayList<String>();
Map lotAndwafers = new HashMap();
for (Map wafers : selectedUnits) {
List unit = new ArrayList();
String lotId = MapUtils.getString(wafers, "lotId");
if (lotIds.contains(lotId)) {
List lotAndwafer = (List) MapUtils.getObject(lotAndwafers, lotId);
lotAndwafer.add(wafers);
lotAndwafers.put(lotId, lotAndwafer);
} else {
unit.add(wafers);
lotAndwafers.put(lotId, unit);
lotIds.add(lotId);
}
}
for (String lotId : lotIds) {
List selectedUnit = (List) MapUtils.getObject(lotAndwafers, lotId);
Lot lot = lotQueryService.getLot(lotId);
List selectedUnitAll = new ArrayList();
List selectedUnitRrns = new ArrayList();
for (Iterator iterator2 = selectedUnit.iterator(); iterator2.hasNext(); ) {
Map unit = (Map) iterator2.next();
unit.put("available", TRUE);
selectedUnitRrns.add(MapUtils.getLong(unit, "unitRrn"));
selectedUnitAll.add(unit);
}
// 选中的unit
lot.setSelectedUnitsInfo(selectedUnitAll);
List<Map> units = wipQueryService.getUnits(lot.getLotRrn());
lot.setUnitsInfo(units);
List removeUnits = new ArrayList();
for (Iterator iterator2 = units.iterator(); iterator2.hasNext(); ) {
Map unit = (Map) iterator2.next();
if (!selectedUnitRrns.contains(MapUtils.getLong(unit, "unitRrn"))) {
unit.put("available", TRUE);
unit.put("position", MapUtils.getLong(unit, "postionInCarrier") + "");
removeUnits.add(unit);
}
}
lot.setRemoveUnitsInfo(removeUnits);
lots.add(lot);
}
return lots;
}
private void validateRegisted(Lot lot) {
EqpMonitorLotSpecialStep step = dmmLotService.getDMMLotSpecialStep(lot.getLotRrn());
Assert.isFalse(step != null, Errors.create().key(MessageIdList.LOT_HAS_BEEN_REGISTERED)
.content("The lot has been registered!").build());
}
}