ReticleQueryManagerImpl.java
package com.mycim.server.wip.manager.impl;
import com.fa.sesa.threadlocal.LocalContext;
import com.mycim.framework.utils.lang.StringUtils;
import com.mycim.framework.utils.lang.collections.CollectionUtils;
import com.mycim.server.ctx.exec.manager.ReticleFamilyContextManager;
import com.mycim.server.ems.manager.EntityManager;
import com.mycim.server.wip.dao.ReticleQueryDAO;
import com.mycim.server.wip.manager.LotQueryManager;
import com.mycim.server.wip.manager.ReticleQueryManager;
import com.mycim.valueobject.bas.Relation;
import com.mycim.valueobject.consts.EntityEnum;
import com.mycim.valueobject.ems.Entity;
import com.mycim.valueobject.wip.Lot;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.*;
/**
* @author Johnson.Wang
* @version 6.0.0
* @date 2019/9/23
**/
@Service
@Transactional
public class ReticleQueryManagerImpl implements ReticleQueryManager {
@Autowired
private ReticleFamilyContextManager reticleFamilyContextManager;
@Autowired
private ReticleQueryDAO reticleQueryDAO;
@Autowired
private EntityManager entityManager;
@Autowired
private LotQueryManager lotQueryManager;
/**
* Get reticles that has already entered equipment (equipment track in)
*
* @param lot
* @param equipmentRrn
* @return
*/
@Override
public List<Relation> getReticlesThatHasAlreadyEnteredEquipment(Lot lot, Long equipmentRrn) {
return getReticleInfosForMovein(lot, equipmentRrn, false);
}
/**
* Get reticles by relationship with the reticle family
*
* @param reticleFamilyRrn if it is not {@code null}, already entered the equipment
* @param statusFLag if it is {@code true}, the reticle's entity status must be IDLE or RELEASE or RUN
* @return {@code Relation} object has value: ["instanceRrn", "instanceId", "instanceDesc", "fromRrn",
* "toRrn"]
*/
@Override
public List<Relation> getReticlesForMovein(Long reticleFamilyRrn, Long entityRrn, Boolean statusFLag) {
return reticleQueryDAO.getReticlesForMovein(reticleFamilyRrn, entityRrn, statusFLag);
}
/**
* Get reticles that has already entered equipment (equipment track in), it is available entity status and
* does not exceed the maximum usage times
*
* @param lot
* @param equipmentRrn
* @return
*/
@Override
public List<Relation> getAvailableReticlesForTrackIn(Lot lot, Long equipmentRrn) {
List<Relation> reticleInfos = getReticleInfosForMovein(lot, equipmentRrn, true);
for (Iterator<Relation> iterator = reticleInfos.iterator(); iterator.hasNext(); ) {
Relation relation = iterator.next();
Entity reticleEntity = entityManager.getEntity(relation.getInstanceRrn());
if (isNeedCheckUseTimes(reticleEntity.getPDFlag())) {
Integer inuseWaferQty = lotQueryManager.getInuseWaferQtyForReticle(relation.getInstanceRrn());
if (isOutMaxTimesOfUse(reticleEntity.getMaxUseTimes(), reticleEntity.getCurrentUseTimes(),
inuseWaferQty, lot.getQty1())) {
iterator.remove();
}
}
}
return reticleInfos;
}
@Override
public String getReticleIdsThatHasAlreadyEnteredEquipmentStr(Lot lot, Long equipmentRrn, Boolean isNeedFilter) {
List<Relation> reticles = getReticlesThatHasAlreadyEnteredEquipment(lot, equipmentRrn);
if (isNeedFilter) {
reticles = filterSpecialStatus(reticles);
}
return buildReticleIdsStr(reticles);
}
@Override
public String getAvailableReticleIdsStr(Lot lot, Long equipmentRrn) {
return buildReticleIdsStr(getAvailableReticlesForTrackIn(lot, equipmentRrn));
}
@Override
public String getAvailableReticleIdsStr(Long reticleFamilyRrn, Long equipmentRrn, Boolean statusFlag) {
return buildReticleIdsStr(getReticlesForMovein(reticleFamilyRrn, equipmentRrn, statusFlag));
}
@Override
public long getReticleFamilyRrnByLot(Lot lot) {
return reticleFamilyContextManager
.getReticleFamilyRrn(lot.getProductRrn(), lot.getProductVersion(), lot.getProcessRrn(),
lot.getProcessVersion(), lot.getRouteRrn(), lot.getOperationRrn());
}
public Boolean isOutMaxTimesOfUse(Integer maxUseTimes, Integer currentUseTimes, Integer inuseWaferQty,
Double lotQty) {
return maxUseTimes < currentUseTimes + inuseWaferQty + lotQty;
}
public Boolean isNeedCheckUseTimes(String pdFlag) {
return EntityEnum.isPDFlagT(pdFlag);
}
private String buildReticleIdsStr(List<Relation> reticles) {
if (CollectionUtils.isEmpty(reticles)) {
return StringUtils.EMPTY;
}
StringBuilder reticleIds = new StringBuilder();
for (Relation relation : reticles) {
if (reticleIds.length() > 0) {
reticleIds.append(",").append(relation.getInstanceId());
} else {
reticleIds.append(relation.getInstanceId());
}
}
return reticleIds.toString();
}
private List<Relation> filterSpecialStatus(List<Relation> reticles) {
Iterator<Relation> iterator = reticles.iterator();
while (iterator.hasNext()) {
Relation relation = iterator.next();
String reticleStatus = entityManager.getEntityCurrentStatus(relation.getInstanceRrn());
if (!EntityEnum.isRelease(reticleStatus)) {
iterator.remove();
}
}
return reticles;
}
private List<Relation> getReticleInfosForMovein(Lot lot, Long equipmentRrn, Boolean statusFLag) {
long reticleFamilyRrn = getReticleFamilyRrnByLot(lot);
if (reticleFamilyRrn > 0) {
return getReticlesForMovein(reticleFamilyRrn, equipmentRrn, statusFLag);
}
return Collections.emptyList();
}
private Map<String, Object> buildProcessInfoForContext(Lot lot) {
Map<String, Object> processInfo = new HashMap<>();
processInfo.put("facilityRrn", LocalContext.getFacilityRrn());
processInfo.put("productRrn", lot.getProductRrn());
processInfo.put("processRrn", lot.getProcessRrn());
processInfo.put("routeRrn", lot.getRouteRrn());
processInfo.put("operationRrn", lot.getOperationRrn());
processInfo.put("routeSeq", lot.getRouteSeq());
processInfo.put("operationSeq", lot.getOperationSeq());
processInfo.put("processVersion", lot.getProcessVersion());
return processInfo;
}
}