Files
hr/app/Filament/Resources/EmployeeStats/Tables/EmployeeStatsTable.php

107 lines
4.4 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Filament\Resources\EmployeeStats\Tables;
use App\Enums\EmploymentStatus;
use App\Filament\Resources\Employees\EmployeeResource;
use App\Models\Employee;
use App\Services\Employee\EmployeeStatisticsService;
use Filament\Actions\ViewAction;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Filters\SelectFilter;
use Filament\Tables\Table;
class EmployeeStatsTable
{
public static function configure(Table $table): Table
{
return $table
->modifyQueryUsing(fn ($query) => app(EmployeeStatisticsService::class)->applyTableAggregates($query))
->columns([
TextColumn::make('employee_number')
->label(__('hr.fields.number'))
->searchable()
->sortable(),
TextColumn::make('full_name')
->label(__('hr.fields.full_name'))
->searchable()
->sortable(),
TextColumn::make('department.name')
->label(__('hr.fields.department'))
->badge()
->color('info')
->searchable()
->sortable(),
TextColumn::make('position.name')
->label(__('hr.fields.position'))
->badge()
->color('primary')
->searchable()
->sortable(),
TextColumn::make('hire_date')
->label(__('hr.fields.hire_date'))
->date()
->sortable(),
TextColumn::make('tenure')
->label(__('hr.fields.tenure'))
->state(fn (Employee $record): string => $record->hire_date
? $record->hire_date->diffForHumans(now(), true)
: '—'),
TextColumn::make('annual_vacation_days_taken')
->label(__('hr.fields.vacation_taken_days'))
->numeric()
->sortable(),
TextColumn::make('vacation_remaining')
->label(__('hr.fields.vacation_remaining_days'))
->state(fn (Employee $record): int => (int) config('hr.annual_leave_days') - (int) ($record->annual_vacation_days_taken ?? 0))
->numeric()
->color('success'),
TextColumn::make('sick_leaves_count')
->label(__('hr.fields.sick_leave_records'))
->numeric()
->sortable(),
TextColumn::make('unpaid_leaves_count')
->label(__('hr.fields.unpaid_leave_records'))
->numeric()
->sortable(),
TextColumn::make('disciplinary_reports_count')
->label(__('hr.fields.disciplinary_reports'))
->numeric()
->sortable(),
TextColumn::make('explanations_count')
->label(__('hr.fields.explanations'))
->numeric()
->sortable(),
TextColumn::make('bonuses_sum_amount')
->label(__('hr.fields.total_bonuses'))
->money('TMT')
->sortable(),
TextColumn::make('gifts_count')
->label(__('hr.fields.gifts_received'))
->numeric()
->sortable(),
])
->filters([
SelectFilter::make('department_id')
->label(__('hr.fields.department'))
->relationship('department', 'name')
->searchable()
->preload(),
SelectFilter::make('position_id')
->label(__('hr.fields.position'))
->relationship('position', 'name')
->searchable()
->preload(),
SelectFilter::make('employment_status')
->label(__('hr.fields.employment_status'))
->options(EmploymentStatus::class),
])
->recordActions([
ViewAction::make()
->url(fn (Employee $record): string => EmployeeResource::getUrl('view', ['record' => $record])),
]);
}
}