<?php
namespace App\EventSubscriber;
use App\Entity\Mission;
use App\Entity\SystemEmail;
use App\Entity\User;
use App\Enum\Role;
use App\Enum\Trigger;
use App\Event\Mission\ContactAddedEvent;
use App\Event\Mission\MissionAcceptedEvent;
use App\Event\Mission\MissionActivatedEvent;
use App\Event\Mission\MissionArchivedEvent;
use App\Event\Mission\MissionCancelledEvent;
use App\Event\Mission\MissionDesiredDeliveryUpdatedAfterValidationEvent;
use App\Event\Mission\MissionDesiredDeliveryUpdatedBeforeValidationEvent;
use App\Event\Mission\MissionInitialTimeEvent;
use App\Event\Mission\MissionRealTimeEvent;
use App\Event\Mission\MissionRefusedEvent;
use App\Event\Mission\MissionWithoutSubContractorCheckedEvent;
use App\Event\Mission\MissionWithoutWorkflowEvent;
use App\Repository\SystemEmailRepository;
use App\Repository\UserRepository;
use App\Service\NotificationService;
use App\Service\TriggerService;
use Symfony\Bridge\Twig\Mime\NotificationEmail;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Mailer\MailerInterface;
use Symfony\Component\Mime\Address;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Routing\RouterInterface;
use App\Event\Mission\MissionSendEvent;
use App\Repository\MissionParticipantRepository;
use App\Enum\AdminMail;
use App\Enum\Manager;
use App\Event\Admin\MissionNotificationActivatedEvent;
use App\Event\Mission\MissionCanActivateEvent;
use App\Event\Mission\MissionResendEvent;
use App\Service\MissionService;
use App\Service\StepsService;
use App\Service\WorkflowStepService;
use App\Service\RelanceService;
use Symfony\Component\Security\Core\Security;
use App\Event\Mission\MissionClosedEvent;
use Doctrine\ORM\EntityManagerInterface;
use App\Service\DynamicHostService;
class MissionSubscriber implements EventSubscriberInterface
{
public function __construct(
private MailerInterface $mailer,
private UserRepository $userRepository,
private RouterInterface $router,
private TriggerService $triggerService,
private SystemEmailRepository $systemEmailRepository,
private NotificationService $notificationService,
private MissionParticipantRepository $missionParticipantRepository,
private Security $security,
private WorkflowStepService $workflowStepService,
private StepsService $stepsService,
private MissionService $missionService,
private RelanceService $relanceService,
private EntityManagerInterface $entityManagerInterface,
private DynamicHostService $dynamicHostService,
){}
public static function getSubscribedEvents()
{
return [
MissionRefusedEvent::NAME => 'onMissionRefused',
MissionArchivedEvent::NAME => 'onMissionArchived',
MissionWithoutWorkflowEvent::NAME => 'onMissionWithoutWorkflow',
MissionCancelledEvent::NAME => 'onMissionCancelled',
MissionAcceptedEvent::NAME => 'onMissionAccepted',
MissionInitialTimeEvent::NAME => 'onMissionInitialTime',
MissionRealTimeEvent::NAME => 'onMissionRealTime',
MissionCanActivateEvent::NAME => 'onMissionCanActivateEvent',
ContactAddedEvent::NAME => 'onContactAdded',
MissionWithoutSubContractorCheckedEvent::NAME => 'onMissionWithoutSubContractorChecked',
MissionActivatedEvent::NAME => 'onMissionActivated',
MissionDesiredDeliveryUpdatedAfterValidationEvent::NAME => 'onMissionDesiredDeliveryUpdatedAfterValidation',
MissionDesiredDeliveryUpdatedBeforeValidationEvent::NAME => 'onMissionDesiredDeliveryUpdatedBeforeValidation',
MissionSendEvent::NAME => 'onMissionSend',
MissionResendEvent::NAME=>'onMissionResend',
MissionNotificationActivatedEvent::NAME=>'onMissionNotificationActivatedEvent',
MissionClosedEvent::NAME=>'onMissionClosedEvent'
];
}
public function onMissionClosedEvent(MissionClosedEvent $event){
$mission = $event->getMission();
$participant = $mission->getParticipants();
$listIdParticipant = [];
$email = $this->systemEmailRepository->findOneBy(['code' => SystemEmail::MISSION_FINISH]);
foreach ($mission->getParticipants() as $participant) {
if ($participant->getRole() === Role::ROLE_SUBCONTRACTOR
and !in_array($participant->getId(), $listIdParticipant) and $participant->getUser()->getSalary() != 1
) {
$user = $participant->getUser();
$this->notificationService->create($email, $user, $user, null, $mission->getWorkflow()?->getActiveStep(), $mission->getCampaign(),null,false,false,null,null,$mission);
$listIdParticipant[] = $participant->getId();
}
}
}
public function onMissionCanActivateEvent(MissionCanActivateEvent $missionCanActivateEvent){
$mission= $missionCanActivateEvent->getMission();
$marge= $missionCanActivateEvent->getMarge();
$refPanier = $mission->getReference();
$productName = $mission->getProduct()->getName();
$content = "Ce projet portant la référence $refPanier présente une marge ({$marge} %)insuffisante.
Nous vous invitons à modifier le panier ou à revoir la tarification des prestataires pour activer la mission (Produit: $productName )";
$admins = $this->dynamicHostService->getMailAdmin();
$addressFrom = new Address("caroline.b@my-flow.fr@my-flow.fr", "Myflow");
foreach ($admins as $admin){
$addressTo = new Address($admin->value);
$this->notificationService->sendEmail($addressFrom,$addressTo, "Projet avec marge insuffisante",$content);
}
}
public function onMissionNotificationActivatedEvent(MissionNotificationActivatedEvent $missionNotificationActivatedEvent)
{ // We commented this code because in line 263 NOTIFICATION_APRES_ACTIVATION is send to a subcontractor (onMissionNotificationActivatedEvent)
// $email = $this->systemEmailRepository->findOneBy(['code' => SystemEmail::NOTIFICATION_APRES_ACTIVATION]);
// foreach ($missionNotificationActivatedEvent->getMission()->getCampaign()->getCompany()->getUsers() as $user) {
// if($user->isEnabled()){
// $this->notificationService->create($email, $user, $user, $user->getCompany(),$missionNotificationActivatedEvent->getMission()->getWorkflow()?->getSteps()?->first());
// }
// }
}
public function onMissionSend(MissionSendEvent $event){
$user = $event->getUser();
$mission = $event->getMission();
$company = $mission->getCampaign()->getCompany();
if (!$mission instanceof Mission) {
return;
}
if (!$user instanceof User) {
return;
}
// if ((gettype($event->getRole()) != 'string' && trim($event->getRole()) == 'ROLE_VALIDATOR') || $event->getRole() == 'ROLE_VALIDATOR'){
// $email = $this->systemEmailRepository->findOneBy(['code' => SystemEmail::AJOUT_VALIDATEUR]);
// }else{
// $email = $this->systemEmailRepository->findOneBy(['code' => SystemEmail::AJOUT_OBSERVATEUR]);
// }
// if (null !== $email) {
// $this->notificationService->create($email, $user, $user, $company, $mission->getWorkflow()?->getActiveStep(), $mission->getCampaign());
// }
}
public function onMissionRefused(MissionRefusedEvent $event)
{
$mission = $event->getMission();
if (!$mission instanceof Mission) {
return;
}
$intervenant = $event->getIntervenant();
$email = $this->systemEmailRepository->findOneBy(['code' => SystemEmail::MISSION_REFUSEE_INTERVENANT]);
if (null !== $email) {
$this->notificationService->create($email, $intervenant, $intervenant, $mission->getCampaign()->getOrderedBy()->getCompany(), null, $mission->getCampaign(), null, false, false,null, null, $mission);
}
$admins = $this->dynamicHostService->getMailAdmin();
$email = $this->systemEmailRepository->findOneBy(['code' => SystemEmail::MISSION_REFUSEE_ADMIN]);
if (null !== $email) {
foreach ($admins as $admin) {
$this->notificationService->create($email, $admin->value, $intervenant, $mission->getCampaign()->getOrderedBy()->getCompany(), null, $mission->getCampaign(), null, false, false,null, null, $mission);
}
}
}
public function onMissionArchived(MissionArchivedEvent $event)
{
$mission = $event->getMission();
if (!$mission instanceof Mission) {
return;
}
foreach ($mission->getWorkflow()->getSteps()->last()->getActions() as $action) {
foreach ($action->getTriggers() as $trigger) {
if ($trigger->getTriggerType() === Trigger::MISSION_ARCHIVED) {
$this->triggerService->execute($trigger);
}
}
}
$email = $this->systemEmailRepository->findOneBy(['code' => SystemEmail::MISSION_ARCHIVED_CLIENT]);
if (null !== $email) {
$this->notificationService->create($email, $mission->getCampaign()->getOrderedBy(), $mission->getCampaign()->getOrderedBy(), $mission->getCampaign()->getOrderedBy()->getCompany(), null, $mission->getCampaign());
}
$email = $this->systemEmailRepository->findOneBy(['code' => SystemEmail::MISSION_ARCHIVED_PRESTATAIRE]);
if (null !== $email) {
foreach ($mission->getParticipants() as $participant) {
if ($participant->getRole() === Role::ROLE_SUBCONTRACTOR) {
$this->notificationService->create($email, $participant->getUser(), $participant->getUser(), $mission->getCampaign()->getOrderedBy()->getCompany(), null, $mission->getCampaign());
}
}
}
$admins = $this->dynamicHostService->getMailAdmin();
$email = $this->systemEmailRepository->findOneBy(['code' => SystemEmail::MISSION_ARCHIVED_ADMIN]);
if (null !== $email) {
foreach ($admins as $admin){
$this->notificationService->create($email, $admin->value, $mission->getCampaign()->getOrderedBy(), $mission->getCampaign()->getOrderedBy()->getCompany(), null, $mission->getCampaign());
}
}
}
public function onMissionWithoutWorkflow(MissionWithoutWorkflowEvent $event)
{
$mission = $event->getMission();
if (!$mission instanceof Mission) {
return;
}
$admins = $this->dynamicHostService->getMailAdmin();
foreach ($admins as $admin) {
$notification = (new NotificationEmail())
->to(new Address($admin->value))
->subject('Une mission a été créée sans workflow')
->content('
<p>Bonjour,</p>
<p>La mission '. $mission->getReference() .' contient un produit "'.$mission->getProduct()->getName().'" qui n\'a pas de Workflow associé.</p>
<p>Merci d\'en créer un pour ce produit et d\'aller le relier à la mission.</p>
')
->action('Modifier la mission', $this->router->generate('handle_mission_campaign', ['id' => $mission->getCampaign()->getId()], UrlGeneratorInterface::ABSOLUTE_URL))
->markAsPublic()
;
$this->mailer->send($notification);
}
}
public function onMissionDesiredDeliveryUpdatedAfterValidation(MissionDesiredDeliveryUpdatedAfterValidationEvent $event)
{
$mission = $event->getMission();
if (!$mission instanceof Mission) {
return;
}
// $email = $this->systemEmailRepository->findOneBy(['code' => SystemEmail::MISSION_DESIRED_DELIVERY_UPDATED_AFTER_VALIDATION]);
// $emailParticipants = [];
// foreach ($mission->getParticipants() as $participant) {
// $user= $participant->getUser();
// $emailUser = $user->getEmail();
// if(!in_array($emailUser, $emailParticipants) && ! $this->security->isGranted('ROLE_SUBCONTRACTOR')){
// $this->notificationService->create($email, $user, $user, $mission->getCampaign()->getOrderedBy()->getCompany(), null, $mission->getCampaign());
// $emailParticipants=[...$emailParticipants, $emailUser];
// }
// }
// if (null !== $email && [...$emailParticipants, $mission->getCampaign()->getOrderedBy()->getEmail()]) {
// $this->notificationService->create($email, $mission->getCampaign()->getOrderedBy(), $mission->getCampaign()->getOrderedBy(), $mission->getCampaign()->getOrderedBy()->getCompany(), null, $mission->getCampaign());
// }
}
public function onMissionDesiredDeliveryUpdatedBeforeValidation(MissionDesiredDeliveryUpdatedBeforeValidationEvent $event)
{
$mission = $event->getMission();
if (!$mission instanceof Mission) {
return;
}
$email = $this->systemEmailRepository->findOneBy(['code' => SystemEmail::MISSION_DESIRED_DELIVERY_UPDATED_BEFORE_VALIDATION]);
if (null !== $email) {
$this->notificationService->create($email, $mission->getCampaign()->getOrderedBy(), $mission->getCampaign()->getOrderedBy(), $mission->getCampaign()->getOrderedBy()->getCompany(), null, $mission->getCampaign());
}
}
public function onMissionCancelled(MissionCancelledEvent $event)
{
$mission = $event->getMission();
if (!$mission instanceof Mission) {
return;
}
$email = $this->systemEmailRepository->findOneBy(['code' => SystemEmail::MISSION_CANCELLED]);
if (null !== $email) {
$this->notificationService->create($email, $mission->getCampaign()->getOrderedBy(), $mission->getCampaign()->getOrderedBy(), $mission->getCampaign()->getOrderedBy()->getCompany(),null,null,null,false,false,null,null,$mission);
$admins = $this->dynamicHostService->getMailAdmin();
foreach ($admins as $admin) {
$this->notificationService->create($email, $admin->value, $mission->getCampaign()->getOrderedBy(), $mission->getCampaign()->getOrderedBy()->getCompany(),null,null,null,false,false,null,null,$mission);
}
}
}
public function onMissionAccepted(MissionAcceptedEvent $event)
{
$mission = $event->getMission();
if (!$mission instanceof Mission) {
return;
}
$intervenant = $event->getIntervenant();
$emailClient = $this->systemEmailRepository->findOneBy(['code' => SystemEmail::NOTIFICATION_APRES_ACTIVATION]);
if (null !== $emailClient) {
if(in_array("ROLE_SUBCONTRACTOR",$intervenant->getRoles())){
$this->notificationService->create($emailClient, $intervenant, $intervenant, $mission->getCampaign()->getOrderedBy()->getCompany(),null,$mission->getCampaign());
}
}
$email = $this->systemEmailRepository->findOneBy(['code' => SystemEmail::MISSION_ACTIVER_CLIENT]);
if (null !== $email) {
$this->notificationService->create($email, $mission->getCampaign()->getOrderedBy(), $mission->getCampaign()->getOrderedBy(), $mission->getCampaign()->getOrderedBy()->getCompany(),null,$mission->getCampaign());
}
}
public function onMissionInitialTime(MissionInitialTimeEvent $event)
{
$mission = $event->getMission();
if (!$mission instanceof Mission) {
return;
}
$admins = $this->dynamicHostService->getMailAdmin();
foreach ($admins as $admin) {
$notification = (new NotificationEmail())
->to(new Address($admin->value))
->subject('Un intervenant vient d\'ajouter le temps initial d\'une mission')
->content('
<p>Bonjour,</p>
<p>Le temps initial pour la mission '. $mission->getCampaign()->getName() .' vient d\'être ajouté</p>
')
->action('Voir la mission', $this->router->generate('mission_edit', ['id' => $mission->getId()], UrlGeneratorInterface::ABSOLUTE_URL))
->markAsPublic()
;
try {
$this->mailer->send($notification);
} catch (\Exception $e) { /* TODO: logger ou afficher une alerte que l'email n'a pas été envoyé */ }
}
}
public function onMissionRealTime(MissionRealTimeEvent $event)
{
$mission = $event->getMission();
if (!$mission instanceof Mission) {
return;
}
$emailSystem = $this->systemEmailRepository->findOneBy(['code' => SystemEmail::RENSEIGNEZ_TEMPS_MISSION]);
if (null !== $emailSystem) {
foreach ($mission->getParticipants() as $participant) {
if ($participant->getRole() === Role::ROLE_SUBCONTRACTOR) {
$this->notificationService->create($emailSystem, $participant->getUser(), $participant->getUser(), $mission->getCampaign()->getOrderedBy()->getCompany(), null, $mission->getCampaign());
}
}
}
}
public function onContactAdded(ContactAddedEvent $event)
{
$contact = $event->getContact();
if (!$contact instanceof User || !$contact->isEnabled()) {
return;
}
if ($event->getParticipant()->getRole() == Role::ROLE_VALIDATOR){
$email = $this->systemEmailRepository->findOneBy(['code' => SystemEmail::AJOUT_VALIDATEUR]);
}else{
$email = $this->systemEmailRepository->findOneBy(['code' => SystemEmail::AJOUT_OBSERVATEUR]);
}
if (null !== $email) {
$this->notificationService->create($email, $contact, $contact, $contact->getCompany(), false, $event->getMission()->getCampaign());
}
$contact->setAutorizationDateAt(new \DateTimeImmutable());
$this->entityManagerInterface->flush();
}
public function onMissionActivated(MissionActivatedEvent $event)
{
$mission = $event->getMission();
$client = $event->getClient();
if (!$mission instanceof Mission) {
return;
}
$email = $this->systemEmailRepository->findOneBy(['code' => SystemEmail::MISSION_ACTIVER_CLIENT]);
if (null !== $email) {
$this->notificationService->create($email, $client, $client, $client->getCompany(), $mission->getWorkflow()?->getSteps()?->first());
}
}
public function onMissionWithoutSubContractorChecked(MissionWithoutSubContractorCheckedEvent $event)
{
$mission = $event->getMission();
if (!$mission instanceof Mission) {
return;
}
$email = $this->systemEmailRepository->findOneBy(['code' => SystemEmail::MISSION_SANS_PARTENAIRE]);
if (null !== $email) {
/* $this->notificationService->create($email, 'admin@my-flow.fr', $mission->getCampaign()->getOrderedBy(), $mission->getCampaign()->getOrderedBy()->getCompany());*/
if (null !== $email->getSmsContent()) {
$admins = $this->dynamicHostService->getMailAdmin();
foreach ($admins as $admin) {
$this->notificationService->create($email, $admin->value, $mission->getCampaign()->getOrderedBy(), $mission->getCampaign()->getOrderedBy()->getCompany(), null, null, null, true);
}
}
}
}
public function onMissionResend(MissionResendEvent $missionResendEvent){
$this->relanceService->sendMailForResponsableStep(mission: $missionResendEvent->getMission());
}
}