src/Controller/FrontController/ProductController.php line 732

Open in your IDE?
  1. <?php
  2. namespace App\Controller\FrontController;
  3. use App\Acme\Bundle\FrontUtility\ProductUtility;
  4. use App\Entity\Product;
  5. use App\Entity\ProductSubscriptionPrice;
  6. use App\Entity\CustomerSubscription;
  7. use App\Entity\UserPlatform;
  8. use App\Entity\Location;
  9. use App\Entity\Order;
  10. use App\Entity\DetailsOrders;
  11. use App\Form\SubscriptionForm\UserMultilType;
  12. use App\Form\ProductType;
  13. use App\Form\CommandeValideType;
  14. use App\Form\RentProductType;
  15. use App\Repository\ProductRepository;
  16. use App\Repository\LocationRepository;
  17. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  18. use Symfony\Component\HttpFoundation\Request;
  19. use Symfony\Component\HttpFoundation\Response;
  20. use Symfony\Component\HttpFoundation\JsonResponse;
  21. use Symfony\Component\Routing\Annotation\Route;
  22. use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
  23. use App\Repository\UserPlatformRepository;
  24. use Symfony\Component\EventDispatcher\EventDispatcher;
  25. use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
  26. use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
  27. use Doctrine\ORM\EntityManagerInterface;
  28. use App\Acme\Bundle\Utility\UtilitySearchSystem;
  29. use App\Repository\StockRepository;
  30. use App\Entity\MotRechercher;
  31. use App\Entity\PriceProduct;
  32. use App\Repository\MotRechercherRepository;
  33. use Exception;
  34. use Symfony\Component\Security\Core\Authorization\AuthorizationChecker;
  35. use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
  36. /**
  37.  * @Route("/produit")
  38.  */
  39. class ProductController extends AbstractController
  40. {
  41.     /**
  42.      * @Route("/", name="app_product_index", methods={"GET"})
  43.      */
  44.     public function index(ProductRepository $productRepository): Response
  45.     {
  46.         return $this->render('/frontView/product/index.html.twig', [
  47.             'topOrderedProducts' => $productRepository->findTopOrderedProductsRandom(4),
  48.             'recentProducts' => $productRepository->findRecentProducts(4),
  49.             'temoin' => 0,
  50.             'message' => ''
  51.         ]);
  52.     }
  53.     /**
  54.      * @Route("/search-product", name="app_product_search", methods={"GET"})
  55.      */
  56.     public function searchProduct(
  57.         Request $request,
  58.         ProductRepository $productRepository,
  59.         MotRechercherRepository $motRechercherRepository
  60.     ): Response {
  61.         $resultat = array();
  62.         if ("GET" == $request->getMethod()) {
  63.             $motrechercher = $request->query->get('searchname');
  64.             if (empty($motrechercher)) {
  65.                 $resultat = array();
  66.             } else {
  67.                 $mot = $motrechercher;
  68.                 $res_objet = UtilitySearchSystem::initStepSearch($motrechercher);
  69.                 //si parmit les recherche du client se trouve dans la liste de mots cles de base
  70.                 if (count($res_objet) > 0) {
  71.                     $resultat = $productRepository->searchProduct($res_objet);
  72.                     if (0 === count($resultat)) {
  73.                         $motRechercherRepository->createOrUpdateMotRecherche($mot,\DateTime::createFromFormat('Y-m-d H:i:s',Date('Y-m-d H:i:s')));
  74.                     }
  75.                 } else {
  76.                     $resultat = array();
  77.                 }
  78.             }
  79.         }
  80.         return $this->render('/frontView/product/index.html.twig', [
  81.             'products' => $resultat,
  82.             'temoin' => 0,
  83.             'message' => ''
  84.         ]);
  85.     }
  86.     
  87.     /**
  88.      * @Route("/ajax-search", name="ajax_search", methods={"GET"})
  89.      */
  90.     public function ajaxSearch(
  91.         Request $request,
  92.         ProductRepository $productRepository
  93.     ): JsonResponse {
  94.         $keyword = $request->query->get('q');
  95.         // $keyword = 'protec';
  96.         if (!$keyword || strlen($keyword) < 2) {
  97.             return $this->json([]);
  98.         }
  99.         $products = $productRepository->findSuggestions($keyword);
  100.         $data = [];
  101.         foreach ($products as $product) {
  102.             $data[] = [
  103.                 'id' => $product->getId(),
  104.                 'title' => $product->getTitle(),
  105.                 'image' => $product->getPicture()/*,
  106.                 'price' => $product->getPrice(),*/
  107.             ];
  108.         }
  109.         // dd($data);
  110.         return $this->json($data);
  111.     }
  112.     /**
  113.      * @Route("/list-categorie/{idcategorie}/{type}", name="app_product_category", methods={"GET"})
  114.      */
  115.     public function lisCategorie(ProductRepository $productRepository, int $idcategorie, string $type): Response
  116.     {
  117.         $criteria = array();
  118.         if ("categorie" == $type) {
  119.             $criteria = array('fkcategorie'=>$idcategorie, 'enabled'=>true);
  120.         } else {
  121.             $criteria = array('fksousCategorie'=>$idcategorie, 'enabled'=>true);
  122.         }
  123.         $listProducts = $productRepository->findBy($criteria);
  124.         return $this->render('/frontView/product/index.html.twig', [
  125.             'products' => $listProducts,
  126.         ]);
  127.     }
  128.     public function createUser(
  129.         $form,
  130.         $user,
  131.         $arrayresult,
  132.         Request $request,
  133.         UserPasswordEncoderInterface $passwordEncoder,
  134.         UserPlatformRepository $userPlatformRepository
  135.     ) {
  136.         $error = 1;
  137.         if ($user->getPassword() != $form->get('confirmpass')->getData()) {
  138.             $arrayresult['error'] = true;
  139.             $arrayresult['msg'] = "Mot de passe non confirmé.";
  140.         } elseif (strpos($user->getEmail(), " ")) {
  141.             $arrayresult['error'] = true;
  142.             $arrayresult['msg'] = "l'identifiant \"".$user->getEmail()."\" ne doit pas contenir un espace.";
  143.         } elseif (strlen($user->getEmail()) < 5) {
  144.             $arrayresult['error'] = true;
  145.             $arrayresult['msg'] = "l'identifiant \"".$user->getEmail()."\" doit contenir plus de 5 caracteres.";
  146.         } else {
  147.             $user->setRoles(["ROLE_CUSTOMER"]);
  148.             $user->setPassword(
  149.                 $passwordEncoder->encodePassword($user, $user->getPassword())
  150.             );
  151.             $userPlatformRepository->add($user, true);
  152.             //Authentification
  153.             $token = new UsernamePasswordToken($user, $user->getPassword(), "public", $user->getRoles());
  154.             $this->get("security.token_storage")->setToken($token);
  155.             $event = new InteractiveLoginEvent($request, $token);
  156.             //$this->get("event_dispatcher")->dispatch("security.interactive_login", $event);
  157.             $error = 0;
  158.         }
  159.         return $error;
  160.     }
  161.     public function createCommande(
  162.     Request $request,
  163.     Order $commande,
  164.     $listPanierSession,
  165.     StockRepository $stockRepository,
  166.     EntityManagerInterface $entityManager,
  167.     AuthorizationCheckerInterface $authorizationChecker
  168. ) {
  169.     $commande->setDateOrder(\DateTime::createFromFormat('Y-m-d H:i:s', Date('Y-m-d H:i:s')));
  170.     $commande->setCustomer($this->getUser());
  171.     $entityManager->getRepository(Order::class)->add($commande, true);
  172.     $commande->setReforder("RP-CMD-" . $commande->getId());
  173.     $entityManager->getRepository(Order::class)->add($commande, true);
  174.     // ── COUPON ───────────────────────────────────────────────────────────
  175.     $couponData = $request->getSession()->get('coupon');
  176.     // ── Calculer le prix unitaire correct selon rôle + quantité ──────────
  177.     $getPrixUnitaire = function (
  178.         $priceProduct,
  179.         int $quantity,
  180.         AuthorizationCheckerInterface $authorizationChecker
  181.     ): float {
  182.         if ($authorizationChecker->isGranted('ROLE_COM')) {
  183.             return $priceProduct->getEffectivePriceCustomer();
  184.         }
  185.         if ($authorizationChecker->isGranted('ROLE_CUSTOMER')) {
  186.             return $priceProduct->getEffectivePriceCustomer();
  187.         }
  188.         return $priceProduct->getEffectivePriceCustomer();
  189.     };
  190.     // ── Total brut (nécessaire pour répartir la remise coupon) ────────────
  191.     $totalBrut = 0.0;
  192.     if ($couponData) {
  193.         foreach ($listPanierSession as $item) {
  194.             $pp  = $entityManager->getRepository(PriceProduct::class)->getPriceProduct(
  195.                 $entityManager->getRepository(Product::class)->find($item['produit']->getId())
  196.             );
  197.             $qty = 1;
  198.             // Priorité : override_price (quantité modifiée côté JS/AJAX)
  199.             $pu = isset($item['override_price'])
  200.                 ? (float) $item['override_price']
  201.                 : $getPrixUnitaire($pp, $qty, $authorizationChecker);
  202.             $totalBrut += $pu * $qty;
  203.         }
  204.     }
  205.     // ── Traitement des lignes de commande ─────────────────────────────────
  206.     $listPanierValider    = [];
  207.     $listPanierNonValider = [];
  208.     for ($incr = 0; $incr < count($listPanierSession); $incr++) {
  209.         $item    = $listPanierSession[$incr];
  210.         $product = $entityManager->getRepository(Product::class)->find($item['produit']->getId());
  211.         $pp      = $entityManager->getRepository(PriceProduct::class)->getPriceProduct($product);
  212.         $qty     = 1;
  213.         $item['number'] = 1;
  214.         // ── Prix unitaire : override JS/AJAX en priorité, sinon calcul rôle ──
  215.         $prixUnitaire = isset($item['override_price'])
  216.             ? (float) $item['override_price']
  217.             : $getPrixUnitaire($pp, $qty, $authorizationChecker);
  218.         // ── Remise coupon répartie proportionnellement ────────────────────
  219.         if ($couponData && $totalBrut > 0) {
  220.             $ligneBrut      = $prixUnitaire * $qty;
  221.             $ratio          = $ligneBrut / $totalBrut;
  222.             $remiseUnitaire = round(($couponData['discount'] * $ratio) / $qty, 4);
  223.             $prixUnitaire   = round($prixUnitaire - $remiseUnitaire, 4);
  224.         }
  225.         // ── Création de la ligne DetailsOrders ───────────────────────────
  226.         $newDetailsOrders = new DetailsOrders();
  227.         $newDetailsOrders->setIdorder($commande);
  228.         $newDetailsOrders->setIdproduct($product);
  229.         $newDetailsOrders->setQuantity($qty);
  230.         $newDetailsOrders->setPrixUnitaire($prixUnitaire);
  231.         $newDetailsOrders->setState(0);
  232.         $newDetailsOrders->setMotif("");
  233.         $entityManager->getRepository(DetailsOrders::class)->add($newDetailsOrders, true);
  234.         // ── Mise à jour du stock ──────────────────────────────────────────
  235.         $listPanierValider[] = $item;
  236.     }
  237.     // ── COUPON : persister sur la commande + incrémenter usage ───────────
  238.     if ($couponData && !empty($listPanierValider)) {
  239.         $commande->setCouponRef($couponData['ref']);
  240.         $commande->setDiscountAmount((float) $couponData['discount']);
  241.         $commande->setTotalAfterDiscount(round($totalBrut - $couponData['discount'], 2));
  242.         $entityManager->getRepository(Order::class)->add($commande, true);
  243.         $coupon = $entityManager->getRepository(\App\Entity\Coupon::class)->find($couponData['id']);
  244.         if ($coupon) {
  245.             $coupon->incrementUsageCount();
  246.             $entityManager->flush();
  247.         }
  248.         $request->getSession()->remove('coupon');
  249.     }
  250.     // ── Résultats en session pour affichage ──────────────────────────────
  251.     $request->getSession()->set("panier_valider", $listPanierValider);
  252.     $request->getSession()->set("panier_non_valider", $listPanierNonValider);
  253. }
  254.     public function validerCommande(
  255.         $arrayresult,
  256.         $form,
  257.         $user,
  258.         $session,
  259.         &$listPanierSession,
  260.         Request $request,
  261.         StockRepository $stockRepository,
  262.         UserPasswordEncoderInterface $passwordEncoder,
  263.         EntityManagerInterface $entityManager,
  264.         UserPlatformRepository $userPlatformRepository,
  265.         AuthorizationCheckerInterface $authorizationChecker
  266.     ) {
  267.         $form->handleRequest($request);
  268.         if ($form->isSubmitted() && $form->isValid()) {
  269.             try {
  270.                 $commande = new Order();
  271.                 $commande->setState(0);
  272.                 if (null == $this->getUser()) {
  273.                     $createUser = $this->createUser($form, $user, $arrayresult, $request, $passwordEncoder, $userPlatformRepository);
  274.                     if (0 === $createUser) {
  275.                         $this->createCommande($request, $commande, $listPanierSession, $stockRepository, $entityManager, $authorizationChecker);
  276.                     }
  277.                 } else {
  278.                     $this->createCommande($request, $commande, $listPanierSession, $stockRepository, $entityManager, $authorizationChecker);
  279.                 }
  280.                 $session->set('listPanier', []);
  281.                 $listPanierSession = [];
  282.             } catch (Exception $exc) {
  283.                 return $this->render('frontView/error.html.twig', [
  284.                     'msg' => $exc->getMessage(),
  285.                 ]);
  286.             }
  287.         }
  288.     }
  289.     /**
  290.      * @Route("/panier/{product}", name="app_product_panier", methods={"GET", "POST"})
  291.      */
  292.     public function addPanier(
  293.         Request $request,
  294.         ProductRepository $productRepository,
  295.         StockRepository $stockRepository,
  296.         Product $product,
  297.         EntityManagerInterface $entityManager
  298.     ): Response {
  299.         //controle si l'utilisateur est membre
  300.         $isMember = false;
  301.         $listPanier = [];
  302.         $arrayresult = array("error"=>false,"msg"=>"");
  303.         $user = new UserPlatform();
  304.         $availableStock = $stockRepository->getAvailableStock($product);
  305.         $subscriptionPrice = null;
  306.         $subscriptionUserCount = null;
  307.         if ($product->getStatetype() === 0) {
  308.             if (!$request->isMethod('POST')) {
  309.                 return $this->redirectToRoute('app_product_show', ['id' => $product->getId()]);
  310.             }
  311.             if (!$this->isCsrfTokenValid('subscription_purchase_' . $product->getId(), (string) $request->request->get('_token'))) {
  312.                 throw $this->createAccessDeniedException('Formule d’abonnement invalide.');
  313.             }
  314.             $subscriptionPrice = $entityManager->getRepository(ProductSubscriptionPrice::class)->find((int) $request->request->get('subscription_price_id'));
  315.             if (!$subscriptionPrice || !$subscriptionPrice->getProduct() || $subscriptionPrice->getProduct()->getId() !== $product->getId() || !$subscriptionPrice->getSubscriptionType()->isEnabled() || (float) $subscriptionPrice->getPrice() <= 0) {
  316.                 $this->addFlash('error', 'La formule choisie n’est plus disponible.');
  317.                 return $this->redirectToRoute('app_product_show', ['id' => $product->getId()]);
  318.             }
  319.             $subscriptionUserCount = filter_var($request->request->get('subscription_user_count', $subscriptionPrice->getIncludedUsers()), FILTER_VALIDATE_INT);
  320.             if ($subscriptionUserCount === false || $subscriptionUserCount < $subscriptionPrice->getIncludedUsers() || $subscriptionUserCount > 1000) {
  321.                 $this->addFlash('error', sprintf('Choisissez entre %d et 1 000 utilisateurs pour cette formule.', $subscriptionPrice->getIncludedUsers()));
  322.                 return $this->redirectToRoute('app_product_show', ['id' => $product->getId(), '_fragment' => 'subscriptionOptionsModal']);
  323.             }
  324.         }
  325.         if ($product->getStatetype() === 2 && ($product->getStatdispo() === 3 || $availableStock <= 0)) {
  326.             return $this->render('/frontView/product/index.html.twig', [
  327.                 'products' => $productRepository->findAll(),
  328.                 'temoin' => $product->getId(),
  329.                 'message' => 'Ce produit est en rupture de stock.',
  330.             ]);
  331.         }
  332.         // Les locations utilisent le type historique 99. Le type 2 correspond aux produits physiques.
  333.         if ($product->getStatetype() === 99) {
  334.             if ($availableStock <= 0) {
  335.                 // $reponse = $stockRepository->addProductIntoOrder($product, 1);
  336.                 $reponse = "Stock disponible 0";
  337.                 return $this->render('/frontView/product/index.html.twig', [
  338.                     'products' => $productRepository->findAll(),
  339.                     'temoin' => $product->getId(),
  340.                     'message' => $reponse
  341.                 ]);
  342.             }
  343.             return $this->redirectToRoute('app_product_rent', [
  344.                 'product' => $product->getId()
  345.             ]);
  346.         }
  347.         
  348.         if (null == $this->getUser()) {
  349.             //recupérer le session list panier si existe
  350.             $price_product = $entityManager->getRepository(PriceProduct::class)->getPriceProduct($product);
  351.             $formatPanier = array('produit'=>$product,'number'=>1, 'price_product'=>$price_product, 'subscription_price'=>$subscriptionPrice, 'subscription_user_count'=>$subscriptionUserCount);
  352.             $session = $request->getSession();
  353.             $listPanierSession = $session->get('listPanier');
  354.             if (null == $listPanierSession) {
  355.                 $isMember = "la session panier n'est pas creer";
  356.                 $listPanier = array();
  357.                 $reponse = $stockRepository->addProductIntoOrder($product, 1);
  358.                 if ('' === $reponse) {
  359.                     array_push($listPanier, $formatPanier);
  360.                 } else {
  361.                     return $this->render('/frontView/product/index.html.twig', [
  362.                         'products' => $productRepository->findAll(),
  363.                         'temoin' => $product->getId(),
  364.                         'message' => $reponse
  365.                     ]);
  366.                 }
  367.                 $session->set('listPanier', $listPanier);
  368.                 $listPanierSession = $listPanier;
  369.             } else {
  370.                 $verificationBasket = new ProductUtility();
  371.                 $controlProd = $verificationBasket->isProductInBasket($listPanierSession, $product);
  372.                 if ($controlProd['inBasket']) {
  373.                     $c = 1;
  374.                     $reponse = $stockRepository->addProductIntoOrder($product, $c);
  375.                     if ('' === $reponse) {
  376.                         $listPanierSession[$controlProd['indice']]['number'] = 1;
  377.                         $listPanierSession[$controlProd['indice']]['subscription_price'] = $subscriptionPrice;
  378.                         $listPanierSession[$controlProd['indice']]['subscription_user_count'] = $subscriptionUserCount;
  379.                     } else {
  380.                         return $this->render('/frontView/product/index.html.twig', [
  381.                             'products' => $productRepository->findAll(),
  382.                             'temoin' => $product->getId(),
  383.                             'message' => $reponse.". Vous avez déjà ".$listPanierSession[$controlProd['indice']]['number']." dans votre panier"
  384.                         ]);
  385.                     }
  386.                 } else {
  387.                     $reponse = $stockRepository->addProductIntoOrder($product, 1);
  388.                     if ('' === $reponse) {
  389.                         array_push($listPanierSession, $formatPanier);
  390.                     } else {
  391.                         return $this->render('/frontView/product/index.html.twig', [
  392.                             'products' => $productRepository->findAll(),
  393.                             'temoin' => $product->getId(),
  394.                             'message' => $reponse
  395.                         ]);
  396.                     }
  397.                 }
  398.                 $session->set('listPanier', $listPanierSession);
  399.             }
  400.             $form = $this->createForm(UserMultilType::class, $user);
  401.         } else {
  402.             //traitement pour voir les commandes du client
  403.             $price_product = $entityManager->getRepository(PriceProduct::class)->getPriceProduct($product);
  404.             $formatPanier = array('produit'=>$product,'number'=>1, 'price_product'=>$price_product, 'subscription_price'=>$subscriptionPrice, 'subscription_user_count'=>$subscriptionUserCount);
  405.             $session = $request->getSession();
  406.             $listPanierSession = $session->get('listPanier');
  407.             if (null == $listPanierSession) {
  408.                 $isMember = "la session panier n'est pas creer";
  409.                 $listPanier = array();
  410.                 $reponse = $stockRepository->addProductIntoOrder($product, 1);
  411.                 if ('' === $reponse) {
  412.                     array_push($listPanier, $formatPanier);
  413.                 } else {
  414.                     return $this->render('/frontView/product/index.html.twig', [
  415.                         'products' => $productRepository->findAll(),
  416.                         'temoin' => $product->getId(),
  417.                         'message' => $reponse
  418.                     ]);
  419.                 }
  420.                 $session->set('listPanier', $listPanier);
  421.                 $listPanierSession = $listPanier;
  422.             } else {
  423.                 $verificationBasket = new ProductUtility();
  424.                 $controlProd = $verificationBasket->isProductInBasket($listPanierSession, $product);
  425.                 if ($controlProd['inBasket']) {
  426.                     $c = 1;
  427.                     $reponse = $stockRepository->addProductIntoOrder($product, $c);
  428.                     if ('' === $reponse) {
  429.                         $listPanierSession[$controlProd['indice']]['number'] = 1;
  430.                         $listPanierSession[$controlProd['indice']]['subscription_price'] = $subscriptionPrice;
  431.                         $listPanierSession[$controlProd['indice']]['subscription_user_count'] = $subscriptionUserCount;
  432.                     } else {
  433.                         return $this->render('/frontView/product/index.html.twig', [
  434.                             'products' => $productRepository->findAll(),
  435.                             'temoin' => $product->getId(),
  436.                             'message' => $reponse.". Vous avez déjà ".$listPanierSession[$controlProd['indice']]['number']." dans votre panier"
  437.                         ]);
  438.                     }
  439.                 } else {
  440.                     $reponse = $stockRepository->addProductIntoOrder($product, 1);//Stock disponible 0
  441.                     if ('' === $reponse) {
  442.                         array_push($listPanierSession, $formatPanier);
  443.                     } else {
  444.                         return $this->render('/frontView/product/index.html.twig', [
  445.                             'products' => $productRepository->findAll(),
  446.                             'temoin' => $product->getId(),
  447.                             'message' => $reponse
  448.                         ]);
  449.                     }
  450.                 }
  451.                 //array_push($listPanierSession,$formatPanier);
  452.                 $session->set('listPanier', $listPanierSession);
  453.             }
  454.             $form = $this->createForm(CommandeValideType::class, null);
  455.         }
  456.         return $this->redirectToRoute('app_product_list_panier');
  457.         // $form->handleRequest($request);
  458.         // if ($form->isSubmitted() && $form->isValid()) {
  459.         //     try{
  460.         //         $commande = new Order();
  461.         //         $commande->setState(0);
  462.         //         if($this->getUser() == null){
  463.         //             if($user->getPassword() != $form->get('confirmpass')->getData()){
  464.         //                     $arrayresult['error'] = true;
  465.         //                     $arrayresult['msg'] = "Mot de passe non confirmé.";
  466.         //                 } else if(strpos($user->getEmail()," ")){
  467.         //                     $arrayresult['error'] = true;
  468.         //                     $arrayresult['msg'] = "l'identifiant \"".$user->getEmail()."\" ne doit pas contenir un espace.";
  469.         //                 }
  470.         //                 else if(strlen($user->getEmail()) < 5){
  471.         //                     $arrayresult['error'] = true;
  472.         //                     $arrayresult['msg'] = "l'identifiant \"".$user->getEmail()."\" doit contenir plus de 5 caracteres.";
  473.         //                 }
  474.         //                 else {
  475.         //                     $user->setRoles(["ROLE_CUSTOMER"]);
  476.         //                     $user->setPassword(
  477.         //                     $passwordEncoder->encodePassword($user, $user->getPassword()));
  478.         //                     $userPlatformRepository->add($user, true);
  479.         //                     //Authentification
  480.         //                     $token = new UsernamePasswordToken($user, $user->getPassword(), "public", $user->getRoles());
  481.         //                     $this->get("security.token_storage")->setToken($token);
  482.         //                     $event = new InteractiveLoginEvent($request, $token);
  483.         //                     //$this->get("event_dispatcher")->dispatch("security.interactive_login", $event);
  484.         //                     //creation commande
  485.         //                     $commande->setDateOrder(\DateTime::createFromFormat('Y-m-d H:i:s',Date('Y-m-d H:i:s')));
  486.         //                     $commande->setCustomer($user);
  487.         //                     $save = $entityManager->getRepository(Order::class)->add($commande,true);
  488.         //                     $session = $request->getSession();
  489.         //                     $listPanierSession = $session->get('listPanier');
  490.         //                     for($incr = 0 ; $incr < count($listPanierSession) ; $incr++){
  491.         //                         $newDetailsOrders = new DetailsOrders();
  492.         //                         $newDetailsOrders->setIdorder($commande);
  493.         //                         $product = $entityManager->getRepository(Product::class)->find($listPanierSession[$incr]['produit']->getId());
  494.         //                         $newDetailsOrders->setIdproduct($product);
  495.         //                         $newDetailsOrders->setQuantity($listPanierSession[$incr]['number']);
  496.         //                         $entityManager->getRepository(DetailsOrders::class)->add($newDetailsOrders,true);
  497.         //                     }
  498.         //                     //return $this->redirectToRoute('app_login', [], Response::HTTP_SEE_OTHER);
  499.         //                 }
  500.         //         }
  501.         //         else {
  502.         //             //$commande = new Order();
  503.         //             $commande->setDateOrder(\DateTime::createFromFormat('Y-m-d H:i:s',Date('Y-m-d H:i:s')));
  504.         //             $commande->setCustomer($this->getUser());
  505.         //             $save = $entityManager->getRepository(Order::class)->add($commande,true);
  506.         //             $session = $request->getSession();
  507.         //             $listPanierSession = $session->get('listPanier');
  508.         //             for($incr = 0 ; $incr < count($listPanierSession) ; $incr++){
  509.         //                 $newDetailsOrders = new DetailsOrders();
  510.         //                 $newDetailsOrders->setIdorder($commande);
  511.         //                 $product = $entityManager->getRepository(Product::class)->find($listPanierSession[$incr]['produit']->getId());
  512.         //                 $newDetailsOrders->setIdproduct($product);
  513.         //                 $newDetailsOrders->setQuantity($listPanierSession[$incr]['number']);
  514.         //                 $entityManager->getRepository(DetailsOrders::class)->add($newDetailsOrders,true);
  515.         //             }
  516.         //             //$arrayresult = array("error"=>true,"msg"=>"test");
  517.         //         }
  518.         //         $session->set('listPanier',[]);
  519.         //         $listPanierSession = [];
  520.         //     }
  521.         //     catch(Exception $exc){
  522.         //         return $this->render('frontView/error.html.twig', [
  523.         //                 'msg' => $exc->getMessage(),
  524.         //         ]);
  525.         //     }
  526.         // }
  527.         // return $this->renderForm('frontView/product/addpanier.html.twig', [
  528.         //     'listPanier' => $listPanierSession,
  529.         //     'arrayresult' => $arrayresult,
  530.         //     'form' => $form,
  531.         // ]);
  532.     }
  533.     /**
  534.      * @Route("/panier/rent/{product}", name="app_product_rent")
  535.      */
  536.     public function rentProduct(
  537.         Request $request,
  538.         Product $product,
  539.         EntityManagerInterface $entityManager,
  540.         StockRepository $stockRepository
  541.     ): Response {
  542.         // Safety check
  543.         if ($product->getStatetype() !== 99) {
  544.             return $this->redirectToRoute('app_product_panier', [
  545.                 'product' => $product->getId()
  546.             ]);
  547.         }
  548.         $form = $this->createForm(RentProductType::class);
  549.         $form->handleRequest($request);
  550.         if ($form->isSubmitted() && $form->isValid()) {
  551.             $data = $form->getData();
  552.             // Date validation
  553.             if ($data['endDate'] <= $data['startDate']) {
  554.                 $this->addFlash('error', 'La date de fin doit être postérieure à la date de début.');
  555.                 return $this->redirectToRoute('app_product_rent', [
  556.                     'product' => $product->getId()
  557.                 ]);
  558.             }
  559.             $session = $request->getSession();
  560.             $listPanier = $session->get('listPanier', []);
  561.             // Prevent duplicate rental of same product
  562.             foreach ($listPanier as $item) {
  563.                 if (
  564.                     $item['produit']->getId() === $product->getId()
  565.                     && isset($item['rent'])
  566.                 ) {
  567.                     $productName = $item['produit']->getTitle();
  568.                     $this->addFlash('error', "Le produit \"$productName\" est déjà loué dans votre panier");
  569.                     // return $this->redirectToRoute('app_product_list_panier');
  570.                     return $this->redirectToRoute('app_product_rent', [
  571.                     'product' => $product->getId()
  572.                 ]);
  573.                 }
  574.             }
  575.             $price_product = $entityManager
  576.                 ->getRepository(PriceProduct::class)
  577.                 ->getPriceProduct($product);
  578.             $listPanier[] = [
  579.                 'produit' => $product,
  580.                 'number' => 1,
  581.                 'price_product' => $price_product,
  582.                 'rent' => [
  583.                     'startDate' => $data['startDate'],
  584.                     'endDate' => $data['endDate'],
  585.                 ],
  586.             ];
  587.             $session->set('listPanier', $listPanier);
  588.             /*Add to db*/
  589.             // Prevent overlapping rentals
  590.             $existing = $entityManager->getRepository(Location::class)
  591.                 ->findOneBy([
  592.                     'product' => $product,
  593.                     'status' => 'active'
  594.                 ]);
  595.             if ($existing) {
  596.                 $this->addFlash('error', 'Ce produit est déjà loué.');
  597.                 // return $this->redirectToRoute('app_product_list');
  598.                 return $this->redirectToRoute('app_product_rent', [
  599.                     'product' => $product->getId()
  600.                 ]);
  601.             }
  602.             $location = new Location();
  603.             $location->setProduct($product);
  604.             $location->setUser($this->getUser());
  605.             $location->setStartDate($data['startDate']);
  606.             $location->setEndDate($data['endDate']);
  607.             $location->setCreatedAt(\DateTime::createFromFormat('Y-m-d H:i:s', Date('Y-m-d H:i:s')));
  608.             $location->setStatus('active');
  609.             // Optional price calculation
  610.             $days = $data['startDate']->diff($data['endDate'])->days;
  611.             $location->setPrice($days * $product->getPriceProducts()[0]->getPriceCustomer());
  612.             $entityManager->persist($location);
  613.             $entityManager->flush();
  614.             $this->addFlash('success', 'Location enregistrée avec succès');
  615.             return $this->redirectToRoute('app_product_list_panier');
  616.         }
  617.         return $this->render('frontView/product/rent.html.twig', [
  618.             'product' => $product,
  619.             'form' => $form->createView(),
  620.         ]);
  621.     }
  622.     /**
  623.      * @Route("/panier-remove", name="app_product_panier_remove", methods={"GET", "POST"})
  624.      */
  625.     public function removePanier(
  626.         Request $request
  627.     ): Response {
  628.         $session = $request->getSession();
  629.         $session->set('listPanier', []);
  630.         return $this->redirectToRoute('app_product_list_panier', [], Response::HTTP_SEE_OTHER);
  631.     }
  632.     /**
  633.      * @Route("/panier-product-remove/{productID}", name="app_product_panier_product_remove", methods={"GET"})
  634.      */
  635.     public function removeProductInPanier(
  636.         Request $request,
  637.         int $productID,
  638.         ProductRepository $productRepository
  639.     ): Response {
  640.         $session = $request->getSession();
  641.         $paniers = $session->get('listPanier');
  642.         if ($paniers) {
  643.             for ($i = 0; $i< count($paniers); $i++) {
  644.                 $panier = $paniers[$i];
  645.                 if ($panier['produit']->getId() === $productID) {
  646.                     $product = $productRepository->find($productID);
  647.                     $verificationBasket = new ProductUtility();
  648.                     $controlProd = $verificationBasket->isProductInBasket($paniers, $product);
  649.                     if ($controlProd['inBasket']) {
  650.                         unset($paniers[$i]);
  651.                         $paniers = array_values($paniers);
  652.                     }
  653.                 }
  654.             }
  655.         }
  656.         $session->set('listPanier', $paniers);
  657.         return $this->redirectToRoute('app_product_list_panier', [], Response::HTTP_SEE_OTHER);
  658.     }
  659.     /**
  660.      * @Route("/list-panier", name="app_product_list_panier", methods={"GET", "POST"})
  661.      */
  662.     public function listPanier(
  663.         Request $request,
  664.         UserPasswordEncoderInterface $passwordEncoder,
  665.         EntityManagerInterface $entityManager,
  666.         StockRepository $stockRepository,
  667.         UserPlatformRepository $userPlatformRepository,
  668.         LocationRepository $locationRepository,
  669.         AuthorizationCheckerInterface $authorizationChecker
  670.     ): Response {
  671.         $arrayresult = array("error"=>false,"msg"=>"");
  672.         $session = $request->getSession();
  673.         $listPanierSession = $session->get('listPanier');
  674.         if (is_array($listPanierSession)) {
  675.             $freshCart = [];
  676.             foreach ($listPanierSession as $panierItem) {
  677.                 if (!isset($panierItem['produit']) || !is_object($panierItem['produit']) || !method_exists($panierItem['produit'], 'getId')) {
  678.                     continue;
  679.                 }
  680.                 $product = $entityManager->getRepository(Product::class)->find($panierItem['produit']->getId());
  681.                 if (!$product) {
  682.                     continue;
  683.                 }
  684.                 $panierItem['produit'] = $product;
  685.                 $panierItem['price_product'] = $entityManager->getRepository(PriceProduct::class)->getPriceProduct($product);
  686.                 if (isset($panierItem['subscription_payment_id'])) {
  687.                     $panierItem['subscription_payment'] = $entityManager->getRepository(CustomerSubscription::class)->find((int) $panierItem['subscription_payment_id']);
  688.                 } elseif (isset($panierItem['subscription_payment']) && is_object($panierItem['subscription_payment']) && method_exists($panierItem['subscription_payment'], 'getId')) {
  689.                     $panierItem['subscription_payment'] = $entityManager->getRepository(CustomerSubscription::class)->find($panierItem['subscription_payment']->getId());
  690.                 }
  691.                 if (isset($panierItem['subscription_price']) && is_object($panierItem['subscription_price']) && method_exists($panierItem['subscription_price'], 'getId')) {
  692.                     $panierItem['subscription_price'] = $entityManager->getRepository(ProductSubscriptionPrice::class)->find($panierItem['subscription_price']->getId());
  693.                 }
  694.                 if ($panierItem['produit']->getStatetype() !== 2) {
  695.                     $panierItem['number'] = 1;
  696.                 }
  697.                 $freshCart[] = $panierItem;
  698.             }
  699.             $listPanierSession = $freshCart;
  700.             $session->set('listPanier', $listPanierSession);
  701.         }
  702.         $listPanierValider = null;
  703.         $listPanierNonValider = null;
  704.         $user = new UserPlatform();
  705.         if (null == $this->getUser()) {
  706.             $form = $this->createForm(UserMultilType::class, $user);
  707.         } else {
  708.             $form = $this->createForm(CommandeValideType::class, null);
  709.         }
  710.         $this->validerCommande($arrayresult, $form, $user, $session, $listPanierSession, $request, $stockRepository, $passwordEncoder, $entityManager, $userPlatformRepository, $authorizationChecker);
  711.         // dd($listPanierSession);
  712.         if ($session->get('panier_valider')) {
  713.             $listPanierValider = $session->get('panier_valider');
  714.             $listPanierNonValider = $session->get('panier_non_valider');
  715.             $session->remove('panier_valider');
  716.             $session->remove('panier_non_valider');
  717.         }
  718.         // Remove rent product if not active
  719.         $listPanierSession = $session->get('listPanier', []);
  720.         if ($this->getUser()) {
  721.             $activeLocations = $locationRepository->findBy([
  722.                 'user' => $this->getUser(),
  723.                 'status' => 'active'
  724.             ]);
  725.             $activeProductIds = array_map(
  726.                 fn($loc) => $loc->getProduct()->getId(),
  727.                 $activeLocations
  728.             );
  729.             foreach ($listPanierSession as $key => $item) {
  730.                 if (
  731.                     isset($item['rent']) &&
  732.                     !in_array($item['produit']->getId(), $activeProductIds)
  733.                 ) {
  734.                     unset($listPanierSession[$key]);
  735.                 }
  736.             }
  737.             // Reindex & update session
  738.             $listPanierSession = array_values($listPanierSession);
  739.             $session->set('listPanier', $listPanierSession);
  740.         }
  741.         return $this->renderForm('frontView/product/addpanier.html.twig', [
  742.             'listPanier' => $listPanierSession,
  743.             'listPanierValider' => $listPanierValider,
  744.             'listPanierNonValider' => $listPanierNonValider,
  745.             'arrayresult' => $arrayresult,
  746.             'form' => $form,
  747.         ]);
  748.         /* return $this->renderForm('frontView/product/listcommande.html.twig', [
  749.         ]); */
  750.     }
  751.     /**
  752.      * @Route("/points/{id}", name="app_product_modif", methods={"GET"})
  753.      */
  754.     public function modifPoint(int $id, ProductRepository $productRepository): Response
  755.     {
  756.         $prod = $productRepository->getPoint($id);
  757.         $sommestockinit = 0;
  758.         $sommestockfinal = 0;
  759.         $sommestockinit = $prod['points'];
  760.         $sommestockfinal = $sommestockinit + 1;
  761.         $productRepository->updatePoint($sommestockfinal, $id);
  762.         return $this->redirectToRoute('app_product_show', [
  763.             'id'=>$id,
  764.             'modif'=>'validation'
  765.         ], Response::HTTP_SEE_OTHER);
  766.     }
  767.     
  768.     
  769.     /**
  770.      * @Route("/ajax-random-products", name="ajax_random_products", methods={"GET"})
  771.      */
  772.     public function ajaxRandomProducts(ProductRepository $productRepository): JsonResponse
  773.     {
  774.         $categories = $productRepository->findRandomGroupedByCategory();
  775.         // dd($categories);
  776.         return $this->json($categories);
  777.     }
  778.     
  779.     /**
  780.      * @Route("/{id}/{modif}", name="app_product_show", methods={"GET"})
  781.      */
  782.     public function show(Request $request, Product $product, ProductRepository $productRepository, EntityManagerInterface $em, string $modif = null): Response
  783.     {
  784.         $sommestockinit = 0;
  785.         $sommestockfinal = 0;
  786.         $prod = array();
  787.         // if($this->getUser() != null ){
  788.         // if($modif != "validation"){
  789.         //     if($this->isGranted('ROLE_CUSTOMER')){
  790.         //         return $this->redirectToRoute('app_product_modif', [
  791.         //             'id'=>$product->getId(),
  792.         //         ], Response::HTTP_SEE_OTHER);
  793.         //     }
  794.         // }
  795.         /*if($this->isGranted('ROLE_CUSTOMER')){
  796.             $prod = $productRepository->getPoint($id);
  797.             $sommestockinit = 0;
  798.             $sommestockfinal = 0;
  799.             $sommestockinit = $prod['points'];
  800.             $sommestockfinal = $sommestockinit + 1;
  801.             $productRepository->updatePoint($sommestockfinal,$id);
  802.         }*/
  803.         /*if($this->isGranted('ROLE_CUSTOMER')){
  804.             $prod = $entityManager->getRepository(Product::class)->getPoint($id);
  805.             $sommestockinit = 0;
  806.             $sommestockfinal = 0;
  807.             $sommestockinit = $prod['points'];
  808.             $sommestockfinal = $sommestockinit + 1;
  809.             $productRepository->updatePoint($sommestockfinal,$id);
  810.             $entityManager->getRepository(Product::class)->updatePoint($sommestockfinal,$id);
  811.         }*/
  812.         // }
  813.         //$product = $productRepository->find($id);
  814.         // if ($request->getMethod() === 'GET') {
  815.         //     $product->setPoints($product->getPoints() + 1);
  816.         //     $em->flush();
  817.         // }
  818.         // If coming from suggestion
  819.         if ($request->query->get('fromSearch')) {
  820.             $product->setSearchCount($product->getSearchCount() + 1);
  821.         }
  822.         $em->flush();
  823.         
  824.         return $this->render('frontView/product/show.html.twig', [
  825.             'product' => $product,
  826.             'sommestockinit' => $sommestockinit,
  827.             'sommestockfinal' => $sommestockfinal,
  828.             'type'=> $product->getStatetype(),//getStatetype() !== 1
  829.             'prod' => $prod,
  830.         ]);
  831.     }
  832.     
  833.     /**
  834.      * @Route("/{id}/click", name="app_product_click", methods={"POST"})
  835.      */
  836.     public function click(
  837.         Request $request,
  838.         Product $product,
  839.         EntityManagerInterface $em
  840.     ): JsonResponse {
  841.         $product->setPoints($product->getPoints() + 1);
  842.         // Increment search count only if coming from search
  843.         /*if ($request->query->get('fromSearch')) {
  844.             $product->setSearchCount($product->getSearchCount() + 1);
  845.         }*/
  846.         $em->flush();
  847.         return new JsonResponse(['ok' => true]);
  848.     }
  849.     /**
  850.      * @Route("/{id}/click-search", name="app_product_click_search", methods={"POST"})
  851.      */
  852.     public function clickSearch(
  853.         Request $request,
  854.         Product $product,
  855.         EntityManagerInterface $em
  856.     ): JsonResponse {
  857.         // Increment search count only if coming from search
  858.         if ($request->query->get('fromSearch')) {
  859.             $product->setSearchCount($product->getSearchCount() + 1);
  860.         }
  861.         $em->flush();
  862.         return new JsonResponse(['ok' => true]);
  863.     }
  864. }