<?php
namespace App\Controller;
use DateTime;
use Mpdf\Mpdf;
use DateInterval;
use DateTimeZone;
use App\Library\GraphUser;
use App\Service\Securizer;
use App\Entity\Intervention;
use App\Entity\LigneDeContrat;
use App\Repository\StatusRepository;
use App\Repository\ActionsRepository;
use App\Repository\ClientsRepository;
use App\Repository\ContactsRepository;
use App\Repository\ContratsRepository;
use Doctrine\ORM\EntityManagerInterface;
use App\Repository\InterventionRepository;
use App\Repository\LigneDeContratRepository;
use Symfony\Component\HttpFoundation\Request;
use App\Repository\TypeInterventionRepository;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Serializer\SerializerInterface;
use Symfony\Component\Validator\Validator\ValidatorInterface;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface;
require_once realpath(__DIR__ . '/../../vendor/autoload.php');
class InterventionController extends AbstractController
{
/**
* @IsGranted("ROLE_USER")
*/
public function index($year, AccessDecisionManagerInterface $accessDecisionManager, InterventionRepository $repoIntervention, ContratsRepository $repoContrat, LigneDeContratRepository $repoLigneContrat): Response
{
//retourne liste des interventions par année
$securizer = new Securizer($accessDecisionManager);
$interventions = $repoIntervention->findInterventions($this->getUser(), $securizer, $repoContrat, $repoLigneContrat);
$res = [];
foreach ($interventions as $key => $value) {
$date = date('Y', $value->getDateInterventionTimestamp());
if ($date === $year)
$res[] = $value;
}
return $this->json($res, 200, [], ['groups' => 'affichageIntervention']);
}
/**
* @IsGranted("ROLE_USER")
*/
public function voir($id, InterventionRepository $repoIntervention, ContratsRepository $repoContrat, AccessDecisionManagerInterface $accessDecisionManager, LigneDeContratRepository $repoLigneContrat): Response
{
//voir une intervention
$securizer = new Securizer($accessDecisionManager);
$interventions = $repoIntervention->findInterventions($this->getUser(), $securizer, $repoContrat, $repoLigneContrat);
//verifi que l'intervention que l'on cherche fait bien partie de la liste de ceux qu'il est possible d'afficher
if (in_array($repoIntervention->find($id), $interventions)) {
$intervention = $repoIntervention->find($id);
} else {
return $this->json([
'status' => 400,
'message' => "Vous ne pouvez pas consulter cette intervention"
], 400);
}
return $this->json($intervention, 200, [], ['groups' => 'affichageIntervention']);
}
/**
* @IsGranted("ROLE_TECH")
*/
public function getByLigne($id, InterventionRepository $repoIntervention, ContratsRepository $repoContrat, ContactsRepository $repoContact, AccessDecisionManagerInterface $accessDecisionManager, LigneDeContratRepository $repoLigneContrat): Response
{
//voir une intervention
$securizer = new Securizer($accessDecisionManager);
if (!$securizer->isGranted($this->getUser(), "ROLE_TECH")) {
$ligneContrat = $repoLigneContrat->find($id);
$contact = $repoContact->findOneBy(['mail' => $this->getUser()->getUserIdentifier()]);
if ($ligneContrat->getIdContrat()->getIdClient() !== $contact->getIdClient()) {
return $this->json([
'status' => 400,
'message' => "Vous ne pouvez pas consulter cette intervention"
], 400);
}
}
$interventions = $repoIntervention->findBy(['idLigneContrat' => $id]);
return $this->json($interventions, 200, [], ['groups' => 'affichageInterventionLigne']);
}
/**
* @IsGranted("ROLE_CLIENT")
*/
public function getResumeClient(ClientsRepository $repoClient, ContratsRepository $repoContrat, AccessDecisionManagerInterface $accessDecisionManager): Response
{
$securizer = new Securizer($accessDecisionManager);
$clients = $repoClient->findClientTous($this->getUser(), $securizer);
$client = $clients[0];
$contrats = $repoContrat->getContratsActifBy($client->getId());
$data = [
'Preventive' => ['Cloture' => 0, 'En Cours' => 0, 'Programmer' => 0],
'Curative' => ['Cloture' => 0, 'En Cours' => 0, 'Programmer' => 0],
'Télémaintenance' => ['rest' => 0, 'spent' => 0],
'nextInterventions' => [],
];
$today = new DateTime();
foreach ($contrats as $contrat) {
foreach ($contrat->getLigneDeContrats() as $ligne) {
if ($ligne->getIdTypeIntervention()->gettype() === "Télémaintenance") {
$data["Télémaintenance"]['spent'] += $ligne->getQuantiteConsome();
$data["Télémaintenance"]['rest'] += ($ligne->getQuantitePrevus() - $ligne->getQuantiteConsome());
} else {
foreach ($ligne->getInterventions() as $interv) {
if (isset($data[$ligne->getIdTypeIntervention()->gettype()][$interv->getIdStatus()->getStatus()])) $data[$ligne->getIdTypeIntervention()->gettype()][$interv->getIdStatus()->getStatus()] += 1;
if ($interv->getDateInterventionTimestamp() > $today->getTimestamp())
array_push($data['nextInterventions'], ['date' => $interv->getDateInterventionTimestamp(), 'tech' => $interv->getTechPrevus()]);
}
}
}
}
return $this->json($data, 200, [], ['groups' => 'affichageIntervention']);
}
/**
* @IsGranted("ROLE_TECH")
*/
public function creer(Request $request, StatusRepository $repoStatus, ValidatorInterface $validator, SerializerInterface $serializer, EntityManagerInterface $manager, ClientsRepository $repoClient, Securizer $securizer): Response
{
//creer une nouvelle intervention, seul les role tech ou superieur peuvent acceder a cette page
$clients = $repoClient->findClientActif($this->getUser(), $securizer);
$jsonRecu = $request->getContent();
try {
//transforme le json reçu en entity
$intervention = $serializer->deserialize($jsonRecu, Intervention::class, 'json');
if (in_array($intervention->getIdLigneContrat()->getIdContrat()->getIdClient(), $clients)) {
$date = new DateTime();
$intervention->setCreateur($this->getUser())
->setDateCreation($date)
->setIdStatus($repoStatus->findOneBy(['status' => 'Programmer']));
$ligneContrat = $intervention->getIdLigneContrat();
$ligneContrat->setQuantiteConsome($intervention->getIdLigneContrat()->getQuantiteConsome() + 1);
//validation des données reçus
//liste les erreur de validation deffini dans les entitées
$errors = $validator->validate($intervention);
if (count($errors) > 0) {
return $this->json($errors, 400);
}
// check if create event in json
$jsonRecu = json_decode($jsonRecu);
$graphUser = new GraphUser();
// recuperer graph id du technicien
$techReferent = $intervention->getTechPrevus();
$users = $graphUser->getUsers();
$idUserGraph = null;
foreach ($users as $key => $value) {
if ($value->getMail() === $techReferent->getMail()) {
$idUserGraph = $value->getId();
break;
}
}
if (isset($idUserGraph)) {
$dateStart = $jsonRecu->dateIntervention . " " . ($jsonRecu->momentOfTheDay->value == "morning" ? "08:30:00" : "14:00:00");
$dateFin = $jsonRecu->dateIntervention . " " . ($jsonRecu->momentOfTheDay->value == "morning" ? "12:30:00" : "18:00:00");
$client = $ligneContrat->getIdContrat()->getIdClient();
// call create event function
$eventId = $graphUser->addEventUserDefaultCalendar($idUserGraph, $dateStart, $dateFin, $jsonRecu->titre, $jsonRecu->description, $client->getAdresse() . ", " . $client->getVille() . " " . $client->getCodePostal(), 1.0);
// recuperer event id
$eventId = $eventId->getBody()['id'];
// save id in $intervention
$intervention->setCalendarEventId($eventId);
}
$manager->persist($intervention);
$manager->flush();
} else {
return $this->json([
'status' => 400,
'message' => "Vous ne pouvez pas lier d'intervention à ce contact"
], 400);
}
} catch (\throwable $e) {
return $this->json([
'status' => 400,
'message' => $e->getMessage()
], 400);
}
return $this->json($intervention, 201, [], ['groups' => 'affichageIntervention']);
}
/**
* @IsGranted("ROLE_TECH")
*/
public function modif($id, Request $request, InterventionRepository $repoIntervention, ContactsRepository $repoContacts, ValidatorInterface $validator, SerializerInterface $serializer, EntityManagerInterface $manager): Response
{
//modifi une intervention existant, seul les role tech ou superieur peuvent acceder a cette url
$intervention = $repoIntervention->find($id);
$clientsDepart = $intervention->getIdLigneContrat()->getIdContrat()->getIdClient();
if ($intervention == null) {
return $this->json([
'status' => 400,
'message' => "l'intervention à modifier n'existe pas"
], 400);
}
$jsonRecu = $request->getContent();
try {
$eventId = $intervention->getCalendarEventId();
if (isset(json_decode($jsonRecu)->techPrevus) && json_decode($jsonRecu)->techPrevus !== $intervention->getTechPrevus()->getId() && isset($eventId)) {
$prevTech = $intervention->getTechPrevus();
$newTech = $repoContacts->find(json_decode($jsonRecu)->techPrevus);
if (!isset($newTech) || !in_array("ROLE_TECH", $newTech->getRoles())) {
return $this->json([
'status' => 400,
'message' => "le nouveau technicien n'est pas valide"
], 400);
}
$graphUser = new GraphUser();
$users = $graphUser->getUsers();
$idPrevTech = null;
$idNewTech = null;
foreach ($users as $key => $value) {
if ($value->getMail() === $prevTech->getMail()) {
$idPrevTech = $value->getId();
} else if ($value->getMail() === $newTech->getMail()) {
$idNewTech = $value->getId();
}
}
if (!isset($idPrevTech) || !isset($idNewTech))
return $this->json([
'status' => 400,
'message' => "Il y a une erreur de synchronisation du calendrier"
], 400);
// Prev event
try {
$prevEvent = $graphUser->getCalendarEvent($idPrevTech, $eventId);
$subject = $prevEvent->getBody()["subject"];
$description = $prevEvent->getBody()["bodyPreview"];
$location = $prevEvent->getBody()["location"]["displayName"];
$time = $prevEvent->getBody()["reminderMinutesBeforeStart"] / 60;
$dateStart = new DateTime($prevEvent->getBody()["start"]["dateTime"], new DateTimeZone("Europe/Paris"));
$dateStart->add(new DateInterval("PT1H"));
$dateStart = $dateStart->format('Y-m-d H:i:s');
$dateFin = new DateTime($prevEvent->getBody()["end"]["dateTime"], new DateTimeZone("Europe/Paris"));
$dateFin->add(new DateInterval("PT1H"));
$dateFin = $dateFin->format('Y-m-d H:i:s');
// Suprimmer event
$graphUser->deleteEventCalendar($idPrevTech, $eventId);
} catch (\throwable $e) {
$dateStart = $intervention->getDateIntervention()->format('Y-m-d') . " 08:30:00";
$dateFin = $intervention->getDateIntervention()->format('Y-m-d') . " 12:30:00";
$client = $intervention->getIdLigneContrat()->getIdContrat()->getIdClient();
$subject = $intervention->getTitre();
$description = $intervention->getDescription();
$location = $client->getAdresse() . ", " . $client->getVille() . " " . $client->getCodePostal();
$time = 1.0;
}
// call create event function
$eventId = $graphUser->addEventUserDefaultCalendar($idNewTech, $dateStart, $dateFin, $subject, $description, $location, $time);
// recuperer event id
$eventId = $eventId->getBody()['id'];
// save id in $intervention
$intervention->setCalendarEventId($eventId);
}
//transforme le json reçu en entity
$serializer->deserialize($jsonRecu, Intervention::class, 'json', ['object_to_populate' => $intervention]);
if ($intervention->getIdLigneContrat()->getIdContrat()->getIdClient() == $clientsDepart) {
$errors = $validator->validate($intervention);
if (count($errors) > 0) {
return $this->json($errors, 400);
}
$manager->persist($intervention);
if ($intervention->getIdStatus()->getStatus() == 'Cloture') {
//recupère la ligne de contrat de l'intervention et mettre a jour qteConsome / qtePrevus
$ligneContrat = $intervention->getIdLigneContrat();
$actions = $intervention->getActions();
$dureeTotale = 0;
foreach ($actions as $action) {
$dureeTotale = $dureeTotale + $action->getDuree();
}
$quantiteConsome = $ligneContrat->getQuantiteConsome() + $dureeTotale;
$ligneContrat = $ligneContrat->setQuantiteConsome($quantiteConsome);
$manager->persist($ligneContrat);
}
$manager->flush();
} else {
return $this->json([
'status' => 400,
'message' => "Vous ne pouvez pas modifier le client d'une intervention"
], 400);
}
} catch (\throwable $e) {
return $this->json([
'status' => 400,
'message' => $e->getMessage()
], 400);
}
return $this->json($intervention, 201, [], ['groups' => 'affichageIntervention']);
}
/**
* @IsGranted("ROLE_TECH")
*/
public function delete($id, InterventionRepository $repoIntervention): Response
{
//Permets de supprimer une intervention
$intervention = $repoIntervention->find($id);
if ($intervention == null) {
return $this->json([
'status' => 400,
'message' => "l'intervention à supprimer n'existe pas"
], 400);
}
if ($intervention->getIdStatus()->getStatus() != "Programmer") {
return $this->json([
'status' => 400,
'message' => "l'intervention ne peut pas être supprimé car il a pas un état 'Programmer'"
], 400);
}
$ligneContrat = $intervention->getIdLigneContrat();
$ligneContrat->setQuantiteConsome($ligneContrat->getQuantiteConsome() - 1);
//Remove calendrier id si exist
$eventId = $intervention->getCalendarEventId();
if (isset($eventId)) {
$graphUser = new GraphUser();
$techReferent = $intervention->getTechPrevus();
$users = $graphUser->getUsers();
$idUserGraph = null;
foreach ($users as $key => $value) {
if ($value->getMail() === $techReferent->getMail()) {
$idUserGraph = $value->getId();
break;
}
}
if (isset($idUserGraph)) {
try {
$graphUser->deleteEventCalendar($idUserGraph, $eventId);
} catch (\Throwable $th) {
}
}
}
$repoIntervention->remove($intervention);
return $this->json(true, 200, [], ['groups' => 'affichageIntervention']);
}
/**
* @IsGranted("ROLE_TECH")
*/
public function types(TypeInterventionRepository $repoTypeIntervention): Response
{
$interventionsType = $repoTypeIntervention->findAllInterventionsTypes();
return $this->json($interventionsType, 200, [], ['groups' => 'affichageContrat']);
}
/**
* @IsGranted("ROLE_TECH")
*/
public function exportRapport(int $id, InterventionRepository $repoIntervention, ActionsRepository $repoActions, ContratsRepository $repoContrats)
{
$filename = 'rapport_intervention.pdf';
$intervention = $repoIntervention->find($id);
$preActions = $repoActions->findBy(["intervention" => $intervention->getId()]);
$actions = [];
foreach ($preActions as $value) {
$actions[] = $value;
if ($value->getTicket() !== null) {
$actionsTicktes = $repoActions->findBy(["ticket" => $value->getTicket()->getId()]);
foreach ($actionsTicktes as $v) {
if ($v->getIntervention() === null)
$actions[] = $v;
}
}
}
$contrat = $repoContrats->find($intervention->getIdLigneContrat()->getIdContrat());
$acts = [];
foreach ($actions as $key => $action) {
array_push($acts, ["date" => $action->getDateAction()->format('d/m/Y'), "message" => $action->getMessage(), "class" => ($key > 0 ? "border" : "")]);
}
try {
$mpdf = new Mpdf();
$html = $this->renderView('export/rapportIntervention.html.twig', [
'dateIntervention' => $intervention->getDateIntervention()->format("d/m/Y"),
'intervenant' => $intervention->getTechPrevus()->getNom() . " " . $intervention->getTechPrevus()->getPrenom(),
'nomClient' => $contrat->getIdClient()->getNom(),
'adressClient' => $contrat->getIdClient()->getAdresse(),
'villeClient' => $contrat->getIdClient()->getCodePostal() . " " . $contrat->getIdClient()->getVille(),
'titre' => $intervention->getTitre(),
'description' => $intervention->getDescription(),
'actions' => $acts,
'route' => $_SERVER["DOCUMENT_ROOT"] . '/ExtranetV2/public'
]);
$mpdf->setFooter('{PAGENO}');
$mpdf->WriteHTML("");
$mpdf->WriteHTML($html);
$path = $_SERVER["DOCUMENT_ROOT"] . ($_ENV['APP_ENV'] == "dev" ? '../documents/' : '/ExtranetV2/documents/') . $filename;
$mpdf->Output($path, 'F');
// header('Access-Control-Allow-Origin: ' . "http://localhost:8001");
header('Access-Control-Allow-Origin: ' . "https://extranet.cco-info.fr/");
header('Access-Control-Allow-Credentials: true');
header('Access-Control-Allow-Methods: POST');
header('Access-Control-Allow-Headers: Content-Type');
header('Content-Description: File Transfer');
header('Content-Type: application/pdf');
header('Content-Disposition: attachment; filename="rapport_intervention.pdf"');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($path));
return readfile($path);
} catch (\throwable $e) {
return $this->json([
'status' => 400,
'message' => $e->getMessage()
], 400);
}
}
/**
* @IsGranted("ROLE_COMMERCIAL")
*/
public function stats(Request $request, InterventionRepository $repoIntervention): Response
{
$jsonRecu = json_decode($request->getContent());
$startDate = (new DateTime())->setTimestamp($jsonRecu->startDate / 1000);
$endDate = (new DateTime())->setTimestamp($jsonRecu->endDate / 1000);
$interventions = $repoIntervention->findByDate($startDate, $endDate);
$monthsData = [];
/** @var Intervention $intervention */
foreach ($interventions as $key => $intervention) {
if ($intervention->getIdLigneContrat()->getIdTypeIntervention()->getType() !== "Télémaintenance") {
$i = $intervention->getDateIntervention()->format('Y-m');
if (!isset($monthsData[$i])) $monthsData[$i] = ["month" => (int) $intervention->getDateIntervention()->format('m'), "total" => 0, "curative" => 0, "preventive" => 0];
$monthsData[$i]["total"]++;
if ($intervention->getIdLigneContrat()->getIdTypeIntervention()->getType() == "Preventive") {
$monthsData[$i]["preventive"]++;
} else if ($intervention->getIdLigneContrat()->getIdTypeIntervention()->getType() == "Curative") {
$monthsData[$i]["curative"]++;
}
}
}
return $this->json($monthsData, 200);
}
/**
* @IsGranted("ROLE_COMMERCIAL")
*/
public function statsTelemaintenance(Request $request, LigneDeContratRepository $repoLigneContrat, TypeInterventionRepository $repoType): Response
{
$jsonRecu = json_decode($request->getContent());
if ($jsonRecu->getBy !== "activeContrats") {
$startDate = (new DateTime())->setTimestamp($jsonRecu->startDate / 1000);
$endDate = (new DateTime())->setTimestamp($jsonRecu->endDate / 1000);
$lignesTelemaintenanceContrat = $repoLigneContrat->findTelemeaintenanceByDate($startDate, $endDate, $repoType);
} else {
$lignesTelemaintenanceContrat = $repoLigneContrat->findTelemeaintenanceContratsActifs($repoType);
}
$telemaintenanceData = [];
/** @var LigneDeContrat $ligne */
foreach ($lignesTelemaintenanceContrat as $key => $ligne) {
$client = (string) $ligne->getIdContrat()->getIdClient()->getNom();
if (!isset($telemaintenanceData[$client])) $telemaintenanceData[$client] = ['sold' => 0, 'spent' => 0];
$telemaintenanceData[$client]["sold"] += $ligne->getQuantitePrevus();
$telemaintenanceData[$client]["spent"] += $ligne->getQuantiteConsome();
}
return $this->json($telemaintenanceData, 200);
}
/**
* @IsGranted("ROLE_TECH")
*/
public function syncEvenementsOutlook(InterventionRepository $repoIntervention, EntityManagerInterface $manager)
{
$graphUser = new GraphUser();
$interventionsPorgrammes = $repoIntervention->findInterventionsProgrammes();
$users = $graphUser->getUsers();
$idUserGraph = null;
/** @var Intervention $intervention */
for ($i = 0; $i < count($interventionsPorgrammes); $i++) {
$intervention = $interventionsPorgrammes[$i];
if ($intervention->getCalendarEventId() == null) {
$this->delete($intervention->getId(), $repoIntervention);
continue;
}
$idUserGraph = null;
foreach ($users as $key => $value) {
if ($value->getMail() === $intervention->getTechPrevus()->getMail()) {
$idUserGraph = $value->getId();
break;
}
}
if (isset($idUserGraph)) {
try {
$event = $graphUser->getCalendarEvent($idUserGraph, $intervention->getCalendarEventId());
} catch (\Throwable $e) {
if ($e->getCode() == 404) {
$this->delete($intervention->getId(), $repoIntervention);
}
continue;
}
$date = new DateTime($event->getBody()['start']['dateTime']);
if ($date->format('Y-m-d') != $intervention->getDateIntervention()->format('Y-m-d'))
$intervention->setDateIntervention($date);
$manager->persist($intervention);
}
}
$manager->flush();
return $this->json(true, 200);
}
}