OWL ITS + 탐지시스템(인터넷 진흥원)
src/main/java/kr/wisestone/owl/service/impl/IssueServiceImpl.java
@@ -46,11 +46,10 @@
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.text.ParseException;
import java.util.*;
import static kr.wisestone.owl.domain.enumType.CustomFieldType.DATETIME;
import static kr.wisestone.owl.domain.enumType.CustomFieldType.INPUT;
import static kr.wisestone.owl.domain.enumType.CustomFieldType.*;
@Service
public class IssueServiceImpl extends AbstractServiceImpl<Issue, Long, JpaRepository<Issue, Long>> implements IssueService {
@@ -310,7 +309,7 @@
                    issueApiForm.addUseIssueCustomFieldId(customFieldApiOverlap.getCustomField().getId());
                }
                // 종료상태가 아닌 중복된 상위 이슈검색
                // 중복된 상위 이슈검색
                List<Issue> issues = this.findIssue(issueApiForm, customFieldApiOverlaps, user.getId());
                int size = issues.size();
                if (size > 0) {
@@ -356,17 +355,17 @@
                    if(companyFields != null && companyFields.size() > 0) {
                        for (Map<String, Object> companyField : companyFields) {
                            CompanyFieldVo companyFieldVo = ConvertUtil.convertMapToClass(companyField, CompanyFieldVo.class);
                            if(useValue.equals(companyFieldVo.getUrl())) {
                            if(companyFieldVo.getUrl() != null && useValue.equals(companyFieldVo.getUrl())) {
                                companyField.put("companyId", companyField.get("id"));
                                issueCompanyFields.add(companyField);
                                if(companyFieldVo.getIspId() != null) {
                                if(companyFieldVo.getIspId() != null && companyFieldVo.getIspId() != -1) {
                                    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) {
                                if(companyFieldVo.getHostingId() != null && companyFieldVo.getHostingId() != -1) {
                                    Map<String, Object> hostingField = this.hostingFieldService.find(companyFieldVo.getHostingId());
                                    if (hostingField != null) {
                                        hostingField.put("hostingId", hostingField.get("id"));
@@ -467,7 +466,7 @@
            issueCustomFieldValueCondition.setUseValue(concatUseValue);
            issueCustomFieldValueCondition.setUseValues(userValues);
            issueCustomFieldValueCondition.setIssueTypeId(issueApiform.getIssueTypeId());
            issueCustomFieldValueCondition.setIssueStatusType("CLOSE");
//            issueCustomFieldValueCondition.setIssueStatusType("CLOSE");
            List<Map<String, Object>> results = this.issueMapper.findByCustomFieldValue(issueCustomFieldValueCondition);
            if (results != null && results.size() > 0) {
                for (Map<String, Object> result : results) {
@@ -522,6 +521,12 @@
        if (issueForm.getParentIssueId() != null){
            Issue parentIssue = this.getIssue(issueForm.getParentIssueId());
            issue.setParentIssue(parentIssue);
            // 상위 이슈가 종료일경우 대기로 변경
            IssueStatus parentIssueStatus = parentIssue.getIssueStatus();
            if (parentIssueStatus.getIssueStatusType().equals(IssueStatusType.CLOSE)) {
                parentIssue.setIssueStatus(issueStatus);
            }
        }
        issue.setIssueNumber(this.issueNumberGeneratorService.generateIssueNumber(project));    //  각 프로젝트의 고유 이슈 번호 생성
@@ -576,15 +581,15 @@
    //  하위이슈를 생성한다.
    @Override
    @Transactional
    public Issue addDownIssue(IssueForm issueForm, List<MultipartFile> multipartFiles) {
    public Issue addDownIssue(Map<String, Object> resJsonData, IssueForm issueForm, List<MultipartFile> multipartFiles) {
        User user = this.webAppUtil.getLoginUserObject();
        return addDownIssue(user, issueForm, multipartFiles);
        return addDownIssue(resJsonData, user, issueForm, multipartFiles);
    }
    //  하위이슈를 생성한다.
    @Override
    @Transactional
    public Issue addDownIssue(User user, IssueForm issueForm, List<MultipartFile> multipartFiles) {
    public Issue addDownIssue(Map<String, Object> resJsonData, User user, IssueForm issueForm, List<MultipartFile> multipartFiles) {
        StringBuilder detectIssueChange = new StringBuilder();
        //  사용하고 있는 업무 공간이 활성 상태인지 확인한다. 사용 공간에서 로그인한 사용자가 비활성인지 확인한다.
@@ -648,6 +653,7 @@
        this.issueHistoryService.addIssueHistory(issue, user, IssueHistoryType.ADD, null);
        //  이슈 위험 관리 생성
        this.issueRiskService.addIssueRisk(issue, project.getWorkspace());
        //  영속성 컨텍스트 비우기
        this.clear();
        //  이슈 생성, 삭제시 예약 이메일에 등록해놓는다.
@@ -657,7 +663,22 @@
        UserVo userVo = ConvertUtil.copyProperties(user, UserVo.class);
        log.info(ElasticSearchUtil.makeUserActiveHistoryMessage(userVo, ElasticSearchConstants.ISSUE_ADD));
        IssueVo issueVo = this.convertToIssueVo(issue);
        resJsonData.put(Constants.RES_KEY_CONTENTS, issueVo);
        return issue;
    }
    /**
     * Issue를 IssueVo로 변환(하위이슈의 파트너 정보 상속 시 필요)
     * @param issue Issue
     * @return IssueVo
     */
    private IssueVo convertToIssueVo(Issue issue) {
        IssueVo issueVo = ConvertUtil.copyProperties(issue, IssueVo.class);
        issueVo.setInheritPartners(issue.getIssueType().getInheritPartners());
        issueVo.setUsePartner(issue.getIssueType().getUsePartner());
        return issueVo;
    }
    //  연관이슈를 생성한다.
@@ -867,15 +888,28 @@
        }
    }
    //  날짜 유효성 체크
    /**
     * 날짜 유효성 체크
     * @param startDate 시작 일자(문자)
     * @param completeDate 종료 일자(문자)
     */
    private void checkStartCompleteDate(String startDate, String completeDate) {
        if (!StringUtils.isEmpty(startDate) && !StringUtils.isEmpty(completeDate)) {
            Date start = DateUtil.convertStrToDate(startDate, "yy-MM-dd");
            Date end = DateUtil.convertStrToDate(completeDate, "yy-MM-dd");
            if (start.getTime() > end.getTime()) {
                throw new OwlRuntimeException(
                        this.messageAccessor.getMessage(MsgConstants.DATE_PICKER_NOT_AVAILABLE));
            }
            checkStartCompleteDate(start, end);
        }
    }
    /**
     * 날짜 유효성 체크
     * @param start 시작 일자
     * @param end 종료 일자
     */
    private void checkStartCompleteDate(Date start, Date end) {
        if (start.getTime() > end.getTime()) {
            throw new OwlRuntimeException(
                    this.messageAccessor.getMessage(MsgConstants.DATE_PICKER_NOT_AVAILABLE));
        }
    }
@@ -1256,6 +1290,9 @@
    private void setMapToIssueVo(List<Map<String, Object>> results, List<IssueVo> issueVos, IssueCondition issueCondition, User user) {
        for (Map<String, Object> result : results) {
            IssueVo issueVo = ConvertUtil.convertMapToClass(result, IssueVo.class);
            if (MapUtil.getString(result, "inheritPartners") != null && MapUtil.getString(result, "inheritPartners").equals("1")) {
                issueVo.setInheritPartners(true);
            }
            issueVos.add(issueVo);
            issueCondition.addIssueIds(String.valueOf(issueVo.getId()));
        }
@@ -2107,6 +2144,15 @@
        //  HOSTING 정보 저장
        this.issueHostingService.modifyIssueHostingField(issue, issueForm, detectIssueChange);
        //  파트너정보 하위이슈 상속
        List<Issue> downIssues = this.issueRepository.findByParentIssueId(issue.getId());
        if (issueForm.getInheritYn() != null && issueForm.getInheritYn()
                && downIssues != null && downIssues.size() > 0) {
            for (Issue downIssue : downIssues) {
                this.inheritPartners(downIssue, issue);
            }
        }
        //  이슈 이력 등록
        if (!StringUtils.isEmpty(detectIssueChange.toString())) {
            this.issueHistoryService.addIssueHistory(issue, user, IssueHistoryType.MODIFY, detectIssueChange.toString());
@@ -2755,6 +2801,9 @@
        excelInfo.addAttrInfos(new ExportExcelAttrVo("register", this.messageAccessor.message("common.register"), 20, ExportExcelAttrVo.ALIGN_CENTER)); // 등록자
        excelInfo.addAttrInfos(new ExportExcelAttrVo("period", this.messageAccessor.message("common.period"), 20, ExportExcelAttrVo.ALIGN_CENTER)); // 기간
        excelInfo.addAttrInfos(new ExportExcelAttrVo("modifyDate", this.messageAccessor.message("common.modifyDate"), 20, ExportExcelAttrVo.ALIGN_CENTER)); // 최종 변경일
        excelInfo.addAttrInfos(new ExportExcelAttrVo("companyName", this.messageAccessor.message("common.company"), 20, ExportExcelAttrVo.ALIGN_CENTER)); // 업체
        excelInfo.addAttrInfos(new ExportExcelAttrVo("ispName", this.messageAccessor.message("common.isp"), 20, ExportExcelAttrVo.ALIGN_CENTER)); // ISP
        excelInfo.addAttrInfos(new ExportExcelAttrVo("hostingName", this.messageAccessor.message("common.hosting"), 20, ExportExcelAttrVo.ALIGN_CENTER)); // 호스팅
        //  사용자 정의 필드를 사용한 이슈를 찾는다. 만약 이슈가 없다면 여기서 이슈 조회가 끝난다.
@@ -2815,8 +2864,16 @@
        for (IssueVo issueVo : issueVos) {
            for (Map<String, Object> issueCustomFieldValue : issueCustomFieldValues) {
                int count = 0;
                Map<String, Object> useValues = new HashMap<>();
                if (issueVo.getId().equals(MapUtil.getLong(issueCustomFieldValue, "issueId"))) {
                    IssueCustomFieldValueVo issueCustomFieldValueVo = new IssueCustomFieldValueVo();
                    useValues.put("useValue"+count, MapUtil.getString(issueCustomFieldValue, "useValue"));
                    useValues.put("customFieldId", MapUtil.getLong(issueCustomFieldValue, "customFieldId"));
                    issueCustomFieldValueVo.setUseValues(useValues);
                    issueCustomFieldValueVo.setUseValue(MapUtil.getString(issueCustomFieldValue, "useValue"));
                    CustomFieldVo customFieldVo = new CustomFieldVo();
@@ -2855,8 +2912,12 @@
                    issueCompanyVo.setRegionName(region.getUseValue());
                }
                if (issueCompany.getStatusId() != null && issueCompany.getStatusId() != -1) {
                    CompanyFieldCategory status = this.companyFieldCategoryService.find(issueCompany.getStatusId());
                    issueCompanyVo.setStatusName(status.getUseValue());
                    if (issueCompany.getStatusName() != null && !issueCompany.getStatusName().equals("")) {
                        issueCompanyVo.setStatusName(issueCompany.getStatusName());
                    } else {
                        CompanyFieldCategory status = this.companyFieldCategoryService.find(issueCompany.getStatusId());
                        issueCompanyVo.setStatusName(status.getUseValue());
                    }
                }
            }
            issueCompanyVos.add(issueCompanyVo);
@@ -2927,6 +2988,9 @@
                result.put("departments", CommonUtil.convertDepartmentVosToString(issueVo.getDepartmentVos()));
                result.put("priorityName", issueVo.getPriorityName());
                result.put("severityName", issueVo.getSeverityName());
                result.put("companyName", issueVo.getCompanyName());
                result.put("ispName", issueVo.getIspName());
                result.put("hostingName", issueVo.getHostingName());
                UserVo register = this.userService.removeSensitiveUser(issueVo.getRegisterId());
                //  등록자
@@ -3004,6 +3068,9 @@
        excelInfo.addAttrInfos(new ExportExcelAttrVo("id", this.messageAccessor.message("common.importance"), 5, ExportExcelAttrVo.ALIGN_CENTER)); // 중요도
        excelInfo.addAttrInfos(new ExportExcelAttrVo("id", this.messageAccessor.message("common.startDate"), 10, ExportExcelAttrVo.ALIGN_CENTER)); // 시작일
        excelInfo.addAttrInfos(new ExportExcelAttrVo("id", this.messageAccessor.message("common.endDate"), 10, ExportExcelAttrVo.ALIGN_CENTER)); // 종료일
        excelInfo.addAttrInfos(new ExportExcelAttrVo("id", this.messageAccessor.message("common.company"), 10, ExportExcelAttrVo.ALIGN_CENTER)); // 업체
        excelInfo.addAttrInfos(new ExportExcelAttrVo("id", this.messageAccessor.message("common.isp"), 10, ExportExcelAttrVo.ALIGN_CENTER)); // ISP
        excelInfo.addAttrInfos(new ExportExcelAttrVo("id", this.messageAccessor.message("common.hosting"), 10, ExportExcelAttrVo.ALIGN_CENTER)); // 호스팅
        //  프로젝트에 연결된 사용자 정의 필드 정보를 추출하여 엑셀 download 템플릿을 만든다.
        this.makeIssueExcelTemplateCustomFields(excelInfo, conditions);
        //  엑셀에 넣을 데이터 - IssueVos 데이터를 엑셀에서 표시할 수 있는 데이터로 변경한다.
@@ -3043,9 +3110,14 @@
            Map<Long, Long> issueNumberMaps = new HashMap<>();  //  이슈 번호 모음
            Map<String, Long> issueTypeCustomFieldMaps = new HashMap<>(); //  이슈 타입 + 사용자 정의 필드 연결 정보
            Map<String, CompanyField> companyFieldMaps = new HashMap<>();   //업체 모음
            Map<String, IspField> ispFieldMaps = new HashMap<>();   //isp 모음
            Map<String, HostingField> hostingFieldMaps = new HashMap<>();   //호스팅 모음
            Workspace workspace = this.workspaceService.getWorkspace(this.userService.getUser(this.webAppUtil.getLoginId()).getLastWorkspaceId());  //  이슈를 넣으려는 업무 공간
            //  이슈의 주요 속성을 map 에 저장하여 엑셀 import 에서 지정한 대상(이슈 속성)을 빠르게 찾을 수 있게 한다.
            this.IssueAttributeMapToList(issueForm, priorityMaps, severityMaps, departmentMaps, customFieldMaps, issueTypeCustomFieldMaps);
            this.IssueAttributeMapToList(issueForm, priorityMaps, severityMaps, departmentMaps, customFieldMaps,
                    issueTypeCustomFieldMaps, companyFieldMaps, ispFieldMaps, hostingFieldMaps);
            //  0.237 - 0.230
            List<IssueForm> issueForms = Lists.newArrayList();
@@ -3088,14 +3160,11 @@
                //  1번 헤더부터 데이터 영역
                if (rowIndex > 1) {
                    //  이슈로 등록하기 위해 IssueForm 에 데이터를 셋팅한다.
                    IssueForm newIssueForm = this.setIssueFormToExcelField(row, (rowIndex + 1), priorityMaps, severityMaps, departmentMaps, customFieldMaps, headers);
                    IssueForm newIssueForm = this.setIssueFormToExcelField(row, (rowIndex + 1), priorityMaps, severityMaps, customFieldMaps,
                            companyFieldMaps, ispFieldMaps, hostingFieldMaps, headers);
                    ConvertUtil.copyProperties(issueForm, newIssueForm);
                    issueForms.add(newIssueForm);
                }
            }
@@ -3132,6 +3201,11 @@
                issue = this.issueRepository.saveAndFlush(issue);
                if (issueForm.getInheritYn() != null && issueForm.getInheritYn() && issue.getParentIssue() != null) {
                    //  상위이슈의 파트너 정보 상속
                    this.inheritPartners(issue, issue.getParentIssue());
                }
                saveIssueForm.setId(issue.getId());
                IssueDepartment issueDepartment = new IssueDepartment();
@@ -3147,6 +3221,8 @@
                }
                saveIssueForm.setIssueStatusId(issueStatus.getId());
                this.setIssuePartners(saveIssueForm, issue);
            }
@@ -3179,6 +3255,69 @@
            //  증가된 이슈 번호를 업데이트 한다.
//            issueNumberMaps.put(issueForm.getProjectId(), issueForm.getProjectId());
//            this.issueNumberGeneratorService.updateIssueNumber(issueNumberMaps);
        }
    }
    /**
     * 엑셀로 입력한 파트너 정보 저장
     * @param issueForm IssueForm
     */
    private void setIssuePartners(IssueForm issueForm, Issue issue) {
        IssueCompany issueCompany = new IssueCompany();
        IssueIsp issueIsp = new IssueIsp();
        IssueHosting issueHosting = new IssueHosting();
        //issueCompany 등록
        if (issueForm.getIssueCompanyFields() != null && issueForm.getIssueCompanyFields().size() > 0) {
            for (Map<String, Object> issueCompanyMap : issueForm.getIssueCompanyFields()) {
                CompanyField companyField =  ConvertUtil.convertMapToClass(issueCompanyMap, CompanyField.class);
                issueCompany = ConvertUtil.convertMapToClass(issueCompanyMap, IssueCompany.class, "id");
                issueCompany.setCompanyField(companyField);
                issueCompany.setIssue(issue);
                this.issueCompanyRepository.saveAndFlush(issueCompany);
                //  사용자가 ISP를 직접 입력하지 않았을 경우 업체에 등록되어있는 ISP 설정
                if (issueForm.getIssueIspFields() == null || issueForm.getIssueIspFields().size() < 1) {
                    //  업체의 ISP가 있는 경우 issueISP 등록
                    if (companyField.getIspId() != null && companyField.getIspId() != -1) {
                        IspField ispField = this.ispFieldService.getIsp(companyField.getIspId());
                        issueIsp = ConvertUtil.copyProperties(ispField, IssueIsp.class, "id");
                        issueIsp.setIspField(ispField);
                        issueIsp.setIssue(issue);
                        this.issueIspRepository.saveAndFlush(issueIsp);
                    }
                }
                //  사용자가 호스팅을 직접 입력하지 않았을 경우 업체에 등록되어있는 호스팅 설정
                if (issueForm.getIssueHostingFields() == null || issueForm.getIssueHostingFields().size() < 1) {
                    //  업체의 호스팅이 있는 경우 issueHosting 등록
                    if (companyField.getHostingId() != null && companyField.getHostingId() != -1) {
                        HostingField hostingField = this.hostingFieldService.getHosting(companyField.getHostingId());
                        issueHosting = ConvertUtil.copyProperties(hostingField, IssueHosting.class, "id");
                        issueHosting.setHostingField(hostingField);
                        issueHosting.setIssue(issue);
                        this.issueHostingRepository.saveAndFlush(issueHosting);
                    }
                }
            }
        }
        //issueIsp 등록
        if (issueForm.getIssueIspFields() != null && issueForm.getIssueIspFields().size() > 0) {
            for (Map<String, Object> issueIspMap : issueForm.getIssueIspFields()) {
                issueIsp = ConvertUtil.convertMapToClass(issueIspMap, IssueIsp.class, "id");
                IspField ispField = ConvertUtil.convertMapToClass(issueIspMap, IspField.class);
                issueIsp.setIspField(ispField);
                issueIsp.setIssue(issue);
                this.issueIspRepository.saveAndFlush(issueIsp);
            }
        }
        //issueHosting 등록
        if (issueForm.getIssueHostingFields() != null && issueForm.getIssueHostingFields().size() > 0) {
            for (Map<String, Object> issueHostingMap : issueForm.getIssueHostingFields()) {
                issueHosting = ConvertUtil.convertMapToClass(issueHostingMap, IssueHosting.class, "id");
                HostingField hostingField = ConvertUtil.convertMapToClass(issueHostingMap, HostingField.class);
                issueHosting.setHostingField(hostingField);
                issueHosting.setIssue(issue);
                this.issueHostingRepository.saveAndFlush(issueHosting);
            }
        }
    }
@@ -3279,27 +3418,39 @@
                issueCustomField.put("registerId", this.webAppUtil.getLoginId());
                issueCustomFieldValueMaps.add(issueCustomField);
            }
            IssueForm partners = this.findCompanyField(issueForm); // 같은 도메인 업체 찾기
            Issue issue = this.findOne(issueForm.getId());
            if (partners.getIssueCompanyFields() != null && partners.getIssueCompanyFields().size() > 0) {
                for (Map<String, Object> company : partners.getIssueCompanyFields()) {
                    IssueCompany issueCompany = ConvertUtil.convertMapToClass(company, IssueCompany.class);
                    issueCompany.setIssue(issue);
                    this.issueCompanyRepository.saveAndFlush(issueCompany);
            //  엑셀에 업체명을 입력하지 않았을 경우 같은 도메인 업체 찾기
            if (issueForm.getIssueCompanyFields() == null || issueForm.getIssueCompanyFields().size() < 1) {
                // 같은 도메인 업체 찾기
                IssueForm partners = this.findCompanyField(issueForm);
                Issue issue = this.findOne(issueForm.getId());
                if (partners.getIssueCompanyFields() != null && partners.getIssueCompanyFields().size() > 0) {
                    for (Map<String, Object> company : partners.getIssueCompanyFields()) {
                        IssueCompany issueCompany = ConvertUtil.convertMapToClass(company, IssueCompany.class);
                        CompanyField companyField = ConvertUtil.convertMapToClass(company, CompanyField.class);
                        issueCompany.setCompanyField(companyField);
                        issueCompany.setIssue(issue);
                        this.issueCompanyRepository.saveAndFlush(issueCompany);
                    }
                }
            }
            if (partners.getIssueIspFields() != null && partners.getIssueIspFields().size() > 0) {
                for (Map<String, Object> isp : partners.getIssueIspFields()) {
                    IssueIsp issueIsp = ConvertUtil.convertMapToClass(isp, IssueIsp.class);
                    issueIsp.setIssue(issue);
                    this.issueIspRepository.saveAndFlush(issueIsp);
                if (partners.getIssueIspFields() != null && partners.getIssueIspFields().size() > 0) {
                    for (Map<String, Object> isp : partners.getIssueIspFields()) {
                        IssueIsp issueIsp = ConvertUtil.convertMapToClass(isp, IssueIsp.class);
                        IspField ispField = ConvertUtil.convertMapToClass(isp, IspField.class);
                        issueIsp.setIspField(ispField);
                        issueIsp.setIssue(issue);
                        this.issueIspRepository.saveAndFlush(issueIsp);
                    }
                }
            }
            if (partners.getIssueHostingFields() != null && partners.getIssueHostingFields().size() > 0) {
                for (Map<String, Object> hosting : partners.getIssueHostingFields()) {
                    IssueHosting issueHosting = ConvertUtil.convertMapToClass(hosting, IssueHosting.class);
                    issueHosting.setIssue(issue);
                    this.issueHostingRepository.saveAndFlush(issueHosting);
                if (partners.getIssueHostingFields() != null && partners.getIssueHostingFields().size() > 0) {
                    for (Map<String, Object> hosting : partners.getIssueHostingFields()) {
                        IssueHosting issueHosting = ConvertUtil.convertMapToClass(hosting, IssueHosting.class);
                        HostingField hostingField = ConvertUtil.convertMapToClass(hosting, HostingField.class);
                        issueHosting.setHostingField(hostingField);
                        issueHosting.setIssue(issue);
                        this.issueHostingRepository.saveAndFlush(issueHosting);
                    }
                }
            }
        }
@@ -3311,7 +3462,8 @@
    //  이슈의 주요 속성을 map 에 저장하여 엑셀 import 에서 지정한 대상(이슈 속성)을 빠르게 찾을 수 있게 한다.
    private void IssueAttributeMapToList(IssueForm issueForm, Map<String, Priority> priorityMaps, Map<String, Severity> severityMaps,
                                         Map<String, DepartmentVo> departmentMaps, Map<String, CustomField> customFieldMaps,Map<String, Long> issueTypeCustomFieldMaps) {
                                         Map<String, DepartmentVo> departmentMaps, Map<String, CustomField> customFieldMaps,Map<String, Long> issueTypeCustomFieldMaps,
                                         Map<String, CompanyField> companyFieldMaps, Map<String, IspField> ispFieldMaps, Map<String, HostingField> hostingFieldMaps) {
        Project project = this.projectService.getProject(issueForm.getProjectId());
@@ -3338,52 +3490,112 @@
        for (CustomField customField : customFields) {
            customFieldMaps.put(customField.getName(), customField);
        }
        //  업체 정보를 바로 찾을 수 있게 준비
        List<CompanyField> companyFields = this.companyFieldService.findAll();
        for (CompanyField companyField : companyFields) {
            companyFieldMaps.put(companyField.getName(), companyField);
        }
        //  ISP 정보를 바로 찾을 수 있게 준비
        List<IspField> ispFields = this.ispFieldService.findAll();
        for (IspField ispField : ispFields) {
            ispFieldMaps.put(ispField.getName(), ispField);
        }
        //  호스팅 정보를 바로 찾을 수 있게 준비
        List<HostingField> hostingFields = this.hostingFieldService.findAll();
        for (HostingField hostingField : hostingFields) {
            hostingFieldMaps.put(hostingField.getName(), hostingField);
        }
    }
    /**
     * cell String으로 변환 함수
     * @param cell Cell
     * @param isNull boolean
     * @return String
     */
    private String stringToCell (Cell cell, boolean isNull) {
        String cellStr = "";
        if (!isNull) {
            cellStr = CommonUtil.convertExcelStringToCell(cell);
            //  공백 제거
            cell.setCellValue(cellStr.trim());
        } else {
            cell.setCellValue(cellStr);
        }
        return cellStr;
    }
    /**
     * cell NULL 체크 함수
     * 빈 값이 아닌 cell 체크
     * @param cell Cell
     * @return boolean
     */
    private Boolean cellNullCheck (Cell cell) {
        return cell != null && cell.getStringCellValue() != null && cell.getCellType() != Cell.CELL_TYPE_BLANK;
        int cellType = cell.getCellType();
        if (cellType < Cell.CELL_TYPE_BLANK) {
            if (cellType == Cell.CELL_TYPE_STRING) {
                if (cell.getStringCellValue() != null && !cell.getStringCellValue().equals("")) {
                    return false;
                }
            } else {
                return false;
            }
        }
        return true;
    }
    //  엑셀 필드에 있는 정보를 이슈 form 으로 옮긴다.
    private IssueForm setIssueFormToExcelField(Row row, int rowIndex, Map<String, Priority> priorityMaps,
                                               Map<String, Severity> severityMaps, Map<String, DepartmentVo> departmentMaps,
                                               Map<String, CustomField> customFieldMaps, List<String> headers) {
                                               Map<String, Severity> severityMaps, Map<String, CustomField> customFieldMaps,
                                               Map<String, CompanyField> companyFieldMaps, Map<String, IspField> ispFieldMaps, Map<String, HostingField> hostingFieldMaps,
                                               List<String> headers) throws ParseException {
        IssueForm issueForm = new IssueForm();
        issueForm.setRegisterId(this.webAppUtil.getLoginId());
        Project project = null;
        //  제목, 내용, 프로젝트 키, 이슈 타입, 우선순위, 중요도, 담당자, 시작일, 종료일, 사용자 정의 필드
        for (int cellIndex = 0; cellIndex < headers.size(); cellIndex++) {
            Cell cell = row.getCell(cellIndex);
            String cellStr = "";
            boolean isNull = true;
            if (cell != null) {
                isNull = cellNullCheck(cell);
                cellStr = stringToCell(cell, isNull); //cell을 String으로 변환
            }
            switch (cellIndex) {
                case 0:
                    //  이슈 제목을 IssueForm 에 저장한다.
                    this.setIssueFormTitle(cell, issueForm, rowIndex);
                    if (isNull) {
                        throw new OwlRuntimeException(
                                this.messageAccessor.getMessage(MsgConstants.EXCEL_IMPORT_ISSUE_TITLE_IS_NULL, rowIndex));
                    }
                    this.setIssueFormTitle(cellStr, issueForm, rowIndex);
                    break;
                case 1:    //  내용
                    if (cellNullCheck(cell)) {
                        issueForm.setDescription(CommonUtil.convertExcelStringToCell(cell));
                    } else {
                        //  null 입력 방지
                        issueForm.setDescription("");
                    }
                    issueForm.setDescription(cellStr);
                    break;
                case 2:
                    //  우선순위를 IssueForm 에 저장한다.
                    this.setIssueFormPriority(cell, priorityMaps, issueForm, rowIndex);
                    if (isNull) {
                        throw new OwlRuntimeException(
                                this.messageAccessor.getMessage(MsgConstants.EXCEL_IMPORT_PRIORITY_IS_NULL, rowIndex));
                    }
                    this.setIssueFormPriority(cellStr, priorityMaps, issueForm, rowIndex);
                    break;
                case 3:
                    //  중요도를 IssueForm 에 저장한다.
                    this.setIssueFormSeverity(cell, severityMaps, issueForm, rowIndex);
                    if (isNull) {
                        throw new OwlRuntimeException(
                                this.messageAccessor.getMessage(MsgConstants.EXCEL_IMPORT_SEVERITY_IS_NULL, rowIndex));
                    }
                    this.setIssueFormSeverity(cellStr, severityMaps, issueForm, rowIndex);
                    break;
                /*case 6:
                    //  담당자를 IssueForm 에 저장한다.
@@ -3391,34 +3603,74 @@
                    break;*/
                case 4:
                    //  시작일을 IssueForm 에 저장한다.
                    if (cellNullCheck(cell)) {
                        this.setIssueFormPeriod(cell, issueForm, true, rowIndex);
                    }
                    this.setIssueFormPeriod(cellStr, issueForm, true, rowIndex, isNull);
                    break;
                case 5:
                    //  종료일을 IssueForm 에 저장한다.
                    if (cellNullCheck(cell)) {
                        this.setIssueFormPeriod(cell, issueForm, false, rowIndex);
                    }
                    this.setIssueFormPeriod(cellStr, issueForm, false, rowIndex, isNull);
                    break;
                case 6:
                    //  업체를 IssueForm 에 저장한다.
                    this.setIssueFormCompanyField(cellStr, companyFieldMaps, issueForm, rowIndex);
                    break;
                case 7:
                    //  ISP를 IssueForm 에 저장한다.
                    this.setIssueFormIspField(cellStr, ispFieldMaps, issueForm, rowIndex);
                    break;
                case 8:
                    //  호스팅을 IssueForm 에 저장한다.
                    this.setIssueFormHostingField(cellStr, hostingFieldMaps, issueForm, rowIndex);
                    break;
                default:
                    //  9번 부터는 사용자 정의 필드. 사용자 정의 필드 정보를 IssueForm 에 저장한다.
                    this.setIssueFormCustomFieldValue(cell, customFieldMaps, issueForm, headers.get(cellIndex), rowIndex);
                    this.setIssueFormCustomFieldValue(cellStr, customFieldMaps, issueForm, headers.get(cellIndex), rowIndex);
            }
        }
        return issueForm;
    }
    //  이슈 제목을 IssueForm 에 저장한다.
    private void setIssueFormTitle(Cell cell, IssueForm issueForm, int rowIndex) {
        if (cell == null) {
            throw new OwlRuntimeException(
                    this.messageAccessor.getMessage(MsgConstants.EXCEL_IMPORT_ISSUE_TITLE_IS_NULL, rowIndex));
    private void setIssueFormHostingField(String cell, Map<String, HostingField> hostingFieldMaps, IssueForm issueForm, int rowIndex) {
        if (cell.length() > 0) {
            Map<String, Object> issueHostingFields = new HashMap<>();
            HostingField hostingFieldMap = hostingFieldMaps.get(cell);
            if (hostingFieldMap == null) {
                throw new OwlRuntimeException(
                        this.messageAccessor.getMessage(MsgConstants.EXCEL_IMPORT_HOSTING_NOT_EXIST, rowIndex));
            }
            ConvertUtil.copyProperties(hostingFieldMap, issueHostingFields);
            issueForm.addIssueHostingField(issueHostingFields);
        }
    }
        String title = CommonUtil.convertExcelStringToCell(cell);
    private void setIssueFormIspField(String cell, Map<String, IspField> ispFieldMaps, IssueForm issueForm, int rowIndex) {
        if (cell.length() > 0) {
            Map<String, Object> issueIspFields = new HashMap<>();
            IspField ispFieldMap = ispFieldMaps.get(cell);
            if (ispFieldMap == null) {
                throw new OwlRuntimeException(
                        this.messageAccessor.getMessage(MsgConstants.EXCEL_IMPORT_ISP_NOT_EXIST, rowIndex));
            }
            ConvertUtil.copyProperties(ispFieldMap, issueIspFields);
            issueForm.addIssueIspField(issueIspFields);
        }
    }
    private void setIssueFormCompanyField(String cell, Map<String, CompanyField> companyFieldMaps, IssueForm issueForm, int rowIndex) {
        if (cell.length() > 0) {
            Map<String, Object> issueCompanyFields = new HashMap<>();
            CompanyField companyFieldMap = companyFieldMaps.get(cell);
            if (companyFieldMap == null) {
                throw new OwlRuntimeException(
                        this.messageAccessor.getMessage(MsgConstants.EXCEL_IMPORT_COMPANY_NOT_EXIST, rowIndex));
            }
            ConvertUtil.copyProperties(companyFieldMap, issueCompanyFields);
            issueForm.addissueCompanyField(issueCompanyFields);
        }
    }
    //  이슈 제목을 IssueForm 에 저장한다.
    private void setIssueFormTitle(String title, IssueForm issueForm, int rowIndex) {
        //  제목 유효성 체크
        this.verifyTitle(title);
        issueForm.setTitle(title);
@@ -3459,13 +3711,8 @@
    //  우선순위를 IssueForm 에 저장한다.
    private void setIssueFormPriority(Cell cell, Map<String, Priority> priorityMaps, IssueForm issueForm, int rowIndex) {
        if (cell == null) {
            throw new OwlRuntimeException(
                    this.messageAccessor.getMessage(MsgConstants.EXCEL_IMPORT_PRIORITY_IS_NULL, rowIndex));
        }
        Priority priority = priorityMaps.get(CommonUtil.convertExcelStringToCell(cell));
    private void setIssueFormPriority(String priorityStr, Map<String, Priority> priorityMaps, IssueForm issueForm, int rowIndex) {
        Priority priority = priorityMaps.get(priorityStr);
        if (priority == null) {
            throw new OwlRuntimeException(
@@ -3476,13 +3723,8 @@
    }
    //  중요도를 IssueForm 에 저장한다.
    private void setIssueFormSeverity(Cell cell, Map<String, Severity> severityMaps, IssueForm issueForm, int rowIndex) {
        if (cell == null) {
            throw new OwlRuntimeException(
                    this.messageAccessor.getMessage(MsgConstants.EXCEL_IMPORT_SEVERITY_IS_NULL, rowIndex));
        }
        Severity severity = severityMaps.get(CommonUtil.convertExcelStringToCell(cell));
    private void setIssueFormSeverity(String strSeverity, Map<String, Severity> severityMaps, IssueForm issueForm, int rowIndex) {
        Severity severity = severityMaps.get(strSeverity);
        if (severity == null) {
            throw new OwlRuntimeException(
@@ -3508,20 +3750,11 @@
        }
    }
    //  시작일, 종료일을 IssueForm 에 저장한다.
    private void setIssueFormPeriod(Cell cell, IssueForm issueForm, Boolean checkStartDate, int rowIndex) {
        if (cell != null && !cell.toString().equals("")) {
    private void setIssueFormPeriod(String periodDate, IssueForm issueForm, Boolean checkStartDate, int rowIndex, boolean isNull) throws ParseException {
        if (!isNull) {
            //  값이 공백이면 중지
            String cellValue = CommonUtil.convertExcelStringToCell(cell);
            if (StringUtils.isEmpty(cellValue) || !cell.toString().equals("null")) {
                return;
            }
            Date startDate;
            try {
                startDate = cell.getDateCellValue();
            } catch (Exception e) {
            Date startDate = DateUtil.convertStrToDateOnly(periodDate);
            if (startDate == null) {
                throw new OwlRuntimeException(
                        this.messageAccessor.getMessage(MsgConstants.EXCEL_IMPORT_PERIOD_NOT_VALIDITY_EMPTY, rowIndex));
            }
@@ -3531,101 +3764,121 @@
            } else {
                issueForm.setCompleteDate(DateUtil.convertDateToStr(startDate, "yyyy-MM-dd"));
                //  종료일만 입력 했을 경우
                if (issueForm.getCompleteDate() != null && issueForm.getStartDate() == null) {
                    throw new OwlRuntimeException(
                            this.messageAccessor.getMessage(MsgConstants.EXCEL_IMPORT_PERIOD_NOT_VALIDITY_EMPTY_START, rowIndex));
                }
                try {
                    //  날짜 유효성 체크
                    this.checkStartCompleteDate(issueForm.getStartDate(), issueForm.getCompleteDate());
                } catch (OwlRuntimeException e) {
                    throw new OwlRuntimeException(
                            this.messageAccessor.getMessage(MsgConstants.EXCEL_IMPORT_PERIOD_NOT_VALIDITY, rowIndex));
                            this.messageAccessor.getMessage(MsgConstants.EXCEL_IMPORT_PERIOD_NOT_VALID, rowIndex));
                }
            }
        }
    }
    //  사용자 정의 필드 정보를 IssueForm 에 저장한다.-
    private void setIssueFormCustomFieldValue(Cell cell, Map<String, CustomField> customFieldMaps, IssueForm issueForm, String customFieldName, int rowIndex) {
        if (cell != null) {
            String cellValue = CommonUtil.convertExcelStringToCell(cell);
            Map<String, Object> issueCustomFieldMap = new HashMap<>();
            CustomField customField = customFieldMaps.get(customFieldName);
    private void setIssueFormCustomFieldValue(String cellValue, Map<String, CustomField> customFieldMaps, IssueForm issueForm, String customFieldName, int rowIndex) {
        Map<String, Object> issueCustomFieldMap = new HashMap<>();
        CustomField customField = customFieldMaps.get(customFieldName);
            if (customField == null) {
                throw new OwlRuntimeException(
                        this.messageAccessor.getMessage(MsgConstants.EXCEL_IMPORT_HEADER_CUSTOM_FIELD_NOT_EXIST, rowIndex));
            }
            //  사용자 정의 필드 값이 공백이면 중지
            if (StringUtils.isEmpty(cellValue)) {
                return;
            }
        if (customField == null) {
            throw new OwlRuntimeException(
                    this.messageAccessor.getMessage(MsgConstants.EXCEL_IMPORT_HEADER_CUSTOM_FIELD_NOT_EXIST, rowIndex));
        }
        //  사용자 정의 필드 값이 공백이면 중지
        if (StringUtils.isEmpty(cellValue)) {
            return;
        }
            boolean validity = false;
        boolean validity = false;
            switch (customField.getCustomFieldType()) {
                case INPUT:
                case NUMBER:
                case DATETIME:
                case IP_ADDRESS:
                case EMAIL:
                case SITE:
                case TEL:
                    if (customField.getCustomFieldType() != INPUT && cellValue.length() > 100) { //INPUT 타입은 100자 제한 없음
        switch (customField.getCustomFieldType()) {
            case INPUT:
            case NUMBER:
            case DATETIME:
            case IP_ADDRESS:
            case EMAIL:
            case SITE:
            case TEL:
                if (customField.getCustomFieldType() != INPUT && cellValue.length() > 100) { //INPUT 타입은 100자 제한 없음
                    throw new OwlRuntimeException(
                            this.messageAccessor.getMessage(MsgConstants.CUSTOM_FIELD_TEXT_TYPE_MAX_LENGTH_OUT));
                }
                //DATETIME일 경우 format 변경
                if (customField.getCustomFieldType() == DATETIME) {
                    Date date = DateUtil.convertStrToDate(cellValue);
                    if (date == null) {
                        throw new OwlRuntimeException(
                                this.messageAccessor.getMessage(MsgConstants.CUSTOM_FIELD_TEXT_TYPE_MAX_LENGTH_OUT));
                                this.messageAccessor.getMessage(MsgConstants.EXCEL_IMPORT_DATETIME_NOT_DASH, rowIndex));
                    }
                }
                    if (customField.getCustomFieldType() == DATETIME) { //DATETIME일 경우 format 변경
                        Date date = cell.getDateCellValue();
                        cellValue = new SimpleDateFormat("yyyy-MM-dd H:mm:ss").format(date);
                //IP_ADDRESS일 경우 정규표현식 체크
                if (customField.getCustomFieldType() == IP_ADDRESS) {
                    String regExp = "^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\."
                            + "(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\."
                            + "(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\."
                            + "(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$";
                    if (!cellValue.matches(regExp)) {
                        throw new OwlRuntimeException(
                                this.messageAccessor.getMessage(MsgConstants.EXCEL_IMPORT_IP_ADDRESS_NOT_VALIDITY, rowIndex));
                    }
                }
                    issueCustomFieldMap.put("customFieldId", customField.getId());
                    issueCustomFieldMap.put("useValue", cellValue);
                    issueForm.addIssueCustomFields(issueCustomFieldMap);
                    break;
                case SINGLE_SELECT:
                    //  값 유효성 체크
                issueCustomFieldMap.put("customFieldId", customField.getId());
                issueCustomFieldMap.put("useValue", cellValue);
                issueForm.addIssueCustomFields(issueCustomFieldMap);
                break;
            case SINGLE_SELECT:
                //  값 유효성 체크
                for (CustomFieldValue customFieldValue : customField.getCustomFieldValues()) {
                    if (customFieldValue.getValue().equals(cellValue)) {
                        validity = true;
                        break;
                    }
                }
                if (!validity) {
                    throw new OwlRuntimeException(
                            this.messageAccessor.getMessage(MsgConstants.EXCEL_CUSTOM_FIELD_VALUE_NOT_VALIDITY, rowIndex));
                }
                issueCustomFieldMap.put("customFieldId", customField.getId());
                issueCustomFieldMap.put("useValue", cellValue);
                issueForm.addIssueCustomFields(issueCustomFieldMap);
                break;
            case MULTI_SELECT:
                //  값 유효성 체크
                String[] useValues = cellValue.split("#");
                //  해, 달
                for (String useValue : useValues) {
                    for (CustomFieldValue customFieldValue : customField.getCustomFieldValues()) {
                        if (customFieldValue.getValue().equals(cellValue)) {
                        if (customFieldValue.getValue().equals(useValue)) {
                            validity = true;
                            break;
                            Map<String, Object> multiValueMap = new HashMap<>();
                            multiValueMap.put("customFieldId", customField.getId());
                            multiValueMap.put("useValue", useValue);
                            issueForm.addIssueCustomFields(multiValueMap);
                        }
                    }
                }
                    if (!validity) {
                        throw new OwlRuntimeException(
                                this.messageAccessor.getMessage(MsgConstants.EXCEL_CUSTOM_FIELD_VALUE_NOT_VALIDITY, rowIndex));
                    }
                if (!validity) {
                    throw new OwlRuntimeException(
                            this.messageAccessor.getMessage(MsgConstants.EXCEL_CUSTOM_FIELD_VALUE_NOT_VALIDITY, rowIndex));
                }
                    issueCustomFieldMap.put("customFieldId", customField.getId());
                    issueCustomFieldMap.put("useValue", cellValue);
                    issueForm.addIssueCustomFields(issueCustomFieldMap);
                    break;
                case MULTI_SELECT:
                    //  값 유효성 체크
                    String[] useValues = cellValue.split("#");
                    //  해, 달
                    for (String useValue : useValues) {
                        for (CustomFieldValue customFieldValue : customField.getCustomFieldValues()) {
                            if (customFieldValue.getValue().equals(useValue)) {
                                validity = true;
                                Map<String, Object> multiValueMap = new HashMap<>();
                                multiValueMap.put("customFieldId", customField.getId());
                                multiValueMap.put("useValue", useValue);
                                issueForm.addIssueCustomFields(multiValueMap);
                            }
                        }
                    }
                    if (!validity) {
                        throw new OwlRuntimeException(
                                this.messageAccessor.getMessage(MsgConstants.EXCEL_CUSTOM_FIELD_VALUE_NOT_VALIDITY, rowIndex));
                    }
                    break;
            }
                break;
        }
    }
@@ -3683,7 +3936,7 @@
    //  이슈를 템플릿에 따라 파트너 담당자에게 메일로 발송한다.
    @Override
    @Transactional(readOnly = true)
    public void sendIssueEmailPartners(EmailTemplateForm emailTemplateForm) {
    public void sendIssueEmailPartners(EmailTemplateForm emailTemplateForm, List<MultipartFile> multipartFiles) {
        if (emailTemplateForm.getSendEmails().size() < 1) {
            throw new OwlRuntimeException(
                    this.messageAccessor.getMessage(MsgConstants.ISSUE_NOT_SEND_USER));
@@ -3710,14 +3963,14 @@
        for(int i=0; i < sendMails.length; i++) {
            sendMails[i] = CommonUtil.decryptAES128(sendMails[i]);
        }
        this.systemEmailService.sendEmail(emailTemplateForm.getTitle(), emailTemplateForm.getTemplate(), sendMails, null);
        this.systemEmailService.sendEmail(emailTemplateForm.getTitle(), emailTemplateForm.getTemplate(), sendMails, null, multipartFiles);
        this.issueHistoryService.detectSendIssueMail(IssueHistoryType.SEND, emailTemplateForm.getSendEmails(), sb);
        this.issueHistoryService.addIssueHistory(issue, IssueHistoryType.SEND, sb.toString());
    }
    @Override
    public void sendCommonEmail(EmailCommonForm emailCommonForm) {
    public void sendCommonEmail(EmailCommonForm emailCommonForm, List<MultipartFile> multipartFiles) {
        if (emailCommonForm.getSendEmails().size() < 1) {
            throw new OwlRuntimeException(
                    this.messageAccessor.getMessage(MsgConstants.ISSUE_NOT_SEND_USER));
@@ -3741,7 +3994,7 @@
        for(int i=0; i < sendMails.length; i++) {
            sendMails[i] = CommonUtil.decryptAES128(sendMails[i]);
        }
        this.systemEmailService.sendEmail(emailCommonForm.getTitle(), emailCommonForm.getDescription(), sendMails, null);
        this.systemEmailService.sendEmail(emailCommonForm.getTitle(), emailCommonForm.getDescription(), sendMails, null, multipartFiles);
        if (issue != null) {
            this.issueHistoryService.detectSendIssueMail(IssueHistoryType.SEND, emailCommonForm.getSendEmails(), sb);
@@ -3939,11 +4192,71 @@
                this.issueHistoryService.detectDownIssues(IssueHistoryType.DELETE, issue, sb);
                issue.setParentIssue(null);
            }
            if (issueDownForm.getInheritYn() != null && issueDownForm.getInheritYn() && issue.getParentIssue() != null) {
                //  상위이슈의 파트너 정보 상속받기
                issue = this.inheritPartners(issue, parentIssue);
            }
            this.issueHistoryService.addIssueHistory(parentIssue, IssueHistoryType.MODIFY, sb.toString()); //parentIssue = myIssue(기록은 현재 상세페이지에 해야하니까)
            this.issueRepository.saveAndFlush(issue);
        }
    }
    /**
     * 상위이슈의 파트너 정보 상속받기
     * @param issue Issue
     * @param parentIssue Issue
     * @return Issue
     */
    private Issue inheritPartners(Issue issue, Issue parentIssue) {
        if (parentIssue != null) {
            if (parentIssue.getIssueType().getInheritPartners()) {
                IssueCompany issueCompany = new IssueCompany();
                IssueIsp issueIsp = new IssueIsp();
                IssueHosting issueHosting = new IssueHosting();
                if (parentIssue.getIssueCompanies() != null && parentIssue.getIssueCompanies().size() > 0) {
                    issue.getIssueCompanies().clear();
                    issue.getIssueCompanies().addAll(parentIssue.getIssueCompanies());
                    Iterator<IssueCompany> itrCompany = issue.getIssueCompanies().iterator();
                    ConvertUtil.copyProperties(itrCompany.next(), issueCompany, "id");
                    issueCompany.setIssue(issue);
                    issueCompany.setCompanyField(parentIssue.getIssueCompanies().iterator().next().getCompanyField());
                    this.issueCompanyRepository.saveAndFlush(issueCompany);
                } else {
                    this.issueCompanyRepository.deleteByIssueId(issue.getId());
                    this.issueCompanyRepository.flush();
                }
                if (parentIssue.getIssueIspFields() != null && parentIssue.getIssueIspFields().size() > 0) {
                    issue.getIssueIspFields().clear();
                    issue.getIssueIspFields().addAll(parentIssue.getIssueIspFields());
                    Iterator<IssueIsp> itrIsp = issue.getIssueIspFields().iterator();
                    ConvertUtil.copyProperties(itrIsp.next(), issueIsp, "id");
                    issueIsp.setIssue(issue);
                    issueIsp.setIspField(parentIssue.getIssueIspFields().iterator().next().getIspField());
                    this.issueIspRepository.saveAndFlush(issueIsp);
                } else {
                    this.issueIspRepository.deleteByIssueId(issue.getId());
                    this.issueIspRepository.flush();
                }
                if (parentIssue.getIssueHostingFields() != null && parentIssue.getIssueHostingFields().size() > 0) {
                    issue.getIssueHostingFields().clear();
                    issue.getIssueHostingFields().addAll(parentIssue.getIssueHostingFields());
                    Iterator<IssueHosting> itrHosting = issue.getIssueHostingFields().iterator();
                    ConvertUtil.copyProperties(itrHosting.next(), issueHosting, "id");
                    issueHosting.setIssue(issue);
                    issueHosting.setHostingField(parentIssue.getIssueHostingFields().iterator().next().getHostingField());
                    this.issueHostingRepository.saveAndFlush(issueHosting);
                } else {
                    this.issueHostingRepository.deleteByIssueId(issue.getId());
                    this.issueHostingRepository.flush();
                }
            }
        }
        return issue;
    }
    @Override
    public void findPartner(Map<String, Object> resJsonData, Map<String, Object> params) {
        Long issueTypeId = MapUtil.getLong(params, "issueTypeId");