Files
OnAPB-Carrere_Demartin/app/Console/Commands/ReporteSemanal.php
T
2026-06-04 14:47:50 -03:00

107 lines
4.3 KiB
PHP

<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use App\Models\Evento;
use App\Models\Configuracion;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\DB;
use Carbon\Carbon;
class ReporteSemanal extends Command
{
protected $signature = 'reportes:semanal {--dry-run : Solo muestra el contenido sin enviar}';
protected $description = 'Genera y envía el reporte semanal de actividad a los administradores';
public function handle(): int
{
$ahora = Carbon::now();
$semanaAnteriorDesde = $ahora->copy()->subDays(7)->startOfDay();
$semanaAnteriorHasta = $ahora->copy()->subDay()->endOfDay();
$proximaSemanaHasta = $ahora->copy()->addDays(7)->endOfDay();
// ── Partidos jugados la semana anterior ──
$jugados = Evento::with(['equipoLocal.club', 'equipoVisitante.club'])
->whereBetween('fecha_evento', [$semanaAnteriorDesde->toDateString(), $semanaAnteriorHasta->toDateString()])
->whereNotNull('marcador_local')
->get();
// ── Próximos partidos ──
$proximos = Evento::with(['equipoLocal.club', 'equipoVisitante.club'])
->where('fecha_evento', '>=', $ahora->toDateString())
->where('fecha_evento', '<=', $proximaSemanaHasta->toDateString())
->orderBy('fecha_evento')
->orderBy('hora_inicio')
->get();
// ── Top goleadores ──
$topGoleadores = DB::table('evento_jugador')
->join('jugadores', 'evento_jugador.id_jugador', '=', 'jugadores.id_jugador')
->selectRaw('jugadores.nombre, jugadores.apellido, SUM(evento_jugador.puntos) as total_puntos, COUNT(evento_jugador.id_evento) as partidos')
->groupBy('jugadores.id_jugador', 'jugadores.nombre', 'jugadores.apellido')
->orderByDesc('total_puntos')
->limit(10)
->get();
// ── QRs de la semana ──
$qrsSemana = DB::table('qr_codes')
->where('creado', '>=', $semanaAnteriorDesde)
->count();
$qrsValidados = DB::table('qr_codes')
->where('creado', '>=', $semanaAnteriorDesde)
->where('escaneos_restantes', 0)
->count();
$data = compact('jugados', 'proximos', 'topGoleadores', 'qrsSemana', 'qrsValidados', 'semanaAnteriorDesde', 'semanaAnteriorHasta');
if ($this->option('dry-run')) {
$this->info('=== REPORTE SEMANAL (DRY RUN) ===');
$this->line("Partidos jugados: {$jugados->count()}");
$this->line("Próximos partidos: {$proximos->count()}");
$this->line("Top goleador: " . ($topGoleadores->first() ? $topGoleadores->first()->apellido . ' (' . $topGoleadores->first()->total_puntos . ' pts)' : 'N/A'));
$this->line("QRs generados: {$qrsSemana} | Validados: {$qrsValidados}");
return self::SUCCESS;
}
// 1. Priorizar email configurado en sistema
$emails = [];
$configEmail = \App\Models\Configuracion::get('email_reportes');
if ($configEmail) {
$emails[] = $configEmail;
}
// 2. Si no hay, buscar superadmins (rol=1)
if (empty($emails)) {
$emails = DB::table('admin_users')->where('rol', 1)->whereNotNull('email')->pluck('email')->toArray();
}
// 3. Fallback: email del .env
if (empty($emails)) {
$fallback = config('mail.from.address');
if ($fallback) $emails = [$fallback];
}
if (empty($emails)) {
$this->error('No hay destinatarios configurados para enviar el reporte.');
return self::FAILURE;
}
try {
Mail::send('emails.reporte_semanal', $data, function ($mail) use ($emails, $ahora) {
$mail->to($emails)
->subject("📊 Reporte Semanal ONAPB — Semana del " . $ahora->startOfWeek()->format('d/m'));
});
$this->info("✅ Reporte enviado a: " . implode(', ', $emails));
} catch (\Exception $e) {
Log::error('Error enviando reporte semanal: ' . $e->getMessage());
$this->error('Error: ' . $e->getMessage());
return self::FAILURE;
}
return self::SUCCESS;
}
}