LotAutoMonitorReqManagerImpl.java

package com.mycim.server.automonitor.manager.impl;

import com.fa.sesa.threadlocal.LocalContext;
import com.mycim.framework.oid.IDGenerators;
import com.mycim.framework.oid.type.IDNames;
import com.mycim.framework.oid.type.SequenceNames;
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.server.automonitor.dao.LotAutoMonitorReqDao;
import com.mycim.server.automonitor.manager.AutoMonitorItemInqManager;
import com.mycim.server.automonitor.manager.LotAutoMonitorInqManager;
import com.mycim.server.automonitor.manager.LotAutoMonitorReqManager;
import com.mycim.server.base.manager.TransactionLogManager;
import com.mycim.server.carrier.manager.CarrierManager;
import com.mycim.server.carrier.manager.PcdManager;
import com.mycim.server.prp.manager.WorkflowManager;
import com.mycim.server.wip.manager.*;
import com.mycim.utils.CheckRegexUtils;
import com.mycim.valueobject.ObjectList;
import com.mycim.valueobject.automonitor.dto.AutoMonitorJobDTO;
import com.mycim.valueobject.automonitor.entity.*;
import com.mycim.valueobject.automonitor.util.AutoMonitorOperationConstants;
import com.mycim.valueobject.automonitor.util.AutoMonitorUtils;
import com.mycim.valueobject.automonitor.util.MonitorJobStatusConts;
import com.mycim.valueobject.bas.TransactionLog;
import com.mycim.valueobject.consts.LotInfoConstants;
import com.mycim.valueobject.consts.TransactionNames;
import com.mycim.valueobject.ems.Carrier;
import com.mycim.valueobject.ems.Equipment;
import com.mycim.valueobject.wip.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.rmi.RemoteException;
import java.util.*;

/**
 * @author finatice.yang
 * @date 2021/8/31
 **/
@Service
@Transactional
public class LotAutoMonitorReqManagerImpl implements LotAutoMonitorReqManager {

    @Autowired
    LotAutoMonitorReqDao lotAutoMonitorDao;

    @Autowired
    LotAutoMonitorInqManager lotAutoMonitorInqManager;

    @Autowired
    AutoMonitorItemInqManager autoMonitorItemInqManager;

    @Autowired
    TransactionLogManager transactionLogManager;

    @Autowired
    LotManager lotManager;

    @Autowired
    LotQueryManager lotQueryManager;

    @Autowired
    LotInqManager lotInqManager;

    @Autowired
    LotReqManager lotReqManager;

    @Autowired
    LotTransHistoryReqManager lotTransHistoryReqManager;

    @Autowired
    LotStepHistoryReqManager lotStepHistoryReqManager;

    @Autowired
    UnitManager unitManager;

    @Autowired
    UnitQueryManager unitQueryManager;

    @Autowired
    PcdManager pcdManager;

    @Autowired
    CarrierManager carrierManager;

    @Autowired
    WorkflowManager workflowManager;

    @Autowired
    WipWorkflowQueryManager wipWorkflowQueryManager;


    @Override
    public void insertLotMonitorJobStore(TransactionLog transactionLog, LotMonitorJobStore store) {
        lotAutoMonitorDao.insertLotMonitorJobStore(store);
        lotAutoMonitorDao.insertLotMonitorJobStoreHistory(transactionLog, store);
    }

    @Override
    public void updateMonitorJobStatus(TransactionLog transactionLog, Long lotRrn, String jobStatus) {
        LotMonitorJobStore store = new LotMonitorJobStore();
        store.setLotRrn(lotRrn);
        store.setJobStatus(jobStatus);
        lotAutoMonitorDao.updateLotMonitorJobStore(store);

        store = lotAutoMonitorInqManager.getLotMonitorJobStore(lotRrn);
        lotAutoMonitorDao.insertLotMonitorJobStoreHistory(transactionLog, store);
    }

    @Override
    public void insertLotMonitorStepEdcInfo(List<LotMonitorJobStepEdcInfo> stepEdcInfoList) {
        lotAutoMonitorDao.insertLotMonitorStepEdcInfo(stepEdcInfoList);
    }

    @Override
    public void insertMonitorCarrierMapping(List<MonitorCarrierMapping> monitorCarrierMappings) {
        lotAutoMonitorDao.insertMonitorCarrierMapping(monitorCarrierMappings);
    }

    @Override
    public void updateMonitorCarrierMapping(List<MonitorCarrierMapping> monitorCarrierMappings,
                                            Long monitorCarrierRrn) {
        lotAutoMonitorDao.deleteMonitorCarrierMappingByCarrier(monitorCarrierRrn);
        lotAutoMonitorDao.insertMonitorCarrierMapping(monitorCarrierMappings);
    }

    @Override
    public void deleteMonitorCarrierMappingByLot(Long lotRrn) {
        lotAutoMonitorDao.deleteMonitorCarrierMappingByLot(lotRrn);
    }

    @Override
    public void amfinishLot(Lot lot) {
        TransactionLog transactionLog = transactionLogManager
                .startTransactionLog(LocalContext.getUserId(), TransactionNames.AUTO_MONITOR_AMFINISH);

        Lot updateLot = new Lot(lot.getLotRrn());
        updateLot.setEqptRrn(NumberUtils.LONG_ZERO);
        updateLot.setBeforeStatus(lot.getLotStatus());
        updateLot.setLotStatus(LotStatus.AUTO_MONITOR_JOB_FINISH);

        // 将mother lot的merge info填入lot 中
        LotMonitorJobStore jobStore = lotAutoMonitorInqManager.getLotMonitorJobStore(lot.getLotRrn());
        if (Objects.nonNull(jobStore)) {
            updateLot.setFlowSeq(wipWorkflowQueryManager.getFlowSeqByWflStep(jobStore.getMergeWflStep()));
        }
        updateLot.setStageId(AutoMonitorOperationConstants.PARENT_MERGE_STAGE);
        lotReqManager.updateLot(updateLot);

        updateLot = lotInqManager.getLot(lot.getLotRrn());
        lotTransHistoryReqManager.createLotTransHistory(transactionLog, updateLot, StringUtils.EMPTY);

        updateMonitorJobStatus(transactionLog, lot.getLotRrn(), MonitorJobStatusConts.FINISH_KEY);

        transactionLogManager.markTransactionLog(transactionLog);
    }

    @Override
    public boolean synAutoMonitorJobInfo(LotAutoMonitorInfo monitorInfo, String transId) {
        if (Objects.isNull(monitorInfo)) {
            return false;
        }
        if (AutoMonitorUtils.checkJobStatusIsFixed(monitorInfo.getJobStatus())) {
            return false;
        }

        TransactionLog transactionLog = transactionLogManager
                .startTransactionLog(LocalContext.getUserId(), transId);
        Long lotRrn = monitorInfo.getLotRrn();

        if (StringUtils.equals(AutoMonitorOperationConstants.STEP_TYPE_MAIN, monitorInfo.getEqptType())) {
            updateMonitorJobStatus(transactionLog, lotRrn, MonitorJobStatusConts.WAIT_PROCESS_KEY);
        } else if (StringUtils.equals(MonitorJobStatusConts.WAIT_PROCESS_KEY, monitorInfo.getJobStatus())) {
            updateMonitorJobStatus(transactionLog, lotRrn, MonitorJobStatusConts.PROCESSED_KEY);
        }

        return true;
    }

    @Override
    public boolean synAutoMonitorJobInfo(TransactionLog transactionLog, LotAutoMonitorInfo monitorInfo) {
        if (Objects.isNull(monitorInfo)) {
            return false;
        }
        if (AutoMonitorUtils.checkJobStatusIsFixed(monitorInfo.getJobStatus())) {
            return false;
        }

        Long lotRrn = monitorInfo.getLotRrn();
        if (StringUtils.equals(AutoMonitorOperationConstants.STEP_TYPE_MAIN, monitorInfo.getEqptType())) {
            updateMonitorJobStatus(transactionLog, lotRrn, MonitorJobStatusConts.WAIT_PROCESS_KEY);
        } else if (StringUtils.equals(MonitorJobStatusConts.WAIT_PROCESS_KEY, monitorInfo.getJobStatus())) {
            updateMonitorJobStatus(transactionLog, lotRrn, MonitorJobStatusConts.PROCESSED_KEY);
        }

        return true;
    }

    @Override
    public void splitLotByAutoMonitor(TransactionLog transactionLog, AutoMonitorJobDTO monitorJobDTO) {
        Lot childLot = monitorJobDTO.getChildLot();
        Lot parentLot = monitorJobDTO.getParentLot();

        childLot = createChildLotByAutoMonitor(transactionLog, monitorJobDTO);

        Integer parentQty = parentLot.getInt_qty1().intValue() - monitorJobDTO.getUnitList().size();
        parentLot.setQty1(parentQty.doubleValue());
        lotManager.updateLotQty(parentLot);

        lotTransHistoryReqManager.createLotTransHistory(transactionLog, parentLot, childLot.getLotId());
    }

    @Override
    public void mergeLotByAutoMonitor(TransactionLog transactionLog, Lot parentLot, List<Lot> childLotList) {
        List<Map> newUnits = new ArrayList<>();

        List<Map<String, Object>> childLots = new ArrayList<>();
        for (Lot childLot : childLotList) {
            List<Unit> unitList = unitQueryManager.getUnitList(childLot.getLotRrn());
            List<Map<String, Object>> units = buildUnits(unitList, childLot.getLotId(), false);
            childLot.setUnitsInfo(units);
        }

        TransReason transReason = new TransReason();
        transReason.setReasonCode(StringUtils.EMPTY);
        transReason.setResponsibility(LocalContext.getUserId());
        transReason.setReason(transactionLog.getComments());

        mergeLot(transactionLog, parentLot, childLotList, transReason);
    }

    @Override
    public void exchangeAutoMonitorLotCarrier(TransactionLog transactionLog, LotAutoMonitorInfo lotAutoMonitorInfo,
                                              Long targetCarrierRrn) {
        String userId = LocalContext.getUserId();
        Long facilityRrn = LocalContext.getFacilityRrn();

        String transId = transactionLog.getTransId();

        // update target Carrier info
        List<Lot> targetLotList = lotInqManager.getLotListByCarrierRrn(targetCarrierRrn);
        long targetQty = NumberUtils.LONG_ZERO.longValue();
        for (Lot targetLot : targetLotList) {
            targetQty += targetLot.getInt_qty1().longValue();
        }

        Carrier targetCarrier = carrierManager.getCarrier(targetCarrierRrn);
        pcdManager.changeStatusFromFreeOrAssemblyToInUse(facilityRrn, userId, targetCarrierRrn, StringUtils.EMPTY);

        // update lot carrierRrn
        Lot updateLot = new Lot(lotAutoMonitorInfo.getLotRrn());
        updateLot.setCarrierRrn(targetCarrierRrn);
        updateLot.setCarrierSharedFlag(lotAutoMonitorInfo.getLotRrn() + "");
        lotReqManager.updateLot(updateLot);

        // update unit to new carrierRrn
        List<MonitorCarrierMapping> carrierMappingList = lotAutoMonitorInqManager
                .getMonitorCarrierMappings(lotAutoMonitorInfo.getMonitorCarrierRrn());
        List<Unit> unitList = new ArrayList<>();
        for (MonitorCarrierMapping carrierMapping : carrierMappingList) {
            if (carrierMapping.getLotRrn().longValue() == lotAutoMonitorInfo.getLotRrn()) {
                Unit unit = new Unit();
                unit.setUnitRrn(carrierMapping.getUnitRrn());
                if (StringUtils.equals(TransactionNames.AUTO_MONITOR_MERGE, transId)) {
                    unit.setPositionInCarrier(carrierMapping.getSourcePosition());
                } else {
                    unit.setPositionInCarrier(carrierMapping.getPosition());
                }
                unit.setCarrierRrn(targetCarrierRrn);
                unitList.add(unit);
            }
        }
        if (CollectionUtils.isNotEmpty(unitList)) {
            unitManager.updateUnitListWithChangeCarrier(unitList);
        }

        // merge check carrier to FREE
        if (StringUtils.equals(TransactionNames.AUTO_MONITOR_MERGE, transId)) {
            Long oldCarrierRrn = lotAutoMonitorInfo.getCarrierRrn();
            List<Lot> monitorCarrierLotList = lotInqManager.getLotListByCarrierRrn(oldCarrierRrn);
            if (CollectionUtils.isEmpty(monitorCarrierLotList)) {
                pcdManager.changeStatusFromInUseToFreeOrAssembly(facilityRrn, userId, oldCarrierRrn, StringUtils.EMPTY);
            }
        }

        Lot lot = lotInqManager.getLot(lotAutoMonitorInfo.getLotRrn());
        if (lotAutoMonitorInfo.isBySort()){
            lot.setSorterFlag(true);
            lot.setLocation(lotAutoMonitorInfo.getSorterEqptId());
            lot.setEqptRrn(lotAutoMonitorInfo.getSorterEqptRrn());
        }
        lotTransHistoryReqManager.createLotTransHistory(transactionLog,lot,StringUtils.EMPTY);
    }

    @Override
    public void insertAutoMonitorUnit(List<AutoMonitorUnitInfo> unitInfoList) {
        lotAutoMonitorDao.insertAutoMonitorUnit(unitInfoList);
    }

    private void mergeLot(TransactionLog transactionLog, Lot parentLot, List<Lot> childLotList,
                          TransReason transReason) {
        String userId = LocalContext.getUserId();
        Long facilityRrn = LocalContext.getFacilityRrn();

        List<Unit> targetParentUnits = unitQueryManager.getUnitList(parentLot.getLotRrn());

        double mergeQty1 = 0;
        double mergeQty2 = 0;

        for (Lot childLot : childLotList) {
            Double qty1 = childLot.getInt_qty1().doubleValue();
            Double qty2 = childLot.getInt_qty2().doubleValue();

            List<Unit> targetChildUnitList = unitQueryManager.getUnitList(childLot.getLotRrn());

            Carrier carrier = carrierManager.setCarrierForVirtual(userId, facilityRrn, childLot.getLotId(), qty1);
            Carrier virtualCarrier = carrierManager.getCarrier(carrier);
            Long virtualCstRrn = Objects.isNull(virtualCarrier) ? carrierManager.insertCarrier(carrier) : virtualCarrier
                    .getInstanceRrn();
            carrier.setInstanceRrn(virtualCstRrn);
            carrier = carrierManager.getCarrier(carrier);

            childLot.setTransPerformedby(transactionLog.getTransPerformedBy());
            childLot.setTransId(transactionLog.getTransId() + "_" + TransactionNames.VIRTUAL_KEY);
            childLot.setLotComments(
                    "After merge Lot,the Casstte is released,The initial Casstte Id is:" + parentLot.getCarrierId());
            carrierManager.createCarrierMapping(transactionLog.getTransRrn(), carrier, childLot.getUnitsInfo());

            Lot updateLot = new Lot(childLot.getLotRrn());
            updateLot.setBeforeStatus(childLot.getLotStatus());
            updateLot.setLotStatus(LotStatus.TERMINATED);
            updateLot.setCarrierRrn(carrier.getInstanceRrn());
            updateLot.setJobRrn(NumberUtils.LONG_ZERO);
            updateLot.setQty1(NumberUtils.DOUBLE_ZERO);
            lotReqManager.updateLot(updateLot);

            // setp3-2: create lot_trans_h
            lotTransHistoryReqManager.createLotTransHistory(transactionLog, childLot, transReason.getReason());

            mergeQty1 += qty1.doubleValue();
            mergeQty2 += qty2.doubleValue();
            targetParentUnits.addAll(targetChildUnitList);
        }

        double parentQty1 = parentLot.getInt_qty1().doubleValue() + mergeQty1;
        double parentQty2 = parentLot.getInt_qty2().doubleValue() + mergeQty2;
        parentLot.setQty1(parentQty1);
        parentLot.setQty2(parentQty2);
        lotTransHistoryReqManager.createLotTransHistory(transactionLog, parentLot, transReason.getReason());

        // step5:update th lot qty
        Lot updateLot = new Lot(parentLot.getLotRrn());
        updateLot.setQty1(parentQty1);
        updateLot.setQty2(parentQty2);
        lotReqManager.updateLot(updateLot);

        // create unit step range history
        unitManager.transferUnitInALot(transactionLog, parentLot, targetParentUnits);
        unitManager.createUnitStepRangeHistory(transactionLog, parentLot, targetParentUnits);

        // step7:update lot step hitory
        LotStepHistory lotStepHistory = new LotStepHistory(parentLot.getLotRrn(), parentLot.getStepSequence());
        lotStepHistory.setMergeQty1(new Double(parentQty1).intValue());
        lotStepHistory.setMergeQty2(new Double(parentQty2).intValue());
        lotStepHistoryReqManager.updateLotStepHistory(lotStepHistory);

        lotManager.insertTransReason(transactionLog.getTransRrn(), parentLot.getLotRrn(), transReason,
                                     NumberUtils.INTEGER_ONE);
    }

    private List<Map<String, Object>> buildUnits(List<Unit> unitList, String lotId, Boolean rePosition) {
        List<Map<String, Object>> units = new ArrayList<>();
        for (Unit unit : unitList) {
            Map<String, Object> map = MapUtils.newHashMap();
            if (rePosition) {
                map.put("position", StringUtils.substringAfter(unit.getUnitId(), "#"));
            } else {
                map.put("position", unit.getPositionInCarrier() + "");
            }

            map.put("unitId", unit.getUnitId());
            map.put("unitRrn", unit.getUnitRrn() + "");
            map.put("dummyflag", unit.getDummyFlag());
            map.put("available", CheckRegexUtils.FLAG_ON);
            map.put("lotid", lotId);

            units.add(map);
        }
        return units;
    }

    private Lot createChildLotByAutoMonitor(TransactionLog transactionLog, AutoMonitorJobDTO monitorJobDTO) {
        Lot childLot = monitorJobDTO.getChildLot();
        Lot parentLot = monitorJobDTO.getParentLot();

        AutoMonitorItem monitorItem = monitorJobDTO.getMonitorItem();
        Long workflowRrn = monitorItem.getWorkflowRrn();
        Integer workflowVersion = monitorItem.getWorkflowVersion();

        // step-1 : get split runcard workflow
        String stepNumber = workflowManager.getFirstWflStepInWorkflow(workflowRrn, workflowVersion);
        childLot = lotManager.buildLotProcessStepInfo(childLot, workflowRrn, workflowVersion, stepNumber);
        childLot.setProcessRrn(parentLot.getProcessRrn());
        childLot.setProcessId(parentLot.getProcessId());
        childLot.setProcessVersion(parentLot.getProcessVersion());
        childLot.setRouteRrn(null);
        childLot.setRouteId(null);
        childLot.setBeforeStatus(StringUtils.EMPTY);
        childLot.setStartedFlag(CheckRegexUtils.FLAG_ON);
        childLot.setDummyFlag(CheckRegexUtils.FLAG_ON);
        childLot.setLotRrn(createNewRrn());
        childLot.setBasedLotRrn(parentLot.getLotRrn());
        childLot.setCreatedTimestamp(transactionLog.getTransStartTimestamp());
        childLot.setCarrierSharedFlag(childLot.getLotId());

        AutoMonitorItemStep stepInfo = autoMonitorItemInqManager
                .getAutoMonitorItemStep(workflowRrn, workflowVersion, childLot.getOperationRrn());
        if (Objects.nonNull(stepInfo)) {
            childLot.setStepType(stepInfo.getEqptType());
            childLot.setOperationDesc(stepInfo.getOperationDesc());
            childLot.setFlowSeq(stepInfo.getFlowSeq());
            childLot.setStageId(stepInfo.getStageId());
        }

        childLot.setIsDummyLot(Boolean.TRUE);
        childLot.setSysType(LotInfoConstants.SysType.AUTOMONITOR.toString());

        lotReqManager.insertLot(childLot);

        // step 2: create carrier mapping
        // 清洗时间超出,晶舟不能使用
        Carrier carrier = carrierManager.getCarrier(childLot.getCarrierRrn());
        childLot.setCarrierMapRrn(carrier.getCarrierMapRrn());

        List<Unit> childUnitList = monitorJobDTO.getUnitList();

        // step 3: insert into lot transaction table
        lotTransHistoryReqManager.createLotTransHistory(transactionLog, childLot, StringUtils.EMPTY);

        // step 4: start lot step history
        startChildLot(transactionLog, childLot, childUnitList);

        return childLot;
    }

    private void startChildLot(TransactionLog transactionLog, Lot childLot, List<Unit> childUnitList) {
        // step1: update lot table
        lotManager.start(childLot.getLotRrn());
        // step2: create lot step history
        lotStepHistoryReqManager.createLotStepHistory(childLot);

        unitManager.transferUnitInALot(transactionLog, childLot, childUnitList);
        unitManager.createUnitStepRangeHistory(transactionLog, childLot, childUnitList);
    }

    private long createNewRrn() {
        return Long.parseLong(IDGenerators.get(IDNames.SEQUENCE).generateId(SequenceNames.MODULE_SEQ_OBJECT_RRN));
    }

}