commit 491c8be8853b3c59a18f6f75489bc7a602847efe Author: bangae1 Date: Sat May 24 01:45:57 2025 +0900 first diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c5e7300 --- /dev/null +++ b/.gitignore @@ -0,0 +1,38 @@ +HELP.md +.gradle +build/ +!gradle/wrapper/gradle-wrapper.jar +!**/src/main/**/build/ +!**/src/test/**/build/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache +bin/ +!**/src/main/**/bin/ +!**/src/test/**/bin/ + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr +out/ +!**/src/main/**/out/ +!**/src/test/**/out/ + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ + +### VS Code ### +.vscode/ +/logs/ diff --git a/api/IntegratedAppr/통합결재 목록(관리자&부서)조회.http b/api/IntegratedAppr/통합결재 목록(관리자&부서)조회.http new file mode 100644 index 0000000..65b0725 --- /dev/null +++ b/api/IntegratedAppr/통합결재 목록(관리자&부서)조회.http @@ -0,0 +1,6 @@ +### GET request to example server +GET http://localhost:8010/api/itg/appr?page=1&row=10 +sabun: psn14020 + + +### \ No newline at end of file diff --git a/api/IntegratedAppr/통합결재 승인목록(본인)조회.http b/api/IntegratedAppr/통합결재 승인목록(본인)조회.http new file mode 100644 index 0000000..ac34ab8 --- /dev/null +++ b/api/IntegratedAppr/통합결재 승인목록(본인)조회.http @@ -0,0 +1,6 @@ +### GET request to example server +GET http://localhost:8010/api/itg/appr/req?page=1&row=10 +sabun: 17131303 + + +### \ No newline at end of file diff --git a/api/approval/가격조사 결재 상태 변경.http b/api/approval/가격조사 결재 상태 변경.http new file mode 100644 index 0000000..ff87d52 --- /dev/null +++ b/api/approval/가격조사 결재 상태 변경.http @@ -0,0 +1,16 @@ +PUT http://localhost:8010//api/appr +sabun: 17131303 +Content-Type: application/json + +{ + "apprNo": "APPR-0000000052", + "apprOrd": 2, + "sabun": "17131303", + "apprStatCd": "0200", + "reason": "" +} + +### + +#APPR-20250519017,20,17131303,김진형,0000,결재요청 +#APPR-20250519017,30,17131304,손원장,0000,결재요청 diff --git a/api/business/비밀번호 변경.http b/api/business/비밀번호 변경.http new file mode 100644 index 0000000..c420f3f --- /dev/null +++ b/api/business/비밀번호 변경.http @@ -0,0 +1,12 @@ +PUT http://localhost:8010//api/business/password +Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJiaXpObyI6Ijk5OS05OS05OTk5OCIsImlwIjoiMTI3LjAuMC4xIiwic3ViIjoiOTk5LTk5LTk5OTk4IiwiaWF0IjoxNzQ2MDEyNjcyLCJleHAiOjE3NDYwMTI5NzJ9.RaT9wa3_8oPeL6nWv1_uM6QlY1mcHyCN2tC6sP_N03w +Content-Type: application/json + +{ + "bizNo": "999-99-99998", + "oldPwd": "kospo2025!", + "pwd": "kospo2024!", + "rePwd": "kospo2024!" +} + +### \ No newline at end of file diff --git a/api/business/회원가입.http b/api/business/회원가입.http new file mode 100644 index 0000000..30142f8 --- /dev/null +++ b/api/business/회원가입.http @@ -0,0 +1,13 @@ +POST http://localhost:8010//api/business +Content-Type: application/json + +{ + "bizNo": "999-99-99998", + "pwd": "kospo2025!", + "rePwd": "kospo2025!", + "compNm": "테스트2", + "repNm": "테스트2", + "email": "bangae1@gmail.com" +} + +### \ No newline at end of file diff --git a/api/business/회원정보 수정.http b/api/business/회원정보 수정.http new file mode 100644 index 0000000..97cc678 --- /dev/null +++ b/api/business/회원정보 수정.http @@ -0,0 +1,12 @@ +PUT http://localhost:8010//api/business +Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJiaXpObyI6Ijk5OS05OS05OTk5OCIsImlwIjoiMTI3LjAuMC4xIiwic3ViIjoiOTk5LTk5LTk5OTk4IiwiaWF0IjoxNzQ2MDEyNjcyLCJleHAiOjE3NDYwMTI5NzJ9.RaT9wa3_8oPeL6nWv1_uM6QlY1mcHyCN2tC6sP_N03w +Content-Type: application/json + +{ + "bizNo": "999-99-99998", + "compNm": "테스트3", + "repNm": "테스트3", + "email": "bangae3@gmail.com" +} + +### \ No newline at end of file diff --git a/api/business/회원탈퇴.http b/api/business/회원탈퇴.http new file mode 100644 index 0000000..c271610 --- /dev/null +++ b/api/business/회원탈퇴.http @@ -0,0 +1,5 @@ +DELETE http://localhost:8010//api/business/999-99-99998 +Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJiaXpObyI6Ijk5OS05OS05OTk5OCIsImlwIjoiMTI3LjAuMC4xIiwic3ViIjoiOTk5LTk5LTk5OTk4IiwiaWF0IjoxNzQ2MDEyNjcyLCJleHAiOjE3NDYwMTI5NzJ9.RaT9wa3_8oPeL6nWv1_uM6QlY1mcHyCN2tC6sP_N03w +Content-Type: application/json + +### \ No newline at end of file diff --git a/api/contract/계약관리 상세조회.http b/api/contract/계약관리 상세조회.http new file mode 100644 index 0000000..6e05089 --- /dev/null +++ b/api/contract/계약관리 상세조회.http @@ -0,0 +1,4 @@ +### GET request to example server +GET http://localhost:8010/api/cont/CONT-0000000005 + +### \ No newline at end of file diff --git a/api/contract/계약관리 조회(페이징).http b/api/contract/계약관리 조회(페이징).http new file mode 100644 index 0000000..dc69532 --- /dev/null +++ b/api/contract/계약관리 조회(페이징).http @@ -0,0 +1,5 @@ +### GET request to example server +GET http://localhost:8010/api/cont/page + ?cateStatCd=&signSdt=&signEdt=&page=1&row=10 + +### \ No newline at end of file diff --git a/api/contract/계약관리저장.http b/api/contract/계약관리저장.http new file mode 100644 index 0000000..124d17c --- /dev/null +++ b/api/contract/계약관리저장.http @@ -0,0 +1,18 @@ +POST http://localhost:8010/api/cont +Content-Type: application/json + +{ + "bizNo": "999-99-99999", + "prcsNo": "PRCS-20250521020", + "compNm": "영창피아노", + "contSdat": "2025-06-01", + "contEdat": "2025-06-06", + "contAtts": [ + { + "logiFnm": "계약서.pdf", + "data": "aWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjA==" + } + ] +} + +### \ No newline at end of file diff --git a/api/dtlSpec/상세규격 엑셀업로드.http b/api/dtlSpec/상세규격 엑셀업로드.http new file mode 100644 index 0000000..5251053 --- /dev/null +++ b/api/dtlSpec/상세규격 엑셀업로드.http @@ -0,0 +1,8 @@ +POST https://svcm.hmsn.ink/api/dtl/excel +Content-Type: application/json + +{ + "data": "UEsDBBQACAgIAOcctFoAAAAAAAAAAAAAAAAYAAAAeGwvZHJhd2luZ3MvZHJhd2luZzEueG1sndBdbsIwDAfwE+wOVd5pWhgTQxRe0E4wDuAlbhuRj8oOo9x+0Uo2aXsBHm3LP/nvzW50tvhEYhN8I+qyEgV6FbTxXSMO72+zlSg4gtdgg8dGXJDFbvu0GTWtz7ynIu17XqeyEX2Mw1pKVj064DIM6NO0DeQgppI6qQnOSXZWzqvqRfJACJp7xLifJuLqwQOaA+Pz/k3XhLY1CvdBnRz6OCGEFmL6Bfdm4KypB65RPVD8AcZ/gjOKAoc2liq46ynZSEL9PAk4/hr13chSvsrVX8jdFMcBHU/DLLlDesiHsSZevpNlRnfugbdoAx2By8i4OPjj3bEqyTa1KCtssV7ercyzIrdfUEsHCAdiaYMFAQAABwMAAFBLAwQUAAgICADnHLRaAAAAAAAAAAAAAAAAGAAAAHhsL3dvcmtzaGVldHMvc2hlZXQxLnhtbJ2V3Y6jIBiGr2DvwXBeUaud1qiTnWkmO2eTyc7uMYNYSUUMYG3vftG2pIX9MXsGn+/38AgYs8cja7wDEZLyNgehHwCPtJiXtN3l4OP7y2INPKlQW6KGtyQHJyLBY/ElG7jYy5oQ5WlAK3NQK9WlEEpcE4akzzvS6icVFwwpPRU7KDtBUDk1sQZGQbCCDNEWnAmpmMPgVUUx2XLcM9KqM0SQBimtL2vaySuNHR0co1hwySvlY84uJG2AITliMgmt74QYnmPEkNj33UIjO23xSRuqTpOXwRxy0Is2vTAWRmPsSfX66YE11/AxjOd5O5u5gZs7+2OY/B8pDGAYWqgYuXsxXwthQ2LzMOZELlekyCbkmygy3quGtuRNeLJnevNPT6ThQw70xb0U3umuVmMBFhk0fdPgByWDvBl74zX+5Hw/Tl7Lu6bb7Mt04HpN3EvF2TdyXiIEXkkq1DfqmTc/aalqXYv81dLU3/lgwon/kIz4ibhFChWZ4IMnRk6R4XHwVRPlxNUNUlcPRZDBg1bCl8STmwjvE89uIrpPbN3E0iSgdjJikRGLppbopiW2xNxEYom5iZUldk1MrxX5we+tlsZq6RAfLCs3sbas3IRttbyxiuI/WcXGKnaIG8vKTdhWbsK2imdZJcYq+aeVm7Ct3IRtlfzdCt5c/lKgQf9mPJFS/eWJ1zKcPj7zZyl+AVBLBwi1xQfRDQIAAJ0GAABQSwMEFAAICAgA5xy0WgAAAAAAAAAAAAAAACMAAAB4bC93b3Jrc2hlZXRzL19yZWxzL3NoZWV0MS54bWwucmVsc43PSwrCMBAG4BN4hzB7k9aFiDTtRoRupR5gSKYPbB4k8dHbm42i4MLlzM98w181DzOzG4U4OSuh5AUwssrpyQ4Szt1xvQMWE1qNs7MkYaEITb2qTjRjyjdxnHxkGbFRwpiS3wsR1UgGI3eebE56FwymPIZBeFQXHEhsimIrwqcB9ZfJWi0htLoE1i2e/rFd30+KDk5dDdn044XQAe+5WCYxDJQkcP7avcOSZxZEXYmvivUTUEsHCK2o602zAAAAKgEAAFBLAwQUAAgICADnHLRaAAAAAAAAAAAAAAAAEwAAAHhsL3RoZW1lL3RoZW1lMS54bWzNV9tu3CAQ/YL+A+K9wde9KbtRsptVH1pV6rbqM7HxpcHYAjZp/r4Ye218S6JmI2VfAuMzhzMzwJDLq78ZBQ+EizRna2hfWBAQFuRhyuI1/PVz/3kBgZCYhZjmjKzhExHwavPpEq9kQjIClDsTK7yGiZTFCiERKDMWF3lBmPoW5TzDUk15jEKOHxVtRpFjWTOU4ZTB2p+/xj+PojQguzw4ZoTJioQTiqWSLpK0EBAwnCmNh4QQKeDmJPKWktJDlIaA8kOglQ+w4b1d/hE8vttSDh4wXUNL/yDaXKIGQOUQt9e/GlcDwnvnJT6n4hvienwagINARTFc23MW/t6rsQaoGg65b6891/U7eIPfHWq5udlaXX63xXsDvOtdL3y3g/davD8S62xn2R283+Jnw3hnN7vtrIPXoISm7H6Atm3f325rdAOJcvrlZXiLQsbOqfyZnNpHGf6T870C6OKq7cmAfCpIhAOFu+YppiU9XhE8bg/EmB31iLOUvdMqLTEyA9VhZ92ov+sjqaOOUkoP8omSr0JLEjlNw70y6ol2apJcJGpYL9fBxRzrMeC5/J3K5JDgQi1j6xViUVPHAhS5UIcJTnLrpByzb3l4Kuvp3CkHLFu75Td2lUJZWWfz9pA29HoWC1OAr0lfL8JYrCvCHRExd18nwrbOpWI5omJhP6cCGVVRBwXgsmv4XqUIiABTEpZ1qvxP1T17paeS2Q3bGQlv6Z2t0h0RxnbrijC2YYJD0jefudbL5XipnVEZ88V71BoN7wbKujPwqM6c6yuaABdrGKnrTA2zQvEJFkOAaaweJ4GsE/0/N0vBhdxhkVQw/amKP0sl4YCmmdrrZhkoa7XZztz6uOKW1sfLHOoXmUQRCeSEpZ2qbxXJ6Nc3gstJflSiD0n4CO7okf/AKlH+3C4TGKZCNtkMU25s7jaLveuqPoojLzz9gKFFguuOYl7mFVyPGzlGHFppPyo0lsK7eH+OrvuyU+/SnGgg88lb7P2avKHKHVflj951y4X1fJd4e0MwpC3Gpbnj0qZ6xxkfBMZys4m8OZPVfGM36O9aZLwr9az3T9vJsvkHUEsHCGWjgWEoAwAArQ4AAFBLAwQUAAgICADnHLRaAAAAAAAAAAAAAAAAFAAAAHhsL3NoYXJlZFN0cmluZ3MueG1sZdCxTsMwEAbgJ+AdLO/UaYWqCjnugMQTwANYydFYis8h56CyVkUKsDF1qMQKiAkGGHiiJn0HjGDBGe+7/+6kk/OlLdkV1GQcpnw8SjgDzFxucJHy87PTwxln5DXmunQIKb8G4nN1IIk8C6NIKS+8r46FoKwAq2nkKsDQuXC11T6U9UJQVYPOqQDwthSTJJkKqw1ylrkGfTg75axBc9nAyR8kXEkySnq1f2i7lxspvJLiR35197HdvT3H2t0/9dt1rH276R5vB9nVpl+9xjqzli3ZkbVxA/Rgwbrd333GOp4MZ7v3r39JEZ6nvgFQSwcIOaKSW+wAAAB6AQAAUEsDBBQACAgIAOcctFoAAAAAAAAAAAAAAAANAAAAeGwvc3R5bGVzLnhtbLVUTW+cMBD9Bf0Plu9Zs7ttlERAFKWi6qU9ZCv1aowBK/5AtjeF/vqOMWTZbqMkK5UD2DPj954fY6e3vZLoiVsnjM7wepVgxDUzldBNhn/siosrjJynuqLSaJ7hgTt8m39InR8kf2g59wgQtMtw6313Q4hjLVfUrUzHNWRqYxX1MLUNcZ3ltHJhkZJkkySXRFGhcUS46dcfKTvBUYJZ40ztV8woYupaMH6KdE2uCWUzkjqF+YccRe3jvrsA2I56UQop/DCqwnlaG+0dYmavfYa3UyBP3W/0RCX4lIBRJE+ZkcYi25QZLopkfEJYU8Vj4Z0VVIbQqGMKKqGNDUESUeO7/BsvPmfjRSwfykDwGTDjxwGckPLYCwjkKZjmudUFTNA03g0dcGlolAgz1r1SLUXT+i+WDm9f4owUVdDR3C/92n6++nR/GWDKlxJkgfnMNn5gn6WxFRyEeadrPIfCwikJtnIpH0Lz/6yPSvsaxZqvVYbhFAXQeQg+TkO9V4WaJ7Tr5HAHBmjFI0wMFSbOAu+SLpIveLfn8fb1GwXkKZ2TKBw4uBS+B6pxsWut0I87Uwg/zuES8YKFRiqN90Zh9MvSbsf7MR320tcvy90c5K7fLRcw3if+NTUL8zb/w7yZn0w/dNFWR031HD3QhkOc4W/hHpMYlXshvdAxd9QvgFn1h1aJ2cOtnf8BUEsHCITDsawJAgAA+gUAAFBLAwQUAAgICADnHLRaAAAAAAAAAAAAAAAADwAAAHhsL3dvcmtib29rLnhtbJ2SS07DMBCGT8AdIu9bJ6igNmrSDULqBrGAA7j2pLHiR2S7Ib0CXIGDcCi4A9M0iVS6iVj5Od98sv/1ptUqasB5aU1GknlMIjDcCmn2GXl9eZwtSeQDM4IpayAjR/Bkk9+s36yrdtZWEdYbn5EyhDql1PMSNPNzW4PBk8I6zQIu3Z762gETvgQIWtHbOL6nmklDzoTUTWHYopAcHiw/aDDhDHGgWEB7X8raDzTdXuG05M56W4Q5t7onoQGn0HLohJYXQppPMdLMVYd6hsgaLXZSyXDsvEZMk5GDM2nPmI0ap5oU+6eNVsPlNllM8756zBVdXdi3yd3/SElMk+QPasGu32K6FuMjSU/DjD/SRyQf4/bsaL7u+L4fT+kMGMxGerlTQCLDNC6/Pz5/3r8SDO/p0lZgtknkUokTtxULghg6cAQU0oB4wkKP+5wp3vWhQ9f8F1BLBwhbusWcUwEAACcDAABQSwMEFAAICAgA5xy0WgAAAAAAAAAAAAAAABoAAAB4bC9fcmVscy93b3JrYm9vay54bWwucmVsc62SQWrDMBBFT9A7iNnXspNSSomcTShk26YHENLYMrElIU3a+vadNuA6EEIXXon/xfz/0Giz/Rp68YEpd8ErqIoSBHoTbOdbBe+Hl/snEJm0t7oPHhWMmGFb321esdfEM9l1MQsO8VmBI4rPUmbjcNC5CBE93zQhDZpYplZGbY66Rbkqy0eZ5hlQX2SKvVWQ9rYCcRgj/ic7NE1ncBfMaUBPVyok8SxyoE4tkoJfeTargsNAXmdYLcmQaez5DSeIs75Vv1603umE9o0SL3hOMbdvwTwsCfMZ0jE7RPoDmawfVD6mxciLH1d/A1BLBwiWGcFT6gAAALkCAABQSwMEFAAICAgA5xy0WgAAAAAAAAAAAAAAAAsAAABfcmVscy8ucmVsc43PQQ6CMBAF0BN4h2b2UnBhjKGwMSZsDR6gtkMhQKdpq8Lt7VKNC5eT+fN+pqyXeWIP9GEgK6DIcmBoFenBGgHX9rw9AAtRWi0nsihgxQB1tSkvOMmYbkI/uMASYoOAPkZ35DyoHmcZMnJo06YjP8uYRm+4k2qUBvkuz/fcvxtQfZis0QJ8owtg7erwH5u6blB4InWf0cYfFV+JJEtvMApYJv4kP96IxiyhwKuSfzxYvQBQSwcIpG+hILIAAAAoAQAAUEsDBBQACAgIAOcctFoAAAAAAAAAAAAAAAATAAAAW0NvbnRlbnRfVHlwZXNdLnhtbLVTy07DMBD8Av4h8hU1bjkghJr2wOMISJQPWOxNY9Uved3X37NJWiSqIIHUXry2xzsz67Wn852zxQYTmeArMSnHokCvgjZ+WYmPxfPoThSUwWuwwWMl9khiPruaLvYRqeBkT5Voco73UpJq0AGVIaJnpA7JQeZlWsoIagVLlDfj8a1UwWf0eZRbDjGbPmINa5uLh36/pa4ExGiNgsy+JJOJ4mnHYG+zXcs/5G28PjEzOhgpE9ruDDUm0vWpAKPUKrzyzSSj8V8Soa6NQh3U2nFKSTEhaGoQs7PlNqRVN+813yDlF3BMKndWfoMkuzApD5We3wc1kFC/58SNpiEvPw6c04dOsGXOIc0DRMfJJevPe4vDhXfIOZUzfwsckuqAfrxoqzmWDoz/7c19hrA66svuZ8++AFBLBwhtiLRQNQEAABkEAABQSwECFAAUAAgICADnHLRaB2JpgwUBAAAHAwAAGAAAAAAAAAAAAAAAAAAAAAAAeGwvZHJhd2luZ3MvZHJhd2luZzEueG1sUEsBAhQAFAAICAgA5xy0WrXFB9ENAgAAnQYAABgAAAAAAAAAAAAAAAAASwEAAHhsL3dvcmtzaGVldHMvc2hlZXQxLnhtbFBLAQIUABQACAgIAOcctFqtqOtNswAAACoBAAAjAAAAAAAAAAAAAAAAAJ4DAAB4bC93b3Jrc2hlZXRzL19yZWxzL3NoZWV0MS54bWwucmVsc1BLAQIUABQACAgIAOcctFplo4FhKAMAAK0OAAATAAAAAAAAAAAAAAAAAKIEAAB4bC90aGVtZS90aGVtZTEueG1sUEsBAhQAFAAICAgA5xy0WjmiklvsAAAAegEAABQAAAAAAAAAAAAAAAAACwgAAHhsL3NoYXJlZFN0cmluZ3MueG1sUEsBAhQAFAAICAgA5xy0WoTDsawJAgAA+gUAAA0AAAAAAAAAAAAAAAAAOQkAAHhsL3N0eWxlcy54bWxQSwECFAAUAAgICADnHLRaW7rFnFMBAAAnAwAADwAAAAAAAAAAAAAAAAB9CwAAeGwvd29ya2Jvb2sueG1sUEsBAhQAFAAICAgA5xy0WpYZwVPqAAAAuQIAABoAAAAAAAAAAAAAAAAADQ0AAHhsL19yZWxzL3dvcmtib29rLnhtbC5yZWxzUEsBAhQAFAAICAgA5xy0WqRvoSCyAAAAKAEAAAsAAAAAAAAAAAAAAAAAPw4AAF9yZWxzLy5yZWxzUEsBAhQAFAAICAgA5xy0Wm2ItFA1AQAAGQQAABMAAAAAAAAAAAAAAAAAKg8AAFtDb250ZW50X1R5cGVzXS54bWxQSwUGAAAAAAoACgCaAgAAoBAAAAAA" +} + +### \ No newline at end of file diff --git a/api/estimate/견적서(첨부파일) 삭제.http b/api/estimate/견적서(첨부파일) 삭제.http new file mode 100644 index 0000000..94be556 --- /dev/null +++ b/api/estimate/견적서(첨부파일) 삭제.http @@ -0,0 +1,4 @@ +DELETE http://localhost:8010/api/bid/BID-0000000009/1 +Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJiaXpObyI6Ijk5OS05OS05OTk5OSIsImlwIjoiMTI3LjAuMC4xIiwic3ViIjoiOTk5LTk5LTk5OTk5IiwiaWF0IjoxNzQ1NTkwNjQ3LCJleHAiOjE3NDU1OTA5NDd9.a9nwoQTDV702VbU0HnP1jS8SGhFi_3UjkjdBcjoDzCE + +### \ No newline at end of file diff --git a/api/estimate/견적수정.http b/api/estimate/견적수정.http new file mode 100644 index 0000000..75ecbfc --- /dev/null +++ b/api/estimate/견적수정.http @@ -0,0 +1,24 @@ +PUT http://localhost:8010/api/estimate +Content-Type: application/json +Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJiaXpObyI6Ijk5OS05OS05OTk5OSIsImlwIjoiMTI3LjAuMC4xIiwic3ViIjoiOTk5LTk5LTk5OTk5IiwiaWF0IjoxNzQ3MDQ4NDI5LCJleHAiOjE3NDcwNTAyMjl9.6SzI3eiNVmXOz1s1p8ab26fT80rbSJBfoDlKLQ4z5Sg + +{ + "estimates": [ + { + "estNo": "EST-0000000003", + "mngNm": "조진우", + "unitPrc": 2, + "amt": 40000 + }, + { + "estNo": "EST-0000000004", + "mngNm": "조진우", + "unitPrc": 12, + "amt": 60000 + } + ], + "pbAtts": [] +} + + +### \ No newline at end of file diff --git a/api/estimate/견적저장.http b/api/estimate/견적저장.http new file mode 100644 index 0000000..dc460af --- /dev/null +++ b/api/estimate/견적저장.http @@ -0,0 +1,28 @@ +POST http://localhost:8010/api/estimate +Content-Type: application/json +Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJiaXpObyI6IjExMS0xMS0xMTExMSIsImlwIjoiMTgyLjIyNy4xNS45MiIsInN1YiI6IjExMS0xMS0xMTExMSIsImlhdCI6MTc0NzY0MDcxMCwiZXhwIjoxNzQ3NjQyNTEwfQ.nUFFdX1nZ_-n_TLzZbfHLIOEbt0swKcGPOQ1nR_2MzI + +{ + "estimates": [ + { + "bizNo": "111-11-11111", + "prcsNo": "PRCS-20250519017", + "dtlSpNo": "DTL-0000000036", + "mngNm": "테스트1", + "unitPrc": 2, + "amt": 70000 + } + ], + "pbAtts": [ + { + "logiFnm": "text1.pdf", + "data": "aWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjA==" + }, + { + "logiFnm": "text1.pdf", + "data": "aWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjA==" + } + ] +} + +### \ No newline at end of file diff --git a/api/estimate/견적조회.http b/api/estimate/견적조회.http new file mode 100644 index 0000000..dbdc097 --- /dev/null +++ b/api/estimate/견적조회.http @@ -0,0 +1,6 @@ +### GET request to example server +GET http://localhost:8010/api/estimate + ?prcsNo=PRCS-0000000006 +Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJiaXpObyI6Ijk5OS05OS05OTk5OSIsImlwIjoiMTI3LjAuMC4xIiwic3ViIjoiOTk5LTk5LTk5OTk5IiwiaWF0IjoxNzQ3MDQ4NDI5LCJleHAiOjE3NDcwNTAyMjl9.6SzI3eiNVmXOz1s1p8ab26fT80rbSJBfoDlKLQ4z5Sg + +### \ No newline at end of file diff --git a/api/login/사업자로그인.http b/api/login/사업자로그인.http new file mode 100644 index 0000000..ad04291 --- /dev/null +++ b/api/login/사업자로그인.http @@ -0,0 +1,10 @@ +### GET request to example server +POST http://localhost:8010/api/login +Content-Type: application/json + +{ + "bizNo": "111-11-11111", + "pwd": "kospo2025!" +} + +### \ No newline at end of file diff --git a/api/price_survey/(외부)가격조사_견적관리 조회(페이징).http b/api/price_survey/(외부)가격조사_견적관리 조회(페이징).http new file mode 100644 index 0000000..c8496a1 --- /dev/null +++ b/api/price_survey/(외부)가격조사_견적관리 조회(페이징).http @@ -0,0 +1,6 @@ +### GET request to example server +GET http://localhost:8010/api/prcs/external/page + ?cateCd=&stCd=®Nm=®Sdt=®Edt=&page=1&row=10 +Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJiaXpObyI6Ijk5OS05OS05OTk5OSIsImlwIjoiMTI3LjAuMC4xIiwic3ViIjoiOTk5LTk5LTk5OTk5IiwiaWF0IjoxNzQ2MDEzMjAwLCJleHAiOjE3NDYwMTM1MDB9.2mSDvhpXtvkYHeRr_d1tiKvnSU0OGehBq0ce1AOvXnE + +### \ No newline at end of file diff --git a/api/price_survey/가격조사상세조회.http b/api/price_survey/가격조사상세조회.http new file mode 100644 index 0000000..786861c --- /dev/null +++ b/api/price_survey/가격조사상세조회.http @@ -0,0 +1,4 @@ +### GET request to example server +GET http://localhost:8010/api/prcs/PRCS-20250523052 + +### \ No newline at end of file diff --git a/api/price_survey/가격조사수정.http b/api/price_survey/가격조사수정.http new file mode 100644 index 0000000..158e63e --- /dev/null +++ b/api/price_survey/가격조사수정.http @@ -0,0 +1,57 @@ +PUT http://localhost:8010//api/prcs +Content-Type: application/json + +{ + "prcsNo": "PRCS-20250521019", + "cateCd": "0200", + "title": "5층 파티션 구매", + "content": "싼거 찾아요111", + "regSdat": "2025-04-01", + "regEdat": "2025-07-30", + "prvYn": false, + "prvRsn": "", + "prvPwd": "", + "aiYn": false, + "prcsAtts": [ + ], + "dtlSpecs": [ + ], + "apprReqs": [ + { + "gubunCd": "", + "apprNo": "APPR-20250514013", + "apprOrd": 10, + "sabun": "psn14020", + "name": "조진우", + "attendCd": "" + }, + { + "gubunCd": "0100", + "apprNo": "APPR-20250514013", + "apprOrd": 20, + "sabun": "17131303", + "name": "김진형1", + "attendCd": "" + }, + { + "gubunCd": "0200", + "apprNo": "APPR-20250514013", + "apprOrd": 30, + "sabun": "17131304", + "name": "손원장1", + "attendCd": "01" + } + ], + "prcsBizs": [ + { + "bizNo": "999-99-99999", + "email": "bangae2@gmail.com" + }, + { + "bizNo": "111-11-11111", + "email": "bangae1@gmail.com" + } + ] +} + +### \ No newline at end of file diff --git a/api/price_survey/가격조사수정_Test.http b/api/price_survey/가격조사수정_Test.http new file mode 100644 index 0000000..4dcd5c0 --- /dev/null +++ b/api/price_survey/가격조사수정_Test.http @@ -0,0 +1,46 @@ +PUT https://svcm.hmsn.ink//api/prcs +Content-Type: application/json + +{ + "prcsNo": "PRCS-20250521023", + "cateCd": "0000", + "title": "4층 파티션 구매123", + "content": "싼거 찾아요123", + "regSdat": "2025-05-01", + "regEdat": "2025-05-03", + "prvYn": true, + "prvRsn": "", + "prvPwd": "", + "aiYn": true, + "prcsBizs": [ + { + "bizNo": "999-99-99999", + "email": "aa@gmail.com" + }, + { + "bizNo": "111-11-11111", + "email": "bb@gmail.com" + } + ], + "prcsAtts": [], + "apprReqs": [ + { + "gubunCd": "0000", + "sabun": "psn14020", + "name": "조진우", + "apprNo": "APPR-0000000023", + "apprOrd": 1, + "attendCd": null + }, + { + "gubunCd": "0100", + "sabun": "15000007", + "name": "조용식", + "apprNo": "APPR-0000000023", + "apprOrd": 2, + "attendCd": null + } + ] +} + +### \ No newline at end of file diff --git a/api/price_survey/가격조사완료처리.http b/api/price_survey/가격조사완료처리.http new file mode 100644 index 0000000..9dd6f59 --- /dev/null +++ b/api/price_survey/가격조사완료처리.http @@ -0,0 +1,4 @@ +PUT http://localhost:8010/api/prcs/survey/PRCS-20250522038 +Content-Type: application/json + +### \ No newline at end of file diff --git a/api/price_survey/가격조사저장.http b/api/price_survey/가격조사저장.http new file mode 100644 index 0000000..ee51f12 --- /dev/null +++ b/api/price_survey/가격조사저장.http @@ -0,0 +1,60 @@ +POST http://localhost:8010//api/prcs +Content-Type: application/json + +{ + "cateCd": "0200", + "title": "가격조사 시나리오 테스트99", + "content": "시나리오테스트입니다.\n시나리오테스트입니다.\n시나리오테스트입니다.\n시나리오테스트입니다.\n시나리오테스트입니다.\n시나리오테스트입니다.\n시나리오테스트입니다.\n시나리오테스트입니다.\n시나리오테스트입니다.\n시나리오테스트입니다.\n시나리오테스트입니다.\n시나리오테스트입니다.\n", + "regSdat": "2025-04-01", + "regEdat": "2025-05-22", + "prvYn": false, + "prvRsn": "", + "prvPwd": "", + "aiYn": false, + "prcsAtts": [ + { + "logiFnm": "text1.pdf", + "data": "aWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjGlkIDcyMiDquYzsp4Ag7JmE66OMaWQgNzIyIOq5jOyngCDsmYTro4xpZCA3MjIg6rmM7KeAIOyZhOujjA==" + } + ], + "dtlSpecs": [ + { + "itemNm": "철판", + "spec": "3*6 (914*1829)", + "unit": "1.6T", + "qty": 3 + } + ], + "apprReqs": [ + { + "gubunCd": "", + "sabun": "psn14020", + "name": "조진우", + "attendCd": null + }, + { + "gubunCd": "0100", + "sabun": "17131303", + "name": "김진형", + "attendCd": null + }, + { + "gubunCd": "0200", + "sabun": "17131304", + "name": "손원장", + "attendCd": null + } + ], + "prcsBizs": [ + { + "bizNo": "999-99-99999", + "email": "aa@gmail.com" + }, + { + "bizNo": "111-11-11111", + "email": "bb@gmail.com" + } + ] +} + +### \ No newline at end of file diff --git a/api/price_survey/가격조사조회(페이징).http b/api/price_survey/가격조사조회(페이징).http new file mode 100644 index 0000000..a15752f --- /dev/null +++ b/api/price_survey/가격조사조회(페이징).http @@ -0,0 +1,5 @@ +### GET request to example server +GET http://localhost:8010/api/prcs/page + ?cateCd=&stCd=®Nm=®Sdt=®Edt=&page=1&row=10 + +### \ No newline at end of file diff --git a/api/price_survey/가격조사회수.http b/api/price_survey/가격조사회수.http new file mode 100644 index 0000000..db2ff1b --- /dev/null +++ b/api/price_survey/가격조사회수.http @@ -0,0 +1,3 @@ +PUT http://localhost:8010/api/prcs/ret/PRCS-20250522037 +Content-Type: application/json +### \ No newline at end of file diff --git a/api/sapAppr/sap결재상태 변경.http b/api/sapAppr/sap결재상태 변경.http new file mode 100644 index 0000000..48d1179 --- /dev/null +++ b/api/sapAppr/sap결재상태 변경.http @@ -0,0 +1,10 @@ +PUT http://localhost:8010/api/sap/appr +sabun: 15000004 +Content-Type: application/json + +{ + "wkfid": "FI2025900007", + "wkfsq": 3, + "bname": "15000004", + "wkfst": "A" +} \ No newline at end of file diff --git a/api/sapAppr/sap결재저장.http b/api/sapAppr/sap결재저장.http new file mode 100644 index 0000000..cce8875 --- /dev/null +++ b/api/sapAppr/sap결재저장.http @@ -0,0 +1,44 @@ +POST http://localhost:8010/api/sap/appr +Content-Type: application/json + +{ + "belnr": "202500102045", + "wkftx": "자재유형:SILLING, 품질등급 E:, 자재내역 : SUS", + "apprs": [ + { + "label": "결재", + "value": [ + { + "lineclsf": "Q", + "bname": "15000037", + "abscd": "" + }, + { + "lineclsf": "I", + "bname": "15000003", + "abscd": "" + }, + { + "lineclsf": "I", + "bname": "15000004", + "abscd": "A" + }, + { + "lineclsf": "E", + "bname": "15000037", + "abscd": "" + }, + { + "lineclsf": "E", + "bname": "15000062", + "abscd": "" + }, + { + "lineclsf": "A", + "bname": "15000005", + "abscd": "" + } + ] + } + ] +} \ No newline at end of file diff --git a/api/sapAppr/sap협조 (신규결재) 저장.http b/api/sapAppr/sap협조 (신규결재) 저장.http new file mode 100644 index 0000000..335fbaf --- /dev/null +++ b/api/sapAppr/sap협조 (신규결재) 저장.http @@ -0,0 +1,33 @@ +POST http://localhost:8010/api/sap/appr +sabun: 15000062 +Content-Type: application/json + +{ + "wkfid": "FI2025900004", + "apprs": [ + { + "label": "협조", + "value": [ + { + "lineclsf": "Q", + "bname": "15000062", + "abscd": "", + "grpid": 1 + }, + { + "lineclsf": "I", + "bname": "15000057", + "abscd": "", + "grpid": 1 + }, + { + "lineclsf": "A", + "bname": "15000056", + "abscd": "", + "grpid": 1 + } + ] + } + ] +} + diff --git a/api/slip/임시전표저장.http b/api/slip/임시전표저장.http new file mode 100644 index 0000000..9d90c2f --- /dev/null +++ b/api/slip/임시전표저장.http @@ -0,0 +1,20 @@ +POST http://localhost:8010/api/slip +Content-Type: application/json + +{ + "contNo": "CONT-0000000005", + "lifnr": "999-99-99999", + "gsber": "1000", + "wrbtrS": "1102", + "mwskz": "V4", + "waers": "KRW", + "bldat": "20250501", + "budat": "20250502", + "hkont": "5366010", + "kostl": "12330", + "projk": "", + "wrbtr": "1203", + "bvtyp": "3100", + "bankl": "012", + "bankn": "3510876657453" +} \ No newline at end of file diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..5f5a22d --- /dev/null +++ b/build.gradle @@ -0,0 +1,90 @@ +plugins { + id 'java' + id 'org.springframework.boot' version '3.3.2' + id 'io.spring.dependency-management' version '1.1.6' +} + +group = 'com.kospo' +version = '0.0.1-SNAPSHOT' + +java { + toolchain { + languageVersion = JavaLanguageVersion.of(21) + } +} + +configurations { + compileOnly { + extendsFrom annotationProcessor + } +} + +repositories { + mavenCentral() +} +ext['queryDslVersion'] = '5.0.0' + + +dependencies { + implementation 'org.springframework.boot:spring-boot-starter-data-jdbc' + implementation 'org.springframework.boot:spring-boot-starter-data-jpa' + implementation 'org.springframework.boot:spring-boot-starter-data-rest' + implementation 'org.springframework.boot:spring-boot-starter-web-services' + implementation 'org.springframework.boot:spring-boot-starter-security' + implementation 'org.springframework.boot:spring-boot-starter-reactor-netty' + implementation 'org.springframework.boot:spring-boot-starter-mail' + implementation 'org.springframework.retry:spring-retry:2.0.8' + implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.3.0' + + + implementation 'org.bgee.log4jdbc-log4j2:log4jdbc-log4j2-jdbc4.1:1.16' + implementation 'com.github.ulisesbocchio:jasypt-spring-boot-starter:3.0.5' + implementation 'com.github.ulisesbocchio:jasypt-maven-plugin:3.0.5' + + implementation 'org.jetbrains:annotations:24.0.0' + + implementation "com.querydsl:querydsl-jpa:${queryDslVersion}:jakarta" + implementation 'org.springframework.boot:spring-boot-starter-actuator' +// annotationProcessor "com.querydsl:querydsl-apt:${queryDslVersion}" + annotationProcessor "com.querydsl:querydsl-apt:${dependencyManagement.importedProperties['querydsl.version']}:jakarta" + annotationProcessor "jakarta.annotation:jakarta.annotation-api" + annotationProcessor "jakarta.persistence:jakarta.persistence-api" + + implementation 'com.google.code.gson:gson:2.9.0' + implementation 'com.fasterxml.jackson.core:jackson-databind:2.15.3' + implementation 'com.fasterxml.jackson.core:jackson-core:2.15.3' + implementation 'com.fasterxml.jackson.core:jackson-annotations:2.15.3' + implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.15.3' + + implementation 'io.jsonwebtoken:jjwt-api:0.11.5' + runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.11.5' + runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.11.5' + + implementation 'org.apache.poi:poi:5.4.1' + implementation 'org.apache.poi:poi-ooxml:5.4.1' + + implementation 'javax.xml.bind:jaxb-api:2.3.1' + implementation 'org.modelmapper:modelmapper:3.2.0' + implementation 'org.apache.commons:commons-lang3:3.13.0' + implementation 'commons-codec:commons-codec:1.16.0' + implementation 'org.apache.commons:commons-dbcp2:2.10.0' + implementation 'org.apache.commons:commons-pool2:2.12.0' + implementation 'commons-logging:commons-logging:1.2' + implementation 'commons-io:commons-io:2.19.0' + implementation 'org.apache.commons:commons-email:1.5' + implementation 'org.postgresql:postgresql:42.7.3' + + + // sockjs + + runtimeOnly group: 'io.netty', name: 'netty-resolver-dns-native-macos', version: '4.1.112.Final' + compileOnly 'org.projectlombok:lombok' + developmentOnly 'org.springframework.boot:spring-boot-devtools' + annotationProcessor 'org.projectlombok:lombok' + testImplementation 'org.springframework.boot:spring-boot-starter-test' + testRuntimeOnly 'org.junit.platform:junit-platform-launcher' +} + +tasks.named('test') { + useJUnitPlatform() +} diff --git a/fileToByte.html b/fileToByte.html new file mode 100644 index 0000000..3e8782b --- /dev/null +++ b/fileToByte.html @@ -0,0 +1,30 @@ + + + + + Title + + + + + + \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..e644113 Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..a441313 --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,7 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip +networkTimeout=10000 +validateDistributionUrl=true +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew new file mode 100644 index 0000000..b740cf1 --- /dev/null +++ b/gradlew @@ -0,0 +1,249 @@ +#!/bin/sh + +# +# Copyright © 2015-2021 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000..25da30d --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,92 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..72dc8c7 --- /dev/null +++ b/readme.md @@ -0,0 +1 @@ +소액 계약 관리 플랫폼 \ No newline at end of file diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 0000000..1f76ea7 --- /dev/null +++ b/settings.gradle @@ -0,0 +1 @@ +rootProject.name = 'svcm' diff --git a/src/main/java/com/kospo/svcm/Application.java b/src/main/java/com/kospo/svcm/Application.java new file mode 100644 index 0000000..0b4c66b --- /dev/null +++ b/src/main/java/com/kospo/svcm/Application.java @@ -0,0 +1,21 @@ +package com.kospo.svcm; + +import io.swagger.v3.oas.annotations.OpenAPIDefinition; +import io.swagger.v3.oas.annotations.servers.Server; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.scheduling.annotation.EnableScheduling; + +@OpenAPIDefinition(servers = { + @Server(url = "http://localhost:8010", description = "로컬 api"), + @Server(url = "http://hmsn.ink:8010", description = "개발 api"), + @Server(url = "https://svcm.hmsn.ink", description = "외부 api"), +}) +@EnableScheduling +@SpringBootApplication +public class Application { + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } + +} diff --git a/src/main/java/com/kospo/svcm/config/CorsPreflightHandler.java b/src/main/java/com/kospo/svcm/config/CorsPreflightHandler.java new file mode 100644 index 0000000..2f16978 --- /dev/null +++ b/src/main/java/com/kospo/svcm/config/CorsPreflightHandler.java @@ -0,0 +1,19 @@ +package com.kospo.svcm.config; + +import org.springframework.http.HttpHeaders; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RestControllerAdvice; + +@RestControllerAdvice +public class CorsPreflightHandler { + @RequestMapping(method = RequestMethod.OPTIONS, path="/api/**") + public ResponseEntity options() { + return ResponseEntity.ok() + .header(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, "*") + .header(HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS, "GET, POST, PUT, DELETE, OPTIONS") + .header(HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS, "*") + .build(); + } +} diff --git a/src/main/java/com/kospo/svcm/config/exception/CustomErrorResponse.java b/src/main/java/com/kospo/svcm/config/exception/CustomErrorResponse.java new file mode 100644 index 0000000..cfbbd0e --- /dev/null +++ b/src/main/java/com/kospo/svcm/config/exception/CustomErrorResponse.java @@ -0,0 +1,21 @@ +package com.kospo.svcm.config.exception; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@AllArgsConstructor +@NoArgsConstructor +@Builder +@Data +@Schema(name="errorResponse", description = "오류") +public class CustomErrorResponse { + @Schema(name="code", description = "오류 코드", example = "30000") + private String code; + @Schema(name="body", description = "오류 메시지", example = "오류 발생") + private String body; + @Schema(name="errTime", description = "오류 시간", example = "1761000247") + private long errTime; +} diff --git a/src/main/java/com/kospo/svcm/config/exception/CustomExceptionHandler.java b/src/main/java/com/kospo/svcm/config/exception/CustomExceptionHandler.java new file mode 100644 index 0000000..2b8afbf --- /dev/null +++ b/src/main/java/com/kospo/svcm/config/exception/CustomExceptionHandler.java @@ -0,0 +1,132 @@ +package com.kospo.svcm.config.exception; + + +import com.kospo.svcm.exception.CustomException; +import com.kospo.svcm.exception.CustomMessageException; +import jakarta.servlet.http.HttpServletRequest; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.context.request.WebRequest; +import org.springframework.web.method.HandlerMethod; +import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler; + +import java.util.Date; + +@Slf4j +@ControllerAdvice +@Controller +public class CustomExceptionHandler extends ResponseEntityExceptionHandler { + + public static final String ANSI_RESET = "\u001B[0m"; + public static final String ANSI_YELLOW_COLOR = "\u001B[33m"; + + + @ExceptionHandler(CustomException.class) + @ResponseBody + public ResponseEntity customException(CustomException e, HandlerMethod method, HttpServletRequest request, WebRequest webRequest) { + + Date errorDate = new Date(); + String exceptionName = e.getClass().getSimpleName(); + String controllerName = method.getMethod().getDeclaringClass().getSimpleName(); + String methodName = method.getMethod().getName(); + int lineNumber = e.getStackTrace()[0].getLineNumber(); + String detail = e.getMessage(); + String requestURI = request.getRequestURI(); + + + + log.error(ANSI_YELLOW_COLOR + "[EVENT_TIME: {} | CONTROLLER_NAME : {} | METHOD_NAME : {} | EXCEPTION_LINE : {} | EXCEPTION_NAME : {} | DETAIL : {} | REQUEST_URI : {}]" + ANSI_RESET + , errorDate + , controllerName + , methodName + , lineNumber + , exceptionName + , detail + , requestURI); + + HttpHeaders resHeaders = new HttpHeaders(); + resHeaders.add("Content-Type", "application/json;charset=UTF-8"); + + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).headers(resHeaders).body( + CustomErrorResponse.builder() + .code(e.getErrorCode().getCode()) + .body(e.getErrorCode().getBody()) + .errTime(System.currentTimeMillis()).build() + ); + } + @ExceptionHandler(CustomMessageException.class) + @ResponseBody + public ResponseEntity customMessageException(CustomMessageException e, HandlerMethod method, HttpServletRequest request, WebRequest webRequest) { + + Date errorDate = new Date(); + String exceptionName = e.getClass().getSimpleName(); + String controllerName = method.getMethod().getDeclaringClass().getSimpleName(); + String methodName = method.getMethod().getName(); + int lineNumber = e.getStackTrace()[0].getLineNumber(); + String detail = e.getMessage(); + String requestURI = request.getRequestURI(); + + + + log.error(ANSI_YELLOW_COLOR + "[EVENT_TIME: {} | CONTROLLER_NAME : {} | METHOD_NAME : {} | EXCEPTION_LINE : {} | EXCEPTION_NAME : {} | DETAIL : {} | REQUEST_URI : {}]" + ANSI_RESET + , errorDate + , controllerName + , methodName + , lineNumber + , exceptionName + , detail + , requestURI); + + HttpHeaders resHeaders = new HttpHeaders(); + resHeaders.add("Content-Type", "application/json;charset=UTF-8"); + + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).headers(resHeaders).body( + CustomErrorResponse.builder() + .code(e.getCusMessage().getCode()) + .body(e.getCusMessage().getMessage()) + .errTime(System.currentTimeMillis()).build() + ); + } + + @ExceptionHandler(Exception.class) + public ResponseEntity handleException(Exception e, HandlerMethod method, HttpServletRequest request, WebRequest webRequest) { + +// Date errorDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(Calendar.getInstance().getTime()); + Date errorDate = new Date(); + String exceptionName = e.getClass().getSimpleName(); + String controllerName = method.getMethod().getDeclaringClass().getSimpleName(); + String methodName = method.getMethod().getName(); + int lineNumber = e.getStackTrace()[0].getLineNumber(); + String detail = e.getMessage(); + String requestURI = request.getRequestURI(); + + + + log.error(ANSI_YELLOW_COLOR + "[EVENT_TIME: {} | CONTROLLER_NAME : {} | METHOD_NAME : {} | EXCEPTION_LINE : {} | EXCEPTION_NAME : {} | DETAIL : {} | REQUEST_URI : {}]" + ANSI_RESET + , errorDate + , controllerName + , methodName + , lineNumber + , exceptionName + , detail + , requestURI); + + + HttpHeaders resHeaders = new HttpHeaders(); + resHeaders.add("Content-Type", "application/json;charset=UTF-8"); + return ResponseEntity.status(500).headers(resHeaders).body( + CustomErrorResponse.builder() + .code(ErrorCode.INTERNAL_SERVER_ERROR.getCode()) + .body(ErrorCode.INTERNAL_SERVER_ERROR.getBody()) + .errTime(System.currentTimeMillis()).build() + ); + } + + +} diff --git a/src/main/java/com/kospo/svcm/config/exception/ErrorCode.java b/src/main/java/com/kospo/svcm/config/exception/ErrorCode.java new file mode 100644 index 0000000..b670ec8 --- /dev/null +++ b/src/main/java/com/kospo/svcm/config/exception/ErrorCode.java @@ -0,0 +1,65 @@ +package com.kospo.svcm.config.exception; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@AllArgsConstructor +@Getter +public enum ErrorCode { + /*트랜잭션 관련*/ + FIND_ERR("20000", "조회에 실패했습니다."), + SAVE_ERR("20001", "저장에 실패했습니다."), + UPD_ERR("20002", "수정에 실패했습니다."), + DEL_ERR("20003", "삭제에 실패했습니다."), + APPR_ERR("20004", "결재가 완료 되지 않았습니다.."), + APPR_LOCK("20005", "결재 진행중 이거나 완료 상태로 수정이 불가합니다."), + APPR_SVY_ERR("20006", "조사완료 되어 등록이 불가합니다."), + /*토큰 관련*/ + EXPIRE_TOKEN("30000", "토큰이 만료 되었습니다."), + MALFORMED_JWT("30001", "JWT 문자열은 정확히 2개의 마침표 문자를 포함해야 합니다."), + /*bad request*/ + BIND_ERROR("40001", "파라미터를 다시 확인해주세요."), + /*존재 하지 않음*/ + NO_RESULT("44001", "존재하지 않는 데이터 입니다."), + NO_ACCOUNT("44011", "아이디 또는 비밀번호를 다시 확인해주세요."), + NO_MATCH_ACCOUNT("44012", "일치하는 사용자가 없습니다."), + NO_TOKEN("44021", "헤더에 토큰이 없습니다."), + NO_MATCH_TOKEN("44022", "일치 하지 않는 토큰입니다."), + NO_SAME_IP("44030", "등록된 아이피와 일치 하지 않습니다. 다시 로그인 해주세요"), + NO_SAME_DATA("44031", "사용자가 소유한 데이터가 아닙니다."), + No_SVY_NOT_EXECUTE("44032", "사전조사가 실행 되지 않았거나 등록 기간중 입니다."), + SAME_DATA("44020", "이미 등록된 데이터가 있습니다."), + /*권한 관련*/ + + AUTHENTICATION("43000", "사용자가 정보가 일치하지 않습니다."), + AUTHENTICATION_NOT_SUPPORT("43001", "허용되지 않은 사용자입니다."), + NO_REGISTER("43002", "사용자가 존재하지 않습니다."), + SLEEP_ACCOUNT("43003", "휴면 계정입니다. 개인정보에 약관에 동의해주세요."), + //500 INTERNAL SERVER ERROR + INTERNAL_SERVER_ERROR("50000", "서버 에러입니다. 유지보수관리자에게 연락주세요!"), + + /*로그인 관련*/ + LOGIN_ERR("60000", "사업자번호 또는 비밀번호가 일치 하지 않습니다."), + NOT_REGISTER("60001", "가입된 사업자가 아닙니다."), + ALREADY_REGISTER("60001", "이미 가입된 사업자 입니다."), + OLD_PWD_NOT_MATCH("60002", "현재 비밀번호가 일치 하지 않습니다."), + PWD_NOT_MATCH("60003", "비밀번호가 일치 하지 않습니다."), + EMAIL_VALIDATE_ERR("60004", "정상적인 이메일이 아닙니다."), + + /*결재관련*/ + PASS_APPR_TWO_PERSON("70001", "전결이 두명이상 될수 없습니다."), + PASS_APPR_MANIPULATE_DATA("70002", "변경 대상자 정보가 변조 되었습니다."), + + /*파일 관련*/ + FILE_NOT_FOUND_ERROR("80000", "파일이 존재 하지 않습니다."), + FILE_EXT_UPLOAD_ERROR("80001", "허용되지 않은 확장자 입니다."), + FILE_UPLOAD_ERROR("80002", "파일이 정상적이지 않습니다. 확인해주세요"), + FILE_DELETE_ERROR("80003", "파일 삭제중 오류가 발생했습니다. 확인해주세요"), + FILE_DOWNLOAD_ERROR("80004", "파일 다운로드에 실패 했습니다."), + FILE_REQUIRED("80005", "첨부파일은 필수 항목입니다."), + + NO_SIGNAL("90000", "응답 코드가 없습니다."); + + private final String code; + private final String body; +} diff --git a/src/main/java/com/kospo/svcm/config/filter/AuthenticationFilter.java b/src/main/java/com/kospo/svcm/config/filter/AuthenticationFilter.java new file mode 100644 index 0000000..1831c25 --- /dev/null +++ b/src/main/java/com/kospo/svcm/config/filter/AuthenticationFilter.java @@ -0,0 +1,34 @@ +package com.kospo.svcm.config.filter; + +import com.kospo.svcm.service.UserService; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import lombok.RequiredArgsConstructor; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.web.filter.OncePerRequestFilter; + +import java.io.IOException; + +@Configuration +@RequiredArgsConstructor +public class AuthenticationFilter extends OncePerRequestFilter { + private final UserService userService; + + + @Override + protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { + Authentication auth = SecurityContextHolder.getContext().getAuthentication(); + /*sso 로그인 추가*/ + filterChain.doFilter(request, response); + } + + private static String decodeCredentials(String credentials) { + + return new String(java.util.Base64.getDecoder().decode(credentials.getBytes())); + } + +} diff --git a/src/main/java/com/kospo/svcm/config/filter/CustomBasicAuthenticationFilter.java b/src/main/java/com/kospo/svcm/config/filter/CustomBasicAuthenticationFilter.java new file mode 100644 index 0000000..f277b57 --- /dev/null +++ b/src/main/java/com/kospo/svcm/config/filter/CustomBasicAuthenticationFilter.java @@ -0,0 +1,174 @@ +package com.kospo.svcm.config.filter; + +import com.kospo.svcm.config.exception.ErrorCode; +import com.kospo.svcm.config.jwt.JwtUtil; +import com.kospo.svcm.exception.*; +import com.kospo.svcm.model.Business; +import com.kospo.svcm.model.User; +import com.kospo.svcm.repository.UserRepository; +import com.kospo.svcm.service.BusinessService; +import io.jsonwebtoken.ExpiredJwtException; +import io.jsonwebtoken.MalformedJwtException; +import io.jsonwebtoken.io.DecodingException; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; + +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.context.SecurityContext; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.security.web.AuthenticationEntryPoint; +import org.springframework.security.web.authentication.WebAuthenticationDetailsSource; +import org.springframework.security.web.authentication.www.BasicAuthenticationFilter; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class CustomBasicAuthenticationFilter extends BasicAuthenticationFilter { + private UserRepository userRepository; + private JwtUtil jwtUtil; + private BusinessService businessService; + + public CustomBasicAuthenticationFilter(AuthenticationManager authenticationManager, UserRepository userRepository, JwtUtil jwtUtil, BusinessService businessService) { + super(authenticationManager); + this.jwtUtil = jwtUtil; + this.businessService = businessService; + this.userRepository = userRepository; + } + + + @Override + protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException { + final String requestTokenHeader = request.getHeader("Authorization"); + boolean isAnonymous = false; + String sabun = null; + String jwtToken = null; + + if (requestTokenHeader == null) { + jakarta.servlet.http.HttpSession session = request.getSession(); + User user = (User) session.getAttribute("user"); + + String sso_sabun = ""; + boolean isSso = true; + + sso_sabun = request.getHeader("sabun"); + + try { + if (sso_sabun == null || sso_sabun.isEmpty()) { + sso_sabun = "psn14020"; +// sso_sabun = request.getHeader("Authentication"); + +// if (sso_sabun != null) sso_sabun = CryptoUtil.decrypt(sso_sabun); + } + } catch (Exception e) { + new RuntimeException(e); + } + + + + isSso = sso_sabun == null || sso_sabun.equals(""); + + if (!isSso) user = null; + + + /* SSO 인증 부분 */ + if (user == null) { + /*sso 인증 개발시 header 정보에 사번 추가 하여 테스트*/ + user = userRepository.findBySabun(sso_sabun); + + Authentication authentication = null; + List mergedAuth = new ArrayList<>(); + mergedAuth.addAll(Arrays.asList(new SimpleGrantedAuthority("ROLE_USER"))); + + if (user.getAuthorities().size() != 0 ) { + user.getAuthorities().stream().forEach(auth -> mergedAuth.add(new SimpleGrantedAuthority(auth.toString()))); + } + + authentication = new UsernamePasswordAuthenticationToken(user, null, mergedAuth); + + SecurityContext securityContext = SecurityContextHolder.createEmptyContext(); + securityContext.setAuthentication(authentication); + SecurityContextHolder.setContext(securityContext); + SecurityContextHolder.getContext().getAuthentication(); + session.setAttribute("user", user); + + } else { + Authentication getAuth = SecurityContextHolder.getContext().getAuthentication(); + if (getAuth == null) { + Authentication authentication = null; + if (user.getAuthorities() == null) { + authentication = new UsernamePasswordAuthenticationToken(user, null, Arrays.asList(new SimpleGrantedAuthority("ROLE_DEFAULT"))); + } else { + authentication = new UsernamePasswordAuthenticationToken(user, null, user.getAuthorities()); + } + SecurityContext securityContext = SecurityContextHolder.createEmptyContext(); + securityContext.setAuthentication(authentication); + SecurityContextHolder.setContext(securityContext); + SecurityContextHolder.getContext().getAuthentication(); + } + } + isAnonymous = true; + chain.doFilter(request, response); + SecurityContextHolder.clearContext(); + } else if(requestTokenHeader != null && requestTokenHeader.startsWith("Bearer")) { + jwtToken = requestTokenHeader.substring(7); + try { + sabun = jwtUtil.extractUserName(jwtToken); + } catch(ExpiredJwtException e) { + System.out.println(e.getMessage()); + throw new CustomExpireTokenException(e.getMessage()); + } catch (DecodingException e) { + System.out.println(e.getMessage()); + throw new CustomNoMatchTokenException(e.getMessage()); + } catch(MalformedJwtException e) { + System.out.println(e.getMessage()); + throw new CustomMalformedJwtException(e.getMessage()); + } + + if(!isAnonymous) { + Business business = null; + + if(sabun != null) { + + try { + business = businessService.findById(sabun); + } catch(UsernameNotFoundException e) { + throw new CustomNoResultException(ErrorCode.NO_RESULT.getBody()); + } + + if(jwtUtil.validateToken(jwtToken, business)) { + jwtUtil.extendAccessToken(jwtToken); + jwtUtil.extendRefreshToken(business.getRefreshToken()); + UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(business, null, business.getAuthorities()); + usernamePasswordAuthenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request)); + SecurityContext securityContext = SecurityContextHolder.createEmptyContext(); + securityContext.setAuthentication(usernamePasswordAuthenticationToken); + SecurityContextHolder.setContext(securityContext); + SecurityContextHolder.getContext().getAuthentication(); + chain.doFilter(request, response); + SecurityContextHolder.clearContext(); + } + } else { + throw new CustomNoAccountException(ErrorCode.NO_ACCOUNT.getBody()); + } + } + } + + } + + public CustomBasicAuthenticationFilter(AuthenticationManager authenticationManager) { + super(authenticationManager); + } + + public CustomBasicAuthenticationFilter(AuthenticationManager authenticationManager, AuthenticationEntryPoint authenticationEntryPoint) { + super(authenticationManager, authenticationEntryPoint); + } +} + diff --git a/src/main/java/com/kospo/svcm/config/filter/LoggingFilter.java b/src/main/java/com/kospo/svcm/config/filter/LoggingFilter.java new file mode 100644 index 0000000..4642753 --- /dev/null +++ b/src/main/java/com/kospo/svcm/config/filter/LoggingFilter.java @@ -0,0 +1,18 @@ +package com.kospo.svcm.config.filter; + +import ch.qos.logback.classic.spi.ILoggingEvent; +import ch.qos.logback.core.filter.Filter; +import ch.qos.logback.core.spi.FilterReply; + +public class LoggingFilter extends Filter { + @Override + public FilterReply decide(ILoggingEvent iLoggingEvent) { + if(iLoggingEvent.getMessage().contains("locale")) { + return FilterReply.DENY; + } else { + return FilterReply.ACCEPT; + } + } +} + + diff --git a/src/main/java/com/kospo/svcm/config/filter/SecurityExceptionFilter.java b/src/main/java/com/kospo/svcm/config/filter/SecurityExceptionFilter.java new file mode 100644 index 0000000..502dde7 --- /dev/null +++ b/src/main/java/com/kospo/svcm/config/filter/SecurityExceptionFilter.java @@ -0,0 +1,104 @@ +package com.kospo.svcm.config.filter; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.kospo.svcm.config.exception.CustomErrorResponse; +import com.kospo.svcm.config.exception.ErrorCode; +import com.kospo.svcm.exception.*; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import org.springframework.web.filter.OncePerRequestFilter; + +import java.io.IOException; + +public class SecurityExceptionFilter extends OncePerRequestFilter { + @Override + protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws IOException { + ObjectMapper om = new ObjectMapper(); + try { + filterChain.doFilter(request, response); + } catch (CustomExpireTokenException e) { + response.setStatus(500); + response.setContentType("application/json;charset=utf-8"); + response.getWriter().println( + om.writeValueAsString(CustomErrorResponse.builder() + .code(ErrorCode.EXPIRE_TOKEN.getCode()) + .body(ErrorCode.EXPIRE_TOKEN.getBody()) + .errTime(System.currentTimeMillis()).build()) + ); + } catch (CustomNoAccountException e) { + response.setStatus(500); + response.setContentType("application/json;charset=utf-8"); + response.getWriter().println( + om.writeValueAsString(CustomErrorResponse.builder() + .code(ErrorCode.NO_ACCOUNT.getCode()) + .body(ErrorCode.NO_ACCOUNT.getBody()) + .errTime(System.currentTimeMillis()).build()) + ); + } catch (CustomNoMatchTokenException e) { + response.setStatus(500); + response.setContentType("application/json;charset=utf-8"); + response.getWriter().println( + om.writeValueAsString(CustomErrorResponse.builder() + .code(ErrorCode.NO_MATCH_TOKEN.getCode()) + .body(ErrorCode.NO_MATCH_TOKEN.getBody()) + .errTime(System.currentTimeMillis()).build()) + ); + } catch (CustomNoResultException e) { + response.setStatus(500); + response.setContentType("application/json;charset=utf-8"); + response.getWriter().println( + om.writeValueAsString(CustomErrorResponse.builder() + .code(ErrorCode.NO_RESULT.getCode()) + .body(ErrorCode.NO_RESULT.getBody()) + .errTime(System.currentTimeMillis()).build()) + ); + } catch (CustomNoTokenException e) { + response.setStatus(500); + response.setContentType("application/json;charset=utf-8"); + response.getWriter().println( + om.writeValueAsString(CustomErrorResponse.builder() + .code(ErrorCode.NO_TOKEN.getCode()) + .body(ErrorCode.NO_TOKEN.getBody()) + .errTime(System.currentTimeMillis()).build()) + ); + } catch (ServletException e) { + response.setStatus(500); + response.setContentType("application/json;charset=utf-8"); + response.getWriter().println( + om.writeValueAsString(CustomErrorResponse.builder() + .code(ErrorCode.INTERNAL_SERVER_ERROR.getCode()) + .body(ErrorCode.INTERNAL_SERVER_ERROR.getBody()) + .errTime(System.currentTimeMillis()).build()) + ); + } catch (IOException e) { + response.setStatus(500); + response.setContentType("application/json;charset=utf-8"); + response.getWriter().println( + om.writeValueAsString(CustomErrorResponse.builder() + .code(ErrorCode.INTERNAL_SERVER_ERROR.getCode()) + .body(ErrorCode.INTERNAL_SERVER_ERROR.getBody()) + .errTime(System.currentTimeMillis()).build()) + ); + } catch (CustomMalformedJwtException e) { + response.setStatus(500); + response.setContentType("application/json;charset=utf-8"); + response.getWriter().println( + om.writeValueAsString(CustomErrorResponse.builder() + .code(ErrorCode.MALFORMED_JWT.getCode()) + .body(ErrorCode.MALFORMED_JWT.getBody()) + .errTime(System.currentTimeMillis()).build()) + ); + } catch (CustomNoSameIpException e) { + response.setStatus(500); + response.setContentType("application/json;charset=utf-8"); + response.getWriter().println( + om.writeValueAsString(CustomErrorResponse.builder() + .code(ErrorCode.NO_SAME_IP.getCode()) + .body(ErrorCode.NO_SAME_IP.getBody()) + .errTime(System.currentTimeMillis()).build()) + ); + } + } +} diff --git a/src/main/java/com/kospo/svcm/config/jasypt/JasyptConfigAES.java b/src/main/java/com/kospo/svcm/config/jasypt/JasyptConfigAES.java new file mode 100644 index 0000000..8e00e55 --- /dev/null +++ b/src/main/java/com/kospo/svcm/config/jasypt/JasyptConfigAES.java @@ -0,0 +1,33 @@ +package com.kospo.svcm.config.jasypt; + +import com.ulisesbocchio.jasyptspringboot.annotation.EnableEncryptableProperties; +import org.jasypt.encryption.StringEncryptor; +import org.jasypt.encryption.pbe.PooledPBEStringEncryptor; +import org.jasypt.encryption.pbe.config.SimpleStringPBEConfig; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +@EnableEncryptableProperties +public class JasyptConfigAES { + @Value("${jasypt.encryptor.key}") + private String key; + + @Bean("jasyptEncryptorAES") + public StringEncryptor stringEncryptor() { + PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor(); + SimpleStringPBEConfig config = new SimpleStringPBEConfig(); + + config.setPassword(key); // 암호화키 + config.setAlgorithm("PBEWITHHMACSHA512ANDAES_256"); // 알고리즘 + config.setKeyObtentionIterations("1000"); // 반복할 해싱 회수 + config.setPoolSize("1"); // 인스턴스 pool + config.setProviderName("SunJCE"); + config.setSaltGeneratorClassName("org.jasypt.salt.RandomSaltGenerator"); // salt 생성 클래스 + config.setIvGeneratorClassName("org.jasypt.iv.RandomIvGenerator"); + config.setStringOutputType("base64"); //인코딩 방식 + encryptor.setConfig(config); + return encryptor; + } +} diff --git a/src/main/java/com/kospo/svcm/config/jwt/JwtRequestFilter.java b/src/main/java/com/kospo/svcm/config/jwt/JwtRequestFilter.java new file mode 100644 index 0000000..3a30203 --- /dev/null +++ b/src/main/java/com/kospo/svcm/config/jwt/JwtRequestFilter.java @@ -0,0 +1,84 @@ +package com.kospo.svcm.config.jwt; + +import com.kospo.svcm.config.exception.ErrorCode; +import com.kospo.svcm.exception.CustomExpireTokenException; +import com.kospo.svcm.exception.CustomMalformedJwtException; +import com.kospo.svcm.exception.CustomNoMatchTokenException; +import com.kospo.svcm.exception.CustomNoResultException; +import com.kospo.svcm.model.Business; +import com.kospo.svcm.service.BusinessService; +import io.jsonwebtoken.ExpiredJwtException; +import io.jsonwebtoken.MalformedJwtException; +import io.jsonwebtoken.io.DecodingException; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import lombok.RequiredArgsConstructor; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.security.web.authentication.WebAuthenticationDetailsSource; +import org.springframework.web.filter.OncePerRequestFilter; + +import java.io.IOException; + +@RequiredArgsConstructor +public class JwtRequestFilter extends OncePerRequestFilter { + private final JwtUtil jwtUtil; + private final BusinessService businessService; + @Override + protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { + final String requestTokenHeader = request.getHeader("Authorization"); + boolean isAnonymous = false; + String sabun = null; + String jwtToken = null; + if(requestTokenHeader != null && requestTokenHeader.startsWith("Bearer")) { + jwtToken = requestTokenHeader.substring(7); + try { + sabun = jwtUtil.extractUserName(jwtToken); + } catch(ExpiredJwtException e) { + System.out.println(e.getMessage()); + throw new CustomExpireTokenException(e.getMessage()); + } catch (DecodingException e) { + System.out.println(e.getMessage()); + throw new CustomNoMatchTokenException(e.getMessage()); + } catch(MalformedJwtException e) { + System.out.println(e.getMessage()); + throw new CustomMalformedJwtException(e.getMessage()); + } + } else { + System.out.println("noToken"); + isAnonymous = true; + } + + if(!isAnonymous) { + Business business = null; + + if(sabun != null && SecurityContextHolder.getContext().getAuthentication() == null) { + + try { + business = businessService.findById(sabun); + } catch(UsernameNotFoundException e) { + throw new CustomNoResultException(ErrorCode.NO_RESULT.getBody()); + } + + if(jwtUtil.validateToken(jwtToken, business)) { + + UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(business, null, business.getAuthorities()); + usernamePasswordAuthenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request)); + SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken); + } + } else { +// throw new CustomNoAccountException(ErrorCode.NO_ACCOUNT.getBody()); + } + } + + +// String ip = jwtUtil.extractIp(jwtToken); +// if(!CommonUtils.getClientIp(request).equals(ip)) { +// throw new CustomNoSameIpException(ErrorCode.NO_SAME_IP.getBody()); +// } + filterChain.doFilter(request, response); + } +} diff --git a/src/main/java/com/kospo/svcm/config/jwt/JwtUtil.java b/src/main/java/com/kospo/svcm/config/jwt/JwtUtil.java new file mode 100644 index 0000000..fafd3f9 --- /dev/null +++ b/src/main/java/com/kospo/svcm/config/jwt/JwtUtil.java @@ -0,0 +1,166 @@ +package com.kospo.svcm.config.jwt; + + +import com.kospo.svcm.config.exception.ErrorCode; +import com.kospo.svcm.config.utils.CommonUtils; +import com.kospo.svcm.exception.CustomException; +import com.kospo.svcm.model.Business; +import com.kospo.svcm.dto.res.TokenResponse; +import io.jsonwebtoken.*; +import jakarta.servlet.http.HttpServletRequest; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; +import org.springframework.web.context.request.RequestAttributes; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import java.util.Date; +import java.util.HashMap; +import java.util.Map; +import java.util.function.Function; + +@Component +public class JwtUtil { + @Value("${jwt.key}") + private String SECRET_KEY; + + /* 토큰 사용자이름을 추출한다. */ + public String extractUserName(String token) { + return extractClaim(token, Claims::getSubject); + } + /* 토큰 IP을 추출한다. */ + public String extractIp(String token) { + return extractClaim(token, claims -> (String)claims.get("ip")); + } + + /* 토큰 만료시간을 추출한다. */ + public Date extractExpirationDate(String token) { + return extractClaim(token, Claims::getExpiration); + } + + + /* 토큰 정보를 추출한다. */ + private T extractClaim(String token, Function claimsResolver) { + final Claims claims = extractAllClaims(token); + return claimsResolver.apply(claims); + } + + /* 토큰 모든 정보를 추출한다. */ + private Claims extractAllClaims(String token) { + return Jwts.parserBuilder().setSigningKey(SECRET_KEY).build().parseClaimsJws(token).getBody(); + } + + /* 토큰 만료여부 확인. */ + private Boolean isTokenExpired(String token) { + return extractExpirationDate(token).before(new Date()); + } + + /* 토큰 엑서스 토큰을 생성한다. */ + public String generateAccessToken(Business business, Date expired) { + RequestAttributes reqAttr = RequestContextHolder.getRequestAttributes(); + ServletRequestAttributes servlReqAttr = (ServletRequestAttributes)reqAttr; + HttpServletRequest req = servlReqAttr.getRequest(); + Map claims = new HashMap<>(); + claims.put("bizNo", business.getBizNo()); + claims.put("ip", CommonUtils.getClientIp(req)); + return createAccessToken(claims, business.getBizNo(), expired); + } + + /* 토큰 엑서스 토큰을 생성한다. */ + private String createAccessToken(Map claims, String subject, Date expired) { + return Jwts.builder().setClaims(claims).setSubject(subject) + .setIssuedAt(new Date(System.currentTimeMillis())) + .setExpiration(expired) // 5minutes + .signWith(SignatureAlgorithm.HS256, SECRET_KEY).compact(); + } + + /* 토큰 리플래쉬토큰을 생성한다. */ + public String generateRefreshToken(Business business, Date expired) { + return createRefreshToken(business.getBizNo(), expired); + } + + /* 토큰 리플래쉬토큰을 생성한다. */ + private String createRefreshToken(String subject, Date expired) { + return Jwts.builder().setSubject(subject) + .setIssuedAt(new Date(System.currentTimeMillis())) + .setExpiration(expired) // 30minutes + .signWith(SignatureAlgorithm.HS256, SECRET_KEY).compact(); + } + + + /* 토큰 생성(엑서스, 리플레시) 동시 생성. */ + public TokenResponse generateToken(Business business) { + return TokenResponse.builder() + .accessToken(generateAccessToken(business, getAccessDate())) + .accessTokenExpired(getAccessDate().getTime()) + .refreshToken(generateRefreshToken(business, getRefreshDate())) + .refreshTokenExpired(getRefreshDate().getTime()) + .bid(business.getBizNo()).build(); + } + + /* 토큰 리플레쉬토큰으로 엑서스토큰을 재발급한다. */ + public TokenResponse renewalToken(String accessToken, Business business) { + if(validateToken(accessToken, business)) { + Claims claims = extractAllClaims(accessToken); + return TokenResponse.builder() + .accessToken(generateAccessToken(business, getAccessDate())) + .accessTokenExpired(getAccessDate().getTime()) + .refreshToken(accessToken) + .refreshTokenExpired(claims.getExpiration().getTime()) + .bid(business.getBizNo()).build(); + } else { + throw new CustomException(ErrorCode.EXPIRE_TOKEN); + } + } + + /*토큰 정보로 jws 정보를 맵핑한다..*/ + private Jws parseToken(String token) { + return Jwts.parserBuilder().setSigningKey(SECRET_KEY).build().parseClaimsJws(token); + } + + /* 토큰 리플레시토큰 만료기간을 연장한다. */ + public TokenResponse extendRefreshToken(String refreshToken) { + Date refreshDate = getRefreshDate(); + Jws jws = parseToken(refreshToken); + jws.getBody().setExpiration(refreshDate).getSubject(); + return TokenResponse.builder() + .refreshToken(refreshToken) + .refreshTokenExpired(refreshDate.getTime()).build(); + } + + + + /* 토큰 액세스토큰 만료기간을 연장한다. */ + public TokenResponse extendAccessToken(String AccessToken) { + Date accessDate = getAccessDate(); + Jws jws = parseToken(AccessToken); + jws.getBody().setExpiration(accessDate).getSubject(); + return TokenResponse.builder() + .accessToken(AccessToken) + .accessTokenExpired(accessDate.getTime()).build(); + } + + + + + /* 토큰 만료 여부 확인. */ + public Boolean validateToken(String token, Business business) { + try { + final String username = extractUserName(token); + return (username.equals(business.getBizNo()) && !isTokenExpired(token)); + } catch(ExpiredJwtException e) { + return false; + } + + } + + /*리플레시토큰 만료기간 생성 30분*/ + private Date getRefreshDate() { + return new Date(System.currentTimeMillis() + (1000 * 60 * 60 * 4)); + } + + /*엑서스토큰 만료기간 생성 5분*/ + private Date getAccessDate() { + return new Date(System.currentTimeMillis() + (1000 * 60 * 30)); + } +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/config/schedule/PrcsSchedule.java b/src/main/java/com/kospo/svcm/config/schedule/PrcsSchedule.java new file mode 100644 index 0000000..fe14068 --- /dev/null +++ b/src/main/java/com/kospo/svcm/config/schedule/PrcsSchedule.java @@ -0,0 +1,52 @@ +package com.kospo.svcm.config.schedule; + +import com.kospo.svcm.config.utils.CommonUtils; +import com.kospo.svcm.model.CodeId; +import com.kospo.svcm.repository.CodeRepository; +import com.kospo.svcm.repository.PrcsRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.context.annotation.Configuration; +import org.springframework.scheduling.annotation.EnableScheduling; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; + +@Component +@RequiredArgsConstructor +public class PrcsSchedule { + private final PrcsRepository prcsRepository; + private final CodeRepository codeRepository; + + /*가격조사 등록기간 만료 자동 완료 처리 로직*/ + @Scheduled(cron = "0 1 0 * * *") + public void SurveyAutoClose() { + System.out.println("come"); + prcsRepository.findBySvyYn(false).stream().forEach(prc -> { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + try { + Date endDt = sdf.parse(prc.getRegEdat()); + Date nowDt = new Date(); + if(endDt.getTime() < nowDt.getTime()) { + System.out.println("종료"); + System.out.println(prc.getPrcsNo()); + System.out.println(prc.getTitle()); + System.out.println("***********************************"); + prc.setSvyYn(true); + prc.setSvyDt(CommonUtils.dateFormat("yyyy-MM-dd HH:mm:ss")); + prc.setStCd("0200"); + prc.setStNm(codeRepository.findById(CodeId.builder() + .cd("0200") + .id(1) + .build()).get().getNm()); + prcsRepository.save(prc); + } + } catch (ParseException e) { + throw new RuntimeException(e); + } + + }); + } +} diff --git a/src/main/java/com/kospo/svcm/config/security/PasswordEncoder.java b/src/main/java/com/kospo/svcm/config/security/PasswordEncoder.java new file mode 100644 index 0000000..cb48a90 --- /dev/null +++ b/src/main/java/com/kospo/svcm/config/security/PasswordEncoder.java @@ -0,0 +1,40 @@ +package com.kospo.svcm.config.security; + +import org.postgresql.shaded.com.ongres.scram.common.bouncycastle.pbkdf2.SHA256Digest; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.codec.Hex; +import org.springframework.security.crypto.password.*; +import org.springframework.security.crypto.scrypt.SCryptPasswordEncoder; + +import java.nio.charset.StandardCharsets; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.HashMap; +import java.util.Map; + +public class PasswordEncoder { + + public String sha256Encoding(String password) { + String encPassword = ""; + MessageDigest digest = null; + try { + digest = MessageDigest.getInstance("SHA-256"); + byte[] hash = digest.digest(password.getBytes(StandardCharsets.UTF_8)); + encPassword = new String(Hex.encode(hash)); + return encPassword; + } catch (NoSuchAlgorithmException e) { + throw new RuntimeException(e); + } + + } + + public boolean matches(String passwd1, String passwd2) { + if(passwd2.equals(sha256Encoding(passwd1))) { + return true; + } else { + return false; + } + } +} diff --git a/src/main/java/com/kospo/svcm/config/security/SecurityConfig.java b/src/main/java/com/kospo/svcm/config/security/SecurityConfig.java new file mode 100644 index 0000000..d7cd4a3 --- /dev/null +++ b/src/main/java/com/kospo/svcm/config/security/SecurityConfig.java @@ -0,0 +1,117 @@ +package com.kospo.svcm.config.security; + +import com.kospo.svcm.config.filter.CustomBasicAuthenticationFilter; +import com.kospo.svcm.config.filter.SecurityExceptionFilter; +import com.kospo.svcm.config.jwt.JwtUtil; +import com.kospo.svcm.repository.UserRepository; +import com.kospo.svcm.service.BusinessService; +import com.kospo.svcm.service.UserService; +import jakarta.servlet.http.HttpServletRequest; +import lombok.RequiredArgsConstructor; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer; +import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.core.session.SessionRegistry; +import org.springframework.security.core.session.SessionRegistryImpl; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.web.SecurityFilterChain; +import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; +import org.springframework.security.web.authentication.session.RegisterSessionAuthenticationStrategy; +import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy; +import org.springframework.web.cors.CorsConfiguration; +import org.springframework.web.cors.CorsConfigurationSource; + +import java.util.List; + +@Configuration +@EnableWebSecurity +@EnableGlobalMethodSecurity(prePostEnabled = true) +@RequiredArgsConstructor +public class SecurityConfig { + private final UserService userService; + private final JwtUtil jwtUtil; + private final BusinessService businessService; + + @Bean + public SecurityFilterChain securityFilterChain(HttpSecurity http, + UserRepository userRepository) throws Exception { + http + .authorizeHttpRequests(authorizationManagerRequestMatcherRegistry -> authorizationManagerRequestMatcherRegistry + .requestMatchers("/admin*").hasRole("ADMIN") + .anyRequest().authenticated() + ) + .csrf(AbstractHttpConfigurer::disable) + .formLogin(httpSecurityFormLoginConfigurer -> httpSecurityFormLoginConfigurer.disable()) + .addFilterBefore(new CustomBasicAuthenticationFilter(authenticationManager(), userRepository, jwtUtil, businessService), UsernamePasswordAuthenticationFilter.class) +// .addFilterBefore(new SecurityExceptionFilter(), JwtRequestFilter.class) + .addFilterBefore(new SecurityExceptionFilter(), CustomBasicAuthenticationFilter.class) + .headers(httpSecurityHeadersConfigurer -> httpSecurityHeadersConfigurer.frameOptions(frameOptionsConfig -> frameOptionsConfig.disable())) + .sessionManagement(httpSecuritySessionManagementConfigurer -> + httpSecuritySessionManagementConfigurer + .maximumSessions(1) + .sessionRegistry(sessionRegistry()) + ) + .cors(httpSecurityCorsConfigurer -> httpSecurityCorsConfigurer.configurationSource(new CorsConfigurationSource() { + @Override + public CorsConfiguration getCorsConfiguration(HttpServletRequest request) { + CorsConfiguration config = new CorsConfiguration(); +// String origin = request.getHeader("Origin"); + config.setAllowCredentials(true); + config.setAllowedOrigins(List.of("http://localhost:3000", "http://hmsn.ink:3000", "http://hmsn.ink:8010", "http://hmsn.ink", "https://svcm.hmsn.ink", "http://182.227.15.92:3000")); + config.setAllowedMethods(List.of("POST","GET","DELETE","PUT","OPTIONS")); + config.setAllowedHeaders(List.of("*")); + config.setExposedHeaders(List.of("*")); + return config; + } + })); + return http.build(); + } + + private String getEncoding (String str) { + BCryptPasswordEncoder b = new BCryptPasswordEncoder(); + return b.encode(str); + } + + @Bean + public SessionRegistry sessionRegistry() { + return new SessionRegistryImpl(); + } + + + @Bean + public AuthenticationManager authenticationManager() { + AuthenticationManager manager = new AuthenticationManager() { + @Override + public Authentication authenticate(Authentication authentication) throws AuthenticationException { + return authentication; + } + }; + return manager; + } + + + /*특정 url 필터 제외 처리*/ + @Bean + public WebSecurityCustomizer webSecurityCustomizer() { + return (web) -> web.ignoring().requestMatchers( + "/api/login", "/api/register", "/api/token/valid", "/css/**", "/images/**", "/js/**", "/pages/**" + // -- Swagger UI v2 + , "/v2/api-docs/**", "/swagger-resources/**", "/v3/api-docs/**" + , "/swagger-ui/**", "/swagger/**", "/api-docs/**" + ); + } + + + @Bean + public SessionAuthenticationStrategy sessionAuthenticationStrategy() { + return new RegisterSessionAuthenticationStrategy(sessionRegistry()); + } +} + diff --git a/src/main/java/com/kospo/svcm/config/security/SecurityWebInitializer.java b/src/main/java/com/kospo/svcm/config/security/SecurityWebInitializer.java new file mode 100644 index 0000000..56c569a --- /dev/null +++ b/src/main/java/com/kospo/svcm/config/security/SecurityWebInitializer.java @@ -0,0 +1,6 @@ +package com.kospo.svcm.config.security; + +import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer; + +public class SecurityWebInitializer extends AbstractSecurityWebApplicationInitializer { +} diff --git a/src/main/java/com/kospo/svcm/config/swagger/SwaggerConfig.java b/src/main/java/com/kospo/svcm/config/swagger/SwaggerConfig.java new file mode 100644 index 0000000..ef417bf --- /dev/null +++ b/src/main/java/com/kospo/svcm/config/swagger/SwaggerConfig.java @@ -0,0 +1,49 @@ +package com.kospo.svcm.config.swagger; + +import io.swagger.v3.oas.models.Components; +import io.swagger.v3.oas.models.OpenAPI; +import io.swagger.v3.oas.models.info.Info; +import io.swagger.v3.oas.models.security.SecurityRequirement; +import io.swagger.v3.oas.models.security.SecurityScheme; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class SwaggerConfig { + private final String JWTSCHEMENAME = "jwtAuth"; + private SecurityRequirement securityRequirement = new SecurityRequirement().addList(JWTSCHEMENAME); + + @Bean + public OpenAPI openAPI() { +// return new OpenAPI() +// .info(apiInfo()) +// .components(new Components().addSecuritySchemes("basicScheme", new SecurityScheme() +// .type(SecurityScheme.Type.HTTP).scheme("basic"))); +// } + + return new OpenAPI() + .info(apiInfo()) + .addSecurityItem(securityRequirement) + .components(new Components() + .addSecuritySchemes(JWTSCHEMENAME, new SecurityScheme() + .name(JWTSCHEMENAME) + .type(SecurityScheme.Type.HTTP) + .scheme("bearer") + .bearerFormat("JWT") + .name("Authentication")) + .addSecuritySchemes("custom-header", new SecurityScheme() + .type(SecurityScheme.Type.APIKEY) + .in(SecurityScheme.In.HEADER) + .name("sabun"))) + .addSecurityItem(new SecurityRequirement().addList("custom-header")); + } + + + + private Info apiInfo() { + return new Info() + .title("소액계약거래") + .description("소액계약거래 api") + .version("1.0.0"); + } +} diff --git a/src/main/java/com/kospo/svcm/config/utils/CommonUtils.java b/src/main/java/com/kospo/svcm/config/utils/CommonUtils.java new file mode 100644 index 0000000..a862639 --- /dev/null +++ b/src/main/java/com/kospo/svcm/config/utils/CommonUtils.java @@ -0,0 +1,177 @@ +package com.kospo.svcm.config.utils; + +import com.kospo.svcm.model.Code; +import jakarta.servlet.http.HttpServletRequest; +import lombok.extern.slf4j.Slf4j; +import org.springframework.data.domain.Sort; + +import javax.xml.bind.DatatypeConverter; +import java.io.*; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.*; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.stream.Collectors; + + +@Slf4j +public class CommonUtils { + private static HashMap>> listenings; + + public CommonUtils() { + + } + + public static String getClientIp(HttpServletRequest request) { + String ip = ""; + ip = request.getHeader("X-FORWARDED-FOR"); + if (ip == null) { + ip = request.getHeader("Proxy-Client-IP"); + log.info("Proxy-Client-IP : " + ip); + } + if (ip == null) { + ip = request.getHeader("WL-Proxy-Client-IP"); + log.info("WL-Proxy-Client-IP : " + ip); + } + if (ip == null) { + ip = request.getHeader("HTTP_CLIENT_IP"); + log.info("HTTP_CLIENT_IP : " + ip); + } + if (ip == null) { + ip = request.getHeader("HTTP_X_FORWARDED_FOR"); + log.info("HTTP_X_FORWARDED_FOR : " + ip); + } + if (ip == null) { + ip = request.getRemoteAddr(); + log.info("getRemoteAddr : "+ip); + } + log.info("Result : IP Address : "+ip); + return ip; + } + + public static Sort convertSort(String field) { + String[] propertyAndDirection = field.split(","); + if(propertyAndDirection.length == 1) propertyAndDirection = field.split(" "); + String property = propertyAndDirection[0]; + Sort.Direction direction = Sort.DEFAULT_DIRECTION; + if(propertyAndDirection.length > 1) { + String directionString = propertyAndDirection[1]; + direction = Sort.Direction.fromOptionalString(directionString) + .orElse(Sort.DEFAULT_DIRECTION); + } + Sort.Order order = new Sort.Order(direction, property); + return Sort.by(order); + } + + + public static String dateFormat(Date setDate, String pattern) { + SimpleDateFormat sdf = new SimpleDateFormat(pattern); + return sdf.format(setDate); + } + + + public static String dateFormat(String pattern) { + SimpleDateFormat sdf = new SimpleDateFormat(pattern); + return sdf.format(new Date()); + } + + public static Date plusDays(Date dt, int day) { + Calendar cal = Calendar.getInstance(); + cal.setTime(dt); + cal.add(Calendar.DAY_OF_MONTH, day); + + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + System.out.println(sdf.format(cal.getTime())); + return cal.getTime(); + } + + public static String stringToPlusYear(String str, int year) { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + Date dt = null; + try { + dt = sdf.parse(str); + } catch (ParseException e) { + throw new RuntimeException(e); + } + Calendar cal = Calendar.getInstance(); + cal.setTime(dt); + cal.add(Calendar.YEAR, year); + + SimpleDateFormat result = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + return result.format(cal.getTime()); + } + + public static Date stringToDate(String dd) { + SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd"); + Date result = null; + try { + result = sdf.parse(dd); + System.out.println(sdf.format(result)); + } catch (ParseException e) { + throw new RuntimeException(e); + } + return result; + } + + public static String generateFileName() { + LocalDateTime now = LocalDateTime.now(); + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSSSSSS"); + String datePart = now.format(formatter); + String uniquePart = UUID.randomUUID().toString().substring(0, 8); + return datePart + "_" + uniquePart; + } + + public static boolean checkAllowExt(String fileNm) { + String fileExtNm = ""; + List allowList = Arrays.asList("pdf"); + + fileExtNm = fileNm.toLowerCase().substring(fileNm.toLowerCase().lastIndexOf(".") + 1); + fileExtNm = fileExtNm.toLowerCase(); + + String allows = allowList.stream().map((str) -> str).collect(Collectors.joining(",")); + + return allows.contains(fileExtNm); + } + + public static Date epochToDate(long epoch) { + return new Date(epoch); + } + + public static String epochToString(long epoch, String pattern) { + Date expiry = new Date(epoch); + SimpleDateFormat sdf = new SimpleDateFormat(pattern); + return sdf.format(expiry); + } + + public static String getNo(String prefix, int seq) { + return prefix+String.format("%010d", seq); + } + + public static String getSapNo(int seq) { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy"); + String year = sdf.format(new Date()); + return "FI"+ year +"9" + String.format("%05d", seq); + } + + public static String getEstNo(String estNo) { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy"); + String year = sdf.format(new Date()); + return estNo+year+"1000"; + } + + public static String getDateNo(String prefix, int seq) { + SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd"); + return prefix+ sdf.format(new Date()) +String.format("%03d", seq); + } + + public static String getCodeNm(List list, String cd) { + Optional optionalCode = list.stream().filter(c -> c.getId().getCd().equals(cd)).findFirst(); + if(optionalCode.isEmpty()) { + return ""; + } else { + return optionalCode.get().getNm(); + } + } +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/config/utils/CryptoUtil.java b/src/main/java/com/kospo/svcm/config/utils/CryptoUtil.java new file mode 100644 index 0000000..a43bd38 --- /dev/null +++ b/src/main/java/com/kospo/svcm/config/utils/CryptoUtil.java @@ -0,0 +1,89 @@ +package com.kospo.svcm.config.utils; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Configurable; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.core.io.ClassPathResource; +import org.springframework.core.io.Resource; +import org.springframework.core.io.ResourceLoader; +import org.springframework.util.FileCopyUtils; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.security.*; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.RSAKeyGenParameterSpec; +import java.security.spec.X509EncodedKeySpec; +import java.util.Base64; + +public class CryptoUtil { + + public static String encrypt(String plainText) throws Exception { + Cipher cipher = Cipher.getInstance("RSA"); + cipher.init(Cipher.ENCRYPT_MODE, loadPublicKey()); + byte[] encryptedBytes = cipher.doFinal(plainText.getBytes()); + return Base64.getEncoder().encodeToString(encryptedBytes); + } + + public static String decrypt(String encryptText) throws Exception { + encryptText = encryptText.replaceAll(" ", "+"); + Cipher cipher = Cipher.getInstance("RSA"); + cipher.init(Cipher.DECRYPT_MODE, loadPrivateKey()); + byte[] decryptBytes = cipher.doFinal(Base64.getDecoder().decode(encryptText)); + return new String(decryptBytes); + } + + private static PublicKey loadPublicKey() throws NoSuchAlgorithmException, InvalidKeySpecException, IOException { + ClassPathResource resource = new ClassPathResource("public.key"); + byte[] keyBytes = FileCopyUtils.copyToByteArray(resource.getInputStream()); + X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes); + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + return keyFactory.generatePublic(spec); + } + + private static PrivateKey loadPrivateKey() throws NoSuchAlgorithmException, InvalidKeySpecException, IOException { + ClassPathResource resource = new ClassPathResource("private.key"); + byte[] keyBytes = FileCopyUtils.copyToByteArray(resource.getInputStream()); + PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes); + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + return keyFactory.generatePrivate(spec); + } + + private static byte[] readKeyFromFile(String fileName) { + File file = new File(fileName); + byte[] keyBytes = new byte[(int) file.length()]; + try(FileInputStream fis = new FileInputStream(file)) { + fis.read(keyBytes); + } catch (IOException e) { + throw new RuntimeException(e); + } + + return keyBytes; + } + + private static void saveKeyToFile(String fileName, byte[] keyBytes) { + File file = new File(fileName); + try(FileOutputStream fos = new FileOutputStream(file)) { + fos.write(keyBytes); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + public static void main(String[] args) { +// System.out.println(encrypt("psn14020")); +// KeyPairGenerator keygen = KeyPairGenerator.getInstance("RSA"); +// keygen.initialize(new RSAKeyGenParameterSpec(2048, RSAKeyGenParameterSpec.F4)); +// KeyPair pair = keygen.generateKeyPair(); +// +// saveKeyToFile("C:\\Users\\psn14020\\IdeaProjects\\talk\\src\\main\\resources\\private.key", pair.getPrivate().getEncoded()); +// saveKeyToFile("C:\\Users\\psn14020\\IdeaProjects\\talk\\src\\main\\resources\\public.key", pair.getPublic().getEncoded()); + } +} diff --git a/src/main/java/com/kospo/svcm/config/utils/ExcelUtils.java b/src/main/java/com/kospo/svcm/config/utils/ExcelUtils.java new file mode 100644 index 0000000..038abc3 --- /dev/null +++ b/src/main/java/com/kospo/svcm/config/utils/ExcelUtils.java @@ -0,0 +1,58 @@ +package com.kospo.svcm.config.utils; + +import com.kospo.svcm.dto.res.DtlSpecExcelResponse; +import lombok.RequiredArgsConstructor; +import org.apache.poi.ss.usermodel.*; +import org.springframework.stereotype.Component; + +import javax.xml.bind.DatatypeConverter; +import java.io.ByteArrayInputStream; +import java.io.FileInputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; + +@Component +@RequiredArgsConstructor +public class ExcelUtils { + public List dtlSpecExcel(String base64) { + ByteArrayInputStream bias = null; + try { + List DtlSpecExcelResponses = new ArrayList<>(); + byte[] data = DatatypeConverter.parseBase64Binary(base64); + bias = new ByteArrayInputStream(data); + Workbook workbook = WorkbookFactory.create(bias); + Sheet sheet = workbook.getSheetAt(0); + for(Row row : sheet) { + if(row.getRowNum() != 0) { + AtomicInteger cellCount = new AtomicInteger(0); + DtlSpecExcelResponse DtlSpecExcelResponse = new DtlSpecExcelResponse(); + for(Cell cell : row) { + if(cellCount.get() == 0) { + DtlSpecExcelResponse.setItemNm(cell.getStringCellValue()); + } else if(cellCount.get() == 1) { + DtlSpecExcelResponse.setSpec(cell.getStringCellValue()); + } else if(cellCount.get() == 2) { + DtlSpecExcelResponse.setUnit(cell.getStringCellValue()); + } else if(cellCount.get() == 3) { + DtlSpecExcelResponse.setQty((int) cell.getNumericCellValue()); + } + cellCount.incrementAndGet(); + + } + DtlSpecExcelResponses.add(DtlSpecExcelResponse); + } + } + return DtlSpecExcelResponses; + } catch(Exception e) { + throw new RuntimeException(e); + } finally { + try { + bias.close(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + } +} diff --git a/src/main/java/com/kospo/svcm/config/utils/FileUtils.java b/src/main/java/com/kospo/svcm/config/utils/FileUtils.java new file mode 100644 index 0000000..c968093 --- /dev/null +++ b/src/main/java/com/kospo/svcm/config/utils/FileUtils.java @@ -0,0 +1,70 @@ +package com.kospo.svcm.config.utils; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.stereotype.Component; + +import javax.xml.bind.DatatypeConverter; +import java.awt.image.BufferedImage; +import java.io.*; + +@Component +public class FileUtils { + + public synchronized boolean fileUpload(String full, String base64) { + boolean result = false; + File file = new File(full); + + BufferedOutputStream bos = null; + + try { + byte[] data = DatatypeConverter.parseBase64Binary(base64); + bos = new BufferedOutputStream(new FileOutputStream(file)); + bos.write(data); + bos.flush(); + result = true; + } catch (FileNotFoundException e) { + throw new RuntimeException(e); + } catch (IOException e) { + throw new RuntimeException(e); + } finally { + if (bos != null) { + try { + bos.close(); + } catch (IOException ex) { + throw new RuntimeException(ex); + } + } + } + return result; + } + + public synchronized boolean fileDelete(String full) { + File file = new File(full); + if(!file.exists()) { + return false; + } else { + file.delete(); + return true; + } + } + + public synchronized byte[] fileRead(String full) { + File file = new File(full); + if(file.exists()) { + BufferedImage originalImage = null; + FileInputStream fis = null; + + try { + fis = new FileInputStream(file); + + return fis.readAllBytes(); + } catch (FileNotFoundException e) { + throw new RuntimeException(e); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + return null; + } +} diff --git a/src/main/java/com/kospo/svcm/config/utils/MailUtils.java b/src/main/java/com/kospo/svcm/config/utils/MailUtils.java new file mode 100644 index 0000000..546c33f --- /dev/null +++ b/src/main/java/com/kospo/svcm/config/utils/MailUtils.java @@ -0,0 +1,32 @@ +package com.kospo.svcm.config.utils; + +import jakarta.mail.internet.MimeMessage; +import lombok.RequiredArgsConstructor; +import org.springframework.context.annotation.Configuration; +import org.springframework.mail.javamail.JavaMailSender; +import org.springframework.mail.javamail.JavaMailSenderImpl; +import org.springframework.mail.javamail.MimeMessageHelper; +import org.springframework.stereotype.Component; + +import javax.mail.MessagingException; + +@Component +@RequiredArgsConstructor +public class MailUtils { +// private final JavaMailSender mailSender; + public Boolean sendMail(String from, String to, String subject, String text) { + JavaMailSender mailSender = new JavaMailSenderImpl(); + MimeMessage mimeMessage = mailSender.createMimeMessage(); + try { + MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, false, "UTF-8"); + mimeMessageHelper.setTo(to); + mimeMessageHelper.setFrom(from); + mimeMessageHelper.setSubject(subject); + mimeMessageHelper.setText(text); + mailSender.send(mimeMessage); + return true; + } catch (Exception e) { + return false; + } + } +} diff --git a/src/main/java/com/kospo/svcm/config/utils/SequenceUtils.java b/src/main/java/com/kospo/svcm/config/utils/SequenceUtils.java new file mode 100644 index 0000000..811d2ee --- /dev/null +++ b/src/main/java/com/kospo/svcm/config/utils/SequenceUtils.java @@ -0,0 +1,20 @@ +package com.kospo.svcm.config.utils; + +import com.kospo.svcm.model.Sequence; +import com.kospo.svcm.repository.SequenceRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.context.annotation.Configuration; + +@Configuration +@RequiredArgsConstructor +public class SequenceUtils { + private final SequenceRepository sequenceRepository; + + public Integer findSeqAfterUpdate(String seqNm) { + Sequence sequence = sequenceRepository.findById(seqNm).get(); + long nextVal = sequence.getNextVal() + 1; + sequence.setNextVal(nextVal); + sequenceRepository.save(sequence); + return Math.toIntExact(nextVal); + } +} diff --git a/src/main/java/com/kospo/svcm/config/utils/XmlUtils.java b/src/main/java/com/kospo/svcm/config/utils/XmlUtils.java new file mode 100644 index 0000000..8a373f1 --- /dev/null +++ b/src/main/java/com/kospo/svcm/config/utils/XmlUtils.java @@ -0,0 +1,42 @@ +package com.kospo.svcm.config.utils; + +import jakarta.xml.bind.JAXBContext; +import jakarta.xml.bind.JAXBException; +import jakarta.xml.bind.Marshaller; +import jakarta.xml.bind.Unmarshaller; +import org.springframework.context.annotation.Configuration; + +import javax.xml.bind.DatatypeConverter; +import java.awt.image.BufferedImage; +import java.io.*; + +@Configuration +public class XmlUtils { + + public Object xmlToModel(String xml , Class cla) throws JAXBException, IOException, NoSuchMethodException { + ByteArrayInputStream bais = new ByteArrayInputStream(xml.getBytes()); + JAXBContext jaxbContext = JAXBContext.newInstance(cla); + Unmarshaller unmarshaller = jaxbContext.createUnmarshaller(); + + Object obj = unmarshaller.unmarshal(bais); + + bais.close(); + return obj; + } + + public String modelToXml(Object obj) throws JAXBException, IOException { + JAXBContext jaxbContext = JAXBContext.newInstance(obj.getClass()); + Marshaller marshaller = jaxbContext.createMarshaller(); + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + + marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); + marshaller.marshal(obj, baos); + + String list = baos.toString(); + + baos.close(); + + return list; + } +} diff --git a/src/main/java/com/kospo/svcm/controller/ApprController.java b/src/main/java/com/kospo/svcm/controller/ApprController.java new file mode 100644 index 0000000..9f6a18a --- /dev/null +++ b/src/main/java/com/kospo/svcm/controller/ApprController.java @@ -0,0 +1,101 @@ +package com.kospo.svcm.controller; + +import com.kospo.svcm.config.exception.CustomErrorResponse; +import com.kospo.svcm.dto.req.ApprReqRequest; +import com.kospo.svcm.dto.res.ApprMstResponse; +import com.kospo.svcm.dto.res.ApprReqResponse; +import com.kospo.svcm.dto.res.PageResponse; +import com.kospo.svcm.dto.res.PrcsResponse; +import com.kospo.svcm.repository.ApprReqRepository; +import com.kospo.svcm.service.ApprService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.ArraySchema; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.data.web.PagedResourcesAssembler; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.security.Principal; +import java.util.List; + +@Tag(name = "Approval Api", description = "결재 관리") +@RestController +@RequiredArgsConstructor +@RequestMapping("/api") +public class ApprController { + private final ApprService apprService; + + @Operation(summary = "가격조사 결재 상세 조회", description = "가격조사 결재 조회") + @ApiResponses({ + @ApiResponse(description = "Success", responseCode = "200", + content = @Content(mediaType = "application/json", schema = @Schema(oneOf = + {ApprMstResponse.class}) + )), + @ApiResponse(description = "Not found", responseCode = "404", + content = @Content(mediaType = "text/plain", schema = @Schema(oneOf = + {String.class}))), + @ApiResponse(description = "Internal Error", responseCode = "500", + content = @Content(mediaType = "application/json", schema = @Schema(oneOf = + {CustomErrorResponse.class }))) + }) + @GetMapping("/appr/{prcsNo}") + public ResponseEntity findSearch( + @Parameter(description = "가격조사번호") @PathVariable(required = false) String prcsNo + ) { + + return ResponseEntity.ok(apprService.findByPrcsNo(prcsNo)); + } + +// @Operation(summary = "본인 결재목록 조회", description = "가격조사 결재 조회") +// @ApiResponses({ +// @ApiResponse(description = "Success", responseCode = "200", +// content = @Content(mediaType = "application/json", schema = @Schema(oneOf = +// {PageResponse.class}) +// )), +// @ApiResponse(description = "Not found", responseCode = "404", +// content = @Content(mediaType = "text/plain", schema = @Schema(oneOf = +// {String.class}))), +// @ApiResponse(description = "Internal Error", responseCode = "500", +// content = @Content(mediaType = "application/json", schema = @Schema(oneOf = +// {CustomErrorResponse.class }))) +// }) +// @GetMapping("/appr/req") +// public ResponseEntity findReq( +// @Parameter(description = "page") @RequestParam("page") int page, +// @Parameter(description = "row") @RequestParam("row") int row, +// Principal principal +// ) { +// Pageable pageable = PageRequest.of(page -1, row); +// return ResponseEntity.ok(apprService.findByApprBySabun(principal.getName(), pageable)); +// } + + @Operation(summary = "가격조사 결재 상태변경", description = "결재 상태변경 (결재승인 0200 결재반려 0400)") + @ApiResponses({ + @ApiResponse(description = "Success", responseCode = "200", + content = @Content(mediaType = "application/json", schema = @Schema(oneOf = + {ApprMstResponse.class}))), + @ApiResponse(description = "Not found", responseCode = "404", + content = @Content(mediaType = "text/plain", schema = @Schema(oneOf = + {String.class}))), + @ApiResponse(description = "Internal Error", responseCode = "500", + content = @Content(mediaType = "application/json", schema = @Schema(oneOf = + {CustomErrorResponse.class }))) + }) + @PutMapping("/appr") + public ResponseEntity save( + @RequestBody ApprReqRequest apprReqRequest, + Principal principal + ) { + return ResponseEntity.ok(apprService.stateUpdate(principal.getName(), apprReqRequest)); + } + +} diff --git a/src/main/java/com/kospo/svcm/controller/BusinessController.java b/src/main/java/com/kospo/svcm/controller/BusinessController.java new file mode 100644 index 0000000..2022eea --- /dev/null +++ b/src/main/java/com/kospo/svcm/controller/BusinessController.java @@ -0,0 +1,176 @@ +package com.kospo.svcm.controller; + +import com.kospo.svcm.config.exception.CustomErrorResponse; +import com.kospo.svcm.config.exception.ErrorCode; +import com.kospo.svcm.dto.req.BusinessRePasswdRequest; +import com.kospo.svcm.dto.req.BusinessUpdateRequest; +import com.kospo.svcm.dto.req.RegisterRequest; +import com.kospo.svcm.dto.res.BusinessResponse; +import com.kospo.svcm.exception.CustomException; +import com.kospo.svcm.service.BusinessService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.ArraySchema; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.security.Principal; + +@Tag(name = "Business Api", description = "사업자 관리") +@RestController +@RequiredArgsConstructor +@RequestMapping("/api") +public class BusinessController { + private final BusinessService businessService; + + @Operation(summary = "사업자 조회", description = "전체 조회") + @ApiResponses({ + @ApiResponse(description = "Success", responseCode = "200", + content = @Content(mediaType = "application/json", array = @ArraySchema( + schema = @Schema(oneOf = + {BusinessResponse.class}) + ))), + @ApiResponse(description = "Not found", responseCode = "404", + content = @Content(mediaType = "text/plain", schema = @Schema(oneOf = + {String.class}))), + @ApiResponse(description = "Internal Error", responseCode = "500", + content = @Content(mediaType = "application/json", schema = @Schema(oneOf = + {CustomErrorResponse.class }))) + }) + @GetMapping("/business") + public ResponseEntity findAll() { + return ResponseEntity.ok(businessService.findAll()); + } + + @Operation(summary = "사업자 개인 조회", description = "개인 조회") + @ApiResponses({ + @ApiResponse(description = "Success", responseCode = "200", + content = @Content(mediaType = "application/json", array = @ArraySchema( + schema = @Schema(oneOf = + {BusinessResponse.class}) + ))), + @ApiResponse(description = "Not found", responseCode = "404", + content = @Content(mediaType = "text/plain", schema = @Schema(oneOf = + {String.class}))), + @ApiResponse(description = "Internal Error", responseCode = "500", + content = @Content(mediaType = "application/json", schema = @Schema(oneOf = + {CustomErrorResponse.class }))) + }) + @GetMapping("/business/me") + public ResponseEntity findById( + Principal principal + ) { + return ResponseEntity.ok(businessService.findMe(principal.getName())); + } + + + + @Operation(summary = "회원가입", description = "사업자 회원가입 한다.") + @ApiResponses({ + @ApiResponse(description = "Success", responseCode = "200", + content = @Content(mediaType = "application/json", schema = @Schema(oneOf = + {BusinessResponse.class }))), + @ApiResponse(description = "Not found", responseCode = "404", + content = @Content(mediaType = "text/plain", schema = @Schema(oneOf = + {String.class}))), + @ApiResponse(description = "Internal Error", responseCode = "500", + content = @Content(mediaType = "application/json", schema = @Schema(oneOf = + {CustomErrorResponse.class }))) + }) + @PostMapping("/business") + public ResponseEntity register(@RequestBody RegisterRequest registerRequest) { + return ResponseEntity.ok(businessService.register(registerRequest)); + } + + @Operation(summary = "회원정보 수정", description = "사업자 정보 수정") + @ApiResponses({ + @ApiResponse(description = "Success", responseCode = "200", + content = @Content(mediaType = "application/json", schema = @Schema(oneOf = + {BusinessResponse.class }))), + @ApiResponse(description = "Not found", responseCode = "404", + content = @Content(mediaType = "text/plain", schema = @Schema(oneOf = + {String.class}))), + @ApiResponse(description = "Internal Error", responseCode = "500", + content = @Content(mediaType = "application/json", schema = @Schema(oneOf = + {CustomErrorResponse.class }))) + }) + @PutMapping("/business") + public ResponseEntity update( + @RequestBody BusinessUpdateRequest businessUpdateRequest, + Principal principal + ) { + return ResponseEntity.ok(businessService.update(principal.getName(), businessUpdateRequest)); + } + + @Operation(summary = "비밀번호 변경", description = "사업자 비밀번호 변경") + @ApiResponses({ + @ApiResponse(description = "Success", responseCode = "200", + content = @Content(mediaType = "application/json", schema = @Schema(oneOf = + {BusinessResponse.class }))), + @ApiResponse(description = "Not found", responseCode = "404", + content = @Content(mediaType = "text/plain", schema = @Schema(oneOf = + {String.class}))), + @ApiResponse(description = "Internal Error", responseCode = "500", + content = @Content(mediaType = "application/json", schema = @Schema(oneOf = + {CustomErrorResponse.class }))) + }) + @PutMapping("/business/password") + public ResponseEntity rePassword( + @RequestBody BusinessRePasswdRequest businessRePasswdRequest, + Principal principal + ) { + return ResponseEntity.ok(businessService.rePassword(principal.getName(), businessRePasswdRequest)); + } + + @Operation(summary = "회원탈퇴", description = "사업자 회원 탈퇴") + @ApiResponses({ + @ApiResponse(description = "Success", responseCode = "200", + content = @Content(mediaType = "application/json", schema = @Schema(oneOf = + {String.class }))), + @ApiResponse(description = "Not found", responseCode = "404", + content = @Content(mediaType = "text/plain", schema = @Schema(oneOf = + {String.class}))), + @ApiResponse(description = "Internal Error", responseCode = "500", + content = @Content(mediaType = "application/json", schema = @Schema(oneOf = + {CustomErrorResponse.class }))) + }) + @DeleteMapping("/business/{bizNo}") + public ResponseEntity delete( + @Parameter(description = "사업자번호") @PathVariable String bizNo, + Principal principal + ) { + if(principal.getName().equals(bizNo)) { + businessService.delete(principal.getName(), bizNo); + return ResponseEntity.ok("삭제 되었습니다."); + } else { + throw new CustomException(ErrorCode.AUTHENTICATION); + } + + } + + @Operation(summary = "개인정보 만료 체크", description = "보유기간 만료된 사용자 휴면 계정으로 전환") + @ApiResponses({ + @ApiResponse(description = "Success", responseCode = "200", + content = @Content(mediaType = "application/json", schema = @Schema(oneOf = + {String.class }))), + @ApiResponse(description = "Not found", responseCode = "404", + content = @Content(mediaType = "text/plain", schema = @Schema(oneOf = + {String.class}))), + @ApiResponse(description = "Internal Error", responseCode = "500", + content = @Content(mediaType = "application/json", schema = @Schema(oneOf = + {CustomErrorResponse.class }))) + }) + @GetMapping("/business/privary") + public ResponseEntity privacy( + Principal principal + ) { + businessService.privacy(); + return ResponseEntity.ok(""); + } +} diff --git a/src/main/java/com/kospo/svcm/controller/CodeController.java b/src/main/java/com/kospo/svcm/controller/CodeController.java new file mode 100644 index 0000000..83d7fa4 --- /dev/null +++ b/src/main/java/com/kospo/svcm/controller/CodeController.java @@ -0,0 +1,260 @@ +package com.kospo.svcm.controller; + +import com.kospo.svcm.config.exception.CustomErrorResponse; +import com.kospo.svcm.dto.req.CodeRequest; +import com.kospo.svcm.dto.req.GrpCodeSaveRequest; +import com.kospo.svcm.dto.req.GrpCodeUpdateRequest; +import com.kospo.svcm.dto.res.CodeResponse; +import com.kospo.svcm.dto.res.GrpCodeResponse; +import com.kospo.svcm.dto.res.PageResponse; +import com.kospo.svcm.service.CodeService; +import com.kospo.svcm.service.GrpCodeService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.ArraySchema; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; + +@Tag(name = "Code Api", description = "코드 관리") +@RestController +@RequiredArgsConstructor +@RequestMapping("/api") +public class CodeController { + private final CodeService codeService; + private final GrpCodeService grpCodeService; + + @Operation(summary = "그룹코드 조회 (페이징)", description = "전체 조회") + @ApiResponses({ + @ApiResponse(description = "Success", responseCode = "200", + content = @Content(mediaType = "application/json", schema = @Schema(oneOf = + {PageResponse.class}) + )), + @ApiResponse(description = "Not found", responseCode = "404", + content = @Content(mediaType = "text/plain", schema = @Schema(oneOf = + {String.class}))), + @ApiResponse(description = "Internal Error", responseCode = "500", + content = @Content(mediaType = "application/json", schema = @Schema(oneOf = + {CustomErrorResponse.class }))) + }) + @GetMapping("/grpCode/page") + @PreAuthorize("hasRole('ADMIN')") + public ResponseEntity findGrpCodePage( + @Parameter(description = "nm") @RequestParam(value = "nm", required = false, defaultValue = "") String nm, + @Parameter(description = "useYn") @RequestParam(value = "useYn", required = false) boolean useYn, + @Parameter(description = "page") @RequestParam("page") int page, + @Parameter(description = "row") @RequestParam("row") int row + ) { + Pageable pageable = PageRequest.of(page -1, row); + return ResponseEntity.ok(grpCodeService.findSearch(nm, useYn, pageable)); + } + + @Operation(summary = "그룹코드 조회", description = "전체 조회") + @ApiResponses({ + @ApiResponse(description = "Success", responseCode = "200", + content = @Content(mediaType = "application/json", array = @ArraySchema( + schema = @Schema(oneOf = + {GrpCodeResponse.class}) + ))), + @ApiResponse(description = "Not found", responseCode = "404", + content = @Content(mediaType = "text/plain", schema = @Schema(oneOf = + {String.class}))), + @ApiResponse(description = "Internal Error", responseCode = "500", + content = @Content(mediaType = "application/json", schema = @Schema(oneOf = + {CustomErrorResponse.class }))) + }) + @GetMapping("/grpCode") + @PreAuthorize("hasRole('ADMIN')") + public ResponseEntity findGrpCode( + @Parameter(description = "nm") @RequestParam(value = "nm", required = false, defaultValue = "") String nm, + @Parameter(description = "useYn") @RequestParam(value = "useYn", required = false) boolean useYn + ) { + return ResponseEntity.ok(grpCodeService.findSearch(nm, useYn)); + } + + @Operation(summary = "그룹코드 저장", description = "그룹코드 저장") + @ApiResponses({ + @ApiResponse(description = "Success", responseCode = "200", + content = @Content(mediaType = "application/json", schema = @Schema(oneOf = + {GrpCodeResponse.class}) + )), + @ApiResponse(description = "Not found", responseCode = "404", + content = @Content(mediaType = "text/plain", schema = @Schema(oneOf = + {String.class}))), + @ApiResponse(description = "Internal Error", responseCode = "500", + content = @Content(mediaType = "application/json", schema = @Schema(oneOf = + {CustomErrorResponse.class }))) + }) + @PostMapping("/grpCode") + @PreAuthorize("hasRole('ADMIN')") + public ResponseEntity saveRole( + @RequestBody GrpCodeSaveRequest grpCodeDto + ) { + ; + return ResponseEntity.ok(grpCodeService.save(grpCodeDto)); + } + + @Operation(summary = "그룹코드 수정", description = "그룹코드 수정") + @ApiResponses({ + @ApiResponse(description = "Success", responseCode = "200", + content = @Content(mediaType = "application/json", schema = @Schema(oneOf = + {GrpCodeResponse.class}) + )), + @ApiResponse(description = "Not found", responseCode = "404", + content = @Content(mediaType = "text/plain", schema = @Schema(oneOf = + {String.class}))), + @ApiResponse(description = "Internal Error", responseCode = "500", + content = @Content(mediaType = "application/json", schema = @Schema(oneOf = + {CustomErrorResponse.class }))) + }) + @PutMapping("/grpCode") + @PreAuthorize("hasRole('ADMIN')") + public ResponseEntity updRole( + @RequestBody GrpCodeUpdateRequest grpCodeRequest + ) { + + return ResponseEntity.ok(grpCodeService.update(grpCodeRequest)); + } + + @Operation(summary = "그룹코드 삭제", description = "그룹코드 삭제") + @ApiResponses({ + @ApiResponse(description = "Success", responseCode = "200", + content = @Content(mediaType = "application/json", schema = @Schema(oneOf = + {String.class}) + )), + @ApiResponse(description = "Not found", responseCode = "404", + content = @Content(mediaType = "text/plain", schema = @Schema(oneOf = + {String.class}))), + @ApiResponse(description = "Internal Error", responseCode = "500", + content = @Content(mediaType = "application/json", schema = @Schema(oneOf = + {CustomErrorResponse.class }))) + }) + @DeleteMapping("/grpCode/{id}") + @PreAuthorize("hasRole('ADMIN')") + public ResponseEntity delRole( + @Parameter(description = "아이디") @PathVariable("id") Integer id + ) { + grpCodeService.delete(id); + return ResponseEntity.ok("삭제 되었습니다."); + } + + @Operation(summary = "특정 코드 조회", description = "코드 조회") + @ApiResponses({ + @ApiResponse(description = "Success", responseCode = "200", + content = @Content(mediaType = "application/json", array = @ArraySchema( + schema = @Schema(oneOf = + {CodeResponse.class}) + ))), + @ApiResponse(description = "Not found", responseCode = "404", + content = @Content(mediaType = "text/plain", schema = @Schema(oneOf = + {String.class}))), + @ApiResponse(description = "Internal Error", responseCode = "500", + content = @Content(mediaType = "application/json", schema = @Schema(oneOf = + {CustomErrorResponse.class }))) + }) + @GetMapping("/code/{id}") + public ResponseEntity findSpecificCode( + @Parameter(description = "그룹 아이디") @PathVariable int id + ) { + return ResponseEntity.ok(codeService.findSpecificCode(id)); + } + + + @Operation(summary = "코드 조회", description = "코드 조회") + @ApiResponses({ + @ApiResponse(description = "Success", responseCode = "200", + content = @Content(mediaType = "application/json", array = @ArraySchema( + schema = @Schema(oneOf = + {CodeResponse.class}) + ))), + @ApiResponse(description = "Not found", responseCode = "404", + content = @Content(mediaType = "text/plain", schema = @Schema(oneOf = + {String.class}))), + @ApiResponse(description = "Internal Error", responseCode = "500", + content = @Content(mediaType = "application/json", schema = @Schema(oneOf = + {CustomErrorResponse.class }))) + }) + @GetMapping("/code") + @PreAuthorize("hasRole('ADMIN')") + public ResponseEntity findCode( + @Parameter(description = "useYn") @RequestParam(value = "useYn", required = false) boolean useYn, + @Parameter(description = "page") @RequestParam("page") int page, + @Parameter(description = "row") @RequestParam("row") int row + ) { + Pageable pageable = PageRequest.of(page -1, row); + return ResponseEntity.ok(codeService.findSearch(useYn, pageable)); + } + + @Operation(summary = "코드 추가", description = "코드 저장") + @ApiResponses({ + @ApiResponse(description = "Success", responseCode = "200", + content = @Content(mediaType = "application/json", schema = @Schema(oneOf = + {CodeResponse.class}) + )), + @ApiResponse(description = "Not found", responseCode = "404", + content = @Content(mediaType = "text/plain", schema = @Schema(oneOf = + {String.class}))), + @ApiResponse(description = "Internal Error", responseCode = "500", + content = @Content(mediaType = "application/json", schema = @Schema(oneOf = + {CustomErrorResponse.class }))) + }) + @PostMapping("/code") + @PreAuthorize("hasRole('ADMIN')") + public ResponseEntity saveCode( + @RequestBody CodeRequest codeRequest + ) { + ; + return ResponseEntity.ok(codeService.save(codeRequest)); + } + + @Operation(summary = "코드 수정", description = "코드 수정") + @ApiResponses({ + @ApiResponse(description = "Success", responseCode = "200", + content = @Content(mediaType = "application/json", schema = @Schema(oneOf = + {CodeResponse.class}) + )), + @ApiResponse(description = "Not found", responseCode = "404", + content = @Content(mediaType = "text/plain", schema = @Schema(oneOf = + {String.class}))), + @ApiResponse(description = "Internal Error", responseCode = "500", + content = @Content(mediaType = "application/json", schema = @Schema(oneOf = + {CustomErrorResponse.class }))) + }) + @PutMapping("/code") + @PreAuthorize("hasRole('ADMIN')") + public ResponseEntity updCode( + @RequestBody CodeRequest codeRequest + ) { + return ResponseEntity.ok(codeService.update(codeRequest)); + } + + @Operation(summary = "코드 삭제", description = "코드 삭제") + @ApiResponses({ + @ApiResponse(description = "Success", responseCode = "200", + content = @Content(mediaType = "application/json", schema = @Schema(oneOf = + {String.class}) + )), + @ApiResponse(description = "Not found", responseCode = "404", + content = @Content(mediaType = "text/plain", schema = @Schema(oneOf = + {String.class}))), + @ApiResponse(description = "Internal Error", responseCode = "500", + content = @Content(mediaType = "application/json", schema = @Schema(oneOf = + {CustomErrorResponse.class }))) + }) + @DeleteMapping("/code") + @PreAuthorize("hasRole('ADMIN')") + public ResponseEntity delCode( + @RequestBody CodeRequest codeRequest + ) { + codeService.delete(codeRequest.getId(), codeRequest.getCd()); + return ResponseEntity.ok("삭제 되었습니다."); + } +} diff --git a/src/main/java/com/kospo/svcm/controller/ContController.java b/src/main/java/com/kospo/svcm/controller/ContController.java new file mode 100644 index 0000000..a44e91a --- /dev/null +++ b/src/main/java/com/kospo/svcm/controller/ContController.java @@ -0,0 +1,140 @@ +package com.kospo.svcm.controller; + +import com.kospo.svcm.config.exception.CustomErrorResponse; +import com.kospo.svcm.dto.req.ContSaveRequest; +import com.kospo.svcm.dto.res.ContListResponse; +import com.kospo.svcm.dto.res.ContSaveResponse; +import com.kospo.svcm.dto.res.PrcsResponse; +import com.kospo.svcm.service.ContService; +import com.kospo.svcm.service.PrcsService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.ArraySchema; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.security.Principal; + +@Tag(name = "Contract Api", description = "계약 관리") +@RestController +@RequiredArgsConstructor +@RequestMapping("/api") +public class ContController { + private final ContService contService; + private final PrcsService prcsService; + + @Operation(summary = "계약관리 - 가격조사 가져오기", description = "계약관리 등록 가격조사 가져오기") + @ApiResponses({ + @ApiResponse(description = "Success", responseCode = "200", + content = @Content(mediaType = "application/json", array = @ArraySchema( + schema = @Schema(oneOf = + {PrcsResponse.class}) + ))), + @ApiResponse(description = "Not found", responseCode = "404", + content = @Content(mediaType = "text/plain", schema = @Schema(oneOf = + {String.class}))), + @ApiResponse(description = "Internal Error", responseCode = "500", + content = @Content(mediaType = "application/json", schema = @Schema(oneOf = + {CustomErrorResponse.class }))) + }) + @GetMapping("/cont/prcs") + public ResponseEntity findContTarget( + ) { + return ResponseEntity.ok(prcsService.findContTarget()); + } + + @Operation(summary = "계약관리 조회 (페이징)", description = "전체 조회") + @ApiResponses({ + @ApiResponse(description = "Success", responseCode = "200", + content = @Content(mediaType = "application/json", array = @ArraySchema( + schema = @Schema(oneOf = + {ContListResponse.class}) + ))), + @ApiResponse(description = "Not found", responseCode = "404", + content = @Content(mediaType = "text/plain", schema = @Schema(oneOf = + {String.class}))), + @ApiResponse(description = "Internal Error", responseCode = "500", + content = @Content(mediaType = "application/json", schema = @Schema(oneOf = + {CustomErrorResponse.class }))) + }) + @GetMapping("/cont/page") + public ResponseEntity findCode( + @Parameter(description = "등록상태") @RequestParam(required = false) String contStatCd, + @Parameter(description = "계약체결시작일") @RequestParam(required = false, defaultValue = "1970-01-01") String signSdt, + @Parameter(description = "계약체결종료일") @RequestParam(required = false, defaultValue = "2070-01-01") String signEdt, + @Parameter(description = "페이지") @RequestParam("page") int page, + @Parameter(description = "아이템갯수") @RequestParam("row") int row, + Principal principal + ) { + Pageable pageable = PageRequest.of(page -1, row); + return ResponseEntity.ok(contService.findPage(principal.getName(), contStatCd, signSdt, signEdt, pageable)); + } + + @Operation(summary = "계약관리 상세조회", description = "계약번호로 조회") + @ApiResponses({ + @ApiResponse(description = "Success", responseCode = "200", + content = @Content(mediaType = "application/json", schema = @Schema(oneOf = + {ContListResponse.class}) + )), + @ApiResponse(description = "Not found", responseCode = "404", + content = @Content(mediaType = "text/plain", schema = @Schema(oneOf = + {String.class}))), + @ApiResponse(description = "Internal Error", responseCode = "500", + content = @Content(mediaType = "application/json", schema = @Schema(oneOf = + {CustomErrorResponse.class }))) + }) + @GetMapping("/cont/{contNo}") + public ResponseEntity findCode( + @Parameter(description = "계약번호") @PathVariable String contNo, + Principal principal + ) { + return ResponseEntity.ok(contService.findDetail(contNo)); + } + + @Operation(summary = "계약관리 저장", description = "계약관리, 첨부파일, 전자결재 통합저장") + @ApiResponses({ + @ApiResponse(description = "Success", responseCode = "200", + content = @Content(mediaType = "application/json", schema = @Schema(oneOf = + {ContSaveResponse.class}))), + @ApiResponse(description = "Not found", responseCode = "404", + content = @Content(mediaType = "text/plain", schema = @Schema(oneOf = + {String.class}))), + @ApiResponse(description = "Internal Error", responseCode = "500", + content = @Content(mediaType = "application/json", schema = @Schema(oneOf = + {CustomErrorResponse.class }))) + }) + @PostMapping("/cont") + public ResponseEntity save( + @RequestBody ContSaveRequest contSaveRequest + ) { + return ResponseEntity.ok(contService.save(contSaveRequest)); + } + + @Operation(summary = "계약관리 회수 처리", description = "결재진행중인건에 대한 회수 처리") + @ApiResponses({ + @ApiResponse(description = "Success", responseCode = "200", + content = @Content(mediaType = "application/json", schema = @Schema(oneOf = + {PrcsResponse.class}))), + @ApiResponse(description = "Not found", responseCode = "404", + content = @Content(mediaType = "text/plain", schema = @Schema(oneOf = + {String.class}))), + @ApiResponse(description = "Internal Error", responseCode = "500", + content = @Content(mediaType = "application/json", schema = @Schema(oneOf = + {CustomErrorResponse.class }))) + }) + @PutMapping("/cont/ret/{contNo}") + public ResponseEntity retrieve( + @Parameter(description = "계약번호") @PathVariable String contNo, + Principal principal + ) { + return ResponseEntity.ok(contService.retrieve(contNo)); + } +} diff --git a/src/main/java/com/kospo/svcm/controller/DtlSpecController.java b/src/main/java/com/kospo/svcm/controller/DtlSpecController.java new file mode 100644 index 0000000..b03524d --- /dev/null +++ b/src/main/java/com/kospo/svcm/controller/DtlSpecController.java @@ -0,0 +1,53 @@ +package com.kospo.svcm.controller; + +import com.kospo.svcm.config.exception.CustomErrorResponse; +import com.kospo.svcm.dto.req.ContSaveRequest; +import com.kospo.svcm.dto.req.DtlSpecExcelRequest; +import com.kospo.svcm.dto.res.ContSaveResponse; +import com.kospo.svcm.dto.res.DtlSpecExcelResponse; +import com.kospo.svcm.dto.res.DtlSpecResponse; +import com.kospo.svcm.service.DtlSpecService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.ArraySchema; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@Tag(name = "DtlSpec Api", description = "상세규격") +@RestController +@RequiredArgsConstructor +@RequestMapping("/api") +public class DtlSpecController { + private final DtlSpecService dtlSpecService; + + @Operation(summary = "상세규격 엑셀업로드", description = "엑셀파일 업로드 모델로 반환 sample: UEsDBBQACAgIAOMhtFoAAAAAAAAAAAAAAAAYAAAAeGwvZHJhd2luZ3MvZHJhd2luZzEueG1sndBdbsIwDAfwE+wOVd5pWhgTQxRe0E4wDuAlbhuRj8oOo9x+0Uo2aXsBHm3LP/nvzW50tvhEYhN8I+qyEgV6FbTxXSMO72+zlSg4gtdgg8dGXJDFbvu0GTWtz7ynIu17XqeyEX2Mw1pKVj064DIM6NO0DeQgppI6qQnOSXZWzqvqRfJACJp7xLifJuLqwQOaA+Pz/k3XhLY1CvdBnRz6OCGEFmL6Bfdm4KypB65RPVD8AcZ/gjOKAoc2liq46ynZSEL9PAk4/hr13chSvsrVX8jdFMcBHU/DLLlDesiHsSZevpNlRnfugbdoAx2By8i4OPjj3bEqyTa1KCtssV7ercyzIrdfUEsHCAdiaYMFAQAABwMAAFBLAwQUAAgICADjIbRaAAAAAAAAAAAAAAAAGAAAAHhsL3dvcmtzaGVldHMvc2hlZXQxLnhtbJ2V326bMBTGn2DvgLgPBgP5J6BaG1XrXVWt27ULTrCCMbJNIG8/4xA3wVkX7SbA4fu+8/PBhOShp5VzwFwQVqdu4Pmug+ucFaTepe77z+fZ0nWERHWBKlbj1D1i4T5k35KO8b0oMZaOCqhF6pZSNmsARF5iioTHGlyrO1vGKZLqku+AaDhGhTbRCkDfnwOKSO2eEtb8ngy23ZIcb1jeUlzLUwjHFZIKX5SkEec02ltxlOScCbaVXs7omKQIcoD7HGug5RUQze8hoojv22amIhtF8UEqIo+ay8QcUrfl9XrMmBmMwbNW/dcHWp3FfRDdx20NcwVWV/R9EP9fUuCDIJhERciexf1YKDdJ9L4Y80TGLZIlOvKVZwlrZUVq/Mod0VI1/OMjrliXumrjjoU3sivlUABZAoxPn/wiuBMX586wjT8Y2w8XL8WV6VL7rB+46pm3QjL6A59aBK5T4C1qK/nEqt+kkKWqQW8emvob64w49hbxEJ+zSujfMe1sdB1K6tMR9frYne5A34Nn520PHD3QeOLIC8IvPeHoCT/7BJ+Etz3R6ImMJ1h42gJOq9LT2iCJsoSzzuHaOqwehsMarPmpXoPou1IJrVVVoaqHzE/AYYgdFY+2IrhWPNkKeK3Y2IrQKIDiNdDQgEFtgReWaAJmK+IJmK2YT8DOCr0s6Pm3qUJDFVqJiwmVrVhOqGzFlCq8oILR36giQxVZiasJla2YUtmKKVV0F1VsqOJ/UtmKKZWtmFLFX1OBixej4KhTn1eHr4n6x+EvRaBfIPNFzf4AUEsHCGon2T5RAgAAlQcAAFBLAwQUAAgICADjIbRaAAAAAAAAAAAAAAAAIwAAAHhsL3dvcmtzaGVldHMvX3JlbHMvc2hlZXQxLnhtbC5yZWxzjc9LCsIwEAbgE3iHMHuT1oWINO1GhG6lHmBIpg9sHiTx0dubjaLgwuXMz3zDXzUPM7MbhTg5K6HkBTCyyunJDhLO3XG9AxYTWo2zsyRhoQhNvapONGPKN3GcfGQZsVHCmJLfCxHVSAYjd55sTnoXDKY8hkF4VBccSGyKYivCpwH1l8laLSG0ugTWLZ7+sV3fT4oOTl0N2fTjhdAB77lYJjEMlCRw/tq9w5JnFkRdia+K9RNQSwcIrajrTbMAAAAqAQAAUEsDBBQACAgIAOMhtFoAAAAAAAAAAAAAAAATAAAAeGwvdGhlbWUvdGhlbWUxLnhtbM1X227cIBD9gv4D4r3B170pu1Gym1UfWlXqtuozsfGlwdgCNmn+vhh7bXxLomYjZV8C4zOHMzPAkMurvxkFD4SLNGdraF9YEBAW5GHK4jX89XP/eQGBkJiFmOaMrOETEfBq8+kSr2RCMgKUOxMrvIaJlMUKIREoMxYXeUGY+hblPMNSTXmMQo4fFW1GkWNZM5ThlMHan7/GP4+iNCC7PDhmhMmKhBOKpZIukrQQEDCcKY2HhBAp4OYk8paS0kOUhoDyQ6CVD7DhvV3+ETy+21IOHjBdQ0v/INpcogZA5RC3178aVwPCe+clPqfiG+J6fBqAg0BFMVzbcxb+3quxBqgaDrlvrz3X9Tt4g98darm52VpdfrfFewO8610vfLeD91q8PxLrbGfZHbzf4mfDeGc3u+2sg9eghKbsfoC2bd/fbmt0A4ly+uVleItCxs6p/Jmc2kcZ/pPzvQLo4qrtyYB8KkiEA4W75immJT1eETxuD8SYHfWIs5S90yotMTID1WFn3ai/6yOpo45SSg/yiZKvQksSOU3DvTLqiXZqklwkalgv18HFHOsx4Ln8ncrkkOBCLWPrFWJRU8cCFLlQhwlOcuukHLNveXgq6+ncKQcsW7vlN3aVQllZZ/P2kDb0ehYLU4CvSV8vwlisK8IdETF3XyfCts6lYjmiYmE/pwIZVVEHBeCya/hepQiIAFMSlnWq/E/VPXulp5LZDdsZCW/pna3SHRHGduuKMLZhgkPSN5+51svleKmdURnzxXvUGg3vBsq6M/CozpzrK5oAF2sYqetMDbNC8QkWQ4BprB4ngawT/T83S8GF3GGRVDD9qYo/SyXhgKaZ2utmGShrtdnO3Pq44pbWx8sc6heZRBEJ5ISlnapvFcno1zeCy0l+VKIPSfgI7uiR/8AqUf7cLhMYpkI22QxTbmzuNou966o+iiMvPP2AoUWC645iXuYVXI8bOUYcWmk/KjSWwrt4f46u+7JT79KcaCDzyVvs/Zq8ocodV+WP3nXLhfV8l3h7QzCkLcaluePSpnrHGR8ExnKzibw5k9V8Yzfo71pkvCv1rPdP28my+QdQSwcIZaOBYSgDAACtDgAAUEsDBBQACAgIAOMhtFoAAAAAAAAAAAAAAAAUAAAAeGwvc2hhcmVkU3RyaW5ncy54bWxl0LFOwzAQBuAn4B0s79RphaoKOe6AxBPAA1jJ0ViKzyHnoLJWRQqwMXWoxAqICQYYeKImfQeMYMEZ77v/7qST86Ut2RXUZBymfDxKOAPMXG5wkfLzs9PDGWfkNea6dAgpvwbic3UgiTwLo0gpL7yvjoWgrACraeQqwNC5cLXVPpT1QlBVg86pAPC2FJMkmQqrDXKWuQZ9ODvlrEFz2cDJHyRcSTJKerV/aLuXGym8kuJHfnX3sd29Pcfa3T/123WsfbvpHm8H2dWmX73GOrOWLdmRtXED9GDBut3ffcY6ngxnu/evf0kRnqe+AVBLBwg5opJb7AAAAHoBAABQSwMEFAAICAgA4yG0WgAAAAAAAAAAAAAAAA0AAAB4bC9zdHlsZXMueG1stVTLbpwwFP2C/oPlfcbzaKMkAqIoEVU37SJTKVtjDFjxA9meFPL1vcaQYTRJk44UFmCfe33O8eXayXWnJHri1gmjU7xaLDHimplS6DrFv7f52QVGzlNdUmk0T3HPHb7OviTO95LfN5x7BAzapbjxvr0ixLGGK+oWpuUaIpWxinqY2pq41nJaurBISbJeLs+JokLjyHDVrb5SdsSjBLPGmcovmFHEVJVg/JjpklwSyiYmdUzzih1F7eOuPQPalnpRCCl8P7jCWVIZ7R1iZqd9ijcjkCXuGT1RCXVaQqFIljAjjUW2LlKc58vhCbCmisfEGyuoDNDgYwSV0MYGkETW+C7IjH/9Cn98TuaPXD6kgcAJNMPHAZ2Q8rA2AGQJFNFzq3OYoHG87VvQ0tA4kWbIeydbirrx3y3tP77EGSnK4KO+nddrc3fx7fY80BRvBciM80Vt+MA+C2NLOBjTTld4gsLCMQhl5VLeh8PwUB2kdhWKOT/KFMOpCqTTEOo4DvVO5Wqa0LaV/Q0UQCseaSKUmzgLunO5KD7T3Zym21UfNJAldAqicADhkvgVpIbFrrFCP25NLvwwh0vFCxYaqTDeG4XRH0vbLe+GcNhLV71td723u/pvu8Dxb/ONseIZ8OCOAcAtPtrQew5nBV1/RkEnfTL+5FmrHTTaC7qXDQc7xT/DXScxKnZCeqFj7KCHgLPs9u0To/ubPfsLUEsHCEAY0fIZAgAAHgYAAFBLAwQUAAgICADjIbRaAAAAAAAAAAAAAAAADwAAAHhsL3dvcmtib29rLnhtbJ2SS07DMBCGT8AdIu9bJ6igNmrSDULqBrGAA7j2pLHiR2S7Ib0CXIGDcCi4A9M0iVS6iVj5Od98sv/1ptUqasB5aU1GknlMIjDcCmn2GXl9eZwtSeQDM4IpayAjR/Bkk9+s36yrdtZWEdYbn5EyhDql1PMSNPNzW4PBk8I6zQIu3Z762gETvgQIWtHbOL6nmklDzoTUTWHYopAcHiw/aDDhDHGgWEB7X8raDzTdXuG05M56W4Q5t7onoQGn0HLohJYXQppPMdLMVYd6hsgaLXZSyXDsvEZMk5GDM2nPmI0ap5oU+6eNVsPlNllM8756zBVdXdi3yd3/SElMk+QPasGu32K6FuMjSU/DjD/SRyQf4/bsaL7u+L4fT+kMGMxGerlTQCLDNC6/Pz5/3r8SDO/p0lZgtknkUokTtxULghg6cAQU0oB4wkKP+5wp3vWhQ9f8F1BLBwhbusWcUwEAACcDAABQSwMEFAAICAgA4yG0WgAAAAAAAAAAAAAAABoAAAB4bC9fcmVscy93b3JrYm9vay54bWwucmVsc62SQWrDMBBFT9A7iNnXspNSSomcTShk26YHENLYMrElIU3a+vadNuA6EEIXXon/xfz/0Giz/Rp68YEpd8ErqIoSBHoTbOdbBe+Hl/snEJm0t7oPHhWMmGFb321esdfEM9l1MQsO8VmBI4rPUmbjcNC5CBE93zQhDZpYplZGbY66Rbkqy0eZ5hlQX2SKvVWQ9rYCcRgj/ic7NE1ncBfMaUBPVyok8SxyoE4tkoJfeTargsNAXmdYLcmQaez5DSeIs75Vv1603umE9o0SL3hOMbdvwTwsCfMZ0jE7RPoDmawfVD6mxciLH1d/A1BLBwiWGcFT6gAAALkCAABQSwMEFAAICAgA4yG0WgAAAAAAAAAAAAAAAAsAAABfcmVscy8ucmVsc43PQQ6CMBAF0BN4h2b2UnBhjKGwMSZsDR6gtkMhQKdpq8Lt7VKNC5eT+fN+pqyXeWIP9GEgK6DIcmBoFenBGgHX9rw9AAtRWi0nsihgxQB1tSkvOMmYbkI/uMASYoOAPkZ35DyoHmcZMnJo06YjP8uYRm+4k2qUBvkuz/fcvxtQfZis0QJ8owtg7erwH5u6blB4InWf0cYfFV+JJEtvMApYJv4kP96IxiyhwKuSfzxYvQBQSwcIpG+hILIAAAAoAQAAUEsDBBQACAgIAOMhtFoAAAAAAAAAAAAAAAATAAAAW0NvbnRlbnRfVHlwZXNdLnhtbLVTy07DMBD8Av4h8hU1bjkghJr2wOMISJQPWOxNY9Uved3X37NJWiSqIIHUXry2xzsz67Wn852zxQYTmeArMSnHokCvgjZ+WYmPxfPoThSUwWuwwWMl9khiPruaLvYRqeBkT5Voco73UpJq0AGVIaJnpA7JQeZlWsoIagVLlDfj8a1UwWf0eZRbDjGbPmINa5uLh36/pa4ExGiNgsy+JJOJ4mnHYG+zXcs/5G28PjEzOhgpE9ruDDUm0vWpAKPUKrzyzSSj8V8Soa6NQh3U2nFKSTEhaGoQs7PlNqRVN+813yDlF3BMKndWfoMkuzApD5We3wc1kFC/58SNpiEvPw6c04dOsGXOIc0DRMfJJevPe4vDhXfIOZUzfwsckuqAfrxoqzmWDoz/7c19hrA66svuZ8++AFBLBwhtiLRQNQEAABkEAABQSwECFAAUAAgICADjIbRaB2JpgwUBAAAHAwAAGAAAAAAAAAAAAAAAAAAAAAAAeGwvZHJhd2luZ3MvZHJhd2luZzEueG1sUEsBAhQAFAAICAgA4yG0Wmon2T5RAgAAlQcAABgAAAAAAAAAAAAAAAAASwEAAHhsL3dvcmtzaGVldHMvc2hlZXQxLnhtbFBLAQIUABQACAgIAOMhtFqtqOtNswAAACoBAAAjAAAAAAAAAAAAAAAAAOIDAAB4bC93b3Jrc2hlZXRzL19yZWxzL3NoZWV0MS54bWwucmVsc1BLAQIUABQACAgIAOMhtFplo4FhKAMAAK0OAAATAAAAAAAAAAAAAAAAAOYEAAB4bC90aGVtZS90aGVtZTEueG1sUEsBAhQAFAAICAgA4yG0WjmiklvsAAAAegEAABQAAAAAAAAAAAAAAAAATwgAAHhsL3NoYXJlZFN0cmluZ3MueG1sUEsBAhQAFAAICAgA4yG0WkAY0fIZAgAAHgYAAA0AAAAAAAAAAAAAAAAAfQkAAHhsL3N0eWxlcy54bWxQSwECFAAUAAgICADjIbRaW7rFnFMBAAAnAwAADwAAAAAAAAAAAAAAAADRCwAAeGwvd29ya2Jvb2sueG1sUEsBAhQAFAAICAgA4yG0WpYZwVPqAAAAuQIAABoAAAAAAAAAAAAAAAAAYQ0AAHhsL19yZWxzL3dvcmtib29rLnhtbC5yZWxzUEsBAhQAFAAICAgA4yG0WqRvoSCyAAAAKAEAAAsAAAAAAAAAAAAAAAAAkw4AAF9yZWxzLy5yZWxzUEsBAhQAFAAICAgA4yG0Wm2ItFA1AQAAGQQAABMAAAAAAAAAAAAAAAAAfg8AAFtDb250ZW50X1R5cGVzXS54bWxQSwUGAAAAAAoACgCaAgAA9BAAAAAA") + @ApiResponses({ + @ApiResponse(description = "Success", responseCode = "200", + content = @Content(mediaType = "application/json", + array = @ArraySchema( + schema = @Schema(oneOf = {DtlSpecExcelResponse.class}) + ) + ) + ), + @ApiResponse(description = "Not found", responseCode = "404", + content = @Content(mediaType = "text/plain", schema = @Schema(oneOf = + {String.class}))), + @ApiResponse(description = "Internal Error", responseCode = "500", + content = @Content(mediaType = "application/json", schema = @Schema(oneOf = + {CustomErrorResponse.class }))) + }) + @PostMapping("/dtl/excel") + public ResponseEntity save( + @RequestBody DtlSpecExcelRequest dtlSpecExcelRequest + ) { + return ResponseEntity.ok(dtlSpecService.excelConverter(dtlSpecExcelRequest)); + } +} diff --git a/src/main/java/com/kospo/svcm/controller/EstimateController.java b/src/main/java/com/kospo/svcm/controller/EstimateController.java new file mode 100644 index 0000000..dad32b0 --- /dev/null +++ b/src/main/java/com/kospo/svcm/controller/EstimateController.java @@ -0,0 +1,293 @@ +package com.kospo.svcm.controller; + +import com.kospo.svcm.config.exception.CustomErrorResponse; +import com.kospo.svcm.config.utils.FileUtils; +import com.kospo.svcm.dto.req.EstimateListSaveRequest; +import com.kospo.svcm.dto.req.EstimateListUpdateRequest; +import com.kospo.svcm.dto.res.EstimateListResponse; +import com.kospo.svcm.dto.res.EstimateResponse; +import com.kospo.svcm.model.PbAtt; +import com.kospo.svcm.service.EstimateService; +import com.kospo.svcm.service.PrcsService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.ArraySchema; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import org.springframework.core.io.UrlResource; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; +import org.yaml.snakeyaml.util.UriEncoder; + +import java.io.IOException; +import java.net.MalformedURLException; +import java.security.Principal; + +@Tag(name = "Estimate Api", description = "견적 관리") +@RestController +@RequiredArgsConstructor +@RequestMapping("/api") +public class EstimateController { + private final EstimateService estimateService; + private final PrcsService prcsService; + private final FileUtils fileUtils; + + @Operation(summary = "가격조사 조회", description = "전체 조회") + @ApiResponses({ + @ApiResponse(description = "Success", responseCode = "200", + content = @Content(mediaType = "application/json", array = @ArraySchema( + schema = @Schema(oneOf = + {EstimateResponse.class}) + ))), + @ApiResponse(description = "Not found", responseCode = "404", + content = @Content(mediaType = "text/plain", schema = @Schema(oneOf = + {String.class}))), + @ApiResponse(description = "Internal Error", responseCode = "500", + content = @Content(mediaType = "application/json", schema = @Schema(oneOf = + {CustomErrorResponse.class}))) + }) + @GetMapping("/estimate") + public ResponseEntity findByBizNoAndPrcsNo( + @Parameter(description = "가격조사번호") @RequestParam(required = false) String prcsNo, + Principal principal + ) { + + return ResponseEntity.ok(estimateService.findByBizNoAndPrcsNo(principal.getName(), prcsNo)); + } + + @Operation(summary = "가격조사_견적관리 조회 (페이징)", description = "전체 조회") + @ApiResponses({ + @ApiResponse(description = "Success", responseCode = "200", + content = @Content(mediaType = "application/json", + schema = @Schema(oneOf = + {Pageable.class}))), + @ApiResponse(description = "Not found", responseCode = "404", + content = @Content(mediaType = "text/plain", schema = @Schema(oneOf = + {String.class}))), + @ApiResponse(description = "Internal Error", responseCode = "500", + content = @Content(mediaType = "application/json", schema = @Schema(oneOf = + {CustomErrorResponse.class }))) + }) + @GetMapping("/estimate/external/page") + @PreAuthorize("hasRole('EXTERNAL')") + public ResponseEntity findExternalEstimateSearchPage( + @Parameter(description = "담당자") @RequestParam(required = false) String mngNm, + @Parameter(description = "제목") @RequestParam(required = false) String title, + @Parameter(description = "견적상태코드") @RequestParam(required = false) String estStatCd, + @Parameter(description = "페이지") @RequestParam("page") int page, + @Parameter(description = "아이템갯수") @RequestParam("row") int row, + Principal principal + ) { + Pageable pageable = PageRequest.of(page -1, row); + return ResponseEntity.ok(prcsService.findExternalEstSearch(principal.getName(), title, estStatCd, mngNm, pageable)); + } +// +// @Operation(summary = "가격조사 조회 (페이징)", description = "전체 조회") +// @ApiResponses({ +// @ApiResponse(description = "Success", responseCode = "200", +// content = @Content(mediaType = "application/json", array = @ArraySchema( +// schema = @Schema(oneOf = +// {PrcsResponse.class}) +// ))), +// @ApiResponse(description = "Not found", responseCode = "404", +// content = @Content(mediaType = "text/plain", schema = @Schema(oneOf = +// {String.class}))), +// @ApiResponse(description = "Internal Error", responseCode = "500", +// content = @Content(mediaType = "application/json", schema = @Schema(oneOf = +// {CustomErrorResponse.class }))) +// }) +// @GetMapping("/prcs/page") +// public ResponseEntity findCode( +// @Parameter(description = "분야코드") @RequestParam(required = false) String cateCd, +// @Parameter(description = "등록상태") @RequestParam(required = false) String stCd, +// @Parameter(description = "담당자") @RequestParam(required = false) String regNm, +// @Parameter(description = "등록시작일") @RequestParam(required = false, defaultValue = "1970-01-01") String regSdt, +// @Parameter(description = "등록종료일") @RequestParam(required = false, defaultValue = "2070-01-01") String regEdt, +// @Parameter(description = "페이지") @RequestParam("page") int page, +// @Parameter(description = "아이템갯수") @RequestParam("row") int row +// ) { +// Pageable pageable = PageRequest.of(page -1, row); +// return ResponseEntity.ok( +// MsgResponse.builder() +// .code("10000") +// .body(prcsService.findSearch(cateCd, stCd, regNm, regSdt, regEdt, pageable)) +// .build() +// ); +// } + + @Operation(summary = "견적 관리 저장", description = "견적, 견적서(첨부파일) 저장") + @ApiResponses({ + @ApiResponse(description = "Success", responseCode = "200", + content = @Content(mediaType = "application/json", array = @ArraySchema( + schema = @Schema(oneOf = + {EstimateListResponse.class}) + ))), + @ApiResponse(description = "Not found", responseCode = "404", + content = @Content(mediaType = "text/plain", schema = @Schema(oneOf = + {String.class}))), + @ApiResponse(description = "Internal Error", responseCode = "500", + content = @Content(mediaType = "application/json", schema = @Schema(oneOf = + {CustomErrorResponse.class}))) + }) + @PostMapping("/estimate") + public ResponseEntity save( + @RequestBody EstimateListSaveRequest estimateListSaveRequest + ) { + return ResponseEntity.ok(estimateService.save(estimateListSaveRequest)); + } + + @Operation(summary = "견적 관리 수정", description = "견적, 견적서(첨부파일) 수정") + @ApiResponses({ + @ApiResponse(description = "Success", responseCode = "200", + content = @Content(mediaType = "application/json", schema = @Schema(oneOf = + {EstimateListResponse.class}))), + @ApiResponse(description = "Not found", responseCode = "404", + content = @Content(mediaType = "text/plain", schema = @Schema(oneOf = + {String.class}))), + @ApiResponse(description = "Internal Error", responseCode = "500", + content = @Content(mediaType = "application/json", schema = @Schema(oneOf = + {CustomErrorResponse.class}))) + }) + @PutMapping("/estimate") + public ResponseEntity update( + @RequestBody EstimateListUpdateRequest estimateListUpdateRequest, + Principal principal + ) { + return ResponseEntity.ok(estimateService.update(principal.getName(), estimateListUpdateRequest)); + } + + @Operation(summary = "견적서 삭제", description = "견적서(첨부파일) 삭제") + @ApiResponses({ + @ApiResponse(description = "Success", responseCode = "200", + content = @Content(mediaType = "application/json", schema = @Schema(oneOf = + {String.class}))), + @ApiResponse(description = "Not found", responseCode = "404", + content = @Content(mediaType = "text/plain", schema = @Schema(oneOf = + {String.class}))), + @ApiResponse(description = "Internal Error", responseCode = "500", + content = @Content(mediaType = "application/json", schema = @Schema(oneOf = + {CustomErrorResponse.class}))) + }) + @DeleteMapping("/pbAtt/{prcsNo}/{bizNo}/{fileOrd}") + public ResponseEntity delete( + @Parameter(description = "가격조사번호") @PathVariable String prcsNo, + @Parameter(description = "견적관리번호") @PathVariable String bizNo, + @Parameter(description = "파일순서") @PathVariable Integer fileOrd, + Principal principal + ) { + estimateService.pbAttFileDelete(prcsNo, bizNo, fileOrd); + return ResponseEntity.ok("삭제 되었습니다."); + } + + @Operation(summary = "견적서 다운로드", description = "견적서(첨부파일) 다운로드") + @ApiResponses({ + @ApiResponse(description = "Success", responseCode = "200", + content = @Content(mediaType = "application/json", schema = @Schema(oneOf = + {byte[].class}))), + @ApiResponse(description = "Not found", responseCode = "404", + content = @Content(mediaType = "text/plain", schema = @Schema(oneOf = + {String.class}))), + @ApiResponse(description = "Internal Error", responseCode = "500", + content = @Content(mediaType = "application/json", schema = @Schema(oneOf = + {CustomErrorResponse.class}))) + }) + @GetMapping("/pbAtt/{prcsNo}/{bizNo}/{fileOrd}") + public ResponseEntity download( + @Parameter(description = "가격조사번호") @PathVariable String prcsNo, + @Parameter(description = "견적관리번호") @PathVariable String bizNo, + @Parameter(description = "파일순서") @PathVariable Integer fileOrd, + Principal principal + ) { + PbAtt pbAtt = estimateService.getPbAtt(prcsNo, bizNo, fileOrd, principal.getName()); + UrlResource resource = null; + HttpHeaders headers = new HttpHeaders(); + try { + resource = new UrlResource("file:"+pbAtt.getPath()); + headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + UriEncoder.encode(pbAtt.getLogiFnm()).replace("+", " ")); + headers.setContentType(MediaType.APPLICATION_OCTET_STREAM); + headers.setContentLength(resource.contentLength()); + } catch (MalformedURLException e) { + throw new RuntimeException(e); + } catch (IOException e) { + throw new RuntimeException(e); + } + + // HTTP 헤더 설정 + + + return ResponseEntity.ok() + .headers(headers) + .body(resource); + } + +// @Operation(summary = "견적서 삭제", description = "견적서(첨부파일) 삭제") +// @ApiResponses({ +// @ApiResponse(description = "Success", responseCode = "200", +// content = @Content(mediaType = "application/json", schema = @Schema(oneOf = +// {String.class}))), +// @ApiResponse(description = "Not found", responseCode = "404", +// content = @Content(mediaType = "text/plain", schema = @Schema(oneOf = +// {String.class}))), +// @ApiResponse(description = "Internal Error", responseCode = "500", +// content = @Content(mediaType = "application/json", schema = @Schema(oneOf = +// {CustomErrorResponse.class}))) +// }) +// @DeleteMapping("/estimate/{bidNo}/{fileOrd}") +// public ResponseEntity delete( +// @Parameter(description = "견적관리번호") @PathVariable String bidNo, +// @Parameter(description = "파일순서") @PathVariable Integer fileOrd, +// Principal principal +// ) { +// estimateService.bidFileDelete(bidNo, fileOrd); +// return ResponseEntity.ok("삭제 되었습니다."); +// } +// +// @Operation(summary = "견적서 다운로드", description = "견적서(첨부파일) 다운로드") +// @ApiResponses({ +// @ApiResponse(description = "Success", responseCode = "200", +// content = @Content(mediaType = "application/json", schema = @Schema(oneOf = +// {byte[].class}))), +// @ApiResponse(description = "Not found", responseCode = "404", +// content = @Content(mediaType = "text/plain", schema = @Schema(oneOf = +// {String.class}))), +// @ApiResponse(description = "Internal Error", responseCode = "500", +// content = @Content(mediaType = "application/json", schema = @Schema(oneOf = +// {CustomErrorResponse.class}))) +// }) +// @GetMapping("/estimate/{bidNo}/{fileOrd}") +// public ResponseEntity download( +// @Parameter(description = "견적관리번호") @PathVariable String bidNo, +// @Parameter(description = "파일순서") @PathVariable Integer fileOrd, +// Principal principal +// ) { +// BidDoc bidDoc = estimateService.getBidDoc(bidNo, fileOrd); +// UrlResource resource = null; +// HttpHeaders headers = new HttpHeaders(); +// try { +// resource = new UrlResource("file:"+bidDoc.getPath()); +// headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + UriEncoder.encode(bidDoc.getLogiFnm()).replace("+", " ")); +// headers.setContentType(MediaType.APPLICATION_OCTET_STREAM); +// headers.setContentLength(resource.contentLength()); +// } catch (MalformedURLException e) { +// throw new RuntimeException(e); +// } catch (IOException e) { +// throw new RuntimeException(e); +// } +// +// // HTTP 헤더 설정 +// +// +// return ResponseEntity.ok() +// .headers(headers) +// .body(resource); +// } +} diff --git a/src/main/java/com/kospo/svcm/controller/IntegratedApprController.java b/src/main/java/com/kospo/svcm/controller/IntegratedApprController.java new file mode 100644 index 0000000..8f28361 --- /dev/null +++ b/src/main/java/com/kospo/svcm/controller/IntegratedApprController.java @@ -0,0 +1,80 @@ +package com.kospo.svcm.controller; + +import com.kospo.svcm.config.exception.CustomErrorResponse; +import com.kospo.svcm.dto.req.ApprReqRequest; +import com.kospo.svcm.dto.res.ApprMstResponse; +import com.kospo.svcm.dto.res.ApprReqResponse; +import com.kospo.svcm.dto.res.PageResponse; +import com.kospo.svcm.repository.ApprReqRepository; +import com.kospo.svcm.service.ApprService; +import com.kospo.svcm.service.IntegratedApprService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.security.Principal; + +@Tag(name = "Integrated Approval Api", description = "통합 결재 관리") +@RestController +@RequiredArgsConstructor +@RequestMapping("/api") +public class IntegratedApprController { + private final IntegratedApprService integratedApprService; + + @Operation(summary = "통합 결재 승인 목록(개인) 조회", description = "통합 결재 승인 목록 조회") + @ApiResponses({ + @ApiResponse(description = "Success", responseCode = "200", + content = @Content(mediaType = "application/json", schema = @Schema(oneOf = + {PageResponse.class}) + )), + @ApiResponse(description = "Not found", responseCode = "404", + content = @Content(mediaType = "text/plain", schema = @Schema(oneOf = + {String.class}))), + @ApiResponse(description = "Internal Error", responseCode = "500", + content = @Content(mediaType = "application/json", schema = @Schema(oneOf = + {CustomErrorResponse.class }))) + }) + @GetMapping("/itg/appr/req") + public ResponseEntity findReq( + @Parameter(description = "결재제목") @RequestParam(value="title", required = false) String title, + @Parameter(description = "결재상태") @RequestParam(value="apprStat", required = false) String apprStat, + @Parameter(description = "페이지") @RequestParam("page") int page, + @Parameter(description = "아이템갯수") @RequestParam("row") int row + ) { + Pageable pageable = PageRequest.of(page -1, row); + return ResponseEntity.ok(integratedApprService.searchBySabun(title, apprStat, pageable)); + } + + @Operation(summary = "통합 결재 목록(부서) 조회", description = "통합 결재 목록 조회 (관리자 :전체, 일반사용자 :부서)") + @ApiResponses({ + @ApiResponse(description = "Success", responseCode = "200", + content = @Content(mediaType = "application/json", schema = @Schema(oneOf = + {PageResponse.class}) + )), + @ApiResponse(description = "Not found", responseCode = "404", + content = @Content(mediaType = "text/plain", schema = @Schema(oneOf = + {String.class}))), + @ApiResponse(description = "Internal Error", responseCode = "500", + content = @Content(mediaType = "application/json", schema = @Schema(oneOf = + {CustomErrorResponse.class }))) + }) + @GetMapping("/itg/appr") + public ResponseEntity findAll( + @Parameter(description = "결재제목") @RequestParam(value="title", required = false) String title, + @Parameter(description = "페이지") @RequestParam("page") int page, + @Parameter(description = "아이템갯수") @RequestParam("row") int row + ) { + Pageable pageable = PageRequest.of(page -1, row); + return ResponseEntity.ok(integratedApprService.searchList(title, pageable)); + } + +} diff --git a/src/main/java/com/kospo/svcm/controller/LoginController.java b/src/main/java/com/kospo/svcm/controller/LoginController.java new file mode 100644 index 0000000..d556954 --- /dev/null +++ b/src/main/java/com/kospo/svcm/controller/LoginController.java @@ -0,0 +1,73 @@ +package com.kospo.svcm.controller; + +import com.kospo.svcm.config.exception.CustomErrorResponse; +import com.kospo.svcm.config.utils.CommonUtils; +import com.kospo.svcm.dto.req.LoginRequest; +import com.kospo.svcm.dto.res.LoginResponse; +import com.kospo.svcm.service.BusinessService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.servlet.http.HttpServletRequest; +import lombok.RequiredArgsConstructor; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.security.Principal; + + +@Tag(name = "Login Api", description = "로그인 관리") +@RestController +@RequiredArgsConstructor +@RequestMapping("/api") +public class LoginController { + private final BusinessService businessService; + + @Operation(summary = "로그인", description = "토큰을 생성한다.") + @ApiResponses({ + @ApiResponse(description = "Success", responseCode = "200", + content = @Content(mediaType = "application/json", schema = @Schema(oneOf = + {LoginResponse.class }))), + @ApiResponse(description = "Not found", responseCode = "404", + content = @Content(mediaType = "text/plain", schema = @Schema(oneOf = + {String.class}))), + @ApiResponse(description = "Internal Error", responseCode = "500", + content = @Content(mediaType = "application/json", schema = @Schema(oneOf = + {CustomErrorResponse.class }))) + }) + @PostMapping("/login") + public ResponseEntity login( + @RequestBody LoginRequest loginRequest, + HttpServletRequest request + ) { + return ResponseEntity.ok(businessService.login(loginRequest, CommonUtils.getClientIp(request))); + } + + @Operation(summary = "토큰 유효성 검증", description = "토큰 만료 여부 확인") + @ApiResponses({ + @ApiResponse(description = "Success", responseCode = "200", + content = @Content(mediaType = "application/json", schema = @Schema(oneOf = + {LoginResponse.class }))), + @ApiResponse(description = "Not found", responseCode = "404", + content = @Content(mediaType = "text/plain", schema = @Schema(oneOf = + {String.class}))), + @ApiResponse(description = "Internal Error", responseCode = "500", + content = @Content(mediaType = "application/json", schema = @Schema(oneOf = + {CustomErrorResponse.class }))) + }) + @GetMapping("/token/valid") + public ResponseEntity tokenValidate( + @RequestHeader("Authentication") String accessToken, + Principal principal + ) { + if(accessToken == null || accessToken.isEmpty()) { + return ResponseEntity.ok(false); + } else { + return ResponseEntity.ok(businessService.tokenValidate(principal.getName(), accessToken)); + } + + } +} diff --git a/src/main/java/com/kospo/svcm/controller/PrcsController.java b/src/main/java/com/kospo/svcm/controller/PrcsController.java new file mode 100644 index 0000000..1ca017c --- /dev/null +++ b/src/main/java/com/kospo/svcm/controller/PrcsController.java @@ -0,0 +1,355 @@ +package com.kospo.svcm.controller; + +import com.kospo.svcm.config.exception.CustomErrorResponse; +import com.kospo.svcm.dto.req.PrcsSaveRequest; +import com.kospo.svcm.dto.req.PrcsUpdateRequest; +import com.kospo.svcm.dto.res.PrcsResponse; +import com.kospo.svcm.model.PrcsAtt; +import com.kospo.svcm.service.PrcsService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.ArraySchema; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import org.springframework.core.io.UrlResource; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; +import org.yaml.snakeyaml.util.UriEncoder; + +import java.io.IOException; +import java.net.MalformedURLException; +import java.security.Principal; + +@Tag(name = "PriceSurvey Api", description = "가격조사 관리") +@RestController +@RequiredArgsConstructor +@RequestMapping("/api") +public class PrcsController { + private final PrcsService prcsService; + + @Operation(summary = "가격조사 상세조회", description = "가격조사번로 조회") + @ApiResponses({ + @ApiResponse(description = "Success", responseCode = "200", + content = @Content(mediaType = "application/json", + schema = @Schema(oneOf = + {PrcsResponse.class}))), + @ApiResponse(description = "Not found", responseCode = "404", + content = @Content(mediaType = "text/plain", schema = @Schema(oneOf = + {String.class}))), + @ApiResponse(description = "Internal Error", responseCode = "500", + content = @Content(mediaType = "application/json", schema = @Schema(oneOf = + {CustomErrorResponse.class }))) + }) + @GetMapping("/prcs/{prcsNo}") + public ResponseEntity findSearchPage( + @Parameter(description = "가격조사번호") @PathVariable(required = false) String prcsNo + ) { + return ResponseEntity.ok(prcsService.findDetail(prcsNo)); + } + + @Operation(summary = "가격조사 조회 (페이징)", description = "전체 조회") + @ApiResponses({ + @ApiResponse(description = "Success", responseCode = "200", + content = @Content(mediaType = "application/json", + schema = @Schema(oneOf = + {Pageable.class}))), + @ApiResponse(description = "Not found", responseCode = "404", + content = @Content(mediaType = "text/plain", schema = @Schema(oneOf = + {String.class}))), + @ApiResponse(description = "Internal Error", responseCode = "500", + content = @Content(mediaType = "application/json", schema = @Schema(oneOf = + {CustomErrorResponse.class }))) + }) + @GetMapping("/prcs/page") + public ResponseEntity findSearchPage( + @Parameter(description = "분야코드") @RequestParam(required = false) String cateCd, + @Parameter(description = "등록상태") @RequestParam(required = false) String stCd, + @Parameter(description = "담당자") @RequestParam(required = false) String regNm, + @Parameter(description = "등록시작일") @RequestParam(required = false, defaultValue = "1970-01-01") String regSdt, + @Parameter(description = "등록종료일") @RequestParam(required = false, defaultValue = "2070-01-01") String regEdt, + @Parameter(description = "페이지") @RequestParam("page") int page, + @Parameter(description = "아이템갯수") @RequestParam("row") int row + ) { + Pageable pageable = PageRequest.of(page -1, row); + return ResponseEntity.ok(prcsService.findSearch(cateCd, stCd, regNm, regSdt, regEdt, pageable)); + } + + @Operation(summary = "가격조사_견적관리 조회", description = "단일 조회") + @ApiResponses({ + @ApiResponse(description = "Success", responseCode = "200", + content = @Content(mediaType = "application/json", + schema = @Schema(oneOf = + {Pageable.class}))), + @ApiResponse(description = "Not found", responseCode = "404", + content = @Content(mediaType = "text/plain", schema = @Schema(oneOf = + {String.class}))), + @ApiResponse(description = "Internal Error", responseCode = "500", + content = @Content(mediaType = "application/json", schema = @Schema(oneOf = + {CustomErrorResponse.class }))) + }) + @GetMapping("/prcs/external/{prcsNo}") + @PreAuthorize("hasRole('EXTERNAL')") + public ResponseEntity findExternalPrcs( + @Parameter(description = "가격조사번호") @PathVariable String prcsNo, + Principal principal + ) { + + return ResponseEntity.ok(prcsService.findOne(principal.getName(), prcsNo)); + } + + @Operation(summary = "가격조사_견적관리 조회 (페이징)", description = "전체 조회") + @ApiResponses({ + @ApiResponse(description = "Success", responseCode = "200", + content = @Content(mediaType = "application/json", + schema = @Schema(oneOf = + {Pageable.class}))), + @ApiResponse(description = "Not found", responseCode = "404", + content = @Content(mediaType = "text/plain", schema = @Schema(oneOf = + {String.class}))), + @ApiResponse(description = "Internal Error", responseCode = "500", + content = @Content(mediaType = "application/json", schema = @Schema(oneOf = + {CustomErrorResponse.class }))) + }) + @GetMapping("/prcs/external/page") + @PreAuthorize("hasRole('EXTERNAL')") + public ResponseEntity findExternalSearchPage( + @Parameter(description = "분야코드") @RequestParam(required = false) String cateCd, + @Parameter(description = "담당자") @RequestParam(required = false) String regNm, + @Parameter(description = "제목") @RequestParam(required = false) String title, + @Parameter(description = "등록시작일") @RequestParam(required = false, defaultValue = "1970-01-01") String regSdt, + @Parameter(description = "등록종료일") @RequestParam(required = false, defaultValue = "9999-12-31") String regEdt, + @Parameter(description = "페이지") @RequestParam("page") int page, + @Parameter(description = "아이템갯수") @RequestParam("row") int row, + Principal principal + ) { + Pageable pageable = PageRequest.of(page -1, row); + return ResponseEntity.ok(prcsService.findExternalSearch(principal.getName(), cateCd, title, regNm, regSdt, regEdt, pageable)); + } + + + @Operation(summary = "가격조사_견적관리 조회 (페이징)", description = "전체 조회") + @ApiResponses({ + @ApiResponse(description = "Success", responseCode = "200", + content = @Content(mediaType = "application/json", + schema = @Schema(oneOf = + {Pageable.class}))), + @ApiResponse(description = "Not found", responseCode = "404", + content = @Content(mediaType = "text/plain", schema = @Schema(oneOf = + {String.class}))), + @ApiResponse(description = "Internal Error", responseCode = "500", + content = @Content(mediaType = "application/json", schema = @Schema(oneOf = + {CustomErrorResponse.class }))) + }) + @GetMapping("/prcs/external/count") + @PreAuthorize("hasRole('EXTERNAL')") + public ResponseEntity findExternalSearchPage( + Principal principal + ) { + return ResponseEntity.ok(prcsService.countReqByBizNo(principal.getName())); + } + + + @Operation(summary = "가격조사_계약관리 조회 (페이징)", description = "전체 조회") + @ApiResponses({ + @ApiResponse(description = "Success", responseCode = "200", + content = @Content(mediaType = "application/json", + schema = @Schema(oneOf = + {Pageable.class}))), + @ApiResponse(description = "Not found", responseCode = "404", + content = @Content(mediaType = "text/plain", schema = @Schema(oneOf = + {String.class}))), + @ApiResponse(description = "Internal Error", responseCode = "500", + content = @Content(mediaType = "application/json", schema = @Schema(oneOf = + {CustomErrorResponse.class }))) + }) + @GetMapping("/prcs/contract/page") + public ResponseEntity findContractSearchPage( + @Parameter(description = "분야코드") @RequestParam(required = false) String cateCd, + @Parameter(description = "담당자") @RequestParam(required = false) String regNm, + @Parameter(description = "등록시작일") @RequestParam(required = false, defaultValue = "1970-01-01") String regSdt, + @Parameter(description = "등록종료일") @RequestParam(required = false, defaultValue = "2070-01-01") String regEdt, + @Parameter(description = "페이지") @RequestParam("page") int page, + @Parameter(description = "아이템갯수") @RequestParam("row") int row + ) { + Pageable pageable = PageRequest.of(page -1, row); + return ResponseEntity.ok(prcsService.findContractSearch(cateCd, regNm, regSdt, regEdt, pageable)); + } + + + @Operation(summary = "가격조사_결재관리 조회 (페이징)", description = "전체 조회") + @ApiResponses({ + @ApiResponse(description = "Success", responseCode = "200", + content = @Content(mediaType = "application/json", + schema = @Schema(oneOf = + {Pageable.class}))), + @ApiResponse(description = "Not found", responseCode = "404", + content = @Content(mediaType = "text/plain", schema = @Schema(oneOf = + {String.class}))), + @ApiResponse(description = "Internal Error", responseCode = "500", + content = @Content(mediaType = "application/json", schema = @Schema(oneOf = + {CustomErrorResponse.class }))) + }) + @GetMapping("/prcs/approval/page") + public ResponseEntity findApprSearchPage( + @Parameter(description = "분야코드") @RequestParam(required = false) String cateCd, + @Parameter(description = "담당자") @RequestParam(required = false) String regNm, + @Parameter(description = "등록시작일") @RequestParam(required = false, defaultValue = "1970-01-01") String regSdt, + @Parameter(description = "등록종료일") @RequestParam(required = false, defaultValue = "2070-01-01") String regEdt, + @Parameter(description = "페이지") @RequestParam("page") int page, + @Parameter(description = "아이템갯수") @RequestParam("row") int row, + Principal principal + ) { + Pageable pageable = PageRequest.of(page -1, row); + return ResponseEntity.ok(prcsService.findApprovalSearch(principal.getName(), cateCd, regNm, regSdt, regEdt, pageable)); + } + + @Operation(summary = "가격조사 저장", description = "가격조사, 규격, 첨부파일, 결재 통합저장") + @ApiResponses({ + @ApiResponse(description = "Success", responseCode = "200", + content = @Content(mediaType = "application/json", schema = @Schema(oneOf = + {PrcsResponse.class}))), + @ApiResponse(description = "Not found", responseCode = "404", + content = @Content(mediaType = "text/plain", schema = @Schema(oneOf = + {String.class}))), + @ApiResponse(description = "Internal Error", responseCode = "500", + content = @Content(mediaType = "application/json", schema = @Schema(oneOf = + {CustomErrorResponse.class }))) + }) + @PostMapping("/prcs") + public ResponseEntity save( + @RequestBody PrcsSaveRequest prcsRequest + ) { + return ResponseEntity.ok(prcsService.save(prcsRequest)); + } + + @Operation(summary = "가격조사 수정", description = "가격조사, 규격, 첨부파일, 결재 통합 수정") + @ApiResponses({ + @ApiResponse(description = "Success", responseCode = "200", + content = @Content(mediaType = "application/json", schema = @Schema(oneOf = + {PrcsResponse.class}))), + @ApiResponse(description = "Not found", responseCode = "404", + content = @Content(mediaType = "text/plain", schema = @Schema(oneOf = + {String.class}))), + @ApiResponse(description = "Internal Error", responseCode = "500", + content = @Content(mediaType = "application/json", schema = @Schema(oneOf = + {CustomErrorResponse.class }))) + }) + @PutMapping("/prcs") + public ResponseEntity update( + @RequestBody PrcsUpdateRequest prcsRequest, + Principal principal + ) { + return ResponseEntity.ok(prcsService.update(principal.getName(), prcsRequest)); + } + + @Operation(summary = "가격조사 회수 처리", description = "결재진행중인건에 대한 회수 처리") + @ApiResponses({ + @ApiResponse(description = "Success", responseCode = "200", + content = @Content(mediaType = "application/json", schema = @Schema(oneOf = + {PrcsResponse.class}))), + @ApiResponse(description = "Not found", responseCode = "404", + content = @Content(mediaType = "text/plain", schema = @Schema(oneOf = + {String.class}))), + @ApiResponse(description = "Internal Error", responseCode = "500", + content = @Content(mediaType = "application/json", schema = @Schema(oneOf = + {CustomErrorResponse.class }))) + }) + @PutMapping("/prcs/ret/{prcsNo}") + public ResponseEntity retrieve( + @Parameter(description = "가격조사번호") @PathVariable String prcsNo, + Principal principal + ) { + return ResponseEntity.ok(prcsService.retrieve(prcsNo)); + } + + @Operation(summary = "가격조사 첨부파일 삭제", description = "가격조사 문서(첨부파일) 삭제") + @ApiResponses({ + @ApiResponse(description = "Success", responseCode = "200", + content = @Content(mediaType = "application/json", schema = @Schema(oneOf = + {String.class}))), + @ApiResponse(description = "Not found", responseCode = "404", + content = @Content(mediaType = "text/plain", schema = @Schema(oneOf = + {String.class}))), + @ApiResponse(description = "Internal Error", responseCode = "500", + content = @Content(mediaType = "application/json", schema = @Schema(oneOf = + {CustomErrorResponse.class }))) + }) + @DeleteMapping("/prcs/{prcsNo}/{fileOrd}") + public ResponseEntity fileDelete( + @Parameter(description = "가격조사번호") @PathVariable String prcsNo, + @Parameter(description = "파일순서") @PathVariable Integer fileOrd, + Principal principal + ) { + prcsService.prcsAttFileDelete(prcsNo, fileOrd); + return ResponseEntity.ok("삭제 되었습니다."); + } + + @Operation(summary = "가격조사 완료 처리", description = "가격조사 완료 처리(사전 처리 및 자동 완료 처리)") + @ApiResponses({ + @ApiResponse(description = "Success", responseCode = "200", + content = @Content(mediaType = "application/json", schema = @Schema(oneOf = + {PrcsResponse.class}))), + @ApiResponse(description = "Not found", responseCode = "404", + content = @Content(mediaType = "text/plain", schema = @Schema(oneOf = + {String.class}))), + @ApiResponse(description = "Internal Error", responseCode = "500", + content = @Content(mediaType = "application/json", schema = @Schema(oneOf = + {CustomErrorResponse.class }))) + }) + @PutMapping("/prcs/survey/{prcsNo}") + public ResponseEntity surveyUpdate( + @Parameter(description = "가겨조사 번호") @PathVariable String prcsNo, + Principal principal + ) { + return ResponseEntity.ok(prcsService.surveyUpdate(principal.getName(), prcsNo)); + } + + @Operation(summary = "가격조사서 다운로드", description = "가격조사서(첨부파일) 다운로드") + @ApiResponses({ + @ApiResponse(description = "Success", responseCode = "200", + content = @Content(mediaType = "application/json", schema = @Schema(oneOf = + {byte[].class}))), + @ApiResponse(description = "Not found", responseCode = "404", + content = @Content(mediaType = "text/plain", schema = @Schema(oneOf = + {String.class}))), + @ApiResponse(description = "Internal Error", responseCode = "500", + content = @Content(mediaType = "application/json", schema = @Schema(oneOf = + {CustomErrorResponse.class}))) + }) + @GetMapping("/prcs/{prcsNo}/{fileOrd}") + public ResponseEntity download( + @Parameter(description = "가격조사번호") @PathVariable String prcsNo, + @Parameter(description = "파일순서") @PathVariable Integer fileOrd, + Principal principal + ) { + PrcsAtt prcsAtt = prcsService.getPrcsAtt(prcsNo, fileOrd, principal.getName()); + UrlResource resource = null; + HttpHeaders headers = new HttpHeaders(); + try { + resource = new UrlResource("file:"+prcsAtt.getPath()); + headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + UriEncoder.encode(prcsAtt.getLogiFnm()).replace("+", " ")); + headers.setContentType(MediaType.APPLICATION_OCTET_STREAM); + headers.setContentLength(resource.contentLength()); + } catch (MalformedURLException e) { + throw new RuntimeException(e); + } catch (IOException e) { + throw new RuntimeException(e); + } + + // HTTP 헤더 설정 + + + return ResponseEntity.ok() + .headers(headers) + .body(resource); + } +} diff --git a/src/main/java/com/kospo/svcm/controller/RoleController.java b/src/main/java/com/kospo/svcm/controller/RoleController.java new file mode 100644 index 0000000..ee7b347 --- /dev/null +++ b/src/main/java/com/kospo/svcm/controller/RoleController.java @@ -0,0 +1,115 @@ +package com.kospo.svcm.controller; + +import com.kospo.svcm.config.exception.CustomErrorResponse; +import com.kospo.svcm.dto.req.RoleRequest; +import com.kospo.svcm.dto.res.RoleResponse; +import com.kospo.svcm.dto.res.UserResponse; +import com.kospo.svcm.service.RoleService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.ArraySchema; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; + +@RestController +@Tag(name = "Role Api", description = "권한 관리") +@RequestMapping("/api") +@RequiredArgsConstructor +public class RoleController { + private final RoleService roleService; + + @Operation(summary = "권한 조회", description = "전체 조회") + @ApiResponses({ + @ApiResponse(description = "Success", responseCode = "200", + content = @Content(mediaType = "application/json", array = @ArraySchema( + schema = @Schema(oneOf = + {UserResponse.class}) + ))), + @ApiResponse(description = "Not found", responseCode = "404", + content = @Content(mediaType = "text/plain", schema = @Schema(oneOf = + {String.class}))), + @ApiResponse(description = "Internal Error", responseCode = "500", + content = @Content(mediaType = "application/json", schema = @Schema(oneOf = + {CustomErrorResponse.class }))) + }) + @GetMapping("/role") + @PreAuthorize("hasRole('ADMIN')") + public ResponseEntity findRole( + @Parameter(description = "권한아이디") @RequestParam("roleId") String roleId + ) { + return ResponseEntity.ok(roleService.findByRoleId(roleId)); + } + + @Operation(summary = "권한 추가", description = "관리자 권한부여") + @ApiResponses({ + @ApiResponse(description = "Success", responseCode = "200", + content = @Content(mediaType = "application/json", schema = @Schema(oneOf = + {RoleResponse.class}) + )), + @ApiResponse(description = "Not found", responseCode = "404", + content = @Content(mediaType = "text/plain", schema = @Schema(oneOf = + {String.class}))), + @ApiResponse(description = "Internal Error", responseCode = "500", + content = @Content(mediaType = "application/json", schema = @Schema(oneOf = + {CustomErrorResponse.class }))) + }) + @PostMapping("/role") + @PreAuthorize("hasRole('ADMIN')") + public ResponseEntity saveRole( + @RequestBody RoleRequest roleRequest + ) { + ; + return ResponseEntity.ok(roleService.save(roleRequest)); + } + + @Operation(summary = "권한 수정", description = "관리자 아이피 수정") + @ApiResponses({ + @ApiResponse(description = "Success", responseCode = "200", + content = @Content(mediaType = "application/json", schema = @Schema(oneOf = + {RoleResponse.class}) + )), + @ApiResponse(description = "Not found", responseCode = "404", + content = @Content(mediaType = "text/plain", schema = @Schema(oneOf = + {String.class}))), + @ApiResponse(description = "Internal Error", responseCode = "500", + content = @Content(mediaType = "application/json", schema = @Schema(oneOf = + {CustomErrorResponse.class }))) + }) + @PutMapping("/role") + @PreAuthorize("hasRole('ADMIN')") + public ResponseEntity updRole( + @RequestBody RoleRequest roleRequest + ) { + + return ResponseEntity.ok(roleService.update(roleRequest)); + } + + @Operation(summary = "권한 삭제", description = "특정 사용자 권한삭제") + @ApiResponses({ + @ApiResponse(description = "Success", responseCode = "200", + content = @Content(mediaType = "application/json", schema = @Schema(oneOf = + {String.class}) + )), + @ApiResponse(description = "Not found", responseCode = "404", + content = @Content(mediaType = "text/plain", schema = @Schema(oneOf = + {String.class}))), + @ApiResponse(description = "Internal Error", responseCode = "500", + content = @Content(mediaType = "application/json", schema = @Schema(oneOf = + {CustomErrorResponse.class }))) + }) + @DeleteMapping("/role") + @PreAuthorize("hasRole('ADMIN')") + public ResponseEntity delRole( + @RequestBody RoleRequest roleRequest + ) { + roleService.delete(roleRequest); + return ResponseEntity.ok("삭제 되었습니다."); + } +} diff --git a/src/main/java/com/kospo/svcm/controller/SapApprController.java b/src/main/java/com/kospo/svcm/controller/SapApprController.java new file mode 100644 index 0000000..5af8645 --- /dev/null +++ b/src/main/java/com/kospo/svcm/controller/SapApprController.java @@ -0,0 +1,187 @@ +package com.kospo.svcm.controller; + +import com.kospo.svcm.config.exception.CustomErrorResponse; +import com.kospo.svcm.dto.req.Zwf0011tSaveRequest; +import com.kospo.svcm.dto.req.ZwfApprUpdateRequest; +import com.kospo.svcm.dto.res.PageResponse; +import com.kospo.svcm.dto.res.Zwf0011tResponse; +import com.kospo.svcm.service.ApprService; +import com.kospo.svcm.service.SapService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.ArraySchema; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.security.Principal; + +@Tag(name = "Sap Approval Api", description = "Sap 결재 관리") +@RestController +@RequiredArgsConstructor +@RequestMapping("/api") +public class SapApprController { + private final SapService sapService; + +// @Operation(summary = "SAP 결재 전체 조회", description = "임시전표 -> 확정전표 결재 조회") +// @ApiResponses({ +// @ApiResponse(description = "Success", responseCode = "200", +// content = @Content(mediaType = "application/json", array = @ArraySchema( +// schema = @Schema(oneOf = {Zwf0011tResponse.class}) +// ))), +// @ApiResponse(description = "Not found", responseCode = "404", +// content = @Content(mediaType = "text/plain", schema = @Schema(oneOf = +// {String.class}))), +// @ApiResponse(description = "Internal Error", responseCode = "500", +// content = @Content(mediaType = "application/json", schema = @Schema(oneOf = +// {CustomErrorResponse.class }))) +// }) +// @GetMapping("/sap/appr") +// public ResponseEntity findSearch( +// @Parameter(description = "결재상태") @RequestParam(required = false) String wkfst, +// @Parameter(description = "요청자") @RequestParam(required = false) String ernam, +// @Parameter(description = "등록시작일") @RequestParam(required = false, defaultValue = "1970-01-01") String erSdat, +// @Parameter(description = "등록종료일") @RequestParam(required = false, defaultValue = "2070-01-01") String erEdat, +// @Parameter(description = "페이지") @RequestParam("page") int page, +// @Parameter(description = "아이템갯수") @RequestParam("row") int row +// ) { +// Pageable pageable = PageRequest.of(page-1, row); +// return ResponseEntity.ok(sapService.findSearch(wkfst, ernam, erSdat, erEdat, pageable)); +// } + +// @Operation(summary = "SAP 결재 본인 승인 목록 조회", description = "결재시행 목록 조회") +// @ApiResponses({ +// @ApiResponse(description = "Success", responseCode = "200", +// content = @Content(mediaType = "application/json", array = @ArraySchema( +// schema = @Schema(oneOf = {Zwf0011tResponse.class}) +// ))), +// @ApiResponse(description = "Not found", responseCode = "404", +// content = @Content(mediaType = "text/plain", schema = @Schema(oneOf = +// {String.class}))), +// @ApiResponse(description = "Internal Error", responseCode = "500", +// content = @Content(mediaType = "application/json", schema = @Schema(oneOf = +// {CustomErrorResponse.class }))) +// }) +// @GetMapping("/sap/appr") +// public ResponseEntity findSearchBySabun( +// @Parameter(description = "결재상태") @RequestParam(required = false) String wkfst, +// @Parameter(description = "등록시작일") @RequestParam(required = false, defaultValue = "1970-01-01") String erSdat, +// @Parameter(description = "등록종료일") @RequestParam(required = false, defaultValue = "2070-01-01") String erEdat, +// @Parameter(description = "페이지") @RequestParam("page") int page, +// @Parameter(description = "아이템갯수") @RequestParam("row") int row +// ) { +// Pageable pageable = PageRequest.of(page-1, row); +// return ResponseEntity.ok(sapService.findSearchBySabun(wkfst, erSdat, erEdat, pageable)); +// } + +// @Operation(summary = "SAP 결재 상세 조회", description = "임시전표 -> 확정전표 결재 상세 조회") +// @ApiResponses({ +// @ApiResponse(description = "Success", responseCode = "200", +// content = @Content(mediaType = "application/json", +// schema = @Schema(oneOf = {PageResponse.class}) +// )), +// @ApiResponse(description = "Not found", responseCode = "404", +// content = @Content(mediaType = "text/plain", schema = @Schema(oneOf = +// {String.class}))), +// @ApiResponse(description = "Internal Error", responseCode = "500", +// content = @Content(mediaType = "application/json", schema = @Schema(oneOf = +// {CustomErrorResponse.class }))) +// }) +// @GetMapping("/sap/appr/{wkfid}") +// public ResponseEntity findDetail( +// @Parameter(description = "요청번호") String wfkid +// ) { +// +// return ResponseEntity.ok(sapService.getDetail(wfkid)); +// } + + @Operation(summary = "SAP 결재 저장", description = "임시전표 + sap 결재 저장") + @ApiResponses({ + @ApiResponse(description = "Success", responseCode = "200", + content = @Content(mediaType = "application/json", + schema = @Schema(oneOf = {PageResponse.class}) + )), + @ApiResponse(description = "Not found", responseCode = "404", + content = @Content(mediaType = "text/plain", schema = @Schema(oneOf = + {String.class}))), + @ApiResponse(description = "Internal Error", responseCode = "500", + content = @Content(mediaType = "application/json", schema = @Schema(oneOf = + {CustomErrorResponse.class }))) + }) + @PostMapping("/sap/appr") + public ResponseEntity save( + @RequestBody Zwf0011tSaveRequest zwf0011tSaveRequest + ) { + return ResponseEntity.ok(sapService.save(zwf0011tSaveRequest)); + } + + @Operation(summary = "SAP 결재상태 변경", description = "sap 결재상태 변경(결재승인 A, 결재반려 S") + @ApiResponses({ + @ApiResponse(description = "Success", responseCode = "200", + content = @Content(mediaType = "application/json", array = @ArraySchema( + schema = @Schema(oneOf = {Zwf0011tResponse.class}) + ))), + @ApiResponse(description = "Not found", responseCode = "404", + content = @Content(mediaType = "text/plain", schema = @Schema(oneOf = + {String.class}))), + @ApiResponse(description = "Internal Error", responseCode = "500", + content = @Content(mediaType = "application/json", schema = @Schema(oneOf = + {CustomErrorResponse.class }))) + }) + @PutMapping("/sap/appr") + public ResponseEntity approve( + @RequestBody ZwfApprUpdateRequest zwfApprUpdateRequest + ) { + return ResponseEntity.ok(sapService.approve(zwfApprUpdateRequest)); + } +// @Operation(summary = "본인 결재목록 조회", description = "가격조사 결재 조회") +// @ApiResponses({ +// @ApiResponse(description = "Success", responseCode = "200", +// content = @Content(mediaType = "application/json", schema = @Schema(oneOf = +// {PageResponse.class}) +// )), +// @ApiResponse(description = "Not found", responseCode = "404", +// content = @Content(mediaType = "text/plain", schema = @Schema(oneOf = +// {String.class}))), +// @ApiResponse(description = "Internal Error", responseCode = "500", +// content = @Content(mediaType = "application/json", schema = @Schema(oneOf = +// {CustomErrorResponse.class }))) +// }) +// @GetMapping("/appr/req") +// public ResponseEntity findReq( +// @Parameter(description = "page") @RequestParam("page") int page, +// @Parameter(description = "row") @RequestParam("row") int row, +// Principal principal +// ) { +// Pageable pageable = PageRequest.of(page -1, row); +// return ResponseEntity.ok(apprService.findByApprBySabun(principal.getName(), pageable)); +// } +// +// @Operation(summary = "결재 갱신", description = "결재 상태 갱신") +// @ApiResponses({ +// @ApiResponse(description = "Success", responseCode = "200", +// content = @Content(mediaType = "application/json", schema = @Schema(oneOf = +// {ApprReqResponse.class}))), +// @ApiResponse(description = "Not found", responseCode = "404", +// content = @Content(mediaType = "text/plain", schema = @Schema(oneOf = +// {String.class}))), +// @ApiResponse(description = "Internal Error", responseCode = "500", +// content = @Content(mediaType = "application/json", schema = @Schema(oneOf = +// {CustomErrorResponse.class }))) +// }) +// @PutMapping("/appr") +// public ResponseEntity save( +// @RequestBody ApprReqRequest apprReqRequest, +// Principal principal +// ) { +// return ResponseEntity.ok(apprService.stateUpdate(principal.getName(), apprReqRequest)); +// } + +} diff --git a/src/main/java/com/kospo/svcm/controller/SlipController.java b/src/main/java/com/kospo/svcm/controller/SlipController.java new file mode 100644 index 0000000..ab25707 --- /dev/null +++ b/src/main/java/com/kospo/svcm/controller/SlipController.java @@ -0,0 +1,122 @@ +package com.kospo.svcm.controller; + +import com.kospo.svcm.config.exception.CustomErrorResponse; +import com.kospo.svcm.config.utils.FileUtils; +import com.kospo.svcm.dto.req.SlipSaveRequest; +import com.kospo.svcm.dto.res.EstimateListResponse; +import com.kospo.svcm.service.EstimateService; +import com.kospo.svcm.service.PrcsService; +import com.kospo.svcm.service.SlipService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.ArraySchema; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.security.Principal; + +@Tag(name = "slip Api", description = "전표 관리") +@RestController +@RequiredArgsConstructor +@RequestMapping("/api") +public class SlipController { + private final EstimateService estimateService; + private final PrcsService prcsService; + private final FileUtils fileUtils; + private final SlipService slipService; + +// @Operation(summary = "전표 목록 조회", description = "임시, 확정 전표 조회") +// @ApiResponses({ +// @ApiResponse(description = "Success", responseCode = "200", +// content = @Content(mediaType = "application/json", +// schema = @Schema(oneOf = +// {Pageable.class}))), +// @ApiResponse(description = "Not found", responseCode = "404", +// content = @Content(mediaType = "text/plain", schema = @Schema(oneOf = +// {String.class}))), +// @ApiResponse(description = "Internal Error", responseCode = "500", +// content = @Content(mediaType = "application/json", schema = @Schema(oneOf = +// {CustomErrorResponse.class }))) +// }) +// @GetMapping("/slip/page") +// public ResponseEntity findExternalEstimateSearchPage( +// @Parameter(description = "페이지") @RequestParam("page") int page, +// @Parameter(description = "아이템갯수") @RequestParam("row") int row, +// Principal principal +// ) { +// Pageable pageable = PageRequest.of(page -1, row); +// return null; +// } + + @Operation(summary = "전표 상세 조회", description = "임시, 확정 전표 상세 조회") + @ApiResponses({ + @ApiResponse(description = "Success", responseCode = "200", + content = @Content(mediaType = "application/json", + schema = @Schema(oneOf = + {Pageable.class}))), + @ApiResponse(description = "Not found", responseCode = "404", + content = @Content(mediaType = "text/plain", schema = @Schema(oneOf = + {String.class}))), + @ApiResponse(description = "Internal Error", responseCode = "500", + content = @Content(mediaType = "application/json", schema = @Schema(oneOf = + {CustomErrorResponse.class }))) + }) + @GetMapping("/slip/page/{contNo}") + public ResponseEntity findByContNo( + @Parameter(description = "계약번호") @PathVariable("contNo") String contNo, + Principal principal + ) { + return ResponseEntity.ok(slipService.findByContNo(contNo)); + } + + @Operation(summary = "임시전표 저장", description = "임시전표 (계약중 대상자) 저장") + @ApiResponses({ + @ApiResponse(description = "Success", responseCode = "200", + content = @Content(mediaType = "application/json", array = @ArraySchema( + schema = @Schema(oneOf = + {EstimateListResponse.class}) + ))), + @ApiResponse(description = "Not found", responseCode = "404", + content = @Content(mediaType = "text/plain", schema = @Schema(oneOf = + {String.class}))), + @ApiResponse(description = "Internal Error", responseCode = "500", + content = @Content(mediaType = "application/json", schema = @Schema(oneOf = + {CustomErrorResponse.class}))) + }) + @PostMapping("/slip") + public ResponseEntity save( + @RequestBody SlipSaveRequest slipSaveRequest + ) { + return ResponseEntity.ok(slipService.save(slipSaveRequest)); + } + + + @Operation(summary = "임시전표삭제 삭제", description = "임시전표삭제 삭제") + @ApiResponses({ + @ApiResponse(description = "Success", responseCode = "200", + content = @Content(mediaType = "application/json", schema = @Schema(oneOf = + {String.class}))), + @ApiResponse(description = "Not found", responseCode = "404", + content = @Content(mediaType = "text/plain", schema = @Schema(oneOf = + {String.class}))), + @ApiResponse(description = "Internal Error", responseCode = "500", + content = @Content(mediaType = "application/json", schema = @Schema(oneOf = + {CustomErrorResponse.class}))) + }) + @DeleteMapping("/slip/{contNo}") + public ResponseEntity delete( + @Parameter(description = "계약번호") @PathVariable String contNo, + Principal principal + ) { + slipService.delete(contNo); + return ResponseEntity.ok("삭제 되었습니다."); + } +} diff --git a/src/main/java/com/kospo/svcm/controller/UserController.java b/src/main/java/com/kospo/svcm/controller/UserController.java new file mode 100644 index 0000000..7802e3a --- /dev/null +++ b/src/main/java/com/kospo/svcm/controller/UserController.java @@ -0,0 +1,65 @@ +package com.kospo.svcm.controller; + +import com.kospo.svcm.config.exception.CustomErrorResponse; +import com.kospo.svcm.model.User; +import com.kospo.svcm.service.UserService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; + +import java.security.Principal; + +@RestController +@Tag(name = "User Api", description = "사용자 관리") +@RequestMapping("/api") +@RequiredArgsConstructor +public class UserController { + private final UserService userService; + + @Operation(summary = "현재 사용자 정보 조회", description = "현재 사용자의 인사정보를 조회") + @ApiResponses({ + @ApiResponse(description = "Success", responseCode = "200", + content = @io.swagger.v3.oas.annotations.media.Content(mediaType = "application/json", schema = @Schema(oneOf = + {User.class}))), + @ApiResponse(description = "Not found", responseCode = "404", + content = @io.swagger.v3.oas.annotations.media.Content(mediaType = "text/plain", schema = @Schema(oneOf = + {String.class}))), + @ApiResponse(description = "Internal Error", responseCode = "500", + content = @io.swagger.v3.oas.annotations.media.Content(mediaType = "application/json", schema = @Schema(oneOf = + {CustomErrorResponse.class }))) + }) + @GetMapping("/user/info") + public ResponseEntity userInfo( + Principal principal) { + System.out.println(principal.getName()); + return ResponseEntity.ok(userService.findOne(principal.getName())); + } + + @Operation(summary = "직원검색", description = "이름 또는 사번으로 직원검색") + @ApiResponses({ + @ApiResponse(description = "Success", responseCode = "200", + content = @io.swagger.v3.oas.annotations.media.Content(mediaType = "application/json", schema = @Schema(oneOf = + {User.class}))), + @ApiResponse(description = "Not found", responseCode = "404", + content = @io.swagger.v3.oas.annotations.media.Content(mediaType = "text/plain", schema = @Schema(oneOf = + {String.class}))), + @ApiResponse(description = "Internal Error", responseCode = "500", + content = @io.swagger.v3.oas.annotations.media.Content(mediaType = "application/json", schema = @Schema(oneOf = + {CustomErrorResponse.class }))) + }) + @GetMapping("/user") +// @PreAuthorize("hasRole('USER')") + public ResponseEntity findByName( + @Parameter(description = "이름") @RequestParam String name, + Principal principal) { + return ResponseEntity.ok(userService.findByNameContaining(name)); + } + +} diff --git a/src/main/java/com/kospo/svcm/dto/req/ApprReqRequest.java b/src/main/java/com/kospo/svcm/dto/req/ApprReqRequest.java new file mode 100644 index 0000000..ce40c9d --- /dev/null +++ b/src/main/java/com/kospo/svcm/dto/req/ApprReqRequest.java @@ -0,0 +1,31 @@ +package com.kospo.svcm.dto.req; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.kospo.svcm.model.ApprReq; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; + +import java.io.Serializable; + +/** + * DTO for {@link ApprReq} + */ +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@JsonIgnoreProperties(ignoreUnknown = true) +@Schema(name = "ApprReqRequest", description = "현재 결재자") +public class ApprReqRequest implements Serializable { + @Schema(name = "apprNo", description = "결재번호") + String apprNo; + @Schema(name = "apprOrd", description = "결재순서") + Integer apprOrd; + @Schema(name = "sabun", description = "사번") + String sabun; + @Schema(name = "apprStatCd", description = "결재상태코드") + String apprStatCd; + @Schema(name = "reason", description = "사유 (반려일시 상태코드 0400)") + String reason; +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/dto/req/BusinessRePasswdRequest.java b/src/main/java/com/kospo/svcm/dto/req/BusinessRePasswdRequest.java new file mode 100644 index 0000000..63589f3 --- /dev/null +++ b/src/main/java/com/kospo/svcm/dto/req/BusinessRePasswdRequest.java @@ -0,0 +1,32 @@ +package com.kospo.svcm.dto.req; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.kospo.svcm.model.Business; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + * DTO for {@link Business} + */ + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Builder +@JsonIgnoreProperties(ignoreUnknown = true) +@Schema(name = "BusinessRePasswdRequest", description = "사업자 비밀번호 변경") +public class BusinessRePasswdRequest implements Serializable { + @Schema(name = "bizNo", description = "사업자번호") + String bizNo; + @Schema(name = "oldPwd", description = "이전비밀번호(비밀번호 변경시)") + String oldPwd; + @Schema(name = "pwd", description = "비밀번호 (삭제시 비밀번호 확인용으로도 사용됨)") + String pwd; + @Schema(name = "rePwd", description = "비밀번호 재확인") + String rePwd; +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/dto/req/BusinessRequest.java b/src/main/java/com/kospo/svcm/dto/req/BusinessRequest.java new file mode 100644 index 0000000..f049398 --- /dev/null +++ b/src/main/java/com/kospo/svcm/dto/req/BusinessRequest.java @@ -0,0 +1,38 @@ +package com.kospo.svcm.dto.req; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.kospo.svcm.model.Business; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + * DTO for {@link Business} + */ + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Builder +@JsonIgnoreProperties(ignoreUnknown = true) +@Schema(name = "BusinessRequest", description = "사업자") +public class BusinessRequest implements Serializable { + @Schema(name = "bizNo", description = "사업자번호") + String bizNo; + @Schema(name = "oldPwd", description = "이전비밀번호(비밀번호 변경시)") + String oldPwd; + @Schema(name = "pwd", description = "비밀번호 (삭제시 비밀번호 확인용으로도 사용됨)") + String pwd; + @Schema(name = "rePwd", description = "비밀번호 재확인") + String rePwd; + @Schema(name = "compNm", description = "업체명") + String compNm; + @Schema(name = "repNm", description = "대표자명") + String repNm; + @Schema(name = "email", description = "이메일") + String email; +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/dto/req/BusinessUpdateRequest.java b/src/main/java/com/kospo/svcm/dto/req/BusinessUpdateRequest.java new file mode 100644 index 0000000..745fde2 --- /dev/null +++ b/src/main/java/com/kospo/svcm/dto/req/BusinessUpdateRequest.java @@ -0,0 +1,32 @@ +package com.kospo.svcm.dto.req; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.kospo.svcm.model.Business; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + * DTO for {@link Business} + */ + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Builder +@JsonIgnoreProperties(ignoreUnknown = true) +@Schema(name = "BusinessUpdateRequest", description = "사업자") +public class BusinessUpdateRequest implements Serializable { + @Schema(name = "bizNo", description = "사업자번호") + String bizNo; + @Schema(name = "compNm", description = "업체명") + String compNm; + @Schema(name = "repNm", description = "대표자명") + String repNm; + @Schema(name = "email", description = "이메일") + String email; +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/dto/req/CodeRequest.java b/src/main/java/com/kospo/svcm/dto/req/CodeRequest.java new file mode 100644 index 0000000..c10087e --- /dev/null +++ b/src/main/java/com/kospo/svcm/dto/req/CodeRequest.java @@ -0,0 +1,28 @@ +package com.kospo.svcm.dto.req; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Builder +@JsonIgnoreProperties(ignoreUnknown = true) +@Schema(name = "CodeDto", description = "코드") +public class CodeRequest { + @Schema(name = "id", description = "아이디") + private Integer id; + @Schema(name = "cd", description = "코드") + private String cd; + @Schema(name = "nm", description = "코드명") + private String nm; + @Schema(name = "desc", description = "설명") + private String desc; + @Schema(name = "useYn", description = "사용여부") + private Boolean useYn; + +} diff --git a/src/main/java/com/kospo/svcm/dto/req/ContSaveRequest.java b/src/main/java/com/kospo/svcm/dto/req/ContSaveRequest.java new file mode 100644 index 0000000..e7bf5fe --- /dev/null +++ b/src/main/java/com/kospo/svcm/dto/req/ContSaveRequest.java @@ -0,0 +1,53 @@ +package com.kospo.svcm.dto.req; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.kospo.svcm.model.Cont; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; + +import java.io.Serializable; +import java.util.List; + +/** + * DTO for {@link Cont} + */ +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@JsonIgnoreProperties(ignoreUnknown = true) +@Schema(name = "ContSaveRequest", description = "계약관리 저장") +public class ContSaveRequest implements Serializable { + @Schema(name = "bizNo", description = "사업자번호") + String bizNo; + @Schema(name = "prcsNo", description = "가겨조사 번호") + String prcsNo; + @Schema(name = "title", description = "계약명") + String title; + @Schema(name = "compNm", description = "업체명") + String compNm; + @Schema(name = "contSdat", description = "계약시작일") + String contSdat; + @Schema(name = "contEdat", description = "계약종료일") + String contEdat; + @Schema(name = "excYn", description = "가격조사 예외") + boolean excYn; + @Schema(name = "reason", description = "가격조사 예외사유") + String reason; + List contAtts; + + @Getter + @Setter + @NoArgsConstructor + @AllArgsConstructor + @Builder + @JsonIgnoreProperties(ignoreUnknown = true) + @Schema(name = "ContAttSaveRequest", description = "계약 문서") + public static class ContAttSaveRequest implements Serializable { + @Schema(name = "logiFnm", description = "논리파일명") + String logiFnm; + @Schema(name = "data", description = "base64") + String data; + } +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/dto/req/ContUpdateRequest.java b/src/main/java/com/kospo/svcm/dto/req/ContUpdateRequest.java new file mode 100644 index 0000000..6a20411 --- /dev/null +++ b/src/main/java/com/kospo/svcm/dto/req/ContUpdateRequest.java @@ -0,0 +1,56 @@ +package com.kospo.svcm.dto.req; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.kospo.svcm.model.Cont; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; + +import java.io.Serializable; +import java.util.List; + +/** + * DTO for {@link Cont} + */ +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@JsonIgnoreProperties(ignoreUnknown = true) +@Schema(name = "ContUpdateRequest", description = "계약관리 수정") +public class ContUpdateRequest implements Serializable { + @Schema(name = "contNo", description = "계약번호") + String contNo; + @Schema(name = "bizNo", description = "사업자번호") + String bizNo; + @Schema(name = "compNm", description = "업체명") + String compNm; + @Schema(name = "signDt", description = "계약체결일") + String signDt; + @Schema(name = "contAmt", description = "계약금액") + Integer contAmt; + @Schema(name = "contSdat", description = "계약시작일") + String contSdat; + @Schema(name = "contEdat", description = "계약종료일") + String contEdat; + List contAtts; + + @Getter + @Setter + @NoArgsConstructor + @AllArgsConstructor + @Builder + @JsonIgnoreProperties(ignoreUnknown = true) + @Schema(name = "ContAttUpdateResponse", description = "계약 문서") + public static class ContAttUpdateResponse implements Serializable { + @Schema(name = "contNo", description = "계약번호") + String contNo; + @Schema(name = "fileOrd", description = "파일순서") + Integer fileOrd; + @Schema(name = "logiFnm", description = "논리파일명") + String logiFnm; + @Schema(name = "data", description = "base64") + String data; + + } +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/dto/req/DtlSpecExcelRequest.java b/src/main/java/com/kospo/svcm/dto/req/DtlSpecExcelRequest.java new file mode 100644 index 0000000..8d03b01 --- /dev/null +++ b/src/main/java/com/kospo/svcm/dto/req/DtlSpecExcelRequest.java @@ -0,0 +1,19 @@ +package com.kospo.svcm.dto.req; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; + +import java.io.Serializable; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@JsonIgnoreProperties(ignoreUnknown = true) +@Schema(name = "DtlSpecExcelRequest", description = "엑셀 업로드") +public class DtlSpecExcelRequest implements Serializable { + @Schema(name = "data", description = "엑셀 파일 base64") + String data; +} diff --git a/src/main/java/com/kospo/svcm/dto/req/EstimateListSaveRequest.java b/src/main/java/com/kospo/svcm/dto/req/EstimateListSaveRequest.java new file mode 100644 index 0000000..1cbb4e6 --- /dev/null +++ b/src/main/java/com/kospo/svcm/dto/req/EstimateListSaveRequest.java @@ -0,0 +1,40 @@ +package com.kospo.svcm.dto.req; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.kospo.svcm.model.Estimate; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; + +import java.io.Serializable; +import java.util.List; + +/** + * DTO for {@link Estimate} + */ +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@JsonIgnoreProperties(ignoreUnknown = true) +@Schema(name = "EstimateListSaveRequest", description = "견적 저장") +public class EstimateListSaveRequest implements Serializable { + List estimates; + List pbAtts; + + @Getter + @Setter + @NoArgsConstructor + @AllArgsConstructor + @Builder + @JsonIgnoreProperties(ignoreUnknown = true) + @Schema(name = "PbAttSaveRequest", description = "견적서 저장") + public static class PbAttSaveRequest implements Serializable { + @Schema(name = "logiFnm", description = "논리파일명") + String logiFnm; + @Schema(name = "physFnm", description = "물리파일명") + String physFnm; + @Schema(name = "data", description = "base64") + String data; + } +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/dto/req/EstimateListUpdateRequest.java b/src/main/java/com/kospo/svcm/dto/req/EstimateListUpdateRequest.java new file mode 100644 index 0000000..d736272 --- /dev/null +++ b/src/main/java/com/kospo/svcm/dto/req/EstimateListUpdateRequest.java @@ -0,0 +1,46 @@ +package com.kospo.svcm.dto.req; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.kospo.svcm.model.Estimate; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; + +import java.io.Serializable; +import java.util.List; + +/** + * DTO for {@link Estimate} + */ +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@JsonIgnoreProperties(ignoreUnknown = true) +@Schema(name = "EstimateListUpdateRequest", description = "견적 수정") +public class EstimateListUpdateRequest implements Serializable { + List estimates; + List pbAtts; + + @Getter + @Setter + @NoArgsConstructor + @AllArgsConstructor + @Builder + @JsonIgnoreProperties(ignoreUnknown = true) + @Schema(name = "PbAttUpdateRequest", description = "견적서 수정") + public static class PbAttUpdateRequest implements Serializable { + @Schema(name = "prcsNo", description = "가격조사번호") + String prcsNo; + @Schema(name = "bizNo", description = "사업자번호") + String bizNo; + @Schema(name = "fileOrd", description = "파일순서") + Integer fileOrd; + @Schema(name = "logiFnm", description = "논리파일명") + String logiFnm; + @Schema(name = "physFnm", description = "물리파일명") + String physFnm; + @Schema(name = "data", description = "base64") + String data; + } +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/dto/req/EstimateSaveRequest.java b/src/main/java/com/kospo/svcm/dto/req/EstimateSaveRequest.java new file mode 100644 index 0000000..7573d5c --- /dev/null +++ b/src/main/java/com/kospo/svcm/dto/req/EstimateSaveRequest.java @@ -0,0 +1,35 @@ +package com.kospo.svcm.dto.req; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.kospo.svcm.model.Estimate; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; + +import java.io.Serializable; + +/** + * DTO for {@link Estimate} + */ +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@JsonIgnoreProperties(ignoreUnknown = true) +@Schema(name = "EstimateSaveRequest", description = "견적 저장") +public class EstimateSaveRequest implements Serializable { + @Schema(name = "bizNo", description = "사업자번호") + String bizNo; + @Schema(name = "prcsNo", description = "가격조사번호") + String prcsNo; + @Schema(name = "dtlSpNo", description = "견적번호") + String dtlSpNo; + @Schema(name = "mngNm", description = "담당자명") + String mngNm; + @Schema(name = "unitPrc", description = "단가") + Integer unitPrc; + @Schema(name = "amt", description = "금액") + Integer amt; + @Schema(name = "regDt", description = "등록일시") + String regDt; +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/dto/req/EstimateUpdateRequest.java b/src/main/java/com/kospo/svcm/dto/req/EstimateUpdateRequest.java new file mode 100644 index 0000000..da42d10 --- /dev/null +++ b/src/main/java/com/kospo/svcm/dto/req/EstimateUpdateRequest.java @@ -0,0 +1,39 @@ +package com.kospo.svcm.dto.req; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.kospo.svcm.model.Estimate; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; + +import java.io.Serializable; +import java.util.List; + +/** + * DTO for {@link Estimate} + */ +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@JsonIgnoreProperties(ignoreUnknown = true) +@Schema(name = "EstimateUpdateRequest", description = "견적 수정") +public class EstimateUpdateRequest implements Serializable { + @Schema(name = "estNo", description = "견적관리번호") + String estNo; + @Schema(name = "bizNo", description = "사업자번호") + String bizNo; + @Schema(name = "prcsNo", description = "가격조사번호") + String prcsNo; + @Schema(name = "dtlSpNo", description = "견적번호") + String dtlSpNo; + @Schema(name = "mngNm", description = "담당자명") + String mngNm; + @Schema(name = "unitPrc", description = "단가") + Integer unitPrc; + @Schema(name = "amt", description = "금액") + Integer amt; + @Schema(name = "regDt", description = "등록일시") + String regDt; + +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/dto/req/GrpCodeSaveRequest.java b/src/main/java/com/kospo/svcm/dto/req/GrpCodeSaveRequest.java new file mode 100644 index 0000000..52673e4 --- /dev/null +++ b/src/main/java/com/kospo/svcm/dto/req/GrpCodeSaveRequest.java @@ -0,0 +1,27 @@ +package com.kospo.svcm.dto.req; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.kospo.svcm.model.GrpCode; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; + +import java.io.Serializable; + +/** + * DTO for {@link GrpCode} + */ +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@JsonIgnoreProperties(ignoreUnknown = true) +@Schema(name = "GrpCodeDto", description = "그룹코드 요청") +public class GrpCodeSaveRequest implements Serializable { + @Schema(name = "nm", description = "코드명") + String nm; + @Schema(name = "desc", description = "설명") + String desc; + @Schema(name = "useYn", description = "사용여부(수정)") + Boolean useYn; +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/dto/req/GrpCodeUpdateRequest.java b/src/main/java/com/kospo/svcm/dto/req/GrpCodeUpdateRequest.java new file mode 100644 index 0000000..76d9b75 --- /dev/null +++ b/src/main/java/com/kospo/svcm/dto/req/GrpCodeUpdateRequest.java @@ -0,0 +1,29 @@ +package com.kospo.svcm.dto.req; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.kospo.svcm.model.GrpCode; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; + +import java.io.Serializable; + +/** + * DTO for {@link GrpCode} + */ +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@JsonIgnoreProperties(ignoreUnknown = true) +@Schema(name = "GrpCodeDto", description = "그룹코드 요청") +public class GrpCodeUpdateRequest implements Serializable { + @Schema(name = "id", description = "코드 그룹 아이디(수정)") + Integer id; + @Schema(name = "nm", description = "코드명") + String nm; + @Schema(name = "desc", description = "설명") + String desc; + @Schema(name = "useYn", description = "사용여부(수정)") + Boolean useYn; +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/dto/req/LoginRequest.java b/src/main/java/com/kospo/svcm/dto/req/LoginRequest.java new file mode 100644 index 0000000..bcbcd1f --- /dev/null +++ b/src/main/java/com/kospo/svcm/dto/req/LoginRequest.java @@ -0,0 +1,27 @@ +package com.kospo.svcm.dto.req; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.kospo.svcm.model.Business; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + * DTO for {@link Business} + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +@Builder +@JsonIgnoreProperties(ignoreUnknown = true) +@Schema(name = "LoginRequest", description = "로그인") +public class LoginRequest implements Serializable { + @Schema(name = "bizNo", description = "사업자번호") + private String bizNo; + @Schema(name = "pwd", description = "비밀번호") + private String pwd; +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/dto/req/PrcsSaveRequest.java b/src/main/java/com/kospo/svcm/dto/req/PrcsSaveRequest.java new file mode 100644 index 0000000..87788ee --- /dev/null +++ b/src/main/java/com/kospo/svcm/dto/req/PrcsSaveRequest.java @@ -0,0 +1,109 @@ +package com.kospo.svcm.dto.req; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.kospo.svcm.model.Prcs; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; + +import java.io.Serializable; +import java.util.List; + +/** + * DTO for {@link Prcs} + */ +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@JsonIgnoreProperties(ignoreUnknown = true) +@Schema(name = "PrcsSaveRequest", description = "가격조사 저장") +public class PrcsSaveRequest implements Serializable { + @Schema(name = "cateCd", description = "분야") + String cateCd; + @Schema(name = "title", description = "제목") + String title; + @Schema(name = "content", description = "내용") + String content; + @Schema(name = "regSdat", description = "등록시작일") + String regSdat; + @Schema(name = "regEdat", description = "등록종료일") + String regEdat; + @Schema(name = "prvYn", description = "비공개여부") + Boolean prvYn; + @Schema(name = "prvRsn", description = "비공개사유") + String prvRsn; + @Schema(name = "prvPwd", description = "비공개비밀번호") + String prvPwd; + @Schema(name = "aiYn", description = "ai검증여부") + Boolean aiYn; + List prcsAtts; + List dtlSpecs; + List apprReqs; + List prcsBizs; + + @Getter + @Setter + @NoArgsConstructor + @AllArgsConstructor + @Builder + @JsonIgnoreProperties(ignoreUnknown = true) + @Schema(name = "PrcsAttSaveRequest", description = "가격조사 첨부파일") + public static class PrcsAttSaveRequest implements Serializable { + String logiFnm; + @Schema(name = "data", description = "base64") + String data; + + } + + @Getter + @Setter + @NoArgsConstructor + @AllArgsConstructor + @Builder + @JsonIgnoreProperties(ignoreUnknown = true) + @Schema(name = "DtlSpecSaveRequest", description = "상세규격") + public static class DtlSpecSaveRequest implements Serializable { + @Schema(name = "itemNm", description = "품명") + String itemNm; + @Schema(name = "spec", description = "규격") + String spec; + @Schema(name = "unit", description = "단위") + String unit; + @Schema(name = "qty", description = "수량") + Integer qty; + + } + + @Getter + @Setter + @NoArgsConstructor + @AllArgsConstructor + @Builder + @JsonIgnoreProperties(ignoreUnknown = true) + @Schema(name = "ApprReqSaveRequest", description = "결재요청") + public static class ApprReqSaveRequest implements Serializable { + @Schema(name = "gubunCd", description = "구분코드") + String gubunCd; + @Schema(name = "sabun", description = "사번") + String sabun; + @Schema(name = "name", description = "이름") + String name; + @Schema(name = "attendCd", description = "근태코드") + String attendCd; + } + + @Getter + @Setter + @NoArgsConstructor + @AllArgsConstructor + @Builder + @JsonIgnoreProperties(ignoreUnknown = true) + @Schema(name = "PrcsBizSaveRequest", description = "입찰사업자") + public static class PrcsBizSaveRequest implements Serializable { + @Schema(name = "bizNo", description = "사업자번호") + String bizNo; + @Schema(name = "email", description = "이름") + String email; + } +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/dto/req/PrcsUpdateRequest.java b/src/main/java/com/kospo/svcm/dto/req/PrcsUpdateRequest.java new file mode 100644 index 0000000..8bd9c2e --- /dev/null +++ b/src/main/java/com/kospo/svcm/dto/req/PrcsUpdateRequest.java @@ -0,0 +1,125 @@ +package com.kospo.svcm.dto.req; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.kospo.svcm.model.Prcs; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; + +import java.io.Serializable; +import java.util.List; + +/** + * DTO for {@link Prcs} + */ +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@JsonIgnoreProperties(ignoreUnknown = true) +@Schema(name = "PrcsUpdateRequest", description = "가격조사 수정") +public class PrcsUpdateRequest implements Serializable { + @Schema(name = "prcsNo", description = "가격조사 번호") + String prcsNo; + @Schema(name = "cateCd", description = "분야") + String cateCd; + @Schema(name = "title", description = "제목") + String title; + @Schema(name = "content", description = "내용") + String content; + @Schema(name = "regSdat", description = "등록시작일") + String regSdat; + @Schema(name = "regEdat", description = "등록종료일") + String regEdat; + @Schema(name = "prvYn", description = "비공개여부") + Boolean prvYn; + @Schema(name = "prvRsn", description = "비공개사유") + String prvRsn; + @Schema(name = "prvPwd", description = "비공개비밀번호") + String prvPwd; + @Schema(name = "aiYn", description = "ai검증여부") + Boolean aiYn; + List prcsAtts; + List dtlSpecs; + List apprReqs; + List prcsBizs; + + @Getter + @Setter + @NoArgsConstructor + @AllArgsConstructor + @Builder + @JsonIgnoreProperties(ignoreUnknown = true) + @Schema(name = "PrcsAttRequest", description = "가격조사 첨부파일") + public static class PrcsAttUpdateRequest implements Serializable { + @Schema(name = "prcsNo", description = "가격조사 번호") + String prcsNo; + @Schema(name = "fileOrd", description = "파일순서") + Integer fileOrd; + @Schema(name = "logiFnm", description = "논리파일명") + String logiFnm; + @Schema(name = "data", description = "base64") + String data; + + + } + + @Getter + @Setter + @NoArgsConstructor + @AllArgsConstructor + @Builder + @JsonIgnoreProperties(ignoreUnknown = true) + @Schema(name = "DtlSpecUpdateRequest", description = "상세규격") + public static class DtlSpecUpdateRequest implements Serializable { + @Schema(name = "prcsNo", description = "가격조사 번호") + String prcsNo; + @Schema(name = "dtlSpNo", description = "상세규격 번호") + String dtlSpNo; + @Schema(name = "itemNm", description = "품명") + String itemNm; + @Schema(name = "spec", description = "규격") + String spec; + @Schema(name = "unit", description = "단위") + String unit; + @Schema(name = "qty", description = "수량") + Integer qty; + + } + + @Getter + @Setter + @NoArgsConstructor + @AllArgsConstructor + @Builder + @JsonIgnoreProperties(ignoreUnknown = true) + @Schema(name = "ApprReqUpdateRequest", description = "결재요청") + public static class ApprReqUpdateRequest implements Serializable { + @Schema(name = "apprNO", description = "결재번호") + String apprNo; + @Schema(name = "apprOrd", description = "결재순번") + Integer apprOrd; + @Schema(name = "gubunCd", description = "구분코드") + String gubunCd; + @Schema(name = "sabun", description = "사번") + String sabun; + @Schema(name = "name", description = "이름") + String name; + @Schema(name = "attendCd", description = "근태코드") + String attendCd; + } + + @Getter + @Setter + @NoArgsConstructor + @AllArgsConstructor + @Builder + @JsonIgnoreProperties(ignoreUnknown = true) + @Schema(name = "PrcsBizUpdateRequest", description = "입찰사업자") + public static class PrcsBizUpdateRequest implements Serializable { + @Schema(name = "bizNo", description = "사업자번호") + String bizNo; + @Schema(name = "email", description = "이름") + String email; + } +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/dto/req/RegisterRequest.java b/src/main/java/com/kospo/svcm/dto/req/RegisterRequest.java new file mode 100644 index 0000000..8971eb4 --- /dev/null +++ b/src/main/java/com/kospo/svcm/dto/req/RegisterRequest.java @@ -0,0 +1,35 @@ +package com.kospo.svcm.dto.req; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.kospo.svcm.model.Business; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + * DTO for {@link Business} + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +@Builder +@JsonIgnoreProperties(ignoreUnknown = true) +@Schema(name = "RegisterRequest", description = "회원가입") +public class RegisterRequest implements Serializable { + @Schema(name = "bizNo", description = "사업자번호") + private String bizNo; + @Schema(name = "pwd", description = "비밀번호") + private String pwd; + @Schema(name = "rePwd", description = "비밀번호") + private String rePwd; + @Schema(name = "compNm", description = "업체명") + private String compNm; + @Schema(name = "repNm", description = "대표자명") + String repNm; + @Schema(name = "email", description = "이메일") + String email; +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/dto/req/RoleRequest.java b/src/main/java/com/kospo/svcm/dto/req/RoleRequest.java new file mode 100644 index 0000000..b913cf1 --- /dev/null +++ b/src/main/java/com/kospo/svcm/dto/req/RoleRequest.java @@ -0,0 +1,21 @@ +package com.kospo.svcm.dto.req; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@JsonIgnoreProperties(ignoreUnknown = true) +@Schema(name = "RoleDto", description = "권한부여 요청") +public class RoleRequest { + @Schema(name = "sabun", description = "사번") + private String sabun; + @Schema(name = "roleId", description = "권한명") + private String roleId; + @Schema(name = "ip", description = "아이피") + private String ip; +} diff --git a/src/main/java/com/kospo/svcm/dto/req/SlipSaveRequest.java b/src/main/java/com/kospo/svcm/dto/req/SlipSaveRequest.java new file mode 100644 index 0000000..09a9118 --- /dev/null +++ b/src/main/java/com/kospo/svcm/dto/req/SlipSaveRequest.java @@ -0,0 +1,61 @@ +package com.kospo.svcm.dto.req; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; + +import java.io.Serializable; +import java.util.List; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@JsonIgnoreProperties(ignoreUnknown = true) +@Schema(name = "SlipSaveRequest", description = "임시전표 생성") +public class SlipSaveRequest implements Serializable { + @Schema(name = "contNo", description = "계약번호") + String contNo; + @Schema(name = "lifnr", description = "계약대상자") + String lifnr; + @Schema(name = "gsber", description = "사업영역코드") + String gsber; + @Schema(name = "wrbtrS", description = "전기금액(공급가액)") + String wrbtrS; + @Schema(name = "mwskz", description = "세금코드") + String mwskz; + @Schema(name = "waers", description = "통화코드") + String waers; + @Schema(name = "bldat", description = "증빙일") + String bldat; + @Schema(name = "budat", description = "전기일") + String budat; + @Schema(name = "hkont", description = "계정과목코드") + String hkont; + @Schema(name = "kostl", description = "코스트센터코드") + String kostl; + @Schema(name = "projk", description = "wbs요소코드") + String projk; + @Schema(name = "wrbtr", description = "전기금액(공급가액+세액") + String wrbtr; + @Schema(name = "bankl", description = "은행코드") + String bankl; + @Schema(name = "bankn", description = "계좌번호") + String bankn; + List slipAtts; + + @Getter + @Setter + @NoArgsConstructor + @AllArgsConstructor + @Builder + @JsonIgnoreProperties(ignoreUnknown = true) + @Schema(name = "SlipAttSaveRequest", description = "가격조사 첨부파일") + public static class SlipAttSaveRequest implements Serializable { + String logiFnm; + @Schema(name = "data", description = "base64") + String data; + + } +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/dto/req/Zwf0011tSaveRequest.java b/src/main/java/com/kospo/svcm/dto/req/Zwf0011tSaveRequest.java new file mode 100644 index 0000000..04c0330 --- /dev/null +++ b/src/main/java/com/kospo/svcm/dto/req/Zwf0011tSaveRequest.java @@ -0,0 +1,30 @@ +package com.kospo.svcm.dto.req; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.kospo.svcm.model.Zwf0011t; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; + +import java.io.Serializable; +import java.util.List; + +/** + * DTO for {@link Zwf0011t} + */ +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@JsonIgnoreProperties(ignoreUnknown = true) +@Schema(name = "Zwf0011tSaveRequest", description = "SAP 결재 마스터") +public class Zwf0011tSaveRequest implements Serializable { + @Schema(name = "belnr", description = "전표번호") + String belnr; + @Schema(name = "wkfid", description = "요청번호 (협조용)") + String wkfid; + @Schema(name = "wkftx", description = "결재제목") + String wkftx; + + List apprs; +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/dto/req/ZwfApprGrpSaveRequest.java b/src/main/java/com/kospo/svcm/dto/req/ZwfApprGrpSaveRequest.java new file mode 100644 index 0000000..03f5457 --- /dev/null +++ b/src/main/java/com/kospo/svcm/dto/req/ZwfApprGrpSaveRequest.java @@ -0,0 +1,27 @@ +package com.kospo.svcm.dto.req; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.kospo.svcm.model.Zwf0011t; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; + +import java.io.Serializable; +import java.util.List; + +/** + * DTO for {@link Zwf0011t} + */ +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@JsonIgnoreProperties(ignoreUnknown = true) +@Schema(name = "ZwfApprRequest", description = "SAP 결재 마스터") +public class ZwfApprGrpSaveRequest implements Serializable { + @Schema(name = "label", description = "명칭") + String label; + @Schema(name = "value", description = "결재선") + List value; + +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/dto/req/ZwfApprSaveRequest.java b/src/main/java/com/kospo/svcm/dto/req/ZwfApprSaveRequest.java new file mode 100644 index 0000000..7a26f25 --- /dev/null +++ b/src/main/java/com/kospo/svcm/dto/req/ZwfApprSaveRequest.java @@ -0,0 +1,32 @@ +package com.kospo.svcm.dto.req; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.kospo.svcm.model.Zwf0012t; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; + +import java.io.Serializable; + +/** + * DTO for {@link Zwf0012t} + */ +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@JsonIgnoreProperties(ignoreUnknown = true) +@Schema(name = "ZwfApprSaveRequest", description = "SAP 결재선") +public class ZwfApprSaveRequest implements Serializable { + @Schema(name = "lineclsf", description = "결재구분") + String lineclsf; + @Schema(name = "bname", description = "사번") + String bname; + @Schema(name = "gubun", description = "결재선 구분") + String gubun; + @Schema(name = "abscd", description = "사유코드(근태)") + String abscd; + @Schema(name = "grpid", description = "그룹번호") + Integer grpid; + +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/dto/req/ZwfApprUpdateRequest.java b/src/main/java/com/kospo/svcm/dto/req/ZwfApprUpdateRequest.java new file mode 100644 index 0000000..c95955f --- /dev/null +++ b/src/main/java/com/kospo/svcm/dto/req/ZwfApprUpdateRequest.java @@ -0,0 +1,32 @@ +package com.kospo.svcm.dto.req; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.kospo.svcm.model.Zwf0012t; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; + +import java.io.Serializable; + +/** + * DTO for {@link Zwf0012t} + */ +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@JsonIgnoreProperties(ignoreUnknown = true) +@Schema(name = "ZwfApprUpdateRequest", description = "SAP 결재 승인") +public class ZwfApprUpdateRequest implements Serializable { + @Schema(name = "wkfid", description = "요청번호") + String wkfid; + @Schema(name = "wkfsq", description = "결재순번") + Integer wkfsq; + @Schema(name = "bname", description = "사번") + String bname; + @Schema(name = "wkfst", description = "결재상태") + String wkfst; + @Schema(name = "reason", description = "(반려)사유") + String reason; + +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/dto/res/ApprMstResponse.java b/src/main/java/com/kospo/svcm/dto/res/ApprMstResponse.java new file mode 100644 index 0000000..e376a67 --- /dev/null +++ b/src/main/java/com/kospo/svcm/dto/res/ApprMstResponse.java @@ -0,0 +1,51 @@ +package com.kospo.svcm.dto.res; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.kospo.svcm.model.ApprMst; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; + +import java.io.Serializable; +import java.util.List; +import java.util.stream.Collectors; + +/** + * DTO for {@link ApprMst} + */ +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@JsonIgnoreProperties(ignoreUnknown = true) +@Schema(name = "ApprMstResponse", description = "결재 마스터") +public class ApprMstResponse implements Serializable { + @Schema(name = "apprNo", description = "결재번호") + String apprNo; + @Schema(name = "apprStatCd", description = "결재상태코드") + String apprStatCd; + @Schema(name = "apprStat", description = "결재상태") + String apprStat; + @Schema(name = "reason", description = "반려사유") + String reason; + @Schema(name = "compDt", description = "승인완료 일시") + String compDt; + @Schema(name = "regDt", description = "등록일시") + String regDt; + @Schema(name = "regSabun", description = "등록자") + String regSabun; + + List apprReqs; + + public static ApprMstResponse from(ApprMst apprMst) { + return ApprMstResponse.builder() + .apprNo(apprMst.getApprNo()) + .apprStat(apprMst.getApprStat()) + .apprStatCd(apprMst.getApprStatCd()) + .compDt(apprMst.getCompDt()) + .regDt(apprMst.getRegDt()) + .regSabun(apprMst.getRegSabun()) + .apprReqs(apprMst.getApprReqs().stream().map(ApprReqResponse::from).collect(Collectors.toList())) + .build(); + } +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/dto/res/ApprReqResponse.java b/src/main/java/com/kospo/svcm/dto/res/ApprReqResponse.java new file mode 100644 index 0000000..ce6749e --- /dev/null +++ b/src/main/java/com/kospo/svcm/dto/res/ApprReqResponse.java @@ -0,0 +1,67 @@ +package com.kospo.svcm.dto.res; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.kospo.svcm.model.ApprReq; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; + +import java.io.Serializable; + +/** + * DTO for {@link ApprReq} + */ +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@JsonIgnoreProperties(ignoreUnknown = true) +@Schema(name = "ApprReqResponse", description = "결재요청") +public class ApprReqResponse implements Serializable { + @Schema(name = "apprNo", description = "결재번호") + String apprNo; + @Schema(name = "apprOrd", description = "결재순서") + Integer apprOrd; + @Schema(name = "sabun", description = "사번") + String sabun; + @Schema(name = "name", description = "이름") + String name; + @Schema(name = "apprStatCd", description = "결재상태코드") + String apprStatCd; + @Schema(name = "apprStat", description = "결재상태") + String apprStat; + @Schema(name = "apprDt", description = "결재시행일시") + String apprDt; + @Schema(name = "attendCd", description = "근태상태코드") + String attendCd; + @Schema(name = "attendNm", description = "근태상태") + String attendNm; + @Schema(name = "attendStaYmd", description = "근태시작일") + String attendStaYmd; + @Schema(name = "attendEndYmd", description = "근태종료일") + String attendEndYmd; + @Schema(name = "gubunCd", description = "구분코드") + String gubunCd; + @Schema(name = "gubunNm", description = "구분") + String gubunNm; + @Schema(name = "deptCd", description = "부서코드") + String deptCd; + @Schema(name = "gubunNm", description = "부서명") + String deptNm; + + public static ApprReqResponse from(ApprReq apprReq) { + return ApprReqResponse.builder() + .apprNo(apprReq.getId().getApprNo()) + .apprOrd(apprReq.getId().getApprOrd()) + .sabun(apprReq.getSabun()) + .name(apprReq.getName()) + .apprStatCd(apprReq.getApprStatCd()) + .apprStat(apprReq.getApprStat()) + .apprDt(apprReq.getApprDt()) + .gubunCd(apprReq.getGubunCd()) + .gubunNm(apprReq.getGubunNm()) + .deptCd(apprReq.getDeptCd()) + .deptNm(apprReq.getDeptNm()) + .build(); + } +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/dto/res/BusinessResponse.java b/src/main/java/com/kospo/svcm/dto/res/BusinessResponse.java new file mode 100644 index 0000000..d877b5c --- /dev/null +++ b/src/main/java/com/kospo/svcm/dto/res/BusinessResponse.java @@ -0,0 +1,44 @@ +package com.kospo.svcm.dto.res; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.kospo.svcm.model.Business; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; +import org.springframework.security.core.GrantedAuthority; + +import java.io.Serializable; +import java.util.Collection; + +/** + * DTO for {@link Business} + */ + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Builder +@JsonIgnoreProperties(ignoreUnknown = true) +@Schema(name = "BusinessResponse", description = "사업자") +public class BusinessResponse implements Serializable { + @Schema(name = "bizNo", description = "사업자번호") + String bizNo; + @Schema(name = "pwd", description = "비밀번호") + String pwd; + @Schema(name = "compNm", description = "업체명") + String compNm; + @Schema(name = "repNm", description = "대표자명") + String repNm; + @Schema(name = "email", description = "이메일") + String email; + Collection authorities; + public static BusinessResponse from(Business business) { + return BusinessResponse.builder() + .bizNo(business.getBizNo()) + .pwd(business.getPwd()) + .compNm(business.getCompNm()) + .repNm(business.getRepNm()) + .email(business.getEmail()) + .authorities(business.getAuthorities()) + .build(); + } +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/dto/res/CodeResponse.java b/src/main/java/com/kospo/svcm/dto/res/CodeResponse.java new file mode 100644 index 0000000..3ea90e1 --- /dev/null +++ b/src/main/java/com/kospo/svcm/dto/res/CodeResponse.java @@ -0,0 +1,38 @@ +package com.kospo.svcm.dto.res; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.kospo.svcm.model.Code; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Builder +@JsonIgnoreProperties(ignoreUnknown = true) +@Schema(name = "CodeResponse", description = "코드") +public class CodeResponse { + @Schema(name = "id", description = "아이디") + private Integer id; + @Schema(name = "cd", description = "코드") + private String cd; + @Schema(name = "nm", description = "코드명") + private String nm; + @Schema(name = "desc", description = "설명") + private String desc; + @Schema(name = "useYn", description = "사용여부") + private Boolean useYn; + + public static CodeResponse from(Code code) { + return CodeResponse.builder() + .id(code.getId().getId()) + .cd(code.getId().getCd()) + .nm(code.getNm()) + .desc(code.getDesc()) + .useYn(code.getUseYn()).build(); + + } +} diff --git a/src/main/java/com/kospo/svcm/dto/res/ContApprResponse.java b/src/main/java/com/kospo/svcm/dto/res/ContApprResponse.java new file mode 100644 index 0000000..3cab395 --- /dev/null +++ b/src/main/java/com/kospo/svcm/dto/res/ContApprResponse.java @@ -0,0 +1,34 @@ +package com.kospo.svcm.dto.res; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.kospo.svcm.model.ContAppr; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; + +import java.io.Serializable; + +/** + * DTO for {@link ContAppr} + */ +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@JsonIgnoreProperties(ignoreUnknown = true) +@Schema(name = "ContApprResponse", description = "계약 전자결재") +public class ContApprResponse implements Serializable { + @Schema(name = "contNo", description = "계약번호") + String contNo; + @Schema(name = "transactionKey", description = "연계 시스템 문서 키") + String transactionKey; + ContSaveResponse cont; + + public static ContApprResponse from(ContAppr contAppr) { + return ContApprResponse.builder() + .contNo(contAppr.getId().getContNo()) + .transactionKey(contAppr.getId().getTransactionKey()) + .cont(ContSaveResponse.from(contAppr.getCont())) + .build(); + } +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/dto/res/ContAttResponse.java b/src/main/java/com/kospo/svcm/dto/res/ContAttResponse.java new file mode 100644 index 0000000..0ee171e --- /dev/null +++ b/src/main/java/com/kospo/svcm/dto/res/ContAttResponse.java @@ -0,0 +1,44 @@ +package com.kospo.svcm.dto.res; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.kospo.svcm.model.ContAtt; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; + +import java.io.Serializable; + +/** + * DTO for {@link ContAtt} + */ +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@JsonIgnoreProperties(ignoreUnknown = true) +@Schema(name = "ContAttResponse", description = "계약 문서") +public class ContAttResponse implements Serializable { + @Schema(name = "contNo", description = "계약번호") + String contNo; + @Schema(name = "fileOrd", description = "파일순서") + Integer fileOrd; + @Schema(name = "logiFnm", description = "논리파일명") + String logiFnm; + @Schema(name = "physFnm", description = "물리파일명") + String physFnm; + @Schema(name = "size", description = "사이즈") + Integer size; + @Schema(name = "path", description = "경로") + String path; + + public static ContAttResponse from(ContAtt contAtt) { + return ContAttResponse.builder() + .contNo(contAtt.getId().getContNo()) + .fileOrd(contAtt.getId().getFileOrd()) + .logiFnm(contAtt.getLogiFnm()) + .physFnm(contAtt.getPhysFnm()) + .size(contAtt.getSize()) + .path(contAtt.getPath()) + .build(); + } +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/dto/res/ContListResponse.java b/src/main/java/com/kospo/svcm/dto/res/ContListResponse.java new file mode 100644 index 0000000..6cff4cd --- /dev/null +++ b/src/main/java/com/kospo/svcm/dto/res/ContListResponse.java @@ -0,0 +1,51 @@ +package com.kospo.svcm.dto.res; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.kospo.svcm.repository.ContRepository; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@JsonIgnoreProperties(ignoreUnknown = true) +@Schema(name = "ContResponse", description = "계약관리") +public class ContListResponse { + @Schema(name = "contNo", description = "계약번호") + String contNo; + @Schema(name = "title", description = "제목") + String title; + @Schema(name = "compNm", description = "업체명") + String compNm; + @Schema(name = "signDt", description = "계약체결일") + String signDt; + @Schema(name = "contAmt", description = "계약금액") + Integer contAmt; + @Schema(name = "contStatCd", description = "계약상태코드") + String contStatCd; + @Schema(name = "contStat", description = "계약상태") + String contStat; + @Schema(name = "regSabun", description = "등록사번") + String regSabun; + @Schema(name = "regNm", description = "등록자") + String regNm; + @Schema(name = "regDt", description = "등록일시") + String regDt; + + public static ContListResponse iFrom(ContRepository.IContResponse cont) { + return ContListResponse.builder() + .contNo(cont.getContNo()) + .compNm(cont.getCompNm()) + .title(cont.getTitle()) + .signDt(cont.getSignDt()) + .contAmt(cont.getContAmt()) + .contStatCd(cont.getContStatCd()) + .contStat(cont.getContStat()) + .regSabun(cont.getRegSabun()) + .regNm(cont.getRegNm()) + .regDt(cont.getRegDt()) + .build(); + } +} diff --git a/src/main/java/com/kospo/svcm/dto/res/ContPrcsResponse.java b/src/main/java/com/kospo/svcm/dto/res/ContPrcsResponse.java new file mode 100644 index 0000000..6a47ea3 --- /dev/null +++ b/src/main/java/com/kospo/svcm/dto/res/ContPrcsResponse.java @@ -0,0 +1,67 @@ +package com.kospo.svcm.dto.res; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.kospo.svcm.model.Prcs; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; + +import java.io.Serializable; +import java.util.List; + +/** + * DTO for {@link Prcs} + */ +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@JsonIgnoreProperties(ignoreUnknown = true) +@Schema(name = "ConstPrcsResponse", description = "계약관리-가격조사") +public class ContPrcsResponse implements Serializable { + @Schema(name = "prcsNo", description = "가격조사번호") + String prcsNo; + @Schema(name = "cateCd", description = "분야코드") + String cateCd; + @Schema(name = "cateNm", description = "분야") + String cateNm; + @Schema(name = "title", description = "제목") + String title; + @Schema(name = "content", description = "내용") + String content; + @Schema(name = "regSdat", description = "등록시작일") + String regSdat; + @Schema(name = "regEdat", description = "등록종료일") + String regEdat; + @Schema(name = "regSabun", description = "등록사번") + String regSabun; + @Schema(name = "regNm", description = "등록자") + String regNm; + @Schema(name = "regDt", description = "등록일시") + String regDt; + @Schema(name = "stCd", description = "등록상태코드") + String stCd; + @Schema(name = "stNm", description = "등록상태") + String stNm; + @Schema(name = "svyDt", description = "조사완료일시") + String svyDt; + List estimates; + + public static ContPrcsResponse from(Prcs prcs) { + return ContPrcsResponse.builder() + .prcsNo(prcs.getPrcsNo()) + .cateCd(prcs.getCateCd()) + .cateNm(prcs.getCateNm()) + .title(prcs.getTitle()) + .content(prcs.getContent()) + .regSdat(prcs.getRegSdat()) + .regEdat(prcs.getRegEdat()) + .regSabun(prcs.getRegSabun()) + .regNm(prcs.getRegNm()) + .stCd(prcs.getStCd()) + .stNm(prcs.getStNm()) + .svyDt(prcs.getSvyDt()) + .regDt(prcs.getRegDt()) + .build(); + } +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/dto/res/ContSaveResponse.java b/src/main/java/com/kospo/svcm/dto/res/ContSaveResponse.java new file mode 100644 index 0000000..b028025 --- /dev/null +++ b/src/main/java/com/kospo/svcm/dto/res/ContSaveResponse.java @@ -0,0 +1,76 @@ +package com.kospo.svcm.dto.res; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.kospo.svcm.model.Cont; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; + +import java.io.Serializable; +import java.util.List; +import java.util.stream.Collectors; + +/** + * DTO for {@link Cont} + */ +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@JsonIgnoreProperties(ignoreUnknown = true) +@Schema(name = "ContSaveResponse", description = "계약관리") +public class ContSaveResponse implements Serializable { + @Schema(name = "contNo", description = "계약번호") + String contNo; + @Schema(name = "bizNo", description = "사업자번호") + String bizNo; + @Schema(name = "title", description = "계약명") + String title; + @Schema(name = "compNm", description = "업체명") + String compNm; + @Schema(name = "signDt", description = "계약체결일") + String signDt; + @Schema(name = "contAmt", description = "계약금액") + Integer contAmt; + @Schema(name = "contSdat", description = "계약시작일") + String contSdat; + @Schema(name = "contEdat", description = "계약종료일") + String contEdat; + @Schema(name = "contStatCd", description = "계약상태코드") + String contStatCd; + @Schema(name = "contStat", description = "계약상태") + String contStat; + @Schema(name = "regSabun", description = "등록사번") + String regSabun; + @Schema(name = "regNm", description = "등록자") + String regNm; + @Schema(name = "regDt", description = "등록일시") + String regDt; + @Schema(name = "docUrl", description = "전자문서url") + String docUrl; + @Schema(name = "excYn", description = "가격조사 예외") + boolean excYn; + @Schema(name = "reason", description = "가격조사 예외사유") + String reason; + + List contAtts; + + public static ContSaveResponse from(Cont cont) { + return ContSaveResponse.builder() + .contNo(cont.getContNo()) + .bizNo(cont.getBizNo()) + .title(cont.getTitle()) + .compNm(cont.getCompNm()) + .signDt(cont.getSignDt()) + .contAmt(cont.getContAmt()) + .contSdat(cont.getContSdat()) + .contEdat(cont.getContEdat()) + .contStatCd(cont.getContStatCd()) + .contStat(cont.getContStat()) + .regSabun(cont.getRegSabun()) + .regNm(cont.getRegNm()) + .regDt(cont.getRegDt()) + .contAtts(cont.getContAtts().stream().map(ContAttResponse::from).collect(Collectors.toList())) + .build(); + } +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/dto/res/DtlSpecExcelResponse.java b/src/main/java/com/kospo/svcm/dto/res/DtlSpecExcelResponse.java new file mode 100644 index 0000000..0b7a24e --- /dev/null +++ b/src/main/java/com/kospo/svcm/dto/res/DtlSpecExcelResponse.java @@ -0,0 +1,29 @@ +package com.kospo.svcm.dto.res; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.kospo.svcm.model.DtlSpec; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; + +import java.io.Serializable; + +/** + * DTO for {@link DtlSpec} + */ +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@JsonIgnoreProperties(ignoreUnknown = true) +@Schema(name = "DtlSpecExcelResponse", description = "상세규격") +public class DtlSpecExcelResponse implements Serializable { + @Schema(name = "itemNm", description = "품명") + String itemNm; + @Schema(name = "spec", description = "규격") + String spec; + @Schema(name = "unit", description = "단위") + String unit; + @Schema(name = "qty", description = "수량") + Integer qty; +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/dto/res/DtlSpecExternalResponse.java b/src/main/java/com/kospo/svcm/dto/res/DtlSpecExternalResponse.java new file mode 100644 index 0000000..cf2a72e --- /dev/null +++ b/src/main/java/com/kospo/svcm/dto/res/DtlSpecExternalResponse.java @@ -0,0 +1,46 @@ +package com.kospo.svcm.dto.res; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.kospo.svcm.model.DtlSpec; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; + +import java.io.Serializable; + +/** + * DTO for {@link DtlSpec} + */ +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@JsonIgnoreProperties(ignoreUnknown = true) +@Schema(name = "DtlSpecResponse", description = "상세규격") +public class DtlSpecExternalResponse implements Serializable { + @Schema(name = "prcsNo", description = "가격조사번호") + String prcsNo; + @Schema(name = "dtlSpNo", description = "상세규격번호") + String dtlSpNo; + @Schema(name = "itemNm", description = "품명") + String itemNm; + @Schema(name = "spec", description = "규격") + String spec; + @Schema(name = "unit", description = "단위") + String unit; + @Schema(name = "qty", description = "수량") + Integer qty; + + EstimateResponse estimate; + + public static DtlSpecExternalResponse from(DtlSpec dtlSpec) { + return DtlSpecExternalResponse.builder() + .prcsNo(dtlSpec.getId().getPrcsNo()) + .dtlSpNo(dtlSpec.getId().getDtlSpNo()) + .itemNm(dtlSpec.getItemNm()) + .spec(dtlSpec.getSpec()) + .unit(dtlSpec.getUnit()) + .qty(dtlSpec.getQty()) + .build(); + } +} diff --git a/src/main/java/com/kospo/svcm/dto/res/DtlSpecResponse.java b/src/main/java/com/kospo/svcm/dto/res/DtlSpecResponse.java new file mode 100644 index 0000000..609fb63 --- /dev/null +++ b/src/main/java/com/kospo/svcm/dto/res/DtlSpecResponse.java @@ -0,0 +1,44 @@ +package com.kospo.svcm.dto.res; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.kospo.svcm.model.DtlSpec; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; + +import java.io.Serializable; + +/** + * DTO for {@link DtlSpec} + */ +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@JsonIgnoreProperties(ignoreUnknown = true) +@Schema(name = "DtlSpecResponse", description = "상세규격") +public class DtlSpecResponse implements Serializable { + @Schema(name = "prcsNo", description = "가격조사번호") + String prcsNo; + @Schema(name = "dtlSpNo", description = "상세규격번호") + String dtlSpNo; + @Schema(name = "itemNm", description = "품명") + String itemNm; + @Schema(name = "spec", description = "규격") + String spec; + @Schema(name = "unit", description = "단위") + String unit; + @Schema(name = "qty", description = "수량") + Integer qty; + + public static DtlSpecResponse from(DtlSpec dtlSpec) { + return DtlSpecResponse.builder() + .prcsNo(dtlSpec.getId().getPrcsNo()) + .dtlSpNo(dtlSpec.getId().getDtlSpNo()) + .itemNm(dtlSpec.getItemNm()) + .spec(dtlSpec.getSpec()) + .unit(dtlSpec.getUnit()) + .qty(dtlSpec.getQty()) + .build(); + } +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/dto/res/EstDocResponse.java b/src/main/java/com/kospo/svcm/dto/res/EstDocResponse.java new file mode 100644 index 0000000..6de2f94 --- /dev/null +++ b/src/main/java/com/kospo/svcm/dto/res/EstDocResponse.java @@ -0,0 +1,44 @@ +package com.kospo.svcm.dto.res; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.kospo.svcm.model.EstDoc; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; + +import java.io.Serializable; + +/** + * DTO for {@link EstDoc} + */ +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@JsonIgnoreProperties(ignoreUnknown = true) +@Schema(name = "EstDocResponse", description = "견적서") +public class EstDocResponse implements Serializable { + @Schema(name = "estNo", description = "견적관리번호") + String estNo; + @Schema(name = "fileOrd", description = "파일순서") + Integer fileOrd; + @Schema(name = "logiFnm", description = "논리파일명") + String logiFnm; + @Schema(name = "physFnm", description = "물리파일명") + String physFnm; + @Schema(name = "size", description = "사이즈") + Integer size; + @Schema(name = "path", description = "경로") + String path; + + public static EstDocResponse from(EstDoc estDoc) { + return EstDocResponse.builder() + .estNo(estDoc.getId().getEstNo()) + .fileOrd(estDoc.getId().getFileOrd()) + .logiFnm(estDoc.getLogiFnm()) + .physFnm(estDoc.getPhysFnm()) + .size(estDoc.getSize()) + .path(estDoc.getPath()) + .build(); + } +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/dto/res/EstimateContResponse.java b/src/main/java/com/kospo/svcm/dto/res/EstimateContResponse.java new file mode 100644 index 0000000..fa0567b --- /dev/null +++ b/src/main/java/com/kospo/svcm/dto/res/EstimateContResponse.java @@ -0,0 +1,54 @@ +package com.kospo.svcm.dto.res; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.kospo.svcm.model.Business; +import com.kospo.svcm.model.Estimate; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; + +import java.io.Serializable; +import java.util.List; +import java.util.stream.Collectors; + +/** + * DTO for {@link Estimate} + */ +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@JsonIgnoreProperties(ignoreUnknown = true) +@Schema(name = "EstimateResponse", description = "견적") +public class EstimateContResponse implements Serializable { + @Schema(name = "estNo", description = "견적관리번호") + String estNo; + @Schema(name = "mngNm", description = "담당자명") + String mngNm; + @Schema(name = "unitPrc", description = "단가") + Integer unitPrc; + @Schema(name = "amt", description = "금액") + Integer amt; + @Schema(name = "bizNo", description = "사업자번호") + String bizNo; + @Schema(name = "compNm", description = "회사명") + String compNm; + @Schema(name = "repNm", description = "대표자명") + String repNm; + @Schema(name = "regDt", description = "등록일시") + String regDt; + + public static EstimateContResponse from(Estimate estimate) { + Business bus = estimate.getBusiness(); + return EstimateContResponse.builder() + .estNo(estimate.getEstNo()) + .mngNm(estimate.getMngNm()) + .unitPrc(estimate.getUnitPrc()) + .amt(estimate.getAmt()) + .regDt(estimate.getRegDt()) + .bizNo(estimate.getBizNo()) + .compNm(bus.getCompNm()) + .repNm(bus.getRepNm()) + .build(); + } +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/dto/res/EstimateListResponse.java b/src/main/java/com/kospo/svcm/dto/res/EstimateListResponse.java new file mode 100644 index 0000000..e25a46b --- /dev/null +++ b/src/main/java/com/kospo/svcm/dto/res/EstimateListResponse.java @@ -0,0 +1,24 @@ +package com.kospo.svcm.dto.res; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.kospo.svcm.model.Estimate; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; + +import java.io.Serializable; +import java.util.List; + +/** + * DTO for {@link Estimate} + */ +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@JsonIgnoreProperties(ignoreUnknown = true) +@Schema(name = "EstimateListResponse", description = "견적 목록") +public class EstimateListResponse implements Serializable { + List estimates; + List pbAtts; +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/dto/res/EstimateResponse.java b/src/main/java/com/kospo/svcm/dto/res/EstimateResponse.java new file mode 100644 index 0000000..d91588c --- /dev/null +++ b/src/main/java/com/kospo/svcm/dto/res/EstimateResponse.java @@ -0,0 +1,49 @@ +package com.kospo.svcm.dto.res; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.kospo.svcm.model.Estimate; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; + +import java.io.Serializable; +import java.util.List; +import java.util.stream.Collectors; + +/** + * DTO for {@link Estimate} + */ +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@JsonIgnoreProperties(ignoreUnknown = true) +@Schema(name = "EstimateResponse", description = "견적") +public class EstimateResponse implements Serializable { + @Schema(name = "estNo", description = "견적관리번호") + String estNo; + @Schema(name = "mngNm", description = "담당자명") + String mngNm; + @Schema(name = "unitPrc", description = "단가") + Integer unitPrc; + @Schema(name = "amt", description = "금액") + Integer amt; + @Schema(name = "regDt", description = "등록일시") + String regDt; + BusinessResponse business; + DtlSpecResponse dtlSpec; + List estDocs; + + public static EstimateResponse from(Estimate estimate) { + return EstimateResponse.builder() + .estNo(estimate.getEstNo()) + .mngNm(estimate.getMngNm()) + .unitPrc(estimate.getUnitPrc()) + .amt(estimate.getAmt()) + .regDt(estimate.getRegDt()) + .business(estimate.getBusiness() == null ? null : BusinessResponse.from(estimate.getBusiness())) + .dtlSpec(estimate.getDtlSpec() == null ? null : DtlSpecResponse.from(estimate.getDtlSpec())) + .estDocs(estimate.getEstDocs() == null ? null : estimate.getEstDocs().stream().map(EstDocResponse::from).collect(Collectors.toList())) + .build(); + } +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/dto/res/GrpCodeResponse.java b/src/main/java/com/kospo/svcm/dto/res/GrpCodeResponse.java new file mode 100644 index 0000000..e9b8124 --- /dev/null +++ b/src/main/java/com/kospo/svcm/dto/res/GrpCodeResponse.java @@ -0,0 +1,42 @@ +package com.kospo.svcm.dto.res; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.kospo.svcm.model.GrpCode; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; + +import java.io.Serializable; +import java.util.List; +import java.util.stream.Collectors; + +/** + * DTO for {@link GrpCode} + */ +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@JsonIgnoreProperties(ignoreUnknown = true) +@Schema(name = "GrpCodeResponse", description = "그룹코드") +public class GrpCodeResponse implements Serializable { + @Schema(name = "id", description = "아이디") + Integer id; + @Schema(name = "nm", description = "코드명") + String nm; + @Schema(name = "desc", description = "설명") + String desc; + @Schema(name = "useYn", description = "사용여부") + Boolean useYn; + List codes; + + public static GrpCodeResponse from(GrpCode grpCode) { + return GrpCodeResponse.builder() + .id(grpCode.getId()) + .nm(grpCode.getNm()) + .desc(grpCode.getDesc()) + .useYn(grpCode.getUseYn()) + .codes(grpCode.getCodes() == null && grpCode.getCodes().size() == 0 ? null : grpCode.getCodes().stream().map(CodeResponse::from).collect(Collectors.toList())) + .build(); + } +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/dto/res/LoginResponse.java b/src/main/java/com/kospo/svcm/dto/res/LoginResponse.java new file mode 100644 index 0000000..8c5656a --- /dev/null +++ b/src/main/java/com/kospo/svcm/dto/res/LoginResponse.java @@ -0,0 +1,38 @@ +package com.kospo.svcm.dto.res; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + +import com.kospo.svcm.model.Business; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + * DTO for {@link Business} + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +@Builder +@JsonIgnoreProperties(ignoreUnknown = true) +@Schema(name = "LoginResponse", description = "로그인") +public class LoginResponse implements Serializable { + @Schema(name = "bizNo", description = "사업자번호") + private String bizNo; + @Schema(name = "pwd", description = "비밀번호") + private String pwd; + @Schema(name = "compNm", description = "업체명") + private String compNm; + @Schema(name = "repNm", description = "대표자명") + String repNm; + @Schema(name = "email", description = "이메일") + String email; + @Schema(name = "accessToken", description = "엑서스 토큰") + private String accessToken; + @Schema(name = "accessTokenExpired", description = "엑서스 토큰 만료시간") + private Long accessTokenExpired; +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/dto/res/MsgResponse.java b/src/main/java/com/kospo/svcm/dto/res/MsgResponse.java new file mode 100644 index 0000000..1904d87 --- /dev/null +++ b/src/main/java/com/kospo/svcm/dto/res/MsgResponse.java @@ -0,0 +1,19 @@ +package com.kospo.svcm.dto.res; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@JsonIgnoreProperties(ignoreUnknown = true) +@Schema(name = "MsgResponse", description = "응답 메시지") +public class MsgResponse { + @Schema(name = "code", description = "응답 코드") + private String code; + @Schema(name = "body", description = "응답 바디") + private Object body; +} diff --git a/src/main/java/com/kospo/svcm/dto/res/PageResponse.java b/src/main/java/com/kospo/svcm/dto/res/PageResponse.java new file mode 100644 index 0000000..3549529 --- /dev/null +++ b/src/main/java/com/kospo/svcm/dto/res/PageResponse.java @@ -0,0 +1,25 @@ +package com.kospo.svcm.dto.res; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@JsonIgnoreProperties(ignoreUnknown = true) +@Schema(name = "PageResponse", description = "응답 메시지(페이징)") +public class PageResponse { + @Schema(name = "totalElements", description = "총 개수") + private long totalElements; + @Schema(name = "totalPages", description = "전체 페이지") + private int totalPages; + @Schema(name = "content", description = "내용") + private Object content; + @Schema(name = "pageable", description = "페이징 정보") + private Pageable pageable; +} diff --git a/src/main/java/com/kospo/svcm/dto/res/PbAttResponse.java b/src/main/java/com/kospo/svcm/dto/res/PbAttResponse.java new file mode 100644 index 0000000..68282f3 --- /dev/null +++ b/src/main/java/com/kospo/svcm/dto/res/PbAttResponse.java @@ -0,0 +1,48 @@ +package com.kospo.svcm.dto.res; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.kospo.svcm.model.EstDoc; +import com.kospo.svcm.model.PbAtt; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; + +import java.io.Serializable; + +/** + * DTO for {@link EstDoc} + */ +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@JsonIgnoreProperties(ignoreUnknown = true) +@Schema(name = "PbAttResponse", description = "견적서") +public class PbAttResponse implements Serializable { + @Schema(name = "prcsNo", description = "가격조사번호") + String prcsNo; + @Schema(name = "bizNo", description = "사업자번호") + String bizNo; + @Schema(name = "fileOrd", description = "파일순서") + Integer fileOrd; + @Schema(name = "logiFnm", description = "논리파일명") + String logiFnm; + @Schema(name = "physFnm", description = "물리파일명") + String physFnm; + @Schema(name = "size", description = "사이즈") + Integer size; + @Schema(name = "path", description = "경로") + String path; + + public static PbAttResponse from(PbAtt pbAtt) { + return PbAttResponse.builder() + .prcsNo(pbAtt.getId().getPrcsNo()) + .bizNo(pbAtt.getId().getBizNo()) + .fileOrd(pbAtt.getId().getFileOrd()) + .logiFnm(pbAtt.getLogiFnm()) + .physFnm(pbAtt.getPhysFnm()) + .size(pbAtt.getSize()) + .path(pbAtt.getPath()) + .build(); + } +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/dto/res/PrcsAttResponse.java b/src/main/java/com/kospo/svcm/dto/res/PrcsAttResponse.java new file mode 100644 index 0000000..3e7a7d3 --- /dev/null +++ b/src/main/java/com/kospo/svcm/dto/res/PrcsAttResponse.java @@ -0,0 +1,44 @@ +package com.kospo.svcm.dto.res; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.kospo.svcm.model.PrcsAtt; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; + +import java.io.Serializable; + +/** + * DTO for {@link PrcsAtt} + */ +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@JsonIgnoreProperties(ignoreUnknown = true) +@Schema(name = "PrcsAttResponse", description = "가격조사 첨부파일") +public class PrcsAttResponse implements Serializable { + @Schema(name = "prcsNo", description = "가격조사번호") + String prcsNo; + @Schema(name = "fileOrd", description = "파일순서") + Integer fileOrd; + @Schema(name = "logiFnm", description = "논리파일명") + String logiFnm; + @Schema(name = "physFnm", description = "물리파일명") + String physFnm; + @Schema(name = "size", description = "사이즈") + Integer size; + @Schema(name = "path", description = "경로") + String path; + + public static PrcsAttResponse from(PrcsAtt prcsAtt) { + return PrcsAttResponse.builder() + .prcsNo(prcsAtt.getId().getPrcsNo()) + .fileOrd(prcsAtt.getId().getFileOrd()) + .logiFnm(prcsAtt.getLogiFnm()) + .physFnm(prcsAtt.getPhysFnm()) + .size(prcsAtt.getSize()) + .path(prcsAtt.getPath()) + .build(); + } +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/dto/res/PrcsBizResponse.java b/src/main/java/com/kospo/svcm/dto/res/PrcsBizResponse.java new file mode 100644 index 0000000..cfa8a62 --- /dev/null +++ b/src/main/java/com/kospo/svcm/dto/res/PrcsBizResponse.java @@ -0,0 +1,45 @@ +package com.kospo.svcm.dto.res; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.kospo.svcm.model.DtlSpec; +import com.kospo.svcm.model.PrcsBiz; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; + +import java.io.Serializable; + +/** + * DTO for {@link DtlSpec} + */ +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@JsonIgnoreProperties(ignoreUnknown = true) +@Schema(name = "DtlSpecResponse", description = "상세규격") +public class PrcsBizResponse implements Serializable { + @Schema(name = "prcsNo", description = "가격조사번호") + String prcsNo; + @Schema(name = "bizNo", description = "사업자번호") + String bizNo; + @Schema(name = "email", description = "이메일") + String email; + @Schema(name = "sendYn", description = "전송여부") + Boolean sendYn; + @Schema(name = "estStatCd", description = "입찰상태코드") + String estStatCd; + @Schema(name = "estStat", description = "입찰상태") + String estStat; + + public static PrcsBizResponse from(PrcsBiz prcsBiz) { + return PrcsBizResponse.builder() + .prcsNo(prcsBiz.getId().getPrcsNo()) + .bizNo(prcsBiz.getId().getBizNo()) + .email(prcsBiz.getEmail()) + .sendYn(prcsBiz.getSendYn()) + .estStatCd(prcsBiz.getEstStatCd()) + .estStat(prcsBiz.getEstStat()) + .build(); + } +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/dto/res/PrcsExternalResponse.java b/src/main/java/com/kospo/svcm/dto/res/PrcsExternalResponse.java new file mode 100644 index 0000000..c91f405 --- /dev/null +++ b/src/main/java/com/kospo/svcm/dto/res/PrcsExternalResponse.java @@ -0,0 +1,96 @@ +package com.kospo.svcm.dto.res; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.kospo.svcm.model.Prcs; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; + +import java.io.Serializable; +import java.util.List; +import java.util.stream.Collectors; + +/** + * DTO for {@link Prcs} + */ +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@JsonIgnoreProperties(ignoreUnknown = true) +@Schema(name = "PrcsResponse", description = "가격조사") +public class PrcsExternalResponse implements Serializable { + @Schema(name = "prcsNo", description = "가격조사번호") + String prcsNo; + @Schema(name = "cateCd", description = "분야코드") + String cateCd; + @Schema(name = "cateNm", description = "분야") + String cateNm; + @Schema(name = "title", description = "제목") + String title; + @Schema(name = "content", description = "내용") + String content; + @Schema(name = "regSdat", description = "등록시작일") + String regSdat; + @Schema(name = "regEdat", description = "등록종료일") + String regEdat; + @Schema(name = "prvYn", description = "비공개여부") + Boolean prvYn; + @Schema(name = "prvRsn", description = "비공개사유") + String prvRsn; + @Schema(name = "prvPwd", description = "비공개비밀번호") + String prvPwd; + @Schema(name = "aiYn", description = "ai검증여부") + Boolean aiYn; + @Schema(name = "regSabun", description = "등록사번") + String regSabun; + @Schema(name = "regNm", description = "등록자") + String regNm; + @Schema(name = "regDt", description = "등록일시") + String regDt; + @Schema(name = "stCd", description = "등록상태코드") + String stCd; + @Schema(name = "stNm", description = "등록상태") + String stNm; + @Schema(name = "svyYn", description = "조사완료여부") + Boolean svyYn; + @Schema(name = "svyDt", description = "조사완료일시") + String svyDt; + @Schema(name = "estStatCd", description = "입찰상태코드") + String estStatCd; + @Schema(name = "estStat", description = "입찰상태") + String estStat; + @Schema(name = "totAmt", description = "입찰총금액") + Integer totAmt; + ApprMstResponse apprMst; + List prcsAtts; + List dtlSpecs; + List pbAtts; + + + public static PrcsExternalResponse from(Prcs prcs) { + return PrcsExternalResponse.builder() + .prcsNo(prcs.getPrcsNo()) + .cateCd(prcs.getCateCd()) + .cateNm(prcs.getCateNm()) + .title(prcs.getTitle()) + .content(prcs.getContent()) + .regSdat(prcs.getRegSdat()) + .regEdat(prcs.getRegEdat()) + .prvYn(prcs.getPrvYn()) + .prvRsn(prcs.getPrvRsn()) + .prvPwd(prcs.getPrvPwd()) + .aiYn(prcs.getAiYn()) + .regSabun(prcs.getRegSabun()) + .regNm(prcs.getRegNm()) + .stCd(prcs.getStCd()) + .stNm(prcs.getStNm()) + .svyYn(prcs.getSvyYn()) + .svyDt(prcs.getSvyDt()) + .regDt(prcs.getRegDt()) + .apprMst(prcs.getApprMst() == null ? null : ApprMstResponse.from(prcs.getApprMst())) + .prcsAtts(prcs.getPrcsAtts() == null ? null : prcs.getPrcsAtts().stream().map(PrcsAttResponse::from).collect(Collectors.toList())) + .dtlSpecs(prcs.getDtlSpecs() == null ? null : prcs.getDtlSpecs().stream().map(DtlSpecExternalResponse::from).collect(Collectors.toList())) + .build(); + } +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/dto/res/PrcsListResponse.java b/src/main/java/com/kospo/svcm/dto/res/PrcsListResponse.java new file mode 100644 index 0000000..c335ee2 --- /dev/null +++ b/src/main/java/com/kospo/svcm/dto/res/PrcsListResponse.java @@ -0,0 +1,85 @@ +package com.kospo.svcm.dto.res; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.kospo.svcm.model.Prcs; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; + +import java.io.Serializable; +import java.util.List; +import java.util.stream.Collectors; + +/** + * DTO for {@link Prcs} + */ +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@JsonIgnoreProperties(ignoreUnknown = true) +@Schema(name = "PrcsListResponse", description = "가격조사 목록") +public class PrcsListResponse implements Serializable { + @Schema(name = "prcsNo", description = "가격조사번호") + String prcsNo; + @Schema(name = "cateCd", description = "분야코드") + String cateCd; + @Schema(name = "cateNm", description = "분야") + String cateNm; + @Schema(name = "title", description = "제목") + String title; + @Schema(name = "content", description = "내용") + String content; + @Schema(name = "regSdat", description = "등록시작일") + String regSdat; + @Schema(name = "regEdat", description = "등록종료일") + String regEdat; + @Schema(name = "prvYn", description = "비공개여부") + Boolean prvYn; + @Schema(name = "prvRsn", description = "비공개사유") + String prvRsn; + @Schema(name = "prvPwd", description = "비공개비밀번호") + String prvPwd; + @Schema(name = "aiYn", description = "ai검증여부") + Boolean aiYn; + @Schema(name = "regSabun", description = "등록사번") + String regSabun; + @Schema(name = "regNm", description = "등록자") + String regNm; + @Schema(name = "regDt", description = "등록일시") + String regDt; + @Schema(name = "stCd", description = "등록상태코드") + String stCd; + @Schema(name = "stNm", description = "등록상태") + String stNm; + @Schema(name = "svyYn", description = "조사완료여부") + Boolean svyYn; + @Schema(name = "svyDt", description = "조사완료일시") + String svyDt; + @Schema(name = "compDt", description = "등록완료일시") + String compDt; + + public static PrcsListResponse from(Prcs prcs) { + return PrcsListResponse.builder() + .prcsNo(prcs.getPrcsNo()) + .cateCd(prcs.getCateCd()) + .cateNm(prcs.getCateNm()) + .title(prcs.getTitle()) + .content(prcs.getContent()) + .regSdat(prcs.getRegSdat()) + .regEdat(prcs.getRegEdat()) + .prvYn(prcs.getPrvYn()) + .prvRsn(prcs.getPrvRsn()) + .prvPwd(prcs.getPrvPwd()) + .aiYn(prcs.getAiYn()) + .regSabun(prcs.getRegSabun()) + .regNm(prcs.getRegNm()) + .stCd(prcs.getStCd()) + .stNm(prcs.getStNm()) + .svyYn(prcs.getSvyYn()) + .svyDt(prcs.getSvyDt()) + .regDt(prcs.getRegDt()) + .compDt(prcs.getApprMst().getCompDt()) + .build(); + } +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/dto/res/PrcsResponse.java b/src/main/java/com/kospo/svcm/dto/res/PrcsResponse.java new file mode 100644 index 0000000..edc0e0b --- /dev/null +++ b/src/main/java/com/kospo/svcm/dto/res/PrcsResponse.java @@ -0,0 +1,90 @@ +package com.kospo.svcm.dto.res; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.kospo.svcm.model.Prcs; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; + +import java.io.Serializable; +import java.util.List; +import java.util.stream.Collectors; + +/** + * DTO for {@link Prcs} + */ +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@JsonIgnoreProperties(ignoreUnknown = true) +@Schema(name = "PrcsResponse", description = "가격조사") +public class PrcsResponse implements Serializable { + @Schema(name = "prcsNo", description = "가격조사번호") + String prcsNo; + @Schema(name = "cateCd", description = "분야코드") + String cateCd; + @Schema(name = "cateNm", description = "분야") + String cateNm; + @Schema(name = "title", description = "제목") + String title; + @Schema(name = "content", description = "내용") + String content; + @Schema(name = "regSdat", description = "등록시작일") + String regSdat; + @Schema(name = "regEdat", description = "등록종료일") + String regEdat; + @Schema(name = "prvYn", description = "비공개여부") + Boolean prvYn; + @Schema(name = "prvRsn", description = "비공개사유") + String prvRsn; + @Schema(name = "prvPwd", description = "비공개비밀번호") + String prvPwd; + @Schema(name = "aiYn", description = "ai검증여부") + Boolean aiYn; + @Schema(name = "regSabun", description = "등록사번") + String regSabun; + @Schema(name = "regNm", description = "등록자") + String regNm; + @Schema(name = "regDt", description = "등록일시") + String regDt; + @Schema(name = "stCd", description = "등록상태코드") + String stCd; + @Schema(name = "stNm", description = "등록상태") + String stNm; + @Schema(name = "svyYn", description = "조사완료여부") + Boolean svyYn; + @Schema(name = "svyDt", description = "조사완료일시") + String svyDt; + ApprMstResponse apprMst; + List prcsAtts; + List dtlSpecs; + List prcsBizs; + + public static PrcsResponse from(Prcs prcs) { + return PrcsResponse.builder() + .prcsNo(prcs.getPrcsNo()) + .cateCd(prcs.getCateCd()) + .cateNm(prcs.getCateNm()) + .title(prcs.getTitle()) + .content(prcs.getContent()) + .regSdat(prcs.getRegSdat()) + .regEdat(prcs.getRegEdat()) + .prvYn(prcs.getPrvYn()) + .prvRsn(prcs.getPrvRsn()) + .prvPwd(prcs.getPrvPwd()) + .aiYn(prcs.getAiYn()) + .regSabun(prcs.getRegSabun()) + .regNm(prcs.getRegNm()) + .stCd(prcs.getStCd()) + .stNm(prcs.getStNm()) + .svyYn(prcs.getSvyYn()) + .svyDt(prcs.getSvyDt()) + .regDt(prcs.getRegDt()) + .apprMst(prcs.getApprMst() == null ? null : ApprMstResponse.from(prcs.getApprMst())) + .prcsAtts(prcs.getPrcsAtts() == null ? null : prcs.getPrcsAtts().stream().map(PrcsAttResponse::from).collect(Collectors.toList())) + .dtlSpecs(prcs.getDtlSpecs() == null ? null : prcs.getDtlSpecs().stream().map(DtlSpecResponse::from).collect(Collectors.toList())) + .prcsBizs(prcs.getPrcsBizs() == null ? null : prcs.getPrcsBizs().stream().map(PrcsBizResponse::from).collect(Collectors.toList())) + .build(); + } +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/dto/res/RoleResponse.java b/src/main/java/com/kospo/svcm/dto/res/RoleResponse.java new file mode 100644 index 0000000..5b3c4a2 --- /dev/null +++ b/src/main/java/com/kospo/svcm/dto/res/RoleResponse.java @@ -0,0 +1,35 @@ +package com.kospo.svcm.dto.res; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.kospo.svcm.model.Role; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Builder +@JsonIgnoreProperties(ignoreUnknown = true) +@Schema(name = "RoleResponse", description = "권한") +public class RoleResponse { + @Schema(name = "roleId", description = "권한아이디") + private String roleId; + @Schema(name = "roleNm", description = "권한명") + private String roleNm; + @Schema(name = "sabun", description = "사번") + private String sabun; + @Schema(name = "ip", description = "아이피") + private String ip; + + public static RoleResponse from(Role role) { + return RoleResponse.builder() + .roleId(role.getId().getRoleId()) + .roleNm(role.getRoleNm()) + .ip(role.getIp()) + .sabun(role.getId().getSabun()) + .build(); + } +} diff --git a/src/main/java/com/kospo/svcm/dto/res/SignDocResponse.java b/src/main/java/com/kospo/svcm/dto/res/SignDocResponse.java new file mode 100644 index 0000000..23a77ab --- /dev/null +++ b/src/main/java/com/kospo/svcm/dto/res/SignDocResponse.java @@ -0,0 +1,100 @@ +package com.kospo.svcm.dto.res; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.kospo.svcm.model.SignDoc; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; + +import java.io.Serializable; +import java.util.List; +import java.util.stream.Collectors; + +/** + * DTO for {@link SignDoc} + */ +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@JsonIgnoreProperties(ignoreUnknown = true) +@Schema(name = "SignDocResponse", description = "전자결재") +public class SignDocResponse implements Serializable { + @Schema(name = "transactionKey", description = "연계 시스템 문서키") + String transactionKey; + @Schema(name = "systemGubun", description = "전자결재 시스템 구분") + String systemGubun; + @Schema(name = "writeDate", description = "기안일시") + String writeDate; + @Schema(name = "title", description = "제목") + String title; + @Schema(name = "regiDate", description = "완료일시") + String regiDate; + @Schema(name = "permGrade", description = "보안등급") + String permGrade; + @Schema(name = "deptCode", description = "부서코드") + String deptCode; + @Schema(name = "deptName", description = "부서명") + String deptName; + @Schema(name = "officeCode", description = "처실코드") + String officeCode; + @Schema(name = "officeName", description = "처실명") + String officeName; + @Schema(name = "ldmType", description = "ldm분류유형") + String ldmType; + @Schema(name = "standardDocNo", description = "공식문서번호") + String standardDocNo; + @Schema(name = "docFileName", description = "문서파일명") + String docFileName; + @Schema(name = "docFileSeq", description = "문서저장파일(경로+파일명)") + String docFileSeq; + @Schema(name = "processStatus", description = "기안진행상태") + String processStatus; + @Schema(name = "processStatusCode", description = "기안진행상태코드") + String processStatusCode; + @Schema(name = "writerId", description = "작성자 사번") + String writerId; + @Schema(name = "writerName", description = "작성자") + String writerName; + @Schema(name = "sendDate", description = "수정일시") + String sendDate; + @Schema(name = "docUrl", description = "문서URL") + String docUrl; + @Schema(name = "recvYn", description = "수신여부") + Boolean recvYn; + @Schema(name = "recvDate", description = "수신일시") + String recvDate; + @Schema(name = "recvErrorMsg", description = "수신내역") + String recvErrorMsg; + + List signLines; + + public static SignDocResponse from(SignDoc signDoc) { + return SignDocResponse.builder() + .transactionKey(signDoc.getTransactionKey()) + .systemGubun(signDoc.getSystemGubun()) + .writeDate(signDoc.getWriteDate()) + .title(signDoc.getTitle()) + .regiDate(signDoc.getRegiDate()) + .permGrade(signDoc.getPermGrade()) + .deptCode(signDoc.getDeptCode()) + .deptName(signDoc.getDeptName()) + .officeCode(signDoc.getOfficeCode()) + .officeName(signDoc.getOfficeName()) + .ldmType(signDoc.getLdmType()) + .standardDocNo(signDoc.getStandardDocNo()) + .docFileName(signDoc.getDocFileName()) + .docFileSeq(signDoc.getDocFileSeq()) + .processStatus(signDoc.getProcessStatus()) + .processStatusCode(signDoc.getProcessStatusCode()) + .writerId(signDoc.getWriterId()) + .writerName(signDoc.getWriterName()) + .sendDate(signDoc.getSendDate()) + .docUrl(signDoc.getDocUrl()) + .recvYn(signDoc.getRecvYn()) + .recvDate(signDoc.getRecvDate()) + .recvErrorMsg(signDoc.getRecvErrorMsg()) + .signLines(signDoc.getSignLines().stream().map(SignLineResponse::from).collect(Collectors.toList())) + .build(); + } +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/dto/res/SignLineResponse.java b/src/main/java/com/kospo/svcm/dto/res/SignLineResponse.java new file mode 100644 index 0000000..6e9129c --- /dev/null +++ b/src/main/java/com/kospo/svcm/dto/res/SignLineResponse.java @@ -0,0 +1,77 @@ +package com.kospo.svcm.dto.res; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.kospo.svcm.model.SignLine; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; + +import java.io.Serializable; + +/** + * DTO for {@link SignLine} + */ +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@JsonIgnoreProperties(ignoreUnknown = true) +@Schema(name = "SignLineResponse", description = "전자결재 결재선") +public class SignLineResponse implements Serializable { + @Schema(name = "transactionKey", description = "연계 시스템 문서 키") + String transactionKey; + @Schema(name = "signOrder", description = "결재순번") + Integer signOrder; + @Schema(name = "systemGubun", description = "시스템구분") + String systemGubun; + @Schema(name = "signerId", description = "결재자 사번") + String signerId; + @Schema(name = "signerGubun", description = "결재자 구분") + String signerGubun; + @Schema(name = "signLevel", description = "결재 레벨") + Integer signLevel; + @Schema(name = "signerName", description = "결재자 성명") + String signerName; + @Schema(name = "signerPosName", description = "결재자 직위") + String signerPosName; + @Schema(name = "signDate", description = "결재일시") + String signDate; + @Schema(name = "signerStatus", description = "결재상태") + String signerStatus; + @Schema(name = "signResult", description = "결재방법") + String signResult; + @Schema(name = "opinion", description = "결재의견") + String opinion; + @Schema(name = "replaceId", description = "대결자사번") + String replaceId; + @Schema(name = "replaceName", description = "대결자") + String replaceName; + @Schema(name = "recvYn", description = "수신여부") + Boolean recvYn; + @Schema(name = "recvDate", description = "수신일시") + String recvDate; + @Schema(name = "recvErrorMsg", description = "수신내역") + String recvErrorMsg; + + public static SignLineResponse from(SignLine signLine) { + return SignLineResponse.builder() + .transactionKey(signLine.getId().getTransactionKey()) + .signOrder(signLine.getId().getSignOrder()) + .systemGubun(signLine.getSystemGubun()) + .signerId(signLine.getSignerId()) + .signerGubun(signLine.getSignerGubun()) + .signLevel(signLine.getSignLevel()) + .signerName(signLine.getSignerName()) + .signerPosName(signLine.getSignerPosName()) + .signDate(signLine.getSignDate()) + .signerStatus(signLine.getSignerStatus()) + .signResult(signLine.getSignResult()) + .opinion(signLine.getOpinion()) + .replaceId(signLine.getReplaceId()) + .replaceName(signLine.getReplaceName()) + .recvYn(signLine.getRecvYn()) + .recvDate(signLine.getRecvDate()) + .recvErrorMsg(signLine.getRecvErrorMsg()) + .build(); + } +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/dto/res/SlipAttResponse.java b/src/main/java/com/kospo/svcm/dto/res/SlipAttResponse.java new file mode 100644 index 0000000..e5366d9 --- /dev/null +++ b/src/main/java/com/kospo/svcm/dto/res/SlipAttResponse.java @@ -0,0 +1,45 @@ +package com.kospo.svcm.dto.res; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.kospo.svcm.model.PrcsAtt; +import com.kospo.svcm.model.SlipAtt; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; + +import java.io.Serializable; + +/** + * DTO for {@link PrcsAtt} + */ +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@JsonIgnoreProperties(ignoreUnknown = true) +@Schema(name = "SlipAttResponse", description = "전표 첨부파일") +public class SlipAttResponse implements Serializable { + @Schema(name = "contNo", description = "계약번호") + String prcsNo; + @Schema(name = "fileOrd", description = "파일순서") + Integer fileOrd; + @Schema(name = "logiFnm", description = "논리파일명") + String logiFnm; + @Schema(name = "physFnm", description = "물리파일명") + String physFnm; + @Schema(name = "size", description = "사이즈") + Integer size; + @Schema(name = "path", description = "경로") + String path; + + public static SlipAttResponse from(SlipAtt slipAtt) { + return SlipAttResponse.builder() + .prcsNo(slipAtt.getId().getContNo()) + .fileOrd(slipAtt.getId().getFileOrd()) + .logiFnm(slipAtt.getLogiFnm()) + .physFnm(slipAtt.getPhysFnm()) + .size(slipAtt.getSize()) + .path(slipAtt.getPath()) + .build(); + } +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/dto/res/SlipResponse.java b/src/main/java/com/kospo/svcm/dto/res/SlipResponse.java new file mode 100644 index 0000000..eda3b6e --- /dev/null +++ b/src/main/java/com/kospo/svcm/dto/res/SlipResponse.java @@ -0,0 +1,95 @@ +package com.kospo.svcm.dto.res; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.kospo.svcm.model.Slip; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; + +import java.io.Serializable; +import java.util.List; + +/** + * DTO for {@link Slip} + */ +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@JsonIgnoreProperties(ignoreUnknown = true) +@Schema(name = "SlipResponse", description = "FI 임시 전표") +public class SlipResponse implements Serializable { + @Schema(name = "contNo", description = "계약번호") + String contNo; + @Schema(name = "lifnr", description = "계약대상자") + String lifnr; + @Schema(name = "gsber", description = "사업영역코드") + String gsber; + @Schema(name = "wrbtrS", description = "전기금액(공급가액)") + String wrbtrS; + @Schema(name = "mwskz", description = "세금코드") + String mwskz; + @Schema(name = "waers", description = "통화코드") + String waers; + @Schema(name = "bldat", description = "증빙일") + String bldat; + @Schema(name = "budat", description = "전기일") + String budat; + @Schema(name = "hkont", description = "계정과목코드") + String hkont; + @Schema(name = "kostl", description = "코스트센터코드") + String kostl; + @Schema(name = "projk", description = "WBS요소코드") + String projk; + @Schema(name = "wrbtr", description = "전기금액(공급가액+세액)") + String wrbtr; + @Schema(name = "bvtyp", description = "파트너은행") + String bvtyp; + @Schema(name = "bstat", description = "전표상태") + String bstat; + @Schema(name = "bankl", description = "은행코드") + String bankl; + @Schema(name = "usnam", description = "전표생성자사번") + String usnam; + @Schema(name = "gjahr", description = "회계년도") + String gjahr; + @Schema(name = "belnr", description = "전표번호") + String belnr; + @Schema(name = "bukrs", description = "남부발전코드(1000)") + String bukrs; + @Schema(name = "type", description = "메시지유형") + String type; + @Schema(name = "message", description = "메시지") + String message; + @Schema(name = "regDt", description = "결재순번") + String regDt; + List slipAtts; + + + public static SlipResponse to(Slip slip) { + return SlipResponse.builder() + .contNo(slip.getContNo()) + .lifnr(slip.getLifnr()) + .gsber(slip.getGsber()) + .wrbtrS(slip.getWrbtrS()) + .mwskz(slip.getMwskz()) + .waers(slip.getWaers()) + .bldat(slip.getBldat()) + .budat(slip.getBudat()) + .hkont(slip.getHkont()) + .kostl(slip.getKostl()) + .projk(slip.getProjk()) + .wrbtr(slip.getWrbtr()) + .bvtyp(slip.getBvtyp()) + .bstat(slip.getBstat()) + .usnam(slip.getUsnam()) + .gjahr(slip.getGjahr()) + .belnr(slip.getBelnr()) + .bukrs(slip.getBukrs()) + .type(slip.getType()) + .message(slip.getMessage()) + .regDt(slip.getRegDt()) + .slipAtts(slip.getSlipAtts() == null ? null : slip.getSlipAtts().stream().map(SlipAttResponse::from).toList()) + .build(); + } +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/dto/res/TokenResponse.java b/src/main/java/com/kospo/svcm/dto/res/TokenResponse.java new file mode 100644 index 0000000..a1fc43a --- /dev/null +++ b/src/main/java/com/kospo/svcm/dto/res/TokenResponse.java @@ -0,0 +1,29 @@ +package com.kospo.svcm.dto.res; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Builder +@JsonIgnoreProperties(ignoreUnknown = true) +@Schema(name = "TokenResponse", description = "토큰") +public class TokenResponse implements Serializable { + @Schema(name = "bid", description = "사업자번호") + private String bid; + @Schema(name = "accessToken", description = "엑서스 토큰") + private String accessToken; + @Schema(name = "accessTokenExpired", description = "엑서스 토큰 만료시간") + private Long accessTokenExpired; + @Schema(name = "refreshToken", description = "리플레시 토큰") + private String refreshToken; + @Schema(name = "refreshTokenExpired", description = "리플레시 토큰 만료시간") + private Long refreshTokenExpired; +} diff --git a/src/main/java/com/kospo/svcm/dto/res/UserResponse.java b/src/main/java/com/kospo/svcm/dto/res/UserResponse.java new file mode 100644 index 0000000..04b838e --- /dev/null +++ b/src/main/java/com/kospo/svcm/dto/res/UserResponse.java @@ -0,0 +1,56 @@ +package com.kospo.svcm.dto.res; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.kospo.svcm.model.Role; +import com.kospo.svcm.model.User; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; + +import java.util.List; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@JsonIgnoreProperties(ignoreUnknown = true) +@Schema(name = "UserResponse", description = "인사정보") +public class UserResponse { + @Schema(name = "sabun", description = "사번") + private String sabun; + @Schema(name = "name", description = "이름") + private String name; + @Schema(name = "deptCd", description = "부서코드") + private String deptCd; + @Schema(name = "deptNm", description = "부서명") + private String deptNm; + @Schema(name = "ptsnNm", description = "직위") + private String ptsnNm; + @Schema(name = "gradeCd", description = "직급코드") + private String gradeCd; + @Schema(name = "gradeNm", description = "직급명") + private String gradeNm; + @Schema(name = "ofcePhn", description = "내선벟노") + private String ofcePhn; + @Schema(name = "mblPhn", description = "이동번호") + private String mblPhn; + @Schema(name = "state", description = "상태") + private String state; + List roles; + + public static UserResponse from(User user) { + return UserResponse.builder() + .sabun(user.getSabun()) + .name(user.getName()) + .deptCd(user.getDeptCd()) + .deptNm(user.getDept().getDeptNm()) + .ptsnNm(user.getPtsnNm()) + .gradeCd(user.getGradeCd()) + .gradeNm(user.getGradeNm()) + .ofcePhn(user.getOfcePhn()) + .mblPhn(user.getMblPhn()) + .state(user.getState()) + .roles(user.getRoles()) + .build(); + } +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/dto/res/UserSelectListResponse.java b/src/main/java/com/kospo/svcm/dto/res/UserSelectListResponse.java new file mode 100644 index 0000000..4d1e47b --- /dev/null +++ b/src/main/java/com/kospo/svcm/dto/res/UserSelectListResponse.java @@ -0,0 +1,72 @@ +package com.kospo.svcm.dto.res; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.kospo.svcm.model.User; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@JsonIgnoreProperties(ignoreUnknown = true) +@Schema(name = "UserSelectLIstResponse", description = "직원 선택") +public class UserSelectListResponse { + String label; + UserSelect value; + + @Getter + @Setter + @NoArgsConstructor + @AllArgsConstructor + @Builder + @JsonIgnoreProperties(ignoreUnknown = true) + @Schema(name = "UserSelect", description = "직원 정보") + public static class UserSelect{ + @Schema(name = "sabun", description = "사번") + String sabun; + @Schema(name = "name", description = "이름") + private String name; + @Schema(name = "deptCd", description = "무서코드") + private String deptCd; + @Schema(name = "deptNm", description = "부서명") + private String deptNm; + @Schema(name = "ptsnNm", description = "직위") + private String ptsnNm; + @Schema(name = "gradeCd", description = "직급코드") + private String gradeCd; + @Schema(name = "gradeNm", description = "직급명") + private String gradeNm; + @Schema(name = "ofcePhn", description = "내선벟노") + private String ofcePhn; + @Schema(name = "mblPhn", description = "이동번호") + private String mblPhn; + @Schema(name = "state", description = "상태") + private String state; + @Schema(name = "attendCd", description = "근태상태코드") + private String attendCd; + @Schema(name = "attendNm", description = "근태상태") + private String attendNm; + @Schema(name = "attendStaYmd", description = "근태시작일") + private String attendStaYmd; + @Schema(name = "attendEndYmd", description = "근태종료일") + private String attendEndYmd; + + public static UserSelect from(User user) { + return UserSelect.builder() + .sabun(user.getSabun()) + .name(user.getName()) + .deptCd(user.getDeptCd()) + .deptNm(user.getDept().getDeptNm()) + .ptsnNm(user.getPtsnNm()) + .gradeCd(user.getGradeCd()) + .gradeNm(user.getGradeNm()) + .attendCd(user.getAttendCd()) + .attendNm(user.getAttendNm()) + .attendStaYmd(user.getAttendStaYmd()) + .attendEndYmd(user.getAttendEndYmd()) + .build(); + } + } +} diff --git a/src/main/java/com/kospo/svcm/dto/res/Zwf0011tResponse.java b/src/main/java/com/kospo/svcm/dto/res/Zwf0011tResponse.java new file mode 100644 index 0000000..b1b5524 --- /dev/null +++ b/src/main/java/com/kospo/svcm/dto/res/Zwf0011tResponse.java @@ -0,0 +1,62 @@ +package com.kospo.svcm.dto.res; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.kospo.svcm.model.Zwf0011t; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; + +import java.io.Serializable; +import java.util.List; + +/** + * DTO for {@link com.kospo.svcm.model.Zwf0011t} + */ +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@JsonIgnoreProperties(ignoreUnknown = true) +@Schema(name = "Zwf0011tResponse", description = "SAP 결재 마스터") +public class Zwf0011tResponse implements Serializable { + @Schema(name = "wkfid", description = "요청번호") + String wkfid; + @Schema(name = "catag", description = "업무구분") + String catag; + @Schema(name = "obkey", description = "오브젝트키") + String obkey; + @Schema(name = "wkfst", description = "결재상태") + String wkfst; + @Schema(name = "wkftx", description = "결재제목") + String wkftx; + @Schema(name = "ernam", description = "결재요청자사번") + String ernam; + @Schema(name = "erdat", description = "결재요청일") + String erdat; + @Schema(name = "erzet", description = "결재요청시간") + String erzet; + @Schema(name = "aenam", description = "결재승인자사번") + String aenam; + @Schema(name = "aedat", description = "결재승인일") + String aedat; + @Schema(name = "aezet", description = "결재승인시간") + String aezet; + + List apprs; + + public static Zwf0011tResponse to(Zwf0011t zwf0011t) { + return Zwf0011tResponse.builder() + .catag(zwf0011t.getId().getCatag()) + .wkfid(zwf0011t.getId().getWkfid()) + .obkey(zwf0011t.getObkey()) + .wkfst(zwf0011t.getWkfst()) + .wkftx(zwf0011t.getWkftx()) + .ernam(zwf0011t.getErnam()) + .erdat(zwf0011t.getErdat()) + .erzet(zwf0011t.getErzet()) + .aenam(zwf0011t.getAenam()) + .aedat(zwf0011t.getAedat()) + .aezet(zwf0011t.getAezet()) + .build(); + } +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/dto/res/Zwf0012tResponse.java b/src/main/java/com/kospo/svcm/dto/res/Zwf0012tResponse.java new file mode 100644 index 0000000..3c7b199 --- /dev/null +++ b/src/main/java/com/kospo/svcm/dto/res/Zwf0012tResponse.java @@ -0,0 +1,72 @@ +package com.kospo.svcm.dto.res; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.kospo.svcm.model.Zwf0012t; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.Size; +import lombok.*; + +import java.io.Serializable; + +/** + * DTO for {@link com.kospo.svcm.model.Zwf0012t} + */ +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@JsonIgnoreProperties(ignoreUnknown = true) +@Schema(name = "Zwf0012tResponse", description = "SAP 결재선") +public class Zwf0012tResponse implements Serializable { + @Schema(name = "wkfid", description = "요청번호") + String wkfid; + @Schema(name = "wkfsq", description = "결재순번") + Integer wkfsq; + @Schema(name = "lineclsf", description = "결재구분") + String lineclsf; + @Schema(name = "bname", description = "사번") + String bname; + @Schema(name = "btext", description = "성명") + String btext; + @Schema(name = "posit", description = "직급") + String posit; + @Schema(name = "deptn", description = "부서명") + String deptn; + @Schema(name = "wkfst", description = "결재상태") + String wkfst; + @Schema(name = "abscd", description = "사유코드") + String abscd; + @Schema(name = "ernam", description = "결재요청자사번") + String ernam; + @Schema(name = "erdat", description = "결재요청일") + String erdat; + @Schema(name = "erzet", description = "결재요청시간") + String erzet; + @Schema(name = "aenam", description = "결재승인자사번") + String aenam; + @Schema(name = "aedat", description = "결재승인일") + String aedat; + @Schema(name = "aezet", description = "결재승인시간") + String aezet; + + public static Zwf0012tResponse to(Zwf0012t zwf0012t) { + return Zwf0012tResponse.builder() + .wkfid(zwf0012t.getId().getWkfid()) + .wkfsq(zwf0012t.getId().getWkfsq()) + .lineclsf(zwf0012t.getLineclsf()) + .bname(zwf0012t.getBname()) + .btext(zwf0012t.getBtext()) + .posit(zwf0012t.getPosit()) + .deptn(zwf0012t.getDeptn()) + .wkfst(zwf0012t.getWkfst()) + .abscd(zwf0012t.getAbscd()) + .ernam(zwf0012t.getErnam()) + .erdat(zwf0012t.getErdat()) + .erzet(zwf0012t.getErzet()) + .aenam(zwf0012t.getAenam()) + .aedat(zwf0012t.getAedat()) + .aezet(zwf0012t.getAezet()) + .build(); + } +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/dto/res/Zwf0013tResponse.java b/src/main/java/com/kospo/svcm/dto/res/Zwf0013tResponse.java new file mode 100644 index 0000000..f143aa9 --- /dev/null +++ b/src/main/java/com/kospo/svcm/dto/res/Zwf0013tResponse.java @@ -0,0 +1,80 @@ +package com.kospo.svcm.dto.res; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.kospo.svcm.model.Zwf0013t; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.Size; +import lombok.*; + +import java.io.Serializable; + +/** + * DTO for {@link com.kospo.svcm.model.Zwf0013t} + */ +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@JsonIgnoreProperties(ignoreUnknown = true) +@Schema(name = "Zwf0013tResponse", description = "SAP (협조, 통제) 결재선") +public class Zwf0013tResponse implements Serializable { + @Schema(name = "wkfid", description = "요청번호") + String wkfid; + @Schema(name = "gubun", description = "결재선 구분") + String gubun; + @Schema(name = "bname", description = "사번") + String bname; + @Schema(name = "wkfsq", description = "결재순번") + Integer wkfsq; + @Schema(name = "lineclsf", description = "[WF]결재구분") + String lineclsf; + @Schema(name = "btext", description = "성명") + String btext; + @Schema(name = "posit", description = "직급") + String posit; + @Schema(name = "deptn", description = "부서명") + String deptn; + @Schema(name = "wkfst", description = "결재상태") + String wkfst; + @Schema(name = "abscd", description = "사유코드") + String abscd; + @Schema(name = "ernam", description = "결재요청자사번") + String ernam; + @Schema(name = "erdat", description = "결재요청일") + String erdat; + @Schema(name = "erzet", description = "결재요청시간") + String erzet; + @Schema(name = "aenam", description = "결재승인자사번") + String aenam; + @Schema(name = "aedat", description = "결재승인일") + String aedat; + @Schema(name = "aezet", description = "결재승인시간") + String aezet; + @Schema(name = "wkfsq1", description = "결재구분") + Integer wkfsq1; + @Schema(name = "grpid", description = "그룹번호") + Integer grpid; + + public static Zwf0013tResponse to(Zwf0013t zwf0013t) { + return Zwf0013tResponse.builder() + .wkfid(zwf0013t.getId().getWkfid()) + .gubun(zwf0013t.getId().getGubun()) + .bname(zwf0013t.getId().getBname()) + .wkfsq(zwf0013t.getWkfsq()) + .lineclsf(zwf0013t.getLineclsf()) + .btext(zwf0013t.getBtext()) + .posit(zwf0013t.getPosit()) + .deptn(zwf0013t.getDeptn()) + .wkfst(zwf0013t.getWkfst()) + .abscd(zwf0013t.getAbscd()) + .ernam(zwf0013t.getErnam()) + .erdat(zwf0013t.getErdat()) + .erzet(zwf0013t.getErzet()) + .aenam(zwf0013t.getAenam()) + .aedat(zwf0013t.getAedat()) + .aezet(zwf0013t.getAezet()) + .wkfsq1(zwf0013t.getWkfsq1()) + .build(); + } +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/dto/res/ZwfApprGrpResponse.java b/src/main/java/com/kospo/svcm/dto/res/ZwfApprGrpResponse.java new file mode 100644 index 0000000..e8d9950 --- /dev/null +++ b/src/main/java/com/kospo/svcm/dto/res/ZwfApprGrpResponse.java @@ -0,0 +1,27 @@ +package com.kospo.svcm.dto.res; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.kospo.svcm.model.Zwf0011t; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; + +import java.io.Serializable; +import java.util.List; + +/** + * DTO for {@link Zwf0011t} + */ +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@JsonIgnoreProperties(ignoreUnknown = true) +@Schema(name = "ZwfApprResponse", description = "SAP 결재 마스터") +public class ZwfApprGrpResponse implements Serializable { + @Schema(name = "label", description = "명칭") + String label; + @Schema(name = "value", description = "결재선") + List value; + +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/dto/res/ZwfApprResponse.java b/src/main/java/com/kospo/svcm/dto/res/ZwfApprResponse.java new file mode 100644 index 0000000..31cd9a7 --- /dev/null +++ b/src/main/java/com/kospo/svcm/dto/res/ZwfApprResponse.java @@ -0,0 +1,98 @@ +package com.kospo.svcm.dto.res; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.kospo.svcm.model.Zwf0012t; +import com.kospo.svcm.model.Zwf0013t; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; + +import java.io.Serializable; + +/** + * DTO for {@link Zwf0012t} + */ +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@JsonIgnoreProperties(ignoreUnknown = true) +@Schema(name = "ZwfListResponse", description = "SAP 결재선 목록") +public class ZwfApprResponse implements Serializable { + @Schema(name = "wkfid", description = "요청번호") + String wkfid; + @Schema(name = "wkfsq", description = "결재순번") + Integer wkfsq; + @Schema(name = "lineclsf", description = "결재구분") + String lineclsf; + @Schema(name = "bname", description = "사번") + String bname; + @Schema(name = "btext", description = "성명") + String btext; + @Schema(name = "posit", description = "직급") + String posit; + @Schema(name = "deptn", description = "부서명") + String deptn; + @Schema(name = "wkfst", description = "결재상태") + String wkfst; + @Schema(name = "abscd", description = "사유코드") + String abscd; + @Schema(name = "ernam", description = "결재요청자사번") + String ernam; + @Schema(name = "erdat", description = "결재요청일") + String erdat; + @Schema(name = "erzet", description = "결재요청시간") + String erzet; + @Schema(name = "aenam", description = "결재승인자사번") + String aenam; + @Schema(name = "aedat", description = "결재승인일") + String aedat; + @Schema(name = "aezet", description = "결재승인시간") + String aezet; + @Schema(name = "gubun", description = "결재선구분") + String gubun; + @Schema(name = "wkfsq1", description = "결재구분") + Integer wkfsq1; + + public static ZwfApprResponse to12(Zwf0012t zwf0012t) { + return ZwfApprResponse.builder() + .wkfid(zwf0012t.getId().getWkfid()) + .wkfsq(zwf0012t.getId().getWkfsq()) + .lineclsf(zwf0012t.getLineclsf()) + .bname(zwf0012t.getBname()) + .btext(zwf0012t.getBtext()) + .posit(zwf0012t.getPosit()) + .deptn(zwf0012t.getDeptn()) + .wkfst(zwf0012t.getWkfst()) + .abscd(zwf0012t.getAbscd()) + .ernam(zwf0012t.getErnam()) + .erdat(zwf0012t.getErdat()) + .erzet(zwf0012t.getErzet()) + .aenam(zwf0012t.getAenam()) + .aedat(zwf0012t.getAedat()) + .aezet(zwf0012t.getAezet()) + .build(); + } + + public static ZwfApprResponse to13(Zwf0013t zwf0013t) { + return ZwfApprResponse.builder() + .wkfid(zwf0013t.getId().getWkfid()) + .wkfsq(zwf0013t.getWkfsq()) + .lineclsf(zwf0013t.getLineclsf()) + .bname(zwf0013t.getId().getBname()) + .gubun(zwf0013t.getId().getGubun()) + .btext(zwf0013t.getBtext()) + .posit(zwf0013t.getPosit()) + .deptn(zwf0013t.getDeptn()) + .wkfst(zwf0013t.getWkfst()) + .abscd(zwf0013t.getAbscd()) + .ernam(zwf0013t.getErnam()) + .erdat(zwf0013t.getErdat()) + .erzet(zwf0013t.getErzet()) + .aenam(zwf0013t.getAenam()) + .aedat(zwf0013t.getAedat()) + .aezet(zwf0013t.getAezet()) + .wkfsq1(zwf0013t.getWkfsq1()) + .build(); + } +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/dto/xml/QsSample.java b/src/main/java/com/kospo/svcm/dto/xml/QsSample.java new file mode 100644 index 0000000..e8816ee --- /dev/null +++ b/src/main/java/com/kospo/svcm/dto/xml/QsSample.java @@ -0,0 +1,45 @@ +package com.kospo.svcm.dto.xml; + +import jakarta.xml.bind.annotation.XmlAccessType; +import jakarta.xml.bind.annotation.XmlAccessorType; +import jakarta.xml.bind.annotation.XmlElement; +import jakarta.xml.bind.annotation.XmlRootElement; +import lombok.*; +import java.util.List; + +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Setter +@Getter +@XmlAccessorType(XmlAccessType.FIELD) +@XmlRootElement(name = "AP_REP_MSG") +@ToString +public class QsSample { + @XmlElement(name = "E_MESSAGE") + String message; + @XmlElement(name = "E_TYPE") + String type; + @XmlElement(name="T_LIST_QS") + List qss; + + @Builder + @NoArgsConstructor + @AllArgsConstructor + @Setter + @Getter + @XmlAccessorType(XmlAccessType.FIELD) + @ToString + public static class Qs { + @XmlElement(name = "SAP_ZDOCNO") + String zDocno; + @XmlElement(name = "SAP_ZSTAT") + String zStat; + @XmlElement(name = "SAP_ZSTAT_T") + String zStatT; + @XmlElement(name = "SAP_DKTXT") + String zSDkTxt; + @XmlElement(name = "SAP_CODE") + String code; + } +} diff --git a/src/main/java/com/kospo/svcm/dto/xml/SlipXml.java b/src/main/java/com/kospo/svcm/dto/xml/SlipXml.java new file mode 100644 index 0000000..882a7cb --- /dev/null +++ b/src/main/java/com/kospo/svcm/dto/xml/SlipXml.java @@ -0,0 +1,54 @@ +package com.kospo.svcm.dto.xml; + +import com.kospo.svcm.model.SlipAtt; +import jakarta.persistence.*; +import jakarta.validation.constraints.Size; +import jakarta.xml.bind.annotation.XmlElement; +import jakarta.xml.bind.annotation.XmlRootElement; +import lombok.*; + +import java.util.List; +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Setter +@Getter +@XmlRootElement(name = "EaiSend") +public class SlipXml { + @XmlElement(name = "SAP_CONT_NO") + private String contNo; + @XmlElement(name = "SAP_LIFNR") + private String lifnr; + @XmlElement(name = "SAP_GSBER") + private String gsber; + @XmlElement(name = "SAP_WRBTR_S") + private String wrbtrS; + @XmlElement(name = "SAP_MWSKZ") + private String mwskz; + @XmlElement(name = "SAP_WAERS") + private String waers; + @XmlElement(name = "SAP_BLDAT") + private String bldat; + @XmlElement(name = "SAP_BUDAT") + private String budat; + @XmlElement(name = "SAP_HKONT") + private String hkont; + @XmlElement(name = "SAP_KOSTL") + private String kostl; + @XmlElement(name = "SAP_PROJK") + private String projk; + @XmlElement(name = "SAP_WRBTR") + private String wrbtr; + @XmlElement(name = "SAP_BVTYP") + private String bvtyp; + @XmlElement(name = "SAP_BSTAT") + private String bstat; + @XmlElement(name = "SAP_USNAM") + private String usnam; + @XmlElement(name = "SAP_GJAHR") + private String gjahr; + @XmlElement(name = "SAP_BELNR") + private String belnr; + @XmlElement(name = "SAP_BUKRS") + private String bukrs; +} diff --git a/src/main/java/com/kospo/svcm/exception/CustomException.java b/src/main/java/com/kospo/svcm/exception/CustomException.java new file mode 100644 index 0000000..8327a5a --- /dev/null +++ b/src/main/java/com/kospo/svcm/exception/CustomException.java @@ -0,0 +1,14 @@ +package com.kospo.svcm.exception; + + +import com.kospo.svcm.config.exception.ErrorCode; +import lombok.*; + +@Getter +public class CustomException extends RuntimeException{ + private ErrorCode errorCode; + + public CustomException(ErrorCode errorCode) { + this.errorCode = errorCode; + } +} diff --git a/src/main/java/com/kospo/svcm/exception/CustomExpireTokenException.java b/src/main/java/com/kospo/svcm/exception/CustomExpireTokenException.java new file mode 100644 index 0000000..8b54d2a --- /dev/null +++ b/src/main/java/com/kospo/svcm/exception/CustomExpireTokenException.java @@ -0,0 +1,7 @@ +package com.kospo.svcm.exception; + +public class CustomExpireTokenException extends RuntimeException{ + public CustomExpireTokenException(String message) { + super(message); + } +} diff --git a/src/main/java/com/kospo/svcm/exception/CustomMalformedJwtException.java b/src/main/java/com/kospo/svcm/exception/CustomMalformedJwtException.java new file mode 100644 index 0000000..ada26cc --- /dev/null +++ b/src/main/java/com/kospo/svcm/exception/CustomMalformedJwtException.java @@ -0,0 +1,7 @@ +package com.kospo.svcm.exception; + +public class CustomMalformedJwtException extends RuntimeException{ + public CustomMalformedJwtException(String message) { + super(message); + } +} diff --git a/src/main/java/com/kospo/svcm/exception/CustomMessageException.java b/src/main/java/com/kospo/svcm/exception/CustomMessageException.java new file mode 100644 index 0000000..90d8b1e --- /dev/null +++ b/src/main/java/com/kospo/svcm/exception/CustomMessageException.java @@ -0,0 +1,25 @@ +package com.kospo.svcm.exception; + + +import com.kospo.svcm.config.exception.ErrorCode; +import lombok.*; + +@Getter +public class CustomMessageException extends RuntimeException{ + private CusMessage cusMessage; + + @NoArgsConstructor + @AllArgsConstructor + @Data + @Builder + public static class CusMessage { + String code; + String message; + } + + + + public CustomMessageException(CusMessage cusMessage) { + this.cusMessage = cusMessage; + } +} diff --git a/src/main/java/com/kospo/svcm/exception/CustomNoAccountException.java b/src/main/java/com/kospo/svcm/exception/CustomNoAccountException.java new file mode 100644 index 0000000..5bd1370 --- /dev/null +++ b/src/main/java/com/kospo/svcm/exception/CustomNoAccountException.java @@ -0,0 +1,7 @@ +package com.kospo.svcm.exception; + +public class CustomNoAccountException extends RuntimeException{ + public CustomNoAccountException(String message) { + super(message); + } +} diff --git a/src/main/java/com/kospo/svcm/exception/CustomNoMatchTokenException.java b/src/main/java/com/kospo/svcm/exception/CustomNoMatchTokenException.java new file mode 100644 index 0000000..fc98a89 --- /dev/null +++ b/src/main/java/com/kospo/svcm/exception/CustomNoMatchTokenException.java @@ -0,0 +1,7 @@ +package com.kospo.svcm.exception; + +public class CustomNoMatchTokenException extends RuntimeException{ + public CustomNoMatchTokenException(String message) { + super(message); + } +} diff --git a/src/main/java/com/kospo/svcm/exception/CustomNoResultException.java b/src/main/java/com/kospo/svcm/exception/CustomNoResultException.java new file mode 100644 index 0000000..b3c9020 --- /dev/null +++ b/src/main/java/com/kospo/svcm/exception/CustomNoResultException.java @@ -0,0 +1,7 @@ +package com.kospo.svcm.exception; + +public class CustomNoResultException extends RuntimeException{ + public CustomNoResultException(String message) { + super(message); + } +} diff --git a/src/main/java/com/kospo/svcm/exception/CustomNoSameIpException.java b/src/main/java/com/kospo/svcm/exception/CustomNoSameIpException.java new file mode 100644 index 0000000..ef52fb4 --- /dev/null +++ b/src/main/java/com/kospo/svcm/exception/CustomNoSameIpException.java @@ -0,0 +1,7 @@ +package com.kospo.svcm.exception; + +public class CustomNoSameIpException extends RuntimeException{ + public CustomNoSameIpException(String message) { + super(message); + } +} diff --git a/src/main/java/com/kospo/svcm/exception/CustomNoTokenException.java b/src/main/java/com/kospo/svcm/exception/CustomNoTokenException.java new file mode 100644 index 0000000..e8072bf --- /dev/null +++ b/src/main/java/com/kospo/svcm/exception/CustomNoTokenException.java @@ -0,0 +1,7 @@ +package com.kospo.svcm.exception; + +public class CustomNoTokenException extends RuntimeException{ + public CustomNoTokenException(String message) { + super(message); + } +} diff --git a/src/main/java/com/kospo/svcm/model/ApprMst.java b/src/main/java/com/kospo/svcm/model/ApprMst.java new file mode 100644 index 0000000..cdcb001 --- /dev/null +++ b/src/main/java/com/kospo/svcm/model/ApprMst.java @@ -0,0 +1,58 @@ +package com.kospo.svcm.model; + +import jakarta.persistence.*; +import jakarta.validation.constraints.Size; +import lombok.*; + +import java.util.List; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@Entity +@Table(name = "appr_mst") +public class ApprMst { + @Id + @Size(max = 20) + @Column(name = "appr_no", nullable = false, length = 20) + private String apprNo; + + @Size(max = 20) + @Column(name = "prcs_no", nullable = false, length = 20) + private String prcsNo; + + @Size(max = 4) + @Column(name = "appr_stat_cd", length = 4) + private String apprStatCd; + + @Size(max = 50) + @Column(name = "appr_stat", length = 50) + private String apprStat; + + @Size(max = 1000) + @Column(name = "reason", length = 1000) + private String reason; + + @Size(max = 25) + @Column(name = "comp_dt", length = 25) + private String compDt; + + @Size(max = 25) + @Column(name = "reg_dt", length = 25) + private String regDt; + + @Size(max = 20) + @Column(name = "reg_sabun", length = 20) + private String regSabun; + + @OneToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "prcs_no", nullable = false, updatable = false, insertable = false) + Prcs prcs; + + @OrderBy("id.apprOrd asc") + @OneToMany(fetch = FetchType.LAZY) + @JoinColumn(name = "appr_no", referencedColumnName = "appr_no", updatable = false, insertable = false) + List apprReqs; +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/model/ApprReq.java b/src/main/java/com/kospo/svcm/model/ApprReq.java new file mode 100644 index 0000000..7e47949 --- /dev/null +++ b/src/main/java/com/kospo/svcm/model/ApprReq.java @@ -0,0 +1,68 @@ +package com.kospo.svcm.model; + +import jakarta.persistence.*; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; +import lombok.*; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@Entity +@Table(name = "appr_req") +public class ApprReq { + @EmbeddedId + private ApprReqId id; + + @Size(max = 10) + @Column(name = "sabun", length = 10) + private String sabun; + + @Size(max = 20) + @Column(name = "name", length = 20) + private String name; + + @Size(max = 4) + @Column(name = "appr_stat_cd", length = 4) + private String apprStatCd; + + @Size(max = 50) + @Column(name = "appr_stat", length = 50) + private String apprStat; + + @Size(max = 25) + @Column(name = "appr_dt", length = 25) + private String apprDt; + + @Size(max = 4) + @Column(name = "attend_cd", length = 4) + private String attendCd; + + @Size(max = 50) + @Column(name = "attend_nm", length = 50) + private String attendNm; + + @Size(max = 4) + @Column(name = "gubun_cd", length = 4) + private String gubunCd; + + @Size(max = 50) + @Column(name = "gubun_nm", length = 50) + private String gubunNm; + + @Size(max = 10) + @Column(name = "dept_cd", length = 10) + private String deptCd; + + @Size(max = 200) + @Column(name = "dept_nm", length = 200) + private String deptNm; + + + @NotNull + @ManyToOne(fetch = FetchType.LAZY, optional = false) + @JoinColumn(name = "appr_no", nullable = false, updatable = false, insertable = false) + private ApprMst apprMst; +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/model/ApprReqId.java b/src/main/java/com/kospo/svcm/model/ApprReqId.java new file mode 100644 index 0000000..51c41d6 --- /dev/null +++ b/src/main/java/com/kospo/svcm/model/ApprReqId.java @@ -0,0 +1,44 @@ +package com.kospo.svcm.model; + +import jakarta.persistence.Column; +import jakarta.persistence.Embeddable; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; +import lombok.*; +import org.hibernate.Hibernate; + +import java.io.Serializable; +import java.util.Objects; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@Embeddable +public class ApprReqId implements Serializable { + private static final long serialVersionUID = 5765309624528101663L; + @Size(max = 20) + @NotNull + @Column(name = "appr_no", nullable = false, length = 20) + private String apprNo; + + @NotNull + @Column(name = "appr_ord", nullable = false) + private Integer apprOrd; + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || Hibernate.getClass(this) != Hibernate.getClass(o)) return false; + ApprReqId entity = (ApprReqId) o; + return Objects.equals(this.apprOrd, entity.apprOrd) && + Objects.equals(this.apprNo, entity.apprNo); + } + + @Override + public int hashCode() { + return Objects.hash(apprOrd, apprNo); + } + +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/model/Business.java b/src/main/java/com/kospo/svcm/model/Business.java new file mode 100644 index 0000000..09db3a7 --- /dev/null +++ b/src/main/java/com/kospo/svcm/model/Business.java @@ -0,0 +1,94 @@ +package com.kospo.svcm.model; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.Table; +import jakarta.validation.constraints.Size; +import lombok.*; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.userdetails.UserDetails; + +import java.util.Collection; +import java.util.List; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@Entity +@Table(name = "business") +public class Business implements UserDetails { + public Business(String bizNo, String compNm, String repNm, String email, char state) { + this.bizNo = bizNo; + this.compNm = compNm; + this.repNm = repNm; + this.email = email; + this.state = state; + } + + @Id + @Size(max = 20) + @Column(name = "biz_no", nullable = false, length = 20) + private String bizNo; + + @Size(max = 100) + @Column(name = "pwd", length = 100) + private String pwd; + + @Size(max = 100) + @Column(name = "comp_nm", length = 100) + private String compNm; + + @Size(max = 20) + @Column(name = "rep_nm", length = 20) + private String repNm; + + @Size(max = 50) + @Column(name = "email", length = 50) + private String email; + + @Size(max = 200) + @Column(name = "refresh_token", length = 200) + private String refreshToken; + + @Size(max = 1) + @Column(name = "state", length = 1, columnDefinition = "char(1)") + private char state; + + + @Override + public Collection getAuthorities() { + return List.of(new SimpleGrantedAuthority("ROLE_EXTERNAL")); + } + + + @Override + public String getPassword() { + return pwd; + } + + @Override + public String getUsername() { + return bizNo; + } + + + @Override + public boolean isAccountNonExpired() {return true; + } + + @Override + public boolean isAccountNonLocked() {return true; + } + + @Override + public boolean isCredentialsNonExpired() {return true; + } + + @Override + public boolean isEnabled() {return true; + } +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/model/Code.java b/src/main/java/com/kospo/svcm/model/Code.java new file mode 100644 index 0000000..aa35a19 --- /dev/null +++ b/src/main/java/com/kospo/svcm/model/Code.java @@ -0,0 +1,32 @@ +package com.kospo.svcm.model; + +import jakarta.persistence.*; +import jakarta.validation.constraints.Size; +import lombok.*; +import org.hibernate.type.YesNoConverter; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@Entity +@Table(name = "code") +public class Code { + @EmbeddedId + private CodeId id; + + @Size(max = 20) + @Column(name = "nm", length = 20) + private String nm; + + @Size(max = 200) + @Column(name = "\"desc\"", length = 200) + private String desc; + + + @Column(name = "use_yn", columnDefinition = "CHAR(1)") + @Convert(converter = YesNoConverter.class) + private Boolean useYn; + +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/model/CodeId.java b/src/main/java/com/kospo/svcm/model/CodeId.java new file mode 100644 index 0000000..06b6702 --- /dev/null +++ b/src/main/java/com/kospo/svcm/model/CodeId.java @@ -0,0 +1,43 @@ +package com.kospo.svcm.model; + +import jakarta.persistence.Column; +import jakarta.persistence.Embeddable; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; +import lombok.*; +import org.hibernate.Hibernate; + +import java.util.Objects; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@Embeddable +public class CodeId implements java.io.Serializable { + private static final long serialVersionUID = -9144701466423603292L; + @NotNull + @Column(name = "id", nullable = false) + private Integer id; + + @Size(max = 10) + @NotNull + @Column(name = "cd", nullable = false, length = 10) + private String cd; + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || Hibernate.getClass(this) != Hibernate.getClass(o)) return false; + CodeId entity = (CodeId) o; + return Objects.equals(this.cd, entity.cd) && + Objects.equals(this.id, entity.id); + } + + @Override + public int hashCode() { + return Objects.hash(cd, id); + } + +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/model/Cont.java b/src/main/java/com/kospo/svcm/model/Cont.java new file mode 100644 index 0000000..6f2a6a2 --- /dev/null +++ b/src/main/java/com/kospo/svcm/model/Cont.java @@ -0,0 +1,85 @@ +package com.kospo.svcm.model; + +import jakarta.persistence.*; +import jakarta.validation.constraints.Size; +import lombok.*; +import org.hibernate.type.YesNoConverter; + +import java.util.List; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@Entity +@Table(name = "cont") +public class Cont { + @Id + @Size(max = 20) + @Column(name = "cont_no", nullable = false, length = 20) + private String contNo; + + @Size(max = 20) + @Column(name = "prcs_no", nullable = false, length = 20) + private String prcsNo; + + @Size(max = 20) + @Column(name = "biz_no", length = 20) + private String bizNo; + + @Size(max = 200) + @Column(name = "title", length = 200) + private String title; + + @Size(max = 100) + @Column(name = "comp_nm", length = 100) + private String compNm; + + @Size(max = 25) + @Column(name = "sign_dt", length = 25) + private String signDt; + + @Column(name = "cont_amt") + private Integer contAmt; + + @Size(max = 10) + @Column(name = "cont_sdat", length = 10) + private String contSdat; + + @Size(max = 10) + @Column(name = "cont_edat", length = 10) + private String contEdat; + + @Size(max = 4) + @Column(name = "cont_stat_cd", length = 4) + private String contStatCd; + + @Size(max = 50) + @Column(name = "cont_stat", length = 50) + private String contStat; + + @Size(max = 10) + @Column(name = "reg_sabun", length = 10) + private String regSabun; + + @Size(max = 20) + @Column(name = "reg_nm", length = 20) + private String regNm; + + @Size(max = 25) + @Column(name = "reg_dt", length = 25) + private String regDt; + + @Column(name = "exc_yn",columnDefinition = "CHAR(1)") + @Convert(converter = YesNoConverter.class) + private Boolean excYn; + + @Size(max = 200) + @Column(name = "reason", length = 200) + private String reason; + + @OneToMany(fetch = FetchType.LAZY) + @JoinColumn(name = "cont_no", nullable = false, updatable = false, insertable = false) + List contAtts; +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/model/ContAppr.java b/src/main/java/com/kospo/svcm/model/ContAppr.java new file mode 100644 index 0000000..ef21e77 --- /dev/null +++ b/src/main/java/com/kospo/svcm/model/ContAppr.java @@ -0,0 +1,24 @@ +package com.kospo.svcm.model; + +import jakarta.persistence.*; +import lombok.*; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@Entity +@Table(name = "cont_appr") +public class ContAppr { + @EmbeddedId + private ContApprId id; + + @ManyToOne(fetch = FetchType.LAZY, optional = false) + @JoinColumn(name = "cont_no", nullable = false, updatable = false, insertable = false) + private Cont cont; + + @OneToOne(fetch = FetchType.LAZY, optional = false) + @JoinColumn(name= "transaction_key", nullable = false, updatable = false, insertable = false) + private SignDoc signDoc; +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/model/ContApprId.java b/src/main/java/com/kospo/svcm/model/ContApprId.java new file mode 100644 index 0000000..c3d1f92 --- /dev/null +++ b/src/main/java/com/kospo/svcm/model/ContApprId.java @@ -0,0 +1,45 @@ +package com.kospo.svcm.model; + +import jakarta.persistence.Column; +import jakarta.persistence.Embeddable; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; +import lombok.*; +import org.hibernate.Hibernate; + +import java.io.Serializable; +import java.util.Objects; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@Embeddable +public class ContApprId implements Serializable { + private static final long serialVersionUID = -3923744271503664921L; + @Size(max = 20) + @NotNull + @Column(name = "cont_no", nullable = false, length = 20) + private String contNo; + + @Size(max = 100) + @NotNull + @Column(name = "transaction_key", nullable = false, length = 100) + private String transactionKey; + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || Hibernate.getClass(this) != Hibernate.getClass(o)) return false; + ContApprId entity = (ContApprId) o; + return Objects.equals(this.transactionKey, entity.transactionKey) && + Objects.equals(this.contNo, entity.contNo); + } + + @Override + public int hashCode() { + return Objects.hash(transactionKey, contNo); + } + +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/model/ContAtt.java b/src/main/java/com/kospo/svcm/model/ContAtt.java new file mode 100644 index 0000000..5465e4a --- /dev/null +++ b/src/main/java/com/kospo/svcm/model/ContAtt.java @@ -0,0 +1,33 @@ +package com.kospo.svcm.model; + +import jakarta.persistence.*; +import jakarta.validation.constraints.Size; +import lombok.*; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@Entity +@Table(name = "cont_att") +public class ContAtt { + @EmbeddedId + private ContAttId id; + + @Size(max = 100) + @Column(name = "logi_fnm", length = 100) + private String logiFnm; + + @Size(max = 100) + @Column(name = "phys_fnm", length = 100) + private String physFnm; + + @Column(name = "size") + private Integer size; + + @Size(max = 100) + @Column(name = "path", length = 100) + private String path; + +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/model/ContAttId.java b/src/main/java/com/kospo/svcm/model/ContAttId.java new file mode 100644 index 0000000..27de53d --- /dev/null +++ b/src/main/java/com/kospo/svcm/model/ContAttId.java @@ -0,0 +1,44 @@ +package com.kospo.svcm.model; + +import jakarta.persistence.Column; +import jakarta.persistence.Embeddable; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; +import lombok.*; +import org.hibernate.Hibernate; + +import java.io.Serializable; +import java.util.Objects; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@Embeddable +public class ContAttId implements Serializable { + private static final long serialVersionUID = 5659382207559769763L; + @Size(max = 20) + @NotNull + @Column(name = "cont_no", nullable = false, length = 20) + private String contNo; + + @NotNull + @Column(name = "file_ord", nullable = false) + private Integer fileOrd; + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || Hibernate.getClass(this) != Hibernate.getClass(o)) return false; + ContAttId entity = (ContAttId) o; + return Objects.equals(this.fileOrd, entity.fileOrd) && + Objects.equals(this.contNo, entity.contNo); + } + + @Override + public int hashCode() { + return Objects.hash(fileOrd, contNo); + } + +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/model/Dept.java b/src/main/java/com/kospo/svcm/model/Dept.java new file mode 100644 index 0000000..3b84fe2 --- /dev/null +++ b/src/main/java/com/kospo/svcm/model/Dept.java @@ -0,0 +1,45 @@ +package com.kospo.svcm.model; + +import jakarta.persistence.*; +import jakarta.validation.constraints.Size; +import lombok.*; +import org.hibernate.type.YesNoConverter; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@Entity +@Table(name = "dept") +public class Dept { + @Id + @Size(max = 10) + @Column(name = "dept_cd", nullable = false, length = 10) + private String deptCd; + + @Size(max = 200) + @Column(name = "dept_nm", length = 200) + private String deptNm; + + @Column(name = "use_yn", columnDefinition = "CHAR(1)") + @Convert(converter = YesNoConverter.class) + private Boolean useYn; + + @Size(max = 50) + @Column(name = "p_dept_cd", length = 50) + private String pDeptCd; + + @Size(max = 200) + @Column(name = "formal_name", length = 200) + private String formalName; + + @Size(max = 10) + @Column(name = "chief", length = 10) + private String chief; + + @Column(name = "bonsa_yn", columnDefinition = "CHAR(1)") + @Convert(converter = YesNoConverter.class) + private Boolean bonsaYn; + +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/model/DtlSpec.java b/src/main/java/com/kospo/svcm/model/DtlSpec.java new file mode 100644 index 0000000..5794ca0 --- /dev/null +++ b/src/main/java/com/kospo/svcm/model/DtlSpec.java @@ -0,0 +1,33 @@ +package com.kospo.svcm.model; + +import jakarta.persistence.*; +import jakarta.validation.constraints.Size; +import lombok.*; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@Entity +@Table(name = "dtl_spec") +public class DtlSpec { + @EmbeddedId + private DtlSpecId id; + + @Size(max = 100) + @Column(name = "item_nm", length = 100) + private String itemNm; + + @Size(max = 100) + @Column(name = "spec", length = 100) + private String spec; + + @Size(max = 10) + @Column(name = "unit", length = 10) + private String unit; + + @Column(name = "qty") + private Integer qty; + +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/model/DtlSpecId.java b/src/main/java/com/kospo/svcm/model/DtlSpecId.java new file mode 100644 index 0000000..ae68cd3 --- /dev/null +++ b/src/main/java/com/kospo/svcm/model/DtlSpecId.java @@ -0,0 +1,46 @@ +package com.kospo.svcm.model; + +import jakarta.persistence.*; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; +import lombok.*; +import org.hibernate.Hibernate; + +import java.io.Serializable; +import java.util.Objects; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@Embeddable +public class DtlSpecId implements Serializable { + private static final long serialVersionUID = -6648132664642955087L; + + @Size(max = 20) + @NotNull + @Column(name = "prcs_no", nullable = false, length = 20) + private String prcsNo; + + @Size(max = 20) + @NotNull + @Column(name = "dtl_sp_no", nullable = false, length = 20) + private String dtlSpNo; + + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || Hibernate.getClass(this) != Hibernate.getClass(o)) return false; + DtlSpecId entity = (DtlSpecId) o; + return Objects.equals(this.prcsNo, entity.prcsNo) && + Objects.equals(this.dtlSpNo, entity.dtlSpNo); + } + + @Override + public int hashCode() { + return Objects.hash(prcsNo, dtlSpNo); + } + +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/model/EstDoc.java b/src/main/java/com/kospo/svcm/model/EstDoc.java new file mode 100644 index 0000000..8b76fc6 --- /dev/null +++ b/src/main/java/com/kospo/svcm/model/EstDoc.java @@ -0,0 +1,33 @@ +package com.kospo.svcm.model; + +import jakarta.persistence.*; +import jakarta.validation.constraints.Size; +import lombok.*; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@Entity +@Table(name = "est_doc") +public class EstDoc { + @EmbeddedId + private EstDocId id; + + @Size(max = 100) + @Column(name = "logi_fnm", length = 100) + private String logiFnm; + + @Size(max = 100) + @Column(name = "phys_fnm", length = 100) + private String physFnm; + + @Column(name = "size") + private Integer size; + + @Size(max = 100) + @Column(name = "path", length = 100) + private String path; + +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/model/EstDocId.java b/src/main/java/com/kospo/svcm/model/EstDocId.java new file mode 100644 index 0000000..a7a0446 --- /dev/null +++ b/src/main/java/com/kospo/svcm/model/EstDocId.java @@ -0,0 +1,44 @@ +package com.kospo.svcm.model; + +import jakarta.persistence.Column; +import jakarta.persistence.Embeddable; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; +import lombok.*; +import org.hibernate.Hibernate; + +import java.io.Serializable; +import java.util.Objects; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@Embeddable +public class EstDocId implements Serializable { + private static final long serialVersionUID = -1604272017395681825L; + @Size(max = 20) + @NotNull + @Column(name = "est_no", nullable = false, length = 20) + private String estNo; + + @NotNull + @Column(name = "file_ord", nullable = false) + private Integer fileOrd; + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || Hibernate.getClass(this) != Hibernate.getClass(o)) return false; + EstDocId entity = (EstDocId) o; + return Objects.equals(this.estNo, entity.estNo) && + Objects.equals(this.fileOrd, entity.fileOrd); + } + + @Override + public int hashCode() { + return Objects.hash(estNo, fileOrd); + } + +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/model/Estimate.java b/src/main/java/com/kospo/svcm/model/Estimate.java new file mode 100644 index 0000000..bb18f05 --- /dev/null +++ b/src/main/java/com/kospo/svcm/model/Estimate.java @@ -0,0 +1,68 @@ +package com.kospo.svcm.model; + +import jakarta.persistence.*; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; +import lombok.*; + +import java.util.List; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@Entity +@Table(name = "estimate") +public class Estimate { + @Id + @Size(max = 20) + @Column(name = "est_no", nullable = false, length = 20) + private String estNo; + + @Size(max = 20) + @Column(name = "biz_no", nullable = false, length = 20) + private String bizNo; + + @Size(max = 20) + @Column(name = "prcs_no", nullable = false, length = 20) + private String prcsNo; + + @Size(max = 20) + @Column(name = "dtl_sp_no", nullable = false, length = 20) + private String dtlSpNo; + + @Size(max = 20) + @Column(name = "mng_nm", length = 20) + private String mngNm; + + @Column(name = "unit_prc") + private Integer unitPrc; + + @Column(name = "amt") + private Integer amt; + + @Size(max = 25) + @Column(name = "reg_dt", length = 25) + private String regDt; + + + + @NotNull + @ManyToOne(fetch = FetchType.LAZY, optional = false) + @JoinColumn(name = "biz_no", nullable = false, updatable = false, insertable = false) + private Business business; + + @NotNull + @ManyToOne(fetch = FetchType.LAZY, optional = false) + @JoinColumns({ + @JoinColumn(name = "prcs_no", referencedColumnName = "prcs_no", nullable = false, updatable = false, insertable = false), + @JoinColumn(name = "dtl_sp_no", referencedColumnName = "dtl_sp_no", nullable = false, updatable = false, insertable = false) + }) + private DtlSpec dtlSpec; + + @OneToMany(fetch = FetchType.LAZY) + @JoinColumn(name = "est_no", nullable = false, updatable = false, insertable = false) + List estDocs; + +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/model/GrpCode.java b/src/main/java/com/kospo/svcm/model/GrpCode.java new file mode 100644 index 0000000..e2670f9 --- /dev/null +++ b/src/main/java/com/kospo/svcm/model/GrpCode.java @@ -0,0 +1,47 @@ +package com.kospo.svcm.model; + +import jakarta.persistence.*; +import jakarta.validation.constraints.Size; +import lombok.*; +import org.hibernate.type.YesNoConverter; + +import java.util.List; + +@TableGenerator( + table = "sequence", + name = "seq_grp_code", + pkColumnName = "seq_nm", + valueColumnName = "next_val", + allocationSize = 1 +) + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@Entity +@Table(name = "grp_code") +public class GrpCode { + @Id + @GeneratedValue(strategy = GenerationType.TABLE, generator = "seq_grp_code") + @Column(name = "id", nullable = false) + private Integer id; + + @Size(max = 20) + @Column(name = "nm", length = 20) + private String nm; + + @Size(max = 200) + @Column(name = "\"desc\"", length = 200) + private String desc; + + @Column(name = "use_yn", columnDefinition = "CHAR(1)") + @Convert(converter = YesNoConverter.class) + private Boolean useYn; + + @OneToMany(fetch = FetchType.LAZY) + @JoinColumn(name = "id") + List codes; + +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/model/LoginHis.java b/src/main/java/com/kospo/svcm/model/LoginHis.java new file mode 100644 index 0000000..234333b --- /dev/null +++ b/src/main/java/com/kospo/svcm/model/LoginHis.java @@ -0,0 +1,26 @@ +package com.kospo.svcm.model; + +import jakarta.persistence.*; +import jakarta.validation.constraints.Size; +import lombok.*; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@Entity +@Table(name = "login_his") +public class LoginHis { + @EmbeddedId + private LoginHisId id; + + @Size(max = 20) + @Column(name = "ip", length = 20) + private String ip; + + @Size(max = 25) + @Column(name = "conn_dt", length = 25) + private String connDt; + +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/model/LoginHisId.java b/src/main/java/com/kospo/svcm/model/LoginHisId.java new file mode 100644 index 0000000..394beeb --- /dev/null +++ b/src/main/java/com/kospo/svcm/model/LoginHisId.java @@ -0,0 +1,44 @@ +package com.kospo.svcm.model; + +import jakarta.persistence.Column; +import jakarta.persistence.Embeddable; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; +import lombok.*; +import org.hibernate.Hibernate; + +import java.io.Serializable; +import java.util.Objects; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@Embeddable +public class LoginHisId implements Serializable { + private static final long serialVersionUID = 7123000235046627019L; + @Size(max = 20) + @NotNull + @Column(name = "biz_no", nullable = false, length = 20) + private String bizNo; + + @NotNull + @Column(name = "his_no", nullable = false) + private String hisNo; + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || Hibernate.getClass(this) != Hibernate.getClass(o)) return false; + LoginHisId entity = (LoginHisId) o; + return Objects.equals(this.bizNo, entity.bizNo) && + Objects.equals(this.hisNo, entity.hisNo); + } + + @Override + public int hashCode() { + return Objects.hash(bizNo, hisNo); + } + +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/model/PbAtt.java b/src/main/java/com/kospo/svcm/model/PbAtt.java new file mode 100644 index 0000000..359b0c5 --- /dev/null +++ b/src/main/java/com/kospo/svcm/model/PbAtt.java @@ -0,0 +1,33 @@ +package com.kospo.svcm.model; + +import jakarta.persistence.*; +import jakarta.validation.constraints.Size; +import lombok.*; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@Entity +@Table(name = "pb_att") +public class PbAtt { + @EmbeddedId + private PbAttId id; + + @Size(max = 100) + @Column(name = "logi_fnm", length = 100) + private String logiFnm; + + @Size(max = 100) + @Column(name = "phys_fnm", length = 100) + private String physFnm; + + @Column(name = "size") + private Integer size; + + @Size(max = 100) + @Column(name = "path", length = 100) + private String path; + +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/model/PbAttId.java b/src/main/java/com/kospo/svcm/model/PbAttId.java new file mode 100644 index 0000000..1fc75f4 --- /dev/null +++ b/src/main/java/com/kospo/svcm/model/PbAttId.java @@ -0,0 +1,50 @@ +package com.kospo.svcm.model; + +import jakarta.persistence.Column; +import jakarta.persistence.Embeddable; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; +import lombok.*; +import org.hibernate.Hibernate; + +import java.io.Serializable; +import java.util.Objects; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@Embeddable +public class PbAttId implements Serializable { + private static final long serialVersionUID = -7825335917532524197L; + @Size(max = 20) + @NotNull + @Column(name = "prcs_no", nullable = false, length = 20) + private String prcsNo; + + @Size(max = 20) + @NotNull + @Column(name = "biz_no", nullable = false, length = 20) + private String bizNo; + + @NotNull + @Column(name = "file_ord", nullable = false) + private Integer fileOrd; + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || Hibernate.getClass(this) != Hibernate.getClass(o)) return false; + PbAttId entity = (PbAttId) o; + return Objects.equals(this.prcsNo, entity.prcsNo) && + Objects.equals(this.bizNo, entity.bizNo) && + Objects.equals(this.fileOrd, entity.fileOrd); + } + + @Override + public int hashCode() { + return Objects.hash(prcsNo, bizNo, fileOrd); + } + +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/model/Prcs.java b/src/main/java/com/kospo/svcm/model/Prcs.java new file mode 100644 index 0000000..8596d03 --- /dev/null +++ b/src/main/java/com/kospo/svcm/model/Prcs.java @@ -0,0 +1,131 @@ +package com.kospo.svcm.model; + +import jakarta.persistence.*; +import jakarta.validation.constraints.Size; +import lombok.*; +import org.hibernate.type.YesNoConverter; + +import java.util.List; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@Entity +@Table(name = "prcs") +public class Prcs { + + public Prcs(String prcsNo, String cateCd, String cateNm, String title, String content, String regSdat, String regEdat, Boolean prvYn, String prvRsn, String prvPwd, Boolean aiYn, String regSabun, String regNm, String regDt, String stCd, String stNm, Boolean svyYn, String svyDt) { + this.prcsNo = prcsNo; + this.cateCd = cateCd; + this.cateNm = cateNm; + this.title = title; + this.content = content; + this.regSdat = regSdat; + this.regEdat = regEdat; + this.prvYn = prvYn; + this.prvRsn = prvRsn; + this.prvPwd = prvPwd; + this.aiYn = aiYn; + this.regSabun = regSabun; + this.regNm = regNm; + this.regDt = regDt; + this.stCd = stCd; + this.stNm = stNm; + this.svyYn = svyYn; + this.svyDt = svyDt; + } + + @Id + @Size(max = 20) + @Column(name = "prcs_no", nullable = false, length = 20) + private String prcsNo; + + @Size(max = 4) + @Column(name = "cate_cd", length = 4) + private String cateCd; + + @Size(max = 50) + @Column(name = "cate_nm", length = 50) + private String cateNm; + + @Size(max = 200) + @Column(name = "title", length = 200) + private String title; + + @Size(max = 400) + @Column(name = "content", length = 400) + private String content; + + @Size(max = 10) + @Column(name = "reg_sdat", length = 10) + private String regSdat; + + @Size(max = 10) + @Column(name = "reg_edat", length = 10) + private String regEdat; + + @Column(name = "prv_yn", columnDefinition = "CHAR(1)") + @Convert(converter = YesNoConverter.class) + private Boolean prvYn; + + @Size(max = 400) + @Column(name = "prv_rsn", length = 400) + private String prvRsn; + + @Size(max = 100) + @Column(name = "prv_pwd", length = 100) + private String prvPwd; + + @Column(name = "ai_yn",columnDefinition = "CHAR(1)") + @Convert(converter = YesNoConverter.class) + private Boolean aiYn; + + @Size(max = 10) + @Column(name = "reg_sabun", length = 10) + private String regSabun; + + @Size(max = 20) + @Column(name = "reg_nm", length = 20) + private String regNm; + + @Size(max = 25) + @Column(name = "reg_dt", length = 25) + private String regDt; + + @Size(max = 4) + @Column(name = "st_cd", length = 4) + private String stCd; + + @Size(max = 50) + @Column(name = "st_nm", length = 50) + private String stNm; + + @Column(name = "svy_yn",columnDefinition = "CHAR(1)") + @Convert(converter = YesNoConverter.class) + private Boolean svyYn; + + @Size(max = 25) + @Column(name = "svy_dt", length = 25) + private String svyDt; + + @OneToOne(mappedBy = "prcs") + @JoinColumn(name = "prcs_no", updatable = false, insertable = false) + ApprMst apprMst; + + @OrderBy("id.fileOrd asc") + @OneToMany(fetch = FetchType.LAZY) + @JoinColumn(name = "prcs_no", updatable = false, insertable = false) + List prcsAtts; + + @OrderBy("id asc") + @OneToMany(fetch = FetchType.LAZY) + @JoinColumn(name = "prcs_no", updatable = false, insertable = false) + List dtlSpecs; + + @OneToMany(fetch = FetchType.LAZY) + @JoinColumn(name = "prcs_no", updatable = false, insertable = false) + List prcsBizs; + +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/model/PrcsAtt.java b/src/main/java/com/kospo/svcm/model/PrcsAtt.java new file mode 100644 index 0000000..e9653a3 --- /dev/null +++ b/src/main/java/com/kospo/svcm/model/PrcsAtt.java @@ -0,0 +1,33 @@ +package com.kospo.svcm.model; + +import jakarta.persistence.*; +import jakarta.validation.constraints.Size; +import lombok.*; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@Entity +@Table(name = "prcs_att") +public class PrcsAtt { + @EmbeddedId + private PrcsAttId id; + + @Size(max = 100) + @Column(name = "logi_fnm", length = 100) + private String logiFnm; + + @Size(max = 100) + @Column(name = "phys_fnm", length = 100) + private String physFnm; + + @Column(name = "size") + private Integer size; + + @Size(max = 100) + @Column(name = "path", length = 100) + private String path; + +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/model/PrcsAttId.java b/src/main/java/com/kospo/svcm/model/PrcsAttId.java new file mode 100644 index 0000000..adb7dff --- /dev/null +++ b/src/main/java/com/kospo/svcm/model/PrcsAttId.java @@ -0,0 +1,44 @@ +package com.kospo.svcm.model; + +import jakarta.persistence.Column; +import jakarta.persistence.Embeddable; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; +import lombok.*; +import org.hibernate.Hibernate; + +import java.io.Serializable; +import java.util.Objects; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@Embeddable +public class PrcsAttId implements Serializable { + private static final long serialVersionUID = 3695695507763137214L; + @Size(max = 20) + @NotNull + @Column(name = "prcs_no", nullable = false, length = 20) + private String prcsNo; + + @NotNull + @Column(name = "file_ord", nullable = false) + private Integer fileOrd; + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || Hibernate.getClass(this) != Hibernate.getClass(o)) return false; + PrcsAttId entity = (PrcsAttId) o; + return Objects.equals(this.prcsNo, entity.prcsNo) && + Objects.equals(this.fileOrd, entity.fileOrd); + } + + @Override + public int hashCode() { + return Objects.hash(prcsNo, fileOrd); + } + +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/model/PrcsBiz.java b/src/main/java/com/kospo/svcm/model/PrcsBiz.java new file mode 100644 index 0000000..40f8f31 --- /dev/null +++ b/src/main/java/com/kospo/svcm/model/PrcsBiz.java @@ -0,0 +1,43 @@ +package com.kospo.svcm.model; + +import jakarta.persistence.*; +import jakarta.validation.constraints.Size; +import lombok.*; +import org.hibernate.type.YesNoConverter; + +import java.util.List; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@Entity +@Table(name = "prcs_biz") +public class PrcsBiz { + @EmbeddedId + private PrcsBizId id; + + @Size(max = 40) + @Column(name = "email", length = 40) + private String email; + + @Column(name = "send_yn", columnDefinition = "CHAR(1)") + @Convert(converter = YesNoConverter.class) + private Boolean sendYn; + + @Size(max = 4) + @Column(name = "est_stat_cd", length = 4) + private String estStatCd; + + @Size(max = 50) + @Column(name = "est_stat", length = 50) + private String estStat; + + @OneToMany(fetch = FetchType.LAZY) + @JoinColumns({ + @JoinColumn(name = "prcs_no", referencedColumnName = "prcs_no", nullable = false, updatable = false, insertable = false), + @JoinColumn(name = "biz_no", referencedColumnName = "biz_no", nullable = false, updatable = false, insertable = false) + }) + List pbAtts; +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/model/PrcsBizId.java b/src/main/java/com/kospo/svcm/model/PrcsBizId.java new file mode 100644 index 0000000..6544353 --- /dev/null +++ b/src/main/java/com/kospo/svcm/model/PrcsBizId.java @@ -0,0 +1,45 @@ +package com.kospo.svcm.model; + +import jakarta.persistence.Column; +import jakarta.persistence.Embeddable; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; +import lombok.*; +import org.hibernate.Hibernate; + +import java.io.Serializable; +import java.util.Objects; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@Embeddable +public class PrcsBizId implements Serializable { + private static final long serialVersionUID = -6851503990577267284L; + @Size(max = 20) + @NotNull + @Column(name = "biz_no", nullable = false, length = 20) + private String bizNo; + + @Size(max = 20) + @NotNull + @Column(name = "prcs_no", nullable = false, length = 20) + private String prcsNo; + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || Hibernate.getClass(this) != Hibernate.getClass(o)) return false; + PrcsBizId entity = (PrcsBizId) o; + return Objects.equals(this.prcsNo, entity.prcsNo) && + Objects.equals(this.bizNo, entity.bizNo); + } + + @Override + public int hashCode() { + return Objects.hash(prcsNo, bizNo); + } + +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/model/PvyPeriod.java b/src/main/java/com/kospo/svcm/model/PvyPeriod.java new file mode 100644 index 0000000..77d5b5d --- /dev/null +++ b/src/main/java/com/kospo/svcm/model/PvyPeriod.java @@ -0,0 +1,25 @@ +package com.kospo.svcm.model; + +import jakarta.persistence.Column; +import jakarta.persistence.EmbeddedId; +import jakarta.persistence.Entity; +import jakarta.persistence.Table; +import jakarta.validation.constraints.Size; +import lombok.*; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@Entity +@Table(name = "pvy_period") +public class PvyPeriod { + @EmbeddedId + private PvyPeriodId id; + + @Size(max = 25) + @Column(name = "expire_dt", length = 25) + private String expireDt; + +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/model/PvyPeriodId.java b/src/main/java/com/kospo/svcm/model/PvyPeriodId.java new file mode 100644 index 0000000..f5a36c2 --- /dev/null +++ b/src/main/java/com/kospo/svcm/model/PvyPeriodId.java @@ -0,0 +1,46 @@ +package com.kospo.svcm.model; + +import jakarta.persistence.Column; +import jakarta.persistence.Embeddable; +import jakarta.persistence.Entity; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; +import lombok.*; +import org.hibernate.Hibernate; + +import java.io.Serializable; +import java.util.Objects; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@Embeddable +public class PvyPeriodId implements Serializable { + private static final long serialVersionUID = 7203390344224116013L; + @Size(max = 20) + @NotNull + @Column(name = "biz_no", nullable = false, length = 20) + private String bizNo; + + @Size(max = 25) + @NotNull + @Column(name = "agr_dt", nullable = false, length = 25) + private String agrDt; + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || Hibernate.getClass(this) != Hibernate.getClass(o)) return false; + PvyPeriodId entity = (PvyPeriodId) o; + return Objects.equals(this.bizNo, entity.bizNo) && + Objects.equals(this.agrDt, entity.agrDt); + } + + @Override + public int hashCode() { + return Objects.hash(bizNo, agrDt); + } + +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/model/Role.java b/src/main/java/com/kospo/svcm/model/Role.java new file mode 100644 index 0000000..62d8052 --- /dev/null +++ b/src/main/java/com/kospo/svcm/model/Role.java @@ -0,0 +1,38 @@ +package com.kospo.svcm.model; + +import jakarta.persistence.*; +import jakarta.validation.constraints.Size; +import lombok.*; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@Entity +@Table(name = "role") +public class Role { + @EmbeddedId + private RoleId id; + + @Size(max = 20) + @Column(name = "role_nm", length = 20) + private String roleNm; + + @Size(max = 12) + @Column(name = "ip", length = 12) + private String ip; + + @Size(max = 10) + @Column(name = "reg_sabun", length = 10) + private String regSabun; + + @Size(max = 20) + @Column(name = "reg_nm", length = 20) + private String regNm; + + @Size(max = 25) + @Column(name = "reg_dt", length = 25) + private String regDt; + +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/model/RoleId.java b/src/main/java/com/kospo/svcm/model/RoleId.java new file mode 100644 index 0000000..f264fd8 --- /dev/null +++ b/src/main/java/com/kospo/svcm/model/RoleId.java @@ -0,0 +1,44 @@ +package com.kospo.svcm.model; + +import jakarta.persistence.Column; +import jakarta.persistence.Embeddable; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; +import lombok.*; +import org.hibernate.Hibernate; + +import java.util.Objects; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@Embeddable +public class RoleId implements java.io.Serializable { + private static final long serialVersionUID = -8824456448256682460L; + @Size(max = 4) + @NotNull + @Column(name = "role_id", nullable = false, length = 4) + private String roleId; + + @Size(max = 10) + @NotNull + @Column(name = "sabun", nullable = false, length = 10) + private String sabun; + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || Hibernate.getClass(this) != Hibernate.getClass(o)) return false; + RoleId entity = (RoleId) o; + return Objects.equals(this.roleId, entity.roleId) && + Objects.equals(this.sabun, entity.sabun); + } + + @Override + public int hashCode() { + return Objects.hash(roleId, sabun); + } + +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/model/Sequence.java b/src/main/java/com/kospo/svcm/model/Sequence.java new file mode 100644 index 0000000..68e8242 --- /dev/null +++ b/src/main/java/com/kospo/svcm/model/Sequence.java @@ -0,0 +1,24 @@ +package com.kospo.svcm.model; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.Table; +import lombok.*; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@Entity +@Table(name = "sequence") +public class Sequence { + @Id + @Column(name = "seq_nm", nullable = false, length = Integer.MAX_VALUE) + private String seqNm; + + @Column(name = "next_val") + private Long nextVal; + +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/model/SignDoc.java b/src/main/java/com/kospo/svcm/model/SignDoc.java new file mode 100644 index 0000000..fa7a618 --- /dev/null +++ b/src/main/java/com/kospo/svcm/model/SignDoc.java @@ -0,0 +1,115 @@ +package com.kospo.svcm.model; + +import jakarta.persistence.*; +import jakarta.validation.constraints.Size; +import lombok.*; +import org.hibernate.type.YesNoConverter; + +import java.util.List; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@Entity +@Table(name = "sign_doc") +public class SignDoc { + @Id + @Size(max = 100) + @Column(name = "transaction_key", nullable = false, length = 100) + private String transactionKey; + + @Size(max = 3) + @Column(name = "system_gubun", length = 3) + private String systemGubun; + + @Size(max = 25) + @Column(name = "write_date", length = 25) + private String writeDate; + + @Size(max = 400) + @Column(name = "title", length = 400) + private String title; + + @Size(max = 25) + @Column(name = "regi_date", length = 25) + private String regiDate; + + @Size(max = 50) + @Column(name = "perm_grade", length = 50) + private String permGrade; + + @Size(max = 50) + @Column(name = "dept_code", length = 50) + private String deptCode; + + @Size(max = 100) + @Column(name = "dept_name", length = 100) + private String deptName; + + @Size(max = 50) + @Column(name = "office_code", length = 50) + private String officeCode; + + @Size(max = 100) + @Column(name = "office_name", length = 100) + private String officeName; + + @Size(max = 3) + @Column(name = "ldm_type", length = 3) + private String ldmType; + + @Size(max = 50) + @Column(name = "standard_doc_no", length = 50) + private String standardDocNo; + + @Size(max = 100) + @Column(name = "doc_file_name", length = 100) + private String docFileName; + + @Size(max = 100) + @Column(name = "doc_file_seq", length = 100) + private String docFileSeq; + + @Size(max = 50) + @Column(name = "process_status", length = 50) + private String processStatus; + + @Size(max = 4) + @Column(name = "process_status_code", length = 4) + private String processStatusCode; + + @Size(max = 10) + @Column(name = "writer_id", length = 10) + private String writerId; + + @Size(max = 50) + @Column(name = "writer_name", length = 50) + private String writerName; + + @Size(max = 25) + @Column(name = "send_date", length = 25) + private String sendDate; + + @Size(max = 200) + @Column(name = "doc_url", length = 200) + private String docUrl; + + @Column(name = "recv_yn", columnDefinition = "CHAR(1)") + @Convert(converter = YesNoConverter.class) + private Boolean recvYn; + + @Size(max = 25) + @Column(name = "recv_date", length = 25) + private String recvDate; + + @Size(max = 400) + @Column(name = "recv_error_msg", length = 400) + private String recvErrorMsg; + + @OneToMany(fetch = FetchType.LAZY) + @JoinColumn(name = "transaction_key") + List signLines; + +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/model/SignLine.java b/src/main/java/com/kospo/svcm/model/SignLine.java new file mode 100644 index 0000000..55d1d28 --- /dev/null +++ b/src/main/java/com/kospo/svcm/model/SignLine.java @@ -0,0 +1,78 @@ +package com.kospo.svcm.model; + +import jakarta.persistence.*; +import jakarta.validation.constraints.Size; +import lombok.*; +import org.hibernate.type.YesNoConverter; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@Entity +@Table(name = "sign_line") +public class SignLine { + @EmbeddedId + private SignLineId id; + + @Size(max = 3) + @Column(name = "system_gubun", length = 3) + private String systemGubun; + + @Size(max = 10) + @Column(name = "signer_id", length = 10) + private String signerId; + + @Size(max = 50) + @Column(name = "signer_gubun", length = 50) + private String signerGubun; + + @Column(name = "sign_level") + private Integer signLevel; + + @Size(max = 50) + @Column(name = "signer_name", length = 50) + private String signerName; + + @Size(max = 50) + @Column(name = "signer_pos_name", length = 50) + private String signerPosName; + + @Size(max = 25) + @Column(name = "sign_date", length = 25) + private String signDate; + + @Size(max = 50) + @Column(name = "signer_status", length = 50) + private String signerStatus; + + @Size(max = 50) + @Column(name = "sign_result", length = 50) + private String signResult; + + @Size(max = 1000) + @Column(name = "opinion", length = 1000) + private String opinion; + + @Size(max = 10) + @Column(name = "replace_id", length = 10) + private String replaceId; + + @Size(max = 50) + @Column(name = "replace_name", length = 50) + private String replaceName; + + @Column(name = "recv_yn", columnDefinition = "CHAR(1)") + @Convert(converter = YesNoConverter.class) + private Boolean recvYn; + + @Size(max = 25) + @Column(name = "recv_date", length = 25) + private String recvDate; + + @Size(max = 400) + @Column(name = "recv_error_msg", length = 400) + private String recvErrorMsg; + +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/model/SignLineId.java b/src/main/java/com/kospo/svcm/model/SignLineId.java new file mode 100644 index 0000000..00db23f --- /dev/null +++ b/src/main/java/com/kospo/svcm/model/SignLineId.java @@ -0,0 +1,44 @@ +package com.kospo.svcm.model; + +import jakarta.persistence.Column; +import jakarta.persistence.Embeddable; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; +import lombok.*; +import org.hibernate.Hibernate; + +import java.io.Serializable; +import java.util.Objects; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@Embeddable +public class SignLineId implements Serializable { + private static final long serialVersionUID = -5681284153092933449L; + @Size(max = 100) + @NotNull + @Column(name = "transaction_key", nullable = false, length = 100) + private String transactionKey; + + @NotNull + @Column(name = "sign_order", nullable = false) + private Integer signOrder; + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || Hibernate.getClass(this) != Hibernate.getClass(o)) return false; + SignLineId entity = (SignLineId) o; + return Objects.equals(this.transactionKey, entity.transactionKey) && + Objects.equals(this.signOrder, entity.signOrder); + } + + @Override + public int hashCode() { + return Objects.hash(transactionKey, signOrder); + } + +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/model/Slip.java b/src/main/java/com/kospo/svcm/model/Slip.java new file mode 100644 index 0000000..5522323 --- /dev/null +++ b/src/main/java/com/kospo/svcm/model/Slip.java @@ -0,0 +1,111 @@ +package com.kospo.svcm.model; + +import jakarta.persistence.*; +import jakarta.validation.constraints.Size; +import lombok.*; + +import java.util.List; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@Entity +@Table(name = "slip") +public class Slip { + @Id + @Size(max = 20) + @Column(name = "cont_no", nullable = false, length = 20) + private String contNo; + + @Size(max = 20) + @Column(name = "lifnr", length = 20) + private String lifnr; + + @Size(max = 4) + @Column(name = "gsber", length = 4) + private String gsber; + + @Size(max = 31) + @Column(name = "wrbtr_s", length = 31) + private String wrbtrS; + + @Size(max = 2) + @Column(name = "mwskz", length = 2) + private String mwskz; + + @Size(max = 5) + @Column(name = "waers", length = 5) + private String waers; + + @Size(max = 8) + @Column(name = "bldat", length = 8) + private String bldat; + + @Size(max = 8) + @Column(name = "budat", length = 8) + private String budat; + + @Size(max = 10) + @Column(name = "hkont", length = 10) + private String hkont; + + @Size(max = 10) + @Column(name = "kostl", length = 10) + private String kostl; + + @Size(max = 24) + @Column(name = "projk", length = 24) + private String projk; + + @Size(max = 31) + @Column(name = "wrbtr", length = 31) + private String wrbtr; + + @Size(max = 4) + @Column(name = "bvtyp", length = 4) + private String bvtyp; + + @Size(max = 1) + @Column(name = "bstat", length = 1) + private String bstat; + + @Size(max = 12) + @Column(name = "usnam", length = 12) + private String usnam; + + @Size(max = 4) + @Column(name = "gjahr", length = 4) + private String gjahr; + + @Size(max = 10) + @Column(name = "belnr", length = 10) + private String belnr; + + @Size(max = 4) + @Column(name = "bukrs", length = 4) + private String bukrs; + + @Size(max = 1) + @Column(name = "type", length = 1) + private String type; + + @Size(max = 1000) + @Column(name = "message", length = 1000) + private String message; + + @Size(max = 20) + @Column(name = "reg_sabun", length = 20) + private String regSabun; + + @Size(max = 25) + @Column(name = "reg_dt", length = 25) + private String regDt; + + + @OneToMany(fetch = FetchType.EAGER) + @JoinColumn(name = "cont_no", insertable = false, updatable = false) + private List slipAtts; + +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/model/SlipAtt.java b/src/main/java/com/kospo/svcm/model/SlipAtt.java new file mode 100644 index 0000000..21717ae --- /dev/null +++ b/src/main/java/com/kospo/svcm/model/SlipAtt.java @@ -0,0 +1,41 @@ +package com.kospo.svcm.model; + +import jakarta.persistence.*; +import jakarta.validation.constraints.Size; +import lombok.*; +import org.hibernate.annotations.OnDelete; +import org.hibernate.annotations.OnDeleteAction; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@Entity +@Table(name = "slip_att") +public class SlipAtt { + @EmbeddedId + private SlipAttId id; + + @MapsId("contNo") + @ManyToOne(fetch = FetchType.LAZY, optional = false) + @OnDelete(action = OnDeleteAction.CASCADE) + @JoinColumn(name = "cont_no", nullable = false) + private Cont contNo; + + @Size(max = 100) + @Column(name = "logi_fnm", length = 100) + private String logiFnm; + + @Size(max = 100) + @Column(name = "phys_fnm", length = 100) + private String physFnm; + + @Column(name = "size") + private Integer size; + + @Size(max = 100) + @Column(name = "path", length = 100) + private String path; + +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/model/SlipAttId.java b/src/main/java/com/kospo/svcm/model/SlipAttId.java new file mode 100644 index 0000000..70687f9 --- /dev/null +++ b/src/main/java/com/kospo/svcm/model/SlipAttId.java @@ -0,0 +1,45 @@ +package com.kospo.svcm.model; + +import jakarta.persistence.Column; +import jakarta.persistence.Embeddable; +import jakarta.persistence.Entity; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; +import lombok.*; +import org.hibernate.Hibernate; + +import java.io.Serializable; +import java.util.Objects; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@Embeddable +public class SlipAttId implements Serializable { + private static final long serialVersionUID = 690944658042895309L; + @Size(max = 20) + @NotNull + @Column(name = "cont_no", nullable = false, length = 20) + private String contNo; + + @NotNull + @Column(name = "file_ord", nullable = false) + private Integer fileOrd; + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || Hibernate.getClass(this) != Hibernate.getClass(o)) return false; + SlipAttId entity = (SlipAttId) o; + return Objects.equals(this.contNo, entity.contNo) && + Objects.equals(this.fileOrd, entity.fileOrd); + } + + @Override + public int hashCode() { + return Objects.hash(contNo, fileOrd); + } + +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/model/User.java b/src/main/java/com/kospo/svcm/model/User.java new file mode 100644 index 0000000..c1b4837 --- /dev/null +++ b/src/main/java/com/kospo/svcm/model/User.java @@ -0,0 +1,113 @@ +package com.kospo.svcm.model; + +import jakarta.persistence.*; +import jakarta.validation.constraints.Size; +import lombok.*; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.userdetails.UserDetails; + +import java.util.Collection; +import java.util.List; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@Entity +@Table(name = "users") +public class User implements UserDetails { + @Id + @Size(max = 10) + @Column(name = "sabun", nullable = false, length = 10) + private String sabun; + + @Size(max = 200) + @Column(name = "name", length = 200) + private String name; + + @Size(max = 20) + @Column(name = "dept_cd", length = 20) + private String deptCd; + + @Size(max = 20) + @Column(name = "grade_cd", length = 20) + private String gradeCd; + + @Size(max = 200) + @Column(name = "grade_nm", length = 200) + private String gradeNm; + + @Size(max = 100) + @Column(name = "ptsn_nm", length = 100) + private String ptsnNm; + + @Size(max = 20) + @Column(name = "ofce_phn", length = 20) + private String ofcePhn; + + + @Size(max = 20) + @Column(name = "mbl_phn", length = 20) + private String mblPhn; + + @Size(max = 10) + @Column(name = "state", length = 10) + private String state; + + @Size(max = 10) + @Column(name = "attend_cd", length = 4) + private String attendCd; + + @Size(max = 10) + @Column(name = "attend_nm", length = 10) + private String attendNm; + + @Size(max = 10) + @Column(name = "attend_sta_ymd", length = 10) + private String attendStaYmd; + + @Size(max = 10) + @Column(name = "attend_end_ymd", length = 10) + private String attendEndYmd; + + @OneToMany(fetch = FetchType.EAGER) + @JoinColumn(name = "sabun") + List roles; + + @OneToOne(fetch = FetchType.EAGER) + @JoinColumn(name = "dept_cd", updatable = false, insertable = false) + Dept dept; + + @Override + public Collection getAuthorities() { + return roles.stream().map(r -> new SimpleGrantedAuthority(r.getId().getRoleId())).toList(); + } + + @Override + public String getPassword() { + return ""; + } + + @Override + public String getUsername() { + return sabun; + } + + @Override + public boolean isAccountNonExpired() {return true; + } + + @Override + public boolean isAccountNonLocked() {return true; + } + + @Override + public boolean isCredentialsNonExpired() {return true; + } + + @Override + public boolean isEnabled() {return true; + } +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/model/Zwf0011t.java b/src/main/java/com/kospo/svcm/model/Zwf0011t.java new file mode 100644 index 0000000..87f3c6e --- /dev/null +++ b/src/main/java/com/kospo/svcm/model/Zwf0011t.java @@ -0,0 +1,61 @@ +package com.kospo.svcm.model; + +import jakarta.persistence.Column; +import jakarta.persistence.EmbeddedId; +import jakarta.persistence.Entity; +import jakarta.persistence.Table; +import jakarta.validation.constraints.Size; +import lombok.*; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@Entity +@Table(name = "zwf0011t") +public class Zwf0011t { + @EmbeddedId + private Zwf0011tId id; + + @Size(max = 150) + @Column(name = "obkey", length = 150) + private String obkey; + + @Size(max = 1) + @Column(name = "wkfst", length = 1) + private String wkfst; + + @Size(max = 300) + @Column(name = "wkftx", length = 300) + private String wkftx; + + @Size(max = 12) + @Column(name = "ernam", length = 12) + private String ernam; + + @Size(max = 8) + @Column(name = "erdat", length = 8) + private String erdat; + + @Size(max = 6) + @Column(name = "erzet", length = 6) + private String erzet; + + @Size(max = 12) + @Column(name = "aenam", length = 12) + private String aenam; + + @Size(max = 8) + @Column(name = "aedat", length = 8) + private String aedat; + + @Size(max = 6) + @Column(name = "aezet", length = 6) + private String aezet; + + @Size(max = 1000) + @Column(name = "reason", length = 1000) + private String reason; + +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/model/Zwf0011tId.java b/src/main/java/com/kospo/svcm/model/Zwf0011tId.java new file mode 100644 index 0000000..88f395c --- /dev/null +++ b/src/main/java/com/kospo/svcm/model/Zwf0011tId.java @@ -0,0 +1,46 @@ +package com.kospo.svcm.model; + +import jakarta.persistence.Column; +import jakarta.persistence.Embeddable; +import jakarta.persistence.Entity; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; +import lombok.*; +import org.hibernate.Hibernate; + +import java.io.Serializable; +import java.util.Objects; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@Embeddable +public class Zwf0011tId implements Serializable { + private static final long serialVersionUID = -3482805602888337937L; + @Size(max = 12) + @NotNull + @Column(name = "wkfid", nullable = false, length = 12) + private String wkfid; + + @Size(max = 3) + @NotNull + @Column(name = "catag", nullable = false, length = 3) + private String catag; + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || Hibernate.getClass(this) != Hibernate.getClass(o)) return false; + Zwf0011tId entity = (Zwf0011tId) o; + return Objects.equals(this.wkfid, entity.wkfid) && + Objects.equals(this.catag, entity.catag); + } + + @Override + public int hashCode() { + return Objects.hash(wkfid, catag); + } + +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/model/Zwf0012t.java b/src/main/java/com/kospo/svcm/model/Zwf0012t.java new file mode 100644 index 0000000..2243eb3 --- /dev/null +++ b/src/main/java/com/kospo/svcm/model/Zwf0012t.java @@ -0,0 +1,73 @@ +package com.kospo.svcm.model; + +import jakarta.persistence.Column; +import jakarta.persistence.EmbeddedId; +import jakarta.persistence.Entity; +import jakarta.persistence.Table; +import jakarta.validation.constraints.Size; +import lombok.*; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@Entity +@Table(name = "zwf0012t") +public class Zwf0012t { + @EmbeddedId + private Zwf0012tId id; + + @Size(max = 1) + @Column(name = "lineclsf", length = 1) + private String lineclsf; + + @Size(max = 12) + @Column(name = "bname", length = 12) + private String bname; + + @Size(max = 40) + @Column(name = "btext", length = 40) + private String btext; + + @Size(max = 120) + @Column(name = "posit", length = 120) + private String posit; + + @Size(max = 120) + @Column(name = "deptn", length = 120) + private String deptn; + + @Size(max = 1) + @Column(name = "wkfst", length = 1) + private String wkfst; + + @Size(max = 2) + @Column(name = "abscd", length = 2) + private String abscd; + + @Size(max = 12) + @Column(name = "ernam", length = 12) + private String ernam; + + @Size(max = 8) + @Column(name = "erdat", length = 8) + private String erdat; + + @Size(max = 6) + @Column(name = "erzet", length = 6) + private String erzet; + + @Size(max = 12) + @Column(name = "aenam", length = 12) + private String aenam; + + @Size(max = 8) + @Column(name = "aedat", length = 8) + private String aedat; + + @Size(max = 6) + @Column(name = "aezet", length = 6) + private String aezet; + +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/model/Zwf0012tId.java b/src/main/java/com/kospo/svcm/model/Zwf0012tId.java new file mode 100644 index 0000000..ef6a45c --- /dev/null +++ b/src/main/java/com/kospo/svcm/model/Zwf0012tId.java @@ -0,0 +1,45 @@ +package com.kospo.svcm.model; + +import jakarta.persistence.Column; +import jakarta.persistence.Embeddable; +import jakarta.persistence.Entity; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; +import lombok.*; +import org.hibernate.Hibernate; + +import java.io.Serializable; +import java.util.Objects; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@Embeddable +public class Zwf0012tId implements Serializable { + private static final long serialVersionUID = -6726950156900686838L; + @Size(max = 12) + @NotNull + @Column(name = "wkfid", nullable = false, length = 12) + private String wkfid; + + @NotNull + @Column(name = "wkfsq", nullable = false) + private Integer wkfsq; + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || Hibernate.getClass(this) != Hibernate.getClass(o)) return false; + Zwf0012tId entity = (Zwf0012tId) o; + return Objects.equals(this.wkfid, entity.wkfid) && + Objects.equals(this.wkfsq, entity.wkfsq); + } + + @Override + public int hashCode() { + return Objects.hash(wkfid, wkfsq); + } + +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/model/Zwf0013t.java b/src/main/java/com/kospo/svcm/model/Zwf0013t.java new file mode 100644 index 0000000..b7d1381 --- /dev/null +++ b/src/main/java/com/kospo/svcm/model/Zwf0013t.java @@ -0,0 +1,78 @@ +package com.kospo.svcm.model; + +import jakarta.persistence.Column; +import jakarta.persistence.EmbeddedId; +import jakarta.persistence.Entity; +import jakarta.persistence.Table; +import jakarta.validation.constraints.Size; +import lombok.*; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@Entity +@Table(name = "zwf0013t") +public class Zwf0013t { + @EmbeddedId + private Zwf0013tId id; + + @Column(name = "wkfsq") + private Integer wkfsq; + + @Size(max = 1) + @Column(name = "lineclsf", length = 1) + private String lineclsf; + + @Size(max = 40) + @Column(name = "btext", length = 40) + private String btext; + + @Size(max = 120) + @Column(name = "posit", length = 120) + private String posit; + + @Size(max = 120) + @Column(name = "deptn", length = 120) + private String deptn; + + @Size(max = 1) + @Column(name = "wkfst", length = 1) + private String wkfst; + + @Size(max = 2) + @Column(name = "abscd", length = 2) + private String abscd; + + @Size(max = 12) + @Column(name = "ernam", length = 12) + private String ernam; + + @Size(max = 8) + @Column(name = "erdat", length = 8) + private String erdat; + + @Size(max = 6) + @Column(name = "erzet", length = 6) + private String erzet; + + @Size(max = 12) + @Column(name = "aenam", length = 12) + private String aenam; + + @Size(max = 8) + @Column(name = "aedat", length = 8) + private String aedat; + + @Size(max = 6) + @Column(name = "aezet", length = 6) + private String aezet; + + @Column(name = "wkfsq1") + private Integer wkfsq1; + + @Column(name = "grpid") + private Integer grpid; + +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/model/Zwf0013tId.java b/src/main/java/com/kospo/svcm/model/Zwf0013tId.java new file mode 100644 index 0000000..61a4654 --- /dev/null +++ b/src/main/java/com/kospo/svcm/model/Zwf0013tId.java @@ -0,0 +1,52 @@ +package com.kospo.svcm.model; + +import jakarta.persistence.Column; +import jakarta.persistence.Embeddable; +import jakarta.persistence.Entity; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; +import lombok.*; +import org.hibernate.Hibernate; + +import java.io.Serializable; +import java.util.Objects; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@Embeddable +public class Zwf0013tId implements Serializable { + private static final long serialVersionUID = 1682378332257796994L; + @Size(max = 12) + @NotNull + @Column(name = "wkfid", nullable = false, length = 12) + private String wkfid; + + @Size(max = 1) + @NotNull + @Column(name = "gubun", nullable = false, length = 1) + private String gubun; + + @Size(max = 12) + @NotNull + @Column(name = "bname", nullable = false, length = 12) + private String bname; + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || Hibernate.getClass(this) != Hibernate.getClass(o)) return false; + Zwf0013tId entity = (Zwf0013tId) o; + return Objects.equals(this.wkfid, entity.wkfid) && + Objects.equals(this.bname, entity.bname) && + Objects.equals(this.gubun, entity.gubun); + } + + @Override + public int hashCode() { + return Objects.hash(wkfid, bname, gubun); + } + +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/repository/ApprMstRepository.java b/src/main/java/com/kospo/svcm/repository/ApprMstRepository.java new file mode 100644 index 0000000..385981c --- /dev/null +++ b/src/main/java/com/kospo/svcm/repository/ApprMstRepository.java @@ -0,0 +1,9 @@ +package com.kospo.svcm.repository; + +import com.kospo.svcm.model.ApprMst; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface ApprMstRepository extends JpaRepository { + ApprMst findByPrcsNo(String prcsNo); + ApprMst findByApprNo(String apprNo); +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/repository/ApprReqRepository.java b/src/main/java/com/kospo/svcm/repository/ApprReqRepository.java new file mode 100644 index 0000000..dcc3a52 --- /dev/null +++ b/src/main/java/com/kospo/svcm/repository/ApprReqRepository.java @@ -0,0 +1,522 @@ +package com.kospo.svcm.repository; + +import com.kospo.svcm.model.ApprReq; +import com.kospo.svcm.model.ApprReqId; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; + +import java.util.List; + +public interface ApprReqRepository extends JpaRepository { + void deleteByIdApprNo(String apprNo); + + List findByIdApprNoAndIdApprOrdGreaterThan(String apprNo, int apprOrd); + + ApprReq findFirstByIdApprNoAndIdApprOrdGreaterThan(String apprNo, int apprOrd); + + ApprReq findByIdApprNoAndIdApprOrdAndSabun(String apprNo, int apprOrd, String sabun); + + ApprReq findTopByIdApprNoAndApprStatCdOrderByIdApprOrdAsc(String apprNo, String apprStatCd); + + interface ApprReqDto { + String getPrcsNo(); + String getApprNo(); + Integer getApprOrd(); + String getTitle(); + String getSabun(); + String getName(); + String getApprStatCd(); + String getApprStat(); + String getRegDt(); + } + + @Query(value = "with req as (select ar.*\n" + + " from (select ar.*, row_number() over (partition by appr_no order by appr_ord) as num\n" + + " from appr_req as ar\n" + + " where appr_stat_cd = '0000'\n" + + " order by appr_ord) as ar\n" + + " where num = 1)\n" + + "select p.prcs_no, am.appr_no, req.appr_ord, p.title, req.sabun, req.name, am.appr_stat_cd, am.appr_stat, req.p_sabun, req.p_name, p.reg_dt " + + "from req " + + "inner join appr_mst am on req.appr_no = am.appr_no\n" + + "inner join prcs p on am.prcs_no = p.prcs_no and req.sabun = :sabun", nativeQuery = true) + Page findByApprBySabun(@Param("sabun") String sabun, Pageable pageable); + + interface igtApprReqDto { + String getApprNo(); + String getApprOrd(); + String getTitle(); + String getSabun(); + String getName(); + String getApprStatCd(); + String getApprStat(); + String getRegDt(); + String getGubun(); + } + + @Query(value = "select *\n" + + " from (with cte as (select appr_no,\n" + + " appr_ord,\n" + + " sabun,\n" + + " name,\n" + + " appr_stat_cd,\n" + + " '결재대기' AS appr_stat,\n" + + " row_number() over (partition by appr_no order by appr_ord) as num\n" + + " from appr_req\n" + + " where gubun_cd != ''\n" + + " and appr_stat_cd = '0000')\n" + + " select cte.appr_no,\n" + + " cte.appr_ord,\n" + + " p.title,\n" + + " cte.sabun,\n" + + " cte.name,\n" + + " cte.appr_stat_cd,\n" + + " cte.appr_stat,\n" + + " cte.num,\n" + + " am.reg_dt as reg_dt,\n" + + " 'SAP' as gubun\n" + + " from cte\n" + + " inner join appr_mst am on cte.appr_no = am.appr_no\n" + + " and am.appr_stat_cd in ('0000', '0100')\n" + + " inner join prcs p on am.prcs_no = p.prcs_no \n" + + " and num = 1 and sabun = :sabun)\n" + + "union all\n" + + "select cc.wkfid, cc.wkfsq, z11.wkftx, cc.bname, cc.btext, cc.wkfst, '결재대기', cc.num, to_char(to_date(cc.erdat||cc.erzet, 'yyyymmddHH24miss'), 'yyyy-mm-dd HH24:mi:ss') as erdt, 'SAP' from (\n" + + "WITH z2_counts AS (SELECT wkfid,\n" + + " sum(case when wkfst = 'A' then 1 else 0 end) as z2_acount,\n" + + " sum(case when wkfst = 'I' then 1 else 0 end) as z2_count\n" + + " FROM zwf0012t group by wkfid),\n" + + " z3_counts AS (SELECT wkfid,\n" + + " sum(case when wkfst = 'A' then 1 else 0 end) as z3_acount,\n" + + " sum(case when wkfst = 'I' then 1 else 0 end) as z3_count\n" + + " FROM zwf0013t group by wkfid),\n" + + " z2_data AS (SELECT wkfid,\n" + + " ROW_NUMBER() OVER (PARTITION BY wkfid ORDER BY lineclsf DESC, wkfsq) AS rn,\n" + + " lineclsf,\n" + + " 0 AS grpid,\n" + + " wkfsq,\n" + + " wkfst,\n" + + " abscd,\n" + + " bname,\n" + + " btext,\n" + + " posit,\n" + + " deptn,\n" + + " ernam,\n" + + " erdat,\n" + + " erzet,\n" + + " aenam,\n" + + " aedat,\n" + + " aezet,\n" + + " 0 AS wkfsq1\n" + + " FROM zwf0012t\n" + + " WHERE wkfst = 'I'),\n" + + " z3_data AS (SELECT wkfid,\n" + + " RANK() OVER (PARTITION BY grpid ORDER BY lineclsf DESC, wkfsq) AS rk,\n" + + " lineclsf,\n" + + " grpid,\n" + + " wkfsq,\n" + + " wkfst,\n" + + " abscd,\n" + + " bname,\n" + + " btext,\n" + + " posit,\n" + + " deptn,\n" + + " ernam,\n" + + " erdat,\n" + + " erzet,\n" + + " aenam,\n" + + " aedat,\n" + + " aezet,\n" + + " wkfsq1\n" + + " FROM zwf0013t\n" + + " WHERE wkfst = 'I')\n" + + "SELECT wkfid,\n" + + " num,\n" + + " lineclsf,\n" + + " grpid,\n" + + " wkfsq,\n" + + " wkfst,\n" + + " abscd,\n" + + " bname,\n" + + " btext,\n" + + " posit,\n" + + " deptn,\n" + + " ernam,\n" + + " erdat,\n" + + " erzet,\n" + + " aenam,\n" + + " aedat,\n" + + " aezet,\n" + + " wkfsq1\n" + + "FROM (SELECT z2.wkfid,\n" + + " CASE\n" + + " WHEN z2c.z2_count <= 1 AND z3c.z3_count > 0 THEN 99\n" + + " ELSE z2.rn\n" + + " END AS num,\n" + + " z2.lineclsf,\n" + + " z2.grpid,\n" + + " z2.wkfsq,\n" + + " z2.wkfst,\n" + + " z2.abscd,\n" + + " z2.bname,\n" + + " z2.btext,\n" + + " z2.posit,\n" + + " z2.deptn,\n" + + " z2.ernam,\n" + + " z2.erdat,\n" + + " z2.erzet,\n" + + " z2.aenam,\n" + + " z2.aedat,\n" + + " z2.aezet,\n" + + " z2.wkfsq1\n" + + " FROM z2_data z2\n" + + " inner JOIN z2_counts z2c on z2c.wkfid = z2.wkfid\n" + + " inner JOIN z3_counts z3c on z3c.wkfid = z2.wkfid\n" + + " WHERE z2c.z2_count > 1\n" + + " OR z3c.z3_count <= 0 \n" + + " UNION ALL\n" + + " SELECT z3.wkfid,\n" + + " z3.rk AS num,\n" + + " z3.lineclsf,\n" + + " z3.grpid,\n" + + " z3.wkfsq,\n" + + " z3.wkfst,\n" + + " z3.abscd,\n" + + " z3.bname,\n" + + " z3.btext,\n" + + " z3.posit,\n" + + " z3.deptn,\n" + + " z3.ernam,\n" + + " z3.erdat,\n" + + " z3.erzet,\n" + + " z3.aenam,\n" + + " z3.aedat,\n" + + " z3.aezet,\n" + + " z3.wkfsq1\n" + + " FROM z3_data z3\n" + + "inner JOIN z2_counts z2c on z2c.wkfid = z3.wkfid \n" + + " WHERE z2c.z2_count = 1) aa\n" + + "WHERE num = 1 and bname = :sabun\n" + + ") cc inner join zwf0011t z11 \n" + + " on cc.wkfid = z11.wkfid\n" + + " and z11.wkfst in ('Q', 'I')\n" + + " and (:title is null or :title = '' or z11.wkftx like concat('%', :title, '%'))\n" + + " and (:apprStat is null or :apprStat = '' or (select nm from code where id = 8 and cd = cc.wkfst) = :apprStat)\n" + + "order by reg_dt desc", + countQuery = "select count(appr_no)\n" + + " from (select appr_no,\n" + + " title,\n" + + " sabun,\n" + + " name,\n" + + " appr_stat_cd,\n" + + " appr_stat,\n" + + " num,\n" + + " reg_dt,\n" + + " gubun\n" + + " from (with cte as (select appr_no,\n" + + " sabun,\n" + + " name,\n" + + " appr_stat_cd,\n" + + " '결재대기' AS appr_stat,\n" + + " row_number() over (partition by appr_no order by appr_ord) as num\n" + + " from appr_req\n" + + " where gubun_cd != ''\n" + + " and appr_stat_cd = '0000')\n" + + " select cte.appr_no,\n" + + " p.title,\n" + + " cte.sabun,\n" + + " cte.name,\n" + + " cte.appr_stat_cd,\n" + + " cte.appr_stat,\n" + + " cte.num,\n" + + " am.reg_dt as reg_dt,\n" + + " 'SAP' as gubun\n" + + " from cte\n" + + " inner join appr_mst am on cte.appr_no = am.appr_no\n" + + " and am.appr_stat_cd in ('0000', '0100')\n" + + " inner join prcs p on am.prcs_no = p.prcs_no \n" + + " and num = 1 and sabun = :sabun)\n" + + " union all\n" + + " select cc.wkfid,\n" + + " z11.wkftx,\n" + + " cc.bname,\n" + + " cc.btext,\n" + + " cc.wkfst,\n" + + " '결재대기',\n" + + " cc.num,\n" + + " to_char(to_date(cc.erdat || cc.erzet, 'yyyymmddHH24miss'), 'yyyy-mm-dd HH24:mi:ss') as erdt,\n" + + " 'SAP'\n" + + " from (WITH z2_counts AS (SELECT wkfid,\n" + + " sum(case when wkfst = 'A' then 1 else 0 end) as z2_acount,\n" + + " sum(case when wkfst = 'I' then 1 else 0 end) as z2_count\n" + + " FROM zwf0012t group by wkfid),\n" + + " z3_counts AS (SELECT wkfid,\n" + + " sum(case when wkfst = 'A' then 1 else 0 end) as z3_acount,\n" + + " sum(case when wkfst = 'I' then 1 else 0 end) as z3_count\n" + + " FROM zwf0013t group by wkfid),\n" + + " z2_data AS (SELECT wkfid,\n" + + " ROW_NUMBER() OVER (PARTITION BY wkfid ORDER BY lineclsf DESC, wkfsq) AS rn,\n" + + " lineclsf,\n" + + " 0 AS grpid,\n" + + " wkfsq,\n" + + " wkfst,\n" + + " abscd,\n" + + " bname,\n" + + " btext,\n" + + " posit,\n" + + " deptn,\n" + + " ernam,\n" + + " erdat,\n" + + " erzet,\n" + + " aenam,\n" + + " aedat,\n" + + " aezet,\n" + + " 0 AS wkfsq1\n" + + " FROM zwf0012t\n" + + " WHERE wkfst = 'I'),\n" + + " z3_data AS (SELECT wkfid,\n" + + " RANK() OVER (PARTITION BY grpid ORDER BY lineclsf DESC, wkfsq) AS rk,\n" + + " lineclsf,\n" + + " grpid,\n" + + " wkfsq,\n" + + " wkfst,\n" + + " abscd,\n" + + " bname,\n" + + " btext,\n" + + " posit,\n" + + " deptn,\n" + + " ernam,\n" + + " erdat,\n" + + " erzet,\n" + + " aenam,\n" + + " aedat,\n" + + " aezet,\n" + + " wkfsq1\n" + + " FROM zwf0013t\n" + + " WHERE wkfst = 'I')\n" + + " SELECT wkfid,\n" + + " num,\n" + + " lineclsf,\n" + + " grpid,\n" + + " wkfsq,\n" + + " wkfst,\n" + + " abscd,\n" + + " bname,\n" + + " btext,\n" + + " posit,\n" + + " deptn,\n" + + " ernam,\n" + + " erdat,\n" + + " erzet,\n" + + " aenam,\n" + + " aedat,\n" + + " aezet,\n" + + " wkfsq1\n" + + " FROM (SELECT z2.wkfid,\n" + + " CASE\n" + + " WHEN z2c.z2_count <= 1 AND z3c.z3_count > 0 THEN 99\n" + + " ELSE z2.rn\n" + + " END AS num,\n" + + " z2.lineclsf,\n" + + " z2.grpid,\n" + + " z2.wkfsq,\n" + + " z2.wkfst,\n" + + " z2.abscd,\n" + + " z2.bname,\n" + + " z2.btext,\n" + + " z2.posit,\n" + + " z2.deptn,\n" + + " z2.ernam,\n" + + " z2.erdat,\n" + + " z2.erzet,\n" + + " z2.aenam,\n" + + " z2.aedat,\n" + + " z2.aezet,\n" + + " z2.wkfsq1\n" + + " FROM z2_data z2\n" + + " inner JOIN z2_counts z2c on z2c.wkfid = z2.wkfid\n" + + " inner JOIN z3_counts z3c on z3c.wkfid = z2.wkfid\n" + + " WHERE z2c.z2_count > 1\n" + + " OR z3c.z3_count <= 0 \n" + + " UNION ALL\n" + + " SELECT z3.wkfid,\n" + + " z3.rk AS num,\n" + + " z3.lineclsf,\n" + + " z3.grpid,\n" + + " z3.wkfsq,\n" + + " z3.wkfst,\n" + + " z3.abscd,\n" + + " z3.bname,\n" + + " z3.btext,\n" + + " z3.posit,\n" + + " z3.deptn,\n" + + " z3.ernam,\n" + + " z3.erdat,\n" + + " z3.erzet,\n" + + " z3.aenam,\n" + + " z3.aedat,\n" + + " z3.aezet,\n" + + " z3.wkfsq1\n" + + " FROM z3_data z3\n" + + " inner join z2_counts z2c \n" + + " WHERE z2c.z2_count = 1) aa\n" + + " WHERE num = 1\n" + + " and bname = :sabun) cc\n" + + " inner join zwf0011t z11 on cc.wkfid = z11.wkfid\n" + + " and z11.wkfst in ('Q', 'I') \n" + + " and (:title is null or :title = '' or z11.wkftx like concat('%', :title, '%'))\n" + + " and (:apprStat is null or :apprStat = '' or (select nm from code where id = 8 and cd = cc.wkfst) = :apprStat)\n" + + " order by reg_dt desc)", + nativeQuery = true) + Page igtFindhBySabun(@Param("sabun") String sabun, @Param("title") String title, @Param("apprStat") String apprStat, Pageable pageable); + + interface igtApprDto { + String getApprNo(); + String getTitle(); + String getApprStatCd(); + String getApprStat(); + String getReason(); + String getCompDt(); + String getRegDt(); + String getRegSabun(); + String getGubun(); + } + + @Query(value = "with cte as (select bb.*\n" + + " from (select am.appr_no,\n" + + " p.title,\n" + + " am.appr_stat_cd,\n" + + " am.appr_stat,\n" + + " am.reason,\n" + + " am.comp_dt,\n" + + " am.reg_dt,\n" + + " am.reg_sabun,\n" + + " 'SVCM' gubun\n" + + " from appr_mst am\n" + + " inner join prcs p on am.prcs_no = p.prcs_no\n" + + " and (:title is null or :title = '' or p.title like concat('%', :title, '%'))\n" + + " union all\n" + + " select zwf.wkfid,\n" + + " zwf.wkftx,\n" + + " zwf.wkfst,\n" + + " (select nm from code where id = 8 and cd = zwf.wkfst),\n" + + " zwf.reason,\n" + + " to_char(to_timestamp(zwf.aedat || zwf.aezet, 'yyyymmddHH24miss'), 'yyyy-mm-dd HH24:mi:ss'),\n" + + " to_char(to_timestamp(zwf.erdat || zwf.erzet, 'yyyymmddHH24miss'), 'yyyy-mm-dd HH24:mi:ss'),\n" + + " zwf.ernam,\n" + + " 'SAP'\n" + + " from zwf0011t zwf\n" + + " where 1 = 1\n" + + " and (:title is null or :title = '' or zwf.wkftx like concat('%', :title, '%'))" + + " order by reg_dt desc\n" + + " ) bb\n" + + ")\n" + + "select *\n" + + "from cte\n" + + "where 1 = 1", + countQuery = "with cte as (select bb.*\n" + + " from (select am.appr_no,\n" + + " p.title,\n" + + " am.appr_stat_cd,\n" + + " am.appr_stat,\n" + + " am.reason,\n" + + " am.comp_dt,\n" + + " am.reg_dt,\n" + + " am.reg_sabun,\n" + + " 'SVCM' gubun\n" + + " from appr_mst am\n" + + " inner join prcs p on am.prcs_no = p.prcs_no\n" + + " and (:title is null or :title = '' or p.title like concat('%', :title, '%'))\n" + + " union all\n" + + " select zwf.wkfid,\n" + + " zwf.wkftx,\n" + + " zwf.wkfst,\n" + + " (select nm from code where id = 8 and cd = zwf.wkfst),\n" + + " zwf.reason,\n" + + " to_char(to_timestamp(zwf.aedat || zwf.aezet, 'yyyymmddHH24miss'), 'yyyy-mm-dd HH24:mi:ss'),\n" + + " to_char(to_timestamp(zwf.erdat || zwf.erzet, 'yyyymmddHH24miss'), 'yyyy-mm-dd HH24:mi:ss'),\n" + + " zwf.ernam,\n" + + " 'SAP'\n" + + " from zwf0011t zwf\n" + + " where 1 = 1\n" + + " and (:title is null or :title = '' or zwf.wkftx like concat('%', :title, '%'))" + + " order by reg_dt desc\n" + + " ) bb\n" + + ")\n" + + "select count(cte.appr_no)\n" + + "from cte\n" + + "where 1 = 1", + nativeQuery = true) + Page igtFindAll(@Param("title") String title, Pageable pageable); + + + @Query(value = "with cte as (select am.appr_no,\n" + + " p.title,\n" + + " am.appr_stat_cd,\n" + + " am.appr_stat,\n" + + " am.reason,\n" + + " am.comp_dt,\n" + + " am.reg_dt,\n" + + " am.reg_sabun,\n" + + " 'SVCM' gubun\n" + + " from appr_mst am\n" + + " inner join prcs p on am.prcs_no = p.prcs_no\n" + + " where 1= 1\n"+ + " and (select dept_cd from users where sabun = am.reg_sabun) = :deptCd\n" + + " and (:title is null or :title = '' or p.title like concat('%', :title, '%'))\n" + + " union all\n" + + " select zwf.wkfid,\n" + + " zwf.wkftx,\n" + + " zwf.wkfst,\n" + + " (select nm from code where id = 8 and cd = zwf.wkfst),\n" + + " zwf.reason,\n" + + " to_char(to_timestamp(zwf.aedat || zwf.aezet, 'yyyymmddHH24miss'), 'yyyy-mm-dd HH24:mi:ss'),\n" + + " to_char(to_timestamp(zwf.erdat || zwf.erzet, 'yyyymmddHH24miss'), 'yyyy-mm-dd HH24:mi:ss'),\n" + + " zwf.ernam,\n" + + " 'SAP'\n" + + " from zwf0011t zwf\n" + + " where 1= 1\n"+ + " and (select dept_cd from users where sabun = zwf.ernam) = :deptCd\n" + + " and (:title is null or :title = '' or zwf.wkftx like concat('%', :title, '%'))\n" + + " order by reg_dt desc\n" + + ") \n" + + "select *\n" + + "from cte", + countQuery = "with cte as (select am.appr_no,\n" + + " p.title,\n" + + " am.appr_stat_cd,\n" + + " am.appr_stat,\n" + + " am.reason,\n" + + " am.comp_dt,\n" + + " am.reg_dt,\n" + + " am.reg_sabun,\n" + + " 'SVCM' gubun\n" + + " from appr_mst am\n" + + " inner join prcs p on am.prcs_no = p.prcs_no\n" + + " where 1= 1\n"+ + " and (select dept_cd from users where sabun = am.reg_sabun) = :deptCd\n" + + " and (:title is null or :title = '' or p.title like concat('%', :title, '%'))\n" + + " union all\n" + + " select zwf.wkfid,\n" + + " zwf.wkftx,\n" + + " zwf.wkfst,\n" + + " (select nm from code where id = 8 and cd = zwf.wkfst),\n" + + " zwf.reason,\n" + + " to_char(to_timestamp(zwf.aedat || zwf.aezet, 'yyyymmddHH24miss'), 'yyyy-mm-dd HH24:mi:ss'),\n" + + " to_char(to_timestamp(zwf.erdat || zwf.erzet, 'yyyymmddHH24miss'), 'yyyy-mm-dd HH24:mi:ss'),\n" + + " zwf.ernam,\n" + + " 'SAP'\n" + + " from zwf0011t zwf\n" + + " where 1= 1\n"+ + " and (select dept_cd from users where sabun = zwf.ernam) = :deptCd\n" + + " and (:title is null or :title = '' or zwf.wkftx like concat('%', :title, '%'))\n" + + " order by reg_dt desc\n" + + ") \n" + + "select count(cte.appr_no)\n" + + "from cte", + nativeQuery = true) + Page igtFindByDeptCd(@Param("deptCd") String deptCd, @Param("title") String title, Pageable pageable); +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/repository/BusinessRepository.java b/src/main/java/com/kospo/svcm/repository/BusinessRepository.java new file mode 100644 index 0000000..4947521 --- /dev/null +++ b/src/main/java/com/kospo/svcm/repository/BusinessRepository.java @@ -0,0 +1,40 @@ +package com.kospo.svcm.repository; + +import com.kospo.svcm.model.Business; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; + +import java.util.List; + +public interface BusinessRepository extends JpaRepository { + + @Query("with bus as ( " + + " select aa.bizNo as bizNo," + + " aa.compNm as compNm, " + + " aa.repNm as repNm, " + + " aa.email as email, " + + " aa.expireDt as expireDt, " + + " aa.state as state " + + " from (" + + " select b.bizNo as bizNo, " + + " b.compNm as compNm, " + + " b.repNm as repNm, " + + " b.email as email, " + + " b.state as state, " + + " pp.expireDt as expireDt, " + + " row_number() over (partition by pp.id.bizNo order by pp.expireDt desc) as num" + + " from Business b " + + " inner join PvyPeriod pp " + + " on b.bizNo = pp.id.bizNo " + + " ) aa " + + " where aa.num = 1 " + + ") select " + + " new Business (bb.bizNo, " + + " bb.compNm, " + + " bb.repNm, " + + " bb.email, " + + " bb.state) " + + "from bus bb " + + "where to_timestamp(bb.expireDt, 'yyyy-mm-dd HH24:mi:ss') > current_date") + List findByExpireDt(); +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/repository/CodeRepository.java b/src/main/java/com/kospo/svcm/repository/CodeRepository.java new file mode 100644 index 0000000..703f22f --- /dev/null +++ b/src/main/java/com/kospo/svcm/repository/CodeRepository.java @@ -0,0 +1,20 @@ +package com.kospo.svcm.repository; + +import com.kospo.svcm.model.Code; +import com.kospo.svcm.model.CodeId; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; + +import java.util.List; + +public interface CodeRepository extends JpaRepository { + @Query(value = "select c from Code c " + + "where (:useYn is null or c.useYn = :useYn)") + Page findSearch(Boolean useYn, Pageable pageable); + + List findByIdId(int id); + + List findByIdIdAndUseYn(int id, boolean useYn); +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/repository/ContApprRepository.java b/src/main/java/com/kospo/svcm/repository/ContApprRepository.java new file mode 100644 index 0000000..3cfa4da --- /dev/null +++ b/src/main/java/com/kospo/svcm/repository/ContApprRepository.java @@ -0,0 +1,11 @@ +package com.kospo.svcm.repository; + +import com.kospo.svcm.model.ContAppr; +import com.kospo.svcm.model.ContApprId; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.List; + +public interface ContApprRepository extends JpaRepository { + List findByIdContNoOrderByIdTransactionKeyDesc(String contNo); +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/repository/ContAttRepository.java b/src/main/java/com/kospo/svcm/repository/ContAttRepository.java new file mode 100644 index 0000000..461bd5d --- /dev/null +++ b/src/main/java/com/kospo/svcm/repository/ContAttRepository.java @@ -0,0 +1,11 @@ +package com.kospo.svcm.repository; + +import com.kospo.svcm.model.ContAtt; +import com.kospo.svcm.model.ContAttId; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.List; + +public interface ContAttRepository extends JpaRepository { + List findByIdContNo(String contNo); +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/repository/ContRepository.java b/src/main/java/com/kospo/svcm/repository/ContRepository.java new file mode 100644 index 0000000..4053ed5 --- /dev/null +++ b/src/main/java/com/kospo/svcm/repository/ContRepository.java @@ -0,0 +1,44 @@ +package com.kospo.svcm.repository; + +import com.kospo.svcm.model.Cont; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; + +import java.util.List; + +public interface ContRepository extends JpaRepository { + Cont findByPrcsNo(String prcsNo); + + Cont findByContNoAndContStatCd(String contNo, String contStatCd); + + interface IContResponse { + String getContNo(); + String getCompNm(); + String getTitle(); + String getSignDt(); + int getContAmt(); + String getContStatCd(); + String getContStat(); + String getRegDt(); + String getRegNm(); + String getRegSabun(); + } + @Query(value = "select c.contNo as contNo, " + + " c.compNm as compNm, " + + " p.title as title, " + + " c.signDt as signDt, " + + " c.contAmt as contAmt, " + + " c.contStatCd as contStatCd, " + + " c.contStat as contStat, " + + " c.regDt as regDt, " + + " c.regNm as regNm, " + + " c.regSabun as regSabun " + + "from Cont c inner join Prcs p " + + "on c.prcsNo = p.prcsNo " + + "and c.regSabun = :sabun " + + "and (:contStatCd is null or :contStatCd = '' or c.contStatCd = :contStatCd) " + + "and c.signDt between :signSdt and :signEdt order by c.contNo desc") + Page findBySearch(String sabun, String contStatCd, String signSdt, String signEdt, Pageable pageable); +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/repository/DeptRepository.java b/src/main/java/com/kospo/svcm/repository/DeptRepository.java new file mode 100644 index 0000000..3795926 --- /dev/null +++ b/src/main/java/com/kospo/svcm/repository/DeptRepository.java @@ -0,0 +1,7 @@ +package com.kospo.svcm.repository; + +import com.kospo.svcm.model.Dept; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface DeptRepository extends JpaRepository { +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/repository/DtlSpecRepository.java b/src/main/java/com/kospo/svcm/repository/DtlSpecRepository.java new file mode 100644 index 0000000..11c8a37 --- /dev/null +++ b/src/main/java/com/kospo/svcm/repository/DtlSpecRepository.java @@ -0,0 +1,11 @@ +package com.kospo.svcm.repository; + +import com.kospo.svcm.model.DtlSpec; +import com.kospo.svcm.model.DtlSpecId; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.List; + +public interface DtlSpecRepository extends JpaRepository { + List findByIdPrcsNo(String prcsNo); +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/repository/EstDocRepository.java b/src/main/java/com/kospo/svcm/repository/EstDocRepository.java new file mode 100644 index 0000000..f1033ad --- /dev/null +++ b/src/main/java/com/kospo/svcm/repository/EstDocRepository.java @@ -0,0 +1,8 @@ +package com.kospo.svcm.repository; + +import com.kospo.svcm.model.EstDoc; +import com.kospo.svcm.model.EstDocId; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface EstDocRepository extends JpaRepository { +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/repository/EstimateRepository.java b/src/main/java/com/kospo/svcm/repository/EstimateRepository.java new file mode 100644 index 0000000..b328fee --- /dev/null +++ b/src/main/java/com/kospo/svcm/repository/EstimateRepository.java @@ -0,0 +1,12 @@ +package com.kospo.svcm.repository; + +import com.kospo.svcm.model.Estimate; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.List; + +public interface EstimateRepository extends JpaRepository { + List findByPrcsNo(String prcsNo); + List findByBizNoAndPrcsNo(String bizNo, String prcsNo); + Estimate findByBizNoAndPrcsNoAndDtlSpNo(String bizNo, String prcsNo, String dtlSpNo); +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/repository/GrpCodeRepository.java b/src/main/java/com/kospo/svcm/repository/GrpCodeRepository.java new file mode 100644 index 0000000..5a849d4 --- /dev/null +++ b/src/main/java/com/kospo/svcm/repository/GrpCodeRepository.java @@ -0,0 +1,22 @@ +package com.kospo.svcm.repository; + +import com.kospo.svcm.model.GrpCode; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; + +import java.util.List; + +public interface GrpCodeRepository extends JpaRepository { + + @Query(value = "select g from GrpCode g " + + "where (:nm is null or :nm = '' or g.nm like concat('%', :nm, '%')) " + + "and (:useYn is null or g.useYn = :useYn)") + Page findSearchPage(String nm, Boolean useYn, Pageable pageable); + + @Query(value = "select g from GrpCode g " + + "where (:nm is null or :nm = '' or g.nm like concat('%', :nm, '%')) " + + "and (:useYn is null or g.useYn = :useYn)") + List findSearch(String nm, Boolean useYn); +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/repository/LoginHiRepository.java b/src/main/java/com/kospo/svcm/repository/LoginHiRepository.java new file mode 100644 index 0000000..b386f09 --- /dev/null +++ b/src/main/java/com/kospo/svcm/repository/LoginHiRepository.java @@ -0,0 +1,8 @@ +package com.kospo.svcm.repository; + +import com.kospo.svcm.model.LoginHis; +import com.kospo.svcm.model.LoginHisId; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface LoginHiRepository extends JpaRepository { +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/repository/LoginHisRepository.java b/src/main/java/com/kospo/svcm/repository/LoginHisRepository.java new file mode 100644 index 0000000..6749533 --- /dev/null +++ b/src/main/java/com/kospo/svcm/repository/LoginHisRepository.java @@ -0,0 +1,8 @@ +package com.kospo.svcm.repository; + +import com.kospo.svcm.model.LoginHis; +import com.kospo.svcm.model.LoginHisId; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface LoginHisRepository extends JpaRepository { +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/repository/PbAttRepository.java b/src/main/java/com/kospo/svcm/repository/PbAttRepository.java new file mode 100644 index 0000000..d8f9f1d --- /dev/null +++ b/src/main/java/com/kospo/svcm/repository/PbAttRepository.java @@ -0,0 +1,8 @@ +package com.kospo.svcm.repository; + +import com.kospo.svcm.model.PbAtt; +import com.kospo.svcm.model.PbAttId; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface PbAttRepository extends JpaRepository { +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/repository/PrcsAttRepository.java b/src/main/java/com/kospo/svcm/repository/PrcsAttRepository.java new file mode 100644 index 0000000..efbdee1 --- /dev/null +++ b/src/main/java/com/kospo/svcm/repository/PrcsAttRepository.java @@ -0,0 +1,11 @@ +package com.kospo.svcm.repository; + +import com.kospo.svcm.model.PrcsAtt; +import com.kospo.svcm.model.PrcsAttId; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.List; + +public interface PrcsAttRepository extends JpaRepository { + List findByIdPrcsNo(String prcsNo); +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/repository/PrcsBizRepository.java b/src/main/java/com/kospo/svcm/repository/PrcsBizRepository.java new file mode 100644 index 0000000..224b657 --- /dev/null +++ b/src/main/java/com/kospo/svcm/repository/PrcsBizRepository.java @@ -0,0 +1,26 @@ +package com.kospo.svcm.repository; + +import com.kospo.svcm.model.PrcsBiz; +import com.kospo.svcm.model.PrcsBizId; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Modifying; +import org.springframework.data.jpa.repository.Query; + +public interface PrcsBizRepository extends JpaRepository { + @Query("select count(p.prcsNo) from Prcs p \n" + + "inner join PrcsBiz pb on p.prcsNo = pb.id.prcsNo \n" + + "inner join ApprMst am on am.prcsNo = p.prcsNo \n" + + "and pb.id.bizNo = :bizNo " + + "and p.stCd = '0100' and pb.estStatCd = '0000' and am.apprStatCd = '0200' ") + int countReqByBizNo(String bizNo); + + /*입찰 상태 변경*/ + @Modifying + @Query(value = "update PrcsBiz AS p set p.estStatCd = :estStatCd, p.estStat = (select c.nm from Code AS c where c.id.id = 4 and c.id.cd = :estStatCd ) where p.id.prcsNo = :prcsNo") + void updatePrcsBizByEstStatCd(String prcsNo, String estStatCd); + + /*(특정 업체) 입찰 상태 변경*/ + @Modifying + @Query(value = "update PrcsBiz AS p set p.estStatCd = :estStatCd, p.estStat = (select c.nm from Code AS c where c.id.id = 4 and c.id.cd = :estStatCd ) where p.id.prcsNo = :prcsNo and p.id.bizNo = :bizNo") + void updatePrcsBizByEstStatCd(String prcsNo, String bizNo, String estStatCd); +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/repository/PrcsRepository.java b/src/main/java/com/kospo/svcm/repository/PrcsRepository.java new file mode 100644 index 0000000..6f2f1d7 --- /dev/null +++ b/src/main/java/com/kospo/svcm/repository/PrcsRepository.java @@ -0,0 +1,200 @@ +package com.kospo.svcm.repository; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.kospo.svcm.model.Prcs; +import io.swagger.v3.oas.annotations.media.Schema; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; + +import java.util.List; + +public interface PrcsRepository extends JpaRepository { + List findBySvyYn(boolean svyYn); + + @Query("select p, pb.estStat, pb.estStatCd from Prcs p inner join PrcsBiz pb on p.prcsNo = pb.id.prcsNo \n" + + "and pb.id.bizNo = :bizNo " + + "and p.prcsNo = :prcsNo group by p, pb.estStat, pb.estStatCd order by p.prcsNo desc" + ) + Prcs findOne(String bizNo, String prcsNo); + + Prcs findByPrcsNoAndRegSabun(String prcsNo, String regSabun); + + @Query("select p from Prcs p " + + "where (:cateCd is null or :cateCd = '' or p.cateCd = :cateCd) " + + "and (:stCd is null or :stCd = '' or p.stCd = :stCd)" + + "and (:regNm is null or :regNm = '' or p.regNm like concat('%', :regNm, '%'))" + + "and p.regDt between :regSdt and :regEdt order by p.prcsNo desc" + ) + List findSearch(String cateCd, String stCd, String regNm, String regSdt, String regEdt); + + @Query("select p from Prcs p " + + "where (:cateCd is null or :cateCd = '' or p.cateCd = :cateCd) " + + "and (:stCd is null or :stCd = '' or p.stCd = :stCd)" + + "and (:regNm is null or :regNm = '' or p.regNm like concat('%', :regNm, '%'))" + + "and p.regDt between :regSdt and :regEdt order by p.prcsNo desc" + ) + Page findSearch(String cateCd, String stCd, String regNm, String regSdt, String regEdt, Pageable pageable); + + @Query("select p from Prcs p inner join User u " + + "on p.regSabun = u.sabun " + + "and u.deptCd = :deptCd " + + "and (:cateCd is null or :cateCd = '' or p.cateCd = :cateCd) " + + "and (:stCd is null or :stCd = '' or p.stCd = :stCd)" + + "and (:regNm is null or :regNm = '' or p.regNm like concat('%', :regNm, '%'))" + + "and p.regDt between :regSdt and :regEdt order by p.prcsNo desc" + ) + Page findSearch(String deptCd, String cateCd, String stCd, String regNm, String regSdt, String regEdt, Pageable pageable); + + @Query("with prc as ( " + + "select p.prcsNo as prcsNo, " + + " p.cateCd as cateCd, " + + " p.cateNm as cateNm, " + + " p.title as title, " + + " p.content as content, " + + " p.regSdat as regSdat, " + + " p.regEdat as regEdat, " + + " p.prvYn as prvYn, " + + " p.prvRsn as prvRsn, " + + " p.prvPwd as prvPwd, " + + " p.aiYn as aiYn, " + + " p.regSabun as regSabun, " + + " p.regNm as regNm, " + + " p.stCd as stCd, " + + " p.stNm as stNm, " + + " p.svyYn as svyYn, " + + " p.svyDt as svyDt, " + + " p.regDt as regDt " + + " from Prcs p " + + " where p.prcsNo not in (select c.prcsNo from Cont c) " + + "and p.svyYn = true " + + ") " + + "select new Prcs(pr.prcsNo, " + + " pr.cateCd, " + + " pr.cateNm, " + + " pr.title, " + + " pr.content, " + + " pr.regSdat, " + + " pr.regEdat, " + + " pr.prvYn, " + + " pr.prvRsn, " + + " pr.prvPwd, " + + " pr.aiYn, " + + " pr.regSabun, " + + " pr.regNm, " + + " pr.regDt, " + + " pr.stCd, " + + " pr.stNm, " + + " pr.svyYn, " + + " pr.svyDt) " + + "from prc pr " + + "where pr.regSabun = :sabun " + + "order by pr.prcsNo desc ") + List findContTarget(String sabun); + + @Query("select p from Prcs p \n" + + "inner join PrcsBiz pb on p.prcsNo = pb.id.prcsNo \n" + + "inner join ApprMst am on am.prcsNo = p.prcsNo \n" + + "and pb.id.bizNo = :bizNo " + + "and p.stCd = '0100' and pb.estStatCd = '0000' and am.apprStatCd = '0200' " + + "and (:cateCd is null or :cateCd = '' or p.cateCd = :cateCd) " + + "and (:regNm is null or :regNm = '' or p.regNm like concat('%', :regNm, '%'))" + + "and (:title is null or :title = '' or p.title like concat('%', :title, '%'))" + + "and p.regDt between :regSdt and :regEdt group by p order by p.prcsNo desc" + ) + Page findExternalSearch(String bizNo, String cateCd, String title, String regNm, String regSdt, String regEdt, Pageable pageable); + + + @Query("select p from Prcs p inner join PrcsBiz pb on p.prcsNo = pb.id.prcsNo \n" + + "and pb.id.bizNo = :bizNo " + + "and p.stCd = '0200' and pb.estStatCd != '0000' " + + "and (:cateCd is null or :cateCd = '' or p.cateCd = :cateCd) " + + "and (:regNm is null or :regNm = '' or p.regNm like concat('%', :regNm, '%'))" + + "and (:title is null or :title = '' or p.title like concat('%', :title, '%'))" + + "and p.regDt between :regSdt and :regEdt group by p order by p.prcsNo desc" + ) + Page findExternalEstSearch(String bizNo, String cateCd, String title, String regNm, String regSdt, String regEdt, Pageable pageable); + + @JsonIgnoreProperties(ignoreUnknown = true) + @Schema(name = "IBidExternalResponse", description = "입찰내역") + interface IEstExternalResponse { + @Schema(name = "prcsNo", description = "가격조사번호") + String getPrcsNo(); + @Schema(name = "title", description = "제목") + String getTitle(); + @Schema(name = "totAmt", description = "입찰금액") + Integer getTotAmt(); + @Schema(name = "mngNm", description = "담당자") + String getMngNm(); + @Schema(name = "estDt", description = "입찰일시") + String getEstDt(); + @Schema(name = "estStat", description = "입찰상태") + String getEstStat(); + @Schema(name = "estStatCd", description = "입찰상태코드") + String getEstStatCd(); + @Schema(name = "svyDt", description = "조사 완료시간") + String getSvyDt(); + } + @Query("select p.prcsNo as prcsNo, p.title as title, e.mngNm as mngNm, e.totAmt as totAmt, e.estDt as estDt, pb.estStatCd as estStatCd, pb.estStat as estStat, p.svyDt as svyDt \n" + + "from Prcs p\n" + + " inner join PrcsBiz pb on p.prcsNo = pb.id.prcsNo \n" + + " inner join (select prcsNo as prcsNo, bizNo as bizNo, mngNm as mngNm, sum(amt) AS totAmt, max(regDt) AS estDt\n" + + " from Estimate \n" + + " where bizNo = :bizNo\n" + + " group by prcsNo, bizNo, mngNm) e\n" + + " on p.prcsNo = e.prcsNo\n" + + " and e.bizNo = pb.id.bizNo \n" + + " and pb.id.bizNo = :bizNo" + + " and p.stCd in ('0100', '0200') and pb.estStatCd != '0000' " + + " and (:estStatCd is null or :estStatCd = '' or pb.estStatCd = :estStatCd) " + + " and (:mngNm is null or :mngNm = '' or e.mngNm like concat('%', :mngNm, '%'))" + + " and (:title is null or :title = '' or p.title like concat('%', :title, '%'))" + + " order by e.estDt desc") + Page findEstList(String bizNo, String title, String estStatCd, String mngNm, Pageable pageable); + + @Query("select p from Prcs p " + + "where p.svyYn = true " + + "and (:cateCd is null or :cateCd = '' or p.cateCd = :cateCd)" + + "and (:regNm is null or :regNm = '' or p.regNm like concat('%', :regNm, '%'))" + + "and p.regDt between :regSdt and :regEdt order by p.prcsNo desc" + ) + Page findContractSearch(String cateCd, String regNm, String regSdt, String regEdt, Pageable pageable); + + + @Query("SELECT p.prcsNo AS prcsNo, " + + " p.cateCd AS cateCd, " + + " p.title AS title, " + + " p.content AS content, " + + " p.regSdat AS regSdat, " + + " p.regEdat AS regEdat, " + + " p.prvYn AS prvYn, " + + " p.prvRsn AS prvRsn, " + + " p.prvPwd AS prvPwd, " + + " p.aiYn AS aiYn, " + + " p.regSabun AS regSabun, " + + " p.regNm AS regNm, " + + " p.stCd AS stCd, " + + " p.stNm AS stNm, " + + " p.svyYn AS svyYn, " + + " p.svyDt AS svyDt, " + + " p.regDt AS regDt " + + "FROM Prcs p\n" + + " INNER JOIN (SELECT am.prcsNo AS prcsNo,\n" + + " ar.sabun as sabun,\n" + + " Row_number()\n" + + " OVER (\n" + + " PARTITION BY am.prcsNo\n" + + " ORDER BY am.apprNo) AS rn\n" + + " FROM ApprMst am\n" + + " INNER JOIN ApprReq ar\n" + + " ON am.apprNo = ar.id.apprNo\n" + + " WHERE am.apprStatCd IN ( '0000', '0100' )) AS a\n" + + " ON p.prcsNo = a.prcsNo\n" + + "WHERE a.rn = 1\n" + + "AND a.sabun = :sabun " + + "and (:cateCd is null or :cateCd = '' or p.cateCd = :cateCd)" + + "and (:regNm is null or :regNm = '' or p.regNm like concat('%', :regNm, '%'))" + + "and p.regDt between :regSdt and :regEdt order by p.prcsNo desc") + Page findApprSearch(String sabun, String cateCd, String regNm, String regSdt, String regEdt, Pageable pageable); +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/repository/PvyPeriodRepository.java b/src/main/java/com/kospo/svcm/repository/PvyPeriodRepository.java new file mode 100644 index 0000000..fbf333d --- /dev/null +++ b/src/main/java/com/kospo/svcm/repository/PvyPeriodRepository.java @@ -0,0 +1,8 @@ +package com.kospo.svcm.repository; + +import com.kospo.svcm.model.PvyPeriod; +import com.kospo.svcm.model.PvyPeriodId; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface PvyPeriodRepository extends JpaRepository { +} diff --git a/src/main/java/com/kospo/svcm/repository/RoleRepository.java b/src/main/java/com/kospo/svcm/repository/RoleRepository.java new file mode 100644 index 0000000..39516e1 --- /dev/null +++ b/src/main/java/com/kospo/svcm/repository/RoleRepository.java @@ -0,0 +1,13 @@ +package com.kospo.svcm.repository; + +import com.kospo.svcm.model.Role; +import com.kospo.svcm.model.RoleId; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.List; + +public interface RoleRepository extends JpaRepository { + List findByIdSabun(String sabun); + + List findByIdRoleId(String roleId); +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/repository/SequenceRepository.java b/src/main/java/com/kospo/svcm/repository/SequenceRepository.java new file mode 100644 index 0000000..54df8b6 --- /dev/null +++ b/src/main/java/com/kospo/svcm/repository/SequenceRepository.java @@ -0,0 +1,7 @@ +package com.kospo.svcm.repository; + +import com.kospo.svcm.model.Sequence; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface SequenceRepository extends JpaRepository { +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/repository/SignDocRepository.java b/src/main/java/com/kospo/svcm/repository/SignDocRepository.java new file mode 100644 index 0000000..9a06df4 --- /dev/null +++ b/src/main/java/com/kospo/svcm/repository/SignDocRepository.java @@ -0,0 +1,7 @@ +package com.kospo.svcm.repository; + +import com.kospo.svcm.model.SignDoc; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface SignDocRepository extends JpaRepository { +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/repository/SignLineRepository.java b/src/main/java/com/kospo/svcm/repository/SignLineRepository.java new file mode 100644 index 0000000..2719c49 --- /dev/null +++ b/src/main/java/com/kospo/svcm/repository/SignLineRepository.java @@ -0,0 +1,8 @@ +package com.kospo.svcm.repository; + +import com.kospo.svcm.model.SignLine; +import com.kospo.svcm.model.SignLineId; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface SignLineRepository extends JpaRepository { +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/repository/SlipAttRepository.java b/src/main/java/com/kospo/svcm/repository/SlipAttRepository.java new file mode 100644 index 0000000..b8bf710 --- /dev/null +++ b/src/main/java/com/kospo/svcm/repository/SlipAttRepository.java @@ -0,0 +1,8 @@ +package com.kospo.svcm.repository; + +import com.kospo.svcm.model.SlipAtt; +import com.kospo.svcm.model.SlipAttId; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface SlipAttRepository extends JpaRepository { +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/repository/SlipRepository.java b/src/main/java/com/kospo/svcm/repository/SlipRepository.java new file mode 100644 index 0000000..dfe3c14 --- /dev/null +++ b/src/main/java/com/kospo/svcm/repository/SlipRepository.java @@ -0,0 +1,11 @@ +package com.kospo.svcm.repository; + +import com.kospo.svcm.model.Slip; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.List; + +public interface SlipRepository extends JpaRepository { + Slip findByContNo(String contNo); + Slip findByBelnr(String belnr); +} diff --git a/src/main/java/com/kospo/svcm/repository/UserRepository.java b/src/main/java/com/kospo/svcm/repository/UserRepository.java new file mode 100644 index 0000000..809d610 --- /dev/null +++ b/src/main/java/com/kospo/svcm/repository/UserRepository.java @@ -0,0 +1,11 @@ +package com.kospo.svcm.repository; + +import com.kospo.svcm.model.User; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.List; + +public interface UserRepository extends JpaRepository { + User findBySabun(String sabun); + List findByNameContaining(String name); +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/repository/Zwf0011tRepository.java b/src/main/java/com/kospo/svcm/repository/Zwf0011tRepository.java new file mode 100644 index 0000000..3198554 --- /dev/null +++ b/src/main/java/com/kospo/svcm/repository/Zwf0011tRepository.java @@ -0,0 +1,31 @@ +package com.kospo.svcm.repository; + +import com.kospo.svcm.model.Zwf0011t; +import com.kospo.svcm.model.Zwf0011tId; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; + +import java.util.List; + +public interface Zwf0011tRepository extends JpaRepository { + List findByErnam(String sabun); + + Zwf0011t findByObkey(String obkey); + + @Query("select z from Zwf0011t z " + + "where (:wkfst is null or :wkfst = '' or z.wkfst = :wkfst) " + + "and (:ernam is null or :ernam = '' or z.ernam like concat('%', :ernam, '%'))" + + "and z.erdat between :erSdat and :erEdat order by z.erdat desc") + Page findSearch(String wkfst, String ernam, String erSdat, String erEdat, Pageable pageable); + + + @Query("select z from Zwf0011t z " + + "where z.ernam = :sabun " + + "and (:wkfst is null or :wkfst = '' or z.wkfst = :wkfst) " + + "and z.erdat between :erSdat and :erEdat order by z.erdat desc") + Page findSearchBySabun(String sabun, String wkfst, String erSdat, String erEdat, Pageable pageable); + + Zwf0011t findByIdWkfid(String wkfid); +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/repository/Zwf0012tRepository.java b/src/main/java/com/kospo/svcm/repository/Zwf0012tRepository.java new file mode 100644 index 0000000..aa1f0d6 --- /dev/null +++ b/src/main/java/com/kospo/svcm/repository/Zwf0012tRepository.java @@ -0,0 +1,148 @@ +package com.kospo.svcm.repository; + +import com.kospo.svcm.model.Zwf0012t; +import com.kospo.svcm.model.Zwf0012tId; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; + +import java.util.List; + +public interface Zwf0012tRepository extends JpaRepository { + List findByIdWkfid(String WkfId); + Zwf0012t findByIdWkfidAndIdWkfsqAndBname(String wkfid, Integer wkfsq, String bname); + + interface SapApprReqDto { + String getWkfid(); + String getWkftx(); + Integer getWkfsq(); + String getBname(); + String getBtext(); + String getWkfst(); + String getRegDt(); + String getGubun(); + } + @Query(value = "select cc.wkfid, z11.wkftx, cc.wkfsq, cc.bname, cc.btext, cc.wkfst, to_char(to_date(cc.erdat||cc.erzet, 'yyyymmddHH24miss'), 'yyyy-mm-dd HH24:mi:ss') as erdt, cc.gubun from (\n" + + "WITH z2_counts AS (SELECT wkfid,\n" + + " sum(case when wkfst = 'A' then 1 else 0 end) as z2_acount,\n" + + " sum(case when wkfst = 'I' then 1 else 0 end) as z2_count\n" + + " FROM zwf0012t group by wkfid),\n" + + " z3_counts AS (SELECT wkfid,\n" + + " sum(case when wkfst = 'A' then 1 else 0 end) as z3_acount,\n" + + " sum(case when wkfst = 'I' then 1 else 0 end) as z3_count\n" + + " FROM zwf0013t group by wkfid),\n" + + " z2_data AS (SELECT wkfid,\n" + + " ROW_NUMBER() OVER (PARTITION BY wkfid ORDER BY lineclsf DESC, wkfsq) AS rn,\n" + + " lineclsf,\n" + + " 0 AS grpid,\n" + + " wkfsq,\n" + + " wkfst,\n" + + " abscd,\n" + + " bname,\n" + + " btext,\n" + + " posit,\n" + + " deptn,\n" + + " ernam,\n" + + " erdat,\n" + + " erzet,\n" + + " aenam,\n" + + " aedat,\n" + + " aezet,\n" + + " 't12' as gubun,\n" + + " 0 AS wkfsq1\n" + + " FROM zwf0012t\n" + + " WHERE wkfst = 'I'),\n" + + " z3_data AS (SELECT wkfid,\n" + + " RANK() OVER (PARTITION BY grpid ORDER BY lineclsf DESC, wkfsq) AS rk,\n" + + " lineclsf,\n" + + " grpid,\n" + + " wkfsq,\n" + + " wkfst,\n" + + " abscd,\n" + + " bname,\n" + + " btext,\n" + + " posit,\n" + + " deptn,\n" + + " ernam,\n" + + " erdat,\n" + + " erzet,\n" + + " aenam,\n" + + " aedat,\n" + + " aezet,\n" + + " 't13' as gubun,\n" + + " wkfsq1\n" + + " FROM zwf0013t\n" + + " WHERE wkfst = 'I')\n" + + "SELECT wkfid,\n" + + " num,\n" + + " lineclsf,\n" + + " grpid,\n" + + " wkfsq,\n" + + " wkfst,\n" + + " abscd,\n" + + " bname,\n" + + " btext,\n" + + " posit,\n" + + " deptn,\n" + + " ernam,\n" + + " erdat,\n" + + " erzet,\n" + + " aenam,\n" + + " aedat,\n" + + " aezet,\n" + + " gubun,\n" + + " wkfsq1\n" + + "FROM (SELECT z2.wkfid,\n" + + " CASE\n" + + " WHEN z2c.z2_count <= 1 AND z3c.z3_count > 0 THEN 99\n" + + " ELSE z2.rn\n" + + " END AS num,\n" + + " z2.lineclsf,\n" + + " z2.grpid,\n" + + " z2.wkfsq,\n" + + " z2.wkfst,\n" + + " z2.abscd,\n" + + " z2.bname,\n" + + " z2.btext,\n" + + " z2.posit,\n" + + " z2.deptn,\n" + + " z2.ernam,\n" + + " z2.erdat,\n" + + " z2.erzet,\n" + + " z2.aenam,\n" + + " z2.aedat,\n" + + " z2.aezet,\n" + + " z2.gubun,\n" + + " z2.wkfsq1\n" + + " FROM z2_data z2\n" + + "inner JOIN z2_counts z2c on z2c.wkfid = z2.wkfid\n" + + "inner JOIN z3_counts z3c on z3c.wkfid = z2.wkfid\n" + + " WHERE z2c.z2_count > 1\n" + + " OR z3c.z3_count <= 0 \n" + + " UNION ALL\n" + + " SELECT z3.wkfid,\n" + + " z3.rk AS num,\n" + + " z3.lineclsf,\n" + + " z3.grpid,\n" + + " z3.wkfsq,\n" + + " z3.wkfst,\n" + + " z3.abscd,\n" + + " z3.bname,\n" + + " z3.btext,\n" + + " z3.posit,\n" + + " z3.deptn,\n" + + " z3.ernam,\n" + + " z3.erdat,\n" + + " z3.erzet,\n" + + " z3.aenam,\n" + + " z3.aedat,\n" + + " z3.aezet,\n" + + " z3.gubun,\n" + + " z3.wkfsq1\n" + + " FROM z3_data z3\n" + + "inner JOIN z2_counts z2c on z2c.wkfid = z3.wkfid \n" + + " WHERE z2c.z2_count = 1) aa\n" + + "WHERE wkfid = :wkfid and num = 1\n" + + ") cc inner join zwf0011t z11 on cc.wkfid = z11.wkfid", nativeQuery = true) + List nextTarget(@Param("wkfid") String wkfid); +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/repository/Zwf0013tRepository.java b/src/main/java/com/kospo/svcm/repository/Zwf0013tRepository.java new file mode 100644 index 0000000..7992713 --- /dev/null +++ b/src/main/java/com/kospo/svcm/repository/Zwf0013tRepository.java @@ -0,0 +1,14 @@ +package com.kospo.svcm.repository; + +import com.kospo.svcm.model.Zwf0013t; +import com.kospo.svcm.model.Zwf0013tId; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.List; + +public interface Zwf0013tRepository extends JpaRepository { + List findByIdWkfid(String WkfId); + + + Zwf0013t findByWkfsqAndIdWkfidAndIdBname(Integer wkfsq, String idWkfid, String idBname); +} \ No newline at end of file diff --git a/src/main/java/com/kospo/svcm/service/ApprService.java b/src/main/java/com/kospo/svcm/service/ApprService.java new file mode 100644 index 0000000..780996e --- /dev/null +++ b/src/main/java/com/kospo/svcm/service/ApprService.java @@ -0,0 +1,20 @@ +package com.kospo.svcm.service; + +import com.kospo.svcm.dto.req.ApprReqRequest; +import com.kospo.svcm.dto.res.ApprMstResponse; +import com.kospo.svcm.dto.res.ApprReqResponse; +import com.kospo.svcm.dto.res.PageResponse; +import com.kospo.svcm.repository.ApprReqRepository; +import jakarta.transaction.Transactional; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; + +import java.util.List; + +public interface ApprService { + ApprMstResponse findByPrcsNo(String prcsNo); + + PageResponse findByApprBySabun(String sabun, Pageable pageable) ; + + ApprMstResponse stateUpdate(String sabun, ApprReqRequest apprReqRequest); +} diff --git a/src/main/java/com/kospo/svcm/service/BusinessService.java b/src/main/java/com/kospo/svcm/service/BusinessService.java new file mode 100644 index 0000000..14c5dfc --- /dev/null +++ b/src/main/java/com/kospo/svcm/service/BusinessService.java @@ -0,0 +1,33 @@ +package com.kospo.svcm.service; + +import com.kospo.svcm.dto.req.BusinessRePasswdRequest; +import com.kospo.svcm.dto.req.BusinessUpdateRequest; +import com.kospo.svcm.dto.req.LoginRequest; +import com.kospo.svcm.dto.req.RegisterRequest; +import com.kospo.svcm.model.Business; +import com.kospo.svcm.dto.res.BusinessResponse; +import com.kospo.svcm.dto.res.LoginResponse; + +import java.util.List; + +public interface BusinessService { + LoginResponse login(LoginRequest loginDto, String ip); + + Boolean tokenValidate(String bizNo, String accessToken); + + Business findById(String id); + + BusinessResponse findMe(String id); + + List findAll(); + + BusinessResponse register(RegisterRequest registerRequest); + + BusinessResponse update(String bizNo, BusinessUpdateRequest businessRequest); + + BusinessResponse rePassword(String bizNo, BusinessRePasswdRequest businessRequest); + + void delete(String sessionBizNo, String bizNo); + + void privacy(); +} diff --git a/src/main/java/com/kospo/svcm/service/CodeService.java b/src/main/java/com/kospo/svcm/service/CodeService.java new file mode 100644 index 0000000..436083c --- /dev/null +++ b/src/main/java/com/kospo/svcm/service/CodeService.java @@ -0,0 +1,21 @@ +package com.kospo.svcm.service; + +import com.kospo.svcm.dto.req.CodeRequest; +import com.kospo.svcm.dto.res.CodeResponse; +import jakarta.transaction.Transactional; +import org.springframework.data.domain.Pageable; + +import java.util.List; + +public interface CodeService { + List findSearch(Boolean useYn, Pageable pageable); + + @Transactional + List findSpecificCode(int id); + + CodeResponse save(CodeRequest codeRequest); + + CodeResponse update(CodeRequest codeRequest); + + void delete(Integer id, String cd); +} diff --git a/src/main/java/com/kospo/svcm/service/ContService.java b/src/main/java/com/kospo/svcm/service/ContService.java new file mode 100644 index 0000000..b559bf3 --- /dev/null +++ b/src/main/java/com/kospo/svcm/service/ContService.java @@ -0,0 +1,21 @@ +package com.kospo.svcm.service; + +import com.kospo.svcm.dto.req.ContSaveRequest; +import com.kospo.svcm.dto.res.ContListResponse; +import com.kospo.svcm.dto.res.ContSaveResponse; +import jakarta.transaction.Transactional; +import org.springframework.data.domain.Pageable; + +import java.util.List; + +public interface ContService { + List findPage(String sabun, String contStatCd, String signSdt, String signEdt, Pageable pageable); + + @Transactional + ContSaveResponse findDetail(String contNo); + + ContSaveResponse save(ContSaveRequest contSaveRequest); + + @org.springframework.transaction.annotation.Transactional + ContSaveResponse retrieve(String contNo); +} diff --git a/src/main/java/com/kospo/svcm/service/DtlSpecService.java b/src/main/java/com/kospo/svcm/service/DtlSpecService.java new file mode 100644 index 0000000..b07c8ce --- /dev/null +++ b/src/main/java/com/kospo/svcm/service/DtlSpecService.java @@ -0,0 +1,10 @@ +package com.kospo.svcm.service; + +import com.kospo.svcm.dto.req.DtlSpecExcelRequest; +import com.kospo.svcm.dto.res.DtlSpecExcelResponse; + +import java.util.List; + +public interface DtlSpecService { + List excelConverter(DtlSpecExcelRequest dtlSpecExcelRequest); +} diff --git a/src/main/java/com/kospo/svcm/service/EstimateService.java b/src/main/java/com/kospo/svcm/service/EstimateService.java new file mode 100644 index 0000000..cad4ce1 --- /dev/null +++ b/src/main/java/com/kospo/svcm/service/EstimateService.java @@ -0,0 +1,24 @@ +package com.kospo.svcm.service; + +import com.kospo.svcm.dto.req.EstimateListSaveRequest; +import com.kospo.svcm.dto.req.EstimateListUpdateRequest; +import com.kospo.svcm.dto.res.EstimateListResponse; +import com.kospo.svcm.dto.res.EstimateResponse; +import com.kospo.svcm.model.PbAtt; +import jakarta.transaction.Transactional; + +import java.util.List; + +public interface EstimateService { + List findByBizNoAndPrcsNo(String bizNo, String prcsNo); + + @Transactional + EstimateListResponse save(EstimateListSaveRequest estimateListSaveRequest); + + @Transactional + EstimateListResponse update(String sabun, EstimateListUpdateRequest estimateListUpdateRequest); + + void pbAttFileDelete(String prcsNo, String bizNo, Integer fileOrd); + + PbAtt getPbAtt(String prcsNo, String bizNo, Integer fileOrd, String id); +} diff --git a/src/main/java/com/kospo/svcm/service/GrpCodeService.java b/src/main/java/com/kospo/svcm/service/GrpCodeService.java new file mode 100644 index 0000000..fabefeb --- /dev/null +++ b/src/main/java/com/kospo/svcm/service/GrpCodeService.java @@ -0,0 +1,21 @@ +package com.kospo.svcm.service; + +import com.kospo.svcm.dto.req.GrpCodeSaveRequest; +import com.kospo.svcm.dto.req.GrpCodeUpdateRequest; +import com.kospo.svcm.dto.res.GrpCodeResponse; +import com.kospo.svcm.dto.res.PageResponse; +import org.springframework.data.domain.Pageable; + +import java.util.List; + +public interface GrpCodeService { + PageResponse findSearch(String nm, Boolean useYn, Pageable pageable); + + List findSearch(String nm, Boolean useYn); + + GrpCodeResponse save(GrpCodeSaveRequest grpCodeDto); + + GrpCodeResponse update(GrpCodeUpdateRequest grpCodeRequest); + + void delete(Integer id); +} diff --git a/src/main/java/com/kospo/svcm/service/IntegratedApprService.java b/src/main/java/com/kospo/svcm/service/IntegratedApprService.java new file mode 100644 index 0000000..14a6262 --- /dev/null +++ b/src/main/java/com/kospo/svcm/service/IntegratedApprService.java @@ -0,0 +1,14 @@ +package com.kospo.svcm.service; + +import com.kospo.svcm.dto.res.PageResponse; +import com.kospo.svcm.repository.ApprReqRepository; +import jakarta.transaction.Transactional; +import org.springframework.data.domain.Pageable; + +import java.util.List; + +public interface IntegratedApprService { + PageResponse searchBySabun(String title, String apprStat, Pageable pageable); + + PageResponse searchList(String title, Pageable pageable); +} diff --git a/src/main/java/com/kospo/svcm/service/PrcsService.java b/src/main/java/com/kospo/svcm/service/PrcsService.java new file mode 100644 index 0000000..63abbe3 --- /dev/null +++ b/src/main/java/com/kospo/svcm/service/PrcsService.java @@ -0,0 +1,57 @@ +package com.kospo.svcm.service; + +import com.kospo.svcm.dto.req.PrcsSaveRequest; +import com.kospo.svcm.dto.req.PrcsUpdateRequest; +import com.kospo.svcm.dto.res.ContPrcsResponse; +import com.kospo.svcm.dto.res.PageResponse; +import com.kospo.svcm.dto.res.PrcsExternalResponse; +import com.kospo.svcm.dto.res.PrcsResponse; +import com.kospo.svcm.model.PrcsAtt; +import org.springframework.data.domain.Pageable; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; + +public interface PrcsService { + @Transactional + PrcsExternalResponse findOne(String bizNo, String prcsNo); + + List findSearch(String cateCd, String stCd, String regNm, String regSdt, String regEdt); + + @Transactional + List findContTarget(); + + PageResponse findSearch(String cateCd, String stCd, String regNm, String regSdt, String regEdt, Pageable pageable); + + @Transactional + PrcsResponse findDetail(String prcsNo); + + @Transactional + PageResponse findExternalSearch(String bizNo, String cateCd, String title, String regNm, String regSdt, String regEdt, Pageable pageable); + + @Transactional + PageResponse findExternalEstSearch(String bizNo, String title, String bidStatCd, String mngNm, Pageable pageable); + + @Transactional + int countReqByBizNo(String bizNo); + + @Transactional + PageResponse findContractSearch(String cateCd, String regNm, String regSdt, String regEdt, Pageable pageable); + + @Transactional + PageResponse findApprovalSearch(String sabun, String cateCd, String regNm, String regSdt, String regEdt, Pageable pageable); + + @Transactional + PrcsResponse save(PrcsSaveRequest prcsRequest); + + @Transactional + PrcsResponse update(String sabun, PrcsUpdateRequest prcsRequest); + + PrcsResponse retrieve(String prcsNo); + + void prcsAttFileDelete(String prcsNo, Integer fileOrd); + + PrcsResponse surveyUpdate(String sabun, String prcsNo); + + PrcsAtt getPrcsAtt(String prcsNo, Integer fileOrd, String id); +} diff --git a/src/main/java/com/kospo/svcm/service/RoleService.java b/src/main/java/com/kospo/svcm/service/RoleService.java new file mode 100644 index 0000000..3e35c5f --- /dev/null +++ b/src/main/java/com/kospo/svcm/service/RoleService.java @@ -0,0 +1,17 @@ +package com.kospo.svcm.service; + +import com.kospo.svcm.dto.req.RoleRequest; +import com.kospo.svcm.dto.res.RoleResponse; +import com.kospo.svcm.dto.res.UserResponse; + +import java.util.List; + +public interface RoleService { + List findByRoleId(String roleId); + + RoleResponse save(RoleRequest roleDto); + + void delete(RoleRequest roleDto); + + RoleResponse update(RoleRequest roleDto); +} diff --git a/src/main/java/com/kospo/svcm/service/SapService.java b/src/main/java/com/kospo/svcm/service/SapService.java new file mode 100644 index 0000000..2cd5001 --- /dev/null +++ b/src/main/java/com/kospo/svcm/service/SapService.java @@ -0,0 +1,26 @@ +package com.kospo.svcm.service; + +import com.kospo.svcm.dto.req.Zwf0011tSaveRequest; +import com.kospo.svcm.dto.req.ZwfApprUpdateRequest; +import com.kospo.svcm.dto.res.PageResponse; +import com.kospo.svcm.dto.res.Zwf0011tResponse; +import com.kospo.svcm.dto.res.ZwfApprResponse; +import jakarta.transaction.Transactional; +import org.springframework.data.domain.Pageable; + +import java.util.List; + +public interface SapService { + PageResponse findSearch(String wkfst, String ernam, String erSdat, String erEdat, Pageable pageable); + + @Transactional + PageResponse findSearchBySabun(String wkfst, String erSdat, String erEdat, Pageable pageable); + + @Transactional + Zwf0011tResponse getDetail(String wfkid); + + @Transactional + Zwf0011tResponse save(Zwf0011tSaveRequest zwf0011tSaveRequest); + + List approve(ZwfApprUpdateRequest zwfApprUpdateRequest); +} diff --git a/src/main/java/com/kospo/svcm/service/SlipService.java b/src/main/java/com/kospo/svcm/service/SlipService.java new file mode 100644 index 0000000..4db5c7b --- /dev/null +++ b/src/main/java/com/kospo/svcm/service/SlipService.java @@ -0,0 +1,16 @@ +package com.kospo.svcm.service; + +import com.kospo.svcm.dto.req.SlipSaveRequest; +import com.kospo.svcm.dto.res.SlipResponse; +import jakarta.transaction.Transactional; + +public interface SlipService { + @Transactional + SlipResponse findByContNo(String contNo); + + @Transactional + SlipResponse save(SlipSaveRequest slipSaveRequest); + + @Transactional + void delete(String contNo); +} diff --git a/src/main/java/com/kospo/svcm/service/UserService.java b/src/main/java/com/kospo/svcm/service/UserService.java new file mode 100644 index 0000000..335ac17 --- /dev/null +++ b/src/main/java/com/kospo/svcm/service/UserService.java @@ -0,0 +1,16 @@ +package com.kospo.svcm.service; + +import com.kospo.svcm.dto.res.UserSelectListResponse; +import com.kospo.svcm.model.User; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UsernameNotFoundException; + +import java.util.List; + +public interface UserService { + User findOne(String sabun); + + UserDetails loadUserByUsername(String sabun) throws UsernameNotFoundException; + + List findByNameContaining(String name); +} diff --git a/src/main/java/com/kospo/svcm/service/impl/ApprServiceImpl.java b/src/main/java/com/kospo/svcm/service/impl/ApprServiceImpl.java new file mode 100644 index 0000000..a4a87eb --- /dev/null +++ b/src/main/java/com/kospo/svcm/service/impl/ApprServiceImpl.java @@ -0,0 +1,179 @@ +package com.kospo.svcm.service.impl; + +import com.kospo.svcm.config.exception.ErrorCode; +import com.kospo.svcm.config.utils.CommonUtils; +import com.kospo.svcm.config.utils.MailUtils; +import com.kospo.svcm.dto.req.ApprReqRequest; +import com.kospo.svcm.dto.res.ApprMstResponse; +import com.kospo.svcm.dto.res.GrpCodeResponse; +import com.kospo.svcm.dto.res.PageResponse; +import com.kospo.svcm.exception.CustomException; +import com.kospo.svcm.exception.CustomMessageException; +import com.kospo.svcm.model.*; +import com.kospo.svcm.repository.*; +import com.kospo.svcm.service.ApprService; +import jakarta.transaction.Transactional; +import lombok.RequiredArgsConstructor; +import org.apache.poi.util.StringUtil; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.security.core.context.SecurityContext; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.stereotype.Service; + +import java.util.Date; +import java.util.List; + +@Service +@RequiredArgsConstructor +public class ApprServiceImpl implements ApprService { + private final ApprMstRepository apprMstRepository; + private final ApprReqRepository apprReqRepository; + private final CodeRepository codeRepository; + private final PrcsBizRepository prcsBizRepository; + private final UserRepository userRepository; + private final MailUtils mailUtils; + private final PrcsRepository prcsRepository; + + @Transactional + @Override + public ApprMstResponse findByPrcsNo(String prcsNo) { + ApprMstResponse apprMstResponse = ApprMstResponse.from(apprMstRepository.findByPrcsNo(prcsNo)); + apprMstResponse.getApprReqs().stream().forEach(apprReq -> { + User user = userRepository.findById(apprReq.getSabun()).get(); + apprReq.setAttendCd(user.getAttendCd()); + apprReq.setAttendNm(user.getAttendNm()); + apprReq.setAttendStaYmd(user.getAttendEndYmd()); + apprReq.setAttendEndYmd(user.getAttendEndYmd()); + }); + return apprMstResponse; + } + + @Transactional + @Override + public PageResponse findByApprBySabun(String sabun, Pageable pageable) { + Page p = apprReqRepository.findByApprBySabun(sabun, pageable); + return PageResponse.builder() + .totalPages(p.getTotalPages()) + .totalElements(p.getTotalElements()) + .content(p.getContent()) + .pageable(p.getPageable()) + .build(); + } + + @Transactional + @Override + public ApprMstResponse stateUpdate(String sabun, ApprReqRequest apprReqRequest) { + ApprReq checkerReq = apprReqRepository.findTopByIdApprNoAndApprStatCdOrderByIdApprOrdAsc(apprReqRequest.getApprNo(), "0000"); + if(!checkerReq.getSabun().equals(sabun)) throw new CustomMessageException(CustomMessageException.CusMessage.builder() + .code("999999") + .message("결재 대상이 아닙니다.") + .build()); + /* 결재 대기 상태 인지 확인 */ + if(!checkerReq.getApprStatCd().equals("0000")) throw new CustomMessageException(CustomMessageException.CusMessage.builder() + .code("999999") + .message("결재 대기 상태 또는 결재 진행상태 가 아닙니댜.") + .build()); + + ApprMst apprMst = checkerReq.getApprMst(); + Prcs prcs = apprMst.getPrcs(); + if(!prcs.getStCd().equals("0000") && !prcs.getStCd().equals("0100")) throw new CustomMessageException(CustomMessageException.CusMessage.builder() + .code("999999") + .message("결재 대기 상태 또는 결재 진행상태 가 아닙니댜.") + .build()); + + checkerReq.setApprStatCd(apprReqRequest.getApprStatCd()); + checkerReq.setApprStat(codeRepository.findById(CodeId.builder() + .cd(apprReqRequest.getApprStatCd()) + .id(2) + .build()).get().getNm()); + checkerReq.setApprDt(CommonUtils.dateFormat("yyyy-MM-dd HH:mm:ss")); + checkerReq = apprReqRepository.save(checkerReq); + + /*전결 처리를 위한 로직 시작*/ + List apprReqs = apprReqRepository.findByIdApprNoAndIdApprOrdGreaterThan(apprReqRequest.getApprNo(), apprReqRequest.getApprOrd()); + if(apprReqs.size() > 0) { + List result = apprReqs.stream().filter(apprReq -> StringUtil.isNotBlank(apprReq.getAttendCd())).toList(); + + /* 전결 대상자가 하나 이상 일시 오류 발생 */ + if(result.size() > 1) { + throw new CustomException(ErrorCode.PASS_APPR_TWO_PERSON); + } + + checkerReq = apprReqs.get(0); + if(checkerReq.getAttendCd() != null && StringUtil.isNotBlank(checkerReq.getAttendCd())) { + /*전결처리 로직*/ + checkerReq.setApprStatCd("0500"); + checkerReq.setApprStat(codeRepository.findById(CodeId.builder() + .cd("0500") + .id(2) + .build()).get().getNm()); + checkerReq.setApprDt(CommonUtils.dateFormat("yyyy-MM-dd HH:mm:ss")); + checkerReq = apprReqRepository.save(checkerReq); + } + } + + /*전결 처리를 위한 로직 종료*/ + + /*결재 마스터 갱신*/ + List apprMstReq = apprMst.getApprReqs(); + /* 전결재 승인 확인 */ + List complete = apprMstReq.stream().filter(req -> req.getApprStatCd().equals("0200") || req.getApprStatCd().equals("0500")|| req.getApprStatCd().equals("0600")).toList(); + /* 반려 상태 확인 */ + List reject = apprMstReq.stream().filter(req -> req.getApprStatCd().equals("0400")).toList(); + + /* 결재 상태 코드 (진행중) */ + String code = "0100"; + /*반려처리*/ + if(reject.size() > 0) { + code = "0400"; + apprMst.setReason(apprReqRequest.getReason()); + /*가격조사 반려 상태 변경 */ + prcs.setStCd("0400"); + prcs.setStNm(codeRepository.findById(CodeId.builder() + .cd("0400") + .id(1) + .build()).get().getNm()); + + prcsRepository.save(prcs); + } else if(complete.size() == apprMstReq.size()) { + code = "0200"; + prcs.getPrcsBizs().stream().forEach(prcsBiz -> { + Boolean sendYn = mailUtils.sendMail("nambu@kospo.co.kr", prcsBiz.getEmail(), "테스트", "테스트2"); + prcsBiz.setSendYn(sendYn); + prcsBizRepository.save(prcsBiz); + }); + + /*가격조사 등록완료 상태 변경 */ + prcs.setStCd("0200"); + prcs.setStNm(codeRepository.findById(CodeId.builder() + .cd("0200") + .id(1) + .build()).get().getNm()); + + prcsRepository.save(prcs); + + apprMst.setCompDt(CommonUtils.dateFormat("yyyy-MM-dd HH:mm:ss")); + } else { + /*가격조사 등록중 상태 변경 */ + prcs.setStCd("0100"); + prcs.setStNm(codeRepository.findById(CodeId.builder() + .cd("0100") + .id(1) + .build()).get().getNm()); + + prcsRepository.save(prcs); + + apprMst.setCompDt(CommonUtils.dateFormat("yyyy-MM-dd HH:mm:ss")); + } + + apprMst.setApprStatCd(code); + apprMst.setApprStat(codeRepository.findById(CodeId.builder() + .cd(code) + .id(2) + .build()).get().getNm()); + + ApprMst result = apprMstRepository.save(apprMst); + return ApprMstResponse.from(result); + } +} diff --git a/src/main/java/com/kospo/svcm/service/impl/BusinessServiceImpl.java b/src/main/java/com/kospo/svcm/service/impl/BusinessServiceImpl.java new file mode 100644 index 0000000..69ed9e6 --- /dev/null +++ b/src/main/java/com/kospo/svcm/service/impl/BusinessServiceImpl.java @@ -0,0 +1,227 @@ +package com.kospo.svcm.service.impl; + +import com.kospo.svcm.config.exception.ErrorCode; +import com.kospo.svcm.config.jwt.JwtUtil; +import com.kospo.svcm.config.security.PasswordEncoder; +import com.kospo.svcm.config.utils.CommonUtils; +import com.kospo.svcm.config.utils.SequenceUtils; +import com.kospo.svcm.dto.req.BusinessRePasswdRequest; +import com.kospo.svcm.dto.req.BusinessUpdateRequest; +import com.kospo.svcm.dto.req.LoginRequest; +import com.kospo.svcm.dto.req.RegisterRequest; +import com.kospo.svcm.exception.CustomException; +import com.kospo.svcm.model.*; +import com.kospo.svcm.dto.res.BusinessResponse; +import com.kospo.svcm.dto.res.LoginResponse; +import com.kospo.svcm.dto.res.TokenResponse; +import com.kospo.svcm.repository.BusinessRepository; +import com.kospo.svcm.repository.LoginHisRepository; +import com.kospo.svcm.repository.PvyPeriodRepository; +import com.kospo.svcm.service.BusinessService; +import jakarta.servlet.http.HttpServletRequest; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.util.StringUtils; + +import java.util.ArrayList; +import java.util.List; +import java.util.NoSuchElementException; +import java.util.Optional; + +@Service +@RequiredArgsConstructor +public class BusinessServiceImpl implements BusinessService { + private final BusinessRepository businessRepository; + private final LoginHisRepository loginHisRepository; + private final SequenceUtils sequenceUtils; + private final JwtUtil jwtUtil; + private final PvyPeriodRepository pvyPeriodRepository; + + @Override + public LoginResponse login(LoginRequest loginRequest, String ip) { + PasswordEncoder passwordEncoder = new PasswordEncoder(); + Optional optionalBusiness = businessRepository.findById(loginRequest.getBizNo()); + + if(optionalBusiness.isEmpty()) { + throw new CustomException(ErrorCode.NO_REGISTER); + } else { + + Business business = optionalBusiness.get(); + if(business.getState() == 'H') throw new CustomException(ErrorCode.SLEEP_ACCOUNT); + String hisNo = CommonUtils.getNo("HIS-", sequenceUtils.findSeqAfterUpdate("login_his_no")); + if (passwordEncoder.matches(loginRequest.getPwd(), business.getPassword())) { + TokenResponse tokenDto = jwtUtil.generateToken(business); + + business.setRefreshToken(tokenDto.getRefreshToken()); + businessRepository.save(business); + + loginHisRepository.save(LoginHis.builder() + .id(LoginHisId.builder() + .bizNo(loginRequest.getBizNo()) + .hisNo(hisNo) + .build()) + .ip(ip) + .connDt(CommonUtils.dateFormat("yyyy-MM-dd HH:mm:ss")) + .build()); + + return LoginResponse.builder() + .email(business.getEmail()) + .bizNo(business.getBizNo()) + .compNm(business.getCompNm()) + .repNm(business.getRepNm()) + .accessToken(tokenDto.getAccessToken()) + .accessTokenExpired(tokenDto.getAccessTokenExpired()).build(); + // modelMapper.createTypeMap(Users.class, UserDto.class); + // return modelMapper.map(getUser, UserDto.class); + } else { + throw new CustomException(ErrorCode.AUTHENTICATION); + } + } + + } + + @Override + public Boolean tokenValidate(String bizNo, String accessToken) { + Business business = businessRepository.findById(bizNo).get(); + return jwtUtil.validateToken(accessToken, business); + } + + @Override + public Business findById(String id) { + return businessRepository.findById(id).get(); + } + + @Override + public BusinessResponse findMe(String id) { + try { + Business business = businessRepository.findById(id).get(); + business.setPwd(null); + return BusinessResponse.from(business); + } catch(NoSuchElementException e) { + throw new CustomException(ErrorCode.NO_MATCH_ACCOUNT); + } + } + + @Override + public List findAll() { + return businessRepository.findAll().stream().map(business -> BusinessResponse.from(business)).toList(); + } + + @Override + public BusinessResponse register(RegisterRequest registerRequest) { + PasswordEncoder passwordEncoder = new PasswordEncoder(); + Optional checker = businessRepository.findById(registerRequest.getBizNo()); + if (checker.isPresent()) { + throw new CustomException(ErrorCode.ALREADY_REGISTER); + } + + if (!registerRequest.getPwd().equals(registerRequest.getRePwd())) { + throw new CustomException(ErrorCode.PWD_NOT_MATCH); + } + + Business business = businessRepository.save(Business.builder() + .bizNo(registerRequest.getBizNo()) + .pwd(passwordEncoder.sha256Encoding(registerRequest.getPwd())) + .compNm(registerRequest.getCompNm()) + .repNm(registerRequest.getRepNm()) + .email(registerRequest.getEmail()) + .state('C') + .build()); + + String agreeDt = CommonUtils.dateFormat("yyyy-MM-dd HH:mm:ss"); + pvyPeriodRepository.save(PvyPeriod.builder() + .id(PvyPeriodId.builder() + .bizNo(business.getBizNo()) + .agrDt(agreeDt) + .build()) + .expireDt(CommonUtils.stringToPlusYear(agreeDt, 1)) + .build()); + + return BusinessResponse.from(business); + } + + @Override + public BusinessResponse update(String bizNo, BusinessUpdateRequest businessRequest) { + Business checker = businessRepository.findById(businessRequest.getBizNo()).get(); + if (bizNo.equals(checker.getBizNo())) { + checker.setEmail(businessRequest.getEmail()); + checker.setCompNm(businessRequest.getCompNm()); + checker.setRepNm(businessRequest.getRepNm()); + return BusinessResponse.from(businessRepository.save(checker)); + } else { + throw new CustomException(ErrorCode.AUTHENTICATION); + } + } + + @Override + public BusinessResponse rePassword(String bizNo, BusinessRePasswdRequest businessRequest) { + PasswordEncoder passwordEncoder = new PasswordEncoder(); + Business checker = businessRepository.findById(businessRequest.getBizNo()).get(); + if (bizNo.equals(checker.getBizNo())) { + if (!checker.getPwd().equals(passwordEncoder.sha256Encoding(businessRequest.getOldPwd()))) { + throw new CustomException(ErrorCode.OLD_PWD_NOT_MATCH); + } + + if (!businessRequest.getPwd().equals(businessRequest.getRePwd())) { + throw new CustomException(ErrorCode.PWD_NOT_MATCH); + } + + checker.setPwd(passwordEncoder.sha256Encoding(businessRequest.getPwd())); + return BusinessResponse.from(businessRepository.save(checker)); + } else { + throw new CustomException(ErrorCode.AUTHENTICATION); + } + } + + @Override + public void delete(String sessionBizNo, String bizNo) { + Business checker = businessRepository.findById(bizNo).get(); + if(sessionBizNo.equalsIgnoreCase(checker.getBizNo())) { + businessRepository.deleteById(checker.getBizNo()); + } else { + throw new CustomException(ErrorCode.AUTHENTICATION); + } + } + + @Override + public void privacy() { + List lists = businessRepository.findByExpireDt(); + lists.stream().forEach(biz -> { + Business business = businessRepository.findById(biz.getBizNo()).get(); + business.setState('H'); + businessRepository.save(business); + }); + } + + public static String getClientIp(HttpServletRequest request) { + + String clientIp = null; + boolean isIpInHeader = false; + + List headerList = new ArrayList<>(); + headerList.add("X-Forwarded-For"); + headerList.add("HTTP_CLIENT_IP"); + headerList.add("HTTP_X_FORWARDED_FOR"); + headerList.add("HTTP_X_FORWARDED"); + headerList.add("HTTP_FORWARDED_FOR"); + headerList.add("HTTP_FORWARDED"); + headerList.add("Proxy-Client-IP"); + headerList.add("WL-Proxy-Client-IP"); + headerList.add("HTTP_VIA"); + headerList.add("IPV6_ADR"); + + for (String header : headerList) { + clientIp = request.getHeader(header); + if (StringUtils.hasText(clientIp) && !clientIp.equals("unknown")) { + isIpInHeader = true; // 각각의 헤더를 확인하여 유효한 IP 주소를 찾으면 해당 값을 반환하고 종료. + break; + } + } + + if (!isIpInHeader) { + clientIp = request.getRemoteAddr(); // 그렇지 않은 경우에는 request.getRemoteAddr()를 통해 기본적인 IP 주소를 얻기 + } + + return clientIp; + } +} diff --git a/src/main/java/com/kospo/svcm/service/impl/CodeServiceImpl.java b/src/main/java/com/kospo/svcm/service/impl/CodeServiceImpl.java new file mode 100644 index 0000000..f4b5e62 --- /dev/null +++ b/src/main/java/com/kospo/svcm/service/impl/CodeServiceImpl.java @@ -0,0 +1,69 @@ +package com.kospo.svcm.service.impl; + +import com.kospo.svcm.dto.req.CodeRequest; +import com.kospo.svcm.dto.res.CodeResponse; +import com.kospo.svcm.model.Code; +import com.kospo.svcm.model.CodeId; +import com.kospo.svcm.repository.CodeRepository; +import com.kospo.svcm.service.CodeService; +import jakarta.transaction.Transactional; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +@RequiredArgsConstructor +public class CodeServiceImpl implements CodeService { + private final CodeRepository codeRepository; + + @Override + @Transactional + public List findSearch(Boolean useYn, Pageable pageable) { + return codeRepository.findSearch(useYn, pageable).stream().map(CodeResponse::from).toList(); + } + + @Transactional + @Override + public List findSpecificCode(int id) { + return codeRepository.findByIdIdAndUseYn(id, true).stream().map(CodeResponse::from).toList(); + } + + @Override + public CodeResponse save(CodeRequest codeRequest) { + return CodeResponse.from(codeRepository.save(Code.builder() + .id(CodeId.builder() + .id(codeRequest.getId()) + .cd(codeRequest.getCd()) + .build()) + .nm(codeRequest.getNm()) + .desc(codeRequest.getDesc()) + .useYn(codeRequest.getUseYn()) + .build())); + } + + @Override + public CodeResponse update(CodeRequest codeRequest) { + Code code = codeRepository.findById( + CodeId.builder() + .id(codeRequest.getId()) + .cd(codeRequest.getCd()) + .build() + ).get(); + code.setDesc(codeRequest.getDesc()); + code.setNm(codeRequest.getNm()); + code.setUseYn(codeRequest.getUseYn()); + return CodeResponse.from(codeRepository.save(code)); + } + + @Override + public void delete(Integer id, String cd) { + codeRepository.deleteById( + CodeId.builder() + .id(id) + .cd(cd) + .build() + ); + } +} diff --git a/src/main/java/com/kospo/svcm/service/impl/ContServiceImpl.java b/src/main/java/com/kospo/svcm/service/impl/ContServiceImpl.java new file mode 100644 index 0000000..4916f3e --- /dev/null +++ b/src/main/java/com/kospo/svcm/service/impl/ContServiceImpl.java @@ -0,0 +1,166 @@ +package com.kospo.svcm.service.impl; + +import com.kospo.svcm.config.exception.ErrorCode; +import com.kospo.svcm.config.utils.CommonUtils; +import com.kospo.svcm.config.utils.SequenceUtils; +import com.kospo.svcm.dto.req.ContSaveRequest; +import com.kospo.svcm.dto.res.ContListResponse; +import com.kospo.svcm.dto.res.ContSaveResponse; +import com.kospo.svcm.exception.CustomException; +import com.kospo.svcm.exception.CustomMessageException; +import com.kospo.svcm.model.*; +import com.kospo.svcm.repository.*; +import com.kospo.svcm.service.ContService; +import lombok.RequiredArgsConstructor; +import org.apache.poi.util.StringUtil; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.data.domain.Pageable; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.Date; +import java.util.List; +import java.util.Optional; +import java.util.concurrent.atomic.AtomicInteger; + +@Service +@RequiredArgsConstructor +public class ContServiceImpl implements ContService { + private final ContAttRepository contAttRepository; + private final PrcsRepository prcsRepository; + private final EstimateRepository estimateRepository; + private final Zwf0011tRepository zwf0011tRepository; + private final SlipRepository slipRepository; + @Value("${server.attach}") + private String filePath; + private final ContRepository contRepository; + private final ContApprRepository contApprRepository; + private final CodeRepository codeRepository; + private final PrcsBizRepository prcsBizRepository; + private final SequenceUtils sequenceUtils; + + @Transactional + @Override + public List findPage(String sabun, String contStatCd, String signSdt, String signEdt, Pageable pageable) { + return contRepository.findBySearch(sabun, contStatCd, signSdt, signEdt, pageable).stream().map(ContListResponse::iFrom).toList(); + } + + @Transactional + @Override + public ContSaveResponse findDetail(String contNo) { + ContSaveResponse contSaveResponse = ContSaveResponse.from(contRepository.findById(contNo).get()); + ContAppr contAppr = contApprRepository.findByIdContNoOrderByIdTransactionKeyDesc(contNo) + .stream().findFirst().get(); + if(contAppr != null) contSaveResponse.setDocUrl(contAppr.getSignDoc().getDocUrl()); + + + return contSaveResponse; + } + + @Transactional + @Override + public ContSaveResponse save(ContSaveRequest contSaveRequest) { + Cont cont = contRepository.findByPrcsNo(contSaveRequest.getPrcsNo()); + if(cont == null) { + User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); + Prcs prcs = prcsRepository.findByPrcsNoAndRegSabun(contSaveRequest.getPrcsNo(), user.getSabun()); + Date now = new Date(); + + if(prcs != null) { + if(!prcs.getSvyYn()) throw new CustomException(ErrorCode.No_SVY_NOT_EXECUTE); + } else { + if(!contSaveRequest.isExcYn() || StringUtil.isBlank(contSaveRequest.getReason())) throw new CustomMessageException(CustomMessageException.CusMessage.builder() + .code("999999") + .message("가격조사를 안했을 시 예외 사유는 필수 입니다.") + .build()); + } + + String contNo = CommonUtils.getDateNo("CONT-", sequenceUtils.findSeqAfterUpdate("cont_no")); + + String contStatCd = "0000"; + AtomicInteger fileOrd = new AtomicInteger(0); + + List estimates = estimateRepository.findByBizNoAndPrcsNo(contSaveRequest.getBizNo(), contSaveRequest.getPrcsNo()); + Integer sum = estimates.stream().map(estimate -> estimate.getAmt()).reduce(0, Integer::sum); + + cont = contRepository.save(Cont.builder() + .contNo(contNo) + .prcsNo(contSaveRequest.getPrcsNo()) + .bizNo(contSaveRequest.getBizNo()) + .title(contSaveRequest.getTitle()) + .compNm(contSaveRequest.getCompNm()) + .signDt(CommonUtils.dateFormat("yyyy-MM-dd")) + .contAmt(sum) + .contSdat(contSaveRequest.getContSdat()) + .contEdat(contSaveRequest.getContEdat()) + .contStatCd(contStatCd) + .contStat(codeRepository.findById(CodeId.builder() + .id(3) + .cd(contStatCd) + .build()).get().getNm()) + .regSabun(user.getSabun()) + .regNm(user.getName()) + .regDt(CommonUtils.dateFormat("yyyy-MM-dd HH:mm:ss")) + .excYn(contSaveRequest.isExcYn()) + .reason(contSaveRequest.getReason()) + .build()); + + if(contSaveRequest.getContAtts() != null && contSaveRequest.getContAtts().size() > 0){ + cont.setContAtts(contAttRepository.saveAll(contSaveRequest.getContAtts().stream().map(contAttSaveRequest -> { + String pNm = CommonUtils.dateFormat("yyyyMMddHHmmssSSS"); + return ContAtt.builder() + .id(ContAttId.builder() + .contNo(contNo) + .fileOrd(fileOrd.incrementAndGet()) + .build() + ) + .logiFnm(contAttSaveRequest.getLogiFnm()) + .physFnm(pNm) + .size(contAttSaveRequest.getData().length()) + .path(filePath + pNm) + .build(); + }).toList())); + } + + /* 전체 업체 유찰 처리 */ + prcsBizRepository.updatePrcsBizByEstStatCd(contSaveRequest.getPrcsNo(), "0400"); + /* 특정 업체 낙찰 처리 */ + prcsBizRepository.updatePrcsBizByEstStatCd(contSaveRequest.getPrcsNo(), contSaveRequest.getBizNo(), "0300"); + return ContSaveResponse.from(cont); + + } else { + throw new CustomException(ErrorCode.SAME_DATA); + } + } + + @Transactional + @Override + public ContSaveResponse retrieve(String contNo) { + User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); + Optional optionalCont = contRepository.findById(contNo); + if(optionalCont.isEmpty()) throw new CustomException(ErrorCode.FIND_ERR); + Cont cont = optionalCont.get(); + if(!cont.getRegSabun().equals(user.getSabun())) throw new CustomException(ErrorCode.AUTHENTICATION_NOT_SUPPORT); + Slip slip = slipRepository.findByContNo(contNo); + if(slip == null) throw new CustomException(ErrorCode.FIND_ERR); + /*임시 전표 삭제 로직 시작*/ + + /*임시 전표 삭제 로직 종료*/ + + Zwf0011t zwf0011t = zwf0011tRepository.findByObkey(slip.getBelnr()+ slip.getGjahr() + "1000"); + if(zwf0011t == null) throw new CustomException(ErrorCode.FIND_ERR); + + zwf0011t.setWkfst("C"); + zwf0011tRepository.save(zwf0011t); + + cont.setContStatCd("0600"); + cont.setContStat(codeRepository.findById(CodeId.builder() + .id(3) + .cd("0600") + .build()).get().getDesc()); + + return ContSaveResponse.from(contRepository.save(cont)); + } + +} diff --git a/src/main/java/com/kospo/svcm/service/impl/DtlSpecServiceImpl.java b/src/main/java/com/kospo/svcm/service/impl/DtlSpecServiceImpl.java new file mode 100644 index 0000000..c2526e3 --- /dev/null +++ b/src/main/java/com/kospo/svcm/service/impl/DtlSpecServiceImpl.java @@ -0,0 +1,21 @@ +package com.kospo.svcm.service.impl; + +import com.kospo.svcm.config.utils.ExcelUtils; +import com.kospo.svcm.dto.req.DtlSpecExcelRequest; +import com.kospo.svcm.dto.res.DtlSpecExcelResponse; +import com.kospo.svcm.service.DtlSpecService; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +@RequiredArgsConstructor +public class DtlSpecServiceImpl implements DtlSpecService { + private final ExcelUtils excelUtils; + + @Override + public List excelConverter(DtlSpecExcelRequest dtlSpecExcelRequest) { + return excelUtils.dtlSpecExcel(dtlSpecExcelRequest.getData()); + } +} diff --git a/src/main/java/com/kospo/svcm/service/impl/EstimateServiceImpl.java b/src/main/java/com/kospo/svcm/service/impl/EstimateServiceImpl.java new file mode 100644 index 0000000..2db87a4 --- /dev/null +++ b/src/main/java/com/kospo/svcm/service/impl/EstimateServiceImpl.java @@ -0,0 +1,248 @@ +package com.kospo.svcm.service.impl; + +import com.kospo.svcm.config.exception.ErrorCode; +import com.kospo.svcm.config.utils.CommonUtils; +import com.kospo.svcm.config.utils.FileUtils; +import com.kospo.svcm.config.utils.SequenceUtils; +import com.kospo.svcm.dto.req.EstimateListSaveRequest; +import com.kospo.svcm.dto.req.EstimateListUpdateRequest; +import com.kospo.svcm.dto.res.EstimateListResponse; +import com.kospo.svcm.dto.res.EstimateResponse; +import com.kospo.svcm.dto.res.PbAttResponse; +import com.kospo.svcm.exception.CustomException; +import com.kospo.svcm.model.*; +import com.kospo.svcm.repository.*; +import com.kospo.svcm.service.EstimateService; +import jakarta.transaction.Transactional; +import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.stereotype.Service; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; + +@Service +@RequiredArgsConstructor +public class EstimateServiceImpl implements EstimateService { + private final PrcsRepository prcsRepository; + @Value("${server.attach}") + private String filePath; + private final EstimateRepository bidRepository; + private final PrcsBizRepository prcsBizRepository; + private final CodeRepository codeRepository; + private final SequenceUtils sequenceUtils; + private final PbAttRepository pbAttRepository; + private final FileUtils fileUtils; + + + @Transactional + @Override + public List findByBizNoAndPrcsNo(String bizNo, String prcsNo) { + return bidRepository.findByBizNoAndPrcsNo(bizNo, prcsNo).stream().map(EstimateResponse::from).toList(); + } + + @Transactional + @Override + public EstimateListResponse save(EstimateListSaveRequest bidListSaveRequest) { + Business business = (Business) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); + + List bids = new ArrayList<>(); + + /*입찰사업자 투찰 상태로 변경*/ + PrcsBiz prcsBiz = prcsBizRepository.findById(PrcsBizId.builder() + .prcsNo(bidListSaveRequest.getEstimates().get(0).getPrcsNo()) + .bizNo(business.getBizNo()) + .build()).get(); + prcsBiz.setEstStatCd("0100"); + prcsBiz.setEstStat(codeRepository.findById(CodeId.builder() + .id(4) + .cd("0100") + .build()).get().getNm()); + prcsBizRepository.save(prcsBiz); + + bidListSaveRequest.getEstimates().stream().forEach((bidRequest) -> { + String estNo = CommonUtils.getNo("EST-", sequenceUtils.findSeqAfterUpdate("est_no")); + Estimate bid = bidRepository.save(Estimate.builder() + .estNo(estNo) + .bizNo(bidRequest.getBizNo()) + .prcsNo(bidRequest.getPrcsNo()) + .dtlSpNo(bidRequest.getDtlSpNo()) + .mngNm(bidRequest.getMngNm()) + .unitPrc(bidRequest.getUnitPrc()) + .amt(bidRequest.getAmt()) + .regDt(CommonUtils.dateFormat("yyyy-MM-dd HH:mm:ss")) + .build()); + + bids.add(bid); + + }); + List pbAtts = null; + AtomicInteger fileOrd= new AtomicInteger(0); + if (bidListSaveRequest.getPbAtts() != null && bidListSaveRequest.getPbAtts().size() > 0) { + pbAtts = pbAttRepository.saveAll(bidListSaveRequest.getPbAtts().stream().filter(pbAttSaveRequest -> { + if(!CommonUtils.checkAllowExt(pbAttSaveRequest.getLogiFnm())) throw new CustomException(ErrorCode.FILE_EXT_UPLOAD_ERROR); + String pnm = CommonUtils.dateFormat("yyyyMMddHHmmssSSS"); + pbAttSaveRequest.setPhysFnm(pnm); + return fileUtils.fileUpload(filePath + pnm, pbAttSaveRequest.getData()); + }).map((pbAttSaveRequest) -> { + try { + return PbAtt.builder() + .id(PbAttId.builder() + .bizNo(prcsBiz.getId().getBizNo()) + .prcsNo(prcsBiz.getId().getPrcsNo()) + .fileOrd(fileOrd.incrementAndGet()) + .build()) + .logiFnm(pbAttSaveRequest.getLogiFnm()) + .physFnm(pbAttSaveRequest.getPhysFnm()) + .size((int) Files.size(Path.of(filePath + pbAttSaveRequest.getPhysFnm()))) + .path(filePath + pbAttSaveRequest.getPhysFnm()) + .build(); + } catch (IOException e) { + throw new RuntimeException(e); + } + }).toList()); + } + + if(pbAtts == null) throw new CustomException(ErrorCode.FILE_REQUIRED); + + return EstimateListResponse.builder() + .estimates(bids.stream().map(EstimateResponse::from).toList()) + .pbAtts(pbAtts == null ? null : pbAtts.stream().map(PbAttResponse::from).toList()).build(); + } + + @Transactional + @Override + public EstimateListResponse update(String bizNo, EstimateListUpdateRequest estimateListUpdateRequest) { + List bids = new ArrayList<>(); + + estimateListUpdateRequest.getEstimates().stream().forEach((bidRequest) -> { + String estNo = ""; + if (bidRequest.getEstNo() != null) { + Estimate bid = bidRepository.findById(bidRequest.getEstNo()).get(); + bid.setMngNm(bidRequest.getMngNm()); + bid.setUnitPrc(bidRequest.getUnitPrc()); + bid.setAmt(bidRequest.getAmt()); + estNo = bidRequest.getEstNo(); + bids.add(bidRepository.save(bid)); + } else { + estNo = CommonUtils.getNo("EST-", sequenceUtils.findSeqAfterUpdate("est_no")); + bids.add(Estimate.builder() + .estNo(estNo) + .bizNo(bidRequest.getBizNo()) + .prcsNo(bidRequest.getPrcsNo()) + .dtlSpNo(bidRequest.getDtlSpNo()) + .mngNm(bidRequest.getMngNm()) + .unitPrc(bidRequest.getUnitPrc()) + .amt(bidRequest.getAmt()) + .regDt(CommonUtils.dateFormat("yyyy-MM-dd HH:mm:ss")) + .build() + ); + } + }); + + AtomicInteger fileOrd = null; + try { + fileOrd = new AtomicInteger(estimateListUpdateRequest.getPbAtts().stream().mapToInt(pbAtt -> pbAtt.getFileOrd() == null ? 0 : pbAtt.getFileOrd()).max().getAsInt()); + } catch (Exception e) { + fileOrd = new AtomicInteger(0); + } + List pbAtts = new ArrayList<>(); + AtomicInteger finalFileOrd = fileOrd; + estimateListUpdateRequest.getPbAtts().stream().forEach(pbAttUpdateRequest -> { + if(pbAttUpdateRequest.getBizNo() == null) { + if(!CommonUtils.checkAllowExt(pbAttUpdateRequest.getLogiFnm())) throw new CustomException(ErrorCode.FILE_EXT_UPLOAD_ERROR); + String pnm = CommonUtils.dateFormat("yyyyMMddHHmmssSSS"); + if (fileUtils.fileUpload(filePath + pnm, pbAttUpdateRequest.getData())) { + try { + pbAtts.add(pbAttRepository.save(PbAtt.builder() + .id(PbAttId.builder() + .fileOrd(finalFileOrd.incrementAndGet()) + .prcsNo(pbAttUpdateRequest.getPrcsNo()) + .bizNo(bizNo) + .build()) + .logiFnm(pbAttUpdateRequest.getLogiFnm()) + .size((int) Files.size(Path.of(filePath + pnm))) + .path(filePath + pnm) + .physFnm(pnm) + .build())); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + } + }); + + return EstimateListResponse.builder() + .estimates(bids.stream().map(EstimateResponse::from).toList()) + .pbAtts(pbAtts.stream().map(PbAttResponse::from).toList()).build(); + } + + @Override + public void pbAttFileDelete(String prcsNo, String bizNo, Integer fileOrd) { + PbAtt pbAtt = pbAttRepository.findById(PbAttId.builder() + .prcsNo(prcsNo) + .bizNo(bizNo) + .fileOrd(fileOrd) + .build()).get(); + if(fileUtils.fileDelete(pbAtt.getPath())) { + pbAttRepository.delete(pbAtt); + } else { + throw new CustomException(ErrorCode.FILE_DELETE_ERROR); + } + } + + @Override + public PbAtt getPbAtt(String prcsNo, String bizNo, Integer fileOrd, String id) { + if(id != null && !id.isEmpty()) { + if(id.contains("-")) { + PrcsBiz prcsBiz = prcsBizRepository.findById(PrcsBizId.builder() + .prcsNo(prcsNo) + .bizNo(id) + .build()).get(); + if(prcsBiz == null) { + throw new CustomException(ErrorCode.AUTHENTICATION_NOT_SUPPORT); + } + } else { + Prcs prcs = prcsRepository.findByPrcsNoAndRegSabun(prcsNo, id); + if(prcs == null) { + throw new CustomException(ErrorCode.AUTHENTICATION_NOT_SUPPORT); + } + } + } else { + throw new CustomException(ErrorCode.AUTHENTICATION_NOT_SUPPORT); + } + PbAtt pbAtt = pbAttRepository.findById(PbAttId.builder() + .prcsNo(prcsNo) + .bizNo(bizNo) + .fileOrd(fileOrd) + .build()).get(); + return pbAtt; + } + +// @Override +// public void bidFileDelete(String estNo, Integer fileOrd) { +// BidDoc bidDoc = bidDocRepository.findById(BidDocId.builder() +// .estNo(estNo) +// .fileOrd(fileOrd) +// .build()).get(); +// if(fileUtils.fileDelete(bidDoc.getPath())) { +// bidDocRepository.delete(bidDoc); +// } else { +// throw new CustomException(ErrorCode.EXCEL_UPLOAD_ERROR); +// } +// } +// +// @Override +// public BidDoc getBidDoc(String estNo, Integer fileOrd) { +// BidDoc bidDoc = bidDocRepository.findById(BidDocId.builder() +// .estNo(estNo) +// .fileOrd(fileOrd) +// .build()).get(); +// return bidDoc; +// } +} diff --git a/src/main/java/com/kospo/svcm/service/impl/GrpCodeServiceImpl.java b/src/main/java/com/kospo/svcm/service/impl/GrpCodeServiceImpl.java new file mode 100644 index 0000000..7ba5811 --- /dev/null +++ b/src/main/java/com/kospo/svcm/service/impl/GrpCodeServiceImpl.java @@ -0,0 +1,67 @@ +package com.kospo.svcm.service.impl; + +import com.kospo.svcm.dto.req.GrpCodeSaveRequest; +import com.kospo.svcm.dto.req.GrpCodeUpdateRequest; +import com.kospo.svcm.dto.res.GrpCodeResponse; +import com.kospo.svcm.dto.res.PageResponse; +import com.kospo.svcm.model.Code; +import com.kospo.svcm.model.GrpCode; +import com.kospo.svcm.repository.GrpCodeRepository; +import com.kospo.svcm.service.GrpCodeService; +import jakarta.transaction.Transactional; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +@RequiredArgsConstructor +public class GrpCodeServiceImpl implements GrpCodeService { + private final GrpCodeRepository grpCodeRepository; + + @Override + @Transactional + public PageResponse findSearch(String nm, Boolean useYn, Pageable pageable) { + Page codes = grpCodeRepository.findSearchPage(nm, useYn, pageable); + return PageResponse.builder() + .totalPages(codes.getTotalPages()) + .totalElements(codes.getTotalElements()) + .content(codes.getContent().stream().map(GrpCodeResponse::from).toList()) + .pageable(codes.getPageable()) + .build(); + } + + @Transactional + @Override + public List findSearch(String nm, Boolean useYn) { + return grpCodeRepository.findSearch(nm, useYn).stream().map(GrpCodeResponse::from).toList(); + } + + @Override + public GrpCodeResponse save(GrpCodeSaveRequest grpCodeRequest) { + return GrpCodeResponse.from(grpCodeRepository.save(GrpCode.builder() + .nm(grpCodeRequest.getNm()) + .desc(grpCodeRequest.getDesc()) + .useYn(true) + .build())); + } + + @Override + @Transactional + public GrpCodeResponse update(GrpCodeUpdateRequest grpCodeRequest) { + GrpCode grpCode = grpCodeRepository.findById(grpCodeRequest.getId()).get(); + List codes = grpCode.getCodes(); + System.out.println(codes); + grpCode.setDesc(grpCodeRequest.getDesc()); + grpCode.setNm(grpCodeRequest.getNm()); + grpCode.setUseYn(grpCodeRequest.getUseYn()); + return GrpCodeResponse.from(grpCodeRepository.save(grpCode)); + } + + @Override + public void delete(Integer id) { + grpCodeRepository.deleteById(id); + } +} diff --git a/src/main/java/com/kospo/svcm/service/impl/IntegratedApprServiceImpl.java b/src/main/java/com/kospo/svcm/service/impl/IntegratedApprServiceImpl.java new file mode 100644 index 0000000..6147069 --- /dev/null +++ b/src/main/java/com/kospo/svcm/service/impl/IntegratedApprServiceImpl.java @@ -0,0 +1,54 @@ +package com.kospo.svcm.service.impl; + +import com.kospo.svcm.dto.res.PageResponse; +import com.kospo.svcm.model.User; +import com.kospo.svcm.repository.ApprReqRepository; +import com.kospo.svcm.service.IntegratedApprService; +import jakarta.transaction.Transactional; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.stereotype.Service; + +import java.util.Collection; +import java.util.List; + +@Service +@RequiredArgsConstructor +public class IntegratedApprServiceImpl implements IntegratedApprService { + private final ApprReqRepository apprReqRepository; + + @Transactional + @Override + public PageResponse searchBySabun(String title, String apprStat, Pageable pageable) { + User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); + Page p = apprReqRepository.igtFindhBySabun(user.getSabun(), title, apprStat, pageable); + return PageResponse.builder() + .totalPages(p.getTotalPages()) + .totalElements(p.getTotalElements()) + .content(p.getContent()) + .pageable(p.getPageable()) + .build(); + } + + @Transactional + @Override + public PageResponse searchList(String title, Pageable pageable) { + User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); + List auths = (List)user.getAuthorities(); + Page p = null; + if(auths.stream().anyMatch(auth -> auth.getAuthority().equals("ROLE_ADMIN"))) { + p = apprReqRepository.igtFindAll(title, pageable); + } else { + p =apprReqRepository.igtFindByDeptCd(user.getDeptCd(), title, pageable); + } + return PageResponse.builder() + .totalPages(p.getTotalPages()) + .totalElements(p.getTotalElements()) + .content(p.getContent()) + .pageable(p.getPageable()) + .build(); + } +} diff --git a/src/main/java/com/kospo/svcm/service/impl/PrcsServiceImpl.java b/src/main/java/com/kospo/svcm/service/impl/PrcsServiceImpl.java new file mode 100644 index 0000000..8234ae3 --- /dev/null +++ b/src/main/java/com/kospo/svcm/service/impl/PrcsServiceImpl.java @@ -0,0 +1,654 @@ +package com.kospo.svcm.service.impl; + +import com.kospo.svcm.config.exception.ErrorCode; +import com.kospo.svcm.config.utils.CommonUtils; +import com.kospo.svcm.config.utils.FileUtils; +import com.kospo.svcm.config.utils.MailUtils; +import com.kospo.svcm.config.utils.SequenceUtils; +import com.kospo.svcm.dto.req.PrcsSaveRequest; +import com.kospo.svcm.dto.req.PrcsUpdateRequest; +import com.kospo.svcm.dto.res.*; +import com.kospo.svcm.exception.CustomException; +import com.kospo.svcm.exception.CustomMessageException; +import com.kospo.svcm.model.*; +import com.kospo.svcm.repository.*; +import com.kospo.svcm.service.PrcsService; +import lombok.RequiredArgsConstructor; +import org.apache.poi.util.StringUtil; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.stream.IntStream; + +@Service +@RequiredArgsConstructor +public class PrcsServiceImpl implements PrcsService { + private final PrcsRepository prcsRepository; + private final PrcsAttRepository prcsAttRepository; + private final PrcsBizRepository prcsBizRepository; + private final DtlSpecRepository dtlSpecRepository; + private final ApprMstRepository apprMstRepository; + private final ApprReqRepository apprReqRepository; + private final CodeRepository codeRepository; + private final EstimateRepository estimateRepository; + private final FileUtils fileUtils; + private final MailUtils mailUtils; + private final SequenceUtils sequenceUtils; + private final UserRepository userRepository; + @Value("${server.attach}") + private String filePath; + + @Transactional + @Override + public PrcsExternalResponse findOne(String bizNo, String prcsNo) { + Prcs prcs = prcsRepository.findOne(bizNo, prcsNo); + PrcsExternalResponse prcsExternalResponse = PrcsExternalResponse.from(prcs); + prcsExternalResponse.setDtlSpecs(prcsExternalResponse.getDtlSpecs().stream().map(dtlSpec -> { + dtlSpec.setEstimate(EstimateResponse.from(estimateRepository.findByBizNoAndPrcsNoAndDtlSpNo(bizNo, prcsNo, dtlSpec.getDtlSpNo()))); + return dtlSpec; + }).toList()); + PrcsBiz pb = prcsBizRepository.findById(PrcsBizId.builder() + .prcsNo(prcs.getPrcsNo()) + .bizNo(bizNo) + .build()).get(); + prcsExternalResponse.setEstStat(pb.getEstStat()); + prcsExternalResponse.setEstStatCd(pb.getEstStatCd()); + prcsExternalResponse.setPbAtts(pb.getPbAtts().stream().map(PbAttResponse::from).toList()); + return prcsExternalResponse; + } + + @Override + @Transactional + public List findSearch(String cateCd, String stCd, String regNm, String regSdt, String regEdt) { + return prcsRepository.findSearch(cateCd, stCd, regNm, regSdt, regEdt).stream().map(PrcsResponse::from).toList(); + } + + @Transactional + @Override + public List findContTarget() { + User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); + return prcsRepository.findContTarget(user.getSabun()).stream().map(cont -> { + ContPrcsResponse contPrcsResponse = ContPrcsResponse.from(cont); + contPrcsResponse.setEstimates( + estimateRepository.findByPrcsNo(cont.getPrcsNo()) + .stream().map(EstimateContResponse::from).toList() + ); + return contPrcsResponse; + }).toList(); + } + + @Override + @Transactional + public PageResponse findSearch(String cateCd, String stCd, String regNm, String regSdt, String regEdt, Pageable pageable) { + User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); + AtomicBoolean isAdmin = new AtomicBoolean(false); + user.getAuthorities().stream().forEach(auth -> { + if(auth.getAuthority().equals("ROLE_ADMIN")) isAdmin.set(true); + }); + + Page prcsPage = null; + if(isAdmin.get()) { + prcsPage = prcsRepository.findSearch(cateCd, stCd, regNm, regSdt, regEdt, pageable); + } else { + prcsPage = prcsRepository.findSearch(user.getDeptCd(), cateCd, stCd, regNm, regSdt, regEdt, pageable); + } + return PageResponse.builder() + .totalPages(prcsPage.getTotalPages()) + .totalElements(prcsPage.getTotalElements()) + .pageable(prcsPage.getPageable()) + .content(prcsPage.getContent().stream().map(PrcsListResponse::from).toList()) + .build(); + } + + @Transactional + @Override + public PrcsResponse findDetail(String prcsNo) { + Optional optionalPrcs = prcsRepository.findById(prcsNo); + if(optionalPrcs.isPresent()) { + return PrcsResponse.from(optionalPrcs.get()); + } else { + throw new CustomException(ErrorCode.FIND_ERR); + } + } + + @Transactional + @Override + public PageResponse findExternalSearch(String bizNo, String cateCd, String title, String regNm, String regSdt, String regEdt, Pageable pageable) { + Page prcsPage = prcsRepository.findExternalSearch(bizNo, cateCd, title, regNm, regSdt, regEdt, pageable); + return PageResponse.builder() + .totalPages(prcsPage.getTotalPages()) + .totalElements(prcsPage.getTotalElements()) + .pageable(prcsPage.getPageable()) + .content(prcsPage.getContent().stream().map(PrcsExternalResponse::from).toList()) + .build(); + } + + @Transactional + @Override + public PageResponse findExternalEstSearch(String bizNo, String title, String bidStatCd, String mngNm, Pageable pageable) { + Page prcsPage = prcsRepository.findEstList(bizNo, title, bidStatCd, mngNm, pageable); + return PageResponse.builder() + .totalPages(prcsPage.getTotalPages()) + .totalElements(prcsPage.getTotalElements()) + .pageable(prcsPage.getPageable()) + .content(prcsPage.getContent()) + .build(); + } + + + @Transactional + @Override + public int countReqByBizNo(String bizNo) { + return prcsBizRepository.countReqByBizNo(bizNo); + } + + @Transactional + @Override + public PageResponse findContractSearch(String cateCd, String regNm, String regSdt, String regEdt, Pageable pageable) { + Page prcsPage = prcsRepository.findContractSearch(cateCd, regNm, regSdt, regEdt, pageable); + return PageResponse.builder() + .totalPages(prcsPage.getTotalPages()) + .totalElements(prcsPage.getTotalElements()) + .pageable(prcsPage.getPageable()) + .content(prcsPage.getContent().stream().map(PrcsExternalResponse::from).toList()) + .build(); + } + + @Transactional + @Override + public PageResponse findApprovalSearch(String sabun, String cateCd, String regNm, String regSdt, String regEdt, Pageable pageable) { + Page prcsPage = prcsRepository.findApprSearch(sabun, cateCd, regNm, regSdt, regEdt, pageable); + return PageResponse.builder() + .totalPages(prcsPage.getTotalPages()) + .totalElements(prcsPage.getTotalElements()) + .pageable(prcsPage.getPageable()) + .content(prcsPage.getContent().stream().map(PrcsExternalResponse::from).toList()) + .build(); + } + + @Transactional + @Override + public PrcsResponse save(PrcsSaveRequest prcsRequest) { + User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); + String prcsNo = CommonUtils.getDateNo("PRCS-", sequenceUtils.findSeqAfterUpdate("prcs_no")); + String apprNo = CommonUtils.getNo("APPR-", sequenceUtils.findSeqAfterUpdate("appr_no")); + AtomicInteger fileOrd = new AtomicInteger(0); + AtomicInteger apprOrd = new AtomicInteger(0); + String apprCodeCd = "0000"; + /*결재상태코드*/ + List apprCodes = codeRepository.findByIdId(2); + List attendCodes = codeRepository.findByIdId(6); + List gubunCodes = codeRepository.findByIdId(7); + List estStatCodes = codeRepository.findByIdId(4); + String regDt = CommonUtils.dateFormat("yyyy-MM-dd HH:mm:ss"); + + Prcs prcs = prcsRepository.save( + Prcs.builder() + .prcsNo(prcsNo) + .cateCd(prcsRequest.getCateCd()) + .cateNm(codeRepository.findById(CodeId.builder() + .id(5) + .cd(prcsRequest.getCateCd()) + .build()).get().getNm()) + .title(prcsRequest.getTitle()) + .content(prcsRequest.getContent()) + .regSdat(prcsRequest.getRegSdat()) + .regEdat(prcsRequest.getRegEdat()) + .prvYn(prcsRequest.getPrvYn()) + .prvRsn(prcsRequest.getPrvRsn()) + .prvPwd(prcsRequest.getPrvPwd()) + .aiYn(prcsRequest.getAiYn()) + .regSabun(user.getSabun()) + .regNm(user.getName()) + .regDt(regDt) + .stCd(apprCodeCd) /*등록전*/ + .stNm(codeRepository.findById(CodeId.builder() + .id(1) + .cd(apprCodeCd) + .build()).get().getNm()) + .svyYn(false) + .svyDt("") + .build() + ); + + + /*견적 저장*/ + List dtlSpecs = null; + if(prcsRequest.getDtlSpecs() != null && prcsRequest.getDtlSpecs().size() > 0) { + dtlSpecs = dtlSpecRepository.saveAll(prcsRequest.getDtlSpecs().stream().map((spec) -> { + String dtlNo = CommonUtils.getNo("DTL-", sequenceUtils.findSeqAfterUpdate("dtl_sp_no")); + return DtlSpec.builder() + .id(DtlSpecId.builder() + .prcsNo(prcsNo) + .dtlSpNo(dtlNo) + .build()) + .spec(spec.getSpec()) + .qty(spec.getQty()) + .unit(spec.getUnit()) + .itemNm(spec.getItemNm()) + .build(); + }).toList()); + } else { + throw new CustomMessageException(CustomMessageException.CusMessage.builder() + .code("999999") + .message("상세규격은 필수 입니다.") + .build()); + } + + + /*첨부파일 저장*/ + List prcsAtts = null; + if (prcsRequest.getPrcsAtts() != null && prcsRequest.getPrcsAtts().size() > 0) { + prcsAtts = prcsAttRepository.saveAll(prcsRequest.getPrcsAtts().stream().map(att -> { + if(!CommonUtils.checkAllowExt(att.getLogiFnm())) throw new CustomException(ErrorCode.FILE_EXT_UPLOAD_ERROR); + String pNm = CommonUtils.dateFormat("yyyyMMddHHmmssSSS"); + fileUtils.fileUpload(filePath + pNm, att.getData()); + try { + return PrcsAtt.builder() + .id( + PrcsAttId.builder() + .fileOrd(fileOrd.incrementAndGet()) + .prcsNo(prcsNo) + .build() + ) + .logiFnm(att.getLogiFnm()) + .physFnm(pNm) + .size((int) Files.size(Path.of(filePath + pNm))) + .path(filePath + pNm) + .build(); + } catch (IOException e) { + throw new RuntimeException(e); + } + }).toList()); + } + + /* 결재 마스터 저장*/ + ApprMst apprMst = null; + List apprReqs = null; + if(prcsRequest.getApprReqs() != null && prcsRequest.getApprReqs().size() > 0) { + apprMst = apprMstRepository.save(ApprMst.builder() + .apprNo(apprNo) + .prcsNo(prcsNo) + .apprStatCd(apprCodeCd) + .apprStat(CommonUtils.getCodeNm(apprCodes, apprCodeCd)) + .regDt(regDt) + .regSabun(user.getSabun()) + .build()); + /* 결재선 저장 */ + apprReqs = apprReqRepository.saveAll(prcsRequest.getApprReqs().stream().map(apprReq -> { + User apprUser = userRepository.findById(apprReq.getSabun()).get(); + String deptCd = apprUser.getDept().getDeptCd(); + String deptNm = apprUser.getDept().getDeptNm(); + return ApprReq.builder() + .id( + ApprReqId.builder() + .apprNo(apprNo) + .apprOrd(apprOrd.incrementAndGet()) + .build() + ) + .sabun(apprReq.getSabun()) + .name(apprReq.getName()) + .apprDt("") + .apprStatCd(apprReq.getSabun().equals(user.getSabun()) ? "0200" : apprCodeCd) + .apprStat(apprReq.getSabun().equals(user.getSabun()) ? CommonUtils.getCodeNm(apprCodes, "0200") : CommonUtils.getCodeNm(apprCodes, apprCodeCd)) + .gubunCd(apprReq.getGubunCd()) + .gubunNm(StringUtil.isBlank(apprReq.getGubunCd()) ? "입안" : CommonUtils.getCodeNm(gubunCodes, apprReq.getGubunCd())) + .attendCd(StringUtil.isBlank(apprReq.getAttendCd()) ? "" : apprReq.getAttendCd()) + .attendNm(StringUtil.isBlank(apprReq.getAttendCd()) ? "재중" : CommonUtils.getCodeNm(attendCodes, apprReq.getAttendCd())) + .deptCd(deptCd) + .deptNm(deptNm) + .build(); + } + ).toList()); + } else { + throw new CustomMessageException(CustomMessageException.CusMessage.builder() + .code("999999") + .message("결재는 필수 입니다.") + .build()); + } + + + /*메일 전송 로직 영역 시작*/ + List prcsBizs = null; + if(prcsRequest.getPrcsBizs() != null && prcsRequest.getPrcsBizs().size() > 0) { + prcsBizs = prcsBizRepository.saveAll(prcsRequest.getPrcsBizs().stream().map(prcsBizSaveReq -> { + return PrcsBiz.builder() + .id(PrcsBizId.builder() + .prcsNo(prcsNo) + .bizNo(prcsBizSaveReq.getBizNo()) + .build()) + .email(prcsBizSaveReq.getEmail()) + .sendYn(false) + .estStatCd("0000") /*입찰 상태코드*/ + .estStat(CommonUtils.getCodeNm(estStatCodes, "0000")) + .build(); + }).toList()); + + } else { + throw new CustomMessageException(CustomMessageException.CusMessage.builder() + .code("999999") + .message("참여 사업자는 필수 입니다.") + .build()); + } + + /*메일 전송 로직 영역 종료*/ + + apprMst.setApprReqs(apprReqs); + + prcs.setPrcsAtts(prcsAtts); + prcs.setDtlSpecs(dtlSpecs); + prcs.setApprMst(apprMst); + prcs.setPrcsBizs(prcsBizs); + + return PrcsResponse.from(prcs); + + } + + + @Transactional + @Override + public PrcsResponse update(String sabun, PrcsUpdateRequest prcsRequest) { + + Prcs getPrcs = prcsRepository.findById(prcsRequest.getPrcsNo()).get(); + /* 본인 글인지 확인 */ + if (!getPrcs.getRegSabun().equals(sabun)) throw new CustomException(ErrorCode.AUTHENTICATION_NOT_SUPPORT); + /* 결재 완료된 상태 견적 받는 상태 */ + if(!getPrcs.getStCd().equals("0000")) throw new CustomException(ErrorCode.APPR_LOCK); + if(getPrcs.getSvyYn()) throw new CustomException(ErrorCode.APPR_SVY_ERR); + + AtomicInteger apprOrd = new AtomicInteger(0); + String apprCodeCd = "0000"; + /*결재상태코드*/ + List apprCodes = codeRepository.findByIdId(2); + List attendCodes = codeRepository.findByIdId(6); + List gubunCodes = codeRepository.findByIdId(7); + List estStatCodes = codeRepository.findByIdId(4); + + /*가격조사 갱신*/ + getPrcs.setCateCd(prcsRequest.getCateCd()); + getPrcs.setCateNm(codeRepository.findById(CodeId.builder() + .id(5) + .cd(prcsRequest.getCateCd()) + .build()).get().getNm()); + getPrcs.setTitle(prcsRequest.getTitle()); + getPrcs.setContent(prcsRequest.getContent()); + getPrcs.setRegSdat(prcsRequest.getRegSdat()); + getPrcs.setRegEdat(prcsRequest.getRegEdat()); + getPrcs.setPrvYn(prcsRequest.getPrvYn()); + getPrcs.setPrvRsn(prcsRequest.getPrvRsn()); + getPrcs.setPrvPwd(prcsRequest.getPrvPwd()); + getPrcs.setAiYn(prcsRequest.getAiYn()); + + + /*첨부파일 갱신*/ + List prcsAttList = new ArrayList<>(); + List prcsAtts = prcsRequest.getPrcsAtts(); + if (prcsAtts != null && prcsAtts.size() > 0) { + IntStream.range(0, prcsAtts.size()).forEach(idx -> { + PrcsUpdateRequest.PrcsAttUpdateRequest prcsAttRequest = prcsAtts.get(idx); + if (prcsAttRequest.getData() == null) { + PrcsAtt getPrcsAtt = prcsAttRepository.findById(PrcsAttId.builder() + .prcsNo(prcsAttRequest.getPrcsNo()) + .fileOrd(prcsAttRequest.getFileOrd()) + .build()).get(); + prcsAttList.add(getPrcsAtt); + } else { + if(!CommonUtils.checkAllowExt(prcsAttRequest.getLogiFnm())) throw new CustomException(ErrorCode.FILE_EXT_UPLOAD_ERROR); + String pnm = CommonUtils.dateFormat("yyyyMMddHHmmssSSS"); + if (fileUtils.fileUpload(filePath + pnm, prcsAttRequest.getData())) { + try { + PrcsAtt.builder() + .id(PrcsAttId.builder() + .prcsNo(prcsAttRequest.getPrcsNo()) + .fileOrd(idx) + .build() + ) + .logiFnm(prcsAttRequest.getLogiFnm()) + .physFnm(pnm) + .size((int) Files.size(Path.of(filePath + pnm))) + .path(filePath + pnm) + .build(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + } + }); + } + + /*결재선 갱신*/ + List apprReqs = new ArrayList<>(); + ApprMst getApprMst = apprMstRepository.findByPrcsNo(prcsRequest.getPrcsNo()); + + IntStream.range(0, prcsRequest.getApprReqs().size()).forEach(idx -> { + PrcsUpdateRequest.ApprReqUpdateRequest apprReqRequest = prcsRequest.getApprReqs().get(idx); + + User apprUser = userRepository.findById(apprReqRequest.getSabun()).get(); + if (apprReqRequest.getApprNo() != null) { + ApprReq apprReq = apprReqRepository.findById(ApprReqId.builder() + .apprOrd(apprReqRequest.getApprOrd()) + .apprNo(getApprMst.getApprNo()) + .build()).get(); + apprReq.setName(apprReqRequest.getName()); + apprReq.setSabun(apprReqRequest.getSabun()); + apprReq.setAttendCd(apprReqRequest.getAttendCd()); + apprReq.setAttendNm(StringUtil.isBlank(apprReqRequest.getAttendCd()) ? "재중" : CommonUtils.getCodeNm(attendCodes, apprReqRequest.getAttendCd())); + apprReq.setGubunCd(apprReqRequest.getGubunCd()); + apprReq.setGubunNm(StringUtil.isBlank(apprReqRequest.getGubunCd()) ? "입안" : CommonUtils.getCodeNm(gubunCodes, apprReqRequest.getGubunCd())); + apprReq.setDeptCd(apprUser.getDept().getDeptCd()); + apprReq.setDeptNm(apprUser.getDept().getDeptNm()); + apprReqs.add(apprReq); + apprOrd.incrementAndGet(); + } else { + apprReqs.add(ApprReq.builder() + .id(ApprReqId.builder() + .apprNo(getApprMst.getApprNo()) + .apprOrd(apprOrd.incrementAndGet()) + .build()) + .sabun(apprReqRequest.getSabun()) + .name(apprReqRequest.getName()) + .apprDt("") + .apprStatCd(apprCodeCd) + .apprStat(CommonUtils.getCodeNm(apprCodes, apprCodeCd)) + .gubunCd(apprReqRequest.getGubunCd()) + .gubunNm(CommonUtils.getCodeNm(gubunCodes, apprReqRequest.getGubunCd())) + .attendCd(apprReqRequest.getAttendCd()) + .attendNm(CommonUtils.getCodeNm(attendCodes, apprReqRequest.getAttendCd())) + .deptCd(apprUser.getDept().getDeptCd()) + .deptNm(apprUser.getDept().getDeptNm()) + .build()); + } + }); + + getApprMst.setApprReqs(apprReqs); + + /*상세규격 갱신*/ + List dtlSpecs = new ArrayList<>(); + IntStream.range(0, prcsRequest.getDtlSpecs().size()).forEach(idx -> { + PrcsUpdateRequest.DtlSpecUpdateRequest dtlSpecRequest = prcsRequest.getDtlSpecs().get(idx); + if (dtlSpecRequest.getDtlSpNo() != null) { + DtlSpec dtlSpec = dtlSpecRepository.findById(DtlSpecId.builder() + .prcsNo(prcsRequest.getPrcsNo()) + .dtlSpNo(dtlSpecRequest.getDtlSpNo()) + .build()).get(); + dtlSpec.setSpec(dtlSpecRequest.getSpec()); + dtlSpec.setItemNm(dtlSpecRequest.getItemNm()); + dtlSpec.setUnit(dtlSpecRequest.getUnit()); + dtlSpec.setQty(dtlSpecRequest.getQty()); + dtlSpecs.add(dtlSpec); + } else { + String dtlNo = CommonUtils.getNo("DTL-", sequenceUtils.findSeqAfterUpdate("dtl_sp_no")); + dtlSpecs.add(DtlSpec.builder() + .id(DtlSpecId.builder() + .prcsNo(prcsRequest.getPrcsNo()) + .dtlSpNo(dtlNo) + .build()) + .itemNm(dtlSpecRequest.getItemNm()) + .qty(dtlSpecRequest.getQty()) + .spec(dtlSpecRequest.getSpec()) + .unit(dtlSpecRequest.getUnit()) + .build()); + } + }); + + /*입찰사업자 갱신*/ + List prcsBizs = new ArrayList<>(); + IntStream.range(0, prcsRequest.getPrcsBizs().size()).forEach(idx -> { + PrcsUpdateRequest.PrcsBizUpdateRequest prcsBizUpdateRequest = prcsRequest.getPrcsBizs().get(idx); + Optional optionalPrcsBiz = prcsBizRepository.findById(PrcsBizId.builder() + .prcsNo(prcsRequest.getPrcsNo()) + .bizNo(prcsBizUpdateRequest.getBizNo()) + .build()); + if (!optionalPrcsBiz.isEmpty()) { + PrcsBiz prcsBiz = optionalPrcsBiz.get(); + Boolean sendYn = prcsBiz.getSendYn(); + // if (!prcsBiz.getSendYn()) { + // mailUtils.sendMail("nambu@kospo.co.kr", prcsBizUpdateRequest.getEmail(), "테스트", "테스트2"); + // } + prcsBiz.setEmail(prcsBizUpdateRequest.getEmail()); + prcsBiz.setSendYn(false); + prcsBizs.add(prcsBiz); + } else { + // Boolean sendYn = mailUtils.sendMail("nambu@kospo.co.kr", prcsBizUpdateRequest.getEmail(), "테스트", "테스트2"); + prcsBizs.add(PrcsBiz.builder() + .id(PrcsBizId.builder() + .prcsNo(prcsRequest.getPrcsNo()) + .bizNo(prcsBizUpdateRequest.getBizNo()) + .build()) + .email(prcsBizUpdateRequest.getEmail()) + .sendYn(false) + .estStatCd("0000") + .estStat(CommonUtils.getCodeNm(estStatCodes, "0000")) + .build()); + } + }); + + + getPrcs.setPrcsAtts(prcsAttRepository.saveAll(prcsAttList)); + getPrcs.setDtlSpecs(dtlSpecRepository.saveAll(dtlSpecs)); + getApprMst.setApprReqs(apprReqRepository.saveAll(apprReqs)); + getPrcs.setApprMst(getApprMst); + getPrcs.setPrcsBizs(prcsBizRepository.saveAll(prcsBizs)); + + + Prcs savePrcs = prcsRepository.save(getPrcs); + return PrcsResponse.from(savePrcs); + } + + @Transactional + @Override + public PrcsResponse retrieve(String prcsNo) { + User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); + Optional optionalPrcs = prcsRepository.findById(prcsNo); + if(optionalPrcs.isEmpty()) throw new CustomException(ErrorCode.FIND_ERR); + Prcs prcs = optionalPrcs.get(); + if(!prcs.getRegSabun().equals(user.getSabun())) throw new CustomException(ErrorCode.AUTHENTICATION_NOT_SUPPORT); + + ApprMst apprMst = apprMstRepository.findByPrcsNo(prcsNo); + apprMst.setApprStatCd("0300"); + apprMst.setApprStat(codeRepository.findById(CodeId.builder() + .cd("0300") + .id(2) + .build()).get().getNm()); + apprMst.setCompDt(CommonUtils.dateFormat("yyyy-MM-dd HH:mm:ss")); + + prcs.setStCd("0300"); + prcs.setStNm(codeRepository.findById(CodeId.builder() + .cd("0300") + .id(1) + .build()).get().getNm()); + + /*통합결재 처리*/ + + return PrcsResponse.from(prcsRepository.save(prcs)); + } + + @Override + public void prcsAttFileDelete(String prcsNo, Integer fileOrd) { + User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); + Prcs checker = prcsRepository.findByPrcsNoAndRegSabun(prcsNo, user.getSabun()); + if(checker != null) { + PrcsAtt prcsAtt = prcsAttRepository.findById(PrcsAttId.builder() + .prcsNo(prcsNo) + .fileOrd(fileOrd) + .build()).get(); + if (fileUtils.fileDelete(prcsAtt.getPath())) { + prcsAttRepository.delete(prcsAtt); + } else { + throw new CustomException(ErrorCode.FILE_DELETE_ERROR); + } + } else { + throw new CustomException(ErrorCode.AUTHENTICATION_NOT_SUPPORT); + } + + } + + @Transactional + @Override + public PrcsResponse surveyUpdate(String sabun, String prcsNo) { + Prcs checker = prcsRepository.findByPrcsNoAndRegSabun(prcsNo, sabun); + + if(checker != null) { + ApprMst apprMst = checker.getApprMst(); + if(apprMst.getApprStatCd().equals("0200")) { + checker.setSvyYn(true); + checker.setSvyDt(CommonUtils.dateFormat("yyyy-MM-dd HH:mm:ss")); + checker.setStCd("0200"); + checker.setStNm(codeRepository.findById(CodeId.builder() + .cd("0200") + .id(1) + .build()).get().getNm()); + + /* 견적 상태 코드 변경 0200(조사진행중) */ + prcsBizRepository.updatePrcsBizByEstStatCd(prcsNo, "0200"); + + prcsRepository.save(checker); + } else { + throw new CustomException(ErrorCode.APPR_SVY_ERR); + } + return PrcsResponse.from(checker); + } else { + throw new CustomException(ErrorCode.AUTHENTICATION_NOT_SUPPORT); + } + } + + @Override + public PrcsAtt getPrcsAtt(String prcsNo, Integer fileOrd, String id) { + if(id != null && !id.isEmpty()) { + if(id.contains("-")) { + PrcsBiz prcsBiz = prcsBizRepository.findById(PrcsBizId.builder() + .prcsNo(prcsNo) + .bizNo(id) + .build()).get(); + if(prcsBiz == null) { + throw new CustomException(ErrorCode.AUTHENTICATION_NOT_SUPPORT); + } + } else { + Prcs prcs = prcsRepository.findByPrcsNoAndRegSabun(prcsNo, id); + if(prcs == null) { + throw new CustomException(ErrorCode.AUTHENTICATION_NOT_SUPPORT); + } + } + } else { + throw new CustomException(ErrorCode.AUTHENTICATION_NOT_SUPPORT); + } + PrcsAtt prcsAtt = prcsAttRepository.findById(PrcsAttId.builder() + .prcsNo(prcsNo) + .fileOrd(fileOrd) + .build()).get(); + return prcsAtt; + } + +} diff --git a/src/main/java/com/kospo/svcm/service/impl/RoleServiceImpl.java b/src/main/java/com/kospo/svcm/service/impl/RoleServiceImpl.java new file mode 100644 index 0000000..6fdea2d --- /dev/null +++ b/src/main/java/com/kospo/svcm/service/impl/RoleServiceImpl.java @@ -0,0 +1,86 @@ +package com.kospo.svcm.service.impl; + +import com.kospo.svcm.config.exception.ErrorCode; +import com.kospo.svcm.config.utils.CommonUtils; +import com.kospo.svcm.dto.req.RoleRequest; +import com.kospo.svcm.dto.res.RoleResponse; +import com.kospo.svcm.dto.res.UserResponse; +import com.kospo.svcm.exception.CustomException; +import com.kospo.svcm.model.Role; +import com.kospo.svcm.model.RoleId; +import com.kospo.svcm.model.User; +import com.kospo.svcm.repository.RoleRepository; +import com.kospo.svcm.repository.UserRepository; +import com.kospo.svcm.service.RoleService; +import lombok.RequiredArgsConstructor; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +@RequiredArgsConstructor +public class RoleServiceImpl implements RoleService { + private final RoleRepository roleRepository; + private final UserRepository userRepository; + + @Override + public List findByRoleId(String roleId) { + try { + return roleRepository.findByIdRoleId(roleId).stream().map(role -> + UserResponse.from(userRepository.findBySabun(role.getId().getSabun())) + ).toList(); + } catch(Exception e) { + throw new CustomException(ErrorCode.FIND_ERR); + } + + } + + @Override + public RoleResponse save(RoleRequest roleRequest) { + User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); + try { + return RoleResponse.from(roleRepository.save( + Role.builder() + .roleNm("관리자") + .ip(roleRequest.getIp()) + .id(RoleId.builder() + .roleId(roleRequest.getRoleId()) + .sabun(roleRequest.getSabun()).build()) + .regSabun(user.getSabun()) + .regNm(user.getName()) + .regDt(CommonUtils.dateFormat("yyyy-MM-dd HH:mm:ss")) + .build() + )); + } catch(Exception e) { + throw new CustomException(ErrorCode.SAVE_ERR); + } + } + + @Override + public void delete(RoleRequest roleRequest) { + try { + roleRepository.deleteById(RoleId.builder() + .roleId(roleRequest.getRoleId()) + .sabun(roleRequest.getSabun()).build()); + } catch(Exception e) { + throw new CustomException(ErrorCode.DEL_ERR); + } + + } + + @Override + public RoleResponse update(RoleRequest roleRequest) { + try { + RoleId roleId = RoleId.builder() + .roleId(roleRequest.getRoleId()) + .sabun(roleRequest.getSabun()).build(); + Role current = roleRepository.findById(roleId).get(); + current.setIp(roleRequest.getIp()); + return RoleResponse.from(roleRepository.save(current)); + } catch(Exception e) { + throw new CustomException(ErrorCode.UPD_ERR); + } + + } +} diff --git a/src/main/java/com/kospo/svcm/service/impl/SapServiceImpl.java b/src/main/java/com/kospo/svcm/service/impl/SapServiceImpl.java new file mode 100644 index 0000000..744f315 --- /dev/null +++ b/src/main/java/com/kospo/svcm/service/impl/SapServiceImpl.java @@ -0,0 +1,385 @@ +package com.kospo.svcm.service.impl; + +import com.kospo.svcm.config.exception.ErrorCode; +import com.kospo.svcm.config.utils.CommonUtils; +import com.kospo.svcm.config.utils.SequenceUtils; +import com.kospo.svcm.dto.req.Zwf0011tSaveRequest; +import com.kospo.svcm.dto.req.ZwfApprUpdateRequest; +import com.kospo.svcm.dto.res.*; +import com.kospo.svcm.exception.CustomException; +import com.kospo.svcm.exception.CustomMessageException; +import com.kospo.svcm.model.*; +import com.kospo.svcm.repository.*; +import com.kospo.svcm.service.SapService; +import jakarta.transaction.Transactional; +import lombok.RequiredArgsConstructor; +import org.apache.poi.util.StringUtil; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Optional; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; +import java.util.stream.Collectors; + +@Service +@RequiredArgsConstructor +public class SapServiceImpl implements SapService { + private final Zwf0011tRepository zwf0011tRepository; + private final Zwf0012tRepository zwf0012tRepository; + private final Zwf0013tRepository zwf0013tRepository; + private final SequenceUtils sequenceUtils; + private final UserRepository userRepository; + private final ContRepository contRepository; + private final SlipRepository slipRepository; + private final CodeRepository codeRepository; + + @Transactional + @Override + public PageResponse findSearch(String wkfst, String ernam, String erSdat, String erEdat, Pageable pageable) { + Page p = zwf0011tRepository.findSearch(wkfst, ernam, erSdat.replace("-", ""), erEdat.replace("-", ""), pageable); + return PageResponse.builder() + .totalPages(p.getTotalPages()) + .totalElements(p.getTotalElements()) + .content(p.getContent().stream().map(Zwf0011tResponse::to).toList()) + .pageable(p.getPageable()) + .build(); + } + + @Transactional + @Override + public PageResponse findSearchBySabun(String wkfst, String erSdat, String erEdat, Pageable pageable) { + User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); + Page p = zwf0011tRepository.findSearchBySabun(user.getSabun(), wkfst, erSdat.replace("-", ""), erEdat.replace("-", ""), pageable); + return PageResponse.builder() + .totalPages(p.getTotalPages()) + .totalElements(p.getTotalElements()) + .content(p.getContent().stream().map(Zwf0011tResponse::to).toList()) + .pageable(p.getPageable()) + .build(); + } + + @Transactional + @Override + public Zwf0011tResponse getDetail(String wfkid) { + User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); + Zwf0011t zwf0011t = zwf0011tRepository.findByIdWkfid(wfkid); + + if (user.getSabun().equals(zwf0011t.getErnam())) { + Zwf0011tResponse zwf0011tResponse = Zwf0011tResponse.to(zwf0011t); + List mergeList = new ArrayList<>(); + List zwf0012ts = zwf0012tRepository.findByIdWkfid(zwf0011t.getId().getWkfid()); + /* 12T 테이블에 있는 입안자 검토자만 주입 */ + + mergeList.add(ZwfApprGrpResponse.builder() + .label("결재") + .value(zwf0012ts.stream().map(Zwf0012tResponse::to).collect(Collectors.toUnmodifiableList())) + .build()); + + /* 13T 테이블 조회 주입*/ + List zwf0013ts = zwf0013tRepository.findByIdWkfid(zwf0011t.getId().getWkfid()); + int groupIdx = zwf0013ts.stream().mapToInt(z -> z.getGrpid()).max().orElse(0); + for (int i = 1; i < groupIdx + 1; i++) { + int finalI = i; + mergeList.add(ZwfApprGrpResponse.builder() + .label("협조") + .value(zwf0013ts.stream().filter(z -> z.getGrpid() == finalI).map(Zwf0013tResponse::to).collect(Collectors.toUnmodifiableList())) + .build()); + } + zwf0011tResponse.setApprs(mergeList); + return zwf0011tResponse; + } else { + throw new CustomException(ErrorCode.AUTHENTICATION_NOT_SUPPORT); + } + } + + @Transactional + @Override + public Zwf0011tResponse save(Zwf0011tSaveRequest zwf0011tSaveRequest) { + AtomicReference wkfid = new AtomicReference<>(CommonUtils.getSapNo(sequenceUtils.findSeqAfterUpdate("sap_appr"))); + User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); + String ernam = user.getSabun(); + String erdat = CommonUtils.dateFormat("yyyyMMdd"); + String erzet = CommonUtils.dateFormat("HHmmss"); + AtomicReference label = new AtomicReference<>(""); + + AtomicReference zwf0011tResponse = new AtomicReference<>(); + if(StringUtil.isBlank(zwf0011tSaveRequest.getWkfid())) { + zwf0011tResponse.set(Zwf0011tResponse.to(zwf0011tRepository.save(Zwf0011t.builder() + .id(Zwf0011tId.builder() + .wkfid(wkfid.get()) + .catag("095") + .build()) + .obkey(CommonUtils.getEstNo(zwf0011tSaveRequest.getBelnr())) + .wkfst("Q") + .wkftx(zwf0011tSaveRequest.getWkftx()) + .ernam(ernam) + .erdat(erdat) + .erzet(erzet) + .build()))); + } else { + zwf0011tResponse.set(Zwf0011tResponse.to(zwf0011tRepository.findById(Zwf0011tId.builder() + .catag("095") + .wkfid(zwf0011tSaveRequest.getWkfid()) + .build()).get())); + } + + + List mergeList = new ArrayList<>(); + + AtomicInteger sq = new AtomicInteger(1); + zwf0011tSaveRequest.getApprs().stream().forEach(z -> { + label.set(z.getLabel()); + if (z.getLabel().equals("결재")) { + AtomicInteger eSq = new AtomicInteger(1); + z.getValue().stream().forEach(zwfAppr -> { + Optional userOptional = userRepository.findById(zwfAppr.getBname()); + if (userOptional.isEmpty()) throw new CustomException(ErrorCode.AUTHENTICATION_NOT_SUPPORT); + + if (zwfAppr.getLineclsf().equals("E")) { + mergeList.add(zwf0013tRepository.save(Zwf0013t.builder() + .id(Zwf0013tId.builder() + .wkfid(wkfid.get()) + .gubun("I") + .bname(userOptional.get().getSabun()) + .build()) + .lineclsf(zwfAppr.getLineclsf()) + .abscd(zwfAppr.getAbscd()) + .btext(userOptional.get().getName()) + .posit(userOptional.get().getGradeNm()) + .deptn(userOptional.get().getPtsnNm()) + .wkfst(zwfAppr.getLineclsf().equals("Q") ? "Q" : "I") + .wkfsq(eSq.get()) + .ernam(ernam) + .erdat(erdat) + .erzet(erzet) + .wkfsq1(2) + .grpid(eSq.getAndIncrement()) + .build())); + } else { + mergeList.add(zwf0012tRepository.save(Zwf0012t.builder() + .id(Zwf0012tId.builder() + .wkfid(wkfid.get()) + .wkfsq(sq.getAndIncrement()) + .build()) + .lineclsf(zwfAppr.getLineclsf()) + .abscd(zwfAppr.getAbscd()) + .bname(userOptional.get().getSabun()) + .btext(userOptional.get().getName()) + .posit(userOptional.get().getGradeNm()) + .deptn(userOptional.get().getPtsnNm()) + .wkfst(zwfAppr.getLineclsf().equals("Q") ? "Q" : "I") + .ernam(ernam) + .erdat(erdat) + .erzet(erzet) + .build())); + } + }); + } else if(z.getLabel().equals("협조")) { + wkfid.set(zwf0011tSaveRequest.getWkfid()); + AtomicInteger eSq = new AtomicInteger(1); + + z.getValue().stream().forEach(zwfAppr -> { + Optional userOptional = userRepository.findById(zwfAppr.getBname()); + if (userOptional.isEmpty()) throw new CustomException(ErrorCode.AUTHENTICATION_NOT_SUPPORT); + if(zwfAppr.getLineclsf().equals("Q")) { + /* 협조 결재자 -> 신규 결재 입안자로 변경 */ + Optional zwf0013tOptional = zwf0013tRepository.findById(Zwf0013tId.builder() + .wkfid(wkfid.get()) + .gubun("I") + .bname(userOptional.get().getSabun()) + .build()); + + if(zwf0013tOptional.isEmpty()) throw new CustomException(ErrorCode.AUTHENTICATION_NOT_SUPPORT); + + Zwf0013t zwf0013t = zwf0013tOptional.get(); + zwf0013t.setLineclsf(zwfAppr.getLineclsf()); + + zwf0013t.setErnam(ernam); + zwf0013t.setErdat(erdat); + zwf0013t.setErzet(erzet); + + zwf0013t.setAenam(ernam); + zwf0013t.setAedat(erdat); + zwf0013t.setAezet(erzet); + + zwf0013t.setWkfst("A"); + zwf0013t.setWkfsq(eSq.getAndIncrement()); + mergeList.add(zwf0013tRepository.save(zwf0013t)); + } else { + mergeList.add(zwf0013tRepository.save(Zwf0013t.builder() + .id(Zwf0013tId.builder() + .wkfid(wkfid.get()) + .gubun("I") + .bname(userOptional.get().getSabun()) + .build()) + .lineclsf(zwfAppr.getLineclsf()) + .abscd(zwfAppr.getAbscd()) + .btext(userOptional.get().getName()) + .posit(userOptional.get().getGradeNm()) + .deptn(userOptional.get().getPtsnNm()) + .wkfst(zwfAppr.getLineclsf().equals("Q") ? "A" : "I") + .wkfsq(eSq.getAndIncrement()) + .ernam(ernam) + .erdat(erdat) + .erzet(erzet) + .wkfsq1(0) + .grpid(zwfAppr.getGrpid()) + .build())); + } + }); + } + }); + + zwf0011tResponse.get().setApprs(Arrays.asList(ZwfApprGrpResponse.builder() + .label(label.get()) + .value(mergeList) + .build())); + + return zwf0011tResponse.get(); + } + + + @Transactional + @Override + public List approve(ZwfApprUpdateRequest zwfApprUpdateRequest) { + User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); + List zwfApprResponseList = new ArrayList<>(); +// if (!zwfApprUpdateRequest.getBname().equals(user.getSabun())) throw new CustomException(ErrorCode.AUTHENTICATION_NOT_SUPPORT); + + String aedat = CommonUtils.dateFormat("yyyyMMdd"); + String aezet = CommonUtils.dateFormat("HHmmss"); + ZwfApprResponse result = null; + Zwf0012t zwf0012t = zwf0012tRepository.findByIdWkfidAndIdWkfsqAndBname(zwfApprUpdateRequest.getWkfid(), zwfApprUpdateRequest.getWkfsq(), zwfApprUpdateRequest.getBname()); + if (zwf0012t != null) { +// if(!zwf0012t.getWkfst().equals("I")) throw new CustomMessageException(CustomMessageException.CusMessage.builder() +// .code("999999") +// .message("결재 대기 상태가 아닙니댜.") +// .build()); + zwf0012t.setWkfst(zwfApprUpdateRequest.getWkfst()); + zwf0012t.setAenam(user.getSabun()); + zwf0012t.setAedat(aedat); + zwf0012t.setAezet(aezet); + result = ZwfApprResponse.to12(zwf0012tRepository.save(zwf0012t)); + } + + + Zwf0013t zwf0013t = zwf0013tRepository.findByWkfsqAndIdWkfidAndIdBname(zwfApprUpdateRequest.getWkfsq(), zwfApprUpdateRequest.getWkfid(), zwfApprUpdateRequest.getBname()); + if (zwf0013t != null) { +// if(!zwf0013t.getWkfst().equals("I")) throw new CustomMessageException(CustomMessageException.CusMessage.builder() +// .code("999999") +// .message("결재 대기 상태가 아닙니댜.") +// .build()); + zwf0013t.setWkfst(zwfApprUpdateRequest.getWkfst()); + zwf0013t.setAenam(user.getSabun()); + zwf0013t.setAedat(aedat); + zwf0013t.setAezet(aezet); + result = ZwfApprResponse.to13(zwf0013tRepository.save(zwf0013t)); + } + +// if(zwf0012t == null && zwf0013t == null) throw new CustomMessageException(CustomMessageException.CusMessage.builder() +// .code("999999") +// .message("결재 대상이 아닙니다.") +// .build()); + + zwfApprResponseList.add(result); + /* 대결 처리 시작 */ + if(StringUtil.isNotBlank(zwfApprUpdateRequest.getWkfst())) { + List apprNextTargetDtos = zwf0012tRepository.nextTarget(zwfApprUpdateRequest.getWkfid()); +// Zwf0012tRepository.ApprNextTargetDto apprNextTargetDto = zwf0012tRepository.nextTarget(zwfApprUpdateRequest.getWkfid()); + apprNextTargetDtos.stream().forEach((apprNextTargetDto) -> { + System.out.println(apprNextTargetDto.getBtext() + "///" + apprNextTargetDto.getBname()); + if(apprNextTargetDto != null) { + Zwf0012t nextZwf0012t = zwf0012tRepository.findByIdWkfidAndIdWkfsqAndBname(zwfApprUpdateRequest.getWkfid(), apprNextTargetDto.getWkfsq(), apprNextTargetDto.getBname()); + if (nextZwf0012t != null) { + if(StringUtil.isNotBlank(nextZwf0012t.getAbscd())) { + nextZwf0012t.setWkfst(zwfApprUpdateRequest.getWkfst()); + nextZwf0012t.setAenam(user.getSabun()); + nextZwf0012t.setAedat(aedat); + nextZwf0012t.setAezet(aezet); + nextZwf0012t.setWkfst("N"); + ZwfApprResponse subResult = ZwfApprResponse.to12(zwf0012tRepository.save(nextZwf0012t)); + zwfApprResponseList.add(subResult); + } + + } + + + Zwf0013t nextZwf0013t = zwf0013tRepository.findByWkfsqAndIdWkfidAndIdBname(apprNextTargetDto.getWkfsq(), zwfApprUpdateRequest.getWkfid(), apprNextTargetDto.getBname()); + if (nextZwf0013t != null) { + if(StringUtil.isNotBlank(nextZwf0013t.getAbscd())) { + nextZwf0013t.setWkfst(zwfApprUpdateRequest.getWkfst()); + nextZwf0013t.setAenam(user.getSabun()); + nextZwf0013t.setAedat(aedat); + nextZwf0013t.setAezet(aezet); + nextZwf0013t.setWkfst("N"); + ZwfApprResponse subResult = ZwfApprResponse.to13(zwf0013tRepository.save(nextZwf0013t)); + zwfApprResponseList.add(subResult); + } + } + } + }); + } + + + List zwf0012ts = zwf0012tRepository.findByIdWkfid(zwfApprUpdateRequest.getWkfid()); + List zwf0013ts = zwf0013tRepository.findByIdWkfid(zwfApprUpdateRequest.getWkfid()); + + List zwf0012tsChecker = zwf0012ts.stream().filter(z -> z.getWkfst().equals("Q") || z.getWkfst().equals("A") || z.getWkfst().equals("N")).toList(); + List zwf0013tsChecker = zwf0013ts.stream().filter(z -> z.getWkfst().equals("Q") || z.getWkfst().equals("A") || z.getWkfst().equals("N")).toList(); + + Zwf0011t zwf0011t = zwf0011tRepository.findByIdWkfid(zwfApprUpdateRequest.getWkfid()); + String belnr = zwf0011t.getObkey().substring(0, 10); + Slip slip = slipRepository.findByBelnr(belnr); + if(slip == null) throw new CustomException(ErrorCode.FIND_ERR); + Cont cont = contRepository.findById(slip.getContNo()).get(); + if(cont == null) throw new CustomException(ErrorCode.FIND_ERR); + + if (zwf0011t != null) { + /* 결재 승인 */ + if (zwf0012ts.size() == zwf0012tsChecker.size() && zwf0013ts.size() == zwf0013tsChecker.size()) { + zwf0011t.setWkfst("S"); + } + /*반려 처리*/ + else if(zwfApprUpdateRequest.getWkfst().equals("R")) { + zwf0011t.setWkfst(zwfApprUpdateRequest.getWkfst()); + zwf0011t.setReason(zwfApprUpdateRequest.getReason()); + /* 임시 전표 삭제 시작 */ + + /* 임시 전표 삭제 종료 */ + cont.setContStatCd("0700"); + cont.setContStat(codeRepository.findById(CodeId.builder() + .id(3) + .cd("0700") + .build()).get().getNm()); + contRepository.save(cont); + } else { + zwf0011t.setWkfst("I"); + cont.setContStatCd("0400"); + cont.setContStat(codeRepository.findById(CodeId.builder() + .id(3) + .cd("0400") + .build()).get().getNm()); + contRepository.save(cont); + } + + zwf0011t.setAenam(user.getSabun()); + zwf0011t.setAedat(aedat); + zwf0011t.setAezet(aezet); + + zwf0011tRepository.save(zwf0011t); + } else { + throw new CustomException(ErrorCode.NO_SAME_DATA); + } + if (result == null) throw new CustomException(ErrorCode.NO_SAME_DATA); + + return zwfApprResponseList; + } + + +} diff --git a/src/main/java/com/kospo/svcm/service/impl/SlipServiceImpl.java b/src/main/java/com/kospo/svcm/service/impl/SlipServiceImpl.java new file mode 100644 index 0000000..6e3e2fb --- /dev/null +++ b/src/main/java/com/kospo/svcm/service/impl/SlipServiceImpl.java @@ -0,0 +1,129 @@ +package com.kospo.svcm.service.impl; + +import com.kospo.svcm.config.exception.ErrorCode; +import com.kospo.svcm.config.utils.CommonUtils; +import com.kospo.svcm.config.utils.FileUtils; +import com.kospo.svcm.dto.req.SlipSaveRequest; +import com.kospo.svcm.dto.res.SlipAttResponse; +import com.kospo.svcm.dto.res.SlipResponse; +import com.kospo.svcm.exception.CustomException; +import com.kospo.svcm.model.*; +import com.kospo.svcm.repository.ContRepository; +import com.kospo.svcm.repository.SlipAttRepository; +import com.kospo.svcm.repository.SlipRepository; +import com.kospo.svcm.service.SlipService; +import jakarta.transaction.Transactional; +import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.stereotype.Service; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.List; +import java.util.Optional; +import java.util.concurrent.atomic.AtomicInteger; + +@Service +@RequiredArgsConstructor +public class SlipServiceImpl implements SlipService { + @Value("${server.attach}") + private String filePath; + private final SlipRepository slipRepository; + private final ContRepository contRepository; + private final SlipAttRepository slipAttRepository; + private final FileUtils fileUtils; + + @Transactional + @Override + public SlipResponse findByContNo(String contNo) { + Optional optionalSlip = slipRepository.findById(contNo); + if(optionalSlip.isPresent()) { + return SlipResponse.to(optionalSlip.get()); + } else { + throw new CustomException(ErrorCode.FIND_ERR); + } + } + + @Transactional + @Override + public SlipResponse save(SlipSaveRequest slipSaveRequest) { + + User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); + + /* eai fi 전송 성공후 저장*/ + /*계약진행중인 대상자*/ + Cont cont = contRepository.findByContNoAndContStatCd(slipSaveRequest.getContNo(), "0200"); + if(cont != null) { + Slip slip = slipRepository.save(Slip.builder() + .contNo(slipSaveRequest.getContNo()) + .lifnr(slipSaveRequest.getLifnr()) + .gsber(slipSaveRequest.getGsber()) + .wrbtrS(slipSaveRequest.getWrbtrS()) + .mwskz(slipSaveRequest.getMwskz()) + .waers(slipSaveRequest.getWaers()) + .bldat(slipSaveRequest.getBldat()) + .budat(slipSaveRequest.getBudat()) + .hkont(slipSaveRequest.getHkont()) + .wrbtrS(slipSaveRequest.getWrbtrS()) + .kostl(slipSaveRequest.getKostl()) + .projk(slipSaveRequest.getProjk()) + .usnam(user.getSabun()) + .regSabun(user.getSabun()) + .wrbtr(String.valueOf(Integer.parseInt(slipSaveRequest.getWrbtrS()) + Math.floor((Integer.parseInt(slipSaveRequest.getWrbtrS())* 0.1)))) + .regDt(CommonUtils.dateFormat("yyyy-MM-dd HH:mm:ss")) + .build()); + List slipAtts = null; + AtomicInteger fileOrd = new AtomicInteger(0); + if (slipSaveRequest.getSlipAtts() != null && slipSaveRequest.getSlipAtts().size() > 0) { + slipAtts = slipAttRepository.saveAll(slipSaveRequest.getSlipAtts().stream().map(att -> { + if(!CommonUtils.checkAllowExt(att.getLogiFnm())) throw new CustomException(ErrorCode.FILE_EXT_UPLOAD_ERROR); + String pNm = CommonUtils.dateFormat("yyyyMMddHHmmssSSS"); + fileUtils.fileUpload(filePath + pNm, att.getData()); + try { + return SlipAtt.builder() + .id( + SlipAttId.builder() + .fileOrd(fileOrd.incrementAndGet()) + .contNo(cont.getContNo()) + .build() + ) + .logiFnm(att.getLogiFnm()) + .physFnm(pNm) + .size((int) Files.size(Path.of(filePath + pNm))) + .path(filePath + pNm) + .build(); + } catch (IOException e) { + throw new RuntimeException(e); + } + }).toList()); + } + + slip.setSlipAtts(slipAtts); + return SlipResponse.to(slip); + } else { + throw new CustomException(ErrorCode.SAVE_ERR); + } + } + + @Transactional + @Override + public void delete(String contNo) { + User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); + /*eai 임시전표 삭제후 처리*/ + slipRepository.findById(contNo) + .ifPresentOrElse( + slip -> { + if(slip.getRegSabun().equals(user.getSabun())) { + slipRepository.delete(slip); + } else { + throw new CustomException(ErrorCode.AUTHENTICATION_NOT_SUPPORT); + } + }, + () -> { + throw new CustomException(ErrorCode.DEL_ERR); + } + ); + } +} diff --git a/src/main/java/com/kospo/svcm/service/impl/UserServiceImpl.java b/src/main/java/com/kospo/svcm/service/impl/UserServiceImpl.java new file mode 100644 index 0000000..9e154bb --- /dev/null +++ b/src/main/java/com/kospo/svcm/service/impl/UserServiceImpl.java @@ -0,0 +1,45 @@ +package com.kospo.svcm.service.impl; + +import com.kospo.svcm.dto.res.UserSelectListResponse; +import com.kospo.svcm.model.User; +import com.kospo.svcm.repository.UserRepository; +import com.kospo.svcm.service.UserService; +import jakarta.transaction.Transactional; +import lombok.RequiredArgsConstructor; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; + +@Service +@RequiredArgsConstructor +public class UserServiceImpl implements UserService { + private final UserRepository userRepository; + + @Override + @Transactional + public User findOne(String sabun) { + return userRepository.findBySabun(sabun); + } + + @Override + public UserDetails loadUserByUsername(String sabun) throws UsernameNotFoundException { + return userRepository.findBySabun(sabun); + } + + @Override + public List findByNameContaining(String name) { + if(name.equals("") || name == null) { + return new ArrayList(); + } else { + return userRepository.findByNameContaining(name).stream().map(u -> UserSelectListResponse.builder() + .label(u.getDept().getDeptNm() + " - " + u.getName() + " (" + u.getSabun() + ")") + .value(UserSelectListResponse.UserSelect.from(u)) + .build()).toList(); + } + } + +} + diff --git a/src/main/java/excelSample.java b/src/main/java/excelSample.java new file mode 100644 index 0000000..d348ad9 --- /dev/null +++ b/src/main/java/excelSample.java @@ -0,0 +1,66 @@ +import com.kospo.svcm.dto.xml.QsSample; +import jakarta.xml.bind.JAXBContext; +import jakarta.xml.bind.JAXBException; +import jakarta.xml.bind.Marshaller; +import jakarta.xml.bind.Unmarshaller; +import jakarta.xml.bind.annotation.XmlAccessType; +import jakarta.xml.bind.annotation.XmlAccessorType; +import jakarta.xml.bind.annotation.XmlElement; +import jakarta.xml.bind.annotation.XmlRootElement; +import lombok.*; +import org.apache.poi.ss.usermodel.*; +import org.apache.poi.xssf.usermodel.*; + +import javax.xml.bind.DatatypeConverter; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.FileInputStream; +import java.io.IOException; +import java.nio.charset.Charset; + +public class excelSample { + public static void main(String[] args) throws JAXBException, IOException, NoSuchMethodException { + String excel = "UEsDBBQACAgIAOcctFoAAAAAAAAAAAAAAAAYAAAAeGwvZHJhd2luZ3MvZHJhd2luZzEueG1sndBdbsIwDAfwE+wOVd5pWhgTQxRe0E4wDuAlbhuRj8oOo9x+0Uo2aXsBHm3LP/nvzW50tvhEYhN8I+qyEgV6FbTxXSMO72+zlSg4gtdgg8dGXJDFbvu0GTWtz7ynIu17XqeyEX2Mw1pKVj064DIM6NO0DeQgppI6qQnOSXZWzqvqRfJACJp7xLifJuLqwQOaA+Pz/k3XhLY1CvdBnRz6OCGEFmL6Bfdm4KypB65RPVD8AcZ/gjOKAoc2liq46ynZSEL9PAk4/hr13chSvsrVX8jdFMcBHU/DLLlDesiHsSZevpNlRnfugbdoAx2By8i4OPjj3bEqyTa1KCtssV7ercyzIrdfUEsHCAdiaYMFAQAABwMAAFBLAwQUAAgICADnHLRaAAAAAAAAAAAAAAAAGAAAAHhsL3dvcmtzaGVldHMvc2hlZXQxLnhtbJ2V3Y6jIBiGr2DvwXBeUaud1qiTnWkmO2eTyc7uMYNYSUUMYG3vftG2pIX9MXsGn+/38AgYs8cja7wDEZLyNgehHwCPtJiXtN3l4OP7y2INPKlQW6KGtyQHJyLBY/ElG7jYy5oQ5WlAK3NQK9WlEEpcE4akzzvS6icVFwwpPRU7KDtBUDk1sQZGQbCCDNEWnAmpmMPgVUUx2XLcM9KqM0SQBimtL2vaySuNHR0co1hwySvlY84uJG2AITliMgmt74QYnmPEkNj33UIjO23xSRuqTpOXwRxy0Is2vTAWRmPsSfX66YE11/AxjOd5O5u5gZs7+2OY/B8pDGAYWqgYuXsxXwthQ2LzMOZELlekyCbkmygy3quGtuRNeLJnevNPT6ThQw70xb0U3umuVmMBFhk0fdPgByWDvBl74zX+5Hw/Tl7Lu6bb7Mt04HpN3EvF2TdyXiIEXkkq1DfqmTc/aalqXYv81dLU3/lgwon/kIz4ibhFChWZ4IMnRk6R4XHwVRPlxNUNUlcPRZDBg1bCl8STmwjvE89uIrpPbN3E0iSgdjJikRGLppbopiW2xNxEYom5iZUldk1MrxX5we+tlsZq6RAfLCs3sbas3IRttbyxiuI/WcXGKnaIG8vKTdhWbsK2imdZJcYq+aeVm7Ct3IRtlfzdCt5c/lKgQf9mPJFS/eWJ1zKcPj7zZyl+AVBLBwi1xQfRDQIAAJ0GAABQSwMEFAAICAgA5xy0WgAAAAAAAAAAAAAAACMAAAB4bC93b3Jrc2hlZXRzL19yZWxzL3NoZWV0MS54bWwucmVsc43PSwrCMBAG4BN4hzB7k9aFiDTtRoRupR5gSKYPbB4k8dHbm42i4MLlzM98w181DzOzG4U4OSuh5AUwssrpyQ4Szt1xvQMWE1qNs7MkYaEITb2qTjRjyjdxnHxkGbFRwpiS3wsR1UgGI3eebE56FwymPIZBeFQXHEhsimIrwqcB9ZfJWi0htLoE1i2e/rFd30+KDk5dDdn044XQAe+5WCYxDJQkcP7avcOSZxZEXYmvivUTUEsHCK2o602zAAAAKgEAAFBLAwQUAAgICADnHLRaAAAAAAAAAAAAAAAAEwAAAHhsL3RoZW1lL3RoZW1lMS54bWzNV9tu3CAQ/YL+A+K9wde9KbtRsptVH1pV6rbqM7HxpcHYAjZp/r4Ye218S6JmI2VfAuMzhzMzwJDLq78ZBQ+EizRna2hfWBAQFuRhyuI1/PVz/3kBgZCYhZjmjKzhExHwavPpEq9kQjIClDsTK7yGiZTFCiERKDMWF3lBmPoW5TzDUk15jEKOHxVtRpFjWTOU4ZTB2p+/xj+PojQguzw4ZoTJioQTiqWSLpK0EBAwnCmNh4QQKeDmJPKWktJDlIaA8kOglQ+w4b1d/hE8vttSDh4wXUNL/yDaXKIGQOUQt9e/GlcDwnvnJT6n4hvienwagINARTFc23MW/t6rsQaoGg65b6891/U7eIPfHWq5udlaXX63xXsDvOtdL3y3g/davD8S62xn2R283+Jnw3hnN7vtrIPXoISm7H6Atm3f325rdAOJcvrlZXiLQsbOqfyZnNpHGf6T870C6OKq7cmAfCpIhAOFu+YppiU9XhE8bg/EmB31iLOUvdMqLTEyA9VhZ92ov+sjqaOOUkoP8omSr0JLEjlNw70y6ol2apJcJGpYL9fBxRzrMeC5/J3K5JDgQi1j6xViUVPHAhS5UIcJTnLrpByzb3l4Kuvp3CkHLFu75Td2lUJZWWfz9pA29HoWC1OAr0lfL8JYrCvCHRExd18nwrbOpWI5omJhP6cCGVVRBwXgsmv4XqUIiABTEpZ1qvxP1T17paeS2Q3bGQlv6Z2t0h0RxnbrijC2YYJD0jefudbL5XipnVEZ88V71BoN7wbKujPwqM6c6yuaABdrGKnrTA2zQvEJFkOAaaweJ4GsE/0/N0vBhdxhkVQw/amKP0sl4YCmmdrrZhkoa7XZztz6uOKW1sfLHOoXmUQRCeSEpZ2qbxXJ6Nc3gstJflSiD0n4CO7okf/AKlH+3C4TGKZCNtkMU25s7jaLveuqPoojLzz9gKFFguuOYl7mFVyPGzlGHFppPyo0lsK7eH+OrvuyU+/SnGgg88lb7P2avKHKHVflj951y4X1fJd4e0MwpC3Gpbnj0qZ6xxkfBMZys4m8OZPVfGM36O9aZLwr9az3T9vJsvkHUEsHCGWjgWEoAwAArQ4AAFBLAwQUAAgICADnHLRaAAAAAAAAAAAAAAAAFAAAAHhsL3NoYXJlZFN0cmluZ3MueG1sZdCxTsMwEAbgJ+AdLO/UaYWqCjnugMQTwANYydFYis8h56CyVkUKsDF1qMQKiAkGGHiiJn0HjGDBGe+7/+6kk/OlLdkV1GQcpnw8SjgDzFxucJHy87PTwxln5DXmunQIKb8G4nN1IIk8C6NIKS+8r46FoKwAq2nkKsDQuXC11T6U9UJQVYPOqQDwthSTJJkKqw1ylrkGfTg75axBc9nAyR8kXEkySnq1f2i7lxspvJLiR35197HdvT3H2t0/9dt1rH276R5vB9nVpl+9xjqzli3ZkbVxA/Rgwbrd333GOp4MZ7v3r39JEZ6nvgFQSwcIOaKSW+wAAAB6AQAAUEsDBBQACAgIAOcctFoAAAAAAAAAAAAAAAANAAAAeGwvc3R5bGVzLnhtbLVUTW+cMBD9Bf0Plu9Zs7ttlERAFKWi6qU9ZCv1aowBK/5AtjeF/vqOMWTZbqMkK5UD2DPj954fY6e3vZLoiVsnjM7wepVgxDUzldBNhn/siosrjJynuqLSaJ7hgTt8m39InR8kf2g59wgQtMtw6313Q4hjLVfUrUzHNWRqYxX1MLUNcZ3ltHJhkZJkkySXRFGhcUS46dcfKTvBUYJZ40ztV8woYupaMH6KdE2uCWUzkjqF+YccRe3jvrsA2I56UQop/DCqwnlaG+0dYmavfYa3UyBP3W/0RCX4lIBRJE+ZkcYi25QZLopkfEJYU8Vj4Z0VVIbQqGMKKqGNDUESUeO7/BsvPmfjRSwfykDwGTDjxwGckPLYCwjkKZjmudUFTNA03g0dcGlolAgz1r1SLUXT+i+WDm9f4owUVdDR3C/92n6++nR/GWDKlxJkgfnMNn5gn6WxFRyEeadrPIfCwikJtnIpH0Lz/6yPSvsaxZqvVYbhFAXQeQg+TkO9V4WaJ7Tr5HAHBmjFI0wMFSbOAu+SLpIveLfn8fb1GwXkKZ2TKBw4uBS+B6pxsWut0I87Uwg/zuES8YKFRiqN90Zh9MvSbsf7MR320tcvy90c5K7fLRcw3if+NTUL8zb/w7yZn0w/dNFWR031HD3QhkOc4W/hHpMYlXshvdAxd9QvgFn1h1aJ2cOtnf8BUEsHCITDsawJAgAA+gUAAFBLAwQUAAgICADnHLRaAAAAAAAAAAAAAAAADwAAAHhsL3dvcmtib29rLnhtbJ2SS07DMBCGT8AdIu9bJ6igNmrSDULqBrGAA7j2pLHiR2S7Ib0CXIGDcCi4A9M0iVS6iVj5Od98sv/1ptUqasB5aU1GknlMIjDcCmn2GXl9eZwtSeQDM4IpayAjR/Bkk9+s36yrdtZWEdYbn5EyhDql1PMSNPNzW4PBk8I6zQIu3Z762gETvgQIWtHbOL6nmklDzoTUTWHYopAcHiw/aDDhDHGgWEB7X8raDzTdXuG05M56W4Q5t7onoQGn0HLohJYXQppPMdLMVYd6hsgaLXZSyXDsvEZMk5GDM2nPmI0ap5oU+6eNVsPlNllM8756zBVdXdi3yd3/SElMk+QPasGu32K6FuMjSU/DjD/SRyQf4/bsaL7u+L4fT+kMGMxGerlTQCLDNC6/Pz5/3r8SDO/p0lZgtknkUokTtxULghg6cAQU0oB4wkKP+5wp3vWhQ9f8F1BLBwhbusWcUwEAACcDAABQSwMEFAAICAgA5xy0WgAAAAAAAAAAAAAAABoAAAB4bC9fcmVscy93b3JrYm9vay54bWwucmVsc62SQWrDMBBFT9A7iNnXspNSSomcTShk26YHENLYMrElIU3a+vadNuA6EEIXXon/xfz/0Giz/Rp68YEpd8ErqIoSBHoTbOdbBe+Hl/snEJm0t7oPHhWMmGFb321esdfEM9l1MQsO8VmBI4rPUmbjcNC5CBE93zQhDZpYplZGbY66Rbkqy0eZ5hlQX2SKvVWQ9rYCcRgj/ic7NE1ncBfMaUBPVyok8SxyoE4tkoJfeTargsNAXmdYLcmQaez5DSeIs75Vv1603umE9o0SL3hOMbdvwTwsCfMZ0jE7RPoDmawfVD6mxciLH1d/A1BLBwiWGcFT6gAAALkCAABQSwMEFAAICAgA5xy0WgAAAAAAAAAAAAAAAAsAAABfcmVscy8ucmVsc43PQQ6CMBAF0BN4h2b2UnBhjKGwMSZsDR6gtkMhQKdpq8Lt7VKNC5eT+fN+pqyXeWIP9GEgK6DIcmBoFenBGgHX9rw9AAtRWi0nsihgxQB1tSkvOMmYbkI/uMASYoOAPkZ35DyoHmcZMnJo06YjP8uYRm+4k2qUBvkuz/fcvxtQfZis0QJ8owtg7erwH5u6blB4InWf0cYfFV+JJEtvMApYJv4kP96IxiyhwKuSfzxYvQBQSwcIpG+hILIAAAAoAQAAUEsDBBQACAgIAOcctFoAAAAAAAAAAAAAAAATAAAAW0NvbnRlbnRfVHlwZXNdLnhtbLVTy07DMBD8Av4h8hU1bjkghJr2wOMISJQPWOxNY9Uved3X37NJWiSqIIHUXry2xzsz67Wn852zxQYTmeArMSnHokCvgjZ+WYmPxfPoThSUwWuwwWMl9khiPruaLvYRqeBkT5Voco73UpJq0AGVIaJnpA7JQeZlWsoIagVLlDfj8a1UwWf0eZRbDjGbPmINa5uLh36/pa4ExGiNgsy+JJOJ4mnHYG+zXcs/5G28PjEzOhgpE9ruDDUm0vWpAKPUKrzyzSSj8V8Soa6NQh3U2nFKSTEhaGoQs7PlNqRVN+813yDlF3BMKndWfoMkuzApD5We3wc1kFC/58SNpiEvPw6c04dOsGXOIc0DRMfJJevPe4vDhXfIOZUzfwsckuqAfrxoqzmWDoz/7c19hrA66svuZ8++AFBLBwhtiLRQNQEAABkEAABQSwECFAAUAAgICADnHLRaB2JpgwUBAAAHAwAAGAAAAAAAAAAAAAAAAAAAAAAAeGwvZHJhd2luZ3MvZHJhd2luZzEueG1sUEsBAhQAFAAICAgA5xy0WrXFB9ENAgAAnQYAABgAAAAAAAAAAAAAAAAASwEAAHhsL3dvcmtzaGVldHMvc2hlZXQxLnhtbFBLAQIUABQACAgIAOcctFqtqOtNswAAACoBAAAjAAAAAAAAAAAAAAAAAJ4DAAB4bC93b3Jrc2hlZXRzL19yZWxzL3NoZWV0MS54bWwucmVsc1BLAQIUABQACAgIAOcctFplo4FhKAMAAK0OAAATAAAAAAAAAAAAAAAAAKIEAAB4bC90aGVtZS90aGVtZTEueG1sUEsBAhQAFAAICAgA5xy0WjmiklvsAAAAegEAABQAAAAAAAAAAAAAAAAACwgAAHhsL3NoYXJlZFN0cmluZ3MueG1sUEsBAhQAFAAICAgA5xy0WoTDsawJAgAA+gUAAA0AAAAAAAAAAAAAAAAAOQkAAHhsL3N0eWxlcy54bWxQSwECFAAUAAgICADnHLRaW7rFnFMBAAAnAwAADwAAAAAAAAAAAAAAAAB9CwAAeGwvd29ya2Jvb2sueG1sUEsBAhQAFAAICAgA5xy0WpYZwVPqAAAAuQIAABoAAAAAAAAAAAAAAAAADQ0AAHhsL19yZWxzL3dvcmtib29rLnhtbC5yZWxzUEsBAhQAFAAICAgA5xy0WqRvoSCyAAAAKAEAAAsAAAAAAAAAAAAAAAAAPw4AAF9yZWxzLy5yZWxzUEsBAhQAFAAICAgA5xy0Wm2ItFA1AQAAGQQAABMAAAAAAAAAAAAAAAAAKg8AAFtDb250ZW50X1R5cGVzXS54bWxQSwUGAAAAAAoACgCaAgAAoBAAAAAA"; + ByteArrayInputStream bais = null; +// try { +// +// byte[] data = DatatypeConverter.parseBase64Binary(excel); +// bais = new ByteArrayInputStream(data); +// XSSFWorkbook workbook = new XSSFWorkbook(bais); +// XSSFSheet sheet = workbook.getSheetAt(0); +// for(int r=0; r <= sheet.getLastRowNum(); r++) { +// XSSFRow row = sheet.getRow(r); +// for (int c = 0; c < row.getLastCellNum(); c++) { +// XSSFCell cell = row.getCell(c); +// if(cell.getCellType() == CellType.NUMERIC) { +// System.out.print(cell.getNumericCellValue() + "\t"); +// } else { +// System.out.print(new String(cell.getStringCellValue().getBytes(), "UTF-8") + "\t"); +// } +// } +// } +// bais.close(); +// } catch(Exception e) { +// new RuntimeException(e); +// } + try { + byte[] data = DatatypeConverter.parseBase64Binary(excel); + bais = new ByteArrayInputStream(data); + Workbook workbook = WorkbookFactory.create(bais); + Sheet sheet = workbook.getSheetAt(0); + for(Row row : sheet) { + for (Cell cell : row) { + if(cell.getCellType() == CellType.NUMERIC) { + System.out.print(cell.getNumericCellValue() + "\t"); + } else { + System.out.print(cell.getStringCellValue() + "\t"); + } + + } + } + bais.close(); + } catch(Exception e) { + new RuntimeException(e); + } + } +} diff --git a/src/main/java/javax/servlet/http/HttpServletRequest.java b/src/main/java/javax/servlet/http/HttpServletRequest.java new file mode 100644 index 0000000..a973394 --- /dev/null +++ b/src/main/java/javax/servlet/http/HttpServletRequest.java @@ -0,0 +1,5 @@ +package javax.servlet.http; + +public interface HttpServletRequest extends jakarta.servlet.http.HttpServletRequest { + +} diff --git a/src/main/java/javax/servlet/http/HttpServletResponse.java b/src/main/java/javax/servlet/http/HttpServletResponse.java new file mode 100644 index 0000000..7f9b8bc --- /dev/null +++ b/src/main/java/javax/servlet/http/HttpServletResponse.java @@ -0,0 +1,5 @@ +package javax.servlet.http; + +public interface HttpServletResponse extends jakarta.servlet.http.HttpServletResponse { + +} diff --git a/src/main/java/javax/servlet/http/HttpSession.java b/src/main/java/javax/servlet/http/HttpSession.java new file mode 100644 index 0000000..5ea999a --- /dev/null +++ b/src/main/java/javax/servlet/http/HttpSession.java @@ -0,0 +1,4 @@ +package javax.servlet.http; + +public interface HttpSession extends jakarta.servlet.http.HttpSession { +} diff --git a/src/main/java/javax/servlet/http/HttpUtils.java b/src/main/java/javax/servlet/http/HttpUtils.java new file mode 100644 index 0000000..64a94c1 --- /dev/null +++ b/src/main/java/javax/servlet/http/HttpUtils.java @@ -0,0 +1,135 @@ +package javax.servlet.http; + + +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.util.Hashtable; +import java.util.ResourceBundle; +import java.util.StringTokenizer; +import jakarta.servlet.ServletInputStream; + +/** @deprecated */ +public class HttpUtils { + private static final String LSTRING_FILE = "javax.servlet.http.LocalStrings"; + private static ResourceBundle lStrings = ResourceBundle.getBundle("javax.servlet.http.LocalStrings"); + + public HttpUtils() { + } + + public static Hashtable parseQueryString(String s) { + String[] valArray = null; + if (s == null) { + throw new IllegalArgumentException(); + } else { + Hashtable ht = new Hashtable(); + StringBuilder sb = new StringBuilder(); + + String key; + for(StringTokenizer st = new StringTokenizer(s, "&"); st.hasMoreTokens(); ht.put(key, valArray)) { + String pair = st.nextToken(); + int pos = pair.indexOf(61); + if (pos == -1) { + throw new IllegalArgumentException(); + } + + key = parseName(pair.substring(0, pos), sb); + String val = parseName(pair.substring(pos + 1, pair.length()), sb); + if (!ht.containsKey(key)) { + valArray = new String[]{val}; + } else { + String[] oldVals = (String[])ht.get(key); + valArray = new String[oldVals.length + 1]; + + for(int i = 0; i < oldVals.length; ++i) { + valArray[i] = oldVals[i]; + } + + valArray[oldVals.length] = val; + } + } + + return ht; + } + } + + public static Hashtable parsePostData(int len, ServletInputStream in) { + if (len <= 0) { + return new Hashtable(); + } else if (in == null) { + throw new IllegalArgumentException(); + } else { + byte[] postedBytes = new byte[len]; + + try { + int offset = 0; + + do { + int inputLen = in.read(postedBytes, offset, len - offset); + if (inputLen <= 0) { + String msg = lStrings.getString("err.io.short_read"); + throw new IllegalArgumentException(msg); + } + + offset += inputLen; + } while(len - offset > 0); + } catch (IOException e) { + throw new IllegalArgumentException(e.getMessage()); + } + + try { + String postedBody = new String(postedBytes, 0, len, "8859_1"); + return parseQueryString(postedBody); + } catch (UnsupportedEncodingException e) { + throw new IllegalArgumentException(e.getMessage()); + } + } + } + + private static String parseName(String s, StringBuilder sb) { + sb.setLength(0); + + for(int i = 0; i < s.length(); ++i) { + char c = s.charAt(i); + switch (c) { + case '%': + try { + sb.append((char)Integer.parseInt(s.substring(i + 1, i + 3), 16)); + i += 2; + } catch (NumberFormatException var6) { + throw new IllegalArgumentException(); + } catch (StringIndexOutOfBoundsException var7) { + String rest = s.substring(i); + sb.append(rest); + if (rest.length() == 2) { + ++i; + } + } + break; + case '+': + sb.append(' '); + break; + default: + sb.append(c); + } + } + + return sb.toString(); + } + + public static StringBuffer getRequestURL(HttpServletRequest req) { + StringBuffer url = new StringBuffer(); + String scheme = req.getScheme(); + int port = req.getServerPort(); + String urlPath = req.getRequestURI(); + url.append(scheme); + url.append("://"); + url.append(req.getServerName()); + if (scheme.equals("http") && port != 80 || scheme.equals("https") && port != 443) { + url.append(':'); + url.append(req.getServerPort()); + } + + url.append(urlPath); + return url; + } +} \ No newline at end of file diff --git a/src/main/java/javax/servlet/http/ServletException.java b/src/main/java/javax/servlet/http/ServletException.java new file mode 100644 index 0000000..62ef01a --- /dev/null +++ b/src/main/java/javax/servlet/http/ServletException.java @@ -0,0 +1,4 @@ +package javax.servlet.http; + +public class ServletException extends jakarta.servlet.ServletException { +} diff --git a/src/main/java/xmlSample.java b/src/main/java/xmlSample.java new file mode 100644 index 0000000..c236638 --- /dev/null +++ b/src/main/java/xmlSample.java @@ -0,0 +1,148 @@ +import com.kospo.svcm.dto.xml.QsSample; +import jakarta.xml.bind.*; +import jakarta.xml.bind.annotation.*; +import lombok.*; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +public class xmlSample { + public static void main(String[] args) throws JAXBException, IOException, NoSuchMethodException { + String xml = "\n" + + "\n" + + " \n" + + " S\n" + + " \n" + + " 2025017227\n" + + " SS\n" + + " SS\n" + + " itp for control\n" + + " Q010\n" + + " \n" + + ""; +// String xml = "\n" + +// "\n" + +// " CONT-0000000005\n" + +// " 999-99-99999\n" + +// " 1000\n" + +// " 1102\n" + +// " V4\n" + +// " KRW\n" + +// " 20250501\n" + +// " 20250502\n" + +// " 5366010\n" + +// " 12330\n" + +// " \n" + +// " 1212\n" + +// " \n" + +// " \n" + +// " psn14020\n" + +// " \n" + +// " \n" + +// ""; +// + QsSample slip = (QsSample) xmlToModel(xml, QsSample.class); + System.out.println(slip.toString()); +// +// Slip slip = Slip.builder() +// .contNo("CONT-0000000005") +// .lifnr("999-99-99999") +// .gsber("1000") +// .wrbtrS("1102") +// .mwskz("V4") +// .waers("KRW") +// .bldat("20250501") +// .budat("20250502") +// .hkont("5366010") +// .kostl("12330") +// .projk("") +// .wrbtr("1212") +// .bvtyp("") +// .bstat("") +// .usnam("psn14020") +// .gjahr("") +// .bukrs("") +// .build(); +// +// String list= modelToXml(slip); +// System.out.println(list); + } + + public static Object xmlToModel(String xml , Class cla) throws JAXBException, IOException, NoSuchMethodException { + + ByteArrayInputStream bais = new ByteArrayInputStream(xml.getBytes()); + JAXBContext jaxbContext = JAXBContext.newInstance(cla); + Unmarshaller unmarshaller = jaxbContext.createUnmarshaller(); + + Object obj = unmarshaller.unmarshal(bais); + + bais.close(); + return obj; + } + + public static String modelToXml(Object obj) throws JAXBException, IOException { + + + JAXBContext jaxbContext = JAXBContext.newInstance(obj.getClass()); + Marshaller marshaller = jaxbContext.createMarshaller(); + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + + marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); + marshaller.marshal(obj, baos); + + String list = baos.toString(); + + baos.close(); + + return list; + } + + @NoArgsConstructor + @AllArgsConstructor + @Setter + @Getter + @ToString + @XmlRootElement(name = "ROOT") + @XmlAccessorType(XmlAccessType.FIELD) + @Builder + public static class Slip{ + @XmlElement(name = "cont_no") + String contNo; + @XmlElement(name = "lifnr") + String lifnr; + @XmlElement(name = "gsber") + String gsber; + @XmlElement(name = "wrbtr_s") + String wrbtrS; + @XmlElement(name = "mwskz") + String mwskz; + @XmlElement(name = "waers") + String waers; + @XmlElement(name = "bldat") + String bldat; + @XmlElement(name = "budat") + String budat; + @XmlElement(name = "hkont") + String hkont; + @XmlElement(name = "kostl") + String kostl; + @XmlElement(name = "projk") + String projk; + @XmlElement(name = "wrbtr") + String wrbtr; + @XmlElement(name = "bvtyp") + String bvtyp; + @XmlElement(name = "bstat") + String bstat; + @XmlElement(name = "usnam") + String usnam; + @XmlElement(name = "gjahr") + String gjahr; + @XmlElement(name = "belnr") + String belnr; + @XmlElement(name = "bukrs") + String bukrs; + } +} diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml new file mode 100644 index 0000000..e5e12f6 --- /dev/null +++ b/src/main/resources/application-dev.yml @@ -0,0 +1,78 @@ +jasypt: + encryptor: + key: kospo2025 + bean: jasyptEncryptorAES + property: + prefix: ENC( + suffix: ) +server: + address: 0.0.0.0 + port: 8010 + servlet: + encoding: + charset: UTF-8 + enabled: true + force: true + session: + timeout: 1800s + attach: '/appl/svcm/attach/' + jetty: + max-http-form-post-size: 100MB +spring: + application: + name: svcm + servlet: + multipart: + max-file-size: 100MB + max-request-size: 100MB + data: + rest: + detection-strategy: annotated + devtools: + livereload: + enabled: true + remote: + restart: + enabled: false + jpa: + show-sql: false + hibernate: + ddl-auto: validate + naming: + physical-strategy: org.hibernate.boot.model.naming.CamelCaseToUnderscoresNamingStrategy + open-in-view: false + mvc: + pathmatch: + matching-strategy: ant_path_matcher + datasource: + hikari: + username: ENC(gLQTvX57MBGvHAhEGckIJbVdgG5w1YPO+bZk5+xOvg6DhAIcGcyXib8T605t2Icd) + password: ENC(KpBRMJPNmBe/zi0mPo32beSSXteAaSEp/Kf7dVV3ss8Qi4mS2bJ+P0eFw2Qs15sV) + connection-timeout: 20000 + maximum-pool-size: 30 + data-source-properties: + cachePrepStmts: true + prepStmtCacheSize: 200 + prepStmtCacheSqlLimit: 2048 + useServerPrepStmts: true + url: jdbc:log4jdbc:postgresql://hmsn.ink:35432/svcm + driver-class-name: net.sf.log4jdbc.sql.jdbcapi.DriverSpy +jwt: + key: 5840f916c19111ee86fcf38ac250f21377907a8ac19111eebab6e7179f8e5c87 +springdoc: + packages-to-scan: com.kospo.svcm + api-docs: + path: /api-docs + groups: + enabled: true + swagger-ui: + path: /swagger-ui.html + enabled: true + groups-order: ASC + tags-sorter: alpha + operations-sorter: alpha + display-request-duration: true + doc-expansion: none + cache: + disabled: true + model-and-view-allowed: true \ No newline at end of file diff --git a/src/main/resources/application-prod.yml b/src/main/resources/application-prod.yml new file mode 100644 index 0000000..c2b8eb0 --- /dev/null +++ b/src/main/resources/application-prod.yml @@ -0,0 +1,89 @@ +jasypt: + encryptor: + key: kospo2025 + bean: jasyptEncryptorAES + property: + prefix: ENC( + suffix: ) +server: + address: 0.0.0.0 + port: 8010 + servlet: + encoding: + charset: UTF-8 + enabled: true + force: true + session: + timeout: 1800s + attach: '/appl/svcm/attach/' + jetty: + max-http-form-post-size: 100MB +spring: + application: + name: svcm + servlet: + multipart: + max-file-size: 100MB + max-request-size: 100MB + data: + rest: + detection-strategy: annotated + devtools: + livereload: + enabled: true + remote: + restart: + enabled: false + jpa: + show-sql: false + hibernate: + ddl-auto: validate + naming: + physical-strategy: org.hibernate.boot.model.naming.CamelCaseToUnderscoresNamingStrategy + open-in-view: false + mvc: + pathmatch: + matching-strategy: ant_path_matcher + mail: + host: smtp.kospo.co.kr + port: 587 + username: psn14020 + password: kospo2025! + properties: + smtp: + auth: true + timeout: 5000 + starttls: + enable: true + datasource: + hikari: + username: ENC(gLQTvX57MBGvHAhEGckIJbVdgG5w1YPO+bZk5+xOvg6DhAIcGcyXib8T605t2Icd) + password: ENC(KpBRMJPNmBe/zi0mPo32beSSXteAaSEp/Kf7dVV3ss8Qi4mS2bJ+P0eFw2Qs15sV) + connection-timeout: 20000 + maximum-pool-size: 30 + data-source-properties: + cachePrepStmts: true + prepStmtCacheSize: 200 + prepStmtCacheSqlLimit: 2048 + useServerPrepStmts: true + url: jdbc:log4jdbc:postgresql://hmsn.ink:35432/svcm + driver-class-name: net.sf.log4jdbc.sql.jdbcapi.DriverSpy +jwt: + key: 5840f916c19111ee86fcf38ac250f21377907a8ac19111eebab6e7179f8e5c87 +springdoc: + packages-to-scan: com.kospo.svcm + api-docs: + path: /api-docs + groups: + enabled: true + swagger-ui: + path: /swagger-ui.html + enabled: true + groups-order: ASC + tags-sorter: alpha + operations-sorter: alpha + display-request-duration: true + doc-expansion: none + cache: + disabled: true + model-and-view-allowed: true \ No newline at end of file diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml new file mode 100644 index 0000000..caf4dfc --- /dev/null +++ b/src/main/resources/application.yml @@ -0,0 +1,3 @@ +spring: + profiles: + active: dev \ No newline at end of file diff --git a/src/main/resources/logback-dev.properties b/src/main/resources/logback-dev.properties new file mode 100644 index 0000000..7a106f0 --- /dev/null +++ b/src/main/resources/logback-dev.properties @@ -0,0 +1,4 @@ +log.config.path=./logs/ +log.config.filename=api_log +log.level=debug + diff --git a/src/main/resources/logback-prod.properties b/src/main/resources/logback-prod.properties new file mode 100644 index 0000000..cd70f03 --- /dev/null +++ b/src/main/resources/logback-prod.properties @@ -0,0 +1,4 @@ +log.config.path=./logs/ +log.config.filename=api_log +log.level=warn + diff --git a/src/main/resources/logback-spring.xml b/src/main/resources/logback-spring.xml new file mode 100644 index 0000000..a585d06 --- /dev/null +++ b/src/main/resources/logback-spring.xml @@ -0,0 +1,144 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ${LOG_PATTERN} + + + + + + + + ${LOG_PATH}/${LOG_FILE_NAME}.log + + + + ${LOG_PATTERN} + + + + + + ${LOG_PATH}/${LOG_FILE_NAME}.%d{yyyy-MM-dd}_%i.log + + + 10MB + + + 30 + + + + + + + + error + ACCEPT + DENY + + ${LOG_PATH}/${ERR_LOG_FILE_NAME}.log + + ${LOG_PATTERN} + + + + + ${LOG_PATH}/${ERR_LOG_FILE_NAME}.%d{yyyy-MM-dd}_%i.log + + + 10MB + + + 60 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/private.key b/src/main/resources/private.key new file mode 100644 index 0000000..1981fd6 Binary files /dev/null and b/src/main/resources/private.key differ diff --git a/src/main/resources/public.key b/src/main/resources/public.key new file mode 100644 index 0000000..ec96fbb Binary files /dev/null and b/src/main/resources/public.key differ