From 1c0c755d167d23860a2a715a56c7b8b87c0312c9 Mon Sep 17 00:00:00 2001
From: wyu <kknd09321@nate.com>
Date: 수, 05 1월 2022 11:08:28 +0900
Subject: [PATCH] 이슈 상세 페이지에 "일반 메일 보내기 기능 추가" 이메일 템플릿 명칭 변경 -> 업체 이메일 이메일 템플릿 제목 추가

---
 src/main/java/kr/wisestone/owl/service/impl/IssueServiceImpl.java     |   31 ++++
 src/main/webapp/scripts/app/issue/issue.js                            |    2 
 src/main/webapp/scripts/components/issue/issue.service.js             |    6 
 src/main/webapp/scripts/app/issue/issueDetail.controller.js           |   16 ++
 src/main/webapp/assets/styles/main.css                                |    8 +
 src/main/webapp/views/issue/issueCommonSendMail.html                  |   69 +++++++++
 src/main/webapp/scripts/app/issue/issueCommonSendMail.controller.js   |  111 +++++++++++++++
 src/main/java/kr/wisestone/owl/service/IssueService.java              |    3 
 src/main/webapp/i18n/ko/global.json                                   |   13 +
 src/main/java/kr/wisestone/owl/web/controller/IssueController.java    |   12 +
 src/main/webapp/views/issue/issueDetail.html                          |    3 
 src/main/webapp/views/issue/issueSendMailPartners.html                |   69 ++++++---
 src/main/webapp/scripts/app/issue/issueSendMailPartners.controller.js |   21 +-
 src/main/webapp/scripts/main.js                                       |    4 
 14 files changed, 327 insertions(+), 41 deletions(-)

diff --git a/src/main/java/kr/wisestone/owl/service/IssueService.java b/src/main/java/kr/wisestone/owl/service/IssueService.java
index abf54aa..1221d84 100644
--- a/src/main/java/kr/wisestone/owl/service/IssueService.java
+++ b/src/main/java/kr/wisestone/owl/service/IssueService.java
@@ -9,6 +9,7 @@
 import kr.wisestone.owl.web.condition.DepartmentCondition;
 import kr.wisestone.owl.web.condition.IssueCondition;
 import kr.wisestone.owl.web.condition.ProjectCondition;
+import kr.wisestone.owl.web.form.EmailCommonForm;
 import kr.wisestone.owl.web.form.EmailTemplateForm;
 import kr.wisestone.owl.web.form.IssueApiForm;
 import kr.wisestone.owl.web.form.IssueForm;
@@ -112,4 +113,6 @@
     void setCountDownIssues(List<IssueVo> issueVos);
 
     void makeIssueMapToIssue(Issue issue, Map<String, Object> issueMap);
+
+    void sendCommonEmail(EmailCommonForm make);
 }
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 bce5de5..415eaef 100644
--- a/src/main/java/kr/wisestone/owl/service/impl/IssueServiceImpl.java
+++ b/src/main/java/kr/wisestone/owl/service/impl/IssueServiceImpl.java
@@ -3564,6 +3564,37 @@
         this.issueHistoryService.addIssueHistory(issue, IssueHistoryType.SEND, sb.toString());
     }
 
+    @Override
+    public void sendCommonEmail(EmailCommonForm emailCommonForm) {
+        if (emailCommonForm.getSendEmails().size() < 1) {
+            throw new OwlRuntimeException(
+                    this.messageAccessor.getMessage(MsgConstants.ISSUE_NOT_SEND_USER));
+        } else if (emailCommonForm.getIssueId() == null) {
+            throw new OwlRuntimeException(
+                    this.messageAccessor.getMessage(MsgConstants.ISSUE_NOT_EXIST));
+        }
+
+        Issue issue = this.getIssue(emailCommonForm.getIssueId());
+
+        //  諛쒖떊�옄 �몴�떆
+        User user = this.webAppUtil.getLoginUserObject();
+        UserVo toUser = this.webAppUtil.getLoginUser();
+
+        //  �궗�슜�옄 �떆�뒪�뀥 湲곕뒫 �궗�슜 �젙蹂� �닔吏�
+        log.info(ElasticSearchUtil.makeUserActiveHistoryMessage(this.webAppUtil.getLoginUser(), ElasticSearchConstants.ISSUE_ANOTHER_USER_SEND_EMAIL));
+        StringBuilder sb = new StringBuilder();
+
+        Locale locale = CommonUtil.getUserLanguage(user.getLanguage());
+        String[] sendMails = ConvertUtil.ToArray(emailCommonForm.getSendEmails());
+        for(int i=0; i < sendMails.length; i++) {
+            sendMails[i] = CommonUtil.decryptAES128(sendMails[i]);
+        }
+        this.systemEmailService.sendEmail(emailCommonForm.getTitle(), emailCommonForm.getDescription(), sendMails, null);
+
+        this.issueHistoryService.detectSendIssueMail(IssueHistoryType.SEND, emailCommonForm.getSendEmails(), sb);
+        this.issueHistoryService.addIssueHistory(issue, IssueHistoryType.SEND, sb.toString());
+    }
+
     //  �삁�빟 諛쒖깮 �씠�뒋瑜� �떎�뻾�븳�떎
     @Override
     @Transactional
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 28c74b5..22fa9f6 100644
--- a/src/main/java/kr/wisestone/owl/web/controller/IssueController.java
+++ b/src/main/java/kr/wisestone/owl/web/controller/IssueController.java
@@ -7,6 +7,7 @@
 import kr.wisestone.owl.web.condition.ApiMonitorCondition;
 import kr.wisestone.owl.web.condition.DepartmentCondition;
 import kr.wisestone.owl.web.condition.IssueCondition;
+import kr.wisestone.owl.web.form.EmailCommonForm;
 import kr.wisestone.owl.web.form.EmailTemplateForm;
 import kr.wisestone.owl.web.form.IssueForm;
 import org.slf4j.Logger;
@@ -245,6 +246,17 @@
     }
 
 
+    // �씪諛� 硫붿씪 諛쒖넚 (�궗�슜�옄 吏곸젒 �옉�꽦)
+    @RequestMapping(value = "/issue/sendCommonEmail", produces = MediaType.APPLICATION_JSON_VALUE)
+    public
+    @ResponseBody
+    Map<String, Object> sendCommonEmail(@RequestBody Map<String, Map<String, Object>> params) {
+        Map<String, Object> resJsonData = new HashMap<>();
+        this.issueService.sendCommonEmail(EmailCommonForm.make(params.get(Constants.REQ_KEY_CONTENT)));
+        return this.setSuccessMessage(resJsonData);
+    }
+
+
     //  api 湲곕줉 議고쉶
     @RequestMapping(value = "/api/findHistory", produces = MediaType.APPLICATION_JSON_VALUE)
     public
diff --git a/src/main/webapp/assets/styles/main.css b/src/main/webapp/assets/styles/main.css
index 98f700e..bedb35f 100644
--- a/src/main/webapp/assets/styles/main.css
+++ b/src/main/webapp/assets/styles/main.css
@@ -11310,6 +11310,14 @@
     font-size: 0.79rem;
 }
 
+.select3-selection__email__remove {
+    color: #0066ff;
+    margin-left: 8px;
+    margin-top: 7px;
+    cursor: pointer;
+    font-size: 0.79rem;
+}
+
 .select4-selection__choice {
     font-size: 0.66rem;
     letter-spacing: -0.01em;
diff --git a/src/main/webapp/i18n/ko/global.json b/src/main/webapp/i18n/ko/global.json
index fa6a8c1..860aabd 100644
--- a/src/main/webapp/i18n/ko/global.json
+++ b/src/main/webapp/i18n/ko/global.json
@@ -281,12 +281,16 @@
         "setIssueRelationTableDisplay": "�뿰愿� �씠�뒋 �뀒�씠釉� �몴�떆 �꽕�젙",
         "setIssueDownTableDisplay": "�븯�쐞 �씠�뒋 �뀒�씠釉� �몴�떆 �꽕�젙",
         "columnName": "而щ읆紐�",
+        "selectPartners": "�뾽泥� �꽑�깮",
+        "partners" : "�뾽泥� �씠硫붿씪",
         "area": "�꼻�씠",
         "displayed": "�몴�떆 �뿬遺�",
         "sequence": "�닚�꽌",
         "cannotChangedIssueTitle": "�씠�뒋 �젣紐⑹� 蹂�寃쏀븷 �닔 �뾾�뒿�땲�떎.",
         "cannotChangedIssueType": "�씠�뒋 援щ텇�� 蹂�寃쏀븷 �닔 �뾾�뒿�땲�떎.",
-        "selectSendIssueMail": "�씠�뒋 硫붿씪 諛쒖넚 ���긽�옄 �꽑�깮",
+        "selectSendIssueMail": "�뾽泥� 硫붿씪 諛쒖넚",
+        "CommonSendIssueMail": "�씪諛� 硫붿씪 諛쒖넚",
+        "SendIssueMail": "硫붿씪 諛쒖넚 �엯�젰",
         "sendIssueSelectedUsers": "�봽濡쒖젥�듃�뿉 李몄뿬�븯怨� �엳�뒗 �떎瑜� �궗�슜�옄�뿉寃� �씠�뒋 �젙蹂대�� 蹂대깄�땲�떎.",
         "sendMail": "�씠硫붿씪 諛쒖넚",
         "changedHistory": "�씠�뒋 蹂�寃� �씠�젰 �긽�꽭�젙蹂�",
@@ -327,6 +331,10 @@
         "succeededIssueMail": "�씠�뒋 硫붿씪 諛쒖넚 �셿猷�",
         "sentToTheSelectedUser": "�꽑�깮�븳 �궗�슜�옄�뿉寃� �씠硫붿씪�씠 諛쒖넚�릺�뿀�뒿�땲�떎.",
         "failedIssueMail": "�씠�뒋 硫붿씪 諛쒖넚 �떎�뙣",
+        "selectedPartnersMail": "�뾽泥� �씠硫붿씪�쓣 �꽑�깮�븯�꽭�슂.",
+        "selectedPartnersTemplate": "�뾽泥� �씠硫붿씪 �뀥�뵆由우쓣 �꽑�깮�빐二쇱꽭�슂.",
+        "writeIssueMail": "�씠硫붿씪�쓣 �엯�젰�빐二쇱꽭�슂.",
+        "writeMail": "�씠硫붿씪�쓣 �엯�젰�븯�뀛�빞 異붽��븷�닔 �엳�뒿�땲�떎.",
         "issueVersionLookupFailed": "�씠�뒋 踰꾩쟾 議고쉶 �떎�뙣",
         "relationIssueType1" : "�떎�쓬 �씠�뒋�� 愿��젴�맖",
         "relationIssueType2" : "�떎�쓬 �씠�뒋�뿉 以묐났�맖",
@@ -694,6 +702,8 @@
         "checkAll": "�쟾泥� �꽑�깮",
         "unCheckAll": "�쟾泥� �빐�젣",
         "send": "蹂대궡湲�",
+        "emailExplain": "諛쏅뒗 �궗�엺�쓽 �씠硫붿씪 �삎�떇�쓣 �엯�젰�븯�뀛�빞 �빀�땲�떎.",
+        "sendToPerson" : "�떎瑜� �궗�슜�옄�뿉寃� 硫붿씪�쓣 蹂대깄�땲�떎.",
         "selected": "�꽑�깮�맖",
         "selectable": "�꽑�깮 媛��뒫",
         "password": "鍮꾨�踰덊샇",
@@ -710,6 +720,7 @@
         "priority": "�슦�꽑 �닚�쐞",
         "importance": "以묒슂�룄",
         "assignee": "�떞�떦�옄",
+        "toPerson": "諛쏅뒗 �궗�엺",
         "assigneeTeam" : "�떞�떦遺��꽌",
         "register": "�벑濡앹옄",
         "startDate": "�떆�옉�씪",
diff --git a/src/main/webapp/scripts/app/issue/issue.js b/src/main/webapp/scripts/app/issue/issue.js
index 81cc436..d8684c8 100644
--- a/src/main/webapp/scripts/app/issue/issue.js
+++ b/src/main/webapp/scripts/app/issue/issue.js
@@ -37,7 +37,7 @@
                                 'chartLoader', 'jsTable', 'jsTree', 'tableColumnGenerator', 'treeColumnGenerator', 'modalFormAutoScroll', 'summerNote', 'summerNote-ko-KR', 'fullScroll', 'workflowService', 'priorityService', 'issueSearchService', 'issueTableConfigService', 'inputRegex',
                                 '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',
+                                'issueAddTableConfigController','issueAddRelationTableConfigController','issueAddDownTableConfigController','domAppend', 'issueDetailImagePreview', 'issueSendMailPartnersController', 'issueCommonSendMailController', 'htmlDiff', 'issueVersionViewController', 'issueVersionService',
                                 'jsHtmlDiff', 'issueReservationController', 'issueReservationService', 'issueVersionService', 'issueStatusAutoFocus', 'issueRelationService'
                             ], function () {
                                 deferred.resolve();
diff --git a/src/main/webapp/scripts/app/issue/issueCommonSendMail.controller.js b/src/main/webapp/scripts/app/issue/issueCommonSendMail.controller.js
new file mode 100644
index 0000000..6440824
--- /dev/null
+++ b/src/main/webapp/scripts/app/issue/issueCommonSendMail.controller.js
@@ -0,0 +1,111 @@
+'use strict';
+
+define([
+        'app'
+    ],
+    function (app) {
+        app.controller('issueCommonSendMailController', ['$scope', '$rootScope', '$state', '$log', '$resourceProvider', '$uibModalInstance', '$controller', '$injector', '$q','SweetAlert', '$filter', 'Issue', 'parameter',
+            function ($scope, $rootScope, $state, $log, $resourceProvider, $uibModalInstance, $controller, $injector, $q, SweetAlert, $filter, Issue, parameter) {
+
+                $scope.fn = {
+                    cancel : cancel,    //  �뙘�뾽 李� �떕湲�
+                    formSubmit : formSubmit,    //  �뤌 �쟾�넚
+                    formCheck : formCheck,   //  �뤌 泥댄겕
+                    addInput : addInput,
+                    removeInput : removeInput
+                };
+
+                $scope.vm = {
+                    form : {
+                        issueId : parameter.issueId,
+                        title : "",
+                        description: "",
+                        inputs : [0],
+                        emails : {},    //  �엯�젰�맂 �궗�슜�옄 �씠硫붿씪
+                    },
+                    userName : "",
+                    autoCompletePage : {
+                        user : {
+                            page : 0,
+                            totalPage : 0
+                        }
+                    }
+                };
+
+                // �뤌 泥댄겕
+                function formCheck(formInvalid) {
+                    if (formInvalid) {
+                        return true;
+                    }
+                    return false;
+                }
+
+                // 硫붿씪 二쇱냼 input 李� 異붽� 踰꾪듉
+                function addInput() {
+                    var arrayFull = true;      // 諛곗뿴�씠 媛��뱷 李� �엳�뒗吏� �뿬遺�
+                    var index = 0;
+                    $scope.vm.form.inputs.forEach(function (email) {
+                        if (!$rootScope.isDefined($scope.vm.form.emails[index])) {
+                            arrayFull = false;
+                        }
+                        index++;
+                    });
+
+                    if (arrayFull) {
+                        $scope.vm.form.inputs.push(index);
+                        $scope.vm.form.emails[index] = ""
+                    } else {
+                        SweetAlert.warning($filter("translate")("issue.writeIssueMail"), $filter("translate")("issue.writeMail")); // 異붽�踰꾪듉 寃쎄퀬
+                    }
+                }
+
+                //  �뤌 �쟾�넚
+                function formSubmit() {
+                    $rootScope.spinner = true;
+
+                    var content = {
+                        issueId : $scope.vm.form.issueId,
+                        title : $scope.vm.form.title,
+                        description : $scope.vm.form.description,
+                        sendEmails : (function () {
+                            var sendEmails = [];
+                            var index = 0
+                            $scope.vm.form.inputs.forEach(function (email) {
+                                if ($rootScope.isDefined($scope.vm.form.emails[index])) {
+                                    sendEmails.push($rootScope.encryption($scope.vm.form.emails[index]));   // �씠硫붿씪二쇱냼 �븫�샇�솕
+                                }
+                                index++;
+                            });
+
+                            return sendEmails;
+                        })()
+                    };
+
+                    Issue.sendCommonEmail($resourceProvider.getContent(
+                        content,
+                        $resourceProvider.getPageContent(0, 10))).then(function (result) {
+
+                        if (result.data.message.status === "success") {
+                            SweetAlert.success($filter("translate")("issue.succeededIssueMail"), $filter("translate")("issue.sentToTheSelectedUser")); // "�씠�뒋 硫붿씪 諛쒖넚 �셿猷�"
+                            $scope.fn.cancel();
+                        }
+                        else {
+                            SweetAlert.error($filter("translate")("issue.failedIssueMail"), result.data.message.message); // "�씠�뒋 硫붿씪 諛쒖넚 �떎�뙣"
+                        }
+
+                        $rootScope.spinner = false;
+                    });
+                }
+
+                // �씠硫붿씪 二쇱냼 input �궘�젣
+                function removeInput(index) {
+                    $scope.vm.form.inputs.splice(index, 1);
+                }
+
+                function cancel() {
+                    $rootScope.$broadcast("closeLayer");    //  �뙘�뾽�씠 �뿴由ш퀬 �굹�꽌 js-multi, js-single �벑�뿉�꽌 body �씠踰ㅽ듃媛� �궇�븘媛��뒗 �쁽�긽 �닔�젙
+                    $uibModalInstance.dismiss('cancel');
+                    $(document).unbind("keydown");  //  �떒異뺥궎 �씠踰ㅽ듃 �젣嫄�
+                }
+            }]);
+    });
diff --git a/src/main/webapp/scripts/app/issue/issueDetail.controller.js b/src/main/webapp/scripts/app/issue/issueDetail.controller.js
index 57f8369..47d6dad 100644
--- a/src/main/webapp/scripts/app/issue/issueDetail.controller.js
+++ b/src/main/webapp/scripts/app/issue/issueDetail.controller.js
@@ -53,6 +53,7 @@
                 $scope.fn.issueBack = issueBack;
                 $scope.fn.removeRelationIssue = removeRelationIssue;
                 $scope.fn.removeDownIssue = removeDownIssue;
+                $scope.fn.sendCommonMail = sendCommonMail;
 
                 //  �씠�뒋 紐⑸줉 而⑦듃濡ㅻ윭 vm, fn �긽�냽 以�
                 $scope.vm.viewer = {};      // �쁽�옱 �씠�뒋
@@ -1290,6 +1291,21 @@
                     });
                 }
 
+                // �씪諛� 硫붿씪 諛쒖넚 (�궗�슜�옄 吏곸젒 �옉�꽦)
+                function sendCommonMail() {
+                    $uibModal.open({
+                        templateUrl : 'views/issue/issueCommonSendMail.html',
+                        size : "md",
+                        controller : 'issueCommonSendMailController',
+                        backdrop : 'static',
+                        resolve : {
+                            parameter : {
+                                issueId : $scope.vm.viewer.id,
+                            }
+                        }
+                    });
+                }
+
                 function getParametersAll() {
                     var params = $scope.fn.getParameters(null, $scope.vm.viewer.issueCompanyVos);
                     params = $scope.fn.getParameters(params, $scope.vm.viewer.issueIspVos);
diff --git a/src/main/webapp/scripts/app/issue/issueSendMailPartners.controller.js b/src/main/webapp/scripts/app/issue/issueSendMailPartners.controller.js
index 9e8d0c7..32b7a6e 100644
--- a/src/main/webapp/scripts/app/issue/issueSendMailPartners.controller.js
+++ b/src/main/webapp/scripts/app/issue/issueSendMailPartners.controller.js
@@ -17,7 +17,6 @@
                     formCheck : formCheck,   //  �뤌 泥댄겕
                     onChangeEmailTemplate : onChangeEmailTemplate, // �씠硫붿씪 �뀥�뵆由� �꽑�깮�떆 �떎�뻾
                     getEmailTemplateList : getEmailTemplateList // �씠硫붿씪 �뀥�뵆由� 紐⑸줉 媛��졇�삤湲�
-                    // showEmailTemplate : showEmailTemplate,
                 };
 
                 $scope.vm = {
@@ -26,6 +25,7 @@
                     hostingVos : parameter.hostingVos,
                     partners : parameter.partnersAll.slice(),
                     html : "",
+                    tab : "SEND_TEMPLATE",
                     form : {
                         id : parameter.issueId,  //  �씠�뒋 踰덊샇
                         projects : [{ id : parameter.projectId}],  //  �봽濡쒖젥�듃
@@ -59,7 +59,8 @@
                             $scope.vm.html = result.data.data.template;
                         }
                         else {
-                            SweetAlert.error($filter("translate")("issue.failedIssueMail"), result.data.message.message); // "�씠�뒋 硫붿씪 諛쒖넚 �떎�뙣"
+                            $scope.vm.html = "";
+                            //SweetAlert.warning($filter("translate")("issue.selectedPartnersMail"),$filter("translate")("issue.selectedPartnersTemplate")); // option �꽑�깮 寃쎄퀬
                         }
 
                         $rootScope.spinner = false;
@@ -85,14 +86,13 @@
 
                     $scope.vm.emailTemplateId = 1;
                     $scope.vm.emailTitle = "";
-                    $scope.vm.emailTemplates.forEach(function (emailTemplate) {
-                        /*if (emailTemplate.id === $scope.vm.emailTemplateId) {
-                            $scope.vm.emailTitle = emailTemplate.title;
-                        }*/
-                        if (emailTemplate.templateType === $scope.vm.emailTemplateType) {
-                            $scope.vm.emailTitle = emailTemplate.title;
-                        }
-                    })
+                    if ($rootScope.isDefined($scope.vm.emailTemplateType)) {
+                        $scope.vm.emailTemplates.forEach(function (emailTemplate) {
+                            if (emailTemplate.templateType === $scope.vm.emailTemplateType) {
+                                $scope.vm.emailTitle = emailTemplate.title;
+                            }
+                        })
+                    }
                 }
 
 
@@ -182,6 +182,7 @@
                 }
 
                 $scope.fn.getEmailTemplateList();
+
             }]);
 
     });
diff --git a/src/main/webapp/scripts/components/issue/issue.service.js b/src/main/webapp/scripts/components/issue/issue.service.js
index 8290ed9..d9f9086 100644
--- a/src/main/webapp/scripts/components/issue/issue.service.js
+++ b/src/main/webapp/scripts/components/issue/issue.service.js
@@ -144,6 +144,12 @@
                     $log.debug("�씠�뒋 �씠硫붿씪 諛쒖넚 寃곌낵 : ", response);
                     return response;
                 });
+            },
+            sendCommonEmail : function (conditions) {
+                return $http.post("issue/sendCommonEmail", conditions).then(function (response) {
+                    $log.debug("�씠�뒋 �씠硫붿씪 諛쒖넚 寃곌낵 : ", response);
+                    return response;
+                });
             }
         }
     }
diff --git a/src/main/webapp/scripts/main.js b/src/main/webapp/scripts/main.js
index 20165a1..cd292ba 100644
--- a/src/main/webapp/scripts/main.js
+++ b/src/main/webapp/scripts/main.js
@@ -191,7 +191,8 @@
         'issueAddTableConfigController' : 'app/issue/issueAddTableConfig.controller',   //  �씠�뒋 �뀒�씠釉� �꽕�젙 而⑦듃濡ㅻ윭
         'issueAddRelationTableConfigController' : 'app/issue/issueAddRelationTableConfig.controller',   //  �씠�뒋 �뀒�씠釉� �꽕�젙 而⑦듃濡ㅻ윭
         'issueAddDownTableConfigController' : 'app/issue/issueAddDownTableConfig.controller',   //  �씠�뒋 �뀒�씠釉� �꽕�젙 而⑦듃濡ㅻ윭
-        'issueSendMailPartnersController' : 'app/issue/issueSendMailPartners.controller',   //  �씠�뒋 �씠硫붿씪 諛쒖넚 而⑦듃濡ㅻ윭
+        'issueSendMailPartnersController' : 'app/issue/issueSendMailPartners.controller',   //  �뾽泥� �씠硫붿씪 諛쒖넚 而⑦듃濡ㅻ윭
+        'issueCommonSendMailController' : 'app/issue/issueCommonSendMail.controller',   //  �씪諛� �씠硫붿씪 諛쒖넚 而⑦듃濡ㅻ윭
         'issueVersionViewController' : 'app/issue/issueVersionView.controller', //  �씠�뒋 踰꾩쟾 �솗�씤 而⑦듃濡ㅻ윭
         'issueReservationController' : 'app/issue/issueReservation.controller', //  �씠�뒋 諛쒖깮 �삁�빟 而⑦듃濡ㅻ윭
         'issueModifyUserController' : 'app/issue/issueModifyUser.controller', // �씠�뒋 �떞�떦�옄 而⑦듃濡ㅻ윭
@@ -506,6 +507,7 @@
     'config',   //  angularJs �꽕�젙 - route �씠�룞 愿��젴, �씠�룞�떆 珥덇린�솕 濡쒖쭅�씠 �뱾�뼱�엳�떎. - 吏곸젒 濡쒕뱶
     'constants',
     'commonController',
+    'issueCommonSendMailController',
     'autoCompleteController',
     'userInviteController',
     'issueAddController',   //  �씠�뒋 留뚮뱾湲곗뿉�꽌 �궗�슜
diff --git a/src/main/webapp/views/issue/issueCommonSendMail.html b/src/main/webapp/views/issue/issueCommonSendMail.html
new file mode 100644
index 0000000..c2f3ab4
--- /dev/null
+++ b/src/main/webapp/views/issue/issueCommonSendMail.html
@@ -0,0 +1,69 @@
+<div class="formModal">
+    <div class="modal-header faded smaller">
+        <div class="modal-title">
+            <strong translate="issue.CommonSendIssueMail">�씪諛� 硫붿씪 諛쒖넚</strong>
+        </div>
+        <button aria-label="Close" class="close" type="button" ng-click="fn.cancel()">
+            <span aria-hidden="true"> &times;</span>
+        </button>
+    </div>
+
+    <div class="modal-body">
+        <form role="form" name="issueSendForm">
+            <button type="button" class="btn btn-secondary mr-3 float-right mb-1" ng-click="fn.addInput()">
+                <span translate="common.add">異붽�</span>
+            </button>
+            <div class="form-group">
+                <label class="issue-label mt-2"><span translate="common.toPerson">諛쏅뒗 �궗�엺</span>&nbsp;<code class="highlighter-rouge">*</code></label>
+                <div class="input-group" ng-repeat="i in vm.form.inputs">
+                    <input type="text"
+                           name="email"
+                           class="form-control mt-1"
+                           kr-input
+                           ng-model="vm.form.emails[$index]"
+                           ng-pattern="/^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/"
+                           required
+                           autocomplete="off">
+                    <span class="select3-selection__email__remove" ng-click="fn.removeInput($index)">횞</span>
+                </div>
+                <small translate="common.emailExplain">諛쏅뒗 �궗�엺�쓽 �씠硫붿씪 �삎�떇�쓣 �엯�젰�븯�뀛�빞 �빀�땲�떎.</small>
+                <div ng-if="issueSendForm.email.$error.pattern" class="help-block form-text text-danger"
+                     translate="common.invalidEmailFormat">�씠硫붿씪 �삎�떇�씠 留욎� �븡�뒿�땲�떎.
+                </div>
+            </div>
+
+
+            <label class="issue-label"><span translate="common.title">�젣紐�</span></label>
+            <input id="title"
+                   type="text"
+                   name="title"
+                   class="form-control mt-1"
+                   kr-input
+                   ng-model="vm.form.title"
+                   autocomplete="off">
+
+            <div class="form-group mb10 mt-10">
+                <label class="issue-label"><span translate="common.content">�궡�슜</span></label>
+                <summernote
+                        class="summernote mt-1"
+                        lang="ko-KR"
+                        summer-note-auto-focus
+                        ng-model="vm.form.description"
+                        data-editor="vm.summerNote.editor"
+                        data-editable="vm.summerNote.editable"
+                        on-image-upload="fn.imageUpload(files)"
+                        target=".note-editable"></summernote>
+            </div>
+            <small class="mt-1" translate="common.sendToPerson">�떎瑜� �궗�슜�옄�뿉寃� 硫붿씪�쓣 蹂대깄�땲�떎.</small>
+        </form>
+    </div>
+
+    <div class="modal-footer buttons-on-right">
+        <button type="button" class="btn btn-md btn-grey" ng-click="fn.cancel()"><span
+                translate="common.cancel">痍⑥냼</span></button>
+        <button type="button" class="btn btn-md btn-primary bold"
+                ng-disabled="fn.formCheck(issueSendForm.$invalid)"
+                ng-click="fn.formSubmit()"><span translate="issue.sendMail">�씠硫붿씪 諛쒖넚</span>
+        </button>
+    </div>
+</div>
diff --git a/src/main/webapp/views/issue/issueDetail.html b/src/main/webapp/views/issue/issueDetail.html
index 390f5ef..7e051a3 100644
--- a/src/main/webapp/views/issue/issueDetail.html
+++ b/src/main/webapp/views/issue/issueDetail.html
@@ -102,7 +102,8 @@
                 </div>
             </span>
             <a class="show-ticket-info cursor">
-                <i class="os-icon os-icon-email-forward mr-20" ng-if="vm.viewer.modifyPermissionCheck" ng-click="fn.sendMailAll()" data-toggle="tooltip" data-placement="right" title="�떎瑜� �궗�슜�옄�뿉寃� �씠�뒋 蹂대궡湲�"></i>
+                <i class="os-icon os-icon-email-2-at2 mr-20" ng-if="vm.viewer.modifyPermissionCheck" ng-click="fn.sendCommonMail()" data-toggle="tooltip" data-placement="right" title="吏곸젒 �옉�꽦�븳 硫붿씪 蹂대궡湲�"></i>
+                <i class="os-icon os-icon-email-forward mr-20" ng-if="vm.viewer.modifyPermissionCheck" ng-click="fn.sendMailAll()" data-toggle="tooltip" data-placement="right" title="�뾽泥� 硫붿씪 蹂대궡湲�"></i>
                 <i class="os-icon os-icon-airplay mr-20" ng-click="fn.versionView(vm.viewer.id)" data-toggle="tooltip" data-placement="right" title="�씠�뒋 蹂�寃� �씠�젰 �긽�꽭 蹂닿린"></i>
                 <i class="os-icon os-icon-calendar-time mr-20" ng-if="vm.viewer.modifyPermissionCheck"
                    ng-click="fn.reservation(vm.viewer.id)" data-toggle="tooltip" data-placement="right" title="�씠�뒋 諛쒖깮 �삁�빟 �븯湲�"></i>
diff --git a/src/main/webapp/views/issue/issueSendMailPartners.html b/src/main/webapp/views/issue/issueSendMailPartners.html
index 6fdc84d..40eb4af 100644
--- a/src/main/webapp/views/issue/issueSendMailPartners.html
+++ b/src/main/webapp/views/issue/issueSendMailPartners.html
@@ -1,7 +1,7 @@
 <div class="formModal">
     <div class="modal-header faded smaller">
         <div class="modal-title">
-            <strong translate="issue.selectSendIssueMail">�씠�뒋 硫붿씪 諛쒖넚 ���긽�옄 �꽑�깮</strong>
+            <strong translate="issue.selectSendIssueMail">�씠�뒋 硫붿씪 諛쒖넚</strong>
         </div>
         <button aria-label="Close" class="close" type="button" ng-click="fn.cancel()">
             <span aria-hidden="true"> &times;</span>
@@ -20,6 +20,9 @@
                     </span>
                 </div>
 
+                <label class="issue-label mt-10">
+                    <span translate="issue.selectPartners">�뾽泥� �꽑�깮</span>&nbsp;<code class="highlighter-rouge">*</code>
+                </label>
                 <js-input-autocomplete data-input-name="mailUsers"
                                        owl-auto-focus
                                        target=".auto-complete-i0nput"
@@ -29,38 +32,50 @@
                                        page="vm.autoCompletePage.user.page"
                                        total-page="vm.autoCompletePage.user.totalPage"
                                        source="fn.getMailTargetAll(vm.form.mailUsers)"
-                                       translation-texts="{ empty : 'common.emptyUser'}"
+                                       translation-texts="{ empty : 'common.emptyCompanyPartners'}"
                                        input-disabled="vm.form.mailUsers == null"
                                        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">
-                        <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.emailTemplateType"
-                                    ng-change="fn.onChangeEmailTemplate()"
-                                    required>
-                                <option ng-repeat="emailTemplate in vm.emailTemplates"
-                                        value="{{emailTemplate.templateType}}"
-                                        translate="{{emailTemplate.title}}">
-                                </option>
-                            </select>
-                        </div>
-                    </div>
-                <summernote
-                        class="summernote"
-                        lang="ko-KR"
-                        config="vm.options"
-                        ng-model="vm.html"
-                        target=".note-editable"></summernote>
+
+                <div class="form-group mb10 mt-20">
+                    <label for="emailTemplateForm" class="issue-label">
+                        <span translate="issue.partners">�뾽泥� �씠硫붿씪</span>&nbsp;<code class="highlighter-rouge">*</code>
+                    </label>
+                    <select id="emailTemplateForm"
+                            name="emailTemplate"
+                            class="form-control input-sm issue-select-label"
+                            ng-model="vm.emailTemplateType"
+                            ng-change="fn.onChangeEmailTemplate()"
+                            required>
+                        <option value="" ng-selected="true">�꽑�깮�븯�꽭�슂</option>
+                        <option ng-repeat="emailTemplate in vm.emailTemplates"
+                                value="{{emailTemplate.templateType}}"
+                                translate="{{emailTemplate.title}}">
+                        </option>
+                    </select>
+                </div>
+
+                <label class="issue-label"><span translate="common.title">�젣紐�</span></label>
+                <input id="title"
+                       type="text"
+                       name="title"
+                       class="form-control"
+                       kr-input
+                       ng-model="vm.emailTitle"
+                       autocomplete="off">
+
+                <div class="form-group mb10 mt-10">
+                    <label class="issue-label"><span translate="common.content">�궡�슜</span></label>
+                    <summernote
+                            class="summernote"
+                            lang="ko-KR"
+                            config="vm.options"
+                            ng-model="vm.html"
+                            target=".note-editable"></summernote>
+                </div>
             </div>
         </form>
     </div>
-
 
     <div class="modal-footer buttons-on-right">
         <button type="button" class="btn btn-md btn-grey" ng-click="fn.cancel()"><span

--
Gitblit v1.8.0