fix: Items API 유연성 개선 - Flow Tester 호환성
- GET /api/v1/items/bom 엔드포인트 추가 (BOM 있는 전체 품목 목록) - ItemService::index() item_type/group_id 없으면 group_id=1 기본값 적용 - ItemService::showByCode() item_type 없으면 items 테이블에서 직접 검색 - ItemsBomController::listAll() 메서드 추가 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -16,6 +16,49 @@
|
||||
*/
|
||||
class ItemsBomController extends Controller
|
||||
{
|
||||
/**
|
||||
* GET /api/v1/items/bom
|
||||
* BOM이 있는 전체 품목 목록 조회 (item_id 없이)
|
||||
*/
|
||||
public function listAll(Request $request)
|
||||
{
|
||||
return ApiResponse::handle(function () use ($request) {
|
||||
$tenantId = app('tenant_id');
|
||||
$perPage = (int) ($request->input('per_page', $request->input('size', 20)));
|
||||
$itemType = $request->input('item_type');
|
||||
|
||||
$query = Item::query()
|
||||
->where('tenant_id', $tenantId)
|
||||
->whereNotNull('bom')
|
||||
->where('bom', '!=', '[]')
|
||||
->where('bom', '!=', 'null');
|
||||
|
||||
// item_type 필터 (선택)
|
||||
if ($itemType) {
|
||||
$query->where('item_type', strtoupper($itemType));
|
||||
}
|
||||
|
||||
$items = $query->orderBy('id')
|
||||
->paginate($perPage, ['id', 'code', 'name', 'item_type', 'unit', 'bom']);
|
||||
|
||||
// BOM 개수 추가
|
||||
$items->getCollection()->transform(function ($item) {
|
||||
$bom = $item->bom ?? [];
|
||||
return [
|
||||
'id' => $item->id,
|
||||
'code' => $item->code,
|
||||
'name' => $item->name,
|
||||
'item_type' => $item->item_type,
|
||||
'unit' => $item->unit,
|
||||
'bom_count' => count($bom),
|
||||
'bom' => $this->expandBomItems($bom),
|
||||
];
|
||||
});
|
||||
|
||||
return $items;
|
||||
}, __('message.bom.fetch'));
|
||||
}
|
||||
|
||||
/**
|
||||
* GET /api/v1/items/{id}/bom
|
||||
* BOM 라인 목록 조회 (flat list)
|
||||
|
||||
@@ -344,7 +344,7 @@ protected function fetchCategoryTree(?int $parentId = null)
|
||||
/**
|
||||
* 목록/검색 (동적 테이블 라우팅)
|
||||
*
|
||||
* @param array $params 검색 파라미터 (item_type 또는 group_id 필수)
|
||||
* @param array $params 검색 파라미터 (item_type/group_id 없으면 group_id=1 기본값)
|
||||
*/
|
||||
public function index(array $params): LengthAwarePaginator
|
||||
{
|
||||
@@ -355,9 +355,9 @@ public function index(array $params): LengthAwarePaginator
|
||||
$groupId = $params['group_id'] ?? null;
|
||||
$active = $params['active'] ?? null;
|
||||
|
||||
// item_type 또는 group_id 필수 검증
|
||||
// item_type 또는 group_id 없으면 group_id = 1 기본값 적용
|
||||
if (! $itemType && ! $groupId) {
|
||||
throw new BadRequestHttpException(__('error.item_type_or_group_required'));
|
||||
$groupId = 1;
|
||||
}
|
||||
|
||||
// group_id로 조회 시 해당 그룹의 모든 item_type 조회
|
||||
@@ -778,11 +778,29 @@ public function toggle(int $id, string $itemType): array
|
||||
* code 기반 품목 조회 (동적 테이블 라우팅, BOM 포함 옵션)
|
||||
*
|
||||
* @param string $code 품목 코드
|
||||
* @param string $itemType 품목 유형 (필수)
|
||||
* @param string $itemType 품목 유형 (없으면 items 테이블에서 직접 검색)
|
||||
* @param bool $includeBom BOM 포함 여부
|
||||
*/
|
||||
public function showByCode(string $code, string $itemType, bool $includeBom = false): Model
|
||||
{
|
||||
// item_type 없으면 items 테이블에서 직접 검색
|
||||
if (empty($itemType)) {
|
||||
$item = Item::where('tenant_id', $this->tenantId())
|
||||
->where('code', $code)
|
||||
->with(['category:id,name', 'details'])
|
||||
->first();
|
||||
|
||||
if (! $item) {
|
||||
throw new BadRequestHttpException(__('error.not_found'));
|
||||
}
|
||||
|
||||
if ($includeBom && ! empty($item->bom) && method_exists($item, 'loadBomChildren')) {
|
||||
$item->loadBomChildren();
|
||||
}
|
||||
|
||||
return $item;
|
||||
}
|
||||
|
||||
// 동적 테이블 라우팅
|
||||
$modelInfo = $this->getModelInfoByItemType($itemType);
|
||||
$query = $this->newQuery($itemType)->where('code', $code);
|
||||
|
||||
@@ -778,6 +778,10 @@
|
||||
Route::delete('/{id}', [ItemsController::class, 'destroy'])->name('v1.items.destroy'); // 품목 삭제
|
||||
});
|
||||
|
||||
// Items BOM - 전체 BOM 목록 (item_id 없이)
|
||||
// 주의: /items/{id}/bom 보다 먼저 정의해야 함 ('bom'이 {id}로 인식되지 않도록)
|
||||
Route::get('items/bom', [ItemsBomController::class, 'listAll'])->name('v1.items.bom.list-all');
|
||||
|
||||
// Items BOM (ID-based BOM API)
|
||||
Route::prefix('items/{id}/bom')->group(function () {
|
||||
Route::get('', [ItemsBomController::class, 'index'])->name('v1.items.bom.index'); // BOM 목록 (flat)
|
||||
|
||||
Reference in New Issue
Block a user