296 lines
12 KiB
PHP
296 lines
12 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
use App\Models\Evento;
|
|
use App\Models\Gruppo;
|
|
use App\Models\Individuo;
|
|
use Illuminate\Http\Request;
|
|
|
|
class EventoController extends Controller
|
|
{
|
|
public function index(Request $request)
|
|
{
|
|
$this->authorizeRead('eventi');
|
|
$query = Evento::with(['gruppi', 'responsabili']);
|
|
|
|
if ($request->filled('search')) {
|
|
$query->where('nome_evento', 'like', '%' . $request->search . '%');
|
|
}
|
|
|
|
if ($request->filled('gruppo_id')) {
|
|
$query->whereHas('gruppi', fn($q) => $q->where('gruppi.id', $request->gruppo_id));
|
|
}
|
|
|
|
if ($request->filled('tipo')) {
|
|
$query->where('tipo_recorrenza', $request->tipo);
|
|
}
|
|
|
|
$sortBy = $request->get('sort', 'created_at');
|
|
$sortDir = $request->get('direction', 'desc');
|
|
$allowedSorts = ['nome_evento', 'descrizione_evento', 'tipo_recorrenza', 'data_specifica', 'created_at'];
|
|
|
|
if ($sortBy === 'gruppi') {
|
|
$query->withCount('gruppi')->orderBy('gruppi_count', $sortDir === 'asc' ? 'asc' : 'desc');
|
|
} elseif ($sortBy === 'responsabili') {
|
|
$query->withCount('responsabili')->orderBy('responsabili_count', $sortDir === 'asc' ? 'asc' : 'desc');
|
|
} elseif (in_array($sortBy, $allowedSorts)) {
|
|
$query->orderBy($sortBy, $sortDir === 'asc' ? 'asc' : 'desc');
|
|
} else {
|
|
$query->orderByDesc('created_at');
|
|
}
|
|
|
|
$eventi = $query->paginate(20);
|
|
$gruppi = Gruppo::orderBy('nome')->get();
|
|
|
|
return view('eventi.index', compact('eventi', 'gruppi'));
|
|
}
|
|
|
|
public function create(Request $request)
|
|
{
|
|
$this->authorizeWrite('eventi');
|
|
$gruppi = Gruppo::orderBy('nome')->get();
|
|
$individui = Individuo::orderBy('cognome')->orderBy('nome')->get();
|
|
$selectedGruppo = $request->query('gruppo_id') ? Gruppo::find($request->query('gruppo_id')) : null;
|
|
|
|
return view('eventi.create', compact('gruppi', 'individui', 'selectedGruppo'));
|
|
}
|
|
|
|
public function store(Request $request)
|
|
{
|
|
$this->authorizeWrite('eventi');
|
|
$data = $request->validate([
|
|
'nome_evento' => 'required|string|max:255',
|
|
'descrizione_evento' => 'nullable|string|max:255',
|
|
'tipo_evento' => 'nullable|string|max:100',
|
|
'tipo_recorrenza' => 'nullable|in:singolo,settimanale,mensile,annuale,altro',
|
|
'giorno_settimana' => 'nullable|integer|min:0|max:6',
|
|
'giorno_mese' => 'nullable|integer|min:1|max:31',
|
|
'occorrenza_mese' => 'nullable|string|max:10',
|
|
'mesi_recorrenza' => 'nullable|string',
|
|
'mese_annuale' => 'nullable|integer|min:1|max:12',
|
|
'ora_inizio' => 'nullable|date_format:H:i',
|
|
'data_specifica' => 'nullable|date',
|
|
'durata_minuti' => 'nullable|integer|min:1',
|
|
'descrizione' => 'nullable|string',
|
|
'note' => 'nullable|string',
|
|
'is_incontro_gruppo' => 'nullable|boolean',
|
|
'gruppi' => 'nullable|array',
|
|
'gruppi.*' => 'exists:gruppi,id',
|
|
'responsabili' => 'nullable|array',
|
|
'responsabili.*' => 'exists:individui,id',
|
|
'luogo_indirizzo' => 'nullable|string|max:500',
|
|
'luogo_url_maps' => 'nullable|string',
|
|
]);
|
|
|
|
$evento = Evento::create([
|
|
'nome_evento' => $data['nome_evento'],
|
|
'descrizione_evento' => $data['descrizione_evento'] ?? null,
|
|
'tipo_evento' => $data['tipo_evento'] ?? null,
|
|
'tipo_recorrenza' => $data['tipo_recorrenza'] ?? 'singolo',
|
|
'giorno_settimana' => $data['giorno_settimana'] ?? null,
|
|
'giorno_mese' => $data['giorno_mese'] ?? null,
|
|
'occorrenza_mese' => $data['occorrenza_mese'] ?? null,
|
|
'mesi_recorrenza' => is_array($request->mesi_recorrenza) ? implode(',', $request->mesi_recorrenza) : ($data['mesi_recorrenza'] ?? null),
|
|
'mese_annuale' => $data['mese_annuale'] ?? null,
|
|
'ora_inizio' => $data['ora_inizio'] ?? null,
|
|
'data_specifica' => $data['data_specifica'] ?? null,
|
|
'durata_minuti' => $data['durata_minuti'] ?? null,
|
|
'descrizione' => $data['descrizione'] ?? null,
|
|
'note' => $data['note'] ?? null,
|
|
'is_incontro_gruppo' => $request->boolean('is_incontro_gruppo'),
|
|
'luogo_indirizzo' => $data['luogo_indirizzo'] ?? null,
|
|
'luogo_url_maps' => $data['luogo_url_maps'] ?? null,
|
|
]);
|
|
|
|
if (!empty($data['gruppi'])) {
|
|
$evento->gruppi()->attach($data['gruppi']);
|
|
}
|
|
|
|
if (!empty($data['responsabili'])) {
|
|
$evento->responsabili()->attach($data['responsabili']);
|
|
}
|
|
|
|
return redirect('/eventi/' . $evento->id)->with('success', 'Evento creato con successo.');
|
|
}
|
|
|
|
public function show($evento)
|
|
{
|
|
$this->authorizeRead('eventi');
|
|
$evento = Evento::with(['gruppi', 'responsabili.contatti', 'documenti'])->findOrFail($evento);
|
|
return view('eventi.show', compact('evento'));
|
|
}
|
|
|
|
public function edit($evento)
|
|
{
|
|
$this->authorizeWrite('eventi');
|
|
$evento = Evento::with(['gruppi', 'responsabili', 'documenti'])->findOrFail($evento);
|
|
$gruppi = Gruppo::orderBy('nome')->get();
|
|
$individui = Individuo::orderBy('cognome')->orderBy('nome')->get();
|
|
|
|
return view('eventi.edit', compact('evento', 'gruppi', 'individui'));
|
|
}
|
|
|
|
public function update(Request $request, $evento)
|
|
{
|
|
$this->authorizeWrite('eventi');
|
|
$evento = Evento::findOrFail($evento);
|
|
|
|
$data = $request->validate([
|
|
'nome_evento' => 'required|string|max:255',
|
|
'descrizione_evento' => 'nullable|string|max:255',
|
|
'tipo_evento' => 'nullable|string|max:100',
|
|
'tipo_recorrenza' => 'nullable|in:singolo,settimanale,mensile,annuale,altro',
|
|
'giorno_settimana' => 'nullable|integer|min:0|max:6',
|
|
'giorno_mese' => 'nullable|integer|min:1|max:31',
|
|
'occorrenza_mese' => 'nullable|string|max:10',
|
|
'mesi_recorrenza' => 'nullable|string',
|
|
'mese_annuale' => 'nullable|integer|min:1|max:12',
|
|
'ora_inizio' => 'nullable|date_format:H:i',
|
|
'data_specifica' => 'nullable|date',
|
|
'durata_minuti' => 'nullable|integer|min:1',
|
|
'descrizione' => 'nullable|string',
|
|
'note' => 'nullable|string',
|
|
'is_incontro_gruppo' => 'nullable|boolean',
|
|
'gruppi' => 'nullable|array',
|
|
'gruppi.*' => 'exists:gruppi,id',
|
|
'responsabili' => 'nullable|array',
|
|
'responsabili.*' => 'exists:individui,id',
|
|
'luogo_indirizzo' => 'nullable|string|max:500',
|
|
'luogo_url_maps' => 'nullable|string',
|
|
]);
|
|
|
|
$evento->update([
|
|
'nome_evento' => $data['nome_evento'],
|
|
'descrizione_evento' => $data['descrizione_evento'] ?? null,
|
|
'tipo_evento' => $data['tipo_evento'] ?? null,
|
|
'tipo_recorrenza' => $data['tipo_recorrenza'] ?? 'singolo',
|
|
'giorno_settimana' => $data['giorno_settimana'] ?? null,
|
|
'giorno_mese' => $data['giorno_mese'] ?? null,
|
|
'occorrenza_mese' => $data['occorrenza_mese'] ?? null,
|
|
'mesi_recorrenza' => is_array($request->mesi_recorrenza) ? implode(',', $request->mesi_recorrenza) : ($data['mesi_recorrenza'] ?? null),
|
|
'mese_annuale' => $data['mese_annuale'] ?? null,
|
|
'ora_inizio' => $data['ora_inizio'] ?? null,
|
|
'data_specifica' => $data['data_specifica'] ?? null,
|
|
'durata_minuti' => $data['durata_minuti'] ?? null,
|
|
'descrizione' => $data['descrizione'] ?? null,
|
|
'note' => $data['note'] ?? null,
|
|
'is_incontro_gruppo' => $request->boolean('is_incontro_gruppo'),
|
|
'luogo_indirizzo' => $data['luogo_indirizzo'] ?? null,
|
|
'luogo_url_maps' => $data['luogo_url_maps'] ?? null,
|
|
]);
|
|
|
|
$evento->gruppi()->sync($data['gruppi'] ?? []);
|
|
$evento->responsabili()->sync($data['responsabili'] ?? []);
|
|
|
|
return redirect('/eventi/' . $evento->id)->with('success', 'Evento aggiornato.');
|
|
}
|
|
|
|
public function destroy($evento)
|
|
{
|
|
$this->authorizeDelete('eventi');
|
|
$evento = Evento::findOrFail($evento);
|
|
$evento->delete();
|
|
return redirect('/eventi')->with('success', 'Evento eliminato.');
|
|
}
|
|
|
|
public function massElimina(Request $request)
|
|
{
|
|
$this->authorizeDelete('eventi');
|
|
|
|
$ids = $request->input('ids', []);
|
|
if (!is_array($ids) || empty($ids)) {
|
|
return redirect('/eventi')->with('error', 'Nessun evento selezionato.');
|
|
}
|
|
|
|
$eventi = Evento::whereIn('id', $ids)->get();
|
|
|
|
foreach ($eventi as $evento) {
|
|
$evento->gruppi()->detach();
|
|
$evento->responsabili()->detach();
|
|
$evento->delete();
|
|
}
|
|
|
|
return redirect('/eventi')->with('success', count($eventi) . ' eventi eliminati con successo.');
|
|
}
|
|
|
|
public function calendar()
|
|
{
|
|
$this->authorizeRead('eventi');
|
|
return view('eventi.calendar');
|
|
}
|
|
|
|
public function calendarEvents(Request $request)
|
|
{
|
|
$this->authorizeRead('eventi');
|
|
|
|
$start = $request->input('start');
|
|
$end = $request->input('end');
|
|
|
|
$baseUrl = $request->getSchemeAndHttpHost();
|
|
$query = Evento::with(['gruppi', 'responsabili']);
|
|
|
|
$eventi = $query->get();
|
|
|
|
$events = [];
|
|
|
|
foreach ($eventi as $evento) {
|
|
if ($evento->tipo_recorrenza === 'singolo' || $evento->tipo_recorrenza === null) {
|
|
if ($evento->data_specifica) {
|
|
$events[] = [
|
|
'id' => $evento->id,
|
|
'title' => $evento->nome_evento,
|
|
'start' => $evento->data_specifica->format('Y-m-d') . ($evento->ora_inizio ? 'T' . $evento->ora_inizio->format('H:i') : ''),
|
|
'url' => $baseUrl . '/eventi/' . $evento->id,
|
|
'backgroundColor' => $this->getEventoColor($evento),
|
|
'borderColor' => $this->getEventoColor($evento),
|
|
];
|
|
}
|
|
} elseif ($evento->tipo_recorrenza === 'settimanale' && $evento->giorno_settimana !== null) {
|
|
$startDate = \Carbon\Carbon::parse($start);
|
|
$endDate = \Carbon\Carbon::parse($end);
|
|
|
|
$current = $startDate->copy();
|
|
while ($current <= $endDate) {
|
|
$nextOccurrence = $current->copy()->next($evento->giorno_settimana);
|
|
if ($nextOccurrence >= $startDate && $nextOccurrence <= $endDate) {
|
|
$events[] = [
|
|
'id' => $evento->id . '_' . $nextOccurrence->format('Ymd'),
|
|
'title' => $evento->nome_evento,
|
|
'start' => $nextOccurrence->format('Y-m-d') . ($evento->ora_inizio ? 'T' . $evento->ora_inizio->format('H:i') : ''),
|
|
'url' => $baseUrl . '/eventi/' . $evento->id,
|
|
'backgroundColor' => $this->getEventoColor($evento),
|
|
'borderColor' => $this->getEventoColor($evento),
|
|
];
|
|
}
|
|
$current->addWeek();
|
|
}
|
|
}
|
|
}
|
|
|
|
return response()->json($events);
|
|
}
|
|
|
|
private function getEventoColor(Evento $evento): string
|
|
{
|
|
$colors = [
|
|
'primary' => '#007bff',
|
|
'secondary' => '#6c757d',
|
|
'success' => '#28a745',
|
|
'danger' => '#dc3545',
|
|
'warning' => '#ffc107',
|
|
'info' => '#17a2b8',
|
|
'dark' => '#343a40',
|
|
];
|
|
|
|
if ($evento->isIncroGruppo()) {
|
|
return $colors['info'];
|
|
}
|
|
|
|
if ($evento->isRicorrente()) {
|
|
return $colors['success'];
|
|
}
|
|
|
|
return $colors['primary'];
|
|
}
|
|
} |