feat: 근태관리/직원관리 API 구현
- AttendanceController, AttendanceService 추가 - EmployeeController, EmployeeService 추가 - Attendance 모델 및 마이그레이션 추가 - TenantUserProfile에 employee_status 컬럼 추가 - DepartmentService 트리 조회 기능 개선 - Swagger 문서 추가 (AttendanceApi, EmployeeApi) - API 라우트 등록
This commit is contained in:
@@ -13,6 +13,8 @@
|
||||
use App\Http\Controllers\Api\V1\ClientGroupController;
|
||||
use App\Http\Controllers\Api\V1\CommonController;
|
||||
use App\Http\Controllers\Api\V1\DepartmentController;
|
||||
use App\Http\Controllers\Api\V1\EmployeeController;
|
||||
use App\Http\Controllers\Api\V1\AttendanceController;
|
||||
use App\Http\Controllers\Api\V1\Design\AuditLogController as DesignAuditLogController;
|
||||
use App\Http\Controllers\Api\V1\Design\BomCalculationController;
|
||||
use App\Http\Controllers\Api\V1\Design\BomTemplateController as DesignBomTemplateController;
|
||||
@@ -30,6 +32,9 @@
|
||||
use App\Http\Controllers\Api\V1\ItemMaster\ItemSectionController;
|
||||
use App\Http\Controllers\Api\V1\ItemMaster\SectionTemplateController;
|
||||
use App\Http\Controllers\Api\V1\ItemMaster\UnitOptionController;
|
||||
use App\Http\Controllers\Api\V1\ItemsBomController;
|
||||
use App\Http\Controllers\Api\V1\ItemsController;
|
||||
use App\Http\Controllers\Api\V1\ItemsFileController;
|
||||
use App\Http\Controllers\Api\V1\MaterialController;
|
||||
use App\Http\Controllers\Api\V1\MenuController;
|
||||
use App\Http\Controllers\Api\V1\ModelSetController;
|
||||
@@ -194,6 +199,7 @@
|
||||
Route::prefix('departments')->group(function () {
|
||||
Route::get('', [DepartmentController::class, 'index'])->name('v1.departments.index'); // 목록
|
||||
Route::post('', [DepartmentController::class, 'store'])->name('v1.departments.store'); // 생성
|
||||
Route::get('/tree', [DepartmentController::class, 'tree'])->name('v1.departments.tree'); // 트리
|
||||
Route::get('/{id}', [DepartmentController::class, 'show'])->name('v1.departments.show'); // 단건
|
||||
Route::patch('/{id}', [DepartmentController::class, 'update'])->name('v1.departments.update'); // 수정
|
||||
Route::delete('/{id}', [DepartmentController::class, 'destroy'])->name('v1.departments.destroy'); // 삭제(soft)
|
||||
@@ -210,6 +216,31 @@
|
||||
Route::delete('/{id}/permissions/{permission}', [DepartmentController::class, 'revokePermissions'])->name('v1.departments.permissions.revoke'); // 권한 제거(해당 메뉴 범위까지)
|
||||
});
|
||||
|
||||
// Employee API (사원 관리)
|
||||
Route::prefix('employees')->group(function () {
|
||||
Route::get('', [EmployeeController::class, 'index'])->name('v1.employees.index');
|
||||
Route::post('', [EmployeeController::class, 'store'])->name('v1.employees.store');
|
||||
Route::get('/stats', [EmployeeController::class, 'stats'])->name('v1.employees.stats');
|
||||
Route::get('/{id}', [EmployeeController::class, 'show'])->name('v1.employees.show');
|
||||
Route::patch('/{id}', [EmployeeController::class, 'update'])->name('v1.employees.update');
|
||||
Route::delete('/{id}', [EmployeeController::class, 'destroy'])->name('v1.employees.destroy');
|
||||
Route::post('/bulk-delete', [EmployeeController::class, 'bulkDelete'])->name('v1.employees.bulkDelete');
|
||||
Route::post('/{id}/create-account', [EmployeeController::class, 'createAccount'])->name('v1.employees.createAccount');
|
||||
});
|
||||
|
||||
// Attendance API (근태 관리)
|
||||
Route::prefix('attendances')->group(function () {
|
||||
Route::get('', [AttendanceController::class, 'index'])->name('v1.attendances.index');
|
||||
Route::post('', [AttendanceController::class, 'store'])->name('v1.attendances.store');
|
||||
Route::get('/monthly-stats', [AttendanceController::class, 'monthlyStats'])->name('v1.attendances.monthlyStats');
|
||||
Route::post('/check-in', [AttendanceController::class, 'checkIn'])->name('v1.attendances.checkIn');
|
||||
Route::post('/check-out', [AttendanceController::class, 'checkOut'])->name('v1.attendances.checkOut');
|
||||
Route::get('/{id}', [AttendanceController::class, 'show'])->name('v1.attendances.show');
|
||||
Route::patch('/{id}', [AttendanceController::class, 'update'])->name('v1.attendances.update');
|
||||
Route::delete('/{id}', [AttendanceController::class, 'destroy'])->name('v1.attendances.destroy');
|
||||
Route::post('/bulk-delete', [AttendanceController::class, 'bulkDelete'])->name('v1.attendances.bulkDelete');
|
||||
});
|
||||
|
||||
// Permission API
|
||||
Route::prefix('permissions')->group(function () {
|
||||
Route::get('departments/{dept_id}/menu-matrix', [PermissionController::class, 'deptMenuMatrix'])->name('v1.permissions.deptMenuMatrix'); // 부서별 권한 메트릭스
|
||||
@@ -408,33 +439,33 @@
|
||||
|
||||
// Items (통합 품목 조회 - materials + products UNION)
|
||||
Route::prefix('items')->group(function () {
|
||||
Route::get('', [\App\Http\Controllers\Api\V1\ItemsController::class, 'index'])->name('v1.items.index'); // 통합 목록
|
||||
Route::post('', [\App\Http\Controllers\Api\V1\ItemsController::class, 'store'])->name('v1.items.store'); // 품목 생성
|
||||
Route::get('/code/{code}', [\App\Http\Controllers\Api\V1\ItemsController::class, 'showByCode'])->name('v1.items.show_by_code'); // code 기반 조회
|
||||
Route::get('/{id}', [\App\Http\Controllers\Api\V1\ItemsController::class, 'show'])->name('v1.items.show'); // 단건 (item_type 파라미터 필수)
|
||||
Route::put('/{id}', [\App\Http\Controllers\Api\V1\ItemsController::class, 'update'])->name('v1.items.update'); // 품목 수정
|
||||
Route::delete('/batch', [\App\Http\Controllers\Api\V1\ItemsController::class, 'batchDestroy'])->name('v1.items.batch_destroy'); // 품목 일괄 삭제
|
||||
Route::delete('/{id}', [\App\Http\Controllers\Api\V1\ItemsController::class, 'destroy'])->name('v1.items.destroy'); // 품목 삭제
|
||||
Route::get('', [ItemsController::class, 'index'])->name('v1.items.index'); // 통합 목록
|
||||
Route::post('', [ItemsController::class, 'store'])->name('v1.items.store'); // 품목 생성
|
||||
Route::get('/code/{code}', [ItemsController::class, 'showByCode'])->name('v1.items.show_by_code'); // code 기반 조회
|
||||
Route::get('/{id}', [ItemsController::class, 'show'])->name('v1.items.show'); // 단건 (item_type 파라미터 필수)
|
||||
Route::put('/{id}', [ItemsController::class, 'update'])->name('v1.items.update'); // 품목 수정
|
||||
Route::delete('/batch', [ItemsController::class, 'batchDestroy'])->name('v1.items.batch_destroy'); // 품목 일괄 삭제
|
||||
Route::delete('/{id}', [ItemsController::class, 'destroy'])->name('v1.items.destroy'); // 품목 삭제
|
||||
});
|
||||
|
||||
// Items BOM (ID-based BOM API)
|
||||
Route::prefix('items/{id}/bom')->group(function () {
|
||||
Route::get('', [\App\Http\Controllers\Api\V1\ItemsBomController::class, 'index'])->name('v1.items.bom.index'); // BOM 목록 (flat)
|
||||
Route::get('/tree', [\App\Http\Controllers\Api\V1\ItemsBomController::class, 'tree'])->name('v1.items.bom.tree'); // BOM 트리 (계층)
|
||||
Route::post('', [\App\Http\Controllers\Api\V1\ItemsBomController::class, 'store'])->name('v1.items.bom.store'); // BOM 추가 (bulk)
|
||||
Route::put('/{lineId}', [\App\Http\Controllers\Api\V1\ItemsBomController::class, 'update'])->name('v1.items.bom.update'); // BOM 수정
|
||||
Route::delete('/{lineId}', [\App\Http\Controllers\Api\V1\ItemsBomController::class, 'destroy'])->name('v1.items.bom.destroy'); // BOM 삭제
|
||||
Route::get('/summary', [\App\Http\Controllers\Api\V1\ItemsBomController::class, 'summary'])->name('v1.items.bom.summary'); // BOM 요약
|
||||
Route::get('/validate', [\App\Http\Controllers\Api\V1\ItemsBomController::class, 'validate'])->name('v1.items.bom.validate'); // BOM 검증
|
||||
Route::post('/replace', [\App\Http\Controllers\Api\V1\ItemsBomController::class, 'replace'])->name('v1.items.bom.replace'); // BOM 전체 교체
|
||||
Route::post('/reorder', [\App\Http\Controllers\Api\V1\ItemsBomController::class, 'reorder'])->name('v1.items.bom.reorder'); // BOM 정렬
|
||||
Route::get('/categories', [\App\Http\Controllers\Api\V1\ItemsBomController::class, 'listCategories'])->name('v1.items.bom.categories'); // 카테고리 목록
|
||||
Route::get('', [ItemsBomController::class, 'index'])->name('v1.items.bom.index'); // BOM 목록 (flat)
|
||||
Route::get('/tree', [ItemsBomController::class, 'tree'])->name('v1.items.bom.tree'); // BOM 트리 (계층)
|
||||
Route::post('', [ItemsBomController::class, 'store'])->name('v1.items.bom.store'); // BOM 추가 (bulk)
|
||||
Route::put('/{lineId}', [ItemsBomController::class, 'update'])->name('v1.items.bom.update'); // BOM 수정
|
||||
Route::delete('/{lineId}', [ItemsBomController::class, 'destroy'])->name('v1.items.bom.destroy'); // BOM 삭제
|
||||
Route::get('/summary', [ItemsBomController::class, 'summary'])->name('v1.items.bom.summary'); // BOM 요약
|
||||
Route::get('/validate', [ItemsBomController::class, 'validate'])->name('v1.items.bom.validate'); // BOM 검증
|
||||
Route::post('/replace', [ItemsBomController::class, 'replace'])->name('v1.items.bom.replace'); // BOM 전체 교체
|
||||
Route::post('/reorder', [ItemsBomController::class, 'reorder'])->name('v1.items.bom.reorder'); // BOM 정렬
|
||||
Route::get('/categories', [ItemsBomController::class, 'listCategories'])->name('v1.items.bom.categories'); // 카테고리 목록
|
||||
});
|
||||
|
||||
// Items Files (ID-based File Upload API)
|
||||
Route::prefix('items/{id}/files')->group(function () {
|
||||
Route::post('', [\App\Http\Controllers\Api\V1\ItemsFileController::class, 'upload'])->name('v1.items.files.upload'); // 파일 업로드
|
||||
Route::delete('/{type}', [\App\Http\Controllers\Api\V1\ItemsFileController::class, 'delete'])->name('v1.items.files.delete'); // 파일 삭제 (type: bending_diagram|specification|certification)
|
||||
Route::post('', [ItemsFileController::class, 'upload'])->name('v1.items.files.upload'); // 파일 업로드
|
||||
Route::delete('/{type}', [ItemsFileController::class, 'delete'])->name('v1.items.files.delete'); // 파일 삭제 (type: bending_diagram|specification|certification)
|
||||
});
|
||||
|
||||
// BOM (product_components: ref_type=PRODUCT|MATERIAL)
|
||||
|
||||
Reference in New Issue
Block a user