PcdManagerImpl.java
package com.mycim.server.carrier.manager.impl;
import com.fa.sesa.exception.Assert;
import com.fa.sesa.exception.Errors;
import com.fa.sesa.i18n.I18nUtils;
import com.fa.sesa.threadlocal.LocalContext;
import com.mycim.framework.utils.lang.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.server.base.manager.EventManager;
import com.mycim.server.base.manager.NamedObjectManager;
import com.mycim.server.base.manager.TransactionLogManager;
import com.mycim.server.carrier.dao.DoorDAO;
import com.mycim.server.carrier.dao.PcdDAO;
import com.mycim.server.carrier.dao.PodDAO;
import com.mycim.server.carrier.manager.CarrierManager;
import com.mycim.server.carrier.manager.DoorManager;
import com.mycim.server.carrier.manager.PcdManager;
import com.mycim.server.carrier.manager.PodManager;
import com.mycim.server.ems.manager.EntityManager;
import com.mycim.server.status.manager.StatusManager;
import com.mycim.server.system.manager.ReferenceFileManager;
import com.mycim.utils.WipUtils;
import com.mycim.valueobject.Constants;
import com.mycim.valueobject.MessageIdList;
import com.mycim.valueobject.ObjectList;
import com.mycim.valueobject.bas.NamedObject;
import com.mycim.valueobject.bas.TransactionLog;
import com.mycim.valueobject.consts.EventName;
import com.mycim.valueobject.consts.PcdStatus;
import com.mycim.valueobject.consts.ReferenceDetailNames;
import com.mycim.valueobject.consts.TransactionNames;
import com.mycim.valueobject.ems.*;
import com.mycim.valueobject.sys.ReferenceFileDetail;
import com.mycim.valueobject.wip.Lot;
import com.mycim.valueobject.wip.TransReason;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.sql.Timestamp;
import java.text.DecimalFormat;
import java.util.*;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.regex.Matcher;
import java.util.stream.Collectors;
/**
* @author yanbing.chen
* @date 2019/10/10
* @since 1.8
**/
@Service
@Transactional
public class PcdManagerImpl implements PcdManager {
private final static String PCD_CLEAN_EQPT_REFERENCE_ID = "$PCD_CLEAN_EQPT";
@Autowired
PcdDAO pcdDAO;
@Autowired
PodDAO podDAO;
@Autowired
DoorDAO doorDAO;
@Autowired
NamedObjectManager namedObjectManager;
@Autowired
ReferenceFileManager referenceFileManager;
@Autowired
TransactionLogManager transactionLogManager;
@Autowired
CarrierManager carrierManager;
@Autowired
PodManager podManager;
@Autowired
DoorManager doorManager;
@Autowired
EventManager eventManager;
@Autowired
EntityManager entityManager;
@Autowired
StatusManager statusManager;
@Override
public PcdAssembly getPcdAssembly(Long carrierRrn, Long podRrn, Long doorRrn) {
return pcdDAO.getPcdAssembly(carrierRrn, podRrn, doorRrn);
}
@Override
public boolean isPcdCleaningTimeIsLessThan3Days(Long pcdRrn) {
if (pcdRrn == null || pcdRrn <= 0) {
return false;
}
PcdClean pcdCleanInfo = pcdDAO.getPcdCleanInfo(pcdRrn);
if (pcdCleanInfo != null && pcdCleanInfo.getInstanceRrn() > 0) {
if (this.isCleanValidPcd(pcdCleanInfo.getCleanOverDate())) {
// 过期时间三天前的时间(毫秒数)
long time = DateUtils.addTimeByUnit(pcdCleanInfo.getCleanOverDate().getTime(), "D", -3);
if (this.isCleanValidPcd(new Timestamp(time))) {
return false;
}
}
}
return true;
}
@Override
public boolean isCleanValidPcd(Timestamp cleanOverDate) {
if (cleanOverDate != null) {
if (DateUtils.compareDateWithNow(cleanOverDate) >= 1) {
return true;
}
}
return false;
}
@Override
public PcdClean getPcdCleanInfo(Long pcdRrn) {
if (pcdRrn != null && pcdRrn > 0) {
PcdClean pcdCleanInfo = pcdDAO.getPcdCleanInfo(pcdRrn);
if (pcdCleanInfo != null && pcdCleanInfo.getInstanceRrn() > 0) {
return pcdCleanInfo;
}
}
return null;
}
@Override
public Map<String, Object> checkPcdChangeStatusButton(Long facilityRrn, Long pcdRrn, String currentStatus) {
Map<String, Object> btnMap = new HashMap();
// WAIT_CLEAN状态下,如果前一个状态是ASSEMBLY状态,允许To Free按钮使用,以解绑PCD
String preStatus = StringUtils.EMPTY;
PcdAssembly assembly = null;
preStatus = entityManager.getPreStatusByEntityRrn(pcdRrn);
assembly = getPcdAssembly(pcdRrn, null, null);
if (assembly == null || StringUtils.isBlank(assembly.getCarrierId())) {
assembly = getPcdAssembly(null, pcdRrn, null);
if (assembly == null || StringUtils.isBlank(assembly.getCarrierId())) {
assembly = getPcdAssembly(null, null, pcdRrn);
}
}
if (StringUtils.isNotBlank(preStatus)) {
if (StringUtils.equals(currentStatus, PcdStatus.WAIT_CLEAN_KEY) &&
StringUtils.equals(preStatus, PcdStatus.ASSEMBLY_KEY)) {
btnMap.put("toFreeBtn", true);
} else {
btnMap.put("toFreeBtn", isPcdChangeStatus(facilityRrn, pcdRrn, currentStatus, PcdStatus.FREE_KEY));
}
} else {
if (StringUtils.equals(currentStatus, PcdStatus.WAIT_CLEAN_KEY) && assembly != null &&
StringUtils.isNotBlank(assembly.getCarrierId())) {
btnMap.put("toFreeBtn", true);
} else {
btnMap.put("toFreeBtn", isPcdChangeStatus(facilityRrn, pcdRrn, currentStatus, PcdStatus.FREE_KEY));
}
}
btnMap.put("toInDamageBtn", isPcdChangeStatus(facilityRrn, pcdRrn, currentStatus, PcdStatus.IN_DAMAGE_KEY));
btnMap.put("toScrapBtn", isPcdChangeStatus(facilityRrn, pcdRrn, currentStatus, PcdStatus.SCRAP_KEY));
btnMap.put("toWatiCleanBtn", isPcdChangeStatus(facilityRrn, pcdRrn, currentStatus, PcdStatus.WAIT_CLEAN_KEY));
btnMap.put("toInCleanBtn", isPcdChangeStatus(facilityRrn, pcdRrn, currentStatus, PcdStatus.IN_CLEAN_KEY));
btnMap.put("toWaitCheckBtn", isPcdChangeStatus(facilityRrn, pcdRrn, currentStatus, PcdStatus.WAIT_CHECK_KEY));
btnMap.put("toHoldBtn", isPcdChangeStatus(facilityRrn, pcdRrn, currentStatus, PcdStatus.HOLD_KEY));
btnMap.put("toStartCleanBtn", isPcdChangeStatus(facilityRrn, pcdRrn, currentStatus, PcdStatus.IN_CLEAN_KEY));
btnMap.put("toEndCleanBtn", isPcdChangeStatus(facilityRrn, pcdRrn, currentStatus, PcdStatus.FREE_KEY));
return btnMap;
}
@Override
public boolean isPcdChangeStatus(Long facilityRrn, Long pcdRrn, String currentStatus, String tragetStatus) {
String autoChangeStatusRefId = "$$AUTO_CHANGE_STATUS";
String refNamedSpace = namedObjectManager.getNamedSpace(facilityRrn, ObjectList.REFERENCE_FILE_KEY);
// 获取设置的只有系统能自动执行的事件模型
List<ReferenceFileDetail> refColl = referenceFileManager.getRefFileValues(autoChangeStatusRefId, refNamedSpace);
List<Map> eventInfoList = eventManager.getEventInfoList(facilityRrn, pcdRrn, currentStatus, tragetStatus);
if (CollectionUtils.isNotEmpty(eventInfoList)) {
Map<String, Object> eventMap = eventInfoList.get(0);
if (CollectionUtils.isNotEmpty(refColl)) {
for (ReferenceFileDetail de : refColl) {
if (StringUtils.isNotBlank(de.getData2Value())) {
// 如果有相同的,则代表是只有系统自动使用的,用户不可以手动修改
if (StringUtils.equals(de.getKey1Value(), MapUtils.getString(eventMap, "eventId"))) {
return false;
}
}
}
}
return true;
} else {
return false;
}
}
@Override
public Map getPcdDefaultCleanCycleInfo(String category, String type) {
return pcdDAO.getPcdDefaultCleanCycleInfo(category, type);
}
@Override
public void deletePcdCleanInfo(Long pcdRrn, Long transRrn) {
if (pcdRrn != null && pcdRrn > 0) {
PcdClean cleanInfo = pcdDAO.getPcdCleanInfo(pcdRrn);
pcdDAO.deletePcdCleanInfo(pcdRrn);
pcdDAO.insertPcdCleanH(transRrn, cleanInfo);
}
}
@Override
public int insertPcdCleanH(Long transRrn, PcdClean cleanInfo) {
return pcdDAO.insertPcdCleanH(transRrn, cleanInfo);
}
@Override
public void insertPcdNamedObjectExt(Long pcdRrn, String flagType, String dmm_type) {
pcdDAO.insertPcdNamedObjectExt(pcdRrn, flagType, dmm_type);
}
@Override
public void updatePcdNamedObjectExt(Long pcdRrn, String flagType) {
pcdDAO.updatePcdNamedObjectExt(pcdRrn, flagType);
}
@Override
public void addPcdCleanInfo(Long pcdRrn, Long transRrn, Long facilityRrn, String pcdType, double cleanCycle) {
if (pcdRrn != null && pcdRrn > 0) {
PcdClean cleanInfo = new PcdClean();
cleanInfo.setInstanceRrn(pcdRrn);
cleanInfo.setCleanCycle(cleanCycle);
cleanInfo.setPcdType(pcdType);
long currentTime = System.currentTimeMillis();
long cleanOverTime = (long) (currentTime + (cleanCycle * 24 * 60 * 60 * 1000));
cleanInfo.setCleanOverDate(new Timestamp(cleanOverTime));
cleanInfo.setCleanCount(0);
pcdDAO.insertPcdCleanInfo(cleanInfo);
pcdDAO.insertPcdCleanH(transRrn, cleanInfo);
}
}
@Override
public int countPcdCategoryByRrn(Long pcdRrn) {
return pcdDAO.countPcdCategoryByRrn(pcdRrn);
}
@Override
public void updatePcdCleanInfo(Long transRrn, PcdClean updateCleanInfo) {
if (updateCleanInfo != null && updateCleanInfo.getInstanceRrn() > 0) {
PcdClean existCleanInfo = getPcdCleanInfo(updateCleanInfo.getInstanceRrn());
if (existCleanInfo != null && existCleanInfo.getInstanceRrn() > 0) {
if (updateCleanInfo.getCleanCycle() > 0) {
existCleanInfo.setCleanCycle(updateCleanInfo.getCleanCycle());
// 如果需要更新清洗周期,则需要重新计算清洗有效截止时间
long cleanOverTime = 0;
if (existCleanInfo.getOutCleanDate() != null && existCleanInfo.getOutCleanDate().getTime() > 0) {
cleanOverTime = (long) (existCleanInfo.getOutCleanDate().getTime() +
(updateCleanInfo.getCleanCycle() * 24 * 60 * 60 * 1000));
} else {
// 没有清洗记录,使用创建时间计算
long currentTime = 0;
if (StringUtils.equalsIgnoreCase(existCleanInfo.getPcdType(), ObjectList.CARRIER_KEY)) {
Map<String, Object> carrierMap = carrierManager
.qryCarrierInfoDetailById(updateCleanInfo.getInstanceId(),
updateCleanInfo.getNamedSpace());
currentTime = DateUtils.parse(MapUtils.getString(carrierMap, "carrierCreateTime"),
DateUtils.DATE_FORMAT4DATE).getTime();
} else if (StringUtils.equalsIgnoreCase(existCleanInfo.getPcdType(), ObjectList.POD_KEY)) {
Map<String, Object> podMap = podManager
.qryPodInfoDetailById(updateCleanInfo.getInstanceId(),
updateCleanInfo.getNamedSpace());
currentTime = DateUtils
.parse(MapUtils.getString(podMap, "podCreateTime"), DateUtils.DATE_FORMAT4DATE)
.getTime();
} else if (StringUtils.equalsIgnoreCase(existCleanInfo.getPcdType(), ObjectList.DOOR_KEY)) {
Map<String, Object> doorMap = doorManager
.qrysDoorInfoDetailById(updateCleanInfo.getInstanceId(),
updateCleanInfo.getNamedSpace());
currentTime = DateUtils
.parse(MapUtils.getString(doorMap, "doorCreateTime"), DateUtils.DATE_FORMAT4DATE)
.getTime();
}
cleanOverTime = (long) (currentTime + (updateCleanInfo.getCleanCycle() * 24 * 60 * 60 * 1000));
}
updateCleanInfo.setCleanOverDate(new Timestamp(cleanOverTime));
existCleanInfo.setCleanOverDate(new Timestamp(cleanOverTime));
}
if (updateCleanInfo.getInCleanDate() != null) {
existCleanInfo.setInCleanDate(updateCleanInfo.getInCleanDate());
}
if (updateCleanInfo.getOutCleanDate() != null) {
existCleanInfo.setOutCleanDate(updateCleanInfo.getOutCleanDate());
} else {
updateCleanInfo.setOutCleanDate(existCleanInfo.getOutCleanDate());
}
if (StringUtils.isNotBlank(updateCleanInfo.getPcdType())) {
existCleanInfo.setPcdType(updateCleanInfo.getPcdType());
}
updateCleanInfo.setCleanCount(existCleanInfo.getCleanCount());
pcdDAO.updatePcdCleanInfo(updateCleanInfo);
pcdDAO.insertPcdCleanH(transRrn, existCleanInfo);
}
}
}
@Override
public void inCleanPcd(String cleanEqptId, Long pcdRrn, String performedBy, Long facilityRrn) {
cleanPcd(cleanEqptId, pcdRrn, performedBy, "in");
}
@Override
public void outCleanPcd(Long pcdRrn, String performedBy, Long facilityRrn) {
cleanPcd(StringUtils.EMPTY, pcdRrn, performedBy, "out");
}
@Override
public PcdAssembly getPcdAssembly(Long carrierRrn) {
return pcdDAO.getPcdAssembly(carrierRrn);
}
@Override
public void deAssemblyPcd(Long carrierRrn, String user, Long transRrn) {
TransactionLog transactionLog = null;
if (transRrn == null || transRrn <= 0) {
transactionLog = transactionLogManager.startTransactionLog(user, TransactionNames.CST_DEASSEMBLY);
transRrn = transactionLog.getTransRrn();
}
pcdDAO.insertPcdAssemblyH(carrierRrn, user, transRrn);
pcdDAO.deletePcdAssembly(carrierRrn);
if (transactionLog != null) {
transactionLogManager.markTransactionLog(transactionLog);
}
}
@Override
public void deAssemblyPcd(Long carrierRrn, Long podRrn, Long doorRrn, String user, Long facilityRrn) {
TransactionLog transactionLog = transactionLogManager.startTransactionLog(user,
TransactionNames.CST_DEASSEMBLY);
long transRrn = transactionLog.getTransRrn();
Carrier carrier = carrierManager.getCarrier(carrierRrn);
boolean isWaitClean = false;
if (StringUtils.equalsIgnoreCase(carrier.getCarrierStatus(), PcdStatus.WAIT_CLEAN_KEY)) {
//wait clean 状态不变
// statusManager.changePCDStatusByEvent(facilityRrn, user, carrierRrn, ObjectList.CARRIER_KEY,
// EventName.CST_WAIT_CLEAN_TO_FREE, "Deassembly");
isWaitClean=true;
} else {
statusManager.changePCDStatusByEvent(facilityRrn, user, carrierRrn, ObjectList.CARRIER_KEY,
EventName.CST_ASSEMBLY_TO_FREE, "Deassembly");
}
if (podRrn != null && podRrn > 0) {
POD pod = podManager.getPod(podRrn);
if (StringUtils.equalsIgnoreCase(pod.getPodStatus(), PcdStatus.WAIT_CLEAN_KEY)) {
//wait clean 状态不变
// statusManager.changePCDStatusByEvent(facilityRrn, user, podRrn, ObjectList.POD_KEY,
// EventName.POD_WAIT_CLEAN_TO_FREE, "Deassembly");
isWaitClean=true;
} else {
statusManager.changePCDStatusByEvent(facilityRrn, user, podRrn, ObjectList.POD_KEY,
EventName.POD_ASSEMBLY_TO_FREE, "Deassembly");
}
}
/** by #40125 */
if (doorRrn != null && doorRrn > 0) {
Door door = doorManager.getDoor(doorRrn);
if (StringUtils.equalsIgnoreCase(door.getDoorStatus(), PcdStatus.WAIT_CLEAN_KEY)) {
//wait clean 状态不变
// statusManager.changePCDStatusByEvent(facilityRrn, user, doorRrn, ObjectList.DOOR_KEY,
// EventName.DOOR_WAIT_CLEAN_TO_FREE, "Deassembly");
isWaitClean=true;
} else {
statusManager.changePCDStatusByEvent(facilityRrn, user, doorRrn, ObjectList.DOOR_KEY,
EventName.DOOR_ASSEMBLY_TO_FREE, "Deassembly");
}
}
deAssemblyPcd(carrierRrn, user, transRrn);
// 在PCD解绑的时候一次性同步carrier信息到POD以及DOOR,平时信息查询通过PCD关联关系查询
updatePcdByDeassembly(carrierRrn, podRrn, doorRrn, transRrn,isWaitClean);
transactionLogManager.markTransactionLog(transactionLog);
}
private void updatePcdByDeassembly(Long carrierRrn, Long podRrn, Long doorRrn, Long transRrn,boolean isWaitClean) {
// 在PCD解绑的时候一次性同步carrier信息到POD以及DOOR,平时信息查询通过PCD关联关系查询
Carrier carrier = carrierManager.getCarrier(carrierRrn);
POD pod = podRrn == null || podRrn == 0 ? null : podManager.getPod(podRrn);
Door door = doorRrn == null || doorRrn == 0 ? null : doorManager.getDoor(doorRrn);
//因为解除绑定是要判断当前状态是否为 wait_clean 状态
//1.如果整体状态属于wait_clean 则意味着所有备件都要进行清理
//2.简单粗暴的方式就是直接更改pcd_clean 表的时间,所有组件时间按照清理时间去更新.
//3.首先状态不能转换成free 等其他状态.
//4.获取清理时间 全部更换
String groupState =isWaitClean?PcdStatus.WAIT_CLEAN_KEY: PcdStatus.FREE_KEY;
if (isWaitClean) {//判断是否变更为 wait_clean
//代码进到这 意味着 所有组件时间都要更新到清理时间
List<Long> cleanOverTimes =new ArrayList<>();
List<Consumer<Timestamp>> callback=new ArrayList<>();
TransactionLog transactionLog= transactionLogManager.startTransactionLog("System","Deassembly Wait Clean");
final BiConsumer<Timestamp,Long> updateFunction=(time,rrn)->{
pcdDAO.updateCleanOverTimeByRrn(rrn,time);
PcdClean pcdClean = new PcdClean();
pcdClean.setInstanceRrn(rrn);
pcdClean.setCleanOverDate(time);
pcdDAO.insertPcdCleanH(transactionLog.getTransRrn(),pcdClean);
};
callback.add((time)->{updateFunction.accept(time,carrierRrn);});
cleanOverTimes.add(getPcdCleanInfo(carrierRrn).getCleanOverDate().getTime());
if(pod!=null){
cleanOverTimes.add(getPcdCleanInfo(podRrn).getCleanOverDate().getTime());
callback.add((time)->{updateFunction.accept(time,podRrn);});
}
if(door!=null){
cleanOverTimes.add(getPcdCleanInfo(doorRrn).getCleanOverDate().getTime());
callback.add((time)->{updateFunction.accept(time,doorRrn);});
}
Long minTime = cleanOverTimes.stream().min(Long::compare).get();
final Timestamp minTimeStamp= new Timestamp(minTime);//最终全部改成这个时间
callback.forEach((e)->e.accept(minTimeStamp));//更新
transactionLogManager.markTransactionLog(transactionLog);
}
carrier.setCarrierStatus(groupState);
final String commons = "Deassembly to "+groupState;
//pod
if (pod != null) {
pod.setPodStatus(groupState);
pod.setPollutionLevel(carrier.getPollutionLevel());
pod.setMcsMoveStatus(carrier.getMcsMoveStatus());
pod.setMcsLastMoveTime(carrier.getMcsLastMoveTime());
pod.setMcsLastOperatorRrn(carrier.getMcsLastOperatorRrn());
pod.setEqptRrn(carrier.getEqptRrn());
pod.setJobRrn(carrier.getJobRrn());
pod.setRunRrn(carrier.getRunRrn());
pod.setCarrierMapRrn(carrier.getCarrierMapRrn());
pod.setLoadPosition(carrier.getLoadPosition());
podManager.updatePodByDeassembly(transRrn, pod);//此函数跟踪后 内部已经插入 POD_H流水数据
}
//door
/** by #40125 */
if (doorRrn != null && doorRrn > 0) {
door.setDoorStatus(groupState);
door.setPollutionLevel(carrier.getPollutionLevel());
door.setMcsMoveStatus(carrier.getMcsMoveStatus());
door.setMcsLastMoveTime(carrier.getMcsLastMoveTime());
door.setMcsLastOperatorRrn(carrier.getMcsLastOperatorRrn());
door.setEqptRrn(carrier.getEqptRrn());
door.setJobRrn(carrier.getJobRrn());
door.setRunRrn(carrier.getRunRrn());
door.setCarrierMapRrn(carrier.getCarrierMapRrn());
door.setLoadPosition(carrier.getLoadPosition());
doorManager.updateDoorByDeassembly(transRrn, door);//此函数跟踪后 内部已经插入 DOOR_H流水数据
}
carrierManager.updateCarrierAvailableSlotCount(carrierRrn);
carrierManager.insertCarrierH(carrierRrn,commons,transRrn);
statusManager.updateCarrierStatus(carrierRrn, transRrn, groupState, "Deassembly");
}
@Override
public void assemblyPcd(Long carrierRrn, Long podRrn, Long doorRrn, String user, Long facilityRrn) {
TransactionLog transactionLog = transactionLogManager.startTransactionLog(user, TransactionNames.CST_ASSEMBLY);
long transRrn = transactionLog.getTransRrn();
statusManager.changePCDStatusByEvent(facilityRrn, user, carrierRrn, ObjectList.CARRIER_KEY,
EventName.CST_FREE_TO_ASSEMBLY, "Assembly");
carrierManager.insertCarrierH(carrierRrn,PcdStatus.ASSEMBLY_KEY,transRrn);//插入流水
if(podRrn!=null&&podRrn>0){
statusManager
.changePCDStatusByEvent(facilityRrn, user, podRrn, ObjectList.POD_KEY, EventName.POD_FREE_TO_ASSEMBLY,
"Assembly");
podManager.insertPodH(podRrn,PcdStatus.ASSEMBLY_KEY,transRrn);//插入流水
}
if (doorRrn != null && doorRrn > 0) {
statusManager.changePCDStatusByEvent(facilityRrn, user, doorRrn, ObjectList.DOOR_KEY,
EventName.DOOR_FREE_TO_ASSEMBLY, "Assembly");
doorManager.insertDoorH(doorRrn,PcdStatus.ASSEMBLY_KEY,transRrn);//插入流水
}
//插入pcd_Assembly 插入历史表
pcdDAO.insertPcdAssembly(carrierRrn, podRrn, doorRrn, user);
pcdDAO.insertPcdAssemblyH(carrierRrn, podRrn, doorRrn, user, transRrn);
//修改pdc 组件状态
statusManager.updatePcdStatus(carrierRrn, podRrn, doorRrn, PcdStatus.ASSEMBLY_KEY, transRrn, "Assembly");
transactionLogManager.markTransactionLog(transactionLog);
}
@Override
public Boolean isAssembledPCD(Long instanceRrn) {
return pcdDAO.isAssembledPCD(instanceRrn);
}
@Override
public List<Map> getHoldReasons(long instanceRrn) {
return pcdDAO.getHoldReasons(instanceRrn);
}
@Override
public void insertMultipleHold(long instanceRrn, long holdBy, long transRrn) {
pcdDAO.insertMultipleHold(instanceRrn, holdBy, transRrn);
}
@Override
public void insertTransReason(long transRrn, long instanceRrn, TransReason transReason, int reasonCodeSequence) {
pcdDAO.insertTransReason(transRrn, instanceRrn, transReason, reasonCodeSequence);
}
@Override
public void deleteMultipleHold(long instanceRrn, long sequence) {
pcdDAO.deleteMultipleHold(instanceRrn, sequence);
}
@Override
public List<Map> getHoldReasonCodes(String holdReasonGroupID, List<String> holdReasonRoles,
String referenceFileId) {
return pcdDAO.getHoldReasonCodes(holdReasonGroupID, holdReasonRoles, referenceFileId);
}
@Override
public List<Map> getReleaseGroup(String holdCode, String classTableValue) {
return pcdDAO.getReleaseGroup(holdCode, classTableValue);
}
@Override
public List<Map> getReleaseReasonCodes(String releaseReasonGroupID, List releaseRoles, String referenceFileId) {
return pcdDAO.getReleaseReasonCodes(releaseReasonGroupID, releaseRoles, referenceFileId);
}
@Override
public void resetCleanCycle(List<Map<String, Object>> defaultCleanCycleList, Long facilityRrn, String user) {
// update之前,获取设置的clean cycle
List<Map<String, Object>> allCycleList = pcdDAO.getAllPcdDefaultCleanCycle();
pcdDAO.batchInsertOrUpdatePcdDefaultCleanCycle(defaultCleanCycleList);
// 重置默认周期后,同步修改所有P/C/D的周期信息 PS:source为旧配置,target为新的配置
TransactionLog createTrans = transactionLogManager.startTransactionLog(user, TransactionNames.CREATE_KEY);
TransactionLog modifyTrans = transactionLogManager.startTransactionLog(user, TransactionNames.MODIFY_KEY);
for (Map<String, Object> targetCycleMap : defaultCleanCycleList) {
String targetCategory = MapUtils.getString(targetCycleMap, "categoryCode");
String targetCategoryDesc = MapUtils.getString(targetCycleMap, "categoryDesc");
String targetType = MapUtils.getString(targetCycleMap, "typeCode");
String targetTypeDesc = MapUtils.getString(targetCycleMap, "typeDesc");
String targetDefaultCycle = MapUtils.getString(targetCycleMap, "defaultCleanCycle");
double targetDefaultCycleD = NumberUtils.toDouble(targetDefaultCycle);
boolean updateFlag = true;
for (Map<String, Object> sourceCycleMap : allCycleList) {
String sourceCategory = MapUtils.getString(sourceCycleMap, "category");
String sourceType = MapUtils.getString(sourceCycleMap, "type");
String sourceDefaultCycle = MapUtils.getString(sourceCycleMap, "defaultCleanCycle");
if (StringUtils.equals(sourceCategory, targetCategory) && StringUtils.equals(sourceType, targetType)) {
if (!StringUtils.equals(sourceDefaultCycle, targetDefaultCycle)) {
// 如果相同的category和type下的defaultCleanCycle有改动,则修改所有相关的P/C/D
updateAllPCDCleanCycleByCategoryAndType(facilityRrn, user, targetCategory, targetType,
targetDefaultCycleD);
// modify history
pcdDAO.addPcdDefaultCleanCycleHistory(modifyTrans.getTransRrn(), targetCategoryDesc,
targetTypeDesc, targetDefaultCycleD, user);
}
updateFlag = false;
break;
} else {
updateFlag = true;
}
}
if (updateFlag) {
// 走到此处,表示有新的配置是之前没有的,则直接根据category和type更新cycle信息
updateAllPCDCleanCycleByCategoryAndType(facilityRrn, user, targetCategory, targetType,
targetDefaultCycleD);
// create history
pcdDAO.addPcdDefaultCleanCycleHistory(createTrans.getTransRrn(), targetCategoryDesc, targetTypeDesc,
targetDefaultCycleD, user);
}
}
transactionLogManager.markTransactionLog(createTrans);
transactionLogManager.markTransactionLog(modifyTrans);
}
@Override
public List<ReferenceFileDetail> getCleanEqptRefDetailInfo(String eqptId, Long facilityRrn) {
if (StringUtils.isBlank(eqptId)) {
return new ArrayList<>();
}
List<ReferenceFileDetail> refDetailList = new ArrayList<ReferenceFileDetail>();
List<ReferenceFileDetail> deatilColl = referenceFileManager
.getRefFileValues(PCD_CLEAN_EQPT_REFERENCE_ID, facilityRrn);
if (CollectionUtils.isNotEmpty(deatilColl)) {
for (ReferenceFileDetail detail : deatilColl) {
if (StringUtils.equals(detail.getData1Value(), eqptId)) {
refDetailList.add(detail);
}
}
}
return refDetailList;
}
@Override
public String checkCleanEqptIsInUse(String eqptId, Long facilityRrn) {
String entityNamedSpace = namedObjectManager.getNamedSpace(facilityRrn, ObjectList.ENTITY_KEY);
List<PcdClean> list = getPcdInfoByCleanEqpt(eqptId, entityNamedSpace);
if (CollectionUtils.isNotEmpty(list)) {
String msg = I18nUtils.getMessage(MessageIdList.PCD_EQPT_IS_CLEANING, "Equipment is cleaning.", eqptId);
String cleaningP = "P:";
String cleaningC = "C:";
String cleaningD = "D:";
for (PcdClean pc : list) {
if (StringUtils.equals(pc.getPcdType(), ObjectList.POD_KEY)) {
cleaningP += pc.getInstanceId() + " ";
}
if (StringUtils.equals(pc.getPcdType(), ObjectList.CARRIER_KEY)) {
cleaningC += pc.getInstanceId() + " ";
}
if (StringUtils.equals(pc.getPcdType(), ObjectList.DOOR_KEY)) {
cleaningD += pc.getInstanceId() + " ";
}
}
if (StringUtils.length(cleaningP) > 3) {
msg += cleaningP + " ";
}
if (StringUtils.length(cleaningC) > 3) {
msg += cleaningC + " ";
}
if (StringUtils.length(cleaningD) > 3) {
msg += cleaningD + " ";
}
return msg;
}
return "";
}
@Override
public List<PcdClean> getCleaningPcdByEqpt(String eqptId, Long facilityRrn) {
List<PcdClean> list = new ArrayList<PcdClean>();
String entityNamedSpace = namedObjectManager.getNamedSpace(facilityRrn, ObjectList.ENTITY_KEY);
list = getPcdInfoByCleanEqpt(eqptId, entityNamedSpace);
return list;
}
@Override
public void batchOutClean(Long facilityRrn, String eqptId, String cstIds, String podIds, String doorIds,
String user) {
List<ReferenceFileDetail> eqptList = getCleanEqptRefDetailInfo(eqptId, facilityRrn);
if (CollectionUtils.isNotEmpty(eqptList)) {
String eqptCleaningMsg = checkCleanEqptIsInUse(eqptId, facilityRrn);
Assert.isFalse(StringUtils.isBlank(eqptCleaningMsg),
Errors.create().key(MessageIdList.PCD_NO_CLEANING_PCD).content("当前设备没有正在清洗的PCD!").build());
double cstMinMinutes = 0;
double podMinMinutes = 0;
double doorMinMinutes = 0;
for (ReferenceFileDetail eqpt : eqptList) {
double minMinutes = Double.parseDouble(eqpt.getData4Value());
if (StringUtils.equals(eqpt.getData2Value(), "CASSETTE")) {
cstMinMinutes = minMinutes;
} else if (StringUtils.equals(eqpt.getData2Value(), ObjectList.POD_KEY)) {
podMinMinutes = minMinutes;
} else if (StringUtils.equals(eqpt.getData2Value(), ObjectList.DOOR_KEY)) {
doorMinMinutes = minMinutes;
}
}
String[] cstArray = StringUtils.split(cstIds, ",");
String[] podArray = StringUtils.split(podIds, ",");
String[] doorArray = StringUtils.split(doorIds, ",");
IsPcdCleaningDateAboveThanMinMinutes(podArray, podMinMinutes, facilityRrn);
IsPcdCleaningDateAboveThanMinMinutes(cstArray, cstMinMinutes, facilityRrn);
IsPcdCleaningDateAboveThanMinMinutes(doorArray, doorMinMinutes, facilityRrn);
// batch out clean
if (cstArray.length > 0) {
batchOutCleanByPcd(eqptId, cstArray, ObjectList.CARRIER_KEY, EventName.CST_IN_CLEAN_TO_FREE,
facilityRrn, user);
}
if (podArray.length > 0) {
batchOutCleanByPcd(eqptId, podArray, ObjectList.POD_KEY, EventName.POD_IN_CLEAN_TO_FREE, facilityRrn,
user);
}
if (doorArray.length > 0) {
batchOutCleanByPcd(eqptId, doorArray, ObjectList.DOOR_KEY, EventName.DOOR_IN_CLEAN_TO_FREE, facilityRrn,
user);
}
}
}
@Override
public List<Map<String, Object>> getAllPcdCategory(Long facilityRrn) {
List<ReferenceFileDetail> categoryColl = referenceFileManager.getRefFileValues("$PCD_CATEGORY",
namedObjectManager.getNamedSpace(
facilityRrn,
ObjectList.REFERENCE_FILE_KEY));
List<Map<String, Object>> categoryList = new ArrayList<Map<String, Object>>();
if (CollectionUtils.isNotEmpty(categoryColl)) {
for (ReferenceFileDetail detail : categoryColl) {
Map<String, Object> map = new HashMap<String, Object>();
map.put("categoryCode", detail.getKey1Value());
map.put("categoryDesc", detail.getData1Value());
categoryList.add(map);
}
return categoryList;
}
return new ArrayList<Map<String, Object>>();
}
@Override
public List<Map<String, Object>> getAllPcdType(Long facilityRrn) {
List<ReferenceFileDetail> categoryColl = referenceFileManager.getRefFileValues("$CARRIER_TYPE",
namedObjectManager.getNamedSpace(
facilityRrn,
ObjectList.REFERENCE_FILE_KEY));
List<Map<String, Object>> categoryList = new ArrayList<Map<String, Object>>();
if (CollectionUtils.isNotEmpty(categoryColl)) {
for (ReferenceFileDetail detail : categoryColl) {
Map<String, Object> map = new HashMap<String, Object>();
map.put("typeCode", detail.getKey1Value());
map.put("typeDesc", detail.getData1Value());
map.put("pcdFlag", detail.getData2Value());
categoryList.add(map);
}
return categoryList;
}
return new ArrayList<Map<String, Object>>();
}
@Override
public List<PcdClean> getPcdInfoByCleanEqpt(String eqptId, String entityNamedSpace) {
return pcdDAO.getPcdInfoByCleanEqpt(eqptId, entityNamedSpace);
}
@Override
public void batchInClean(Long facilityRrn, String eqptId, String cstIds, String podIds, String doorIds,
String user) {
List<ReferenceFileDetail> eqptList = getCleanEqptRefDetailInfo(eqptId, facilityRrn);
Assert.isTrue(CollectionUtils.isNotEmpty(eqptList),
Errors.create().key(MessageIdList.PCD_CLEAN_EQPT_MISSING).content("清洗作业设备不存在!").build());
String eqptCleaningMsg = checkCleanEqptIsInUse(eqptId, facilityRrn);
Assert.isFalse(StringUtils.isNotBlank(eqptCleaningMsg), Errors.create().content(eqptCleaningMsg).build());
String[] cstArray = StringUtils.split(cstIds, ",");
String[] podArray = StringUtils.split(podIds, ",");
String[] doorArray = StringUtils.split(doorIds, ",");
int cstMaxCount = 0;
int podMaxCount = 0;
int doorMaxCount = 0;
for (ReferenceFileDetail eqpt : eqptList) {
int maxCount = Integer.parseInt(eqpt.getData3Value());
if (StringUtils.equals(eqpt.getData2Value(), "CASSETTE")) {
cstMaxCount = maxCount;
} else if (StringUtils.equals(eqpt.getData2Value(), ObjectList.POD_KEY)) {
podMaxCount = maxCount;
} else if (StringUtils.equals(eqpt.getData2Value(), ObjectList.DOOR_KEY)) {
doorMaxCount = maxCount;
}
}
Assert.isFalse(cstArray.length > cstMaxCount,
Errors.create().key(MessageIdList.PCD_CASSETTE_OUT_OF_MAX).content("Cassette超出最大计数!").build());
Assert.isFalse(podArray.length > podMaxCount,
Errors.create().key(MessageIdList.PCD_POD_OUT_OF_MAX).content("Cassette超出最大计数!").build());
Assert.isFalse(doorArray.length > doorMaxCount,
Errors.create().key(MessageIdList.PCD_DOOR_OUT_OF_MAX).content("Cassette超出最大计数!").build());
// 检查PCD是否都存在并且是未绑定的空P/C/D
if (cstArray.length > 0 && StringUtils.isNotBlank(cstArray[0])) {
checkPcdIsExist(cstArray, facilityRrn);
}
if (podArray.length > 0 && StringUtils.isNotBlank(podArray[0])) {
checkPcdIsExist(podArray, facilityRrn);
}
if (doorArray.length > 0 && StringUtils.isNotBlank(doorArray[0])) {
checkPcdIsExist(doorArray, facilityRrn);
}
// batch in clean
if (cstArray.length > 0) {
batchInCleanByPcd(eqptId, cstArray, ObjectList.CARRIER_KEY, EventName.CST_WAIT_CLEAN_TO_IN_CLEAN,
facilityRrn, user);
}
if (podArray.length > 0) {
batchInCleanByPcd(eqptId, podArray, ObjectList.POD_KEY, EventName.POD_WAIT_CLEAN_TO_IN_CLEAN, facilityRrn,
user);
}
if (doorArray.length > 0) {
batchInCleanByPcd(eqptId, doorArray, ObjectList.DOOR_KEY, EventName.DOOR_WAIT_CLEAN_TO_IN_CLEAN,
facilityRrn, user);
}
}
@Override
public void checkPcdIsValid(Long carrierRrn, Long facilityRrn) {
String cleanInvalidMsg = checkPcdIsValidReturnString(carrierRrn, facilityRrn);
Assert.isFalse(StringUtils.isNotBlank(cleanInvalidMsg),
Errors.create().content(cleanInvalidMsg).build());
Map<String, Object> resultMap = checkNotAllowUsePcdStatusByCarrier(carrierRrn, facilityRrn);
Assert.isTrue(MapUtils.getBooleanValue(resultMap, "result", true),
Errors.create().content(MapUtils.getString(resultMap, "msg", "Invalid Entity")).build());
}
/**
* 通过carrierRrn检查OPEN-CST或PCD当前状态是否允许使用
*
* @return 返回一个map,包含两个key(1.result,2.msg) result为boolean类型,true 表示允许,false 表示不允许 msg为String类型,包含不允许的原因
*/
@Override
public Map<String, Object> checkNotAllowUsePcdStatusByCarrier(Long carrierRrn, Long facilityRrn) {
Map<String, Object> resultMap = new HashMap<String, Object>();
resultMap.put("result", true);
String refId = "$$NOT_ALLOW_USE_CASSETTE_STATUS";
String refNamedSpace = namedObjectManager.getNamedSpace(facilityRrn, ObjectList.REFERENCE_FILE_KEY);
List<ReferenceFileDetail> notAllowStatusColl = referenceFileManager.getRefFileValues(refId, refNamedSpace);
if (CollectionUtils.isEmpty(notAllowStatusColl)) {
return resultMap;
}
PcdAssembly pcd = this.getPcdAssembly(carrierRrn, null, null);
// 如果是PCD组装的,则逐个检查每个组件
if (pcd != null && StringUtils.isNotBlank(pcd.getPodId())) {
Long podRrn = pcd.getPodRrn();
Long doorRrn = pcd.getDoorRrn();
Carrier c = carrierManager.getCarrier(carrierRrn);
POD p = podRrn==null||podRrn==0?null:podManager.getPod(podRrn);
Door d = doorRrn==null||doorRrn==0?null:doorManager.getDoor(doorRrn);
for (ReferenceFileDetail refDetail : notAllowStatusColl) {
if (StringUtils.equalsIgnoreCase(c.getCarrierStatus(), refDetail.getKey1Value())) {
resultMap.put("result", false);
resultMap.put("msg", "Invalid " + c.getInstanceId() + " status: " + refDetail.getKey1Value());
break;
}
if (p!=null&&StringUtils.equalsIgnoreCase(p.getPodStatus(), refDetail.getKey1Value())) {
resultMap.put("result", false);
resultMap.put("msg", "Invalid " + p.getInstanceId() + " status: " + refDetail.getKey1Value());
break;
}
if (d!=null&&StringUtils.equalsIgnoreCase(d.getDoorStatus(), refDetail.getKey1Value())) {
resultMap.put("result", false);
resultMap.put("msg", "Invalid " + d.getInstanceId() + " status: " + refDetail.getKey1Value());
break;
}
}
} else {
for (ReferenceFileDetail refDetail : notAllowStatusColl) {
Carrier c = carrierManager.getCarrier(carrierRrn);
if (StringUtils.equalsIgnoreCase(c.getCarrierStatus(), refDetail.getKey1Value())) {
resultMap.put("result", false);
resultMap.put("msg", "Invalid " + c.getInstanceId() + " status: " + refDetail.getKey1Value());
break;
}
}
}
return resultMap;
}
@Override
public double getDefaultCleanCycle(String category, String type, Long facilityRrn) {
if (StringUtils.isNotBlank(category) && StringUtils.isNotBlank(type)) {
Map<String, Object> map = getPcdDefaultCleanCycleInfo(category, type);
return MapUtils.getDoubleValue(map, "defaultCleanCycle");
}
return 0;
}
@Override
public String generateCarrierId(String prefix) {
String subfix = pcdDAO.getCarrierIdSerial(prefix);
Integer serialNumber = Integer.parseInt(subfix);
Assert.isFalse(serialNumber >= 9999,
Errors.create().key(MessageIdList.CARRIER_ID_OVERFLOW).content("晶舟号已超过系统定义,请联系管理员!").build());
serialNumber++;
DecimalFormat dfSuffix = new DecimalFormat("0000");
subfix = dfSuffix.format(serialNumber);
return prefix + subfix;
}
@Override
public String generateCarrierId(String prefix, int serialLength) {
String zerosPattern = "";
String maxSerial = "";
for (int i = 0; i < serialLength; i++) {
maxSerial += "9";
zerosPattern += "0";
}
String subfix = pcdDAO.getCarrierIdSerial(prefix, serialLength);
Long serialNumber = Long.parseLong(subfix);
Assert.isFalse(serialNumber >= NumberUtils.toLong(maxSerial),
Errors.create().key(MessageIdList.CARRIER_ID_OVERFLOW).content("晶舟号已超过系统定义,请联系管理员!").build());
serialNumber++;
DecimalFormat dfSuffix = new DecimalFormat(zerosPattern);
subfix = dfSuffix.format(serialNumber);
return prefix + subfix;
}
@Override
public boolean checkPcdOverClean(long pcdRrn) {
PcdClean pcdCleanInfo = getPcdCleanInfo(pcdRrn);
if (pcdCleanInfo != null && pcdCleanInfo.getInstanceRrn() > 0) {
if (!isCleanValidPcd(pcdCleanInfo.getCleanOverDate())) {
return false;
}
}
return true;
}
@Override
public void exchangePCD(List<Map> transInfo) {
for (Map transMap : transInfo) {
Lot lot = (Lot) transMap.get("lot");
Long targetCarrierRrn = MapUtils.getLongValue(transMap, "targetCarrierRrn", 0L);
List<Map> unitsList = (List<Map>) transMap.get("unitsList");
this.changeStatusFromInUseToFreeOrAssembly(MapUtils.getLong(transMap, "facilityRrn"),
MapUtils.getString(transMap, "user"), lot.getCarrierRrn(),
"Release for move out exchange pcd");
this.changeStatusFromFreeOrAssemblyToInUse(MapUtils.getLong(transMap, "facilityRrn"),
MapUtils.getString(transMap, "user"), targetCarrierRrn,
"In use for move out exchange pcd");
carrierManager.exchangeCarrierByCarrier(lot, targetCarrierRrn, unitsList);
}
}
@Override
public void changeStatusFromInUseToFreeOrAssembly(Long facilityRrn, String user, Long carrierRrn, String comments) {
Carrier carrier = new Carrier();
carrier = carrierManager.getCarrier(carrierRrn);
if (StringUtils.isNotBlank(carrier.getInstanceId())) {
if (carrier.getSlotCount() > carrier.getAvailableSlotCount()) {
// 将PCD的状态从IN USE切换到ASSEMBLY
PcdAssembly pcd = getPcdAssembly(carrierRrn, null, null);
if (pcd != null && StringUtils.isNotBlank(pcd.getPodId())) {
// pcd-cst
POD p =pcd.getPodRrn()==null||pcd.getPodRrn()<=0?null: podManager.getPod(pcd.getPodRrn());
Door d =pcd.getDoorRrn()==null||pcd.getDoorRrn()<=0?null: doorManager.getDoor(pcd.getDoorRrn());
/**
* 释放PCD,如果释放时,批次上PCD是IN_USE状态,直接释放为ASSEMBLY状态
* 如果批次上PCD某个组件是WAIT_CLEAN状态,则需要先释放为ASSEMBLY状态
* 再从ASSEMBLY状态自动切换为WAIT_CLEAN状态
*/
if (StringUtils.equalsIgnoreCase(PcdStatus.IN_USE_KEY, carrier.getCarrierStatus())) {
statusManager.changePCDStatusByEvent(facilityRrn, user, pcd.getCarrierRrn(),
ObjectList.CARRIER_KEY, EventName.CST_IN_USE_TO_ASSEMBLY,
comments);
} else if (StringUtils.equalsIgnoreCase(PcdStatus.WAIT_CLEAN_KEY, carrier.getCarrierStatus())) {
statusManager.changePCDStatusByEvent(facilityRrn, user, pcd.getCarrierRrn(),
ObjectList.CARRIER_KEY,
EventName.CST_WAIT_CLEAN_TO_ASSEMBLY, comments);
statusManager.changePCDStatusByEvent(facilityRrn, user, pcd.getCarrierRrn(),
ObjectList.CARRIER_KEY,
EventName.CST_ASSEMBLY_TO_WAIT_CLEAN, comments);
}
if (p!=null&&StringUtils.equalsIgnoreCase(PcdStatus.IN_USE_KEY, p.getPodStatus())) {
statusManager.changePCDStatusByEvent(facilityRrn, user, pcd.getPodRrn(), ObjectList.POD_KEY,
EventName.POD_IN_USE_TO_ASSEMBLY, comments);
} else if (p!=null&&StringUtils.equalsIgnoreCase(PcdStatus.WAIT_CLEAN_KEY, p.getPodStatus())) {
statusManager.changePCDStatusByEvent(facilityRrn, user, pcd.getPodRrn(), ObjectList.POD_KEY,
EventName.POD_WAIT_CLEAN_TO_ASSEMBLY, comments);
statusManager.changePCDStatusByEvent(facilityRrn, user, pcd.getPodRrn(), ObjectList.POD_KEY,
EventName.POD_ASSEMBLY_TO_WAIT_CLEAN, comments);
}
if (d!=null&&StringUtils.equalsIgnoreCase(PcdStatus.IN_USE_KEY, d.getDoorStatus())) {
statusManager.changePCDStatusByEvent(facilityRrn, user, pcd.getDoorRrn(), ObjectList.DOOR_KEY,
EventName.DOOR_IN_USE_TO_ASSEMBLY, comments);
} else if (d!=null&&StringUtils.equalsIgnoreCase(PcdStatus.WAIT_CLEAN_KEY, d.getDoorStatus())) {
statusManager.changePCDStatusByEvent(facilityRrn, user, pcd.getDoorRrn(), ObjectList.DOOR_KEY,
EventName.DOOR_WAIT_CLEAN_TO_ASSEMBLY, comments);
statusManager.changePCDStatusByEvent(facilityRrn, user, pcd.getDoorRrn(), ObjectList.DOOR_KEY,
EventName.DOOR_ASSEMBLY_TO_WAIT_CLEAN, comments);
}
} else {
/**
* 释放晶舟,如果批次上晶舟是IN_USE,则直接释放为FREE状态 如果批次上晶舟是WAIT_CLEAN状态,则先释放为FREE状态,
* 再从FREE状态自动切换为WAIT_CLEAN状态
*/
if (StringUtils.equalsIgnoreCase(PcdStatus.IN_USE_KEY, carrier.getCarrierStatus())) {
statusManager.changePCDStatusByEvent(facilityRrn, user, carrierRrn, ObjectList.CARRIER_KEY,
EventName.CST_IN_USE_TO_FREE, comments);
} else if (StringUtils.equalsIgnoreCase(PcdStatus.WAIT_CLEAN_KEY, carrier.getCarrierStatus())) {
statusManager.changePCDStatusByEvent(facilityRrn, user, carrierRrn, ObjectList.CARRIER_KEY,
EventName.CST_WAIT_CLEAN_TO_FREE, comments);
statusManager.changePCDStatusByEvent(facilityRrn, user, carrierRrn, ObjectList.CARRIER_KEY,
EventName.CST_FREE_TO_WAIT_CLEAN, comments);
}
}
}
}
}
@Override
public void changeStatusFromFreeOrAssemblyToInUse(Long facilityRrn, String user, Long carrierRrn, String comments) {
Carrier carrier = carrierManager.getCarrier(carrierRrn);
if (StringUtils.isNotBlank(carrier.getInstanceId())) {
if (carrierManager.isPcdType(carrier.getObjectSubtype())) {
// 将PCD的状态从ASSEMBLY切换为IN USE
if (StringUtils.equalsIgnoreCase(carrier.getCarrierStatus(), PcdStatus.ASSEMBLY_KEY)) {
PcdAssembly pcd = getPcdAssembly(carrierRrn, null, null);
if (pcd != null && StringUtils.isNotBlank(pcd.getPodId())) {
statusManager.changePCDStatusByEvent(facilityRrn, user, pcd.getCarrierRrn(),
ObjectList.CARRIER_KEY, EventName.CST_ASSEMBLY_TO_IN_USE,
comments);
if(pcd.getPodRrn()!=null&&pcd.getPodRrn()>0){
statusManager.changePCDStatusByEvent(facilityRrn, user, pcd.getPodRrn(), ObjectList.POD_KEY,
EventName.POD_ASSEMBLY_TO_IN_USE, comments);
}
if(pcd.getDoorRrn()!=null&&pcd.getDoorRrn()>0){
statusManager.changePCDStatusByEvent(facilityRrn, user, pcd.getDoorRrn(), ObjectList.DOOR_KEY,
EventName.DOOR_ASSEMBLY_TO_IN_USE, comments);
}
}
}
} else {
// 将OPEN-CST的状态从FREE切换为IN USE
if (StringUtils.equalsIgnoreCase(carrier.getCarrierStatus(), PcdStatus.FREE_KEY)) {
statusManager.changePCDStatusByEvent(facilityRrn, user, carrierRrn, ObjectList.CARRIER_KEY,
EventName.CST_FREE_TO_IN_USE, comments);
}
}
}
}
@Override
public void checkPCDCleanTimeAndLogEvent(String waitCleanKey) {
// 在允许事件集里面,在自动的类表值里面,超过清洗时间
List<PcdClean> pcdCleanInfos = this.qryPCDCleanInfo(waitCleanKey);
Set<Long> pcdRrnSet = new HashSet<>(); // set做防止重复更改状态的作用
for (PcdClean cleanInfo : pcdCleanInfos) {
if(pcdRrnSet.contains(cleanInfo.getInstanceRrn())){
continue;
}
// 如果到了清洗时间,执行log event,将Carrier, Pod,Door变成WAIT_CLEAN状态
statusManager.changePCDStatusAndEvent("SYSTEM", cleanInfo.getInstanceRrn(), cleanInfo.getPcdType(),
cleanInfo.getEventRrn(), "Wait clean by system auto",
PcdStatus.WAIT_CLEAN_KEY);
pcdRrnSet.add(cleanInfo.getInstanceRrn());
// 如果是组合的PCD,只要其中有一个组件过期,其它组件即使没过期也做过期处理(状态变成WAIT_CLEAN)
// 如果是组合的PCD,把三个组件都查询出来
PcdAssembly pcd = new PcdAssembly();
if (StringUtils.equalsIgnoreCase(cleanInfo.getPcdType(), ObjectList.CARRIER_KEY)) {
pcd = this.getPcdAssembly(cleanInfo.getInstanceRrn(), null, null);
} else if (StringUtils.equalsIgnoreCase(cleanInfo.getPcdType(), ObjectList.POD_KEY)) {
pcd = this.getPcdAssembly(null, cleanInfo.getInstanceRrn(), null);
} else if (StringUtils.equalsIgnoreCase(cleanInfo.getPcdType(), ObjectList.DOOR_KEY)) {
pcd = this.getPcdAssembly(null, null, cleanInfo.getInstanceRrn());
}
if (pcd != null) {
if (StringUtils.isNotBlank(pcd.getCarrierId())) {
// 是组合的PCD,组装clean信息
//修改 pod
if(pcd.getPodRrn()!=null&&pcd.getPodRrn()>0){
PcdClean podCleanInfo = this.getPcdCleanInfo(pcd.getPodRrn());
podCleanInfo.setInstanceId(pcd.getPodId());
pcdRrnSet = checkOtherPCDCleanTimeAndLogEvent(pcdRrnSet, podCleanInfo, cleanInfo);
}
//修改door
if (pcd.getDoorRrn() != null && pcd.getDoorRrn() > 0) {
PcdClean doorCleanInfo = this.getPcdCleanInfo(pcd.getDoorRrn());
doorCleanInfo.setInstanceId(pcd.getDoorId());
pcdRrnSet = checkOtherPCDCleanTimeAndLogEvent(pcdRrnSet, doorCleanInfo, cleanInfo);
}
//修改cst
PcdClean carrierCleanInfo = this.getPcdCleanInfo(pcd.getCarrierRrn());
carrierCleanInfo.setInstanceId(pcd.getCarrierId());
pcdRrnSet = checkOtherPCDCleanTimeAndLogEvent(pcdRrnSet, carrierCleanInfo, cleanInfo);
}
}
}
}
@Override
public List<PcdClean> qryPCDCleanInfo(String targetStatus) {
return pcdDAO.qryPCDCleanInfo(targetStatus);
}
@Override
public Set<Long> checkOtherPCDCleanTimeAndLogEvent(Set<Long> pcdRrnSet, PcdClean targetPcdClean,
PcdClean sourcePcdClean) {
if (targetPcdClean != null && targetPcdClean.getInstanceRrn() > 0) {
long facilityRrn = LocalContext.getFacilityRrn();
// 查询事件信息
Map<String, Object> eventMap = getEventInfoByPcdId(facilityRrn, targetPcdClean.getInstanceId(),
targetPcdClean.getPcdType(), PcdStatus.WAIT_CLEAN_KEY);
if (MapUtils.isNotEmpty(eventMap)) {
targetPcdClean.setEventId(MapUtils.getString(eventMap, "eventId", StringUtils.EMPTY));
targetPcdClean.setEventRrn(MapUtils.getLongValue(eventMap, "eventRrn"));
int setSize = pcdRrnSet.size();
pcdRrnSet.add(targetPcdClean.getInstanceRrn());
if (setSize == pcdRrnSet.size()) {
// 重复更改
} else {
statusManager.changePCDStatusAndEvent("SYSTEM", targetPcdClean.getInstanceRrn(),
targetPcdClean.getPcdType(), targetPcdClean.getEventRrn(),
"Wait clean by system auto", PcdStatus.WAIT_CLEAN_KEY);
}
}
}
return pcdRrnSet;
}
@Override
public Map<String, Object> getEventInfoByPcdId(Long facilityRrn, String pcdId, String pcdType,
String targetStatus) {
String currentStatus = StringUtils.EMPTY;
String entityNamedSpace = namedObjectManager.getNamedSpace(facilityRrn, ObjectList.ENTITY_KEY);
long entityRrn = 0;
if (StringUtils.equalsIgnoreCase(pcdType, ObjectList.CARRIER_KEY)) {
Carrier c = carrierManager.getCarrier(facilityRrn, pcdId);
if (c != null && c.getInstanceRrn() > 0) {
entityRrn = c.getInstanceRrn();
currentStatus = c.getCarrierStatus();
}
} else if (StringUtils.equalsIgnoreCase(pcdType, ObjectList.POD_KEY)) {
long podRrn = namedObjectManager.getNamedObjectRrn(pcdId, entityNamedSpace, ObjectList.ENTITY_KEY,
ObjectList.POD_KEY);
POD p = podManager.getPod(podRrn);
if (p != null && p.getInstanceRrn() > 0) {
entityRrn = p.getInstanceRrn();
currentStatus = p.getPodStatus();
}
} else if (StringUtils.equalsIgnoreCase(pcdType, ObjectList.DOOR_KEY)) {
long doorRrn = namedObjectManager.getNamedObjectRrn(pcdId, entityNamedSpace, ObjectList.ENTITY_KEY,
ObjectList.DOOR_KEY);
Door d = doorManager.getDoor(doorRrn);
if (d != null && d.getInstanceRrn() > 0) {
entityRrn = d.getInstanceRrn();
currentStatus = d.getDoorStatus();
}
}
if (StringUtils.isNotBlank(currentStatus)) {
List<Map> eventInfoList = eventManager.getEventInfoList(facilityRrn, entityRrn, currentStatus,
targetStatus);
if (CollectionUtils.isNotEmpty(eventInfoList)) {
// 获取第一个
Map<String, Object> eventMap = eventInfoList.get(0);
return eventMap;
}
}
return null;
}
@Override
public String checkPcdIsValidReturnString(Long carrierRrn, long facilityRrn) {
StringBuilder cleanInvalidMsg = new StringBuilder();
if (carrierRrn != null && carrierRrn > 0) {
PcdAssembly pcd = this.getPcdAssembly(carrierRrn);
if (pcd != null && pcd.getCarrierRrn() > 0) {
PcdClean carrierCleanInfo = this.getPcdCleanInfo(pcd.getCarrierRrn());
PcdClean podCleanInfo = this.getPcdCleanInfo(pcd.getPodRrn());
PcdClean doorCleanInfo = this.getPcdCleanInfo(pcd.getDoorRrn());
if (carrierCleanInfo != null) {
if (!this.isCleanValidPcd(carrierCleanInfo.getCleanOverDate())) {
cleanInvalidMsg.append(pcd.getCarrierId());
}
}
if (podCleanInfo != null) {
if (!this.isCleanValidPcd(podCleanInfo.getCleanOverDate())) {
if (StringUtils.isNotBlank(cleanInvalidMsg.toString())) {
cleanInvalidMsg.append(", ");
}
cleanInvalidMsg.append(pcd.getPodId());
}
}
if (doorCleanInfo != null) {
if (!this.isCleanValidPcd(doorCleanInfo.getCleanOverDate())) {
if (StringUtils.isNotBlank(cleanInvalidMsg.toString())) {
cleanInvalidMsg.append(", ");
}
cleanInvalidMsg.append(pcd.getDoorId());
}
}
if (cleanInvalidMsg.length() > 0) {
cleanInvalidMsg.append(" is out of clean date! ");
}
} else {
// 如果不是pcd组装晶舟,则查询open-cst
Carrier carrier = new Carrier(carrierRrn);
carrier = carrierManager.getCarrier(carrier);
if (StringUtils.isNotBlank(carrier.getInstanceId())) {
PcdClean carrierCleanInfo = this.getPcdCleanInfo(carrier.getInstanceRrn());
if (carrierCleanInfo != null && !this.isCleanValidPcd(carrierCleanInfo.getCleanOverDate())) {
cleanInvalidMsg.append(carrier.getInstanceId() + " is out of clean date! ");
}
} else {
cleanInvalidMsg.append("Cassette is invalid!");
}
}
}
return cleanInvalidMsg.toString();
}
public void updateAllPCDCleanCycleByCategoryAndType(Long facilityRrn, String user, String cateogory, String type,
double tragetCleanCycle) {
String namedSpcace = namedObjectManager.getNamedSpace(facilityRrn, ObjectList.ENTITY_KEY);
updateAllCstCleanCycleByCategoryAndType(facilityRrn, user, cateogory, type, tragetCleanCycle, namedSpcace);
updateAllPodCleanCycleByCategoryAndType(facilityRrn, user, cateogory, type, tragetCleanCycle, namedSpcace);
updateAllDoorCleanCycleByCategoryAndType(facilityRrn, user, cateogory, type, tragetCleanCycle, namedSpcace);
}
public void updateAllCstCleanCycleByCategoryAndType(Long facilityRrn, String user, String cateogory, String type,
double tragetCleanCycle, String carrierNamedSpcace) {
Map<String, Object> getAllCarrierMap = new HashMap<String, Object>();
getAllCarrierMap.put("category", cateogory);
getAllCarrierMap.put("type", type);
getAllCarrierMap.put("namedSpace", carrierNamedSpcace);
List<Map> allCarrier = carrierManager.getAllCarrier(getAllCarrierMap);
if (CollectionUtils.isNotEmpty(allCarrier)) {
for (Map carrierMap : allCarrier) {
Map<String, Object> carrierAttrMap = new HashMap<String, Object>();
carrierAttrMap.put("carrierRrn", MapUtils.getLong(carrierMap, "carrierRrn"));
carrierAttrMap.put("carrierId", MapUtils.getString(carrierMap, "carrierId"));
carrierAttrMap.put("carrierDesc", MapUtils.getString(carrierMap, "carrierDesc"));
carrierAttrMap.put("carrierStatus", MapUtils.getString(carrierMap, "carrierStatus"));
carrierAttrMap.put("carrierType", MapUtils.getString(carrierMap, "carrierType"));
carrierAttrMap.put("carrierColor", MapUtils.getString(carrierMap, "carrierColorCode"));
carrierAttrMap.put("carrierCategory", MapUtils.getString(carrierMap, "carrierCategoryCode"));
// carrierAttrMap.put("carrierPosition", MapUtils.getString(carrierMap, ""));
// carrierAttrMap.put("carrierlocation", MapUtils.getString(carrierMap, ""));
carrierAttrMap.put("carrierSlotCount", MapUtils.getString(carrierMap, "slotCount"));
carrierAttrMap.put("carrierAvailableSlotCount", MapUtils.getString(carrierMap, "availableSlotCount"));
carrierAttrMap.put("carrierPollutionLevel", MapUtils.getString(carrierMap, "carrierPollution"));
carrierAttrMap.put("carrierAllowableEvent", MapUtils.getString(carrierMap, "carrierAllowable"));
carrierAttrMap.put("carrierEngineerGroupID", MapUtils.getString(carrierMap, "carrierEngineer", ""));
carrierAttrMap.put("carrierCleanCycle", tragetCleanCycle);
carrierManager.updateCarrierEntity(carrierAttrMap, facilityRrn, user);
}
}
}
public void updateAllPodCleanCycleByCategoryAndType(Long facilityRrn, String user, String cateogory, String type,
double tragetCleanCycle, String carrierNamedSpcace) {
Map<String, Object> getAllPodMap = new HashMap<String, Object>();
getAllPodMap.put("category", cateogory);
getAllPodMap.put("type", type);
getAllPodMap.put("namedSpace", carrierNamedSpcace);
List<Map> allPod = podManager.getAllPod(getAllPodMap);
if (CollectionUtils.isNotEmpty(allPod)) {
for (Map podMap : allPod) {
Map<String, Object> updatePodMap = new HashMap<String, Object>();
updatePodMap.put("podRrn", MapUtils.getLong(podMap, "podRrn"));
updatePodMap.put("podId", MapUtils.getString(podMap, "podId", ""));
updatePodMap.put("podDesc", MapUtils.getString(podMap, "podDesc", ""));
updatePodMap.put("podStatus", MapUtils.getString(podMap, "podStatus", ""));
updatePodMap.put("podType", MapUtils.getString(podMap, "podType", ""));
updatePodMap.put("podPollutionLevel", MapUtils.getString(podMap, "podPollution", ""));
updatePodMap.put("podAllowableEvent", MapUtils.getString(podMap, "podAllowable", ""));
updatePodMap.put("podEngineerGroupID", MapUtils.getString(podMap, "podEngineer", ""));
updatePodMap.put("podSlotCount", MapUtils.getString(podMap, "podSlotCount", ""));
updatePodMap.put("podPosition", MapUtils.getString(podMap, "podLoadPosition", ""));
updatePodMap.put("podColor", MapUtils.getString(podMap, "podColor", ""));
updatePodMap.put("podCategory", MapUtils.getString(podMap, "podCategoryCode", ""));
updatePodMap.put("podCleanCycle", tragetCleanCycle);
podManager.updatePodEntity(updatePodMap, facilityRrn, user);
}
}
}
public void updateAllDoorCleanCycleByCategoryAndType(Long facilityRrn, String user, String cateogory, String type,
double tragetCleanCycle, String doorNamedSpcace) {
Map<String, Object> getAllDoorMap = new HashMap<String, Object>();
getAllDoorMap.put("category", cateogory);
getAllDoorMap.put("type", type);
getAllDoorMap.put("namedSpace", doorNamedSpcace);
List<Map> allDoor = doorManager.getAllDoor(getAllDoorMap);
if (CollectionUtils.isNotEmpty(allDoor)) {
for (Map doorMap : allDoor) {
Map<String, Object> updateDoorMap = new HashMap<String, Object>();
updateDoorMap.put("doorRrn", MapUtils.getLong(doorMap, "doorRrn"));
updateDoorMap.put("doorId", MapUtils.getString(doorMap, "doorId", ""));
updateDoorMap.put("doorDesc", MapUtils.getString(doorMap, "doorDesc", ""));
updateDoorMap.put("doorStatus", MapUtils.getString(doorMap, "doorStatus", ""));
updateDoorMap.put("doorType", MapUtils.getString(doorMap, "doorType", ""));
updateDoorMap.put("doorColor", MapUtils.getString(doorMap, "doorColor", ""));
updateDoorMap.put("doorPosition", MapUtils.getString(doorMap, "doorLoadPosition", ""));
updateDoorMap.put("doorSlotCount", MapUtils.getString(doorMap, "doorSlotCount", ""));
updateDoorMap.put("doorPollutionLevel", MapUtils.getString(doorMap, "doorPollution", ""));
updateDoorMap.put("doorAllowableEvent", MapUtils.getString(doorMap, "doorAllowable", ""));
updateDoorMap.put("doorEngineerGroupID", MapUtils.getString(doorMap, "doorEngineer", ""));
updateDoorMap.put("doorCategory", MapUtils.getString(doorMap, "doorCategoryCode", ""));
updateDoorMap.put("doorCleanCycle", tragetCleanCycle);
doorManager.updateDoorEntity(updateDoorMap, facilityRrn, user);
}
}
}
/**
* 检查P/C/D是否是目标状态下的未绑定的空P/C/D
*/
public void checkPcdIsExistAndNotAssemblyOrInUseAndCurrentStatus(String pcdId, Long facilityRrn,
String targetStatus) {
NamedObject no = new NamedObject(pcdId, namedObjectManager.getNamedSpace(facilityRrn, ObjectList.ENTITY_KEY),
ObjectList.ENTITY_KEY);
no = namedObjectManager.getNamedObject(no);
if (null == no) {
no = new NamedObject();
}
Assert.isTrue(no.getInstanceRrn() > 0,
Errors.create().key(MessageIdList.PCD_NO_CLEANING_EQPT_ID).content("{} is not exist!").args(pcdId)
.build());
if (StringUtils.equals(no.getObjectType(), ObjectList.CARRIER_KEY)) {
PcdAssembly pcdAll = getPcdAssembly(no.getInstanceRrn(), null, null); // C
Assert.isTrue(pcdAll == null || StringUtils.isBlank(pcdAll.getCarrierId()),
Errors.create().key(MessageIdList.PCD_DEASSEMBLY_PCD_FIRST).content("请先解绑PCD").build());
// 没有绑定关系,检查是否是空晶舟
Carrier c = carrierManager.getCarrier(no.getInstanceRrn());
Assert.isTrue(c.getAvailableSlotCount().equals(c.getSlotCount()),
Errors.create().key(MessageIdList.PCD_IS_IN_USE).content("{} is in use!").args(pcdId)
.build());
Assert.isTrue(StringUtils.equals(c.getCarrierStatus(), targetStatus),
Errors.create().key(MessageIdList.PCD_STATUS_ERROR)
.content("{} current " + "status is " + "not {}!").args(pcdId, targetStatus).build());
} else if (StringUtils.equals(no.getObjectType(), ObjectList.POD_KEY)) {
PcdAssembly pcdAll = getPcdAssembly(null, no.getInstanceRrn(), null); // P
Assert.isFalse(pcdAll != null && StringUtils.isNotBlank(pcdAll.getCarrierId()),
Errors.create().key(MessageIdList.PCD_DEASSEMBLY_PCD_FIRST).content("请先解绑PCD").build());
POD p = podManager.getPod(no.getInstanceRrn());
Assert.isTrue(StringUtils.equals(p.getPodStatus(), targetStatus),
Errors.create().key(MessageIdList.PCD_STATUS_ERROR)
.content("{} current status " + "is not {}!").args(pcdId, targetStatus).build());
} else if (StringUtils.equals(no.getObjectType(), ObjectList.DOOR_KEY)) {
PcdAssembly pcdAll = getPcdAssembly(null, null, no.getInstanceRrn()); // D
Assert.isFalse(pcdAll != null && StringUtils.isNotBlank(pcdAll.getCarrierId()),
Errors.create().key(MessageIdList.PCD_DEASSEMBLY_PCD_FIRST).content("请先解绑PCD").build());
Door d = doorManager.getDoor(no.getInstanceRrn());
Assert.isTrue(StringUtils.equals(d.getDoorStatus(), targetStatus),
Errors.create().key(MessageIdList.PCD_STATUS_ERROR)
.content("{} current status" + " " + "is not {}!").args(pcdId, targetStatus).build());
}
}
private void batchOutCleanByPcd(String eqptId, String[] pcdIds, String pcdType, String eventId, Long facilityRrn,
String user) {
String comments = "Out clean from " + eqptId;
String targetStatus = PcdStatus.FREE_KEY;
String currentStatus = PcdStatus.IN_CLEAN_KEY;
String returnMsg = "";
for (int i = 0; i < pcdIds.length; i++) {
statusManager.changePcdStatusByLogEvent(facilityRrn, user, pcdIds[i], pcdType, eventId, comments,
targetStatus, currentStatus, eqptId);
}
}
/**
* 判断pcd的清洗时间是否大于设置的最小清洗时间
*/
private void IsPcdCleaningDateAboveThanMinMinutes(String[] pcdIds, double minMinutes, Long facilityRrn) {
if (pcdIds.length > 0) {
for (int i = 0; i < pcdIds.length; i++) {
String pcdId = StringUtils.EMPTY;
pcdId = pcdIds[i];
NamedObject no = new NamedObject(pcdId,
namedObjectManager.getNamedSpace(facilityRrn, ObjectList.ENTITY_KEY),
ObjectList.ENTITY_KEY);
no = namedObjectManager.getNamedObject(no);
Assert.isTrue(no.getInstanceRrn() > 0,
Errors.create().key(MessageIdList.PCD_PCD_MISSING).content("PCD 不存在!").build());
PcdClean pc = getPcdCleanInfo(no.getInstanceRrn());
Assert.isTrue(pc != null && pc.getInCleanDate() != null,
Errors.create().key(MessageIdList.PCD_NOT_CLEAN_RECORD).content("{} has no clean record!")
.args(pcdId).build());
Assert.isFalse(pc.getCleaningMinutes() < minMinutes,
Errors.create().key(MessageIdList.PCD_CLEAN_LESS_MIN_TIME)
.content("{} 's clean time is less than" + " min time!").args(pcdId).build());
}
}
}
private void cleanPcd(String cleanEqptId, Long pcdRrn, String performedBy, String inOrOutClean) {
if (pcdRrn != null && pcdRrn > 0) {
NamedObject pcd = new NamedObject(pcdRrn);
pcd = namedObjectManager.getNamedObject(pcd);
if (pcd != null & StringUtils.isNotBlank(pcd.getInstanceId())) {
if (StringUtils.equalsIgnoreCase(pcd.getObjectType(), ObjectList.CARRIER_KEY) ||
StringUtils.equalsIgnoreCase(pcd.getObjectType(), ObjectList.POD_KEY) ||
StringUtils.equalsIgnoreCase(pcd.getObjectType(), ObjectList.DOOR_KEY)) {
if (StringUtils.equalsIgnoreCase("in", inOrOutClean)) {
inCleanPcd(cleanEqptId, pcd, performedBy);
} else if (StringUtils.equalsIgnoreCase("out", inOrOutClean)) {
outCleanPcd(pcd, performedBy);
}
}
}
}
}
/**
* 开始清洗工作
*
* @param pcd
* @param performedBy
*/
private void inCleanPcd(String cleanEqptId, NamedObject pcd, String performedBy) {
PcdClean cleanInfo = getPcdCleanInfo(pcd.getInstanceRrn());
if (cleanInfo != null && cleanInfo.getInstanceRrn() > 0) {
TransactionLog transactionLog = transactionLogManager.startTransactionLog(performedBy,
TransactionNames.IN_CLEAN_KEY);
long currentTime = System.currentTimeMillis();
cleanInfo.setInCleanDate(new Timestamp(currentTime));
cleanInfo.setOutCleanDate(null);
cleanInfo.setCleanEqptId(cleanEqptId);
pcdDAO.updatePcdCleanInfo(cleanInfo);
pcdDAO.insertPcdCleanH(transactionLog.getTransRrn(), cleanInfo);
transactionLogManager.markTransactionLog(transactionLog);
}
}
/**
* pcd 结束清洗工作
*
* @param pcd
* @param performedBy
*/
private void outCleanPcd(NamedObject pcd, String performedBy) {
PcdClean cleanInfo = pcdDAO.getPcdCleanInfo(pcd.getInstanceRrn());
if (cleanInfo != null && cleanInfo.getInstanceRrn() > 0) {
TransactionLog transactionLog = transactionLogManager.startTransactionLog(performedBy,
TransactionNames.OUT_CLEAN_KEY);
// 清洗工作结束后,
cleanInfo.setInstanceRrn(pcd.getInstanceRrn());
long currentTime = System.currentTimeMillis();
cleanInfo.setOutCleanDate(new Timestamp(currentTime)); // 记录清洗结束时间
long cleanOverTime = (long) (currentTime + (cleanInfo.getCleanCycle() * 24 * 60 * 60 * 1000));
cleanInfo.setCleanOverDate(new Timestamp(cleanOverTime)); // 更新清洗有效期限
cleanInfo.setCleanCount(cleanInfo.getCleanCount() + 1); // 追加清洗次数
String cleanEqptId = cleanInfo.getCleanEqptId();
cleanInfo.setCleanEqptId(StringUtils.EMPTY); // 结束清洗时清除清洗机台
pcdDAO.updatePcdCleanInfo(cleanInfo);
cleanInfo.setCleanEqptId(cleanEqptId); // 历史需要记录结束清洗时的清洗机台
pcdDAO.insertPcdCleanH(transactionLog.getTransRrn(), cleanInfo);
// change cassette type 后清洗完成自动切换type
cleanExchangePCDType(cleanInfo);
transactionLogManager.markTransactionLog(transactionLog);
}
}
private void batchInCleanByPcd(String eqptId, String[] pcdIds, String pcdType, String eventId, Long facilityRrn,
String user) {
String comments = "In clean from " + eqptId;
String targetStatus = PcdStatus.IN_CLEAN_KEY;
String currentStatus = PcdStatus.WAIT_CLEAN_KEY;
for (int i = 0; i < pcdIds.length; i++) {
statusManager.changePcdStatusByLogEvent(facilityRrn, user, pcdIds[i], pcdType, eventId, comments,
targetStatus, currentStatus, eqptId);
}
}
/**
* 检查PCD是否是未绑定的空的P/C/D,并且当前状态是WAIT_CLEAN
*
* @return 返回空字符串表示是,返回不为空的字符串表示不是
*/
private void checkPcdIsExist(String[] pcdIds, Long facilityRrn) {
for (int i = 0; i < pcdIds.length; i++) {
// 检查PCD是否都存在并且是未绑定的空P/C/D
checkPcdIsExistAndNotAssemblyOrInUseAndCurrentStatus(pcdIds[i], facilityRrn, PcdStatus.WAIT_CLEAN_KEY);
}
}
@Override
public void manualExchangePCDType(Carrier carrier) {
Map<String,Object> map = getAutoChangeCassetteTypes();
String sourceCstType = MapUtils.getString(map, "sourceCstType");
String targetCstType = MapUtils.getString(map, "targetCstType");
Assert.state(StringUtils.equalsIgnoreCase(carrier.getObjectSubtype(), sourceCstType),
Errors.create().key(MessageIdList.CARRIER_MANUAL_CHANGE_TYPE_ERROR)
.content("Manual change cassette type can only is {}!").args(sourceCstType).build());
TransactionLog transactionLog = transactionLogManager
.startTransactionLog(LocalContext.getUserId(),TransactionNames.EXCHANGE_TYPE_KEY);
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("Manual exchange carrier type! Change Type:")
.append(sourceCstType)
.append("-->")
.append(targetCstType);
map.put("comments", stringBuilder.toString());
map.put("carrierRrn", carrier.getInstanceRrn());
map.put("transRrn", transactionLog.getTransRrn());
exchangePodAndDoorType(map);
//手动切换carrier type
carrier.setObjectSubtype(targetCstType);
carrier.setInstanceId(StringUtils.EMPTY);
carrierManager.exchangeCarrierType(carrier, stringBuilder.toString(), transactionLog.getTransRrn(),false);
transactionLogManager.markTransactionLog(transactionLog);
}
@Override
public void autoExchangePCDType(Long carrierRrn) {
Map<String,Object> map = getAutoChangeCassetteTypes();
String sourceCstType = MapUtils.getString(map, "sourceCstType");
String targetCstType = MapUtils.getString(map, "targetCstType");
TransactionLog transactionLog = transactionLogManager
.startTransactionLog("SYSTEM", TransactionNames.EXCHANGE_TYPE_KEY);
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("Move out auto exchange carrier type! Change Type:")
.append(sourceCstType)
.append("-->")
.append(targetCstType);
map.put("comments", stringBuilder.toString());
map.put("carrierRrn", carrierRrn);
map.put("transRrn", transactionLog.getTransRrn());
exchangePodAndDoorType(map);
//moveOut 自动切换carrier type
Carrier carrier = carrierManager.getCarrier(carrierRrn);
carrier.setObjectSubtype(targetCstType);
carrier.setTransId(TransactionNames.EXCHANGE_TYPE_KEY);
carrier.setTransPerformedby("SYSTEM");
carrier.setInstanceId(StringUtils.EMPTY);
carrierManager.exchangeCarrierType(carrier, stringBuilder.toString(), transactionLog.getTransRrn(),true);
transactionLogManager.markTransactionLog(transactionLog);
}
@Override
public void cleanExchangePCDType(PcdClean pcdClean) {
Map<String,Object> map = getAutoChangeCassetteTypes();
String sourceCstType = MapUtils.getString(map, "sourceCstType");
String targetCstType = MapUtils.getString(map, "targetCstType");
StringBuilder stringBuilder = new StringBuilder();
TransactionLog transactionLog = transactionLogManager
.startTransactionLog("SYSTEM", TransactionNames.EXCHANGE_TYPE_KEY);
if (StringUtils.equalsIgnoreCase(pcdClean.getPcdType(), Constants.PCD_TYPE.CARRIER_KEY)) {
stringBuilder.append("Clean after exchange carrier type! Change Type:")
.append(targetCstType)
.append("-->")
.append(sourceCstType);
Carrier carrier = carrierManager.getCarrier(pcdClean.getInstanceRrn());
if (StringUtils.equalsIgnoreCase(targetCstType, carrier.getObjectSubtype())) {
carrier.setObjectSubtype(sourceCstType);
carrier.setInstanceId(StringUtils.EMPTY);
carrier.setTransId(TransactionNames.EXCHANGE_TYPE_KEY);
carrier.setTransPerformedby("SYSTEM");
carrierManager.exchangeCarrierType(carrier, stringBuilder.toString(), transactionLog.getTransRrn(),false);
}
} else if(StringUtils.equalsIgnoreCase(pcdClean.getPcdType(), Constants.PCD_TYPE.POD_KEY)) {
stringBuilder.append("Clean after exchange pod type! Change Type:")
.append(targetCstType)
.append("-->")
.append(sourceCstType);
POD pod = podManager.getPod(pcdClean.getInstanceRrn());
if (StringUtils.equalsIgnoreCase(targetCstType, pod.getObjectSubtype())) {
pod.setObjectSubtype(sourceCstType);
podDAO.updatePodType(pod, stringBuilder.toString(), transactionLog.getTransRrn());
}
} else if(StringUtils.equalsIgnoreCase(pcdClean.getPcdType(), Constants.PCD_TYPE.DOOR_KEY)) {
stringBuilder.append("Clean after exchange door type! Change Type:")
.append(targetCstType)
.append("-->")
.append(sourceCstType);
Door door = doorManager.getDoor(pcdClean.getInstanceRrn());
if (StringUtils.equalsIgnoreCase(targetCstType, door.getObjectSubtype())) {
door.setObjectSubtype(sourceCstType);
doorDAO.updateDoorType(door, stringBuilder.toString(), transactionLog.getTransRrn());
}
} else {
}
transactionLogManager.markTransactionLog(transactionLog);
}
/**
* 获取类表值对应关系 change Cassette type
* A-B
* @return
*/
private Map<String,Object> getAutoChangeCassetteTypes() {
Map<String,Object> map = new HashMap<>();
boolean flag = true;
String nameSpace = namedObjectManager.getNamedSpace(LocalContext.getFacilityRrn(),
ObjectList.REFERENCE_FILE_KEY);
ReferenceFileDetail referenceFileDetail = new ReferenceFileDetail(ReferenceDetailNames.PROCESS_LOCATION_AUTO_CHANGE_CASSETTE_TYPE,
nameSpace,
ObjectList.REFERENCE_FILE_KEY);
List<ReferenceFileDetail> referenceFileDetails = referenceFileManager
.getReferenceFileDetails(referenceFileDetail, LocalContext.getFacilityRrn());
if (CollectionUtils.isNotEmpty(referenceFileDetails)) {
for (ReferenceFileDetail ref : referenceFileDetails) {
Matcher mathcher = WipUtils.PCDPATERN.matcher(ref.getData1Value());
if (mathcher.matches()){
map.put("targetCstType", StringUtils.split(ref.getData1Value(), "-")[1]);
map.put("sourceCstType", StringUtils.split(ref.getData1Value(), "-")[0]);
}
}
}else {
flag = false;
}
if (MapUtils.isEmpty(map)) {
flag = false;
}
Assert.state( flag , Errors.create().key(MessageIdList.REFERENCE_$$AUTO_CHANGE_CASSETTE_TYPE).build());
return map;
}
/**
* 判断是否绑定pod、door 如果绑定一起改变type
* @param map
*/
private void exchangePodAndDoorType(Map<String,Object> map) {
Long carrierRrn = MapUtils.getLong(map, "carrierRrn");
Long transRrn = MapUtils.getLong(map, "transRrn");
String targetCstType = MapUtils.getString(map, "targetCstType");
String comments = MapUtils.getString(map, "comments");
PcdAssembly pcdAssembly = pcdDAO.getPcdAssembly(carrierRrn);
if (ObjectUtils.isNotEmpty(pcdAssembly)){
// 修改pod type
if (pcdAssembly.getPodRrn().longValue() > 0) {
POD pod = podManager.getPod(pcdAssembly.getPodRrn().longValue());
pod.setObjectSubtype(targetCstType);
podDAO.updatePodType(pod, comments, transRrn);
}
// 修改door type
if (pcdAssembly.getDoorRrn().longValue() > 0) {
Door door = doorManager.getDoor(pcdAssembly.getDoorRrn().longValue());
door.setObjectSubtype(targetCstType);
doorDAO.updateDoorType(door, comments, transRrn);
}
}
}
}