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

CreateAccountSelect.php 4.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  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. protected function setUp(): void
  38. {
  39. parent::setUp();
  40. $this
  41. ->searchable()
  42. ->live()
  43. ->createOptionForm($this->createAccountForm())
  44. ->createOptionAction(fn (Action $action) => $this->createAccountAction($action));
  45. $this->options(function () {
  46. $query = Account::query();
  47. if ($this->category) {
  48. $query->where('category', $this->category);
  49. }
  50. if ($this->type) {
  51. $query->where('type', $this->type);
  52. }
  53. if (! $this->includeArchived) {
  54. $query->where('archived', false);
  55. }
  56. return $query->orderBy('name')
  57. ->pluck('name', 'id')
  58. ->toArray();
  59. });
  60. $this->createOptionUsing(static function (array $data) {
  61. return DB::transaction(static function () use ($data) {
  62. $account = Account::create([
  63. 'name' => $data['name'],
  64. 'code' => $data['code'],
  65. 'description' => $data['description'] ?? null,
  66. 'subtype_id' => $data['subtype_id'],
  67. ]);
  68. return $account->getKey();
  69. });
  70. });
  71. }
  72. protected function createAccountForm(): array
  73. {
  74. return [
  75. Select::make('subtype_id')
  76. ->label('Type')
  77. ->required()
  78. ->live()
  79. ->searchable()
  80. ->options(function () {
  81. $query = AccountSubtype::query()->orderBy('name');
  82. if ($this->category) {
  83. $query->where('category', $this->category);
  84. }
  85. if ($this->type) {
  86. $query->where('type', $this->type);
  87. return $query->pluck('name', 'id')
  88. ->toArray();
  89. } else {
  90. return $query->get()
  91. ->groupBy(fn (AccountSubtype $subtype) => $subtype->type->getLabel())
  92. ->map(fn (Collection $subtypes, string $type) => $subtypes->mapWithKeys(static fn (AccountSubtype $subtype) => [$subtype->id => $subtype->name]))
  93. ->toArray();
  94. }
  95. })
  96. ->afterStateUpdated(function (string $state, Set $set) {
  97. if ($state) {
  98. $accountSubtype = AccountSubtype::find($state);
  99. $generatedCode = AccountCode::generate($accountSubtype);
  100. $set('code', $generatedCode);
  101. }
  102. }),
  103. TextInput::make('code')
  104. ->label('Code')
  105. ->required()
  106. ->validationAttribute('account code')
  107. ->unique(table: Account::class, column: 'code')
  108. ->validateAccountCode(static fn (Get $get) => $get('subtype_id')),
  109. TextInput::make('name')
  110. ->label('Name')
  111. ->required(),
  112. Textarea::make('description')
  113. ->label('Description'),
  114. ];
  115. }
  116. protected function createAccountAction(Action $action): Action
  117. {
  118. return $action
  119. ->label('Create Account')
  120. ->slideOver()
  121. ->modalWidth(MaxWidth::Large)
  122. ->modalHeading('Create a new account');
  123. }
  124. }