- 컨트롤러와 서비스에서 각각 래핑 후 결과 전달됨으로 이중 래핑되고 있음 -> 서비스에서 래핑하는 부분을 컨트롤러로 옮겨서 컨트롤러에서만 한번 래핑하는 걸로 수정
186 lines
5.6 KiB
PHP
186 lines
5.6 KiB
PHP
<?php
|
|
|
|
namespace App\Services;
|
|
|
|
use App\Helpers\ApiResponse;
|
|
use Illuminate\Support\Facades\Validator;
|
|
use Illuminate\Validation\Rule;
|
|
|
|
use App\Models\Tenants\TenantOptionGroup;
|
|
use App\Models\Tenants\TenantOptionValue;
|
|
use App\Models\Tenants\TenantFieldSetting;
|
|
|
|
class TenantOptionGroupService
|
|
{
|
|
/** 활성 테넌트 ID */
|
|
protected static function tenantId(): ?int
|
|
{
|
|
return app('tenant_id');
|
|
}
|
|
|
|
/**
|
|
* [GET] 옵션 그룹 목록 (페이징)
|
|
* params: page?, per_page?/size?, q?
|
|
*/
|
|
public static function index(array $params = [])
|
|
{
|
|
$tenantId = self::tenantId();
|
|
if (!$tenantId) {
|
|
return ['error' => '활성 테넌트가 없습니다.', 'code' => 400];
|
|
}
|
|
|
|
$per = (int)($params['per_page'] ?? $params['size'] ?? 20);
|
|
$page = isset($params['page']) ? (int)$params['page'] : null;
|
|
|
|
$q = TenantOptionGroup::where('tenant_id', $tenantId)->orderBy('group_key');
|
|
|
|
if (!empty($params['q'])) {
|
|
$kw = $params['q'];
|
|
$q->where(function ($w) use ($kw) {
|
|
$w->where('group_key', 'like', "%{$kw}%")
|
|
->orWhere('name', 'like', "%{$kw}%");
|
|
});
|
|
}
|
|
|
|
$data = $q->paginate($per, ['*'], 'page', $page);
|
|
|
|
return $data;
|
|
}
|
|
|
|
/**
|
|
* [POST] 옵션 그룹 생성
|
|
*/
|
|
public static function store(array $params = [])
|
|
{
|
|
$tenantId = self::tenantId();
|
|
if (!$tenantId) {
|
|
return ['error' => '활성 테넌트가 없습니다.', 'code' => 400];
|
|
}
|
|
|
|
$v = Validator::make($params, [
|
|
'group_key' => [
|
|
'required','string','max:64','alpha_dash',
|
|
Rule::unique('tenant_option_groups', 'group_key')
|
|
->where(fn ($q) => $q->where('tenant_id', $tenantId)),
|
|
],
|
|
'name' => ['required','string','max:100'],
|
|
'description' => ['nullable','string','max:255'],
|
|
]);
|
|
|
|
if ($v->fails()) {
|
|
return ['error' => $v->errors()->first(), 'code' => 422];
|
|
}
|
|
|
|
$data = $v->validated();
|
|
$data['tenant_id'] = $tenantId;
|
|
|
|
$item = TenantOptionGroup::create($data);
|
|
|
|
return $item->toArray();
|
|
}
|
|
|
|
/**
|
|
* [GET] 옵션 그룹 단건 조회
|
|
*/
|
|
public static function show(int $id)
|
|
{
|
|
$tenantId = self::tenantId();
|
|
if (!$tenantId) {
|
|
return ['error' => '활성 테넌트가 없습니다.', 'code' => 400];
|
|
}
|
|
if (!$id) {
|
|
return ['error' => 'id가 올바르지 않습니다.', 'code' => 422];
|
|
}
|
|
|
|
$item = TenantOptionGroup::where('tenant_id', $tenantId)->find($id);
|
|
if (!$item) {
|
|
return ['error' => '옵션 그룹을 찾을 수 없습니다.', 'code' => 404];
|
|
}
|
|
|
|
return $item->toArray();
|
|
}
|
|
|
|
/**
|
|
* [PATCH] 옵션 그룹 수정
|
|
*/
|
|
public static function update(int $id, array $params = [])
|
|
{
|
|
$tenantId = self::tenantId();
|
|
if (!$tenantId) {
|
|
return ['error' => '활성 테넌트가 없습니다.', 'code' => 400];
|
|
}
|
|
if (!$id) {
|
|
return ['error' => 'id가 올바르지 않습니다.', 'code' => 422];
|
|
}
|
|
|
|
$item = TenantOptionGroup::where('tenant_id', $tenantId)->find($id);
|
|
if (!$item) {
|
|
return ['error' => '옵션 그룹을 찾을 수 없습니다.', 'code' => 404];
|
|
}
|
|
|
|
$v = Validator::make($params, [
|
|
'group_key' => [
|
|
'sometimes','string','max:64','alpha_dash',
|
|
Rule::unique('tenant_option_groups', 'group_key')
|
|
->where(fn ($q) => $q->where('tenant_id', $tenantId))
|
|
->ignore($item->id),
|
|
],
|
|
'name' => ['sometimes','string','max:100'],
|
|
'description' => ['nullable','string','max:255'],
|
|
]);
|
|
|
|
if ($v->fails()) {
|
|
return ['error' => $v->errors()->first(), 'code' => 422];
|
|
}
|
|
|
|
$data = $v->validated();
|
|
if (empty($data)) {
|
|
return ['error' => '수정할 항목이 없습니다.', 'code' => 422];
|
|
}
|
|
|
|
$item->fill($data)->save();
|
|
|
|
return $item->toArray();
|
|
}
|
|
|
|
/**
|
|
* [DELETE] 옵션 그룹 삭제
|
|
* - 참조 무결성 검사:
|
|
* 1) tenant_option_values에 값이 남아있으면 삭제 불가
|
|
* 2) tenant_field_settings.option_group_id에서 참조 중이면 삭제 불가
|
|
*/
|
|
public static function destroy(int $id)
|
|
{
|
|
$tenantId = self::tenantId();
|
|
if (!$tenantId) {
|
|
return ['error' => '활성 테넌트가 없습니다.', 'code' => 400];
|
|
}
|
|
if (!$id) {
|
|
return ['error' => 'id가 올바르지 않습니다.', 'code' => 422];
|
|
}
|
|
|
|
$item = TenantOptionGroup::where('tenant_id', $tenantId)->find($id);
|
|
if (!$item) {
|
|
return ['error' => '옵션 그룹을 찾을 수 없습니다.', 'code' => 404];
|
|
}
|
|
|
|
// 1) 옵션 값 존재 여부
|
|
$hasValues = TenantOptionValue::where('group_id', $item->id)->exists();
|
|
if ($hasValues) {
|
|
return ['error' => '해당 그룹에 옵션 값이 존재하여 삭제할 수 없습니다.', 'code' => 409];
|
|
}
|
|
|
|
// 2) 필드 설정에서 참조 여부
|
|
$isReferenced = TenantFieldSetting::where('tenant_id', $tenantId)
|
|
->where('option_group_id', $item->id)
|
|
->exists();
|
|
if ($isReferenced) {
|
|
return ['error' => '필드 설정에서 참조 중인 그룹은 삭제할 수 없습니다.', 'code' => 409];
|
|
}
|
|
|
|
$item->delete();
|
|
|
|
return ['deleted' => true];
|
|
}
|
|
}
|