| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222 | 
							- <?php
 - 
 - namespace App\Filament\Forms\Components;
 - 
 - use App\Enums\Accounting\AdjustmentCategory;
 - use App\Enums\Accounting\AdjustmentComputation;
 - use App\Enums\Accounting\AdjustmentScope;
 - use App\Enums\Accounting\AdjustmentStatus;
 - use App\Enums\Accounting\AdjustmentType;
 - use App\Models\Accounting\Adjustment;
 - use Filament\Forms\Components\Actions\Action;
 - use Filament\Forms\Components\Checkbox;
 - use Filament\Forms\Components\DateTimePicker;
 - use Filament\Forms\Components\Group;
 - use Filament\Forms\Components\Select;
 - use Filament\Forms\Components\Textarea;
 - use Filament\Forms\Components\TextInput;
 - use Filament\Forms\Get;
 - use Filament\Support\Enums\MaxWidth;
 - use Illuminate\Database\Eloquent\Builder;
 - use Illuminate\Database\Eloquent\Model;
 - use Illuminate\Support\Facades\DB;
 - 
 - class CreateAdjustmentSelect extends Select
 - {
 -     protected ?AdjustmentCategory $category = null;
 - 
 -     protected ?AdjustmentType $type = null;
 - 
 -     protected bool $includeInactive = false;
 - 
 -     protected string $adjustmentsRelationship = 'adjustments';
 - 
 -     public function category(AdjustmentCategory $category): static
 -     {
 -         $this->category = $category;
 - 
 -         return $this;
 -     }
 - 
 -     public function type(AdjustmentType $type): static
 -     {
 -         $this->type = $type;
 - 
 -         return $this;
 -     }
 - 
 -     public function includeInactive(bool $includeInactive = true): static
 -     {
 -         $this->includeInactive = $includeInactive;
 - 
 -         return $this;
 -     }
 - 
 -     public function adjustmentsRelationship(string $relationship): static
 -     {
 -         $this->adjustmentsRelationship = $relationship;
 - 
 -         return $this;
 -     }
 - 
 -     public function getCategory(): ?AdjustmentCategory
 -     {
 -         return $this->category;
 -     }
 - 
 -     public function getType(): ?AdjustmentType
 -     {
 -         return $this->type;
 -     }
 - 
 -     public function includesInactive(): bool
 -     {
 -         return $this->includeInactive;
 -     }
 - 
 -     public function getAdjustmentsRelationship(): string
 -     {
 -         return $this->adjustmentsRelationship;
 -     }
 - 
 -     protected function setUp(): void
 -     {
 -         parent::setUp();
 - 
 -         $this
 -             ->searchable()
 -             ->preload()
 -             ->createOptionForm($this->createAdjustmentForm())
 -             ->createOptionAction(fn (Action $action) => $this->createAdjustmentAction($action));
 - 
 -         $this->relationship(
 -             name: $this->getAdjustmentsRelationship(),
 -             titleAttribute: 'name',
 -             modifyQueryUsing: function (Builder $query, ?Model $record) {
 -                 if ($this->getCategory()) {
 -                     $query->where('category', $this->getCategory());
 -                 }
 - 
 -                 if ($this->getType()) {
 -                     $query->where('type', $this->getType());
 -                 }
 - 
 -                 if (! $this->includesInactive()) {
 -                     $existingAdjustmentIds = $record?->{$this->getAdjustmentsRelationship()}()
 -                         ->pluck('adjustments.id')
 -                         ->toArray() ?? [];
 - 
 -                     $query->where(function ($query) use ($existingAdjustmentIds) {
 -                         $query->where('status', AdjustmentStatus::Active)
 -                             ->orWhereIn('adjustments.id', $existingAdjustmentIds);
 -                     });
 -                 }
 - 
 -                 return $query->orderBy('name');
 -             },
 -         );
 - 
 -         $this->createOptionUsing(static function (array $data, CreateAdjustmentSelect $component) {
 -             return DB::transaction(static function () use ($data, $component) {
 -                 $category = $data['category'] ?? $component->getCategory();
 -                 $type = $data['type'] ?? $component->getType();
 - 
 -                 $adjustment = Adjustment::create([
 -                     'name' => $data['name'],
 -                     'description' => $data['description'] ?? null,
 -                     'category' => $category,
 -                     'type' => $type,
 -                     'computation' => $data['computation'],
 -                     'rate' => $data['rate'],
 -                     'scope' => $data['scope'] ?? null,
 -                     'recoverable' => $data['recoverable'] ?? false,
 -                     'start_date' => $data['start_date'] ?? null,
 -                     'end_date' => $data['end_date'] ?? null,
 -                 ]);
 - 
 -                 return $adjustment->getKey();
 -             });
 -         });
 -     }
 - 
 -     protected function createAdjustmentForm(): array
 -     {
 -         return [
 -             TextInput::make('name')
 -                 ->label('Name')
 -                 ->required()
 -                 ->maxLength(255),
 - 
 -             Textarea::make('description')
 -                 ->label('Description'),
 - 
 -             Select::make('category')
 -                 ->label('Category')
 -                 ->options(AdjustmentCategory::class)
 -                 ->default(AdjustmentCategory::Tax)
 -                 ->hidden(fn () => (bool) $this->getCategory())
 -                 ->live()
 -                 ->required(),
 - 
 -             Select::make('type')
 -                 ->label('Type')
 -                 ->options(AdjustmentType::class)
 -                 ->default(AdjustmentType::Sales)
 -                 ->hidden(fn () => (bool) $this->getType())
 -                 ->live()
 -                 ->required(),
 - 
 -             Select::make('computation')
 -                 ->label('Computation')
 -                 ->options(AdjustmentComputation::class)
 -                 ->default(AdjustmentComputation::Percentage)
 -                 ->live()
 -                 ->required(),
 - 
 -             TextInput::make('rate')
 -                 ->label('Rate')
 -                 ->rate(static fn (Get $get) => $get('computation'))
 -                 ->required(),
 - 
 -             Select::make('scope')
 -                 ->label('Scope')
 -                 ->options(AdjustmentScope::class),
 - 
 -             Checkbox::make('recoverable')
 -                 ->label('Recoverable')
 -                 ->default(false)
 -                 ->helperText('When enabled, tax is tracked separately as claimable from the government. Non-recoverable taxes are treated as part of the expense.')
 -                 ->visible(function (Get $get) {
 -                     $category = $this->getCategory() ?? AdjustmentCategory::parse($get('category'));
 -                     $type = $this->getType() ?? AdjustmentType::parse($get('type'));
 - 
 -                     return $category->isTax() && $type->isPurchase();
 -                 }),
 - 
 -             Group::make()
 -                 ->schema([
 -                     DateTimePicker::make('start_date'),
 -                     DateTimePicker::make('end_date')
 -                         ->after('start_date'),
 -                 ])
 -                 ->visible(function (Get $get) {
 -                     $category = $this->getCategory() ?? AdjustmentCategory::parse($get('category'));
 - 
 -                     return $category->isDiscount();
 -                 }),
 -         ];
 -     }
 - 
 -     protected function createAdjustmentAction(Action $action): Action
 -     {
 -         $categoryLabel = $this->getCategory()?->getLabel() ?? 'Adjustment';
 -         $typeLabel = $this->getType()?->getLabel() ?? '';
 -         $label = trim($typeLabel . ' ' . $categoryLabel);
 - 
 -         return $action
 -             ->label('Create ' . $label)
 -             ->slideOver()
 -             ->modalWidth(MaxWidth::ExtraLarge)
 -             ->modalHeading('Create a new ' . strtolower($label));
 -     }
 - }
 
 
  |