Files
sam-manage/app/Http/Controllers/Api/Admin/HR/EmployeeController.php
김보곤 a1ca8b7e46 refactor: [hr] 사번(employee_code) 필드 전체 제거
- Model: appends, accessor 제거
- Service: 검색 필터, json_extra 저장/수정 로직 제거
- Controller: validation 규칙 제거
- View: create, edit, show, table에서 사번 UI 제거
2026-02-26 18:50:12 +09:00

253 lines
8.1 KiB
PHP

<?php
namespace App\Http\Controllers\Api\Admin\HR;
use App\Http\Controllers\Controller;
use App\Services\HR\EmployeeService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
class EmployeeController extends Controller
{
public function __construct(
private EmployeeService $employeeService
) {}
/**
* 사원 목록 조회 (HTMX → HTML / 일반 → JSON)
*/
public function index(Request $request): JsonResponse|Response
{
$employees = $this->employeeService->getEmployees(
$request->all(),
$request->integer('per_page', 20)
);
if ($request->header('HX-Request')) {
return response(view('hr.employees.partials.table', compact('employees')));
}
return response()->json([
'success' => true,
'data' => $employees->items(),
'meta' => [
'current_page' => $employees->currentPage(),
'last_page' => $employees->lastPage(),
'per_page' => $employees->perPage(),
'total' => $employees->total(),
],
]);
}
/**
* 기존 사용자 검색 (사원 미등록, 테넌트 소속)
*/
public function searchUsers(Request $request): JsonResponse
{
$users = $this->employeeService->searchTenantUsers($request->get('q') ?? '');
return response()->json([
'success' => true,
'data' => $users,
]);
}
/**
* 사원 통계
*/
public function stats(): JsonResponse
{
$stats = $this->employeeService->getStats();
return response()->json([
'success' => true,
'data' => $stats,
]);
}
/**
* 사원 등록
*/
public function store(Request $request): JsonResponse
{
$rules = [
'existing_user_id' => 'nullable|integer|exists:users,id',
'name' => 'required|string|max:50',
'email' => 'nullable|email|max:100',
'phone' => 'nullable|string|max:20',
'password' => 'nullable|string|min:6',
'department_id' => 'nullable|integer|exists:departments,id',
'position_key' => 'nullable|string|max:50',
'job_title_key' => 'nullable|string|max:50',
'work_location_key' => 'nullable|string|max:50',
'employment_type_key' => 'nullable|string|max:50',
'employee_status' => 'nullable|string|in:active,leave,resigned',
'manager_user_id' => 'nullable|integer|exists:users,id',
'display_name' => 'nullable|string|max:50',
'hire_date' => 'nullable|date',
'address' => 'nullable|string|max:200',
'emergency_contact' => 'nullable|string|max:100',
];
// 신규 사용자일 때만 이메일 unique 검증
if (! $request->filled('existing_user_id')) {
$rules['email'] = 'nullable|email|max:100|unique:users,email';
}
$validated = $request->validate($rules);
try {
$employee = $this->employeeService->createEmployee($validated);
return response()->json([
'success' => true,
'message' => '사원이 등록되었습니다.',
'data' => $employee,
], 201);
} catch (\Throwable $e) {
report($e);
return response()->json([
'success' => false,
'message' => '사원 등록 중 오류가 발생했습니다.',
'error' => config('app.debug') ? $e->getMessage() : null,
], 500);
}
}
/**
* 사원 상세 조회
*/
public function show(int $id): JsonResponse
{
$employee = $this->employeeService->getEmployeeById($id);
if (! $employee) {
return response()->json([
'success' => false,
'message' => '사원 정보를 찾을 수 없습니다.',
], 404);
}
return response()->json([
'success' => true,
'data' => $employee,
]);
}
/**
* 사원 수정
*/
public function update(Request $request, int $id): JsonResponse
{
$validated = $request->validate([
'name' => 'sometimes|required|string|max:50',
'email' => 'nullable|email|max:100',
'phone' => 'nullable|string|max:20',
'department_id' => 'nullable|integer|exists:departments,id',
'position_key' => 'nullable|string|max:50',
'job_title_key' => 'nullable|string|max:50',
'work_location_key' => 'nullable|string|max:50',
'employment_type_key' => 'nullable|string|max:50',
'employee_status' => 'nullable|string|in:active,leave,resigned',
'manager_user_id' => 'nullable|integer|exists:users,id',
'display_name' => 'nullable|string|max:50',
'hire_date' => 'nullable|date',
'address' => 'nullable|string|max:200',
'emergency_contact' => 'nullable|string|max:100',
]);
try {
$employee = $this->employeeService->updateEmployee($id, $validated);
if (! $employee) {
return response()->json([
'success' => false,
'message' => '사원 정보를 찾을 수 없습니다.',
], 404);
}
return response()->json([
'success' => true,
'message' => '사원 정보가 수정되었습니다.',
'data' => $employee,
]);
} catch (\Throwable $e) {
report($e);
return response()->json([
'success' => false,
'message' => '사원 수정 중 오류가 발생했습니다.',
'error' => config('app.debug') ? $e->getMessage() : null,
], 500);
}
}
/**
* 사원 삭제 (퇴직 처리)
*/
public function destroy(Request $request, int $id): JsonResponse|Response
{
try {
$result = $this->employeeService->deleteEmployee($id);
if (! $result) {
if ($request->header('HX-Request')) {
return response()->json([
'success' => false,
'message' => '사원 정보를 찾을 수 없습니다.',
], 404);
}
return response()->json([
'success' => false,
'message' => '사원 정보를 찾을 수 없습니다.',
], 404);
}
if ($request->header('HX-Request')) {
$employees = $this->employeeService->getEmployees($request->all(), $request->integer('per_page', 20));
return response(view('hr.employees.partials.table', compact('employees')));
}
return response()->json([
'success' => true,
'message' => '퇴직 처리되었습니다.',
]);
} catch (\Throwable $e) {
report($e);
return response()->json([
'success' => false,
'message' => '퇴직 처리 중 오류가 발생했습니다.',
'error' => config('app.debug') ? $e->getMessage() : null,
], 500);
}
}
/**
* 직급/직책 추가
*/
public function storePosition(Request $request): JsonResponse
{
$validated = $request->validate([
'type' => 'required|string|in:rank,title',
'name' => 'required|string|max:50',
]);
$position = $this->employeeService->createPosition($validated['type'], $validated['name']);
return response()->json([
'success' => true,
'message' => ($validated['type'] === 'rank' ? '직급' : '직책').'이 추가되었습니다.',
'data' => [
'id' => $position->id,
'key' => $position->key,
'name' => $position->name,
],
], 201);
}
}