label('Importa estratto (Unicredit WRI)') ->icon('heroicon-o-arrow-up-tray') ->modalWidth('7xl') ->form($this->getImportFormSchema()) ->action(function (array $data): void { $this->runImport('unicredit', $data); }), Action::make('importa_intesa_csv') ->label('Importa estratto (Intesa CSV)') ->icon('heroicon-o-arrow-up-tray') ->modalWidth('7xl') ->form($this->getImportFormSchema()) ->action(function (array $data): void { $this->runImport('intesa', $data); }), ]; } private function getImportFormSchema(): array { return [ Select::make('iban') ->label('Conto (IBAN)') ->native(false) ->searchable() ->options(fn(): array => $this->getIbanOptions()) ->helperText('Consigliato: seleziona il conto per associare i movimenti.'), Select::make('gestione_id') ->label('Gestione (opzionale)') ->native(false) ->searchable() ->options(fn(): array => $this->getGestioneOptions()) ->default(fn(): ?string => $this->resolveDefaultGestioneId()), FileUpload::make('file') ->label('File estratto') ->directory('tmp/banca') ->disk('local') ->required(), Toggle::make('replace') ->label('Sostituisci import nel periodo') ->helperText('Elimina SOLO i movimenti importati e NON riconciliati (registrazione vuota) per lo stesso conto e per l\'intervallo date del file, poi reimporta.') ->default(false), ]; } private function runImport(string $tipo, array $data): void { $user = Auth::user(); if (! $user instanceof User) { Notification::make()->title('Utente non valido')->danger()->send(); return; } $stabileId = StabileContext::resolveActiveStabileId($user); if (! $stabileId) { Notification::make()->title('Seleziona uno stabile')->danger()->send(); return; } $path = (string) ($data['file'] ?? ''); if ($path === '') { Notification::make()->title('Seleziona un file')->danger()->send(); return; } try { $content = Storage::disk('local')->get($path); $importer = new MovimentiBancaImporter(new UnicreditWriParser(), new IntesaCsvParser(), new ExcelMovimentiParser()); $iban = isset($data['iban']) && is_string($data['iban']) && trim($data['iban']) !== '' ? trim((string) $data['iban']) : null; $gestioneId = isset($data['gestione_id']) && is_numeric($data['gestione_id']) ? (int) $data['gestione_id'] : null; $replace = isset($data['replace']) ? (bool) $data['replace'] : false; if ($tipo === 'intesa') { $res = $importer->importIntesaCsv($content, $stabileId, basename($path), $iban, $gestioneId, $replace); } else { $res = $importer->importUnicreditWri($content, $stabileId, basename($path), $iban, $gestioneId, $replace); } Notification::make() ->title('Import completato') ->body('Importati: ' . ($res['imported'] ?? 0) . ' · Duplicati: ' . ($res['duplicates'] ?? 0)) ->success() ->send(); } catch (\Throwable $e) { Notification::make()->title('Errore import')->body($e->getMessage())->danger()->send(); } finally { try { Storage::disk('local')->delete($path); } catch (\Throwable) { // ignore } } } private function getIbanOptions(): array { $user = Auth::user(); if (! $user instanceof User) { return []; } $stabileId = StabileContext::resolveActiveStabileId($user); if (! $stabileId) { return []; } $opts = []; foreach ( DatiBancari::query() ->where('stabile_id', $stabileId) ->orderBy('denominazione_banca') ->orderBy('iban') ->get(['iban', 'denominazione_banca']) as $c ) { $iban = is_string($c->iban) ? trim($c->iban) : ''; if ($iban === '') { continue; } $label = trim(($c->denominazione_banca ?: 'Banca') . ' · ' . $iban); $opts[$iban] = $label; } return $opts; } private function getGestioneOptions(): array { $user = Auth::user(); if (! $user instanceof User) { return []; } $stabileId = StabileContext::resolveActiveStabileId($user); if (! $stabileId) { return []; } if (! DB::getSchemaBuilder()->hasTable('gestioni_contabili')) { return []; } return GestioneContabile::query() ->where('stabile_id', $stabileId) ->orderByDesc('anno_gestione') ->orderBy('tipo_gestione') ->orderByDesc('id') ->get(['id', 'denominazione', 'protocollo_prefix', 'stato']) ->mapWithKeys(fn(GestioneContabile $g) => [ (string) $g->id => trim(($g->protocollo_prefix ? $g->protocollo_prefix . ' · ' : '') . $g->denominazione) . ($g->stato !== 'aperta' ? (' (' . $g->stato . ')') : ''), ]) ->all(); } private function resolveDefaultGestioneId(): ?string { $user = Auth::user(); if (! $user instanceof User) { return null; } $stabileId = StabileContext::resolveActiveStabileId($user); if (! $stabileId) { return null; } if (! DB::getSchemaBuilder()->hasTable('gestioni_contabili')) { return null; } $g = GestioneContabile::query() ->where('stabile_id', $stabileId) ->orderByDesc('anno_gestione') ->orderByDesc('id') ->first(['id']); return $g ? (string) $g->id : null; } }