309 lines
10 KiB
PHP
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
|
|
]);
|
|
}
|
|
}
|