glastree_on_gitea
This commit is contained in:
@@ -0,0 +1,566 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\Individuo;
|
||||
use App\Models\Contatto;
|
||||
use App\Models\Documento;
|
||||
use App\Models\Comune;
|
||||
use App\Models\Diocesi;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Illuminate\Validation\Rule;
|
||||
use Symfony\Component\HttpFoundation\StreamedResponse;
|
||||
|
||||
class IndividuoController extends Controller
|
||||
{
|
||||
public function index(Request $request)
|
||||
{
|
||||
$this->authorizeRead('individui');
|
||||
$individui = Individuo::with('contatti')->orderBy('cognome')->orderBy('nome')->paginate(20);
|
||||
|
||||
$vista = null;
|
||||
|
||||
if ($request->has('vista_id')) {
|
||||
$vista = \App\Models\VistaReport::where('id', $request->vista_id)
|
||||
->where('user_id', auth()->id())
|
||||
->first();
|
||||
}
|
||||
|
||||
if (!$vista && auth()->check()) {
|
||||
$vista = \App\Models\VistaReport::where('user_id', auth()->id())
|
||||
->where('tipo', 'individui')
|
||||
->where('is_default', true)
|
||||
->first();
|
||||
}
|
||||
|
||||
$allColumns = [
|
||||
['key' => 'codice', 'label' => 'Codice'],
|
||||
['key' => 'cognome', 'label' => 'Cognome'],
|
||||
['key' => 'nome', 'label' => 'Nome'],
|
||||
['key' => 'email', 'label' => 'Email'],
|
||||
['key' => 'telefono', 'label' => 'Telefono'],
|
||||
];
|
||||
|
||||
$defaultVisible = ['codice', 'cognome', 'nome', 'email', 'telefono'];
|
||||
$visibleColumns = $vista && !empty($vista->colonne_visibili)
|
||||
? $vista->colonne_visibili
|
||||
: $defaultVisible;
|
||||
|
||||
return view('individui.index', compact('individui', 'vista', 'allColumns', 'visibleColumns'));
|
||||
}
|
||||
|
||||
public function exportCSV(Request $request)
|
||||
{
|
||||
$this->authorizeRead('individui');
|
||||
|
||||
$ids = $request->input('ids', []);
|
||||
|
||||
$query = Individuo::with('contatti')->orderBy('cognome')->orderBy('nome');
|
||||
|
||||
if (is_array($ids) && !empty($ids)) {
|
||||
$query->whereIn('id', array_map('intval', $ids));
|
||||
}
|
||||
|
||||
$individui = $query->get();
|
||||
|
||||
$response = new StreamedResponse(function () use ($individui) {
|
||||
$handle = fopen('php://output', 'w');
|
||||
|
||||
fputcsv($handle, ['Codice', 'Cognome', 'Nome', 'Data Nascita', 'Genere', 'Email', 'Telefono', 'Cellulare', 'Indirizzo', 'CAP', 'Città', 'Provincia', 'Note']);
|
||||
|
||||
foreach ($individui as $ind) {
|
||||
$email = $ind->contatti->where('tipo', 'email')->where('is_primary', true)->first()
|
||||
?? $ind->contatti->where('tipo', 'email')->first();
|
||||
$telefono = $ind->contatti->where('tipo', 'telefono')->where('is_primary', true)->first()
|
||||
?? $ind->contatti->where('tipo', 'telefono')->first();
|
||||
$cellulare = $ind->contatti->where('tipo', 'cellulare')->where('is_primary', true)->first()
|
||||
?? $ind->contatti->where('tipo', 'cellulare')->first();
|
||||
|
||||
fputcsv($handle, [
|
||||
$ind->codice_id,
|
||||
$ind->cognome,
|
||||
$ind->nome,
|
||||
$ind->data_nascita?->format('d/m/Y') ?? '',
|
||||
$ind->genere === 'M' ? 'Maschio' : ($ind->genere === 'F' ? 'Femmina' : ''),
|
||||
$email?->valore ?? '',
|
||||
$telefono?->valore ?? '',
|
||||
$cellulare?->valore ?? '',
|
||||
$ind->indirizzo,
|
||||
$ind->cap,
|
||||
$ind->città,
|
||||
$ind->sigla_provincia,
|
||||
$ind->note,
|
||||
]);
|
||||
}
|
||||
|
||||
fclose($handle);
|
||||
});
|
||||
|
||||
$response->headers->set('Content-Type', 'text/csv; charset=utf-8');
|
||||
$response->headers->set('Content-Disposition', 'attachment; filename="individui_' . now()->format('Y-m-d') . '.csv"');
|
||||
$response->headers->set('Cache-Control', 'no-store');
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
public function create()
|
||||
{
|
||||
$this->authorizeWrite('individui');
|
||||
$comuni = Comune::orderBy('nome')->get();
|
||||
$diocesi = Diocesi::orderBy('nome')->get();
|
||||
return view('individui.create', compact('comuni', 'diocesi'));
|
||||
}
|
||||
|
||||
public function store(Request $request)
|
||||
{
|
||||
$this->authorizeWrite('individui');
|
||||
$data = $request->validate([
|
||||
'cognome' => 'required|string|max:255',
|
||||
'nome' => 'required|string|max:255',
|
||||
'data_nascita' => 'nullable|date',
|
||||
'indirizzo' => 'nullable|string|max:500',
|
||||
'cap' => 'nullable|string|max:10',
|
||||
'città' => 'nullable|string|max:255',
|
||||
'sigla_provincia' => 'nullable|string|max:2',
|
||||
'genere' => 'nullable|in:M,F',
|
||||
'tipo_documento' => 'nullable|in:carta_identita,patente',
|
||||
'numero_documento' => 'nullable|string|max:50',
|
||||
'scadenza_documento' => 'nullable|date',
|
||||
'note' => 'nullable|string',
|
||||
]);
|
||||
|
||||
$individuo = Individuo::create($data);
|
||||
|
||||
if ($request->has('contatti')) {
|
||||
foreach ($request->contatti as $contatto) {
|
||||
if (!empty($contatto['tipo']) && !empty($contatto['valore'])) {
|
||||
$individuo->contatti()->create([
|
||||
'tipo' => $contatto['tipo'],
|
||||
'valore' => $contatto['valore'],
|
||||
'etichetta' => $contatto['etichetta'] ?? null,
|
||||
'is_primary' => $contatto['is_primary'] ?? false,
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return redirect()->route('individui.index')->with('success', 'Individuo creato con successo.');
|
||||
}
|
||||
|
||||
public function show($individuo)
|
||||
{
|
||||
$this->authorizeRead('individui');
|
||||
$individuo = Individuo::with(['contatti', 'gruppi' => function ($q) {
|
||||
$q->withPivot('ruolo_ids', 'ruolo_nel_gruppo', 'data_adesione');
|
||||
}, 'avatar'])->findOrFail($individuo);
|
||||
return view('individui.show', compact('individuo'));
|
||||
}
|
||||
|
||||
public function report($individuo)
|
||||
{
|
||||
$this->authorizeRead('individui');
|
||||
$individuo = Individuo::with(['contatti', 'gruppi', 'documenti', 'eventiResponsabili', 'avatar'])->findOrFail($individuo);
|
||||
return view('individui.report', compact('individuo'));
|
||||
}
|
||||
|
||||
public function reportStampa(Request $request)
|
||||
{
|
||||
$this->authorizeRead('individui');
|
||||
$ids = explode(',', $request->ids ?? '');
|
||||
$individui = Individuo::with(['contatti', 'gruppi', 'documenti', 'eventiResponsabili', 'avatar'])
|
||||
->whereIn('id', $ids)
|
||||
->orderBy('cognome')
|
||||
->orderBy('nome')
|
||||
->get();
|
||||
return view('individui.report-multiplo', compact('individui'));
|
||||
}
|
||||
|
||||
public function edit($individuo)
|
||||
{
|
||||
$this->authorizeWrite('individui');
|
||||
$individuo = Individuo::with(['contatti', 'gruppi', 'avatar'])->findOrFail($individuo);
|
||||
return view('individui.edit', compact('individuo'));
|
||||
}
|
||||
|
||||
public function update(Request $request, $individuo)
|
||||
{
|
||||
$this->authorizeWrite('individui');
|
||||
$individuo = Individuo::findOrFail($individuo);
|
||||
|
||||
\Log::info('=== INDIVIDUO UPDATE START ===', ['id' => $individuo->id]);
|
||||
\Log::info('Request contatti:', ['contatti' => $request->input('contatti'), 'all_keys' => array_keys($request->all())]);
|
||||
|
||||
$data = $request->validate([
|
||||
'cognome' => 'required|string|max:255',
|
||||
'nome' => 'required|string|max:255',
|
||||
'data_nascita' => 'nullable|date',
|
||||
'indirizzo' => 'nullable|string|max:500',
|
||||
'cap' => 'nullable|string|max:10',
|
||||
'città' => 'nullable|string|max:255',
|
||||
'sigla_provincia' => 'nullable|string|max:2',
|
||||
'genere' => 'nullable|in:M,F',
|
||||
'tipo_documento' => 'nullable|in:carta_identita,patente',
|
||||
'numero_documento' => 'nullable|string|max:50',
|
||||
'scadenza_documento' => 'nullable|date',
|
||||
'note' => 'nullable|string',
|
||||
]);
|
||||
|
||||
$individuo->update($data);
|
||||
|
||||
\Log::info('Individuo dati salvati', ['id' => $individuo->id]);
|
||||
|
||||
$contattiData = $request->input('contatti');
|
||||
\Log::info('Contatti ricevuti:', ['contatti' => $contattiData, 'tipo' => gettype($contattiData)]);
|
||||
|
||||
$individuo->contatti()->delete();
|
||||
\Log::info('Contatti precedenti eliminati, count ora:', ['count' => $individuo->contatti()->count()]);
|
||||
|
||||
if (!empty($contattiData) && is_array($contattiData)) {
|
||||
$created = 0;
|
||||
foreach ($contattiData as $contatto) {
|
||||
if (!empty($contatto['tipo']) && !empty($contatto['valore'])) {
|
||||
$individuo->contatti()->create([
|
||||
'tipo' => $contatto['tipo'],
|
||||
'valore' => $contatto['valore'],
|
||||
'etichetta' => $contatto['etichetta'] ?? null,
|
||||
'is_primary' => !empty($contatto['is_primary']),
|
||||
]);
|
||||
$created++;
|
||||
}
|
||||
}
|
||||
\Log::info('Contatti creati:', ['count' => $created]);
|
||||
}
|
||||
|
||||
return redirect()->route('individui.show', $individuo)->with('success', 'Individuo aggiornato con successo!');
|
||||
}
|
||||
|
||||
public function destroy($individuo)
|
||||
{
|
||||
$this->authorizeDelete('individui');
|
||||
$individuo = Individuo::findOrFail($individuo);
|
||||
$individuo->delete();
|
||||
return redirect()->route('individui.index')->with('success', 'Individuo eliminato.');
|
||||
}
|
||||
|
||||
public function elimina(Request $request, $individuo)
|
||||
{
|
||||
$this->authorizeDelete('individui');
|
||||
$individuo = Individuo::findOrFail($individuo);
|
||||
|
||||
$eliminaContatti = filter_var($request->input('elimina_contatti', false), FILTER_VALIDATE_BOOLEAN);
|
||||
$eliminaDocumenti = filter_var($request->input('elimina_documenti', false), FILTER_VALIDATE_BOOLEAN);
|
||||
|
||||
if ($eliminaContatti) {
|
||||
$individuo->contatti()->delete();
|
||||
}
|
||||
|
||||
if ($eliminaDocumenti) {
|
||||
foreach ($individuo->documenti as $documento) {
|
||||
if ($documento->file_path && file_exists(storage_path('app/public/' . $documento->file_path))) {
|
||||
unlink(storage_path('app/public/' . $documento->file_path));
|
||||
}
|
||||
}
|
||||
$individuo->documenti()->delete();
|
||||
}
|
||||
|
||||
$individuo->delete();
|
||||
|
||||
return redirect()->route('individui.index')->with('success', 'Individuo eliminato con successo.');
|
||||
}
|
||||
|
||||
public function massElimina(Request $request)
|
||||
{
|
||||
$this->authorizeDelete('individui');
|
||||
|
||||
$ids = $request->input('ids', []);
|
||||
if (!is_array($ids) || empty($ids)) {
|
||||
return redirect()->route('individui.index')->with('error', 'Nessun individuo selezionato.');
|
||||
}
|
||||
|
||||
$eliminaContatti = filter_var($request->input('elimina_contatti', false), FILTER_VALIDATE_BOOLEAN);
|
||||
$eliminaDocumenti = filter_var($request->input('elimina_documenti', false), FILTER_VALIDATE_BOOLEAN);
|
||||
|
||||
$individui = Individuo::whereIn('id', $ids)->get();
|
||||
|
||||
foreach ($individui as $individuo) {
|
||||
if ($eliminaContatti) {
|
||||
$individuo->contatti()->delete();
|
||||
}
|
||||
|
||||
if ($eliminaDocumenti) {
|
||||
foreach ($individuo->documenti as $documento) {
|
||||
if ($documento->file_path && file_exists(storage_path('app/public/' . $documento->file_path))) {
|
||||
unlink(storage_path('app/public/' . $documento->file_path));
|
||||
}
|
||||
}
|
||||
$individuo->documenti()->delete();
|
||||
}
|
||||
|
||||
$individuo->delete();
|
||||
}
|
||||
|
||||
return redirect()->route('individui.index')->with('success', count($individui) . ' individui eliminati con successo.');
|
||||
}
|
||||
|
||||
public function elementiCollegati($individuo)
|
||||
{
|
||||
$individuo = Individuo::findOrFail($individuo);
|
||||
|
||||
return response()->json([
|
||||
'contatti' => $individuo->contatti()->count(),
|
||||
'gruppi' => $individuo->gruppi()->count(),
|
||||
'documenti' => $individuo->documenti()->count(),
|
||||
'eventi' => $individuo->eventiResponsabili()->count(),
|
||||
]);
|
||||
}
|
||||
|
||||
public function emailList(Request $request)
|
||||
{
|
||||
$this->authorizeRead('individui');
|
||||
$ids = $request->input('ids', '');
|
||||
$idArray = array_filter(array_map('intval', explode(',', $ids)));
|
||||
|
||||
if (empty($idArray)) {
|
||||
return response()->json([]);
|
||||
}
|
||||
|
||||
$individui = Individuo::with('contatti')->whereIn('id', $idArray)->get();
|
||||
|
||||
$result = [];
|
||||
foreach ($individui as $ind) {
|
||||
$emails = $ind->contatti->where('tipo', 'email')->pluck('valore')->toArray();
|
||||
$result[] = [
|
||||
'id' => $ind->id,
|
||||
'codice_id' => $ind->codice_id,
|
||||
'cognome' => $ind->cognome,
|
||||
'nome' => $ind->nome,
|
||||
'email' => count($emails) === 1 ? $emails[0] : null,
|
||||
'emails' => $emails,
|
||||
'email_count' => count($emails)
|
||||
];
|
||||
}
|
||||
|
||||
return response()->json($result);
|
||||
}
|
||||
|
||||
public function allIndividui()
|
||||
{
|
||||
$this->authorizeRead('individui');
|
||||
$individui = Individuo::select('id', 'codice_id', 'cognome', 'nome')
|
||||
->orderBy('cognome')
|
||||
->orderBy('nome')
|
||||
->get();
|
||||
return response()->json($individui);
|
||||
}
|
||||
|
||||
public function import()
|
||||
{
|
||||
$this->authorizeWrite('individui');
|
||||
return view('individui.import');
|
||||
}
|
||||
|
||||
public function importStore(Request $request)
|
||||
{
|
||||
$this->authorizeWrite('individui');
|
||||
$request->validate([
|
||||
'file' => 'required|file|mimes:csv,txt',
|
||||
]);
|
||||
|
||||
$file = $request->file('file');
|
||||
$handle = fopen($file->path(), 'r');
|
||||
$header = fgetcsv($handle, 1000, ',');
|
||||
|
||||
$imported = 0;
|
||||
$skipped = 0;
|
||||
$errors = [];
|
||||
$rowNumber = 1;
|
||||
|
||||
while (($row = fgetcsv($handle, 1000, ',')) !== false) {
|
||||
$rowNumber++;
|
||||
|
||||
if (count($row) < count($header)) {
|
||||
$skipped++;
|
||||
continue;
|
||||
}
|
||||
|
||||
$data = array_combine($header, $row);
|
||||
|
||||
if ($data === false) {
|
||||
$skipped++;
|
||||
continue;
|
||||
}
|
||||
|
||||
$cognome = trim($data['cognome'] ?? '');
|
||||
$nome = trim($data['nome'] ?? '');
|
||||
|
||||
if (empty($cognome) || empty($nome)) {
|
||||
$skipped++;
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
$individuo = Individuo::create([
|
||||
'cognome' => $cognome,
|
||||
'nome' => $nome,
|
||||
'data_nascita' => !empty(trim($data['data_nascita'] ?? '')) ? trim($data['data_nascita']) : null,
|
||||
'indirizzo' => !empty(trim($data['indirizzo'] ?? '')) ? trim($data['indirizzo']) : null,
|
||||
'cap' => !empty(trim($data['cap'] ?? '')) ? trim($data['cap']) : null,
|
||||
'città' => !empty(trim($data['città'] ?? '')) ? trim($data['città']) : null,
|
||||
'sigla_provincia' => !empty(trim($data['sigla_provincia'] ?? '')) ? trim($data['sigla_provincia']) : null,
|
||||
'genere' => !empty(trim($data['genere'] ?? '')) ? strtoupper(trim($data['genere'])) : null,
|
||||
'tipo_documento' => !empty(trim($data['tipo_documento'] ?? '')) ? trim($data['tipo_documento']) : null,
|
||||
'numero_documento' => !empty(trim($data['numero_documento'] ?? '')) ? trim($data['numero_documento']) : null,
|
||||
'scadenza_documento' => !empty(trim($data['scadenza_documento'] ?? '')) ? trim($data['scadenza_documento']) : null,
|
||||
'note' => !empty(trim($data['note'] ?? '')) ? trim($data['note']) : null,
|
||||
]);
|
||||
|
||||
for ($i = 1; $i <= 2; $i++) {
|
||||
$tipoKey = 'contatto_' . $i . '_tipo';
|
||||
$valoreKey = 'contatto_' . $i . '_valore';
|
||||
$etichettaKey = 'contatto_' . $i . '_etichetta';
|
||||
|
||||
$tipo = trim($data[$tipoKey] ?? '');
|
||||
$valore = trim($data[$valoreKey] ?? '');
|
||||
|
||||
if (!empty($tipo) && !empty($valore)) {
|
||||
$individuo->contatti()->create([
|
||||
'tipo' => $tipo,
|
||||
'valore' => $valore,
|
||||
'etichetta' => !empty(trim($data[$etichettaKey] ?? '')) ? trim($data[$etichettaKey]) : null,
|
||||
'is_primary' => $i === 1,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
$imported++;
|
||||
} catch (\Exception $e) {
|
||||
$errors[] = 'Errore riga ' . $rowNumber . ': ' . $e->getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
fclose($handle);
|
||||
|
||||
$message = 'Importati ' . $imported . ' individui.';
|
||||
if ($skipped > 0) {
|
||||
$message .= ' Saltate ' . $skipped . ' righe (vuote o incomplete).';
|
||||
}
|
||||
if (count($errors) > 0) {
|
||||
return back()->with('error', $message . ' Errori: ' . implode('; ', $errors));
|
||||
}
|
||||
|
||||
return redirect()->route('individui.index')->with('success', $message);
|
||||
}
|
||||
|
||||
public function downloadTemplate()
|
||||
{
|
||||
$this->authorizeRead('individui');
|
||||
$headers = ['cognome', 'nome', 'data_nascita', 'indirizzo', 'cap', 'città', 'sigla_provincia', 'genere', 'tipo_documento', 'numero_documento', 'scadenza_documento', 'note', 'contatto_1_tipo', 'contatto_1_valore', 'contatto_1_etichetta', 'contatto_2_tipo', 'contatto_2_valore', 'contatto_2_etichetta'];
|
||||
|
||||
$example = [
|
||||
'Rossi',
|
||||
'Mario',
|
||||
'1990-05-15',
|
||||
'Via Roma 10',
|
||||
'00100',
|
||||
'Roma',
|
||||
'RM',
|
||||
'M',
|
||||
'carta_identita',
|
||||
'AB123456',
|
||||
'2030-05-15',
|
||||
'Socio fondatore',
|
||||
'email',
|
||||
'mario.rossi@email.com',
|
||||
'personale',
|
||||
'cellulare',
|
||||
'3331234567',
|
||||
'lavoro',
|
||||
];
|
||||
|
||||
$csv = implode(',', $headers) . "\n" . implode(',', $example);
|
||||
|
||||
return response($csv, 200, [
|
||||
'Content-Type' => 'text/csv',
|
||||
'Content-Disposition' => 'attachment; filename="template_individui.csv"',
|
||||
]);
|
||||
}
|
||||
|
||||
public function uploadAvatar(Request $request, $individuo)
|
||||
{
|
||||
$this->authorizeWrite('individui');
|
||||
$individuo = Individuo::findOrFail($individuo);
|
||||
|
||||
$request->validate([
|
||||
'avatar' => 'required|image|mimes:jpeg,jpg,png,gif|max:2048',
|
||||
]);
|
||||
|
||||
$file = $request->file('avatar');
|
||||
|
||||
$oldAvatar = $individuo->avatar;
|
||||
if ($oldAvatar) {
|
||||
if (Storage::disk('local')->exists($oldAvatar->file_path)) {
|
||||
Storage::disk('local')->delete($oldAvatar->file_path);
|
||||
}
|
||||
$oldAvatar->delete();
|
||||
}
|
||||
|
||||
$path = $file->store('avatars', 'local');
|
||||
|
||||
$avatar = Documento::create([
|
||||
'tenant_id' => $individuo->tenant_id,
|
||||
'nome_file' => $file->getClientOriginalName(),
|
||||
'file_path' => $path,
|
||||
'tipo' => 'upload',
|
||||
'tipologia' => 'avatar',
|
||||
'visibilita' => 'individuo',
|
||||
'visibilita_target_id' => $individuo->id,
|
||||
'visibilita_target_type' => Individuo::class,
|
||||
'mime_type' => $file->getMimeType(),
|
||||
'dimensione' => $file->getSize(),
|
||||
'user_id' => auth()->id(),
|
||||
]);
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'avatar_url' => url('/individui/' . $individuo->id . '/avatar'),
|
||||
'avatar_id' => $avatar->id,
|
||||
]);
|
||||
}
|
||||
|
||||
public function getAvatar($individuo)
|
||||
{
|
||||
$this->authorizeRead('individui');
|
||||
$individuo = Individuo::findOrFail($individuo);
|
||||
$avatar = $individuo->avatar;
|
||||
|
||||
if (!$avatar || !Storage::disk('local')->exists($avatar->file_path)) {
|
||||
abort(404);
|
||||
}
|
||||
|
||||
return response(
|
||||
Storage::disk('local')->get($avatar->file_path),
|
||||
200,
|
||||
['Content-Type' => $avatar->mime_type]
|
||||
);
|
||||
}
|
||||
|
||||
public function deleteAvatar($individuo)
|
||||
{
|
||||
$this->authorizeDelete('individui');
|
||||
$individuo = Individuo::findOrFail($individuo);
|
||||
$avatar = $individuo->avatar;
|
||||
|
||||
if (!$avatar) {
|
||||
return response()->json(['success' => false, 'message' => 'Nessun avatar da eliminare']);
|
||||
}
|
||||
|
||||
if (Storage::disk('local')->exists($avatar->file_path)) {
|
||||
Storage::disk('local')->delete($avatar->file_path);
|
||||
}
|
||||
|
||||
$avatar->delete();
|
||||
|
||||
return response()->json(['success' => true]);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user