= 결재

== 개요
SDL에서는 Knox결재와 동기화 되는 결재 모듈을 제공하고 있는데, 여기서는 Knox Portal REST API 연계 서비스 신청 및 Knox결재 서비스 연계 부분에 대하여 설명한다. 결재화면 및 기능구현 설명은 해당 가이드를 참조한다.

=== Knox결재 연계 설정
. Knox REST API 연계 서비스 신청이 되었다면, 발급받은 `system-id`, `token` 값을 설정한다. 

.knox.properties (스테이지)
[source,properties]
----
knox.system-id=xxxxxxxxxxx
knox.token=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
knox.address.prefix=openapi.samsung.net
knox.approval-service=/approval/api/v2.0/approvals
----

.knox.properties (운영)
[source,properties]
----
knox.system-id=xxxxxxxxxxx
knox.token=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx,xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx,xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx   // <1>
knox.address.prefix=openapi.samsung.net,openapi.w1.samsung.net,openapi.w2.samsung.net   # <2>
knox.approval-service=/approval/api/v2.0/approvals
----
<1> 토큰 (comma(,)로 구분, 거점 순서와 동일)
<2> 거점 (국내, 구주, 미주)

[start=2]
. 결재화면 및 기능구현 설명은 해당 가이드를 참조한다.

* <<_knox_상신,Knox상신>>


NOTE: 개발자의 IP도 반드시 Knox stage 방화벽에 등록하여야만 개발자 PC에서 상신이 된다. 또한 Knox 스테이지(http://www.stage.samsung.net) 에 개발자와 결재자의 계정도 생성 해야만 개발을 진행 할 수 있다.

== API
KnoxApprovalController는 Knox에서 제공하는 Approval API를 직접 연결하는 API를 제공한다.
시스템의 비즈니스 로직을 거치지 않고 Knox API를 직접 호출 하기 때문에 서비스 호출에 문제가 있는지 파악하는데 유용하다.

NOTE: KnoxApprovalController에서 제공하는 API URI은 Knox REST Service의 API URI와 같다.

. Knox 일반 결재 상신 +
POST /knox/approvals/submit +
* 파라미터는 KnoxApproval 클래스를 참고한다.

* attachments는 첨부파일, knoxApprovalStr는 KnoxApproval의 Json String 값이다.
[source,java]
----
@PostMapping("/submit")
public KnoxApproval submitGeneral(@Parameter(value = "첨부파일", required = true) MultipartFile attachments,
                            @Parameter(value = "상신정보", required = true) String knoxApprovalStr) throws IOException {

    ObjectMapper objectMapper = new ObjectMapper();
    KnoxApproval knoxApproval = objectMapper.readValue(knoxApprovalStr, KnoxApproval.class);

    String serverLocation = Account.currentUser().getServerLocation();
    if (StringUtils.isEmpty(serverLocation)) serverLocation = "KR";

    String fileId = fileManagerService.store(attachments);
    List<Resource> fileList = new ArrayList<>();
    fileList.add(fileManagerService.getResource(fileId));

    return knoxApprovalService.submit(knoxApproval, fileList, serverLocation);
}
----

[start=2] 
. Knox 보안 결재 상신 +
POST /knox/approvals/secu-submit +
* 파라미터는 일반 결재 상신과 같지만 보안문서타입이 "CONFIDENTAIL" 이다.
[source,java]
----
knoxApproval.setDocSecuType("CONFIDENTAIL");
----

[start=3] 
. Knox 결재 상세 상황 조회 +
GET /knox/approvals/{apInfId}/detail +
* 결재 연계 ID로 결재 문서의 정보를 상세 조회한다.

. Knox 결재 본문 조회 +
GET /knox/approvals/{apInfId}/content +
* 결재 연계 ID로 결재 문서의 본문을 조회한다.

. Knox 결재 상황 조회 +
POST /knox/approvals/status +
* 결재문서의 진행 상태를 조회한다.
* 복수개의 결재 연계 ID를 요청하여 각각 해당하는 문서변경횟수와 결재상태정보를 응답받는다. 이를 이용하여 결재문서 동기화시 변경된 건에 대해 결재 상태를 업데이트 한다.
[source,java]
----
public List<KnoxApprovalStatus> getStatus(@RequestBody List<KnoxApprovalStatus> knoxApprovalStatusList) {
----

[start=6]
. Knox 결재 연계 ID 조회 +
POST /knox/approvals/apinfids +
* 결재 ID로 결재 연계 ID를 조회한다.
[source,java]
----
public KnoxApproval getApInfIds(@RequestParam String apId) {
----

[start=7]
. Knox 상신함 리스트 조회 +
POST /knox/approvals/submission +
* 상신자가 상신한 정보를 조회한다.
[source,java]
----
public List<KnoxApproval> getApInfIdInfos(@RequestParam String epId) {
----

[start=8]
. Knox 연계 이력 조회 +
GET /knox/approvals/apinfidinfos +
* 요청 시스템에서 상신된 결재문서의 연계 이력을 조회한다.

. Knox 상신 취소 +
POST /knox/approvals/{apInfId}/cancel +
* 결재 문서를 상신취소한다.

. Knox 완결 처리 +
POST /knox/approvals/{apInfId}/autoprogress +
* 결재문서를 완결처리한다.


== KnoxApprovalService

KnoxApprovalService는 시스템에서 결재 문서를 상신 할때 필요한 API들을 제공한다.

[source, java]
----
/**
 * 일반 상신, 보안 상신
 * @param knoxApproval
 * @param attachments
 * @param locale
 * @return
 */
KnoxApproval submit(KnoxApproval knoxApproval, List<Resource> attachments, String locale);

/**
 * 취소
 * @param apInfId
 * @param locale
 * @return
 */
KnoxApproval cancel(String apInfId,  String opinion, String locale);

/**
 * 완결 처리
 * @param apInfId
 * @param locale
 * @return
 */
KnoxApproval autoProgress(String apInfId, String flag, String timeZone, String locale);

/**
 * 결재 상황 조회
 * @param knoxApprovalStatusList
 * @param locale
 * @return
 */
List<KnoxApprovalStatus> getStatus(List<KnoxApprovalStatus> knoxApprovalStatusList, String locale);

/**
 * 결재상세상황조회
 * @param apInfId
 * @param locale
 * @return
 */
KnoxApproval getDetail(String apInfId, String locale);


/**
 * 결재본문조회
 * @param apInfId
 * @param locale
 * @return
 */
KnoxApproval getContent(String apInfId, String locale);

/**
 * 결재연계ID조회
 * @param apId
 * @return
 */
KnoxApproval getApInfIds(String apId, String locale);

/**
 * 상신함리스트조회
 * @param epId
 * @return
 */
List<KnoxApproval> getSubmission(String epId, String locale);

/**
 * 연계이력조회
 * @param endDate yyyyMMddHHmm 형식
 * @param page 페이지 처리
 * @param duration 단위 : 분 / 최소 1분 ~ 최대 60분
 * @return
 */
List<KnoxApproval> getApInfIdInfos(String endDate, String page, String duration, String locale);
----

각각의 메서드들은 Knox Rest 연계 서비스에서 요구하는 가이드대로 REST 형식을 갖추어 필요한 로직들을 수행한다.













