| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130 | 
							- <?php
 - 
 - namespace App\Filament\Company\Resources\Accounting\BudgetResource\RelationManagers;
 - 
 - use App\Filament\Tables\Columns\DeferredTextInputColumn;
 - use App\Models\Accounting\BudgetAllocation;
 - use App\Models\Accounting\BudgetItem;
 - use Filament\Notifications\Notification;
 - use Filament\Resources\RelationManagers\RelationManager;
 - use Filament\Tables\Actions\Action;
 - use Filament\Tables\Columns\TextColumn;
 - use Filament\Tables\Table;
 - use Livewire\Attributes\On;
 - 
 - class BudgetItemsRelationManager extends RelationManager
 - {
 -     protected static string $relationship = 'budgetItems';
 - 
 -     protected static bool $isLazy = false;
 - 
 -     // Store changes that are pending
 -     public array $batchChanges = [];
 - 
 -     // Listen for events from the custom column
 - 
 -     #[On('batch-column-changed')]
 -     public function handleBatchColumnChanged($data): void
 -     {
 -         ray($data);
 -         // Store the changed value
 -         $key = "{$data['recordKey']}.{$data['name']}";
 -         $this->batchChanges[$key] = $data['value'];
 -     }
 - 
 -     #[On('save-batch-changes')]
 -     public function saveBatchChanges(): void
 -     {
 -         ray('Saving batch changes');
 -         foreach ($this->batchChanges as $key => $value) {
 -             // Parse the composite key
 -             [$recordKey, $column] = explode('.', $key, 2);
 - 
 -             // Extract period from the column name (e.g., "allocations_by_period.2023-Q1")
 -             preg_match('/allocations_by_period\.(.+)/', $column, $matches);
 -             $period = $matches[1] ?? null;
 - 
 -             if (! $period) {
 -                 continue;
 -             }
 - 
 -             // Find the record
 -             $record = BudgetItem::find($recordKey);
 -             if (! $record) {
 -                 continue;
 -             }
 - 
 -             // Update the allocation
 -             $allocation = $record->allocations->firstWhere('period', $period);
 -             if ($allocation) {
 -                 $allocation->update(['amount' => $value]);
 -             } else {
 -                 $record->allocations()->create([
 -                     'period' => $period,
 -                     'amount' => $value,
 -                     // Add other required fields
 -                 ]);
 -             }
 -         }
 - 
 -         // Clear the batch changes
 -         $this->batchChanges = [];
 - 
 -         // Notify the user
 -         Notification::make()
 -             ->title('Budget allocations updated')
 -             ->success()
 -             ->send();
 -     }
 - 
 -     public function table(Table $table): Table
 -     {
 -         $budget = $this->getOwnerRecord();
 - 
 -         // Get distinct periods for this budget
 -         $periods = BudgetAllocation::query()
 -             ->join('budget_items', 'budget_allocations.budget_item_id', '=', 'budget_items.id')
 -             ->where('budget_items.budget_id', $budget->id)
 -             ->orderBy('start_date')
 -             ->pluck('period')
 -             ->unique()
 -             ->values()
 -             ->toArray();
 - 
 -         ray($this->batchChanges);
 - 
 -         return $table
 -             ->recordTitleAttribute('account_id')
 -             ->paginated(false)
 -             ->modifyQueryUsing(
 -                 fn ($query) => $query->with(['account', 'allocations'])
 -             )
 -             ->headerActions([
 -                 Action::make('saveBatchChanges')
 -                     ->label('Save All Changes')
 -                     ->action('saveBatchChanges')
 -                     ->color('primary')
 -                     ->icon('heroicon-o-check-circle'),
 -             ])
 -             ->columns(array_merge([
 -                 TextColumn::make('account.name')
 -                     ->label('Accounts')
 -                     ->sortable()
 -                     ->searchable(),
 -             ], collect($periods)->map(
 -                 fn ($period) => DeferredTextInputColumn::make("allocations_by_period.{$period}")
 -                     ->label($period)
 -                     ->getStateUsing(function ($record, DeferredTextInputColumn $column) use ($period) {
 -                         $key = "{$record->getKey()}.{$column->getName()}";
 - 
 -                         // Check if batch change exists
 -                         if (isset($this->batchChanges[$key])) {
 -                             return $this->batchChanges[$key];
 -                         }
 - 
 -                         return $record->allocations->firstWhere('period', $period)?->amount;
 -                     })
 -                     ->batchMode(),
 -             )->all()));
 -     }
 - }
 
 
  |