components([ Schemas\Components\Section::make('Regulă') ->columns(2) ->schema([ Forms\Components\Select::make('type') ->label('Tip') ->options(MarkupRule::TYPES) ->default('category') ->required() ->live(), Forms\Components\Select::make('key') ->label(fn (Get $get) => $get('type') === 'brand' ? 'Brand' : 'Categorie') ->options(fn (Get $get) => $get('type') === 'brand' ? Part::distinct()->pluck('brand', 'brand')->filter()->toArray() : array_combine(Part::CATEGORIES, Part::CATEGORIES)) ->visible(fn (Get $get) => in_array($get('type'), ['category', 'brand'], true)) ->searchable() ->required(fn (Get $get) => in_array($get('type'), ['category', 'brand'], true)), Forms\Components\TextInput::make('range_from') ->label('De la (preț achiziție)') ->numeric() ->visible(fn (Get $get) => $get('type') === 'range'), Forms\Components\TextInput::make('range_to') ->label('Până la (gol = ∞)') ->numeric() ->visible(fn (Get $get) => $get('type') === 'range'), Forms\Components\TextInput::make('markup_pct') ->label('Markup %') ->numeric() ->required() ->suffix('%') ->helperText('Ex 30 → preț vânzare = preț achiziție × 1.30'), Forms\Components\TextInput::make('priority') ->label('Prioritate') ->numeric() ->default(100) ->helperText('Mai mic = aplicat primul.'), Forms\Components\Toggle::make('is_active')->label('Activă')->default(true), ]), ]); } public static function table(Table $table): Table { return $table ->columns([ Tables\Columns\TextColumn::make('priority')->label('#')->sortable(), Tables\Columns\TextColumn::make('type') ->formatStateUsing(fn ($s) => MarkupRule::TYPES[$s] ?? $s) ->badge(), Tables\Columns\TextColumn::make('key')->label('Cheie')->placeholder('—'), Tables\Columns\TextColumn::make('range_from')->label('De la')->placeholder('—'), Tables\Columns\TextColumn::make('range_to')->label('Până la')->placeholder('∞'), Tables\Columns\TextColumn::make('markup_pct') ->label('Markup') ->formatStateUsing(fn ($s) => '+' . $s . '%') ->color('success') ->weight('bold'), Tables\Columns\IconColumn::make('is_active')->boolean(), ]) ->filters([ Tables\Filters\SelectFilter::make('type')->options(MarkupRule::TYPES), ]) ->headerActions([ Actions\Action::make('apply_all') ->label('Aplică toate regulile la stoc') ->icon('heroicon-m-bolt') ->color('warning') ->requiresConfirmation() ->modalDescription('Va recalcula sell_price pentru TOATE piesele active. Continui?') ->action(function () { $count = 0; Part::where('is_active', true)->where('buy_price', '>', 0)->chunk(100, function ($parts) use (&$count) { foreach ($parts as $part) { MarkupRule::applyToPart($part); $count++; } }); Notification::make()->title("Recalculat preț pentru {$count} piese")->success()->send(); }), ]) ->actions([ Actions\EditAction::make(), Actions\DeleteAction::make(), ]) ->defaultSort('priority'); } public static function getPages(): array { return [ 'index' => Pages\ListMarkupRules::route('/'), 'create' => Pages\CreateMarkupRule::route('/create'), 'edit' => Pages\EditMarkupRule::route('/{record}/edit'), ]; } }