Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

DiscountResource.php 8.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. <?php
  2. namespace App\Filament\Company\Resources\Setting;
  3. use App\Enums\DiscountComputation;
  4. use App\Enums\DiscountScope;
  5. use App\Enums\DiscountType;
  6. use App\Filament\Company\Resources\Setting\DiscountResource\Pages;
  7. use App\Filament\Company\Resources\Setting\DiscountResource\RelationManagers;
  8. use App\Models\Setting\Category;
  9. use App\Models\Setting\Discount;
  10. use Closure;
  11. use Filament\Forms;
  12. use Filament\Forms\Form;
  13. use Filament\Resources\Resource;
  14. use Filament\Tables;
  15. use Filament\Tables\Table;
  16. use Illuminate\Database\Eloquent\Builder;
  17. use Illuminate\Database\Eloquent\SoftDeletingScope;
  18. use Wallo\FilamentSelectify\Components\ToggleButton;
  19. class DiscountResource extends Resource
  20. {
  21. protected static ?string $model = Discount::class;
  22. protected static ?string $navigationIcon = 'heroicon-o-tag';
  23. protected static ?string $navigationGroup = 'Settings';
  24. protected static ?string $slug = 'settings/discounts';
  25. public static function form(Form $form): Form
  26. {
  27. return $form
  28. ->schema([
  29. Forms\Components\Section::make('General')
  30. ->schema([
  31. Forms\Components\TextInput::make('name')
  32. ->label('Name')
  33. ->autofocus()
  34. ->required()
  35. ->maxLength(255)
  36. ->rule(static function (Forms\Get $get, Forms\Components\Component $component): Closure {
  37. return static function (string $attribute, $value, Closure $fail) use ($get, $component) {
  38. $existingCategory = Discount::where('company_id', auth()->user()->currentCompany->id)
  39. ->where('name', $value)
  40. ->where('type', $get('type'))
  41. ->first();
  42. if ($existingCategory && $existingCategory->getKey() !== $component->getRecord()?->getKey()) {
  43. $type = $get('type')->getLabel();
  44. $fail("The {$type} discount \"{$value}\" already exists.");
  45. }
  46. };
  47. }),
  48. Forms\Components\TextInput::make('description')
  49. ->label('Description'),
  50. Forms\Components\Select::make('computation')
  51. ->label('Computation')
  52. ->options(DiscountComputation::class)
  53. ->default(DiscountComputation::Percentage)
  54. ->live()
  55. ->native(false)
  56. ->required(),
  57. Forms\Components\TextInput::make('rate')
  58. ->label('Rate')
  59. ->numeric()
  60. ->suffix(static function (Forms\Get $get) {
  61. $computation = $get('computation');
  62. if ($computation === DiscountComputation::Percentage) {
  63. return '%';
  64. }
  65. return null;
  66. })
  67. ->required(),
  68. Forms\Components\Select::make('type')
  69. ->label('Type')
  70. ->options(DiscountType::class)
  71. ->default(DiscountType::Sales)
  72. ->native(false)
  73. ->required(),
  74. Forms\Components\Select::make('scope')
  75. ->label('Scope')
  76. ->options(DiscountScope::class)
  77. ->native(false),
  78. Forms\Components\DateTimePicker::make('start_date')
  79. ->label('Start Date')
  80. ->native(false)
  81. ->minDate(static function ($context, Discount|null $record = null) {
  82. if ($context === 'create') {
  83. return today()->addDay();
  84. }
  85. return $record?->start_date?->isFuture() ? today()->addDay() : $record?->start_date;
  86. })
  87. ->maxDate(static function (callable $get, Discount|null $record = null) {
  88. $end_date = $get('end_date') ?? $record?->end_date;
  89. return $end_date ?: today()->addYear();
  90. })
  91. ->format('Y-m-d H:i:s')
  92. ->displayFormat('F d, Y H:i')
  93. ->seconds(false)
  94. ->live()
  95. ->disabled(static fn ($context, Discount|null $record = null) => $context === 'edit' && $record?->start_date?->isPast() ?? false)
  96. ->helperText(static fn (Forms\Components\DateTimePicker $component) => $component->isDisabled() ? 'Start date cannot be changed after the discount has begun.' : null),
  97. Forms\Components\DateTimePicker::make('end_date')
  98. ->label('End Date')
  99. ->native(false)
  100. ->live()
  101. ->minDate(static function (callable $get, Discount|null $record = null) {
  102. $start_date = $get('start_date') ?? $record?->start_date;
  103. return $start_date ?: today()->addDay();
  104. })
  105. ->maxDate(today()->addYear())
  106. ->format('Y-m-d H:i:s')
  107. ->displayFormat('F d, Y H:i')
  108. ->seconds(false),
  109. ToggleButton::make('enabled')
  110. ->label('Default'),
  111. ])->columns(),
  112. ]);
  113. }
  114. public static function table(Table $table): Table
  115. {
  116. return $table
  117. ->columns([
  118. Tables\Columns\TextColumn::make('name')
  119. ->label('Name')
  120. ->weight('semibold')
  121. ->icon(static fn (Discount $record) => $record->enabled ? 'heroicon-o-lock-closed' : null)
  122. ->tooltip(static fn (Discount $record) => $record->enabled ? "Default {$record->type->getLabel()} Discount" : null)
  123. ->iconPosition('after')
  124. ->searchable()
  125. ->sortable(),
  126. Tables\Columns\TextColumn::make('computation')
  127. ->label('Computation')
  128. ->searchable()
  129. ->sortable(),
  130. Tables\Columns\TextColumn::make('rate')
  131. ->label('Rate')
  132. ->formatStateUsing(static fn (Discount $record) => $record->rate . ($record->computation === DiscountComputation::Percentage ? '%' : null))
  133. ->searchable()
  134. ->sortable(),
  135. Tables\Columns\TextColumn::make('type')
  136. ->label('Type')
  137. ->badge()
  138. ->searchable()
  139. ->sortable(),
  140. Tables\Columns\TextColumn::make('start_date')
  141. ->label('Start Date')
  142. ->formatStateUsing(static fn (Discount $record) => $record->start_date ? $record->start_date->format('F d, Y H:i') : 'N/A')
  143. ->searchable()
  144. ->sortable(),
  145. Tables\Columns\TextColumn::make('end_date')
  146. ->label('End Date')
  147. ->formatStateUsing(static fn (Discount $record) => $record->end_date ? $record->end_date->format('F d, Y H:i') : 'N/A')
  148. ->color(static fn(Discount $record) => $record->end_date?->isPast() ? 'danger' : null)
  149. ->searchable()
  150. ->sortable(),
  151. ])
  152. ->filters([
  153. //
  154. ])
  155. ->actions([
  156. Tables\Actions\EditAction::make(),
  157. ])
  158. ->bulkActions([
  159. Tables\Actions\BulkActionGroup::make([
  160. Tables\Actions\DeleteBulkAction::make(),
  161. ]),
  162. ])
  163. ->emptyStateActions([
  164. Tables\Actions\CreateAction::make(),
  165. ]);
  166. }
  167. public static function getRelations(): array
  168. {
  169. return [
  170. //
  171. ];
  172. }
  173. public static function getPages(): array
  174. {
  175. return [
  176. 'index' => Pages\ListDiscounts::route('/'),
  177. 'create' => Pages\CreateDiscount::route('/create'),
  178. 'edit' => Pages\EditDiscount::route('/{record}/edit'),
  179. ];
  180. }
  181. }