정합성 문서 및 결재 입력 테스트 갱신
This commit is contained in:
@@ -453,16 +453,20 @@
|
||||
"transaction_no": "TXN-2025-0001",
|
||||
"transaction_type": {
|
||||
"id": 1,
|
||||
"type_name": "입고"
|
||||
"name": "입고"
|
||||
},
|
||||
"transaction_status": {
|
||||
"id": 1,
|
||||
"status_name": "초안"
|
||||
"name": "초안"
|
||||
},
|
||||
"warehouse": {
|
||||
"id": 1,
|
||||
"warehouse_code": "WH-001",
|
||||
"warehouse_name": "1센터"
|
||||
"warehouse_name": "1센터",
|
||||
"zipcode": {
|
||||
"zipcode": "06000",
|
||||
"road_name": "테헤란로"
|
||||
}
|
||||
},
|
||||
"transaction_date": "2025-09-18",
|
||||
"created_by": {
|
||||
@@ -474,6 +478,7 @@
|
||||
"is_active": true,
|
||||
"created_at": "2025-09-18T05:00:00Z",
|
||||
"updated_at": "2025-09-18T05:00:00Z",
|
||||
"expected_return_date": "2025-09-30",
|
||||
"lines": [
|
||||
{
|
||||
"id": 12001,
|
||||
@@ -499,46 +504,50 @@
|
||||
"customers": [
|
||||
{
|
||||
"id": 301,
|
||||
"customer_code": "C001",
|
||||
"customer_name": "ABC물류",
|
||||
"contact_name": "박담당"
|
||||
"customer": {
|
||||
"id": 301,
|
||||
"customer_code": "C001",
|
||||
"customer_name": "ABC물류"
|
||||
},
|
||||
"note": null
|
||||
}
|
||||
],
|
||||
"approval": {
|
||||
"id": 5001,
|
||||
"approval_no": "APP-2025-0001",
|
||||
"approval_status": {
|
||||
"status": {
|
||||
"id": 1,
|
||||
"status_name": "대기",
|
||||
"name": "대기",
|
||||
"is_blocking_next": true,
|
||||
"is_terminal": false
|
||||
},
|
||||
"current_step": {
|
||||
"id": 7001,
|
||||
"step_order": 1,
|
||||
"status": {
|
||||
"id": 1,
|
||||
"name": "대기",
|
||||
"is_blocking_next": true,
|
||||
"is_terminal": false
|
||||
},
|
||||
"approver": {
|
||||
"id": 21,
|
||||
"employee_no": "E2025002",
|
||||
"employee_name": "박검토"
|
||||
},
|
||||
"step_status": {
|
||||
"id": 1,
|
||||
"status_name": "대기",
|
||||
"is_blocking_next": true,
|
||||
"is_terminal": false
|
||||
"name": "박검토"
|
||||
},
|
||||
"assigned_at": "2025-09-18T06:05:00Z",
|
||||
"decided_at": null,
|
||||
"note": null
|
||||
},
|
||||
"requested_by": {
|
||||
"requester": {
|
||||
"id": 7,
|
||||
"employee_no": "E2025001",
|
||||
"employee_name": "김승인"
|
||||
"name": "김승인"
|
||||
},
|
||||
"requested_at": "2025-09-18T06:00:00Z",
|
||||
"decided_at": null,
|
||||
"note": "입고 결재",
|
||||
"template_name": "입고 결재 기본",
|
||||
"is_active": true,
|
||||
"created_at": "2025-09-18T06:00:00Z",
|
||||
"updated_at": "2025-09-18T06:05:00Z"
|
||||
@@ -560,11 +569,11 @@
|
||||
"transaction_no": "TXN-2025-0001",
|
||||
"transaction_type": {
|
||||
"id": 1,
|
||||
"type_name": "입고"
|
||||
"name": "입고"
|
||||
},
|
||||
"transaction_status": {
|
||||
"id": 1,
|
||||
"status_name": "초안"
|
||||
"name": "초안"
|
||||
},
|
||||
"warehouse": {
|
||||
"id": 1,
|
||||
@@ -572,7 +581,8 @@
|
||||
"warehouse_name": "1센터",
|
||||
"zipcode": {
|
||||
"zipcode": "06000",
|
||||
"sido": "서울특별시"
|
||||
"sido": "서울특별시",
|
||||
"road_name": "테헤란로"
|
||||
}
|
||||
},
|
||||
"transaction_date": "2025-09-18",
|
||||
@@ -585,6 +595,7 @@
|
||||
"is_active": true,
|
||||
"created_at": "2025-09-18T05:00:00Z",
|
||||
"updated_at": "2025-09-18T05:00:00Z",
|
||||
"expected_return_date": "2025-09-30",
|
||||
"lines": [
|
||||
{
|
||||
"id": 12001,
|
||||
@@ -610,17 +621,21 @@
|
||||
"customers": [
|
||||
{
|
||||
"id": 301,
|
||||
"customer_code": "C001",
|
||||
"customer_name": "ABC물류",
|
||||
"contact_name": "박담당"
|
||||
"customer": {
|
||||
"id": 301,
|
||||
"customer_code": "C001",
|
||||
"customer_name": "ABC물류"
|
||||
},
|
||||
"note": null
|
||||
}
|
||||
],
|
||||
"approval": {
|
||||
"id": 5001,
|
||||
"approval_no": "APP-2025-0001",
|
||||
"approval_status": {
|
||||
"status": {
|
||||
"id": 1,
|
||||
"status_name": "대기",
|
||||
"name": "대기",
|
||||
"color": "#F97316",
|
||||
"is_blocking_next": true,
|
||||
"is_terminal": false
|
||||
},
|
||||
@@ -630,11 +645,11 @@
|
||||
"approver": {
|
||||
"id": 21,
|
||||
"employee_no": "E2025002",
|
||||
"employee_name": "박검토"
|
||||
"name": "박검토"
|
||||
},
|
||||
"step_status": {
|
||||
"status": {
|
||||
"id": 1,
|
||||
"status_name": "대기",
|
||||
"name": "대기",
|
||||
"is_blocking_next": true,
|
||||
"is_terminal": false
|
||||
},
|
||||
@@ -642,14 +657,58 @@
|
||||
"decided_at": null,
|
||||
"note": null
|
||||
},
|
||||
"requested_by": {
|
||||
"requester": {
|
||||
"id": 7,
|
||||
"employee_no": "E2025001",
|
||||
"employee_name": "김승인"
|
||||
"name": "김승인"
|
||||
},
|
||||
"requested_at": "2025-09-18T06:00:00Z",
|
||||
"decided_at": null,
|
||||
"note": "입고 결재",
|
||||
"template_name": "입고 결재 기본",
|
||||
"steps": [
|
||||
{
|
||||
"id": 7001,
|
||||
"step_order": 1,
|
||||
"approver": {
|
||||
"id": 21,
|
||||
"employee_no": "E2025002",
|
||||
"name": "박검토"
|
||||
},
|
||||
"status": {
|
||||
"id": 1,
|
||||
"name": "대기",
|
||||
"is_blocking_next": true,
|
||||
"is_terminal": false
|
||||
},
|
||||
"assigned_at": "2025-09-18T06:05:00Z",
|
||||
"decided_at": null,
|
||||
"note": null
|
||||
}
|
||||
],
|
||||
"histories": [
|
||||
{
|
||||
"id": 91001,
|
||||
"action": {
|
||||
"id": 1,
|
||||
"name": "상신"
|
||||
},
|
||||
"from_status": null,
|
||||
"to_status": {
|
||||
"id": 1,
|
||||
"name": "대기",
|
||||
"is_blocking_next": true,
|
||||
"is_terminal": false
|
||||
},
|
||||
"approver": {
|
||||
"id": 7,
|
||||
"employee_no": "E2025001",
|
||||
"name": "김승인"
|
||||
},
|
||||
"action_at": "2025-09-18T06:00:00Z",
|
||||
"note": null
|
||||
}
|
||||
],
|
||||
"is_active": true,
|
||||
"created_at": "2025-09-18T06:00:00Z",
|
||||
"updated_at": "2025-09-18T06:05:00Z"
|
||||
@@ -810,17 +869,17 @@
|
||||
"approval": {
|
||||
"id": 5001,
|
||||
"approval_no": "APP-2025-0001",
|
||||
"approval_status": {
|
||||
"status": {
|
||||
"id": 1,
|
||||
"status_name": "대기",
|
||||
"name": "대기",
|
||||
"is_blocking_next": true,
|
||||
"is_terminal": false
|
||||
},
|
||||
"current_step": null,
|
||||
"requested_by": {
|
||||
"requester": {
|
||||
"id": 7,
|
||||
"employee_no": "E2025001",
|
||||
"employee_name": "김승인"
|
||||
"name": "김승인"
|
||||
},
|
||||
"requested_at": "2025-09-18T06:00:00Z",
|
||||
"decided_at": null,
|
||||
@@ -848,61 +907,86 @@
|
||||
"id": 9001,
|
||||
"transaction_no": "TXN-2025-0001"
|
||||
},
|
||||
"approval_status": {
|
||||
"status": {
|
||||
"id": 1,
|
||||
"status_name": "대기",
|
||||
"is_blocking_next": true
|
||||
"name": "대기",
|
||||
"color": "#F97316",
|
||||
"is_blocking_next": true,
|
||||
"is_terminal": false
|
||||
},
|
||||
"current_step": {
|
||||
"id": 7001,
|
||||
"step_order": 1,
|
||||
"status": {
|
||||
"id": 1,
|
||||
"name": "대기",
|
||||
"is_blocking_next": true,
|
||||
"is_terminal": false
|
||||
},
|
||||
"approver": {
|
||||
"id": 21,
|
||||
"employee_no": "E2025002",
|
||||
"employee_name": "박검토"
|
||||
},
|
||||
"step_status": {
|
||||
"id": 1,
|
||||
"status_name": "대기",
|
||||
"is_blocking_next": true,
|
||||
"is_terminal": false
|
||||
"name": "박검토"
|
||||
},
|
||||
"assigned_at": "2025-09-18T06:05:00Z",
|
||||
"decided_at": null,
|
||||
"note": null
|
||||
},
|
||||
"requested_by": {
|
||||
"requester": {
|
||||
"id": 7,
|
||||
"employee_no": "E2025001",
|
||||
"employee_name": "김승인"
|
||||
"name": "김승인"
|
||||
},
|
||||
"requested_at": "2025-09-18T06:00:00Z",
|
||||
"decided_at": null,
|
||||
"note": "입고 결재",
|
||||
"is_active": true,
|
||||
"is_deleted": false,
|
||||
"created_at": "2025-09-18T06:00:00Z",
|
||||
"updated_at": "2025-09-18T06:00:00Z",
|
||||
"updated_at": "2025-09-18T06:05:00Z",
|
||||
"steps": [
|
||||
{
|
||||
"id": 7001,
|
||||
"step_order": 1,
|
||||
"status": {
|
||||
"id": 1,
|
||||
"name": "대기",
|
||||
"is_blocking_next": true,
|
||||
"is_terminal": false
|
||||
},
|
||||
"approver": {
|
||||
"id": 21,
|
||||
"employee_no": "E2025002",
|
||||
"employee_name": "박검토"
|
||||
},
|
||||
"step_status": {
|
||||
"id": 1,
|
||||
"status_name": "대기",
|
||||
"is_blocking_next": true,
|
||||
"is_terminal": false
|
||||
"name": "박검토"
|
||||
},
|
||||
"assigned_at": "2025-09-18T06:05:00Z",
|
||||
"decided_at": null,
|
||||
"note": null
|
||||
}
|
||||
],
|
||||
"histories": []
|
||||
"histories": [
|
||||
{
|
||||
"id": 91001,
|
||||
"action": {
|
||||
"id": 1,
|
||||
"name": "상신"
|
||||
},
|
||||
"from_status": null,
|
||||
"to_status": {
|
||||
"id": 1,
|
||||
"name": "대기",
|
||||
"is_blocking_next": true,
|
||||
"is_terminal": false
|
||||
},
|
||||
"approver": {
|
||||
"id": 7,
|
||||
"employee_no": "E2025001",
|
||||
"name": "김승인"
|
||||
},
|
||||
"action_at": "2025-09-18T06:00:00Z",
|
||||
"note": null
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"page": 1,
|
||||
@@ -922,34 +1006,35 @@
|
||||
"id": 9001,
|
||||
"transaction_no": "TXN-2025-0001"
|
||||
},
|
||||
"approval_status": {
|
||||
"status": {
|
||||
"id": 1,
|
||||
"status_name": "대기",
|
||||
"name": "대기",
|
||||
"color": "#F97316",
|
||||
"is_blocking_next": true,
|
||||
"is_terminal": false
|
||||
},
|
||||
"current_step": {
|
||||
"id": 7001,
|
||||
"step_order": 1,
|
||||
"status": {
|
||||
"id": 1,
|
||||
"name": "대기",
|
||||
"is_blocking_next": true,
|
||||
"is_terminal": false
|
||||
},
|
||||
"approver": {
|
||||
"id": 21,
|
||||
"employee_no": "E2025002",
|
||||
"employee_name": "박검토"
|
||||
},
|
||||
"step_status": {
|
||||
"id": 1,
|
||||
"status_name": "대기",
|
||||
"is_blocking_next": true,
|
||||
"is_terminal": false
|
||||
"name": "박검토"
|
||||
},
|
||||
"assigned_at": "2025-09-18T06:05:00Z",
|
||||
"decided_at": null,
|
||||
"note": null
|
||||
},
|
||||
"requested_by": {
|
||||
"requester": {
|
||||
"id": 7,
|
||||
"employee_no": "E2025001",
|
||||
"employee_name": "김승인"
|
||||
"name": "김승인"
|
||||
},
|
||||
"requested_at": "2025-09-18T06:00:00Z",
|
||||
"decided_at": null,
|
||||
@@ -958,22 +1043,47 @@
|
||||
{
|
||||
"id": 7001,
|
||||
"step_order": 1,
|
||||
"status": {
|
||||
"id": 1,
|
||||
"name": "대기",
|
||||
"is_blocking_next": true,
|
||||
"is_terminal": false
|
||||
},
|
||||
"approver": {
|
||||
"id": 21,
|
||||
"employee_no": "E2025002",
|
||||
"employee_name": "박검토"
|
||||
},
|
||||
"step_status": {
|
||||
"id": 1,
|
||||
"status_name": "대기",
|
||||
"is_blocking_next": true
|
||||
"name": "박검토"
|
||||
},
|
||||
"assigned_at": "2025-09-18T06:05:00Z",
|
||||
"decided_at": null,
|
||||
"note": null
|
||||
}
|
||||
],
|
||||
"histories": [],
|
||||
"histories": [
|
||||
{
|
||||
"id": 91001,
|
||||
"action": {
|
||||
"id": 1,
|
||||
"name": "상신"
|
||||
},
|
||||
"from_status": null,
|
||||
"to_status": {
|
||||
"id": 1,
|
||||
"name": "대기",
|
||||
"is_blocking_next": true,
|
||||
"is_terminal": false
|
||||
},
|
||||
"approver": {
|
||||
"id": 7,
|
||||
"employee_no": "E2025001",
|
||||
"name": "김승인"
|
||||
},
|
||||
"action_at": "2025-09-18T06:00:00Z",
|
||||
"note": null
|
||||
}
|
||||
],
|
||||
"is_active": true,
|
||||
"is_deleted": false,
|
||||
"created_at": "2025-09-18T06:00:00Z",
|
||||
"updated_at": "2025-09-18T06:05:00Z"
|
||||
}
|
||||
@@ -1011,6 +1121,12 @@
|
||||
"step_order": 1,
|
||||
"approver_id": 21,
|
||||
"step_status_id": 1,
|
||||
"status": {
|
||||
"id": 1,
|
||||
"name": "대기",
|
||||
"is_blocking_next": true,
|
||||
"is_terminal": false
|
||||
},
|
||||
"assigned_at": "2025-09-18T06:05:00Z",
|
||||
"decided_at": null,
|
||||
"note": null,
|
||||
@@ -1022,6 +1138,12 @@
|
||||
"step_order": 2,
|
||||
"approver_id": 34,
|
||||
"step_status_id": 1,
|
||||
"status": {
|
||||
"id": 1,
|
||||
"name": "대기",
|
||||
"is_blocking_next": true,
|
||||
"is_terminal": false
|
||||
},
|
||||
"assigned_at": "2025-09-18T06:05:00Z",
|
||||
"decided_at": null,
|
||||
"note": "재무 확인",
|
||||
@@ -1030,9 +1152,9 @@
|
||||
],
|
||||
"approval": {
|
||||
"id": 5001,
|
||||
"approval_status": {
|
||||
"status": {
|
||||
"id": 1,
|
||||
"status_name": "대기",
|
||||
"name": "대기",
|
||||
"is_blocking_next": true,
|
||||
"is_terminal": false
|
||||
},
|
||||
@@ -1040,6 +1162,7 @@
|
||||
"id": 7001,
|
||||
"step_order": 1
|
||||
},
|
||||
"template_name": "입고 결재 기본",
|
||||
"updated_at": "2025-09-18T06:05:00Z"
|
||||
}
|
||||
}
|
||||
@@ -1077,6 +1200,12 @@
|
||||
"step_order": 1,
|
||||
"approver_id": 21,
|
||||
"step_status_id": 1,
|
||||
"status": {
|
||||
"id": 1,
|
||||
"name": "대기",
|
||||
"is_blocking_next": true,
|
||||
"is_terminal": false
|
||||
},
|
||||
"assigned_at": "2025-09-18T06:05:00Z",
|
||||
"decided_at": null,
|
||||
"note": "서류 확인 중",
|
||||
@@ -1088,6 +1217,12 @@
|
||||
"step_order": 2,
|
||||
"approver_id": 35,
|
||||
"step_status_id": 1,
|
||||
"status": {
|
||||
"id": 1,
|
||||
"name": "대기",
|
||||
"is_blocking_next": true,
|
||||
"is_terminal": false
|
||||
},
|
||||
"assigned_at": "2025-09-18T06:05:00Z",
|
||||
"decided_at": null,
|
||||
"note": "재무 확인",
|
||||
@@ -1096,9 +1231,9 @@
|
||||
],
|
||||
"approval": {
|
||||
"id": 5001,
|
||||
"approval_status": {
|
||||
"status": {
|
||||
"id": 1,
|
||||
"status_name": "대기",
|
||||
"name": "대기",
|
||||
"is_blocking_next": true,
|
||||
"is_terminal": false
|
||||
},
|
||||
@@ -1106,6 +1241,7 @@
|
||||
"id": 7001,
|
||||
"step_order": 1
|
||||
},
|
||||
"template_name": "입고 결재 기본",
|
||||
"updated_at": "2025-09-18T06:10:00Z"
|
||||
}
|
||||
}
|
||||
@@ -1127,9 +1263,9 @@
|
||||
"data": {
|
||||
"approval": {
|
||||
"id": 5001,
|
||||
"approval_status": {
|
||||
"status": {
|
||||
"id": 2,
|
||||
"status_name": "진행중",
|
||||
"name": "진행중",
|
||||
"is_blocking_next": true,
|
||||
"is_terminal": false
|
||||
},
|
||||
@@ -1139,11 +1275,11 @@
|
||||
"approver": {
|
||||
"id": 34,
|
||||
"employee_no": "E2025003",
|
||||
"employee_name": "최검토"
|
||||
"name": "최검토"
|
||||
},
|
||||
"step_status": {
|
||||
"status": {
|
||||
"id": 3,
|
||||
"status_name": "진행중",
|
||||
"name": "진행중",
|
||||
"is_blocking_next": true,
|
||||
"is_terminal": false
|
||||
},
|
||||
@@ -1155,18 +1291,21 @@
|
||||
"histories": [
|
||||
{
|
||||
"id": 91001,
|
||||
"approval_action_id": 1,
|
||||
"action": {
|
||||
"id": 1,
|
||||
"name": "승인"
|
||||
},
|
||||
"action_at": "2025-09-18T08:05:00Z",
|
||||
"note": "승인합니다.",
|
||||
"from_status": {
|
||||
"id": 1,
|
||||
"status_name": "대기",
|
||||
"name": "대기",
|
||||
"is_blocking_next": true,
|
||||
"is_terminal": false
|
||||
},
|
||||
"to_status": {
|
||||
"id": 2,
|
||||
"status_name": "진행중",
|
||||
"name": "진행중",
|
||||
"is_blocking_next": true,
|
||||
"is_terminal": false
|
||||
}
|
||||
@@ -1179,15 +1318,15 @@
|
||||
"step_order": 1,
|
||||
"approver_id": 21,
|
||||
"step_status_id": 2,
|
||||
"assigned_at": "2025-09-18T06:05:00Z",
|
||||
"decided_at": "2025-09-18T08:05:00Z",
|
||||
"note": "승인합니다.",
|
||||
"step_status": {
|
||||
"status": {
|
||||
"id": 2,
|
||||
"status_name": "진행중",
|
||||
"name": "진행중",
|
||||
"is_blocking_next": true,
|
||||
"is_terminal": false
|
||||
}
|
||||
},
|
||||
"assigned_at": "2025-09-18T06:05:00Z",
|
||||
"decided_at": "2025-09-18T08:05:00Z",
|
||||
"note": "승인합니다."
|
||||
},
|
||||
"next_step": {
|
||||
"id": 7002,
|
||||
@@ -1195,11 +1334,11 @@
|
||||
"approver": {
|
||||
"id": 34,
|
||||
"employee_no": "E2025003",
|
||||
"employee_name": "최검토"
|
||||
"name": "최검토"
|
||||
},
|
||||
"step_status": {
|
||||
"status": {
|
||||
"id": 3,
|
||||
"status_name": "진행중",
|
||||
"name": "진행중",
|
||||
"is_blocking_next": true,
|
||||
"is_terminal": false
|
||||
},
|
||||
@@ -1210,7 +1349,10 @@
|
||||
"history": {
|
||||
"id": 91001,
|
||||
"approval_step_id": 7001,
|
||||
"approval_action_id": 1,
|
||||
"action": {
|
||||
"id": 1,
|
||||
"name": "승인"
|
||||
},
|
||||
"note": "승인합니다.",
|
||||
"action_at": "2025-09-18T08:05:00Z"
|
||||
}
|
||||
@@ -1247,9 +1389,9 @@
|
||||
"approval": {
|
||||
"id": 5001,
|
||||
"approval_no": "APP-2025-0001",
|
||||
"approval_status": {
|
||||
"status": {
|
||||
"id": 2,
|
||||
"status_name": "진행중",
|
||||
"name": "진행중",
|
||||
"is_blocking_next": true,
|
||||
"is_terminal": false
|
||||
},
|
||||
@@ -1257,14 +1399,15 @@
|
||||
"id": 7002,
|
||||
"step_order": 2
|
||||
},
|
||||
"requested_by": {
|
||||
"requester": {
|
||||
"id": 7,
|
||||
"employee_no": "E2025001",
|
||||
"employee_name": "김승인"
|
||||
"name": "김승인"
|
||||
},
|
||||
"requested_at": "2025-09-18T06:00:00Z",
|
||||
"decided_at": null,
|
||||
"note": "보류 처리",
|
||||
"template_name": "입고 결재 기본",
|
||||
"updated_at": "2025-09-18T08:10:00Z"
|
||||
}
|
||||
}
|
||||
@@ -1282,7 +1425,10 @@
|
||||
"id": 91001,
|
||||
"approval_id": 5001,
|
||||
"approval_step_id": 7001,
|
||||
"approval_action_id": 3,
|
||||
"action": {
|
||||
"id": 3,
|
||||
"name": "보류"
|
||||
},
|
||||
"action_at": "2025-09-18T08:05:00Z",
|
||||
"note": "보류 코멘트",
|
||||
"approver": {
|
||||
@@ -1292,22 +1438,22 @@
|
||||
},
|
||||
"from_status": {
|
||||
"id": 1,
|
||||
"status_name": "대기",
|
||||
"name": "대기",
|
||||
"is_blocking_next": true,
|
||||
"is_terminal": false
|
||||
},
|
||||
"to_status": {
|
||||
"id": 2,
|
||||
"status_name": "진행중",
|
||||
"name": "진행중",
|
||||
"is_blocking_next": true,
|
||||
"is_terminal": false
|
||||
},
|
||||
"approval": {
|
||||
"id": 5001,
|
||||
"approval_no": "APP-2025-0001",
|
||||
"approval_status": {
|
||||
"status": {
|
||||
"id": 2,
|
||||
"status_name": "진행중",
|
||||
"name": "진행중",
|
||||
"is_blocking_next": true,
|
||||
"is_terminal": false
|
||||
}
|
||||
@@ -1319,7 +1465,13 @@
|
||||
"approver": {
|
||||
"id": 21,
|
||||
"employee_no": "E2025002",
|
||||
"employee_name": "박검토"
|
||||
"name": "박검토"
|
||||
},
|
||||
"status": {
|
||||
"id": 2,
|
||||
"name": "진행중",
|
||||
"is_blocking_next": true,
|
||||
"is_terminal": false
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1331,8 +1483,8 @@
|
||||
```
|
||||
|
||||
### 5.10 단계 개별 CRUD
|
||||
- `GET /approval-steps?approval_id=5001&include=approver,step_status` → `{ items: [], page, page_size, total }` 형태로 반환하며, 각 항목은 `approval`, `approver`, `step_status` 서브 오브젝트를 선택적으로 포함한다.
|
||||
- `GET /approval-steps/7001?include=approval,approver,step_status` → `{ data: { ... } }`.
|
||||
- `GET /approval-steps?approval_id=5001&include=approval,approver,status` → `{ items: [], page, page_size, total }` 형태로 반환하며, 각 항목은 `approval`, `approver`, `status` 서브 오브젝트를 선택적으로 포함한다.
|
||||
- `GET /approval-steps/7001?include=approval,approver,status` → `{ data: { ... } }`.
|
||||
- `POST /approval-steps` → 단일 단계를 생성하고 `{ data: { ... } }` 형태로 생성된 요약을 반환한다. `step_status_id`를 생략하면 자동으로 `대기` 상태가 지정된다.
|
||||
- `PATCH /approval-steps/{id}` → 갱신된 단계 요약을 반환한다.
|
||||
- `DELETE /approval-steps/{id}` → `{ data: { id, deleted_at } }`.
|
||||
@@ -1352,7 +1504,10 @@
|
||||
"id": 91001,
|
||||
"approval_id": 5001,
|
||||
"approval_step_id": 7001,
|
||||
"approval_action_id": 3,
|
||||
"action": {
|
||||
"id": 3,
|
||||
"name": "보류"
|
||||
},
|
||||
"action_at": "2025-09-18T08:05:00Z",
|
||||
"note": "보류 코멘트",
|
||||
"approver": {
|
||||
@@ -1363,16 +1518,16 @@
|
||||
"from_status": null,
|
||||
"to_status": {
|
||||
"id": 2,
|
||||
"status_name": "진행중",
|
||||
"name": "진행중",
|
||||
"is_blocking_next": true,
|
||||
"is_terminal": false
|
||||
},
|
||||
"approval": {
|
||||
"id": 5001,
|
||||
"approval_no": "APP-2025-0001",
|
||||
"approval_status": {
|
||||
"status": {
|
||||
"id": 2,
|
||||
"status_name": "진행중",
|
||||
"name": "진행중",
|
||||
"is_blocking_next": true,
|
||||
"is_terminal": false
|
||||
}
|
||||
@@ -1385,6 +1540,12 @@
|
||||
"id": 21,
|
||||
"employee_no": "E2025002",
|
||||
"employee_name": "박검토"
|
||||
},
|
||||
"status": {
|
||||
"id": 2,
|
||||
"name": "진행중",
|
||||
"is_blocking_next": true,
|
||||
"is_terminal": false
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1512,36 +1673,132 @@
|
||||
---
|
||||
|
||||
## 7. 보고서 Export
|
||||
- `format=xlsx|pdf` 파라미터를 지원한다. 현재 구현은 XLSX 다운로드만 제공하며, `format=pdf` 요청 시 400 Bad Request를 반환한다.
|
||||
- `delivery=stream|metadata`(기본값 `stream`) 파라미터를 지원한다.
|
||||
- `delivery=metadata` 요청 시 다운로드 메타데이터를 반환한다.
|
||||
`GET /reports/transactions/export?from=2025-09-01&to=2025-09-30&transaction_status_id=2&delivery=metadata`
|
||||
```json
|
||||
{
|
||||
"data": {
|
||||
"download_url": "/api/v1/reports/transactions/export?from=2025-09-01&to=2025-09-30&transaction_status_id=2&delivery=stream&exported_at=2025-09-30T12:00:00Z",
|
||||
"filename": "transactions_export_20250930120000.xlsx",
|
||||
"mime_type": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
||||
"expires_at": "2025-09-30T12:15:00Z"
|
||||
}
|
||||
- 공통 쿼리 파라미터: `from`, `to`, `format=xlsx|pdf`, `transaction_status_id`, `approval_status_id`, `requested_by_id`. 필요 시 `delivery=metadata`를 전달하면 스트리밍 대신 다운로드 메타데이터(JSON)를 반환한다.
|
||||
- 기본 응답(`delivery=stream` 또는 파라미터 생략)은 `Content-Type`을 포맷에 맞춰 설정하고 `Content-Disposition: attachment; filename="<파일명>"` 헤더를 포함한 바이트 스트림이다.
|
||||
- `delivery=metadata` 응답 예:
|
||||
`GET /reports/transactions/export?from=2025-09-01&to=2025-09-30&transaction_status_id=2&delivery=metadata`
|
||||
```json
|
||||
{
|
||||
"data": {
|
||||
"download_url": "/api/v1/reports/transactions/export?from=2025-09-01&to=2025-09-30&transaction_status_id=2&format=xlsx",
|
||||
"filename": "transactions_export_20250930120000.xlsx",
|
||||
"mime_type": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
||||
"expires_at": "2025-09-30T12:15:00Z"
|
||||
}
|
||||
```
|
||||
`download_url`에는 `delivery=stream`과 `exported_at` 값이 포함되며, 해당 URL을 그대로 호출하면 동일한 파일명을 유지한 스트리밍 응답을 받을 수 있다.
|
||||
- `delivery=stream` 요청(기본값)은 `Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet`, `Content-Disposition: attachment` 헤더를 포함한 바이트 스트림을 반환한다.
|
||||
}
|
||||
```
|
||||
- 감사 로그와 권한 검증은 모든 Export 호출에 공통 적용한다.
|
||||
|
||||
### 7.1 트랜잭션 Export
|
||||
`GET /reports/transactions/export?from=2025-09-01&to=2025-09-30&transaction_status_id=2&warehouse_id=1&requested_by_id=7&format=xlsx`
|
||||
- 열 구성: `Transaction No`, `Transaction Date`, `Transaction Type`, `Status`, `Warehouse`, `Created By`, `Approval No`, `Approval Status`
|
||||
- `approval_status_id`, `requested_by_id` 파라미터로 결재 상태·요청자 기준 필터링이 가능하다.
|
||||
- `from`, `to`는 `yyyy-MM-dd` 형식으로 요청하며, 날짜는 트랜잭션 발생일 기준이다.
|
||||
- 응답 열 구성: `Transaction No`, `Transaction Date`, `Transaction Type`, `Status`, `Warehouse`, `Created By`, `Approval No`, `Approval Status`.
|
||||
- `approval_status_id`, `requested_by_id`, `transaction_status_id`로 필터링이 가능하다.
|
||||
|
||||
### 7.2 결재 Export
|
||||
`GET /reports/approvals/export?approval_status_id=1&requested_by_id=7&from=2025-09-01T00:00:00Z&to=2025-09-30T23:59:59Z&format=xlsx`
|
||||
- 열 구성: `Approval No`, `Approval Status`, `Transaction No`, `Requested By`, `Requested At`, `Decided At`, `Current Step Order`, `Current Step Approver`
|
||||
- `from`, `to` 파라미터는 `requested_at` 기준 UTC 타임스탬프 필터로 동작한다.
|
||||
`GET /reports/approvals/export?approval_status_id=1&requested_by_id=7&from=2025-09-01T00:00:00Z&to=2025-09-30T23:59:59Z&format=pdf`
|
||||
- `from`, `to`는 ISO8601 UTC 문자열이며 `requested_at` 기준으로 필터링한다.
|
||||
- 응답 열 구성: `Approval No`, `Approval Status`, `Transaction No`, `Requested By`, `Requested At`, `Decided At`, `Current Step Order`, `Current Step Approver`.
|
||||
|
||||
---
|
||||
|
||||
## 8. 구현 참고
|
||||
## 8. 인증 및 대시보드 API
|
||||
- `POST /auth/login`
|
||||
```json
|
||||
{
|
||||
"identifier": "user@example.com",
|
||||
"password": "Sup3rS3cret!",
|
||||
"remember_me": true
|
||||
}
|
||||
```
|
||||
응답:
|
||||
```json
|
||||
{
|
||||
"data": {
|
||||
"access_token": "<jwt>",
|
||||
"refresh_token": "<jwt>",
|
||||
"expires_at": "2025-09-18T09:00:00Z",
|
||||
"user": {
|
||||
"id": 7,
|
||||
"name": "김승인",
|
||||
"employee_no": "E2025001",
|
||||
"email": "approver@example.com",
|
||||
"primary_group": {
|
||||
"id": 3,
|
||||
"name": "물류팀"
|
||||
}
|
||||
},
|
||||
"permissions": [
|
||||
{
|
||||
"resource": "/dashboard",
|
||||
"actions": ["read"]
|
||||
},
|
||||
{
|
||||
"resource": "/approvals",
|
||||
"actions": ["read", "update"]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
- `POST /auth/refresh`
|
||||
```json
|
||||
{
|
||||
"refresh_token": "<jwt>"
|
||||
}
|
||||
```
|
||||
응답은 로그인과 동일한 스키마를 따른다.
|
||||
- 인증 실패 시 `401`, 잠금·권한 오류 시 `403`을 반환하며 `{ "error": { "code": 401, "message": "...", "details": [...] } }` 형식을 유지한다.
|
||||
- 토큰/계정 상태별 메시지 매핑
|
||||
- 잘못된 자격 증명: `invalid credentials`
|
||||
- 비활성 계정 접근: `account is inactive`
|
||||
- 만료된 토큰: `token expired`
|
||||
- 재사용·서명 오류: `invalid token`
|
||||
|
||||
### 8.1 대시보드 요약
|
||||
`GET /dashboard/summary`
|
||||
```json
|
||||
{
|
||||
"data": {
|
||||
"generated_at": "2025-09-18T08:00:00Z",
|
||||
"kpis": [
|
||||
{
|
||||
"key": "inbound_today",
|
||||
"label": "오늘 입고",
|
||||
"value": 12,
|
||||
"trend_label": "어제 대비",
|
||||
"delta": 0.2
|
||||
},
|
||||
{
|
||||
"key": "pending_approvals",
|
||||
"label": "대기 결재",
|
||||
"value": 5
|
||||
}
|
||||
],
|
||||
"recent_transactions": [
|
||||
{
|
||||
"transaction_no": "TXN-2025-0001",
|
||||
"transaction_date": "2025-09-18",
|
||||
"transaction_type": "입고",
|
||||
"status_name": "상신",
|
||||
"created_by": "김승인"
|
||||
}
|
||||
],
|
||||
"pending_approvals": [
|
||||
{
|
||||
"approval_no": "APP-2025-0005",
|
||||
"title": "출고 결재",
|
||||
"step_summary": "2단계/3단계 진행중",
|
||||
"requested_at": "2025-09-17T03:00:00Z"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 9. 구현 참고
|
||||
- FK 요약 정보는 기본 응답에 포함하며, 상세 정보가 필요하면 `include` 파라미터를 활용해 확장한다.
|
||||
- 배열 기반 다건 작업은 전체를 트랜잭션 처리해야 한다. 실패 시 롤백하고 부분 처리 결과를 반환하지 않는다.
|
||||
- `is_active` 변경은 권한·결재 등의 즉시성 요구를 고려하여 관련 캐시를 무효화한다.
|
||||
|
||||
Reference in New Issue
Block a user