141 lines
3.6 KiB
PHP
141 lines
3.6 KiB
PHP
|
|
<?php
|
||
|
|
|
||
|
|
namespace App\Services;
|
||
|
|
|
||
|
|
use App\Models\Tenants\Position;
|
||
|
|
use Illuminate\Support\Facades\DB;
|
||
|
|
|
||
|
|
class PositionService extends Service
|
||
|
|
{
|
||
|
|
/**
|
||
|
|
* 목록 조회
|
||
|
|
*/
|
||
|
|
public function index(array $params)
|
||
|
|
{
|
||
|
|
$query = Position::query()
|
||
|
|
->when(isset($params['type']), fn ($q) => $q->where('type', $params['type']))
|
||
|
|
->when(isset($params['is_active']), fn ($q) => $q->where('is_active', (bool) $params['is_active']))
|
||
|
|
->when(! empty($params['q']), fn ($q) => $q->where('name', 'like', '%'.$params['q'].'%'))
|
||
|
|
->ordered();
|
||
|
|
|
||
|
|
if (isset($params['per_page'])) {
|
||
|
|
return $query->paginate((int) $params['per_page']);
|
||
|
|
}
|
||
|
|
|
||
|
|
return $query->get();
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 단건 조회
|
||
|
|
*/
|
||
|
|
public function show(int $id)
|
||
|
|
{
|
||
|
|
$position = Position::find($id);
|
||
|
|
|
||
|
|
if (! $position) {
|
||
|
|
return ['error' => __('error.not_found'), 'code' => 404];
|
||
|
|
}
|
||
|
|
|
||
|
|
return $position;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 생성
|
||
|
|
*/
|
||
|
|
public function store(array $data)
|
||
|
|
{
|
||
|
|
$tenantId = $this->tenantId();
|
||
|
|
|
||
|
|
// 중복 체크
|
||
|
|
$exists = Position::where('tenant_id', $tenantId)
|
||
|
|
->where('type', $data['type'])
|
||
|
|
->where('name', $data['name'])
|
||
|
|
->exists();
|
||
|
|
|
||
|
|
if ($exists) {
|
||
|
|
return ['error' => __('error.duplicate'), 'code' => 409];
|
||
|
|
}
|
||
|
|
|
||
|
|
// 정렬 순서 자동 설정
|
||
|
|
if (! isset($data['sort_order'])) {
|
||
|
|
$maxOrder = Position::where('tenant_id', $tenantId)
|
||
|
|
->where('type', $data['type'])
|
||
|
|
->max('sort_order') ?? 0;
|
||
|
|
$data['sort_order'] = $maxOrder + 1;
|
||
|
|
}
|
||
|
|
|
||
|
|
$position = Position::create([
|
||
|
|
'tenant_id' => $tenantId,
|
||
|
|
'type' => $data['type'],
|
||
|
|
'name' => $data['name'],
|
||
|
|
'sort_order' => $data['sort_order'],
|
||
|
|
'is_active' => $data['is_active'] ?? true,
|
||
|
|
]);
|
||
|
|
|
||
|
|
return $position;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 수정
|
||
|
|
*/
|
||
|
|
public function update(int $id, array $data)
|
||
|
|
{
|
||
|
|
$position = Position::find($id);
|
||
|
|
|
||
|
|
if (! $position) {
|
||
|
|
return ['error' => __('error.not_found'), 'code' => 404];
|
||
|
|
}
|
||
|
|
|
||
|
|
// 이름 중복 체크 (자기 자신 제외)
|
||
|
|
if (isset($data['name'])) {
|
||
|
|
$exists = Position::where('tenant_id', $position->tenant_id)
|
||
|
|
->where('type', $position->type)
|
||
|
|
->where('name', $data['name'])
|
||
|
|
->where('id', '!=', $id)
|
||
|
|
->exists();
|
||
|
|
|
||
|
|
if ($exists) {
|
||
|
|
return ['error' => __('error.duplicate'), 'code' => 409];
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
$position->update([
|
||
|
|
'name' => $data['name'] ?? $position->name,
|
||
|
|
'sort_order' => $data['sort_order'] ?? $position->sort_order,
|
||
|
|
'is_active' => $data['is_active'] ?? $position->is_active,
|
||
|
|
]);
|
||
|
|
|
||
|
|
return $position->fresh();
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 삭제
|
||
|
|
*/
|
||
|
|
public function destroy(int $id)
|
||
|
|
{
|
||
|
|
$position = Position::find($id);
|
||
|
|
|
||
|
|
if (! $position) {
|
||
|
|
return ['error' => __('error.not_found'), 'code' => 404];
|
||
|
|
}
|
||
|
|
|
||
|
|
$position->delete();
|
||
|
|
|
||
|
|
return ['id' => $id, 'deleted_at' => now()->toDateTimeString()];
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 순서 변경 (벌크)
|
||
|
|
*/
|
||
|
|
public function reorder(array $items)
|
||
|
|
{
|
||
|
|
DB::transaction(function () use ($items) {
|
||
|
|
foreach ($items as $item) {
|
||
|
|
Position::where('id', $item['id'])
|
||
|
|
->update(['sort_order' => $item['sort_order']]);
|
||
|
|
}
|
||
|
|
});
|
||
|
|
|
||
|
|
return ['success' => true, 'updated' => count($items)];
|
||
|
|
}
|
||
|
|
}
|