| | |
| | | package kr.wisestone.owl.service.impl; |
| | | |
| | | 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.domain.enumType.IssueHistoryType; |
| | | import kr.wisestone.owl.domain.enumType.IssueStatusType; |
| | | import kr.wisestone.owl.exception.OwlRuntimeException; |
| | | import kr.wisestone.owl.mapper.DepartmentMapper; |
| | | import kr.wisestone.owl.mapper.IssueMapper; |
| | | import kr.wisestone.owl.mapper.ProjectMapper; |
| | | import kr.wisestone.owl.repository.IssueRelationRepository; |
| | |
| | | |
| | | @Autowired |
| | | private ApiTokenService apiTokenService; |
| | | |
| | | @Autowired |
| | | private CompanyFieldService companyFieldService; |
| | | |
| | | @Autowired |
| | | private IspFieldService ispFieldService; |
| | | |
| | | @Autowired |
| | | private HostingFieldService hostingFieldService; |
| | | |
| | | @Autowired |
| | | private CommonConfiguration configuration; |
| | |
| | | private UserWorkspaceService userWorkspaceService; |
| | | |
| | | @Autowired |
| | | private UserLevelService userLevelService; |
| | | |
| | | @Autowired |
| | | private WorkflowDepartmentService workflowDepartmentService; |
| | | |
| | | @Autowired |
| | |
| | | private SimpMessagingTemplate simpMessagingTemplate; |
| | | |
| | | @Autowired |
| | | private UserDepartmentService userDepartmentService; |
| | | |
| | | @Autowired |
| | | private UserDepartmentRepository userDepartmentRepository; |
| | | |
| | | @Autowired |
| | | private DepartmentMapper departmentMapper; |
| | | |
| | | @Autowired |
| | | private WorkflowDepartmentRepository workflowDepartmentRepository; |
| | |
| | | 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) { |
| | |
| | | |
| | | Workflow workflow = issueType.getWorkflow(); |
| | | |
| | | // 이슈 상태가 지정되어 있지 않을 경우 초기값으로 지정 |
| | | if (issueApiForm.getIssueStatusId() == null) { |
| | | List<IssueStatusVo> issueStatusVos = issueStatusService.findByWorkflowId(workflow.getId()); |
| | | IssueStatusVo issueStatusVo = issueStatusVos.get(0); |
| | | issueApiForm.setIssueStatusId(issueStatusVo.getId()); |
| | | } |
| | | |
| | | // 워크플로우 상태에 따른 담당부서 가져오기 |
| | | if (issueApiForm.getIssueStatusId() != null) { |
| | | WorkflowDepartmentCondition workflowDepartmentCondition = new WorkflowDepartmentCondition(); |
| | | workflowDepartmentCondition.setIssueStatusId(issueApiForm.getIssueStatusId()); |
| | | workflowDepartmentCondition.setWorkflowId(workflow.getId()); |
| | | List<WorkflowDepartmentVo> workflowDepartmentVos = this.workflowDepartmentService.find(workflowDepartmentCondition); |
| | | |
| | | for (WorkflowDepartmentVo workflowDepartmentVo : workflowDepartmentVos) { |
| | | issueForm.addDepartmentId(workflowDepartmentVo.getDepartmentVo().getId()); |
| | | if (issueApiForm.getApiType().equals(IssueApiForm.ApiType.add)) { |
| | | // 이슈 상태가 지정되어 있지 않을 경우 워크플로우 대기 상태 값으로 지정 |
| | | List<Long> departmentIds = this.workflowDepartmentService.findFirstDepartmentIds(workflow); |
| | | if (departmentIds != null && departmentIds.size() > 0) { |
| | | for (Long departmentId : departmentIds) { |
| | | issueForm.addDepartmentId(departmentId); |
| | | } |
| | | } |
| | | } else if (issueApiForm.getIssueStatusId() == null){ |
| | | throw new OwlRuntimeException(this.messageAccessor.getMessage(MsgConstants.API_ISSUE_STATUS_NOT_EXIST)); |
| | | } |
| | | |
| | | // 프로젝트 입력 |
| | |
| | | |
| | | // 상위일감에 사용할 중복값 설정 |
| | | List<CustomFieldApiOverlap> customFieldApiOverlaps = this.customFieldApiOverlapService.find(user.getId(), issueApiForm.getIssueTypeId()); |
| | | for(int i=0; i < customFieldApiOverlaps.size() ; i++ ){ |
| | | CustomFieldApiOverlap customFieldApiOverlap = customFieldApiOverlaps.get(i); |
| | | issueApiForm.addUseIssueCustomFieldId(customFieldApiOverlap.getCustomField().getId()); |
| | | } |
| | | // if (customFieldApiOverlaps == null || customFieldApiOverlaps.size() == 0){ |
| | | // throw new OwlRuntimeException(this.messageAccessor.getMessage(MsgConstants.API_OVERLAP_SETTING_NOT_EXIST)); |
| | | // } |
| | | if (customFieldApiOverlaps != null && customFieldApiOverlaps.size() > 0) { |
| | | for (int i = 0; i < customFieldApiOverlaps.size(); i++) { |
| | | CustomFieldApiOverlap customFieldApiOverlap = customFieldApiOverlaps.get(i); |
| | | issueApiForm.addUseIssueCustomFieldId(customFieldApiOverlap.getCustomField().getId()); |
| | | } |
| | | |
| | | List<IssueVo> issueVos = this.findIssue(issueApiForm, customFieldApiOverlaps, user.getId()); |
| | | int size = issueVos.size(); |
| | | if (size > 0) { |
| | | issueForm.setParentIssueId(issueVos.get(0).getId()); |
| | | // 중복된 이슈검색 |
| | | List<Issue> issues = this.findIssue(issueApiForm, customFieldApiOverlaps, user.getId()); |
| | | int size = issues.size(); |
| | | if (size > 0) { |
| | | Issue targetIssue = issues.get(0); |
| | | if (targetIssue.getParentIssue() != null) { |
| | | issueForm.setParentIssueId(targetIssue.getParentIssue().getId()); |
| | | } else { |
| | | issueForm.setParentIssueId(targetIssue.getId()); |
| | | } |
| | | } |
| | | } |
| | | |
| | | issueForm.setIsApi(Issue.IS_API_YES); |
| | | |
| | | // 사용자 정의 필드 설정 |
| | | issueForm.setIssueCustomFields(issueApiForm.getCustomFieldValues()); |
| | | // 같은 도메인 업체 찾기 |
| | | this.findCompanyField(issueForm); |
| | | |
| | | // api 입력값 적용 |
| | | ConvertUtil.copyProperties(issueApiForm, issueForm); |
| | |
| | | |
| | | } else { |
| | | throw new OwlRuntimeException(this.messageAccessor.getMessage(MsgConstants.API_USER_ERROR)); |
| | | } |
| | | } |
| | | |
| | | private void findCompanyField(IssueForm issueForm) { |
| | | if(issueForm.getIssueCustomFields() != null && issueForm.getIssueCustomFields().size() > 0) { |
| | | CompanyFieldCondition condition = new CompanyFieldCondition(); |
| | | List<Map<String, Object>> companyFields = this.companyFieldService.find(condition); |
| | | List<Map<String, Object>> issueCompanyFields = Lists.newArrayList(); |
| | | List<Map<String, Object>> issueIspFields = Lists.newArrayList(); |
| | | List<Map<String, Object>> issueHostingFields = Lists.newArrayList(); |
| | | |
| | | for (Map<String, Object> issueCustomField : issueForm.getIssueCustomFields()) { |
| | | int customFieldId = (Integer) issueCustomField.get("customFieldId"); |
| | | Long customId = (long) customFieldId; |
| | | CustomField customField = this.customFieldService.getCustomField(customId); |
| | | if(customField != null && customField.getCustomFieldType().toString().equals("SITE") && customField.getName().equals("도메인")) { |
| | | String useValue = issueCustomField.get("useValue").toString(); |
| | | if(companyFields != null && companyFields.size() > 0) { |
| | | for (Map<String, Object> companyField : companyFields) { |
| | | CompanyFieldVo companyFieldVo = ConvertUtil.convertMapToClass(companyField, CompanyFieldVo.class); |
| | | if(useValue.equals(companyFieldVo.getUrl())) { |
| | | companyField.put("companyId", companyField.get("id")); |
| | | issueCompanyFields.add(companyField); |
| | | if(companyFieldVo.getIspId() != null) { |
| | | Map<String, Object> ispField = this.ispFieldService.find(companyFieldVo.getIspId()); |
| | | if (ispField != null) { |
| | | ispField.put("ispId", ispField.get("id")); |
| | | issueIspFields.add(ispField); |
| | | } |
| | | } |
| | | if(companyFieldVo.getHostingId() != null) { |
| | | Map<String, Object> hostingField = this.hostingFieldService.find(companyFieldVo.getHostingId()); |
| | | if (hostingField != null) { |
| | | hostingField.put("hostingId", hostingField.get("id")); |
| | | issueHostingFields.add(hostingField); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | issueForm.setIssueCompanyFields(issueCompanyFields); |
| | | issueForm.setIssueIspFields(issueIspFields); |
| | | issueForm.setIssueHostingFields(issueHostingFields); |
| | | } |
| | | } |
| | | } |
| | | |
| | |
| | | IssueForm issueForm = this.convertToIssueForm(issueApiForm, user); |
| | | |
| | | List<Issue> issues = Lists.newArrayList(); |
| | | if (issueForm.getParentIssueId() != null) { |
| | | if (issueForm.getParentIssueId() != null // 기존 추가된 상위 일감이 없거나 설정된 중복 이슈 id가 없을때 |
| | | || issueApiForm.getUseIssueCustomFieldIds().size() == 0) { |
| | | issues.add(addIssue(user, issueForm, issueApiForm.getMultipartFiles())); |
| | | } else { |
| | | // 상위 이슈 추가 |
| | | // 가상 상위 이슈 추가 |
| | | IssueForm parentIssueForm = issueForm.clone(); |
| | | parentIssueForm.setUseIssueCustomFields(issueApiForm.getUseIssueCustomFieldIds()); |
| | | Issue issue = addIssue(user, parentIssueForm, null); |
| | |
| | | } |
| | | |
| | | // 중복된 상위 이슈 검색 |
| | | private List<IssueVo> findIssue(IssueApiForm issueApiform, List<CustomFieldApiOverlap> customFieldApiOverlaps, Long userId) { |
| | | private List<Issue> findIssue(IssueApiForm issueApiform, List<CustomFieldApiOverlap> customFieldApiOverlaps, Long userId) { |
| | | List<IssueCustomFieldValueForm> issueCustomFieldValueForms = issueApiform.getIssueCustomFieldValues(); |
| | | List<IssueVo> resultIssueVos = Lists.newArrayList(); |
| | | List<Issue> resultIssueVos = Lists.newArrayList(); |
| | | String comma = ","; |
| | | |
| | | if (issueCustomFieldValueForms.size() > 0) { |
| | |
| | | |
| | | IssueCustomFieldValueCondition issueCustomFieldValueCondition = new IssueCustomFieldValueCondition(); |
| | | issueCustomFieldValueCondition.setUseValue(concatUseValue); |
| | | issueCustomFieldValueCondition.setIssueTypeId(issueApiform.getIssueTypeId()); |
| | | 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)); |
| | | resultIssueVos.add(this.getIssue(MapUtil.getLong(result, "id"))); |
| | | } |
| | | } |
| | | } |
| | |
| | | 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; |
| | | } |
| | | |
| | | // 연관이슈를 생성한다. |
| | |
| | | for(UserDepartment myDepartment : myDepartments){ |
| | | myDepartmentIds.add(myDepartment.getDepartmentId()); |
| | | } |
| | | } else { |
| | | myDepartmentIds.add(-1L); |
| | | } |
| | | issueCondition.setMyDepartmentIds(myDepartmentIds); |
| | | } |
| | | |
| | | void SetAllDepartmentId(IssueCondition issueCondition){ |
| | | List<Long> departmentIds = Lists.newArrayList(); |
| | | List<Map<String, Object>> departmentList = this.departmentMapper.find(null); |
| | | |
| | | if(departmentList != null && departmentList.size() > 0){ |
| | | for(Map<String, Object> department : departmentList){ |
| | | departmentIds.add((Long) department.get("id")); |
| | | } |
| | | } |
| | | issueCondition.setMyDepartmentIds(departmentIds); |
| | | } |
| | | |
| | | void SetWorkflowDepartment(List<IssueVo> issueVos){ |
| | |
| | | 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)) { |
| | | results = this.issueMapper.find(issueCondition); |
| | | totalCount = this.issueMapper.count(issueCondition); |
| | | if (this.userWorkspaceService.checkWorkspaceManager(user) |
| | | || MngPermission.checkMngPermission(userLevel.getPermission(), MngPermission.USER_PERMISSION_MNG_ISSUE)) { |
| | | this.SetAllDepartmentId(issueCondition); |
| | | } else{ |
| | | this.SetMyDepartmentId(issueCondition); |
| | | results = this.issueMapper.findByDepartment(issueCondition); |
| | | totalCount = this.issueMapper.countByDepartment(issueCondition); |
| | | /*results = this.issueMapper.findByDepartment(issueCondition); |
| | | totalCount = this.issueMapper.countByDepartment(issueCondition);*/ |
| | | } |
| | | results = this.issueMapper.find(issueCondition); |
| | | totalCount = this.issueMapper.count(issueCondition); |
| | | |
| | | |
| | | // 튜닝 전 - 0.8, 0.9, 0.9, 0.9, 0.9 |
| | |
| | | |
| | | 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); |
| | | |
| | | this.setCountDownIssues(results, issueVos); |
| | | if (issueCondition.getTree()) { |
| | | this.setParentIssue(issueVos); |
| | | this.setDownIssues(user, issueVos); |
| | | this.setRelationIssues(issueVos); |
| | | } |
| | | this.setCountDownIssues(issueVos); |
| | | |
| | | this.SetWorkflowDepartment(issueVos); //워크플로우에 설정한 담당부서 가져오기 |
| | | |
| | | resJsonData.put(Constants.RES_KEY_CONTENTS, issueVos); |
| | |
| | | return issueVos; |
| | | } |
| | | |
| | | |
| | | // 하위 이슈 세팅(재귀) |
| | | private void setDownIssues(User user, List<IssueVo> issueVos) { |
| | | for(IssueVo issueVo : issueVos) { |
| | | List<Issue> downIssues = this.issueRepository.findByParentIssueId(issueVo.getId()); |
| | | List<IssueVo> downIssueVos = Lists.newArrayList(); |
| | | IssueCondition issueCondition = new IssueCondition(); |
| | | issueCondition.addIssueIds(String.valueOf(issueVo.getId())); |
| | | |
| | | for(Issue downIssue : downIssues){ |
| | | IssueVo addIssueVo = ConvertUtil.copyProperties(downIssue, IssueVo.class); |
| | | addIssueVo.setIssueTypeId(downIssue.getIssueType().getId()); |
| | | downIssueVos.add(addIssueVo); |
| | | } |
| | | issueVo.setIssueDownVos(downIssueVos); |
| | | |
| | | if (downIssueVos.size() > 0) { |
| | | this.setDownIssues(user, downIssueVos); |
| | | } |
| | | |
| | | // 이슈 사용자 정보 추가 |
| | | //this.setIssueUserList(issueVos, issueCondition); |
| | | this.setIssueDepartmentList(issueVos, issueCondition, user); |
| | | // 등록자 정보 추가 |
| | | this.setRegister(issueVos); // 담당자 정보 셋팅 |
| | | // 사용자 정의 필드 정보 추가 |
| | | this.setIssueCustomFieldValue(issueVos, issueCondition); |
| | | //워크플로우에 설정한 담당부서 가져오기 |
| | | this.SetWorkflowDepartment(issueVos); |
| | | } |
| | | } |
| | | |
| | | // 연관 이슈 세팅 |
| | | private void setRelationIssues(List<IssueVo> issueVos) { |
| | | for(IssueVo issueVo : issueVos) { |
| | | List<IssueVo> relationIssues = this.issueRelationService.findRelationIssue(issueVo.getId()); |
| | | for(IssueVo relationIssue : relationIssues){ |
| | | issueVo.addRelationIssueVo(ConvertUtil.copyProperties(relationIssue, IssueVo.class)); |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 상위 이슈 체크 |
| | | private void setParentIssue(List<IssueVo> issueVos) { |
| | | for(IssueVo issueVo : issueVos) { |
| | | if(issueVo.getParentIssueId() != null) { |
| | | Issue parentIssue = this.getIssue(issueVo.getParentIssueId()); |
| | | //issueVo.setParentIssueVo(ConvertUtil.copyProperties(parentIssue, IssueVo.class)); |
| | | if(parentIssue.getIssueCustomFieldValues() == null || parentIssue.getIssueCustomFieldValues().size() == 0){ |
| | | issueVo.setIssueCustomFieldValueVos(null); |
| | | } |
| | | ConvertUtil.copyProperties(parentIssue, issueVo); |
| | | } |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(readOnly = true) |
| | | public void setCountDownIssues(List<Map<String, Object>> results, List<IssueVo> issueVos) { |
| | | for (Map<String, Object> result : results){ |
| | | List<Issue> downIssues = this.issueRepository.findByParentIssueId((Long) result.get("id")); //하위이슈 가져오기 |
| | | public void setCountDownIssues(List<IssueVo> issueVos) { |
| | | for (IssueVo issueVo : issueVos){ |
| | | List<Issue> downIssues = this.issueRepository.findByParentIssueId(issueVo.getId()); //하위이슈 가져오기 |
| | | if(downIssues != null && downIssues.size() > 0){ //상위이슈 가지고 있는 애들이 있으면 |
| | | int downIssueAllCount = 0;// 하위이슈 전체 카운트 |
| | | int downIssueCount = 0;// 하위이슈 미완료 카운트 |
| | |
| | | downIssueCount ++; |
| | | } |
| | | |
| | | for(IssueVo issueVo : issueVos){ |
| | | if(issueVo.getId().equals(parentIssueVo.getId())){ |
| | | issueVo.setDownIssueCount(downIssueCount); |
| | | issueVo.setDownIssueAllCount(parentIssueVo.getDownIssueAllCount()); |
| | | } |
| | | } |
| | | issueVo.setDownIssueCount(downIssueCount); |
| | | issueVo.setDownIssueAllCount(parentIssueVo.getDownIssueAllCount()); |
| | | } |
| | | } |
| | | } |
| | |
| | | public void findApiIssue(ApiMonitorCondition apiMonitorCondition, Map<String, Object> resJsonData) { |
| | | |
| | | IssueTypeCondition issueTypeCondition = new IssueTypeCondition(); |
| | | issueTypeCondition.setIsApi(Issue.IS_API_YES); |
| | | List<IssueTypeVo> issueTypes = this.issueTypeService.findIssueType(issueTypeCondition); |
| | | |
| | | // 값이 없을 경우 초기값 입력 |
| | | if (StringUtils.isEmpty(apiMonitorCondition.getSearchPeriod())) { |
| | | apiMonitorCondition.setSearchPeriod(DateUtil.LAST_SEVEN_DAYS); |
| | | } |
| | | |
| | | // 검색 일자를 구한다. |
| | | List<Date> searchDates = CommonUtil.findSearchPeriod(apiMonitorCondition.getSearchPeriod()); |
| | | List<Date> searchDates = Lists.newArrayList(); |
| | | if (apiMonitorCondition.getSearchPeriod().equals(DateUtil.CUSTOM_INPUT)) { |
| | | Date startDate = DateUtil.convertStrToDate(apiMonitorCondition.getSearchStartDate(), "yyyy-MM-dd"); |
| | | Date endDate = DateUtil.addDays(DateUtil.convertStrToDate(apiMonitorCondition.getSearchEndDate(), "yyyy-MM-dd"), 1); |
| | | |
| | | searchDates = CommonUtil.findSearchPeriod(startDate, endDate); |
| | | } else { |
| | | searchDates = CommonUtil.findSearchPeriod(apiMonitorCondition.getSearchPeriod()); |
| | | } |
| | | |
| | | // 날짜가 검색되지 않았으면 오류 |
| | | if (searchDates.size() < 1) { |
| | |
| | | // 프로젝트를 선택하지 않았으면 해당 업무 공간에서 참여하고 있는 프로젝트를 찾는다. |
| | | 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)) { |
| | | projects = this.projectMapper.findByWorkspaceManagerAll(projectCondition); |
| | | } else { |
| | | projects = this.projectService.findByWorkspaceIdAndIncludeProjectAll(projectCondition); |
| | |
| | | } |
| | | |
| | | // 이슈 수정 권한을 갖고 있는지 확인 |
| | | if (this.checkHasPermission(issueVo, issueVo.getUserVos(), user)) { |
| | | if (this.checkHasPermission(issueVo, issueVo.getUserVos(), user, null)) { |
| | | issueVo.setModifyPermissionCheck(Boolean.TRUE); |
| | | } |
| | | } |
| | |
| | | } |
| | | |
| | | // 이슈 수정 권한을 갖고 있는지 확인 |
| | | if (this.checkHasPermission(issueVo, issueVo.getUserVos(), user)) { |
| | | if (this.checkHasPermission(issueVo, issueVo.getUserVos(), user, issueVo.getDepartmentVos())) { |
| | | issueVo.setModifyPermissionCheck(Boolean.TRUE); |
| | | } |
| | | } |
| | |
| | | if (issueCondition.getId() != null) { |
| | | Issue issue = this.getIssue(issueCondition.getId()); |
| | | issueVo = ConvertUtil.copyProperties(issue, IssueVo.class); |
| | | User user = this.webAppUtil.getLoginUserObject(); |
| | | |
| | | switch (issueCondition.getDeep()) { |
| | | case "01": // 프로젝트, 이슈 유형, 이슈 상태, 우선순위, 중요도, 담당부서, 첨부파일, 사용자 정의 필드 정보를 셋팅한다. |
| | |
| | | break; |
| | | |
| | | case "02": // 프로젝트, 이슈 유형, 이슈 상태, 우선순위, 중요도, 담당자, 첨부파일, 사용자 정의 필드 정보, 댓글, 기록을 셋팅한다. |
| | | this.setIssueDetail(issueVo, issue); // 이슈 상세 정보를 셋팅한다. |
| | | this.setIssueDetail(issueVo, issue, user); // 이슈 상세 정보를 셋팅한다. |
| | | this.setIssueTableConfigs(issue, issueVo); |
| | | issueVo.setProjectVo(ConvertUtil.copyProperties(issue.getProject(), ProjectVo.class)); |
| | | break; |
| | |
| | | // 하위 이슈 정보를 셋팅한다 |
| | | private void setDownIssues(Issue issue, IssueVo issueVo) { |
| | | List<Issue> downIssues = this.issueRepository.findByParentIssueId(issue.getId()); |
| | | if(downIssues != null && downIssues.size()>0){ |
| | | List<IssueVo> resultList = new ArrayList<>(); |
| | | for(Issue downIssue : downIssues){ |
| | | IssueVo downIssueVo = ConvertUtil.copyProperties(downIssue, IssueVo.class); |
| | | downIssueVo.setIssueTypeVo(ConvertUtil.copyProperties(downIssue.getIssueType(), IssueTypeVo.class)); |
| | | downIssueVo.setPriorityVo(ConvertUtil.copyProperties(downIssue.getPriority(), PriorityVo.class)); |
| | | downIssueVo.setSeverityVo(ConvertUtil.copyProperties(downIssue.getSeverity(), SeverityVo.class)); |
| | | //이슈 상태 추가 |
| | | IssueStatusVo issueStatusVo = ConvertUtil.copyProperties(downIssue.getIssueStatus(), IssueStatusVo.class, "issueStatusType"); |
| | | issueStatusVo.setIssueStatusType(downIssue.getIssueStatus().getIssueStatusType().toString()); |
| | | downIssueVo.setIssueStatusVo(issueStatusVo); |
| | | if(downIssues != null && downIssues.size()>0){ |
| | | List<IssueVo> resultList = new ArrayList<>(); |
| | | for(Issue downIssue : downIssues){ |
| | | IssueVo downIssueVo = ConvertUtil.copyProperties(downIssue, IssueVo.class); |
| | | downIssueVo.setIssueTypeVo(ConvertUtil.copyProperties(downIssue.getIssueType(), IssueTypeVo.class)); |
| | | downIssueVo.setPriorityVo(ConvertUtil.copyProperties(downIssue.getPriority(), PriorityVo.class)); |
| | | downIssueVo.setSeverityVo(ConvertUtil.copyProperties(downIssue.getSeverity(), SeverityVo.class)); |
| | | //이슈 상태 추가 |
| | | IssueStatusVo issueStatusVo = ConvertUtil.copyProperties(downIssue.getIssueStatus(), IssueStatusVo.class, "issueStatusType"); |
| | | issueStatusVo.setIssueStatusType(downIssue.getIssueStatus().getIssueStatusType().toString()); |
| | | downIssueVo.setIssueStatusVo(issueStatusVo); |
| | | |
| | | this.setRegister(downIssue, downIssueVo); // 등록자 |
| | | this.setIssueDepartment(downIssue, downIssueVo); // 담당부서 정보 셋팅 |
| | | this.setIssueCustomFields(downIssue, downIssueVo); // 사용자정의필드 정보 세팅 |
| | | this.setRegister(downIssue, downIssueVo); // 등록자 |
| | | this.setIssueDepartment(downIssue, downIssueVo); // 담당부서 정보 셋팅 |
| | | this.setIssueCustomFields(downIssue, downIssueVo); // 사용자정의필드 정보 세팅 |
| | | |
| | | resultList.add(downIssueVo); |
| | | } |
| | | issueVo.setIssueDownVos(resultList); |
| | | resultList.add(downIssueVo); |
| | | } |
| | | issueVo.setIssueDownVos(resultList); |
| | | } |
| | | } |
| | | |
| | | // 이슈 상세 정보를 셋팅한다. |
| | | @Override |
| | | @Transactional(readOnly = true) |
| | | public void setIssueDetail(IssueVo issueVo, Issue issue) { |
| | | public void setIssueDetail(IssueVo issueVo, Issue issue, User user) { |
| | | issueVo.setProjectVo(ConvertUtil.copyProperties(issue.getProject(), ProjectVo.class)); |
| | | issueVo.setIssueTypeVo(ConvertUtil.copyProperties(issue.getIssueType(), IssueTypeVo.class)); |
| | | IssueStatusVo issueStatusVo = ConvertUtil.copyProperties(issue.getIssueStatus(), IssueStatusVo.class, "issueStatusType"); |
| | |
| | | this.setIssueCompanyField(issue, issueVo); //업체 정보 세팅 |
| | | this.setIssueIspField(issue, issueVo); //ISP 정보 세팅 |
| | | this.setIssueHostingField(issue, issueVo); //HOSTING 정보 세팅 |
| | | |
| | | this.setParentIssue(issue,issueVo); //상위 이슈 정보 세팅 |
| | | |
| | | // 이슈 수정 권한을 갖고 있는지 확인 |
| | | if (this.checkHasPermission(issueVo, issueVo.getUserVos(), user, issueVo.getDepartmentVos())) { |
| | | issueVo.setModifyPermissionCheck(Boolean.TRUE); |
| | | } |
| | | } |
| | | |
| | | // 상위일감 정보 추가 |
| | |
| | | DepartmentVo departmentVo = ConvertUtil.copyProperties(issueDepartment.getDepartment(), DepartmentVo.class); |
| | | departmentVo.setByName(departmentVo.getDepartmentName()); |
| | | departmentVos.add(departmentVo); |
| | | |
| | | List<UserDepartment> userDepartments = this.userDepartmentRepository.findByDepartmentId(departmentVo.getId()); |
| | | if (userDepartments != null && userDepartments.size() > 0) { |
| | | for (UserDepartment userDepartment : userDepartments) { |
| | | if (userDepartment.getUserId().equals(this.webAppUtil.getLoginId())){ |
| | | issueVo.setModifyPermissionCheck(Boolean.TRUE); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | issueVo.setDepartmentVos(departmentVos); |
| | | } |
| | |
| | | // 사용자 정의 필드 값이 같은 이슈 찾기 |
| | | @Override |
| | | @Transactional |
| | | public List<IssueVo> findIssue(IssueApiForm issueApiform) { |
| | | public List<Issue> findIssue(IssueApiForm issueApiform) { |
| | | |
| | | List<IssueCustomFieldValueForm> issueCustomFieldValueForms = issueApiform.getIssueCustomFieldValues(); |
| | | List<IssueVo> resultIssueVos = Lists.newArrayList(); |
| | | List<Issue> resultIssueVos = Lists.newArrayList(); |
| | | String comma = ","; |
| | | |
| | | if (issueCustomFieldValueForms.size() > 0) { |
| | |
| | | |
| | | IssueCustomFieldValueCondition issueCustomFieldValueCondition = new IssueCustomFieldValueCondition(); |
| | | issueCustomFieldValueCondition.setUseValue(concatUseValue); |
| | | issueCustomFieldValueCondition.setIssueTypeId(issueApiform.getIssueTypeId()); |
| | | 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)); |
| | | resultIssueVos.add(this.getIssue(MapUtil.getLong(result, "id"))); |
| | | } |
| | | } |
| | | } |
| | |
| | | User user = this.convertToUser(issueApiForm.getToken()); |
| | | IssueForm issueForm = this.convertToIssueForm(issueApiForm, user); |
| | | |
| | | List<IssueVo> issueVos = this.findIssue(issueApiForm); |
| | | if (issueVos != null && issueVos.size() > 0) { |
| | | List<Issue> issue = Lists.newArrayList(); |
| | | for (IssueVo issueVo : issueVos) { |
| | | IssueVo parentIssueVo = issueVo.getParentIssueVo(); |
| | | List<Issue> issue = this.findIssue(issueApiForm); |
| | | if (issue != null && issue.size() > 0) { |
| | | List<Issue> issues = Lists.newArrayList(); |
| | | for (Issue issueVo : issue) { |
| | | issueForm.setId(issueVo.getId()); |
| | | |
| | | // 자동 종료 상태 설정이 되어 있지 않으면 오류발생 |
| | |
| | | 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) { |
| | | if (issueStatus == null) { |
| | | throw new OwlRuntimeException(this.messageAccessor.getMessage(MsgConstants.API_COMPLETE_ISSUE_STATUS_NOT_EXIST)); |
| | | } |
| | | IssueCondition issueCondition = new IssueCondition(issueVo.getId(), parentIssue.getId()); |
| | | List<Map<String, Object>> results = this.issueMapper.findNotCompleteByParentIssueId(issueCondition); |
| | | // 하위 일감이 모두 종료 상태일때 상위 일감도 종료 처리 |
| | |
| | | } |
| | | } |
| | | |
| | | issue.add(modifyIssue); |
| | | issues.add(modifyIssue); |
| | | } |
| | | return issue; |
| | | return issues; |
| | | } else { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.API_ISSUE_NOT_EXIST)); |
| | |
| | | private Issue modifyIssueForApi(User user, IssueForm issueForm, List<MultipartFile> multipartFiles) { |
| | | CheckIssueData checkIssueData = this.checkIssue(user, issueForm); |
| | | |
| | | Issue issue = checkIssueData.getIssue(); |
| | | Project project = checkIssueData.getProject(); |
| | | IssueType issueType = checkIssueData.getIssueType(); |
| | | IssueStatus oldIssueStatus = checkIssueData.getOldIssueStatus(); |
| | | IssueStatus issueStatus = checkIssueData.getNewIssueStatus(); |
| | | // 이슈 이력 남기기 |
| | | this.addIssueHistoryModify(user, issueForm, checkIssueData, multipartFiles); |
| | | |
| | | // db에 저장 |
| | | return this.saveIssue(issueForm, checkIssueData); |
| | | } |
| | | |
| | | private void addIssueHistoryModify(User user, IssueForm issueForm, CheckIssueData checkIssueData, List<MultipartFile> multipartFiles) { |
| | | // 변경 이력 정보 추출 |
| | | StringBuilder detectIssueChange = this.issueHistoryService.detectIssueChange(issueForm, checkIssueData, multipartFiles); |
| | | |
| | | // 프로젝트가 변경되면 이슈 넘버를 새로 따야 한다. |
| | | this.checkChangeProject(checkIssueData.getProject(), issue); |
| | | this.checkChangeProject(checkIssueData.getProject(), checkIssueData.getIssue()); |
| | | |
| | | // 이슈 유형이 변경되었는지 확인하고 변경되었다면 이슈 상태 속성이 '대기' 인 이슈 상태로 교체한다. |
| | | if (this.checkChangeIssueType(issueType, issueStatus, issue)) { |
| | | issueStatus = this.issueStatusService.findByIssueStatusTypeIsReady(issueType.getWorkflow()); |
| | | if (this.checkChangeIssueType(checkIssueData.getIssueType(), checkIssueData.getNewIssueStatus(), checkIssueData.getIssue())) { |
| | | checkIssueData.setNewIssueStatus(this.issueStatusService.findByIssueStatusTypeIsReady(checkIssueData.getIssueType().getWorkflow())); |
| | | // 이슈 상태 변경 이력 남기기 - 이력을 남기기 위해 issueForm 에 issueStatus Id 값을 저장. |
| | | issueForm.setIssueStatusId(issueStatus.getId()); |
| | | this.issueHistoryService.detectIssueStatus(issue, issueForm, detectIssueChange, oldIssueStatus, issueStatus); |
| | | issueForm.setIssueStatusId(checkIssueData.getNewIssueStatus().getId()); |
| | | this.issueHistoryService.detectIssueStatus(checkIssueData.getIssue(), issueForm, detectIssueChange, checkIssueData.getOldIssueStatus(), checkIssueData.getNewIssueStatus()); |
| | | } |
| | | |
| | | // db에 저장 |
| | | issue = this.saveIssue(issueForm, checkIssueData); |
| | | // checkIssueData.setIssue(this.saveIssue(issueForm, checkIssueData)); |
| | | |
| | | // 이슈 이력 등록 |
| | | if (!StringUtils.isEmpty(detectIssueChange.toString())) { |
| | | this.issueHistoryService.addIssueHistory(issue, user, IssueHistoryType.MODIFY, detectIssueChange.toString()); |
| | | this.issueHistoryService.addIssueHistory(checkIssueData.getIssue(), user, IssueHistoryType.MODIFY, detectIssueChange.toString()); |
| | | } |
| | | // 사용자 시스템 기능 사용 정보 수집 |
| | | UserVo userVo = ConvertUtil.copyProperties(user, UserVo.class); |
| | | log.info(ElasticSearchUtil.makeUserActiveHistoryMessage(userVo, ElasticSearchConstants.ISSUE_MODIFY)); |
| | | |
| | | return issue; |
| | | } |
| | | |
| | | |
| | | |
| | | private Issue saveIssue(IssueForm issueForm, CheckIssueData checkIssueData) { |
| | | Issue issue = checkIssueData.getIssue(); |
| | |
| | | // 이슈 수정 권한 체크 |
| | | private void verifyIssueModifyPermission(Issue issue, User user) { |
| | | // 이슈 수정 권한을 갖고 있는지 확인 |
| | | if (!this.checkHasPermission(ConvertUtil.copyProperties(issue, IssueVo.class), this.getIssueUserVos(issue), user)) { |
| | | if (!this.checkHasPermission(ConvertUtil.copyProperties(issue, IssueVo.class), this.getIssueUserVos(issue), user, this.getIssueDepartmentVos(issue))) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.ISSUE_NOT_MODIFY_PERMISSION)); |
| | | } |
| | |
| | | return userVos; |
| | | } |
| | | |
| | | // 이슈에서 담당자 정보를 추출한다. |
| | | private List<DepartmentVo> getIssueDepartmentVos(Issue issue) { |
| | | List<DepartmentVo> departmentVos = Lists.newArrayList(); |
| | | |
| | | Set<IssueDepartment> issueDepartments = issue.getIssueDepartments(); |
| | | |
| | | try { |
| | | for (IssueDepartment issueDepartment : issueDepartments) { |
| | | Department department = issueDepartment.getDepartment(); |
| | | DepartmentVo departmentVo = ConvertUtil.copyProperties(department, DepartmentVo.class); |
| | | departmentVos.add(departmentVo); |
| | | } |
| | | } catch (Exception ex) { |
| | | |
| | | } |
| | | |
| | | return departmentVos; |
| | | } |
| | | |
| | | // 이슈 수정 권한을 갖고 있는지 확인 |
| | | private boolean checkHasPermission(IssueVo issueVo, List<UserVo> issueUserVos, User user) { |
| | | private boolean checkHasPermission(IssueVo issueVo, List<UserVo> issueUserVos, User user, List<DepartmentVo> departmentVos) { |
| | | boolean hasPermission = false; |
| | | |
| | | // 업무 공간 관리자일 경우 수정 권한을 갖는다. |
| | | hasPermission = this.checkIssueModifyPermission(hasPermission, Issue.WORKSPACE_MANAGER, issueVo, null, null, user); |
| | | // 프로젝트 관리자일 경우 해당 프로젝트에 등록된 이슈는 수정 권한을 갖는다. |
| | | hasPermission = this.checkIssueModifyPermission(hasPermission, Issue.PROJECT_MANAGER, issueVo, null, null, user); |
| | | // 이슈 관리자일 경우 수정 권한을 갖는다. |
| | | hasPermission = this.checkIssueModifyPermission(hasPermission, Issue.ISSUE_MANAGER, issueVo, null, null, user); |
| | | // 이슈 등록자일 경우 수정 권한을 갖는다. |
| | | hasPermission = this.checkIssueModifyPermission(hasPermission, Issue.REGISTER, issueVo, null, null, user); |
| | | // 이슈 담당자일 경우 수정 권한을 갖는다. => 담당부서로 수정 - 체크 |
| | | // 이슈 담당자일 경우 수정 권한을 갖는다. |
| | | //hasPermission = this.checkIssueModifyPermission(hasPermission, Issue.ASSIGNEE, issueVo, issueUserVos); |
| | | // 이슈 담당부서일 경우 수정 권한을 갖는다. |
| | | hasPermission = this.checkIssueModifyPermission(hasPermission, Issue.DEPARTMENT, issueVo, null, departmentVos, user); |
| | | // 담당자가 없으면 모든 사용자가 수정 권한을 갖는다. |
| | | |
| | | //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; |
| | | } |
| | | |
| | | // 이슈 수정 권한을 확인한다. |
| | | private boolean checkIssueModifyPermission(Boolean hasPermission, String checkType, IssueVo issueVo, List<UserVo> issueUserVos, List<DepartmentVo> issueDepartmentVos, User user) { |
| | | private boolean checkIssueModifyPermission(Boolean hasPermission, String checkType, IssueVo issueVo, List<UserVo> issueUserVos, List<DepartmentVo> departmentVos, User user) { |
| | | if (!hasPermission) { |
| | | switch (checkType) { |
| | | case Issue.WORKSPACE_MANAGER: // 업무 공간 관리자 |
| | |
| | | Issue issue = this.getIssue(issueVo.getId()); |
| | | // 프로젝트 관리자일 경우 해당 프로젝트에 등록된 이슈는 수정 권한을 갖는다. |
| | | hasPermission = this.projectRoleUserService.checkProjectManager(issue.getProject(), user); |
| | | break; |
| | | |
| | | case Issue.ISSUE_MANAGER: // 이슈 관리자 |
| | | UserLevel userLevel = this.userLevelService.getUserLevel(user.getUserLevel().getId()); |
| | | hasPermission = MngPermission.checkMngPermission(userLevel.getPermission(), MngPermission.USER_PERMISSION_MNG_ISSUE); |
| | | break; |
| | | |
| | | case Issue.REGISTER: // 이슈 등록자 |
| | |
| | | |
| | | case Issue.DEPARTMENT: |
| | | // 담당부서가 없으면 모든 사용자가 수정 권한을 갖는다. |
| | | if (issueDepartmentVos.size() < 1) { |
| | | /*if (userDepartmentVos.size() < 1) { |
| | | hasPermission = true; |
| | | break; |
| | | } |
| | | // 이슈 담당부서 여부 확인 |
| | | /*for (DepartmentVo issueDepartmentVo : issueDepartmentVos) { |
| | | if (issueDepartmentVo.getId().equals()) { |
| | | hasPermission = true; |
| | | break; |
| | | } |
| | | }*/ |
| | | // 이슈 담당부서 여부 확인 |
| | | for (DepartmentVo departmentVo : departmentVos) { |
| | | List<UserDepartment> userDepartments = this.userDepartmentService.findByDepartmentId(departmentVo.getId()); |
| | | if(userDepartments != null && userDepartments.size() > 0) { |
| | | for (UserDepartment userDepartment : userDepartments) { |
| | | if (userDepartment.getUserId().equals(user.getId())){ |
| | | hasPermission = true; |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | break; |
| | | } |
| | | } |
| | |
| | | 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); |
| | | // 변경 이력 정보 추출 |
| | |
| | | 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<>(); // 이슈 번호 모음 |
| | |
| | | // 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)); |
| | | } |
| | | } |
| | | |
| | |
| | | |
| | | // 이슈의 주요 속성을 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(); |
| | |
| | | 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")); |
| | | } |
| | | } |
| | | |
| | | // 이슈 유형을 바로 찾을 수 있게 준비 |
| | |
| | | |
| | | 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); |
| | | } |
| | | } |
| | | |
| | | // 우선순위를 바로 찾을 수 있게 준비 |
| | |
| | | |
| | | // 엑셀 필드에 있는 정보를 이슈 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; |
| | |
| | | // 중요도를 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 에 저장한다. |
| | |
| | | this.setIssueFormPeriod(cell, issueForm, false, rowIndex); |
| | | break; |
| | | default: |
| | | // 8번 이상부터는 사용자 정의 필드. 사용자 정의 필드 정보를 IssueForm 에 저장한다. |
| | | // 9번 부터는 사용자 정의 필드. 사용자 정의 필드 정보를 IssueForm 에 저장한다. |
| | | this.setIssueFormCustomFieldValue(cell, customFieldMaps, issueForm, headers.get(cellIndex), rowIndex); |
| | | } |
| | | } |
| | |
| | | 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); |
| | | } |
| | | } |
| | |
| | | // 시작일, 종료일을 IssueForm 에 저장한다. |
| | | 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; |
| | | |
| | |
| | | // 이슈를 템플릿에 따라 파트너 담당자에게 메일로 발송한다. |
| | | @Override |
| | | @Transactional(readOnly = true) |
| | | public void sendIssueEmailPartners(IssueForm issueForm) { |
| | | if (issueForm.getSendEmails().size() < 1) { |
| | | public void sendIssueEmailPartners(EmailTemplateForm emailTemplateForm) { |
| | | if (emailTemplateForm.getSendEmails().size() < 1) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.ISSUE_NOT_SEND_USER)); |
| | | }else if (issueForm.getTemplate() == null){ |
| | | }else if (emailTemplateForm.getTemplate() == null){ |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.ISSUE_NOT_SELECT_TEMPLATE)); |
| | | } else if (emailTemplateForm.getIssueId() == null) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.ISSUE_NOT_EXIST)); |
| | | } |
| | | |
| | | Issue issue = this.getIssue(issueForm.getId()); |
| | | Issue issue = this.getIssue(emailTemplateForm.getIssueId()); |
| | | |
| | | Map<String, Object> issueMap = new HashMap<>(); |
| | | // 이슈 정보를 이메일 전송에 사용하기 위해 Map 형태로 변환한다. |
| | | this.makeIssueMapToIssue(issue, issueMap); |
| | | // 발신자 표시 |
| | | User user = this.webAppUtil.getLoginUserObject(); |
| | | UserVo toUser = this.webAppUtil.getLoginUser(); |
| | | issueMap.put("toUser", toUser.getName() + "(" + CommonUtil.decryptAES128(toUser.getAccount()) + ")"); |
| | | |
| | | // 이슈 링크 |
| | | String projectKey = issue.getProject().getProjectKey(); |
| | | Long IssueNumber = issue.getIssueNumber(); |
| | | String link = this.configuration.getEmailSendUrl() + "/#/issues/issueList?projectKey=" + projectKey + "&issueNumber=" + IssueNumber.toString(); |
| | | |
| | | issueMap.put("issueLink", link); |
| | | issueMap.put("projectLink", link); |
| | | |
| | | // 사용자 시스템 기능 사용 정보 수집 |
| | | log.info(ElasticSearchUtil.makeUserActiveHistoryMessage(this.webAppUtil.getLoginUser(), ElasticSearchConstants.ISSUE_ANOTHER_USER_SEND_EMAIL)); |
| | | StringBuilder sb = new StringBuilder(); |
| | | |
| | | if(issueForm.getTemplate().equals(EmailType.ISSUE_SEND_1.toString())){ |
| | | this.systemEmailService.directEmail(ConvertUtil.ToArray(issueForm.getSendEmails()), EmailType.ISSUE_SEND_1, issueMap, null); |
| | | }else if(issueForm.getTemplate().equals(EmailType.ISSUE_SEND_2.toString())){ |
| | | this.systemEmailService.directEmail(ConvertUtil.ToArray(issueForm.getSendEmails()), EmailType.ISSUE_SEND_2, issueMap, null); |
| | | }else if(issueForm.getTemplate().equals(EmailType.ISSUE_SEND_3.toString())){ |
| | | this.systemEmailService.directEmail(ConvertUtil.ToArray(issueForm.getSendEmails()), EmailType.ISSUE_SEND_3, issueMap, null); |
| | | Locale locale = CommonUtil.getUserLanguage(user.getLanguage()); |
| | | String[] sendMails = ConvertUtil.ToArray(emailTemplateForm.getSendEmails()); |
| | | for(int i=0; i < sendMails.length; i++) { |
| | | sendMails[i] = CommonUtil.decryptAES128(sendMails[i]); |
| | | } |
| | | //메일 전송 이력 남기기 |
| | | this.issueHistoryService.detectSendIssueMail(IssueHistoryType.SEND, issueForm, sb); |
| | | this.systemEmailService.sendEmail(emailTemplateForm.getTitle(), emailTemplateForm.getTemplate(), sendMails, null); |
| | | |
| | | this.issueHistoryService.detectSendIssueMail(IssueHistoryType.SEND, emailTemplateForm.getSendEmails(), sb); |
| | | this.issueHistoryService.addIssueHistory(issue, IssueHistoryType.SEND, sb.toString()); |
| | | } |
| | | |
| | |
| | | } |
| | | this.issueHistoryService.addIssueHistory(parentIssue, IssueHistoryType.MODIFY, sb.toString()); //parentIssue = myIssue(기록은 현재 상세페이지에 해야하니까) |
| | | this.issueRepository.saveAndFlush(issue); |
| | | |
| | | } |
| | | |
| | | @Override |