Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

OfferingResource.php 7.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. <?php
  2. namespace App\Filament\Company\Resources\Common;
  3. use App\Enums\Accounting\AccountCategory;
  4. use App\Enums\Accounting\AccountType;
  5. use App\Enums\Common\OfferingType;
  6. use App\Filament\Company\Resources\Common\OfferingResource\Pages;
  7. use App\Models\Accounting\Account;
  8. use App\Models\Common\Offering;
  9. use App\Utilities\Currency\CurrencyAccessor;
  10. use Filament\Forms;
  11. use Filament\Forms\Form;
  12. use Filament\Resources\Resource;
  13. use Filament\Tables;
  14. use Filament\Tables\Table;
  15. use Illuminate\Database\Eloquent\Builder;
  16. use Illuminate\Support\Str;
  17. use JaOcero\RadioDeck\Forms\Components\RadioDeck;
  18. class OfferingResource extends Resource
  19. {
  20. protected static ?string $model = Offering::class;
  21. protected static ?string $navigationIcon = 'heroicon-o-square-3-stack-3d';
  22. public static function form(Form $form): Form
  23. {
  24. return $form
  25. ->schema([
  26. Forms\Components\Section::make('General')
  27. ->schema([
  28. RadioDeck::make('type')
  29. ->options(OfferingType::class)
  30. ->default(OfferingType::Product)
  31. ->icons(OfferingType::class)
  32. ->color('primary')
  33. ->columns()
  34. ->required(),
  35. Forms\Components\TextInput::make('name')
  36. ->autofocus()
  37. ->required()
  38. ->columnStart(1)
  39. ->maxLength(255),
  40. Forms\Components\TextInput::make('price')
  41. ->required()
  42. ->money(),
  43. Forms\Components\Textarea::make('description')
  44. ->label('Description')
  45. ->columnSpan(2)
  46. ->rows(3),
  47. Forms\Components\CheckboxList::make('attributes')
  48. ->options([
  49. 'Sellable' => 'Sellable',
  50. 'Purchasable' => 'Purchasable',
  51. ])
  52. ->hiddenLabel()
  53. ->required()
  54. ->live()
  55. ->bulkToggleable()
  56. ->validationMessages([
  57. 'required' => 'The offering must be either sellable or purchasable.',
  58. ]),
  59. ])->columns(),
  60. // Sellable Section
  61. Forms\Components\Section::make('Sale Information')
  62. ->schema([
  63. Forms\Components\Select::make('income_account_id')
  64. ->label('Income account')
  65. ->options(Account::query()
  66. ->where('category', AccountCategory::Revenue)
  67. ->where('type', AccountType::OperatingRevenue)
  68. ->pluck('name', 'id')
  69. ->toArray())
  70. ->searchable()
  71. ->preload()
  72. ->required()
  73. ->validationMessages([
  74. 'required' => 'The income account is required for sellable offerings.',
  75. ]),
  76. Forms\Components\Select::make('salesTaxes')
  77. ->label('Sales tax')
  78. ->relationship('salesTaxes', 'name')
  79. ->preload()
  80. ->multiple(),
  81. Forms\Components\Select::make('salesDiscounts')
  82. ->label('Sales discount')
  83. ->relationship('salesDiscounts', 'name')
  84. ->preload()
  85. ->multiple(),
  86. ])
  87. ->columns()
  88. ->visible(fn (Forms\Get $get) => in_array('Sellable', $get('attributes') ?? [])),
  89. // Purchasable Section
  90. Forms\Components\Section::make('Purchase Information')
  91. ->schema([
  92. Forms\Components\Select::make('expense_account_id')
  93. ->label('Expense account')
  94. ->options(Account::query()
  95. ->where('category', AccountCategory::Expense)
  96. ->where('type', AccountType::OperatingExpense)
  97. ->orderBy('name')
  98. ->pluck('name', 'id')
  99. ->toArray())
  100. ->searchable()
  101. ->preload()
  102. ->required()
  103. ->validationMessages([
  104. 'required' => 'The expense account is required for purchasable offerings.',
  105. ]),
  106. Forms\Components\Select::make('purchaseTaxes')
  107. ->label('Purchase tax')
  108. ->relationship('purchaseTaxes', 'name')
  109. ->preload()
  110. ->multiple(),
  111. Forms\Components\Select::make('purchaseDiscounts')
  112. ->label('Purchase discount')
  113. ->relationship('purchaseDiscounts', 'name')
  114. ->preload()
  115. ->multiple(),
  116. ])
  117. ->columns()
  118. ->visible(fn (Forms\Get $get) => in_array('Purchasable', $get('attributes') ?? [])),
  119. ])->columns();
  120. }
  121. public static function table(Table $table): Table
  122. {
  123. return $table
  124. ->modifyQueryUsing(function (Builder $query) {
  125. $query->selectRaw("
  126. *,
  127. CONCAT_WS(' & ',
  128. CASE WHEN sellable THEN 'Sellable' END,
  129. CASE WHEN purchasable THEN 'Purchasable' END
  130. ) AS attributes
  131. ");
  132. })
  133. ->columns([
  134. Tables\Columns\TextColumn::make('name')
  135. ->label('Name'),
  136. Tables\Columns\TextColumn::make('attributes')
  137. ->label('Attributes')
  138. ->badge(),
  139. Tables\Columns\TextColumn::make('type')
  140. ->searchable(),
  141. Tables\Columns\TextColumn::make('price')
  142. ->currency(CurrencyAccessor::getDefaultCurrency(), true)
  143. ->sortable()
  144. ->description(function (Offering $record) {
  145. $adjustments = $record->adjustments()
  146. ->pluck('name')
  147. ->join(', ');
  148. if (empty($adjustments)) {
  149. return null;
  150. }
  151. $adjustmentsList = Str::of($adjustments)->limit(40);
  152. return "+ {$adjustmentsList}";
  153. }),
  154. ])
  155. ->filters([
  156. //
  157. ])
  158. ->actions([
  159. Tables\Actions\EditAction::make(),
  160. ])
  161. ->bulkActions([
  162. Tables\Actions\BulkActionGroup::make([
  163. Tables\Actions\DeleteBulkAction::make(),
  164. ]),
  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\ListOfferings::route('/'),
  177. 'create' => Pages\CreateOffering::route('/create'),
  178. 'edit' => Pages\EditOffering::route('/{record}/edit'),
  179. ];
  180. }
  181. }