fino a eventi e report prima del tipo di eventi
This commit is contained in:
@@ -192,11 +192,19 @@ class DocumentoController extends Controller
|
||||
$fullPath = Storage::disk('local')->path($documento->file_path);
|
||||
$mimeType = $documento->mime_type;
|
||||
|
||||
if (str_starts_with($mimeType, 'image/')) {
|
||||
$previewableMimeTypes = [
|
||||
'image/jpeg', 'image/png', 'image/gif', 'image/webp', 'image/svg+xml',
|
||||
'application/pdf',
|
||||
'text/plain', 'text/html', 'text/csv',
|
||||
];
|
||||
|
||||
if (in_array($mimeType, $previewableMimeTypes)) {
|
||||
return response()->file($fullPath, ['Content-Type' => $mimeType]);
|
||||
}
|
||||
|
||||
return response()->file($fullPath, ['Content-Type' => $mimeType]);
|
||||
return response()->view('documenti.preview-fallback', [
|
||||
'documento' => $documento,
|
||||
])->header('X-Preview-Fallback', 'true');
|
||||
}
|
||||
|
||||
public function destroy($documento)
|
||||
|
||||
@@ -342,8 +342,11 @@ class EmailController extends Controller
|
||||
|
||||
public function syncEmails()
|
||||
{
|
||||
\Illuminate\Support\Facades\Log::info('Email sync started');
|
||||
|
||||
$settings = EmailSetting::getActive();
|
||||
if (!$settings) {
|
||||
\Illuminate\Support\Facades\Log::warning('Email sync aborted: no active email configuration');
|
||||
throw new \Exception('Nessuna configurazione email attiva');
|
||||
}
|
||||
|
||||
@@ -351,6 +354,8 @@ class EmailController extends Controller
|
||||
|
||||
$mailbox = $this->connectImap($settings);
|
||||
|
||||
\Illuminate\Support\Facades\Log::info('IMAP connection established', ['host' => $settings->imap_host]);
|
||||
|
||||
$folderMappings = [
|
||||
'INBOX' => 'inbox',
|
||||
'Sent' => 'sent',
|
||||
@@ -362,11 +367,19 @@ class EmailController extends Controller
|
||||
'[Gmail]/Trash' => 'trash',
|
||||
];
|
||||
|
||||
$totalProcessed = 0;
|
||||
$totalNew = 0;
|
||||
|
||||
foreach (array_keys($folderMappings) as $imapFolderName) {
|
||||
try {
|
||||
$folder = $mailbox->folders()->find($imapFolderName);
|
||||
if (!$folder) continue;
|
||||
if (!$folder) {
|
||||
\Illuminate\Support\Facades\Log::debug('IMAP folder not found', ['folder' => $imapFolderName]);
|
||||
continue;
|
||||
}
|
||||
|
||||
\Illuminate\Support\Facades\Log::info('Processing IMAP folder', ['folder' => $imapFolderName]);
|
||||
|
||||
$messages = $folder->messages()
|
||||
->withHeaders()
|
||||
->withBody()
|
||||
@@ -374,14 +387,31 @@ class EmailController extends Controller
|
||||
->limit(100)
|
||||
->get();
|
||||
|
||||
\Illuminate\Support\Facades\Log::info('Messages fetched from folder', ['folder' => $imapFolderName, 'count' => count($messages)]);
|
||||
|
||||
foreach ($messages as $imapMessage) {
|
||||
$totalProcessed++;
|
||||
$messageId = $imapMessage->messageId() ?? uniqid('msg_');
|
||||
$existing = EmailMessage::where('message_id', $messageId)->first();
|
||||
|
||||
if ($existing) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->processImapMessage($imapMessage, $imapFolderName);
|
||||
$totalNew++;
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
\Illuminate\Support\Facades\Log::error('Error processing IMAP folder', ['folder' => $imapFolderName, 'error' => $e->getMessage()]);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
\Illuminate\Support\Facades\Log::info('Email sync completed', [
|
||||
'processed' => $totalProcessed,
|
||||
'new' => $totalNew,
|
||||
]);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -67,14 +67,15 @@ class EventoController extends Controller
|
||||
'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',
|
||||
'mesi_recorrenza' => 'nullable|array',
|
||||
'mesi_recorrenza.*' => 'integer|min:1|max:12',
|
||||
'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',
|
||||
'is_incontro_gruppo' => 'nullable',
|
||||
'gruppi' => 'nullable|array',
|
||||
'gruppi.*' => 'exists:gruppi,id',
|
||||
'responsabili' => 'nullable|array',
|
||||
@@ -144,14 +145,15 @@ class EventoController extends Controller
|
||||
'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',
|
||||
'mesi_recorrenza' => 'nullable|array',
|
||||
'mesi_recorrenza.*' => 'integer|min:1|max:12',
|
||||
'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',
|
||||
'is_incontro_gruppo' => 'nullable',
|
||||
'gruppi' => 'nullable|array',
|
||||
'gruppi.*' => 'exists:gruppi,id',
|
||||
'responsabili' => 'nullable|array',
|
||||
@@ -237,40 +239,168 @@ class EventoController extends Controller
|
||||
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),
|
||||
];
|
||||
$events[] = $this->buildCalendarEvent($evento, $evento->data_specifica);
|
||||
}
|
||||
} 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();
|
||||
}
|
||||
$events = array_merge($events, $this->generateSettimanaleEvents($evento, $start, $end, $baseUrl));
|
||||
} elseif ($evento->tipo_recorrenza === 'mensile' && $evento->occorrenza_mese) {
|
||||
$events = array_merge($events, $this->generateMensileEvents($evento, $start, $end, $baseUrl));
|
||||
} elseif ($evento->tipo_recorrenza === 'annuale' && $evento->mese_annuale) {
|
||||
$events = array_merge($events, $this->generateAnnualeEvents($evento, $start, $end, $baseUrl));
|
||||
} elseif ($evento->tipo_recorrenza === 'altro' && $evento->giorno_settimana !== null) {
|
||||
$events = array_merge($events, $this->generateAltroEvents($evento, $start, $end, $baseUrl));
|
||||
}
|
||||
}
|
||||
|
||||
return response()->json($events);
|
||||
}
|
||||
|
||||
protected function buildCalendarEvent(Evento $evento, $date, ?string $baseUrl = null): array
|
||||
{
|
||||
if ($date instanceof \Carbon\Carbon) {
|
||||
$carbon = $date;
|
||||
} elseif (is_string($date)) {
|
||||
$carbon = \Carbon\Carbon::parse($date);
|
||||
} else {
|
||||
$carbon = $date;
|
||||
}
|
||||
|
||||
$baseUrl = $baseUrl ?? request()->getSchemeAndHttpHost();
|
||||
|
||||
return [
|
||||
'id' => $evento->id . '_' . $carbon->format('Ymd'),
|
||||
'title' => $evento->nome_evento,
|
||||
'start' => $carbon->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),
|
||||
];
|
||||
}
|
||||
|
||||
protected function generateSettimanaleEvents(Evento $evento, $start, $end, $baseUrl): array
|
||||
{
|
||||
$startDate = \Carbon\Carbon::parse($start);
|
||||
$endDate = \Carbon\Carbon::parse($end);
|
||||
$events = [];
|
||||
|
||||
$current = $startDate->copy()->startOfWeek();
|
||||
$targetDay = $evento->giorno_settimana;
|
||||
|
||||
while ($current <= $endDate) {
|
||||
$dayOfWeek = (int) $current->format('w');
|
||||
if ($dayOfWeek === $targetDay && $current >= $startDate && $current <= $endDate) {
|
||||
$events[] = $this->buildCalendarEvent($evento, $current->copy(), $baseUrl);
|
||||
}
|
||||
$current->addDay();
|
||||
}
|
||||
|
||||
return $events;
|
||||
}
|
||||
|
||||
protected function generateMensileEvents(Evento $evento, $start, $end, $baseUrl): array
|
||||
{
|
||||
$startDate = \Carbon\Carbon::parse($start);
|
||||
$endDate = \Carbon\Carbon::parse($end);
|
||||
$events = [];
|
||||
|
||||
$parts = explode(',', $evento->occorrenza_mese);
|
||||
if (count($parts) !== 2) {
|
||||
return $events;
|
||||
}
|
||||
|
||||
$occorrenza = (int) $parts[0];
|
||||
$giornoSettimana = (int) $parts[1];
|
||||
|
||||
$mesiSelezionati = [];
|
||||
if ($evento->mesi_recorrenza) {
|
||||
$mesiSelezionati = array_map('intval', explode(',', $evento->mesi_recorrenza));
|
||||
}
|
||||
|
||||
$currentMonth = $startDate->copy()->startOfMonth();
|
||||
$endMonth = $endDate->copy()->startOfMonth();
|
||||
|
||||
while ($currentMonth <= $endMonth) {
|
||||
$monthNumber = (int) $currentMonth->format('n');
|
||||
|
||||
if (empty($mesiSelezionati) || in_array($monthNumber, $mesiSelezionati)) {
|
||||
$occurrenceDate = $this->findNthWeekdayOfMonth($currentMonth, $occorrenza, $giornoSettimana);
|
||||
|
||||
if ($occurrenceDate && $occurrenceDate >= $startDate && $occurrenceDate <= $endDate) {
|
||||
$events[] = $this->buildCalendarEvent($evento, $occurrenceDate, $baseUrl);
|
||||
}
|
||||
}
|
||||
|
||||
$currentMonth->addMonth();
|
||||
}
|
||||
|
||||
return $events;
|
||||
}
|
||||
|
||||
protected function findNthWeekdayOfMonth(\Carbon\Carbon $month, int $occurrence, int $targetDayOfWeek): ?\Carbon\Carbon
|
||||
{
|
||||
$firstOfMonth = $month->copy()->startOfMonth();
|
||||
$firstDayOfWeek = (int) $firstOfMonth->format('w');
|
||||
|
||||
$daysUntilTarget = ($targetDayOfWeek - $firstDayOfWeek + 7) % 7;
|
||||
$firstOccurrence = $firstOfMonth->copy()->addDays($daysUntilTarget);
|
||||
|
||||
$targetDate = $firstOccurrence->copy()->addWeeks($occurrence - 1);
|
||||
|
||||
if ((int) $targetDate->format('n') !== (int) $month->format('n')) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $targetDate;
|
||||
}
|
||||
|
||||
protected function generateAnnualeEvents(Evento $evento, $start, $end, $baseUrl): array
|
||||
{
|
||||
$startDate = \Carbon\Carbon::parse($start);
|
||||
$endDate = \Carbon\Carbon::parse($end);
|
||||
$events = [];
|
||||
|
||||
$year = $startDate->year;
|
||||
$endYear = $endDate->year;
|
||||
|
||||
while ($year <= $endYear + 1) {
|
||||
$day = $evento->giorno_mese ?? 1;
|
||||
$eventDate = \Carbon\Carbon::create($year, $evento->mese_annuale, $day);
|
||||
|
||||
$daysInMonth = $eventDate->daysInMonth;
|
||||
if ($evento->giorno_mese && $evento->giorno_mese > $daysInMonth) {
|
||||
$eventDate = $eventDate->endOfMonth();
|
||||
}
|
||||
|
||||
if ($eventDate >= $startDate && $eventDate <= $endDate) {
|
||||
$events[] = $this->buildCalendarEvent($evento, $eventDate, $baseUrl);
|
||||
}
|
||||
|
||||
$year++;
|
||||
}
|
||||
|
||||
return $events;
|
||||
}
|
||||
|
||||
protected function generateAltroEvents(Evento $evento, $start, $end, $baseUrl): array
|
||||
{
|
||||
$startDate = \Carbon\Carbon::parse($start);
|
||||
$endDate = \Carbon\Carbon::parse($end);
|
||||
$events = [];
|
||||
|
||||
$current = $startDate->copy()->startOfWeek();
|
||||
$targetDay = $evento->giorno_settimana;
|
||||
|
||||
while ($current <= $endDate) {
|
||||
$dayOfWeek = (int) $current->format('w');
|
||||
if ($dayOfWeek === $targetDay && $current >= $startDate && $current <= $endDate) {
|
||||
$events[] = $this->buildCalendarEvent($evento, $current->copy(), $baseUrl);
|
||||
}
|
||||
$current->addDay();
|
||||
}
|
||||
|
||||
return $events;
|
||||
}
|
||||
|
||||
private function getEventoColor(Evento $evento): string
|
||||
{
|
||||
$colors = [
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\Documento;
|
||||
use App\Models\Gruppo;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
class GruppoAvatarController extends Controller
|
||||
{
|
||||
public function store(Request $request, Gruppo $gruppo)
|
||||
{
|
||||
$this->authorizeWrite('gruppi');
|
||||
|
||||
$request->validate([
|
||||
'avatar' => 'required|image|mimes:jpeg,png,gif,webp|max:2048',
|
||||
]);
|
||||
|
||||
$existing = $gruppo->avatar;
|
||||
if ($existing) {
|
||||
if ($existing->file_path && Storage::disk('local')->exists($existing->file_path)) {
|
||||
Storage::disk('local')->delete($existing->file_path);
|
||||
}
|
||||
$existing->delete();
|
||||
}
|
||||
|
||||
$file = $request->file('avatar');
|
||||
$path = $file->store('avatars/gruppi', 'local');
|
||||
|
||||
$documento = Documento::create([
|
||||
'user_id' => auth()->id(),
|
||||
'nome_file' => $file->getClientOriginalName(),
|
||||
'file_path' => $path,
|
||||
'tipologia' => 'avatar',
|
||||
'visibilita' => 'gruppo',
|
||||
'visibilita_target_id' => $gruppo->id,
|
||||
'visibilita_target_type' => Gruppo::class,
|
||||
'mime_type' => $file->getMimeType(),
|
||||
'dimensione' => $file->getSize(),
|
||||
]);
|
||||
|
||||
$gruppo->avatar()->save($documento);
|
||||
|
||||
return response()->json(['success' => true, 'avatar_url' => $documento->file_path]);
|
||||
}
|
||||
|
||||
public function show(Gruppo $gruppo)
|
||||
{
|
||||
$this->authorizeRead('gruppi');
|
||||
|
||||
$avatar = $gruppo->avatar;
|
||||
if (!$avatar || !$avatar->file_path || !Storage::disk('local')->exists($avatar->file_path)) {
|
||||
abort(404);
|
||||
}
|
||||
|
||||
$fullPath = Storage::disk('local')->path($avatar->file_path);
|
||||
return response()->file($fullPath, ['Content-Type' => $avatar->mime_type]);
|
||||
}
|
||||
|
||||
public function destroy(Gruppo $gruppo)
|
||||
{
|
||||
$this->authorizeWrite('gruppi');
|
||||
|
||||
$avatar = $gruppo->avatar;
|
||||
if ($avatar) {
|
||||
if ($avatar->file_path && Storage::disk('local')->exists($avatar->file_path)) {
|
||||
Storage::disk('local')->delete($avatar->file_path);
|
||||
}
|
||||
$avatar->delete();
|
||||
}
|
||||
|
||||
return response()->json(['success' => true]);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\Gruppo;
|
||||
@@ -30,111 +32,7 @@ class GruppoController extends Controller
|
||||
$visibleColumns = $defaultVisible;
|
||||
}
|
||||
|
||||
$allGruppi = Gruppo::with(['diocesi', 'parent', 'children', 'individui'])
|
||||
->orderBy('nome')
|
||||
->get()
|
||||
->map(function ($gruppo) {
|
||||
$depth = 0;
|
||||
$parent = $gruppo->parent;
|
||||
while ($parent) {
|
||||
$depth++;
|
||||
$parent = $parent->parent;
|
||||
}
|
||||
$gruppo->depth = $depth;
|
||||
return $gruppo;
|
||||
});
|
||||
|
||||
if ($viewMode === 'table') {
|
||||
$gruppi = $this->sortGruppiHierarchically($allGruppi);
|
||||
} else {
|
||||
$gruppi = $allGruppi;
|
||||
}
|
||||
|
||||
return view('gruppi.index', compact(
|
||||
'gruppi',
|
||||
'allColumns',
|
||||
'visibleColumns',
|
||||
'viewMode',
|
||||
'vista'
|
||||
));
|
||||
}
|
||||
|
||||
protected function sortGruppiHierarchically($gruppi)
|
||||
{
|
||||
$rootGroups = $gruppi->filter(fn($g) => $g->parent_id === null)->sortBy('nome');
|
||||
$sorted = collect();
|
||||
|
||||
foreach ($rootGroups as $root) {
|
||||
$sorted->push($root);
|
||||
$this->addChildrenRecursive($root, $gruppi, $sorted);
|
||||
}
|
||||
|
||||
return $sorted;
|
||||
}
|
||||
|
||||
protected function addChildrenRecursive($parent, $allGruppi, &$sorted)
|
||||
{
|
||||
$children = $allGruppi->filter(fn($g) => $g->parent_id === $parent->id)->sortBy('nome');
|
||||
|
||||
foreach ($children as $child) {
|
||||
$sorted->push($child);
|
||||
$this->addChildrenRecursive($child, $allGruppi, $sorted);
|
||||
}
|
||||
}
|
||||
|
||||
$allGruppi = Gruppo::with(['diocesi', 'parent', 'children', 'individui'])
|
||||
->orderBy('nome')
|
||||
->get()
|
||||
->map(function ($gruppo) {
|
||||
$depth = 0;
|
||||
$parent = $gruppo->parent;
|
||||
while ($parent) {
|
||||
$depth++;
|
||||
$parent = $parent->parent;
|
||||
}
|
||||
$gruppo->depth = $depth;
|
||||
return $gruppo;
|
||||
});
|
||||
|
||||
if ($viewMode === 'table') {
|
||||
$gruppi = $this->sortGruppiHierarchically($allGruppi);
|
||||
} else {
|
||||
$gruppi = $allGruppi;
|
||||
}
|
||||
|
||||
return view('gruppi.index', compact(
|
||||
'gruppi',
|
||||
'allColumns',
|
||||
'visibleColumns',
|
||||
'viewMode',
|
||||
'vista'
|
||||
));
|
||||
}
|
||||
|
||||
protected function sortGruppiHierarchically($gruppi)
|
||||
{
|
||||
$rootGroups = $gruppi->filter(fn($g) => $g->parent_id === null)->sortBy('nome');
|
||||
$sorted = collect();
|
||||
|
||||
foreach ($rootGroups as $root) {
|
||||
$sorted->push($root);
|
||||
$this->addChildrenRecursive($root, $gruppi, $sorted);
|
||||
}
|
||||
|
||||
return $sorted;
|
||||
}
|
||||
|
||||
protected function addChildrenRecursive($parent, $allGruppi, &$sorted)
|
||||
{
|
||||
$children = $allGruppi->filter(fn($g) => $g->parent_id === $parent->id)->sortBy('nome');
|
||||
|
||||
foreach ($children as $child) {
|
||||
$sorted->push($child);
|
||||
$this->addChildrenRecursive($child, $allGruppi, $sorted);
|
||||
}
|
||||
}
|
||||
|
||||
$allGruppi = Gruppo::with(['diocesi', 'parent', 'children', 'individui'])
|
||||
$allGruppi = Gruppo::with(['diocesi', 'parent', 'children', 'individui', 'avatar'])
|
||||
->orderBy('nome')
|
||||
->get()
|
||||
->map(function ($gruppo) {
|
||||
@@ -233,31 +131,31 @@ class GruppoController extends Controller
|
||||
return redirect('/gruppi/' . $gruppo->id)->with('success', 'Gruppo creato con successo.');
|
||||
}
|
||||
|
||||
public function show($gruppo)
|
||||
public function show($id)
|
||||
{
|
||||
$this->authorizeRead('gruppi');
|
||||
$gruppo = Gruppo::with(['parent', 'children', 'diocesi', 'individui.contatti', 'individui.documenti', 'individui' => function ($q) {
|
||||
$q->withPivot('ruolo_ids', 'ruolo_nel_gruppo', 'data_adesione');
|
||||
}, 'eventi' => function ($q) {
|
||||
}, 'avatar', 'eventi' => function ($q) {
|
||||
$q->where('is_incontro_gruppo', true);
|
||||
}, 'eventi.responsabili.contatti'])->findOrFail($gruppo);
|
||||
}, 'eventi.responsabili.contatti'])->findOrFail($id);
|
||||
return view('gruppi.show', compact('gruppo'));
|
||||
}
|
||||
|
||||
public function edit($gruppo)
|
||||
public function edit($id)
|
||||
{
|
||||
$this->authorizeWrite('gruppi');
|
||||
$gruppo = Gruppo::with(['individui.contatti', 'individui.documenti'])->findOrFail($gruppo);
|
||||
$gruppo = Gruppo::with(['individui.contatti', 'individui.documenti', 'avatar'])->findOrFail($id);
|
||||
$diocesi = Diocesi::orderBy('nome')->get();
|
||||
$gruppi = Gruppo::where('id', '!=', $gruppo->id)->orderBy('nome')->get();
|
||||
$membri = $gruppo->individui()->withPivot('ruolo_ids', 'ruolo_nel_gruppo', 'data_adesione')->orderBy('cognome')->orderBy('nome')->get();
|
||||
return view('gruppi.edit', compact('gruppo', 'diocesi', 'gruppi', 'membri'));
|
||||
}
|
||||
|
||||
public function update(Request $request, $gruppo)
|
||||
public function update(Request $request, $id)
|
||||
{
|
||||
$this->authorizeWrite('gruppi');
|
||||
$gruppo = Gruppo::findOrFail($gruppo);
|
||||
$gruppo = Gruppo::findOrFail($id);
|
||||
$data = $request->validate([
|
||||
'nome' => 'required|string|max:255',
|
||||
'descrizione' => 'nullable|string',
|
||||
@@ -295,10 +193,10 @@ class GruppoController extends Controller
|
||||
return redirect('/gruppi/' . $gruppo->id)->with('success', 'Gruppo aggiornato.');
|
||||
}
|
||||
|
||||
public function destroy($gruppo)
|
||||
public function destroy($id)
|
||||
{
|
||||
$this->authorizeDelete('gruppi');
|
||||
$gruppo = Gruppo::with('children', 'individui')->findOrFail($gruppo);
|
||||
$gruppo = Gruppo::with('children', 'individui')->findOrFail($id);
|
||||
|
||||
$hasChildren = $gruppo->children()->count() > 0;
|
||||
$isSuperAdmin = auth()->user()->isSuperAdmin();
|
||||
@@ -393,13 +291,13 @@ class GruppoController extends Controller
|
||||
return response()->json(['success' => true, 'vista_id' => $vista->id]);
|
||||
}
|
||||
|
||||
public function deleteVista($vista)
|
||||
public function deleteVista($id)
|
||||
{
|
||||
$vista = \App\Models\VistaReport::where('user_id', auth()->id())
|
||||
->where('id', $vista)
|
||||
->where('id', $id)
|
||||
->firstOrFail();
|
||||
$vista->delete();
|
||||
|
||||
return redirect()->route('gruppi.index')->with('success', 'Vista eliminata.');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -121,6 +121,47 @@ class ReportController extends Controller
|
||||
return redirect()->route('report.index')->with('success', 'Report personalizzato eliminato.');
|
||||
}
|
||||
|
||||
public function printPreview(Request $request)
|
||||
{
|
||||
if (!auth()->user()->canAccess('report')) {
|
||||
abort(403);
|
||||
}
|
||||
|
||||
$reportType = $request->input('report');
|
||||
$customReportId = $request->input('custom_id');
|
||||
|
||||
if ($customReportId) {
|
||||
$report = \App\Models\ReportCustom::findOrFail($customReportId);
|
||||
if ($report->user_id !== auth()->id()) {
|
||||
abort(403);
|
||||
}
|
||||
$data = $this->runCustomReport($report);
|
||||
return view('report.print-preview', compact('reportType', 'data', 'report'));
|
||||
}
|
||||
|
||||
$data = match ($reportType) {
|
||||
'individui_per_genere' => $this->reportIndividuiPerGenere(),
|
||||
'individui_per_eta' => $this->reportIndividuiPerEta(),
|
||||
'gruppi_gerarchia' => $this->reportGruppiGerarchia(),
|
||||
'gruppi_membri' => $this->reportGruppiMembri(),
|
||||
'eventi_calendario' => $this->reportEventiCalendario(),
|
||||
'documenti_per_tipo' => $this->reportDocumentiPerTipo(),
|
||||
'contatti_per_tipo' => $this->reportContattiPerTipo(),
|
||||
'mailing_list_dettaglio' => $this->reportMailingListDettaglio(),
|
||||
'individui_senza_contatti' => $this->reportIndividuiSenzaContatti(),
|
||||
'individui_senza_gruppo' => $this->reportIndividuiSenzaGruppo(),
|
||||
'eventi_per_gruppo' => $this->reportEventiPerGruppo(),
|
||||
'documenti_orfani' => $this->reportDocumentiOrfani(),
|
||||
default => null,
|
||||
};
|
||||
|
||||
if (!$data) {
|
||||
return redirect()->route('report.index')->with('error', 'Report non trovato.');
|
||||
}
|
||||
|
||||
return view('report.print-preview', compact('reportType', 'data'));
|
||||
}
|
||||
|
||||
public function exportCSV(Request $request)
|
||||
{
|
||||
if (!auth()->user()->canAccess('report')) {
|
||||
|
||||
+25
-3
@@ -127,7 +127,15 @@ class Evento extends Model
|
||||
|
||||
public function getOccorrenzeMensiliList(): array
|
||||
{
|
||||
$giorni = ['Lunedì', 'Martedì', 'Mercoledì', 'Giovedì', 'Venerdì', 'Sabato', 'Domenica'];
|
||||
$giorni = [
|
||||
0 => 'Domenica',
|
||||
1 => 'Lunedì',
|
||||
2 => 'Martedì',
|
||||
3 => 'Mercoledì',
|
||||
4 => 'Giovedì',
|
||||
5 => 'Venerdì',
|
||||
6 => 'Sabato',
|
||||
];
|
||||
$list = [];
|
||||
for ($occ = 1; $occ <= 4; $occ++) {
|
||||
foreach ($giorni as $idx => $giorno) {
|
||||
@@ -153,7 +161,15 @@ class Evento extends Model
|
||||
$occorrenza = (int) $parts[0];
|
||||
$giorno = (int) $parts[1];
|
||||
|
||||
$giorni = ['Lunedì', 'Martedì', 'Mercoledì', 'Giovedì', 'Venerdì', 'Sabato', 'Domenica'];
|
||||
$giorni = [
|
||||
0 => 'Domenica',
|
||||
1 => 'Lunedì',
|
||||
2 => 'Martedì',
|
||||
3 => 'Mercoledì',
|
||||
4 => 'Giovedì',
|
||||
5 => 'Venerdì',
|
||||
6 => 'Sabato',
|
||||
];
|
||||
|
||||
return $occorrenza . '° ' . ($giorni[$giorno] ?? '-');
|
||||
}
|
||||
@@ -199,7 +215,13 @@ class Evento extends Model
|
||||
}
|
||||
|
||||
$mesiLabels = $this->getMesiList();
|
||||
return $mesiLabels[$this->mese_annuale]['label'] ?? '-';
|
||||
$label = $mesiLabels[$this->mese_annuale]['label'] ?? '-';
|
||||
|
||||
if ($this->giorno_mese) {
|
||||
$label .= ' (giorno ' . $this->giorno_mese . ')';
|
||||
}
|
||||
|
||||
return $label;
|
||||
}
|
||||
|
||||
public function getPeriodicitaLabelAttribute(): string
|
||||
|
||||
+36
-12
@@ -5,6 +5,7 @@ namespace App\Models;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Database\Eloquent\Relations\HasOne;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
||||
|
||||
class Gruppo extends Model
|
||||
@@ -48,24 +49,47 @@ class Gruppo extends Model
|
||||
->withTimestamps();
|
||||
}
|
||||
|
||||
public function avatar(): HasOne
|
||||
{
|
||||
return $this->hasOne(Documento::class, 'visibilita_target_id')
|
||||
->where('tipologia', 'avatar')
|
||||
->where('visibilita_target_type', self::class);
|
||||
}
|
||||
|
||||
public function getAvatarUrlAttribute(): ?string
|
||||
{
|
||||
if ($this->avatar && $this->avatar->file_path) {
|
||||
return url('/gruppi/' . $this->id . '/avatar-file');
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getResponsabili()
|
||||
{
|
||||
if (empty($this->responsabile_ids)) {
|
||||
return collect();
|
||||
}
|
||||
|
||||
$ids = is_array($this->responsabile_ids)
|
||||
? $this->responsabile_ids
|
||||
: json_decode($this->responsabile_ids, true);
|
||||
|
||||
if (empty($ids)) {
|
||||
return collect();
|
||||
}
|
||||
|
||||
return Individuo::whereIn('id', $ids)->get();
|
||||
}
|
||||
|
||||
public function getResponsabiliIds(): array
|
||||
{
|
||||
if (empty($this->responsabile_ids)) {
|
||||
return [];
|
||||
}
|
||||
if (is_array($this->responsabile_ids)) {
|
||||
return $this->responsabile_ids;
|
||||
}
|
||||
return json_decode($this->responsabile_ids, true) ?? [];
|
||||
}
|
||||
|
||||
public function getResponsabili(): \Illuminate\Database\Eloquent\Collection
|
||||
{
|
||||
$ids = $this->getResponsabiliIds();
|
||||
if (empty($ids)) {
|
||||
return new \Illuminate\Database\Eloquent\Collection();
|
||||
}
|
||||
return Individuo::whereIn('id', $ids)->get();
|
||||
return is_array($this->responsabile_ids)
|
||||
? $this->responsabile_ids
|
||||
: json_decode($this->responsabile_ids, true) ?? [];
|
||||
}
|
||||
|
||||
public function eventi(): BelongsToMany
|
||||
|
||||
Reference in New Issue
Block a user