Files
hr/app/Filament/Widgets/UpcomingBirthdaysWidget.php
2026-07-31 18:08:08 +05:00

84 lines
2.4 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Filament\Widgets;
use App\Models\Employee;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Table;
use Filament\Widgets\TableWidget;
use Illuminate\Database\Eloquent\Builder;
class UpcomingBirthdaysWidget extends TableWidget
{
protected int | string | array $columnSpan = 1;
public function getHeading(): ?string
{
return __('hr.widgets.upcoming_birthdays');
}
public function table(Table $table): Table
{
return $table
->query(
Employee::query()
->whereNotNull('birth_date')
->whereIn('id', $this->upcomingBirthdayEmployeeIds()),
)
->columns([
TextColumn::make('full_name')
->label(__('hr.fields.employee')),
TextColumn::make('birth_date')
->label(__('hr.fields.birthday'))
->date()
->formatStateUsing(fn (Employee $record): string => $record->birth_date?->format('M d') ?? '—'),
TextColumn::make('department.name')
->label(__('hr.fields.department')),
])
->paginated(false);
}
/**
* @return array<int, int>
*/
private function upcomingBirthdayEmployeeIds(): array
{
return Employee::query()
->whereNotNull('birth_date')
->get()
->filter(function (Employee $employee): bool {
if ($employee->birth_date === null) {
return false;
}
$birthday = $employee->birth_date->copy()->year(now()->year);
if ($birthday->lt(now()->startOfDay())) {
$birthday = $birthday->addYear();
}
return $birthday->lte(now()->addDays(30));
})
->sortBy(function (Employee $employee): int {
$birthday = $employee->birth_date->copy()->year(now()->year);
if ($birthday->lt(now()->startOfDay())) {
$birthday = $birthday->addYear();
}
return $birthday->dayOfYear;
})
->pluck('id')
->all();
}
/**
* @return Builder<Employee>|null
*/
protected function getTableQuery(): ?Builder
{
return null;
}
}