src/Controller/PriceController.php line 365

Open in your IDE?
  1. <?php
  2. namespace App\Controller;
  3. use App\Entity\ExchangeRate;
  4. use App\Entity\Payement;
  5. use App\Entity\Prices;
  6. use App\Entity\Fees;
  7. use App\Entity\Folder;
  8. use App\Entity\Transaction;
  9. use App\Form\FeesType;
  10. use App\Form\PriceType;
  11. use App\Repository\BankAccountRepository;
  12. use App\Repository\BankRepository;
  13. use App\Service\FeesService;
  14. use App\Service\MakutaAPIV2;
  15. use App\Service\SendNotificationService;
  16. use App\Utils\Utilitaires;
  17. use Exception;
  18. use Psr\Log\LoggerInterface;
  19. use Doctrine\Persistence\ManagerRegistry;
  20. use Symfony\Component\HttpFoundation\Request;
  21. use Symfony\Component\HttpFoundation\Response;
  22. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  23. use Symfony\Component\Mailer\MailerInterface;
  24. use Symfony\Component\Serializer\Encoder\JsonEncoder;
  25. use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
  26. use Symfony\Component\Serializer\Serializer;
  27. class PriceController extends AbstractController
  28. {
  29.     private ManagerRegistry $managerRegistry;
  30.     private LoggerInterface $logger;
  31.     private SendNotificationService $sendNotificationService;
  32.     private MailerInterface $mailer;
  33.     private FeesService $feesService;
  34.     /**
  35.      * @param ManagerRegistry $managerRegistry
  36.      * @param LoggerInterface $logger
  37.      * @param SendNotificationService $sendNotificationService
  38.      * @param MailerInterface $mailer
  39.      * @param FeesService $feesService
  40.      */
  41.     public function __construct(ManagerRegistry $managerRegistryLoggerInterface $loggerSendNotificationService $sendNotificationServiceMailerInterface $mailerFeesService $feesService)
  42.     {
  43.         $this->managerRegistry $managerRegistry;
  44.         $this->logger $logger;
  45.         $this->sendNotificationService $sendNotificationService;
  46.         $this->mailer $mailer;
  47.         $this->feesService $feesService;
  48.     }
  49.     public function payUI(Request $requestBankRepository $bankRepositoryBankAccountRepository $bankAccountRepository)
  50.     {
  51.         $form $this->createForm(FeesType::class);
  52.         $form->handleRequest($request);
  53.         $demande_id $request->get('demande_id');
  54.         $document_category_id $request->get('document_category_id');
  55.         $site_id $request->get('site_id');
  56.         $bank $bankRepository->findBankAll();
  57.         $bankAccounts $bankAccountRepository->findAllBankAccount();
  58.         $folder $this->managerRegistry->getRepository(Folder::class)->findOneBy([
  59.             'id' => $demande_id,
  60.         ]);
  61.         if ($folder->getStatus() !== 1) {
  62.             $this->addFlash('invalid_payment'"Ce document a déjà été payé");
  63.             return $this->redirectToRoute('app_folder_view', [
  64.                 'folder_id' => $folder->getId(),
  65.             ]);
  66.         }
  67.         if ($folder->getBeneficiary()->getNationality() != null) {
  68.             if ($folder->getBeneficiary()->getNationality()->getId() != "PA001") {
  69.                 $price $this->managerRegistry->getRepository(Prices::class)->findOneBy([
  70.                     'documentCategory' => $document_category_id,
  71.                     'site' => $site_id,
  72.                     'tarif' => 'ETRANGER',
  73.                     'status' => true,
  74.                 ]);
  75.             } else {
  76.                 $price $this->managerRegistry->getRepository(Prices::class)->findOneBy([
  77.                     'documentCategory' => $document_category_id,
  78.                     'site' => $site_id,
  79.                     'status' => true,
  80.                 ]);
  81.             }
  82.         } else {
  83.             $price $this->managerRegistry->getRepository(Prices::class)->findOneBy([
  84.                 'documentCategory' => $document_category_id,
  85.                 'site' => $site_id,
  86.                 'status' => true,
  87.             ]);
  88.         }
  89.         if ($price == null) {
  90.             $this->addFlash('no_price'"Aucun taux n'a été configuré pour ce document! Veuillez contacter l'administrateur");
  91.             return $this->redirectToRoute('app_folder_view', [
  92.                 'folder_id' => $folder->getId(),
  93.             ]);
  94.         }
  95.         $encoders = [new JsonEncoder()];
  96.         $normalizers = [new ObjectNormalizer()];
  97.         $serializer = new Serializer($normalizers$encoders);
  98.         $jsonBankList $serializer->serialize($bank'json', [
  99.             'circular_reference_handler' => function ($object) {
  100.                 return $object->getId();
  101.             }
  102.         ]);
  103.         $jsonBankAccountList $serializer->serialize($bankAccounts'json', [
  104.             'circular_reference_handler' => function ($object) {
  105.                 return $object->getId();
  106.             }
  107.         ]);
  108.         $exchange $this->managerRegistry->getRepository(ExchangeRate::class)->findOneBy([
  109.             'isActive' => true,
  110.         ]);
  111.         $webCardFees $this->managerRegistry->getRepository(Fees::class)->findOneBy([
  112.             'isWebCard' => true,
  113.             'isDeleted' => false
  114.         ]);
  115.         $fees $this->managerRegistry->getRepository(Fees::class)->findBy([
  116.             'isWebCard' => true,
  117.             'isDeleted' => false
  118.         ]);
  119.         $WebCardFeesArray = [];
  120.         foreach ($fees as $fee) {
  121.             if (!is_null($fee)) {
  122.                 $priceCDF $exchange->getRate() * $fee->getPrice();
  123.                 $WebCardFeesArray[] = array(
  124.                     'id' => $fee->getId(),
  125.                     'label' => $fee->getLabel(),
  126.                     'priceCDF' => $priceCDF,
  127.                     'priceUSD' => $fee->getPrice(),
  128.                     "require" => $fee->getIsRequired(),
  129.                     "isWebcard" => $fee->getIsWebCard());
  130.             }
  131.         }
  132.         return $this->render('master/pay_document.html.twig', [
  133.             'webCardFees' => $webCardFees,
  134.             'webCardFeesArray' => $WebCardFeesArray,
  135.             'currentExchange' => $exchange,
  136.             'price' => $price,
  137.             'folder' => $folder,
  138.             'bankList' => $jsonBankList,
  139.             'bankAccountList' => $jsonBankAccountList,
  140.             'userType' => $this->getUser()->getUserType(),
  141.             'isShortcutProcess' => $this->getParameter('shortcut_ops_process'),
  142.             'form' => $form->createView(),
  143.         ]);
  144.     }
  145.     public function feesbyID(Request $request): Response
  146.     {
  147.         $data = [];
  148.         $fees_id_list explode(","$request->get('fees_id'));
  149.         $currency $request->get('currency');
  150.         $currentRate $this->managerRegistry->getRepository(ExchangeRate::class)->findOneBy([
  151.             'isActive' => true
  152.         ]);
  153.         foreach ($fees_id_list as $fees_id) {
  154.             $fees $this->managerRegistry->getRepository(Fees::class)->findOneBy([
  155.                 'id' => $fees_id
  156.             ]);
  157.             if (!is_null($fees)) {
  158.                 if ($fees->getCurrency()->getAcronym() != $currency && $currency == 'CDF') {
  159.                     $price $currentRate->getRate() * $fees->getPrice();
  160.                     $data[] = array('id' => $fees->getId(), 'label' => $fees->getLabel(), 'price' => $price'currency' => $currency"require" => $fees->getIsRequired());
  161.                 } else {
  162.                     $data[] = array('id' => $fees->getId(), 'label' => $fees->getLabel(), 'price' => $fees->getPrice(), 'currency' => $fees->getCurrency(), "require" => $fees->getIsRequired());
  163.                 }
  164.             }
  165.         }
  166.         $response = new Response(json_encode($data));
  167.         $response->headers->set('Content-Type''application/json');
  168.         return $response;
  169.     }
  170.     public function initializeMakuta(MakutaAPIV2 $makutaApiV2): Response
  171.     {
  172.         $response = new Response(json_encode($makutaApiV2->getOperators()));
  173.         $response->headers->set('Content-Type''application/json');
  174.         return $response;
  175.     }
  176.     public function createMakutaTransaction(Request $requestMakutaAPIV2 $makutaApiV2): Response
  177.     {
  178.         $folder $request->get('folder');
  179.         $fees json_decode($request->get('fees'), true);
  180.         $em $this->managerRegistry->getManager();
  181.         $defaultAmount $request->get('defaultAmount');
  182.         $phone $request->get('phone');
  183.         $accountNumber = !empty($phone) ? $phone '243899778838';
  184.         $clientCurrency $request->get('defaultCurrency');
  185.         $operator $request->get('apiKey');
  186.         $email $request->get('email');
  187.         $mailist $this->getParameter('paymentMailList');
  188.         $mailListArray explode(","$mailist);
  189.         $requiresEmail false;
  190.         foreach ($makutaApiV2->getOperators() as $categoryOperators) {
  191.             foreach ($categoryOperators as $operatorDefinition) {
  192.                 if ($operatorDefinition['code'] === $operator) {
  193.                     $requiresEmail $operatorDefinition['requiresEmail'] ?? false;
  194.                 }
  195.             }
  196.         }
  197.         if ($requiresEmail && (empty($email) || !filter_var($emailFILTER_VALIDATE_EMAIL))) {
  198.             $response = new Response(json_encode(['error' => "Une adresse email valide est requise pour ce mode de paiement."]));
  199.             $response->headers->set('Content-Type''application/json');
  200.             $response->setStatusCode(400);
  201.             return $response;
  202.         }
  203.         $folderObj $this->managerRegistry->getRepository(Folder::class)->findOneBy([
  204.             'id' => $folder,
  205.         ]);
  206.         $documentPrice $this->managerRegistry->getRepository(Prices::class)->findOneBy([
  207.             'documentCategory' => $folderObj->getDocumentCategory()->getId(),
  208.             'site' => $folderObj->getSite()->getId(),
  209.             'status' => true,
  210.         ]);
  211.         $makutaAmount $this->calculateTotalAmount($documentPrice$fees$clientCurrency);
  212.         // Chaque soumission crée une transaction neuve avec une référence fraîche : Makuta
  213.         // rejette toute réutilisation de thirdPartyReference ("Duplicate entry detected"), donc
  214.         // on ne réutilise jamais une transaction PENDING précédente. Le dossier ne peut être
  215.         // crédité deux fois de toute façon : voir la vérification de statut dans makutaCallback().
  216.         $transaction = new Transaction();
  217.         $transaction->setAmount($makutaAmount);
  218.         $transaction->setCreationDate(new \DateTime());
  219.         $transaction->setClientOperator($operator);
  220.         $transaction->setCurrency($clientCurrency);
  221.         $transaction->setStatus("PENDING");
  222.         $transaction->setUser($this->getUser());
  223.         $transaction->setDescription($folderObj->getNumber());
  224.         $transaction->setFolder($folderObj);
  225.         $transaction->setWallet(0);
  226.         try {
  227.             $transNum bin2hex(random_bytes(16));
  228.             $transaction->setTransactionNumber($transNum);
  229.         } catch (Exception $e) {
  230.         }
  231.         $em->persist($transaction);
  232.         $em->flush();
  233.         $payement = new Payement();
  234.         $payement->setAmount($defaultAmount);
  235.         $payement->setReference($transaction->getTransactionNumber());
  236.         $payement->setCurrency($clientCurrency);
  237.         $payement->setIntegator('MAKUTA');
  238.         $payement->setFees(null);
  239.         $payement->setFolder($folderObj);
  240.         $payement->setStatus(0);
  241.         $em->persist($payement);
  242.         foreach ($fees as $fee) {
  243.             $feeObj $this->managerRegistry->getRepository(Fees::class)->findOneBy([
  244.                 'id' => $fee['id'],
  245.             ]);
  246.             $payement = new Payement();
  247.             $payement->setAmount($feeObj->getPrice());
  248.             $payement->setReference($transaction->getTransactionNumber());
  249.             $payement->setCurrency($feeObj->getCurrency()->getAcronym());
  250.             $payement->setIntegator('MAKUTA');
  251.             $payement->setFees($feeObj);
  252.             $payement->setFolder($folderObj);
  253.             $payement->setStatus(0);
  254.             $em->persist($payement);
  255.         }
  256.         $em->flush();
  257.         $amountUsd $makutaAmount;
  258.         $exchangeRate null;
  259.         if ($clientCurrency === 'CDF') {
  260.             $exchange $this->managerRegistry->getRepository(ExchangeRate::class)->findOneBy(['isActive' => true]);
  261.             $exchangeRate $exchange->getRate();
  262.             $amountUsd $makutaAmount $exchangeRate;
  263.         }
  264.         $result $makutaApiV2->createTransaction(
  265.             $transaction,
  266.             $operator,
  267.             $accountNumber,
  268.             $clientCurrency,
  269.             $amountUsd,
  270.             $transaction->getDescription(),
  271.             $email
  272.         );
  273.         $transaction->setFinancialTransaction($result['id']);
  274.         $transaction->setFinancialTransactionUrl($result['url'] ?? null);
  275.         $transaction->setAmountUsd($amountUsd);
  276.         $transaction->setExchangeRate($exchangeRate);
  277.         $em->persist($transaction);
  278.         $em->flush();
  279.         $subject "Paiement du document " $folderObj->getDocumentCategory()->getLabel();
  280.         $notificationMessage "Le paiement du dossier N° " $folderObj->getNumber() . " intitulé " $folderObj->getDocumentCategory()->getLabel() .
  281.             " crée dans la commune de " $folderObj->getSite()->getLabel() . " a été Initié pour un montant de " $transaction->getAmount() .
  282.             " " $transaction->getCurrency() . " par " $folderObj->getUserCreate()->getUserName();
  283.         Utilitaires::sendMail(
  284.             $mailListArray,
  285.             $this->mailer,
  286.             $subject,
  287.             $notificationMessage,
  288.             'email/send_payment_notification.html.twig',
  289.             [
  290.                 'folder' => $folderObj,
  291.                 'transaction' => $transaction,
  292.                 'message' => ''
  293.             ],
  294.             $this->logger
  295.         );
  296.         $response = new Response(json_encode($result));
  297.         $response->headers->set('Content-Type''application/json');
  298.         return $response;
  299.     }
  300.     public function makutaCheckMomoTransaction(Request $request): Response
  301.     {
  302.         $makutaTransactionId $request->get('transactionId');
  303.         $transaction $this->managerRegistry->getRepository(Transaction::class)->findOneBy([
  304.             'financialTransaction' => $makutaTransactionId,
  305.         ]);
  306.         if (!is_null($transaction)) {
  307.             $response = new Response(json_encode(['response' => $transaction->getStatus()]));
  308.         } else {
  309.             $response = new Response(json_encode(['response' => 'ERROR']));
  310.         }
  311.         $response->headers->set('Content-Type''application/json');
  312.         return $response;
  313.     }
  314.     public function makutaCallback(Request $requestMakutaAPIV2 $makutaApiV2LoggerInterface $makutaLogger): Response
  315.     {
  316.         $body json_decode($request->getContent(), true) ?? [];
  317.         $makutaLogger->info('[MAKUTA_V2] Callback reçu'$body);
  318.         $result $makutaApiV2->handleCallback($body);
  319.         $mailList $this->getParameter('paymentMailList');
  320.         $mailListArray explode(","$mailList);
  321.         if (($result['status'] ?? null) === 'SUCCESS') {
  322.             $transaction $this->managerRegistry->getRepository(Transaction::class)->find($result['transaction_id']);
  323.             $folder $transaction->getFolder();
  324.             if ($folder->getStatus() === 2) {
  325.                 // Le dossier est déjà marqué payé par une transaction précédente (plusieurs
  326.                 // tentatives de paiement sont possibles pour un même dossier). On ignore ce
  327.                 // callback pour éviter de créditer deux fois le même document.
  328.                 $makutaLogger->info('[MAKUTA_V2] Callback ignoré : dossier déjà payé', ['folder' => $folder->getId(), 'transaction' => $transaction->getId()]);
  329.                 $response = new Response(json_encode(['received' => true]));
  330.                 $response->headers->set('Content-Type''application/json');
  331.                 return $response;
  332.             }
  333.             $folder->setStatus(2);
  334.             $folder->setDateUpdate(new \DateTime());
  335.             $em $this->managerRegistry->getManager();
  336.             $em->persist($folder);
  337.             $payments $this->managerRegistry->getRepository(Payement::class)->findBy([
  338.                 'reference' => $transaction->getTransactionNumber(),
  339.             ]);
  340.             foreach ($payments as $pay) {
  341.                 $pay->setStatus(1);
  342.                 $em->persist($pay);
  343.             }
  344.             $em->flush();
  345.             $makutaLogger->info('[MAKUTA_V2] Callback SUCCESS : dossier crédité', [
  346.                 'folder' => $folder->getId(),
  347.                 'transaction' => $transaction->getId(),
  348.                 'paymentsUpdated' => count($payments),
  349.             ]);
  350.             $subject "Paiement du document " $folder->getDocumentCategory()->getLabel();
  351.             $notificationMessage "Le paiement du dossier N° " $folder->getNumber() . " intitulé " $folder->getDocumentCategory()->getLabel() .
  352.                 " crée dans la commune de " $folder->getSite()->getLabel() . "<br> a été effectué pour un montant de " $transaction->getAmount() .
  353.                 " " $transaction->getCurrency() . " par " $folder->getUserCreate()->getUserName();
  354.             Utilitaires::sendMail(
  355.                 $mailListArray,
  356.                 $this->mailer,
  357.                 $subject,
  358.                 $notificationMessage,
  359.                 'email/send_payment_notification.html.twig',
  360.                 [
  361.                     'folder' => $folder,
  362.                     'transaction' => $transaction,
  363.                     'message' => ''
  364.                 ],
  365.                 $this->logger
  366.             );
  367.         } elseif (($result['status'] ?? null) === 'FAILED') {
  368.             $transaction $this->managerRegistry->getRepository(Transaction::class)->find($result['transaction_id']);
  369.             $folder $transaction->getFolder();
  370.             $makutaLogger->info('[MAKUTA_V2] Callback FAILED : paiement en échec', [
  371.                 'folder' => $folder->getId(),
  372.                 'transaction' => $transaction->getId(),
  373.             ]);
  374.             $subject "Echec de paiement du document " $folder->getDocumentCategory()->getLabel();
  375.             $notificationMessage "Le paiement du dossier N° " $folder->getNumber() . " intitulé " $folder->getDocumentCategory()->getLabel() .
  376.                 " crée dans la commune de " $folder->getSite()->getLabel() . " a <b style='color: darkred'> échoué </b> pour un montant de " $transaction->getAmount() .
  377.                 " " $transaction->getCurrency() . " par " $folder->getUserCreate()->getUserName();
  378.             Utilitaires::sendMail(
  379.                 $mailListArray,
  380.                 $this->mailer,
  381.                 $subject,
  382.                 $notificationMessage,
  383.                 'email/send_payment_notification.html.twig',
  384.                 [
  385.                     'folder' => $folder,
  386.                     'transaction' => $transaction,
  387.                     'message' => ''
  388.                 ],
  389.                 $this->logger
  390.             );
  391.         }
  392.         $response = new Response(json_encode(['received' => true]));
  393.         $response->headers->set('Content-Type''application/json');
  394.         return $response;
  395.     }
  396.     /**
  397.      * Point de retour navigateur après un paiement carte chez Makuta. Makuta ne renvoie
  398.      * aucun paramètre identifiant dans cette redirection (vérifié en preprod : query string
  399.      * vide), donc on ne peut pas retrouver la transaction depuis l'URL. À la place, on utilise
  400.      * la dernière transaction en attente de l'utilisateur encore connecté dans cette session.
  401.      */
  402.     public function makutaRedirect(Request $requestMakutaAPIV2 $makutaApiV2LoggerInterface $makutaLogger): Response
  403.     {
  404.         $body json_decode($request->getContent(), true) ?? [];
  405.         $txnId $body['txnId']
  406.             ?? $body['txn_id']
  407.             ?? $request->request->get('txnId')
  408.             ?? $request->request->get('txn_id');
  409.         if ($txnId !== null) {
  410.             // Observé en preprod : Makuta envoie parfois le callback serveur-à-serveur sur
  411.             // cette URL de redirection plutôt que sur /usr/makuta_callback. Si le corps contient
  412.             // bien un txnId, on le traite comme un callback plutôt que de l'ignorer. Sinon (ex:
  413.             // retour navigateur via formulaire auto-soumis, sans JSON), on continue ci-dessous.
  414.             $makutaLogger->warning('[MAKUTA_V2] Callback reçu sur l\'URL de redirection au lieu de l\'URL de callback');
  415.             return $this->makutaCallback($request$makutaApiV2$makutaLogger);
  416.         }
  417.         $makutaLogger->info('[MAKUTA_V2] Redirection reçue', [
  418.             'method' => $request->getMethod(),
  419.             'query' => $request->query->all(),
  420.             'body' => $body,
  421.         ]);
  422.         $user $this->getUser();
  423.         if ($user !== null) {
  424.             $transaction $this->managerRegistry->getRepository(Transaction::class)->findOneBy(
  425.                 ['user' => $user'status' => 'PENDING'],
  426.                 ['creationDate' => 'DESC']
  427.             );
  428.             if ($transaction !== null) {
  429.                 $makutaLogger->info('[MAKUTA_V2] Redirection : dossier retrouvé via la session', [
  430.                     'user' => $user->getUserIdentifier(),
  431.                     'transaction' => $transaction->getId(),
  432.                     'folder' => $transaction->getFolder()->getId(),
  433.                 ]);
  434.                 return $this->redirectToRoute('app_folder_view', [
  435.                     'folder_id' => $transaction->getFolder()->getId(),
  436.                 ]);
  437.             }
  438.         }
  439.         $makutaLogger->warning('[MAKUTA_V2] Redirection : aucune transaction en attente trouvée', [
  440.             'user' => $user !== null $user->getUserIdentifier() : null,
  441.         ]);
  442.         return $this->redirectToRoute('app_core_workspace_surfer');
  443.     }
  444.     function comparator($object1$object2): bool
  445.     {
  446.         return $object1->financialCorporationCategory->label $object2->financialCorporationCategory->label;
  447.     }
  448.     public function add(Request $requestSendNotificationService $sendNotificationService)
  449.     {
  450.         if ($this->getUser()->getUserType() != && $this->getUser()->getUserType() != 1) {
  451.             $this->addFlash('workspace_alert_warning'"Vous ne pouvez pas accéder à la ressource sollicitée");
  452.             return $this->redirectToRoute('app_core_workspace');
  453.         }
  454.         $price = new Prices();
  455.         $price->setUserCreate($this->getUser());
  456.         $price->setDateCreate(new \DateTime());
  457.         $price->setIsDeleted(false);
  458.         $price->setStatus(true);
  459.         $priceForm $this->createForm(PriceType::class, $price);
  460.         $priceForm->handleRequest($request);
  461.         if ($priceForm->isSubmitted() && $priceForm->isValid()) {
  462.             $p $this->managerRegistry->getRepository(Prices::class)->findOneBy([
  463.                 'site' => $price->getSite(),
  464.                 'documentCategory' => $price->getDocumentCategory(),
  465.                 'tarif' => $price->getTarif(),
  466.                 'isDeleted' => false,
  467.             ]);
  468.             if ($p === null) {
  469.                 $price->setIsDeleted(false);
  470.                 $em $this->managerRegistry->getManager();
  471.                 $em->persist($price);
  472.                 $em->flush();
  473.                 $notificationMessage "Le prix du document '" $price->getDocumentCategory()->getLabel() . "' a été fixé à " $price->getPrice() . "  " $price->getCurrency()->getLabel() . " pour la commune de " $price->getSite()->getLabel() . " par " $this->getUser()->getUserName();
  474.                 $sendNotificationService->sendMailNotification("Ajout de prix "$notificationMessage);
  475.                 $this->addFlash('add_price_success'"Le taux a été enregistré avec succès !");
  476.             } else {
  477.                 $this->addFlash('not_found_price'$price->getDocumentCategory()->getLabel() . " a déjà un taux fixé avec les mêmes éléments");
  478.             }
  479.         }
  480.         return $this->render('price/add.html.twig', [
  481.             'priceForm' => $priceForm->createView(),
  482.         ]);
  483.     }
  484.     public function update(Request $requestSendNotificationService $sendNotificationService)
  485.     {
  486.         if ($this->getUser()->getUserType() != && $this->getUser()->getUserType() != 1) {
  487.             $this->addFlash('workspace_alert_warning'"Vous ne pouvez pas accéder à la ressource sollicitée");
  488.             return $this->redirectToRoute('app_core_workspace');
  489.         }
  490.         $price $this->managerRegistry->getRepository(Prices::class)->findOneBy([
  491.             'id' => $request->get('price_id'),
  492.             'isDeleted' => false,
  493.         ]);
  494.         $currentPrice $price->getPrice();
  495.         $currency $price->getCurrency()->getLabel();
  496.         if ($price === null) {
  497.             $this->addFlash('not_found_price''Le taux ' ucfirst($request->get('price_id')) . ' n\'a pas été trouvé');
  498.             return $this->redirectToRoute('app_admin_prices_register');
  499.         }
  500.         $priceForm $this->createForm(PriceType::class, $price);
  501.         $priceForm->handleRequest($request);
  502.         if ($priceForm->isSubmitted() && $priceForm->isValid()) {
  503.             $price->setUserUpdate($this->getUser());
  504.             $price->setDateUpdate(new \DateTime());
  505.             $em $this->managerRegistry->getManager();
  506.             $em->persist($price);
  507.             $em->flush();
  508.             $this->addFlash('update_price_success'"Le taux a été modifié avec succès !");
  509.             $notificationMessage "Le prix du document '" $price->getDocumentCategory()->getLabel()
  510.                 . " a été modifié de " $currentPrice " " $currency
  511.                 "'  à " $price->getPrice() . " " $price->getCurrency()->getLabel() . " pour la commune de " $price->getSite()->getLabel() . " par " $this->getUser()->getUserName();
  512.             $sendNotificationService->sendMailNotification("Modification de prix "$notificationMessage);
  513.             return $this->redirectToRoute('app_admin_prices_register', []);
  514.         }
  515.         return $this->render('price/add.html.twig', [
  516.             'priceForm' => $priceForm->createView(),
  517.         ]);
  518.     }
  519.     public function register(Request $request)
  520.     {
  521.         if ($this->getUser()->getUserType() != && $this->getUser()->getUserType() != 1) {
  522.             $this->addFlash('workspace_alert_warning'"vous n'avez pas le droit d'accéder à cette fonctionnalité, Prière de contacter votre administrateur pour obtenir les privilèges requis");
  523.             return $this->redirectToRoute('app_core_workspace');
  524.         }
  525.         $prices $this->managerRegistry->getRepository(Prices::class)->findBy([
  526.             'isDeleted' => false,
  527.         ]);
  528.         return $this->render('price/register.html.twig', [
  529.             'prices' => $prices,
  530.         ]);
  531.     }
  532.     /**
  533.      * @param Prices $documentPrice
  534.      * @param array $fees
  535.      * @param $currency
  536.      * @return float
  537.      */
  538.     private function calculateTotalAmount(Prices $documentPrice, array $fees$currency): float
  539.     {
  540.         $currentRate $this->managerRegistry->getRepository(ExchangeRate::class)->findOneBy([
  541.             'isActive' => true
  542.         ]);
  543.         $formatedFees $this->getFees($fees$currentRate$currency);
  544.         switch ($currency) {
  545.             case 'CDF':
  546.                 $totalAmount $documentPrice->getPrice() * $currentRate->getRate();
  547.                 foreach ($formatedFees as $fee) {
  548.                     $totalAmount += $fee['priceCDF'];
  549.                 }
  550.                 break;
  551.             default:
  552.                 $totalAmount $documentPrice->getPrice();
  553.                 foreach ($formatedFees as $fee) {
  554.                     $totalAmount += $fee['priceUSD'];
  555.                 }
  556.                 break;
  557.         }
  558.         return $totalAmount;
  559.     }
  560.     private function getFees(array $fees$currentRate$currency): array
  561.     {
  562.         $array_id array_map(function ($fee) {
  563.             return $fee['id'];
  564.         }, $fees);
  565.         $result $this->managerRegistry->getRepository(Fees::class)->findByIdIn($array_id);
  566.         return $this->feesService->formatFees($result$currentRate$currency);
  567.     }
  568. }