feat: [items] 아이템 API 기능 개선
- ItemsController, ItemsBomController, ItemsFileController 수정 - ItemBatchDeleteRequest 추가 - ItemsService 개선 - ItemsApi Swagger 문서 업데이트
This commit is contained in:
@@ -10,169 +10,167 @@
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
|
||||
/**
|
||||
* Items BOM Controller (Code-based Adapter)
|
||||
* Items BOM Controller (ID-based)
|
||||
*
|
||||
* 프론트엔드 요구사항에 맞춰 itemCode 기반으로 BOM을 관리하는 Adapter
|
||||
* 내부적으로 code → id 변환 후 기존 ProductBomService 재사용
|
||||
* ID 기반으로 BOM을 관리하는 컨트롤러
|
||||
* 내부적으로 기존 ProductBomService 재사용
|
||||
*/
|
||||
class ItemsBomController extends Controller
|
||||
{
|
||||
public function __construct(private ProductBomService $service) {}
|
||||
|
||||
/**
|
||||
* GET /api/v1/items/{code}/bom
|
||||
* GET /api/v1/items/{id}/bom
|
||||
* BOM 라인 목록 조회 (flat list)
|
||||
*/
|
||||
public function index(string $code, Request $request)
|
||||
public function index(int $id, Request $request)
|
||||
{
|
||||
return ApiResponse::handle(function () use ($code, $request) {
|
||||
$productId = $this->getProductIdByCode($code);
|
||||
return ApiResponse::handle(function () use ($id, $request) {
|
||||
$this->validateProductExists($id);
|
||||
|
||||
return $this->service->index($productId, $request->all());
|
||||
return $this->service->index($id, $request->all());
|
||||
}, __('message.bom.fetch'));
|
||||
}
|
||||
|
||||
/**
|
||||
* GET /api/v1/items/{code}/bom/tree
|
||||
* GET /api/v1/items/{id}/bom/tree
|
||||
* BOM 트리 구조 조회 (계층적)
|
||||
*/
|
||||
public function tree(string $code, Request $request)
|
||||
public function tree(int $id, Request $request)
|
||||
{
|
||||
return ApiResponse::handle(function () use ($code, $request) {
|
||||
$productId = $this->getProductIdByCode($code);
|
||||
return ApiResponse::handle(function () use ($id, $request) {
|
||||
$this->validateProductExists($id);
|
||||
|
||||
return $this->service->tree($request, $productId);
|
||||
return $this->service->tree($request, $id);
|
||||
}, __('message.bom.fetch'));
|
||||
}
|
||||
|
||||
/**
|
||||
* POST /api/v1/items/{code}/bom
|
||||
* POST /api/v1/items/{id}/bom
|
||||
* BOM 라인 추가 (bulk upsert)
|
||||
*/
|
||||
public function store(string $code, Request $request)
|
||||
public function store(int $id, Request $request)
|
||||
{
|
||||
return ApiResponse::handle(function () use ($code, $request) {
|
||||
$productId = $this->getProductIdByCode($code);
|
||||
return ApiResponse::handle(function () use ($id, $request) {
|
||||
$this->validateProductExists($id);
|
||||
|
||||
return $this->service->bulkUpsert($productId, $request->input('items', []));
|
||||
return $this->service->bulkUpsert($id, $request->input('items', []));
|
||||
}, __('message.bom.created'));
|
||||
}
|
||||
|
||||
/**
|
||||
* PUT /api/v1/items/{code}/bom/{lineId}
|
||||
* PUT /api/v1/items/{id}/bom/{lineId}
|
||||
* BOM 라인 수정
|
||||
*/
|
||||
public function update(string $code, int $lineId, Request $request)
|
||||
public function update(int $id, int $lineId, Request $request)
|
||||
{
|
||||
return ApiResponse::handle(function () use ($code, $lineId, $request) {
|
||||
$productId = $this->getProductIdByCode($code);
|
||||
return ApiResponse::handle(function () use ($id, $lineId, $request) {
|
||||
$this->validateProductExists($id);
|
||||
|
||||
return $this->service->update($productId, $lineId, $request->all());
|
||||
return $this->service->update($id, $lineId, $request->all());
|
||||
}, __('message.bom.updated'));
|
||||
}
|
||||
|
||||
/**
|
||||
* DELETE /api/v1/items/{code}/bom/{lineId}
|
||||
* DELETE /api/v1/items/{id}/bom/{lineId}
|
||||
* BOM 라인 삭제
|
||||
*/
|
||||
public function destroy(string $code, int $lineId)
|
||||
public function destroy(int $id, int $lineId)
|
||||
{
|
||||
return ApiResponse::handle(function () use ($code, $lineId) {
|
||||
$productId = $this->getProductIdByCode($code);
|
||||
return ApiResponse::handle(function () use ($id, $lineId) {
|
||||
$this->validateProductExists($id);
|
||||
|
||||
$this->service->destroy($productId, $lineId);
|
||||
$this->service->destroy($id, $lineId);
|
||||
|
||||
return 'success';
|
||||
}, __('message.bom.deleted'));
|
||||
}
|
||||
|
||||
/**
|
||||
* GET /api/v1/items/{code}/bom/summary
|
||||
* GET /api/v1/items/{id}/bom/summary
|
||||
* BOM 요약 정보
|
||||
*/
|
||||
public function summary(string $code)
|
||||
public function summary(int $id)
|
||||
{
|
||||
return ApiResponse::handle(function () use ($code) {
|
||||
$productId = $this->getProductIdByCode($code);
|
||||
return ApiResponse::handle(function () use ($id) {
|
||||
$this->validateProductExists($id);
|
||||
|
||||
return $this->service->summary($productId);
|
||||
return $this->service->summary($id);
|
||||
}, __('message.bom.fetch'));
|
||||
}
|
||||
|
||||
/**
|
||||
* GET /api/v1/items/{code}/bom/validate
|
||||
* GET /api/v1/items/{id}/bom/validate
|
||||
* BOM 유효성 검사
|
||||
*/
|
||||
public function validate(string $code)
|
||||
public function validate(int $id)
|
||||
{
|
||||
return ApiResponse::handle(function () use ($code) {
|
||||
$productId = $this->getProductIdByCode($code);
|
||||
return ApiResponse::handle(function () use ($id) {
|
||||
$this->validateProductExists($id);
|
||||
|
||||
return $this->service->validateBom($productId);
|
||||
return $this->service->validateBom($id);
|
||||
}, __('message.bom.fetch'));
|
||||
}
|
||||
|
||||
/**
|
||||
* POST /api/v1/items/{code}/bom/replace
|
||||
* POST /api/v1/items/{id}/bom/replace
|
||||
* BOM 전체 교체
|
||||
*/
|
||||
public function replace(string $code, Request $request)
|
||||
public function replace(int $id, Request $request)
|
||||
{
|
||||
return ApiResponse::handle(function () use ($code, $request) {
|
||||
$productId = $this->getProductIdByCode($code);
|
||||
return ApiResponse::handle(function () use ($id, $request) {
|
||||
$this->validateProductExists($id);
|
||||
|
||||
return $this->service->replaceBom($productId, $request->all());
|
||||
return $this->service->replaceBom($id, $request->all());
|
||||
}, __('message.bom.created'));
|
||||
}
|
||||
|
||||
/**
|
||||
* POST /api/v1/items/{code}/bom/reorder
|
||||
* POST /api/v1/items/{id}/bom/reorder
|
||||
* BOM 정렬 변경
|
||||
*/
|
||||
public function reorder(string $code, Request $request)
|
||||
public function reorder(int $id, Request $request)
|
||||
{
|
||||
return ApiResponse::handle(function () use ($code, $request) {
|
||||
$productId = $this->getProductIdByCode($code);
|
||||
return ApiResponse::handle(function () use ($id, $request) {
|
||||
$this->validateProductExists($id);
|
||||
|
||||
$this->service->reorder($productId, $request->input('items', []));
|
||||
$this->service->reorder($id, $request->input('items', []));
|
||||
|
||||
return 'success';
|
||||
}, __('message.bom.reordered'));
|
||||
}
|
||||
|
||||
/**
|
||||
* GET /api/v1/items/{code}/bom/categories
|
||||
* GET /api/v1/items/{id}/bom/categories
|
||||
* 해당 품목의 BOM에서 사용 중인 카테고리 목록
|
||||
*/
|
||||
public function listCategories(string $code)
|
||||
public function listCategories(int $id)
|
||||
{
|
||||
return ApiResponse::handle(function () use ($code) {
|
||||
$productId = $this->getProductIdByCode($code);
|
||||
return ApiResponse::handle(function () use ($id) {
|
||||
$this->validateProductExists($id);
|
||||
|
||||
return $this->service->listCategoriesForProduct($productId);
|
||||
return $this->service->listCategoriesForProduct($id);
|
||||
}, __('message.bom.fetch'));
|
||||
}
|
||||
|
||||
// ==================== Helper Methods ====================
|
||||
|
||||
/**
|
||||
* itemCode로 product ID 조회
|
||||
* 품목 ID로 tenant 소유권 검증
|
||||
*
|
||||
* @throws NotFoundHttpException
|
||||
*/
|
||||
private function getProductIdByCode(string $code): int
|
||||
private function validateProductExists(int $id): void
|
||||
{
|
||||
$tenantId = app('tenant_id');
|
||||
|
||||
$product = Product::query()
|
||||
$exists = Product::query()
|
||||
->where('tenant_id', $tenantId)
|
||||
->where('code', $code)
|
||||
->first(['id']);
|
||||
->where('id', $id)
|
||||
->exists();
|
||||
|
||||
if (! $product) {
|
||||
if (! $exists) {
|
||||
throw new NotFoundHttpException(__('error.not_found'));
|
||||
}
|
||||
|
||||
return $product->id;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user