whereHas('pianoRateizzazione.ripartizioneSpese.voceSpesa.stabile', function($q) { $q->where('amministratore_id', Auth::user()->amministratore->id_amministratore ?? null); }); // Filtro per stabile if ($request->filled('stabile_id')) { $query->whereHas('pianoRateizzazione.ripartizioneSpese.voceSpesa', function($q) use ($request) { $q->where('stabile_id', $request->stabile_id); }); } // Filtro per unità immobiliare if ($request->filled('unita_immobiliare_id')) { $query->whereHas('pianoRateizzazione', function($q) use ($request) { $q->where('unita_immobiliare_id', $request->unita_immobiliare_id); }); } // Filtro per stato if ($request->filled('stato')) { $query->where('stato', $request->stato); } // Filtro per scadenza if ($request->filled('scadenza_da')) { $query->where('data_scadenza', '>=', $request->scadenza_da); } if ($request->filled('scadenza_a')) { $query->where('data_scadenza', '<=', $request->scadenza_a); } // Filtro per rate in scadenza if ($request->filled('in_scadenza')) { $giorni = (int) $request->in_scadenza; $query->where('data_scadenza', '<=', Carbon::now()->addDays($giorni)) ->where('stato', 'da_pagare'); } // Filtro per rate scadute if ($request->filled('scadute')) { $query->where('data_scadenza', '<', Carbon::now()) ->where('stato', 'da_pagare'); } $rate = $query->orderBy('data_scadenza')->paginate(20); // Dati per i filtri $stabili = \App\Models\Stabile::where('amministratore_id', Auth::user()->amministratore->id_amministratore ?? null) ->orderBy('denominazione') ->get(); // Statistiche $statistiche = [ 'totale_rate' => $query->count(), 'da_pagare' => $query->where('stato', 'da_pagare')->count(), 'pagate' => $query->where('stato', 'pagata')->count(), 'scadute' => $query->where('data_scadenza', '<', Carbon::now())->where('stato', 'da_pagare')->count(), 'importo_totale' => $query->sum('importo'), 'importo_pagato' => $query->where('stato', 'pagata')->sum('importo'), ]; return view('admin.rate.index', compact('rate', 'stabili', 'statistiche')); } /** * Display the specified resource. */ public function show(Rata $rata) { // Verifica autorizzazione $this->authorize('view', $rata); $rata->load([ 'pianoRateizzazione.ripartizioneSpese.voceSpesa.stabile', 'pianoRateizzazione.unitaImmobiliare.anagraficaCondominiale.soggetto', 'createdBy', 'updatedBy' ]); return view('admin.rate.show', compact('rata')); } /** * Show the form for editing the specified resource. */ public function edit(Rata $rata) { // Verifica autorizzazione $this->authorize('update', $rata); // Solo le rate da pagare possono essere modificate if ($rata->stato !== 'da_pagare') { return redirect()->route('admin.rate.show', $rata) ->with('error', 'Impossibile modificare una rata già pagata o annullata.'); } $rata->load([ 'pianoRateizzazione.ripartizioneSpese.voceSpesa.stabile', 'pianoRateizzazione.unitaImmobiliare' ]); return view('admin.rate.edit', compact('rata')); } /** * Update the specified resource in storage. */ public function update(Request $request, Rata $rata) { // Verifica autorizzazione $this->authorize('update', $rata); // Solo le rate da pagare possono essere modificate if ($rata->stato !== 'da_pagare') { return redirect()->route('admin.rate.show', $rata) ->with('error', 'Impossibile modificare una rata già pagata o annullata.'); } $request->validate([ 'importo' => 'required|numeric|min:0', 'data_scadenza' => 'required|date', 'note' => 'nullable|string', ]); $rata->update([ 'importo' => $request->importo, 'data_scadenza' => $request->data_scadenza, 'note' => $request->note, 'updated_by' => Auth::id(), ]); return redirect()->route('admin.rate.show', $rata) ->with('success', 'Rata aggiornata con successo.'); } /** * Registra il pagamento di una rata */ public function registraPagamento(Request $request, Rata $rata) { // Verifica autorizzazione $this->authorize('update', $rata); if ($rata->stato !== 'da_pagare') { return redirect()->route('admin.rate.show', $rata) ->with('error', 'La rata è già stata pagata o annullata.'); } $request->validate([ 'importo_pagato' => 'required|numeric|min:0', 'data_pagamento' => 'required|date', 'metodo_pagamento' => 'required|string|max:100', 'riferimento_pagamento' => 'nullable|string|max:255', 'note_pagamento' => 'nullable|string', ]); DB::beginTransaction(); try { $rata->update([ 'stato' => 'pagata', 'importo_pagato' => $request->importo_pagato, 'data_pagamento' => $request->data_pagamento, 'metodo_pagamento' => $request->metodo_pagamento, 'riferimento_pagamento' => $request->riferimento_pagamento, 'note_pagamento' => $request->note_pagamento, 'registrato_by' => Auth::id(), 'updated_by' => Auth::id(), ]); // Verifica se il piano è completato $pianoRateizzazione = $rata->pianoRateizzazione; $rateRimanenti = $pianoRateizzazione->rate()->where('stato', 'da_pagare')->count(); if ($rateRimanenti === 0) { $pianoRateizzazione->update([ 'stato' => 'completato', 'data_completamento' => now(), ]); } DB::commit(); return redirect()->route('admin.rate.show', $rata) ->with('success', 'Pagamento registrato con successo.'); } catch (\Exception $e) { DB::rollBack(); return redirect()->back() ->withInput() ->with('error', 'Errore durante la registrazione del pagamento: ' . $e->getMessage()); } } /** * Annulla il pagamento di una rata */ public function annullaPagamento(Rata $rata) { // Verifica autorizzazione $this->authorize('update', $rata); if ($rata->stato !== 'pagata') { return redirect()->route('admin.rate.show', $rata) ->with('error', 'La rata non è stata pagata.'); } DB::beginTransaction(); try { $rata->update([ 'stato' => 'da_pagare', 'importo_pagato' => null, 'data_pagamento' => null, 'metodo_pagamento' => null, 'riferimento_pagamento' => null, 'note_pagamento' => null, 'registrato_by' => null, 'updated_by' => Auth::id(), ]); // Aggiorna lo stato del piano se necessario $pianoRateizzazione = $rata->pianoRateizzazione; if ($pianoRateizzazione->stato === 'completato') { $pianoRateizzazione->update([ 'stato' => 'attivo', 'data_completamento' => null, ]); } DB::commit(); return redirect()->route('admin.rate.show', $rata) ->with('success', 'Pagamento annullato con successo.'); } catch (\Exception $e) { DB::rollBack(); return redirect()->route('admin.rate.show', $rata) ->with('error', 'Errore durante l\'annullamento del pagamento: ' . $e->getMessage()); } } /** * Posticipa una rata */ public function posticipa(Request $request, Rata $rata) { // Verifica autorizzazione $this->authorize('update', $rata); if ($rata->stato !== 'da_pagare') { return redirect()->route('admin.rate.show', $rata) ->with('error', 'Impossibile posticipare una rata già pagata o annullata.'); } $request->validate([ 'nuova_data_scadenza' => 'required|date|after:' . $rata->data_scadenza, 'motivo_posticipo' => 'required|string|max:255', ]); $rata->update([ 'data_scadenza' => $request->nuova_data_scadenza, 'motivo_posticipo' => $request->motivo_posticipo, 'posticipata_by' => Auth::id(), 'updated_by' => Auth::id(), ]); return redirect()->route('admin.rate.show', $rata) ->with('success', 'Rata posticipata con successo.'); } /** * Mostra il form per registrare un pagamento */ public function showPagamentoForm(Rata $rata) { // Verifica autorizzazione $this->authorize('update', $rata); if ($rata->stato !== 'da_pagare') { return redirect()->route('admin.rate.show', $rata) ->with('error', 'La rata è già stata pagata o annullata.'); } $rata->load([ 'pianoRateizzazione.ripartizioneSpese.voceSpesa.stabile', 'pianoRateizzazione.unitaImmobiliare.anagraficaCondominiale.soggetto' ]); return view('admin.rate.pagamento', compact('rata')); } /** * Mostra il form per posticipare una rata */ public function showPosticipoForm(Rata $rata) { // Verifica autorizzazione $this->authorize('update', $rata); if ($rata->stato !== 'da_pagare') { return redirect()->route('admin.rate.show', $rata) ->with('error', 'Impossibile posticipare una rata già pagata o annullata.'); } $rata->load([ 'pianoRateizzazione.ripartizioneSpese.voceSpesa.stabile', 'pianoRateizzazione.unitaImmobiliare' ]); return view('admin.rate.posticipo', compact('rata')); } /** * Genera un report delle rate */ public function report(Request $request) { $query = Rata::with([ 'pianoRateizzazione.ripartizioneSpese.voceSpesa.stabile', 'pianoRateizzazione.unitaImmobiliare.anagraficaCondominiale.soggetto' ])->whereHas('pianoRateizzazione.ripartizioneSpese.voceSpesa.stabile', function($q) { $q->where('amministratore_id', Auth::user()->amministratore->id_amministratore ?? null); }); // Applica filtri if ($request->filled('stabile_id')) { $query->whereHas('pianoRateizzazione.ripartizioneSpese.voceSpesa', function($q) use ($request) { $q->where('stabile_id', $request->stabile_id); }); } if ($request->filled('stato')) { $query->where('stato', $request->stato); } if ($request->filled('data_da')) { $query->where('data_scadenza', '>=', $request->data_da); } if ($request->filled('data_a')) { $query->where('data_scadenza', '<=', $request->data_a); } $rate = $query->orderBy('data_scadenza')->get(); // Statistiche per il report $statistiche = [ 'totale_rate' => $rate->count(), 'da_pagare' => $rate->where('stato', 'da_pagare')->count(), 'pagate' => $rate->where('stato', 'pagata')->count(), 'scadute' => $rate->where('data_scadenza', '<', Carbon::now())->where('stato', 'da_pagare')->count(), 'importo_totale' => $rate->sum('importo'), 'importo_pagato' => $rate->where('stato', 'pagata')->sum('importo_pagato'), 'importo_da_pagare' => $rate->where('stato', 'da_pagare')->sum('importo'), ]; return view('admin.rate.report', compact('rate', 'statistiche')); } /** * Esporta le rate in CSV */ public function exportCsv(Request $request) { $query = Rata::with([ 'pianoRateizzazione.ripartizioneSpese.voceSpesa.stabile', 'pianoRateizzazione.unitaImmobiliare.anagraficaCondominiale.soggetto' ])->whereHas('pianoRateizzazione.ripartizioneSpese.voceSpesa.stabile', function($q) { $q->where('amministratore_id', Auth::user()->amministratore->id_amministratore ?? null); }); // Applica gli stessi filtri del report if ($request->filled('stabile_id')) { $query->whereHas('pianoRateizzazione.ripartizioneSpese.voceSpesa', function($q) use ($request) { $q->where('stabile_id', $request->stabile_id); }); } if ($request->filled('stato')) { $query->where('stato', $request->stato); } if ($request->filled('data_da')) { $query->where('data_scadenza', '>=', $request->data_da); } if ($request->filled('data_a')) { $query->where('data_scadenza', '<=', $request->data_a); } $rate = $query->orderBy('data_scadenza')->get(); $filename = 'rate_' . Carbon::now()->format('Y-m-d_H-i-s') . '.csv'; $headers = [ 'Content-Type' => 'text/csv', 'Content-Disposition' => "attachment; filename=\"$filename\"", ]; $callback = function() use ($rate) { $file = fopen('php://output', 'w'); // Intestazioni CSV fputcsv($file, [ 'Stabile', 'Unità Immobiliare', 'Condomino', 'Piano Rateizzazione', 'Numero Rata', 'Importo', 'Data Scadenza', 'Stato', 'Data Pagamento', 'Importo Pagato', 'Metodo Pagamento', 'Riferimento' ]); // Dati foreach ($rate as $rata) { fputcsv($file, [ $rata->pianoRateizzazione->ripartizioneSpese->voceSpesa->stabile->denominazione, $rata->pianoRateizzazione->unitaImmobiliare->denominazione, $rata->pianoRateizzazione->unitaImmobiliare->anagraficaCondominiale?->soggetto?->denominazione, $rata->pianoRateizzazione->denominazione, $rata->numero_rata, $rata->importo, $rata->data_scadenza, $rata->stato, $rata->data_pagamento, $rata->importo_pagato, $rata->metodo_pagamento, $rata->riferimento_pagamento ]); } fclose($file); }; return response()->stream($callback, 200, $headers); } }