feat: Items API에 group_id 파라미터 지원 추가
- common_codes에 item_group 추가 및 item_type parent_id 연결 - /api/v1/items?type=RM → 단일 품목 유형 조회 - /api/v1/items?group_id=103 → 그룹 전체 품목 조회 (FG,PT,SM,RM,CS) - ItemService에 getItemTypesByGroupId(), newQueryForTypes() 메서드 추가 - 에러 메시지 추가 (item_type_or_group_required, invalid_group_id)
This commit is contained in:
@@ -27,6 +27,7 @@ public function index(Request $request)
|
||||
'q' => $request->input('q') ?? $request->input('search'),
|
||||
'category_id' => $request->input('category_id'),
|
||||
'item_type' => $request->input('type') ?? $request->input('item_type'),
|
||||
'group_id' => $request->input('group_id'),
|
||||
'active' => $request->input('is_active') ?? $request->input('active'),
|
||||
];
|
||||
|
||||
|
||||
@@ -79,6 +79,32 @@ private function newQuery(string $itemType)
|
||||
->where('item_type', strtoupper($itemType));
|
||||
}
|
||||
|
||||
/**
|
||||
* group_id로 해당 그룹의 item_type 목록 조회
|
||||
*
|
||||
* @param int $groupId common_codes의 item_group id
|
||||
* @return array item_type 코드 배열 ['FG', 'PT', 'SM', 'RM', 'CS']
|
||||
*/
|
||||
private function getItemTypesByGroupId(int $groupId): array
|
||||
{
|
||||
return \DB::table('common_codes')
|
||||
->where('code_group', 'item_type')
|
||||
->where('parent_id', $groupId)
|
||||
->where('is_active', true)
|
||||
->pluck('code')
|
||||
->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* 여러 item_type으로 Query Builder 생성
|
||||
*/
|
||||
private function newQueryForTypes(array $itemTypes)
|
||||
{
|
||||
return \App\Models\Items\Item::query()
|
||||
->where('tenant_id', $this->tenantId())
|
||||
->whereIn('item_type', array_map('strtoupper', $itemTypes));
|
||||
}
|
||||
|
||||
/**
|
||||
* items 테이블의 고정 컬럼 목록 조회 (SystemFields + ItemField 기반)
|
||||
*/
|
||||
@@ -252,7 +278,7 @@ protected function fetchCategoryTree(?int $parentId = null)
|
||||
/**
|
||||
* 목록/검색 (동적 테이블 라우팅)
|
||||
*
|
||||
* @param array $params 검색 파라미터 (item_type 필수)
|
||||
* @param array $params 검색 파라미터 (item_type 또는 group_id 필수)
|
||||
*/
|
||||
public function index(array $params): LengthAwarePaginator
|
||||
{
|
||||
@@ -260,16 +286,27 @@ public function index(array $params): LengthAwarePaginator
|
||||
$q = trim((string) ($params['q'] ?? $params['search'] ?? ''));
|
||||
$categoryId = $params['category_id'] ?? null;
|
||||
$itemType = $params['item_type'] ?? null;
|
||||
$groupId = $params['group_id'] ?? null;
|
||||
$active = $params['active'] ?? null;
|
||||
|
||||
// item_type 필수 검증
|
||||
if (! $itemType) {
|
||||
throw new BadRequestHttpException(__('error.item_type_required'));
|
||||
// item_type 또는 group_id 필수 검증
|
||||
if (! $itemType && ! $groupId) {
|
||||
throw new BadRequestHttpException(__('error.item_type_or_group_required'));
|
||||
}
|
||||
|
||||
// 동적 테이블 라우팅
|
||||
$query = $this->newQuery($itemType)
|
||||
->with(['category:id,name', 'details']);
|
||||
// group_id로 조회 시 해당 그룹의 모든 item_type 조회
|
||||
if ($groupId && ! $itemType) {
|
||||
$itemTypes = $this->getItemTypesByGroupId((int) $groupId);
|
||||
if (empty($itemTypes)) {
|
||||
throw new BadRequestHttpException(__('error.invalid_group_id'));
|
||||
}
|
||||
$query = $this->newQueryForTypes($itemTypes)
|
||||
->with(['category:id,name', 'details']);
|
||||
} else {
|
||||
// 단일 item_type 조회
|
||||
$query = $this->newQuery($itemType)
|
||||
->with(['category:id,name', 'details']);
|
||||
}
|
||||
|
||||
// 검색어
|
||||
if ($q !== '') {
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
/**
|
||||
* common_codes에 item_group 추가 및 item_type과 연결
|
||||
*
|
||||
* 구조:
|
||||
* - item_group (부모): code_group='item_group', code='ITEM', name='품목'
|
||||
* - item_type (자식): parent_id로 item_group 연결
|
||||
*/
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
// 1. item_group 추가 (품목 그룹)
|
||||
$itemGroupId = DB::table('common_codes')->insertGetId([
|
||||
'tenant_id' => 1,
|
||||
'code_group' => 'item_group',
|
||||
'code' => 'ITEM',
|
||||
'name' => '품목',
|
||||
'description' => '품목 관리 그룹 (FG, PT, SM, RM, CS)',
|
||||
'is_active' => true,
|
||||
'sort_order' => 1,
|
||||
'created_at' => now(),
|
||||
'updated_at' => now(),
|
||||
]);
|
||||
|
||||
// 2. 기존 item_type의 parent_id를 item_group으로 연결
|
||||
DB::table('common_codes')
|
||||
->where('code_group', 'item_type')
|
||||
->whereIn('code', ['FG', 'PT', 'SM', 'RM', 'CS'])
|
||||
->update(['parent_id' => $itemGroupId]);
|
||||
|
||||
// 3. item_type의 attributes에서 source_table을 items로 통일
|
||||
$itemTypes = DB::table('common_codes')
|
||||
->where('code_group', 'item_type')
|
||||
->whereIn('code', ['FG', 'PT', 'SM', 'RM', 'CS'])
|
||||
->get();
|
||||
|
||||
foreach ($itemTypes as $itemType) {
|
||||
$attributes = json_decode($itemType->attributes, true) ?? [];
|
||||
$attributes['source_table'] = 'items';
|
||||
|
||||
DB::table('common_codes')
|
||||
->where('id', $itemType->id)
|
||||
->update(['attributes' => json_encode($attributes)]);
|
||||
}
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
// 1. item_type의 parent_id 초기화
|
||||
DB::table('common_codes')
|
||||
->where('code_group', 'item_type')
|
||||
->whereIn('code', ['FG', 'PT', 'SM', 'RM', 'CS'])
|
||||
->update(['parent_id' => null]);
|
||||
|
||||
// 2. item_group 삭제
|
||||
DB::table('common_codes')
|
||||
->where('code_group', 'item_group')
|
||||
->where('code', 'ITEM')
|
||||
->delete();
|
||||
}
|
||||
};
|
||||
@@ -112,7 +112,9 @@
|
||||
'field_key_reserved' => '":field_key"은(는) 시스템 예약어로 사용할 수 없습니다.',
|
||||
'bom_not_found' => 'BOM 항목을 찾을 수 없습니다.',
|
||||
'item_type_required' => '품목 유형(item_type)은 필수입니다.',
|
||||
'item_type_or_group_required' => '품목 유형(item_type) 또는 그룹 ID(group_id)는 필수입니다.',
|
||||
'invalid_item_type' => '유효하지 않은 품목 유형입니다.',
|
||||
'invalid_group_id' => '유효하지 않은 그룹 ID이거나 해당 그룹에 품목 유형이 없습니다.',
|
||||
'invalid_source_table' => '품목 유형에 대한 소스 테이블이 설정되지 않았습니다.',
|
||||
|
||||
// 품목 관리 관련
|
||||
|
||||
Reference in New Issue
Block a user