user()?->canDo(\App\Auth\Permissions::SALARIES_VIEW_ALL) ?? false; } public static function canCreate(): bool { return auth()->user()?->canDo(\App\Auth\Permissions::SALARIES_CALCULATE) ?? false; } public static function form(Schema $schema): Schema { return $schema->components([ Schemas\Components\Section::make(__('Detalii')) ->columns(2) ->schema([ Forms\Components\Select::make('user_id') ->label(__('Utilizator')) ->options(fn () => User::orderBy('name')->pluck('name', 'id')) ->searchable() ->required(), Forms\Components\TextInput::make('period') ->label(__('Perioada (YYYY-MM)')) ->placeholder(now()->format('Y-m')) ->required() ->regex('/^\d{4}-\d{2}$/'), ]), Schemas\Components\Section::make(__('Calcul')) ->columns(3) ->schema([ Forms\Components\TextInput::make('base')->label(__('Bază'))->numeric()->default(0), Forms\Components\TextInput::make('works_revenue')->label(__('Venit manopere'))->numeric()->disabled(), Forms\Components\TextInput::make('works_pct_amount')->label(__('Comision manopere'))->numeric()->disabled(), Forms\Components\TextInput::make('parts_margin')->label(__('Marja piese'))->numeric()->disabled(), Forms\Components\TextInput::make('parts_pct_amount')->label(__('Comision piese'))->numeric()->disabled(), Forms\Components\TextInput::make('bonus')->numeric()->default(0), Forms\Components\TextInput::make('fines')->label(__('Penalizări'))->numeric()->default(0), Forms\Components\TextInput::make('advance')->label(__('Avans'))->numeric()->default(0), Forms\Components\TextInput::make('total')->label(__('Total net'))->numeric()->disabled(), ]), Schemas\Components\Section::make(__('Plată')) ->columns(2) ->schema([ Forms\Components\Toggle::make('paid')->label(__('Achitat')), Forms\Components\DatePicker::make('paid_at')->label(__('Data plății')), ]), Forms\Components\Textarea::make('notes')->label(__('Notițe'))->columnSpanFull()->rows(2), ]); } public static function table(Table $table): Table { return $table ->columns([ Tables\Columns\TextColumn::make('period')->label(__('Perioadă'))->sortable(), Tables\Columns\TextColumn::make('user.name')->label(__('Utilizator'))->searchable(), Tables\Columns\TextColumn::make('base')->money('MDL')->alignRight(), Tables\Columns\TextColumn::make('works_pct_amount')->label(__('% manopere'))->money('MDL')->alignRight(), Tables\Columns\TextColumn::make('parts_pct_amount')->label(__('% piese'))->money('MDL')->alignRight(), Tables\Columns\TextColumn::make('bonus')->money('MDL')->alignRight()->color('success'), Tables\Columns\TextColumn::make('fines')->money('MDL')->alignRight()->color('danger'), Tables\Columns\TextColumn::make('advance')->money('MDL')->alignRight()->color('warning'), Tables\Columns\TextColumn::make('total')->label(__('Total'))->money('MDL')->alignRight()->weight('bold') ->summarize(Tables\Columns\Summarizers\Sum::make()->money('MDL')), Tables\Columns\IconColumn::make('paid')->boolean(), ]) ->headerActions([ Actions\Action::make('compute_all') ->label(__('Calculează luna curentă')) ->icon('heroicon-m-calculator') ->color('primary') ->action(function () { $period = now()->format('Y-m'); $count = 0; foreach (User::pluck('id') as $uid) { app(PayrollCalculator::class)->compute($uid, $period); $count++; } Notification::make() ->title(__('Calculat salariul :period pentru :count utilizatori', ['period' => $period, 'count' => $count])) ->success()->send(); }), ]) ->filters([ Tables\Filters\SelectFilter::make('period') ->label(__('Perioadă')) ->options(fn () => PayrollRun::distinct()->pluck('period', 'period')->toArray()), Tables\Filters\TernaryFilter::make('paid')->label(__('Achitat')), ]) ->actions([ Actions\Action::make('recompute') ->label(__('Recalculează')) ->icon('heroicon-m-arrow-path') ->action(fn (PayrollRun $r) => app(PayrollCalculator::class)->compute($r->user_id, $r->period)), Actions\EditAction::make(), Actions\DeleteAction::make(), ]) ->defaultSort('period', 'desc'); } public static function getPages(): array { return [ 'index' => Pages\ListPayrollRuns::route('/'), 'create' => Pages\CreatePayrollRun::route('/create'), 'edit' => Pages\EditPayrollRun::route('/{record}/edit'), ]; } }