feat: [hr] 근태관리 영업팀 및 제외 사원 필터링 적용
- 근태 목록/통계/요약/초과근무에서 영업팀+제외 사원 제외 - 근태관리 부서 드롭다운에서 영업팀 제외 - 활성 사원 목록(드롭다운)에서 영업팀+제외 사원 제외
This commit is contained in:
@@ -12,6 +12,24 @@
|
||||
|
||||
class AttendanceService
|
||||
{
|
||||
/**
|
||||
* 제외 대상 사원의 user_id 목록 (영업팀 + 강제 제외)
|
||||
*/
|
||||
private function getExcludedUserIds(?int $tenantId = null): array
|
||||
{
|
||||
$tenantId = $tenantId ?? session('selected_tenant_id');
|
||||
|
||||
return Employee::query()
|
||||
->forTenant($tenantId)
|
||||
->where(function ($q) {
|
||||
$q->whereHas('department', function ($dq) {
|
||||
$dq->where('name', 'like', '%영업팀%');
|
||||
})->orWhere('json_extra->is_excluded', true);
|
||||
})
|
||||
->pluck('user_id')
|
||||
->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* 필터 적용 쿼리 생성 (목록/엑셀 공통)
|
||||
*/
|
||||
@@ -23,6 +41,12 @@ private function buildFilteredQuery(array $filters = [])
|
||||
->with(['user', 'user.tenantProfiles' => fn ($q) => $q->where('tenant_id', $tenantId), 'user.tenantProfiles.department'])
|
||||
->forTenant($tenantId);
|
||||
|
||||
// 제외 사원 필터링 (영업팀 부서 + 강제 제외)
|
||||
$excludedUserIds = $this->getExcludedUserIds($tenantId);
|
||||
if (! empty($excludedUserIds)) {
|
||||
$query->whereNotIn('user_id', $excludedUserIds);
|
||||
}
|
||||
|
||||
if (! empty($filters['q'])) {
|
||||
$search = $filters['q'];
|
||||
$query->whereHas('user', function ($q) use ($search) {
|
||||
@@ -82,9 +106,18 @@ public function getMonthlyStats(?int $year = null, ?int $month = null): array
|
||||
? now()->toDateString()
|
||||
: Carbon::create($year, $month, 1)->endOfMonth()->toDateString();
|
||||
|
||||
$counts = Attendance::query()
|
||||
// 제외 사원 필터링
|
||||
$excludedUserIds = $this->getExcludedUserIds($tenantId);
|
||||
|
||||
$statsQuery = Attendance::query()
|
||||
->forTenant($tenantId)
|
||||
->betweenDates($startDate, $endDate)
|
||||
->betweenDates($startDate, $endDate);
|
||||
|
||||
if (! empty($excludedUserIds)) {
|
||||
$statsQuery->whereNotIn('user_id', $excludedUserIds);
|
||||
}
|
||||
|
||||
$counts = $statsQuery
|
||||
->select('status', DB::raw('COUNT(*) as cnt'))
|
||||
->groupBy('status')
|
||||
->pluck('cnt', 'status')
|
||||
@@ -364,9 +397,17 @@ public function getEmployeeMonthlySummary(int $year, int $month): array
|
||||
$startDate = sprintf('%04d-%02d-01', $year, $month);
|
||||
$endDate = Carbon::create($year, $month, 1)->endOfMonth()->toDateString();
|
||||
|
||||
$raw = Attendance::query()
|
||||
$excludedUserIds = $this->getExcludedUserIds($tenantId);
|
||||
|
||||
$summaryQuery = Attendance::query()
|
||||
->forTenant($tenantId)
|
||||
->betweenDates($startDate, $endDate)
|
||||
->betweenDates($startDate, $endDate);
|
||||
|
||||
if (! empty($excludedUserIds)) {
|
||||
$summaryQuery->whereNotIn('user_id', $excludedUserIds);
|
||||
}
|
||||
|
||||
$raw = $summaryQuery
|
||||
->select(
|
||||
'user_id',
|
||||
'status',
|
||||
@@ -418,9 +459,17 @@ public function getOvertimeAlerts(): array
|
||||
$weekStart = now()->startOfWeek(Carbon::MONDAY)->toDateString();
|
||||
$weekEnd = now()->endOfWeek(Carbon::SUNDAY)->toDateString();
|
||||
|
||||
$results = Attendance::query()
|
||||
$excludedUserIds = $this->getExcludedUserIds($tenantId);
|
||||
|
||||
$overtimeQuery = Attendance::query()
|
||||
->forTenant($tenantId)
|
||||
->betweenDates($weekStart, $weekEnd)
|
||||
->betweenDates($weekStart, $weekEnd);
|
||||
|
||||
if (! empty($excludedUserIds)) {
|
||||
$overtimeQuery->whereNotIn('user_id', $excludedUserIds);
|
||||
}
|
||||
|
||||
$results = $overtimeQuery
|
||||
->select(
|
||||
'user_id',
|
||||
DB::raw("SUM(GREATEST(0, COALESCE(CAST(JSON_UNQUOTE(JSON_EXTRACT(json_details, '$.work_minutes')) AS SIGNED), 0))) as week_minutes")
|
||||
|
||||
@@ -764,13 +764,14 @@ public function getDepartments(): \Illuminate\Database\Eloquent\Collection
|
||||
return Department::query()
|
||||
->where('is_active', true)
|
||||
->when($tenantId, fn ($q) => $q->where('tenant_id', $tenantId))
|
||||
->where('name', 'not like', '%영업팀%')
|
||||
->orderBy('sort_order')
|
||||
->orderBy('name')
|
||||
->get(['id', 'name', 'code']);
|
||||
}
|
||||
|
||||
/**
|
||||
* 활성 사원 목록 (드롭다운용)
|
||||
* 활성 사원 목록 (드롭다운용) — 영업팀 + 강제 제외 사원 제외
|
||||
*/
|
||||
public function getActiveEmployees(): \Illuminate\Database\Eloquent\Collection
|
||||
{
|
||||
@@ -780,6 +781,15 @@ public function getActiveEmployees(): \Illuminate\Database\Eloquent\Collection
|
||||
->with('user:id,name')
|
||||
->forTenant($tenantId)
|
||||
->activeEmployees()
|
||||
->where(function ($q) {
|
||||
$q->whereDoesntHave('department', function ($dq) {
|
||||
$dq->where('name', 'like', '%영업팀%');
|
||||
})->orWhereNull('department_id');
|
||||
})
|
||||
->where(function ($q) {
|
||||
$q->whereNull('json_extra->is_excluded')
|
||||
->orWhere('json_extra->is_excluded', false);
|
||||
})
|
||||
->orderBy('display_name')
|
||||
->get(['id', 'user_id', 'display_name', 'department_id']);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user