WipSetupAction.java
package com.mycim.webapp.actions;
import com.fa.sesa.exception.Assert;
import com.fa.sesa.exception.Errors;
import com.fa.sesa.exception.SystemIllegalArgumentException;
import com.fa.sesa.exception.TransformFunc;
import com.fa.sesa.i18n.I18nUtils;
import com.fa.sesa.threadlocal.LocalContext;
import com.mycim.framework.cache.utils.CacheUtils;
import com.mycim.framework.context.spring.SpringContext;
import com.mycim.framework.utils.MiscUtils;
import com.mycim.framework.utils.beans.BeanUtils;
import com.mycim.framework.utils.beans.PropertyUtils;
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.framework.utils.lang.math.NumberUtils;
import com.mycim.framework.utils.lang.time.DateUtils;
import com.mycim.framework.utils.msg.JsonUtils;
import com.mycim.framework.workflow.engine.WorkflowEngineService;
import com.mycim.server.alarm.service.AlarmService;
import com.mycim.server.asm.service.AsmService;
import com.mycim.server.asm.service.WarehouseService;
import com.mycim.server.automonitor.service.LotAutoMonitorInqService;
import com.mycim.server.carrier.service.CarrierService;
import com.mycim.server.constrain.service.ConstrainService;
import com.mycim.server.ctx.exec.service.CtxExecService;
import com.mycim.server.ctx.service.CtxService;
import com.mycim.server.edc.service.EdcService;
import com.mycim.server.ems.service.EmsService;
import com.mycim.server.erp.service.ErpService;
import com.mycim.server.npw.service.EqpMonitorService;
import com.mycim.server.prp.service.ProductService;
import com.mycim.server.prp.service.PrpService;
import com.mycim.server.rcp.service.RecipeService;
import com.mycim.server.reticle.service.ReticleService;
import com.mycim.server.runcard.service.RecoveryRunCardService;
import com.mycim.server.runcard.service.RunCardLotInqService;
import com.mycim.server.runcard.service.RunCardService;
import com.mycim.server.runcard.service.SplitRunCardService;
import com.mycim.server.security.service.SecurityService;
import com.mycim.server.sorter.exec.service.SorterExecInqService;
import com.mycim.server.sorter.service.SorterQueryService;
import com.mycim.server.sorter.service.SorterService;
import com.mycim.server.spc.service.SpcService;
import com.mycim.server.spec.service.ProcessSpecService;
import com.mycim.server.spec.service.SpecService;
import com.mycim.server.wip.service.*;
import com.mycim.server.workorder.service.WorkOrderService;
import com.mycim.utils.WipUtils;
import com.mycim.valueobject.MessageIdList;
import com.mycim.valueobject.ObjectList;
import com.mycim.valueobject.bas.ErrorMsg;
import com.mycim.valueobject.bas.NamedObject;
import com.mycim.valueobject.bas.ObjectVersion;
import com.mycim.valueobject.bas.Relation;
import com.mycim.valueobject.consts.*;
import com.mycim.valueobject.edcspc.Parameter;
import com.mycim.valueobject.ems.*;
import com.mycim.valueobject.ems.pilot.PiLotView;
import com.mycim.valueobject.ocap.OcapCard;
import com.mycim.valueobject.prp.*;
import com.mycim.valueobject.security.User;
import com.mycim.valueobject.sorter.SortJobBean;
import com.mycim.valueobject.sorter.SorterModel;
import com.mycim.valueobject.sys.ReferenceFileDetail;
import com.mycim.valueobject.wip.*;
import com.mycim.valueobject.wip.dto.LotReleaseInfoDto;
import com.mycim.valueobject.wip.dto.ReassignRequestDto;
import com.mycim.webapp.Constants;
import com.mycim.webapp.WebUtils;
import com.mycim.webapp.forms.RootForm;
import com.mycim.webapp.forms.lot.HoldReleaseLotInfoForm;
import com.mycim.webapp.forms.lot.LotInfoForm;
import com.mycim.webapp.forms.lot.SplitMergeInfoForm;
import com.mycim.workflow.valueobject.WorkflowStepModel;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.Override;
import java.sql.Timestamp;
import java.util.*;
import java.util.stream.Collectors;
public class WipSetupAction extends AbstractAction {
public static final String[] ADJUST_LOT_FIELDS = {"createCategory", "lotType", "priority", "hotFlag",
"splitMergeFlag", "lotOwner", "dueDate", "customerId",
"shippingCode", "outerOrderNO", "outOrderType", "lotComments"};
protected static final String KEY_RECIPE_ID = "recipeId";
protected static final String KEY_STATUS = "status";
protected static final String DUMMY_KEY = "DUMMY";
protected static final String UOM_WAFER = "WAFER";
protected static final String CR_KEY = "CR";
protected static final String EDD_KEY = "EDD";
protected static final String FIFO_KEY = "FIFO";
protected static final String PRIORITY_KEY = "PRIORITY";
protected static final String SAME_SETUP_KEY = "SAME_SETUP";
protected static final String STATION_RRN = "stationRrn";
protected static final String EQUIPMENT_RRN = "equipmentRrn";
protected static final String LOT_STATUS = "lotStatus";
protected static final String DUMMY_FLAG = "dummyFlag";
protected static final String ON = "on";
protected static final String TRUE = "1";
protected static final String FALSE = "0";
protected static final String LOTID_KEY = "lotId";
protected static final String LOT_SEARCH_TYPE_KEY = "lotSearchType";
protected static final String CARRIER_SEARCH_TYPE_KEY = "carrierSearchType";
protected static final String LOT_READONLY_KEY = "readOnly";
protected static final String LOT_DEFAULT_SEARCH_TYPE = "LOT";
protected static final String CARRIER_DEFAULT_SEARCH_TYPE = "LOT_CARRIER";
protected LotService lotService = SpringContext.getBean(LotService.class);
protected PrpService prpService = SpringContext.getBean(PrpService.class);
protected ProductService productService = SpringContext.getBean(ProductService.class);
protected CtxExecService ctxExecService = SpringContext.getBean(CtxExecService.class);
protected WipQueryService wipQueryService = SpringContext.getBean(WipQueryService.class);
protected LotQueryService lotQueryService = SpringContext.getBean(LotQueryService.class);
protected LotInqService lotInqService = SpringContext.getBean(LotInqService.class);
protected DiffBatchQueryService diffBatchQueryService = SpringContext.getBean(DiffBatchQueryService.class);
protected SecurityService securityService = SpringContext.getBean(SecurityService.class);
protected CarrierService carrierService = SpringContext.getBean(CarrierService.class);
protected ConstrainService constrainService = SpringContext.getBean(ConstrainService.class);
protected EmsService emsService = SpringContext.getBean(EmsService.class);
protected WipWorkflowQueryService wipWorkflowQueryService = SpringContext.getBean(WipWorkflowQueryService.class);
protected RecipeService recipeService = SpringContext.getBean(RecipeService.class);
protected WipCheckService wipCheckService = SpringContext.getBean(WipCheckService.class);
protected WipService wipService = SpringContext.getBean(WipService.class);
protected AsmService asmService = SpringContext.getBean(AsmService.class);
protected WarehouseService warehouseService = SpringContext.getBean(WarehouseService.class);
protected CtxService ctxService = SpringContext.getBean(CtxService.class);
protected EdcService edcService = SpringContext.getBean(EdcService.class);
protected ReticleService reticleService = SpringContext.getBean(ReticleService.class);
protected WorkflowEngineService workflowEngineService = SpringContext.getBean(WorkflowEngineService.class);
protected AlarmService alarmService = SpringContext.getBean(AlarmService.class);
protected SpcService spcService = SpringContext.getBean(SpcService.class);
protected SplitRunCardService splitRunCardService = SpringContext.getBean(SplitRunCardService.class);
protected RecoveryRunCardService recoveryRunCardService = SpringContext.getBean(RecoveryRunCardService.class);
protected RunCardService cardService = SpringContext.getBean(RunCardService.class);
protected EqpMonitorService dmmService = SpringContext.getBean(EqpMonitorService.class);
protected WorkOrderService workOrderService = SpringContext.getBean(WorkOrderService.class);
protected SpecService specService = SpringContext.getBean(SpecService.class);
protected ProcessSpecService processSpecService = SpringContext.getBean(ProcessSpecService.class);
protected LotReassignService lotReassignService = SpringContext.getBean(LotReassignService.class);
protected LotRunCardService lotRunCardService = SpringContext.getBean(LotRunCardService.class);
protected LotRunCardQueryService lotRunCardQueryService = SpringContext.getBean(LotRunCardQueryService.class);
protected RunCardLotInqService runCardLotInqService = SpringContext.getBean(RunCardLotInqService.class);
protected LotStatusCheckService lotStatusCheckService = SpringContext.getBean(LotStatusCheckService.class);
protected ErpService erpService = SpringContext.getBean(ErpService.class);
protected LotSamplingService lotSamplingService = SpringContext.getBean(LotSamplingService.class);
protected SorterService sorterService = SpringContext.getBean(SorterService.class);
protected SorterQueryService sorterQueryService = SpringContext.getBean(SorterQueryService.class);
protected SorterExecInqService sorterExecInqService = SpringContext.getBean(SorterExecInqService.class);
protected LotAutoMonitorInqService lotAutoMonitorInqService = SpringContext.getBean(LotAutoMonitorInqService.class);
@Override
public NamedObject getInstance(NamedObject instance) {
NamedObject _instance = null;
if (instance instanceof Item) {
_instance = prpService.getItem((Item) instance);
}
if (_instance != null) {
instance = _instance;
}
return instance;
}
public List<Map> getFutureHoldListbyProduct(Long facilityRrn, long refRrn, Long productRrn, long processRrn,
long lotRrn) {
List<Map> futureHoldListByProduct = ctxExecService.getFutureHoldListByProduct(refRrn, productRrn, processRrn,
lotRrn);
setFlowSeqAndStepdesc(facilityRrn, null, futureHoldListByProduct);
return futureHoldListByProduct;
}
public Collection checkSimiliarLot(long eqptRrn, Collection selectedLots) {
Collection similiarLots = new ArrayList();
Map criterion = new HashMap();
criterion.put(LOT_STATUS, new ArrayList(Arrays.asList("WAITING,DISPATCH,HOLD".split(","))));
criterion.put("objectRrn", (new Long(eqptRrn)).toString());
criterion.put("objectType", "ENTITY");
Collection availLots = lotQueryService.getLotList4ExtAtEqpt(criterion);
for (Iterator itSelected = selectedLots.iterator(); itSelected.hasNext(); ) {
HashMap selectedLot = (HashMap) itSelected.next();
String selectedLotId = ((String) selectedLot.get("lotId")).trim();
for (Iterator itAvail = availLots.iterator(); itAvail.hasNext(); ) {
HashMap availLot = (HashMap) itAvail.next();
String availLotId = ((String) availLot.get("lotId")).trim();
// 循环比较选中的批次和可选批次的批号, 看是否类似, 已选批次存在于可选批次中, 需要排除
// 位数不同的也不需要比较
if ((availLotId.equalsIgnoreCase(selectedLotId)) || (availLotId.length() != selectedLotId.length())) {
} else {
// 批次只比较小数点之前的位数
String s_availLotId = availLotId.substring(0, availLotId.indexOf("."));
String s_selectedLotId = selectedLotId.substring(0, selectedLotId.indexOf("."));
// 如果相同, 那就是同一个母批, 不要求比较
if (s_availLotId.equalsIgnoreCase(s_selectedLotId)) {
} else {
// 将批次分成前后两部分, 如果前后都不相同, 表示起码两个位置不同
// 只比较前部相同后部不同和前部不同和后不相同两种情况, 且比较length/2个字符
int len = s_selectedLotId.length();
int mid = len / 2;
String f_availLotId = s_availLotId.substring(0, mid);
String t_availLotId = s_availLotId.substring(mid);
String f_selectedLotId = s_selectedLotId.substring(0, mid);
String t_selectedLotId = s_selectedLotId.substring(mid);
String result = "";
if ((!f_availLotId.equalsIgnoreCase(f_selectedLotId)) &&
(t_availLotId.equalsIgnoreCase(t_selectedLotId))) {
int diff = 0;
for (int i = 0; i < mid; i++) {
if (f_availLotId.substring(i, i + 1)
.equalsIgnoreCase(f_selectedLotId.substring(i, i + 1))) {
} else {
result = "批次" + selectedLotId + "与待加工的批次" + availLotId + "仅第" + (i + 1) + "位不同";
diff++;
}
}
if (diff == 1) {
similiarLots.add(result);
}
} else if ((f_availLotId.equalsIgnoreCase(f_selectedLotId)) &&
(!t_availLotId.equalsIgnoreCase(t_selectedLotId))) {
int diff = 0;
for (int i = 0; i < len - mid; i++) {
if (t_availLotId.substring(i, i + 1)
.equalsIgnoreCase(t_selectedLotId.substring(i, i + 1))) {
} else {
result = "批次" + selectedLotId + "与待加工的批次" + availLotId + "仅第" + (i + 1 + mid) +
"位不同";
diff++;
}
}
if (diff == 1) {
similiarLots.add(result);
}
}
}
}
}
}
return similiarLots;
}
/**
* 根据选择recipeId 带出可用腔
*
* @param request
* @param lotInfo
* @throws Exception
*/
public void selectRecipeId(HttpServletRequest request, Map lotInfo, int index) {
String recipeId = WebUtils.getParameter("recipeId" + index, request);
List<Map> childRecipeList = (List) MapUtils.getObject(lotInfo, "childRecipes");
boolean hasChildRecipe = childRecipeList != null && childRecipeList.size() > 0;
if (StringUtils.isEmpty(recipeId)) {
recipeId = MapUtils.getString(lotInfo, "recipeId");
}
String selectedRecipeId = StringUtils.EMPTY;
if (StringUtils.isNotEmpty(recipeId)) {
if (StringUtils.equals(WebUtils.getParameter("lotId", request), MapUtils.getString(lotInfo, "lotId"))) {
setEnableChamberList(request, lotInfo, WebUtils.getParameter("recipeId", request));
}
if (CollectionUtils.isNotEmpty(childRecipeList)) {
int i = 0;
for (Map map : childRecipeList) {
String parentRecipe = MapUtils.getString(lotInfo, "recipeId");
String matchRecipeId = recipeService.buildRecipePhysicalId(MapUtils.getString(map, "recipeId"),
lotInfo);
recipeId = hasChildRecipe && StringUtils.equals(parentRecipe, recipeId) &&
i == 0 ? matchRecipeId : recipeId;
if (recipeId.equals(matchRecipeId)) {
map.put("selectRecipeId", matchRecipeId);
selectedRecipeId = matchRecipeId;
setEnableChamberList(request, lotInfo, matchRecipeId);
break;
}
}
if (StringUtils.isEmpty(selectedRecipeId)) {
String matchRecipeId = recipeService.buildRecipePhysicalId(
MapUtils.getString(childRecipeList.get(0), "recipeId"), lotInfo);
setEnableChamberList(request, lotInfo, matchRecipeId);
}
}
lotInfo.put("selectedRecipeId", selectedRecipeId);
}
}
/***
* 根据所选recipe设置可用腔
*
* @param request
* @param lotInfo
* @param recipeId
* @throws Exception
*/
public void setEnableChamberList(HttpServletRequest request, Map lotInfo, String recipeId) {
if (StringUtils.isEmpty(recipeId)) {
return;
}
Recipe recipe = recipeService.getRecipe(recipeId, LocalContext.getFacilityRrn());
Collection versions = recipeService.getRecipeVersions(recipe.getInstanceRrn());
if (versions.size() > 0) {
ObjectVersion objectVersion = null;
Iterator iterator = versions.iterator();
while (iterator.hasNext()) {
objectVersion = (ObjectVersion) iterator.next();
}
RecipeVersion recipeVersion = new RecipeVersion();
recipeVersion.copyObjectVersion(objectVersion);
recipeVersion = recipeService.getRecipeVersion(recipeVersion);
recipeVersion.copyNamedObject(recipe);
Job job = (Job) request.getAttribute("job");
List<String> enableChambers = new ArrayList<String>();
StringBuffer chamberType = new StringBuffer();
if (!StringUtils.isEmpty(recipeVersion.getChamberTypes())) {
List<String> recipeChambers = Arrays.asList(
StringUtils.split(recipeVersion.getChamberTypes(), RecipeVersion.CHAMBERSEPARATOR));
for (String chamberKeys : recipeChambers) {
String c[] = chamberKeys.split(",");
// 所选可用腔组合一个不可用则这个组合不可用
boolean enable = true;
for (int a = 0; a < c.length; a++) {
Entity entity = emsService.getChildChamberEquip(job.getEqptRrn(), c[a]);
// 腔体设备存在 且enable log event
if (entity == null) {
enable = false;
}
}
if (enable) {
enableChambers.add(chamberKeys);
chamberType.append(chamberKeys);
}
}
}
request.setAttribute("chamberJoin", chamberType.toString());
lotInfo.put("chamberTypes", recipeService.getChamberTypes(enableChambers));
}
}
public void setChildRecipe(HttpServletRequest request, Map lotInfo, Long totalWaferQty) {
String recipeId = MapUtils.getString(lotInfo, "recipePhysicalId");
if (StringUtils.isBlank(recipeId)) {
recipeId = MapUtils.getString(lotInfo, "recipeId");
lotInfo.put("recipePhysicalId", recipeId);
}
HashMap parameters = (HashMap) request.getAttribute(SessionNames.PARAMETERSINFO_KEY);
String eventId = parameters == null ? null : (String) parameters.get("eventId");
eventId = eventId == null ? EventName.IDLE_TO_RUN : eventId;
long lotRrn = MapUtils.getLongValue(lotInfo, "lotRrn");
long equipmentRrn = MapUtils.getLongValue(lotInfo, "equipmentRrn");
Collection childRecipes;
long recipeRrn = getInstanceRrn(recipeId, LocalContext.getFacilityRrn(), ObjectList.RECIPE_KEY);
String lotStatus = MapUtils.getString(lotInfo, "lotStatus");
if (LotStatus.isMoveInCheckStatus(lotStatus)) {
Lot lot = lotQueryService.getLot(lotRrn);
Map<String, Object> subRecipeMap = wipService.getAvailableSubRecipes(lot, equipmentRrn, eventId, recipeRrn,
totalWaferQty);
childRecipes = (Collection) subRecipeMap.get("childRecipes");
} else {
childRecipes = new ArrayList<>();
}
Collection recipeConditions = recipeService.getRecipeCondition(recipeRrn);
if (childRecipes != null && childRecipes.size() > 0) {
lotInfo.put("childRecipes", childRecipes);
if (recipeConditions != null && recipeConditions.size() > 0) {
RecipeCondition recipeCondition = (RecipeCondition) recipeConditions.iterator().next();
// Map condition = new HashMap();
// condition.put("lotRrn", MapUtils.getString(lotInfo, "lotRrn"));
// condition.put("productRrn", recipeCondition.getProductRrn() + "");
// condition.put("processRrn", recipeCondition.getProcessRrn() + "");
// condition.put("operationRrn", recipeCondition.getOperationRrn() + "");
// condition.put("parameterRrn", recipeCondition.getParameterRrn() + "");
// condition.put("puType", recipeCondition.getPuType());
double parameterVal = wipQueryService.getParamValByCondition(MapUtils.getLongValue(lotInfo, "lotRrn"),
recipeCondition.getOperationRrn(),
recipeCondition.getProductRrn(),
recipeCondition.getProcessRrn(),
recipeCondition.getParameterRrn(),
recipeCondition.getPuType());
// check has child recipe
if (!LotStatus.RUNNING.equals(lotStatus)) {
for (Iterator it = childRecipes.iterator(); it.hasNext(); ) {
Map recipe = (Map) it.next();
Double paraMinVal = NumberUtils.toDouble(MapUtils.getString(recipe, "paraMinVal"), 0.0);
Double paraMaxVal = NumberUtils.toDouble(MapUtils.getString(recipe, "paraMaxVal"), 0.0);
if (parameterVal >= paraMinVal && parameterVal < paraMaxVal) {
lotInfo.put("autoCalculateRecipe", recipe.get("recipeId"));
}
}
}
}
} else {
// 没有子recipe则设置当前recipe可用chamber
setEnableChamberList(request, lotInfo, recipeId);
lotInfo.remove("childRecipes");
}
if (StringUtils.isNotBlank((String) lotInfo.get("chamberType")) &&
StringUtils.isBlank(MapUtils.getString(lotInfo, "recipeId"))) {
setEnableChamberList(request, lotInfo, recipeId);
}
}
public List<Relation> getEntitiesWithLotSpecial(Lot lot) {
List<Relation> entities = new ArrayList<Relation>();
if (StringUtils.equalsIgnoreCase(LotStatus.OUTSOURCING, lot.getLotStatus()) ||
StringUtils.contains(lot.getOperationId(), "SRC-DUMMY")) {
return entities;
}
LotSpecialEquipContextValue contextValue = ctxExecService.getLotSpecialContextValue(lot);
if (contextValue != null && StringUtils.isNotBlank(contextValue.getEquipmentRrns())) {
String equipmentRrnStr = contextValue.getEquipmentRrns();
entities = emsService.getEntitiesForLotSpecial(equipmentRrnStr);
}
if (CollectionUtils.isEmpty(entities)) {
String eqptGroupRrns = specService.getEqptGroupRrns(lot.getProcessRrn(), lot.getProcessVersion(),
lot.getRouteRrn(), lot.getOperationRrn());
if (StringUtils.isNotBlank(eqptGroupRrns)) {
for (String eqptGroupRrn : eqptGroupRrns.split(",")) {
entities.addAll(emsService.getAllEntities(Long.parseLong(eqptGroupRrn)));
}
} else {
Operation operation = prpService.getOperation(lot.getOperationRrn().longValue());
entities = emsService.getAllEntities(operation.getEntityGroupRrn().longValue());
}
}
List<Relation> distinct = new ArrayList<>();
for (Relation rel : entities) {
boolean sameEqpt = false;
for (Relation rel2 : distinct) {
if (rel2.getInstanceRrn() == rel.getInstanceRrn()) {
sameEqpt = true;
break;
}
}
if (!sameEqpt) {
distinct.add(rel);
}
}
return distinct;
}
private Collection myParseString(String tempString, String index) {
int pos0 = -1;
int pos1 = 0;
int pos2 = 0;
String key;
String _tempString;
Collection _keys = new ArrayList();
if (tempString != null) {
while (tempString.indexOf("$") > 0) {
pos1 = tempString.indexOf("$");
_tempString = tempString.substring(pos0 + 1, pos1);
if (_tempString.indexOf("|") > 0) {
pos2 = _tempString.indexOf("|");
if (index.equals("1")) {
key = StringUtils.trimToUpperCase(_tempString.substring(pos0 + 1, pos2));
} else {
key = StringUtils.trimToUpperCase(_tempString.substring(pos2 + 1, pos1));
}
_keys.add(key);
tempString = tempString.substring(pos1 + 1, tempString.length());
}
}
}
return _keys;
}
private void setFlowSeqAndStepdesc(Long facilityRrn, Lot lot, Collection futureHoldList) {
if (futureHoldList != null) {
Iterator it = futureHoldList.iterator();
while (it.hasNext()) {
Map futureHoldMap = (Map) it.next();
if (lot != null) {
futureHoldMap.put("processVersion", lot.getProcessVersion());
futureHoldMap.put("processRrn", lot.getProcessRrn());
futureHoldMap.put("productRrn", lot.getProductRrn());
} else {
Long productRrn = MapUtils.getLongValue(futureHoldMap, "productRrn");
Long processRrn = MapUtils.getLongValue(futureHoldMap, "processRrn");
long processVer = prpService.getProcessVersion(processRrn);
futureHoldMap.put("processVersion", processVer);
futureHoldMap.put("processRrn", processRrn);
futureHoldMap.put("productRrn", productRrn);
}
futureHoldMap.put("facilityRrn", facilityRrn);
futureHoldMap.put("flowSeq", ctxExecService.getFlowSeqByProcessInfo(futureHoldMap));
futureHoldMap.put("stepDesc", ctxExecService.getOperationDescByProcessInfo(futureHoldMap));
futureHoldMap.put("stageId", ctxExecService.getStageByProcessInfo(futureHoldMap));
}
sortFutureHoldInfosByFlowSeq(futureHoldList);
}
}
private Lot isValidLot(Long facilityRrn, String id) {
return lotQueryService.getLot(id, facilityRrn);
}
private Lot getBondingLot(Long currentLotrrn, Long jobRrn) {
List<Lot> lots = lotQueryService.getLotsByJobRrn(jobRrn);
Lot mainLot = lotQueryService.getLot(currentLotrrn);
Lot anotherLot = new Lot();
Operation mainOper = prpService.getOperation(mainLot.getOperationRrn());
if (mainOper.isBondedOperation() && lots != null && lots.size() == 2) {
Iterator<Lot> it = lots.iterator();
while (it.hasNext()) {
anotherLot = it.next();
if (anotherLot.getLotRrn() != currentLotrrn) {
Map tmp = BeanUtils.copyBeanToMap(anotherLot);
anotherLot.setFlowSeq(ctxExecService.getFlowSeqByProcessInfo(tmp));
anotherLot.setOperationDesc(ctxExecService.getOperationDescByProcessInfo(tmp));
break;
}
}
}
return anotherLot;
}
private String getChildLotId(String lotId, Long facilityRrn) {
String childLotId = "";
if (lotId.indexOf(".") == -1) {
lotId = lotId + ".1";
}
lotId = lotQueryService.getMaxLotId(lotId.substring(0, lotId.indexOf(".") + 1));
if (lotId.indexOf(".") == -1) {
lotId = lotId + ".0";
}
String lotNumber = lotId.substring(lotId.indexOf(".") + 1);
if (StringUtils.isNotBlank(lotNumber)) {
lotNumber = String.valueOf(Integer.parseInt(lotNumber) + 1);
} else {
lotNumber = "1";
}
childLotId = lotId.substring(0, lotId.indexOf(".") + 1) + lotNumber;
// holly modify 20080715 初级排除Carrier与max存在的情况.
if (this.getInstanceRrn(childLotId, this.getNamedSpace(ObjectList.ENTITY_KEY, facilityRrn),
ObjectList.ENTITY_KEY, ObjectList.CARRIER_KEY) > 0) {
childLotId = lotId.substring(0, lotId.indexOf(".") + 1) + String.valueOf(Integer.parseInt(lotNumber) + 1);
}
// MEMS要求个位数, 加0, 类似AAAA.01, 而非AAAA.1
String newChildLotNumber = childLotId.substring(childLotId.indexOf(".") + 1);
if (newChildLotNumber.length() == 1) {
newChildLotNumber = "0" + newChildLotNumber;
}
childLotId = childLotId.substring(0, lotId.indexOf(".") + 1) + newChildLotNumber;
return childLotId;
}
private boolean checkSplitCancelMoveIn(HttpServletRequest request) {
String sourceListValues = request.getParameter("sourceListValues");
Collection sourceList = parseCollection(sourceListValues);
String[] values = request.getParameterValues("allLotCancelMovein");
if (values != null) {
for (int i = 0; i < values.length; i++) {
if (StringUtils.equalsIgnoreCase("true", values[i])) {
return false;
}
}
}
if (sourceList.size() > 0) {
return true;
}
return false;
}
private void splitCancelMoveIn(HttpServletRequest request, Long lotRrn, LotInfoForm theform) throws Exception {
Long facilityRrn = LocalContext.getFacilityRrn();
String user = LocalContext.getUserId();
String childCarrierId = StringUtils.trimToUpperCase(request.getParameter("childCarrierId"));
Map item = new HashMap();
item.put("childLotId", StringUtils.upperCase(theform.getSplitChildLotId()));
item.put("carrierId", WebUtils.getParameterUpperCase("childCarrierId", request));
String sourceValues = request.getParameter("sourceListValues");
String targetValues = request.getParameter("targetListValues");
List<Map> unitsOfParentLot = parseCollection(sourceValues);
List<Map> targetUnits = parseCollection(targetValues);
Lot lot = lotQueryService.getLot(lotRrn.longValue());
lot.setTransPerformedby(user);
lot.setTransId(TransactionNames.CANCELMOVEIN_KEY);
carrierService.compareRealCarrierAndCheckAvailabile(facilityRrn, lot.getCarrierId(), childCarrierId);
Long carrierRrn = carrierService.getCarrierRrnForLot(facilityRrn, new Double(targetUnits.size()),
childCarrierId);
item.put("carrierRrn", carrierRrn);
item.put("technologyRrn", lot.getProcessRrn());
item.put("routeId", lot.getRouteId());
item.put("routeId4Show", lot.getRouteId());
item.put("operationId", lot.getOperationId());
item.put("operationRrn", new Long(
getInstanceRrn(lot.getOperationId(), getNamedSpace(ObjectList.OPERATION_KEY, facilityRrn),
ObjectList.OPERATION_KEY)));
Long opRrn = MapUtils.getLong(item, "operationRrn");
String operationDesc = getInstanceDesc(opRrn.longValue());
item.put("operationDesc", operationDesc);
Assert.isTrue(targetUnits.size() > 0, Errors.create().content("Unselected wafer for cancellation!").build());
// 取选定的Wafer目标值.
item.put("unitList", targetUnits);
item.put("splitQty", targetUnits.size());
HashMap valueMap = new HashMap();
valueMap.put("lot", lot);
valueMap.put("childLot", item);
valueMap.put("unitOfParent", unitsOfParentLot);
valueMap.put("comment", theform.getLotComments());
valueMap.put("facilityRrn", facilityRrn);
valueMap.put("user", user);
Double remainQty = new Double(unitsOfParentLot.size() + "");
String userRRN = theform.getUserId().trim();
String userName = securityService.getUser(Long.parseLong(userRRN)).getUserName();
String reason = theform.getReasonCode() + " " + theform.getDeptExt().trim().toUpperCase() + " " +
userName.toUpperCase() + " " + theform.getReason();
TransReason transReason = new TransReason();
transReason.setReasonCode(theform.getReasonCode());
transReason.setReason(reason);
transReason.setResponsibility(user);
transReason.setTransQty1(remainQty);
valueMap.put("transReason", transReason);
//lotService.splitLotWithCancelIn(valueMap);
}
// protected Equipment validJobSize(Job job) {
// Equipment equipment = new Equipment(job.getEqptId(), getNamedSpace(ObjectList.ENTITY_KEY,
// LocalContext
// .getFacilityRrn()),
// ObjectList.ENTITY_KEY);
// if (job.getEqptRrn() != null) {
// equipment.setInstanceRrn(job.getEqptRrn());
// }
// equipment = emsService.getEquipment(equipment);
//
// // delete rubbish job which is create by wfl error
// if (wipService.deleteRubbishJob(equipment.getInstanceRrn())) {
// equipment = emsService.getEquipment(equipment);
// }
//
// return equipment;
// }
private boolean isAvailableSplitRunCardByHoldReason(String holdReason) {
if (StringUtils.isEmpty(holdReason)) {
return false;
}
if (holdReason.startsWith("(FH)")) {
holdReason = StringUtils.substringAfter(holdReason, "(FH)");
} else if (holdReason.startsWith("(FH)")) {
holdReason = StringUtils.substringAfter(holdReason, "(FH)");
}
String runCardId = StringUtils.substringBefore(StringUtils.substringAfter(holdReason, "ID: "), ",");
NamedObject runCard = new NamedObject(runCardId,
getNamedSpace(ObjectList.ECN_KEY, LocalContext.getFacilityRrn()),
ObjectList.ECN_KEY);
long runCardRrn = baseService.getNamedObjectRrn(runCard);
if (runCardRrn <= 0) {
return false;
}
Map<String, Object> lotRunCardInfo = splitRunCardService.getLotRunCardInfo(runCardRrn);
Map<String, Object> scrInfo = MapUtils.getMap(lotRunCardInfo, "scrInfo");
if (StringUtils.equals(MapUtils.getString(scrInfo, "ecnStatus"), "CLOSED")) {
return false;
}
return true;
}
private boolean checkPositionAvaliable(List units) {
for (Object unit : units) {
boolean childPosition = true;
Map childMap = (Map) unit;
String unitId = MapUtils.getString(childMap, "unitId");
int defaultPosition = Unit.getWaferDefaultPostion(unitId);// 截取unitid的尾号
int actualPosition = MapUtils.getIntValue(childMap, "position");// mapping中的真实位置
if (defaultPosition != actualPosition) {
return false;
}
}
return true;
}
private void addCancelMoveInLotTrans(List<Map> transInfoList, Map<String, Object> transInfoMap) {
boolean canAdd = true;
for (Map transInfo : transInfoList) {
Lot transLot = (Lot) MapUtils.getObject(transInfo, "lot");
Lot addLot = (Lot) MapUtils.getObject(transInfoMap, "lot");
if (transLot.getLotRrn() == addLot.getLotRrn()) {
canAdd = false;
}
}
if (canAdd) {
transInfoList.add(transInfoMap);
}
}
private Map<String, Object> buildCancelMoveInTransInfo(Lot lot, String comments, TransReason transReason) {
Map<String, Object> transInfo = MapUtils.newHashMap();
transInfo.put("lot", lot);
transInfo.put("user", LocalContext.getUserId());
transInfo.put("comments", comments);
transInfo.put("transReason", transReason);
transInfo.put("facilityRrn", LocalContext.getFacilityRrn());
return transInfo;
}
private LotReleaseInfoDto buildLotReleaseInfoList(Lot lot, List<Map> releaseReasons, String comments,
TransReason transReason) {
LotReleaseInfoDto lotReleaseInfoDto = new LotReleaseInfoDto();
lotReleaseInfoDto.setLot(lot);
lotReleaseInfoDto.setReleaseReasonList(releaseReasons);
lotReleaseInfoDto.setUserId(LocalContext.getUserId());
lotReleaseInfoDto.setComments(comments);
TransReason releaseReason = new TransReason();
BeanUtils.copyProperties(transReason, releaseReason);
releaseReason.setTransQty1(lot.getInt_qty1().doubleValue());
releaseReason.setTransQty2(lot.getInt_qty2().doubleValue());
lotReleaseInfoDto.setTransReason(releaseReason);
return lotReleaseInfoDto;
}
// 不显示pilot single lot的future hold信息 #42577
private List<Map> checkPilotSingleFutureHold(List<Map> futureHoldListForlot) {
List<Map> newFutureHoldListForlot = new ArrayList<>();
for (Map map : futureHoldListForlot) {
if (!StringUtils.equals(MapUtils.getString(map, "holdCode"), HoldCodeNames.PILOT_HOLD)) {
newFutureHoldListForlot.add(map);
}
}
return newFutureHoldListForlot;
}
class Comp implements Comparator {
List rules;
Comp(List rule) {
this.rules = rule;
}
@Override
public int compare(Object o1, Object o2) {
HashMap v1 = (HashMap) o1;
HashMap v2 = (HashMap) o2;
int seq = 0;
int res = 0;
if (rules != null) {
boolean _isSamed = true;
for (; seq < rules.size(); seq++) {
String key = (String) rules.get(seq);
Long v_o1 = null;
Long v_o2 = null;
if ("priority".equalsIgnoreCase(key)) {
v_o1 = new Long((String) v1.get(key));
v_o2 = new Long((String) v2.get(key));
// queueTimestamp
} else {
v_o1 = (Long) v1.get(key);
v_o2 = (Long) v2.get(key);
}
if ("priority".equalsIgnoreCase(key) || "dueDate".equalsIgnoreCase(key) ||
"estimatedRemainTime".equalsIgnoreCase(key)) {
if (v_o1 != null && v_o2 != null) {
if (v_o1.longValue() == 0) {
// return 1;
res = 1;
break;
}
if (v_o2.longValue() == 0) {
// return -1;
res = 1;
break;
}
if (v_o1.longValue() > v_o2.longValue()) {
// return 1;
res = 1;
break;
} else if (v_o1.longValue() < v_o2.longValue()) {
// return -1;
res = -1;
break;
}
} else {
res = 0;
}
} else {
// queueTimestamp
if (v_o1 != null && v_o2 != null) {
if (v_o1.longValue() > v_o2.longValue()) {
// return -1;
res = -1;
break;
} else if (v_o1.longValue() < v_o2.longValue()) {
// return 1;
res = 1;
break;
} else {
}
} else if (v_o1 != null) {
// return -1;
res = -1;
break;
}
}
}
} else {
// return 0;
}
return res;
}
@Override
public boolean equals(Object obj) {
if (obj == this) {
return true;
} else {
return false;
}
}
private double getPriority(HashMap object) {
double result =
((division(new Long((String) object.get("priority")), (Long) object.get("totalPriority")) * 1) /
5) + ((division((Long) object.get("dueDate"), (Long) object.get("totalDueDate")) * 1) / 5) +
((division((Long) object.get("createdTimestamp"), (Long) object.get("totalCreateDate")) *
1) / 5) + ((division((Long) object.get("estimatedRemainTime"),
(Long) object.get("totalProcessingTime")) * 1) / 5) +
((0 * 1) / 5);
return result;
}
private double division(Long divident, Long divisor) {
try {
if (divisor.longValue() != 0) {
return ((divident == null) ? 0 : divident.doubleValue()) / divisor.longValue();
} else {
return 0;
}
} catch (java.lang.ArithmeticException ex) {
return 0;
}
}
}
protected void sortFutureHoldInfosByFlowSeq(Collection futureHoldInfos) {
Collections.sort((List) futureHoldInfos, new Comparator() {
@Override
public int compare(Object paramObject1, Object paramObject2) {
Map info1 = (Map) paramObject1;
Map info2 = (Map) paramObject2;
int flowSeq1 = MapUtils.getIntValue(info1, "flowSeq", 0);
int flowSeq2 = MapUtils.getIntValue(info2, "flowSeq", 0);
return (flowSeq1 - flowSeq2);
}
});
}
protected Map buildLotBaseInfo(Lot lot) {
long facilityRrn = LocalContext.getFacilityRrn();
String lotStatus = lot.getLotStatus();
Integer priority = lot.getPriority();
String hotflag = lot.getHotFlag();
Operation operation = new Operation();
if (StringUtils.equalsIgnoreCase(LotStatus.BANKED, lot.getLotStatus()) ||
StringUtils.equalsIgnoreCase(LotStatus.OUTSOURCING, lotStatus)){
operation = prpService.getOperation(lot.getPrevOperationRrn());
lot.setOperationRrn(lot.getPrevOperationRrn());
} else {
operation = prpService.getOperation(lot.getOperationRrn());
}
String priorityString = wipQueryService.getHotflagSplicingPriority(NumberUtils.toInt(hotflag), priority,
facilityRrn);
Map resultMap = BeanUtils.copyBeanToMap(lot);
int cuntScraptUnit = 0;
if (StringUtils.equalsIgnoreCase(lot.getLotStatus(), LotStatus.SCRAPPED)) {
cuntScraptUnit = lotQueryService.getTotalQtyForUnscrap(lot.getLotRrn());
}
Carrier carrier = carrierService.getCarrier(lot.getCarrierRrn());
resultMap.put("lotPurpose", lot.getLotComments());
String eqptGroupIds = specService.getEqptGroupIds(lot.getProcessRrn(), lot.getProcessVersion(),
lot.getRouteRrn(), lot.getOperationRrn());
if (StringUtils.isEmpty(eqptGroupIds)) {
resultMap.put("eqptGroupId", getInstanceId(operation.getEntityGroupRrn()));
} else {
resultMap.put("eqptGroupId", eqptGroupIds);
}
resultMap.put("processLocation", lotQueryService.getProcessLocation(lot));
resultMap.put("carrierType", carrier.getObjectSubtype());
resultMap.put("qty1", lot.getInt_qty1());
resultMap.put("inputQty1", cuntScraptUnit);
resultMap.put("workArea",
StringUtils.isNotBlank(lot.getWorkArea()) ? lot.getWorkArea() : lotQueryService.getWorkArea(lot));
resultMap.put("stageId",
StringUtils.isNotBlank(lot.getStageId()) ? lot.getStageId() : lotQueryService.getStageId(lot));
resultMap.put("priority", priorityString);
resultMap.put("dueDate", DateUtils.formatDate(lot.getDueDate(), DateUtils.DATE_FORMAT4DAYD));
//reticle
long reticleFamilyRrn = wipQueryService.getReticleFamilyRrnByLot(lot);
if (reticleFamilyRrn > 0) {
String reticles = buildReticlesString(reticleFamilyRrn);
resultMap.put("reticles", reticles);
} else {
resultMap.put("reticles", "");
}
//batchID
resultMap.put("batchId", diffBatchQueryService.getLotBatchId(lot.getLotRrn()));
resultMap.put("workOrderId", lot.getInnerOrderNO());
resultMap.put("flipType", lot.getFlipType());
//#42799 lot info界面点功能按钮后的物料批次号数据丢失
String materialLotId = warehouseService.getMaterialInfoByLot(lot.getLotRrn()).stream()
.map(lotNumber -> lotNumber.get("lotNumber").toString())
.collect(Collectors.joining(","));
//需求 #43825 Lot 分批之后,子批Material Lot Id,Lot query 数据栏数据丢失
if (StringUtils.isBlank(materialLotId)){
List<Unit> unitList = wipQueryService.getUnitList(lot.getLotRrn());//当前lot下的wafer集合
if(CollectionUtils.isNotEmpty(unitList)){
Set<String> lotNumberSet = unitList.stream().map(e -> {
//根据当前lot下的每一个wafer去查询其对应的物料信息并去重
Map<String, Object> materialInfo = warehouseService.getMaterialInfoByUnit(e.getUnitRrn());
if (MapUtils.isNotEmpty(materialInfo)) {
return MapUtils.getString(materialInfo, "lotNumber", "");
}
return "";
}).collect(Collectors.toSet());
if(lotNumberSet.contains("")){
lotNumberSet.remove("");
}
materialLotId=String.join(",",lotNumberSet).trim();
}
}
resultMap.put("materialLotId", materialLotId);
//添加ocap id
resultMap.put("ocapId", wipQueryService.getActiveInlineOcapIdByLot(lot.getLotRrn()));
//Pi-Lot
//#42799 lot info界面点功能按钮后的piLotViewId数据丢失
PiLotView piLotView = wipQueryService.getPiLotViewIdByLotRrn(lot.getLotRrn(), lot.getBasedLotRrn());
if (ObjectUtils.isNotEmpty(piLotView)) {
resultMap.put("piLotViewId", piLotView.getViewId());
resultMap.put("viewRrn", piLotView.getViewRrn());
}
return resultMap;
}
protected boolean isSamePollutionLevel(Long entityGroupRrn, Lot lot) {
if (entityGroupRrn == null || entityGroupRrn <= 0) {
return false;
}
if (StringUtils.isEmpty(lot.getPollutionLevel()) || StringUtils.equals("0", lot.getPollutionLevel())) {
return true;
}
Set<String> acceptablePolluctionLevels = emsService.getAcceptablePolluctionLevelInEntityGroup(entityGroupRrn);
boolean isAcceptable = false;
for (String polluctionLevel : acceptablePolluctionLevels) {
if (polluctionLevel == null || StringUtils.equals(lot.getPollutionLevel(), polluctionLevel)) {
isAcceptable = true;
break;
}
}
return isAcceptable;
}
protected List<Relation> getConstrainPairEquipments(Lot lot) {
List<Relation> equipments = new ArrayList<Relation>();
long lotRrn = lot.getLotRrn();
Long operationRrn = lot.getOperationRrn();
Long routeRrn = lot.getRouteRrn();
String routeSeq = lot.getRouteSeq();
String operationSeq = lot.getOperationSeq();
Long facilityRrn = lot.getFacilityRrn();
Long processRrn = lot.getProcessRrn();
Long productRrn = lot.getProductRrn();
// 1.先查批次是否有直接设置的机限
EquipmentConstrainPair constrainPairByLot = constrainService.getConstrainPairByLotRrn(lotRrn);
if (constrainPairByLot == null ||
EquipmentConstrainPairConstants.STATUS_DISABLE.equals(constrainPairByLot.getStatus())) {// 没设置
// 或者禁用时都以产品+流程为准
// 再查看是否通过产品+流程设置机限
constrainPairByLot = constrainService.getConstrainPairByProductAndProcess(productRrn, processRrn);
}
if (constrainPairByLot != null) {
String status = constrainPairByLot.getStatus();
if (EquipmentConstrainPairConstants.STATUS_ENABLE.equals(status)) {// 启用状态
// 获取当前工步的设置
EquipmentConstrainPairDetail detail = constrainService.getConstrainPairDetailByRunInfo(
constrainPairByLot.getConstrainPairRrn(), routeRrn, operationRrn, routeSeq, operationSeq);
EquipmentConstrainPairDetail benchMark = constrainService.getBenchMarkByConstrainRrn(
constrainPairByLot.getConstrainPairRrn());
// 如果当前就是基准层,那么不卡控设备
if (benchMark != null && detail != null &&
benchMark.getConstrainDetailRrn().equals(detail.getConstrainDetailRrn())) {
return equipments;// 不返回机限设备,即是不卡控
}
// 获取批次触发记录
LotConstrainTrigger lotNewTrigger = constrainService.getLotNewTrigger(lotRrn,
constrainPairByLot.getConstrainPairRrn());
if (lotNewTrigger != null && detail != null) {// 已经触发了
String plan = lotNewTrigger.getPlan();
String equipmentStr = "";
if ("PLANA".equalsIgnoreCase(plan)) {
equipmentStr = detail.getPlanA();
} else if ("PLANB".equalsIgnoreCase(plan)) {
equipmentStr = detail.getPlanB();
} else if ("PLANC".equalsIgnoreCase(plan)) {
equipmentStr = detail.getPlanC();
} else if ("PLAND".equalsIgnoreCase(plan)) {
equipmentStr = detail.getPlanD();
} else if ("PLANE".equalsIgnoreCase(plan)) {
equipmentStr = detail.getPlanE();
}
if (StringUtils.isNotBlank(equipmentStr)) {// 设置了设备
String[] equipmentArry = equipmentStr.split(",");
for (String equipmentId : equipmentArry) {
Equipment entity = new Equipment(equipmentId,
getNamedSpace(ObjectList.ENTITY_KEY, facilityRrn),
ObjectList.ENTITY_KEY);
entity = emsService.getEquipment(entity);
Relation eqptRelation = new Relation();
eqptRelation.setInstanceId(equipmentId);
eqptRelation.setInstanceRrn(entity.getInstanceRrn());
eqptRelation.setInstanceDesc(entity.getInstanceDesc());
equipments.add(eqptRelation);
}
}
}
// 获取设备
}
}
return equipments;
}
protected String getHotflagSplicingPriority(Lot lot) {
return wipQueryService.getHotflagSplicingPriority(NumberUtils.toInt(lot.getHotFlag()), lot.getPriority(),
LocalContext.getFacilityRrn());
}
protected boolean checkEqptRecipeAvailable(List<Map<String, Object>> equipmentRecipes, String recipeId) {
if (CollectionUtils.isNotEmpty(equipmentRecipes)) {
for (Map<String, Object> map : equipmentRecipes) {
String equipmentRecipeId = MapUtils.getString(map, KEY_RECIPE_ID);
String status = MapUtils.getString(map, KEY_STATUS);
if (StringUtils.equals(recipeId, equipmentRecipeId) && RecipeStatus.isAvailable(status)) {
return true;
}
}
}
return false;
}
protected String parseToString(Collection unitList) {
Iterator it = unitList.iterator();
HashMap unit = new HashMap();
int number = 1;
int seq = 1;
StringBuffer sb = new StringBuffer();
while (it.hasNext()) {
unit = (HashMap) it.next();
seq = Integer.parseInt((String) unit.get("position"));
while ((number < seq) && (number < 9999)) {
sb.append(" $");
number++;
}
sb.append(unit.get("unitId"));
sb.append(",");
sb.append(unit.get("unitRrn"));
sb.append(",");
sb.append(unit.get("dummyflag"));
sb.append(",");
sb.append(unit.get("available"));
sb.append(",");
sb.append(unit.get("lotid"));
sb.append("$");
number++;
}
if (sb.length() == 0) {
sb.append("$");
}
return sb.substring(0, sb.length() - 1);
}
protected List<Map> parseCollection(String unitString) {
List<Map> unitList = new ArrayList();
long seq = 0;
int index_1 = 0;
int index_2 = 0;
int index_3 = 0;
int index_4 = 0;
if ((unitString == null) || unitString.equalsIgnoreCase("")) {
return unitList;
}
StringTokenizer stn = new StringTokenizer(unitString, "$", false);
String unit = "";
String available = "";
String unitRrn = "";
String unitId = "";
String dummyWaferFlag = "";
String lotId = "";
while (stn.hasMoreElements()) {
seq++;
unit = stn.nextToken();
index_1 = unit.indexOf(",");
index_2 = unit.indexOf(",", index_1 + 1);
index_3 = unit.indexOf(",", index_2 + 1);
index_4 = unit.indexOf(",", index_3 + 1);
if ((index_1 == 0) || (index_1 == -1)) {
unitId = "";
unitRrn = "";
dummyWaferFlag = "";
available = "1";
// continue;
} else {
if (index_1 > 0) {
unitId = unit.substring(0, index_1);
}
if (index_2 > 0) {
unitRrn = unit.substring(index_1 + 1, index_2);
}
if (index_3 > 0) {
dummyWaferFlag = unit.substring(index_2 + 1, index_3);
}
if (index_4 > 0) {
available = unit.substring(index_3 + 1, index_4);
lotId = unit.substring(index_4 + 1);
}
}
if (unitRrn != null && !unitRrn.trim().equals("")) {
HashMap map = new HashMap();
map.put("position", new String("" + seq));
map.put("unitId", unitId);
map.put("unitRrn", unitRrn);
map.put("dummyflag", dummyWaferFlag);
map.put("available", available);
map.put("lotid", lotId);
unitList.add(map);
}
}
return unitList;
}
protected Recipe getRecipeByLot(Lot lot) {
Recipe recipe = null;
String recipeString = lot.getRecipeString();
if (StringUtils.isEmpty(recipeString)) {
recipeString = ctxExecService.getRecipeString(lot);
}
if (StringUtils.isBlankCheckNull(recipeString)) {
} else {
lot.setRecipeString(recipeString);
// /recipeId|recipeParam
int index = recipeString.indexOf("|");
String recipeRrn = null;
if (index >= 0) {
recipeRrn = recipeString.substring(0, index);
String para = recipeString.substring(index + 1, recipeString.length());
lot.setRecipeId(getInstanceId(new Long(recipeRrn).longValue()));
lot.setRecipeParameter(para);
} else {
if (!"".equalsIgnoreCase(recipeString.trim())) {
recipeRrn = recipeString;
lot.setRecipeId(getInstanceId(new Long(recipeString).longValue()));
}
}
recipe = recipeService.getRecipe(Long.parseLong(recipeRrn));
}
return recipe;
}
protected PlanLot getPlanLot(PlanLot planLot) throws Exception {
// temp object to store the value object retrived from database
PlanLot _planLot = lotService.getPlanLot(planLot);
if (_planLot != null) {
planLot = _planLot;
}
return planLot;
}
protected Integer getProcessVersion(long processRrn) throws Exception {
NamedObject object = new NamedObject(processRrn);
object = baseService.isExisted(processRrn);
ObjectVersion version = baseService.getMostActiveVersion(object);
return new Integer(version.getInstanceVersion());
}
protected boolean isProductProcessBined(Long productRrn, long processRrn) {
List<Long> processRrns = prpService.getProcessRrnsByProductRrn(productRrn);
return processRrns.contains(processRrn);
}
protected Map getStepsInfoByVersion(Lot lot, Long processRrn, Integer processVer, String stepPath) {//TODO 改回原SP,待验证
Map matchingRules = new HashMap();
matchingRules.put("productRrn", String.valueOf(lot.getProductRrn()));
matchingRules.put("processRrn", lot.getProcessRrn());
matchingRules.put("lotRrn", lot.getLotRrn() + "");
Map stepsInfo = wipWorkflowQueryService.getStepsInfoByVersion(processRrn, processVer, stepPath, matchingRules);
return stepsInfo;
}
protected String getRecipePhysicalId(Lot lot) {
String recipePhysicalId = "";
RecipeVersion recipeVersion = recipeService.getLotRecipe(lot);
if (recipeVersion != null) {
recipePhysicalId = recipeVersion.getPpid();
}
return recipePhysicalId;
}
protected boolean isValidUnitId(String customerWaferId, Long facilityRrn) {
List unitIds = (List) myParseString(customerWaferId, "1");
for (int i = 0; i < unitIds.size(); i++) {
Unit unit = wipQueryService.getUnit(facilityRrn, (String) unitIds.get(i));
if (unit != null && StringUtils.isNotBlank(unit.getUnitId())) {
return true;
}
}
return false;
}
protected void buildRecipeId(Lot lot) {
RecipeVersion recipeVersion = recipeService.getLotRecipe(lot);
if (recipeVersion != null) {
String physicalId = recipeVersion.getPpid();
lot.setRecipePhysicalId(physicalId);
}
}
protected String getNextStepDesc(Lot lot) {
long facilityRrn = LocalContext.getFacilityRrn();
Map conditionM = new HashMap();
conditionM.put("facilityRrn", facilityRrn);
conditionM.put("productRrn", lot.getProductRrn());
conditionM.put("processRrn", lot.getProcessRrn());
conditionM.put("processVersion", lot.getProcessVersion());
conditionM.put("routeRrn", WipUtils.getRouteRrnByProcessStep(lot.getNextStepVersion1()));
conditionM.put("operationRrn", lot.getNextOperationRrn1());
String nextOperationDesc1 = ctxExecService.getOperationDescByProcessInfo(conditionM);
return nextOperationDesc1;
}
protected void removeEqptlotCache(Lot lot) {
Collection availableEquipmentInfos = buildAvailableEquipInfosForLot(lot, LocalContext.getUserRrn());
for (Object eqpts : availableEquipmentInfos) {
CacheUtils.remove(MapUtils.getLongValue((Map) eqpts, "equipmentRrn") + "");
}
}
/**
* @param lot
* @return
* @throws Exception
*/
protected Collection buildAvailableEquipInfosForLot(Lot lot, Long userRrn) {
long facilityRrn = LocalContext.getFacilityRrn();
Collection availableEquipmentInfos = new ArrayList();
String recipeId = lot.getRecipePhysicalId();
Collection eqptRelations = getEntitiesWithLotSpecial(lot);
// 判断批次的机限设置 并组装设备列表--->开始
long lotRrn = lot.getLotRrn();
List<Relation> constrainPairEquipments = getConstrainPairEquipments(lot);
if (constrainPairEquipments.size() > 0) {
eqptRelations = constrainPairEquipments;
}
// 判断批次的机限设置 并组装设备列表--->结束
for (Iterator it = eqptRelations.iterator(); it.hasNext(); ) {
Relation eqptRelation = (Relation) it.next();
Equipment equipment = new Equipment();
equipment.setInstanceRrn(eqptRelation.getInstanceRrn());
equipment.setInstanceId(eqptRelation.getInstanceId());
equipment.setInstanceDesc(eqptRelation.getInstanceDesc());
Map equipmentInfo = checkEquipmentAvailable(lot, userRrn, equipment);
availableEquipmentInfos.add(equipmentInfo);
}
return availableEquipmentInfos;
}
protected Map checkEquipmentAvailable(Lot lot, Long userRrn, Equipment equipment) {
Map equipmentInfo = new HashMap();
equipmentInfo.put("equipmentId", equipment.getInstanceId());
equipmentInfo.put("equipmentDesc", equipment.getInstanceDesc());
equipmentInfo.put("equipmentRrn", equipment.getInstanceRrn());
// start: 检查批次在当前设备是否有constrain
ErrorMsg errorMsg = constrainService.checkLotConstrain(equipment, lot);
boolean overrideConstrain;
overrideConstrain = wipCheckService.isOverrideConstrain(lot);
if (overrideConstrain) {
errorMsg.setError(false);
errorMsg.setErrorMsg("OK");
}
equipmentInfo.put("equipmentConstrain", errorMsg.getError());
String checkEqptAndRecipeResultMsg = wipCheckService.checkEqptAndRecipeAndReticleAtJobIn(lot,
equipment.getInstanceRrn(),
lot.getRecipePhysicalId(),
userRrn);
equipmentInfo.put("checkEqptAvailable", StringUtils.isEmpty(checkEqptAndRecipeResultMsg));
equipmentInfo.put("checkEqptAvailableMsg", checkEqptAndRecipeResultMsg);
// add edc info
List<Parameter> edcInfoList = wipQueryService.getLotEdcInfoList(lot, equipment);
if (CollectionUtils.isNotEmpty(edcInfoList)) {
equipmentInfo.put("edcInfoList", edcInfoList);
}
// check equipment status
String equipmenStatus = emsService.getEntityCurrentStatus(equipment.getInstanceRrn());
equipmentInfo.put("equipmentStatus", equipmenStatus);
if (wipCheckService.checkEqptStatusAvailable(lot, equipment)) {
equipmentInfo.put("equipmentAvailable", "AVAILABLE");
} else {
equipmentInfo.put("equipmentAvailable", "NOT_AVAILABLE");
}
return equipmentInfo;
}
/**
* @param request
* @param readOnly lotId 和 carrier 输入只读
* @param lotSearchType 查询的lotType
* @param carrierSearchType 查询的carrierType
* @return Lot 可能为 null
*/
protected Lot initLotBaseInfoForJsp(HttpServletRequest request, boolean readOnly, String lotSearchType,
String carrierSearchType) {
request.setAttribute(LOT_SEARCH_TYPE_KEY,
StringUtils.isBlank(lotSearchType) ? LOT_DEFAULT_SEARCH_TYPE : lotSearchType);
request.setAttribute(CARRIER_SEARCH_TYPE_KEY,
StringUtils.isBlank(carrierSearchType) ? CARRIER_DEFAULT_SEARCH_TYPE : carrierSearchType);
request.setAttribute(LOT_READONLY_KEY, readOnly);
long facilityRrn = LocalContext.getFacilityRrn();
String result;
boolean carrierFlag = request.getParameter("byCarrierId") != null;
String carrierId = carrierFlag ? StringUtils.trim(request.getParameter("carrierId")) : StringUtils.EMPTY;
carrierId = carrierId != null ? carrierId.trim().toUpperCase() : StringUtils.EMPTY;
Assert.isFalse(carrierFlag && carrierId.length() < 1,
Errors.create().content("Cassette id can't be empty!").build());
if (carrierFlag) {
Long carrierRrn = this.getInstanceRrn(carrierId, facilityRrn, ObjectList.ENTITY_KEY);
Assert.isTrue(carrierRrn > 0L, Errors.create().key(MessageIdList.CARRIER_CASSETTE_ID_MISSING)
.content("Cassette ID is not exist!").build());
List<String> lotIds = carrierService.getInUseCarrierLotIdList(carrierRrn);
Assert.isFalse(lotIds == null || lotIds.size() != 1,
Errors.create().content("The Cassette have {} lots").args(lotIds == null ? 0 : lotIds.size())
.build());
result = lotIds.get(0);
} else {
result = request.getParameter("lotId") == null ? request.getParameter("instanceId") : StringUtils.trim(
request.getParameter("lotId"));
}
Assert.isFalse(StringUtils.isBlank(result) && readOnly,
Errors.create().key(MessageIdList.LOT_LOTID_OR_CASSETTEID_EMPTY)
.content("Lot Id and Cassette Id can't be Empty!</br>").build());
if (StringUtils.isNotBlank(result)) {
result = result.toUpperCase();
// Lot lot = lotQueryService.getLot(result, facilityRrn);
Lot lot = lotInqService.getLot(result);
Assert.isFalse(lot == null || lot.getLotRrn() < 1,
Errors.create().key(MessageIdList.LOT_ENTER_CORRECT_LOTID)
.content("Please enter the correct lot Id!").build());
//错误#44134:主辅产品做完Bond.无论触发PostFH 还是正常做完Bond.辅产品在Lot tracking 界面与Lot query 页面不一致
//修改lot tracking界面qty的数量,再次判断lot.getLotStatus()状态是否为LotStatus.BONDED,是则修改值为去qty
if(StringUtils.equalsIgnoreCase(lot.getLotStatus(),LotStatus.BONDED)){
double qty = lotQueryService.getLotWaferCount(lot.getLotRrn());
lot.setQty1(qty);
}
Map lotBaseInfo = buildLotBaseInfo(lot);
request.setAttribute("lotBaseInfo", lotBaseInfo);
return lot;
} else {
request.setAttribute("lotBaseInfo", new HashMap());
return null;
}
}
/**
* There are 4 kinds of future hold in two dimensions
*
* @param facilityRrn
* @param lot
* @return
*/
protected List getAllFutureHoldForLot(Long facilityRrn, Lot lot) {
List futureHoldListForlot = new ArrayList();
// future hold by lot
long refRrn = getInstanceRrn(ContextNames.EEN_CONTEXT_HOLDLOT, facilityRrn, ObjectList.CONTEXT_KEY);
List futureholdList = ctxExecService.getFutureHoldListByLot(refRrn, lot.getLotRrn());
if (!futureholdList.isEmpty()) {
futureHoldListForlot.addAll(futureholdList);
}
refRrn = getInstanceRrn(ContextNames.EEN_CONTEXT_POST_HOLDLOT, facilityRrn, ObjectList.CONTEXT_KEY);
futureholdList = ctxExecService.getFutureHoldListByLot(refRrn, lot.getLotRrn());
if (!futureholdList.isEmpty()) {
futureHoldListForlot.addAll(futureholdList);
}
// future hold by product
refRrn = getInstanceRrn(ContextNames.EEN_CONTEXT_HOLDPRODUCT, facilityRrn, ObjectList.CONTEXT_KEY);
Map conditionMap = new HashMap();
conditionMap.put("refRrn", new Long(refRrn));
conditionMap.put("productRrn", lot.getProductRrn().toString());
conditionMap.put("processRrn", lot.getProcessRrn().toString());
conditionMap.put("lotRrn", new Long(lot.getLotRrn()));
futureholdList = ctxExecService.getFutureHoldListByProduct(refRrn, lot.getProductRrn(), lot.getProcessRrn(),
lot.getLotRrn());
if (!futureholdList.isEmpty()) {
futureHoldListForlot.addAll(futureholdList);
}
refRrn = getInstanceRrn(ContextNames.EEN_CONTEXT_POST_HOLDPRODUCT, facilityRrn, ObjectList.CONTEXT_KEY);
conditionMap.put("refRrn", new Long(refRrn));
futureholdList = ctxExecService.getFutureHoldListByProduct(refRrn, lot.getProductRrn(), lot.getProcessRrn(),
lot.getLotRrn());
if (!futureholdList.isEmpty()) {
futureHoldListForlot.addAll(futureholdList);
}
setFlowSeqAndStepdesc(facilityRrn, lot, futureHoldListForlot);
futureHoldListForlot = checkPilotSingleFutureHold(futureHoldListForlot);
return futureHoldListForlot;
}
protected Map getStepsInfoByLot(Lot lot, long processRrn, String stepPath) {//TODO 改回原SP,待验证
Map matchingRules = new HashMap();
matchingRules.put("productRrn", String.valueOf(lot.getProductRrn()));
matchingRules.put("processRrn", processRrn);
matchingRules.put("lotRrn", lot.getLotRrn() + "");
Map stepsInfo = wipWorkflowQueryService.getStepsInfo(processRrn, stepPath, matchingRules);
return stepsInfo;
}
protected boolean isTechnologyValid4Product(Long productRrn, Long processRrn) {
List<Map> technologys = prpService.getProductTechnologys(productRrn);
boolean isValidTechnologyFlag = false;
if ((technologys == null) || (technologys.size() <= 0)) {
return isValidTechnologyFlag;
}
for (Map item : technologys) {
if ((item.get("instancerrn") != null) &&
((new Long((String) item.get("instancerrn"))).compareTo(processRrn) == 0)) {
isValidTechnologyFlag = true;
break;
}
}
return isValidTechnologyFlag;
}
protected long parseRouteRrn(String processStepVersion) {
long routeRrn = 0;
if (StringUtils.isNotBlank(processStepVersion)) {
int firstSep = 0;
int secondSep = 0;
firstSep = processStepVersion.indexOf("|");
secondSep = processStepVersion.indexOf("|", firstSep + 1);
if (secondSep >= 0) {
routeRrn = Long.parseLong(processStepVersion.substring(processStepVersion.indexOf("|", 1) + 1,
processStepVersion.indexOf(",",
processStepVersion.indexOf(
"|", 1))));
} else {
routeRrn = Long.parseLong(processStepVersion.substring(0, processStepVersion.indexOf(",")));
}
}
return routeRrn;
}
protected boolean checkOperationInFacility(Long operationRrn, Long facilityRrn) {
boolean inSameFab = false;
NamedObject object = baseService.getNamedObject(new NamedObject(operationRrn.longValue()));
if (object != null && object.getNamedSpace() != null) {
String _temp = getNamedSpace(ObjectList.OPERATION_KEY, facilityRrn);
if (object.getNamedSpace().equalsIgnoreCase(_temp)) {
inSameFab = true;
}
}
return inSameFab;
}
protected List<Map<String, Object>> dispatch(List<Map<String, Object>> lotList, long equipmentRrn) {
// there are 5 dispatch rule:
// 1. Priority based on plan lot
// 2. Earliest Due Date
// 3. FIFO
// 4. Shortest Remaining time (processing time)
// 5. Same equipment setup. --not available in mimos
// check percentum in each dispatch rule
List<Map> rules = emsService.getEquipmentDispatchingRule(equipmentRrn);
List<String> dispatchRules = new ArrayList();
for (Map item : rules) {
if ((item.get("ruleid") != null) && item.get("ruleid").equals(WipSetupAction.PRIORITY_KEY)) {
dispatchRules.add("priority");
}
if ((item.get("ruleid") != null) && item.get("ruleid").equals(WipSetupAction.EDD_KEY)) {
dispatchRules.add("dueDate");
}
if ((item.get("ruleid") != null) && item.get("ruleid").equals(WipSetupAction.FIFO_KEY)) {
dispatchRules.add("queueTimestamp");
}
if ((item.get("ruleid") != null) && item.get("ruleid").equals(WipSetupAction.CR_KEY)) {
dispatchRules.add("estimatedRemainTime");
}
if ((item.get("ruleid") != null) && item.get("ruleid").equals(WipSetupAction.SAME_SETUP_KEY)) {
dispatchRules.add("sameSetup");
}
}
Comp comp = new Comp(dispatchRules);
lotList.sort(comp);
return lotList;
}
protected List<Map> getFutureHoldListbyLot(long refRrn, Lot lot) {
Long facilityRrn = LocalContext.getFacilityRrn();
List<Map> futureholdListbyLot = ctxExecService.getFutureHoldListByLot(refRrn, lot.getLotRrn());
if (CollectionUtils.isNotEmpty(futureholdListbyLot)) {
for (Iterator<?> iterator = futureholdListbyLot.iterator(); iterator.hasNext(); ) {
Map<?, ?> map = (Map<?, ?>) iterator.next();
if (StringUtils.contains(MapUtils.getString(map, "holdCode"), HoldCodeNames.SRCHOLD_KEY) &&
isAvailableSplitRunCardByHoldReason(MapUtils.getString(map, "holdReason"))) {
iterator.remove();
}
}
}
setFlowSeqAndStepdesc(facilityRrn, lot, futureholdListbyLot);
futureholdListbyLot = checkPilotSingleFutureHold(futureholdListbyLot);
return futureholdListbyLot;
}
protected List<Map> getPreOrPostFutureHoldForLot(Long facilityRrn, Lot lot, String holdlotKey,
String holdProductKey) throws Exception {
List<Map> futureHoldListForlot = new ArrayList();
// future hold by lot
long refRrn = this.getInstanceRrn(holdlotKey, this.getNamedSpace(ObjectList.CONTEXT_KEY, facilityRrn),
ObjectList.CONTEXT_KEY);
List<Map> futureholdList = ctxExecService.getFutureHoldListByLot(refRrn, lot.getLotRrn());
if (!futureholdList.isEmpty()) {
futureHoldListForlot.addAll(futureholdList);
}
// future hold by product
refRrn = baseService.getNamedObjectRrn(holdProductKey,
baseService.getNamedSpace(lot.getFacilityRrn().longValue(),
ObjectList.CONTEXT_KEY),
ObjectList.CONTEXT_KEY);
Map conditionMap = new HashMap();
conditionMap.put("refRrn", new Long(refRrn));
conditionMap.put("productRrn", lot.getProductRrn().toString());
conditionMap.put("processRrn", lot.getProcessRrn().toString());
conditionMap.put("routeRrn", lot.getRouteRrn().toString());
conditionMap.put("operationRrn", lot.getOperationRrn().toString());
conditionMap.put("lotRrn", new Long(lot.getLotRrn()));
futureholdList = ctxExecService.getFutureHoldListByProduct(refRrn, lot.getProductRrn(), lot.getProcessRrn(),
lot.getLotRrn());
if (!futureholdList.isEmpty()) {
futureHoldListForlot.addAll(futureholdList);
}
setFlowSeqAndStepdesc(facilityRrn, lot, futureHoldListForlot);
futureHoldListForlot = checkPilotSingleFutureHold(futureHoldListForlot);
return futureHoldListForlot;
}
protected String checkRecipeTimeOutMsg(Collection lots) {
String recipeTimeOutMsg = "";
for (Iterator it = lots.iterator(); it.hasNext(); ) {
HashMap item = (HashMap) it.next();
Lot lot = lotQueryService.getLot(MapUtils.getLongValue(item, "lotRrn"));
RecipeContextValue contextValue = ctxExecService.getRecipeContextValue(lot);
if (contextValue != null && StringUtils.isNotBlank(contextValue.getCheckUnit()) &&
contextValue.getLastUsedTime() > 0 && contextValue.getFrequency() > 0) {
long lastUsedTime = DateUtils.addTimeByUnit(contextValue.getLastUsedTime(), contextValue.getCheckUnit(),
contextValue.getFrequency());
long nowTime = System.currentTimeMillis();
long diffTime = nowTime - lastUsedTime;
if (diffTime > 0) {
recipeTimeOutMsg +=
contextValue.getTimeOutAction() + "|批次" + lot.getLotId() + "的RECIPE" + lot.getRecipeId() +
"已经超过" + diffTime / 1000 / 60 + "(分钟)未使用!";
}
}
}
return recipeTimeOutMsg;
}
protected void validLotInEqp(long eqptRrn, List<Lot> lots) {
for (Lot lot : lots) {
validLotInEqp(eqptRrn, lot);
}
}
protected void validLotInEqp(long eqptRrn, Lot lot) {
boolean state = false;
List<Relation> entitygroup = new ArrayList<>();
String eqptGroupRrns = specService.getEqptGroupRrns(lot.getProcessRrn(), lot.getProcessVersion(),
lot.getRouteRrn(), lot.getOperationRrn());
if (StringUtils.isNotBlank(eqptGroupRrns)) {
List<Long> eqptGroupRrnList = Arrays.stream(eqptGroupRrns.split(",")).map(s -> Long.parseLong(s))
.collect(Collectors.toList());
for (Long eqptGroupRrn : eqptGroupRrnList) {
entitygroup.addAll(emsService.getAllEntities(eqptGroupRrn));
}
} else {
long operationRrn = lot.getOperationRrn();
Operation operation = prpService.getOperation(operationRrn);
long entityGroupRrn = operation == null ? 0L : operation.getEntityGroupRrn();
entitygroup = emsService.getAllEntities(entityGroupRrn);
}
// 检测当前设备是否在当前步骤可操作的设备组中
for (Relation relation : entitygroup) {
if (eqptRrn == relation.getInstanceRrn()) {
state = true;
break;
}
}
if (lotService.isLotSpecialEqpt(eqptRrn, lot.getLotRrn())) {
state = true;
}
if (lotService.isLotSpecial(lot.getLotRrn(), lot.getOperationRrn())) {
state = true;
}
Assert.isTrue(state, Errors.create().content("该批次所在步骤为{}({})," + "当前设备{}不能操作该步骤,请更换设备!")
.args(getInstanceId(lot.getOperationRrn()), getInstanceDesc(lot.getOperationRrn()),
getInstanceId(eqptRrn)).build());
}
protected boolean isTrackUnitFlag(Lot lot) {
Operation operation = prpService.getOperation(lot.getOperationRrn());
String flag = operation.getTrackUnitFlag();
if ((flag != null) && flag.equals(ON)) {
return true;
} else {
return false;
}
}
protected Collection parseToSimplifyCollection(String unitString) {
Collection unitList = new ArrayList();
long seq = 0;
int index_1 = 0;
int index_2 = 0;
int index_3 = 0;
int index_4 = 0;
if ((unitString == null) || unitString.equalsIgnoreCase("")) {
return unitList;
}
StringTokenizer stn = new StringTokenizer(unitString, "$", false);
String unit = "";
String available = "";
String unitRrn = "";
String unitId = "";
String dummyWaferFlag = "";
String lotId = "";
while (stn.hasMoreElements()) {
seq++;
unit = stn.nextToken();
if ((unit == null) || unit.trim().equals("")) {
continue;
}
index_1 = unit.indexOf(",");
index_2 = unit.indexOf(",", index_1 + 1);
index_3 = unit.indexOf(",", index_2 + 1);
index_4 = unit.indexOf(",", index_3 + 1);
unitId = unit.substring(0, index_1);
unitRrn = unit.substring(index_1 + 1, index_2);
dummyWaferFlag = unit.substring(index_2 + 1, index_3);
available = unit.substring(index_3 + 1, index_4);
lotId = unit.substring(index_4 + 1);
if ((index_1 != 0) && (index_1 != -1) && (unitId != null) && !unitId.equalsIgnoreCase("N/A") &&
(unitRrn != null) && !unitRrn.equalsIgnoreCase("null")) {
HashMap map = new HashMap();
map.put("position", new String("" + seq));
map.put("unitId", unitId);
map.put("unitRrn", unitRrn);
map.put("dummyflag", dummyWaferFlag);
map.put("available", available);
map.put("lotid", lotId);
unitList.add(map);
}
}
return unitList;
}
/**
* @param unitList
* @return String
* @Description 将集合对象转换成json字符串(包含空位置信息的json, 一般用于前台ext的展示)
* @author Aiden
*/
protected String parseToJsonString(List<Map> unitList) {
List<Map> newUnits = new ArrayList<Map>(unitList);
Collections.sort(newUnits, new Comparator<Map>() {
// 将wafer重新排序
@Override
public int compare(Map map1, Map map2) {
int position1 = MapUtils.getIntValue(map1, "position");
int position2 = MapUtils.getIntValue(map2, "position");
if (position1 > position2) {
return 1;
} else if (position1 < position2) {
return -1;
} else {
return 0;
}
}
});
Iterator it = newUnits.iterator();
Map unit = new HashMap();
int number = 1;// 指wafer位置从1开始
int seq = 1;
List<Map> units = new ArrayList<Map>();
while (it.hasNext()) {
Map<String, Object> unitMap = null;
unit = (HashMap) it.next();
seq = MapUtils.getIntValue(unit, "position");
while ((number < seq)) {
unitMap = new HashMap();
unitMap.put("position", number + "");
unitMap.put("unitId", "");
unitMap.put("unitRrn", "");
unitMap.put("lotid", "");
unitMap.put("chooseFlag", "");
unitMap.put("markNumber", "");
unitMap.put("markNumberComment", "");
units.add(unitMap);
number++;
}
unitMap = new HashMap();
unitMap.put("position", number + "");
unitMap.put("unitId", unit.get("unitId"));
unitMap.put("unitRrn", unit.get("unitRrn"));
unitMap.put("lotid", unit.get("lotid"));
unitMap.put("chooseFlag", unit.get("chooseFlag"));
unitMap.put("markNumber", unit.get("markNumber"));
unitMap.put("markNumberComment", unit.get("markNumberComment"));
units.add(unitMap);
number++;
}
int listSize = units.size();// 已有
for (int i = listSize + 1; i <= 25; i++) {
Map<String, Object> unitMap = new HashMap();
unitMap.put("position", i + "");
unitMap.put("unitId", "");
unitMap.put("unitRrn", "");
unitMap.put("lotid", "");
unitMap.put("chooseFlag", "");
unitMap.put("markNumber", "");
unitMap.put("markNumberComment", "");
units.add(unitMap);
}
return JsonUtils.toString(units);
}
protected String initEmptyCarrier() {
List<Map<String, Object>> emptyUnits = new ArrayList<Map<String, Object>>();
int number = 25;// 默认槽位25片
for (int i = 1; i <= number; i++) {
Map<String, Object> unitMap = new HashMap<String, Object>();
unitMap.put("position", i + "");
unitMap.put("unitId", "");
unitMap.put("unitRrn", "");
unitMap.put("lotid", "");
emptyUnits.add(unitMap);
}
String jsonStr = JsonUtils.toString(emptyUnits);
return jsonStr;
}
protected String getValidateId(String objectId, String type) {
long facilityRrn = LocalContext.getFacilityRrn();
if (objectId.equals("")) {
return objectId;
}
objectId = objectId.trim().toUpperCase();
Assert.isFalse(getInstanceRrn(objectId, facilityRrn, type) <= 0,
Errors.create().key(MessageIdList.ID_NOT_EXIST).content("The {}: {} does not exist!")
.args(type, objectId).build());
return objectId;
}
protected void verifyChildLot(String childLotId, String carrierId, List<Map> cLots) {
Assert.isFalse((childLotId == null) || childLotId.equalsIgnoreCase(""),
Errors.create().key(MessageIdList.CHILD_LOT_ID_EMPTY).content("The Child Lot ID is empty!").build());
for (Map item : cLots) {
Assert.isFalse(item.get("childLotId").equals(childLotId),
Errors.create().key(MessageIdList.CHILD_LOT_ID_EXISTS).content("The Child Lot ID already existed!").build());
Assert.isFalse(item.get("carrierId").equals(carrierId),
Errors.create().content("The Carrier has already been specified!").build());
}
}
protected void verifyChildLotId(SplitMergeInfoForm theform, List<Map> childLots) {
String childLotId = theform.getLotId();
Assert.isFalse((childLotId == null) || childLotId.equalsIgnoreCase(""),
Errors.create().key(MessageIdList.CHILD_LOT_ID_EMPTY).content("The Child Lot ID is empty!").build());
childLotId = childLotId.toUpperCase();
theform.setLotId(childLotId);
for (Map item : childLots) {
Assert.isFalse(((String) item.get("childLotId")).equalsIgnoreCase(childLotId),
Errors.create().key(MessageIdList.CHILD_LOT_ID_EXISTS).content("The Child Lot ID already existed!").build());
}
}
protected void validateLotId(String lotId) {
long facilityRrn = LocalContext.getFacilityRrn();
Lot lot = lotQueryService.getLot(lotId, facilityRrn);
Assert.isFalse((lot != null) && (lot.getLotRrn() > 0),
Errors.create().content("This lot ID is already existed!Lot ID='{}'").args(lotId).build());
}
protected void builditemChidLotInfo(HttpServletRequest request, SplitMergeInfoForm theform, LotInfoForm lotInfoForm,
Lot lot, Map item) {
long facilityRrn = LocalContext.getFacilityRrn();
theform.setCarrierId(StringUtils.trimToUpperCase(theform.getCarrierId()));
Lot tmpLot = new Lot();
BeanUtils.copyProperties(lot, tmpLot);
carrierService.compareRealCarrierAndCheckAvailabile(facilityRrn, lot.getCarrierId(), theform.getCarrierId());
long carrierRrn = carrierService.getCarrierRrnForLot(facilityRrn, theform.getQty1(), theform.getCarrierId());
//check sortJob
checkWaitJobs(carrierRrn, 0L, 0L, null);
item.put("childLotId", theform.getLotId());
item.put("carrierId", theform.getCarrierId());
item.put("carrierRrn", carrierRrn);
item.put("splitQty", theform.getQty1());
if (theform.getQty1() != null) {
item.put("intSplitQty", theform.getQty1().intValue() + "");
}
item.put("technologyRrn", lot.getProcessRrn());
if (lotInfoForm.getSplitType().equals("permanent") && theform.getChangeProcessFlag().equals("0")) {
item.put("wflStepPath", null);
} else {
item.put("wflStepPath", request.getParameter("stepNumber"));
}
item.put("routeId", theform.getRouteId());
item.put("routeId4Show", theform.getRouteId());
item.put("operationId", theform.getOperationId());
item.put("operationRrn", new Long(
getInstanceRrn(theform.getOperationId(), getNamedSpace(ObjectList.OPERATION_KEY, facilityRrn),
ObjectList.OPERATION_KEY)));
Long opRrn = (Long) item.get("operationRrn");
String operationDesc = getInstanceDesc(opRrn.longValue());
item.put("operationDesc", operationDesc);
if (StringUtils.isNotEmptyTrim(WebUtils.getParameter("targetListValues", request))) {
item.put("unitList", request.getParameter("targetListValues"));// 取选定的Wafer目标值.
} else {
item.put("unitList", theform.getTargetListValues());// 取选定的Wafer目标值.
}
}
protected Long getDefaultTechnology(Long productRrn) {
Long processRrn = 0L;
boolean firstProcess = true;
List<Map> productTechnologys = prpService.getProductTechnologys(productRrn);
for (Map processMap : productTechnologys) {
if (processMap != null) {
if (StringUtils.isNotBlank(MapUtils.getJsonString(processMap, "default")) &&
StringUtils.equalsIgnoreCase("y", MapUtils.getJsonString(processMap, "default"))) {
// 获取默认流程
processRrn = MapUtils.getLong(processMap, "instancerrn");
break;
} else {
// 获取第一个流程
if (firstProcess) {
firstProcess = false;
processRrn = MapUtils.getLong(processMap, "instancerrn");
}
}
}
}
Assert.isFalse(processRrn == 0L,
Errors.create().key(MessageIdList.PRODUCT_EMPTYPROCESS).content("product dose not have process")
.build());
return processRrn;
}
protected void copyLotForm(SplitMergeInfoForm theform, LotInfoForm lotInfoForm, Lot lot) {
theform.setCacheLotInfo(WebUtils.getCacheObj2String(lotInfoForm));
Map unitsOfParentLot = WebUtils.getCacheString2Obj(theform.getCacheUnitsOfParentLot()) ==
null ? new HashMap() : ((Map) WebUtils.getCacheString2Obj(theform.getCacheUnitsOfParentLot()));
unitsOfParentLot.put(lot.getLotId() + "unitsOfParentLot", lotInfoForm.getSourceListValues());
theform.setCacheUnitsOfParentLot(WebUtils.getCacheObj2String(unitsOfParentLot));
PropertyUtils.copyProperties(theform, lot);
}
/**
* @param jsonStr
* @return List<Map < String, Object>>
* @Description 获得移除空位后的wafer信息
*/
protected List<Map<String, Object>> parseJsonStrAndRemoveIdlePostion(String jsonStr) {
List<Map<String, Object>> unitList = new ArrayList<Map<String, Object>>();
List list = JsonUtils.toObject(jsonStr, List.class);
List<Map<String, Object>> tempUnits = (List) list;
for (Map<String, Object> unitMap : tempUnits) {
String unitId = MapUtils.getString(unitMap, "unitId");
String unitRrn = MapUtils.getString(unitMap, "unitRrn");
String lotid = MapUtils.getString(unitMap, "lotid");
if (StringUtils.isNotBlank(unitId) && StringUtils.isNotBlank(unitRrn) && StringUtils.isNotBlank(lotid)) {
unitList.add(unitMap);
}
}
return unitList;
}
protected void replaceChildRecipeId(Map lotInfo) {
List childRecipeList = (List) MapUtils.getObject(lotInfo, "childRecipes");
if (childRecipeList != null) {
for (Object obj : childRecipeList) {
Map map = (Map) obj;
String matchRecipeId = recipeService.buildRecipePhysicalId(MapUtils.getString(map, "recipeId"),
lotInfo);
map.put("recipePhysicalId", matchRecipeId);
}
}
}
protected Operation getOperation(Operation operation) {
return prpService.getOperation(operation.getInstanceRrn());
}
protected void checkParameters(ReassignRequestDto reassignRequestDto) {
Assert.isFalse(CollectionUtils.isEmpty(reassignRequestDto.getReassignLotIds()),
Errors.create().content("Reassign Lots can not be empty!").build());
Assert.isFalse(StringUtils.isEmpty(reassignRequestDto.getDepartment()),
Errors.create().content("Department can not be empty!").build());
Assert.isFalse(StringUtils.isEmpty(reassignRequestDto.getResponsibilityUserId()) ||
reassignRequestDto.getResponsibilityUserRrn() <= 0,
Errors.create().content("User Id can not be empty!").build());
Assert.isFalse(StringUtils.isEmpty(reassignRequestDto.getReason()),
Errors.create().content("Reason can not be empty!").build());
}
protected String transUnit(String sourceList, String targetList) {
List<Map<String, Object>> source = parseJsonStrAndRemoveIdlePostion(sourceList);
List<Map> target = (List) parseJsonStrAndRemoveIdlePostion(targetList);
target.addAll(source);
return parseToJsonString(target);
}
protected void sourceAndChidUnits(List source, Map item, List<Map> parentLotRunCardCreateTime) {
List buildItem = new ArrayList();
// Collection buildItemTwo = new ArrayList();
List childUnits = (List) item.get("units");
String childLotId = MapUtils.getString(item, "childLotId");
Lot childLot = lotQueryService.getLot(childLotId, LocalContext.getFacilityRrn());
Timestamp childLotCreateTime = childLot.getCreatedTimestamp();
if (parentLotRunCardCreateTime != null && parentLotRunCardCreateTime.size() > 0) {
for (Map parentRunCardCreatedTime : parentLotRunCardCreateTime) {
Timestamp createdTime = (Timestamp) MapUtils.getObject(parentRunCardCreatedTime, "createdTime");
String runCardId = MapUtils.getString(parentRunCardCreatedTime, "runCardId");
Assert.isFalse(createdTime != null && childLotCreateTime.before(createdTime),
Errors.create().key(MessageIdList.LOT_PARENTLOT_HAS_UNFINISHED_RUNCARD)
.content("Parent lot has unfinished runcard({}). Forbid of merger!")
.args(runCardId).build());
}
}
List<Map> childLotRunCardCreatedTimeList = lotRunCardQueryService.getSumbitAndActiveRunCardCreateTime(
childLot.getLotRrn());
Assert.isFalse(childLotRunCardCreatedTimeList != null && childLotRunCardCreatedTimeList.size() > 0,
Errors.create().key(MessageIdList.LOT_PARENTLOT_HAS_UNFINISHED_RUNCARD)
.content("Child lot: {} has unfinished runcard. Forbid of merger!")
.args(childLot.getLotId()).build());
// 检查子批和目批片号与对应的位置是否一致
Assert.isTrue(checkPositionAvaliable(source),
Errors.create().content("Unit Id for parent lot don't match the position!").build());
Assert.isTrue(checkPositionAvaliable(childUnits),
Errors.create().content("Unit Id for child lot don't match the " + "position!").build());
List sourcePosition = new ArrayList();
for (Object childUnit : childUnits) {
boolean childPosition = true;
Map childMap = (Map) childUnit;
String unitId = MapUtils.getString(childMap, "unitId");
int defaultPosition = Unit.getWaferDefaultPostion(unitId);
if (defaultPosition > 0) {
for (Iterator iterator = source.iterator(); iterator.hasNext(); ) {
Map sourceMap = (Map) iterator.next();
int position = MapUtils.getIntValue(sourceMap, "position");
if (defaultPosition == position) {// 说明子批的原来的位置被占用了,不能再合批
childPosition = false;
}
// 再次check unit id唯一性
Assert.isFalse(StringUtils.equals(unitId, MapUtils.getString(sourceMap, "unitId")),
Errors.create().content("Parent lot's unit id is same with child lot'd unit id!")
.build());
}
} else {// 子批默认位置为空
childPosition = false;
}
Assert.isTrue(childPosition, Errors.create().content("Haven't avaliable position for child lot!").build());
childMap.put("position", defaultPosition + "");
buildItem.add(childMap);
}
source.addAll(buildItem);
}
protected void checkLotStepForMerge(Lot parentLot, Lot childLot) {
Assert.isFalse(!parentLot.getOperationRrn().equals(childLot.getOperationRrn()) ||
!StringUtils.equals(parentLot.getRouteId(), childLot.getRouteId()),
Errors.create().key(MessageIdList.MERGELOT_LOTS_STEPID_DIFFERENT)
.content("Lots with different step Id.").build());
}
protected void setCache4WFL(HttpServletRequest request, ActionForm form) {
RootForm theform = (RootForm) form;
theform.setCacheCurrentlots(WebUtils.getCacheObj2String(request.getAttribute("currentlots")));
theform.setCacheJob(WebUtils.getCacheObj2String(request.getAttribute(SessionNames.JOB_KEY)));
theform.setCacheParametersInfo(
WebUtils.getCacheObj2String(request.getAttribute(SessionNames.PARAMETERSINFO_KEY)));
theform.setCacheCollection(WebUtils.getCacheObj2String(request.getAttribute(SessionNames.COLLECTION_KEY)));
theform.setCacheSorterJob(WebUtils.getCacheObj2String(request.getAttribute(SessionNames.SORTER_JOB)));
request.setAttribute("runcardLotId", request.getAttribute("runcardLotId"));
}
protected long getSourceUnitRrn(long targetUnitRrn) throws Exception {
long sourceUnitRrn = 0L;
BondingMapping bondingMapping = wipService.getBondingMapping(targetUnitRrn);
if (bondingMapping != null) {
sourceUnitRrn = bondingMapping.getSourceUnitRrn();
}
return sourceUnitRrn;
}
protected String listToString(List<Map> unitList) {
StringBuilder sb = new StringBuilder();
Iterator it = unitList.iterator();
int number = 1;
int seq;
HashMap unit;
while (it.hasNext()) {
unit = (HashMap) it.next();
seq = Integer.parseInt((String) unit.get("position"));
while ((number < seq) && (number < 51)) {
sb.append(" $");
number++;
}
sb.append(unit.get("unitId"));
sb.append(",");
sb.append(unit.get("unitRrn"));
sb.append(",");
sb.append(unit.get("dummyflag"));
sb.append(",");
sb.append(unit.get("available"));
sb.append(",");
sb.append(unit.get("lotid"));
sb.append("$");
number++;
}
return sb.toString();
}
protected void validateTask(Map params, String task) {
String taskAction = "";
if ("abortjob".equalsIgnoreCase(task)) {
taskAction = "/abortjob.do";
} else if ("changeprocess".equalsIgnoreCase(task)) {
taskAction = "/wip/processswitch.jsp";
} else if ("edc".equalsIgnoreCase(task)) {
taskAction = "/edcstart.do";
} else if ("autoedc".equalsIgnoreCase(task)) {
taskAction = "/autoedcstart.do";
} else if ("holdlot".equalsIgnoreCase(task)) {
taskAction = "/wip/processswitch.jsp";
} else if ("logevent".equalsIgnoreCase(task)) {
taskAction = "/logeventedit.do";
} else if ("movein".equalsIgnoreCase(task)) {
taskAction = "/movein.do";
} else if ("moveout".equalsIgnoreCase(task)) {
taskAction = "/moveout.do";
} else if ("processswitch".equalsIgnoreCase(task)) {
taskAction = "/wip/processswitch.jsp";
} else if ("rework".equalsIgnoreCase(task)) {
taskAction = "/wip/processswitch.jsp";
} else if ("showinstruction".equalsIgnoreCase(task)) {
taskAction = "/showinstruction.do";
} else if ("shiplot".equalsIgnoreCase(task)) {
taskAction = "/shiplottask.do";
} else if ("movenext".equalsIgnoreCase(task)) {
taskAction = "/processswitch.do?next=true&processFlag=nextStep&bgMove=y";
}
Assert.isFalse(params != null && params.get("Task_Method_ID") != null &&
!params.get("Task_Method_ID").equals(taskAction),
Errors.create().key(MessageIdList.SYSTEM_TRANSACTION_NOT_TOKEN).content("验证token失败!").build());
}
protected List<ContextValue> getInstruction(String byType, Map item, String actionPoint) {
Long productRrn = MapUtils.getLongValue(item, "productRrn");
Long processRrn = MapUtils.getLongValue(item, "processRrn");
Long routeRrn = MapUtils.getLongValue(item, "routeRrn");
Long operationRrn = MapUtils.getLongValue(item, "operationRrn");
if (StringUtils.isEmpty(actionPoint) || StringUtils.equalsIgnoreCase(actionPoint, ActionPointList.MOVEIN_KEY)) {
actionPoint = ActionPointList.MOVEIN_KEY;
} else {
actionPoint = ActionPointList.MOVEOUT_KEY;
}
if ("product".equals(byType)) {
return ctxExecService.getInstructionByProduct(productRrn, processRrn, routeRrn, operationRrn, actionPoint);
} else if ("process".equals(byType)) {
return ctxExecService.getInstructionByProcess(processRrn, routeRrn, operationRrn, actionPoint);
} else if ("lot".equals(byType)) {
Lot lot = lotQueryService.getLot(MapUtils.getString(item, "lotId"), LocalContext.getFacilityRrn());
return ctxExecService.getInstructionByLot(lot.getLotRrn(), lot.getRouteSeq(), lot.getOperationSeq(),
productRrn, processRrn, routeRrn, operationRrn, actionPoint);
}
return null;
}
protected String getUOM1(Long operationRrn) {
String UOM1 = "";
Operation oper = prpService.getOperation(operationRrn);
if (oper != null && oper.getUnitOfMeasure1() != null) {
UOM1 = oper.getUnitOfMeasure1();
}
return UOM1;
}
protected Map buildProcessLotInfo(Lot lot) {
Map lotInfo = new HashMap();
lotInfo.put("lotId", lot.getLotId());
lotInfo.put("lotRrn", new Long(lot.getLotRrn()));
lotInfo.put("productId", lot.getProductId());
lotInfo.put("processId", lot.getProcessId());
lotInfo.put("lotStatus", lot.getLotStatus());
lotInfo.put("stageId", lot.getStageId());
lotInfo.put("operationId", lot.getOperationId());
lotInfo.put("operationDesc", lot.getOperationDesc());
lotInfo.put("recipeId", lot.getRecipeId());
try {
lotInfo.put("recipePhysicalId", getRecipePhysicalId(lot));
} catch (Exception e) {
lotInfo.put("recipePhysicalId", "");
}
lotInfo.put("qty1", lot.getQty1());
return lotInfo;
}
protected void buildLotinfo(Job job, List lots) {
int i = 0;
for (Iterator it = lots.iterator(); it.hasNext(); ) {
HashMap item = (HashMap) it.next();
Lot lot = lotQueryService.getLot(MapUtils.getLongValue(item, "lotRrn"));
List<Relation> reticles = wipQueryService.getAvailableReticlesForTrackIn(lot, job.getEqptRrn());
String isReticleRequired = TRUE;
if (CollectionUtils.isEmpty(reticles)) {
reticles = new ArrayList<>();
isReticleRequired = FALSE;
}
item.put("isReticleRequired", isReticleRequired);
item.put("reticleString" + i, reticles);
i++;
RecipeContextValue recipe = ctxExecService.getRecipeContextValue(lot);
Long borRrn = 0L;
if (recipe != null) {
String borString = recipe.getResultValue5();
if (StringUtils.isNotEmpty(borString)) {
borRrn = Long.parseLong(borString);
}
item.put("parame", recipe.getParameter());
if (recipe.getWiringRrn() != null && !getInstanceId(recipe.getWiringRrn()).equalsIgnoreCase("N/A")) {
item.put("wiringId", getInstanceId(recipe.getWiringRrn()));
}
item.put("yield", StringUtils.EMPTY);
}
// For BOR
//Long borRrn = ctxExecService.getBomRrn(lot);
if (borRrn > 0) {
item.put("borRrn", borRrn);
item.put("borId", getInstanceId(borRrn));
}
String stageId = ctxExecService.getStageId(lot);
if (StringUtils.isNotBlank(stageId)) {
item.put("stageId", stageId);
}
}
}
/**
* 取消moveIn init方法
*
* @param theform
* @param request
* @throws Exception
*/
protected void cancelMoveInInit(LotInfoForm theform, HttpServletRequest request) throws Exception {
Long facilityRrn = LocalContext.getFacilityRrn();
// Populate the new valid format id
Lot lotInfo = new Lot();
String lotId = theform.getLotId().trim().toUpperCase();
request.setAttribute("lotId", lotId);
long jobrrn = 0;
Assert.isTrue(lotId != null && !lotId.trim().equals(""), Errors.create().content("No such Lot exist!").build());
lotInfo = isValidLot(facilityRrn, lotId.trim().toUpperCase());
Assert.notNull(lotInfo, Errors.create().content("No such Lot exist!").build());
String equipmentRrns = request.getParameter("avaliableEqtRrn");
request.setAttribute("equipmentRrns", equipmentRrns);
Long lotRrn = lotInfo.getLotRrn();
Lot curLot = lotQueryService.getLot(lotRrn.longValue());
//卡控post future hold被hold住的lot
checkPostFutureHold(lotRrn);
String lotStatus = lotQueryService.getLotStatus(lotRrn.longValue());
jobrrn = wipQueryService.getJobRrn(lotRrn.longValue());
Long jobRrn = new Long(jobrrn);
if (("RUNNING".equals(lotStatus) || "DISPATCH".equals(lotStatus) || "PROCESSED".equals(lotStatus)) &&
jobRrn != null) {
org.apache.commons.beanutils.PropertyUtils.copyProperties(theform, lotInfo);
theform.setLot_rrn(lotRrn);
theform.setJobRrn(jobRrn);
theform.setWflStepPath(curLot.getWflStepPath());
theform.setOperationSeq(lotInfo.getOperationSeq());
request.setAttribute("dueDate", lotInfo.getDueDate());
Lot anotherLot = getBondingLot(lotRrn, jobRrn);
if (anotherLot != null && anotherLot.getLotRrn() > 0) {
request.setAttribute("anotherLot", anotherLot);
}
theform.setSourceListValues(parseToString(wipQueryService.getUnitListByLot(lotRrn)));
theform.setTargetListValues("");
String childLotId = getChildLotId(lotInfo.getLotId(), facilityRrn);
theform.setSplitChildLotId(childLotId);
Map conditionMap = BeanUtils.copyBeanToMap(curLot);
theform.setOperationDesc(ctxExecService.getOperationDescByProcessInfo(conditionMap));
theform.setHotFlagPriorityStr(
wipQueryService.getHotflagSplicingPriority(NumberUtils.toInt(theform.getHotFlag(), 0),
theform.getPriority(), facilityRrn));
NamedObject obj = new NamedObject(curLot.getCarrierRrn());
obj = baseService.getNamedObject(obj);
request.setAttribute("baseCarrierType", obj.getObjectSubtype());
} else {
throw new SystemIllegalArgumentException(
Errors.create().key(MessageIdList.LOT_STATUS_MUST_RUNNING_OR_DISPATCH)
.content("lot status must running or dispatch").build());
}
}
/**
* Cancel MoveIn 处理
**/
protected ActionForward cancelMoveInHandle(ActionMapping mapping, ActionForm form, HttpServletRequest request,
HttpServletResponse response) throws Exception {
String user = LocalContext.getUserId();
Long facilityRrn = LocalContext.getFacilityRrn();
LotInfoForm theform = (LotInfoForm) form;
Long lotRrn = theform.getLot_rrn();
Long jobRrn = theform.getJobRrn();
String comments = theform.getLotComments();
// 没有部分取消作业 永远不会走
if (checkSplitCancelMoveIn(request)) {
//todo 暂时没有部分取消作业
//splitCancelMoveIn(request, lotRrn, theform);
Boolean flag = (Boolean) request.getAttribute("_cancelMoveIn");
if (flag != null && flag.booleanValue()) {
request.getRequestDispatcher("/lotLocation4CSECAction.do?action=lotlocation&lotId=" +
String.valueOf(request.getAttribute("_lotId")))
.forward(request, response);
return null;
}
return new ActionForward(mapping.getInput());
}
String userRRN = StringUtils.trimToUpperCase(theform.getUserId());
Assert.isFalse(StringUtils.isEmpty(theform.getUserId()),
Errors.create().content("Responsibility cannot be empty! ").build());
String userName = securityService.getUser(Long.parseLong(userRRN)).getUserName();
Assert.isFalse(comments != null && comments.getBytes("UTF-8").length > 128,
Errors.create().content("The input content exceeds the length limit!").build());
String reason =
theform.getReasonCode() + " " + theform.getDeptExt().trim().toUpperCase() + " " + userName + " " +
theform.getReason();
Assert.isFalse(reason != null && reason.getBytes("UTF-8").length > 1024,
Errors.create().content("The input content exceeds the length limit!").build());
Lot lot = lotQueryService.getLot(lotRrn.longValue());
if (lot.getJobRrn() != null && lot.getJobRrn().longValue() > 0) {
List<Lot> lotList = lotQueryService.getLotsByJobRrn(lot.getJobRrn());
List<Map> transInfo = new ArrayList<Map>();
for (Lot _lot : lotList) {
_lot = lotQueryService.getLot(_lot.getLotRrn());
//涉及数据权限问题,有些功能比如RRC的cancleMovein的job为0,会查出其它没有权限的批次,导致getLot的结果为空
if (_lot == null || _lot.getLotRrn() <= 0L) {
continue;
}
TransReason transReason = new TransReason();
transReason.setReasonCode(theform.getReasonCode());
transReason.setReason(reason);
transReason.setResponsibility(user);
transReason.setTransQty1(_lot.getQty1());
transReason.setTransQty2(_lot.getQty2());
if (!StringUtils.equalsIgnoreCase(_lot.getLotStatus(), LotStatus.WAITING) && _lot.getJobRrn() != null &&
_lot.getJobRrn() > 0) {
Map<String, Object> tranMap = buildCancelMoveInTransInfo(_lot, comments, transReason);
addCancelMoveInLotTrans(transInfo, tranMap);
}
Lot anotherLot = getBondingLot(_lot.getLotRrn(), jobRrn);
anotherLot = lotQueryService.getLot(anotherLot.getLotId(), facilityRrn);
if (anotherLot != null && anotherLot.getLotRrn() > 0 &&
!StringUtils.equalsIgnoreCase(anotherLot.getLotStatus(), LotStatus.WAITING) &&
anotherLot.getJobRrn() != null && anotherLot.getJobRrn() > 0) {
String comment = "Auto cancel movein with :" + _lot.getLotId() + ";";
Map<String, Object> tranMap = buildCancelMoveInTransInfo(anotherLot, comment, transReason);
addCancelMoveInLotTrans(transInfo, tranMap);
}
List<Lot> batchLotList = diffBatchQueryService.getBatchLotList(_lot.getLotRrn());
if (CollectionUtils.isNotEmpty(batchLotList)) {
for (Lot batchLot : batchLotList) {
if (batchLot.getLotRrn() != _lot.getLotRrn() &&
LotStatus.isCanCancelMoveIn(batchLot.getLotStatus())) {
Map<String, Object> tranMap = buildCancelMoveInTransInfo(batchLot, comments, transReason);
addCancelMoveInLotTrans(transInfo, tranMap);
}
}
}
CacheUtils.remove(lot.getEqptRrn() + "");
}
doCancelMoveIn(transInfo);
}
cancelMoveInRunCardHandle(lot, theform, reason, userName, facilityRrn);
cancelMoveInReturn(theform, request, response);
return WebUtils.NULLActionForward;
}
/**
* 执行cancel move in 特殊情况重写该方法
*
* @author finatice.yang
* @date 2021/7/23
* @version 6.0.0
**/
protected void doCancelMoveIn(List<Map> transInfo) {
List<String> lotRrns = new ArrayList<>();
for (Map map : transInfo) {
Lot lot = (Lot) MapUtils.getObject(map, "lot");
lotRrns.add(StringUtils.toString(lot.getLotRrn()));
}
lotService.cancelMoveIn(transInfo, lotRrns);
}
/**
* Cancel MoveIn RunCard处理(RunCard CancelMoveIn 重写)
*
* @param lot
* @param theform
* @param reason
* @param userName
* @param facilityRrn
*/
protected void cancelMoveInRunCardHandle(Lot lot, LotInfoForm theform, String reason, String userName,
Long facilityRrn) {
}
/**
* Cancel MoveIn 之后返回(子类重写)
*
* @param theform
* @param request
* @param response
* @throws Exception
*/
protected void cancelMoveInReturn(LotInfoForm theform, HttpServletRequest request,
HttpServletResponse response) throws Exception {
}
/**
* Hold 处理
*/
protected ActionForward holdHandle(ActionMapping mapping, ActionForm form, HttpServletRequest request) {
HoldReleaseLotInfoForm theform = (HoldReleaseLotInfoForm) form;
long facilityRrn = LocalContext.getFacilityRrn();
String lotId = theform.getLotId();
long userRrn = LocalContext.getUserRrn();
String userId = LocalContext.getUserId();
User user = securityService.getUser(userId, facilityRrn);
Lot lot = lotQueryService.getLot(lotId, facilityRrn);
Assert.isFalse(lot.getLotRrn() <= 0,
Errors.create().key(MessageIdList.LOT_LOTRRN_NOT_FOUND).content("Cannot Find Lot!").build());
Assert.isFalse((theform.getReason() == null) || ("".equalsIgnoreCase(theform.getReason())),
Errors.create().key(MessageIdList.ERROR_REASON_IS_EMPTY).content("Reason is empty!").build());
String reason = theform.getDepartment() + " Reason:" + "Holdcode is " + theform.getReasonCode() + ". " +
theform.getReason();
TransReason transReason = new TransReason();
transReason.setReasonCode(theform.getReasonCode());
transReason.setReason(reason);
transReason.setTransQty1(lot.getQty1());
transReason.setTransQty2(lot.getQty2());
transReason.setResponsibility(userId);
List<Lot> holdLotList = new ArrayList<>();
List<Lot> batchLotList = diffBatchQueryService.getBatchLotList(lot.getLotRrn());
if (CollectionUtils.isNotEmpty(batchLotList)) {
for (Lot batchLot : batchLotList) {
Assert.state(LotStatus.isCanHold(batchLot.getLotStatus()),
Errors.create().key(MessageIdList.LOT_STATUS_CANT_NOT_BE_HOLD)
.content("Lot status must be 'HOLD' or 'WAITING'!").build());
holdLotList.add(batchLot);
}
} else {
Assert.state(LotStatus.isCanHold(lot.getLotStatus()),
Errors.create().key(MessageIdList.LOT_STATUS_CANT_NOT_BE_HOLD)
.content("Lot status must be 'HOLD' or 'WAITING'!").build());
holdLotList.add(lot);
}
List<String> lockLotRrns = holdLotList.stream().map(holdLot -> StringUtils.toString(holdLot.getLotRrn()))
.collect(Collectors.toList());
lotService.holdLot(holdLotList, user, transReason, lockLotRrns);
//清除派工页面缓存
Collection availableEquipmentInfos = buildAvailableEquipInfosForLot(lot, userRrn);
for (Object temp : availableEquipmentInfos) {
Map equipmentInfo = (Map) temp;
CacheUtils.remove(MapUtils.getString(equipmentInfo, "equipmentRrn"));
}
return mapping.findForward(Constants.LOTLOCATION_KEY);
}
/**
* Hold Running 处理
*/
protected ActionForward holdRunningHandle(ActionMapping mapping, ActionForm form, HttpServletRequest request) {
HoldReleaseLotInfoForm theform = (HoldReleaseLotInfoForm) form;
long facilityRrn = LocalContext.getFacilityRrn();
String lotId = theform.getLotId();
long userRrn = LocalContext.getUserRrn();
String userId = LocalContext.getUserId();
User user = securityService.getUser(userId, facilityRrn);
Lot lot = lotQueryService.getLot(lotId, facilityRrn);
Assert.isFalse(lot.getLotRrn() <= 0,
Errors.create().key(MessageIdList.LOT_LOTRRN_NOT_FOUND).content("Cannot Find Lot!").build());
Assert.isFalse((theform.getReason() == null) || ("".equalsIgnoreCase(theform.getReason())),
Errors.create().key(MessageIdList.ERROR_REASON_IS_EMPTY).content("Reason is empty!").build());
String reason = theform.getDepartment() + " Reason:" + "Holdcode is " + theform.getReasonCode() + ". " +
theform.getReason();
TransReason transReason = new TransReason();
transReason.setReasonCode(theform.getReasonCode());
transReason.setReason(reason);
transReason.setTransQty1(lot.getQty1());
transReason.setTransQty2(lot.getQty2());
transReason.setResponsibility(userId);
List<Lot> holdLotList = new ArrayList<>();
List<Lot> batchLotList = diffBatchQueryService.getBatchLotList(lot.getLotRrn());
if (CollectionUtils.isNotEmpty(batchLotList)) {
for (Lot batchLot : batchLotList) {
Assert.state(LotStatus.isCanRunningHold(batchLot.getLotStatus()),
Errors.create().key(MessageIdList.LOT_STATUS_CANT_NOT_BE_HOLD)
.content("Lot status must be 'RUNNING' or 'RUNNINGHOLD'!").build());
holdLotList.add(batchLot);
}
} else {
Assert.state(LotStatus.isCanRunningHold(lot.getLotStatus()),
Errors.create().key(MessageIdList.LOT_STATUS_CANT_NOT_BE_HOLD)
.content("Lot status must be 'RUNNING' or 'RUNNINGHOLD'!").build());
holdLotList.add(lot);
}
List<String> lockLotRrns = holdLotList.stream().map(holdLot -> StringUtils.toString(holdLot.getLotRrn()))
.collect(Collectors.toList());
lotService.holdRunningLot(holdLotList, user, transReason, lockLotRrns);
//清除派工页面缓存
Collection availableEquipmentInfos = buildAvailableEquipInfosForLot(lot, userRrn);
for (Object temp : availableEquipmentInfos) {
Map equipmentInfo = (Map) temp;
CacheUtils.remove(MapUtils.getString(equipmentInfo, "equipmentRrn"));
}
//TODO CacheHelper相关更新
return mapping.findForward(Constants.LOTLOCATION_KEY);
}
/**
* Release 处理
*/
protected ActionForward releaseHandle(ActionMapping mapping, ActionForm form, HttpServletRequest request,
HttpServletResponse response) {
HoldReleaseLotInfoForm theform = (HoldReleaseLotInfoForm) form;
// List<Lot> lockLots = new ArrayList<Lot>();
boolean superReleaseFlag = StringUtils.isNotEmpty((String) request.getParameter("superrelease"));
long facilityRrn = LocalContext.getFacilityRrn();
String lotId = theform.getLotId();
long userRrn = LocalContext.getUserRrn();
String userId = LocalContext.getUserId();
String[] newPasswords = request.getParameterValues("newPassword");
String fieldFlag = request.getParameter("fieldFlags");
String[] fieldFlags = fieldFlag.split(",");
Lot lot = lotQueryService.getLot(lotId, facilityRrn);
Assert.isFalse(lot.getLotRrn() <= 0,
Errors.create().key(MessageIdList.LOT_LOTRRN_NOT_FOUND).content("Cannot Find Lot!").build());
Assert.isTrue(StringUtils.equals(lot.getLotStatus(), LotStatus.HOLD),
Errors.create().key(MessageIdList.LOT_STATUS_NOT_ALLOW).content("Lot status not allow").build());
PiLotView piLotView = wipQueryService.getPiLotViewIdByLotRrn(lot.getLotRrn(), lot.getBasedLotRrn());
checkRunCard(lot);
List<Map> holdReasons = wipQueryService.getHoldReasons(lot.getLotRrn());
List<Map> releaseReasons = new ArrayList();
List<Map> unReleaseReasons = new ArrayList();
//是否存在trackOutHold释放
boolean trackOutHoldExisted = false;
//工步变更检查flag
boolean lotStepChanged = false;
// 是否存在Bonding绑定错误
boolean sapphireBondedError = false;
for (int i = 0; i < holdReasons.size(); i++) {
Map holdReason = holdReasons.get(i);
String reasonCode = MapUtils.getString(holdReason, "reasonCode");
if (StringUtils.equals(TransReason.reasonCode.BONDERROR.name(), reasonCode)) {
sapphireBondedError = true;
}
if (StringUtils.equals("0", fieldFlags[i])) {
if (StringUtils.contains(MapUtils.getString(holdReason, "reasonCode"), HoldCodeNames.SRCHOLD_KEY)) {
List<LotRunCard> runcardList = cardService.getActivedLotRuncardByLot(lot.getLotRrn());
for (LotRunCard runcard : runcardList) {
Assert.isFalse(StringUtils.contains(MapUtils.getString(holdReason, "reason"),
"Current Lot WaferCnt is not equal to SRC Lot " +
"WaferCnt,Please Check!") &&
StringUtils.equals(lot.getFlowSeq(), runcard.getSplitFlowSeq()),
Errors.create().key(MessageIdList.RC_WITHDRAW_FIRST)
.content("Please withdraw the RC {} first!")
.args(getInstanceId(runcard.getRunCardRrn())).build());
Assert.isFalse(StringUtils.equals(lot.getFlowSeq(), runcard.getSplitFlowSeq()) &&
StringUtils.contains(MapUtils.getString(holdReason, "reason"),
getInstanceId(runcard.getRunCardRrn())),
Errors.create().key(MessageIdList.LOT_RELEASE_SRCHOLD_DENY)
.content("Can't release SRCHOLD!").build());
}
}
// Pilot分批后 卡控子批未合并不允许释放HOlD #41886
if (StringUtils.contains(MapUtils.getString(holdReason, "reasonCode"), "MERGED")) {
Assert.isFalse(Objects.nonNull(piLotView) && StringUtils.equalsIgnoreCase(piLotView.getSingleLot(),
PiLotStatusEnum.NO.toString()),
Errors.create().key(MessageIdList.PILOT_SPLIT_HOLD_RELEASER)
.content("Please release after merging child lot and parent lot!").build());
}
// 增加ocap hold卡控
Assert.isFalse(StringUtils.contains(reasonCode, HoldCodeNames.OCAP_HOLD) &&
wipQueryService.isValidOcapHold(lot.getLotRrn(),
MapUtils.getString(holdReason, "reason")),
Errors.create().content("Unable to release OCAP Hold!").build());
Assert.isFalse(HoldCodeNames.AUTO_MERGE_HOLD_KEY.equalsIgnoreCase(
MapUtils.getString(holdReason, "reasonCode")),
Errors.create().content("Can't release AUTO_MERGE_HOLD!").build());
boolean hasModule = reasonCode.indexOf(HoldCodeNames.MODULE_QTIMEHOLD_KEY) > -1;
if (hasModule) {
ReferenceFileDetail referenceFileDetail = getReferenceFileDetail(ReferenceDetailNames.HOLD_CODE,
reasonCode,
LocalContext.getFacilityRrn());
Assert.nonNull(referenceFileDetail, Errors.create().content(
"Please configure option {} in the $HOLD_CODE reference detail").args(reasonCode).build());
}
if (StringUtils.equals("TRACKOUTHOLD", MapUtils.getString(holdReason, "reasonCategory"))) {
trackOutHoldExisted = true;
}
String holdPassword =
holdReason.get("holdPassword") != null ? ((String) holdReason.get("holdPassword")).trim() : "";
String newPassword = newPasswords[i] != null ? newPasswords[i].trim() : "";
Assert.isTrue(StringUtils.equals(holdPassword, newPassword),
Errors.create().content("Invalid Release Password!").build());
releaseReasons.add(holdReason);
} else {
unReleaseReasons.add(holdReason);
}
}
Assert.isFalse(releaseReasons.size() <= 0,
Errors.create().key(MessageIdList.LOT_RELEASE_HOLD_EMPTY).content("please select release hold!")
.build());
Assert.isFalse(trackOutHoldExisted == true && unReleaseReasons.size() > 0,
Errors.create().key(MessageIdList.LOT_TRACKOUT_HOLD_CANNOT_RELEASE)
.content("Before Trackout hold released, Please release other hold first!").build());
if (trackOutHoldExisted) {
lotStepChanged = lotService.checkLotStepChange(lot.getLotRrn());
}
HashMap releaseInfo = new HashMap();
releaseInfo.put("lotRrn", new Long(lot.getLotRrn()).toString());
releaseInfo.put("lotId", lot.getLotId());
releaseInfo.put("releaseReasons", releaseReasons);
releaseInfo.put("transPerformedBy", userId);
String holdCode = StringUtils.EMPTY;
if (releaseReasons.size() == 1) {
holdCode = MapUtils.getString(releaseReasons.get(0), "reasonCode") + StringUtils.COMMA_SIGN;
} else {
for (Map<String, String> releaseReason: releaseReasons) {
holdCode += MapUtils.getString(releaseReason, "reasonCode") + StringUtils.COMMA_SIGN;
}
}
StringBuilder stringBuilder = new StringBuilder(
theform.getReasonGroup() + ",Release Code: " + theform.getReasonCode() + ",Hold Code: " + holdCode +
"Reason:");
releaseInfo.put("transComments", stringBuilder.toString());
releaseInfo.put("operation", lot.getOperationId());
TransReason transReason = new TransReason();
transReason.setReasonCode(theform.getReasonCode());
transReason.setReason(theform.getLotComments());
transReason.setTransQty1(lot.getQty1());
transReason.setTransQty2(lot.getQty2());
transReason.setResponsibility(userId);
transReason.setReason(theform.getReason());
releaseInfo.put("transReason", transReason);
releaseInfo.put("superFlag", "0");
// lockLots.add(lot);
// checkAndCreateLotsTransLock(LocalContext.getUserRrn(), TransactionNames.LOCK_RELEASE_LOT, lockLots,
// "release in LotReleaseAction by " + userId);
lotService.releaseLot(releaseInfo);
// removeLotLockWhenTransError(LocalContext.getUserRrn(), lockLots, TransactionNames.LOCK_RELEASE_LOT,
// "release in LotReleaseAction by " + userId);
//清除派工页面缓存
Collection availableEquipmentInfos = buildAvailableEquipInfosForLot(lot, userRrn);
for (Object temp : availableEquipmentInfos) {
Map equipmentInfo = (Map) temp;
CacheUtils.remove(MapUtils.getString(equipmentInfo, "equipmentRrn"));
}
releaseSpcHold(lot, releaseReasons);
if (sapphireBondedError || (trackOutHoldExisted && unReleaseReasons.isEmpty() && !lotStepChanged)) {
//查询最新批次信息
lot = lotQueryService.getLot(lot.getLotRrn());
return dispatchLotAfterRelease(mapping, request, response, userId, facilityRrn, lot);
}
splitRunCardService.doStartSplitRunCard(LocalContext.getUserId(), lot);
lotRunCardService.autoMergeRunCardLot(lot.getLotRrn(), LocalContext.getUserId());
return mapping.findForward(Constants.LOTLOCATION_KEY);
}
/**
* 检查Lot 是否属于RunCard.(重写 LotReleaseAction)
*/
protected void checkRunCard(Lot lot) {
}
/**
* releasePostFH 拼接参数返回manual/auto工作流 并不是真正的release操作
**/
protected ActionForward postFutureReleaseHandle(ActionMapping mapping, ActionForm form, HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
HoldReleaseLotInfoForm theform = (HoldReleaseLotInfoForm) form;
Map map = new HashMap();
map.put("lotId", theform.getLotId());
map.put("reasonCode", theform.getReasonCode());
map.put("lotComments", theform.getLotComments());
map.put("reason", theform.getReason());
String fieldFlag = request.getParameter("fieldFlags");
map.put("fieldFlag", fieldFlag);
String[] fieldFlags = fieldFlag.split(",");
List<FutureHoldLot> postFutureHoldLotList = (List<FutureHoldLot>) request.getAttribute("postFutureHoldLotList");
map.put("postFutureHoldLotList", postFutureHoldLotList);
Map<String, Object> parameters = wipService.getWorkflowParametersForRelease(map);
Lot lot = (Lot) MapUtils.getObject(parameters, "lot");
Job job = (Job) MapUtils.getObject(parameters, "job");
request.setAttribute(SessionNames.JOB_KEY, job);
List<Lot> lotList = new ArrayList<>();
lotList.add(lot);
List<Map> handleLotInfos = new ArrayList<>();
Map handleLotInfo = new HashMap<>();
handleLotInfo.put("Lot", lot);
handleLotInfo.put("handleInfo", new HashMap<>());
handleLotInfos.add(handleLotInfo);
request.setAttribute(SessionNames.HANDLE_LOT_INFO_KEY, handleLotInfos);
request.setAttribute(SessionNames.COLLECTION_KEY, lotList);
request.setAttribute(SessionNames.PARAMETERSINFO_KEY, parameters);
if (WipUtils.AUTO.equals(postFutureHoldLotList.get(0).getAttributeData2())) {
lotService.updateLotJobRrn(lot.getLotRrn(), job.getJobRrn());
lotService.doMoveJob(parameters);
request.getRequestDispatcher(
mapping.findForward("jobmanagement4lot").getPath() + "&lotId=" + lot.getLotId())
.forward(request, response);
} else {
request.getRequestDispatcher(mapping.findForward("workflow").getPath()).forward(request, response);
}
return null;
}
/**
* release在主产品debond后被postFH的辅产品lot
**/
protected ActionForward bondedLotPostFHReleaseHandle(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) {
//release该lot
HoldReleaseLotInfoForm theform = (HoldReleaseLotInfoForm) form;
long facilityRrn = LocalContext.getFacilityRrn();
String lotId = theform.getLotId();
String userId = LocalContext.getUserId();
Lot lot = lotQueryService.getLot(lotId, facilityRrn);
String fieldFlag = request.getParameter("fieldFlags");
String[] fieldFlags = fieldFlag.split(",");
//release信息
List<Map> holdReasons = wipQueryService.getHoldReasons(lot.getLotRrn());
List<Map> releaseReasons = new ArrayList<>();
for (int i = 0; i < holdReasons.size(); i++) {
if ("0".equals(fieldFlags[i])) {
releaseReasons.add(holdReasons.get(i));
}
}
HashMap releaseInfo = new HashMap();
releaseInfo.put("lotRrn", new Long(lot.getLotRrn()).toString());
releaseInfo.put("lotId", lot.getLotId());
releaseInfo.put("releaseReasons", releaseReasons);
releaseInfo.put("transPerformedBy", userId);
releaseInfo.put("transComments", theform.getLotComments());
releaseInfo.put("operation", lot.getOperationId());
TransReason transReason = new TransReason();
transReason.setReasonCode(theform.getReasonCode());
transReason.setReason(theform.getLotComments());
transReason.setTransQty1(lot.getQty1());
transReason.setTransQty2(lot.getQty2());
transReason.setResponsibility(userId);
transReason.setReason(theform.getReason());
releaseInfo.put("transReason", transReason);
releaseInfo.put("superFlag", "0");
lotService.releaseLot(releaseInfo);
FutureHoldLot fhLotInfo = wipService.getFutureHoldLotList(lot.getLotRrn(), EenActionType.POST_FUTURE_HOLD)
.get(0);
//删除futurehold表的lot信息
wipService.releaseFutureHoldLot(lot.getLotRrn(), EenActionType.POST_FUTURE_HOLD, releaseInfo);
//判断是否release掉所有hold 之后再完成跳步
List<FutureHoldLot> fhLotList = wipService.getFutureHoldLotList(lot.getLotRrn(),
EenActionType.POST_FUTURE_HOLD);
if (CollectionUtils.isEmpty(fhLotList)) {
//被bond批次跳步到debond工步 更新被bond批次信息
List<HoldDebondLot> holdDebondLot = wipService.getHoldDebondLotBySourceLotRrn(lot.getLotRrn());
Long debondToStepRrn = holdDebondLot.get(0).getDebondToStepRrn();
Map nodeMap = wipQueryService.getNodeInfoByWflTree(lot, debondToStepRrn, false);
String routeId = MapUtils.getString(nodeMap, "routeId");
lot.setRouteId(routeId);
long routeRrn = MapUtils.getLongValue(nodeMap, "routeRrn");
lot.setRouteRrn(new Long(routeRrn));
String operationId = MapUtils.getString(nodeMap, "operationId");
lot.setOperationId(operationId);
long operationRrn = MapUtils.getLongValue(nodeMap, "operationRrn");
lot.setOperationRrn(new Long(operationRrn));
String stepPath = MapUtils.getString(nodeMap, "stepInfo");
Map sourceLotMap = builDebondLot(LocalContext.getFacilityRrn(), userId, lot, stepPath);
lotService.changeLotProcess(sourceLotMap);
//删除hold_debonded_lot信息
wipService.deleteHoldDebondLotBySourceLot(lot.getLotRrn());
}
return mapping.findForward(Constants.LOTLOCATION_KEY);
}
//判断是否有母批。解除spcHold
protected void releaseSpcHold(Lot lot, List<Map> releaseReasons) {
if (lot.getLotRrn() != lot.getBasedLotRrn()) {
int countPilotLot = wipQueryService.countPilotLotInfo(lot.getLotRrn());
if (countPilotLot > 0) {
PilotLotInfo pilotLotInfo = wipQueryService.getPilotLotInfo(lot.getLotRrn());
if (StringUtils.equals(pilotLotInfo.getAutoReleaseSpcHold(), PilotContextValue.YES)) {
Lot baseLot = lotQueryService.getLot(lot.getBasedLotRrn());
List<Map> baseHoldReasons = wipQueryService.getHoldReasons(baseLot.getLotRrn());
List<Map> baseReleaseReasons = new ArrayList<>();
String childLot = "";
if (StringUtils.equalsIgnoreCase("CN", I18nUtils.getCurrentLanguage().toString())) {
childLot = "子批:";
} else {
childLot = "childLot:";
}
for (Map childHoldReasonsMap : releaseReasons) {
String childReasonCode = MapUtils.getString(childHoldReasonsMap, "reasonCode");
String childReason = MapUtils.getString(childHoldReasonsMap, "reason");
for (Map holdReasonsMap : baseHoldReasons) {
String reasonCode = MapUtils.getString(holdReasonsMap, "reasonCode");
String reason = MapUtils.getString(holdReasonsMap, "reason");
String childLotId = StringUtils.substringAfter(reason, childLot);
reason = StringUtils.substringBefore(reason, childLot);
if (StringUtils.equals(reason, childReason) &&
StringUtils.equals(reasonCode, childReasonCode) &&
StringUtils.equals(lot.getLotId(), childLotId)) {
baseReleaseReasons.add(holdReasonsMap);
}
}
}
if (baseReleaseReasons.size() > 0) {
String spcMsg = "";
if (StringUtils.equalsIgnoreCase("CN", I18nUtils.getCurrentLanguage().toString())) {
spcMsg = "先行片释放SPC HOLD,自动释放母批SPC HOLD";
} else {
spcMsg = "The SPC HOLD is released, and the parent batch SPC HOLD is " +
"automatically released.";
}
HashMap baseReleaseInfo = new HashMap();
baseReleaseInfo.put("lotRrn", new Long(baseLot.getLotRrn()).toString());
baseReleaseInfo.put("lotId", baseLot.getLotId());
baseReleaseInfo.put("releaseReasons", releaseReasons);
baseReleaseInfo.put("transPerformedBy", "SYSTEM");
baseReleaseInfo.put("transComments", spcMsg);
baseReleaseInfo.put("operation", baseLot.getOperationId());
TransReason baseTransReason = new TransReason();
baseTransReason.setReasonCode("RELEASESPCHOLD");
baseTransReason.setReason(spcMsg);
baseTransReason.setTransQty1(baseLot.getQty1());
baseTransReason.setTransQty2(baseLot.getQty2());
baseTransReason.setResponsibility("SYSTEM");
baseReleaseInfo.put("transReason", baseTransReason);
baseReleaseInfo.put("superFlag", "0");
lotService.releaseLot(baseReleaseInfo);
}
}
}
}
}
protected ActionForward dispatchLotAfterRelease(ActionMapping mapping, HttpServletRequest request,
HttpServletResponse response, String user, Long facilityRrn,
Lot lot) {
List lots = new ArrayList();
List<Lot> lockLots = new ArrayList<Lot>();
lockLots.add(lot);
lots.add(new Long(lot.getLotRrn()));
Job job = new Job();
job.setJobComments("");
job.setJobStatus(JobStatus.WAITING);
job.setTransPerformedby(user);
//批次出站暂停-点击终止后会清空eqptRrn,现在从批次历史中拿到eqptRrn
if (lot.getEqptRrn() == null || lot.getEqptRrn() == 0L) {
List lotHistory = lotQueryService.qryLotHistoryExp(lot.getLotRrn());
if (lotHistory != null && !lotHistory.isEmpty()) {
int stepSequence = 0;
long eqptRrn = 0L;
for (Iterator iterator = lotHistory.iterator(); iterator.hasNext(); ) {
HashMap object = (HashMap) iterator.next();
Collection operationList = (Collection) object.get(object.get("operationRrn"));
for (Iterator iterator2 = operationList.iterator(); iterator2.hasNext(); ) {
HashMap lotTransmap = (HashMap) iterator2.next();
int tempStepSequence = MapUtils.getIntValue(lotTransmap, "step_sequence");
long tempEqptRrn = MapUtils.getLongValue(lotTransmap, "eqpt_rrn", 0L);
if (tempStepSequence > stepSequence && tempEqptRrn > 0) {
eqptRrn = tempEqptRrn;
}
}
lot.setEqptRrn(eqptRrn);
}
}
}
job.setEqptRrn(lot.getEqptRrn());
job.setOperationRrn(lot.getOperationRrn());
// checkAndCreateLotsTransLock(LocalContext.getUserRrn(), TransactionNames.LOCK_MOVENEXT, lots,
// "dispatchLotAfterRelease in HoldReleaseLotSaveAction");
job = wipService.createJob(job, lots);
HashMap parameters = new HashMap();
parameters.put("eqptRrn", lot.getEqptRrn().toString());
parameters.put("operationRrn", lot.getOperationRrn().toString());
long wflRrn = getInstanceRrn("MOVEOUT_AFTER_RELEASE_STD", facilityRrn, ObjectList.WFL_KEY);
parameters.put("recipeRrn", job.getRecipeString());
parameters.put("jobRrn", job.getJobRrn() + "");
parameters.put("WFL_RRN", wflRrn + "");
parameters.put("RUNSTEP_FLAG", "1");
parameters.put("ROOT_WFL_EXEC_RRN", lot.getExecutionRrn().toString());
parameters.put("PARENT_WFL_EXEC_RRN", "0");
parameters.put("RUNPARENTSTEP_FLAG", "0");
parameters.put("WFL_EXEC_RRN", "0");
if (((String) parameters.get("WFL_EXEC_RRN")).equals("") ||
((String) parameters.get("WFL_EXEC_RRN")).equals("0")) {
long _workflowRrn = MiscUtils.parseSQL(new Long((String) parameters.get("WFL_RRN")));
String _multiRootInstanceRrn = (String) parameters.get("ROOT_WFL_EXEC_RRN");
long _parentInstanceRrn = MiscUtils.parseSQL(new Long((String) parameters.get("PARENT_WFL_EXEC_RRN")));
long executionRrn = -1;
executionRrn = workflowEngineService.createExecutionRrn(_workflowRrn, _multiRootInstanceRrn,
_parentInstanceRrn, null, parameters);
parameters.put("WFL_EXEC_RRN", executionRrn + "");
}
request.setAttribute("job", job);
request.setAttribute("parametersInfo", parameters);
request.removeAttribute("release4moveoutafter");
WebUtils.dispatch(request, response, mapping.findForward("workflow").getPath());
return WebUtils.NULLActionForward;
}
/**
* Release Running 处理
*/
protected ActionForward releaseRunningHandle(ActionMapping mapping, ActionForm form, HttpServletRequest request,
HttpServletResponse response) {
HoldReleaseLotInfoForm theform = (HoldReleaseLotInfoForm) form;
boolean superReleaseFlag = StringUtils.isNotEmpty((String) request.getParameter("superrelease"));
long facilityRrn = LocalContext.getFacilityRrn();
String lotId = theform.getLotId();
long userRrn = LocalContext.getUserRrn();
String userId = LocalContext.getUserId();
String[] newPasswords = request.getParameterValues("newPassword");
String fieldFlag = request.getParameter("fieldFlags");
String[] fieldFlags = fieldFlag.split(",");
// List<Lot> lockLots = new ArrayList<Lot>();
Lot lot = lotQueryService.getLot(lotId, facilityRrn);
Assert.isFalse(lot.getLotRrn() <= 0,
Errors.create().key(MessageIdList.LOT_LOTRRN_NOT_FOUND).content("Cannot Find Lot!").build());
Assert.isTrue(StringUtils.equals(lot.getLotStatus(), LotStatus.RUNNINGHOLD),
Errors.create().key(MessageIdList.LOT_STATUS_NOT_ALLOW).content("Lot status not allow").build());
List<Map> holdReasons = wipQueryService.getHoldReasons(lot.getLotRrn());
List<Map> releaseReasons = new ArrayList();
List<Map> unReleaseReasons = new ArrayList();
//是否存在trackOutHold释放
boolean trackOutHoldExisted = false;
//工步变更检查flag
boolean lotStepChanged = false;
// 是否存在Bonding绑定错误
boolean sapphireBondedError = false;
for (int i = 0; i < holdReasons.size(); i++) {
Map holdReason = holdReasons.get(i);
String reasonCode = MapUtils.getString(holdReason, "reasonCode");
if (StringUtils.equals(TransReason.reasonCode.BONDERROR.name(), reasonCode)) {
sapphireBondedError = true;
}
if (StringUtils.equals("0", fieldFlags[i])) {
if (StringUtils.contains(reasonCode, HoldCodeNames.RRCHOLD_KEY)) {
List<LotRunCard> runcardList = new ArrayList<LotRunCard>();
runcardList = cardService.getActivedLotRuncardByLot(lot.getLotRrn());
for (LotRunCard runcard : runcardList) {
Assert.isFalse(StringUtils.equals(lot.getFlowSeq(), runcard.getSplitFlowSeq()) &&
StringUtils.contains(MapUtils.getString(holdReason, "reason"),
getInstanceId(runcard.getRunCardRrn())),
Errors.create().key(MessageIdList.LOT_RELEASE_RRCHOLD_DENY)
.content("Can't release RRCHOLD").build());
}
}
// 增加ocap hold卡控
if(StringUtils.contains(reasonCode, HoldCodeNames.OCAP_HOLD)) {
Assert.state(
!wipQueryService.isValidOcapHold(lot.getLotRrn(), MapUtils.getString(holdReason, "reason")),
Errors.create().content("Unable to release OCAP Hold!").build());
String ocapId = StringUtils.substringAfter(MapUtils.getString(holdReason, "reason"), "OCAP ID: ");
OcapCard ocapCard = wipQueryService.getOcapCardByUniqueKey(LocalContext.getFacilityRrn(), ocapId, null);
if (Objects.nonNull(ocapCard) && Objects.nonNull(ocapCard.getOcapMainLotRrn()) &&
ocapCard.getOcapMainLotRrn().longValue() != lot.getLotRrn() &&
StringUtils.equals(VersionStatus.ACTIVE_KEY, ocapCard.getStatus())) {
Lot mainLot = lotInqService.getLot(ocapCard.getOcapMainLotRrn());
EdcLotContextValue dto = ctxExecService.getEdcLotContextValue(mainLot, null, ActionPointList.MOVEOUT_KEY);
Long parameterSetRrn = 0L;
if (dto != null && dto.getParameterSetRrn() > 0) {
parameterSetRrn = dto.getParameterSetRrn();
}
dto = ctxExecService.getEdcLotContextValue(lot, null, ActionPointList.MOVEOUT_KEY);
Assert.state(dto == null || dto.getParameterSetRrn().longValue() <= 0 ||
dto.getParameterSetRrn().longValue() != parameterSetRrn.longValue(),
Errors.create().content("need operator ocap main lot:{}").args(mainLot.getLotId()).build());
}
}
if (StringUtils.equals("TRACKOUTHOLD", MapUtils.getString(holdReason, "reasonCategory"))) {
trackOutHoldExisted = true;
}
String holdPassword =
holdReason.get("holdPassword") != null ? ((String) holdReason.get("holdPassword")).trim() : "";
String newPassword = newPasswords[i] != null ? newPasswords[i].trim() : "";
Assert.isTrue(StringUtils.equals(holdPassword, newPassword),
Errors.create().content("Invalid Release Password!").build());
releaseReasons.add(holdReason);
} else {
unReleaseReasons.add(holdReason);
}
}
Assert.isFalse(releaseReasons.size() <= 0,
Errors.create().key(MessageIdList.LOT_RELEASE_HOLD_EMPTY).content("please select release hold!")
.build());
Assert.isFalse(trackOutHoldExisted && unReleaseReasons.size() > 0,
Errors.create().key(MessageIdList.LOT_TRACKOUT_HOLD_CANNOT_RELEASE)
.content("Before Trackout hold released, Please release other hold first!").build());
if (trackOutHoldExisted) {
lotStepChanged = lotService.checkLotStepChange(lot.getLotRrn());
}
TransReason transReason = new TransReason();
transReason.setReasonCode(theform.getReasonCode());
transReason.setReason(theform.getLotComments());
transReason.setResponsibility(userId);
transReason.setReason(theform.getReason());
String holdCode = StringUtils.EMPTY;
if (releaseReasons.size() == 1) {
holdCode = MapUtils.getString(releaseReasons.get(0), "reasonCode") + StringUtils.COMMA_SIGN;
} else {
for (Map<String, String> releaseReason: releaseReasons) {
holdCode += MapUtils.getString(releaseReason, "reasonCode") + StringUtils.COMMA_SIGN;
}
}
StringBuilder stringBuilder = new StringBuilder(
theform.getReasonGroup() + ",Release Code: " + theform.getReasonCode() + ",Hold Code: " + holdCode +
"Reason: " + theform.getReason());
transReason.setReason(stringBuilder.toString());
List<LotReleaseInfoDto> releaseInfoDtoList = new ArrayList<>();
releaseInfoDtoList.add(buildLotReleaseInfoList(lot, releaseReasons, theform.getLotComments(), transReason));
if (CollectionUtils.isEmpty(unReleaseReasons)) {
List<BatchLotStore> batchLotStoreList = diffBatchQueryService.getBatchStoreListByLot(lot.getLotRrn());
for (BatchLotStore batchLotStore : batchLotStoreList) {
if (lot.getLotRrn() == batchLotStore.getLotRrn().longValue()) {
continue;
}
Lot batchLot = lotQueryService.getLot(batchLotStore.getLotRrn());
List<Map> batchReleaseReasonList = wipQueryService.getHoldReasons(batchLot.getLotRrn());
LotReleaseInfoDto releaseInfoDto = buildLotReleaseInfoList(batchLot, batchReleaseReasonList,
theform.getLotComments(), transReason);
releaseInfoDtoList.add(releaseInfoDto);
}
}
List<String> lotRrns = new ArrayList<>();
for (LotReleaseInfoDto releaseInfoDto : releaseInfoDtoList) {
lotRrns.add(StringUtils.toString(releaseInfoDto.getLot().getLotRrn()));
}
lotService.releaseRunningLot(releaseInfoDtoList, lotRrns);
//清除派工页面缓存
Collection availableEquipmentInfos = buildAvailableEquipInfosForLot(lot, userRrn);
for (Object temp : availableEquipmentInfos) {
Map equipmentInfo = (Map) temp;
CacheUtils.remove(MapUtils.getString(equipmentInfo, "equipmentRrn"));
}
//TODO CacheHelper相关更新
recoveryRunCardService.doStartRecoveryRunCard(LocalContext.getUserId(), lot);
return mapping.findForward(Constants.LOTLOCATION_KEY);
}
protected void checkRCHoldCode(String holdCode) {
Assert.isFalse(StringUtils.contains(holdCode, HoldCodeNames.SRCHOLD_KEY),
Errors.create().content("Hold Code can not contains '{}'").args(HoldCodeNames.SRCHOLD_KEY)
.build());
Assert.isFalse(StringUtils.contains(holdCode, HoldCodeNames.RRCHOLD_KEY),
Errors.create().content("Hold Code can not contains '{}'").args(HoldCodeNames.RRCHOLD_KEY)
.build());
}
protected List<Map<String, Object>> getWflPathoperation(Lot lot) throws Exception {
Integer routeVersion = lot.getRouteVersion();
WorkflowStepModel stepModel = new WorkflowStepModel(lot.getRouteRrn(), routeVersion);
stepModel.setStepId(lot.getOperationId());
return prpService.getWflPath(stepModel.getWflRrn(), stepModel.getWflVersion(), stepModel.getStepId());
}
protected List<Map<String, Object>> getWflPathRoute(Lot lot) {
long workflowRrn = getInstanceRrn(lot.getProcessId(), lot.getFacilityRrn(), ObjectList.WFL_KEY);
int workflowVersion = baseService.getActiveVersion(workflowRrn, true);
WorkflowStepModel stepModel = new WorkflowStepModel(workflowRrn, workflowVersion);
stepModel.setStepId(lot.getRouteId());
return prpService.getWflPath(stepModel.getWflRrn(), stepModel.getWflVersion(), stepModel.getStepId());
}
protected String buildReticlesString(Long reticleFamilyRrn) {
StringBuilder rectileInfo = new StringBuilder();
List<Relation> rectiles = reticleService.getReticles(reticleFamilyRrn);
for (Relation relation : rectiles) {
rectileInfo.append(relation.getInstanceId()).append(" ");
}
return rectileInfo.toString();
}
protected ActionForward showRunningHoldInfoDetail(ActionMapping mapping, HttpServletRequest request, long jobRrn) {
List holdInfos = new ArrayList<>();
List<Map> joblots = wipQueryService.getJobList(jobRrn, ObjectList.JOB_KEY);
for (Map lotMap : joblots) {
if (StringUtils.equalsIgnoreCase(lotQueryService.getLotStatus(MapUtils.getLongValue(lotMap, "lotRrn")),
LotStatus.RUNNINGHOLD)) {
holdInfos.addAll(wipQueryService.getHoldReasons(MapUtils.getLongValue(lotMap, "lotRrn")));
}
}
request.setAttribute("holdInfo", holdInfos);
request.setAttribute(SessionNames.COLLECTION_KEY, joblots);
return mapping.findForward("runningHold");
}
protected List<Map> rePositionUnitList(List<Map> unitList) {
List<Map> newUnits = new ArrayList<Map>(unitList);
Collections.sort(newUnits, new Comparator<Map>() {
@Override
public int compare(Map map1, Map map2) {
int position1 = MapUtils.getIntValue(map1, "position");
int position2 = MapUtils.getIntValue(map2, "position");
if (position1 > position2) {
return 1;
} else if (position1 < position2) {
return -1;
} else {
return 0;
}
}
});
Iterator it = newUnits.iterator();
Map unit = new HashMap();
int number = 1;
int seq = 1;
List<Map> units = new ArrayList<Map>();
while (it.hasNext()) {
Map<String, Object> unitMap = null;
unit = (HashMap) it.next();
seq = MapUtils.getIntValue(unit, "position");
while ((number < seq)) {
unitMap = new HashMap();
unitMap.put("position", number + "");
unitMap.put("unitId", "");
units.add(unitMap);
number++;
}
unit.put("position", number + "");
units.add(unit);
number++;
}
int listSize = units.size();
for (int i = listSize + 1; i <= 25; i++) {
Map<String, Object> unitMap = new HashMap();
unitMap.put("position", i + "");
unitMap.put("unitId", "");
units.add(unitMap);
}
return units;
}
protected void checkPostFutureHold(long lotRrn) {
boolean postFutureHold = false;
List<FutureHoldLot> futureHoldLotList = wipService.getFutureHoldLotList(lotRrn, EenActionType.POST_FUTURE_HOLD);
if (CollectionUtils.isNotEmpty(futureHoldLotList)) {
postFutureHold = true;
}
Assert.isFalse(postFutureHold,
Errors.create().key(MessageIdList.LOTS_STATUS_POST_FUTURE_HOLD).content("Lot status not allow")
.build());
}
/**
* 未执行的任务 检查源晶舟和目标晶舟是否存在未执行的Sort任务
*/
protected void checkWaitJobs(long sourceCarrierRrn, long targetCarrierRrn, Long targetCarrierRrn2,
TransformFunc error) {
Assert.isFalse(sorterQueryService.haveWaitJobForCarrier(sourceCarrierRrn),
error != null ? error : Errors.create().key(MessageIdList.SOURCE_CARRIER_BE_OCCUPIED).build());
if (targetCarrierRrn > 0) {
Assert.isFalse(sorterQueryService.haveWaitJobForCarrier(targetCarrierRrn),
error != null ? error : Errors.create().key(MessageIdList.TARGET_CARRIER_BE_OCCUPIED)
.build());
}
if (targetCarrierRrn2 != null && targetCarrierRrn2 > 0) {
Assert.isFalse(sorterQueryService.haveWaitJobForCarrier(targetCarrierRrn2),
error != null ? error : Errors.create().key(MessageIdList.TARGET_CARRIER_BE_OCCUPIED)
.build());
}
}
protected Map builDebondLot(Long facilityRrn, String userId, Lot lot, String stepPath) {
Map tempInfo = new HashMap();
Map changeProcessInfo = new HashMap();
changeProcessInfo.put("lotRrn", new Long(lot.getLotRrn()));
changeProcessInfo.put("lotId", lot.getLotId());
changeProcessInfo.put("lotStatus", lot.getLotStatus());
changeProcessInfo.put("qty", "" + lot.getQty1());
changeProcessInfo.put("lotOwner", lot.getLotOwner());
changeProcessInfo.put("currOperation", lot.getOperationId());
changeProcessInfo.put("transPerformedBy", userId);
changeProcessInfo.put("productRrn", new Long(
getInstanceRrn(lot.getProductId(), getNamedSpace(ObjectList.PRODUCT_KEY, facilityRrn),
ObjectList.PRODUCT_KEY)));
changeProcessInfo.put("productId", lot.getProductId());
changeProcessInfo.put("processRrn", lot.getProcessRrn());
Lot _lot = new Lot();
_lot.setProductRrn(MapUtils.getLong(changeProcessInfo, "productRrn"));
tempInfo = getStepsInfoByLot(_lot, lot.getProcessRrn(), stepPath);
changeProcessInfo.put("stageId", tempInfo.get("stageId"));
changeProcessInfo.put("layerId", tempInfo.get("layerId"));
changeProcessInfo.put("executionRrn", tempInfo.get("executionRrn"));
changeProcessInfo.put("operationRrn", tempInfo.get("operationRrn"));
Long operationRrn = (Long) tempInfo.get("operationRrn");
changeProcessInfo.put("operationId", getInstanceId(((Long) tempInfo.get("operationRrn")).longValue()));
changeProcessInfo.put("operationVer", tempInfo.get("operationVer"));
changeProcessInfo.put("processStepVersion", tempInfo.get("processStepVersion"));
changeProcessInfo.put("processVersion", tempInfo.get("processVersion"));
changeProcessInfo.put("processStepIdVersion", tempInfo.get("processStepIdVersion"));
changeProcessInfo.put("processStepVersion4wfl", tempInfo.get("processStepVersion4wfl"));
changeProcessInfo.put("nextoperationRrn1", tempInfo.get("nextoperationRrn1"));
changeProcessInfo.put("nextoperationRrn2", tempInfo.get("nextoperationRrn2"));
changeProcessInfo.put("nextprocessStepVersion1", tempInfo.get("nextprocessStepVersion1"));
changeProcessInfo.put("nextprocessStepIdVersion1", tempInfo.get("nextprocessStepIdVersion1"));
changeProcessInfo.put("nextprocessStepVersion2", tempInfo.get("nextprocessStepVersion2"));
changeProcessInfo.put("nextprocessStepIdVersion2", tempInfo.get("nextprocessStepIdVersion2"));
String temp = (String) tempInfo.get("processStepVersion");
String route = "";
if (temp != null) {
int i = 0;
int j = 0;
i = temp.indexOf("|");
// find first '|'
if (i != -1) {
j = temp.indexOf("|", i + 1);
// find se '|'
// string is aaa|bbb|cccc
if (j > 0) {
route = temp.substring(i + 1, j);
} else if (i > 0) { // aaa|bbb
route = temp.substring(0, i);
}
}
}
route = route.replace(',', '.');
changeProcessInfo.put("route", route);
tempInfo = prpService.getOperationInfo((Long) tempInfo.get("operationRrn"),
(Integer) tempInfo.get("operationVer"));
changeProcessInfo.put("trackUnitFlag", tempInfo.get("trackUnitFlag"));
changeProcessInfo.put("keepUnitHistoryFlag", tempInfo.get("keepUnitHistoryFlag"));
// get Context info
tempInfo = new HashMap();
tempInfo.put("productRrn", changeProcessInfo.get("productRrn"));
// tempInfo.put("routeId", null);
tempInfo.put("routeRrn", WipUtils.parseRouteRrn((String) changeProcessInfo.get("processStepVersion")) + "");
tempInfo.put("recipeRrn", null);
tempInfo.put("operationRrn", changeProcessInfo.get("operationRrn"));
tempInfo.put("technologyRrn", changeProcessInfo.get("processRrn"));
tempInfo.put("lotRrn", changeProcessInfo.get("lotRrn"));
Map resultInfo = ctxExecService.getBorbyContext(tempInfo);
changeProcessInfo.put("borRrn", resultInfo.get("borRrn"));
changeProcessInfo.put("reticleRrn", tempInfo.get("reticleRrn")); // to do
changeProcessInfo.put("transPerformedBy", userId);
changeProcessInfo.put("transComments", "");
changeProcessInfo.put("sourceLot", lot);
changeProcessInfo.put("facilityRrn", facilityRrn);
return changeProcessInfo;
}
/**
* Check flip for lot and flow
*
* @param lot 批次
* @param psi 流程上的情境值
*/
protected void checkFlip4LotAndFlow(Lot lot, ProcessSpecItemDto psi) {
String flipType = Objects.isNull(psi) ? StringUtils.EMPTY : psi.getFlipType();
// A 可以跳A,A to B, A to B 可以跳 A
boolean state = StringUtils.equalsIgnoreCase(lot.getFlipType(), flipType) ||
StringUtils.startsWith(flipType, lot.getFlipType()) ||
StringUtils.startsWith(lot.getFlipType(), flipType);
Assert.state(state, Errors.create().key(MessageIdList.LOT_FLOW_NOT_SAME).content(
"Flip attribute {} of Lot {} is inconsistent with Flip attribute {} of " +
"corresponding work step on target Flow!").args(lot.getFlipType(),
lot.getLotId(),
flipType)
.build());
}
protected Boolean checkLotIsDummyFlagLot(Long lotRrn) {
return lotAutoMonitorInqService.checkLotIsAutoMonitorLot(lotRrn) ||
lotRunCardQueryService.checkLotInRunCard(lotRrn);
}
protected SorterModel checkSorterModelAndCreateInLineSorterJob(Lot lot, Equipment equipment){
return sorterExecInqService.checkSorterModelAndCreateInLineSorterJob(lot,
equipment.getInstanceId(), null);
}
protected void endSortJob(SortJobBean sortJobBean){
sorterService.endSortJob(sortJobBean);
}
protected SortJobBean getSortJobListByCarrierRrn(Lot lot){
return sorterQueryService.getSortJobListByCarrierRrn(lot.getCarrierRrn());
}
protected void checkCstRemoved(Set<Long> lotRrns){
lotService.checkCstRemoved(lotRrns);
}
}