info('πŸš€ GESCON IMPORT COMPLETO - Avvio importazione...'); // Inizializza connessioni $this->gesconDb = DB::connection('gescon_import'); $this->netgesconDb = DB::connection('mysql'); $isTest = $this->option('test'); $euroOnly = $this->option('euro-only') ?? true; // Default: solo EURO if ($isTest) { $this->warn('πŸ§ͺ MODALITΓ€ TEST - Nessuna modifica verrΓ  salvata'); } if ($euroOnly) { $this->info('πŸ’° MODALITΓ€ EURO-ONLY - Ignoro campi in lire'); } try { // FASE 1: Import anagrafica base $this->importAnagraficaBase($isTest); // FASE 2: Import configurazioni gestioni $this->importConfigurazioniGestioni($isTest); // FASE 3: Import dati contabili per stabile $this->importDatiContabiliStabili($isTest, $euroOnly); // FASE 4: Mappatura verso NetGescon $this->mappaVersNetGescon($isTest); // Report finale $this->showFinalReport(); } catch (\Exception $e) { $this->error('❌ Errore durante importazione: ' . $e->getMessage()); return 1; } return 0; } private function importAnagraficaBase($isTest = false) { $this->info('πŸ“Š FASE 1: Import anagrafica base...'); // 1. Import Stabili da Stabili.csv $stabiliFile = $this->basePath . '/dbc/Stabili.csv'; if (File::exists($stabiliFile)) { $this->importStabiliCsv($stabiliFile, $isTest); } // 2. Import Fornitori da dbc/Fornitori.mdb $fornitoriMdb = $this->basePath . '/dbc/Fornitori.mdb'; if (File::exists($fornitoriMdb)) { $this->importFornitoriMdb($fornitoriMdb, $isTest); } } private function importStabiliCsv($file, $isTest = false) { $this->info(" πŸ“ Importo Stabili da: {$file}"); if (!File::exists($file)) { $this->warn(" ⚠️ File non trovato: {$file}"); return; } $handle = fopen($file, 'r'); $header = fgetcsv($handle); // Prima riga header $count = 0; while (($row = fgetcsv($handle)) !== false) { try { // Mappa solo campi essenziali $data = [ 'cod_stabile' => $row[1] ?? null, // Campo 2: cod_stabile 'denominazione' => $row[2] ?? 'Senza denominazione', // Campo 3 'indirizzo' => $row[3] ?? null, // Campo 4 'cap' => $row[4] ?? null, // Campo 5 'citta' => $row[5] ?? null, // Campo 6 'provincia' => $row[6] ?? null, // Campo 7 'codice_fiscale' => $row[7] ?? null, // Campo 8 'cf_amministratore' => $row[8] ?? null, // Campo 9 'scale' => is_numeric($row[9] ?? null) ? (int)$row[9] : null, 'n_interni' => is_numeric($row[10] ?? null) ? (int)$row[10] : null, 'codice_directory' => $row[11] ?? null, // Campo 12 'flag_attivo' => true, 'iban' => $row[80] ?? null, // Campo IBAN se presente ]; // Controllo campi obbligatori if (empty($data['cod_stabile']) || empty($data['codice_directory'])) { $this->warn(" ⚠️ Stabile saltato - Dati incompleti"); continue; } if (!$isTest) { // Verifica duplicati $exists = $this->gesconDb->table('stabili') ->where('cod_stabile', $data['cod_stabile']) ->exists(); if (!$exists) { $this->gesconDb->table('stabili')->insert($data); $count++; $this->line(" βœ… Stabile {$data['cod_stabile']}: {$data['denominazione']}"); } else { $this->line(" πŸ”„ Stabile {$data['cod_stabile']}: giΓ  presente"); } } else { $count++; $this->line(" πŸ§ͺ TEST - Stabile {$data['cod_stabile']}: {$data['denominazione']}"); } } catch (\Exception $e) { $this->warn(" ❌ Errore riga: " . $e->getMessage()); } } fclose($handle); $this->importStats['stabili'] = $count; $this->info(" πŸ“Š Stabili importati: {$count}"); } private function importFornitoriMdb($file, $isTest = false) { $this->info(" πŸ“ Importo Fornitori da: {$file}"); try { // Esporta tabella fornitori da MDB $csvTemp = '/tmp/fornitori_temp.csv'; exec("mdb-export '{$file}' Fornitori > {$csvTemp} 2>/dev/null", $output, $result); if ($result !== 0 || !File::exists($csvTemp)) { $this->warn(" ⚠️ Impossibile esportare fornitori da MDB"); return; } $handle = fopen($csvTemp, 'r'); $header = fgetcsv($handle); $count = 0; // Trova indici colonne importanti (case-insensitive) $indices = $this->findColumnIndices($header, [ 'cod_forn', 'cognome', 'nome', 'denominazione', 'cod_fisc', 'p_iva', 'indirizzo', 'cap', 'citta', 'pr', 'telef_1', 'indir_email', 'cod_iban' ]); while (($row = fgetcsv($handle)) !== false) { try { // Costruisce ragione sociale da cognome+nome o denominazione $ragioneSociale = ''; if (!empty($row[$indices['denominazione'] ?? -1])) { $ragioneSociale = $row[$indices['denominazione']]; } else { $cognome = $row[$indices['cognome'] ?? -1] ?? ''; $nome = $row[$indices['nome'] ?? -1] ?? ''; $ragioneSociale = trim($cognome . ' ' . $nome); } if (empty($ragioneSociale)) { $ragioneSociale = 'Fornitore senza nome'; } $data = [ 'cod_forn' => $row[$indices['cod_forn'] ?? -1] ?? null, 'ragione_sociale' => $ragioneSociale, 'codice_fiscale' => $row[$indices['cod_fisc'] ?? -1] ?? null, 'partita_iva' => $row[$indices['p_iva'] ?? -1] ?? null, 'indirizzo' => $row[$indices['indirizzo'] ?? -1] ?? null, 'cap' => $row[$indices['cap'] ?? -1] ?? null, 'citta' => $row[$indices['citta'] ?? -1] ?? null, 'provincia' => $row[$indices['pr'] ?? -1] ?? null, 'telefono' => $row[$indices['telef_1'] ?? -1] ?? null, 'email' => $row[$indices['indir_email'] ?? -1] ?? null, 'iban' => $row[$indices['cod_iban'] ?? -1] ?? null, 'attivo' => true, ]; if (empty($data['cod_forn'])) continue; if (!$isTest) { $exists = $this->gesconDb->table('fornitori') ->where('cod_forn', $data['cod_forn']) ->exists(); if (!$exists) { $this->gesconDb->table('fornitori')->insert($data); $count++; } } else { $count++; $this->line(" πŸ§ͺ TEST - Fornitore {$data['cod_forn']}: {$data['ragione_sociale']}"); } } catch (\Exception $e) { $this->warn(" ❌ Errore fornitore: " . $e->getMessage()); } } fclose($handle); unlink($csvTemp); $this->importStats['fornitori'] = $count; $this->info(" πŸ“Š Fornitori importati: {$count}"); } catch (\Exception $e) { $this->warn(" ❌ Errore import fornitori: " . $e->getMessage()); } } private function importConfigurazioniGestioni($isTest = false) { $this->info('πŸ“Š FASE 2: Import configurazioni gestioni...'); // Itera ogni stabile per trovare i suoi anni di gestione $stabili = $this->gesconDb->table('stabili')->get(); foreach ($stabili as $stabile) { $this->importAnniGestioneStabile($stabile->cod_stabile, $stabile->codice_directory, $isTest); } } private function importAnniGestioneStabile($codStabile, $codiceDirectory, $isTest = false) { $stabileDir = $this->basePath . "/{$codiceDirectory}"; if (!File::isDirectory($stabileDir)) { $this->warn(" ⚠️ Directory stabile non trovata: {$stabileDir}"); return; } // Cerca file anni.csv o simili $anniFile = $stabileDir . '/anni.csv'; if (!File::exists($anniFile)) { // Cerca subdirectory per anni (0001, 0002, etc.) $subdirs = glob($stabileDir . '/[0-9][0-9][0-9][0-9]', GLOB_ONLYDIR); foreach ($subdirs as $subdir) { $anno = 2020 + (int)basename($subdir); // Stima anno da directory $this->createAnnoGestione($codStabile, $anno, $isTest); } } else { $this->importAnniCsv($anniFile, $codStabile, $isTest); } } private function createAnnoGestione($codStabile, $anno, $isTest = false) { $data = [ 'cod_stabile' => $codStabile, 'anno' => $anno, 'data_inizio' => "{$anno}-01-01", 'data_fine' => "{$anno}-12-31", 'chiuso' => $anno < date('Y'), ]; if (!$isTest) { $exists = $this->gesconDb->table('anni_gestione') ->where('cod_stabile', $codStabile) ->where('anno', $anno) ->exists(); if (!$exists) { $this->gesconDb->table('anni_gestione')->insert($data); $this->line(" βœ… Anno gestione {$codStabile}/{$anno}"); } } else { $this->line(" πŸ§ͺ TEST - Anno gestione {$codStabile}/{$anno}"); } } private function importDatiContabiliStabili($isTest = false, $euroOnly = true) { $this->info('πŸ“Š FASE 3: Import dati contabili per stabile...'); $stabili = $this->gesconDb->table('stabili')->get(); foreach ($stabili as $stabile) { $this->info(" 🏒 Elaboro stabile: {$stabile->cod_stabile} - {$stabile->denominazione}"); $this->importDatiStabile($stabile, $isTest, $euroOnly); } } private function importDatiStabile($stabile, $isTest = false, $euroOnly = true) { $stabileDir = $this->basePath . "/{$stabile->codice_directory}"; // 1. Import da generale_stabile.mdb (se presente) $generaleMdb = $stabileDir . '/generale_stabile.mdb'; if (File::exists($generaleMdb)) { $this->importFromGeneraleStabile($generaleMdb, $stabile->cod_stabile, $isTest, $euroOnly); } // 2. Import da singolo_anno.mdb per ogni anno $subdirs = glob($stabileDir . '/[0-9][0-9][0-9][0-9]', GLOB_ONLYDIR); foreach ($subdirs as $subdir) { $anno = 2020 + (int)basename($subdir); $singoloAnnoMdb = $subdir . '/singolo_anno.mdb'; if (File::exists($singoloAnnoMdb)) { $this->importFromSingoloAnno($singoloAnnoMdb, $stabile->cod_stabile, $anno, $isTest, $euroOnly); } } } private function importFromSingoloAnno($mdbFile, $codStabile, $anno, $isTest = false, $euroOnly = true) { $this->line(" πŸ“… Anno {$anno}: {$mdbFile}"); $tabelle = ['condomin', 'voc_spe', 'Operazioni', 'rate', 'incassi', 'dett_tab']; foreach ($tabelle as $tabella) { try { $csvTemp = "/tmp/{$tabella}_{$codStabile}_{$anno}.csv"; exec("mdb-export '{$mdbFile}' '{$tabella}' > {$csvTemp} 2>/dev/null", $output, $result); if ($result === 0 && File::exists($csvTemp)) { $count = $this->importTabellaSpecifica($csvTemp, $tabella, $codStabile, $anno, $isTest, $euroOnly); $this->line(" βœ… {$tabella}: {$count} record"); unlink($csvTemp); } else { $this->line(" ⚠️ {$tabella}: non disponibile"); } } catch (\Exception $e) { $this->warn(" ❌ Errore {$tabella}: " . $e->getMessage()); } } } private function importTabellaSpecifica($csvFile, $tabella, $codStabile, $anno, $isTest = false, $euroOnly = true) { $handle = fopen($csvFile, 'r'); $header = fgetcsv($handle); $count = 0; // Metodi specifici per ogni tabella $method = 'import' . ucfirst($tabella) . 'Data'; if (method_exists($this, $method)) { while (($row = fgetcsv($handle)) !== false) { try { $processed = $this->$method($row, $header, $codStabile, $anno, $euroOnly); if ($processed && !$isTest) { $count++; } elseif ($processed && $isTest) { $count++; } } catch (\Exception $e) { // Ignora errori singoli } } } fclose($handle); return $count; } private function importCondominData($row, $header, $codStabile, $anno, $euroOnly) { $indices = $this->findColumnIndices($header, [ 'id_cond', 'cod_cond', 'cognome', 'nome', 'cf', 'codice_fiscale', 'indirizzo', 'cap', 'citta', 'telefono', 'email', 'mm_prop', 'millesimi' ]); $data = [ 'cod_stabile' => $codStabile, 'id_cond' => $row[$indices['id_cond']] ?? null, 'cod_cond' => $row[$indices['cod_cond']] ?? null, 'cognome' => $row[$indices['cognome']] ?? null, 'nome' => $row[$indices['nome']] ?? null, 'codice_fiscale' => $row[$indices['cf']] ?? $row[$indices['codice_fiscale']] ?? null, 'indirizzo' => $row[$indices['indirizzo']] ?? null, 'cap' => $row[$indices['cap']] ?? null, 'citta' => $row[$indices['citta']] ?? null, 'telefono' => $row[$indices['telefono']] ?? null, 'email' => $row[$indices['email']] ?? null, 'millesimi_proprieta' => $row[$indices['mm_prop']] ?? $row[$indices['millesimi']] ?? null, ]; if (!empty($data['id_cond'])) { $exists = $this->gesconDb->table('condomini') ->where('cod_stabile', $codStabile) ->where('id_cond', $data['id_cond']) ->exists(); if (!$exists) { $this->gesconDb->table('condomini')->insert($data); return true; } } return false; } private function importVoc_speData($row, $header, $codStabile, $anno, $euroOnly) { $indices = $this->findColumnIndices($header, [ 'cod', 'descriz', 'tabella', 'preventivo_euro', 'consuntivo_euro', 'Perc_proprietario', 'Perc_Inquilino' ]); // Solo valori in EURO se richiesto $preventivo = $euroOnly ? ($row[$indices['preventivo_euro']] ?? null) : null; $consuntivo = $euroOnly ? ($row[$indices['consuntivo_euro']] ?? null) : null; $data = [ 'cod_stabile' => $codStabile, 'anno' => $anno, 'cod_voce' => $row[$indices['cod']] ?? null, 'descrizione' => $row[$indices['descriz']] ?? 'Voce senza descrizione', 'tabella_millesimi' => $row[$indices['tabella']] ?? null, 'perc_proprietario' => $row[$indices['Perc_proprietario']] ?? null, 'perc_inquilino' => $row[$indices['Perc_Inquilino']] ?? null, 'preventivo_euro' => is_numeric($preventivo) ? $preventivo : null, 'consuntivo_euro' => is_numeric($consuntivo) ? $consuntivo : null, ]; if (!empty($data['cod_voce'])) { $exists = $this->gesconDb->table('voci_spesa') ->where('cod_stabile', $codStabile) ->where('anno', $anno) ->where('cod_voce', $data['cod_voce']) ->exists(); if (!$exists) { $this->gesconDb->table('voci_spesa')->insert($data); return true; } } return false; } private function mappaVersNetGescon($isTest = false) { $this->info('πŸ“Š FASE 4: Mappatura verso NetGescon...'); if ($isTest) { $this->warn('πŸ§ͺ TEST - Mappatura simulata'); return; } // Qui implementeremo il mapping selettivo verso NetGescon // mantenendo l'anagrafica unica e le relazioni $this->info(' πŸ”„ Mappatura in sviluppo...'); } private function findColumnIndices($header, $columns) { $indices = []; foreach ($columns as $col) { $index = array_search(strtolower($col), array_map('strtolower', $header)); if ($index !== false) { $indices[$col] = $index; } } return $indices; } private function showFinalReport() { $this->info('πŸ“Š REPORT FINALE IMPORTAZIONE'); $this->info('================================'); foreach ($this->importStats as $tipo => $count) { $this->info(" {$tipo}: {$count} record"); } $this->info('βœ… Importazione completata!'); } }