# EdcSaveByAutoMonitorTaskManagerImpl.java

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

    import com.fa.sesa.exception.Assert;
    import com.fa.sesa.exception.Errors;
    import com.fa.sesa.threadlocal.LocalContext;
    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.msg.JsonUtils;
    import com.mycim.server.automonitor.manager.LotAutoMonitorInqManager;
    import com.mycim.server.automonitor.manager.LotAutoMonitorReqManager;
    import com.mycim.server.automonitor.manager.job.task.EdcSaveByAutoMonitorTaskManager;
    import com.mycim.server.base.manager.NamedObjectManager;
    import com.mycim.server.base.manager.TransactionLogManager;
    import com.mycim.server.edcchart.manager.EdcSpcManager;
    import com.mycim.server.ems.manager.EntityManager;
    import com.mycim.server.ems.manager.EquipmentManager;
    import com.mycim.server.rcp.manager.RecipeManager;
    import com.mycim.server.rcp.manager.RecipeVersionManager;
    import com.mycim.server.security.manager.UserGroupManager;
    import com.mycim.server.spc.manager.SpcManager;
    import com.mycim.server.wip.manager.JobQueryManager;
    import com.mycim.server.wip.manager.LotManager;
    import com.mycim.server.wip.manager.LotQueryManager;
    import com.mycim.server.wip.manager.UnitQueryManager;
    import com.mycim.utils.NonRTMathUtil;
    import com.mycim.valueobject.MessageIdList;
    import com.mycim.valueobject.ObjectList;
    import com.mycim.valueobject.SystemConstant;
    import com.mycim.valueobject.automonitor.entity.LotAutoMonitorInfo;
    import com.mycim.valueobject.automonitor.entity.LotMonitorJobStepEdcInfo;
    import com.mycim.valueobject.automonitor.entity.LotMonitorJobStepInfo;
    import com.mycim.valueobject.automonitor.util.AutoMonitorOperationConstants;
    import com.mycim.valueobject.bas.TransactionLog;
    import com.mycim.valueobject.consts.*;
    import com.mycim.valueobject.edcspc.dto.nonrt.NonRTJobBaseInfoDTO;
    import com.mycim.valueobject.edcspc.dto.nonrt.NonRTReturnInfoDTO;
    import com.mycim.valueobject.edcspc.dto.nonrt.NonRTUnitInfoDTO;
    import com.mycim.valueobject.edcspc.dto.nonrt.NonRTUploadDTO;
    import com.mycim.valueobject.ems.EntityStatus;
    import com.mycim.valueobject.ems.Equipment;
    import com.mycim.valueobject.security.User;
    import com.mycim.valueobject.sys.Facility;
    import com.mycim.valueobject.wip.Lot;
    import com.mycim.valueobject.wip.LotStatus;
    import com.mycim.valueobject.wip.dto.LotInfoDto;
    import com.mycim.valueobject.wip.dto.ParameterDto;
    import com.mycim.valueobject.wip.dto.ReadingDto;
    import com.mycim.valueobject.wip.dto.SampleDto;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    import org.springframework.transaction.annotation.Transactional;

    import java.util.*;

    @Service
    @Transactional
    public class EdcSaveByAutoMonitorTaskManagerImpl implements EdcSaveByAutoMonitorTaskManager {
        @Autowired
        private JobQueryManager jobQueryManager;

        @Autowired
        private UnitQueryManager unitQueryManager;

        @Autowired
        private LotQueryManager lotQueryManager;

        @Autowired
        private NamedObjectManager namedObjectManager;

        @Autowired
        private RecipeManager recipeManager;

        @Autowired
        private RecipeVersionManager recipeVersionManager;

        @Autowired
        private EquipmentManager equipmentManager;

        @Autowired
        private EntityManager entityManager;

        @Autowired
        private LotManager lotManager;

        @Autowired
        private UserGroupManager userGroupManager;

        @Autowired
        private LotAutoMonitorReqManager lotAutoMonitorReqManager;

        @Autowired
        private LotAutoMonitorInqManager lotAutoMonitorInqManager;

        @Autowired
        private SpcManager spcManager;

        @Autowired
        private EdcSpcManager edcSpcManager;

        @Autowired
        private TransactionLogManager transactionLogManager;

        @Override
        public Map doExecute(Map parameters) {

            List<LotInfoDto> lotInfoDtos = (List<LotInfoDto>) MapUtils.getObject(parameters, "transData");
            Assert.state(CollectionUtils.isNotEmpty(lotInfoDtos),
                         Errors.create().content("Parameters are not enough!").build());

            Boolean pauseFlag = MapUtils.getBoolean(parameters, SystemConstant.Str.PAUSE_FLAG);
            if (Objects.nonNull(MapUtils.getObject(parameters, SystemConstant.Str.PAUSE_FLAG)) && !pauseFlag) {
                parameters.put(SessionNames.RUNSTEP_FLAG, "0");
                return parameters;
            }

            for (LotInfoDto lotInfoDto : lotInfoDtos) {

                Lot lot = lotQueryManager.getLot(lotInfoDto.getLotBaseInfo().getLotId(), LocalContext.getFacilityRrn());

                LotAutoMonitorInfo monitorInfo = lotAutoMonitorInqManager.getLotActiveAutoMonitorInfo(lot.getLotRrn());

                String valueType = StringUtils.EMPTY;
                if (StringUtils.startsWith(monitorInfo.getEqptType(), AutoMonitorOperationConstants.STEP_TYPE_PRE)) {
                    valueType = AutoMonitorOperationConstants.STEP_TYPE_PRE;
                } else {
                    valueType = AutoMonitorOperationConstants.STEP_TYPE_POST;
                }

                List<NonRTUploadDTO> dataList = buildNonRtInfoData(lotInfoDto, monitorInfo.getMainEqptRrn(), valueType);

                Facility facility = new Facility(LocalContext.getFacilityRrn());
                facility.setInstanceId(namedObjectManager.getInstanceId(LocalContext.getFacilityRrn()));
                User user = new User();
                user.setInstanceId(LocalContext.getUserId());
                user.setInstanceRrn(LocalContext.getUserRrn());

                if(CollectionUtils.isNotEmpty(dataList)) {
                    createLotStepDataCollectionTrans(lot, dataList);
                }

                Map ocapInfo = MapUtils.newHashMap();
                ocapInfo.put("eqptType", monitorInfo.getEqptType());
                // 添加当前量测机台
                Long edcEqptRrn = MapUtils.getLong(parameters, "eqptRrn");
                ocapInfo.put("edcEqptId", namedObjectManager.getInstanceId(edcEqptRrn));
                ocapInfo.put("edcEqptRrn", edcEqptRrn);

                NonRTReturnInfoDTO returnInfo = edcSpcManager
                        .importUploadData(dataList, facility, user, NonRTMathUtil.NONRT_IMPORT_TYPE_AUTO_MONITOR, ocapInfo);

                if (returnInfo.getUploadSpc() && returnInfo.getHadViolation()) {
                    parameters.put("hadViolation", returnInfo.getHadViolation());
                }
            }
            parameters.put(SessionNames.RUNSTEP_FLAG, "0");
            return parameters;
        }

        public Map<String, Object> buildReleaseDeptsForLogEvent(String eeGrp) {
            Map<String, Object> resultMap = MapUtils.newHashMap();
            String holdCode = HoldCodeNames.EMPTY_WAITENG_BY_SYSTEM_HOLD_CODE;
            if (StringUtils.isNotBlank(eeGrp)) {
                holdCode = eeGrp + HoldCodeNames.WAITENG_BY_SYSTEM_HOLD_CODE_SUFFIX;
            }
            String releaseDepts = getDepartments(holdCode);
            if (StringUtils.isBlank(releaseDepts) || StringUtils.equals(holdCode, releaseDepts)) {
                holdCode = HoldCodeNames.EMPTY_WAITENG_BY_SYSTEM_HOLD_CODE;
                releaseDepts = getDepartments(holdCode);
            }

            resultMap.put("holdCode", holdCode);
            resultMap.put("releaseDepts", releaseDepts);
            return resultMap;
        }

        public Long checkEventAndEntity(Long entityRrn, String eventId) {
            Long eventRrn = namedObjectManager
                    .getNamedObjectRrn(eventId, LocalContext.getFacilityRrn(), ObjectList.EVENT_KEY);
            Assert.state(entityRrn != null && eventRrn != null, Errors.create().key(MessageIdList.SYSTEM_MISSING_PARAMETER)
                                                                      .content("Required parameters do not exists!")
                                                                      .build());
            return eventRrn;
        }

        private List<NonRTUploadDTO> buildNonRtInfoData(LotInfoDto lotInfoDto, Long mainEqptRrn, String valueType) {

            List<Map> spcJobList = edcSpcManager.getMainEqpNonRTJobList(mainEqptRrn);

            List<NonRTUploadDTO> nonRtUploadInfos = new ArrayList<NonRTUploadDTO>();

            if (lotInfoDto.getParameterSet() != null) {
                List<ParameterDto> parameters = lotInfoDto.getParameterSet().getParameters();
                for (ParameterDto parameter : parameters) {
                    String parameterId = parameter.getParameterId();

                    Map spcJobInfo = null;
                    for (Map map : spcJobList) {
                        String jobName = MapUtils.getString(map, "JobName");
                        if (StringUtils.equals(parameterId, jobName)) {
                            spcJobInfo = map;
                            break;
                        }
                    }

                    NonRTUploadDTO uploadDTO = new NonRTUploadDTO();

                    if (spcJobInfo != null) {
                        NonRTJobBaseInfoDTO jobBaseInfoDTO = new NonRTJobBaseInfoDTO();

                        jobBaseInfoDTO.setEqptId(MapUtils.getString(spcJobInfo, "eqptId"));
                        jobBaseInfoDTO.setEqptRrn(MapUtils.getLong(spcJobInfo, "eqptRrn"));
                        jobBaseInfoDTO.setArea(MapUtils.getString(spcJobInfo, "AreaID"));
                        jobBaseInfoDTO.setFormulaPara(MapUtils.getString(spcJobInfo, "Formula_Para"));
                        jobBaseInfoDTO.setFormulaType(MapUtils.getString(spcJobInfo, "Formula"));
                        jobBaseInfoDTO.setJobId(MapUtils.getString(spcJobInfo, "JobID"));
                        jobBaseInfoDTO.setJobName(MapUtils.getString(spcJobInfo, "JobName"));
                        jobBaseInfoDTO.setNonRTKey(MapUtils.getString(spcJobInfo, "NonRTKey"));
                        jobBaseInfoDTO.setLotId(lotInfoDto.getLotBaseInfo().getLotId());
                        jobBaseInfoDTO.setSubgroupSize(MapUtils.getInteger(spcJobInfo, "SubgroupSize"));
                        jobBaseInfoDTO.setDeriveChartName(MapUtils.getString(spcJobInfo, "DeriveChartName"));
                        jobBaseInfoDTO.setDeriveChartID(MapUtils.getString(spcJobInfo, "DeriveChartID"));
                        jobBaseInfoDTO.setDeriveNonRTKey(MapUtils.getString(spcJobInfo, "DeriveNonRTKey"));

                        if(NonRTMathUtil.isDirectUploadFormula(jobBaseInfoDTO.getFormulaType())) {
                            jobBaseInfoDTO.setValueType(NonRTMathUtil.NONRT_FORMULA_POST_KEY);
                        } else {
                            jobBaseInfoDTO.setValueType(valueType);
                        }
                        uploadDTO.setJobBaseInfo(jobBaseInfoDTO);
                    } else {
                        continue;
                    }

                    List<NonRTUnitInfoDTO> unitInfoDtos = new ArrayList<>();
                    for (int j = 0; j < parameter.getSamplePrompts().size(); j++) {
                        SampleDto sample = parameter.getSamplePrompts().get(j);
                        NonRTUnitInfoDTO unitDTO = new NonRTUnitInfoDTO();
                        unitDTO.setUnitId(sample.getUnitId());
                        double[] valueList = new double[sample.getReadingPrompts().size()];
                        for (int k = 0; k < sample.getReadingPrompts().size(); k++) {
                            ReadingDto reading = (ReadingDto) sample.getReadingPrompts().get(k);
                            valueList[k] = reading.getDataValue();
                        }
                        unitDTO.setValueList(valueList);
                        unitInfoDtos.add(unitDTO);
                    }
                    uploadDTO.setUnitList(unitInfoDtos);
                    nonRtUploadInfos.add(uploadDTO);
                }
            }

            return nonRtUploadInfos;
        }

        private void createLotStepDataCollectionTrans(Lot lot, List<NonRTUploadDTO> dataList) {
            TransactionLog transactionLog = transactionLogManager
                    .startTransactionLog(LocalContext.getUserId(), TransactionNames.DATA_COLLECTION_KEY);

            List<LotMonitorJobStepEdcInfo> stepInfoList = buildStepEdcList(transactionLog.getTransRrn(), lot, dataList);
            lotAutoMonitorReqManager.insertLotMonitorStepEdcInfo(stepInfoList);

            lotManager.createLotTransHistory(transactionLog, lot, StringUtils.EMPTY);

            transactionLogManager.markTransactionLog(transactionLog);
        }

        private List<LotMonitorJobStepEdcInfo> buildStepEdcList(Long transRrn, Lot lot, List<NonRTUploadDTO> dataList) {

            List<LotMonitorJobStepEdcInfo> edcInfos = new ArrayList<>();

            Long sequence = NumberUtils.LONG_ONE;
            for (NonRTUploadDTO uploadData : dataList) {
                List<NonRTUnitInfoDTO> unitList = uploadData.getUnitList();
                for (NonRTUnitInfoDTO unitInfo : unitList) {
                    LotMonitorJobStepEdcInfo edcInfo = new LotMonitorJobStepEdcInfo();
                    edcInfo.setTransRrn(transRrn);
                    edcInfo.setSequence(sequence++);
                    edcInfo.setLotRrn(lot.getLotRrn());
                    edcInfo.setLotId(lot.getLotId());
                    edcInfo.setLotStepSequence(lot.getStepSequence());
                    edcInfo.setUnitRrn(unitInfo.getUnitRrn());
                    edcInfo.setUnitId(unitInfo.getUnitId());
                    edcInfo.setFormula(uploadData.getJobBaseInfo().getFormulaType());
                    edcInfo.setSpcJobId(uploadData.getJobBaseInfo().getJobId());
                    edcInfo.setSpcJobName(uploadData.getJobBaseInfo().getJobName());
                    edcInfo.setDataValue(Arrays.toString(unitInfo.getValueList()));
                    edcInfos.add(edcInfo);
                }
            }
            return edcInfos;
        }

        protected String getDepartments(String holdCode) {
            StringBuilder departments = new StringBuilder();

            List<Map> releaseGroups = lotQueryManager.getReleaseGroup(holdCode, ReferenceDetailNames.HOLD_CODE);
            if (CollectionUtils.isNotEmpty(releaseGroups)) {
                for (Map<String, Object> map : releaseGroups) {
                    String releaseGroup = MapUtils.getString(map, "releaseGroup");
                    List<String> departmentIds = userGroupManager
                            .getDepartmentIds(ReferenceDetailNames.REASON_GROUP_DEPARTMENT, releaseGroup,
                                              ReferenceFileConst.DATA_1_VALUE);
                    if (CollectionUtils.isNotEmpty(departmentIds)) {
                        for (String departmentId : departmentIds) {
                            if (departments.length() > 0) {
                                departments.append(",").append(departmentId);
                            } else {
                                departments.append(departmentId);
                            }
                        }
                    }
                }
            }
            return departments.toString();
        }

    }