| | |
| | | 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; |
| | |
| | | import kr.wisestone.owl.exception.OwlRuntimeException; |
| | | import kr.wisestone.owl.mapper.IssueMapper; |
| | | import kr.wisestone.owl.mapper.ProjectMapper; |
| | | import kr.wisestone.owl.repository.IssueRelationRepository; |
| | | import kr.wisestone.owl.repository.IssueRepository; |
| | | import kr.wisestone.owl.repository.UserDepartmentRepository; |
| | | import kr.wisestone.owl.repository.WorkflowDepartmentRepository; |
| | |
| | | |
| | | @Autowired |
| | | private ProjectService projectService; |
| | | |
| | | @Autowired |
| | | private IssueTableConfigService issueTableConfigService; |
| | | |
| | | @Autowired |
| | | private IssueStatusService issueStatusService; |
| | |
| | | private IssueRelationService issueRelationService; |
| | | |
| | | @Autowired |
| | | private IssueRelationRepository issueRelationRepository; |
| | | |
| | | @Autowired |
| | | private ExcelView excelView; |
| | | |
| | | @Autowired |
| | |
| | | issueForm.setSeverityId(issueApiDefault.getSeverity().getId()); |
| | | } |
| | | |
| | | // 중복 값 하위 이슈로 처리하기 |
| | | // 중복 값 상위 이슈의 하위 이슈로 처리하기 |
| | | CustomFieldApiOverlapForm customFieldApiOverlapForm = new CustomFieldApiOverlapForm(); |
| | | customFieldApiOverlapForm.setUserId(user.getId()); |
| | | customFieldApiOverlapForm.setIssueTypeId(issueForm.getIssueTypeId()); |
| | |
| | | |
| | | 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); |
| | |
| | | return issues; |
| | | } |
| | | |
| | | // 상위 이슈 가져오기 |
| | | private IssueVo getParentIssueVo(Long parentIssueId) { |
| | | if (parentIssueId != null) { |
| | | Issue parentIssue = this.getIssue(parentIssueId); |
| | | return ConvertUtil.copyProperties(parentIssue, IssueVo.class); |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | // 중복된 상위 이슈 검색 |
| | | 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 (customFieldApiOverlaps != null && customFieldApiOverlaps.size() > 0) { |
| | | for (CustomFieldApiOverlap customFieldApiOverlap : customFieldApiOverlaps) { |
| | | for (IssueCustomFieldValueForm issueCustomFieldValue : issueApiForm.getIssueCustomFieldValues()) { |
| | | IssueCustomFieldValueCondition issueCustomFieldValueCondition = new IssueCustomFieldValueCondition(); |
| | | if (customFieldApiOverlap.getCustomField().getId().equals(issueCustomFieldValue.getCustomFieldId())) { |
| | | issueCustomFieldValueCondition.setUseValue(issueCustomFieldValue.getUseValue()); |
| | | if (issueCustomFieldValueForms.size() > 0) { |
| | | String concatUseValue = ""; |
| | | int useIdx = 0; |
| | | |
| | | 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; |
| | | IssueCustomFieldValueFormComparator comp = new IssueCustomFieldValueFormComparator(); |
| | | Collections.sort(issueCustomFieldValueForms, comp); |
| | | |
| | | 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)); |
| | | } |
| | | } |
| | | } |
| | |
| | | // 날짜 유효성 체크 |
| | | this.checkStartCompleteDate(issueForm.getStartDate(), issueForm.getCompleteDate()); |
| | | // 담당 부서 유효성 체크 |
| | | this.verifyIssueDepartment(project, issueForm); |
| | | //this.verifyIssueDepartment(project, issueForm); |
| | | |
| | | // 이슈 상태 유형이 '대기' 인 이슈 상태 가져오기 |
| | | IssueStatus issueStatus = this.issueStatusService.findByIssueStatusTypeIsReady(issueType.getWorkflow()); |
| | |
| | | // 날짜 유효성 체크 |
| | | this.checkStartCompleteDate(issueForm.getStartDate(), issueForm.getCompleteDate()); |
| | | // 담당 부서 유효성 체크 |
| | | this.verifyIssueDepartment(project, issueForm); |
| | | //this.verifyIssueDepartment(project, issueForm); |
| | | |
| | | // 이슈 상태 유형이 '대기' 인 이슈 상태 가져오기 |
| | | IssueStatus issueStatus = this.issueStatusService.findByIssueStatusTypeIsReady(issueType.getWorkflow()); |
| | |
| | | issueCondition.setWorkspaceId(this.userService.getUser(this.webAppUtil.getLoginId()).getLastWorkspaceId()); |
| | | User user = this.webAppUtil.getLoginUserObject(); |
| | | |
| | | |
| | | List<Map<String, Object>> results = Lists.newArrayList(); |
| | | Long totalCount = 0L; |
| | | |
| | | if (this.userWorkspaceService.checkWorkspaceManager(user)) { |
| | | if (this.userWorkspaceService.checkWorkspaceManager(user) || user.getPermission() >= MngPermission.USER_PERMISSION_MNG_ISSUE_ALL) { |
| | | results = this.issueMapper.find(issueCondition); |
| | | totalCount = this.issueMapper.count(issueCondition); |
| | | } else{ |
| | |
| | | |
| | | 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); |
| | |
| | | |
| | | case "02": // 프로젝트, 이슈 유형, 이슈 상태, 우선순위, 중요도, 담당자, 첨부파일, 사용자 정의 필드 정보, 댓글, 기록을 셋팅한다. |
| | | this.setIssueDetail(issueVo, issue); // 이슈 상세 정보를 셋팅한다. |
| | | this.setIssueTableConfigs(issue, issueVo); |
| | | issueVo.setProjectVo(ConvertUtil.copyProperties(issue.getProject(), ProjectVo.class)); |
| | | break; |
| | | } |
| | |
| | | |
| | | resJsonData.put(Constants.RES_KEY_CONTENTS, issueVo); |
| | | } |
| | | |
| | | // 테이블 설정 셋팅 |
| | | private void setIssueTableConfigs(Issue issue, IssueVo issueVo) { |
| | | Long IssueTypeId = issue.getIssueType().getId(); |
| | | |
| | | for (int tableConfigType : IssueTableConfig.IssueTableTypes) { |
| | | if (tableConfigType != IssueTableConfig.ISSUE_TABLE_TYPE_MAIN) { |
| | | issueVo.addIssueTableConfigVo(createIssueTableConfigVo(IssueTypeId, tableConfigType)); |
| | | } |
| | | } |
| | | } |
| | | |
| | | private IssueTableConfigVo createIssueTableConfigVo(Long issueTypeId, int tableConfigType) { |
| | | IssueTableConfig issueTableConfig = this.issueTableConfigService.findByUserIdAndWorkspaceIdAndIssueTypeIdAndIssueTableType(issueTypeId, tableConfigType); |
| | | if (issueTableConfig != null) { |
| | | return ConvertUtil.copyProperties(issueTableConfig, IssueTableConfigVo.class); |
| | | } |
| | | return new IssueTableConfigVo(); |
| | | } |
| | | |
| | | |
| | | // 하위 이슈 정보를 셋팅한다 |
| | | private void setDownIssues(Issue issue, IssueVo issueVo) { |
| | |
| | | @Override |
| | | @Transactional |
| | | 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(); |
| | | if (issueCustomFieldValueForms.size() > 0) { |
| | | for (IssueCustomFieldValueForm issueCustomFieldValueForm : issueCustomFieldValueForms) { |
| | | // 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); |
| | | String concatUseValue = ""; |
| | | for (int i = 0; i < issueCustomFieldValueForms.size(); i++) { |
| | | IssueCustomFieldValueForm issueCustomFieldValueForm = issueCustomFieldValueForms.get(i); |
| | | if (i > 0) { |
| | | concatUseValue = concatUseValue.concat(comma); |
| | | } |
| | | concatUseValue = concatUseValue.concat(issueCustomFieldValueForm.getUseValue()); |
| | | } |
| | | |
| | | 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)); |
| | | } |
| | | } |
| | | } |
| | |
| | | if (issueVos != null && issueVos.size() > 0) { |
| | | List<Issue> issue = Lists.newArrayList(); |
| | | for (IssueVo issueVo : issueVos) { |
| | | IssueVo parentIssueVo = issueVo.getParentIssueVo(); |
| | | issueForm.setId(issueVo.getId()); |
| | | issue.add(this.modifyIssueForApi(user, issueForm, files)); |
| | | |
| | | // 자동 종료 상태 설정이 되어 있지 않으면 오류발생 |
| | | Issue modifyIssue = this.modifyIssueForApi(user, issueForm, files); |
| | | Issue parentIssue = modifyIssue.getParentIssue(); |
| | | IssueType issueType = modifyIssue.getIssueType(); |
| | | IssueStatus issueStatus = issueType.getIssueStatus(); |
| | | if (issueStatus == null) { |
| | | throw new OwlRuntimeException(this.messageAccessor.getMessage(MsgConstants.API_COMPLETE_ISSUE_STATUS_NOT_EXIST)); |
| | | } |
| | | |
| | | if (parentIssue != null) { |
| | | 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); |
| | | } |
| | | } |
| | | |
| | | issue.add(modifyIssue); |
| | | } |
| | | return issue; |
| | | } else { |
| | |
| | | // 담당자 유효성 체크 |
| | | //this.verifyIssueAssignee(project, issueForm); |
| | | // 담당부서 유효성 체크 |
| | | this.verifyIssueDepartment(project, issueForm); |
| | | //this.verifyIssueDepartment(project, issueForm); |
| | | |
| | | CheckIssueData checkIssueData = new CheckIssueData(); |
| | | checkIssueData.setIssue(issue); |
| | |
| | | this.issueHistoryService.detectIssueStatus(issue, issueForm, detectIssueChange, oldIssueStatus, issueStatus); |
| | | } |
| | | |
| | | // db에 저장 |
| | | issue = this.saveIssue(issueForm, checkIssueData); |
| | | |
| | | // 이슈 이력 등록 |
| | |
| | | //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; |
| | | } |
| | | |
| | |
| | | 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); |
| | | Issue issue = null; |
| | | if(issueId != null){ |
| | | issue = this.getIssue(issueId); |
| | | } |
| | | // 이슈 수정 권한을 갖고 있는지 확인 |
| | | this.verifyIssueModifyPermission(issue, user); |
| | | |
| | |
| | | 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); |
| | | } |
| | | } |
| | | |
| | | // 이슈 생성, 삭제시 예약 이메일에 등록해놓는다. |
| | | this.reservationIssueEmail(issue, EmailType.ISSUE_REMOVE); |
| | | // 이슈 삭제 |