From a60879f718fb4fee3bb2b8783a92570f8ead16c3 Mon Sep 17 00:00:00 2001
From: wyu <kknd09321@nate.com>
Date: 토, 11 12월 2021 21:34:07 +0900
Subject: [PATCH] 이메일 템플릿 수정[DB 초기화 필요]

---
 src/main/webapp/scripts/app/issue/issue.js                                 |    2 
 src/main/java/kr/wisestone/owl/vo/EmailTemplateVo.java                     |   36 +++
 src/main/webapp/views/project/projectCustomFieldConfig.html                |    1 
 src/main/webapp/scripts/app/project/projectCustomFieldConfig.controller.js |    9 
 src/main/java/kr/wisestone/owl/service/impl/EmailTemplateServiceImpl.java  |   77 +++++++
 src/main/java/kr/wisestone/owl/web/controller/IssueController.java         |    4 
 src/main/webapp/views/issue/issueSendMailPartners.html                     |   30 +-
 src/main/webapp/custom_components/summernote/summernote.js                 |    2 
 src/main/webapp/scripts/app/issue/issueSendMailPartners.controller.js      |   95 +++++---
 src/main/java/kr/wisestone/owl/service/impl/IssueHistoryServiceImpl.java   |   11 
 src/main/webapp/scripts/main.js                                            |    3 
 src/main/java/kr/wisestone/owl/service/impl/IssueServiceImpl.java          |   43 +--
 src/main/java/kr/wisestone/owl/web/controller/EmailTemplateController.java |   42 ++++
 src/main/java/kr/wisestone/owl/web/form/EmailTemplateForm.java             |   65 ++++++
 src/main/java/kr/wisestone/owl/web/condition/EmailTemplateCondition.java   |   39 +++
 src/main/java/kr/wisestone/owl/service/IssueHistoryService.java            |    1 
 src/main/java/kr/wisestone/owl/service/EmailTemplateService.java           |   22 ++
 src/main/java/kr/wisestone/owl/constant/MsgConstants.java                  |    2 
 src/main/webapp/scripts/app/issue/issueDetail.controller.js                |   17 -
 src/main/java/kr/wisestone/owl/repository/EmailTemplateRepository.java     |   10 +
 src/main/resources/migration/V1_13__Alter_Table.sql                        |   11 +
 src/main/java/kr/wisestone/owl/service/IssueService.java                   |    3 
 src/main/webapp/i18n/ko/global.json                                        |    1 
 src/main/java/kr/wisestone/owl/domain/EmailTemplate.java                   |   41 ++++
 src/main/java/kr/wisestone/owl/mapper/EmailTemplateMapper.java             |   11 +
 25 files changed, 482 insertions(+), 96 deletions(-)

diff --git a/src/main/java/kr/wisestone/owl/constant/MsgConstants.java b/src/main/java/kr/wisestone/owl/constant/MsgConstants.java
index 8689148..71343b2 100644
--- a/src/main/java/kr/wisestone/owl/constant/MsgConstants.java
+++ b/src/main/java/kr/wisestone/owl/constant/MsgConstants.java
@@ -235,6 +235,8 @@
     public static final String ISP_REMOVE_NOT_SELECT = "ISP_REMOVE_NOT_SELECT";   // �궘�젣�븷 ISP媛� �꽑�깮�릺吏� �븡�븯�뒿�땲�떎.
     public static final String PROJECT_NOT_INCLUDE_DEPARTMENT = "PROJECT_NOT_INCLUDE_DEPARTMENT";   // �꽑�깮�븳 遺��꽌 以� �봽濡쒖젥�듃�뿉 李몄뿬�븯怨� �엳吏� �븡�� 遺��꽌媛� �엳�뒿�땲�떎.
 
+    public static final String EMAIL_TEMPLATE_NOT_EXIST = "EMAIL_TEMPLATE_NOT_EXIST"; //  �씠硫붿씪 �뀥�뵆由우쓣 李얠쓣�닔 �뾾�뒿�땲�떎.
+
     public static final String API_PARAMETER_ISSUE_TYPE_ERROR = "API_PARAMETER_ISSUE_TYPE_ERROR";     // api �뙆�씪誘명꽣 �삤瑜�(�씠�뒋���엯)
     public static final String API_PARAMETER_PROJECT_ERROR = "API_PARAMETER_PROJECT_ERROR";     // api �뙆�씪誘명꽣 �삤瑜�(�봽濡쒖젥�듃)
     public static final String API_PARAMETER_ERROR = "API_PARAMETER_ERROR";     // api �뙆�씪誘명꽣 �삤瑜�
diff --git a/src/main/java/kr/wisestone/owl/domain/EmailTemplate.java b/src/main/java/kr/wisestone/owl/domain/EmailTemplate.java
new file mode 100644
index 0000000..61a0d40
--- /dev/null
+++ b/src/main/java/kr/wisestone/owl/domain/EmailTemplate.java
@@ -0,0 +1,41 @@
+package kr.wisestone.owl.domain;
+
+import javax.persistence.*;
+import java.io.Serializable;
+
+@Entity
+public class EmailTemplate extends BaseEntity {
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private Long id;
+    private String title;
+    private String template;
+
+
+    public EmailTemplate() {
+    }
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public String getTitle() {
+        return title;
+    }
+
+    public void setTitle(String title) {
+        this.title = title;
+    }
+
+    public String getTemplate() {
+        return template;
+    }
+
+    public void setTemplate(String template) {
+        this.template = template;
+    }
+}
diff --git a/src/main/java/kr/wisestone/owl/mapper/EmailTemplateMapper.java b/src/main/java/kr/wisestone/owl/mapper/EmailTemplateMapper.java
new file mode 100644
index 0000000..326fd1f
--- /dev/null
+++ b/src/main/java/kr/wisestone/owl/mapper/EmailTemplateMapper.java
@@ -0,0 +1,11 @@
+package kr.wisestone.owl.mapper;
+
+import org.springframework.stereotype.Repository;
+
+
+/**
+ * Created by wisestone on 2018-02-26.
+ */
+@Repository
+public interface EmailTemplateMapper {
+}
diff --git a/src/main/java/kr/wisestone/owl/repository/EmailTemplateRepository.java b/src/main/java/kr/wisestone/owl/repository/EmailTemplateRepository.java
new file mode 100644
index 0000000..5872e56
--- /dev/null
+++ b/src/main/java/kr/wisestone/owl/repository/EmailTemplateRepository.java
@@ -0,0 +1,10 @@
+package kr.wisestone.owl.repository;
+
+import kr.wisestone.owl.domain.CompanyField;
+import kr.wisestone.owl.domain.EmailTemplate;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.repository.query.Param;
+
+public interface EmailTemplateRepository extends JpaRepository<EmailTemplate, Long> {
+
+}
diff --git a/src/main/java/kr/wisestone/owl/service/EmailTemplateService.java b/src/main/java/kr/wisestone/owl/service/EmailTemplateService.java
new file mode 100644
index 0000000..13d2d49
--- /dev/null
+++ b/src/main/java/kr/wisestone/owl/service/EmailTemplateService.java
@@ -0,0 +1,22 @@
+package kr.wisestone.owl.service;
+
+import kr.wisestone.owl.domain.CustomField;
+import kr.wisestone.owl.domain.EmailTemplate;
+import kr.wisestone.owl.vo.CustomFieldVo;
+import kr.wisestone.owl.web.condition.CustomFieldCondition;
+import kr.wisestone.owl.web.condition.EmailTemplateCondition;
+import kr.wisestone.owl.web.form.CustomFieldForm;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.ui.Model;
+import org.springframework.web.servlet.ModelAndView;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.List;
+import java.util.Map;
+
+public interface EmailTemplateService extends AbstractService<EmailTemplate, Long, JpaRepository<EmailTemplate, Long>>{
+
+    EmailTemplate getEmailTemplate(Long id);
+    void find(Map<String, Object> resJsonData, EmailTemplateCondition make);
+}
diff --git a/src/main/java/kr/wisestone/owl/service/IssueHistoryService.java b/src/main/java/kr/wisestone/owl/service/IssueHistoryService.java
index 5813844..a3083e0 100644
--- a/src/main/java/kr/wisestone/owl/service/IssueHistoryService.java
+++ b/src/main/java/kr/wisestone/owl/service/IssueHistoryService.java
@@ -61,6 +61,7 @@
     void detectDownIssues(IssueHistoryType type, Issue issue, StringBuilder description);
 
     void detectSendIssueMail(IssueHistoryType type, IssueForm issueForm, StringBuilder description);
+    void detectSendIssueMail(IssueHistoryType type, List<String> sendMails, StringBuilder description);
 
     void detectIssueCompany(IssueHistoryType type, Map<String, Object> param, IssueCompany issueCompany, StringBuilder description);
 
diff --git a/src/main/java/kr/wisestone/owl/service/IssueService.java b/src/main/java/kr/wisestone/owl/service/IssueService.java
index dab91fe..3e033b8 100644
--- a/src/main/java/kr/wisestone/owl/service/IssueService.java
+++ b/src/main/java/kr/wisestone/owl/service/IssueService.java
@@ -8,6 +8,7 @@
 import kr.wisestone.owl.web.condition.ApiMonitorCondition;
 import kr.wisestone.owl.web.condition.IssueCondition;
 import kr.wisestone.owl.web.condition.ProjectCondition;
+import kr.wisestone.owl.web.form.EmailTemplateForm;
 import kr.wisestone.owl.web.form.IssueApiForm;
 import kr.wisestone.owl.web.form.IssueForm;
 import org.springframework.data.domain.Pageable;
@@ -87,7 +88,7 @@
 
     void sendIssueEmail(IssueForm issueForm);
 
-    void sendIssueEmailPartners(IssueForm issueForm);
+    void sendIssueEmailPartners(EmailTemplateForm emailTemplateForm);
 
     void reservationIssue();
 
diff --git a/src/main/java/kr/wisestone/owl/service/impl/EmailTemplateServiceImpl.java b/src/main/java/kr/wisestone/owl/service/impl/EmailTemplateServiceImpl.java
new file mode 100644
index 0000000..e09e59d
--- /dev/null
+++ b/src/main/java/kr/wisestone/owl/service/impl/EmailTemplateServiceImpl.java
@@ -0,0 +1,77 @@
+package kr.wisestone.owl.service.impl;
+
+import com.google.common.collect.Lists;
+import kr.wisestone.owl.common.ExcelConditionCheck;
+import kr.wisestone.owl.constant.Constants;
+import kr.wisestone.owl.constant.MsgConstants;
+import kr.wisestone.owl.domain.*;
+import kr.wisestone.owl.exception.OwlRuntimeException;
+import kr.wisestone.owl.mapper.CompanyFieldMapper;
+import kr.wisestone.owl.mapper.EmailTemplateMapper;
+import kr.wisestone.owl.repository.CompanyFieldRepository;
+import kr.wisestone.owl.repository.EmailTemplateRepository;
+import kr.wisestone.owl.repository.HostingFieldRepository;
+import kr.wisestone.owl.repository.IspFieldRepository;
+import kr.wisestone.owl.service.*;
+import kr.wisestone.owl.util.ConvertUtil;
+import kr.wisestone.owl.vo.*;
+import kr.wisestone.owl.web.condition.CompanyFieldCondition;
+import kr.wisestone.owl.web.condition.EmailTemplateCondition;
+import kr.wisestone.owl.web.form.CompanyFieldForm;
+import kr.wisestone.owl.web.view.ExcelView;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.ui.Model;
+import org.springframework.web.servlet.ModelAndView;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@Service
+public class EmailTemplateServiceImpl extends AbstractServiceImpl<EmailTemplate, Long, JpaRepository<EmailTemplate, Long>> implements EmailTemplateService {
+
+    @Autowired
+    private EmailTemplateRepository emailTemplateRepository;
+
+    @Autowired
+    private EmailTemplateMapper emailTemplateMapper;
+
+    @Autowired
+    private EmailTemplateService emailTemplateService;
+
+    @Override
+    protected JpaRepository<EmailTemplate, Long> getRepository() {
+        return this.emailTemplateRepository;
+    }
+
+
+    @Override
+    public void find(Map<String, Object> resJsonData, EmailTemplateCondition condition) {
+        EmailTemplate emailTemplate = this.getEmailTemplate(condition.getId());
+        EmailTemplateVo emailTemplateVo = ConvertUtil.copyProperties(emailTemplate, EmailTemplateVo.class);
+
+        resJsonData.put(Constants.RES_KEY_CONTENTS, emailTemplateVo);
+    }
+
+    @Override
+    @Transactional(readOnly = true)
+    public EmailTemplate getEmailTemplate(Long id) {
+        if (id == null) {
+            throw new OwlRuntimeException(this.messageAccessor.getMessage(MsgConstants.EMAIL_TEMPLATE_NOT_EXIST));
+        }
+
+        EmailTemplate emailTemplate = this.findOne(id);
+
+        if (emailTemplate == null) {
+            throw new OwlRuntimeException(this.messageAccessor.getMessage(MsgConstants.EMAIL_TEMPLATE_NOT_EXIST));
+        }
+
+        return emailTemplate;
+    }
+}
diff --git a/src/main/java/kr/wisestone/owl/service/impl/IssueHistoryServiceImpl.java b/src/main/java/kr/wisestone/owl/service/impl/IssueHistoryServiceImpl.java
index ecf6b95..53cab64 100644
--- a/src/main/java/kr/wisestone/owl/service/impl/IssueHistoryServiceImpl.java
+++ b/src/main/java/kr/wisestone/owl/service/impl/IssueHistoryServiceImpl.java
@@ -16,6 +16,7 @@
 import kr.wisestone.owl.vo.IssueHistoryVo;
 import kr.wisestone.owl.vo.IssueVo;
 import kr.wisestone.owl.web.condition.IssueHistoryCondition;
+import kr.wisestone.owl.web.form.EmailTemplateForm;
 import kr.wisestone.owl.web.form.IssueForm;
 import org.apache.commons.lang3.StringUtils;
 import org.slf4j.Logger;
@@ -529,10 +530,16 @@
     // �씠�뒋 硫붿씪 �쟾�넚 �젙蹂대�� 湲곕줉�븳�떎.
     @Override
     public void detectSendIssueMail(IssueHistoryType type, IssueForm issueForm, StringBuilder description) {
+        this.detectSendIssueMail(type, issueForm.getSendEmails(), description);
+    }
+
+    // �씠�뒋 硫붿씪 �쟾�넚 �젙蹂대�� 湲곕줉�븳�떎.
+    @Override
+    public void detectSendIssueMail(IssueHistoryType type, List<String> sendMails, StringBuilder description) {
         if (type == IssueHistoryType.SEND) {
             description.append("<span translate=\"issue.sendIssueMailHistory\">�씠�뒋 硫붿씪 �쟾�넚�쓣 �셿猷뚰뻽�뒿�땲�떎. </span>");
-            if(issueForm.getSendEmails() != null && issueForm.getSendEmails().size() > 0){
-                for (String sendEmail : issueForm.getSendEmails()){
+            if(sendMails != null && sendMails.size() > 0){
+                for (String sendEmail : sendMails){
                     description.append("<span class=\"text-primary bold\">&nbsp;>&nbsp;" + CommonUtil.decryptAES128(sendEmail) + "</span>");
                 }
             }
diff --git a/src/main/java/kr/wisestone/owl/service/impl/IssueServiceImpl.java b/src/main/java/kr/wisestone/owl/service/impl/IssueServiceImpl.java
index dafd80e..d3c4f10 100644
--- a/src/main/java/kr/wisestone/owl/service/impl/IssueServiceImpl.java
+++ b/src/main/java/kr/wisestone/owl/service/impl/IssueServiceImpl.java
@@ -788,10 +788,10 @@
         //  Map �뿉 �엳�뒗 �뜲�씠�꽣瑜� IssueVo �뜲�씠�꽣濡� 蹂��솚�븳�떎.
         this.setMapToIssueVo(results, issueVos, issueCondition, user);
 
-        if (issueCondition.getTree()) {
+//        if (issueCondition.getTree()) {
             this.setDownIssues(issueVos);
             this.setRelationIssues(issueVos);
-        }
+//        }
         this.setCountDownIssues(results, issueVos);
 
         this.SetWorkflowDepartment(issueVos); //�썙�겕�뵆濡쒖슦�뿉 �꽕�젙�븳 �떞�떦遺��꽌 媛��졇�삤湲�
@@ -3262,45 +3262,36 @@
     //  �씠�뒋瑜� �뀥�뵆由우뿉 �뵲�씪 �뙆�듃�꼫 �떞�떦�옄�뿉寃� 硫붿씪濡� 諛쒖넚�븳�떎.
     @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());
     }
 
diff --git a/src/main/java/kr/wisestone/owl/vo/EmailTemplateVo.java b/src/main/java/kr/wisestone/owl/vo/EmailTemplateVo.java
new file mode 100644
index 0000000..7dd49a0
--- /dev/null
+++ b/src/main/java/kr/wisestone/owl/vo/EmailTemplateVo.java
@@ -0,0 +1,36 @@
+package kr.wisestone.owl.vo;
+
+public class EmailTemplateVo extends UsePartnerVo {
+
+    private Long id;
+    private String title;
+    private String template;
+
+    public EmailTemplateVo() {}
+
+    @Override
+    public Long getId() {
+        return id;
+    }
+
+    @Override
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public String getTitle() {
+        return title;
+    }
+
+    public void setTitle(String title) {
+        this.title = title;
+    }
+
+    public String getTemplate() {
+        return template;
+    }
+
+    public void setTemplate(String template) {
+        this.template = template;
+    }
+}
diff --git a/src/main/java/kr/wisestone/owl/web/condition/EmailTemplateCondition.java b/src/main/java/kr/wisestone/owl/web/condition/EmailTemplateCondition.java
new file mode 100644
index 0000000..f4c9215
--- /dev/null
+++ b/src/main/java/kr/wisestone/owl/web/condition/EmailTemplateCondition.java
@@ -0,0 +1,39 @@
+package kr.wisestone.owl.web.condition;
+
+import kr.wisestone.owl.util.ConvertUtil;
+
+import java.util.Map;
+
+public class EmailTemplateCondition {
+    private Long id;
+    private String title;
+    private String template;
+
+    public static EmailTemplateCondition make(Map<String, Object> condition) {
+        return ConvertUtil.convertMapToClass(condition, EmailTemplateCondition.class);
+    }
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public String getTitle() {
+        return title;
+    }
+
+    public void setTitle(String title) {
+        this.title = title;
+    }
+
+    public String getTemplate() {
+        return template;
+    }
+
+    public void setTemplate(String template) {
+        this.template = template;
+    }
+}
diff --git a/src/main/java/kr/wisestone/owl/web/controller/EmailTemplateController.java b/src/main/java/kr/wisestone/owl/web/controller/EmailTemplateController.java
new file mode 100644
index 0000000..15ec9d0
--- /dev/null
+++ b/src/main/java/kr/wisestone/owl/web/controller/EmailTemplateController.java
@@ -0,0 +1,42 @@
+package kr.wisestone.owl.web.controller;
+
+import kr.wisestone.owl.constant.Constants;
+import kr.wisestone.owl.service.CompanyFieldService;
+import kr.wisestone.owl.service.EmailTemplateService;
+import kr.wisestone.owl.web.condition.CompanyFieldCondition;
+import kr.wisestone.owl.web.condition.EmailTemplateCondition;
+import kr.wisestone.owl.web.form.CompanyFieldForm;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Pageable;
+import org.springframework.http.MediaType;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.servlet.ModelAndView;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.HashMap;
+import java.util.Map;
+
+@Controller
+public class EmailTemplateController extends BaseController{
+
+    @Autowired
+    private EmailTemplateService emailTemplateService;
+
+    // �뀥�뵆由� 媛��졇�삤湲�
+    @RequestMapping(value = "/emailTemplate/find", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
+    public
+    @ResponseBody
+    Map<String, Object> find(@RequestBody Map<String, Map<String, Object>> params) {
+        Map<String, Object> resJsonData = new HashMap<>();
+
+        this.emailTemplateService.find(resJsonData, EmailTemplateCondition.make(params.get(Constants.REQ_KEY_CONTENT)));
+
+        return this.setSuccessMessage(resJsonData);
+    }
+}
+
diff --git a/src/main/java/kr/wisestone/owl/web/controller/IssueController.java b/src/main/java/kr/wisestone/owl/web/controller/IssueController.java
index 460c4b5..adcf81d 100644
--- a/src/main/java/kr/wisestone/owl/web/controller/IssueController.java
+++ b/src/main/java/kr/wisestone/owl/web/controller/IssueController.java
@@ -6,6 +6,7 @@
 import kr.wisestone.owl.util.ConvertUtil;
 import kr.wisestone.owl.web.condition.ApiMonitorCondition;
 import kr.wisestone.owl.web.condition.IssueCondition;
+import kr.wisestone.owl.web.form.EmailTemplateForm;
 import kr.wisestone.owl.web.form.IssueForm;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -209,7 +210,8 @@
     @ResponseBody
     Map<String, Object> sendEmailPartners(@RequestBody Map<String, Map<String, Object>> params) {
         Map<String, Object> resJsonData = new HashMap<>();
-        this.issueService.sendIssueEmailPartners(IssueForm.make(params.get(Constants.REQ_KEY_CONTENT)));
+        this.issueService.sendIssueEmailPartners(EmailTemplateForm.make(params.get(Constants.REQ_KEY_CONTENT)));
+//        this.issueService.sendIssueEmailPartners(IssueForm.make(params.get(Constants.REQ_KEY_CONTENT)));
         return this.setSuccessMessage(resJsonData);
     }
 
diff --git a/src/main/java/kr/wisestone/owl/web/form/EmailTemplateForm.java b/src/main/java/kr/wisestone/owl/web/form/EmailTemplateForm.java
new file mode 100644
index 0000000..1d8d277
--- /dev/null
+++ b/src/main/java/kr/wisestone/owl/web/form/EmailTemplateForm.java
@@ -0,0 +1,65 @@
+package kr.wisestone.owl.web.form;
+
+import com.google.common.collect.Lists;
+import kr.wisestone.owl.util.ConvertUtil;
+import kr.wisestone.owl.util.MapUtil;
+
+import java.util.List;
+import java.util.Map;
+
+public class EmailTemplateForm {
+    private Long id;
+    private String title;
+    private String template;
+    private Long issueId;
+    private List<String> sendEmails = Lists.newArrayList();
+
+    public static EmailTemplateForm make(Map<String, Object> params) {
+        EmailTemplateForm form = ConvertUtil.convertMapToClass(params, EmailTemplateForm.class);
+        //  硫붿씪 諛쒖넚�옄 �젙蹂�
+        if (MapUtil.getStrings(params, "sendEmails") != null) {
+            form.setSendEmails(MapUtil.getStrings(params, "sendEmails"));
+        }
+        return  form;
+    }
+
+    public List<String> getSendEmails() {
+        return sendEmails;
+    }
+
+    public void setSendEmails(List<String> sendEmails) {
+        this.sendEmails = sendEmails;
+    }
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public String getTitle() {
+        return title;
+    }
+
+    public void setTitle(String title) {
+        this.title = title;
+    }
+
+    public String getTemplate() {
+        return template;
+    }
+
+    public void setTemplate(String template) {
+        this.template = template;
+    }
+
+    public Long getIssueId() {
+        return issueId;
+    }
+
+    public void setIssueId(Long issueId) {
+        this.issueId = issueId;
+    }
+}
diff --git a/src/main/resources/migration/V1_13__Alter_Table.sql b/src/main/resources/migration/V1_13__Alter_Table.sql
index 7b53c33..cbe5106 100644
--- a/src/main/resources/migration/V1_13__Alter_Table.sql
+++ b/src/main/resources/migration/V1_13__Alter_Table.sql
@@ -22,6 +22,17 @@
 ALTER TABLE `company_field` ADD INDEX `ispIdIndex`(`isp_id`);
 ALTER TABLE `company_field` ADD INDEX `hostingIdIndex`(`hosting_id`);
 
+CREATE TABLE `email_template`(
+    `id` BIGINT(11) AUTO_INCREMENT,
+    `title` VARCHAR (255) NOT NULL,
+    `template` mediumtext NOT NULL,
+    `register_id` BIGINT(20) NOT NULL,
+    `register_date` TIMESTAMP NULL,
+    `modify_id` BIGINT(20) NOT NULL,
+    `modify_date` TIMESTAMP NULL,
+    PRIMARY KEY (`id`) USING BTREE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
+
 
 
 
diff --git a/src/main/webapp/custom_components/summernote/summernote.js b/src/main/webapp/custom_components/summernote/summernote.js
index 1994f12..d2b5ef9 100644
--- a/src/main/webapp/custom_components/summernote/summernote.js
+++ b/src/main/webapp/custom_components/summernote/summernote.js
@@ -7034,7 +7034,6 @@
         };
     };
 
-
     $.summernote = $.extend($.summernote, {
         version: '0.8.2',
         ui: ui,
@@ -7092,6 +7091,7 @@
                 ['insert', ['link', 'picture', 'video']]
             ],
 
+
             // popover
             popover: {
                 image: [
diff --git a/src/main/webapp/i18n/ko/global.json b/src/main/webapp/i18n/ko/global.json
index 1a16158..42499bf 100644
--- a/src/main/webapp/i18n/ko/global.json
+++ b/src/main/webapp/i18n/ko/global.json
@@ -707,6 +707,7 @@
         "selectDestinationDeletion": "�궘�젣 ���긽�쓣 �꽑�깮�븯�꽭�슂.",
         "deleteFailed": "�궘�젣 �떎�뙣",
         "deleteSucceeded": "�궘�젣 �꽦怨�",
+        "emailTemplate": "�씠硫붿씪 �뀥�뵆由�",
         "content": "�궡�슜",
         "selectTarget": "���긽 �꽑�깮",
         "period": "湲곌컙",
diff --git a/src/main/webapp/scripts/app/issue/issue.js b/src/main/webapp/scripts/app/issue/issue.js
index aaeedd3..2c23967 100644
--- a/src/main/webapp/scripts/app/issue/issue.js
+++ b/src/main/webapp/scripts/app/issue/issue.js
@@ -35,7 +35,7 @@
                             require([
                                 'issueListTimelineController', 'issueManagerController', 'issueListController', 'issueAddController', 'issueModifyController', 'issueDetailController', 'issueAddRelationController', 'issueImportExcelController',
                                 'chartLoader', 'jsTable', 'jsTree', 'tableColumnGenerator', 'treeColumnGenerator', 'modalFormAutoScroll', 'summerNote', 'summerNote-ko-KR', 'fullScroll', 'workflowService', 'priorityService', 'issueSearchService', 'issueTableConfigService', 'inputRegex',
-                                'severityService', 'issueTypeService', 'issueTypeCustomFieldService', 'issueService', 'issueStatusService', 'issueUserService','issueDepartmentService','issueModifyUserController', 'issueModifyDepartmentController', 'customFieldService', 'issueSearchFieldKeyViewElement',
+                                'severityService', 'issueTypeService', 'issueTypeCustomFieldService', 'issueService', 'issueStatusService', 'emailTemplateService','issueUserService','issueDepartmentService','issueModifyUserController', 'issueModifyDepartmentController', 'customFieldService', 'issueSearchFieldKeyViewElement',
                                 'issueSearchCustomFieldViewElement', 'tableUserImage', 'fullScroll', 'issueCommentService', 'detectIssueEditor', 'formSubmit', 'issueModifyStatusController', 'downIssueModifyStatusController', 'jsShortCut',
                                 'issueAddTableConfigController','issueAddRelationTableConfigController','issueAddDownTableConfigController','domAppend', 'issueDetailImagePreview', 'issueSendMailPartnersController', 'htmlDiff', 'issueVersionViewController', 'issueVersionService',
                                 'jsHtmlDiff', 'issueReservationController', 'issueReservationService', 'issueVersionService', 'issueStatusAutoFocus', 'issueRelationService'
diff --git a/src/main/webapp/scripts/app/issue/issueDetail.controller.js b/src/main/webapp/scripts/app/issue/issueDetail.controller.js
index 9d8b142..647750a 100644
--- a/src/main/webapp/scripts/app/issue/issueDetail.controller.js
+++ b/src/main/webapp/scripts/app/issue/issueDetail.controller.js
@@ -642,15 +642,20 @@
                         }
                     });
                 }
-                // todo 紐⑤Ⅴ寃좊떎.....
+
                  // �씠�뒋紐낆쓣 �겢由��븯硫� �씠�뒋 �긽�꽭 �젙蹂대�� 議고쉶�븳�떎.
                  // $rootScope.$on("getIssueDetail", function (event, args) {
                  //     $scope.vm.viewer.id = args["id"];
                  //     $scope.fn.getIssueDetail();
                  // });
+
+                //  �씠�뒋紐낆쓣 �겢由��븯硫� �씠�뒋 �긽�꽭 �젙蹂대�� 議고쉶�븳�떎.
+                // $scope.$on("getIssueDetail", function (event, args) {
+                //     $scope.vm.viewer.id = args["id"];
+                //     $scope.fn.getIssueDetail();
+                // });
                 
                 // �씠硫붿씪 蹂대궦�썑 �긽�꽭�솕硫� 媛깆떊
-                // todo �씠嫄� 萸먯�...
                 //  $rootScope.$on("getIssueDetail", function (event, args) {
                 //      $scope.fn.getIssueDetail();
                 //  });
@@ -658,12 +663,6 @@
                 $scope.$on("getIssueDetail", function (event, args) {
                     $scope.fn.getIssueDetail();
                 });
-
-                //  �씠�뒋紐낆쓣 �겢由��븯硫� �씠�뒋 �긽�꽭 �젙蹂대�� 議고쉶�븳�떎.
-                // $scope.$on("getIssueDetail", function (event, args) {
-                //     $scope.vm.viewer.id = args["id"];
-                //     $scope.fn.getIssueDetail();
-                // });
 
                 $scope.$watch(function() {
                     return $rootScope.currentDetailIssueId;
@@ -673,8 +672,6 @@
                         $scope.fn.getIssueDetail();
                     }
                 }, true);
-
-
 
                 //  珥덇린�솕 �빐�빞�븷 �븷紐⑹쓣 吏��젙�븯�뿬 �떎瑜� �씠�뒋瑜� �겢由��븷 �븣 珥덇린�솕�빐以��떎.
                 function initReload() {
diff --git a/src/main/webapp/scripts/app/issue/issueSendMailPartners.controller.js b/src/main/webapp/scripts/app/issue/issueSendMailPartners.controller.js
index e45a790..e4f78ef 100644
--- a/src/main/webapp/scripts/app/issue/issueSendMailPartners.controller.js
+++ b/src/main/webapp/scripts/app/issue/issueSendMailPartners.controller.js
@@ -5,8 +5,8 @@
         'angular'
     ],
     function (app, angular) {
-        app.controller('issueSendMailPartnersController', ['$scope', '$rootScope', '$q','$log', '$resourceProvider', '$uibModalInstance', '$controller', '$injector', 'SweetAlert', '$filter', 'parameter', 'Issue',
-            function ($scope, $rootScope, $q, $log, $resourceProvider, $uibModalInstance, $controller, $injector, SweetAlert, $filter, parameter, Issue) {
+        app.controller('issueSendMailPartnersController', ['$scope', '$rootScope', '$q','$log', '$resourceProvider', '$uibModalInstance', '$controller', '$injector', 'SweetAlert', '$filter', 'parameter', 'Issue', 'EmailTemplate',
+            function ($scope, $rootScope, $q, $log, $resourceProvider, $uibModalInstance, $controller, $injector, SweetAlert, $filter, parameter, Issue, EmailTemplate) {
 
                 $scope.fn = {
                     getUserListCallBack : getUserListCallBack,  //  �궗�슜�옄 auto complete callback function
@@ -15,7 +15,8 @@
                     removeMailTarget : removeMailTarget,
                     formSubmit : formSubmit,    //  �뤌 �쟾�넚
                     formCheck : formCheck,   //  �뤌 泥댄겕
-                    changeTemplate : changeTemplate,
+                    onChangeEmailTemplate : onChangeEmailTemplate, // �씠硫붿씪 �뀥�뵆由� �꽑�깮�떆 �떎�뻾
+                    getEmailTemplateList : getEmailTemplateList // �씠硫붿씪 �뀥�뵆由� 紐⑸줉 媛��졇�삤湲�
                     // showEmailTemplate : showEmailTemplate,
                 };
 
@@ -27,7 +28,6 @@
                     html : "issueSendMailPartners.html",
                     form : {
                         id : parameter.issueId,  //  �씠�뒋 踰덊샇
-                        template : "ISSUE_SEND_2",
                         projects : [{ id : parameter.projectId}],  //  �봽濡쒖젥�듃
                         mailUsers : parameter.partners.slice()   //  硫붿씪 �쟾�넚諛쏅뒗 �궗�슜�옄
                     },
@@ -37,10 +37,58 @@
                             page : 0,
                             totalPage : 0
                         }
-                    }
+                    },
+                    emailTitle : "",
+                    emailTemplateId : -1,
+                    emailTemplates : []
                 };
 
                 angular.extend(this, $controller('autoCompleteController', {$scope : $scope, $injector : $injector}));
+
+                function onChangeEmailTemplate() {
+                    var content = {
+                        id : $scope.vm.emailTemplateId
+                    }
+                    EmailTemplate.find($resourceProvider.getContent(
+                        content,
+                        $resourceProvider.getPageContent(0, 10))).then(function (result) {
+
+                        if (result.data.message.status === "success") {
+                            $scope.vm.html = result.data.data.template;
+                        }
+                        else {
+                            SweetAlert.error($filter("translate")("issue.failedIssueMail"), result.data.message.message); // "�씠�뒋 硫붿씪 諛쒖넚 �떎�뙣"
+                        }
+
+                        $rootScope.spinner = false;
+                    });
+                }
+
+                function getEmailTemplateList() {
+                    $scope.vm.emailTemplates.push({
+                            id : 1,
+                            title : "�뀥�뵆由�1"
+                    });
+
+                    $scope.vm.emailTemplates.push({
+                            id : 2,
+                            title : "�뀥�뵆由�2"
+                    });
+
+
+                    $scope.vm.emailTemplates.push({
+                            id : 3,
+                            title : "�뀥�뵆由�3"
+                    });
+
+                    $scope.vm.emailTemplateId = 1;
+                    $scope.vm.emailTitle = "";
+                    $scope.vm.emailTemplates.forEach(function (emailTemplate) {
+                        if (emailTemplate.id === $scope.vm.emailTemplateId) {
+                            $scope.vm.emailTitle = emailTemplate.title;
+                        }
+                    })
+                }
 
                 //  �궗�슜�옄 �궘�젣
                 function removeMailTarget(index) {
@@ -63,8 +111,10 @@
                 function formSubmit() {
                     $rootScope.spinner = true;
                     var content = {
-                        id : $scope.vm.form.id,
-                        template : $scope.vm.form.template,
+                        id : $scope.vm.emailTemplateId,
+                        template : $scope.vm.html,
+                        title : $scope.vm.emailTitle,
+                        issueId : $scope.vm.form.id,
                         sendEmails : (function () {
                             var sendEmails = [];
 
@@ -125,36 +175,7 @@
                     return deferred.promise;
                 }
 
-                function changeTemplate(templateId){
-                    $scope.vm.form.template = templateId;
-
-                    var elements = document.getElementsByClassName("TemplateIMG");
-                    for (let i = elements.length - 1; i >= 0; i--) {
-                        if (elements[i].id === templateId) {
-                            elements[i].className += " TemplateIMG-selected";
-                        } else {
-                            elements[i].className = "TemplateIMG";
-                        }
-                    }
-
-                    // for(let i = 0 ; i <= 3 ; i++){
-                    //     $('#ISSUE_SEND_'+i).click(function(){
-                    //         $('#Email-Template'+i,'#Email-Template4').slideToggle('slow');
-                    //     });
-                    // }
-                    // $("#ISSUE_SEND_1").click(function () {
-                    //     $("#Email-Template1,#Email-Template4").slideToggle(0);
-                    // });
-                    //
-                    // $("#ISSUE_SEND_2").click(function() {
-                    //     $( "#Email-Template2,#Email-Template4" ).slideToggle(0);
-                    // });
-                    //
-                    // $("#ISSUE_SEND_3").click(function() {
-                    //     $( "#Email-Template3,#Email-Template4" ).slideToggle(0);
-                    // });
-
-                }
+                $scope.fn.getEmailTemplateList();
             }]);
 
     });
diff --git a/src/main/webapp/scripts/app/project/projectCustomFieldConfig.controller.js b/src/main/webapp/scripts/app/project/projectCustomFieldConfig.controller.js
index 9106d78..cfbbd47 100644
--- a/src/main/webapp/scripts/app/project/projectCustomFieldConfig.controller.js
+++ b/src/main/webapp/scripts/app/project/projectCustomFieldConfig.controller.js
@@ -19,7 +19,7 @@
                     getCustomFields : getCustomFields,
                     startExecute : startExecute,
                     issueTypeChange : issueTypeChange,
-                    activeSortable : activeSortable(),
+                    activeSortable : activeSortable,
                 };
 
                 $scope.vm = {
@@ -41,8 +41,14 @@
                     IssueType.find($resourceProvider.getContent({},
                         $resourceProvider.getPageContent(0, 1000))).then(function (result) {
 
+                        // completeIssueStatusVo
                         if (result.data.message.status === "success") {
                             $scope.vm.issueTypes = result.data.data;
+                            for (let i = 0; i < $scope.vm.issueTypes.length; i++) {
+                                if ($scope.vm.issueTypes[i].completeIssueStatusVo !== null) {
+                                    $scope.vm.issueTypes.push()
+                                }
+                            }
                         }
                         else {
                             SweetAlert.swal($filter("translate")("issue.failedToIssueTypeListLookup"), result.data.message.message, "error"); // "�씠�뒋 �쑀�삎 紐⑸줉 議고쉶 �떎�뙣"
@@ -63,7 +69,6 @@
 
                         if (result.data.message.status === "success") {
                             $scope.vm.customFields = result.data.data;
-
                             $scope.vm.originCustomFields = angular.copy(result.data.data);  //  �궗�슜�옄 �젙�쓽 �븘�뱶 蹂듦뎄�뿉 �궗�슜
                         }
                         else {
diff --git a/src/main/webapp/scripts/main.js b/src/main/webapp/scripts/main.js
index eb07840..203fcdb 100644
--- a/src/main/webapp/scripts/main.js
+++ b/src/main/webapp/scripts/main.js
@@ -360,6 +360,9 @@
         'hostingFieldListController' : 'app/hostingField/hostingFieldList.controller', // �샇�뒪�똿 紐⑸줉 而⑦듃濡ㅻ윭
         'hostingFieldAddController' : 'app/hostingField/hostingFieldAdd.controller', // �샇�뒪�똿 �깮�꽦 而⑦듃濡ㅻ윭
         'hostingFieldModifyController' : 'app/hostingField/hostingFieldModify.controller', // �샇�뒪�똿 �닔�젙 而⑦듃濡ㅻ윭
+
+        /* �씠硫붿씪 �뀥�뵆由�*/
+        'emailTemplateService' : 'components/emailTemplate/emailTemplate.service',  // �샇�뒪�똿 愿��젴�맂 �넻�떊 �떞�떦
     },
     shim : {
         'jquery-ui' : {
diff --git a/src/main/webapp/views/issue/issueSendMailPartners.html b/src/main/webapp/views/issue/issueSendMailPartners.html
index dd799c0..e82b1c5 100644
--- a/src/main/webapp/views/issue/issueSendMailPartners.html
+++ b/src/main/webapp/views/issue/issueSendMailPartners.html
@@ -33,21 +33,21 @@
                                        extra-settings="{ displayProp : 'name' , idProp : 'id', imageable : false, imagePathProp : 'profile',
                                        type : 'partner', maxlength : 100, autoResize : true, stopRemoveBodyEvent : true }"></js-input-autocomplete>
                     <div class="Template-area mt-20">
-                        <label class="issue-detail-label">�씠硫붿씪 �뀥�뵆由�</label>
-                            <div class="mt-10" ng-init="fn.changeTemplate('ISSUE_SEND_1')">
-                                <img id="ISSUE_SEND_1" class="TemplateIMG" src="assets/images/emailthumb-badcode.png" ng-click="fn.changeTemplate('ISSUE_SEND_1')">
-                                <img id="ISSUE_SEND_2" class="TemplateIMG" src="assets/images/emailthumb-domain.png" ng-click="fn.changeTemplate('ISSUE_SEND_2')">
-                                <img id="ISSUE_SEND_3" class="TemplateIMG" src="assets/images/emailthumb-hosting.png" ng-click="fn.changeTemplate('ISSUE_SEND_3')">
-                                <div>
-                                    <span class="email_font">�븙�꽦肄붾뱶</span>
-                                    <span class="email_font offset-detail-3">�룄硫붿씤</span>
-                                    <span class="email_font offset-detail-3">�샇�뒪�똿</span>
-                                </div>
-                            </div>
-                        <div>
-                            <img ng-show="vm.form.template == 'ISSUE_SEND_1'" style="margin: 50px auto 0;" id="Email-Template1" src="assets/images/emailthumb-badcode.png">
-                            <img ng-show="vm.form.template == 'ISSUE_SEND_2'" style="margin: 50px auto 0;" id="Email-Template2" src="assets/images/emailthumb-domain.png">
-                            <img ng-show="vm.form.template == 'ISSUE_SEND_3'" style="margin: 50px auto 0;" id="Email-Template3" src="assets/images/emailthumb-hosting.png">
+                        <div class="form-group mb10">
+                            <label for="emailTemplateForm" class="issue-label">
+                                <span translate="common.emailTemplate">�씠硫붿씪 �뀥�뵆由�</span>
+                            </label>
+                            <select id="emailTemplateForm"
+                                    name="emailTemplate"
+                                    class="form-control input-sm issue-select-label"
+                                    ng-model="vm.emailTemplateId"
+                                    ng-change="fn.onChangeEmailTemplate()"
+                                    required>
+                                <option ng-repeat="emailTemplate in vm.emailTemplates"
+                                        value="{{emailTemplate.id}}"
+                                        translate="{{emailTemplate.title}}">
+                                </option>
+                            </select>
                         </div>
                     </div>
                 <summernote
diff --git a/src/main/webapp/views/project/projectCustomFieldConfig.html b/src/main/webapp/views/project/projectCustomFieldConfig.html
index b253b79..37816e4 100644
--- a/src/main/webapp/views/project/projectCustomFieldConfig.html
+++ b/src/main/webapp/views/project/projectCustomFieldConfig.html
@@ -18,6 +18,7 @@
                         required
                         ng-model="vm.form.issueTypeId"
                         ng-change="fn.issueTypeChange()">
+<!--                    ng-if="relationCustomField.checked == 'false'"-->
                     <option value="" translate="common.choose">�꽑�깮�븯�꽭�슂.</option>
                     <option ng-value="issueType.id" ng-repeat="issueType in vm.issueTypes">{{::issueType.name}}</option>
                 </select>

--
Gitblit v1.8.0