netgescon-master/app/Console/Commands/ManageDistribution.php
Pikappa2 f45845ba3c feat: Complete NetGesCon modernization - all core systems implemented
MAJOR IMPLEMENTATION COMPLETED:
 Modern database structure with Laravel best practices
 Complete Eloquent relationships (Amministratore→Stabili→Movements)
 8-character alphanumeric codes system (ADM, ANA, MOV, ALL prefixes)
 Multi-database architecture for administrators
 Complete property management (anagrafica_condominiale, diritti_reali, contratti)
 Distribution system for multi-server deployment
 Universal responsive UI with permission-based sidebar

NEW MODELS & MIGRATIONS:
- AnagraficaCondominiale: Complete person/entity management
- ContattoAnagrafica: Multi-contact system with usage flags
- DirittoReale: Property rights with quotas and percentages
- ContrattoLocazione: Rental contracts with landlord/tenant
- TipoUtilizzo: Property usage types (residential, commercial, etc.)
- Enhanced Stabile: Cadastral data, SDI, rate configuration
- Enhanced UnitaImmobiliare: Modern structure with backward compatibility

SERVICES & CONTROLLERS:
- DistributionService: Multi-server deployment and migration
- FileManagerController: Administrator folder management
- DistributionController: API for server-to-server communication
- MultiDatabaseService: Dynamic database connections

READY FOR PRODUCTION:
 Database schema: Complete and tested
 Models relationships: All working and verified
 Code generation: Automatic 8-char codes implemented
 Testing: Successful data creation confirmed
 Documentation: Complete internal technical docs

NEXT PHASE: Millésimal tables, expense categories, cost distribution engine
2025-07-08 16:24:03 +02:00

282 lines
9.7 KiB
PHP

<?php
namespace App\Console\Commands;
use App\Models\Amministratore;
use App\Services\DistributionService;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Storage;
class ManageDistribution extends Command
{
/**
* The name and signature of the console command.
*/
protected $signature = 'distribution:manage
{action : Action to perform (migrate|status|backup|test)}
{--administrator= : Administrator code (8 characters)}
{--target-server= : Target server URL for migration}
{--all : Apply to all administrators}';
/**
* The console command description.
*/
protected $description = 'Manage multi-server distribution of administrators';
/**
* Execute the console command.
*/
public function handle()
{
$action = $this->argument('action');
switch ($action) {
case 'migrate':
return $this->migrateAdministrator();
case 'status':
return $this->showDistributionStatus();
case 'backup':
return $this->backupAdministrator();
case 'test':
return $this->testDistribution();
default:
$this->error("Unknown action: {$action}");
return 1;
}
}
/**
* Migra un amministratore verso un altro server
*/
private function migrateAdministrator()
{
$adminCode = $this->option('administrator');
$targetServer = $this->option('target-server');
if (!$adminCode) {
$adminCode = $this->ask('Administrator code (8 characters)');
}
if (!$targetServer) {
$targetServer = $this->ask('Target server URL');
}
if (!$adminCode || !$targetServer) {
$this->error('Both administrator code and target server are required');
return 1;
}
$amministratore = Amministratore::where('codice_amministratore', $adminCode)->first();
if (!$amministratore) {
$this->error("Administrator {$adminCode} not found");
return 1;
}
$this->info("Starting migration of administrator {$adminCode} to {$targetServer}");
// Verifica server target
$this->info('Checking target server health...');
$healthCheck = DistributionService::checkServerHealth($targetServer);
if (!$healthCheck['success']) {
$this->error("Target server health check failed: {$healthCheck['error']}");
return 1;
}
$this->info('Target server is healthy and compatible');
// Conferma migrazione
if (!$this->confirm("Are you sure you want to migrate administrator {$adminCode} to {$targetServer}?")) {
$this->info('Migration cancelled');
return 0;
}
// Esegui migrazione
$this->info('Starting migration process...');
$result = DistributionService::migrateAdministrator($amministratore, $targetServer);
if ($result['success']) {
$this->info("✅ Migration completed successfully!");
$this->info("Administrator {$adminCode} is now accessible at: {$result['new_url']}");
} else {
$this->error("❌ Migration failed: {$result['error']}");
return 1;
}
return 0;
}
/**
* Mostra stato della distribuzione
*/
private function showDistributionStatus()
{
$this->info('NetGesCon Multi-Server Distribution Status');
$this->info('==========================================');
$stats = DistributionService::getDistributionStats();
$this->info("Total Administrators: {$stats['total_administrators']}");
$this->info("Local Administrators: {$stats['local_administrators']}");
$this->info("Distributed Administrators: {$stats['distributed_administrators']}");
$this->newLine();
$this->info('Server Distribution:');
if (empty($stats['servers'])) {
$this->info(' No distributed servers configured');
} else {
foreach ($stats['servers'] as $server) {
$this->info(" {$server['server']}: {$server['administrators_count']} administrators");
}
}
$this->newLine();
$this->info('Status Distribution:');
foreach ($stats['status_distribution'] as $status => $count) {
$this->info(" {$status}: {$count}");
}
// Mostra dettagli amministratori distribuiti
$distributedAdmins = Amministratore::whereNotNull('server_database')->get();
if ($distributedAdmins->isNotEmpty()) {
$this->newLine();
$this->info('Distributed Administrators Details:');
$this->table(
['Code', 'Name', 'Server', 'Status', 'Last Backup'],
$distributedAdmins->map(function ($admin) {
return [
$admin->codice_amministratore,
$admin->nome_completo,
$admin->server_database ?: 'localhost',
$admin->stato_sincronizzazione,
$admin->ultimo_backup ? $admin->ultimo_backup->format('Y-m-d H:i') : 'Never'
];
})
);
}
return 0;
}
/**
* Esegue backup di un amministratore
*/
private function backupAdministrator()
{
$adminCode = $this->option('administrator');
$all = $this->option('all');
if (!$adminCode && !$all) {
$adminCode = $this->ask('Administrator code (8 characters) or use --all for all administrators');
}
if ($all) {
$this->info('Backing up all administrators...');
$administrators = Amministratore::all();
} else {
$administrators = Amministratore::where('codice_amministratore', $adminCode)->get();
if ($administrators->isEmpty()) {
$this->error("Administrator {$adminCode} not found");
return 1;
}
}
$successCount = 0;
$errorCount = 0;
foreach ($administrators as $admin) {
$this->info("Backing up administrator {$admin->codice_amministratore}...");
$result = DistributionService::performDistributedBackup($admin);
if ($result['success']) {
$this->info("✅ Backup completed for {$admin->codice_amministratore}");
$successCount++;
} else {
$this->error("❌ Backup failed for {$admin->codice_amministratore}: {$result['error']}");
$errorCount++;
}
}
$this->info("Backup completed: {$successCount} successful, {$errorCount} errors");
return $errorCount > 0 ? 1 : 0;
}
/**
* Testa la funzionalità di distribuzione
*/
private function testDistribution()
{
$this->info('Testing distribution functionality...');
// Test 1: Verifica struttura cartelle
$this->info('1. Testing folder structure...');
$testAdmin = Amministratore::first();
if (!$testAdmin) {
$this->error('No administrators found for testing');
return 1;
}
$archiveInfo = $testAdmin->getArchiveInfo();
if ($archiveInfo['exists']) {
$this->info("✅ Archive exists: {$archiveInfo['path']}");
$this->info(" Size: {$archiveInfo['size_formatted']}");
$this->info(" Files: {$archiveInfo['files_count']}");
} else {
$this->warn("⚠️ Archive not found for {$testAdmin->codice_amministratore}");
}
// Test 2: Health check locale
$this->info('2. Testing local health check...');
$localUrl = config('app.url');
$healthCheck = DistributionService::checkServerHealth($localUrl);
if ($healthCheck['success']) {
$this->info("✅ Local server health check passed");
} else {
$this->error("❌ Local server health check failed: {$healthCheck['error']}");
}
// Test 3: Backup test
$this->info('3. Testing backup functionality...');
$backupResult = $testAdmin->createDatabaseBackup();
if ($backupResult['success']) {
$this->info("✅ Backup test passed");
$this->info(" File: {$backupResult['filename']}");
$this->info(" Size: " . number_format($backupResult['size']) . " bytes");
} else {
$this->error("❌ Backup test failed: {$backupResult['error']}");
}
// Test 4: Migrazione simulata
$this->info('4. Testing migration preparation...');
$migrationResult = $testAdmin->prepareForMigration();
if ($migrationResult['success']) {
$this->info("✅ Migration preparation test passed");
$this->info(" Archive: {$migrationResult['zip_file']}");
$this->info(" Size: " . number_format($migrationResult['size']) . " bytes");
// Cleanup test files
if (file_exists($migrationResult['zip_file'])) {
unlink($migrationResult['zip_file']);
}
if (file_exists($migrationResult['metadata_file'])) {
unlink($migrationResult['metadata_file']);
}
} else {
$this->error("❌ Migration preparation test failed: {$migrationResult['error']}");
}
$this->info('Distribution testing completed');
return 0;
}
}