Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

DiscountResource.php 8.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. <?php
  2. namespace App\Filament\Resources;
  3. use App\Filament\Resources\DiscountResource\Pages;
  4. use App\Models\Setting\Discount;
  5. use Filament\Forms;
  6. use Filament\Forms\Components\TextInput\Mask;
  7. use Filament\Resources\Form;
  8. use Filament\Resources\Resource;
  9. use Filament\Resources\Table;
  10. use Filament\Tables;
  11. use Illuminate\Support\Facades\Auth;
  12. use Wallo\FilamentSelectify\Components\ToggleButton;
  13. class DiscountResource extends Resource
  14. {
  15. protected static ?string $model = Discount::class;
  16. protected static ?string $navigationIcon = 'heroicon-o-tag';
  17. protected static ?string $navigationGroup = 'Settings';
  18. public static function form(Form $form): Form
  19. {
  20. return $form
  21. ->schema([
  22. Forms\Components\Section::make('General')
  23. ->schema([
  24. Forms\Components\TextInput::make('name')
  25. ->label('Name')
  26. ->required(),
  27. Forms\Components\TextInput::make('description')
  28. ->label('Description'),
  29. Forms\Components\Select::make('computation')
  30. ->label('Computation')
  31. ->options(Discount::getComputationTypes())
  32. ->reactive()
  33. ->searchable()
  34. ->default('percentage')
  35. ->required(),
  36. Forms\Components\TextInput::make('rate')
  37. ->label('Rate')
  38. ->mask(static fn (Mask $mask) => $mask
  39. ->numeric()
  40. ->decimalPlaces(4)
  41. ->decimalSeparator('.')
  42. ->thousandsSeparator(',')
  43. ->minValue(0)
  44. ->normalizeZeros()
  45. ->padFractionalZeros()
  46. )
  47. ->suffix(static fn (callable $get) => $get('computation') === 'percentage' ? '%' : null)
  48. ->default(0.0000)
  49. ->required(),
  50. Forms\Components\Select::make('type')
  51. ->label('Type')
  52. ->options(Discount::getDiscountTypes())
  53. ->searchable()
  54. ->default('sales')
  55. ->required(),
  56. Forms\Components\Select::make('scope')
  57. ->label('Scope')
  58. ->options(Discount::getDiscountScopes())
  59. ->searchable(),
  60. Forms\Components\DateTimePicker::make('start_date')
  61. ->label('Start Date')
  62. ->minDate(static function ($context, Discount|null $record = null) {
  63. if ($context === 'create') {
  64. return today()->addDay();
  65. }
  66. return $record?->start_date?->isFuture() ? today()->addDay() : $record?->start_date;
  67. })
  68. ->maxDate(static function (callable $get, Discount|null $record = null) {
  69. $end_date = $get('end_date') ?? $record?->end_date;
  70. return $end_date ?: today()->addYear();
  71. })
  72. ->format('Y-m-d H:i:s')
  73. ->displayFormat('F d, Y H:i')
  74. ->withoutSeconds()
  75. ->reactive()
  76. ->disabled(static fn ($context, Discount|null $record = null) => $context === 'edit' && $record?->start_date?->isPast() ?? false)
  77. ->helperText(static fn (Forms\Components\DateTimePicker $component) => $component->isDisabled() ? 'Start date cannot be changed after the discount has begun.' : null),
  78. Forms\Components\DateTimePicker::make('end_date')
  79. ->label('End Date')
  80. ->reactive()
  81. ->minDate(static function (callable $get, Discount|null $record = null) {
  82. $start_date = $get('start_date') ?? $record?->start_date;
  83. return $start_date ?: today()->addDay();
  84. })
  85. ->maxDate(today()->addYear())
  86. ->format('Y-m-d H:i:s')
  87. ->displayFormat('F d, Y H:i')
  88. ->withoutSeconds(),
  89. ToggleButton::make('enabled')
  90. ->label('Default')
  91. ->offColor('danger')
  92. ->onColor('primary'),
  93. ])->columns(),
  94. ]);
  95. }
  96. public static function table(Table $table): Table
  97. {
  98. return $table
  99. ->columns([
  100. Tables\Columns\TextColumn::make('name')
  101. ->label('Name')
  102. ->weight('semibold')
  103. ->icon(static fn (Discount $record) => $record->enabled ? 'heroicon-o-lock-closed' : null)
  104. ->tooltip(static fn (Discount $record) => $record->enabled ? "Default ". ucwords($record->type) . " Discount" : null)
  105. ->iconPosition('after')
  106. ->searchable()
  107. ->sortable(),
  108. Tables\Columns\TextColumn::make('computation')
  109. ->label('Computation')
  110. ->formatStateUsing(static fn (Discount $record) => ucwords($record->computation))
  111. ->searchable()
  112. ->sortable(),
  113. Tables\Columns\TextColumn::make('rate')
  114. ->label('Rate')
  115. ->formatStateUsing(static function (Discount $record) {
  116. $rate = $record->rate;
  117. return $rate . ($record->computation === 'percentage' ? '%' : null);
  118. })
  119. ->searchable()
  120. ->sortable(),
  121. Tables\Columns\BadgeColumn::make('type')
  122. ->label('Type')
  123. ->formatStateUsing(static fn (Discount $record) => ucwords($record->type))
  124. ->colors([
  125. 'success' => 'sales',
  126. 'warning' => 'purchase',
  127. 'secondary' => 'none',
  128. ])
  129. ->icons([
  130. 'heroicon-o-cash' => 'sales',
  131. 'heroicon-o-shopping-bag' => 'purchase',
  132. 'heroicon-o-x-circle' => 'none',
  133. ])
  134. ->searchable()
  135. ->sortable(),
  136. Tables\Columns\TextColumn::make('start_date')
  137. ->label('Start Date')
  138. ->formatStateUsing(static fn (Discount $record) => $record->start_date ? $record->start_date->format('F d, Y H:i') : 'N/A')
  139. ->searchable()
  140. ->sortable(),
  141. Tables\Columns\TextColumn::make('end_date')
  142. ->label('End Date')
  143. ->formatStateUsing(static fn (Discount $record) => $record->end_date ? $record->end_date->format('F d, Y H:i') : 'N/A')
  144. ->color(static fn(Discount $record) => $record->end_date?->isPast() ? 'danger' : null)
  145. ->searchable()
  146. ->sortable(),
  147. ])
  148. ->filters([
  149. //
  150. ])
  151. ->actions([
  152. // Create a cron job to update recurring discounts once they have expired
  153. Tables\Actions\EditAction::make(),
  154. Tables\Actions\DeleteAction::make(),
  155. ])
  156. ->bulkActions([
  157. Tables\Actions\DeleteBulkAction::make(),
  158. ]);
  159. }
  160. public static function getSlug(): string
  161. {
  162. return '{company}/settings/discounts';
  163. }
  164. public static function getUrl($name = 'index', $params = [], $isAbsolute = true): string
  165. {
  166. $routeBaseName = static::getRouteBaseName();
  167. return route("{$routeBaseName}.{$name}", [
  168. 'company' => Auth::user()->currentCompany,
  169. 'record' => $params['record'] ?? null,
  170. ], $isAbsolute);
  171. }
  172. public static function getRelations(): array
  173. {
  174. return [
  175. //
  176. ];
  177. }
  178. public static function getPages(): array
  179. {
  180. return [
  181. 'index' => Pages\ListDiscounts::route('/'),
  182. 'create' => Pages\CreateDiscount::route('/create'),
  183. 'edit' => Pages\EditDiscount::route('/{record}/edit'),
  184. ];
  185. }
  186. }