Files
sam-api/routes/api/v1/production.php
권혁성 4dd38ab14d feat: [생산지시] 전용 API + 자재투입/공정 개선
- ProductionOrder 전용 엔드포인트 (목록/통계/상세)
- 재고생산 보조공정 일반 워크플로우에서 분리
- 자재투입 replace 모드 + bom_group_key 개별 저장
- 공정단계 options 컬럼 추가 (검사 설정/범위)
- 셔터박스 prefix isStandard 파라미터 제거

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 02:57:59 +09:00

132 lines
12 KiB
PHP

<?php
/**
* 생산 관리 API 라우트 (v1)
*
* - 공정 관리
* - 작업지시 관리
* - 작업실적 관리
* - 검사 관리
*/
use App\Http\Controllers\Api\V1\InspectionController;
use App\Http\Controllers\Api\V1\ProductionOrderController;
use App\Http\Controllers\Api\V1\WorkOrderController;
use App\Http\Controllers\Api\V1\WorkResultController;
use App\Http\Controllers\V1\ProcessController;
use App\Http\Controllers\V1\ProcessStepController;
use Illuminate\Support\Facades\Route;
// Process API (공정 관리)
Route::prefix('processes')->group(function () {
Route::get('', [ProcessController::class, 'index'])->name('v1.processes.index');
Route::get('/options', [ProcessController::class, 'options'])->name('v1.processes.options');
Route::get('/stats', [ProcessController::class, 'stats'])->name('v1.processes.stats');
Route::post('', [ProcessController::class, 'store'])->name('v1.processes.store');
Route::delete('', [ProcessController::class, 'destroyMany'])->name('v1.processes.destroy-many');
Route::get('/{id}', [ProcessController::class, 'show'])->whereNumber('id')->name('v1.processes.show');
Route::put('/{id}', [ProcessController::class, 'update'])->whereNumber('id')->name('v1.processes.update');
Route::delete('/{id}', [ProcessController::class, 'destroy'])->whereNumber('id')->name('v1.processes.destroy');
Route::patch('/{id}/toggle', [ProcessController::class, 'toggleActive'])->whereNumber('id')->name('v1.processes.toggle');
// Process Steps (공정 단계)
Route::prefix('{processId}/steps')->whereNumber('processId')->group(function () {
Route::get('', [ProcessStepController::class, 'index'])->name('v1.processes.steps.index');
Route::post('', [ProcessStepController::class, 'store'])->name('v1.processes.steps.store');
Route::patch('/reorder', [ProcessStepController::class, 'reorder'])->name('v1.processes.steps.reorder');
Route::get('/{stepId}', [ProcessStepController::class, 'show'])->whereNumber('stepId')->name('v1.processes.steps.show');
Route::put('/{stepId}', [ProcessStepController::class, 'update'])->whereNumber('stepId')->name('v1.processes.steps.update');
Route::delete('/{stepId}', [ProcessStepController::class, 'destroy'])->whereNumber('stepId')->name('v1.processes.steps.destroy');
});
});
// Work Order API (작업지시 관리)
Route::prefix('work-orders')->group(function () {
// 기본 CRUD
Route::get('', [WorkOrderController::class, 'index'])->name('v1.work-orders.index'); // 목록
Route::get('/stats', [WorkOrderController::class, 'stats'])->name('v1.work-orders.stats'); // 통계
Route::post('', [WorkOrderController::class, 'store'])->name('v1.work-orders.store'); // 생성
Route::get('/{id}', [WorkOrderController::class, 'show'])->whereNumber('id')->name('v1.work-orders.show'); // 상세
Route::put('/{id}', [WorkOrderController::class, 'update'])->whereNumber('id')->name('v1.work-orders.update'); // 수정
Route::delete('/{id}', [WorkOrderController::class, 'destroy'])->whereNumber('id')->name('v1.work-orders.destroy'); // 삭제
// 상태 및 담당자 관리
Route::patch('/{id}/status', [WorkOrderController::class, 'updateStatus'])->whereNumber('id')->name('v1.work-orders.status'); // 상태 변경
Route::patch('/{id}/assign', [WorkOrderController::class, 'assign'])->whereNumber('id')->name('v1.work-orders.assign'); // 담당자 배정
// 벤딩 공정 상세 토글
Route::patch('/{id}/bending/toggle', [WorkOrderController::class, 'toggleBendingField'])->whereNumber('id')->name('v1.work-orders.bending-toggle');
// 이슈 관리
Route::post('/{id}/issues', [WorkOrderController::class, 'addIssue'])->whereNumber('id')->name('v1.work-orders.issues.store'); // 이슈 등록
Route::patch('/{id}/issues/{issueId}/resolve', [WorkOrderController::class, 'resolveIssue'])->whereNumber('id')->name('v1.work-orders.issues.resolve'); // 이슈 해결
// 품목 상태 변경
Route::patch('/{id}/items/{itemId}/status', [WorkOrderController::class, 'updateItemStatus'])->whereNumber('id')->whereNumber('itemId')->name('v1.work-orders.items.status');
// 자재 관리
Route::get('/{id}/materials', [WorkOrderController::class, 'materials'])->whereNumber('id')->name('v1.work-orders.materials'); // 자재 목록 조회
Route::post('/{id}/material-inputs', [WorkOrderController::class, 'registerMaterialInput'])->whereNumber('id')->name('v1.work-orders.material-inputs'); // 자재 투입 등록
Route::get('/{id}/material-input-history', [WorkOrderController::class, 'materialInputHistory'])->whereNumber('id')->name('v1.work-orders.material-input-history'); // 자재 투입 이력
Route::get('/{id}/material-input-lots', [WorkOrderController::class, 'materialInputLots'])->whereNumber('id')->name('v1.work-orders.material-input-lots'); // 투입 LOT 번호 조회
// 개소별 자재 관리
Route::get('/{id}/items/{itemId}/materials', [WorkOrderController::class, 'materialsForItem'])->whereNumber('id')->whereNumber('itemId')->name('v1.work-orders.items.materials'); // 개소별 자재 조회
Route::post('/{id}/items/{itemId}/material-inputs', [WorkOrderController::class, 'registerMaterialInputForItem'])->whereNumber('id')->whereNumber('itemId')->name('v1.work-orders.items.material-inputs'); // 개소별 자재 투입
Route::get('/{id}/items/{itemId}/material-inputs', [WorkOrderController::class, 'materialInputsForItem'])->whereNumber('id')->whereNumber('itemId')->name('v1.work-orders.items.material-inputs.index'); // 개소별 투입 이력
Route::delete('/{id}/material-inputs/{inputId}', [WorkOrderController::class, 'deleteMaterialInput'])->whereNumber('id')->whereNumber('inputId')->name('v1.work-orders.material-inputs.delete'); // 자재 투입 삭제
Route::patch('/{id}/material-inputs/{inputId}', [WorkOrderController::class, 'updateMaterialInput'])->whereNumber('id')->whereNumber('inputId')->name('v1.work-orders.material-inputs.update'); // 자재 투입 수정
// 공정 단계 진행 관리
Route::get('/{id}/step-progress', [WorkOrderController::class, 'stepProgress'])->whereNumber('id')->name('v1.work-orders.step-progress'); // 단계 진행 조회
Route::patch('/{id}/step-progress/{progressId}/toggle', [WorkOrderController::class, 'toggleStepProgress'])->whereNumber('id')->whereNumber('progressId')->name('v1.work-orders.step-progress.toggle'); // 단계 토글
// 중간검사 관리
Route::post('/{id}/items/{itemId}/inspection', [WorkOrderController::class, 'storeItemInspection'])->whereNumber('id')->whereNumber('itemId')->name('v1.work-orders.items.inspection'); // 품목 검사 저장
Route::get('/{id}/inspection-config', [WorkOrderController::class, 'inspectionConfig'])->whereNumber('id')->name('v1.work-orders.inspection-config'); // 검사 설정 (공정 판별 + 구성품)
Route::get('/{id}/inspection-data', [WorkOrderController::class, 'inspectionData'])->whereNumber('id')->name('v1.work-orders.inspection-data'); // 검사 데이터 조회
Route::get('/{id}/inspection-report', [WorkOrderController::class, 'inspectionReport'])->whereNumber('id')->name('v1.work-orders.inspection-report'); // 검사 성적서 조회
Route::get('/{id}/inspection-template', [WorkOrderController::class, 'inspectionTemplate'])->whereNumber('id')->name('v1.work-orders.inspection-template'); // 검사 문서 템플릿 조회
Route::get('/{id}/inspection-resolve', [WorkOrderController::class, 'resolveInspectionDocument'])->whereNumber('id')->name('v1.work-orders.inspection-resolve'); // 검사 문서 resolve (기존 문서/템플릿)
Route::post('/{id}/inspection-document', [WorkOrderController::class, 'createInspectionDocument'])->whereNumber('id')->name('v1.work-orders.inspection-document'); // 검사 문서 생성/수정
// 작업일지 관리
Route::get('/{id}/work-log-template', [WorkOrderController::class, 'workLogTemplate'])->whereNumber('id')->name('v1.work-orders.work-log-template'); // 작업일지 양식 조회
Route::get('/{id}/work-log', [WorkOrderController::class, 'workLog'])->whereNumber('id')->name('v1.work-orders.work-log'); // 작업일지 조회
Route::post('/{id}/work-log', [WorkOrderController::class, 'createWorkLog'])->whereNumber('id')->name('v1.work-orders.work-log.store'); // 작업일지 생성/수정
});
// Work Result API (작업실적 관리)
Route::prefix('work-results')->group(function () {
// 기본 CRUD
Route::get('', [WorkResultController::class, 'index'])->name('v1.work-results.index'); // 목록
Route::get('/stats', [WorkResultController::class, 'stats'])->name('v1.work-results.stats'); // 통계
Route::post('', [WorkResultController::class, 'store'])->name('v1.work-results.store'); // 생성
Route::get('/{id}', [WorkResultController::class, 'show'])->whereNumber('id')->name('v1.work-results.show'); // 상세
Route::put('/{id}', [WorkResultController::class, 'update'])->whereNumber('id')->name('v1.work-results.update'); // 수정
Route::delete('/{id}', [WorkResultController::class, 'destroy'])->whereNumber('id')->name('v1.work-results.destroy'); // 삭제
// 상태 토글
Route::patch('/{id}/inspection', [WorkResultController::class, 'toggleInspection'])->whereNumber('id')->name('v1.work-results.inspection'); // 검사 상태 토글
Route::patch('/{id}/packaging', [WorkResultController::class, 'togglePackaging'])->whereNumber('id')->name('v1.work-results.packaging'); // 포장 상태 토글
});
// Inspection API (검사 관리)
Route::prefix('inspections')->group(function () {
Route::get('', [InspectionController::class, 'index'])->name('v1.inspections.index'); // 목록
Route::get('/stats', [InspectionController::class, 'stats'])->name('v1.inspections.stats'); // 통계
Route::get('/calendar', [InspectionController::class, 'calendar'])->name('v1.inspections.calendar'); // 캘린더
Route::post('', [InspectionController::class, 'store'])->name('v1.inspections.store'); // 생성
Route::get('/{id}', [InspectionController::class, 'show'])->whereNumber('id')->name('v1.inspections.show'); // 상세
Route::put('/{id}', [InspectionController::class, 'update'])->whereNumber('id')->name('v1.inspections.update'); // 수정
Route::delete('/{id}', [InspectionController::class, 'destroy'])->whereNumber('id')->name('v1.inspections.destroy'); // 삭제
Route::patch('/{id}/complete', [InspectionController::class, 'complete'])->whereNumber('id')->name('v1.inspections.complete'); // 완료 처리
});
// Production Order API (생산지시 조회)
Route::prefix('production-orders')->group(function () {
Route::get('', [ProductionOrderController::class, 'index'])->name('v1.production-orders.index');
Route::get('/stats', [ProductionOrderController::class, 'stats'])->name('v1.production-orders.stats');
Route::get('/{orderId}', [ProductionOrderController::class, 'show'])->whereNumber('orderId')->name('v1.production-orders.show');
});