components([ Schemas\Components\Section::make('Identificare') ->columns(2) ->schema([ Forms\Components\TextInput::make('name')->label('Nume')->required()->maxLength(160), Forms\Components\TextInput::make('contact_name')->label('Persoană contact')->maxLength(120), Forms\Components\TextInput::make('phone')->tel()->maxLength(40), Forms\Components\TextInput::make('email')->email()->maxLength(120), Forms\Components\TextInput::make('website')->url()->maxLength(160), ]), Schemas\Components\Section::make('Comercial') ->columns(3) ->schema([ Forms\Components\TextInput::make('pay_terms')->label('Termeni plată')->placeholder('Net 30 / Avans')->maxLength(60), Forms\Components\TextInput::make('delivery_days')->label('Zile livrare')->numeric()->default(0), Forms\Components\Select::make('rating') ->label('Rating') ->options([1 => '★', 2 => '★★', 3 => '★★★', 4 => '★★★★', 5 => '★★★★★']) ->default(3) ->required(), Forms\Components\TextInput::make('discount_pct')->label('Discount %')->numeric()->default(0), Forms\Components\TagsInput::make('categories')->label('Categorii')->placeholder('Frâne, Ulei, ...')->columnSpan(2), Forms\Components\Toggle::make('is_active')->label('Activ')->default(true), ]), Forms\Components\Textarea::make('notes')->label('Observații')->columnSpanFull()->rows(2), ]); } public static function table(Table $table): Table { return $table ->columns([ Tables\Columns\TextColumn::make('name')->searchable()->sortable(), Tables\Columns\TextColumn::make('contact_name')->label('Contact')->placeholder('—'), Tables\Columns\TextColumn::make('phone')->copyable()->placeholder('—'), Tables\Columns\TextColumn::make('rating') ->label('Rating') ->formatStateUsing(fn ($s) => str_repeat('★', (int) $s)), Tables\Columns\TextColumn::make('on_time_pct') ->label('La timp 90d') ->state(fn (Supplier $r) => app(\App\Services\Warehouse\SupplierAnalytics::class)->onTimeRate($r)) ->formatStateUsing(fn ($s) => $s === null ? '—' : "{$s}%") ->color(fn ($s) => $s === null ? 'gray' : ($s >= 90 ? 'success' : ($s >= 70 ? 'warning' : 'danger'))) ->alignRight() ->toggleable(), Tables\Columns\TextColumn::make('avg_delivery_days') ->label('Avg zile') ->state(fn (Supplier $r) => app(\App\Services\Warehouse\SupplierAnalytics::class)->avgDeliveryDays($r)) ->formatStateUsing(fn ($s) => $s === null ? '—' : (string) $s) ->alignRight() ->toggleable(), Tables\Columns\TextColumn::make('spend_90d') ->label('Cheltuit 90d') ->state(fn (Supplier $r) => app(\App\Services\Warehouse\SupplierAnalytics::class)->spend($r)) ->money('MDL') ->alignRight() ->toggleable(), Tables\Columns\TextColumn::make('delivery_days')->label('Livrare (zile)')->alignRight()->toggleable(), Tables\Columns\TextColumn::make('discount_pct')->label('Discount') ->formatStateUsing(fn ($s) => $s . '%')->alignRight()->toggleable(), Tables\Columns\IconColumn::make('is_active')->boolean(), ]) ->filters([ Tables\Filters\TernaryFilter::make('is_active')->label('Activi'), ]) ->actions([ Actions\Action::make('rate') ->label('Rerating') ->icon('heroicon-m-arrow-path') ->color('gray') ->action(function (Supplier $r) { $score = app(\App\Services\Warehouse\SupplierAnalytics::class) ->computedRating($r); if ($score === null) { \Filament\Notifications\Notification::make() ->title('Date insuficiente') ->body('Necesită cel puțin 2 recepții complete cu data așteptată setată.') ->warning() ->send(); return; } $r->rating = $score; $r->saveQuietly(); \Filament\Notifications\Notification::make() ->title("Rating actualizat → {$score}★") ->success() ->send(); }), Actions\EditAction::make(), Actions\DeleteAction::make(), ]) ->defaultSort('name'); } public static function getPages(): array { return [ 'index' => Pages\ListSuppliers::route('/'), 'create' => Pages\CreateSupplier::route('/create'), 'edit' => Pages\EditSupplier::route('/{record}/edit'), ]; } }