argument('tenant'); $this->info("🏦 Starting Financial Flow Import for tenant: {$tenantId}"); $this->newLine(); // Validation if (!$this->validateInputs()) { return Command::FAILURE; } // Prepare file paths $filePaths = $this->prepareFilePaths(); // Show import plan $this->showImportPlan($filePaths); if (!$this->option('dry-run') && !$this->confirm('Proceed with import?')) { $this->info('Import cancelled by user.'); return Command::SUCCESS; } // Execute import $service = new FinancialFlowImportService($tenantId); if ($this->option('dry-run')) { $this->info('🔍 DRY RUN - No data will be saved'); $this->simulateImport($filePaths); } else { $result = $service->importCompleteFinancialFlow($filePaths); $this->displayResults($result); } return Command::SUCCESS; } private function validateInputs(): bool { $errors = []; // Check tenant exists $tenantId = $this->argument('tenant'); if (empty($tenantId)) { $errors[] = 'Tenant ID is required'; } // Check at least one file is provided $hasFiles = $this->option('anagr-casse') || $this->option('incassi') || $this->option('unicredit-wri'); if (!$hasFiles) { $errors[] = 'At least one input file must be specified'; } // Check file existence foreach (['anagr-casse', 'incassi', 'unicredit-wri'] as $option) { $file = $this->option($option); if ($file && !file_exists($file)) { $errors[] = "File not found: {$file}"; } } if (!empty($errors)) { $this->error('❌ Validation errors:'); foreach ($errors as $error) { $this->line(" • {$error}"); } return false; } return true; } private function prepareFilePaths(): array { $filePaths = []; if ($file = $this->option('anagr-casse')) { $filePaths['anagr_casse'] = $file; } if ($file = $this->option('incassi')) { $filePaths['incassi'] = $file; } if ($file = $this->option('unicredit-wri')) { $filePaths['unicredit_wri'] = $file; } return $filePaths; } private function showImportPlan(array $filePaths): void { $this->info('📋 Import Plan:'); $this->newLine(); $steps = [ 'anagr_casse' => '1. Import Conti Bancari', 'incassi' => '2. Import Incassi/Pagamenti', 'unicredit_wri' => '3. Import Movimenti Bancari' ]; foreach ($steps as $key => $description) { if (isset($filePaths[$key])) { $file = basename($filePaths[$key]); $size = $this->formatFileSize(filesize($filePaths[$key])); $this->line(" ✅ {$description} from {$file} ({$size})"); } else { $this->line(" ⏭️ {$description} - SKIPPED"); } } if ($this->option('auto-reconcile')) { $this->line(" 🔄 4. Automatic Reconciliation - ENABLED"); } else { $this->line(" ⏭️ 4. Automatic Reconciliation - SKIPPED"); } $this->newLine(); } private function simulateImport(array $filePaths): void { foreach ($filePaths as $type => $file) { $this->info("📁 Analyzing {$type}: " . basename($file)); switch ($type) { case 'anagr_casse': $this->simulateContiBancari($file); break; case 'incassi': $this->simulateIncassi($file); break; case 'unicredit_wri': $this->simulateMovimentiBancari($file); break; } $this->newLine(); } } private function simulateContiBancari(string $file): void { $lines = count(file($file)); $this->line(" • Would import " . ($lines - 1) . " bank accounts"); // Sample first few records if (($handle = fopen($file, "r")) !== FALSE) { $headers = fgetcsv($handle); $count = 0; while (($row = fgetcsv($handle)) !== FALSE && $count < 3) { $data = array_combine($headers, $row); $this->line(" - {$data['Codice']}: {$data['Descrizione']}"); $count++; } fclose($handle); } } private function simulateIncassi(string $file): void { $lines = count(file($file)); $this->line(" • Would import " . ($lines - 1) . " payments"); // Count by year if (($handle = fopen($file, "r")) !== FALSE) { $headers = fgetcsv($handle); $years = []; while (($row = fgetcsv($handle)) !== FALSE) { $data = array_combine($headers, $row); $year = $data['anno_rif'] ?? 'unknown'; $years[$year] = ($years[$year] ?? 0) + 1; } fclose($handle); foreach ($years as $year => $count) { $this->line(" - Year {$year}: {$count} payments"); } } } private function simulateMovimentiBancari(string $file): void { $content = file_get_contents($file); $lines = explode("\n", $content); // Find CSV start $csvStart = null; foreach ($lines as $index => $line) { if (strpos($line, 'Data;Valuta;Descrizione;Euro;Caus.') !== false) { $csvStart = $index + 1; break; } } if (!$csvStart) { $this->error(" ❌ Cannot find CSV data in WRI file"); return; } $movements = 0; $entrate = 0; $uscite = 0; for ($i = $csvStart; $i < count($lines); $i++) { $line = trim($lines[$i]); if (empty($line) || !preg_match('/^\d{2}\/\d{2}\/\d{4}/', $line)) { continue; } $parts = explode(';', $line); if (count($parts) >= 4) { $movements++; $importo = (float)str_replace(',', '.', $parts[3]); if ($importo > 0) { $entrate++; } else { $uscite++; } } } $this->line(" • Would import {$movements} bank movements"); $this->line(" - Entrate: {$entrate}"); $this->line(" - Uscite: {$uscite}"); } private function displayResults(array $result): void { if ($result['success']) { $this->info('✅ Financial Flow Import Completed Successfully!'); $this->newLine(); $stats = $result['stats']; $this->info('📊 Import Statistics:'); foreach ($stats as $category => $data) { if (is_array($data) && isset($data['imported'])) { $this->line(" {$category}:"); $this->line(" ✅ Imported: {$data['imported']}"); if ($data['errors'] > 0) { $this->line(" ❌ Errors: {$data['errors']}"); } } } if (isset($stats['riconciliazioni'])) { $recon = $stats['riconciliazioni']; $this->newLine(); $this->info('🔄 Reconciliation Results:'); $this->line(" ✅ Automatic: {$recon['automatiche']}"); $this->line(" ✋ Manual: {$recon['manuali']}"); $this->line(" ⏳ Pending: {$recon['sospese']}"); } } else { $this->error('❌ Import Failed: ' . $result['message']); if (isset($result['stats'])) { $this->newLine(); $this->info('📊 Partial Results:'); foreach ($result['stats'] as $category => $data) { if (is_array($data) && isset($data['imported'])) { $this->line(" {$category}: {$data['imported']} imported, {$data['errors']} errors"); } } } } } private function formatFileSize(int $bytes): string { $units = ['B', 'KB', 'MB', 'GB']; $unitIndex = 0; while ($bytes >= 1024 && $unitIndex < count($units) - 1) { $bytes /= 1024; $unitIndex++; } return round($bytes, 1) . ' ' . $units[$unitIndex]; } }