schema([ Forms\Components\Section::make('General') ->schema([ Forms\Components\TextInput::make('name') ->label('Name') ->required(), Forms\Components\TextInput::make('description') ->label('Description'), Forms\Components\Select::make('computation') ->label('Computation') ->options(Discount::getComputationTypes()) ->reactive() ->searchable() ->default('percentage') ->required(), Forms\Components\TextInput::make('rate') ->label('Rate') ->mask(static fn (Mask $mask) => $mask ->numeric() ->decimalPlaces(4) ->decimalSeparator('.') ->thousandsSeparator(',') ->minValue(0) ->normalizeZeros() ->padFractionalZeros() ) ->suffix(static fn (callable $get) => $get('computation') === 'percentage' ? '%' : null) ->default(0.0000) ->required(), Forms\Components\Select::make('type') ->label('Type') ->options(Discount::getDiscountTypes()) ->searchable() ->default('sales') ->required(), Forms\Components\Select::make('scope') ->label('Scope') ->options(Discount::getDiscountScopes()) ->searchable(), Forms\Components\DateTimePicker::make('start_date') ->label('Start Date') ->minDate(static function ($context, Discount|null $record = null) { if ($context === 'create') { return today()->addDay(); } return $record?->start_date?->isFuture() ? today()->addDay() : $record?->start_date; }) ->maxDate(static function (callable $get, Discount|null $record = null) { $end_date = $get('end_date') ?? $record?->end_date; return $end_date ?: today()->addYear(); }) ->format('Y-m-d H:i:s') ->displayFormat('F d, Y H:i') ->withoutSeconds() ->reactive() ->disabled(static fn ($context, Discount|null $record = null) => $context === 'edit' && $record?->start_date?->isPast() ?? false) ->helperText(static fn (Forms\Components\DateTimePicker $component) => $component->isDisabled() ? 'Start date cannot be changed after the discount has begun.' : null), Forms\Components\DateTimePicker::make('end_date') ->label('End Date') ->reactive() ->minDate(static function (callable $get, Discount|null $record = null) { $start_date = $get('start_date') ?? $record?->start_date; return $start_date ?: today()->addDay(); }) ->maxDate(today()->addYear()) ->format('Y-m-d H:i:s') ->displayFormat('F d, Y H:i') ->withoutSeconds(), ToggleButton::make('enabled') ->label('Default') ->offColor('danger') ->onColor('primary'), ])->columns(), ]); } public static function table(Table $table): Table { return $table ->columns([ Tables\Columns\TextColumn::make('name') ->label('Name') ->weight('semibold') ->icon(static fn (Discount $record) => $record->enabled ? 'heroicon-o-lock-closed' : null) ->tooltip(static fn (Discount $record) => $record->enabled ? "Default ". ucwords($record->type) . " Discount" : null) ->iconPosition('after') ->searchable() ->sortable(), Tables\Columns\TextColumn::make('computation') ->label('Computation') ->formatStateUsing(static fn (Discount $record) => ucwords($record->computation)) ->searchable() ->sortable(), Tables\Columns\TextColumn::make('rate') ->label('Rate') ->formatStateUsing(static function (Discount $record) { $rate = $record->rate; return $rate . ($record->computation === 'percentage' ? '%' : null); }) ->searchable() ->sortable(), Tables\Columns\BadgeColumn::make('type') ->label('Type') ->formatStateUsing(static fn (Discount $record) => ucwords($record->type)) ->colors([ 'success' => 'sales', 'warning' => 'purchase', 'secondary' => 'none', ]) ->icons([ 'heroicon-o-cash' => 'sales', 'heroicon-o-shopping-bag' => 'purchase', 'heroicon-o-x-circle' => 'none', ]) ->searchable() ->sortable(), Tables\Columns\TextColumn::make('start_date') ->label('Start Date') ->formatStateUsing(static fn (Discount $record) => $record->start_date ? $record->start_date->format('F d, Y H:i') : 'N/A') ->searchable() ->sortable(), Tables\Columns\TextColumn::make('end_date') ->label('End Date') ->formatStateUsing(static fn (Discount $record) => $record->end_date ? $record->end_date->format('F d, Y H:i') : 'N/A') ->color(static fn(Discount $record) => $record->end_date?->isPast() ? 'danger' : null) ->searchable() ->sortable(), ]) ->filters([ // ]) ->actions([ // Create a cron job to update recurring discounts once they have expired Tables\Actions\EditAction::make(), Tables\Actions\DeleteAction::make(), ]) ->bulkActions([ Tables\Actions\DeleteBulkAction::make(), ]); } public static function getRelations(): array { return [ // ]; } public static function getPages(): array { return [ 'index' => Pages\ListDiscounts::route('/'), 'create' => Pages\CreateDiscount::route('/create'), 'edit' => Pages\EditDiscount::route('/{record}/edit'), ]; } }