Files
glastree/MEMORY.md
T
2026-05-26 12:28:39 +02:00

31 KiB

MEMORY.md - Glastree Project

Project Context

Laravel 13 / PHP 8.4 project for parish management (Glastree). Full codebase exists and is operational.


System Status

FUNZIONANTE (Stable)

  • Dashboard
  • Individui (CRUD completo) - funziona da internet (con viste personalizzate per colonna)
  • Gruppi (CRUD completo) - funziona da internet (con vista tabella/albero e colonne personalizzate)
  • Documenti - funziona da internet
  • Eventi (CRUD completo) - funziona da internet (con mass delete)
  • Calendario eventi - funziona da internet
  • Email (sistema completo)
  • Impostazioni (App Settings, Logo, Email Settings)
  • Mailing List - funziona da internet (con mass delete)
  • Report (predefiniti e personalizzati, accesso tramite permesso 'report')

⚠️ IN COMPLETAMENTO

  • Sistema Email: funziona al 95%, SMTP potrebbe necessitare credenziali corrette
  • Nuova implementazione: email sync logging

Progress Summary

Eventi Enhancements (Completed)

  • Migration 2026_05_12_142009_add_location_to_eventi_table added luogo_indirizzo and luogo_url_maps columns
  • Evento model updated with fillable fields
  • EventoController updated: index() with search + sorting, store/update with location fields
  • eventi/index.blade.php: search input, sortable columns (nome_evento, created_at), delete button
  • eventi/create.blade.php: "Dove" card with address + Google Maps URL fields
  • eventi/edit.blade.php: "Dove" card with address + Google Maps URL fields
  • eventi/show.blade.php: "Luogo" section with address, link to Google Maps, embedded map preview

Responsabile Multi-select (Completed)

  • Migration 2026_05_12_000003_change_responsabile_to_multi.php changed responsabile_id to responsabile_ids JSON
  • Gruppo model updated with getResponsabiliIds() and getResponsabili() methods
  • GruppoController updated: index(), store(), update(), show() for multi-select
  • Views updated: show, edit, create blades with multi-select support

13 Maggio 2026 - Fixes

  • Ordinamento colonne: Aggiunto ordinamento per Descrizione, Tipo, Gruppi, Responsabili
  • Form edit: Aggiunti campi tipo_evento e note mancanti
  • Show view: Corretta struttura HTML della sezione documenti

14 Maggio 2026 - Fixes

  • Form annidati: La sezione Documenti spostata FUORI dal form principale
  • Tipologia enum: Aggiunti valori 'programma' e 'locandina' alla colonna tipologia in documenti
  • Visibilita enum: Aggiunto valore 'evento' alla colonna visibilita in documenti

15 Maggio 2026 - Eventi Show

  • Rimossa sezione "Dove" duplicata dalla sidebar
  • Aggiunta nuova sezione "Luogo" sotto "Data e Orario" nella colonna centrale

15 Maggio 2026 - Email Settings

  • Aggiunto pulsante "Test Invio Email (SMTP)" nella pagina impostazioni email
  • Aggiunto metodo testSmtp() nel controller per verificare la configurazione SMTP
  • Route: POST /impostazioni/email/test-smtp
  • Campo password opzionale (non più required)
  • Rimossi attributi required dai campi del form impostazioni email

15 Maggio 2026 - Eventi Calendar

  • Nuova vista calendario con FullCalendar 6.1.10
  • Routes: GET /eventi/calendar e GET /eventi/calendar/events
  • Metodo calendar() e calendarEvents() in EventoController
  • Sidebar: menu Eventi con sottovoci Calendario, Elenco, Nuovo Evento
  • Click su evento apre la pagina show dell'evento

15 Maggio 2026 - Email UI

  • Compose view: Rimossa sidebar sinistra, solo form a schermo intero
  • Sidebar menu Email:
    • Ordine: Nuova Email, In arrivo, Preferiti, Inviate, Bozze, Archivio, Cestino
    • Cliccando "Email" apre direttamente inbox
  • Bottone sincronizzazione: "Ricevi/Invia" nella pagina inbox
  • Sincronizzazione: Limitata a 100 messaggi per cartella

15 Maggio 2026 - Bug Fixes

  • RFC 2822: Usare Address::create() di Symfony per gestire correttamente il display name
  • Route email.sync: Sostituito route('email.sync.quick') con url('email/sync/quick') nella vista email/index.blade.php

16 Maggio 2026 - Email UI Fixes

  • Footer: Aggiunto min-height: calc(100vh - 120px) al content-wrapper per garantire visibilità footer
  • Pagination: Creato custom view vendor.pagination.simple-bootstrap-4 con caratteri ‹ e › invece di SVG (problema scalabilità risolto)

16 Maggio 2026 - Logo Upload System

  • Model: App\Models\AppSetting con metodi getLogoUrl(), getLogoSmallUrl(), getAppName()
  • Migration: 2026_05_16_000001_add_logo_path_to_app_settings - aggiunge logo_path e logo_small_path
  • Controller: ImpostazioniController - metodi uploadLogo() e removeLogo()
  • Routes: POST /impostazioni/logo, POST /impostazioni/logo/remove
  • Views: Sezione Logo in /impostazioni per caricare logo grande e piccolo
  • Login page: Logo dinamico da AppSetting::getLogoUrl()
  • Sidebar: Logo piccolo da AppSetting::getLogoSmallUrl() con fallback a icona

16 Maggio 2026 - Email Signature Feature

  • Migration: 2026_05_16_000003_add_signature_to_email_settings - aggiunge colonna signature (longText)
  • Migration: 2026_05_16_000004_add_signature_enabled_to_email_settings - aggiunge colonna signature_enabled (boolean, default true)
  • Model: EmailSetting aggiornato con signature e signature_enabled in fillable, cast boolean, metodo getSignature()
  • View: admin/email-settings/index.blade.php aggiornato con:
    • Titolo cambiato da "Email IMAP" a "Email Settings"
    • Nuova sezione "Firma" nel menu laterale
    • Toggle switch "Attiva firma automatica" per abilitare/disabilitare la firma
    • Editor WYSIWYG Quill.js per la composizione della firma
    • Caricamento lazy di Quill.js da CDN
  • Controller: EmailController aggiornato con metodo appendSignature(body, signature, enabled) che aggiunge la firma al body solo se abilitata
  • La firma viene aggiunta sia alle email inviate via SMTP che a quelle salvate in "Invio"
  • Sidebar: Voce di menu cambiata da "Email IMAP" a "Impostazione Email"

Sistema Email - Dettagli Tecnici

Routes Eventi

GET  /eventi              → eventi.index (elenco)
GET  /eventi/calendar     → eventi.calendar (calendario)
GET  /eventi/calendar/events → eventi.calendar.events (eventi per FullCalendar)
GET  /eventi/create       → eventi.create
POST /eventi              → eventi.store
GET  /eventi/{id}         → eventi.show
GET  /eventi/{id}/edit   → eventi.edit
PUT  /eventi/{id}         → eventi.update
DELETE /eventi/{id}       → eventi.destroy

Routes Email

POST   /email/send              → email.send
POST   /email/sync/quick        → email.sync.quick
POST   /email/bulk              → email.bulk
GET    /email/{folder?}         → email.index
POST   /email/{id}/star         → email.star
DELETE /email/{id}              → email.destroy

Folder Types

  • inbox, sent, drafts, archive, starred, trash

SMTP Configuration

  • Credenziali salvate in email_settings con criptatura
  • Password decriptata con getDecryptedPassword() o getDecryptedSmtpPassword()
  • Display name validato con filter_var($fromName, FILTER_VALIDATE_EMAIL) - se è un'email usa "Glastree"

Email Signature

  • Campo signature in email_settings (longText, nullable)
  • WYSIWYG editor Quill.js via CDN
  • Metodo appendSignature() in EmailController aggiunge "---\n" + signature al body
  • Applicato sia in sendViaImap() che in storeSentMessage()

Key Decisions

Database

  • Location uses separate columns: luogo_indirizzo (varchar 500) and luogo_url_maps (text)
  • Map preview via Google Maps embed iframe using the address
  • Sortable columns: nome_evento, created_at, descrizione_evento, tipo_recorrenza, gruppi, responsabili
  • Multi-select uses Ctrl+click pattern with array input names

Email

  • SMTP defaults to Gmail if not configured
  • Email name sanitized to comply with RFC 2822
  • Sincronizzazione IMAP limitata a 100 messaggi per cartella
  • Signature appended with separator "---\n" before the signature text

UI

  • AdminLTE per tutte le viste
  • Sidebar con menu navigazione
  • Compose email senza sidebar sinistra

Relevant Files

Core Controllers

  • app/Http/Controllers/EventoController.php: eventi with extended sorting
  • app/Http/Controllers/EmailController.php: email system completo, signature auto-append
  • app/Http/Controllers/Admin/EmailSettingsController.php: email settings + test SMTP

Models

  • app/Models/EmailSetting.php: getDecryptedPassword(), getDecryptedSmtpPassword(), getSignature()
  • app/Models/Evento.php: fillable with location fields
  • app/Models/Gruppo.php: getResponsabiliIds(), getResponsabili()

Views

  • resources/views/admin/email-settings/index.blade.php: Email settings with signature section (Quill.js WYSIWYG)
  • resources/views/eventi/index.blade.php: sortable columns
  • resources/views/eventi/edit.blade.php: fixed nested form, added tipo_evento and note
  • resources/views/eventi/show.blade.php: removed duplicate "Dove", added "Luogo" section
  • resources/views/email/index.blade.php: mailbox view con AdminLTE
  • resources/views/email/compose.blade.php: compose senza sidebar sinistra
  • resources/views/layouts/adminlte.blade.php: sidebar menu Email con ordine corretto

Migrations

  • 2026_05_16_000003_add_signature_to_email_settings.php: Adds signature column to email_settings table

Commands Utili

# Clear all caches
php artisan optimize:clear

# Recompile views
php artisan view:cache

# Check routes
php artisan route:list --name=email

Known Issues / TODO

  1. SMTP authentication con Infomaniak - verificare credenziali corrette
  2. Invio email richiede password SMTP corretta nel form impostazioni

16 Maggio 2026 - URL Hardcoded Fix (Internet Access)

  • Problema: Da internet (accesso remoto) molti form e link puntavano a http://localhost invece del server remoto
  • Causa: Uso di url('/path') in tutte le view che generava URL basati su APP_URL=http://localhost
  • Soluzione: Sostituzione di tutte le occorrenze di url('/path') con path relativi /path
  • Files modificati:
    • individui/edit.blade.php: form action, link gruppi/documenti, fetch API calls
    • individui/show.blade.php: link gruppi, documenti, form, fetch API calls
    • gruppi/edit.blade.php: form action, link individui/documenti, fetch API calls
    • gruppi/show.blade.php: link individui, eventi
    • eventi/edit.blade.php: form action, link annulla, documenti
    • eventi/show.blade.php: breadcrumbs, link gruppi/responsabili, documenti
    • eventi/create.blade.php: form action, link annulla
    • eventi/index.blade.php: link create, reset, eventi, gruppi
    • documenti/index.blade.php: link targets, edit, delete, mass actions, fetch API
    • documenti/edit.blade.php: form action, download, back link
    • mailing-liste/edit.blade.php: fetch API calls
    • eventi/calendar.blade.php: eventSource URL
  • Layout fix: Aggiunto meta tag csrf-token in adminlte.blade.php head

16 Maggio 2026 - Individui Edit Form Fix

  • Problema: Form non salvava da accesso internet, il pulsante submit non funzionava
  • Causa: Il button type="submit" non triggherava il form submission
  • Soluzione:
    • Cambiato button da type="submit" a type="button" con onclick="document.getElementById('main-form').submit()"
    • Path relativi per tutti i form action
    • CSRF token in meta tag del layout

17 Maggio 2026 - Bulk Action Error Fix

  • Problema: Azioni massive sulle email (sposta nel cestino) mostravano popup "errore" generico
  • Causa: authorizeWrite() lancia eccezione 403 HTML invece di JSON per richieste AJAX
  • Soluzione: Aggiunto try-catch in bulkAction(), markRead() e toggleStar() per ritornare JSON con messaggio appropriato

17 Maggio 2026 - Nginx Proxy Manager Config

  • Problema: Email non funziona da internet (dietro NPM)
  • bootstrap/app.php: Aggiunto $middleware->trustProxies(at: '*')
  • Configurazione .env:
    APP_URL=
    APP_PROTOCOL=https
    FORCE_HTTPS=true
    TRUSTED_PROXIES=*
    
  • Middleware rimosso: ForceHttps non necessario - NPM gestisce terminazione HTTPS
  • Advanced Tab NPM: Abilitare X-Forwarded-Proto e headers proxy

17 Maggio 2026 - Form Annidati Fix

  • Problema: Contatti, gruppi e documenti in individui/edit non venivano salvati
  • Causa: Sezioni fuori dal main-form (chiusura prematura)
  • Soluzione: Spostata chiusura form dopo tutte le sezioni, aggiunto pulsante "Salva Tutte le Modifiche"
  • Contatti: Aggiunto pulsante salva nella riga nuova (icona💾)

17 Maggio 2026 - Bulk Action Email Fix

  • Problema: Azioni massive su email mostravano popup "errore"
  • Causa: authorizeWrite() lancia eccezione 403 HTML invece di JSON
  • Soluzione: try-catch in bulkAction(), markRead(), toggleStar()

(Last updated: 25 Maggio 2026 - Fix export CSV individui)

18 Maggio 2026 - AGENTS.md Update

  • Aggiunta regola "Verifica Salvataggio" nelle Regole Operative AI
  • Obbligo di verificare SEMPRE l'avvenuta riuscita dopo operazioni di modifica (store, update, delete, upload, sync)

25 Maggio 2026 - IndividuoController::elimina() Method

  • Problema: Errore 500 "Call to undefined method App\Http\Controllers\IndividuoController::elimina()" su richiesta POST /individui/{id}/elimina
  • Causa: Route definita in routes/web.php:58 ma metodo elimina() non implementato nel controller
  • Soluzione: Aggiunto metodo elimina() in IndividuoController che:
    • Verifica autorizzazione con authorizeDelete('individui')
    • Riceve parametri elimina_contatti e elimina_documenti dal form
    • Elimina opzionalmente i contatti collegati se richiesto
    • Elimina opzionalmente i documenti collegati (con rimozione file fisico) se richiesto
    • Elimina l'individuo e redirect alla lista con messaggio di successo
  • Files modificati:
    • app/Http/Controllers/IndividuoController.php: aggiunto metodo elimina() dopo destroy()

25 Maggio 2026 - Fix Eliminazione Singola e Massiva

  • Problema: L'eliminazione non veniva eseguita né per il singolo né per la mass action
  • Cause:
    1. $request->boolean() interpretava male i valori 'true'/'false' come stringhe
    2. deleteSelected() faceva submit multipli di form separati causando redirect concorrenti
  • Soluzione:
    1. Sostituito $request->boolean() con filter_var(..., FILTER_VALIDATE_BOOLEAN) per parsing corretto
    2. Aggiunto metodo massElimina() in IndividuoController per gestire eliminazione multipla con singolo form
    3. Aggiunta route POST /individui/mass-elimina in routes/web.php
    4. Rifattorizzata funzione JS deleteSelected() per usare singolo form con array ids[]
  • Files modificati:
    • app/Http/Controllers/IndividuoController.php: corretto elimina(), aggiunto massElimina()
    • routes/web.php: aggiunta route individui/mass-elimina
    • resources/views/individui/index.blade.php: rifattorizzata deleteSelected()

25 Maggio 2026 - Fix Export CSV Individui

  • Problema: "Esporta Tutti CSV" e "Esporta Selezionati CSV" non funzionavano
  • Cause:
    1. exportCSV() usava :visible (selettore jQuery) con querySelectorAll (JS nativo) che non lo supporta
    2. Export client-side esportava solo righe nel DOM (pagina corrente con pagination), non tutti i record
    3. Dati limitati a 5 colonne senza contatti email/telefono
  • Soluzione:
    1. Creato metodo exportCSV() server-side in IndividuoController con StreamedResponse
    2. Export completo con: Codice, Cognome, Nome, Data Nascita, Genere, Email, Telefono, Cellulare, Indirizzo, CAP, Città, Provincia, Note
    3. Email/Telefono/Cellulare recuperati dai contatti con preferenza per quelli primari
    4. Supporto per export tutti o solo selezionati tramite parametro ids[]
    5. Funzioni JS exportCSV() e exportSelectedCSV() ora puntano a /individui/export
  • Files modificati:
    • app/Http/Controllers/IndividuoController.php: aggiunto metodo exportCSV() con StreamedResponse
    • routes/web.php: aggiunta route GET /individui/export
    • resources/views/individui/index.blade.php: semplificate funzioni exportCSV() e exportSelectedCSV()

(Last updated: 25 Maggio 2026 - Report system, mass actions, gruppi deletion fix)

25 Maggio 2026 - Fix Eliminazione Gruppi Padre (Superadmin Only)

  • Problema: Eliminando un gruppo padre si otteneva pagina 404. Inoltre l'eliminazione di gruppi con figli era disponibile per tutti
  • Cause:
    1. Mancato detach delle tabelle pivot (gruppo_individuo, eventi_gruppi) prima della cancellazione
    2. Nessun controllo per limitare l'eliminazione di gruppi con sottogruppi al superadmin
  • Soluzione:
    1. Rifattorizzato destroy() in GruppoController: aggiunta verifica isSuperAdmin() per gruppi con figli
    2. Creato metodo destroyGruppo() helper che esegue detach pivot, cancella documenti fisici e poi cancella il gruppo
    3. Aggiornata vista tree-item.blade.php: pulsante elimina disabilitato per non-superadmin su gruppi con figli
  • Files modificati:
    • app/Http/Controllers/GruppoController.php: rifattorizzato destroy(), aggiunto destroyGruppo()
    • resources/views/gruppi/partials/tree-item.blade.php: pulsante elimina condizionato a superadmin per gruppi padre

25 Maggio 2026 - Mass Actions Eventi e Mailing List

  • Problema: Eventi e Mailing List non avevano funzionalità di eliminazione massiva
  • Soluzione:
    1. Aggiunti checkbox di selezione, pulsante "Elimina Selezionati" e modal di conferma in eventi/index.blade.php
    2. Aggiunti checkbox di selezione, pulsante "Elimina Selezionati" e modal di conferma in mailing-liste/index.blade.php
    3. Aggiunto metodo massElimina() in EventoController con detach di gruppi e responsabili
    4. Aggiunto metodo massElimina() in MailingListController con cancellazione contatti associati
    5. Aggiunte route POST /eventi/mass-elimina e POST /mailing-liste/mass-elimina
  • Files modificati:
    • app/Http/Controllers/EventoController.php: aggiunto massElimina()
    • app/Http/Controllers/MailingListController.php: aggiunto massElimina()
    • routes/web.php: aggiunte route mass-elimina per eventi e mailing-liste
    • resources/views/eventi/index.blade.php: aggiunta selezione massiva, modal conferma, JS
    • resources/views/mailing-liste/index.blade.php: aggiunta selezione massiva, modal conferma, JS

25 Maggio 2026 - Rimozione Menu Utilità Viste

  • Modifica: Rimosso dal sidebar menu la voce "Utilità Viste" (viste.index)
  • Nota: Le route e i controller per le viste rimangono funzionanti, solo il link sidebar è stato rimosso temporaneamente

25 Maggio 2026 - Sistema Report Completo

  • Funzionalità: Nuova pagina Report accessibile solo dal superadmin con:
    1. Panoramica database: statistiche rapide (individui, gruppi, eventi, documenti, mailing list, contatti)
    2. 12 Report predefiniti:
      • Individui per Genere
      • Individui per Fascia d'Età
      • Gerarchia Gruppi
      • Gruppi e Membri
      • Eventi del Mese
      • Documenti per Tipologia
      • Contatti per Tipo
      • Dettaglio Mailing List
      • Individui senza Contatti
      • Individui senza Gruppo
      • Eventi per Gruppo
      • Documenti Orfani
    3. Report personalizzati: creazione di report custom con selezione tipo dato, colonne, ordinamento e limite
    4. Export CSV: ogni report può essere esportato in CSV
  • Files creati:
    • app/Http/Controllers/ReportController.php: controller completo con 12 report + custom
    • app/Models/ReportCustom.php: modello per report personalizzati
    • database/migrations/2026_05_25_000001_create_report_custom_table.php: migration tabella report_custom
    • resources/views/report/index.blade.php: pagina principale report con card e form creazione
    • resources/views/report/result.blade.php: pagina visualizzazione risultati report
  • Routes aggiunte:
    • GET /report → report.index
    • GET /report/run → report.run
    • GET /report/export → report.export
    • GET /report/custom/{id} → report.run-custom
    • POST /report/custom → report.store-custom
    • DELETE /report/custom/{id} → report.destroy-custom
  • Sidebar aggiornata: link "Report" ora punta a route('report.index') con evidenziazione active

(Last updated: 25 Maggio 2026 - Fix sidebar @endif orfano, verifica completa sintassi)

25 Maggio 2026 - Fix Sidebar Errore Sintassi

  • Problema: Errore "syntax error, unexpected token 'endif'" nella dashboard
  • Causa: Dopo aver rimosso il blocco @if(Auth::user()->isSuperAdmin()) dalla sidebar per sostituirlo con @if(Auth::user()->canAccess('report')), erano rimasti un @endif orfano (linea 237) e un </li> extra (linea 239)
  • Soluzione:
    1. Rimosso @endif orfano
    2. Rimosso </li> extra
    3. Aggiunto nuovo @if(Auth::user()->isSuperAdmin()) per proteggere i menu Impostazioni e Admin
  • Verifica completa: Scansionati tutti i blade file del progetto - tutte le direttive @if/@endif, @foreach/@endforeach, @php/@endphp sono correttamente bilanciate. Compilazione viste OK.

25 Maggio 2026 - Accesso Report Basato su Permessi

  • Modifica: Il modulo 'report' è stato aggiunto a User::MODULES come nuovo modulo permissionabile
  • Funzionalità: Gli utenti con permesso canAccess('report') (livello lettura o superiore) possono accedere alla pagina Report, non più solo il superadmin
  • Files modificati:
    • app/Models/User.php: aggiunto 'report' a MODULES = ['individui', 'gruppi', 'eventi', 'documenti', 'mailing', 'viste', 'report']
    • app/Http/Controllers/ReportController.php: sostituiti tutti i check isSuperAdmin() con canAccess('report')
    • resources/views/layouts/adminlte.blade.php: sidebar mostra "Report" se canAccess('report') invece di isSuperAdmin()
  • Come abilitare un utente: Dal pannello Admin → Utenti, assegnare permesso di livello ≥ 1 (Lettura) per il modulo 'report'

25 Maggio 2026 - Viste Personalizzate per Colonne (Individui e Gruppi)

  • Funzionalità: Ogni utente può personalizzare quali colonne visualizzare nelle liste di Individui e Gruppi
  • Individui:
    • Colonne disponibili: Codice, Cognome, Nome, Email, Telefono
    • Il controller IndividuoController@index() ora passa $allColumns e $visibleColumns alla vista
    • Le colonne visibili sono determinate dalla VistaReport predefinita dell'utente
    • Modal "Colonne Visibili" mostra tutte le colonne con checkbox per toggle
    • Modal "Salva Vista" permette di salvare una vista con nome, colonne, e opzione predefinita
  • Gruppi:
    • Nuova vista tabella affiancata alla vista albero esistente
    • Toggle "Tabella/Albero" nella card header
    • Colonne disponibili: Nome, Descrizione, Diocesi, Livello, Gruppo Padre, Membri, Responsabili, Indirizzo, Città
    • Le colonne visibili sono determinate dalla VistaReport predefinita per tipo 'gruppi'
    • Salvataggio vista dedicato con route POST /gruppi/save-vista
    • Eliminazione vista con route DELETE /gruppi/vista/{id}
  • Model utilizzato: VistaReport (tabella viste_report) con campi: user_id, nome, tipo, colonne_visibili (JSON), is_default
  • Files modificati:
    • app/Http/Controllers/IndividuoController.php: index() passa $allColumns e $visibleColumns
    • app/Http/Controllers/GruppoController.php: index() rifattorizzato per vista tabella/albero, aggiunti saveVista() e deleteVista()
    • routes/web.php: aggiunte route gruppi/save-vista e gruppi/delete-vista
    • resources/views/individui/index.blade.php: colonne condizionali con @if(in_array(..., $visibleColumns))
    • resources/views/gruppi/index.blade.php: riscritta completamente con doppio mode (tabella/albero), modal salvataggio vista, toggle colonne

25 Maggio 2026 - Fix Vari Pagine (Individui, Eventi, Mailing, Documenti Upload)

  • Individui/Gruppi: Errore $tableColumns non definito risolto usando $allColumns
  • Eventi: Checkbox righe senza id impedivano il corretto funzionamento del label; aggiunto id="row-checkbox-{{ $evento->id }}"
  • Mailing List: Stesso problema checkbox, corretto con id univoci
  • Documenti upload: Funzione loadUploadTargets() chiamata ma non definita; aggiunta per popolare il dropdown target

25 Maggio 2026 - Fix Documento Avatar e Morph Map

  • Problema: Caricando un documento avatar associato a un individuo, errore "Class 'individuo' not found"
  • Causa: Il campo visibilita_target_type nel database conteneva nomi brevi ('individuo', 'gruppo') invece del namespace completo
  • Soluzione:
    1. Registrata Relation::morphMap() in AppServiceProvider@boot() per mappare nomi brevi a classi complete
    2. Aggiornato DocumentoController@store() per impostare correttamente visibilita_target_type in base alla visibilità
  • Files modificati:
    • app/Providers/AppServiceProvider.php: aggiunta morphMap per individuo, gruppo, evento, mailing, associazione, federazione
    • app/Http/Controllers/DocumentoController.php: logica esplicita per mappare visibilità → target_type

25 Maggio 2026 - Fix Pagina Gruppi (Tabella Pivot Inesistente)

  • Problema: Pagina gruppi falliva con "Table 'glastree.gruppo_responsabili' doesn't exist"
  • Causa: Il modello Gruppo aveva una relazione responsabili() che puntava a tabella pivot inesistente (la migration 2026_05_12_000003 aveva migrato a JSON responsabile_ids)
  • Soluzione:
    1. Rimossa relazione responsabili() da Gruppo.php
    2. Rimossa eager loading responsabili da GruppoController@index()
    3. Mantenuti metodi helper getResponsabiliIds() e getResponsabili() che leggono dal campo JSON
    4. Corretti riferimenti in gruppi/show.blade.php e individui/show.blade.php per usare getResponsabili()
  • Files modificati:
    • app/Models/Gruppo.php: rimossa relazione responsabili(), mantenuti helper
    • app/Http/Controllers/GruppoController.php: rimossa eager loading responsabili
    • resources/views/gruppi/show.blade.php: corretto $child->responsabile$child->getResponsabili()->first()
    • resources/views/individui/show.blade.php: corretto $gruppo->responsabile$gruppo->getResponsabili()->first()

25 Maggio 2026 - Fix Caricamento Documenti in Pagina Gruppi

  • Funzionalità: Aggiunto modale "Carica Documento" nella pagina gruppi/show per upload diretto
  • Logica Responsabili: Solo i membri del gruppo possono essere selezionati come responsabili
    • In create.blade.php: il dropdown responsabili si aggiorna dinamicamente quando si aggiungono/rimuovono membri
    • Funzione JS updateResponsabiliFromMembri() sincronizza il select responsabili con i membri aggiunti
  • Files modificati:
    • resources/views/gruppi/show.blade.php: aggiunto modale upload documento, alert success/error
    • resources/views/gruppi/create.blade.php: logica JS per vincolare responsabili ai soli membri

(Last updated: 25 Maggio 2026 - Fix report eventi_calendario, colonna data)

25 Maggio 2026 - Fix Report Eventi Calendario

  • Problema: Report "Eventi del Mese" falliva con "Unknown column 'data_inizio' in 'WHERE'"
  • Causa: Il report usava data_inizio che non esiste nella tabella eventi. La colonna corretta è data_specifica
  • Soluzione: Sostituito data_inizio con data_specifica in reportEventiCalendario() e reportEventiPerGruppo()
  • Files modificati:
    • app/Http/Controllers/ReportController.php: righe 389-397 e 532, corretto nome colonna

(Last updated: 25 Maggio 2026 - Fix report eventi_calendario, colonna data)

25 Maggio 2026 - Fix Gruppi Table Hierarchy

  • Problema: La visualizzazione a tabella dei gruppi non mostrava correttamente la gerarchia padre-figlio
  • Soluzione:
    • Aggiunto metodo sortGruppiHierarchically() in GruppoController per ordinare i gruppi in modo gerarchico
    • La tabella ora mostra prima i gruppi root, poi i loro figli in ordine annidato
    • Aggiunta eager loading avatar per supportare il futuro avatar dei gruppi
  • Files modificati:
    • app/Http/Controllers/GruppoController.php: aggiunto sortGruppiHierarchically(), addChildrenRecursive(), aggiunto 'avatar' a eager loading

25 Maggio 2026 - Group Avatar Support

  • Funzionalità: I gruppi ora possono avere un avatar/logo come gli individui
  • Implementazione:
    • Aggiunto metodo avatar() in Gruppo.php (relazione HasOne a Documento con tipologia 'avatar')
    • Aggiunto accessor getAvatarUrlAttribute() per ottenere l'URL dell'avatar
    • Eager loading avatar aggiunto in GruppoController@index()
    • View gruppi/index.blade.php aggiornata per mostrare l'avatar nella tabella
    • View gruppi/show.blade.php aggiornata per mostrare l'avatar del gruppo
    • View gruppi/create.blade.php e edit.blade.php aggiornate per permettere upload avatar
  • Files modificati:
    • app/Models/Gruppo.php: aggiunto avatar(), getAvatarUrlAttribute()
    • app/Http/Controllers/GruppoController.php: aggiunto eager loading avatar
    • resources/views/gruppi/index.blade.php: colonna avatar nella tabella
    • resources/views/gruppi/show.blade.php: avatar nella header card
    • resources/views/gruppi/create.blade.php e edit.blade.php: upload avatar

26 Maggio 2026 - Event Types System (Tipologie Eventi)

  • Nuova tabella: tipologie_eventi con migration + seed dati default (catechesi, liturgia, animazione, formazione, incontro, riunione, festa, altro)
  • Nuovo modello: App\Models\TipologiaEvento — identico pattern a TipologiaDocumento e Ruolo:
    • $fillable: nome, descrizione, ordine, attiva
    • Metodi: eventi() (hasMany), attive(), opzioni()
    • FK via nome (string) → eventi.tipo_evento (stesso pattern Documento.tipologia → TipologiaDocumento.nome)
  • Admin CRUD: 4 nuovi metodi in ImpostazioniController: tipologieEventiStore(), tipologieEventiUpdate(), tipologieEventiDestroy(), tipologieEventiReorder()
  • Routes (5 nuove): /impostazioni/tipologie-eventi/*
  • Impostazioni view: Nuovo tab #tipologie-eventi con tabella sortabile, modali add/edit, stessi pattern esistenti
  • Sidebar: Nuovo link "Tipologie Eventi" sotto Impostazioni (solo superadmin)
  • Evento model: Aggiunta relazione tipologiaEvento() (BelongsTo via 'nome')
  • EventoController: Validazione cambiata da nullable|string|max:100 a nullable|exists:tipologie_eventi,nome in store() e update(); create/edit passano $tipologieEventi alla view
  • Views eventi:
    • create.blade.php: Dropdown "Tipo Evento" dopo Descrizione Breve
    • edit.blade.php: Text libero → dropdown; fallback per vecchi valori non presenti
    • show.blade.php: Badge "Tipologia" nella sezione Data e Orario; colonna rinominata "Ricorrenza"
    • index.blade.php: Nuova colonna sortabile "Tipologia" con badge; colonna "Tipo" → "Ricorrenza"; colspan 8→9
  • Files creati:
    • database/migrations/2026_05_26_000001_create_tipologie_eventi_table.php
    • app/Models/TipologiaEvento.php
  • Files modificati:
    • app/Http/Controllers/ImpostazioniController.php
    • app/Http/Controllers/EventoController.php
    • app/Models/Evento.php
    • routes/web.php
    • resources/views/impostazioni/index.blade.php
    • resources/views/layouts/adminlte.blade.php
    • resources/views/eventi/create.blade.php
    • resources/views/eventi/edit.blade.php
    • resources/views/eventi/show.blade.php
    • resources/views/eventi/index.blade.php

(Last updated: 26 Maggio 2026 - Event Types system)