From ebfd37816a332308519b30af5bfb017c5052be69 Mon Sep 17 00:00:00 2001
From: 이민희 <mhlee@maprex.co.kr>
Date: 목, 13 1월 2022 17:34:35 +0900
Subject: [PATCH] Merge branch 'master' of http://192.168.0.25:9001/r/owl-kisa

---
 src/main/java/kr/wisestone/owl/service/impl/IssueServiceImpl.java                  |    6 +++
 src/main/java/kr/wisestone/owl/web/form/ApiIssueAddForm.java                       |   10 ++--
 src/main/webapp/views/api/apiSettingSpec.html                                      |    4 +
 src/main/java/kr/wisestone/owl/web/resolver/OwlResponseEntityExceptionHandler.java |   10 ++--
 src/main/java/kr/wisestone/owl/service/impl/WorkflowTransitionServiceImpl.java     |    2 
 src/main/resources/META-INF/orm.xml                                                |   20 ++++++++++
 src/main/java/kr/wisestone/owl/web/controller/Api/ApiController.java               |   42 +++++++++++++++++---
 src/main/webapp/i18n/ko/global.json                                                |    2 
 src/main/java/kr/wisestone/owl/config/SecurityConfiguration.java                   |    1 
 src/main/java/kr/wisestone/owl/constant/MsgConstants.java                          |    8 ++++
 src/main/java/kr/wisestone/owl/repository/WorkflowTransitionRepository.java        |    3 +
 src/main/webapp/views/common/header.html                                           |    2 
 12 files changed, 89 insertions(+), 21 deletions(-)

diff --git a/src/main/java/kr/wisestone/owl/config/SecurityConfiguration.java b/src/main/java/kr/wisestone/owl/config/SecurityConfiguration.java
index 0b1c5dd..3df8251 100644
--- a/src/main/java/kr/wisestone/owl/config/SecurityConfiguration.java
+++ b/src/main/java/kr/wisestone/owl/config/SecurityConfiguration.java
@@ -145,6 +145,7 @@
                 .antMatchers("/language/change").permitAll()
                 .antMatchers("/security/*").permitAll()
                 .antMatchers("/api/issue").permitAll()
+                .antMatchers("/api/issue/*").permitAll()
                 .antMatchers("/**/*").authenticated();
 
 //        http.addFilter(new CustomAuthenticationFilter());
diff --git a/src/main/java/kr/wisestone/owl/constant/MsgConstants.java b/src/main/java/kr/wisestone/owl/constant/MsgConstants.java
index e9fdb3b..e4b5d05 100644
--- a/src/main/java/kr/wisestone/owl/constant/MsgConstants.java
+++ b/src/main/java/kr/wisestone/owl/constant/MsgConstants.java
@@ -297,6 +297,10 @@
      */
     public static final String API_ISSUE_STATUS_NOT_EXIST = "API_ISSUE_STATUS_NOT_EXIST";
     /**
+     * �썙�겕�뵆濡쒖슦�뿉 �빐�떦 �씠�뒋 �긽�깭瑜� 李얠쓣�닔 �뾾�뒿�땲�떎
+     */
+    public static final String API_ISSUE_STATUS_NOT_EXIST_IN_WORKFLOW = "API_ISSUE_STATUS_NOT_EXIST_IN_WORKFLOW";
+    /**
      * �씠�뒋 �긽�깭 媛믪씠 �뾾�뒿�땲�떎.
      */
     public static final String API_ISSUE_STATUS_IS_NULL = "API_ISSUE_STATUS_IS_NULL";
@@ -308,4 +312,8 @@
      * �씠�뒋 �긽�깭媛� �썙�겕�뵆濡쒖슦�뿉 �룷�븿�릺�뼱 �엳吏� �븡�뒿�땲�떎
      */
     public static final String API_ISSUE_STATUS_NOT_IN_WORKFLOW = "API_ISSUE_STATUS_NOT_IN_WORKFLOW";
+    /**
+     * api �씠�뒋 �깮�꽦 �셿猷�
+     */
+    public static final String API_ADD_ISSUE_OK = "API_ADD_ISSUE_OK";
 }
diff --git a/src/main/java/kr/wisestone/owl/repository/WorkflowTransitionRepository.java b/src/main/java/kr/wisestone/owl/repository/WorkflowTransitionRepository.java
index 0331a91..2f35907 100644
--- a/src/main/java/kr/wisestone/owl/repository/WorkflowTransitionRepository.java
+++ b/src/main/java/kr/wisestone/owl/repository/WorkflowTransitionRepository.java
@@ -12,4 +12,7 @@
 
     @Query(name="WorkflowTransition.findBySourceIssueStatusIdAndWorkflowId")
     List<WorkflowTransitionVo> findBySourceIssueStatusIdAndWorkflowId(@Param("sourceIssueStatusId") Long sourceIssueStatusId, @Param("workflowId") Long workflowId);
+
+    @Query(name="WorkflowTransition.findBySourceIssueStatusIdAndTargetIssueStatusIdAndWorkflowId")
+    List<WorkflowTransitionVo> findBySourceIssueStatusIdAndTargetIssueStatusIdAndWorkflowId(@Param("sourceIssueStatusId") Long sourceIssueStatusId, @Param("workflowId") Long workflowId);
 }
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 084251d..fefabe8 100644
--- a/src/main/java/kr/wisestone/owl/service/impl/IssueServiceImpl.java
+++ b/src/main/java/kr/wisestone/owl/service/impl/IssueServiceImpl.java
@@ -212,6 +212,9 @@
     @Autowired
     private IssueRelationMapper issueRelationMapper;
 
+    @Autowired
+    private WorkflowTransitionService workflowTransitionService;
+
     @Override
     protected JpaRepository<Issue, Long> getRepository() {
         return this.issueRepository;
@@ -262,6 +265,9 @@
             }
         } else if (issueApiForm.getIssueStatusId() == null){
             throw new ApiParameterException(this.messageAccessor.getMessage(MsgConstants.API_ISSUE_STATUS_NOT_EXIST));
+        } else if (!this.workflowTransitionService.contains(issueApiForm.getIssueStatusId(), workflow.getId())) {
+            //�씠�뒋 �긽�깭 �쑀�슚�꽦 �솗�씤
+            throw new ApiParameterException(this.messageAccessor.getMessage(MsgConstants.API_ISSUE_STATUS_NOT_EXIST_IN_WORKFLOW));
         }
 
         // �봽濡쒖젥�듃 �엯�젰
diff --git a/src/main/java/kr/wisestone/owl/service/impl/WorkflowTransitionServiceImpl.java b/src/main/java/kr/wisestone/owl/service/impl/WorkflowTransitionServiceImpl.java
index 5fc42b4..de116d4 100644
--- a/src/main/java/kr/wisestone/owl/service/impl/WorkflowTransitionServiceImpl.java
+++ b/src/main/java/kr/wisestone/owl/service/impl/WorkflowTransitionServiceImpl.java
@@ -134,7 +134,7 @@
     // �썙�겕�뵆濡쒖슦�뿉 �궗�슜�릺�뒗 �씠�뒋 �긽�깭�씤吏� �솗�씤�븳�떎
     @Override
     public boolean contains(Long issueStatusId, Long workflowId) {
-        List<WorkflowTransitionVo> workflowTransitionVos = this.findBySourceIssueStatusIdAndWorkflowId(issueStatusId, workflowId);
+        List<WorkflowTransitionVo> workflowTransitionVos = workflowTransitionRepository.findBySourceIssueStatusIdAndTargetIssueStatusIdAndWorkflowId(issueStatusId, workflowId);
         return workflowTransitionVos != null && workflowTransitionVos.size() > 0;
     }
 
diff --git a/src/main/java/kr/wisestone/owl/web/controller/Api/ApiController.java b/src/main/java/kr/wisestone/owl/web/controller/Api/ApiController.java
index c0e3290..2f91fb8 100644
--- a/src/main/java/kr/wisestone/owl/web/controller/Api/ApiController.java
+++ b/src/main/java/kr/wisestone/owl/web/controller/Api/ApiController.java
@@ -1,7 +1,9 @@
 package kr.wisestone.owl.web.controller.Api;
 
 import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
 import io.swagger.annotations.ApiOperation;
+import kr.wisestone.owl.constant.Constants;
 import kr.wisestone.owl.constant.MsgConstants;
 import kr.wisestone.owl.domain.Issue;
 import kr.wisestone.owl.exception.ApiParameterException;
@@ -46,11 +48,21 @@
      */
     @PostMapping(value = "/issue")
     @ApiOperation(value = "�씠�뒋 異붽�", notes = "�깉濡쒖슫 �씠�뒋瑜� 異붽��븳�떎.")
-    @ApiImplicitParam(name = "files", dataType = "file")
+    @ApiImplicitParams(
+            {
+                    @ApiImplicitParam(name = "files", dataType = "file"),
+                    @ApiImplicitParam(name = "token", paramType = "form"),
+                    @ApiImplicitParam(name = "title", paramType = "form"),
+                    @ApiImplicitParam(name = "description", paramType = "form"),
+                    @ApiImplicitParam(name = "issueTypeId", paramType = "form"),
+                    @ApiImplicitParam(name = "customFields", paramType = "form")
+            }
+    )
+
     @ResponseStatus(HttpStatus.CREATED)
     public
     @ResponseBody
-    void addIssue(ApiIssueAddForm apiIssueAddForm, @RequestParam("files") List<MultipartFile> files)
+    Map<String, Object> addIssue(ApiIssueAddForm apiIssueAddForm, @RequestParam("files") List<MultipartFile> files)
             throws OwlRuntimeException, CloneNotSupportedException {
         Map<String, Object> resJsonData = new HashMap<>();
 
@@ -66,9 +78,16 @@
 
         List<Issue> issues = this.issueService.addApiIssue(issueApiForm);
         //  踰꾩쟾 �깮�꽦
+        StringBuilder sb = new StringBuilder();
         for (Issue issue : issues) {
             this.issueService.addIssueVersion(issue.getId(), issue.getRegisterId());
+            if (sb.length() > 0)
+                sb.append(",");
+            sb.append(issue.getProject().getProjectKey()).append("-").append(issue.getIssueNumber());
         }
+
+        resJsonData.put(Constants.RES_KEY_MSG_SUCCESS, sb.toString());
+        return resJsonData;
     }
 
     /**
@@ -78,23 +97,32 @@
      * @throws OwlRuntimeException �뙆�씪誘명꽣 �삤瑜섏떆 諛쒖깮
      * @throws CloneNotSupportedException �씠�뒋 蹂듭궗 �떆�뿉 諛쒖깮
      */
-    @PutMapping(value = "/issue")
+    @PostMapping(value = "/issue/status")
     @ApiOperation(value = "�씠�뒋 �긽�깭 �닔�젙", notes = "�궗�슜�옄 �젙�쓽 �븘�뱶媛� �룞�씪�븳 湲곗〈 �씠�뒋瑜� 蹂�寃쏀븳�떎.")
     @ResponseStatus(HttpStatus.OK)
     public
     @ResponseBody
-    void modifyIssue(ApiIssueModifyForm apiIssueModifyForm) throws OwlRuntimeException, CloneNotSupportedException {
+    Map<String, Object> modifyIssue(ApiIssueModifyForm apiIssueModifyForm) throws OwlRuntimeException, CloneNotSupportedException {
         Map<String, Object> resJsonData = new HashMap<>();
-
         IssueApiForm issueApiForm = ConvertUtil.copyProperties(apiIssueModifyForm, IssueApiForm.class);
         issueApiForm.parseCustomFields(apiIssueModifyForm.getCustomFields());
-        issueApiForm.setApiType(IssueApiForm.ApiType.add);
+        issueApiForm.setApiType(IssueApiForm.ApiType.modify);
         // �궗�슜�옄 �젙�쓽 �븘�뱶媛� �뾾�쓣 寃쎌슦 寃��깋�쓣 �븷 �닔 �뾾湲� �븣臾몄뿉 �삁�쇅泥섎━
         if (issueApiForm.getCustomFieldValues() == null || issueApiForm.getCustomFieldValues().size() == 0) {
             throw new OwlRuntimeException(this.messageAccessor.getMessage(MsgConstants.API_CUSTOM_FIELD_NOT_EXIST));
         }
 
-        this.issueService.modifyIssue(issueApiForm, new ArrayList<>());
+        List<Issue> issues = this.issueService.modifyIssue(issueApiForm, new ArrayList<>());
+        if (issues != null && issues.size() > 0) {
+            StringBuilder sb = new StringBuilder();
+            for (Issue issue : issues) {
+                if (sb.length() > 0)
+                    sb.append(",");
+                sb.append(issue.getProject().getProjectKey()).append("-").append(issue.getIssueNumber());
+            }
+            resJsonData.put(Constants.RES_KEY_MSG_SUCCESS, sb.toString());
+        }
+        return resJsonData;
     }
 }
 
diff --git a/src/main/java/kr/wisestone/owl/web/form/ApiIssueAddForm.java b/src/main/java/kr/wisestone/owl/web/form/ApiIssueAddForm.java
index 788438e..231c9b7 100644
--- a/src/main/java/kr/wisestone/owl/web/form/ApiIssueAddForm.java
+++ b/src/main/java/kr/wisestone/owl/web/form/ApiIssueAddForm.java
@@ -7,15 +7,15 @@
  * API �씠�뒋 異붽��슜 Form class
  */
 public class ApiIssueAddForm {
-    @ApiParam(value = "�궗�슜�옄 �넗�겙", required = true)
+    @ApiParam(value = "�궗�슜�옄 �넗�겙", required = true, type = "form")
     private String token;
-    @ApiParam(value = "�씠�뒋 �젣紐�")
+    @ApiParam(value = "�씠�뒋 �젣紐�", type = "form")
     private String title;
-    @ApiParam(value = "�씠�뒋 �궡�슜")
+    @ApiParam(value = "�씠�뒋 �궡�슜", type = "form")
     private String description;
-    @ApiParam(value = "�씠�뒋 ���엯 ID", required = true)
+    @ApiParam(value = "�씠�뒋 ���엯 ID", required = true, type = "form")
     private Long issueTypeId;
-    @ApiParam(value = "�궗�슜�옄 �젙�쓽 �븘�뱶", required = true)
+    @ApiParam(value = "�궗�슜�옄 �젙�쓽 �븘�뱶", required = true, type = "form")
     private String customFields;
 
     public ApiIssueAddForm() {
diff --git a/src/main/java/kr/wisestone/owl/web/resolver/OwlResponseEntityExceptionHandler.java b/src/main/java/kr/wisestone/owl/web/resolver/OwlResponseEntityExceptionHandler.java
index 9f9f3bf..9e0fc10 100644
--- a/src/main/java/kr/wisestone/owl/web/resolver/OwlResponseEntityExceptionHandler.java
+++ b/src/main/java/kr/wisestone/owl/web/resolver/OwlResponseEntityExceptionHandler.java
@@ -57,7 +57,7 @@
         Map<String, Object> resJsonData = new HashMap<String, Object>();
         resJsonData.put(Constants.RES_KEY_MESSAGE, this.messageAccessor.getResMessage(ex, Constants.RES_KEY_MSG_FAIL));
 
-        return this.handleExceptionInternal(ex, resJsonData, new HttpHeaders(), HttpStatus.OK, request);
+        return this.handleExceptionInternal(ex, resJsonData, new HttpHeaders(), HttpStatus.BAD_REQUEST, request);
     }
 
     @ExceptionHandler({ StackOverflowError.class,
@@ -66,7 +66,7 @@
         Map<String, Object> resJsonData = new HashMap<String, Object>();
         resJsonData.put(Constants.RES_KEY_MESSAGE, this.messageAccessor.getResMessage(MsgConstants.NOT_READABLE_JSON_DATA, Constants.RES_KEY_MSG_FAIL));
 
-        return this.handleExceptionInternal(ex, resJsonData, new HttpHeaders(), HttpStatus.OK, request);
+        return this.handleExceptionInternal(ex, resJsonData, new HttpHeaders(), HttpStatus.REQUEST_TIMEOUT, request);
     }
 
     @ExceptionHandler({ Exception.class })
@@ -74,7 +74,7 @@
         Map<String, Object> resJsonData = new HashMap<String, Object>();
         resJsonData.put(Constants.RES_KEY_MESSAGE, this.messageAccessor.getResMessage(MsgConstants.NOT_READABLE_JSON_DATA, Constants.RES_KEY_MSG_FAIL));
 
-        return this.handleExceptionInternal(ex, resJsonData, new HttpHeaders(), HttpStatus.OK, request);
+        return this.handleExceptionInternal(ex, resJsonData, new HttpHeaders(), HttpStatus.BAD_REQUEST, request);
     }
 
     @Override
@@ -85,7 +85,7 @@
         resJsonData.put(Constants.RES_KEY_MESSAGE,
                 this.messageAccessor.getResMessage(MsgConstants.NOT_READABLE_JSON_DATA, Constants.RES_KEY_MSG_FAIL));
 
-        return this.handleExceptionInternal(ex, resJsonData, headers, HttpStatus.OK, request);
+        return this.handleExceptionInternal(ex, resJsonData, headers, HttpStatus.BAD_REQUEST, request);
     }
 
     @Override
@@ -93,7 +93,7 @@
             final MethodArgumentNotValidException ex, final HttpHeaders headers,
             final HttpStatus status, final WebRequest request) {
         final String bodyOfResponse = "This should be application specific4";
-        return this.handleExceptionInternal(ex, bodyOfResponse, headers, HttpStatus.OK, request);
+        return this.handleExceptionInternal(ex, bodyOfResponse, headers, HttpStatus.BAD_REQUEST, request);
     }
 
     @Override
diff --git a/src/main/resources/META-INF/orm.xml b/src/main/resources/META-INF/orm.xml
index 5f64381..5812c2b 100644
--- a/src/main/resources/META-INF/orm.xml
+++ b/src/main/resources/META-INF/orm.xml
@@ -183,6 +183,26 @@
         </query>
     </named-query>
 
+    <named-query name="WorkflowTransition.findBySourceIssueStatusIdAndTargetIssueStatusIdAndWorkflowId">
+        <query>
+            SELECT new kr.wisestone.owl.vo.WorkflowTransitionVo(
+            wt.id
+            , sis.id
+            , sis.name
+            , tis.id
+            , tis.name
+            , wt.correctX
+            , wt.correctY
+            , wt.direct
+            )
+            FROM WorkflowTransition wt
+            INNER JOIN wt.workflow w
+            INNER JOIN wt.sourceIssueStatus sis
+            INNER JOIN wt.targetIssueStatus tis
+            WHERE (sis.id = ?1 OR tis.id = ?1) AND w.id = ?2
+        </query>
+    </named-query>
+
 
 </entity-mappings>
 
diff --git a/src/main/webapp/i18n/ko/global.json b/src/main/webapp/i18n/ko/global.json
index d9beea3..0aba0af 100644
--- a/src/main/webapp/i18n/ko/global.json
+++ b/src/main/webapp/i18n/ko/global.json
@@ -953,7 +953,7 @@
         "successToApiIssueOverlap" : "以묐났媛� �꽕�젙 �셿猷�",
         "failedToApiIssueOverlap" : "以묐났媛� �꽕�젙 �떎�뙣",
         "failedToApiMonitor": "API 湲곕줉 議고쉶 �떎�뙣",
-        "requestSample": "API �슂泥� �깦�뵆",
+        "requestSample": "�궗�슜�옄 �젙�쓽 �븘�뱶 JSON �깦�뵆",
         "requestSampleAdd": "�씠�뒋 異붽�",
         "requestSampleModify": "�씠�뒋 �긽�깭 �닔�젙",
         "downIssueOverlapSetting" : "�븯�쐞 �씠�뒋 泥섎━ 湲곗� �빆紐�",
diff --git a/src/main/webapp/views/api/apiSettingSpec.html b/src/main/webapp/views/api/apiSettingSpec.html
index f015666..1a76bfc 100644
--- a/src/main/webapp/views/api/apiSettingSpec.html
+++ b/src/main/webapp/views/api/apiSettingSpec.html
@@ -46,6 +46,7 @@
     </form>
 </div>
 
+<!--
 <div class="row">
     <div class="col-md-4">
         <label for="issue-detectingInfo" class="issue-label">
@@ -85,4 +86,5 @@
             </div>
         </div>
     </div>
-</div>
\ No newline at end of file
+</div>
+-->
\ No newline at end of file
diff --git a/src/main/webapp/views/common/header.html b/src/main/webapp/views/common/header.html
index 9c6f393..9b0f69f 100644
--- a/src/main/webapp/views/common/header.html
+++ b/src/main/webapp/views/common/header.html
@@ -35,7 +35,7 @@
                        owl-auto-focus
                        ng-model="vm.searchAll.keyWord"
                        placeholder="{{'issue.pleaseEnterIssueKeyWord' | translate}}"
-                       ng-enter="fn.searchAll(0)">
+                       ng-enter="fn.searchAll(0)">�뀗
                 <div class="input-group-prepend ml-10">
                     <button class="btn btn-navy" ng-click="fn.searchAll(0)"> <span translate="common.search">寃��깋</span></button>
                 </div>

--
Gitblit v1.8.0