hasRole('super-admin') && Schema::hasTable('arera_operatori'); } public function mount(): void { $this->mountInteractsWithTable(); } protected function getTableQuery(): Builder { return AreraOperatore::query()->with(['naturaGiuridica', 'settori']); } public function table(Table $table): Table { return $table ->striped() ->defaultSort('societa') ->columns([ TextColumn::make('societa') ->label('Società') ->formatStateUsing(fn($state, AreraOperatore $record): string => trim((string) $state) !== '' ? trim((string) $state) : ('P.IVA ' . (string) ($record->partita_iva ?: $record->partita_iva_normalizzata))) ->searchable() ->sortable() ->wrap(), TextColumn::make('partita_iva')->label('P.IVA')->searchable()->sortable(), TextColumn::make('naturaGiuridica.nome')->label('Natura')->toggleable()->sortable(), TextColumn::make('settori.nome')->label('Settori')->badge()->separator(',')->searchable(), TextColumn::make('sito_internet')->label('Sito')->url(fn(AreraOperatore $record): ?string => $record->sito_internet)->openUrlInNewTab()->toggleable(), TextColumn::make('sede_legale_citta')->label('Città')->searchable()->toggleable(), TextColumn::make('sede_legale_provincia')->label('Prov.')->searchable()->toggleable(), TextColumn::make('updated_at')->label('Aggiornato')->dateTime('d/m/Y H:i')->toggleable(isToggledHiddenByDefault: true), ]) ->filters([ SelectFilter::make('settore') ->label('Settore') ->options(fn(): array=> AreraSettoreAttivita::query()->orderBy('nome')->pluck('nome', 'id')->all()) ->query(function (Builder $query, array $data): Builder { $value = (int) ($data['value'] ?? 0); if ($value <= 0) { return $query; } return $query->whereHas('settori', fn(Builder $q): Builder => $q->whereKey($value)); }), ]) ->headerActions([ Action::make('scarica_zip_arera') ->label('Scarica ZIP ARERA') ->icon('heroicon-o-cloud-arrow-down') ->modalWidth('4xl') ->form([ Select::make('preset_url') ->label('Fonte rapida') ->options([ 'https://www.arera.it/fileadmin/ricercaoperatori/operatori-export-29_06_2026_09_00_10.zip' => 'Operatori - export completo (29/06/2026)', 'https://www.arera.it/fileadmin/ricercaoperatori/export-mercato-vend29_06_2026_09_35_02.zip' => 'Mercato vendita (29/06/2026)', 'https://www.arera.it/fileadmin/ricercaoperatori/export-gas-vend29_06_2026_09_30_02.zip' => 'Gas vendita (29/06/2026)', ]) ->native(false) ->helperText('I nomi file ARERA cambiano nel tempo: se il preset non e aggiornato, incolla sotto il nuovo URL ZIP.') ->reactive(), TextInput::make('custom_url') ->label('URL ZIP ARERA') ->placeholder('https://www.arera.it/fileadmin/ricercaoperatori/operatori-export-...zip') ->url() ->maxLength(1000), ]) ->action(function (array $data): void { $url = trim((string) ($data['custom_url'] ?? '')); if ($url === '') { $url = trim((string) ($data['preset_url'] ?? '')); } if ($url === '') { Notification::make()->title('Indica un URL ZIP ARERA')->danger()->send(); return; } try { $result = app(AreraOperatoriImportService::class)->importZipFromUrl($url); $body = 'File Excel: ' . $result['files'] . ' · Righe: ' . $result['rows'] . ' · Nuovi: ' . $result['imported'] . ' · Aggiornati: ' . $result['updated'] . ' · Saltati: ' . $result['skipped'] . ' · Settori: ' . $result['sectors']; if (! empty($result['errors'])) { $body .= "\n" . implode("\n", $result['errors']); } Notification::make()->title('Download/import ARERA completato')->body($body)->success()->send(); } catch (\Throwable $e) { report($e); Notification::make()->title('Errore download ARERA')->body($e->getMessage())->danger()->send(); } }), Action::make('importa_excel') ->label('Importa Excel ARERA') ->icon('heroicon-o-arrow-up-tray') ->modalWidth('3xl') ->form([ FileUpload::make('xlsx_file') ->label('File operatori-export.xlsx') ->disk('local') ->directory('tmp/arera-operatori') ->acceptedFileTypes([ 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'application/vnd.ms-excel', '.xlsx', '.xls', ]) ->required(), ]) ->action(function (array $data): void { $path = (string) ($data['xlsx_file'] ?? ''); if ($path === '') { Notification::make()->title('Seleziona un file Excel')->danger()->send(); return; } try { $result = app(AreraOperatoriImportService::class)->importXlsx( Storage::disk('local')->path($path), basename($path), ); $body = 'Righe: ' . $result['rows'] . ' · Nuovi: ' . $result['imported'] . ' · Aggiornati: ' . $result['updated'] . ' · Saltati: ' . $result['skipped'] . ' · Settori: ' . $result['sectors']; if (! empty($result['errors'])) { $body .= "\n" . implode("\n", $result['errors']); } Notification::make()->title('Import ARERA completato')->body($body)->success()->send(); } catch (\Throwable $e) { report($e); Notification::make()->title('Errore import ARERA')->body($e->getMessage())->danger()->send(); } }), ]); } }