feat: Items show() API 개선 - files 로딩 및 item_type 선택적 처리

- Item 모델 files() 관계를 document_id/document_type 기반으로 변경
- show() 메서드에 files 로딩 및 field_key별 그룹화 추가
- item_type 파라미터 선택적 처리 (ID만으로 조회 가능)
- showWithPrice() 메서드 반환 타입 변경에 맞게 수정
This commit is contained in:
2025-12-15 19:27:36 +09:00
parent f470978adb
commit 2862015605
3 changed files with 53 additions and 14 deletions

View File

@@ -40,13 +40,14 @@ public function index(Request $request)
*
* GET /api/v1/items/{id}?item_type=FG&include_price=true&client_id=1&price_date=2025-01-10
*
* @param string item_type 품목 유형 (필수 - 동적 테이블 라우팅)
* @param string|null item_type 품목 유형 (선택적 - 없으면 ID만으로 조회)
*/
public function show(Request $request, int $id)
{
return ApiResponse::handle(function () use ($request, $id) {
// item_type 필수 (동적 테이블 라우팅에 사용)
$itemType = strtoupper($request->input('item_type', ''));
// item_type 선택적 (없으면 ID만으로 items 테이블에서 조회)
$itemType = $request->input('item_type');
$itemType = $itemType ? strtoupper($itemType) : null;
$includePrice = filter_var($request->input('include_price', false), FILTER_VALIDATE_BOOLEAN);
if ($includePrice) {

View File

@@ -104,11 +104,15 @@ public function bomChildren()
}
/**
* 파일 (폴리모픽)
* 파일 (document_id/document_type 기반)
*
* ItemsFileController가 document_id=item_id, document_type='1'(group_id)로 저장
* morphMany(fileable) 대신 hasMany + where 조건 사용
*/
public function files()
{
return $this->morphMany(File::class, 'fileable');
return $this->hasMany(File::class, 'document_id')
->where('document_type', '1'); // ITEM_GROUP_ID
}
/**
@@ -200,4 +204,4 @@ public function loadBomChildren(): self
return $this;
}
}
}

View File

@@ -5,6 +5,7 @@
use App\Models\Commons\Category;
use App\Models\ItemMaster\ItemField;
use App\Models\ItemMaster\ItemPage;
use App\Models\Items\Item;
use App\Models\Items\ItemDetail;
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
use Illuminate\Database\Eloquent\Model;
@@ -433,17 +434,30 @@ public function store(array $data): Model
* 단건 조회 (동적 테이블 라우팅)
*
* @param int $id 품목 ID
* @param string $itemType 품목 유형 (필수)
* @param string|null $itemType 품목 유형 (선택적 - 없으면 ID로만 조회)
* @return array 품목 데이터 (files 그룹화 포함)
*/
public function show(int $id, string $itemType): Model
public function show(int $id, ?string $itemType = null): array
{
// item_type이 없으면 items 테이블에서 직접 조회
if (! $itemType) {
$item = Item::with(['category:id,name', 'details', 'files'])
->find($id);
if (! $item) {
throw new BadRequestHttpException(__('error.not_found'));
}
return $this->formatItemResponse($item);
}
// 동적 테이블 라우팅
$modelInfo = $this->getModelInfoByItemType($itemType);
$query = $this->newQuery($itemType);
// items 테이블인 경우 관계 로드
if ($modelInfo['source_table'] === 'items') {
$query->with(['category:id,name', 'details']);
$query->with(['category:id,name', 'details', 'files']);
}
$item = $query->find($id);
@@ -452,7 +466,25 @@ public function show(int $id, string $itemType): Model
throw new BadRequestHttpException(__('error.not_found'));
}
return $item;
return $this->formatItemResponse($item);
}
/**
* 품목 응답 포맷 (files 그룹화 포함)
*/
private function formatItemResponse(Model $item): array
{
$arr = $item->toArray();
// 날짜 포맷
$arr['created_at'] = $item->created_at
? $item->created_at->format('Y-m-d')
: null;
// files를 field_key별로 그룹화
$arr['files'] = $this->groupFilesByFieldKey($arr['files'] ?? []);
return $arr;
}
/**
@@ -706,15 +738,17 @@ public function batchDestroy(array $ids, string $itemType): int
* @param int|null $clientId 거래처 ID
* @param string|null $priceDate 가격 기준일
*/
public function showWithPrice(int $id, string $itemType, ?int $clientId = null, ?string $priceDate = null): array
public function showWithPrice(int $id, ?string $itemType = null, ?int $clientId = null, ?string $priceDate = null): array
{
$item = $this->show($id, $itemType);
$data = $item->toArray();
// show()가 이제 array를 반환
$data = $this->show($id, $itemType);
// PricingService로 가격 조회
try {
$pricingService = app(\App\Services\Pricing\PricingService::class);
$itemTypeCode = in_array(strtoupper($itemType), ['FG', 'PT']) ? 'PRODUCT' : 'MATERIAL';
// item_type에서 가격 유형 결정 (데이터에서 추출)
$actualItemType = $data['item_type'] ?? $itemType ?? 'FG';
$itemTypeCode = in_array(strtoupper($actualItemType), ['FG', 'PT']) ? 'PRODUCT' : 'MATERIAL';
$data['prices'] = [
'sale' => $pricingService->getPriceByType($itemTypeCode, $id, 'SALE', $clientId, $priceDate),