您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

OfferingResource.php 7.5KB

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