- DB 연결: 로컬/Docker 환경 오버라이딩 설정 (.env) - 테넌트 위젯: redirect 버그 수정 (TenantSelectorWidget) - 통계 위젯: 사용자/제품/자재/주문 카드 추가 (StatsOverviewWidget) - 리소스 한국어화: Product, Material 모델 레이블 추가 - 대시보드: 위젯 등록 및 캐시 최적화 🤖 Generated with [Claude Code](https://claude.ai/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
258 lines
11 KiB
PHP
258 lines
11 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers\Api\V1\Design;
|
|
|
|
use App\Helpers\ApiResponse;
|
|
use App\Http\Controllers\Controller;
|
|
use App\Services\ProductFromModelService;
|
|
use App\Http\Requests\Api\V1\Design\ProductFromModelFormRequest;
|
|
|
|
/**
|
|
* @OA\Tag(name="Product from Model", description="Product creation from model APIs")
|
|
*/
|
|
class ProductFromModelController extends Controller
|
|
{
|
|
public function __construct(
|
|
protected ProductFromModelService $service
|
|
) {}
|
|
|
|
/**
|
|
* @OA\Post(
|
|
* path="/v1/design/models/{modelId}/create-product",
|
|
* summary="Create product from model",
|
|
* description="Create actual product with resolved BOM based on model and input parameters",
|
|
* security={{"ApiKeyAuth": {}}, {"BearerAuth": {}}},
|
|
* tags={"Product from Model"},
|
|
* @OA\Parameter(
|
|
* name="modelId",
|
|
* description="Model ID",
|
|
* in="path",
|
|
* required=true,
|
|
* @OA\Schema(type="integer", example=1)
|
|
* ),
|
|
* @OA\RequestBody(
|
|
* required=true,
|
|
* @OA\JsonContent(ref="#/components/schemas/CreateProductFromModelRequest")
|
|
* ),
|
|
* @OA\Response(
|
|
* response=201,
|
|
* description="Product created successfully with resolved BOM",
|
|
* @OA\JsonContent(
|
|
* allOf={
|
|
* @OA\Schema(ref="#/components/schemas/ApiResponse"),
|
|
* @OA\Schema(
|
|
* @OA\Property(property="data", ref="#/components/schemas/ProductWithBomResponse")
|
|
* )
|
|
* }
|
|
* )
|
|
* ),
|
|
* @OA\Response(ref="#/components/responses/ValidationErrorResponse", response=422),
|
|
* @OA\Response(ref="#/components/responses/ErrorResponse", response=400),
|
|
* @OA\Response(ref="#/components/responses/UnauthorizedResponse", response=401),
|
|
* @OA\Response(ref="#/components/responses/NotFoundResponse", response=404)
|
|
* )
|
|
*/
|
|
public function createProduct(ProductFromModelFormRequest $request, int $modelId)
|
|
{
|
|
return ApiResponse::handle(function () use ($request, $modelId) {
|
|
$data = $request->validated();
|
|
$data['model_id'] = $modelId;
|
|
return $this->service->createProductWithBom($data);
|
|
}, __('message.product.created_from_model'));
|
|
}
|
|
|
|
/**
|
|
* @OA\Get(
|
|
* path="/v1/products/{productId}/parameters",
|
|
* summary="Get product parameters",
|
|
* description="Retrieve parameters used to create this product",
|
|
* security={{"ApiKeyAuth": {}}, {"BearerAuth": {}}},
|
|
* tags={"Product from Model"},
|
|
* @OA\Parameter(
|
|
* name="productId",
|
|
* description="Product ID",
|
|
* in="path",
|
|
* required=true,
|
|
* @OA\Schema(type="integer", example=1)
|
|
* ),
|
|
* @OA\Response(
|
|
* response=200,
|
|
* description="Product parameters retrieved successfully",
|
|
* @OA\JsonContent(
|
|
* allOf={
|
|
* @OA\Schema(ref="#/components/schemas/ApiResponse"),
|
|
* @OA\Schema(
|
|
* @OA\Property(property="data", ref="#/components/schemas/ProductParametersResponse")
|
|
* )
|
|
* }
|
|
* )
|
|
* ),
|
|
* @OA\Response(ref="#/components/responses/ErrorResponse", response=400),
|
|
* @OA\Response(ref="#/components/responses/UnauthorizedResponse", response=401),
|
|
* @OA\Response(ref="#/components/responses/NotFoundResponse", response=404)
|
|
* )
|
|
*/
|
|
public function getProductParameters(int $productId)
|
|
{
|
|
return ApiResponse::handle(function () use ($productId) {
|
|
return $this->service->getProductParameters($productId);
|
|
}, __('message.fetched'));
|
|
}
|
|
|
|
/**
|
|
* @OA\Get(
|
|
* path="/v1/products/{productId}/calculated-values",
|
|
* summary="Get product calculated values",
|
|
* description="Retrieve calculated output values for this product",
|
|
* security={{"ApiKeyAuth": {}}, {"BearerAuth": {}}},
|
|
* tags={"Product from Model"},
|
|
* @OA\Parameter(
|
|
* name="productId",
|
|
* description="Product ID",
|
|
* in="path",
|
|
* required=true,
|
|
* @OA\Schema(type="integer", example=1)
|
|
* ),
|
|
* @OA\Response(
|
|
* response=200,
|
|
* description="Product calculated values retrieved successfully",
|
|
* @OA\JsonContent(
|
|
* allOf={
|
|
* @OA\Schema(ref="#/components/schemas/ApiResponse"),
|
|
* @OA\Schema(
|
|
* @OA\Property(property="data", ref="#/components/schemas/ProductCalculatedValuesResponse")
|
|
* )
|
|
* }
|
|
* )
|
|
* ),
|
|
* @OA\Response(ref="#/components/responses/ErrorResponse", response=400),
|
|
* @OA\Response(ref="#/components/responses/UnauthorizedResponse", response=401),
|
|
* @OA\Response(ref="#/components/responses/NotFoundResponse", response=404)
|
|
* )
|
|
*/
|
|
public function getCalculatedValues(int $productId)
|
|
{
|
|
return ApiResponse::handle(function () use ($productId) {
|
|
return $this->service->getCalculatedValues($productId);
|
|
}, __('message.fetched'));
|
|
}
|
|
|
|
/**
|
|
* @OA\Post(
|
|
* path="/v1/products/{productId}/recalculate",
|
|
* summary="Recalculate product values",
|
|
* description="Recalculate product BOM and values with updated parameters",
|
|
* security={{"ApiKeyAuth": {}}, {"BearerAuth": {}}},
|
|
* tags={"Product from Model"},
|
|
* @OA\Parameter(
|
|
* name="productId",
|
|
* description="Product ID",
|
|
* in="path",
|
|
* required=true,
|
|
* @OA\Schema(type="integer", example=1)
|
|
* ),
|
|
* @OA\RequestBody(
|
|
* required=true,
|
|
* @OA\JsonContent(
|
|
* @OA\Property(
|
|
* property="input_parameters",
|
|
* description="Updated input parameter values",
|
|
* type="object",
|
|
* additionalProperties=@OA\Property(oneOf={
|
|
* @OA\Schema(type="number"),
|
|
* @OA\Schema(type="string"),
|
|
* @OA\Schema(type="boolean")
|
|
* }),
|
|
* example={"W0": 1200, "H0": 900, "installation_type": "B"}
|
|
* ),
|
|
* @OA\Property(
|
|
* property="update_bom",
|
|
* description="Whether to update the BOM components",
|
|
* type="boolean",
|
|
* example=true
|
|
* )
|
|
* )
|
|
* ),
|
|
* @OA\Response(
|
|
* response=200,
|
|
* description="Product recalculated successfully",
|
|
* @OA\JsonContent(
|
|
* allOf={
|
|
* @OA\Schema(ref="#/components/schemas/ApiResponse"),
|
|
* @OA\Schema(
|
|
* @OA\Property(property="data", ref="#/components/schemas/ProductWithBomResponse")
|
|
* )
|
|
* }
|
|
* )
|
|
* ),
|
|
* @OA\Response(ref="#/components/responses/ValidationErrorResponse", response=422),
|
|
* @OA\Response(ref="#/components/responses/ErrorResponse", response=400),
|
|
* @OA\Response(ref="#/components/responses/UnauthorizedResponse", response=401),
|
|
* @OA\Response(ref="#/components/responses/NotFoundResponse", response=404)
|
|
* )
|
|
*/
|
|
public function recalculate(int $productId)
|
|
{
|
|
return ApiResponse::handle(function () use ($productId) {
|
|
$inputParameters = request()->input('input_parameters', []);
|
|
$updateBom = request()->boolean('update_bom', true);
|
|
|
|
return $this->service->recalculateProduct($productId, $inputParameters, $updateBom);
|
|
}, __('message.product.recalculated'));
|
|
}
|
|
|
|
/**
|
|
* @OA\Get(
|
|
* path="/v1/products/{productId}/model-info",
|
|
* summary="Get product model information",
|
|
* description="Retrieve the model information used to create this product",
|
|
* security={{"ApiKeyAuth": {}}, {"BearerAuth": {}}},
|
|
* tags={"Product from Model"},
|
|
* @OA\Parameter(
|
|
* name="productId",
|
|
* description="Product ID",
|
|
* in="path",
|
|
* required=true,
|
|
* @OA\Schema(type="integer", example=1)
|
|
* ),
|
|
* @OA\Response(
|
|
* response=200,
|
|
* description="Product model information retrieved successfully",
|
|
* @OA\JsonContent(
|
|
* allOf={
|
|
* @OA\Schema(ref="#/components/schemas/ApiResponse"),
|
|
* @OA\Schema(
|
|
* @OA\Property(
|
|
* property="data",
|
|
* @OA\Property(property="model_id", type="integer", example=1),
|
|
* @OA\Property(property="model_code", type="string", example="KSS01"),
|
|
* @OA\Property(property="model_name", type="string", example="Standard Screen"),
|
|
* @OA\Property(property="model_version", type="string", example="v1.0"),
|
|
* @OA\Property(property="creation_timestamp", type="string", format="date-time"),
|
|
* @OA\Property(
|
|
* property="input_parameters_used",
|
|
* type="object",
|
|
* additionalProperties=@OA\Property(oneOf={
|
|
* @OA\Schema(type="number"),
|
|
* @OA\Schema(type="string"),
|
|
* @OA\Schema(type="boolean")
|
|
* }),
|
|
* example={"W0": 1000, "H0": 800, "installation_type": "A"}
|
|
* )
|
|
* )
|
|
* )
|
|
* }
|
|
* )
|
|
* ),
|
|
* @OA\Response(ref="#/components/responses/ErrorResponse", response=400),
|
|
* @OA\Response(ref="#/components/responses/UnauthorizedResponse", response=401),
|
|
* @OA\Response(ref="#/components/responses/NotFoundResponse", response=404)
|
|
* )
|
|
*/
|
|
public function getModelInfo(int $productId)
|
|
{
|
|
return ApiResponse::handle(function () use ($productId) {
|
|
return $this->service->getProductModelInfo($productId);
|
|
}, __('message.fetched'));
|
|
}
|
|
} |