<?php
namespace App\EventSubscriber;
use App\Entity\Aviso;
use App\Enum\TipoAvisoEnum;
use App\Interfaces\AvisoRepositoryInterface;
use App\Interfaces\ParticipanteGrupoDetalleRepositoryInterface;
use App\Services\AsymmetricEncryptionService;
use App\Services\DiplomaGeneratorService;
use App\Services\EventDomain\CuestionarioChangedEvent;
use Psr\Log\LoggerInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
class CuestionarioEventSubscriber implements EventSubscriberInterface
{
public function __construct(
private AsymmetricEncryptionService $asymmetricEncryptionService,
private AvisoRepositoryInterface $avisoRepository,
private TranslatorInterface $translator,
private UrlGeneratorInterface $urlGenerator,
private DiplomaGeneratorService $diplomaGeneratorService,
private ParticipanteGrupoDetalleRepositoryInterface $participanteGrupoDetalleRepository,
private LoggerInterface $logger,
)
{
}
public static function getSubscribedEvents()
{
return [
CuestionarioChangedEvent::class => 'onChangedCuestionario',
];
}
public function onChangedCuestionario(CuestionarioChangedEvent $event): void
{
$cuestionario = $event->getCuestionario();
$aviso = new Aviso();
$aviso->setTipo(TipoAvisoEnum::AVISO_CUESTIONARIO);
$aviso->setFecha($cuestionario->getCreatedAt());
$aviso->setAsunto($this->translator->trans('new.ads.cuestionario', [], 'ads'));
$aviso->setPropietarioContenido($cuestionario->getParticipantesGrupo()->getParticipanteGrupoDetalle()->getParticipante());
$aviso->setObject($cuestionario);
$aviso->setDeletedAt(null);
$token = $this->asymmetricEncryptionService->hybridEncrypt([
'tipoAviso' => TipoAvisoEnum::AVISO_CUESTIONARIO,
'propietarioId' => $aviso->getPropietarioContenido()?->getId(),
'url' => $this->urlGenerator->generate('cuestionarios_pendientes', [], UrlGeneratorInterface::ABSOLUTE_URL),
]);
$aviso->setTokenHash($token);
$this->avisoRepository->save($aviso);
// Generar certificado automáticamente tras completar el cuestionario
try {
// 1. Obtener el participante asociado al cuestionario.
$participanteGrupoDetalle = $cuestionario->getParticipantesGrupo()?->getParticipanteGrupoDetalle();
if (!$participanteGrupoDetalle) {
// Log de advertencia si no se encuentra el participante y salir.
$this->logger->warning('No se encontró un ParticipanteGrupoDetalle para el Cuestionario ID: ' . $cuestionario->getId());
return;
}
// 2. Actualizar el estado del participante a "Finalizado".
// (Se ha confirmado que completar el cuestionario es suficiente para aprobar).
$participanteGrupoDetalle->setEstadoFinalizacion('F');
$participanteGrupoDetalle->setCertificar(true);
// 3. Guardar los cambios en la base de datos.
$this->participanteGrupoDetalleRepository->save($participanteGrupoDetalle);
// 4. Invocar el servicio para generar el diploma.
$this->diplomaGeneratorService->generateDiplomaForParticipante($participanteGrupoDetalle);
} catch (\Exception $e) {
// Log del error para poder depurarlo sin detener el flujo.
$this->logger->error('Error al generar el diploma tras completar el cuestionario: ' . $e->getMessage(), [
'cuestionarioId' => $cuestionario->getId(),
'exception' => $e
]);
}
}
}