self::getStabiliData(), 'condomini' => self::getCondominiData(), 'contabilita' => self::getContabilitaData(), 'tickets' => self::getTicketsData(), 'assemblee' => self::getAssembleeData(), 'sistema' => self::getSistemaData(), ]; }); } /** * Dati degli stabili con dettagli aggiuntivi */ private static function getStabiliData() { try { $totaleStabili = Stabile::count(); $stabiliAttivi = Stabile::where('stato', 'attivo')->count(); $unitaTotali = UnitaImmobiliare::count(); $unitaOccupate = UnitaImmobiliare::whereHas('proprietari')->count(); return [ 'totale' => $totaleStabili, 'attivi' => $stabiliAttivi, 'inattivi' => $totaleStabili - $stabiliAttivi, 'unita_totali' => $unitaTotali, 'unita_occupate' => $unitaOccupate, 'unita_libere' => $unitaTotali - $unitaOccupate, 'percentuale_occupazione' => $unitaTotali > 0 ? round(($unitaOccupate / $unitaTotali) * 100, 1) : 0, ]; } catch (\Exception $e) { return [ 'totale' => 0, 'attivi' => 0, 'inattivi' => 0, 'unita_totali' => 0, 'unita_occupate' => 0, 'unita_libere' => 0, 'percentuale_occupazione' => 0 ]; } } /** * Dati dei condomini con classificazioni */ private static function getCondominiData() { try { $totaleCondomini = Soggetto::count(); $proprietari = Soggetto::where('tipo', 'proprietario')->count(); $inquilini = Soggetto::where('tipo', 'inquilino')->count(); return [ 'totale' => $totaleCondomini, 'proprietari' => $proprietari, 'inquilini' => $inquilini, 'altri' => $totaleCondomini - $proprietari - $inquilini, 'percentuale_proprietari' => $totaleCondomini > 0 ? round(($proprietari / $totaleCondomini) * 100, 1) : 0, ]; } catch (\Exception $e) { return [ 'totale' => 0, 'proprietari' => 0, 'inquilini' => 0, 'altri' => 0, 'percentuale_proprietari' => 0 ]; } } /** * Dati della contabilità con trend */ private static function getContabilitaData() { try { $oggi = Carbon::now(); $meseScorso = $oggi->copy()->subMonth(); $rateScadute = Rata::where('data_scadenza', '<', $oggi) ->where('stato', '!=', 'pagata') ->count(); $incassiMeseCorrente = Rata::whereMonth('data_pagamento', $oggi->month) ->whereYear('data_pagamento', $oggi->year) ->where('stato', 'pagata') ->sum('importo'); $incassiMeseScorso = Rata::whereMonth('data_pagamento', $meseScorso->month) ->whereYear('data_pagamento', $meseScorso->year) ->where('stato', 'pagata') ->sum('importo'); return [ 'rate_scadute' => $rateScadute, 'rate_del_mese' => Rata::whereMonth('data_scadenza', $oggi->month) ->whereYear('data_scadenza', $oggi->year) ->count(), 'incassi_mese_corrente' => $incassiMeseCorrente, 'incassi_mese_scorso' => $incassiMeseScorso, 'trend_incassi' => $incassiMeseScorso > 0 ? round((($incassiMeseCorrente - $incassiMeseScorso) / $incassiMeseScorso) * 100, 1) : 0, 'movimenti_mese' => MovimentoContabile::whereMonth('data_movimento', $oggi->month) ->whereYear('data_movimento', $oggi->year) ->count(), ]; } catch (\Exception $e) { return [ 'rate_scadute' => 0, 'rate_del_mese' => 0, 'incassi_mese_corrente' => 0, 'incassi_mese_scorso' => 0, 'trend_incassi' => 0, 'movimenti_mese' => 0 ]; } } /** * Dati dei tickets con priorità e tempi */ private static function getTicketsData() { try { $ticketsAperti = Ticket::where('stato', 'aperto')->count(); $ticketsUrgenti = Ticket::where('priorita', 'alta') ->where('stato', '!=', 'chiuso') ->count(); $ticketsInLavorazione = Ticket::where('stato', 'in_lavorazione')->count(); $ticketsChiusiOggi = Ticket::where('stato', 'chiuso') ->whereDate('updated_at', Carbon::today()) ->count(); return [ 'aperti' => $ticketsAperti, 'urgenti' => $ticketsUrgenti, 'in_lavorazione' => $ticketsInLavorazione, 'chiusi_oggi' => $ticketsChiusiOggi, 'totali' => Ticket::count(), 'percentuale_risoluzione' => $ticketsAperti + $ticketsInLavorazione > 0 ? round(($ticketsChiusiOggi / ($ticketsAperti + $ticketsInLavorazione + $ticketsChiusiOggi)) * 100, 1) : 100, ]; } catch (\Exception $e) { return [ 'aperti' => 0, 'urgenti' => 0, 'in_lavorazione' => 0, 'chiusi_oggi' => 0, 'totali' => 0, 'percentuale_risoluzione' => 100 ]; } } /** * Dati delle assemblee con calendario */ private static function getAssembleeData() { try { $oggi = Carbon::now(); $prossimi30Giorni = $oggi->copy()->addDays(30); return [ 'prossime' => Assemblea::where('data_assemblea', '>', $oggi)->count(), 'prossimi_30_giorni' => Assemblea::whereBetween('data_assemblea', [$oggi, $prossimi30Giorni])->count(), 'questo_mese' => Assemblea::whereMonth('data_assemblea', $oggi->month) ->whereYear('data_assemblea', $oggi->year) ->count(), 'delibere_da_approvare' => Assemblea::where('stato', 'bozza')->count(), 'verbali_da_completare' => Assemblea::where('stato', 'verbale_incompleto')->count(), ]; } catch (\Exception $e) { return [ 'prossime' => 0, 'prossimi_30_giorni' => 0, 'questo_mese' => 0, 'delibere_da_approvare' => 0, 'verbali_da_completare' => 0 ]; } } /** * Dati generali del sistema */ private static function getSistemaData() { try { return [ 'utenti_attivi' => DB::table('users')->where('active', true)->count(), 'ultimo_backup' => self::getLastBackupDate(), 'spazio_documenti' => self::getDocumentsSpaceUsage(), 'uptime' => self::getSystemUptime(), 'versione' => config('app.version', '2.1.0'), ]; } catch (\Exception $e) { return [ 'utenti_attivi' => 1, 'ultimo_backup' => 'Non disponibile', 'spazio_documenti' => 'Non disponibile', 'uptime' => 'Non disponibile', 'versione' => '2.1.0' ]; } } /** * Ottiene la data dell'ultimo backup */ private static function getLastBackupDate() { // Implementazione placeholder - sostituire con logica reale return Carbon::now()->subDays(1)->format('d/m/Y H:i'); } /** * Ottiene l'utilizzo dello spazio per i documenti */ private static function getDocumentsSpaceUsage() { // Implementazione placeholder - sostituire con logica reale return '245 MB utilizzati'; } /** * Ottiene l'uptime del sistema */ private static function getSystemUptime() { // Implementazione placeholder - sostituire con logica reale return '15 giorni, 8 ore'; } /** * Pulisce la cache */ public static function clearCache() { Cache::forget('dashboard_data'); } }