notifService = $notifService; } /** * Al CREAR un partido: notificar a todos los seguidores de ambos equipos. */ public function created(Evento $evento): void { if (!$evento->id_equipo_local || !$evento->id_equipo_visitante) return; $evento->load(['equipoLocal.club', 'equipoVisitante.club']); $nombreLocal = $evento->equipoLocal->club->nombre ?? '?'; $nombreVisitante= $evento->equipoVisitante->club->nombre ?? '?'; $fechaStr = $evento->fecha_evento ? $evento->fecha_evento->format('d/m/Y') : '—'; $horaStr = $evento->hora_inicio ? \Carbon\Carbon::parse($evento->hora_inicio)->format('H:i') : ''; $sedeStr = $evento->sede ? " en {$evento->sede}" : ''; $titulo = "🏀 Nuevo Partido Programado"; $mensaje = "{$nombreLocal} vs {$nombreVisitante} — {$fechaStr}" . ($horaStr ? " a las {$horaStr}" : '') . $sedeStr . '.'; $url = '/eventos/' . $evento->id_evento; $this->notificarSeguidoresDeEquipos( [$evento->id_equipo_local, $evento->id_equipo_visitante], 'partido', $titulo, $mensaje, $url ); } /** * Al ACTUALIZAR un partido: si cambia el marcador, notificar resultado. */ public function updated(Evento $evento): void { $dirty = $evento->getDirty(); // Solo disparar si se actualizó el marcador if (!array_key_exists('marcador_local', $dirty) && !array_key_exists('marcador_visitante', $dirty)) { return; } if ($evento->marcador_local === null || $evento->marcador_visitante === null) return; // Validación Horaria (Buenos Aires) $tz = 'America/Argentina/Buenos_Aires'; $ahora = \Carbon\Carbon::now($tz); // El usuario solicita que se emita cuando fin > real $fecha = $evento->fecha_evento instanceof \Carbon\Carbon ? $evento->fecha_evento->format('Y-m-d') : substr($evento->fecha_evento, 0, 10); $horaFin = $evento->hora_fin instanceof \Carbon\Carbon ? $evento->hora_fin->format('H:i:s') : $evento->hora_fin; $fin = \Carbon\Carbon::createFromFormat('Y-m-d H:i:s', "{$fecha} {$horaFin}", $tz); if (!($fin->gt($ahora))) { return; } $evento->load(['equipoLocal.club', 'equipoVisitante.club']); $nombreLocal = $evento->equipoLocal->club->nombre ?? '?'; $nombreVisitante = $evento->equipoVisitante->club->nombre ?? '?'; $mloc = $evento->marcador_local; $mvis = $evento->marcador_visitante; if ($mloc > $mvis) { $resultado = "🏆 Ganó {$nombreLocal}"; } elseif ($mvis > $mloc) { $resultado = "🏆 Ganó {$nombreVisitante}"; } else { $resultado = "🤝 Empate"; } $titulo = "Resultado: {$nombreLocal} {$mloc} - {$mvis} {$nombreVisitante}"; $mensaje = "{$resultado}. Partido finalizado."; $url = '/eventos/' . $evento->id_evento; $this->notificarSeguidoresDeEquipos( [$evento->id_equipo_local, $evento->id_equipo_visitante], 'resultado', $titulo, $mensaje, $url ); } /** * Obtiene todos los seguidores de una lista de equipos y envía notificaciones. * También incluye a los jugadores de esos equipos automáticamente. */ private function notificarSeguidoresDeEquipos(array $idEquipos, string $tipo, string $titulo, string $mensaje, ?string $url): void { $idEquipos = array_filter($idEquipos); if (empty($idEquipos)) return; $destinatarios = []; $yaAgregados = []; // Seguidores registrados en equipo_seguimiento $seguimientos = EquipoSeguimiento::whereIn('id_equipo', $idEquipos)->get(); foreach ($seguimientos as $s) { $key = $s->tipo_usuario . ':' . $s->id_usuario; if (!isset($yaAgregados[$key])) { $destinatarios[] = ['tipo' => $s->tipo_usuario, 'id' => $s->id_usuario]; $yaAgregados[$key] = true; } } // Jugadores que pertenecen a estos equipos (siguen automáticamente) $jugadores = \DB::table('jugador_equipo') ->whereIn('id_equipo', $idEquipos) ->pluck('id_jugador'); foreach ($jugadores as $idJ) { $key = 'jugador:' . $idJ; if (!isset($yaAgregados[$key])) { $destinatarios[] = ['tipo' => 'jugador', 'id' => $idJ]; $yaAgregados[$key] = true; } } if (!empty($destinatarios)) { $this->notifService->enviarMasivo($destinatarios, $tipo, $titulo, $mensaje, $url); } } }