Files
hr/app/Services/Employee/EmployeeStatisticsService.php

56 lines
1.9 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Services\Employee;
use App\DTOs\EmployeeSummaryDto;
use App\Enums\ApprovalStatus;
use App\Enums\VacationType;
use App\Models\Employee;
use App\Services\Vacation\VacationBalanceService;
use Illuminate\Database\Eloquent\Builder;
class EmployeeStatisticsService
{
public function __construct(
private readonly VacationBalanceService $vacationBalanceService,
) {}
/**
* @param Builder<Employee> $query
* @return Builder<Employee>
*/
public function applyTableAggregates(Builder $query, ?int $year = null): Builder
{
$year ??= (int) now()->year;
return $query
->with(['department', 'position'])
->withCount(['sickLeaves', 'unpaidLeaves', 'disciplinaryReports', 'explanations', 'gifts'])
->withSum('bonuses', 'amount')
->withSum(['vacations as annual_vacation_days_taken' => fn (Builder $vacationQuery): Builder => $vacationQuery
->where('type', VacationType::Annual)
->where('status', ApprovalStatus::Approved)
->whereYear('start_date', $year),
], 'days');
}
public function summary(Employee $employee): EmployeeSummaryDto
{
return new EmployeeSummaryDto(
vacationTaken: $this->vacationBalanceService->takenAnnualDays($employee),
vacationRemaining: $this->vacationBalanceService->remainingAnnualDays($employee),
sickLeaveCount: $employee->sickLeaves()->count(),
reportsCount: $employee->disciplinaryReports()->count(),
bonusesTotal: (float) $employee->bonuses()->sum('amount'),
giftsCount: $employee->gifts()->count(),
upcomingLeave: $employee->vacations()
->where('status', ApprovalStatus::Approved)
->where('start_date', '>=', now()->toDateString())
->orderBy('start_date')
->get(),
);
}
}