feat: Items BOM API 추가 (Code 기반 Adapter) - BP-MES Phase 1 Day 6-9

- ItemsBomController 생성 (code 기반 BOM 관리)
- 기존 ProductBomService 100% 재사용 (Adapter 패턴)
- Code → ID 변환 후 기존 비즈니스 로직 활용
- 프론트엔드 요구사항 완벽 대응 (itemCode 기반 API)
- 10개 엔드포인트 추가:
  * GET /items/{code}/bom - BOM 목록 (flat)
  * GET /items/{code}/bom/tree - BOM 트리 (계층)
  * POST /items/{code}/bom - BOM 추가 (bulk upsert)
  * PUT /items/{code}/bom/{lineId} - BOM 수정
  * DELETE /items/{code}/bom/{lineId} - BOM 삭제
  * GET /items/{code}/bom/summary - BOM 요약
  * GET /items/{code}/bom/validate - BOM 검증
  * POST /items/{code}/bom/replace - BOM 전체 교체
  * POST /items/{code}/bom/reorder - BOM 정렬
  * GET /items/{code}/bom/categories - 카테고리 목록
- Swagger 문서 완성 (ItemsBomApi.php)
- i18n 메시지 키 추가 (message.bom.created/updated/deleted)
- Hybrid 구조 지원 (quantity_formula, condition, attributes)
This commit is contained in:
2025-11-17 11:45:16 +09:00
parent a23b727557
commit 2f2fffb6f0
4 changed files with 645 additions and 0 deletions

View File

@@ -344,6 +344,20 @@
Route::delete('/{code}', [\App\Http\Controllers\Api\V1\ItemsController::class, 'destroy'])->name('v1.items.destroy'); // 품목 삭제
});
// Items BOM (Code-based BOM API - adapter for frontend)
Route::prefix('items/{code}/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'); // 카테고리 목록
});
// BOM (product_components: ref_type=PRODUCT|MATERIAL)
Route::prefix('products/{id}/bom')->group(function () {
Route::post('/', [ProductBomItemController::class, 'replace'])->name('v1.products.bom.replace');