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

CreateAccountSelect.php 4.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. <?php
  2. namespace App\Filament\Forms\Components;
  3. use App\Enums\Accounting\AccountCategory;
  4. use App\Enums\Accounting\AccountType;
  5. use App\Models\Accounting\Account;
  6. use App\Models\Accounting\AccountSubtype;
  7. use App\Utilities\Accounting\AccountCode;
  8. use Filament\Forms\Components\Actions\Action;
  9. use Filament\Forms\Components\Select;
  10. use Filament\Forms\Components\Textarea;
  11. use Filament\Forms\Components\TextInput;
  12. use Filament\Forms\Get;
  13. use Filament\Forms\Set;
  14. use Filament\Support\Enums\MaxWidth;
  15. use Illuminate\Support\Collection;
  16. use Illuminate\Support\Facades\DB;
  17. class CreateAccountSelect extends Select
  18. {
  19. protected ?AccountCategory $category = null;
  20. protected ?AccountType $type = null;
  21. protected bool $includeArchived = false;
  22. public function category(AccountCategory $category): static
  23. {
  24. $this->category = $category;
  25. return $this;
  26. }
  27. public function type(AccountType $type): static
  28. {
  29. $this->type = $type;
  30. return $this;
  31. }
  32. public function includeArchived(bool $includeArchived = true): static
  33. {
  34. $this->includeArchived = $includeArchived;
  35. return $this;
  36. }
  37. public function getCategory(): ?AccountCategory
  38. {
  39. return $this->category;
  40. }
  41. public function getType(): ?AccountType
  42. {
  43. return $this->type;
  44. }
  45. public function includesArchived(): bool
  46. {
  47. return $this->includeArchived;
  48. }
  49. protected function setUp(): void
  50. {
  51. parent::setUp();
  52. $this
  53. ->searchable()
  54. ->live()
  55. ->createOptionForm($this->createAccountForm())
  56. ->createOptionAction(fn (Action $action) => $this->createAccountAction($action));
  57. $this->options(function () {
  58. $query = Account::query();
  59. if ($this->getCategory()) {
  60. $query->where('category', $this->getCategory());
  61. }
  62. if ($this->getType()) {
  63. $query->where('type', $this->getType());
  64. }
  65. if (! $this->includesArchived()) {
  66. $query->where('archived', false);
  67. }
  68. return $query->orderBy('name')
  69. ->pluck('name', 'id')
  70. ->toArray();
  71. });
  72. $this->createOptionUsing(static function (array $data) {
  73. return DB::transaction(static function () use ($data) {
  74. $account = Account::create([
  75. 'name' => $data['name'],
  76. 'code' => $data['code'],
  77. 'description' => $data['description'] ?? null,
  78. 'subtype_id' => $data['subtype_id'],
  79. ]);
  80. return $account->getKey();
  81. });
  82. });
  83. }
  84. protected function createAccountForm(): array
  85. {
  86. return [
  87. Select::make('subtype_id')
  88. ->label('Type')
  89. ->required()
  90. ->live()
  91. ->searchable()
  92. ->options(function () {
  93. $query = AccountSubtype::query()->orderBy('name');
  94. if ($this->getCategory()) {
  95. $query->where('category', $this->getCategory());
  96. }
  97. if ($this->getType()) {
  98. $query->where('type', $this->getType());
  99. return $query->pluck('name', 'id')
  100. ->toArray();
  101. } else {
  102. return $query->get()
  103. ->groupBy(fn (AccountSubtype $subtype) => $subtype->type->getLabel())
  104. ->map(fn (Collection $subtypes, string $type) => $subtypes->mapWithKeys(static fn (AccountSubtype $subtype) => [$subtype->id => $subtype->name]))
  105. ->toArray();
  106. }
  107. })
  108. ->afterStateUpdated(function (string $state, Set $set) {
  109. if ($state) {
  110. $accountSubtype = AccountSubtype::find($state);
  111. $generatedCode = AccountCode::generate($accountSubtype);
  112. $set('code', $generatedCode);
  113. }
  114. }),
  115. TextInput::make('code')
  116. ->label('Code')
  117. ->required()
  118. ->validationAttribute('account code')
  119. ->unique(table: Account::class, column: 'code')
  120. ->validateAccountCode(static fn (Get $get) => $get('subtype_id')),
  121. TextInput::make('name')
  122. ->label('Name')
  123. ->required(),
  124. Textarea::make('description')
  125. ->label('Description'),
  126. ];
  127. }
  128. protected function createAccountAction(Action $action): Action
  129. {
  130. return $action
  131. ->label('Create Account')
  132. ->slideOver()
  133. ->modalWidth(MaxWidth::Large)
  134. ->modalHeading('Create a new account');
  135. }
  136. }