631 lines
22 KiB
PHP
Executable File
631 lines
22 KiB
PHP
Executable File
<?php
|
|
|
|
namespace App\Console\Commands;
|
|
|
|
use Illuminate\Console\Command;
|
|
use Illuminate\Support\Facades\DB;
|
|
|
|
class GesconTempDatabase extends Command
|
|
{
|
|
protected $signature = 'gescon:temp-db
|
|
{action : create, import, view, cleanup}
|
|
{--stabile-path=0021 : Cartella stabile GESCON}
|
|
{--anno-path=0001 : Cartella anno GESCON}
|
|
{--limit=100 : Limite record per import}';
|
|
|
|
protected $description = 'Gestisce database temporaneo per import GESCON (solo sviluppo)';
|
|
|
|
private $tempDbName = 'gescon_temp_development';
|
|
|
|
public function handle()
|
|
{
|
|
$action = $this->argument('action');
|
|
|
|
switch ($action) {
|
|
case 'create':
|
|
$this->createTempDatabase();
|
|
break;
|
|
case 'import':
|
|
$this->importGesconData();
|
|
break;
|
|
case 'view':
|
|
$this->viewTempData();
|
|
break;
|
|
case 'cleanup':
|
|
$this->cleanupTempDatabase();
|
|
break;
|
|
default:
|
|
$this->error("❌ Azione non valida. Usa: create, import, view, cleanup");
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
private function createTempDatabase()
|
|
{
|
|
$this->info("🔧 CREAZIONE DATABASE TEMPORANEO GESCON");
|
|
$this->warn("⚠️ ATTENZIONE: Database solo per sviluppo, sarà eliminato!");
|
|
|
|
try {
|
|
// Crea database temporaneo
|
|
DB::statement("CREATE DATABASE IF NOT EXISTS {$this->tempDbName} CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci");
|
|
|
|
// Configura connessione temporanea
|
|
config(['database.connections.gescon_temp' => [
|
|
'driver' => 'mysql',
|
|
'host' => '127.0.0.1',
|
|
'database' => $this->tempDbName,
|
|
'username' => 'netgescon_user',
|
|
'password' => 'NetGescon2024!',
|
|
'charset' => 'utf8mb4',
|
|
'collation' => 'utf8mb4_unicode_ci',
|
|
]]);
|
|
|
|
$this->createTempTables();
|
|
$this->info("✅ Database temporaneo creato: {$this->tempDbName}");
|
|
} catch (\Exception $e) {
|
|
$this->error("❌ Errore creazione database: " . $e->getMessage());
|
|
}
|
|
}
|
|
|
|
private function createTempTables()
|
|
{
|
|
$this->info("📊 Creazione tabelle temporanee...");
|
|
|
|
// Tabella stabili GESCON
|
|
DB::connection('gescon_temp')->statement('
|
|
CREATE TABLE IF NOT EXISTS temp_stabili (
|
|
id INT AUTO_INCREMENT PRIMARY KEY,
|
|
codice_stabile VARCHAR(20),
|
|
denominazione VARCHAR(255),
|
|
indirizzo TEXT,
|
|
citta VARCHAR(100),
|
|
amministratore VARCHAR(255),
|
|
note TEXT,
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
) ENGINE=InnoDB
|
|
');
|
|
|
|
// Tabella voci spesa
|
|
DB::connection('gescon_temp')->statement('
|
|
CREATE TABLE IF NOT EXISTS temp_voci_spesa (
|
|
id INT AUTO_INCREMENT PRIMARY KEY,
|
|
stabile_codice VARCHAR(20),
|
|
cod_spe VARCHAR(10),
|
|
descrizione VARCHAR(255),
|
|
categoria VARCHAR(100),
|
|
tipo_voce VARCHAR(50),
|
|
preventivo_euro DECIMAL(15,2),
|
|
consuntivo_euro DECIMAL(15,2),
|
|
ordinamento INT,
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
INDEX idx_stabile_cod (stabile_codice, cod_spe)
|
|
) ENGINE=InnoDB
|
|
');
|
|
|
|
// Tabella fornitori completa
|
|
DB::connection('gescon_temp')->statement('
|
|
CREATE TABLE IF NOT EXISTS temp_fornitori (
|
|
id INT AUTO_INCREMENT PRIMARY KEY,
|
|
cod_forn INT,
|
|
ragione_sociale VARCHAR(255),
|
|
cognome VARCHAR(100),
|
|
nome VARCHAR(100),
|
|
codice_fiscale VARCHAR(20),
|
|
partita_iva VARCHAR(20),
|
|
indirizzo VARCHAR(255),
|
|
cap VARCHAR(10),
|
|
citta VARCHAR(100),
|
|
provincia VARCHAR(10),
|
|
telefono VARCHAR(50),
|
|
cellulare VARCHAR(50),
|
|
fax VARCHAR(50),
|
|
email VARCHAR(255),
|
|
pec VARCHAR(255),
|
|
note TEXT,
|
|
categoria_attivita VARCHAR(255),
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
INDEX idx_cod_forn (cod_forn)
|
|
) ENGINE=InnoDB
|
|
');
|
|
|
|
// Tabella operazioni complete
|
|
DB::connection('gescon_temp')->statement('
|
|
CREATE TABLE IF NOT EXISTS temp_operazioni (
|
|
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
|
stabile_codice VARCHAR(20),
|
|
id_operazione_gescon BIGINT,
|
|
numero_spesa INT,
|
|
data_spesa DATE,
|
|
cod_spe VARCHAR(10),
|
|
cod_for INT,
|
|
importo_euro DECIMAL(15,2),
|
|
beneficiario VARCHAR(255),
|
|
numero_fattura VARCHAR(50),
|
|
data_fattura DATE,
|
|
note TEXT,
|
|
natura VARCHAR(10),
|
|
competenza CHAR(1),
|
|
anno_gestione VARCHAR(20),
|
|
|
|
-- Campi risolti per visualizzazione
|
|
descrizione_spesa VARCHAR(255),
|
|
ragione_sociale_fornitore VARCHAR(255),
|
|
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
INDEX idx_stabile (stabile_codice),
|
|
INDEX idx_data (data_spesa),
|
|
INDEX idx_cod_spe (cod_spe),
|
|
INDEX idx_cod_for (cod_for)
|
|
) ENGINE=InnoDB
|
|
');
|
|
|
|
// Tabella incassi
|
|
DB::connection('gescon_temp')->statement('
|
|
CREATE TABLE IF NOT EXISTS temp_incassi (
|
|
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
|
stabile_codice VARCHAR(20),
|
|
numero_rata INT,
|
|
data_incasso DATE,
|
|
importo_euro DECIMAL(15,2),
|
|
cod_spe VARCHAR(10),
|
|
unita_immobiliare VARCHAR(20),
|
|
note TEXT,
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
INDEX idx_stabile (stabile_codice),
|
|
INDEX idx_rata (numero_rata)
|
|
) ENGINE=InnoDB
|
|
');
|
|
|
|
// Tabella log import per tracciabilità
|
|
DB::connection('gescon_temp')->statement('
|
|
CREATE TABLE IF NOT EXISTS temp_import_log (
|
|
id INT AUTO_INCREMENT PRIMARY KEY,
|
|
stabile_codice VARCHAR(20),
|
|
anno VARCHAR(10),
|
|
tabella VARCHAR(50),
|
|
records_imported INT,
|
|
status VARCHAR(20),
|
|
note TEXT,
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
) ENGINE=InnoDB
|
|
');
|
|
|
|
$this->info("✅ Tabelle temporanee create");
|
|
}
|
|
|
|
private function importGesconData()
|
|
{
|
|
$stabilePath = $this->option('stabile-path');
|
|
$annoPath = $this->option('anno-path');
|
|
$limit = $this->option('limit');
|
|
|
|
$this->info("📂 IMPORT DATI GESCON TEMPORANEO");
|
|
$this->info("Stabile: {$stabilePath} Anno: {$annoPath}");
|
|
$this->warn("🧪 Database temporaneo - Solo per sviluppo!");
|
|
|
|
// Verifica connessione temp
|
|
if (!$this->verifyTempConnection()) {
|
|
$this->error("❌ Database temporaneo non trovato. Esegui prima 'create'");
|
|
return;
|
|
}
|
|
|
|
// Import sequenziale
|
|
$this->importFornitori();
|
|
$this->importVociSpesa($stabilePath, $annoPath);
|
|
$this->importOperazioni($stabilePath, $annoPath, $limit);
|
|
|
|
$this->info("✅ Import completato in database temporaneo");
|
|
$this->showImportSummary();
|
|
}
|
|
|
|
private function importFornitori()
|
|
{
|
|
$this->info("👥 Import fornitori da DBC...");
|
|
|
|
$fornitoriFile = '/home/michele/netgescon/docs/02-architettura-laravel/Gescon/dbc/Fornitori.mdb';
|
|
|
|
if (!file_exists($fornitoriFile)) {
|
|
$this->warn("⚠️ File fornitori non trovato");
|
|
return;
|
|
}
|
|
|
|
$tempCsv = '/tmp/temp_fornitori_' . time() . '.csv';
|
|
exec("mdb-export '{$fornitoriFile}' Fornitori > {$tempCsv}");
|
|
|
|
if (!file_exists($tempCsv) || filesize($tempCsv) < 100) {
|
|
$this->warn("⚠️ Export fornitori fallito");
|
|
return;
|
|
}
|
|
|
|
$imported = $this->processFornitori($tempCsv);
|
|
unlink($tempCsv);
|
|
|
|
$this->info("✅ Fornitori importati: {$imported}");
|
|
$this->logImport('ALL', 'ALL', 'temp_fornitori', $imported, 'SUCCESS');
|
|
}
|
|
|
|
private function importVociSpesa($stabilePath, $annoPath)
|
|
{
|
|
$this->info("📋 Import voci spesa...");
|
|
|
|
$vociFile = "/home/michele/netgescon/docs/02-architettura-laravel/Gescon/{$stabilePath}/{$annoPath}/singolo_anno.mdb";
|
|
|
|
if (!file_exists($vociFile)) {
|
|
$this->warn("⚠️ File voci spesa non trovato");
|
|
return;
|
|
}
|
|
|
|
$tempCsv = '/tmp/temp_voci_' . time() . '.csv';
|
|
exec("mdb-export '{$vociFile}' voc_spe > {$tempCsv}");
|
|
|
|
if (!file_exists($tempCsv) || filesize($tempCsv) < 50) {
|
|
$this->warn("⚠️ Export voci spesa fallito");
|
|
return;
|
|
}
|
|
|
|
$imported = $this->processVociSpesa($tempCsv, $stabilePath);
|
|
unlink($tempCsv);
|
|
|
|
$this->info("✅ Voci spesa importate: {$imported}");
|
|
$this->logImport($stabilePath, $annoPath, 'temp_voci_spesa', $imported, 'SUCCESS');
|
|
}
|
|
|
|
private function importOperazioni($stabilePath, $annoPath, $limit)
|
|
{
|
|
$this->info("📊 Import operazioni...");
|
|
|
|
$operazioniFile = "/home/michele/netgescon/docs/02-architettura-laravel/Gescon/{$stabilePath}/{$annoPath}/singolo_anno.mdb";
|
|
|
|
if (!file_exists($operazioniFile)) {
|
|
$this->warn("⚠️ File operazioni non trovato");
|
|
return;
|
|
}
|
|
|
|
$tempCsv = '/tmp/temp_operazioni_' . time() . '.csv';
|
|
exec("timeout 60s mdb-export '{$operazioniFile}' Operazioni > {$tempCsv}");
|
|
|
|
if (!file_exists($tempCsv) || filesize($tempCsv) < 100) {
|
|
$this->warn("⚠️ Export operazioni fallito");
|
|
return;
|
|
}
|
|
|
|
$imported = $this->processOperazioni($tempCsv, $stabilePath, $limit);
|
|
unlink($tempCsv);
|
|
|
|
$this->info("✅ Operazioni importate: {$imported}");
|
|
$this->logImport($stabilePath, $annoPath, 'temp_operazioni', $imported, 'SUCCESS');
|
|
}
|
|
|
|
private function processFornitori($csvFile)
|
|
{
|
|
$handle = fopen($csvFile, 'r');
|
|
$headers = fgetcsv($handle);
|
|
$fieldMap = $this->createFieldMap($headers);
|
|
|
|
$batch = [];
|
|
$imported = 0;
|
|
|
|
while (($row = fgetcsv($handle)) !== false) {
|
|
$data = [
|
|
'cod_forn' => $this->getFieldValue($row, $fieldMap, 'cod_forn'),
|
|
'ragione_sociale' => $this->cleanString($this->getFieldValue($row, $fieldMap, 'cognome') . ' ' . $this->getFieldValue($row, $fieldMap, 'nome')),
|
|
'cognome' => $this->getFieldValue($row, $fieldMap, 'cognome'),
|
|
'nome' => $this->getFieldValue($row, $fieldMap, 'nome'),
|
|
'codice_fiscale' => $this->getFieldValue($row, $fieldMap, 'cod_fisc'),
|
|
'partita_iva' => $this->getFieldValue($row, $fieldMap, 'p_iva'),
|
|
'indirizzo' => $this->getFieldValue($row, $fieldMap, 'indirizzo'),
|
|
'cap' => $this->getFieldValue($row, $fieldMap, 'cap'),
|
|
'citta' => $this->getFieldValue($row, $fieldMap, 'citta'),
|
|
'provincia' => $this->getFieldValue($row, $fieldMap, 'pr'),
|
|
'telefono' => $this->getFieldValue($row, $fieldMap, 'telef_1'),
|
|
'cellulare' => $this->getFieldValue($row, $fieldMap, 'cellulare'),
|
|
'fax' => $this->getFieldValue($row, $fieldMap, 'fax'),
|
|
'email' => $this->getFieldValue($row, $fieldMap, 'indir_email'),
|
|
'pec' => $this->getFieldValue($row, $fieldMap, 'pec_fornitore'),
|
|
'note' => $this->getFieldValue($row, $fieldMap, 'note'),
|
|
'categoria_attivita' => $this->getFieldValue($row, $fieldMap, 'descrizione')
|
|
];
|
|
|
|
if (!empty($data['cod_forn'])) {
|
|
$batch[] = $data;
|
|
$imported++;
|
|
|
|
if (count($batch) >= 100) {
|
|
DB::connection('gescon_temp')->table('temp_fornitori')->insert($batch);
|
|
$batch = [];
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!empty($batch)) {
|
|
DB::connection('gescon_temp')->table('temp_fornitori')->insert($batch);
|
|
}
|
|
|
|
fclose($handle);
|
|
return $imported;
|
|
}
|
|
|
|
private function processVociSpesa($csvFile, $stabilePath)
|
|
{
|
|
$handle = fopen($csvFile, 'r');
|
|
$headers = fgetcsv($handle);
|
|
$fieldMap = $this->createFieldMap($headers);
|
|
|
|
$batch = [];
|
|
$imported = 0;
|
|
|
|
while (($row = fgetcsv($handle)) !== false) {
|
|
$data = [
|
|
'stabile_codice' => $stabilePath,
|
|
'cod_spe' => $this->getFieldValue($row, $fieldMap, 'cod'),
|
|
'descrizione' => substr($this->getFieldValue($row, $fieldMap, 'descriz'), 0, 255),
|
|
'categoria' => 'Standard',
|
|
'tipo_voce' => $this->getFieldValue($row, $fieldMap, 't_spese') == 'O' ? 'Ordinaria' : 'Straordinaria',
|
|
'preventivo_euro' => $this->parseDecimal($this->getFieldValue($row, $fieldMap, 'preventivo_euro')),
|
|
'consuntivo_euro' => $this->parseDecimal($this->getFieldValue($row, $fieldMap, 'consuntivo_euro')),
|
|
'ordinamento' => $this->getFieldValue($row, $fieldMap, 'id_vocspe')
|
|
];
|
|
|
|
if (!empty($data['cod_spe'])) {
|
|
$batch[] = $data;
|
|
$imported++;
|
|
|
|
if (count($batch) >= 100) {
|
|
DB::connection('gescon_temp')->table('temp_voci_spesa')->insert($batch);
|
|
$batch = [];
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!empty($batch)) {
|
|
DB::connection('gescon_temp')->table('temp_voci_spesa')->insert($batch);
|
|
}
|
|
|
|
fclose($handle);
|
|
return $imported;
|
|
}
|
|
|
|
private function processOperazioni($csvFile, $stabilePath, $limit)
|
|
{
|
|
$handle = fopen($csvFile, 'r');
|
|
$headers = fgetcsv($handle);
|
|
$fieldMap = $this->createFieldMap($headers);
|
|
|
|
$batch = [];
|
|
$imported = 0;
|
|
|
|
while (($row = fgetcsv($handle)) !== false && $imported < $limit) {
|
|
$importoEuro = $this->parseDecimal($this->getFieldValue($row, $fieldMap, 'importo_euro'));
|
|
|
|
if (empty($importoEuro) || $importoEuro == 0) continue;
|
|
|
|
$data = [
|
|
'stabile_codice' => $stabilePath,
|
|
'id_operazione_gescon' => $this->getFieldValue($row, $fieldMap, 'id_operaz'),
|
|
'numero_spesa' => $this->getFieldValue($row, $fieldMap, 'n_spe'),
|
|
'data_spesa' => $this->parseDate($this->getFieldValue($row, $fieldMap, 'dt_spe')),
|
|
'cod_spe' => $this->getFieldValue($row, $fieldMap, 'cod_spe'),
|
|
'cod_for' => $this->getFieldValue($row, $fieldMap, 'cod_for'),
|
|
'importo_euro' => $importoEuro,
|
|
'beneficiario' => substr($this->getFieldValue($row, $fieldMap, 'benef'), 0, 255),
|
|
'numero_fattura' => $this->getFieldValue($row, $fieldMap, 'num_fat'),
|
|
'data_fattura' => $this->parseDate($this->getFieldValue($row, $fieldMap, 'dt_fat')),
|
|
'note' => $this->getFieldValue($row, $fieldMap, 'note'),
|
|
'natura' => $this->getFieldValue($row, $fieldMap, 'natura'),
|
|
'competenza' => $this->getFieldValue($row, $fieldMap, 'compet'),
|
|
'anno_gestione' => $this->getFieldValue($row, $fieldMap, 'anno')
|
|
];
|
|
|
|
$batch[] = $data;
|
|
$imported++;
|
|
|
|
if (count($batch) >= 100) {
|
|
DB::connection('gescon_temp')->table('temp_operazioni')->insert($batch);
|
|
$batch = [];
|
|
}
|
|
}
|
|
|
|
if (!empty($batch)) {
|
|
DB::connection('gescon_temp')->table('temp_operazioni')->insert($batch);
|
|
}
|
|
|
|
fclose($handle);
|
|
|
|
// Aggiorna descrizioni e fornitori
|
|
$this->updateOperazioniDescriptions();
|
|
|
|
return $imported;
|
|
}
|
|
|
|
private function updateOperazioniDescriptions()
|
|
{
|
|
$this->info("🔗 Collegamento descrizioni e fornitori...");
|
|
|
|
// Collega voci spesa
|
|
DB::connection('gescon_temp')->statement("
|
|
UPDATE temp_operazioni o
|
|
JOIN temp_voci_spesa v ON o.stabile_codice = v.stabile_codice AND o.cod_spe = v.cod_spe
|
|
SET o.descrizione_spesa = v.descrizione
|
|
");
|
|
|
|
// Collega fornitori
|
|
DB::connection('gescon_temp')->statement("
|
|
UPDATE temp_operazioni o
|
|
JOIN temp_fornitori f ON o.cod_for = f.cod_forn
|
|
SET o.ragione_sociale_fornitore = f.ragione_sociale
|
|
");
|
|
}
|
|
|
|
private function viewTempData()
|
|
{
|
|
$this->info("👁️ VISUALIZZAZIONE DATI TEMPORANEI");
|
|
|
|
if (!$this->verifyTempConnection()) {
|
|
$this->error("❌ Database temporaneo non trovato");
|
|
return;
|
|
}
|
|
|
|
// Statistiche generali
|
|
$stats = DB::connection('gescon_temp')->select("
|
|
SELECT
|
|
'Fornitori' as tabella, COUNT(*) as records FROM temp_fornitori
|
|
UNION ALL
|
|
SELECT
|
|
'Voci Spesa' as tabella, COUNT(*) as records FROM temp_voci_spesa
|
|
UNION ALL
|
|
SELECT
|
|
'Operazioni' as tabella, COUNT(*) as records FROM temp_operazioni
|
|
UNION ALL
|
|
SELECT
|
|
'Incassi' as tabella, COUNT(*) as records FROM temp_incassi
|
|
");
|
|
|
|
$this->info("📊 STATISTICHE DATABASE TEMPORANEO:");
|
|
foreach ($stats as $stat) {
|
|
$this->info(" {$stat->tabella}: {$stat->records} record");
|
|
}
|
|
|
|
// Operazioni recenti con dettagli
|
|
$operazioni = DB::connection('gescon_temp')->select("
|
|
SELECT
|
|
data_spesa,
|
|
cod_spe,
|
|
descrizione_spesa,
|
|
ragione_sociale_fornitore,
|
|
importo_euro,
|
|
numero_fattura
|
|
FROM temp_operazioni
|
|
ORDER BY data_spesa DESC
|
|
LIMIT 5
|
|
");
|
|
|
|
if (!empty($operazioni)) {
|
|
$this->info("\n📋 OPERAZIONI RECENTI:");
|
|
foreach ($operazioni as $op) {
|
|
$this->info(" {$op->data_spesa} | {$op->cod_spe} | {$op->descrizione_spesa} | €{$op->importo_euro}");
|
|
}
|
|
}
|
|
}
|
|
|
|
private function cleanupTempDatabase()
|
|
{
|
|
$this->warn("🗑️ ELIMINAZIONE DATABASE TEMPORANEO");
|
|
$this->warn("⚠️ ATTENZIONE: Tutti i dati di sviluppo saranno persi!");
|
|
|
|
if (!$this->confirm('Sei sicuro di voler eliminare il database temporaneo?')) {
|
|
$this->info("❌ Operazione annullata");
|
|
return;
|
|
}
|
|
|
|
try {
|
|
DB::statement("DROP DATABASE IF EXISTS {$this->tempDbName}");
|
|
$this->info("✅ Database temporaneo eliminato: {$this->tempDbName}");
|
|
} catch (\Exception $e) {
|
|
$this->error("❌ Errore eliminazione: " . $e->getMessage());
|
|
}
|
|
}
|
|
|
|
private function verifyTempConnection()
|
|
{
|
|
try {
|
|
config(['database.connections.gescon_temp' => [
|
|
'driver' => 'mysql',
|
|
'host' => '127.0.0.1',
|
|
'database' => $this->tempDbName,
|
|
'username' => 'netgescon_user',
|
|
'password' => 'NetGescon2024!',
|
|
'charset' => 'utf8mb4',
|
|
'collation' => 'utf8mb4_unicode_ci',
|
|
]]);
|
|
|
|
DB::connection('gescon_temp')->select('SELECT 1');
|
|
return true;
|
|
} catch (\Exception $e) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
private function logImport($stabile, $anno, $tabella, $records, $status)
|
|
{
|
|
try {
|
|
DB::connection('gescon_temp')->table('temp_import_log')->insert([
|
|
'stabile_codice' => $stabile,
|
|
'anno' => $anno,
|
|
'tabella' => $tabella,
|
|
'records_imported' => $records,
|
|
'status' => $status
|
|
]);
|
|
} catch (\Exception $e) {
|
|
// Ignore log errors
|
|
}
|
|
}
|
|
|
|
private function showImportSummary()
|
|
{
|
|
$logs = DB::connection('gescon_temp')->select("
|
|
SELECT tabella, SUM(records_imported) as totale
|
|
FROM temp_import_log
|
|
GROUP BY tabella
|
|
");
|
|
|
|
$this->info("\n📊 RIEPILOGO IMPORT:");
|
|
foreach ($logs as $log) {
|
|
$this->info(" {$log->tabella}: {$log->totale} record");
|
|
}
|
|
}
|
|
|
|
// Utility methods
|
|
private function createFieldMap($headers)
|
|
{
|
|
$map = [];
|
|
foreach ($headers as $index => $header) {
|
|
$map[strtolower(trim($header))] = $index;
|
|
}
|
|
return $map;
|
|
}
|
|
|
|
private function getFieldValue($row, $fieldMap, $fieldName)
|
|
{
|
|
$fieldName = strtolower($fieldName);
|
|
if (!isset($fieldMap[$fieldName])) return null;
|
|
|
|
$index = $fieldMap[$fieldName];
|
|
return isset($row[$index]) ? trim($row[$index]) : null;
|
|
}
|
|
|
|
private function parseDate($dateString)
|
|
{
|
|
if (empty($dateString)) return null;
|
|
|
|
try {
|
|
$date = \DateTime::createFromFormat('m/d/y H:i:s', $dateString);
|
|
if (!$date) {
|
|
$date = \DateTime::createFromFormat('Y-m-d H:i:s', $dateString);
|
|
}
|
|
if (!$date) {
|
|
$date = \DateTime::createFromFormat('Y-m-d', $dateString);
|
|
}
|
|
return $date ? $date->format('Y-m-d') : null;
|
|
} catch (\Exception $e) {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
private function parseDecimal($value)
|
|
{
|
|
if (empty($value)) return 0;
|
|
|
|
$value = preg_replace('/[^\d.,\-]/', '', $value);
|
|
$value = str_replace(',', '.', $value);
|
|
|
|
return is_numeric($value) ? (float)$value : 0;
|
|
}
|
|
|
|
private function cleanString($string)
|
|
{
|
|
if (empty($string)) return null;
|
|
return trim(preg_replace('/\s+/', ' ', $string));
|
|
}
|
|
}
|