src/Controller/Front/FrontBasketController.php line 152

Open in your IDE?
  1. <?php
  2. namespace Acme\SudcmsBundle\Controller\Front;
  3. use Acme\SudcmsBundle\Entity\ApiSettings;
  4. use Acme\SudcmsBundle\Entity\Cure;
  5. use Acme\SudcmsBundle\Entity\CureOrder;
  6. use Acme\SudcmsBundle\Entity\CureProductOrder;
  7. use Acme\SudcmsBundle\Entity\CureProductSoinsOrder;
  8. use Acme\SudcmsBundle\Entity\EcoCustomers;
  9. use Acme\SudcmsBundle\Entity\EcoDiscountOrders;
  10. use Acme\SudcmsBundle\Entity\EcoOrders;
  11. use Acme\SudcmsBundle\Entity\EcoPlanning;
  12. use Acme\SudcmsBundle\Entity\EcoProductsBundle;
  13. use Acme\SudcmsBundle\Entity\EcoProductsReferences;
  14. use Acme\SudcmsBundle\Entity\EcoSettings;
  15. use Acme\SudcmsBundle\Entity\EcoShippingCarriers;
  16. use Acme\SudcmsBundle\Entity\Site;
  17. use Acme\SudcmsBundle\Entity\SiteCoordonnees;
  18. use Acme\SudcmsBundle\EventListener\BaseListener;
  19. use Acme\SudcmsBundle\Repository\EcoCustomersAddressesRepository;
  20. use Acme\SudcmsBundle\Repository\EcoCustomersRepository;
  21. use Acme\SudcmsBundle\Repository\EcoDiscountRepository;
  22. use Acme\SudcmsBundle\Repository\EcoOrdersProductsRepository;
  23. use Acme\SudcmsBundle\Repository\EcoOrdersRepository;
  24. use Acme\SudcmsBundle\Repository\SiteCoordonneesRepository;
  25. use Acme\SudcmsBundle\Service\ApiLogsService;
  26. use Acme\SudcmsBundle\Service\ApiService;
  27. use Acme\SudcmsBundle\Service\Ecommerce\BasketService;
  28. use Acme\SudcmsBundle\Service\Ecommerce\DiscountService;
  29. use Acme\SudcmsBundle\Service\Ecommerce\LoyaltySystemService;
  30. use Acme\SudcmsBundle\Service\Ecommerce\OrderService;
  31. use Acme\SudcmsBundle\Service\MailerService;
  32. use Acme\SudcmsBundle\Service\OtideaUtils;
  33. use Acme\SudcmsBundle\Service\Payment\PayboxService;
  34. use DateTime;
  35. use DateTimeZone;
  36. use Doctrine\ORM\EntityManagerInterface;
  37. use Exception;
  38. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  39. use Symfony\Component\HttpFoundation\JsonResponse;
  40. use Symfony\Component\HttpFoundation\RedirectResponse;
  41. use Symfony\Component\HttpFoundation\Request;
  42. use Symfony\Component\HttpFoundation\Response;
  43. use Symfony\Component\HttpFoundation\Session\Session;
  44. use Symfony\Component\Routing\Annotation\Route;
  45. use Throwable;
  46. use const SITE_NAME;
  47. #[Route(path'/panier')]
  48. class FrontBasketController extends AbstractController
  49. {
  50.     private $session;
  51.     private $orderService;
  52.     private $entityManager;
  53.     private $mailerService;
  54.     private $otideaUtils;
  55.     private $loyaltySystem;
  56.     private $basketService;
  57.     private $baseListener;
  58.     private $repoDiscount;
  59.     private $discountService;
  60.     private $currentUserConnected;
  61.     private ApiService $apiService;
  62.     private ApiLogsService $logsService;
  63.     private Site $site;
  64.     private array $recipients = [
  65.         [
  66.             "nom" => "Otidea",
  67.             "prenom" => "Debug",
  68.             "email" => "mail@otidea.com",
  69.             "type" => 'to'
  70.         ]
  71.     ];
  72.     private ?ApiSettings $apiSettings;
  73.     public function __construct(
  74.         EntityManagerInterface $entityManager,
  75.         OrderService           $orderService,
  76.         MailerService          $mailerService,
  77.         OtideaUtils            $otideaUtils,
  78.         LoyaltySystemService   $loyaltySystem,
  79.         BasketService          $basketService,
  80.         BaseListener           $baseListener,
  81.         EcoDiscountRepository  $repoDiscount,
  82.         DiscountService        $discountService,
  83.         ApiService             $apiService,
  84.         ApiLogsService         $logsService
  85.     )
  86.     {
  87.         $this->session = new Session();
  88.         $this->entityManager $entityManager;
  89.         $this->orderService $orderService;
  90.         $this->mailerService $mailerService;
  91.         $this->otideaUtils $otideaUtils;
  92.         $this->loyaltySystem $loyaltySystem;
  93.         $this->basketService $basketService;
  94.         $this->baseListener $baseListener;
  95.         $this->repoDiscount $repoDiscount;
  96.         $this->discountService $discountService;
  97.         $this->currentUserConnected $otideaUtils->getUserConnected();
  98.         $this->apiService $apiService;
  99.         $this->logsService $logsService;
  100.         $this->site $this->entityManager->getRepository(Site::class)->findOneBy(
  101.             ['id' => defined('CURRENT_SITE_ID') ? CURRENT_SITE_ID 1]
  102.         );
  103.         $this->apiSettings $this->entityManager->getRepository(ApiSettings::class)->findOneBy(
  104.             ['siteId' => CURRENT_SITE_ID]
  105.         );
  106.         if (!IS_ECOMMERCE) {
  107.             header('Location: ' WEBSITEROOT);
  108.             exit;
  109.         }
  110.     }
  111.     private function validateSession()
  112.     {
  113.         if ($this->session->has('order_id')) {
  114.             $order $this->entityManager->getRepository(EcoOrders::class)->find($this->session->get('order_id'));
  115.             if (!is_string($this->session->get('order_id')) && $this->session->get('order_id') == 0) {
  116.                 $this->session->remove('order_id');
  117.                 return $this->redirectToRoute('front_basket_index');
  118.             }
  119.             //Vérification de la commande en cours, si le statut n'est pas failure on supprime toutes les sessions
  120.             //pour éviter de modifier une commande validée
  121.             if (($order && $order->getOrderStatus() != 'failure') || $this->session->get('order_valid') == 'valid') {
  122.                 //Suppression des sessions
  123.                 $this->session->remove('basket');
  124.                 $this->session->remove('order_id');
  125.                 $this->session->remove('order_valid');
  126.                 $this->session->remove('carrier_id');
  127.                 $this->session->remove('discount_id');
  128.                 $this->session->remove('loyalty_point_used');
  129.                 $this->session->remove('giftText');
  130.                 $this->session->remove('cgv');
  131.                 $this->session->remove('customerIdOdyssee');
  132.                 $this->session->remove('cureIdForAssociatedProducts');
  133.                 return $this->redirectToRoute('front_basket_index');
  134.             }
  135.         }
  136.     }
  137.     #[Route(path'/'name'front_basket_index')]
  138.     public function index(
  139.         Request               $request,
  140.         BasketService         $basketService,
  141.         EcoDiscountRepository $repoDiscount,
  142.         LoyaltySystemService  $loyaltySystem
  143.     ): Response
  144.     {
  145.         //Valider les sessions
  146.         $this->validateSession();
  147.         //Affichage popup
  148.         $this->displayPopup();
  149.         //        //Appliquer un code de réduction
  150.         //        if ($request->isMethod('POST') && $request->get('discount_code')) {
  151.         //
  152.         //            $articles = $basketService->getFormatedBasketProducts();
  153.         //            $ds->initService($articles, $this->session->has('customer') ? $this->session->get('customer') : null);
  154.         //            $discount = $ds->discountValidation($request->get('discount_code'));
  155.         //
  156.         //            if($discount['status']){
  157.         //                $this->session->set('discount_id', $ds->discount_id);
  158.         //                $basketService->applyDiscountBasket($request->get('discount_code'));
  159.         //            } else {
  160.         //                $this->otideaUtils->createPopup(["title" => 'Problème avec votre remise',
  161.         //                        "message" => $discount['message'],
  162.         //                        "btn2" => null]
  163.         //                );
  164.         //            }
  165.         //        }
  166.         $discount null;
  167.         if ($this->session->has('discount_id') && $this->session->get('discount_id') > 0) {
  168.             $discount $repoDiscount->find($this->session->get('discount_id'));
  169.         }
  170.         //Remise fidélité
  171.         if ($this->currentUserConnected != null) {
  172.             $loyaltySystem->init($this->currentUserConnected->getId());
  173.         }
  174.         $now = new \DateTime('', new DateTimeZone('Europe/Paris'));
  175.         $now->format('Y-m-d H:i:s');
  176.         $currentSaisonStart $this->apiSettings->getCurrentYearStartDate();
  177.         $currentSaisonEnd $this->apiSettings->getCurrentYearEndDate();
  178.         $nextSaisonStart $this->apiSettings->getNextYearStartDate();
  179.         $nextSaisonEnd $this->apiSettings->getNextYearEndDate();
  180.         $startYear $currentSaisonStart->format('Y');
  181.         $endYear $nextSaisonEnd->format('Y');
  182.         $datesExcluded = [];
  183.         // Parcourir toutes les dates de l'année en cours
  184.         for ($year $startYear$year <= $endYear$year++) {
  185.             for ($month 1$month <= 12$month++) {
  186.                 $daysInMonth cal_days_in_month(CAL_GREGORIAN$month$year);
  187.                 for ($day 1$day <= $daysInMonth$day++) {
  188.                     // Date du jour testé
  189.                     $dateActuelle = new DateTime("$year-$month-$day");
  190.                     // Si la date est en dehors des saisons en cours et à venir
  191.                     if (($dateActuelle $currentSaisonStart || $dateActuelle $currentSaisonEnd) &&
  192.                         ($dateActuelle $nextSaisonStart || $dateActuelle $nextSaisonEnd)) {
  193.                         $datesExcluded[] = $dateActuelle->format('Y-m-d');
  194.                     }
  195.                 }
  196.             }
  197.         }
  198.         $allSoinsReservation false;
  199.         $basketHasSoin false;
  200.         foreach ($this->session->get('basket') as $item) {
  201.             if (!is_string($item['referenceObject']) && $item['referenceObject']->getTypeOdyssee() == "soin") {
  202.                 $basketHasSoin true;
  203.                 if ($item['referenceObject']->getIsReservable() === true && $item['referenceObject']->getTypeOdyssee() == "soin") {
  204.                     $allSoinsReservation true;
  205.                 }
  206.             }
  207.         }
  208.         if ($this->currentUserConnected == null) {
  209.             return $this->redirectToRoute('front_app_login');
  210.         } else {
  211.             $odysseeCustomers $this->apiService->rechercherClient(
  212.                 adrCourriel$this->currentUserConnected->getAuthUserId()->getEmail()
  213.             );
  214.         }
  215.         $isCure false;
  216.         foreach ($this->session->get('basket') as $key => $basket) {
  217.             if (strpos($key'CURE') === 0) {
  218.                 $isCure true;
  219.             }
  220.         }
  221.         return $this->render('@main-app/front/front_basket/basket.html.twig', [
  222.             'isCure' => $isCure,
  223.             'basket' => $this->session->get('basket'),
  224.             'subtotal' => $basketService->getSubtotal(),
  225.             'defaultShippingFees' => $basketService->getDefaultShippingFees(),
  226.             'discount' => $discount,
  227.             'loyaltyDiscount' => $loyaltySystem->getTotalDiscount(),
  228.             'loyaltyPoints' => $loyaltySystem->getTotalPoint(),
  229.             'step' => 'basket',
  230.             'datesExcluded' => $datesExcluded,
  231.             'startYear' => $startYear,
  232.             'endYear' => $endYear,
  233.             'basketHasSoin' => $basketHasSoin,
  234.             'odysseeCustomers' => $odysseeCustomers,
  235.             'allSoinsReservation' => $allSoinsReservation
  236.         ]);
  237.     }
  238.     /**
  239.      * @throws Throwable
  240.      */
  241.     #[Route(path'/livraison/{carrier_id}'name'front_basket_delivery'defaults: ['carrier_id' => 1])]
  242.     public function delivery(
  243.         Request                         $request,
  244.         EcoCustomersRepository          $repoCustomers,
  245.         BasketService                   $basketService,
  246.         EcoCustomersAddressesRepository $repoAddress,
  247.         OtideaUtils                     $otideaUtils,
  248.         EcoDiscountRepository           $repoDiscount,
  249.         ApiService                      $api,
  250.                                         $carrier_id 1
  251.     ): Response
  252.     {
  253.         //Valider les sessions
  254.         $this->validateSession();
  255.         if (ODYSSEE_TYPE == 'CURE') {
  256.             $carrier_id 'cure';
  257.         }
  258.         if ((ODYSSEE_TYPE == 'SPA' && (!$this->session->get('customerIdOdyssee') || $this->session->get('customerIdOdyssee') != $request->get('valueCustomerIdOdyssee')))) {
  259.             $this->session->set('customerIdOdyssee'$request->get('valueCustomerIdOdyssee'));
  260.         }
  261.         // Si la connexion à Odyssee est impossible, on redirige vers la page d'accueil
  262.         if (!$api->testConnexion()) {
  263.             $this->addFlash('danger''Une erreur est survenue, veuillez réessayer ultérieurement.');
  264.             return $this->redirectToRoute('front_home');
  265.         }
  266.         //Si l'utilisateur n'est pas connecté
  267.         if (!$this->currentUserConnected || $this->currentUserConnected === null) {
  268.             $this->session->set('returnToBasket'true);
  269.             return $this->redirectToRoute('front_app_login');
  270.         }
  271.         $patient $this->getUser()->getCustomer()[0]->getOdysseeReference();
  272.         $odysseeCustomer $api->rechercherClient(idOdyssee: (int)$patient)[0];
  273.         //Enregistrement du message cadeau
  274.         $this->giftText($request);
  275.         //Vérification du choix de la glacière
  276.         if ($request->get('valueGlaciere') != null) {
  277.             $this->session->set('valueGlaciere'$request->get('valueGlaciere'));
  278.         }
  279.         //Vérification de l'acceptation des CGV
  280.         if ($request->get('cgv') == null && $this->session->get('cgv') == null) {
  281.             $this->session->set('displayPopup''cgv-error');
  282.             return $this->redirectToRoute('front_basket_index');
  283.         } else {
  284.             if ($request->get('cgv') != null && $this->session->get('cgv') == null) {
  285.                 $this->session->set('cgv'$request->get('cgv'));
  286.             }
  287.         }
  288.         // <-- DEBUT --> Récupération carrierList
  289.         $customer $repoCustomers->find($this->currentUserConnected->getId());
  290.         $carrierList $basketService->getCarriersList($this->currentUserConnected);
  291.         // <-- FIN --> Récupération carrierList
  292.         // <-- DEBUT --> Récupération planning
  293.         $now = new \DateTime('', new DateTimeZone('Europe/Paris'));
  294.         $now->format('Y-m-d H:i:s');
  295.         // <-- FIN --> Récupération planning
  296.         // <-- DEBUT --> Récupération remise
  297.         $discount null;
  298.         if ($this->session->has('discount_id') && $this->session->get('discount_id') > 0) {
  299.             $discount $repoDiscount->find($this->session->get('discount_id'));
  300.         }
  301.         // <-- FIN --> Récupération remise
  302.         // Vérifie si il y a des produits dans le panier qui ne sont pas des cures et si il y en à au moins un de non livrable
  303.         $basketAsProduct false;
  304.         $basketAsProductNotDeliverable false;
  305.         foreach ($this->session->get('basket') as $items) {
  306.             if (!is_string($items['referenceObject'])) {
  307.                 $basketAsProduct true;
  308.                 if ($items['productObject']->getIsDeliverable() !== 'livrable') {
  309.                     $basketAsProductNotDeliverable true;
  310.                 }
  311.             }
  312.         }
  313.         $this->session->set('cureIdForAssociatedProducts'null);
  314.         // Par défaut sur une CURE, on définie la date de début
  315.         if ($this->session->get('basket')) {
  316.             $firstProductInBasket $this->session->get('basket')[array_key_first(
  317.                 $this->session->get('basket')
  318.             )]['productObject'];
  319.         } else {
  320.             return $this->redirectToRoute('front_basket_index');
  321.         }
  322.         $dateDebut is_object($firstProductInBasket) ? null : new \DateTime($firstProductInBasket['dateDebut']);
  323.         // Si il y a des produits dans le panier qui ne sont pas des cures, on récupère les cures disponibles et valides
  324.         $allAvailablesResaCures = [];
  325.         if ($basketAsProduct and ODYSSEE_TYPE == 'CURE') {
  326.             // On récupère toutes les Cures de tous les patients associés à ce compte
  327.             $customers $this->currentUserConnected->getAuthUserId()->getCustomer();
  328.             $orders = [];
  329.             foreach ($customers as $customer) {
  330.                 // Récupération des commandes du client
  331.                 $order $api->rechercherResaCure(idOdysseeClient: (int)$customer->getOdysseeReference());
  332.                 if (!isset($order->status)) {
  333.                     $orders[] = $api->rechercherResaCure(idOdysseeClient: (int)$customer->getOdysseeReference());
  334.                 }
  335.             }
  336.             // On parcours les cures, on ne garde que celles dont la date de début est supérieure à la date du jour
  337.             foreach ($orders as $cust) {
  338.                 foreach ($cust as $cure) {
  339.                     $dateDebut = new \DateTime($cure->{'Date_Debut_Resa'});
  340.                     $dateJour = new \DateTime();
  341.                     if ($dateDebut $dateJour) {
  342.                         // On remplace le code de l'indication principale par son nom et l'ID patient de la cure par son nom
  343.                         $cure->{'Indication_Principale'} = $this->entityManager->getRepository(Cure::class)->findOneBy(
  344.                             ['odysseeReference' => $cure->{'Indication_Principale'}]
  345.                         )->getTitle();
  346.                         $cure->{'IdOdysseeClient'} = $api->rechercherClient(
  347.                                 idOdyssee: (int)$cure->{'IdOdysseeClient'}
  348.                             )[0]->{'Nom'} . ' ' $api->rechercherClient(
  349.                                 idOdyssee: (int)$cure->{'IdOdysseeClient'}
  350.                             )[0]->{'Prenom'};
  351.                         $allAvailablesResaCures[] = $cure;
  352.                     }
  353.                 }
  354.             }
  355.             if (!empty($allAvailablesResaCures) && $carrier_id == 'cure') {
  356.                 $dateDebut = new \DateTime($allAvailablesResaCures[0]->{'Date_Debut_Resa'});
  357.                 $this->session->set(
  358.                     'cureIdForAssociatedProducts',
  359.                     (int)$allAvailablesResaCures[array_key_first($allAvailablesResaCures)]->{'IdOdysseeResa'}
  360.                 );
  361.             }
  362.         }
  363.         if (empty($this->session->get('basket'))) {
  364.             return $this->redirectToRoute('front_home');
  365.         }
  366.         // Si on est sur un site de CURE, on désactive les transporteurs
  367.         if (ODYSSEE_TYPE == 'CURE') {
  368.             $basketAsProductNotDeliverable true;
  369.         } elseif (ODYSSEE_TYPE == 'SPA') {
  370.             $dateDebut $request->get('wantResa') == '1' ? new \DateTime(
  371.                 str_replace('/''-'$request->get('date_debut'))
  372.             ) : null;
  373.             $wantResa $request->get('wantResa');
  374.             //            if ($dateDebut == null) {
  375.             //                $basketAsProductNotDeliverable = false;
  376.             //            }
  377.         }
  378.         $currentSaisonStart $this->apiSettings->getCurrentYearStartDate();
  379.         $currentSaisonEnd $this->apiSettings->getCurrentYearEndDate();
  380.         $nextSaisonStart $this->apiSettings->getNextYearStartDate();
  381.         $nextSaisonEnd $this->apiSettings->getNextYearEndDate();
  382.         $startYear $currentSaisonStart->format('Y');
  383.         $endYear $nextSaisonEnd->format('Y');
  384.         $datesExcluded = [];
  385.         // Parcourir toutes les dates de l'année en cours
  386.         for ($year $startYear$year <= $endYear$year++) {
  387.             for ($month 1$month <= 12$month++) {
  388.                 $daysInMonth cal_days_in_month(CAL_GREGORIAN$month$year);
  389.                 for ($day 1$day <= $daysInMonth$day++) {
  390.                     // Date du jour testé
  391.                     $dateActuelle = new DateTime("$year-$month-$day");
  392.                     // Si la date est en dehors des saisons en cours et à venir
  393.                     if (($dateActuelle $currentSaisonStart || $dateActuelle $currentSaisonEnd) &&
  394.                         ($dateActuelle $nextSaisonStart || $dateActuelle $nextSaisonEnd)) {
  395.                         $datesExcluded[] = $dateActuelle->format('Y-m-d');
  396.                     }
  397.                 }
  398.             }
  399.         }
  400.         //Définir le transporteur
  401.         $this->session->set('carrier_id'$basketAsProductNotDeliverable $carrier_id);
  402.         $step "";
  403.         if (ODYSSEE_TYPE == 'CURE') {
  404.             $step "CURE";
  405.         } elseif (ODYSSEE_TYPE == 'SPA') {
  406.             $step "SPA";
  407.         } else {
  408.             $step "delivery";
  409.         }
  410.         return $this->render('@main-app/front/front_basket/delivery.html.twig', [
  411.             'step' => $step,
  412.             'subtotal' => $basketService->getSubtotal(),
  413.             'odysseeCustomer' => $odysseeCustomer,
  414.             'defaultShippingFees' => $basketAsProductNotDeliverable $basketService->getDefaultShippingFees(
  415.                 $carrier_id,
  416.                 1
  417.             ),
  418.             'shippingFeesFree' => $basketService->getShippingFeesFree($basketAsProductNotDeliverable $carrier_id),
  419.             'carriersList' => $carrierList,
  420.             'customer' => $customer,
  421.             'discount' => $discount,
  422.             'carrier_id' => $carrier_id,
  423.             'glaciere' => $this->session->get('valueGlaciere'),
  424.             'basketAsProduct' => $basketAsProduct,
  425.             'basketAsProductNotDeliverable' => $basketAsProductNotDeliverable,
  426.             'allAvailablesResaCures' => !isset($allAvailablesResaCures->status) ? $allAvailablesResaCures : [],
  427.             'wantResa' => $wantResa ?? 'false',
  428.             'dateDebut' => $dateDebut $dateDebut->format('d/m/Y') : null,
  429.             'datesExcluded' => $datesExcluded,
  430.             'startYear' => $startYear,
  431.             'endYear' => $endYear
  432.         ]);
  433.     }
  434.     // Requête AJAX pour setter en session PHP l'ID de la cure sélectionnée
  435.     #[Route(path'/axCureIdForAssociatedProducts'name'front_basket_set_cure_associated')]
  436.     public function axCureIdForAssociatedProducts(Request $requestApiService $api): JsonResponse
  437.     {
  438.         if ($request->isXmlHttpRequest()) {
  439.             $this->session->set('cureIdForAssociatedProducts', (int)$request->get('cureId'));
  440.             return new JsonResponse(['status' => 'success']);
  441.         }
  442.         return new JsonResponse(['status' => 'error']);
  443.     }
  444.     // Requête AJAX qui va récupérer les soins d'un produit
  445.     #[Route(path'/axGetSoinOnProduct'name'front_basket_get_soin_on_product')]
  446.     public function axGetSoinOnProduct(Request $requestApiService $api): JsonResponse
  447.     {
  448.         if ($request->isXmlHttpRequest()) {
  449.             $soinProduct $api->rechSoinResaSpaParCodeProduit($request->get('reference'));
  450.             return new JsonResponse(
  451.                 [
  452.                     'status' => true,
  453.                     'soinProductComposition' => $soinProduct[0]->{'Composition'}
  454.                 ]
  455.             );
  456.         }
  457.         return new JsonResponse(
  458.             [
  459.                 'status' => 'error'
  460.             ]
  461.         );
  462.     }
  463.     // Requête AJAX qui va récupérer les disponibilité d'un soin avec son ID
  464.     #[Route(path'/axGetSoinAvailability'name'front_basket_get_soin_availability')]
  465.     public function axGetSoinAvailability(Request $requestApiService $api): JsonResponse
  466.     {
  467.         if ($request->isXmlHttpRequest()) {
  468.             $basket $this->session->get('basket');
  469.             //On sépare chaque élément de la date dans un tableau
  470.             $date explode('/'$request->get('dateDebut'));
  471.             //On vérifie que le tableau de date contient bien 3 éléments
  472.             if (count($date) != 3) {
  473.                 return new JsonResponse(
  474.                     [
  475.                         'date' => $date,
  476.                         'status' => 'error'
  477.                     ]
  478.                 );
  479.             }
  480.             // On converti la date récupérée au format dd/mm/YYYY au format YYYY-mm-ddT00:00:00
  481.             $dateDebut = (new \DateTime($date[2] . '-' $date[1] . '-' $date[0]))->format('Y-m-d') . 'T00:00:00';
  482.             // On créer la date de fin en ajoutant 7 jours à la date de début
  483.             $dateFin = (new \DateTime($date[2] . '-' $date[1] . '-' $date[0]))->modify(
  484.                     '+' $this->apiSettings->getNbDaysAvailableSearch() . ' day'
  485.                 )->format('Y-m-d') . 'T00:00:00';
  486.             try {
  487.                 $disposSoin $api->dispoSoin((string)$request->get('codeSoin'), $dateDebut$dateFin);
  488.             } catch (Exception|Throwable $e) {
  489.                 return new JsonResponse(
  490.                     [
  491.                         'status' => false,
  492.                         'codeSoin' => $request->get('codeSoin'),
  493.                         'error' => $e->getMessage()
  494.                     ]
  495.                 );
  496.             }
  497.             // Vérification erreur API
  498.             $error = isset($disposSoin->status);
  499.             if (!$error) {
  500.                 foreach ($basket as $key => $product) {
  501.                     if (!is_string($product['referenceObject'])
  502.                         && $product['referenceObject']->getId() == (int)$request->get('prodId')) {
  503.                         $basket[$key]['disposSoins'][$request->get('codeSoin')]['day'] = $disposSoin[0]->{'Jour'};
  504.                         $basket[$key]['disposSoins'][$request->get('codeSoin')]['hour'] = $disposSoin[0]->{'Horaire'};
  505.                     }
  506.                 }
  507.             }
  508.             $this->session->set('basket'$basket);
  509.             // Réponse finale
  510.             return new JsonResponse([
  511.                 'status' => !$error,
  512.                 'disposSoin' => $disposSoin,
  513.                 'codeSoin' => $request->get('codeSoin'),
  514.                 'error' => $error
  515.             ]);
  516.         }
  517.         return new JsonResponse(
  518.             [
  519.                 'status' => 'error'
  520.             ]
  521.         );
  522.     }
  523.     // Requête AJAX pour setter en session PHP les dispos des soins choisies
  524.     #[Route(path'/axSetSoinDispo'name'front_basket_set_soin_dispo')]
  525.     public function axSetSoinDispo(Request $request): JsonResponse
  526.     {
  527.         if ($request->isXmlHttpRequest()) {
  528.             $basket $this->session->get('basket');
  529.             $day $request->get('day');
  530.             $hour $request->get('hour');
  531.             $prodId $request->get('prodId');
  532.             foreach ($basket as $key => $product) {
  533.                 if (!is_string($product['referenceObject']) && $product['referenceObject']->getId() == (int)$prodId) {
  534.                     $basket[$key]['disposSoins'][$request->get('codeSoin')]['day'] = $day;
  535.                     $basket[$key]['disposSoins'][$request->get('codeSoin')]['hour'] = $hour;
  536.                 }
  537.             }
  538.             $this->session->set('basket'$basket);
  539.             return new JsonResponse(
  540.                 [
  541.                     'status' => 'success',
  542.                     'basket' => $this->session->get('basket')
  543.                 ]
  544.             );
  545.         }
  546.         return new JsonResponse(
  547.             [
  548.                 'status' => 'error'
  549.             ]
  550.         );
  551.     }
  552.     private function giftText($request)
  553.     {
  554.         if ($request->get('giftText')) {
  555.             $this->session->set('giftText'$request->get('giftText'));
  556.         }
  557.         //        elseif($this->session->has('giftText')) {
  558.         //            $this->session->remove('giftText');
  559.         //        }
  560.     }
  561.     /**
  562.      * @throws Throwable
  563.      */
  564.     #[Route(path'/paiement/{paymentMode}'name'front_basket_payment'defaults: ['paymentMode' => 'bank'])]
  565.     public function payment(
  566.         BasketService                   $basketService,
  567.         EcoCustomersRepository          $customersRepository,
  568.         EcoCustomersAddressesRepository $repoAddress,
  569.         EcoOrdersRepository             $repoOrder,
  570.         EcoDiscountRepository           $repoDiscount,
  571.         ApiService                      $api,
  572.                                         $paymentMode 'bank'
  573.     ): Response
  574.     {
  575.         // Si la connexion à Odyssee est impossible, on redirige vers la page d'accueil
  576.         if (!$api->testConnexion()) {
  577.             $this->addFlash('danger''Une erreur est survenue, veuillez réessayer ultérieurement.');
  578.             return $this->redirectToRoute('front_home');
  579.         }
  580.         //Si l'utilisateur n'est pas connecté
  581.         if (!$this->currentUserConnected || $this->currentUserConnected === null) {
  582.             $this->session->set('returnToBasket'true);
  583.             return $this->redirectToRoute('front_app_login');
  584.         }
  585.         //Valider les sessions
  586.         $this->validateSession();
  587.         $patient $this->getUser()->getCustomer()[0]->getOdysseeReference();
  588.         $odysseeCustomer $api->rechercherClient(idOdyssee: (int)$patient)[0];
  589.         $deliveryAddress $odysseeCustomer->{'Adresse1'} . ' ' $odysseeCustomer->{'Adresse2'} . ' ' $odysseeCustomer->{'Adresse3'} . ' ' $odysseeCustomer->{'CodePostal'} . ' ' $odysseeCustomer->{'Ville'};
  590.         //Vérification des informations obligatoires
  591.         //        if (!$this->session->has('customer') || $this->session->get('customer') === null || $this->session->get('carrier_id') === null || $this->session->get('basket') === null) {
  592.         //            return $this->redirectToRoute('front_customer_connection');
  593.         //        }
  594.         // <-- DEBUT --> Récupération remise
  595.         $discount null;
  596.         if ($this->session->has('discount_id') && $this->session->get('discount_id') > 0) {
  597.             $discount $repoDiscount->find($this->session->get('discount_id'));
  598.         }
  599.         // <-- FIN --> Récupération remise
  600.         //Enregistrer la commande avant de passer au paiement
  601.         //$this->insertOrder($basketService, $deliveryAddress[0]->getId(), $paymentMode, $discount);
  602.         $date = new \DateTime();
  603.         $dateString $date->format('Y-m-d');
  604.         $this->session->set('order_id'$dateString '-' $patient);
  605.         return $this->render('@main-app/front/front_basket/payment.html.twig', [
  606.             'subtotal' => $subtotal $basketService->getSubtotal(),
  607.             'defaultShippingFees' => $basketService->getDefaultShippingFees(
  608.                 $this->session->get('carrier_id'),
  609.                 1
  610.             ),
  611.             //            'order'               => $repoOrder->find($this->session->get('order_id')),
  612.             'step' => 'payment',
  613.             'discount' => $discount,
  614.             'currentUser' => $this->currentUserConnected
  615.         ]);
  616.     }
  617.     private function insertOrder($basketService$shipping_id$paymentMode$discountCode)
  618.     {
  619.         if ($shipping_id == null) {
  620.             return $this->redirectToRoute('front_app_login');
  621.         }
  622.         if (!$this->session->has('order_id') || $this->session->get('order_id') === null) {
  623.             $this->session->set('order_id'0);
  624.         }
  625.         //Récupération de la date de livraison
  626.         $now = new \DateTime('', new DateTimeZone('Europe/Paris'));
  627.         $now $now->format('Y-m-d H:i:s');
  628.         $company 0;
  629.         if ($this->currentUserConnected && $this->currentUserConnected->getCustAccountType() == 'company') {
  630.             $company $this->currentUserConnected->getId();
  631.         } else {
  632.             if ($this->currentUserConnected && $this->currentUserConnected->getCustAccountType() == 'employee') {
  633.                 $company $this->currentUserConnected->getCompany()->getId();
  634.             }
  635.         }
  636.         $planning $this->entityManager->getRepository(EcoPlanning::class)->getCurrentDeliveryAndOrder($now$company);
  637.         if (!$planning) {
  638.             $planning $this->entityManager->getRepository(EcoPlanning::class)->getNextDeliveryAndOrder(
  639.                 $now,
  640.                 $company
  641.             );
  642.         }
  643.         $params = [
  644.             'customer_id' => $this->currentUserConnected->getId(),
  645.             'shipping_id' => $shipping_id,
  646.             'carrier_id' => $this->session->get('carrier_id'),
  647.             'payment_mode' => $paymentMode,
  648.             'order_status' => 'failure',
  649.             'order_shipping_fees_free' => $basketService->getShippingFeesFree(),
  650.             'productsList' => $basketService->getFormatedBasketProducts(),
  651.             'order_actual_weight' => $basketService->getBasketWeight(),
  652.             'order_loyalty_point_used' => $this->session->has('loyalty_point_used') ? true false,
  653.             'order_gift_text' => $this->session->has('giftText') ? $this->session->get('giftText') : null,
  654.             'planning' => $planning,
  655.             'glaciere' => $this->session->get('valueGlaciere'),
  656.             'discountCode' => $discountCode
  657.         ];
  658.         $order_id $this->orderService->saveOrder($this->session->get('order_id'), $params);
  659.         $this->session->set('order_id'$order_id);
  660.         //Liaison avec un code de réduction s'il elle existe
  661.         $discount_id $this->session->has('discount_id') ? $this->session->get('discount_id') : null;
  662.         if ($discount_id !== null && $discount_id 0) {
  663.             $discount = new EcoDiscountOrders;
  664.             $discount->setDiscountId($discount_id);
  665.             $discount->setOrderId($order_id);
  666.             $this->entityManager->persist($discount);
  667.             $this->entityManager->flush();
  668.         }
  669.     }
  670.     /**
  671.      * @throws Throwable
  672.      */
  673.     #[Route(path'/payment_selection'name'front_basket_payment_selection')]
  674.     public function payment_selection(
  675.         Request             $request,
  676.         BasketService       $basketService,
  677.         EcoOrdersRepository $repoOrder,
  678.         ApiService          $api
  679.     )
  680.     {
  681.         if ($request->isMethod('POST')) {
  682.             switch ($request->get('paiement')) {
  683.                 case 'cheque' :
  684.                     $this->addFlash(
  685.                         'danger',
  686.                         'Une erreur est survenue avec cette commande, veuillez nous contacter'
  687.                     );
  688.                     return $this->redirectToRoute('front_home');
  689.                     //                    $order = $repoOrder->find($this->session->get('order_id'));
  690.                     //                    $order->setOrderPayment('cheque');
  691.                     //                    $this->entityManager->persist($order);
  692.                     //                    $this->entityManager->flush();
  693.                     //
  694.                     //                    return $this->redirectToRoute('front_basket_payment_cheque');
  695.                     break;
  696.                 case 'bank' :
  697.                     $carriers $basketService->getCarriersList($this->currentUserConnected);
  698.                     $selectedCarrierAmount 0;
  699.                     foreach ($carriers as $carrier) {
  700.                         if ($carrier['detail']->getId() == $this->session->get('carrier_id')) {
  701.                             $selectedCarrierAmount = (double)$carrier['total'];
  702.                         }
  703.                     }
  704.                     $saveCure $this->saveApiOrder($selectedCarrierAmount);
  705.                     if (in_array('error'$saveCure)) {
  706.                         $this->addFlash('danger''Une erreur est survenue, veuillez réessayer ultérieurement.');
  707.                         return $this->redirectToRoute('front_basket_index');
  708.                     }
  709.                     return $this->redirectToRoute('front_paybox_paiement', [
  710.                         'orderId' => $saveCure[0],
  711.                         'totalOrder' => $saveCure[1] + $selectedCarrierAmount,
  712.                     ]);
  713.                     //                    $order = $repoOrder->find($this->session->get('order_id'));
  714.                     //                    $order->setOrderPayment('bank');
  715.                     //                    $this->entityManager->persist($order);
  716.                     //                    $this->entityManager->flush();
  717.                     //
  718.                     //                    return $this->redirectToRoute('front_basket_payment_paybox');
  719.                     break;
  720.                 case 'nopayment' :
  721.                     $this->addFlash(
  722.                         'danger',
  723.                         'Une erreur est survenue avec cette commande, veuillez nous contacter'
  724.                     );
  725.                     return $this->redirectToRoute('front_home');
  726.                     //                    $order = $repoOrder->find($this->session->get('order_id'));
  727.                     //                    $order->setOrderPayment('nopayment');
  728.                     //                    $this->entityManager->persist($order);
  729.                     //                    $this->entityManager->flush();
  730.                     //
  731.                     //                    $this->validateOrder($order->getId());
  732.                     //
  733.                     //                    return $this->redirectToRoute('front_basket_confirmation');
  734.                     break;
  735.                 case 'store' :
  736.                     $this->addFlash(
  737.                         'danger',
  738.                         'Une erreur est survenue avec cette commande, veuillez nous contacter'
  739.                     );
  740.                     return $this->redirectToRoute('front_home');
  741.                     //                    $order = $repoOrder->find($this->session->get('order_id'));
  742.                     //                    $order->setOrderPayment('store');
  743.                     //                    $this->entityManager->persist($order);
  744.                     //                    $this->entityManager->flush();
  745.                     //
  746.                     //                    $this->validateOrder($order->getId());
  747.                     //                    return $this->redirectToRoute('front_basket_confirmation');
  748.                     break;
  749.             }
  750.         }
  751.         return $this->redirectToRoute('front_basket_index');
  752.     }
  753.     private function saveApiOrder($selectedCarrierAmount): array
  754.     {
  755.         $orderRef null;
  756.         $totalOrder null;
  757.         //Créer une référence unique pour la commande à partir de la date et de l'heure si la commande n'est pas nulle et de l'ID Odyssee du patient
  758.         foreach ($this->session->get('basket') as $product) {
  759.             if (is_string($product['referenceObject'])) {
  760.                 $orderRef = (new \DateTime(
  761.                         '',
  762.                         new DateTimeZone('Europe/Paris')
  763.                     ))->format('Y-m-d-H-i-s') . '-' $product['productObject']['idOdyssee'];
  764.             }
  765.         }
  766.         // On parcourt tous les produits du panier
  767.         foreach ($this->session->get('basket') as $product) {
  768.             // Si le produit est une cure
  769.             if (is_string($product['referenceObject'])) {
  770.                 // === Date de début ===
  771.                 if (!empty($product['productObject']['dateDebut'])) {
  772.                     $dateDebutObj = new \DateTime($product['productObject']['dateDebut'], new \DateTimeZone('Europe/Paris'));
  773.                 } else {
  774.                     return ['error'];
  775.                 }
  776.                 $dateDebut $dateDebutObj->format('Y-m-d') . 'T00:00:00';
  777.                 // === Calcul date de fin si absente ===
  778.                 // On calcule +18 jours ouvrés EN INCLUANT le jour de début
  779.                 $dateFinObj = clone $dateDebutObj;
  780.                 $daysToCount 18;
  781.                 $daysCounted 0;
  782.                 while ($daysCounted $daysToCount) {
  783.                     // Si ce n’est PAS dimanche (0 = dimanche)
  784.                     if ($dateFinObj->format('w') != 0) {
  785.                         $daysCounted++;
  786.                         if ($daysCounted === $daysToCount) {
  787.                             break;
  788.                         }
  789.                     }
  790.                     // On avance d’un jour
  791.                     $dateFinObj->modify('+1 day');
  792.                 }
  793.                 $dateFin $dateFinObj->format('Y-m-d') . 'T00:00:00';
  794.                 try {
  795.                     // On enregistre la cure dans Odyssee
  796.                     $returnAddCure $this->apiService->creerResaCure(
  797.                         idOdysseeClient$product['productObject']['idOdyssee'],
  798.                         idExterneResa$product['productObject']['idExterne'],
  799.                         cureP$product['productObject']['cureP'],
  800.                         cureS$product['productObject']['cureS'],
  801.                         dateDebut$dateDebut,
  802.                         dateFin$dateFin,
  803.                         nss$product['productObject']['nss'],
  804.                         medTherm$product['productObject']['medTherm'],
  805.                         medPresc$product['productObject']['medPresc'],
  806.                         plageHoraire$product['productObject']['plageHoraire'],
  807.                         commentaire$product['productObject']['commentaire'],
  808.                         quota$product['productObject']['quota'],
  809.                         etab$product['productObject']['etab'],
  810.                         pdv$this->site->getOdysseePdvId()
  811.                     );
  812.                     // On enregistre la cure dans la BDD
  813.                     $newCureOrder = new CureOrder();
  814.                     $newCureOrder->setIdOdysseeClient($product['productObject']['idOdyssee']);
  815.                     $newCureOrder->setIdExterne($product['productObject']['idExterne']);
  816.                     $newCureOrder->setCureP($product['productObject']['cureP']);
  817.                     $newCureOrder->setCureS($product['productObject']['cureS']);
  818.                     $newCureOrder->setDateDebut(new \DateTime($dateDebut));
  819.                     $newCureOrder->setDateFin(new \DateTime($dateFin));
  820.                     $newCureOrder->setPlageHoraire($product['productObject']['plageHoraire']);
  821.                     $newCureOrder->setNss($product['productObject']['nss']);
  822.                     $newCureOrder->setMedTherm($product['productObject']['medTherm']);
  823.                     $newCureOrder->setMedPresc($product['productObject']['medPresc']);
  824.                     $newCureOrder->setCommentaire($product['productObject']['commentaire']);
  825.                     $newCureOrder->setArrhes($product['productObject']['arrhes']);
  826.                     $newCureOrder->setQuota($product['productObject']['quota']);
  827.                     $newCureOrder->setEtab($product['productObject']['etab']);
  828.                     $newCureOrder->setPdv($product['productObject']['pdv']);
  829.                     $newCureOrder->setCureOrderRef($orderRef);
  830.                     $newCureOrder->setSavePaymentInOdyssee(0);
  831.                     // On met à jour la cure dans la BDD suivant le retour de l'API
  832.                     if (!isset($returnAddCure->status)) { // Si l'API ne retourne pas d'erreurs
  833.                         $newCureOrder->setIdOdysseeResa($returnAddCure[0]->IdOdysseeResa);
  834.                         $newCureOrder->setSaveInOdyssee(true);
  835.                         $newCureOrder->setSaveInOdysseeDate(
  836.                             new \DateTime(
  837.                                 '',
  838.                                 new DateTimeZone('Europe/Paris')
  839.                             )
  840.                         );
  841.                     } else { // Sinon, on indique l'erreur en BDD pour la traçabilité
  842.                         $newCureOrder->setSaveInOdyssee(false);
  843.                         $newCureOrder->setSaveInOdysseeDate(null);
  844.                         // Si c'est une erreur unique
  845.                         if (is_string(json_decode($returnAddCure)->errors)) {
  846.                             $content "<p><strong style='color:red;'>Erreur :</strong> " json_decode(
  847.                                     $returnAddCure
  848.                                 )->errors "</p>";
  849.                         } else { // Si c'est un tableau d'erreurs
  850.                             $content "<p><strong style='color:red;'>Erreurs :</strong></p>";
  851.                             foreach (json_decode($returnAddCure)->errors as $key => $error) {
  852.                                 $content .= "<br><br><p><strong style='color:red;'>Erreur " $key " :</strong> " $error[0] . "</p>";
  853.                             }
  854.                         }
  855.                         $newCureOrder->setSaveInOdysseeError($content);
  856.                     }
  857.                     $this->entityManager->persist($newCureOrder);
  858.                 } catch (Throwable $apiException) {
  859.                     // Si l'erreur est une erreur de connexion à l'API, on envoie un mail aux admins
  860.                     try {
  861.                         $htmlContent "<br><br><p><strong style='color:red;'>Erreur :</strong> " $apiException->getMessage() . "</p>";
  862.                         $this->mailerService->subject 'Erreur du serveur API - ' $this->site->getSiteName();
  863.                         $this->mailerService->sendMail(
  864.                             $this->recipients,
  865.                             $htmlContent
  866.                         );
  867.                     } catch (Throwable $emailException) {
  868.                         // Si on a une erreur lors de l'envoi du mail, on écrit dans le fichier de log
  869.                         $this->mailerService->writeLog(json_encode([
  870.                             "apiException : " $apiException->getMessage(),
  871.                             "eMailException : " $emailException->getMessage()
  872.                         ]),
  873.                             'FrontBasketController ligne 801 - Try/Catch <creerResaCure\>');
  874.                     }
  875.                     // On retourne une erreur pour afficher un message à l'utilisateur
  876.                     return ['error'];
  877.                 }
  878.                 $totalOrder += $product['productObject']['arrhes'];
  879.             } else { // Si le produit n'est pas une cure
  880.                 if (!$orderRef) {
  881.                     //Créer une référence unique pour la commande à partir de la date et de l'heure si la commande n'est pas nulle et de l'ID Odyssee du patient
  882.                     $orderRef = (new \DateTime(
  883.                             '',
  884.                             new DateTimeZone('Europe/Paris')
  885.                         ))->format('Y-m-d-H-i-s') . '-' . ($this->session->get('cureIdForAssociatedProducts') ?: 'SPA');
  886.                 }
  887.                 if (ODYSSEE_TYPE == 'CURE') {
  888.                     $customerOdyssee $this->apiService->rechercherResaCure(
  889.                         idOdysseeResa$this->session->get(
  890.                             'cureIdForAssociatedProducts'
  891.                         )
  892.                     )[0]->{'IdOdysseeClient'};
  893.                 } elseif (ODYSSEE_TYPE == 'SPA') {
  894.                     $customerOdyssee $this->session->get('customerIdOdyssee');
  895.                 }
  896.                 // On enregistre le produit en BDD
  897.                 $newCureProductOrder = new CureProductOrder();
  898.                 $newCureProductOrder->setCodeProduit(
  899.                     $product['referenceObject']->getTypeOdyssee() == 'bkdovalue' $product['referenceObject']->getTypeOdyssee() : $product['referenceObject']->getRefReference()
  900.                 );
  901.                 $newCureProductOrder->setTypeOdyssee($product['referenceObject']->getTypeOdyssee());
  902.                 $newCureProductOrder->setQteProduit($product['qte']);
  903.                 $newCureProductOrder->setOrderShippingCost($selectedCarrierAmount);
  904.                 $newCureProductOrder->setPrixUnitTtc(
  905.                     $product['referenceObject']->getTypeOdyssee() == 'bkdovalue' $product['referenceObject']->getRefReferencePrice() : $product['referenceObject']->getRefSellingPrice()
  906.                 );
  907.                 $newCureProductOrder->setTvaProduit($product['referenceObject']->getRefTva());
  908.                 $newCureProductOrder->setPrcRemise(0);
  909.                 $newCureProductOrder->setPdv(null);
  910.                 $newCureProductOrder->setOrderRef($orderRef);
  911.                 $newCureProductOrder->setOdysseeId(
  912.                     ODYSSEE_TYPE == 'CURE' $this->session->get('cureIdForAssociatedProducts') : null
  913.                 );
  914.                 $newCureProductOrder->setOdysseeClientId((int)$customerOdyssee ?? null);
  915.                 $newCureProductOrder->setSaveInOdyssee(false);
  916.                 $newCureProductOrder->setSavePaymentInOdyssee(0);
  917.                 $newCureProductOrder->setSiteId(CURRENT_SITE_ID);
  918.                 $this->entityManager->persist($newCureProductOrder);
  919.                 // Si i ly a des dispos soins, on les enregistre
  920.                 if (isset($product['disposSoins'])) {
  921.                     foreach ($product['disposSoins'] as $key => $soin) {
  922.                         $newCureProductSoinsOrder = new CureProductSoinsOrder();
  923.                         $newCureProductSoinsOrder->setCureProductOrder($newCureProductOrder);
  924.                         $newCureProductSoinsOrder->setCodeSoin($key);
  925.                         $newCureProductSoinsOrder->setDateSoin(new \DateTime($soin['day']));
  926.                         $newCureProductSoinsOrder->setHeureSoin($soin['hour']);
  927.                         $this->entityManager->persist($newCureProductSoinsOrder);
  928.                         $newCureProductOrder->addCureProductSoinsOrder($newCureProductSoinsOrder);
  929.                     }
  930.                 }
  931.                 // Suivant la nature du produit, on ajoute le bon montant au total
  932.                 if ($product['referenceObject']->getTypeOdyssee() == 'bkdovalue') {
  933.                     $totalOrder += $product['qte'] * ($product['referenceObject']->getRefReferencePrice() - ($product['referenceObject']->getRefReferencePrice() / 100));
  934.                 } else {
  935.                     $totalOrder += $product['qte'] * ($product['referenceObject']->getRefSellingPrice() - ($product['referenceObject']->getRefSellingPrice() / 100));
  936.                 }
  937.             }
  938.         }
  939.         $this->entityManager->flush();
  940.         // On récupère tous les produits enregistrés pour la commande en cours
  941.         $cureProductsOrder $this->entityManager->getRepository(CureProductOrder::class)->findBy(
  942.             [
  943.                 'orderRef' => $orderRef
  944.             ]
  945.         );
  946.         // Si on est PAS sur un BON CADEAU, on enregistre les produits dans Odyssee
  947.         if ($cureProductsOrder && $cureProductsOrder[0]->getTypeOdyssee() != 'bkdo' && $cureProductsOrder[0]->getTypeOdyssee() != 'bkdovalue') {
  948.             // Récupération des informations de la cure associée aux produits
  949.             if (ODYSSEE_TYPE == 'CURE') {
  950.                 try {
  951.                     $cureAssociated $this->apiService->rechercherResaCure(
  952.                         idOdysseeResa$this->session->get(
  953.                             'cureIdForAssociatedProducts'
  954.                         )
  955.                     );
  956.                 } catch (Throwable $apiException) {
  957.                     // Si l'erreur est une erreur de connexion à l'API, on envoie un mail aux admins
  958.                     try {
  959.                         $htmlContent "<br><br><p><strong style='color:red;'>Erreur :</strong> " $apiException->getMessage() . "</p>";
  960.                         $this->mailerService->subject 'Erreur du serveur API - ' $this->site->getSiteName();
  961.                         $this->mailerService->sendMail(
  962.                             $this->recipients,
  963.                             $htmlContent
  964.                         );
  965.                     } catch (Throwable $emailException) {
  966.                         // Si on a une erreur lors de l'envoi du mail, on écrit dans le fichier de log
  967.                         $this->mailerService->writeLog(json_encode([
  968.                             "apiException : " $apiException->getMessage(),
  969.                             "eMailException : " $emailException->getMessage()
  970.                         ]),
  971.                             'FrontBasketController ligne 801 - Try/Catch <creerResaCure\>');
  972.                     }
  973.                     // On retourne une erreur pour afficher un message à l'utilisateur
  974.                     return ['error'];
  975.                 }
  976.             }
  977.             $produits = [];
  978.             $mntRemise 0;
  979.             $mntTotalTtc 0;
  980.             $mntTotalHt 0;
  981.             $mntTotalTva 0;
  982.             // Enregistrement des produits dans Odyssee
  983.             foreach ($cureProductsOrder as $cureProduct) {
  984.                 // Calcul des montants
  985.                 $ttc $cureProduct->getQteProduit() * ($cureProduct->getPrixUnitTtc() - ($cureProduct->getPrcRemise() * $cureProduct->getPrixUnitTtc() / 100));
  986.                 $ht $cureProduct->getQteProduit() * ($cureProduct->getPrixUnitTtc() - ($cureProduct->getPrcRemise() * $cureProduct->getPrixUnitTtc() / 100)) / ($cureProduct->getTvaProduit() / 100);
  987.                 $tva $cureProduct->getQteProduit() * ($cureProduct->getPrixUnitTtc() - ($cureProduct->getPrcRemise() * $cureProduct->getPrixUnitTtc() / 100)) - ($cureProduct->getQteProduit() * ($cureProduct->getPrixUnitTtc() - ($cureProduct->getPrcRemise() * $cureProduct->getPrixUnitTtc() / 100)) / ($cureProduct->getTvaProduit() / 100));
  988.                 $soinsPlanifs = [];
  989.                 foreach ($cureProduct->getCureProductSoinsOrders() as $soin) {
  990.                     $soinsPlanifs[] = [
  991.                         'Code_Soin' => $soin->getCodeSoin(),
  992.                         'Date_Soin' => $soin->getDateSoin()->format('Y-m-d'),
  993.                         'Heure_Soin' => $soin->getHeureSoin()
  994.                     ];
  995.                 }
  996.                 $produits[] = [
  997.                     'Code_Produit' => $cureProduct->getCodeProduit(),
  998.                     'Qte_Produit' => $cureProduct->getQteProduit(),
  999.                     'Prix_Unit_Ttc' => $cureProduct->getPrixUnitTtc(),
  1000.                     'Tva_Produit' => $cureProduct->getTvaProduit(),
  1001.                     'Prc_Remise' => $cureProduct->getPrcRemise(),
  1002.                     'Mnt_Ttc' => $ttc,
  1003.                     'Mnt_Ht' => $ht,
  1004.                     'Mnt_Tva' => $tva,
  1005.                     'Soins_Planifs' => $soinsPlanifs
  1006.                 ];
  1007.                 $mntRemise += $cureProduct->getPrcRemise() * $cureProduct->getQteProduit() * $cureProduct->getPrixUnitTtc() / 100;
  1008.                 $mntTotalTtc += $ttc;
  1009.                 $mntTotalHt += $ht;
  1010.                 $mntTotalTva += $tva;
  1011.             }
  1012.             if ($selectedCarrierAmount 0) {
  1013.                 $produits[] = [
  1014.                     'Code_Produit' => 'FRAIS',
  1015.                     'Qte_Produit' => 1,
  1016.                     'Prix_Unit_Ttc' => $selectedCarrierAmount,
  1017.                     'Tva_Produit' => 20,
  1018.                     'Prc_Remise' => 0,
  1019.                     'Mnt_Ttc' => $selectedCarrierAmount,
  1020.                     'Mnt_Ht' => $selectedCarrierAmount,
  1021.                     'Mnt_Tva' => $selectedCarrierAmount - ($selectedCarrierAmount 1.2),
  1022.                     'Soins_Planifs' => []
  1023.                 ];
  1024.             }
  1025.             $returnAddProd '';
  1026.             try {
  1027.                 if (ODYSSEE_TYPE == 'CURE') { // Si on est sur le site de cure, on ajoute les produits à la cure correspondante
  1028.                     $returnAddProd $this->apiService->ajoutProduitResaCure(
  1029.                         idOdysseeClient$cureAssociated[0]->{'IdOdysseeClient'},
  1030.                         idOdysseeResa$cureProductsOrder[0]->getOdysseeId(),
  1031.                         idExterneResa$cureAssociated[0]->{'IdExterneResa'},
  1032.                         produits$produits,
  1033.                         Mnt_Remise$mntRemise,
  1034.                         Mnt_Regler0,
  1035.                         Mnt_Total_Ttc$mntTotalTtc,
  1036.                         Mnt_Total_Ht$mntTotalHt,
  1037.                         Mnt_Total_Tva$mntTotalTva
  1038.                     );
  1039.                 } elseif (ODYSSEE_TYPE == 'SPA') { // Si on est sur le site de spa, on créer la réservation avec vente de produits
  1040.                     $returnAddProd $this->apiService->creerResaSpa(
  1041.                         idOdysseeClient$cureProductsOrder[0]->getOdysseeClientId(),
  1042.                         idExterneClient"",
  1043.                         idOdysseeSpa0,
  1044.                         idExterneSpa$cureProductsOrder[0]->getId() . '-' $cureProductsOrder[0]->getCodeProduit(),
  1045.                         dateDebut: (new \DateTime(
  1046.                             'now',
  1047.                             new DateTimeZone('Europe/Paris')
  1048.                         ))->format('Y-m-d') . 'T00:00:00',
  1049.                         dateFin: (new \DateTime('now', new DateTimeZone('Europe/Paris')))
  1050.                             ->modify('+1 year')
  1051.                             ->format('Y-m-d') . 'T00:00:00',
  1052.                         produits$produits,
  1053.                         Mnt_Remise$mntRemise,
  1054.                         Mnt_Regler0,
  1055.                         Mnt_Total_Ttc$mntTotalTtc,
  1056.                         Mnt_Total_Ht$mntTotalHt,
  1057.                         Mnt_Total_Tva$mntTotalTva,
  1058.                         pdv$this->site->getOdysseePdvId()
  1059.                     );
  1060.                 }
  1061.                 // Ajout du statut sauvegardé dans Odyssée de la cure dans la BDD
  1062.                 foreach ($cureProductsOrder as $cureProduct) {
  1063.                     // Si le statut du paiement est valide et que le retour de l'API est ok
  1064.                     if (!isset($returnAddProd->status)) {
  1065.                         if (ODYSSEE_TYPE == 'SPA') {
  1066.                             $cureProduct->setOdysseeId($returnAddProd->IdOdysseeSpa);
  1067.                         }
  1068.                         $cureProduct->setSaveInOdyssee(true);
  1069.                         $cureProduct->setSaveInOdysseeDate(
  1070.                             new \DateTime(
  1071.                                 '',
  1072.                                 new DateTimeZone('Europe/Paris')
  1073.                             )
  1074.                         );
  1075.                     } else {
  1076.                         $cureProduct->setSaveInOdysseeError(
  1077.                             is_object($returnAddProd->errors) ? json_encode(
  1078.                                 $returnAddProd->errors
  1079.                             ) : $returnAddProd->errors
  1080.                         );
  1081.                         return ['error'];
  1082.                     }
  1083.                     $this->entityManager->flush($cureProduct);
  1084.                 }
  1085.             } catch (\Throwable $apiException) {
  1086.                 // Si l'erreur est une erreur de connexion à l'API, on envoie un mail aux admins
  1087.                 try {
  1088.                     $htmlContent "<br><br><p><strong style='color:red;'>Erreur :</strong> " $apiException->getMessage() . "</p>";
  1089.                     $this->mailerService->subject 'Erreur du serveur API - ' $this->site->getSiteName();
  1090.                     $this->mailerService->sendMail(
  1091.                         $this->recipients,
  1092.                         $htmlContent
  1093.                     );
  1094.                 } catch (Throwable $emailException) {
  1095.                     // Si on a une erreur lors de l'envoi du mail, on écrit dans le fichier de log
  1096.                     $this->mailerService->writeLog(json_encode([
  1097.                         "apiException : " $apiException->getMessage(),
  1098.                         "eMailException : " $emailException->getMessage()
  1099.                     ]),
  1100.                         'FrontBasketController ligne 801 - Try/Catch <creerResaCure\>');
  1101.                 }
  1102.                 // On retourne une erreur pour afficher un message à l'utilisateur
  1103.                 return ['error'];
  1104.             }
  1105.         }
  1106.         return [$orderRef$totalOrder];
  1107.     }
  1108.     #[Route(path'/paiement-paybox'name'front_basket_payment_paybox')]
  1109.     public function payment_paybox(
  1110.         Request                         $request,
  1111.         PayboxService                   $paybox,
  1112.         EcoOrdersRepository             $repoOrders,
  1113.         EcoCustomersRepository          $repoCustomers,
  1114.         BasketService                   $basketService,
  1115.         EcoCustomersAddressesRepository $repoAddress,
  1116.         EcoOrdersProductsRepository     $repoProductsOrder,
  1117.         EcoDiscountRepository           $repoDiscount
  1118.     )
  1119.     {
  1120.         //Valider les sessions
  1121.         $this->validateSession();
  1122.         $order $repoOrders->find($this->session->get('order_id'));
  1123.         $orderProducts $repoProductsOrder->findBy(["order_id" => $this->session->get('order_id')]);
  1124.         $customer $repoCustomers->find($order->getCustomerId());
  1125.         $deliveryAddress null;
  1126.         if ($this->currentUserConnected->getCustAccountType() == 'company' && $this->currentUserConnected->getAddressesId() !== null && sizeof(
  1127.                 $this->currentUserConnected->getAddressesId()->getValues()
  1128.             ) > 0) {
  1129.             $deliveryAddress $this->currentUserConnected->getAddressesId()->getValues()[0];
  1130.         } else {
  1131.             if ($this->currentUserConnected->getCustAccountType() == 'employee' && $this->currentUserConnected->getCompany()->getAddressesId() !== null && sizeof(
  1132.                     $this->currentUserConnected->getCompany()->getAddressesId()->getValues()
  1133.                 ) > 0) {
  1134.                 $company $this->currentUserConnected->getCompany();
  1135.                 $deliveryAddress $company->getAddressesId()->getValues()[0];
  1136.             }
  1137.         }
  1138.         $fp $basketService->getDefaultShippingFees(
  1139.             $this->session->get('carrier_id'),
  1140.             $deliveryAddress->getCountryId()
  1141.         );
  1142.         $totalTTC sprintf('%.2f'$basketService->getSubtotal() + $fp);
  1143.         if ($this->session->get('valueGlaciere') == 1) {
  1144.             $totalTTC += 6;
  1145.         }
  1146.         // <-- DEBUT --> Récupération remise
  1147.         if ($this->session->has('discount_id') && $this->session->get('discount_id') > 0) {
  1148.             $discount $repoDiscount->find($this->session->get('discount_id'));
  1149.             if ($discount->getDiscountAmount() != null) {
  1150.                 $totalTTC -= $discount->getDiscountAmount();
  1151.             } elseif ($discount->getDiscountPercentage() != null) {
  1152.                 $totalTTC $totalTTC - ($totalTTC * ($discount->getDiscountPercentage() / 100));
  1153.             }
  1154.         }
  1155.         // <-- FIN --> Récupération remise
  1156.         if ($totalTTC 0) {
  1157.             $totalTTC 0;
  1158.         }
  1159.         $paybox->payboxInit([
  1160.             "cmd" => $order->getOrderReference(),
  1161.             "email" => $customer->getAuthUserId()->getEmail(),
  1162.             "total" => $totalTTC 100,
  1163.         ]);
  1164.         $paybox->launch_payment();
  1165.     }
  1166.     #[Route(path'/validate-paybox'name'front_basket_validate_payment_paybox')]
  1167.     public function validate_paybox(Request $requestPayboxService $payboxEcoOrdersRepository $repoOrders)
  1168.     {
  1169.         if ($request->get('ident') && $request->get('ident') != '' && $request->get('auto') && $request->get(
  1170.                 'amount'
  1171.             ) && $request->get('reponse')) {
  1172.             if ($paybox->validationTransaction($request->get('reponse'))) {
  1173.                 $order $repoOrders->findOneBy(['order_reference' => $request->get('ident')]);
  1174.                 $this->validateOrder($order->getId(), $request->get('amount') / 100);
  1175.             }
  1176.         }
  1177.         return new Response(''200);
  1178.     }
  1179.     #[Route(path'/payment_cheque'name'front_basket_payment_cheque')]
  1180.     public function payment_cheque(
  1181.         Request                   $request,
  1182.         SiteCoordonneesRepository $coordonneesRepository,
  1183.         BasketService             $basketService,
  1184.         EcoOrdersRepository       $repoOrder,
  1185.         EcoCustomersRepository    $repoCustomer
  1186.     )
  1187.     {
  1188.         //Valider les sessions
  1189.         $this->validateSession();
  1190.         $addressBank $coordonneesRepository->findOneBy(['siteUid' => CURRENT_SITE_ID'type' => 'bank-check']);
  1191.         if ($addressBank == null) {
  1192.             $addressBank = new SiteCoordonnees();
  1193.         }
  1194.         //Valider la commande
  1195.         if ($request->isMethod('POST')) {
  1196.             $this->validateOrder($this->session->get('order_id'));
  1197.             return $this->redirectToRoute('front_basket_confirmation');
  1198.         }
  1199.         return $this->render('@main-app/front/front_basket/basket_payment_cheque.html.twig', [
  1200.             'subtotal' => $subtotal $basketService->getSubtotal(),
  1201.             'addressBank' => $addressBank,
  1202.             'siteName' => SITE_NAME,
  1203.             'order' => $order $repoOrder->find($this->session->get('order_id')),
  1204.             'defaultShippingFees' => $basketService->getDefaultShippingFees(
  1205.                 $this->session->get('carrier_id'),
  1206.                 $order->getLivrCountryId()
  1207.             ),
  1208.             'customer' => $repoCustomer->find($this->currentUserConnected->getId()),
  1209.             'step' => 'payment',
  1210.         ]);
  1211.     }
  1212.     /**
  1213.      * Défini les procédures à exécuter quand une commande est payée (pour tous les modes de paiement)
  1214.      * @param integer $order_id
  1215.      * @param integer $amount
  1216.      */
  1217.     private function validateOrder($order_id 0$amount 0)
  1218.     {
  1219.         if ($order_id 0) {
  1220.             //Modification du statut de la commande
  1221.             $order $this->entityManager->getRepository(EcoOrders::class)->find($order_id);
  1222.             if ($order != null && $order != false && $order->getId() > && $order->getOrderStatus() != "valid") {
  1223.                 $order->setOrderStatus('valid');
  1224.                 $order->setOrderPaymentDate(new \DateTime());
  1225.                 $order->setOrderTotalPaid($amount);
  1226.                 $this->entityManager->persist($order);
  1227.                 $this->entityManager->flush();
  1228.                 //Notification confirmation de commande
  1229.                 $this->sendNotification($order);
  1230.                 //Mise à jour des stocks
  1231.                 $this->updateStock($order_id);
  1232.             }
  1233.         } else {
  1234.             return false;
  1235.         }
  1236.     }
  1237.     private function updateStock($order_id)
  1238.     {
  1239.         $orderProducts $this->entityManager->getRepository(EcoOrders::class)->findByOrdersProducts($order_id);
  1240.         foreach ($orderProducts as $prod) {
  1241.             $reference $this->entityManager->getRepository(EcoProductsReferences::class)->find($prod['reference_id']);
  1242.             //Cas d'un pack, on déduit le stock des articles qui composent le pack
  1243.             if ($prod['prod_type'] == 'bundle') {
  1244.                 $productsBundle $this->entityManager->getRepository(EcoProductsBundle::class)->findBy(
  1245.                     ['product_id' => $prod['product_id']]
  1246.                 );
  1247.                 foreach ($productsBundle as $prodBundle) {
  1248.                     $refBundle $this->entityManager->getRepository(EcoProductsReferences::class)->find(
  1249.                         $prodBundle->getReferenceId()
  1250.                     );
  1251.                     $newQte $refBundle->getRefQuantity() - ($prodBundle->getBundleQte() * $prod['op_qte']);
  1252.                     $refBundle->setRefQuantity($newQte $newQte 0);
  1253.                     $this->entityManager->persist($refBundle);
  1254.                 }
  1255.                 $this->entityManager->flush();
  1256.             }
  1257.             //On déduit le stock
  1258.             $newQte $reference->getRefQuantity() - $prod['op_qte'];
  1259.             $reference->setRefQuantity($newQte $newQte 0);
  1260.             //Passage du produit en indispo si stock à 0 et option activée dans les settings Ecommerce
  1261.             $ecoSettings $this->entityManager->getRepository(EcoSettings::class)->findOneBy(
  1262.                 ['siteId' => CURRENT_SITE_ID]
  1263.             );
  1264.             if ($ecoSettings->getUnavailableProductNoStock() && $newQte <= 0) {
  1265.                 $reference->setRefOutOfOrder(true);
  1266.             }
  1267.             $this->entityManager->persist($reference);
  1268.         }
  1269.         $this->entityManager->flush();
  1270.         //        $orderProducts = $this->entityManager->getRepository(EcoOrdersProducts::class)->findBy(['order_id' => $order_id]);
  1271.         //
  1272.         //        foreach ($orderProducts as $prod){
  1273.         //
  1274.         //            $reference = $this->entityManager->getRepository(EcoProductsReferences::class)->find($prod->getReferenceId());
  1275.         ////            $product = $this->entityManager->getRepository(EcoProducts::class)->find($reference->getProductId());
  1276.         //
  1277.         //            $newQte = $reference->getRefQuantity() - $prod->getOpQte();
  1278.         //            $reference->setRefQuantity($newQte > 0 ? $newQte : 0);
  1279.         //            $this->entityManager->persist($reference);
  1280.         //        }
  1281.         //
  1282.         //        $this->entityManager->flush();
  1283.     }
  1284.     /**
  1285.      * Envoi un mail de confirmation de commande au client + copie à l'admin
  1286.      * @param object $order
  1287.      */
  1288.     private function sendNotification($order)
  1289.     {
  1290.         $this->mailerService->fromName SITE_NAME;
  1291.         $this->mailerService->subject SITE_NAME " - Confirmation de votre commande " $order->getOrderReference();
  1292.         $customer $this->entityManager->getRepository(EcoCustomers::class)->find($order->getCustomerId());
  1293.         $allRecipients[] = [
  1294.             "nom" => $order->getFactLastname(),
  1295.             "prenom" => $order->getFactFirstname(),
  1296.             "email" => $customer->getAuthUserId()->getEmail(),
  1297.             "type" => 'to'
  1298.         ];
  1299.         //Remise fidélité
  1300.         if ($this->currentUserConnected && $this->currentUserConnected != null) {
  1301.             $this->loyaltySystem->init($this->currentUserConnected->getId());
  1302.         }
  1303.         $htmlContent $this->renderView('layouts/layouts_emails/notification_order_confirmation.html.twig', [
  1304.             'references' => $this->entityManager->getRepository(
  1305.                 EcoProductsReferences::class
  1306.             )->findByProductReferencesOrder(
  1307.                 $order->getId(),
  1308.                 $isCanceled 0
  1309.             ),
  1310.             'carrier' => $this->entityManager->getRepository(EcoShippingCarriers::class)->find($order->getCarrierId()),
  1311.             'order' => $order,
  1312.             'loyaltyDiscount' => $this->loyaltySystem->getTotalDiscount(),
  1313.             'loyaltyPoints' => $this->loyaltySystem->getTotalPoint(),
  1314.             'siteName' => SITE_NAME,
  1315.         ]);
  1316.         $this->mailerService->sendMail($allRecipients$htmlContentnull'admin');
  1317.     }
  1318.     #[Route(path'/confirmation'name'front_basket_confirmation')]
  1319.     public function confirmation(
  1320.         BasketService         $basketService,
  1321.         EcoOrdersRepository   $repoOrder,
  1322.         EcoDiscountRepository $repoDiscount
  1323.     ): Response
  1324.     {
  1325.         if (!$this->session->has('basket') || $this->session->get('basket') == null) {
  1326.             return $this->redirectToRoute('front_home');
  1327.         }
  1328.         //        $order = $repoOrder->find($this->session->get('order_id'));
  1329.         $subtotal $basketService->getSubtotal();
  1330.         $defaultShippingFees $basketService->getDefaultShippingFees(
  1331.             $this->session->get('carrier_id'),
  1332.             1
  1333.         );
  1334.         // <-- DEBUT --> Récupération remise
  1335.         $discount null;
  1336.         if ($this->session->has('discount_id') && $this->session->get('discount_id') > 0) {
  1337.             $discount $repoDiscount->find($this->session->get('discount_id'));
  1338.         }
  1339.         // <-- FIN --> Récupération remise
  1340.         $this->session->set('order_valid''valid');
  1341.         //Valider les sessions/*a commenté pour test*/
  1342.         $this->validateSession();
  1343.         return $this->render('@main-app/front/front_basket/confirmation.html.twig', [
  1344.             'subtotal' => $subtotal,
  1345.             'discount' => $discount,
  1346.             'user' => $this->currentUserConnected,
  1347.             'defaultShippingFees' => $defaultShippingFees,
  1348.             'step' => 'confirmation',
  1349.             'siteName' => SITE_NAME
  1350.         ]);
  1351.     }
  1352.     #[Route(path'/paiement-refuse'name'front_basket_payment_refuse')]
  1353.     public function payment_refuse(): Response
  1354.     {
  1355.         if (!$this->session->has('basket') || $this->session->get('basket') == null) {
  1356.             return $this->redirectToRoute('front_home');
  1357.         }
  1358.         //Valider les sessions /*a commenté pour test*/
  1359.         $this->validateSession();
  1360.         $site $this->entityManager->getRepository(Site::class)->find(CURRENT_SITE_ID);
  1361.         if ($site == null) {
  1362.             $site = new Site();
  1363.         }
  1364.         return $this->render('@main-app/front/front_basket/payment_refuse.html.twig', [
  1365.             'step' => 'confirmationRefused',
  1366.             'site' => $site,
  1367.         ]);
  1368.     }
  1369.     #[Route(path'/paiement-attente'name'front_basket_payment_pending')]
  1370.     public function payment_pending(): Response
  1371.     {
  1372.         if (!$this->session->has('basket') || $this->session->get('basket') == null) {
  1373.             return $this->redirectToRoute('front_home');
  1374.         }
  1375.         $site $this->entityManager->getRepository(Site::class)->find(CURRENT_SITE_ID);
  1376.         if ($site == null) {
  1377.             $site = new Site();
  1378.         }
  1379.         return $this->render('@main-app/front/front_basket/payment_pending.html.twig', [
  1380.             'step' => 'confirmationPending',
  1381.             'site' => $site,
  1382.         ]);
  1383.     }
  1384.     #[Route(path'/paiement-annule'name'front_basket_payment_canceled')]
  1385.     public function payment_canceled(): Response
  1386.     {
  1387.         if (!$this->session->has('basket') || $this->session->get('basket') == null) {
  1388.             return $this->redirectToRoute('front_home');
  1389.         }
  1390.         //Valider les sessions/*a commenté pour test*/
  1391.         $this->validateSession();
  1392.         $site $this->entityManager->getRepository(Site::class)->find(CURRENT_SITE_ID);
  1393.         if ($site == null) {
  1394.             $site = new Site();
  1395.         }
  1396.         return $this->render('@main-app/front/front_basket/payment_canceled.html.twig', [
  1397.             'step' => 'confirmationCacelled',
  1398.             'site' => $site,
  1399.         ]);
  1400.     }
  1401.     /*
  1402.      * Permet d'initialiser le template du panneau latéral du panier
  1403.      * @var string $fromBasket page du panier ou l'internaute se trouve
  1404.      * @return string le template du panier latéral
  1405.      */
  1406.     private function initBasketPanel($fromBasket "")
  1407.     {
  1408.         return $this->renderView('@main-app/layouts/layouts_front/tpl_basket_panel.html.twig', [
  1409.             'basket' => $this->session->get('basket'),
  1410.             'fromBasket' => $fromBasket,
  1411.             'subtotal' => $this->basketService->getSubtotal(),
  1412.             'defaultShippingFees' => $this->basketService->getDefaultShippingFees()
  1413.         ]);
  1414.     }
  1415.     /*
  1416.      * Permet d'initialiser le template de la page récap du panier
  1417.      * @return string le template du contenu du panier
  1418.      */
  1419.     private function initBasketPage()
  1420.     {
  1421.         $discount null;
  1422.         if ($this->session->has('discount_id') && $this->session->get('discount_id') > 0) {
  1423.             $discount $this->repoDiscount->find($this->session->get('discount_id'));
  1424.         }
  1425.         //Remise fidélité
  1426.         if ($this->currentUserConnected) {
  1427.             $this->loyaltySystem->init($this->currentUserConnected->getId());
  1428.         }
  1429.         $now = new \DateTime('', new DateTimeZone('Europe/Paris'));
  1430.         $now->format('Y-m-d H:i:s');
  1431.         $basketHasSoin false;
  1432.         foreach ($this->session->get('basket') as $item) {
  1433.             if ($item['referenceObject']->getTypeOdyssee() == "soin") {
  1434.                 $basketHasSoin true;
  1435.             }
  1436.         }
  1437.         $isCure false;
  1438.         if ($this->session->has('basket')) {
  1439.             foreach ($this->session->get('basket') as $key => $basket) {
  1440.                 if (strpos($key'CURE') === 0) {
  1441.                     $isCure true;
  1442.                 }
  1443.             }
  1444.         }
  1445.         $odysseeCustomers $this->apiService->rechercherClient(
  1446.             adrCourriel$this->currentUserConnected->getAuthUserId()->getEmail()
  1447.         );
  1448.         return $this->renderView('@main-app/front/front_basket/tpl_basket_page.html.twig', [
  1449.             'isCure' => $isCure,
  1450.             'basket' => $this->session->get('basket'),
  1451.             'subtotal' => $this->basketService->getSubtotal(),
  1452.             'defaultShippingFees' => $this->basketService->getDefaultShippingFees(),
  1453.             'discount' => $discount,
  1454.             'loyaltyDiscount' => $this->loyaltySystem->getTotalDiscount(),
  1455.             'loyaltyPoints' => $this->loyaltySystem->getTotalPoint(),
  1456.             'step' => 'basket',
  1457.             'basketHasSoin' => $basketHasSoin,
  1458.             'odysseeCustomers' => $odysseeCustomers,
  1459.         ]);
  1460.     }
  1461.     /**
  1462.      * Permet l'ajout d'un produit au panier
  1463.      */
  1464.     #[Route(path'/axAddToBasket'name'front_axAddToBasket')]
  1465.     public function axAddToBasket(Request $request): JsonResponse
  1466.     {
  1467.         if (!$this->currentUserConnected) {
  1468.             $url $this->generateUrl('front_app_login');
  1469.             return new JsonResponse(
  1470.                 [
  1471.                     'status' => false,
  1472.                     'route' => $url
  1473.                 ]
  1474.             );
  1475.         }
  1476.         if ($request->isXmlHttpRequest() && $request->get('reference_id') > && $request->get('qte') > 0) {
  1477.             $refForAdd $this->entityManager->getRepository(EcoProductsReferences::class)->find(
  1478.                 $request->get('reference_id')
  1479.             );
  1480.             foreach ($this->session->get('basket') as $items) {
  1481.                 // Vérifie si il y a une cure dans le panier, on ne peut pas ajouter de produits
  1482.                 if (is_string($items['referenceObject'])) {
  1483.                     $url $this->generateUrl('front_shopping_categorie');
  1484.                     $this->addFlash(
  1485.                         'danger',
  1486.                         'Vous ne pouvez pas ajouter de produits lors de la réservation d\'une Cure'
  1487.                     );
  1488.                     return new JsonResponse(
  1489.                         [
  1490.                             'status' => false,
  1491.                             'route' => $url
  1492.                         ]
  1493.                     );
  1494.                 }
  1495.                 // Vérifie si il y a un Bon Cadeau dans le panier, on ne peut pas ajouter de produits
  1496.                 if (($items['referenceObject']->getTypeOdyssee() == "bkdo" && $refForAdd->getTypeOdyssee() != 'bkdo') || ($items['referenceObject']->getTypeOdyssee() == "bkdovalue" && $refForAdd->getTypeOdyssee() != 'bkdovalue')) {
  1497.                     $url $this->generateUrl('front_shopping_categorie');
  1498.                     $this->addFlash(
  1499.                         'danger',
  1500.                         'Vous ne pouvez pas ajouter de produits lors de l\'achat d\'un Bon Cadeau'
  1501.                     );
  1502.                     return new JsonResponse(
  1503.                         [
  1504.                             'status' => false,
  1505.                             'route' => $url
  1506.                         ]
  1507.                     );
  1508.                 }
  1509.                 // Vérifie si il y a un produit dans le panier, on ne peut pas ajouter de Bon Cadeau
  1510.                 if ($items['referenceObject']->getTypeOdyssee() != "bkdo" && $items['referenceObject']->getTypeOdyssee() != "bkdovalue" && ($refForAdd->getTypeOdyssee() == 'bkdo' || $refForAdd->getTypeOdyssee() == 'bkdovalue')) {
  1511.                     $url $this->generateUrl('front_shopping_categorie');
  1512.                     $this->addFlash(
  1513.                         'danger',
  1514.                         'Vous ne pouvez pas ajouter de Bon Cadeau lors de l\'achat de produits'
  1515.                     );
  1516.                     return new JsonResponse(
  1517.                         [
  1518.                             'status' => false,
  1519.                             'route' => $url
  1520.                         ]
  1521.                     );
  1522.                 }
  1523.             }
  1524.             // ajout du produit au panier
  1525.             $this->basketService->addProduct(
  1526.                 $request->get('reference_id'),
  1527.                 $request->get('qte'),
  1528.                 $request->get('bkdoValueAmount')
  1529.             );
  1530.             return new JsonResponse(
  1531.                 [
  1532.                     'status' => true,
  1533.                     'basketPanel' => html_entity_decode($this->initBasketPanel($request->get('fromBasket'))),
  1534.                     // refresh du panneau panier
  1535.                     'totalCountBasket' => $this->baseListener->getProductSumOnBasket()
  1536.                 ]
  1537.             );
  1538.         }
  1539.         return new JsonResponse(
  1540.             [
  1541.                 'status' => false,
  1542.                 'basketPanel' => html_entity_decode($this->initBasketPanel($request->get('fromBasket'))),
  1543.             ]
  1544.         );
  1545.     }
  1546.     /**
  1547.      * Permet de mettre à jour une quantité pour un produit dans le panier
  1548.      * en + ou en -
  1549.      * @param Request $request
  1550.      */
  1551.     #[Route(path'/axUpdateQteBasket'name'front_axUpdateQteBasket')]
  1552.     public function axUpdateQteBasket(Request $request)
  1553.     {
  1554.         if ($request->isXmlHttpRequest() && $request->get('reference_id') > 0) {
  1555.             $qte 0;
  1556.             if ($request->get('qte')) {
  1557.                 $qte $request->get('qte');
  1558.             }
  1559.             $ref_id $request->get('reference_id');
  1560.             $direction $request->get('direction');
  1561.             $this->basketService->updateProductQte($ref_id$direction$qte);
  1562.             //Mise à jour des remises dans le cas d'une remise fidélité
  1563.             if ($this->currentUserConnected && $this->session->has('loyalty_point_used') && $this->session->get(
  1564.                     'loyalty_point_used'
  1565.                 ) > 0) {
  1566.                 $this->loyaltySystem->init($this->currentUserConnected->getId());
  1567.                 $this->basketService->applyDiscountLoyaltyBasket($this->loyaltySystem->getTotalDiscount());
  1568.             }
  1569.             // refresh du panier dans la page si besoin
  1570.             $basketPage "";
  1571.             if ($request->get('fromBasket') == "panier") {
  1572.                 $basketPage html_entity_decode($this->initBasketPage());
  1573.             }
  1574.             return new JsonResponse([
  1575.                 'status' => true,
  1576.                 'basketPanel' => html_entity_decode($this->initBasketPanel($request->get('fromBasket'))),
  1577.                 // refresh du panneau panier
  1578.                 'basketPage' => $basketPage,
  1579.                 'totalCountBasket' => $this->baseListener->getProductSumOnBasket()
  1580.             ]);
  1581.         }
  1582.         return new JsonResponse([
  1583.             'status' => false,
  1584.         ]);
  1585.     }
  1586.     /**
  1587.      * Permet la suppression d'un produit qui est au panier
  1588.      * @param Request $request
  1589.      */
  1590.     #[Route(path'/axRemoveProductBasket'name'front_axRemoveProductBasket')]
  1591.     public function axRemoveProductBasket(Request $request)
  1592.     {
  1593.         if ($request->isXmlHttpRequest() && $request->get('reference_id') > 0) {
  1594.             $ref_id $request->get('reference_id');
  1595.             $this->basketService->removeProduct($ref_id);
  1596.             // refresh du panier dans la page si besoin
  1597.             $basketPage "";
  1598.             if ($request->get('fromBasket') == "panier") {
  1599.                 $basketPage html_entity_decode($this->initBasketPage());
  1600.             }
  1601.             return new JsonResponse([
  1602.                 'status' => true,
  1603.                 'script' => '$("#articlePanier-' $ref_id '").remove();',
  1604.                 'basketPanel' => html_entity_decode($this->initBasketPanel()),
  1605.                 // refresh du panneau panier
  1606.                 'basketPage' => $basketPage,
  1607.                 'totalCountBasket' => $this->baseListener->getProductSumOnBasket()
  1608.             ]);
  1609.         }
  1610.         return new JsonResponse([
  1611.             'status' => false,
  1612.         ]);
  1613.     }
  1614.     #[Route(path'/deleteProductBasket/{productId}'name'front_deleteProductBasket')]
  1615.     public function deleteProductBasket($productId): RedirectResponse
  1616.     {
  1617.         if ($productId 0) {
  1618.             $this->basketService->removeProduct($productId);
  1619.         }
  1620.         return $this->redirectToRoute('front_basket_delivery');
  1621.     }
  1622.     /**
  1623.      * Permet de supprimer l'utilisation des points de fidélité sur un panier
  1624.      * @param Request $request
  1625.      */
  1626.     #[Route(path'/axRemoveLoyaltyDiscount'name'front_axRemoveLoyaltyDiscount')]
  1627.     public function axRemoveLoyaltyDiscount(Request $request)
  1628.     {
  1629.         if ($request->isXmlHttpRequest() && $this->session->has('loyalty_point_used')) {
  1630.             //            $this->session->set('loyalty_point_used', null);
  1631.             //            $this->session->remove('loyalty_point_used');
  1632.             $this->basketService->removeLoyaltyDiscountBasket();
  1633.             return new JsonResponse([
  1634.                 'status' => true,
  1635.                 'basketPanel' => html_entity_decode($this->initBasketPanel('panier')),
  1636.                 // refresh du panneau panier
  1637.                 'basketPage' => html_entity_decode($this->initBasketPage()),
  1638.                 'totalCountBasket' => $this->baseListener->getProductSumOnBasket()
  1639.             ]);
  1640.         }
  1641.         return new JsonResponse([
  1642.             'status' => false,
  1643.         ]);
  1644.     }
  1645.     /**
  1646.      * Permet d'ajouter des points de fidélité sur un panier
  1647.      * @param Request $request
  1648.      */
  1649.     #[Route(path'/axAddLoyaltyDiscount'name'front_axAddLoyaltyDiscount')]
  1650.     public function axAddLoyaltyDiscount(Request $request)
  1651.     {
  1652.         if ($request->isXmlHttpRequest() && $this->currentUserConnected) {
  1653.             $this->loyaltySystem->init($this->currentUserConnected->getId());
  1654.             $this->session->set('loyalty_point_used'true);
  1655.             $this->basketService->applyDiscountLoyaltyBasket($this->loyaltySystem->getTotalDiscount());
  1656.             return new JsonResponse([
  1657.                 'status' => true,
  1658.                 'basketPanel' => html_entity_decode($this->initBasketPanel('panier')),
  1659.                 // refresh du panneau panier
  1660.                 'basketPage' => html_entity_decode($this->initBasketPage()),
  1661.                 'totalCountBasket' => $this->baseListener->getProductSumOnBasket()
  1662.             ]);
  1663.         }
  1664.         return new JsonResponse([
  1665.             'status' => false,
  1666.         ]);
  1667.     }
  1668.     /**
  1669.      * Permet de supprimer une remise sur un panier
  1670.      * @param Request $request
  1671.      */
  1672.     #[Route(path'/axRemoveDiscount'name'front_axRemoveDiscount')]
  1673.     public function axRemoveDiscount(Request $request)
  1674.     {
  1675.         if ($request->isXmlHttpRequest()) {
  1676.             $this->basketService->removeDiscountBasket();
  1677.             return new JsonResponse([
  1678.                 'status' => true,
  1679.                 'basketPanel' => html_entity_decode($this->initBasketPanel('panier')),
  1680.                 // refresh du panneau panier
  1681.                 'basketPage' => html_entity_decode($this->initBasketPage()),
  1682.                 'totalCountBasket' => $this->baseListener->getProductSumOnBasket()
  1683.             ]);
  1684.         }
  1685.         return new JsonResponse([
  1686.             'status' => false,
  1687.         ]);
  1688.     }
  1689.     /**
  1690.      * Permet d'ajouter une remise sur un panier
  1691.      * @param Request $request
  1692.      */
  1693.     #[Route(path'/axAddDiscount'name'front_axAddDiscount')]
  1694.     public function axAddDiscount(Request $request)
  1695.     {
  1696.         if ($request->isXmlHttpRequest() && $request->get('discount_code')) {
  1697.             $popup "";
  1698.             $articles $this->basketService->getFormatedBasketProducts();
  1699.             $this->discountService->initService(
  1700.                 $articles,
  1701.                 $this->currentUserConnected $this->currentUserConnected null
  1702.             );
  1703.             $discount $this->discountService->discountValidation($request->get('discount_code'));
  1704.             if ($discount['status']) {
  1705.                 $this->session->set('discount_id'$this->discountService->discount_id);
  1706.                 //Mise en commentaire du DiscountService actuel => non fonctionnel
  1707.                 //$this->basketService->applyDiscountBasket($request->get('discount_code'));
  1708.             } else {
  1709.                 $popup $this->renderView('layouts/layouts_front/tpl_popup.html.twig', [
  1710.                     'popupTitle' => "Problème avec votre remise",
  1711.                     'popupMessage' => isset($discount['message']) && trim(
  1712.                         $discount['message']
  1713.                     ) != "" $discount['message'] : "Code promo invalide",
  1714.                     'popupBtn2' => null,
  1715.                 ]);
  1716.             }
  1717.             return new JsonResponse([
  1718.                 'popup' => $popup,
  1719.                 'status' => true,
  1720.                 'basketPanel' => html_entity_decode($this->initBasketPanel('panier')),
  1721.                 // refresh du panneau panier
  1722.                 'basketPage' => html_entity_decode($this->initBasketPage()),
  1723.                 'totalCountBasket' => $this->baseListener->getProductSumOnBasket()
  1724.             ]);
  1725.         }
  1726.         return new JsonResponse([
  1727.             'status' => false,
  1728.         ]);
  1729.     }
  1730.     private function displayPopup()
  1731.     {
  1732.         if ($this->session->has('displayPopup')) {
  1733.             //Erreur de connexion
  1734.             if ($this->session->get('displayPopup') == 'delivery-account-error') {
  1735.                 $this->otideaUtils->createPopup([
  1736.                         "title" => 'Adresse de livraison indisponible',
  1737.                         "message" => "Aucune adresse de livraison n'est défini dans votre espace client.",
  1738.                         "btn2" => null
  1739.                     ]
  1740.                 );
  1741.             }
  1742.             //Acceptation des CGV
  1743.             if ($this->session->get('displayPopup') == 'cgv-error') {
  1744.                 $this->otideaUtils->createPopup([
  1745.                         "title" => 'CGV',
  1746.                         "message" => "Vous devez accepter les conditions générales de vente pour valider votre commande.",
  1747.                         "btn2" => null
  1748.                     ]
  1749.                 );
  1750.             }
  1751.             $this->session->set('displayPopup'null);
  1752.         }
  1753.     }
  1754. }