123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152 |
- <?php
-
- namespace App\Filament\Forms\Components;
-
- use App\Enums\Accounting\AccountCategory;
- use App\Enums\Accounting\AccountType;
- use App\Models\Accounting\Account;
- use App\Models\Accounting\AccountSubtype;
- use App\Utilities\Accounting\AccountCode;
- use Filament\Forms\Components\Actions\Action;
- use Filament\Forms\Components\Select;
- use Filament\Forms\Components\Textarea;
- use Filament\Forms\Components\TextInput;
- use Filament\Forms\Get;
- use Filament\Forms\Set;
- use Filament\Support\Enums\MaxWidth;
- use Illuminate\Support\Collection;
- use Illuminate\Support\Facades\DB;
-
- class CreateAccountSelect extends Select
- {
- protected ?AccountCategory $category = null;
-
- protected ?AccountType $type = null;
-
- protected bool $includeArchived = false;
-
- public function category(AccountCategory $category): static
- {
- $this->category = $category;
-
- return $this;
- }
-
- public function type(AccountType $type): static
- {
- $this->type = $type;
-
- return $this;
- }
-
- public function includeArchived(bool $includeArchived = true): static
- {
- $this->includeArchived = $includeArchived;
-
- return $this;
- }
-
- protected function setUp(): void
- {
- parent::setUp();
-
- $this
- ->searchable()
- ->live()
- ->createOptionForm($this->createAccountForm())
- ->createOptionAction(fn (Action $action) => $this->createAccountAction($action));
-
- $this->options(function () {
- $query = Account::query();
-
- if ($this->category) {
- $query->where('category', $this->category);
- }
-
- if ($this->type) {
- $query->where('type', $this->type);
- }
-
- if (! $this->includeArchived) {
- $query->where('archived', false);
- }
-
- return $query->orderBy('name')
- ->pluck('name', 'id')
- ->toArray();
- });
-
- $this->createOptionUsing(static function (array $data) {
- return DB::transaction(static function () use ($data) {
- $account = Account::create([
- 'name' => $data['name'],
- 'code' => $data['code'],
- 'description' => $data['description'] ?? null,
- 'subtype_id' => $data['subtype_id'],
- ]);
-
- return $account->getKey();
- });
- });
- }
-
- protected function createAccountForm(): array
- {
- return [
- Select::make('subtype_id')
- ->label('Type')
- ->required()
- ->live()
- ->searchable()
- ->options(function () {
- $query = AccountSubtype::query()->orderBy('name');
-
- if ($this->category) {
- $query->where('category', $this->category);
- }
-
- if ($this->type) {
- $query->where('type', $this->type);
-
- return $query->pluck('name', 'id')
- ->toArray();
- } else {
- return $query->get()
- ->groupBy(fn (AccountSubtype $subtype) => $subtype->type->getLabel())
- ->map(fn (Collection $subtypes, string $type) => $subtypes->mapWithKeys(static fn (AccountSubtype $subtype) => [$subtype->id => $subtype->name]))
- ->toArray();
- }
- })
- ->afterStateUpdated(function (string $state, Set $set) {
- if ($state) {
- $accountSubtype = AccountSubtype::find($state);
- $generatedCode = AccountCode::generate($accountSubtype);
- $set('code', $generatedCode);
- }
- }),
-
- TextInput::make('code')
- ->label('Code')
- ->required()
- ->validationAttribute('account code')
- ->unique(table: Account::class, column: 'code')
- ->validateAccountCode(static fn (Get $get) => $get('subtype_id')),
-
- TextInput::make('name')
- ->label('Name')
- ->required(),
-
- Textarea::make('description')
- ->label('Description'),
- ];
- }
-
- protected function createAccountAction(Action $action): Action
- {
- return $action
- ->label('Create Account')
- ->slideOver()
- ->modalWidth(MaxWidth::Large)
- ->modalHeading('Create a new account');
- }
- }
|