OWL ITS + 탐지시스템(인터넷 진흥원)
src/main/java/kr/wisestone/owl/service/impl/IssueServiceImpl.java
@@ -211,6 +211,15 @@
        this.issueVersionService.addIssueVersion(issue);
    }
    @Override
    @Transactional
    public void addIssueVersion(Long id, Long userId) {
        Issue issue = this.getIssue(id);
        User user = this.userService.getUser(userId);
        //  이슈 버전 생성
        this.issueVersionService.addIssueVersion(issue, user);
    }
    private IssueForm convertToIssueForm(IssueApiForm issueApiForm, User user) {
        if (issueApiForm.getIssueTypeId() == null) {
@@ -521,6 +530,91 @@
    public Issue addRelIssue(IssueForm issueForm, List<MultipartFile> multipartFiles) {
        User user = this.webAppUtil.getLoginUserObject();
        return addRelIssue(user, issueForm, multipartFiles);
    }
    //  하위이슈를 생성한다.
    @Override
    @Transactional
    public Issue addDownIssue(IssueForm issueForm, List<MultipartFile> multipartFiles) {
        User user = this.webAppUtil.getLoginUserObject();
        return addDownIssue(user, issueForm, multipartFiles);
    }
    //  하위이슈를 생성한다.
    @Override
    @Transactional
    public Issue addDownIssue(User user, IssueForm issueForm, List<MultipartFile> multipartFiles) {
        //  사용하고 있는 업무 공간이 활성 상태인지 확인한다. 사용 공간에서 로그인한 사용자가 비활성인지 확인한다.
        Workspace workspace = this.workspaceService.checkUseWorkspace(user, user.getLastWorkspaceId());
        //  프로젝트 유효성 체크
        Project project = this.projectService.getProject(issueForm.getProjectId());
        //  이슈 유형 유효성 체크
        IssueType issueType = this.issueTypeService.getIssueType(issueForm.getIssueTypeId());
        //  우선순위 유효성 체크
        Priority priority = this.priorityService.getPriority(issueForm.getPriorityId());
        //  중요도 유효성 체크
        Severity severity = this.severityService.getSeverity(issueForm.getSeverityId());
        //  제목 유효성 체크
        this.verifyTitle(issueForm.getTitle());
        //  날짜 유효성 체크
        this.checkStartCompleteDate(issueForm.getStartDate(), issueForm.getCompleteDate());
        //  담당 부서 유효성 체크
        //this.verifyIssueDepartment(project, issueForm);
        //  이슈 상태 유형이 '대기' 인 이슈 상태 가져오기
        IssueStatus issueStatus = this.issueStatusService.findByIssueStatusTypeIsReady(issueType.getWorkflow());
        Issue issue = ConvertUtil.copyProperties(issueForm, Issue.class);
        issue.setProject(project);
        issue.setIssueStatus(issueStatus);
        issue.setIssueType(issueType);
        issue.setPriority(priority);
        issue.setSeverity(severity);
        if (issueForm.getParentIssueId() != null){
            Issue parentIssue = this.getIssue(issueForm.getParentIssueId());
            issue.setParentIssue(parentIssue);
        }
        issue.setIssueNumber(this.issueNumberGeneratorService.generateIssueNumber(project));    //  각 프로젝트의 고유 이슈 번호 생성
        issue = this.issueRepository.saveAndFlush(issue);
        issue.setReverseIndex(issue.getId() * -1);  //  쿼리 속도 개선을 위해 리버스 인덱스 생성
        //  담당자 지정
        //this.issueUserService.modifyIssueUser(issue, project.getWorkspace(), issueForm.getUserIds());
        //  담당부서 지정
        this.issueDepartmentService.modifyIssueDepartment(issue, user, project.getWorkspace(), issueForm.getDepartmentIds());
        //  업체 정보 저장
        this.issueCompanyService.modifyIssueCompanyField(issue, issueForm.getIssueCompanyFields());
        //  ISP 정보 저장
        this.issueIspService.modifyIssueIspField(issue, issueForm.getIssueIspFields());
        //  HOSTING 정보 저장
        this.issueHostingService.modifyIssueHostingField(issue, issueForm.getIssueHostingFields());
        //  첨부 파일 저장
        //  multipartFile 을 file Map List 객체로 변경한다.
        List<Map<String, Object>> convertFileMaps = this.convertMultipartFileToFile(multipartFiles);
        this.attachedFileService.addAttachedFile(convertFileMaps, issue, user.getAccount());
        //  텍스트 에디터에 첨부한 파일을 이슈와 연결
        this.checkNotHaveIssueIdAttachedFile(issue, issueForm);
        //  사용자 정의 필드 저장
        this.issueCustomFieldValueService.modifyIssueCustomFieldValue(issue, issueForm.getIssueCustomFields());
        //  이슈 이력 생성
        this.issueHistoryService.addIssueHistory(issue, user, IssueHistoryType.ADD, null);
        //  이슈 위험 관리 생성
        this.issueRiskService.addIssueRisk(issue, project.getWorkspace());
        //  영속성 컨텍스트 비우기
        this.clear();
        //  이슈 생성, 삭제시 예약 이메일에 등록해놓는다.
        this.reservationIssueEmail(issue, EmailType.ISSUE_ADD);
        //  사용자 시스템 기능 사용 정보 수집
        UserVo userVo = ConvertUtil.copyProperties(user, UserVo.class);
        log.info(ElasticSearchUtil.makeUserActiveHistoryMessage(userVo, ElasticSearchConstants.ISSUE_ADD));
        return issue;
    }
    //  연관이슈를 생성한다.
@@ -1475,7 +1569,7 @@
        this.setParentIssue(issue,issueVo); //상위 이슈 정보 세팅
        //  이슈 수정 권한을 갖고 있는지 확인
        if (user != null && this.checkHasPermission(issueVo, issueVo.getUserVos(), user, issueVo.getDepartmentVos())) {
        if (this.checkHasPermission(issueVo, issueVo.getUserVos(), user, issueVo.getDepartmentVos())) {
            issueVo.setModifyPermissionCheck(Boolean.TRUE);
        }
    }
@@ -2147,6 +2241,19 @@
        this.verifyIssueModifyPermission(issue, user);
        IssueStatus issueStatus = this.issueStatusService.getIssueStatus(issueForm.getIssueStatusId());
        if (issueStatus.getIssueStatusType().toString().equals("CLOSE")) {
            List<String> downIssuesStatus = issueForm.getDownIssuesStatus();
            if (downIssuesStatus != null && downIssuesStatus.size() > 0) {
                for (String downIssueStatus : downIssuesStatus) {
                    if (!downIssueStatus.equals("CLOSE")) {
                        throw new OwlRuntimeException(
                                this.messageAccessor.getMessage(MsgConstants.ISSUE_NOT_MODIFY_STATUS));
                    }
                }
            }
        }
        //  이슈 상태를 변경할 때 선택한 이슈 상태로 변경할 수 있는지 확인한다.
        this.issueStatusService.checkNextIssueStatus(issue, issueStatus);
        //  변경 이력 정보 추출
@@ -2784,7 +2891,7 @@
            Map<String, Priority> priorityMaps = new HashMap<>();   //  우선 순위 모음
            Map<String, Severity> severityMaps = new HashMap<>();   //  중요도 모음
            Map<String, Object> userMaps = new HashMap<>(); //  사용자 모음
            Map<String, Object> departmentMaps = new HashMap<>(); //  부서 모음
            Map<String, DepartmentVo> departmentMaps = new HashMap<>(); //  부서 모음
            Map<String, CustomField> customFieldMaps = new HashMap<>();
            Map<String, IssueStatus> issueStatusReadyMaps = new HashMap<>();   //  상태 속성 '대기'인 이슈 상태
            Map<Long, Long> issueNumberMaps = new HashMap<>();  //  이슈 번호 모음
@@ -2834,7 +2941,7 @@
                //  1번 헤더부터 데이터 영역
                if (rowIndex > 1) {
                    //  이슈로 등록하기 위해 IssueForm 에 데이터를 셋팅한다.
                    issueForms.add(this.setIssueFormToExcelField(row, (rowIndex + 1), issueStatusReadyMaps, projectMaps, issueTypeMaps, priorityMaps, severityMaps, userMaps, customFieldMaps, issueNumberMaps, headers));
                    issueForms.add(this.setIssueFormToExcelField(row, (rowIndex + 1), issueStatusReadyMaps, projectMaps, issueTypeMaps, priorityMaps, severityMaps, userMaps, departmentMaps, customFieldMaps, issueNumberMaps, headers));
                }
            }
@@ -2985,7 +3092,7 @@
    //  이슈의 주요 속성을 map 에 저장하여 엑셀 import 에서 지정한 대상(이슈 속성)을 빠르게 찾을 수 있게 한다.
    private void IssueAttributeMapToList(Map<String, Project> projectMaps, Map<String, IssueType> issueTypeMaps, Map<String, Priority> priorityMaps, Map<String, Severity> severityMaps,
                                         Map<String, Object> userMaps, Map<String, Object> departmentMaps, Map<String, CustomField> customFieldMaps, Map<Long, Long> issueNumberMaps, Map<String, Long> issueTypeCustomFieldMaps, Map<String, IssueStatus> issueStatusReadyMaps) {
                                         Map<String, Object> userMaps, Map<String, DepartmentVo> departmentMaps, Map<String, CustomField> customFieldMaps, Map<Long, Long> issueNumberMaps, Map<String, Long> issueTypeCustomFieldMaps, Map<String, IssueStatus> issueStatusReadyMaps) {
        //  프로젝트 키로 바로 찾을 수 있게 준비
        List<Project> projects = this.projectService.findByWorkspaceId();
        List<Long> projectIds = Lists.newArrayList();
@@ -3009,16 +3116,7 @@
            for (Map<String, Object> user : users) {
                userMap.put(CommonUtil.decryptAES128(MapUtil.getString(user, "account")), MapUtil.getLong(user, "userId"));
            }
            userMaps.put(project.getProjectKey(), userMap);
            //  프로젝트에 참여하는 부서 정보
            List<Map<String, Object>> departments = this.departmentService.findProjectDepartment(project);
            List<Long> departmentList = Lists.newArrayList();
            //  부서 정보를 저장
            for (Map<String, Object> department : departments) {
                departmentList.add(MapUtil.getLong(department, "departmentId"));
            }
        }
        //  이슈 유형을 바로 찾을 수 있게 준비
@@ -3028,6 +3126,13 @@
            IssueStatus issueStatus = this.issueStatusService.findByIssueStatusTypeIsReady(issueType.getWorkflow());
            issueStatusReadyMaps.put(issueType.getId().toString(), issueStatus);
            //  워크플로우에 속해있는 부서 정보
            List<DepartmentVo> departments = this.departmentService.findWorkflowDepartment(issueType.getId());
            //  부서 정보를 저장
            for (DepartmentVo department : departments) {
                departmentMaps.put(department.getDepartmentName(), department);
            }
        }
        //  우선순위를 바로 찾을 수 있게 준비
@@ -3051,7 +3156,7 @@
    //  엑셀 필드에 있는 정보를 이슈 form 으로 옮긴다.
    private IssueForm setIssueFormToExcelField(Row row, int rowIndex, Map<String, IssueStatus> issueStatusReadyMaps, Map<String, Project> projectMaps, Map<String, IssueType> issueTypeMaps, Map<String,
            Priority> priorityMaps, Map<String, Severity> severityMaps, Map<String, Object> userMaps, Map<String, CustomField> customFieldMaps, Map<Long, Long> issueNumberMaps, List<String> headers) {
            Priority> priorityMaps, Map<String, Severity> severityMaps, Map<String, Object> userMaps, Map<String, DepartmentVo> departmentMaps, Map<String, CustomField> customFieldMaps, Map<Long, Long> issueNumberMaps, List<String> headers) {
        IssueForm issueForm = new IssueForm();
        issueForm.setRegisterId(this.webAppUtil.getLoginId());
        Project project = null;
@@ -3095,9 +3200,13 @@
                    //  중요도를 IssueForm 에 저장한다.
                    this.setIssueFormSeverity(cell, severityMaps, issueForm, rowIndex);
                    break;
                /*case 6:
                    //  담당자를 IssueForm 에 저장한다.
                    this.setIssueFormAssignee(cell, userMaps, issueForm, project);
                    break;*/
                case 6:
                    //  담당부서를 IssueForm 에 저장한다.
                    this.setIssueFormAssignee(cell, userMaps, issueForm, project);
                    this.setIssueFormDepartment(cell, departmentMaps, issueForm, project);
                    break;
                case 7:
                    //  시작일을 IssueForm 에 저장한다.
@@ -3108,7 +3217,7 @@
                    this.setIssueFormPeriod(cell, issueForm, false, rowIndex);
                    break;
                default:
                    //  8번 이상부터는 사용자 정의 필드. 사용자 정의 필드 정보를 IssueForm 에 저장한다.
                    //  9번 부터는 사용자 정의 필드. 사용자 정의 필드 정보를 IssueForm 에 저장한다.
                    this.setIssueFormCustomFieldValue(cell, customFieldMaps, issueForm, headers.get(cellIndex), rowIndex);
            }
        }
@@ -3237,20 +3346,39 @@
        issueForm.setSeverityId(severity.getId());
    }
    //  담당부서를 IssueForm 에 저장한다.
    private void setIssueFormAssignee(Cell cell, Map<String, Object> userMaps, IssueForm issueForm, Project project) {
        if (cell != null) {
            String[] splitAssignee = CommonUtil.convertExcelStringToCell(cell).split("#");
            Map<String, Object> userMap = (Map<String, Object>) MapUtil.getObject(userMaps, project.getProjectKey());
            List<Long> departmentIds = Lists.newArrayList();
            List<Long> userIds = Lists.newArrayList();
            for (String account : splitAssignee) {
                if (MapUtil.getLong(userMap, account) != null) {
                    departmentIds.add(MapUtil.getLong(userMap, account));
                    userIds.add(MapUtil.getLong(userMap, account));
                }
            }
            issueForm.setUserIds(userIds);
        }
    }
    //  담당부서를 IssueForm 에 저장한다.
    private void setIssueFormDepartment(Cell cell, Map<String, DepartmentVo> departmentMaps, IssueForm issueForm, Project project) {
        if (cell != null) {
            String[] splitDepartment = CommonUtil.convertExcelStringToCell(cell).split("#");
            //  값이 공백이면 중지
            String cellValue = CommonUtil.convertExcelStringToCell(cell);
            if (StringUtils.isEmpty(cellValue)) {
                return;
            }
            List<Long> departmentIds = Lists.newArrayList();
            for (String department : splitDepartment) {
                DepartmentVo departmentVo = departmentMaps.get(department);
                departmentIds.add(departmentVo.getId());
            }
            issueForm.setDepartmentIds(departmentIds);
        }
    }
@@ -3259,6 +3387,12 @@
    private void setIssueFormPeriod(Cell cell, IssueForm issueForm, Boolean checkStartDate, int rowIndex) {
        if (cell != null && !cell.toString().equals("")) {
            //  값이 공백이면 중지
            String cellValue = CommonUtil.convertExcelStringToCell(cell);
            if (StringUtils.isEmpty(cellValue)) {
                return;
            }
            Date startDate;
            try {