<?php
namespace App\Controller\Client;
use App\Entity\User;
use DateTimeImmutable;
use App\Entity\JobCard;
use App\Entity\Service;
use App\Entity\Historique;
use App\Form\EtatsDesLieuxJobCardType;
use App\Form\JobCardModificationFormType;
use App\Form\ModificationJobcardClientType;
use App\Form\RegistrationType;
use App\Repository\HistoriqueRepository;
use App\Repository\JobCardRepository;
use App\Services\SendMail;
use Symfony\Component\Mime\Email;
use Symfony\Config\FrameworkConfig;
use Doctrine\ORM\EntityManagerInterface;
use Knp\Component\Pager\PaginatorInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Validator\Constraints\Length;
use Symfony\Component\String\Slugger\SluggerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\File\Exception\FileException;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
use Symfony\Component\Security\Core\Exception\UserNotFoundException;
/**
* Gestion de des jobCard
*/
class JobCardController extends AbstractController
{
/**
* cette methode affiche les jobcard de l'utilisateur connecté
* et le nombre de jobcard qui ont le status soumis.
*
* @param JobCardRepository $jobCardRepository
* @param PaginatorInterface $paginator
* @param Request $request
* @return Response
*/
#[Route('/jobcard/index', name: 'app.index')]
public function index(JobCardRepository $jobCardRepository, PaginatorInterface $paginator, Request $request): Response
{
if (!$this->getUser()) {
throw new UserNotFoundException();
}
$this->denyAccessUnlessGranted('ROLE_USER');
# a l'aide de la pagination on recupère les jobcards créer par l'utilisateur connecté
$jobcards = $paginator->paginate(
$jobCardRepository->findBy(['user' => $this->getUser()], ['createdAt' => 'desc']),
$request->query->getInt('page', 1), /*page number*/
5 /*limit per page*/
);
# On récupère tous les jobcards de l'user connecté dont leurs status sont à soumis
$qb = $jobCardRepository->createQueryBuilder('j')
->where('j.status = :soumis')
->andWhere('j.user = :user')
->setParameter('soumis', JobCard::SOUMIS)
->setParameter('user', $this->getUser())
->getQuery()
->getResult();
return $this->render('Client/home.html.twig', [
'jobcards' => $jobcards,
'total' => count($qb)
]);
}
/**
* Cette methode permet de faire la création d'un jobcard
* A savoir elle prend en compte l'enregistrement des fichiers
* Et l'enregistrement de l'historique de création du jobcard.
*
* @param EntityManagerInterface $em
* @param Request $request
* @param SluggerInterface $slugger
* @return Response
*/
#[Route('/jobcard/nouveau', name: 'jobcard.new')]
public function create(EntityManagerInterface $em, Request $request, SluggerInterface $slugger): Response
{
if (!$this->getUser()) {
throw new UserNotFoundException();
}
$this->denyAccessUnlessGranted('ROLE_USER');
#Création du formulaire pour la création du jobcard
$jobcard = new JobCard();
$form = $this->createForm(RegistrationType::class, $jobcard);
$form->handleRequest($request);
if ($form->isSubmitted()) {
# Enrégistrement des photos télécharger par le client
$photo = $form->get('photo')->getData();
if ($photo) {
for ($i = 0; $i < count($photo); $i++) {
$nomOrigineFichier[$i] = pathinfo($photo[$i]->getClientOriginalName(), PATHINFO_FILENAME);
$safeFilename[$i] = $slugger->slug($nomOrigineFichier[$i]);
$nouveauNom[$i] = $safeFilename[$i] . '-' . uniqid() . '.' . $photo[$i]->guessExtension();
try {
$photo[$i]->move(
$this->getParameter('images_directory'),
$nouveauNom[$i]
);
} catch (FileException $e) {
}
}
$jobcard->setImageFile($nouveauNom);
}
#Récupération des différents services selectionés par le client
$services = $form->get('services')->getData();
#Ajouter chaque service selectioné dans le jobcard
for ($i = 0; $i < count($services); $i++) {
$jobcard->addService($services[$i]);
}
#Récupération de tous les champs soumis du formulaire
$jobcard = $form->getData();
#Ajout l'utilisateur connecté au jobcard encours d'enregistrement
$jobcard->setUser($this->getUser());
#Sauvegarde des données dans la BD pour enfin récuperer l'id
$em->persist($jobcard);
$em->flush();
#Mise en place de l'enregistrement d'un jobcard avec un numéro unique à l'aide de son id
if ($jobcard->getId() < 10) {
$numero = 'JB-00' . $jobcard->getId();
$jobcard->setNumero($numero);
} else if ($jobcard->getId() >= 10 && $jobcard->getId() < 100) {
$numero = 'JB-0' . $jobcard->getId();
$jobcard->setNumero($numero);
} else {
$numero = 'JB-' . $jobcard->getId();
$jobcard->setNumero($numero);
}
# Création de l'historique et enregistrement des informationn dans la BD
$historique = new Historique();
$historique
->setAction('création du jobCard')
->setJobcard($jobcard)
->setProfil('Client')
->setUser($this->getUser());
$em->persist($historique);
$em->flush();
$this->addFlash(
'success',
"La création du jobcard à aboutit et enrégistré avec un numéro unique " . $jobcard->getNumero(),
);
return $this->redirectToRoute('app.index');
}
return $this->render('Client/nouveau.html.twig', [
'form' => $form->createView()
]);
}
/**
* Cette methode permet de faire l'édition d'un jobcard par le commercial.
*/
#[Route('/commercial/jobcard/edit/{id}', name: 'jobacard.edit')]
public function ModificationJobcardParLeCommercial($id, EntityManagerInterface $em, Request $request, JobCardRepository $jobCardRepository)
{
//$this->denyAccessUnlessGranted('ROLE_USER', null, "Vous n'avez pas access à cette ressource");
$jobcard = $jobCardRepository->findOneBy(['id' => $id]);
$form = $this->createForm(JobCardModificationFormType::class, $jobcard);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$jobcard = $form->getData();
$em->persist($jobcard);
$em->flush();
$this->addFlash('success', 'Modification éffécuté avec success');
return $this->redirectToRoute('jobcard.details', ['id' => $jobcard->getId()]);
}
return $this->render('commercial/dashbord_edit_jobcard.html.twig', [
'form' => $form->createView(),
'jobcard' => $jobcard
]);
}
/**
* Cette methode permet de faire la suppression d'un jobcard
* En supprimant elle suprimme les services selectionés l'ors de la crétion du jobcard.
* @param EntityManagerInterface $em
* @param JobCardRepository $jobCardRepository
* @param HistoriqueRepository $historiqueRepository
*/
#[Route('/jobcard/suppression/{id}', name: 'jobcard.supp', methods: ['GET', 'POST'])]
public function delete($id, EntityManagerInterface $em, JobCardRepository $jobCardRepository, HistoriqueRepository $historiqueRepository)
{
$jobcard = $jobCardRepository->findOneBy(['id' => $id]);
if (!$jobcard) {
$this->addFlash(
'warning',
'Le jobcard en question n\'est pas trouvé!'
);
}
$historique = $historiqueRepository->findBy(['jobcard' => $jobcard->getId()]);
for ($i = 0; $i < count($historique); $i++) {
$jobcard->removeHistorique($historique[$i]);
}
$em->remove($jobcard);
$em->flush();
$this->addFlash(
'success',
'le jobcard avec le numéro ' . $jobcard->getNumero() . ' a été supprimé avec succes!'
);
return $this->redirectToRoute('app.index');
}
/**
* Cette methode affiche les détails d'un jobcard.
* Et l'historique assoicié à cet jobcard.
* @param int $id
* @param JobCardRepository $repository
* @param HistoriqueRepository $historiqueRepository
* @param PaginatorInterface $paginator
* @param Request $request
*/
#[Route('/jobcard/detail/{id}', name: 'jobcard.details', methods: ['GET', 'POST'])]
public function detail($id, JobCardRepository $repository, HistoriqueRepository $historiqueRepository, PaginatorInterface $paginator, Request $request): Response
{
$historiques = new Historique();
#Réchercher un jobcard à travers son id s'il existe
$jobcard = $repository->findOneBy(['id' => $id]);
if (!$jobcard) {
$this->addFlash(
'warning',
'les détails de cet jobcard ne sont pas disponibles'
);
}
# Affichage de l'historique d'un jobcard à l'aide de la pagination
$historiques = $paginator->paginate(
$historiqueRepository->findBy(['jobcard' => $jobcard], ['createdAt' => 'desc']),
$request->query->getInt('page', 1), /*page number*/
5 /*limit per page*/
);
return $this->render('Client/details.html.twig', [
'jobcard' => $jobcard,
'historiques' => $historiques
]);
}
#[Route('/jobcard/all', name: 'jobcard.all', methods: ['GET', 'POST'])]
/**
* Cette methode affiche tous les jobcards enrégistrés
* Et le nombre de jobcard avec le status soumis.
*
* @param JobCardRepository $repository
* @param PaginatorInterface $paginator
* @param Request $request
* @return Response
*/
public function afficherTousLesJobcards(JobCardRepository $repository, PaginatorInterface $paginator, Request $request): Response
{
if (!$this->getUser()) {
throw new UserNotFoundException();
}
#Affichage de tous les jobcard créer pour le profil commercial
$jobcards = $paginator->paginate(
$repository->findBy([], ['createdAt' => 'desc']),
$request->query->getInt('page', 1),
5
);
#Trouver tous le jobcard dont leur status est à = soumis
$qb = $repository->createQueryBuilder('j')
->where('j.status = :soumis')
->setParameter('soumis', JobCard::SOUMIS)
->getQuery()
->getResult();
return $this->render('commercial/dashbord_index.html.twig', [
'jobcards' => $jobcards,
'total' => count($qb)
]);
}
#[Route('/jobcard/etat_des_lieux_entrant/{id}', name: 'etat.lieu', methods: ['GET', 'POST'])]
/**
* Cette methode fait l'enrégistrement des états de lieux entrant,
* Cette methode est une forme de modification de l'objet jobcard en cours puisqu'on complète des données,
* sur un objet déja rempli par le client,
* On fait la signature qu'un seule fois si elle n'est pas encore faites,
* Pour la signature une fois la signature est faite ce n'est plus possible de faire sa modification,
* On fait l'enrégistrement de son historique.
*/
/**
* bazar bazar.
*
* @param mixe $id
* @param EntityManagerInterface $em
* @param Request $request
* @param JobCardRepository $repository
* @return Response
*/
public function saisirEtatDesLieuxEntrant($id, EntityManagerInterface $em, Request $request, JobCardRepository $repository, SendMail $sendMail): Response
{
if (!$this->getUser()) {
throw new UserNotFoundException();
}
$this->denyAccessUnlessGranted('ROLE_COMMERCIAL');
$jobcard_actu = $repository->find($id);
#Création du formulaire de saisie
$form = $this->createForm(EtatsDesLieuxJobCardType::class, $jobcard_actu);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
# recupération de l'url des images
$jobcard_actu->setPneumatique($form->get('pneumatique')->getData());
$jobcard_actu->setNettoyage($form->get('nettoyage')->getData());
$jobcard_actu->setRayures($form->get('rayures')->getData());
$jobcard_actu->setDeformination($form->get('deformination')->getData());
$jobcard_actu->setPhareD($form->get('phareD')->getData());
$jobcard_actu->setPhareG($form->get('phareG')->getData());
$jobcard_actu->setPareBrise($form->get('pareBrise')->getData());
$jobcard_actu->setVidangeMoteur($form->get('vidangeMoteur')->getData());
$jobcard_actu->setVidangePontAV($form->get('vidangePontAV')->getData());
$jobcard_actu->setFiltreAire($form->get('filtreAire')->getData());
$jobcard_actu->setLavage($form->get('lavage')->getData());
$jobcard_actu->setEquilibreRoues($form->get('equilibreRoues')->getData());
$jobcard_actu->setControleNiveau($form->get('controleNiveau')->getData());
$jobcard_actu->setVidangeBoite($form->get('vidangeBoite')->getData());
$jobcard_actu->setVidangePontAr($form->get('vidangePontAr')->getData());
$jobcard_actu->setFreinAr($form->get('freinAr')->getData());
$jobcard_actu->setFreinAhuile($form->get('freinAhuile')->getData());
$jobcard_actu->setGraissageTransmission($form->get('graissageTransmission')->getData());
$jobcard_actu->setPressionDespneux($form->get('pressionDespneux')->getData());
$jobcard_actu->setControleEclairage($form->get('controleEclairage')->getData());
$jobcard_actu->setTraveauxDemander($form->get('traveauxDemander')->getData());
$jobcard_actu->setAutreObservations($form->get('autreObservations')->getData());
//énregistrement de la date de la saisie des etats de lieu
#modification des propriéte pour stocker le chemain ou seront enrégistrés les images et la date de l'enrégistrement
if ($jobcard_actu->getClientSignature() === null && $jobcard_actu->getCommercialSignature() === null) {
$urlClient = $form->get('signatureClient')->getData();
$urlCommercial = $form->get('signatureCommerciale')->getData();
$jobcard_actu->setCommercialSignature($this->sauvegardeSignature($urlCommercial));
$jobcard_actu->setClientSignature($this->sauvegardeSignature($urlClient));
$jobcard_actu->setDateArrivee(new DateTimeImmutable());
}
$jobcard_actu->setIsEtatEntre(true);
//enrégistrment du nom complet du commericial qui à saisie l'état des lieux
/**@var User */
$user = $this->getUser();
if ($jobcard_actu->getNomCommercial() === null) {
$jobcard_actu->setNomCommercial($user->getPrenom() . ' ' . $user->getNom());
}
#la pérsistance des données
$em->persist($jobcard_actu);
$em->persist($user);
#Création de l'historique
$historique = new Historique();
$historique
->setAction('remplissage état des lieux')
->setJobcard($jobcard_actu)
->setProfil('Commercial')
->setUser($this->getUser());
$em->persist($historique);
$em->flush();
$this->addFlash('success', 'Remplissage des états de lieux entrants éffectué pour le jobcard ' . $jobcard_actu->getNumero(),);
return $this->redirectToRoute('jobcard.all');
}
return $this->render('commercial/dashbord_saisie_etat_lieu.twig', [
'form' => $form->createView(),
'jobcard' => $jobcard_actu
]);
}
/**
* Cette methode fais le traitement des images qu'on reçoit des deux signataires
* La conversion de l'image en chaine
* décodage de l'image dans la base64
* Le chemin de stockage des signatures avec un nom unique.
* @param string $urlImage
* @return string
*/
private function sauvegardeSignature(string $urlImage): string
{
$encoded_image = explode(",", $urlImage)[1];
$decoded_image = base64_decode($encoded_image);
$filename = "signatures/signature-" . uniqid() . '.png';
file_put_contents($filename, $decoded_image);
return $filename;
}
#[Route('/jobcard/ajouter_photo/{id}', name: 'ajouter_photo', methods: (['POST']))]
public function ajouterPhotos(EntityManagerInterface $em, $id, Request $request, SluggerInterface $slugger, JobCardRepository $repository)
{
$jobcard = $repository->find($id);
if (!$jobcard) {
throw new AccessDeniedException('jobcard inexistant');
}
$token = $request->request->get('token');
if ($this->isCsrfTokenValid('add-file', $token)) {
$photo = $request->files->get('photos');
$nomOrigineFichier = pathinfo($photo->getClientOriginalName(), PATHINFO_FILENAME);
$safeFilename = $slugger->slug($nomOrigineFichier);
$nouveauNom = $safeFilename . '-' . uniqid() . '.' . $photo->guessExtension();
try {
$photo->move(
$this->getParameter('images_directory'),
$nouveauNom
);
} catch (FileException $e) {
}
$jobcard->setImages($nouveauNom);
$em->persist($jobcard);
$em->flush();
$this->addFlash('info', 'ajout de photos éffectué');
return $this->redirectToRoute('jobcard.details', ['id' => $jobcard->getId()]);
}
return new Response();
}
#[Route('/client/jobcard/liste_des_demandes_soumise', name: 'jobcard.soumise', methods: (['GET']))]
public function afficherLesJobcardSoumisesPourLeClient(JobCardRepository $repository, PaginatorInterface $paginator, Request $request): Response
{
$jobcardSoumises = $paginator->paginate(
$repository->findBy(['status' => JobCard::SOUMIS, 'user' => $this->getUser()], ['createdAt' => 'desc']),
$request->query->getInt('page', 1),
5
);
return $this->render('Client/demandes_soumises.html.twig', [
'jobcardsSoumises' => $jobcardSoumises
]);
}
#[Route('/client/jobcard/liste_des_demandes_en_cours', name: 'jobcard.enCours', methods: (['GET']))]
public function afficherLesJobcardEnCoursPourLeClient(JobCardRepository $repository, PaginatorInterface $paginator, Request $request): Response
{
$jobcardEncours = $paginator->paginate(
$repository->findBy(['status' => JobCard::EN_COURS, 'user' => $this->getUser()], ['createdAt' => 'desc']),
$request->query->getInt('page', 1),
5
);
return $this->render('Client/demandes_enCours.html.twig', [
'jobcardEncours' => $jobcardEncours
]);
}
#[Route('/client/jobcard/liste_des_demandes_terminees', name: 'jobcard.terminees', methods: (['GET']))]
public function afficherLesJobcardTermineesPourLeClient(JobCardRepository $repository, PaginatorInterface $paginator, Request $request): Response
{
$jobcardTerminees = $paginator->paginate(
$repository->findBy(['status' => JobCard::TERMINE, 'user' => $this->getUser()], ['createdAt' => 'desc']),
$request->query->getInt('page', 1),
5
);
return $this->render('Client/demandes_terminees.html.twig', [
'jobcardTerminees' => $jobcardTerminees
]);
}
#[Route('/jobcard/liste_des_tous_les_demandandes_terminees', name: 'jobcards_terminees', methods: (['GET']))]
public function afficherLesJobcardsTerminees(JobCardRepository $repository, PaginatorInterface $paginator, Request $request): Response
{
$jobcardTerminees = $paginator->paginate(
$repository->findBy(['status' => JobCard::TERMINE], ['createdAt' => 'desc']),
$request->query->getInt('page', 1),
5
);
return $this->render('Client/ReparationsStatus/demandes_terminees.html.twig', [
'jobcardTerminees' => $jobcardTerminees
]);
}
#[Route('/jobcard/liste_de_toutes_les_demandes_en_cours', name: 'jobcards.enCours', methods: (['GET']))]
public function afficherLesJobcardEnCours(JobCardRepository $repository, PaginatorInterface $paginator, Request $request): Response
{
$jobcardEncours = $paginator->paginate(
$repository->findBy(['status' => JobCard::EN_COURS], ['createdAt' => 'desc']),
$request->query->getInt('page', 1),
5
);
return $this->render('Client/ReparationsStatus/demandes_enCours.html.twig', [
'jobcardEncours' => $jobcardEncours
]);
}
#[Route('/jobcard/liste_de_toutes_les_demandes_soumises', name: 'jobcards.soumises', methods: (['GET']))]
public function afficherLesJobcardSoumises(JobCardRepository $repository, PaginatorInterface $paginator, Request $request): Response
{
$jobcardSoumises = $paginator->paginate(
$repository->findBy(['status' => JobCard::SOUMIS], ['createdAt' => 'desc']),
$request->query->getInt('page', 1),
5
);
return $this->render('Client/ReparationsStatus/demandes_soumises.html.twig', [
'jobcardsSoumises' => $jobcardSoumises
]);
}
#[Route('commercial/jobcard/traitement_demande/{id}', name: 'traitement_demande', methods: ['POST', 'GET'])]
public function traitementDelaDemande($id, Request $request, JobCardRepository $repository, EntityManagerInterface $em, SendMail $sendMail){
$jobcard = $repository->find($id);
$token = $request->request->get('token');
/* la vérification du token récupéré et le token mis sur le formulaire pour la sécurité
si la vérification est vrai on procède à l'enregistrement
sinon on affiche les détails de la demande */
if ($this->isCsrfTokenValid('add', $token)) {
$status = $request->request->get('traitement');
$jobcard->setStatus($status);
$em->persist($jobcard);
$em->flush();
$this->addFlash('success', 'Le status de la demande est changé en '.$status);
$sendMail->sendMail(
$jobcard->getUser()->getEmail(),
'Changement de Status de la demande '.$jobcard->getNumero(),
'information_changement_status.html.twig',
[
'commentaire' => $request->request->get('commentaire'),
'jobcard' => $jobcard
]
);
return $this->redirectToRoute('jobcard.details', ['id' => $jobcard->getId()]);
}
return $this->redirectToRoute('jobcard.details', ['id' => $jobcard->getId()]);
}
#[Route('/client/jobcard/edit/{id}', name: 'jobacard.client.edit')]
public function ModificationJobcardParLeClient($id, EntityManagerInterface $em, Request $request, JobCardRepository $jobCardRepository)
{
$jobcard = $jobCardRepository->find(['id' => $id]);
$form = $this->createForm(ModificationJobcardClientType::class, $jobcard);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$jobcard = $form->getData();
$jobcard->setStatus(JobCard::SOUMIS);
$em->persist($jobcard);
$em->flush();
$this->addFlash('success', 'Modification éffécuté avec success');
return $this->redirectToRoute('jobcard.details', ['id' => $jobcard->getId()]);
}
return $this->render('Client/edit.html.twig', [
'form' => $form->createView(),
'jobcard' => $jobcard
]);
}
}