netgescon-master/app/Http/Controllers/Admin/DocumentiController.php
2025-07-20 14:57:25 +00:00

309 lines
10 KiB
PHP

<?php
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use App\Models\DocumentoStabile;
use App\Models\Stabile;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Str;
use ZipArchive;
class DocumentiController extends Controller
{
/**
* Carica nuovi documenti per uno stabile
*/
public function store(Request $request, Stabile $stabile)
{
$request->validate([
'documenti.*' => 'required|file|max:10240|mimes:pdf,doc,docx,xls,xlsx,jpg,jpeg,png,gif',
'categoria_documento' => 'required|string|in:' . implode(',', array_keys(DocumentoStabile::categorie()))
]);
$documentiCaricati = [];
$errori = [];
if ($request->hasFile('documenti')) {
foreach ($request->file('documenti') as $file) {
try {
// Genera nome unico per il file
$nomeOriginale = $file->getClientOriginalName();
$estensione = $file->getClientOriginalExtension();
$nomeFile = Str::slug(pathinfo($nomeOriginale, PATHINFO_FILENAME)) . '_' . time() . '.' . $estensione;
// Percorso di salvataggio: documenti/stabili/{stabile_id}/
$percorso = "documenti/stabili/{$stabile->id}";
$percorsoCompleto = $file->storeAs($percorso, $nomeFile, 'public');
// Crea record nel database
$documento = DocumentoStabile::create([
'stabile_id' => $stabile->id,
'nome_file' => $nomeFile,
'nome_originale' => $nomeOriginale,
'percorso_file' => $percorsoCompleto,
'categoria' => $request->categoria_documento,
'tipo_mime' => $file->getMimeType(),
'dimensione' => $file->getSize(),
'descrizione' => $request->descrizione_documento,
'data_scadenza' => $request->data_scadenza_documento,
'tags' => $request->tags_documento,
'pubblico' => $request->has('pubblico_documento'),
'caricato_da' => Auth::id()
]);
$documentiCaricati[] = $documento;
} catch (\Exception $e) {
$errori[] = "Errore nel caricamento di {$nomeOriginale}: " . $e->getMessage();
}
}
}
if (count($documentiCaricati) > 0) {
return response()->json([
'success' => true,
'message' => count($documentiCaricati) . ' documento/i caricato/i con successo',
'documenti' => $documentiCaricati,
'errori' => $errori
]);
} else {
return response()->json([
'success' => false,
'message' => 'Nessun documento caricato',
'errori' => $errori
], 400);
}
}
/**
* Lista documenti di uno stabile
*/
public function index(Stabile $stabile)
{
$documenti = $stabile->documenti()
->with('caricatore')
->orderBy('created_at', 'desc')
->get();
return response()->json([
'success' => true,
'documenti' => $documenti
]);
}
/**
* Download di un documento
*/
public function download(DocumentoStabile $documento)
{
if (!$documento->fileEsiste()) {
abort(404, 'File non trovato');
}
// Incrementa contatore download
$documento->incrementaDownload();
return Storage::disk('public')->download(
$documento->percorso_file,
$documento->nome_originale
);
}
/**
* Visualizza un documento nel browser
*/
public function view(DocumentoStabile $documento)
{
if (!$documento->fileEsiste()) {
abort(404, 'File non trovato');
}
// Incrementa contatore accessi
$documento->update(['ultimo_accesso' => now()]);
$path = Storage::disk('public')->path($documento->percorso_file);
return response()->file($path, [
'Content-Type' => $documento->tipo_mime,
'Content-Disposition' => 'inline; filename="' . $documento->nome_originale . '"'
]);
}
/**
* Elimina un documento
*/
public function destroy(DocumentoStabile $documento)
{
try {
$documento->delete(); // Il boot() del model si occuperà di eliminare il file fisico
return response()->json([
'success' => true,
'message' => 'Documento eliminato con successo'
]);
} catch (\Exception $e) {
return response()->json([
'success' => false,
'message' => 'Errore nell\'eliminazione del documento: ' . $e->getMessage()
], 500);
}
}
/**
* Download multiplo di documenti
*/
public function downloadMultiple(Request $request)
{
$request->validate([
'documento_ids' => 'required|array',
'documento_ids.*' => 'exists:documenti_stabili,id'
]);
$documenti = DocumentoStabile::whereIn('id', $request->documento_ids)->get();
if ($documenti->isEmpty()) {
return response()->json(['success' => false, 'message' => 'Nessun documento trovato'], 404);
}
// Crea un file ZIP temporaneo
$zipFileName = 'documenti_' . time() . '.zip';
$zipPath = storage_path('app/temp/' . $zipFileName);
// Assicurati che la directory temp esista
if (!file_exists(dirname($zipPath))) {
mkdir(dirname($zipPath), 0755, true);
}
$zip = new ZipArchive;
if ($zip->open($zipPath, ZipArchive::CREATE) === TRUE) {
foreach ($documenti as $documento) {
if ($documento->fileEsiste()) {
$filePath = Storage::disk('public')->path($documento->percorso_file);
$zip->addFile($filePath, $documento->nome_originale);
$documento->incrementaDownload();
}
}
$zip->close();
return response()->download($zipPath, $zipFileName)->deleteFileAfterSend(true);
}
return response()->json(['success' => false, 'message' => 'Errore nella creazione dell\'archivio'], 500);
}
/**
* Eliminazione multipla di documenti
*/
public function deleteMultiple(Request $request)
{
$request->validate([
'documento_ids' => 'required|array',
'documento_ids.*' => 'exists:documenti_stabili,id'
]);
try {
$documenti = DocumentoStabile::whereIn('id', $request->documento_ids)->get();
$deletedCount = 0;
foreach ($documenti as $documento) {
$documento->delete();
$deletedCount++;
}
return response()->json([
'success' => true,
'message' => "{$deletedCount} documento/i eliminato/i con successo",
'deleted_count' => $deletedCount
]);
} catch (\Exception $e) {
return response()->json([
'success' => false,
'message' => 'Errore nell\'eliminazione dei documenti: ' . $e->getMessage()
], 500);
}
}
/**
* Stampa elenco documenti
*/
public function printList(Stabile $stabile)
{
$documenti = $stabile->documenti()
->with('caricatore')
->orderBy('categoria')
->orderBy('created_at', 'desc')
->get()
->groupBy('categoria');
return view('admin.documenti.print-list', compact('stabile', 'documenti'));
}
/**
* Aggiorna i metadati di un documento
*/
public function updateMetadata(Request $request, DocumentoStabile $documento)
{
$request->validate([
'categoria' => 'required|string|in:' . implode(',', array_keys(DocumentoStabile::categorie())),
'descrizione' => 'nullable|string|max:1000',
'data_scadenza' => 'nullable|date',
'tags' => 'nullable|string',
'pubblico' => 'boolean'
]);
$documento->update($request->only([
'categoria', 'descrizione', 'data_scadenza', 'tags', 'pubblico'
]));
return response()->json([
'success' => true,
'message' => 'Metadati documento aggiornati con successo',
'documento' => $documento->fresh()
]);
}
/**
* Ricerca documenti
*/
public function search(Request $request, Stabile $stabile)
{
$query = $stabile->documenti();
if ($request->filled('categoria')) {
$query->where('categoria', $request->categoria);
}
if ($request->filled('search')) {
$search = $request->search;
$query->where(function($q) use ($search) {
$q->where('nome_originale', 'like', "%{$search}%")
->orWhere('descrizione', 'like', "%{$search}%")
->orWhere('tags', 'like', "%{$search}%");
});
}
if ($request->filled('scadenza')) {
switch ($request->scadenza) {
case 'scaduti':
$query->scaduti();
break;
case 'in_scadenza':
$query->inScadenza(30);
break;
}
}
$documenti = $query->with('caricatore')
->orderBy('created_at', 'desc')
->get();
return response()->json([
'success' => true,
'documenti' => $documenti
]);
}
}