feat: [hr] 연차잔여 탭에 재직상태 필터 추가 (전체/재직자/퇴직자)

- 필터 기본값: 재직자 (active + leave)
- 퇴직자 선택 시 resigned만 표시
- 전체 선택 시 모든 상태 표시
This commit is contained in:
김보곤
2026-03-05 15:16:54 +09:00
parent 013df2592f
commit 8af1647173
4 changed files with 29 additions and 5 deletions

View File

@@ -229,10 +229,11 @@ public function balance(Request $request): JsonResponse|Response
$year = $request->integer('year', now()->year);
$sort = $request->input('sort', 'hire_date');
$direction = $request->input('direction', 'asc');
$balances = $this->leaveService->getBalanceSummary($year, $sort, $direction);
$empStatus = $request->input('emp_status');
$balances = $this->leaveService->getBalanceSummary($year, $sort, $direction, $empStatus);
if ($request->header('HX-Request')) {
return response(view('hr.leaves.partials.balance', compact('balances', 'year', 'sort', 'direction')));
return response(view('hr.leaves.partials.balance', compact('balances', 'year', 'sort', 'direction', 'empStatus')));
}
return response()->json([

View File

@@ -481,7 +481,7 @@ public function rejectByApproval(Leave $leave, string $comment, int $rejecterId)
* 사원관리의 모든 재직/휴직 직원을 표시하며,
* balance 레코드가 없는 직원은 자동 생성한다.
*/
public function getBalanceSummary(?int $year = null, ?string $sort = null, ?string $direction = null): Collection
public function getBalanceSummary(?int $year = null, ?string $sort = null, ?string $direction = null, ?string $empStatus = null): Collection
{
$tenantId = session('selected_tenant_id');
$year = $year ?? now()->year;
@@ -489,11 +489,17 @@ public function getBalanceSummary(?int $year = null, ?string $sort = null, ?stri
// (1) 테넌트 연차 정책 조회
$policy = LeavePolicy::forTenant($tenantId)->first();
// (2) 재직/휴직/퇴사 직원 전체 조회
// (2) 재직상태 필터에 따른 직원 조회
$statusFilter = match ($empStatus) {
'active' => ['active', 'leave'],
'resigned' => ['resigned'],
default => ['active', 'leave', 'resigned'],
};
$employees = Employee::query()
->with(['user:id,name', 'department:id,name'])
->forTenant($tenantId)
->whereIn('employee_status', ['active', 'leave', 'resigned'])
->whereIn('employee_status', $statusFilter)
->get();
// (3) 기존 balance 일괄 조회

View File

@@ -136,6 +136,14 @@ class="w-full px-3 py-2 text-sm border border-gray-300 rounded-lg focus:ring-2 f
@endfor
</select>
</div>
<div style="flex: 0 0 130px;">
<label class="block text-xs font-medium text-gray-600 mb-1">재직상태</label>
<select id="balance-emp-status" class="w-full px-3 py-2 text-sm border border-gray-300 rounded-lg" onchange="loadBalance()">
<option value="">전체</option>
<option value="active" selected>재직자</option>
<option value="resigned">퇴직자</option>
</select>
</div>
<div class="shrink-0">
<button onclick="loadBalance()" class="px-4 py-2 bg-gray-100 hover:bg-gray-200 text-gray-700 text-sm font-medium rounded-lg transition-colors">
조회
@@ -247,7 +255,9 @@ function loadRequests(page) {
// =========================================================================
function loadBalance(sort, direction) {
const year = document.getElementById('balance-year')?.value || new Date().getFullYear();
const empStatus = document.getElementById('balance-emp-status')?.value || '';
const params = new URLSearchParams({ year });
if (empStatus) params.set('emp_status', empStatus);
if (sort) params.set('sort', sort);
if (direction) params.set('direction', direction);

View File

@@ -174,6 +174,13 @@ class="inline-flex items-center gap-1 hover:text-blue-600 transition-colors">
</x-table-swipe>
@if($balances->count())
@php
$statusLabel = match($empStatus ?? null) {
'active' => '재직자',
'resigned' => '퇴직자',
default => '전체',
};
@endphp
<div class="px-6 py-3 bg-gray-50 border-t border-gray-200 text-sm text-gray-500">
{{ $balances->count() }} | 부여합계: {{ $balances->sum('total_days') }} | 사용합계: {{ $balances->sum('used_days') }} | 잔여합계: {{ $balances->sum('total_days') - $balances->sum('used_days') }}
</div>