762 lines
27 KiB
PHP
762 lines
27 KiB
PHP
<?php
|
|
|
|
namespace App\Modules\StampeRate\Controllers;
|
|
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Http\Response;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Facades\Log;
|
|
use Illuminate\Support\Facades\Mail;
|
|
use Illuminate\Support\Facades\Storage;
|
|
use Illuminate\Support\Facades\Cache;
|
|
use App\Http\Controllers\Controller;
|
|
use App\Services\HookManager;
|
|
use Carbon\Carbon;
|
|
|
|
/**
|
|
* Controller per la gestione della cronologia e tracking
|
|
* Modulo: Stampe Rate Avanzate
|
|
*
|
|
* Gestisce cronologia stampe, tracking email, statistiche,
|
|
* report e tutte le funzionalità di monitoraggio del modulo
|
|
*/
|
|
class HistoryController extends Controller
|
|
{
|
|
protected $hookManager;
|
|
|
|
public function __construct()
|
|
{
|
|
$this->middleware('auth')->except(['trackEmailOpen', 'trackDownload', 'unsubscribe']);
|
|
$this->middleware('permission:stampe_rate_history_view')->only(['index', 'dashboard', 'emailTracking']);
|
|
$this->middleware('permission:stampe_rate_reports_view')->only(['reports', 'monthlyReport', 'yearlyReport']);
|
|
$this->middleware('permission:stampe_rate_export')->only(['export', 'exportCSV', 'exportExcel']);
|
|
$this->middleware('permission:stampe_rate_admin')->only(['cleanup', 'archive']);
|
|
|
|
$this->hookManager = app(HookManager::class);
|
|
}
|
|
|
|
/**
|
|
* Dashboard cronologia principale
|
|
*/
|
|
public function index(Request $request)
|
|
{
|
|
try {
|
|
$this->hookManager->execute('stampe_rate.history.before_index', [$request]);
|
|
|
|
// Filtri cronologia
|
|
$query = DB::table('stampe_rate_history as h')
|
|
->leftJoin('stampe_rate as s', 'h.stampa_id', '=', 's.id')
|
|
->leftJoin('users as u', 'h.created_by', '=', 'u.id')
|
|
->select([
|
|
'h.*',
|
|
's.nome as stampa_nome',
|
|
's.tipo_documento',
|
|
'u.name as utente_nome'
|
|
])
|
|
->where('h.deleted_at', null)
|
|
->orderBy('h.created_at', 'desc');
|
|
|
|
// Filtri
|
|
if ($request->filled('date_from')) {
|
|
$query->where('h.created_at', '>=', $request->get('date_from'));
|
|
}
|
|
|
|
if ($request->filled('date_to')) {
|
|
$query->where('h.created_at', '<=', $request->get('date_to') . ' 23:59:59');
|
|
}
|
|
|
|
if ($request->filled('action')) {
|
|
$query->where('h.action', $request->get('action'));
|
|
}
|
|
|
|
if ($request->filled('user_id')) {
|
|
$query->where('h.created_by', $request->get('user_id'));
|
|
}
|
|
|
|
if ($request->filled('search')) {
|
|
$search = $request->get('search');
|
|
$query->where(function ($q) use ($search) {
|
|
$q->where('s.nome', 'like', "%{$search}%")
|
|
->orWhere('h.dettagli', 'like', "%{$search}%")
|
|
->orWhere('u.name', 'like', "%{$search}%");
|
|
});
|
|
}
|
|
|
|
$cronologia = $query->paginate(50);
|
|
|
|
// Statistiche rapide
|
|
$stats = $this->getStatsRapide();
|
|
|
|
// Lista utenti per filtro
|
|
$utenti = DB::table('users')
|
|
->whereIn('id', function ($query) {
|
|
$query->select('created_by')
|
|
->from('stampe_rate_history')
|
|
->whereNotNull('created_by')
|
|
->distinct();
|
|
})
|
|
->select('id', 'name')
|
|
->orderBy('name')
|
|
->get();
|
|
|
|
$this->hookManager->execute('stampe_rate.history.after_index', [$cronologia, $stats]);
|
|
|
|
return view('modules.stampe-rate.history.index', compact('cronologia', 'stats', 'utenti'));
|
|
} catch (\Exception $e) {
|
|
Log::error("Errore cronologia stampe: " . $e->getMessage());
|
|
return back()->with('error', 'Errore nel caricamento della cronologia: ' . $e->getMessage());
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Dashboard statistiche avanzate
|
|
*/
|
|
public function dashboard()
|
|
{
|
|
try {
|
|
$this->hookManager->execute('stampe_rate.history.before_dashboard');
|
|
|
|
// Statistiche generali
|
|
$statsGenerali = [
|
|
'stampe_totali' => DB::table('stampe_rate')->where('deleted_at', null)->count(),
|
|
'stampe_oggi' => DB::table('stampe_rate')->whereDate('created_at', today())->count(),
|
|
'stampe_settimana' => DB::table('stampe_rate')->whereBetween('created_at', [now()->startOfWeek(), now()->endOfWeek()])->count(),
|
|
'stampe_mese' => DB::table('stampe_rate')->whereMonth('created_at', now()->month)->whereYear('created_at', now()->year)->count()
|
|
];
|
|
|
|
// Email statistics
|
|
$emailStats = [
|
|
'inviate_totali' => DB::table('stampe_rate_email_log')->count(),
|
|
'inviate_oggi' => DB::table('stampe_rate_email_log')->whereDate('sent_at', today())->count(),
|
|
'aperte_totali' => DB::table('stampe_rate_email_log')->whereNotNull('opened_at')->count(),
|
|
'click_totali' => DB::table('stampe_rate_email_log')->whereNotNull('clicked_at')->count()
|
|
];
|
|
|
|
// Grafici dati ultimi 30 giorni
|
|
$graficoStampe = $this->getGraficoStampeUltimi30Giorni();
|
|
$graficoEmail = $this->getGraficoEmailUltimi30Giorni();
|
|
|
|
// Top template utilizzati
|
|
$topTemplate = DB::table('stampe_rate as s')
|
|
->leftJoin('stampe_templates as t', 's.template_id', '=', 't.id')
|
|
->select('t.nome', DB::raw('COUNT(*) as utilizzi'))
|
|
->where('s.deleted_at', null)
|
|
->groupBy('t.id', 't.nome')
|
|
->orderBy('utilizzi', 'desc')
|
|
->limit(10)
|
|
->get();
|
|
|
|
// Errori recenti
|
|
$erroriRecenti = DB::table('stampe_rate_history')
|
|
->where('action', 'error')
|
|
->where('created_at', '>=', now()->subDays(7))
|
|
->orderBy('created_at', 'desc')
|
|
->limit(10)
|
|
->get();
|
|
|
|
return view('modules.stampe-rate.history.dashboard', compact(
|
|
'statsGenerali',
|
|
'emailStats',
|
|
'graficoStampe',
|
|
'graficoEmail',
|
|
'topTemplate',
|
|
'erroriRecenti'
|
|
));
|
|
} catch (\Exception $e) {
|
|
Log::error("Errore dashboard history: " . $e->getMessage());
|
|
return back()->with('error', 'Errore nel caricamento della dashboard: ' . $e->getMessage());
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Tracking email inviate
|
|
*/
|
|
public function emailTracking(Request $request)
|
|
{
|
|
try {
|
|
$query = DB::table('stampe_rate_email_log as e')
|
|
->leftJoin('stampe_rate as s', 'e.stampa_id', '=', 's.id')
|
|
->leftJoin('users as u', 'e.sent_by', '=', 'u.id')
|
|
->select([
|
|
'e.*',
|
|
's.nome as stampa_nome',
|
|
'u.name as inviato_da'
|
|
])
|
|
->orderBy('e.sent_at', 'desc');
|
|
|
|
// Filtri
|
|
if ($request->filled('status')) {
|
|
$status = $request->get('status');
|
|
switch ($status) {
|
|
case 'sent':
|
|
$query->whereNotNull('e.sent_at');
|
|
break;
|
|
case 'opened':
|
|
$query->whereNotNull('e.opened_at');
|
|
break;
|
|
case 'clicked':
|
|
$query->whereNotNull('e.clicked_at');
|
|
break;
|
|
case 'failed':
|
|
$query->whereNotNull('e.failed_at');
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ($request->filled('date_from')) {
|
|
$query->where('e.sent_at', '>=', $request->get('date_from'));
|
|
}
|
|
|
|
if ($request->filled('date_to')) {
|
|
$query->where('e.sent_at', '<=', $request->get('date_to') . ' 23:59:59');
|
|
}
|
|
|
|
if ($request->filled('search')) {
|
|
$search = $request->get('search');
|
|
$query->where(function ($q) use ($search) {
|
|
$q->where('e.recipient_email', 'like', "%{$search}%")
|
|
->orWhere('e.recipient_name', 'like', "%{$search}%")
|
|
->orWhere('s.nome', 'like', "%{$search}%");
|
|
});
|
|
}
|
|
|
|
$emailLog = $query->paginate(50);
|
|
|
|
// Statistiche email
|
|
$emailStats = [
|
|
'totali' => DB::table('stampe_rate_email_log')->count(),
|
|
'inviate' => DB::table('stampe_rate_email_log')->whereNotNull('sent_at')->count(),
|
|
'aperte' => DB::table('stampe_rate_email_log')->whereNotNull('opened_at')->count(),
|
|
'cliccate' => DB::table('stampe_rate_email_log')->whereNotNull('clicked_at')->count(),
|
|
'fallite' => DB::table('stampe_rate_email_log')->whereNotNull('failed_at')->count(),
|
|
'tasso_apertura' => $this->calcolaTassoApertura(),
|
|
'tasso_click' => $this->calcolaTassoClick()
|
|
];
|
|
|
|
return view('modules.stampe-rate.history.email-tracking', compact('emailLog', 'emailStats'));
|
|
} catch (\Exception $e) {
|
|
Log::error("Errore tracking email: " . $e->getMessage());
|
|
return back()->with('error', 'Errore nel caricamento del tracking email: ' . $e->getMessage());
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Dettaglio tracking singola email
|
|
*/
|
|
public function emailTrackingDetail($invioId)
|
|
{
|
|
try {
|
|
$invio = DB::table('stampe_rate_email_log as e')
|
|
->leftJoin('stampe_rate as s', 'e.stampa_id', '=', 's.id')
|
|
->leftJoin('users as u', 'e.sent_by', '=', 'u.id')
|
|
->select([
|
|
'e.*',
|
|
's.nome as stampa_nome',
|
|
's.tipo_documento',
|
|
'u.name as inviato_da'
|
|
])
|
|
->where('e.id', $invioId)
|
|
->first();
|
|
|
|
if (!$invio) {
|
|
return redirect()->route('stampeRate.history.email.tracking')
|
|
->with('error', 'Invio email non trovato');
|
|
}
|
|
|
|
// Cronologia tracking per questa email
|
|
$trackingHistory = DB::table('stampe_rate_email_tracking')
|
|
->where('email_log_id', $invioId)
|
|
->orderBy('tracked_at', 'desc')
|
|
->get();
|
|
|
|
// Allegati inviati
|
|
$allegati = DB::table('stampe_rate_email_attachments')
|
|
->where('email_log_id', $invioId)
|
|
->get();
|
|
|
|
return view('modules.stampe-rate.history.email-detail', compact('invio', 'trackingHistory', 'allegati'));
|
|
} catch (\Exception $e) {
|
|
Log::error("Errore dettaglio email: " . $e->getMessage());
|
|
return back()->with('error', 'Errore nel caricamento del dettaglio: ' . $e->getMessage());
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Report e statistiche avanzate
|
|
*/
|
|
public function reports(Request $request)
|
|
{
|
|
try {
|
|
$tipoReport = $request->get('tipo', 'mensile');
|
|
$dataInizio = $request->get('data_inizio', now()->startOfMonth()->format('Y-m-d'));
|
|
$dataFine = $request->get('data_fine', now()->endOfMonth()->format('Y-m-d'));
|
|
|
|
$reportData = $this->generaReport($tipoReport, $dataInizio, $dataFine);
|
|
|
|
return view('modules.stampe-rate.history.reports', compact('reportData', 'tipoReport', 'dataInizio', 'dataFine'));
|
|
} catch (\Exception $e) {
|
|
Log::error("Errore report: " . $e->getMessage());
|
|
return back()->with('error', 'Errore nella generazione del report: ' . $e->getMessage());
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Report mensile
|
|
*/
|
|
public function monthlyReport(Request $request)
|
|
{
|
|
$mese = $request->get('mese', now()->month);
|
|
$anno = $request->get('anno', now()->year);
|
|
|
|
return $this->generaReportMensile($mese, $anno);
|
|
}
|
|
|
|
/**
|
|
* Report annuale
|
|
*/
|
|
public function yearlyReport(Request $request)
|
|
{
|
|
$anno = $request->get('anno', now()->year);
|
|
|
|
return $this->generaReportAnnuale($anno);
|
|
}
|
|
|
|
/**
|
|
* Report personalizzato
|
|
*/
|
|
public function customReport(Request $request)
|
|
{
|
|
try {
|
|
$parametri = $request->validate([
|
|
'data_inizio' => 'required|date',
|
|
'data_fine' => 'required|date|after:data_inizio',
|
|
'metriche' => 'required|array',
|
|
'formato' => 'required|in:html,pdf,excel,csv'
|
|
]);
|
|
|
|
$reportData = $this->generaReportPersonalizzato($parametri);
|
|
|
|
if ($parametri['formato'] === 'html') {
|
|
return view('modules.stampe-rate.history.custom-report', compact('reportData', 'parametri'));
|
|
} else {
|
|
return $this->esportaReport($reportData, $parametri['formato']);
|
|
}
|
|
} catch (\Exception $e) {
|
|
Log::error("Errore report personalizzato: " . $e->getMessage());
|
|
return back()->with('error', 'Errore nella generazione del report: ' . $e->getMessage());
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Export cronologia
|
|
*/
|
|
public function export(Request $request)
|
|
{
|
|
try {
|
|
$formato = $request->get('formato', 'csv');
|
|
$filtri = $request->only(['date_from', 'date_to', 'action', 'user_id']);
|
|
|
|
$dati = $this->getCronologiaPerExport($filtri);
|
|
|
|
switch ($formato) {
|
|
case 'csv':
|
|
return $this->exportCSV($dati);
|
|
case 'excel':
|
|
return $this->exportExcel($dati);
|
|
case 'pdf':
|
|
return $this->exportPDF($dati);
|
|
default:
|
|
throw new \Exception('Formato non supportato');
|
|
}
|
|
} catch (\Exception $e) {
|
|
Log::error("Errore export cronologia: " . $e->getMessage());
|
|
return back()->with('error', 'Errore nell\'export: ' . $e->getMessage());
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Export CSV
|
|
*/
|
|
public function exportCSV($dati = null)
|
|
{
|
|
if (!$dati) {
|
|
$dati = $this->getCronologiaPerExport();
|
|
}
|
|
|
|
$filename = 'cronologia_stampe_' . date('Y-m-d_H-i-s') . '.csv';
|
|
$headers = [
|
|
'Content-Type' => 'text/csv',
|
|
'Content-Disposition' => 'attachment; filename="' . $filename . '"'
|
|
];
|
|
|
|
return response()->stream(function () use ($dati) {
|
|
$handle = fopen('php://output', 'w');
|
|
|
|
// Header CSV
|
|
fputcsv($handle, [
|
|
'ID',
|
|
'Data/Ora',
|
|
'Azione',
|
|
'Stampa',
|
|
'Utente',
|
|
'Dettagli',
|
|
'IP'
|
|
]);
|
|
|
|
// Dati
|
|
foreach ($dati as $record) {
|
|
fputcsv($handle, [
|
|
$record->id,
|
|
$record->created_at,
|
|
$record->action,
|
|
$record->stampa_nome ?? 'N/A',
|
|
$record->utente_nome ?? 'Sistema',
|
|
$record->dettagli,
|
|
$record->ip_address
|
|
]);
|
|
}
|
|
|
|
fclose($handle);
|
|
}, 200, $headers);
|
|
}
|
|
|
|
/**
|
|
* Export Excel
|
|
*/
|
|
public function exportExcel($dati = null)
|
|
{
|
|
// Implementazione Excel con PhpSpreadsheet se necessario
|
|
return $this->exportCSV($dati); // Fallback a CSV per ora
|
|
}
|
|
|
|
/**
|
|
* Cleanup cronologia vecchia
|
|
*/
|
|
public function cleanup(Request $request)
|
|
{
|
|
try {
|
|
$giorni = $request->get('giorni', 90);
|
|
$dataLimite = now()->subDays($giorni);
|
|
|
|
$this->hookManager->execute('stampe_rate.history.before_cleanup', [$giorni]);
|
|
|
|
$eliminati = DB::table('stampe_rate_history')
|
|
->where('created_at', '<', $dataLimite)
|
|
->delete();
|
|
|
|
// Cleanup email log
|
|
$emailEliminati = DB::table('stampe_rate_email_log')
|
|
->where('sent_at', '<', $dataLimite)
|
|
->delete();
|
|
|
|
$this->hookManager->execute('stampe_rate.history.after_cleanup', [$eliminati, $emailEliminati]);
|
|
|
|
// Invalida cache
|
|
Cache::tags(['stampe_rate_history'])->flush();
|
|
|
|
return response()->json([
|
|
'success' => true,
|
|
'message' => "Eliminati {$eliminati} record di cronologia e {$emailEliminati} log email"
|
|
]);
|
|
} catch (\Exception $e) {
|
|
Log::error("Errore cleanup cronologia: " . $e->getMessage());
|
|
return response()->json(['error' => 'Errore nel cleanup: ' . $e->getMessage()], 500);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Archivia cronologia vecchia
|
|
*/
|
|
public function archive(Request $request)
|
|
{
|
|
try {
|
|
$giorni = $request->get('giorni', 365);
|
|
$dataLimite = now()->subDays($giorni);
|
|
|
|
// Esporta prima di archiviare
|
|
$datiDaArchiviare = DB::table('stampe_rate_history')
|
|
->where('created_at', '<', $dataLimite)
|
|
->get();
|
|
|
|
if ($datiDaArchiviare->count() > 0) {
|
|
$archiveFile = 'archive_' . date('Y-m-d_H-i-s') . '.json';
|
|
$archivePath = 'archives/stampe_rate/' . $archiveFile;
|
|
|
|
Storage::disk('local')->put($archivePath, json_encode($datiDaArchiviare));
|
|
|
|
// Elimina i record archiviati
|
|
$eliminati = DB::table('stampe_rate_history')
|
|
->where('created_at', '<', $dataLimite)
|
|
->delete();
|
|
|
|
return response()->json([
|
|
'success' => true,
|
|
'message' => "Archiviati {$eliminati} record in {$archiveFile}"
|
|
]);
|
|
} else {
|
|
return response()->json([
|
|
'info' => 'Nessun record da archiviare'
|
|
]);
|
|
}
|
|
} catch (\Exception $e) {
|
|
Log::error("Errore archiviazione: " . $e->getMessage());
|
|
return response()->json(['error' => 'Errore nell\'archiviazione: ' . $e->getMessage()], 500);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Tracking apertura email (route pubblica)
|
|
*/
|
|
public function trackEmailOpen($trackingId)
|
|
{
|
|
try {
|
|
// Trova l'email log
|
|
$emailLog = DB::table('stampe_rate_email_log')
|
|
->where('tracking_id', $trackingId)
|
|
->first();
|
|
|
|
if ($emailLog && !$emailLog->opened_at) {
|
|
// Aggiorna apertura
|
|
DB::table('stampe_rate_email_log')
|
|
->where('id', $emailLog->id)
|
|
->update([
|
|
'opened_at' => now(),
|
|
'opened_ip' => request()->ip(),
|
|
'opened_user_agent' => request()->userAgent()
|
|
]);
|
|
|
|
// Log tracking
|
|
DB::table('stampe_rate_email_tracking')->insert([
|
|
'email_log_id' => $emailLog->id,
|
|
'action' => 'opened',
|
|
'tracked_at' => now(),
|
|
'ip_address' => request()->ip(),
|
|
'user_agent' => request()->userAgent()
|
|
]);
|
|
|
|
$this->hookManager->execute('stampe_rate.email.opened', [$emailLog->id]);
|
|
}
|
|
|
|
// Ritorna pixel 1x1 trasparente
|
|
return response(base64_decode('R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7'))
|
|
->header('Content-Type', 'image/gif')
|
|
->header('Cache-Control', 'no-cache, no-store, must-revalidate')
|
|
->header('Pragma', 'no-cache')
|
|
->header('Expires', '0');
|
|
} catch (\Exception $e) {
|
|
Log::error("Errore tracking email: " . $e->getMessage());
|
|
return response('', 200);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Tracking download allegati
|
|
*/
|
|
public function trackDownload($trackingId)
|
|
{
|
|
try {
|
|
// Implementa tracking download
|
|
DB::table('stampe_rate_email_tracking')->insert([
|
|
'tracking_id' => $trackingId,
|
|
'action' => 'download',
|
|
'tracked_at' => now(),
|
|
'ip_address' => request()->ip(),
|
|
'user_agent' => request()->userAgent()
|
|
]);
|
|
|
|
return response()->json(['tracked' => true]);
|
|
} catch (\Exception $e) {
|
|
Log::error("Errore tracking download: " . $e->getMessage());
|
|
return response()->json(['error' => false], 200);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Unsubscribe link
|
|
*/
|
|
public function unsubscribe($token)
|
|
{
|
|
try {
|
|
// Trova email dal token
|
|
$emailLog = DB::table('stampe_rate_email_log')
|
|
->where('unsubscribe_token', $token)
|
|
->first();
|
|
|
|
if ($emailLog) {
|
|
// Aggiorna stato unsubscribe
|
|
DB::table('stampe_rate_email_log')
|
|
->where('id', $emailLog->id)
|
|
->update(['unsubscribed_at' => now()]);
|
|
|
|
// Aggiungi a blacklist se necessario
|
|
DB::table('email_blacklist')->insertOrIgnore([
|
|
'email' => $emailLog->recipient_email,
|
|
'reason' => 'unsubscribed',
|
|
'created_at' => now()
|
|
]);
|
|
|
|
return view('modules.stampe-rate.unsubscribe-success');
|
|
} else {
|
|
return view('modules.stampe-rate.unsubscribe-error');
|
|
}
|
|
} catch (\Exception $e) {
|
|
Log::error("Errore unsubscribe: " . $e->getMessage());
|
|
return view('modules.stampe-rate.unsubscribe-error');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Webhook per status email esterni
|
|
*/
|
|
public function webhookEmailStatus(Request $request)
|
|
{
|
|
try {
|
|
$data = $request->all();
|
|
|
|
// Log webhook per debugging
|
|
Log::info("Webhook email status ricevuto", $data);
|
|
|
|
// Processa webhook in base al provider
|
|
if (isset($data['provider'])) {
|
|
switch ($data['provider']) {
|
|
case 'sendgrid':
|
|
$this->processaSendGridWebhook($data);
|
|
break;
|
|
case 'mailchimp':
|
|
$this->processaMailChimpWebhook($data);
|
|
break;
|
|
default:
|
|
Log::warning("Provider webhook sconosciuto: " . $data['provider']);
|
|
}
|
|
}
|
|
|
|
return response()->json(['status' => 'ok']);
|
|
} catch (\Exception $e) {
|
|
Log::error("Errore webhook email: " . $e->getMessage());
|
|
return response()->json(['error' => 'Webhook processing failed'], 500);
|
|
}
|
|
}
|
|
|
|
// Metodi di supporto privati
|
|
|
|
private function getStatsRapide()
|
|
{
|
|
return [
|
|
'azioni_oggi' => DB::table('stampe_rate_history')->whereDate('created_at', today())->count(),
|
|
'azioni_settimana' => DB::table('stampe_rate_history')->whereBetween('created_at', [now()->startOfWeek(), now()->endOfWeek()])->count(),
|
|
'errori_settimana' => DB::table('stampe_rate_history')->where('action', 'error')->whereBetween('created_at', [now()->startOfWeek(), now()->endOfWeek()])->count(),
|
|
'email_inviate_oggi' => DB::table('stampe_rate_email_log')->whereDate('sent_at', today())->count()
|
|
];
|
|
}
|
|
|
|
private function getGraficoStampeUltimi30Giorni()
|
|
{
|
|
return DB::table('stampe_rate')
|
|
->selectRaw('DATE(created_at) as data, COUNT(*) as count')
|
|
->where('created_at', '>=', now()->subDays(30))
|
|
->groupBy('data')
|
|
->orderBy('data')
|
|
->get();
|
|
}
|
|
|
|
private function getGraficoEmailUltimi30Giorni()
|
|
{
|
|
return DB::table('stampe_rate_email_log')
|
|
->selectRaw('DATE(sent_at) as data, COUNT(*) as inviate, COUNT(opened_at) as aperte')
|
|
->where('sent_at', '>=', now()->subDays(30))
|
|
->groupBy('data')
|
|
->orderBy('data')
|
|
->get();
|
|
}
|
|
|
|
private function calcolaTassoApertura()
|
|
{
|
|
$totali = DB::table('stampe_rate_email_log')->whereNotNull('sent_at')->count();
|
|
$aperte = DB::table('stampe_rate_email_log')->whereNotNull('opened_at')->count();
|
|
|
|
return $totali > 0 ? round(($aperte / $totali) * 100, 2) : 0;
|
|
}
|
|
|
|
private function calcolaTassoClick()
|
|
{
|
|
$totali = DB::table('stampe_rate_email_log')->whereNotNull('sent_at')->count();
|
|
$cliccate = DB::table('stampe_rate_email_log')->whereNotNull('clicked_at')->count();
|
|
|
|
return $totali > 0 ? round(($cliccate / $totali) * 100, 2) : 0;
|
|
}
|
|
|
|
private function generaReport($tipo, $dataInizio, $dataFine)
|
|
{
|
|
// Implementa generazione report base
|
|
return [
|
|
'periodo' => "{$dataInizio} - {$dataFine}",
|
|
'stampe_create' => DB::table('stampe_rate')->whereBetween('created_at', [$dataInizio, $dataFine])->count(),
|
|
'email_inviate' => DB::table('stampe_rate_email_log')->whereBetween('sent_at', [$dataInizio, $dataFine])->count()
|
|
];
|
|
}
|
|
|
|
private function getCronologiaPerExport($filtri = [])
|
|
{
|
|
$query = DB::table('stampe_rate_history as h')
|
|
->leftJoin('stampe_rate as s', 'h.stampa_id', '=', 's.id')
|
|
->leftJoin('users as u', 'h.created_by', '=', 'u.id')
|
|
->select([
|
|
'h.*',
|
|
's.nome as stampa_nome',
|
|
'u.name as utente_nome'
|
|
]);
|
|
|
|
// Applica filtri
|
|
foreach ($filtri as $campo => $valore) {
|
|
if ($valore) {
|
|
switch ($campo) {
|
|
case 'date_from':
|
|
$query->where('h.created_at', '>=', $valore);
|
|
break;
|
|
case 'date_to':
|
|
$query->where('h.created_at', '<=', $valore . ' 23:59:59');
|
|
break;
|
|
case 'action':
|
|
$query->where('h.action', $valore);
|
|
break;
|
|
case 'user_id':
|
|
$query->where('h.created_by', $valore);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
return $query->orderBy('h.created_at', 'desc')->get();
|
|
}
|
|
|
|
private function processaSendGridWebhook($data)
|
|
{
|
|
// Implementa processing SendGrid webhook
|
|
Log::info("Processing SendGrid webhook", $data);
|
|
}
|
|
|
|
private function processaMailChimpWebhook($data)
|
|
{
|
|
// Implementa processing MailChimp webhook
|
|
Log::info("Processing MailChimp webhook", $data);
|
|
}
|
|
|
|
/**
|
|
* API: Ottiene info tracking per AJAX
|
|
*/
|
|
public function getTrackingInfo($invioId)
|
|
{
|
|
try {
|
|
$info = DB::table('stampe_rate_email_log')
|
|
->where('id', $invioId)
|
|
->select(['sent_at', 'opened_at', 'clicked_at', 'failed_at'])
|
|
->first();
|
|
|
|
return response()->json(['tracking' => $info]);
|
|
} catch (\Exception $e) {
|
|
Log::error("Errore API tracking: " . $e->getMessage());
|
|
return response()->json(['error' => 'Errore nel caricamento tracking'], 500);
|
|
}
|
|
}
|
|
}
|