OWL ITS + 탐지시스템(인터넷 진흥원)
이민희
2021-12-10 3bdf2a1f2757de8ab6570508385d89124243943c
src/main/java/kr/wisestone/owl/service/impl/IssueServiceImpl.java
@@ -3,11 +3,9 @@
import com.google.common.collect.Lists;
import com.sun.org.apache.bcel.internal.generic.NEW;
import kr.wisestone.owl.common.ExcelConditionCheck;
import kr.wisestone.owl.common.IssueCustomFieldValueFormComparator;
import kr.wisestone.owl.config.CommonConfiguration;
import kr.wisestone.owl.constant.Constants;
import kr.wisestone.owl.constant.ElasticSearchConstants;
import kr.wisestone.owl.constant.MsgConstants;
import kr.wisestone.owl.constant.UsePartner;
import kr.wisestone.owl.constant.*;
import kr.wisestone.owl.data.CheckIssueData;
import kr.wisestone.owl.domain.*;
import kr.wisestone.owl.domain.enumType.CustomFieldType;
@@ -153,6 +151,9 @@
    private UserWorkspaceService userWorkspaceService;
    @Autowired
    private UserLevelService userLevelService;
    @Autowired
    private WorkflowDepartmentService workflowDepartmentService;
    @Autowired
@@ -263,11 +264,8 @@
            List<IssueVo> issueVos = this.findIssue(issueApiForm, customFieldApiOverlaps, user.getId());
            int size = issueVos.size();
            if (size == 1) {
            if (size > 0) {
                issueForm.setParentIssueId(issueVos.get(0).getId());
            } else if (size > 1) {
                throw new OwlRuntimeException(
                        this.messageAccessor.getMessage(MsgConstants.API_OVERLAP_ERROR));
            }
            issueForm.setIsApi(Issue.IS_API_YES);
@@ -328,39 +326,36 @@
    }
    // 중복된 상위 이슈 검색
    private List<IssueVo> findIssue(IssueApiForm issueApiForm, List<CustomFieldApiOverlap> customFieldApiOverlaps, Long userId) {
    private List<IssueVo> findIssue(IssueApiForm issueApiform, List<CustomFieldApiOverlap> customFieldApiOverlaps, Long userId) {
        List<IssueCustomFieldValueForm> issueCustomFieldValueForms = issueApiform.getIssueCustomFieldValues();
        List<IssueVo> resultIssueVos = Lists.newArrayList();
        String comma = ",";
        List<IssueVo> resultIssueVos = new ArrayList<>();
        if (issueCustomFieldValueForms.size() > 0) {
            String concatUseValue = "";
            int useIdx = 0;
        if (customFieldApiOverlaps != null && customFieldApiOverlaps.size() > 0) {
            for (CustomFieldApiOverlap customFieldApiOverlap : customFieldApiOverlaps) {
                for (IssueCustomFieldValueForm issueCustomFieldValue : issueApiForm.getIssueCustomFieldValues()) {
                    IssueCustomFieldValueCondition issueCustomFieldValueCondition = new IssueCustomFieldValueCondition();
                    issueCustomFieldValueCondition.setUseParentIssueId(true);
                    if (customFieldApiOverlap.getCustomField().getId().equals(issueCustomFieldValue.getCustomFieldId())) {
                        issueCustomFieldValueCondition.setUseValue(issueCustomFieldValue.getUseValue());
            IssueCustomFieldValueFormComparator comp = new IssueCustomFieldValueFormComparator();
            Collections.sort(issueCustomFieldValueForms, comp);
                        List<Map<String, Object>> results = this.issueMapper.findByCustomFieldValue(issueCustomFieldValueCondition);
                        if (results != null && results.size() > 0) {
                            List<IssueVo> findIssueVos = new ArrayList<>();
                            Collections.copy(resultIssueVos, findIssueVos);
                            resultIssueVos.clear();
                            for (Map<String, Object> result : results) {
                                IssueVo issueVo = ConvertUtil.convertMapToClass(result, IssueVo.class);
                                if (findIssueVos.size() == 0) {
                                    resultIssueVos.add(issueVo);
                                } else {
                                    IssueVo findIssueVo = findIssueVo(findIssueVos, issueVo.getId());
                                    if (findIssueVo != null) {
                                        resultIssueVos.add(findIssueVo);
                                    }
                                }
                            }
                        } else {
                            resultIssueVos.clear();
                            return resultIssueVos;
            for (IssueCustomFieldValueForm issueCustomFieldValueForm : issueCustomFieldValueForms) {
                for(CustomFieldApiOverlap customFieldApiOverlap : customFieldApiOverlaps) {
                    if (customFieldApiOverlap.getCustomField().getId().equals(issueCustomFieldValueForm.getCustomFieldId())) {
                        if (useIdx > 0) {
                            concatUseValue = concatUseValue.concat(comma);
                        }
                        concatUseValue = concatUseValue.concat(issueCustomFieldValueForm.getUseValue());
                        useIdx++;
                    }
                }
            }
            IssueCustomFieldValueCondition issueCustomFieldValueCondition = new IssueCustomFieldValueCondition();
            issueCustomFieldValueCondition.setUseValue(concatUseValue);
            List<Map<String, Object>> results = this.issueMapper.findByCustomFieldValue(issueCustomFieldValueCondition);
            if (results != null && results.size() > 0) {
                for (Map<String, Object> result : results) {
                    resultIssueVos.add(ConvertUtil.convertMapToClass(result, IssueVo.class));
                }
            }
        }
@@ -723,11 +718,11 @@
    public List<IssueVo> findIssue(Map<String, Object> resJsonData, IssueCondition issueCondition, Pageable pageable) {
        //  검색 조건을 만든다
        if (!this.makeIssueSearchCondition(issueCondition, Lists.newArrayList("01", "02", "03"), pageable)) {
        /*if (!this.makeIssueSearchCondition(issueCondition, Lists.newArrayList("01", "02", "03"), pageable)) {
            //  이슈 목록을 찾지 못할 경우 기본 정보로 리턴한다.
            this.notFoundIssueList(resJsonData, pageable);
            return Lists.newArrayList();
        }
        }*/
        Set<String> issueIds = new HashSet<>(); //  사용자 정의 필드 검색시 나오는 이슈 아이디 저장 컬렉션
@@ -750,10 +745,13 @@
        issueCondition.setWorkspaceId(this.userService.getUser(this.webAppUtil.getLoginId()).getLastWorkspaceId());
        User user = this.webAppUtil.getLoginUserObject();
        List<Map<String, Object>> results = Lists.newArrayList();
        Long totalCount = 0L;
        UserLevel userLevel = this.userLevelService.getUserLevel(user.getUserLevel().getId());
        if (this.userWorkspaceService.checkWorkspaceManager(user)) {
        if (this.userWorkspaceService.checkWorkspaceManager(user)
                || MngPermission.checkMngPermission(userLevel.getPermission(), MngPermission.USER_PERMISSION_MNG_ISSUE_PROJECT_ALL)) {
            results = this.issueMapper.find(issueCondition);
            totalCount = this.issueMapper.count(issueCondition);
        } else{
@@ -773,6 +771,7 @@
        int totalPage = (int) Math.ceil((totalCount - 1) / pageable.getPageSize()) + 1;
        //  이슈 아이디 초기화
        issueCondition.setIsApi(issueCondition.getIsApi());
        issueCondition.setIssueIds(Lists.newArrayList());
        //  Map 에 있는 데이터를 IssueVo 데이터로 변환한다.
        this.setMapToIssueVo(results, issueVos, issueCondition, user);
@@ -1039,6 +1038,7 @@
        condition.setWorkspaceId(this.userService.getUser(this.webAppUtil.getLoginId()).getLastWorkspaceId());
        projectCondition.setWorkspaceId(condition.getWorkspaceId());
        //  프로젝트 키가 존재할 경우 프로젝트 키에 해당하는 프로젝트를 조회하고 검색 조건에 셋팅한다.
        if (!this.getProjectByProjectKey(condition.getProjectKey(), condition)) {
            return false;
@@ -1047,7 +1047,9 @@
        //  프로젝트를 선택하지 않았으면 해당 업무 공간에서 참여하고 있는 프로젝트를 찾는다.
        if (condition.getProjectIds().size() < 1) {
            List<Map<String, Object>> projects = null;
            if (this.userWorkspaceService.checkWorkspaceManager(user)) {
            UserLevel userLevel = this.userLevelService.getUserLevel(user.getUserLevel().getId());
            if (this.userWorkspaceService.checkWorkspaceManager(user)
                    || MngPermission.checkMngPermission(userLevel.getPermission(), MngPermission.USER_PERMISSION_MNG_ISSUE_PROJECT_ALL)) {
                projects = this.projectMapper.findByWorkspaceManagerAll(projectCondition);
            } else  {
                projects = this.projectService.findByWorkspaceIdAndIncludeProjectAll(projectCondition);
@@ -1483,42 +1485,25 @@
    public List<IssueVo> findIssue(IssueApiForm issueApiform) {
        List<IssueCustomFieldValueForm> issueCustomFieldValueForms = issueApiform.getIssueCustomFieldValues();
        List<IssueVo> resultIssueVos = new ArrayList<>();
        List<IssueVo> resultIssueVos = Lists.newArrayList();
        String comma = ",";
        IssueCustomFieldValueCondition issueCustomFieldValueCondition = new IssueCustomFieldValueCondition();
        issueCustomFieldValueCondition.setUseParentIssueId(false);
        if (issueCustomFieldValueForms.size() > 0) {
            for (IssueCustomFieldValueForm issueCustomFieldValueForm : issueCustomFieldValueForms) {
                CustomField customField = this.customFieldService.getCustomField(issueCustomFieldValueForm.getCustomFieldId());
                CustomFieldType customFieldType = CustomFieldType.DATETIME;
                if (customFieldType.equals(customField.getCustomFieldType())) {
                    continue;
            String concatUseValue = "";
            for (int i = 0; i < issueCustomFieldValueForms.size(); i++) {
                IssueCustomFieldValueForm issueCustomFieldValueForm = issueCustomFieldValueForms.get(i);
                if (i > 0) {
                    concatUseValue = concatUseValue.concat(comma);
                }
//                issueCustomFieldValueCondition.addUseValue(issueCustomFieldValueForm.getUseValue());
                issueCustomFieldValueCondition.setUseValue(issueCustomFieldValueForm.getUseValue());
                List<Map<String, Object>> results = this.issueMapper.findByCustomFieldValue(issueCustomFieldValueCondition);
                if (results != null && results.size() > 0) {
                    List<IssueVo> findIssueVos = new ArrayList<>();
                    Collections.copy(resultIssueVos, findIssueVos);
                    resultIssueVos.clear();
                    for (Map<String, Object> result : results) {
                        IssueVo issueVo = ConvertUtil.convertMapToClass(result, IssueVo.class);
                concatUseValue = concatUseValue.concat(issueCustomFieldValueForm.getUseValue());
            }
                        issueVo.setParentIssueVo(this.getParentIssueVo(MapUtil.getLong(result, "parentIssueId")));
                        if (findIssueVos.size() == 0) {
                            resultIssueVos.add(issueVo);
                        } else {
                            IssueVo findIssueVo = findIssueVo(findIssueVos, issueVo.getId());
                            if (findIssueVo != null) {
                                resultIssueVos.add(findIssueVo);
                            }
                        }
                    }
                } else {
                    resultIssueVos.clear();
                    return resultIssueVos;
            IssueCustomFieldValueCondition issueCustomFieldValueCondition = new IssueCustomFieldValueCondition();
            issueCustomFieldValueCondition.setUseValue(concatUseValue);
            List<Map<String, Object>> results = this.issueMapper.findByCustomFieldValue(issueCustomFieldValueCondition);
            if (results != null && results.size() > 0) {
                for (Map<String, Object> result : results) {
                    resultIssueVos.add(ConvertUtil.convertMapToClass(result, IssueVo.class));
                }
            }
        }
@@ -1534,15 +1519,6 @@
            }
        }
        return null;
    }
    // 하위 이슈가 모두 종료 처리 되었을 경우 상위이슈도 완료 처리
    private void setParentIssueComplete(Issue parentIssue) {
        if (parentIssue != null) {
            this.issueMapper.findNotCompleteByParentIssueId(parentIssue.getId());
        }
    }
@@ -1570,10 +1546,12 @@
                }
                if (parentIssue != null) {
                    List<Map<String, Object>> results = this.issueMapper.findNotCompleteByParentIssueId(parentIssue.getId());
                    IssueCondition issueCondition = new IssueCondition(issueVo.getId(), parentIssue.getId());
                    List<Map<String, Object>> results = this.issueMapper.findNotCompleteByParentIssueId(issueCondition);
                    // 하위 일감이 모두 종료 상태일때 상위 일감도 종료 처리
                    if (results == null || results.size() == 0) {
                        parentIssue.setIssueStatus(issueType.getIssueStatus());
                        this.issueRepository.saveAndFlush(parentIssue);
                    }
                }
@@ -1660,6 +1638,7 @@
            this.issueHistoryService.detectIssueStatus(issue, issueForm, detectIssueChange, oldIssueStatus, issueStatus);
        }
        // db에 저장
        issue = this.saveIssue(issueForm, checkIssueData);
        //  이슈 이력 등록
@@ -1900,6 +1879,9 @@
        //hasPermission = this.checkIssueModifyPermission(hasPermission, Issue.ASSIGNEE, issueVo, issueUserVos);
        //  담당자가 없으면 모든 사용자가 수정 권한을 갖는다.
        hasPermission = this.checkIssueModifyPermission(hasPermission, Issue.ALL_ISSUE_MANAGER, issueVo, null, null, user);
        hasPermission = this.checkIssueModifyPermission(hasPermission, Issue.ALL_PROJECT_MANAGER, issueVo, null, null, user);
        return hasPermission;
    }
@@ -2096,49 +2078,123 @@
        List<Issue> removeIssues = Lists.newArrayList();
        for (Long issueId : issueForm.getRemoveIds()) {
            //하위이슈 체크
            List<Issue> downIssues = this.issueRepository.findByParentIssueId(issueId);
            if(downIssues != null && downIssues.size() > 0){
                for(Issue downIssue : downIssues){
                    if(downIssue.getParentIssue() != null){
                        downIssue.setParentIssue(null);
                    }
                }
            }
            Issue issue = this.issueRemoves(issueId, user);
            removeIssues.add(issue);
        }
        if (removeIssues.size() > 0) {
            //this.issueRepository.deleteAll(removeIssues);
        }
        /*if (removeIssues.size() > 0) {
            this.issueRepository.deleteAll(removeIssues);
        }*/
        //  사용자 시스템 기능 사용 정보 수집
        log.info(ElasticSearchUtil.makeUserActiveHistoryMessage(this.webAppUtil.getLoginUser(), ElasticSearchConstants.ISSUE_REMOVE));
    }
    //  이슈를 삭제한다.
    @Override
    @Transactional
    public void removeAllIssues(IssueForm issueForm) {
        //  사용하고 있는 업무 공간이 활성 상태인지 확인한다. 사용 공간에서 로그인한 사용자가 비활성인지 확인한다.
        User user = this.webAppUtil.getLoginUserObject();
        this.workspaceService.checkUseWorkspace();
        if (issueForm.getRemoveIds().size() < 1) {
            throw new OwlRuntimeException(
                    this.messageAccessor.getMessage(MsgConstants.ISSUE_REMOVE_NOT_SELECT));
        }
        List<Issue> removeIssues = Lists.newArrayList();
        for (Long issueId : issueForm.getRemoveIds()) {
            //하위이슈 체크
            List<Issue> downIssues = this.issueRepository.findByParentIssueId(issueId);
            if(downIssues != null && downIssues.size() > 0){
                for(Issue downIssue : downIssues){
                    Long downIssueId = downIssue.getId();
                    downIssue = this.issueRemoves(downIssueId, user);
                    removeIssues.add(downIssue);
                }
            }
            Issue issue = this.issueRemoves(issueId, user);
            removeIssues.add(issue);
        }
        //  사용자 시스템 기능 사용 정보 수집
        log.info(ElasticSearchUtil.makeUserActiveHistoryMessage(this.webAppUtil.getLoginUser(), ElasticSearchConstants.ISSUE_REMOVE));
    }
    //  하위이슈를 삭제한다.
    @Override
    @Transactional
    public void removeDownIssues(IssueForm issueForm) {
        //  사용하고 있는 업무 공간이 활성 상태인지 확인한다. 사용 공간에서 로그인한 사용자가 비활성인지 확인한다.
        User user = this.webAppUtil.getLoginUserObject();
        this.workspaceService.checkUseWorkspace();
        if (issueForm.getRemoveIds().size() < 1) {
            throw new OwlRuntimeException(
                    this.messageAccessor.getMessage(MsgConstants.ISSUE_REMOVE_NOT_SELECT));
        }
        List<Issue> removeIssues = Lists.newArrayList();
        Long downIssueId = 0L;
        for (Long issueId : issueForm.getRemoveIds()) {
            //삭제 할 이슈의 하위이슈 체크
            List<Issue> downIssues = this.issueRepository.findByParentIssueId(issueId);
            if(downIssues != null && downIssues.size() > 0){
                for(Issue downIssue : downIssues){
                    downIssueId = downIssue.getId();
                }
            }
            Issue issue = this.issueRemoves(downIssueId, user);
            removeIssues.add(issue);
        }
        //  사용자 시스템 기능 사용 정보 수집
        log.info(ElasticSearchUtil.makeUserActiveHistoryMessage(this.webAppUtil.getLoginUser(), ElasticSearchConstants.ISSUE_REMOVE));
    }
    private Issue issueRemoves(Long issueId, User user) {
        Issue issue = this.getIssue(issueId);
        //  이슈 수정 권한을 갖고 있는지 확인
        this.verifyIssueModifyPermission(issue, user);
        Issue issue = this.findOne(issueId);
        if(issue != null){
            //  이슈 수정 권한을 갖고 있는지 확인
            this.verifyIssueModifyPermission(issue, user);
        //  이슈 첨부 파일을 삭제한다.
        if (issue.getAttachedFiles().size() > 0) {
            List<Long> attachedFileIds = Lists.newArrayList();
            //  이슈 첨부 파일을 삭제한다.
            if (issue.getAttachedFiles().size() > 0) {
                List<Long> attachedFileIds = Lists.newArrayList();
            for (AttachedFile attachedFile : issue.getAttachedFiles()) {
                attachedFileIds.add(attachedFile.getId());
                for (AttachedFile attachedFile : issue.getAttachedFiles()) {
                    attachedFileIds.add(attachedFile.getId());
                }
                //  첨부파일 삭제
                this.attachedFileService.removeAttachedFiles(attachedFileIds);
            }
            //  첨부파일 삭제
            this.attachedFileService.removeAttachedFiles(attachedFileIds);
        }
        // 지울 이슈가 연관이슈인지 체크 후 연관이슈 테이블에서도 삭제한다.
        List<IssueRelation> issueRelationList = this.issueRelationRepository.findByRelationIssueId(issueId);
        if (issueRelationList != null && issueRelationList.size() > 0) {
            for(IssueRelation issueRelation : issueRelationList){
                StringBuilder sb = new StringBuilder();
                issueHistoryService.detectRelationIssue(IssueHistoryType.DELETE, issueRelation, sb);
                issueHistoryService.addIssueHistory(issueRelation.getIssue(), IssueHistoryType.MODIFY, sb.toString());
                this.issueRelationRepository.delete(issueRelation);
            // 지울 이슈가 연관이슈인지 체크 후 연관이슈 테이블에서도 삭제한다.
            List<IssueRelation> issueRelationList = this.issueRelationRepository.findByRelationIssueId(issueId);
            if (issueRelationList != null && issueRelationList.size() > 0) {
                for(IssueRelation issueRelation : issueRelationList){
                    StringBuilder sb = new StringBuilder();
                    issueHistoryService.detectRelationIssue(IssueHistoryType.DELETE, issueRelation, sb);
                    issueHistoryService.addIssueHistory(issueRelation.getIssue(), IssueHistoryType.MODIFY, sb.toString());
                    this.issueRelationRepository.delete(issueRelation);
                }
            }
        }
        //  이슈 생성, 삭제시 예약 이메일에 등록해놓는다.
        this.reservationIssueEmail(issue, EmailType.ISSUE_REMOVE);
        //  이슈 삭제
        this.issueRepository.delete(issue);
            //  이슈 생성, 삭제시 예약 이메일에 등록해놓는다.
            this.reservationIssueEmail(issue, EmailType.ISSUE_REMOVE);
            //  이슈 삭제
            this.issueRepository.delete(issue);
        }
        return issue;
    }