netgescon-day0/app/Modules/StampeRate/Controllers/StampeRateController.php

433 lines
14 KiB
PHP

<?php
namespace App\Modules\StampeRate\Controllers;
use App\Http\Controllers\Controller;
use App\Services\HookManager;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\View;
use PDF; // Libreria PDF (da installare: composer require dompdf/dompdf)
use Mail;
/**
* Controller per il modulo Stampe Rate Avanzate
*/
class StampeRateController extends Controller
{
protected $moduleName = 'StampeRate';
public function __construct()
{
// Middleware per verificare permessi del modulo
$this->middleware('permission:stampe.rate.view')->only(['index', 'show']);
$this->middleware('permission:stampe.rate.create')->only(['create', 'store', 'generate']);
$this->middleware('permission:stampe.rate.update')->only(['edit', 'update']);
$this->middleware('permission:stampe.rate.delete')->only(['destroy']);
$this->middleware('permission:stampe.rate.send')->only(['send', 'sendBulk']);
}
/**
* Lista stampe rate generate
*/
public function index(Request $request)
{
$query = DB::table('stampe_rate')
->join('stabili', 'stampe_rate.stabile_id', '=', 'stabili.id')
->select([
'stampe_rate.*',
'stabili.denominazione as stabile_nome',
'stabili.indirizzo as stabile_indirizzo'
])
->where('stampe_rate.created_by', Auth::id())
->orderBy('stampe_rate.created_at', 'desc');
// Filtri
if ($request->filled('stabile_id')) {
$query->where('stampe_rate.stabile_id', $request->stabile_id);
}
if ($request->filled('periodo')) {
$query->where('stampe_rate.periodo', $request->periodo);
}
if ($request->filled('status')) {
$query->where('stampe_rate.status', $request->status);
}
$stampe = $query->paginate(20);
// Hook per permettere ad altri moduli di modificare i dati
$stampe = HookManager::execute('stampe_rate_list_loaded', $stampe);
$stabili = DB::table('stabili')
->where('amministratore_id', Auth::id())
->select('id', 'denominazione', 'indirizzo')
->get();
return view('modules.stampe-rate.index', compact('stampe', 'stabili'));
}
/**
* Form per generare nuove stampe rate
*/
public function create()
{
$stabili = DB::table('stabili')
->where('amministratore_id', Auth::id())
->select('id', 'denominazione', 'indirizzo')
->get();
$templates = DB::table('stampe_rate_templates')
->where('status', 'active')
->where(function ($query) {
$query->where('created_by', Auth::id())
->orWhere('is_public', true);
})
->select('id', 'name', 'description')
->get();
return view('modules.stampe-rate.create', compact('stabili', 'templates'));
}
/**
* Visualizza i dettagli di una stampa rate
*/
public function show($stampaId)
{
$stampa = DB::table('stampe_rate')
->join('stabili', 'stampe_rate.stabile_id', '=', 'stabili.id')
->leftJoin('stampe_rate_templates', 'stampe_rate.template_id', '=', 'stampe_rate_templates.id')
->select([
'stampe_rate.*',
'stabili.denominazione as stabile_nome',
'stabili.indirizzo as stabile_indirizzo',
'stampe_rate_templates.name as template_nome'
])
->where('stampe_rate.id', $stampaId)
->where('stampe_rate.created_by', Auth::id())
->first();
if (!$stampa) {
abort(404, 'Stampa rate non trovata');
}
// Decodifica i dati JSON
$stampa->file_generati = json_decode($stampa->file_generati, true) ?? [];
$stampa->parametri_stampa = json_decode($stampa->parametri_stampa, true) ?? [];
$stampa->rate_selezionate = json_decode($stampa->rate_selezionate, true) ?? [];
// Statistiche di invio (se presenti)
$invii = DB::table('stampe_rate_invii')
->where('stampa_id', $stampaId)
->orderBy('created_at', 'desc')
->get();
$statsInvii = [
'totali' => $invii->count(),
'inviati' => $invii->where('status', 'sent')->count(),
'falliti' => $invii->where('status', 'failed')->count(),
'in_coda' => $invii->where('status', 'pending')->count()
];
return view('modules.stampe-rate.show', compact('stampa', 'invii', 'statsInvii'));
}
/**
* Genera le stampe rate per uno stabile
*/
public function generate(Request $request)
{
$request->validate([
'stabile_id' => 'required|exists:stabili,id',
'periodo' => 'required|string',
'template_id' => 'required|exists:stampe_rate_templates,id',
'include_pdf' => 'boolean',
'auto_send' => 'boolean'
]);
try {
DB::beginTransaction();
// Hook prima della generazione
$data = HookManager::execute('before_stampa_generated', [
'stabile_id' => $request->stabile_id,
'periodo' => $request->periodo,
'template_id' => $request->template_id,
'user_id' => Auth::id()
]);
// Ottieni le rate da stampare
$rate = $this->getRateByStabile($request->stabile_id, $request->periodo);
if ($rate->isEmpty()) {
return response()->json([
'success' => false,
'message' => 'Nessuna rata trovata per il periodo selezionato'
], 404);
}
// Crea record stampa principale
$stampaId = DB::table('stampe_rate')->insertGetId([
'stabile_id' => $request->stabile_id,
'periodo' => $request->periodo,
'template_id' => $request->template_id,
'total_rate' => $rate->count(),
'status' => 'generating',
'created_by' => Auth::id(),
'created_at' => now(),
'updated_at' => now()
]);
// Genera PDF per ogni rata
$generatedFiles = [];
foreach ($rate as $rata) {
$pdfData = $this->generateRataPDF($rata, $request->template_id);
$fileName = "rata_{$rata->id}_{$request->periodo}.pdf";
$filePath = storage_path("app/public/stampe-rate/{$stampaId}/{$fileName}");
// Crea directory se non exists
if (!file_exists(dirname($filePath))) {
mkdir(dirname($filePath), 0755, true);
}
// Salva PDF
file_put_contents($filePath, $pdfData);
// Registra il file generato
DB::table('stampe_rate_files')->insert([
'stampa_id' => $stampaId,
'rata_id' => $rata->id,
'unita_id' => $rata->unita_immobiliare_id,
'file_name' => $fileName,
'file_path' => $filePath,
'file_size' => filesize($filePath),
'created_at' => now()
]);
$generatedFiles[] = [
'rata_id' => $rata->id,
'file_name' => $fileName,
'file_path' => $filePath
];
}
// Aggiorna stato stampa
DB::table('stampe_rate')->where('id', $stampaId)->update([
'status' => 'completed',
'generated_files' => count($generatedFiles),
'completed_at' => now(),
'updated_at' => now()
]);
DB::commit();
// Hook dopo la generazione
$result = HookManager::execute('after_stampa_generated', [
'stampa_id' => $stampaId,
'files_generated' => $generatedFiles,
'auto_send' => $request->auto_send
]);
// Invio automatico se richiesto
if ($request->auto_send) {
$this->sendBulk($stampaId);
}
return response()->json([
'success' => true,
'message' => "Stampe generate con successo: {$rate->count()} rate elaborate",
'stampa_id' => $stampaId,
'files_count' => count($generatedFiles),
'download_url' => route('stampeRate.download', $stampaId)
]);
} catch (\Exception $e) {
DB::rollback();
return response()->json([
'success' => false,
'message' => 'Errore durante la generazione: ' . $e->getMessage()
], 500);
}
}
/**
* Invia stampe rate via email
*/
public function send(Request $request, $stampaId)
{
$request->validate([
'email_subject' => 'required|string|max:255',
'email_body' => 'required|string',
'send_to' => 'required|array',
'send_to.*' => 'email'
]);
$stampa = DB::table('stampe_rate')->where('id', $stampaId)->first();
if (!$stampa) {
return response()->json([
'success' => false,
'message' => 'Stampa non trovata'
], 404);
}
// Hook prima dell'invio
HookManager::execute('before_email_sent', [
'stampa_id' => $stampaId,
'recipients' => $request->send_to
]);
// Ottieni i file da allegare
$files = DB::table('stampe_rate_files')
->where('stampa_id', $stampaId)
->get();
$sentCount = 0;
$errors = [];
foreach ($request->send_to as $email) {
try {
// Invia email con allegati
Mail::send('modules.stampe-rate.emails.rate-email', [
'subject' => $request->email_subject,
'body' => $request->email_body,
'stampa' => $stampa
], function ($message) use ($email, $request, $files) {
$message->to($email)
->subject($request->email_subject);
// Allega i PDF
foreach ($files as $file) {
if (file_exists($file->file_path)) {
$message->attach($file->file_path, [
'as' => $file->file_name,
'mime' => 'application/pdf'
]);
}
}
});
// Registra invio
DB::table('stampe_rate_invii')->insert([
'stampa_id' => $stampaId,
'email' => $email,
'status' => 'sent',
'sent_at' => now(),
'created_at' => now()
]);
$sentCount++;
} catch (\Exception $e) {
$errors[] = "Errore invio a {$email}: " . $e->getMessage();
// Registra errore
DB::table('stampe_rate_invii')->insert([
'stampa_id' => $stampaId,
'email' => $email,
'status' => 'failed',
'error_message' => $e->getMessage(),
'created_at' => now()
]);
}
}
// Hook dopo l'invio
HookManager::execute('after_email_sent', [
'stampa_id' => $stampaId,
'sent_count' => $sentCount,
'errors' => $errors
]);
return response()->json([
'success' => $sentCount > 0,
'message' => "Email inviate: {$sentCount}/" . count($request->send_to),
'sent_count' => $sentCount,
'errors' => $errors
]);
}
/**
* Download ZIP con tutte le stampe
*/
public function download($stampaId)
{
$stampa = DB::table('stampe_rate')->where('id', $stampaId)->first();
if (!$stampa) {
abort(404, 'Stampa non trovata');
}
$files = DB::table('stampe_rate_files')
->where('stampa_id', $stampaId)
->get();
if ($files->isEmpty()) {
abort(404, 'Nessun file trovato');
}
// Crea ZIP temporaneo
$zipFileName = "stampe_rate_{$stampaId}_" . date('Y-m-d_H-i-s') . '.zip';
$zipPath = storage_path("app/temp/{$zipFileName}");
$zip = new \ZipArchive();
$zip->open($zipPath, \ZipArchive::CREATE);
foreach ($files as $file) {
if (file_exists($file->file_path)) {
$zip->addFile($file->file_path, $file->file_name);
}
}
$zip->close();
return response()->download($zipPath)->deleteFileAfterSend(true);
}
// =============================================
// METODI PRIVATI DI SUPPORTO
// =============================================
private function getRateByStabile($stabileId, $periodo)
{
return DB::table('rate')
->join('unita_immobiliari', 'rate.unita_immobiliare_id', '=', 'unita_immobiliari.id')
->where('unita_immobiliari.stabile_id', $stabileId)
->where('rate.periodo', $periodo)
->select([
'rate.*',
'unita_immobiliari.numero as unita_numero',
'unita_immobiliari.piano',
'unita_immobiliari.scala'
])
->get();
}
private function generateRataPDF($rata, $templateId)
{
// Ottieni template
$template = DB::table('stampe_rate_templates')->where('id', $templateId)->first();
// Hook per modificare il template
$templateData = HookManager::execute('template_loaded', [
'template' => $template,
'rata' => $rata
]);
// Genera HTML dal template
$html = view('modules.stampe-rate.templates.pdf', [
'rata' => $rata,
'template' => $template
])->render();
// Converti in PDF
$pdf = PDF::loadHTML($html);
$pdf->setPaper('A4', 'portrait');
return $pdf->output();
}
}