PiLotCheckManagerImpl.java

package com.mycim.server.pilot.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.BooleanUtils;
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.time.DateUtils;
import com.mycim.server.base.manager.NamedObjectManager;
import com.mycim.server.ems.manager.EntityManager;
import com.mycim.server.ems.manager.EquipmentManager;
import com.mycim.server.pilot.manager.PiLotCheckManager;
import com.mycim.server.pilot.manager.PiLotReqManager;
import com.mycim.server.wip.manager.EquipmentQueryManager;
import com.mycim.server.wip.manager.PiLotInqManager;
import com.mycim.valueobject.Constants;
import com.mycim.valueobject.MessageIdList;
import com.mycim.valueobject.ObjectList;
import com.mycim.valueobject.consts.EntityEnum;
import com.mycim.valueobject.consts.PiLotStatusEnum;
import com.mycim.valueobject.consts.PiLotTypeEnum;
import com.mycim.valueobject.ems.Entity;
import com.mycim.valueobject.ems.Equipment;
import com.mycim.valueobject.ems.Season;
import com.mycim.valueobject.ems.pilot.IdleType;
import com.mycim.valueobject.ems.pilot.PiLotSetup;
import com.mycim.valueobject.ems.pilot.PiLotView;
import com.mycim.valueobject.ems.pilot.dto.PiLotSetupQueryDTO;
import com.mycim.valueobject.sys.Message;
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.Date;
import java.util.List;
import java.util.Objects;

/**
 * @author songpy
 * @version 1.0.0
 * @date 2021/9/12
 **/
@Service
@Transactional
public class PiLotCheckManagerImpl implements PiLotCheckManager {
    @Autowired
    private PiLotInqManager piLotInqManager;

    @Autowired
    private NamedObjectManager namedObjectManager;

    @Autowired
    private PiLotReqManager piLotReqManager;

    @Autowired
    private EquipmentQueryManager equipmentQueryManager;

    @Autowired
    private EquipmentManager equipmentManager;

    @Autowired
    private EntityManager entityManager;

    @Override
    public String checkEquipmentPiLot(Lot lot, Equipment equipment) {
        StringBuilder msg = new StringBuilder(StringUtils.EMPTY);
        PiLotView view = piLotInqManager.getPiLotViewByLotRrn(lot.getLotRrn());
        if (Objects.isNull(view)) {
            view = piLotInqManager.getPiLotViewByChildLotRrn(lot.getLotRrn());
        }

        // pilot绑定lot
        if (Objects.nonNull(view)) {
            // 绑定lot  不允许进入pilot设置机台外的其他机台
            if (StringUtils.equalsIgnoreCase(lot.getRouteId(), view.getStartRoute()) &&
                    StringUtils.equalsIgnoreCase(lot.getOperationId(), view.getStartStep())) {
                Equipment viewEquipment = equipmentManager.getEquipment(view.getEqptRrn());
                if (!StringUtils.equalsIgnoreCase(getParentEquipment(viewEquipment), getParentEquipment(equipment))) {
                    msg.append(I18nUtils.getMessage(MessageIdList.PILOT_CHECK_EQPT_IN_USE, new Object[]{equipment.getInstanceId(),view.getEqptId()}));
                }
            }
            if (StringUtils.isNotEmpty(msg.toString())) {
                return msg.toString();
            }

            if (!StringUtils.equalsIgnoreCase(equipment.getObjectSubtype(), "P")) {
                return msg.toString();
            }

            //子母批模式
            if (StringUtils.equalsIgnoreCase(view.getSingleLot(), PiLotStatusEnum.NO.toString())) {
                msg.append(checkSplitBefore(equipment, view));
                if (StringUtils.isNotEmpty(msg.toString())) {
                    return msg.toString();
                }

                msg.append(checkSplitAfter(lot, equipment, view));
                if (StringUtils.isNotEmpty(msg.toString())) {
                    return msg.toString();
                }
            }

            // 单批模式
            if (StringUtils.equalsIgnoreCase(view.getSingleLot(), PiLotStatusEnum.YES.toString())) {
                msg.append(checkSingleLot(lot,equipment,view));
                if (StringUtils.isNotEmpty(msg.toString())) {
                    return msg.toString();
                }
            }
        } else {
            // 触发pilot
            msg.append(checkIdleTimePiLot(equipment));
            if (StringUtils.isNotEmpty(msg.toString())) {
                return msg.toString();
            }

            // 校验设置pilot  其他lot卡控进入设备
            msg.append(checkEquipment(equipment));

        }
        return msg.toString();
    }

    @Override
    public void checkEquipmentPiLotByPM(String eqpId) {
        PiLotSetupQueryDTO queryDTO = new PiLotSetupQueryDTO();
        queryDTO.addStatus(PiLotStatusEnum.ON.toString());
        queryDTO.setType(PiLotTypeEnum.PM.toString());
        queryDTO.setEqptRrn(
                namedObjectManager.getNamedObjectRrn(eqpId, LocalContext.getFacilityRrn(), ObjectList.ENTITY_KEY));

        PiLotSetup setup = piLotInqManager.getPiLotSetup(queryDTO);
        if (Objects.nonNull(setup)) {
            piLotReqManager.createPiLotView(setup);
        }
    }

    @Override
    public void checkPiLotBoundLot(Long lotRrn) {
        PiLotView view = piLotInqManager.getPiLotViewByLotRrn(lotRrn);
        Assert.state(Objects.nonNull(view), Errors.create().key(MessageIdList.PILOT_NOT_USED_SPLIT)
                                                  .content("This lot cannot be used Pilot Split").build());

        Assert.state(view.getCanSplit(),
                     Errors.create().key(MessageIdList.PILOT_NOT_SPLIT).content("This Lot Not Split").build());

        Assert.state(StringUtils.equalsIgnoreCase(view.getSingleLot(), PiLotStatusEnum.NO.toString()),
                     Errors.create().key(MessageIdList.PILOT_SINGLE_LOT_CANNOT_SPLIT)
                           .content("Pilot single lot cannot split!").build());
    }

    @Override
    public void checkPiLotNormalFunction(long lotRrn,long baseLotRrn) {
        PiLotView piLotView = getPiLotView(lotRrn, baseLotRrn);
        Assert.state(ObjectUtils.isEmpty(piLotView), Errors.create().key(MessageIdList.PILOT_NOT_USED_FUNCTION)
                                                             .content("Pilot This Function cannot be used").build());
    }

    @Override
    public String checkEquipmentPiLot(Lot lot, Long eqptRrn) {
        Equipment equipment = equipmentManager.getEquipment(eqptRrn);
        return checkEquipmentPiLot(lot, equipment);
    }

    @Override
    public PiLotView getPiLotView(Long lotRrn, Long baseLotRrn) {
        PiLotView piLotView = piLotInqManager.getPiLotViewByLotRrn(lotRrn);
        if (ObjectUtils.isNotEmpty(piLotView)) {
            return piLotView;
        }
        if (lotRrn.longValue() == baseLotRrn.longValue()){
            return  piLotInqManager.getPiLotViewByLotRrn(baseLotRrn);
        } else {
            return  piLotInqManager.getPiLotViewByChildLotRrn(lotRrn);
        }
    }

    @Override
    public void checkPilotRepositionStep(Lot lot, Boolean pilotFlag) {
        PiLotView view = getPiLotView(lot.getLotRrn(),lot.getBasedLotRrn());
        if(pilotFlag) {
            if (ObjectUtils.isEmpty(view)){
                Assert.state(false, Errors.create().key(MessageIdList.PILOT_NOT_USED_SPLIT)
                                          .content("This lot cannot be used Pilot Split").build());
            }else {
                // 单批模式没有分批可以使用跳步     子母批模式未分批前不能使用跳步
                if (StringUtils.equalsIgnoreCase(view.getSingleLot(), PiLotStatusEnum.NO.toString())) {
                    Assert.state(StringUtils.isNotEmpty(view.getChildLotId()), Errors.create().key(MessageIdList.PILOT_NOT_SPLIT)
                                                                                     .content("This Lot Not Split").build());
                }
            }
        } else {
            Assert.state(ObjectUtils.isEmpty(view), Errors.create().key(MessageIdList.PILOT_NOT_USED_FUNCTION)
                                                          .content("Pilot This Function cannot be used").build());
        }
    }

    private String checkSplitAfter(Lot lot, Equipment equipment, PiLotView view) {
        StringBuilder msg = new StringBuilder();
        PiLotView piLotView = piLotInqManager.getSplitAfterPiLotViewByEqpt(equipment.getInstanceId(),
                                                                           equipment.getInstanceRrn());

        // 分批后母批不能进入任何设备  子批只能走pilot chamber     #42103
        // 没有设置pilot其他的chamber #42283
        if(ObjectUtils.isEmpty(piLotView)
                && StringUtils.equalsIgnoreCase(view.getStatus(), PiLotStatusEnum.WAITMERGE.toString())
                && StringUtils.isNotEmpty(equipment.getParentEntityId())) {
            Equipment parentEquipment = equipmentManager.getEquipment(equipment.getParentEntityRrn());
            //子批flow未完成
            if (!view.getComplete()) {
                //母批 需等待
                if (StringUtils.equalsIgnoreCase(view.getBoundLotId(),lot.getLotId())) {
                    msg.append(I18nUtils.getMessage(MessageIdList.PILOT_CHILDLOT_FLOW_NOCOMPLETE,"{}:Pilot child lot flow not complete!",
                                                    new Object[]{equipment.getInstanceId()}));
                }
                //子批
                if (StringUtils.equalsIgnoreCase(view.getChildLotId(),lot.getLotId())) {
                    checkPilotChamber(equipment, parentEquipment, view.getParallelRunType(), msg);
                }
                //子批flow完成 子批hold  母批走flow
            } else {
                checkPilotChamber(equipment, parentEquipment, view.getParallelRunType(), msg);
            }
        }

        if (Objects.isNull(piLotView)) {
            return msg.toString();
        }

        // 母批
        if (StringUtils.equalsIgnoreCase(lot.getLotId(), piLotView.getBoundLotId())) {
            if (!piLotView.getComplete()) {
                msg.append(I18nUtils.getMessage(MessageIdList.PILOT_CHILDLOT_FLOW_NOCOMPLETE,"{}:Pilot child lot flow not complete!",
                                                new Object[]{equipment.getInstanceId()}));
            }
        }

        return msg.toString();
    }

    private String checkSplitBefore(Equipment equipment,PiLotView view) {
        // 先检查是否存在已经触发的
        StringBuilder msg = new StringBuilder();
        List<PiLotView> piLotViewList = piLotInqManager.getSplitBeforePiLotViewByEqpt(equipment.getInstanceId(),
                                                                                      equipment.getInstanceRrn());

        // 分批前母批 不能进入任何设备  chamber
        if(CollectionUtils.isEmpty(piLotViewList)) {
            if((StringUtils.equalsIgnoreCase(view.getStatus(),PiLotStatusEnum.WAITSPLIT.toString()) ||
                    (StringUtils.equalsIgnoreCase(view.getStatus(),PiLotStatusEnum.WAITMERGE.toString()) &&
                            StringUtils.isEmpty(view.getChildLotId()))
                    ) && StringUtils.isNotEmpty(equipment.getParentEntityId())) {
                msg.append(I18nUtils.getMessage(MessageIdList.PILOT_PARENT_LOT_NOT_SPLIT,"{}:Pilot parent lot not spilt!",
                                                new Object[]{equipment.getInstanceId()}));
            }
        }

        for (PiLotView piLotView : piLotViewList) {
           if (StringUtils.equalsIgnoreCase(piLotView.getStatus(), PiLotStatusEnum.WAITSPLIT.toString()) ||
                    (StringUtils.equalsIgnoreCase(piLotView.getStatus(),PiLotStatusEnum.WAITMERGE.toString()) &&
                    StringUtils.isEmpty(piLotView.getChildLotId()))) {
                msg.append(I18nUtils.getMessage(MessageIdList.PILOT_PARENT_LOT_NOT_SPLIT,"{}:Pilot parent lot not spilt!",
                                                new Object[]{equipment.getInstanceId()}));
           }
        }
        return msg.toString();
    }

    private String checkIdleTimePiLot(Equipment equipment) {
        StringBuilder msg = new StringBuilder();
        Boolean needPiLot = false;
        PiLotSetup piLotSetup = piLotInqManager.getPiLotSetupIdleByEquipment(equipment.getInstanceId(),
                                                                             equipment.getInstanceRrn());
        if (Objects.nonNull(piLotSetup)) {

            needPiLot = checkNeedPilotByTime(piLotSetup, equipment, needPiLot);

            if (Boolean.TRUE.equals(needPiLot)) {
                piLotReqManager.createPiLotView(piLotSetup);
                piLotSetup = piLotInqManager.getPiLotSetupByRrn(piLotSetup.getPiLotRrn());
                PiLotView view = piLotInqManager.getPiLotViewByRrn(piLotSetup.getBoundViewRrn());
                // msg.append("Pilot:" + view.getViewId() + ",Please handle(bound Lot)!</br>");
                msg.append(I18nUtils.getMessage(MessageIdList.PILOT_SETUP_AND_TRIGGER, "{}:setup and trigger pilot!Please assign lot!Pilot numberId:{}!",
                                                new Object[]{equipment.getInstanceId(), view.getViewId()}));
            }
        }
        return msg.toString();
    }

    private Long getEquipmentMaxRunTime(PiLotSetup piLotSetup, IdleType idleType, Equipment equipment) {
        Long maxRunTime;
        String lastMoveInTimeStr;
        Date sysDate = new Date(System.currentTimeMillis());
        Date lastUpdateTime = Objects.nonNull(
                piLotSetup.getCloseTime()) ? piLotSetup.getCloseTime() : piLotSetup.getCreateTime();
        Entity entity = entityManager.getEntity(equipment.getInstanceRrn());
        if (StringUtils.endsWithIgnoreCase(Season.SUBTYPE_LOTLEVEL, idleType.getSubType())) {

            lastMoveInTimeStr = equipmentQueryManager.getLastMoveInTimeByEqp(equipment.getInstanceId(),
                                                                             equipment.getInstanceRrn());
        } else {
            Entity parentEntity = entityManager.getEntity(entity.getParentEntityRrn());
            lastMoveInTimeStr = equipmentQueryManager.getLastProcessStartTime(parentEntity.getInstanceRrn(),
                                                                              parentEntity.getInstanceId(),
                                                                              entity.getChamberType());

        }

        Date maxRunTimeStart = getEffectiveTime4PiLot(lastMoveInTimeStr, lastUpdateTime);

        maxRunTime = sysDate.getTime() - maxRunTimeStart.getTime();
        return maxRunTime;
    }

    private Long getEquipmentIdleByWaferLevel(Equipment equipment, PiLotSetup piLotSetup) {
        Long idleTimeSum = 0L;
        Date sysDate = new Date(System.currentTimeMillis());
        Date lastUpdateTime = Objects.nonNull(
                piLotSetup.getCloseTime()) ? piLotSetup.getCloseTime() : piLotSetup.getCreateTime();
        String equipmentStatus = entityManager.getEntityCurrentStatus(equipment.getInstanceRrn());
        Entity entity = entityManager.getEntity(equipment.getInstanceRrn());
        String mainEquipmentId = namedObjectManager.getNamedObjectId(entity.getParentEntityRrn());

        if (StringUtils.equalsIgnoreCase(EntityEnum.IDLE.getValue(), equipmentStatus)) {
            String lastProcessEndTimeStr = equipmentQueryManager.getLastProcessEndTime(mainEquipmentId,
                                                                                       entity.getChamberType());
            Date lastProcessEndTime = getEffectiveTime4PiLot(lastProcessEndTimeStr, lastUpdateTime);
            idleTimeSum = sysDate.getTime() - lastProcessEndTime.getTime();
        } else if (StringUtils.equalsIgnoreCase(EntityEnum.RUN.getValue(), equipmentStatus)) {
            if (equipmentQueryManager.checkEquipmentHasRunningLot(entity.getParentEntityRrn())) {
                idleTimeSum = 0L;
            } else {
                Date idleStartTime;
                String lastHoldTimeStr = equipmentQueryManager.getLastHoldTimeOnEqp(entity.getParentEntityRrn());
                String equipmentLastMoveOutTimeStr = equipmentQueryManager.getLastProcessEndTime(mainEquipmentId,
                                                                                                 entity.getChamberType());
                idleStartTime = getEffectiveTime4PiLot(lastHoldTimeStr, lastUpdateTime);
                idleStartTime = getEffectiveTime4PiLot(equipmentLastMoveOutTimeStr, idleStartTime);
                idleTimeSum = sysDate.getTime() - idleStartTime.getTime();
            }
        }
        return idleTimeSum;
    }

    private Long getEquipmentIdleByLotLevel(Equipment equipment, PiLotSetup piLotSetup) {
        Long idleTimeSum = 0L;
        Date sysDate = new Date(System.currentTimeMillis());
        Date lastUpdateTime = Objects.nonNull(
                piLotSetup.getCloseTime()) ? piLotSetup.getCloseTime() : piLotSetup.getCreateTime();
        String equipmentStatus = entityManager.getEntityCurrentStatus(equipment.getInstanceRrn());
        if (StringUtils.equalsIgnoreCase(EntityEnum.IDLE.getValue(), equipmentStatus)) {

            String equipmentLastMoveOutTimeStr = equipmentQueryManager.getEquipmentLastMoveOutTime(
                    equipment.getInstanceId());
            Date equipmentLastMoveOutTime = getEffectiveTime4PiLot(equipmentLastMoveOutTimeStr, lastUpdateTime);
            idleTimeSum = sysDate.getTime() - equipmentLastMoveOutTime.getTime();

        } else if (StringUtils.equalsIgnoreCase(EntityEnum.RUN.getValue(), equipmentStatus)) {
            if (equipmentQueryManager.checkEquipmentHasRunningLot(equipment.getInstanceRrn())) {
                idleTimeSum = 0L;
            } else {
                String lastHoldTimeStr = equipmentQueryManager.getLastHoldTimeOnEqp(equipment.getInstanceRrn());
                String equipmentLastMoveOutTimeStr = equipmentQueryManager.getEquipmentLastMoveOutTime(
                        equipment.getInstanceId());
                Date idleStartTime = getEffectiveTime4PiLot(lastHoldTimeStr, lastUpdateTime);
                idleStartTime = getEffectiveTime4PiLot(equipmentLastMoveOutTimeStr, idleStartTime);
                idleTimeSum = sysDate.getTime() - idleStartTime.getTime();
            }
        }
        return idleTimeSum;
    }

    private Date getEffectiveTime4PiLot(String timeStr, Date lastUpdateTime) {
        Date effectiveTime;
        if (StringUtils.isNotBlank(timeStr)) {
            effectiveTime = DateUtils.parse(timeStr, DateUtils.DATE_FORMAT);
        } else {
            effectiveTime = lastUpdateTime;
        }
        effectiveTime = effectiveTime.after(lastUpdateTime) ? effectiveTime : lastUpdateTime;
        return effectiveTime;
    }

    private String getParentEquipment(Equipment equipment){
        if(StringUtils.isNotEmpty(equipment.getParentEntityId())){
            return equipment.getParentEntityId();
        }else {
            return equipment.getInstanceId();
        }
    }

    private String checkSingleLot(Lot lot, Equipment equipment,PiLotView view) {
        StringBuilder msg = new StringBuilder();
        PiLotView piLotView = piLotInqManager.getSingleLotPiLotViewByEqpt(equipment.getInstanceId(),
                                                                                      equipment.getInstanceRrn());
        //chamber机台 pilot逻辑
        if (Objects.isNull(piLotView) && StringUtils.isNotEmpty(equipment.getParentEntityId())) {
            Equipment parentEquipment = equipmentManager.getEquipment(equipment.getParentEntityRrn());
            checkPilotChamber(equipment, parentEquipment, view.getParallelRunType(), msg);
        }

        if (Objects.isNull(piLotView)) {
            return msg.toString();
        }

        return msg.toString();
    }

    // 没有绑定pilot的lot
    private String checkEquipment(Equipment equipment) {
        StringBuilder msg = new StringBuilder();
        PiLotView piLotView = piLotInqManager.getPiLotViewByEqpt(equipment.getInstanceId(),
                                                                        equipment.getInstanceRrn());

        if (Objects.isNull(piLotView)) {
            return msg.toString();
        }

        if (StringUtils.equalsIgnoreCase(piLotView.getStatus(), PiLotStatusEnum.ONGOING.toString())
                && StringUtils.isEmpty(piLotView.getBoundLotId())) {
            msg.append(I18nUtils.getMessage(MessageIdList.PILOT_NOT_ASSIGN_LOT, "{}:setup pilot!Please assign lot!Pilot NumberId:{}!",
                                            new Object[]{equipment.getInstanceId(), piLotView.getViewId()}));
        } else if ( StringUtils.equalsIgnoreCase(piLotView.getStatus(), PiLotStatusEnum.WAITCOMPLETE.toString()) ||
                    StringUtils.equalsIgnoreCase(piLotView.getStatus(), PiLotStatusEnum.WAITMERGE.toString()) ||
                    StringUtils.equalsIgnoreCase(piLotView.getStatus(), PiLotStatusEnum.WAITSPLIT.toString())){
            msg.append(I18nUtils.getMessage(MessageIdList.PILOT_EQPT_SETUP_PILOT, "{}:setup pilot!Pilot NumberId:{}!",
                                            new Object[]{equipment.getInstanceId(),piLotView.getViewId()}));
        }
        return msg.toString();
    }

    /**
     * pilot chamber机台卡控逻辑
     * @param equipment
     * @param parentEquipment
     * @param runType
     * @param msg
     */
    private void checkPilotChamber(Equipment equipment, Equipment parentEquipment, String runType, StringBuilder msg) {
        // 并行chamber single模式卡控
        if (StringUtils.equalsIgnoreCase(parentEquipment.getChamberMode(), PiLotStatusEnum.PARALLEL.toString()) &&
                StringUtils.equalsIgnoreCase(runType, PiLotStatusEnum.SINGLE.toString())) {
            msg.append(I18nUtils.getMessage(MessageIdList.PILOT_PARALLEL_EQPT_SIGNLE,"{}:Pilot setup parallel run type is single!",
                                            new Object[]{equipment.getInstanceId()}));
        }
        // 并行chamber mulit模式  其他腔设置pilot
        if (StringUtils.equalsIgnoreCase(parentEquipment.getChamberMode(), PiLotStatusEnum.PARALLEL.toString()) &&
                StringUtils.equalsIgnoreCase(runType, PiLotStatusEnum.MULTI.toString())) {
            PiLotView otherPiLotView = piLotInqManager.getPiLotViewByEqpt(equipment.getInstanceId(),
                                                                                    equipment.getInstanceRrn());
            if (ObjectUtils.isNotEmpty(otherPiLotView)) {
                msg.append(I18nUtils.getMessage(MessageIdList.PILOT_EQPT_SETUP_PILOT, "{}:setup pilot!Pilot NumberId:{}!",
                                                new Object[]{equipment.getInstanceId(),otherPiLotView.getViewId()}));
            }
        }
    }

    /**
     * 判断是否满足by idletime的pilot 触发条件
     * @param piLotSetup
     * @param equipment
     * @param needPiLot
     * @return
     */
    @Override
    public Boolean checkNeedPilotByTime(PiLotSetup piLotSetup, Equipment equipment, Boolean needPiLot) {
        IdleType idleType = piLotSetup.getIdle();
        double idleTime = idleType.getIdleTime() * 60 * 60 * 1000;
        double maxRunTime = idleType.getMaxRunTime() * 60 * 60 * 1000;
        Long idleTimeSum = 0L;
        Long realmaxRunTime = 0L;
        if (StringUtils.equalsIgnoreCase(idleType.getSubType(), IdleType.SUBTYPE_LOTLEVEL.toString())) {
            idleTimeSum = getEquipmentIdleByLotLevel(equipment, piLotSetup);
        } else if (StringUtils.equalsIgnoreCase(idleType.getSubType(), IdleType.SUBTYPE_WAFERLEVEL.toString())) {
            idleTimeSum = getEquipmentIdleByWaferLevel(equipment, piLotSetup);
        }

        if (idleTimeSum > 0 && idleTimeSum > idleTime) {
            needPiLot = true;
        } else if (idleTimeSum == 0 && maxRunTime != 0) {
            realmaxRunTime = getEquipmentMaxRunTime(piLotSetup, idleType, equipment);
            if (realmaxRunTime > maxRunTime) {
                needPiLot = true;
            }
        }
        return needPiLot;
    }


}