Files
sam-api/app/Services/ModelParameterService.php
kent bf8036a64b feat: DB 연결 오버라이딩 및 대시보드 통계 위젯 추가
- DB 연결: 로컬/Docker 환경 오버라이딩 설정 (.env)
- 테넌트 위젯: redirect 버그 수정 (TenantSelectorWidget)
- 통계 위젯: 사용자/제품/자재/주문 카드 추가 (StatsOverviewWidget)
- 리소스 한국어화: Product, Material 모델 레이블 추가
- 대시보드: 위젯 등록 및 캐시 최적화

🤖 Generated with [Claude Code](https://claude.ai/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-30 23:31:14 +09:00

278 lines
8.1 KiB
PHP

<?php
namespace App\Services;
use App\Services\Service;
use Shared\Models\Products\ModelParameter;
use Shared\Models\Products\ModelMaster;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Pagination\LengthAwarePaginator;
/**
* Model Parameter Service
* 모델 매개변수 관리 서비스
*/
class ModelParameterService extends Service
{
/**
* 모델별 매개변수 목록 조회
*/
public function getParametersByModel(int $modelId, bool $paginate = false, int $perPage = 15): Collection|LengthAwarePaginator
{
$this->validateModelAccess($modelId);
$query = ModelParameter::where('model_id', $modelId)
->active()
->ordered()
->with('model');
if ($paginate) {
return $query->paginate($perPage);
}
return $query->get();
}
/**
* 매개변수 상세 조회
*/
public function getParameter(int $id): ModelParameter
{
$parameter = ModelParameter::where('tenant_id', $this->tenantId())
->findOrFail($id);
$this->validateModelAccess($parameter->model_id);
return $parameter;
}
/**
* 매개변수 생성
*/
public function createParameter(array $data): ModelParameter
{
$this->validateModelAccess($data['model_id']);
// 기본값 설정
$data['tenant_id'] = $this->tenantId();
$data['created_by'] = $this->apiUserId();
// 순서가 지정되지 않은 경우 마지막으로 설정
if (!isset($data['order'])) {
$maxOrder = ModelParameter::where('tenant_id', $this->tenantId())
->where('model_id', $data['model_id'])
->max('order') ?? 0;
$data['order'] = $maxOrder + 1;
}
// 매개변수명 중복 체크
$this->validateParameterNameUnique($data['model_id'], $data['name']);
// 검증 규칙 처리
if (isset($data['validation_rules']) && is_string($data['validation_rules'])) {
$data['validation_rules'] = json_decode($data['validation_rules'], true);
}
// 옵션 처리 (SELECT 타입)
if (isset($data['options']) && is_string($data['options'])) {
$data['options'] = json_decode($data['options'], true);
}
$parameter = ModelParameter::create($data);
return $parameter->fresh();
}
/**
* 매개변수 수정
*/
public function updateParameter(int $id, array $data): ModelParameter
{
$parameter = $this->getParameter($id);
// 매개변수명 변경 시 중복 체크
if (isset($data['name']) && $data['name'] !== $parameter->name) {
$this->validateParameterNameUnique($parameter->model_id, $data['name'], $id);
}
// 검증 규칙 처리
if (isset($data['validation_rules']) && is_string($data['validation_rules'])) {
$data['validation_rules'] = json_decode($data['validation_rules'], true);
}
// 옵션 처리
if (isset($data['options']) && is_string($data['options'])) {
$data['options'] = json_decode($data['options'], true);
}
$data['updated_by'] = $this->apiUserId();
$parameter->update($data);
return $parameter->fresh();
}
/**
* 매개변수 삭제
*/
public function deleteParameter(int $id): bool
{
$parameter = $this->getParameter($id);
// 다른 공식에서 사용 중인지 확인
$this->validateParameterNotInUse($parameter->model_id, $parameter->name);
$parameter->update(['deleted_by' => $this->apiUserId()]);
$parameter->delete();
return true;
}
/**
* 매개변수 순서 변경
*/
public function reorderParameters(int $modelId, array $orderData): bool
{
$this->validateModelAccess($modelId);
foreach ($orderData as $item) {
ModelParameter::where('tenant_id', $this->tenantId())
->where('model_id', $modelId)
->where('id', $item['id'])
->update([
'order' => $item['order'],
'updated_by' => $this->apiUserId()
]);
}
return true;
}
/**
* 매개변수 복사 (다른 모델로)
*/
public function copyParametersToModel(int $sourceModelId, int $targetModelId): Collection
{
$this->validateModelAccess($sourceModelId);
$this->validateModelAccess($targetModelId);
$sourceParameters = $this->getParametersByModel($sourceModelId);
$copiedParameters = collect();
foreach ($sourceParameters as $sourceParam) {
$data = $sourceParam->toArray();
unset($data['id'], $data['created_at'], $data['updated_at'], $data['deleted_at']);
$data['model_id'] = $targetModelId;
$data['created_by'] = $this->apiUserId();
// 이름 중복 시 수정
$originalName = $data['name'];
$counter = 1;
while ($this->isParameterNameExists($targetModelId, $data['name'])) {
$data['name'] = $originalName . '_' . $counter;
$counter++;
}
$copiedParameter = ModelParameter::create($data);
$copiedParameters->push($copiedParameter);
}
return $copiedParameters;
}
/**
* 매개변수 값 검증
*/
public function validateParameterValues(int $modelId, array $values): array
{
$this->validateModelAccess($modelId);
$parameters = $this->getParametersByModel($modelId);
$errors = [];
foreach ($parameters as $parameter) {
$value = $values[$parameter->name] ?? null;
$paramErrors = $parameter->validateValue($value);
if (!empty($paramErrors)) {
$errors[$parameter->name] = $paramErrors;
}
}
return $errors;
}
/**
* 매개변수 값을 적절한 타입으로 변환
*/
public function castParameterValues(int $modelId, array $values): array
{
$this->validateModelAccess($modelId);
$parameters = $this->getParametersByModel($modelId);
$castedValues = [];
foreach ($parameters as $parameter) {
$value = $values[$parameter->name] ?? null;
$castedValues[$parameter->name] = $parameter->castValue($value);
}
return $castedValues;
}
/**
* 모델 접근 권한 검증
*/
private function validateModelAccess(int $modelId): void
{
$model = ModelMaster::where('tenant_id', $this->tenantId())
->findOrFail($modelId);
}
/**
* 매개변수명 중복 검증
*/
private function validateParameterNameUnique(int $modelId, string $name, ?int $excludeId = null): void
{
$query = ModelParameter::where('tenant_id', $this->tenantId())
->where('model_id', $modelId)
->where('name', $name);
if ($excludeId) {
$query->where('id', '!=', $excludeId);
}
if ($query->exists()) {
throw new \InvalidArgumentException(__('error.parameter_name_duplicate'));
}
}
/**
* 매개변수명 존재 여부 확인
*/
private function isParameterNameExists(int $modelId, string $name): bool
{
return ModelParameter::where('tenant_id', $this->tenantId())
->where('model_id', $modelId)
->where('name', $name)
->exists();
}
/**
* 매개변수가 다른 공식에서 사용 중인지 확인
*/
private function validateParameterNotInUse(int $modelId, string $parameterName): void
{
$formulaService = new ModelFormulaService();
$formulas = $formulaService->getFormulasByModel($modelId);
foreach ($formulas as $formula) {
if (in_array($parameterName, $formula->dependencies ?? [])) {
throw new \InvalidArgumentException(__('error.parameter_in_use_by_formula', [
'parameter' => $parameterName,
'formula' => $formula->name
]));
}
}
}
}