netgescon-day0/app/Http/Controllers/Condomino/AssembleaConvocazioneController.php

291 lines
11 KiB
PHP

<?php
namespace App\Http\Controllers\Condomino;
use App\Http\Controllers\Controller;
use App\Models\Convocazione;
use App\Models\OrdineGiorno;
use App\Models\AssembleaVoto;
use App\Models\AssembleaPresenza;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;
class AssembleaConvocazioneController extends Controller
{
public function show(string $token)
{
$convocazione = Convocazione::where('token_accesso', $token)
->with(['assemblea.stabile', 'soggetto', 'unitaImmobiliare'])
->firstOrFail();
$assemblea = $convocazione->assemblea;
// Recupera Ordine del Giorno
$odg = OrdineGiorno::where('assemblea_id', $assemblea->id)
->with('tabellaMillesimale')
->orderBy('numero_punto')
->get();
// Controlla se il soggetto ha deleghe attive per questa assemblea
$deleghe = AssembleaPresenza::where('assemblea_id', $assemblea->id)
->where('tipo_partecipazione', 'delega')
->where('delegato_soggetto_id', $convocazione->soggetto_id)
->with(['unitaImmobiliare', 'soggetto'])
->get();
// Recupera i voti già espressi per questa convocazione/unità
$votiEspressi = AssembleaVoto::where('assemblea_id', $assemblea->id)
->where('soggetto_id', $convocazione->soggetto_id)
->get()
->pluck('voto', 'ordine_giorno_id')
->toArray();
// Recupera i voti espressi per le deleghe
$votiDeleghe = [];
foreach ($deleghe as $delega) {
$votiDeleghe[$delega->unita_immobiliare_id] = AssembleaVoto::where('assemblea_id', $assemblea->id)
->where('soggetto_id', $delega->soggetto_id)
->where('unita_immobiliare_id', $delega->unita_immobiliare_id)
->get()
->pluck('voto', 'ordine_giorno_id')
->toArray();
}
// Recupera il punto attivo per la votazione (dal cache)
$attivoOdgId = Cache::get("assemblea.{$assemblea->id}.attivo_odg_id");
return view('mobile.assemblea.convocazione-mobile', compact(
'convocazione',
'assemblea',
'odg',
'deleghe',
'votiEspressi',
'votiDeleghe',
'attivoOdgId'
));
}
public function confermaRicezione(Request $request, string $token)
{
$convocazione = Convocazione::where('token_accesso', $token)->firstOrFail();
$signatureData = $request->input('firma_dati');
$signaturePath = null;
if ($signatureData && preg_match('/^data:image\/(\w+);base64,/', $signatureData, $type)) {
$data = substr($signatureData, strpos($signatureData, ',') + 1);
$data = base64_decode($data);
if ($data !== false) {
$signaturePath = 'firme/' . $token . '.png';
\Illuminate\Support\Facades\Storage::disk('public')->put($signaturePath, $data);
}
}
$convocazione->update([
'ricezione_confermata_at' => now(),
'ip_conferma' => $request->ip(),
'user_agent_conferma' => $request->userAgent(),
'firma_ricezione_percorso' => $signaturePath ? 'storage/' . $signaturePath : null,
'stato_ricezione' => 'confermato_online',
]);
return response()->json([
'success' => true,
'message' => 'Firma e ricezione registrate con successo!',
'ricezione_confermata_at' => $convocazione->ricezione_confermata_at->format('d/m/Y H:i'),
]);
}
public function downloadZip(string $token)
{
$convocazione = Convocazione::where('token_accesso', $token)
->with(['assemblea'])
->firstOrFail();
$assemblea = $convocazione->assemblea;
$odg = OrdineGiorno::where('assemblea_id', $assemblea->id)->get();
$zipFileName = 'allegati_assemblea_' . $assemblea->id . '.zip';
$zipFilePath = storage_path('app/public/' . $zipFileName);
$zip = new \ZipArchive();
if ($zip->open($zipFilePath, \ZipArchive::CREATE | \ZipArchive::OVERWRITE) === true) {
$hasFiles = false;
foreach ($odg as $punto) {
if ($punto->allegati && is_array($punto->allegati)) {
foreach ($punto->allegati as $file) {
$fullPath = storage_path('app/public/' . $file['path']);
if (file_exists($fullPath)) {
$zip->addFile($fullPath, $punto->numero_punto . '_' . $file['nome']);
$hasFiles = true;
}
}
}
}
$zip->close();
if ($hasFiles && file_exists($zipFilePath)) {
return response()->download($zipFilePath)->deleteFileAfterSend(true);
}
}
return redirect()->back()->with('error', 'Nessun allegato disponibile per il download.');
}
public function updateAnagrafica(Request $request, string $token)
{
$convocazione = Convocazione::where('token_accesso', $token)->firstOrFail();
$request->validate([
'email' => 'nullable|email|max:255',
'pec' => 'nullable|email|max:255',
'telefono' => 'nullable|string|max:50',
'indirizzo' => 'nullable|string|max:255',
]);
$soggetto = $convocazione->soggetto;
$datiAttuali = [
'email' => $soggetto->email,
'pec' => $soggetto->pec,
'telefono' => $soggetto->telefono,
'indirizzo' => $soggetto->indirizzo_residenza ?? $soggetto->indirizzo,
];
$datiProposti = [
'email' => $request->input('email'),
'pec' => $request->input('pec'),
'telefono' => $request->input('telefono'),
'indirizzo' => $request->input('indirizzo'),
];
\App\Models\RichiestaModifica::create([
'unita_immobiliare_id' => $convocazione->unita_immobiliare_id,
'soggetto_richiedente_id' => $convocazione->soggetto_id,
'tipo_modifica' => 'recapiti',
'descrizione' => 'Aggiornamento recapiti conduttore/proprietario inviato dal portale assemblea.',
'dati_attuali' => $datiAttuali,
'dati_proposti' => $datiProposti,
'stato' => 'in_attesa',
]);
return response()->json([
'success' => true,
'message' => 'Richiesta di variazione anagrafica inviata allo studio. Verrà esaminata a breve dall\'amministratore!',
]);
}
public function vota(Request $request, string $token)
{
$convocazione = Convocazione::where('token_accesso', $token)
->with('assemblea')
->firstOrFail();
$assemblea = $convocazione->assemblea;
$request->validate([
'ordine_giorno_id' => 'required|integer',
'voto' => 'required|string|in:favorevole,contrario,astenuto',
'unita_immobiliare_id' => 'nullable|integer',
'soggetto_id' => 'nullable|integer',
]);
$odgId = (int) $request->input('ordine_giorno_id');
$votoStr = $request->input('voto');
// Verifica se il punto è effettivamente aperto alla votazione
$attivoOdgId = Cache::get("assemblea.{$assemblea->id}.attivo_odg_id");
if ((int)$attivoOdgId !== $odgId) {
return response()->json([
'success' => false,
'message' => 'Le votazioni per questo punto all\'ordine del giorno sono chiuse o non ancora aperte.',
], 422);
}
$odg = OrdineGiorno::findOrFail($odgId);
// Se vota per una delega
$unitaId = $request->input('unita_immobiliare_id') ?: $convocazione->unita_immobiliare_id;
$soggettoId = $request->input('soggetto_id') ?: $convocazione->soggetto_id;
// Se vota per delega, verifichiamo che la delega esista
if ($soggettoId !== $convocazione->soggetto_id) {
$hasDelega = AssembleaPresenza::where('assemblea_id', $assemblea->id)
->where('tipo_partecipazione', 'delega')
->where('soggetto_id', $soggettoId)
->where('unita_immobiliare_id', $unitaId)
->where('delegato_soggetto_id', $convocazione->soggetto_id)
->exists();
if (!$hasDelega) {
return response()->json([
'success' => false,
'message' => 'Non sei autorizzato a votare per questa delega.',
], 403);
}
}
// Calcola millesimi per questa unità
$millesimi = 0.000;
if ($odg->tabella_millesimale_id) {
$millesimi = DB::table('dettagli_tabelle_millesimali')
->where('tabella_millesimale_id', $odg->tabella_millesimale_id)
->where('unita_immobiliare_id', $unitaId)
->value('millesimi') ?: 0.000;
}
if ($millesimi <= 0) {
// Fallback millesimi generali dell'unità
$millesimi = DB::table('unita_immobiliari')
->where('id', $unitaId)
->value('millesimi_generali') ?: 0.000;
}
// Salva il voto
AssembleaVoto::updateOrCreate(
[
'ordine_giorno_id' => $odgId,
'soggetto_id' => $soggettoId,
'unita_immobiliare_id' => $unitaId,
],
[
'assemblea_id' => $assemblea->id,
'voto' => $votoStr,
'millesimi_voto' => $millesimi,
]
);
return response()->json([
'success' => true,
'message' => 'Voto registrato con successo!',
'voto' => $votoStr,
]);
}
public function pollVotazioneAttiva(string $token)
{
$convocazione = Convocazione::where('token_accesso', $token)->firstOrFail();
$assemblea = $convocazione->assemblea;
$attivoOdgId = Cache::get("assemblea.{$assemblea->id}.attivo_odg_id");
$punto = null;
if ($attivoOdgId) {
$odg = OrdineGiorno::find($attivoOdgId);
if ($odg) {
$punto = [
'id' => $odg->id,
'numero' => $odg->numero_punto,
'titolo' => $odg->titolo,
'descrizione' => $odg->descrizione,
];
}
}
return response()->json([
'attivo_odg_id' => $attivoOdgId,
'punto' => $punto,
]);
}
}