src/Controller/CartController.php line 246

  1. <?php
  2. namespace App\Controller;
  3. use App\Entity\ActionShock;
  4. use App\Entity\AdditionalCompanyInformation;
  5. use App\Entity\Billings;
  6. use App\Entity\BrandDiscount;
  7. use App\Entity\Cart;
  8. use App\Entity\CartFinished;
  9. use App\Entity\ConfigSite;
  10. use App\Entity\CustomerControl;
  11. use App\Entity\DeliveryAddress;
  12. use App\Entity\Joker;
  13. use App\Entity\LotNumber;
  14. use App\Entity\Products;
  15. use App\Entity\Rebate;
  16. use App\Entity\SpecialCustomer;
  17. use App\Entity\SpecialDiscount;
  18. use App\Entity\User;
  19. use App\Service\JwtMercator;
  20. use Symfony\Component\Mime\Email;
  21. use Symfony\Component\Mailer\MailerInterface;
  22. use Doctrine\ORM\EntityManagerInterface;
  23. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  24. use Symfony\Component\HttpFoundation\JsonResponse;
  25. use Symfony\Component\HttpFoundation\RedirectResponse;
  26. use Symfony\Component\HttpFoundation\Request;
  27. use Symfony\Component\HttpFoundation\Response;
  28. use Symfony\Component\Routing\Annotation\Route;
  29. use Symfony\Contracts\HttpClient\HttpClientInterface;
  30. use TCPDF;
  31. class CartController extends AbstractController
  32. {
  33.     private EntityManagerInterface $manager;
  34.     private $client;
  35.     private $jwtMercator;
  36.     public function __construct(EntityManagerInterface $managerHttpClientInterface $clientJwtMercator $jwtMercator)
  37.     {
  38.         $this->manager $manager;
  39.         $this->client $client;
  40.         $this->jwtMercator $jwtMercator;
  41.     }
  42.     #[Route('/addtocart'name'addtocart'methods: ['GET''POST'])]
  43.     public function index(Request $request): Response
  44.     {
  45.         $checkControl $this->manager->getRepository(CustomerControl::class)->findOneBy(array('user' => $this->getUser(), 'finish' => false));
  46.         if (!$checkControl) {
  47.             $user $this->getUser();
  48.         } else {
  49.             $user $checkControl->getCustomer();
  50.         }
  51.         $information $this->manager->getRepository(AdditionalCompanyInformation::class)->findOneBy(['user' => $user]);
  52.         $exist_cart $this->manager->getRepository(Cart::class)->findOneBy(array('user' => $user'finish' => false), array('commandNumber' => 'DESC'));
  53.         if ($exist_cart) {
  54.             $exist_product $this->manager->getRepository(Cart::class)->findOneBy(array('user' => $user'finish' => false'products' => $this->manager->getRepository(Products::class)->find($request->get('id_product'))));
  55.             if ($exist_product) {
  56.                 $availableStock $this->manager->getRepository(LotNumber::class)->getProductAvailableStock($exist_product->getProducts()->getId(), $information->getCompanyCountry() === 'Belgique' 'BE' 'LU');
  57.                 $newQuantity $exist_product->getQuantity() + $request->get('quantity');
  58.                 if ($newQuantity $availableStock) {
  59.                     $newQuantity $availableStock;
  60.                 }
  61.                 $exist_product->setQuantity($newQuantity);
  62.                 $this->manager->flush();
  63.             } else {
  64.                 $cart = new Cart();
  65.                 $cart->setFinish(0);
  66.                 $cart->setCommandNumber($exist_cart->getCommandNumber());
  67.                 $cart->setProducts($this->manager->getRepository(Products::class)->find($request->get('id_product')));
  68.                 $cart->setUser($user);
  69.                 $cart->setQuantity($request->get('quantity'));
  70.                 $this->manager->persist($cart);
  71.                 $this->manager->flush();
  72.             }
  73.         } else {
  74.             $exist_cart_before $this->manager->getRepository(Cart::class)->findOneBy(array('user' => $user'finish' => true), array('commandNumber' => 'DESC'));
  75.             $cart = new Cart();
  76.             $cart->setFinish(0);
  77.             if ($exist_cart_before) {
  78.                 $cart->setCommandNumber($exist_cart_before->getCommandNumber() + 1);
  79.             } else {
  80.                 $cart->setCommandNumber(1);
  81.             }
  82.             $cart->setProducts($this->manager->getRepository(Products::class)->find($request->get('id_product')));
  83.             $cart->setUser($user);
  84.             $cart->setQuantity($request->get('quantity'));
  85.             $this->manager->persist($cart);
  86.             $this->manager->flush();
  87.         }
  88.         // Récupérer les informations pour la réponse JSON
  89.         $cartCount $this->calculateCountItemInCart();
  90.         
  91.         // Calculer le pourcentage de remise en cours
  92.         $specialCustomer $this->manager->getRepository(SpecialCustomer::class)->findOneBy(array('user' => $user));
  93.         $pourcentSpecialCustomer null;
  94.         if ($specialCustomer) {
  95.             $pourcentSpecialCustomer $specialCustomer;
  96.         }
  97.         $rebatePercent $this->calculateRebate($pourcentSpecialCustomer);
  98.         
  99.         // Récupérer les informations sur les produits gratuits
  100.         $carts $this->retrieveCart();
  101.         $freeProductInfo $this->checkFreeProduct($carts);
  102.         
  103.         // Récupérer les informations de remises
  104.         $rebates $this->manager->getRepository(Rebate::class)->getActiveNormalRebates();
  105.         $rebateInfo = [];
  106.         
  107.         foreach ($rebates as $rebate) {
  108.             $rebateInfo[] = [
  109.                 'min' => $rebate->getMin(),
  110.                 'percent' => $rebate->getPourcentRebate()
  111.             ];
  112.         }
  113.         
  114.         // Créer la réponse JSON avec toutes les informations nécessaires
  115.         return new JsonResponse([
  116.             'success' => true,
  117.             'cartCount' => $cartCount,
  118.             'rebateInfo' => [
  119.                 'currentPercent' => $rebatePercent,
  120.                 'availableRebates' => $rebateInfo
  121.             ],
  122.             'freeProductInfo' => $freeProductInfo,
  123.             'message' => 'Produit ajouté au panier'
  124.         ]);
  125.     }
  126.     #[Route('/addtocartfromcart'name'addtocartfromcart')]
  127.     public function addToCartFromCart(Request $request): JsonResponse
  128.     {
  129.         $checkControl $this->manager->getRepository(CustomerControl::class)->findOneBy(array('user' => $this->getUser(), 'finish' => false));
  130.         if (!$checkControl) {
  131.             $user $this->getUser();
  132.         } else {
  133.             $user $checkControl->getCustomer();
  134.         }
  135.         $information $this->manager->getRepository(AdditionalCompanyInformation::class)->findOneBy(['user' => $user]);
  136.         $exist_cart $this->manager->getRepository(Cart::class)->findOneBy(array('user' => $user'finish' => false), array('commandNumber' => 'DESC'));
  137.         if ($exist_cart) {
  138.             $exist_product $this->manager->getRepository(Cart::class)->find($request->get('id_product'));
  139.             if (!$exist_product) {
  140.                 return new JsonResponse('Cart item not found');
  141.             }
  142.             if ($request->get('move') == "quantity-increase") {
  143.                 $availableStock $this->manager->getRepository(LotNumber::class)->getProductAvailableStock($exist_product->getProducts()->getId(), $information->getCompanyCountry() === 'Belgique' 'BE' 'LU');
  144.                 $newQuantity $exist_product->getQuantity() + 1;
  145.                 if ($newQuantity $availableStock) {
  146.                     $newQuantity $availableStock;
  147.                 }
  148.                 $exist_product->setQuantity($newQuantity);
  149.             } elseif ($request->get('move') == "quantity-decrease") {
  150.                 $exist_product->setQuantity($exist_product->getQuantity() - 1);
  151.             }
  152.             if ($exist_product->getQuantity() == 0) {
  153.                 $this->manager->remove($exist_product);
  154.             }
  155.             $this->manager->flush();
  156.         }
  157.         return new JsonResponse('ok');
  158.     }
  159.     #[Route('/cart'name'cartView')]
  160.     public function cartView(JwtMercator $jwtMercatorRequest $request): Response
  161.     {
  162.         if (!$this->getUser()) {
  163.             return $this->redirectToRoute('app_login');
  164.         }
  165.         $checkControl $this->manager->getRepository(CustomerControl::class)->findOneBy(array('user' => $this->getUser(), 'finish' => false));
  166.         if (!$checkControl) {
  167.             $user $this->getUser();
  168.             $additionalInformations $this->manager->getRepository(AdditionalCompanyInformation::class)->findOneBy(array('user' => $this->getUser()));
  169.         } else {
  170.             $user $checkControl->getCustomer();
  171.             $additionalInformations $this->manager->getRepository(AdditionalCompanyInformation::class)->findOneBy(array('user' => $checkControl->getCustomer()));
  172.         }
  173.         $costDelivery $this->manager->getRepository(ConfigSite::class)->findAll();
  174.         $costDelivery $costDelivery[0];
  175.         $informations $this->manager->getRepository(User::class)->getAllInformationsForAccount($user);
  176.         if ($additionalInformations != null && $additionalInformations->getGeneralCondition()) {
  177.             $cart $this->retrieveCart();
  178.         } else {
  179.             $this->addFlash('danger''Veuillez remplir votre pays & accepter les conditions générales de ventes!');
  180.             return $this->redirectToRoute('profile');
  181.         }
  182.         //            $this->applyDiscountOnNewRefItems($cart);
  183.         $faReference = ['NMJ007''NMJ008''NMJ011''NMJ084''NMJ013''NMJ056''NMJ040'];
  184.         $countFaInCart 0;
  185.         foreach ($cart['carts'] as $item) {
  186.             if (isset($item['reference'])) {
  187.                 if (in_array($item['reference'], $faReference)) {
  188.                     $countFaInCart += $item[0]['quantity'];
  189.                 }
  190.             }
  191.         }
  192.         $numberOfFaRef null;
  193.         if ($countFaInCart >= 2) {
  194.             $numberOfFaRef floor($countFaInCart 2);
  195.         }
  196.         $flyersProduct $this->manager->getRepository(Products::class)->findOneBy(array('reference' => 'NMZZ21'));
  197.         $deliveryAdress $this->manager->getRepository(DeliveryAddress::class)->findOneBy(array('user' => $user));
  198.         //            if ($additionalInformations->getCompanyAddress() != null && $additionalInformations->getCompanyPostal() != null && $additionalInformations->getCompanyCountry() &&
  199.         //                $additionalInformations->getTownAddressCompany() != null)
  200.         if (!$deliveryAdress) {
  201.             $this->addFlash('danger''Veuillez ajouter une adresse de livraison! "Bouton bleu gestion des adresses"');
  202.             return $this->redirectToRoute('profile');
  203.         }
  204.         $address $this->manager->getRepository(DeliveryAddress::class)->findBy(array('user' => $user));
  205.         $rebates $this->manager->getRepository(Rebate::class)->getActiveNormalRebates();
  206.         $specificRebates $this->manager->getRepository(Rebate::class)->getActiveSpecificRebates();
  207.         $brandDiscounts $this->manager->getRepository(BrandDiscount::class)->findBy(['active' => true]);
  208.         // Gestion de la préférence flyers via session
  209.         if (!$request->getSession()->has('wantFlyers')) {
  210.             $request->getSession()->set('wantFlyers'true);
  211.         }
  212.         $wantFlyers $request->getSession()->get('wantFlyers');
  213.         // Si l'utilisateur ne veut pas de flyers, on n'ajoute pas de flyers
  214.         if (!$wantFlyers) {
  215.             $numberOfFaRef null;
  216.         }
  217.         return $this->render('cart/index.html.twig', [
  218.             'shockActionTypes' => ActionShock::TYPES,
  219.             'informations' => $informations,
  220.             'carts' => $cart['carts'],
  221.             'rebate' => $cart['rebate'],
  222.             'grandTotalPrice' => $cart['grandTotalPrice'],
  223.             'freeProduct' => $cart['freeProduct'],
  224.             'freeTransport' => $cart['freeTransport'],
  225.             'joker' => $cart['joker'],
  226.             'user' => $this->getUser(),
  227.             'address' => $address,
  228.             'jokerNumber' => $this->checkJokerNumber(),
  229.             'missingItems' => $cart['missingItems'],
  230.             'costDelivery' => $costDelivery->getCostDelivery(),
  231.             'phFlyers' => (int)$numberOfFaRef,
  232.             'countFaInCart' => $countFaInCart,
  233.             'flyersProduct' => $flyersProduct,
  234.             'wantFlyers' => $wantFlyers,
  235.             'rebates' => array_reverse($rebates),
  236.             'specificRebates' => array_reverse($specificRebates),
  237.             // TODO update twig template
  238.             'brandDiscounts' => $brandDiscounts
  239.         ]);
  240.     }
  241.     private function applyDiscountOnNewRefItems(&$cart)
  242.     {
  243.         // Parcourez chaque élément du panier directement.
  244.         foreach ($cart as $key => &$item) {
  245.             // Vérifiez si l'élément est un tableau et a une propriété 'newRef' à true.
  246.             if (is_array($item) && isset($item['newRef']) && $item['newRef']) {
  247.                 // Vérifiez si 'PriceRebateInclude' existe et appliquez la réduction de 2%.
  248.                 if (isset($item['PriceRebateInclude'])) {
  249.                     // Calcul de la réduction de 2%.
  250.                     $discountAmount $item['PriceRebateInclude'] * 0.02;
  251.                     // Calculez le nouveau prix après réduction et stockez-le dans 'PriceRebateIncludeWith2pourcent'.
  252.                     $item['PriceRebateIncludeWith2pourcent'] = $item['PriceRebateInclude'] - $discountAmount;
  253.                 }
  254.             }
  255.         }
  256.         unset($item); // Détruisez la référence sur le dernier élément pour éviter les problèmes potentiels.
  257.         // Pas besoin de retourner $cart car il est modifié par référence.
  258.     }
  259.     #[Route('/cart/send'name'cartSend')]
  260.     public function sendCart(Request $requestMailerInterface $mailerJwtMercator $jwtMercator): RedirectResponse|JsonResponse
  261.     {
  262.         $orderRecipientEmails $this->getParameter('app.order.emails');
  263.         if (!is_array($orderRecipientEmails)) {
  264.             $orderRecipientEmails explode(','$orderRecipientEmails);
  265.         }
  266.         $defaultRebatePercent floatval($request->query->get('rebatePourcent'));
  267.         $jwtToken $jwtMercator->getToken()->getContent();
  268.         $costDelivery $this->manager->getRepository(ConfigSite::class)->findAll();
  269.         $costDelivery $costDelivery[0];
  270.         if ($request->query->get('idUser') === null) {
  271.             return $this->redirectToRoute('app_login');
  272.         }
  273.         $checkControl $this->manager->getRepository(CustomerControl::class)->findOneBy(array('user' => $this->getUser(), 'finish' => false));
  274.         if ($checkControl != null) {
  275.             $user $checkControl->getCustomer();
  276.             $additionalInformation $this->manager->getRepository(AdditionalCompanyInformation::class)->findOneBy(array('user' => $user));
  277.             $country $additionalInformation->getCompanyCountry();
  278.             $saleField $country === 'Belgique' 'p.saleBe' 'p.saleFr';
  279.             $folderMercatorValue $country === 'Belgique' 'BE' 'LU';
  280.             $countryShip null;
  281.             if ($additionalInformation->getCompanyCountry() == "France") {
  282.                 $countryShip "FR";
  283.             } elseif ($additionalInformation->getCompanyCountry() == "Belgique") {
  284.                 $countryShip "BE";
  285.             } elseif ($additionalInformation->getCompanyCountry() == "Luxembourg") {
  286.                 $countryShip "LU";
  287.             }
  288.         } else {
  289.             $user $this->manager->getRepository(User::class)->find($request->query->get('idUser'));
  290.             $additionalInformation $this->manager->getRepository(AdditionalCompanyInformation::class)->findOneBy(array('user' => $user));
  291.             $country $additionalInformation->getCompanyCountry();
  292.             $saleField $country === 'Belgique' 'p.saleBe' 'p.saleFr';
  293.             $folderMercatorValue $country === 'Belgique' 'BE' 'LU';
  294.             $countryShip null;
  295.             if ($additionalInformation->getCompanyCountry() == "France") {
  296.                 $countryShip "FR";
  297.             } elseif ($additionalInformation->getCompanyCountry() == "Belgique") {
  298.                 $countryShip "BE";
  299.             } elseif ($additionalInformation->getCompanyCountry() == "Luxembourg") {
  300.                 $countryShip "LU";
  301.             }
  302.         }
  303.         $pourcentSpecialCustomer null;
  304.         if ($user->getSpecialCustomer()) {
  305.             $checkUserSpecialEntity $this->manager->getRepository(SpecialCustomer::class)->findOneBy(array('user' => $user'active' => true));
  306.             if ($checkUserSpecialEntity == null) {
  307.                 $pourcentSpecialCustomer $this->manager->getRepository(ConfigSite::class)->findAll();
  308.                 $pourcentSpecialCustomer $pourcentSpecialCustomer[0];
  309.             } else {
  310.                 $pourcentSpecialCustomer $checkUserSpecialEntity->getPourcentRebate();
  311.             }
  312.         }
  313.         $articles $this->manager->getRepository(Cart::class)->getCurrentCart($user$request->query->get('idCommande')); //ai5: commented this => findBy(array('user' => $user, 'commandNumber' => $request->query->get('idCommande')));
  314.         $jwtToken $this->jwtMercator->getToken()->getContent();
  315.         $content = [];
  316.         try {
  317.             $response $this->client->request('GET''https://ns3190747.ip-51-89-219.eu/OrderHistory?clientId=' $additionalInformation->getIdClientMercator(), [
  318.                 'headers' => [
  319.                     'Authorization' => 'Bearer ' $jwtToken,
  320.                 ],
  321.             ]);
  322.             $content $response->getContent();
  323.             $content json_decode($contenttrue);
  324.         } catch (\Exception $e) {
  325.             // TODO log error somewhere
  326.         }
  327.         $addressDelivery $this->manager->getRepository(DeliveryAddress::class)->find($request->query->get('deliveryAddress'));
  328.         $cart $this->manager->getRepository(Cart::class)->getAllCart($user);
  329.         $freeProducts $this->checkFreeProduct($cart);
  330.         $specificRebates =  $this->manager->getRepository(Rebate::class)->getActiveSpecificRebates();
  331.         if ($additionalInformation->getCompanyCountry() == 'Belgique') {
  332.             $tvaLow 6;
  333.             $tvaHigh 21;
  334.         } elseif ($additionalInformation->getCompanyCountry() == 'France') {
  335.             $tvaLow 5.5;
  336.             $tvaHigh 20;
  337.         } elseif ($additionalInformation->getCompanyCountry() == 'Luxembourg') {
  338.             $tvaLow 3;
  339.             $tvaHigh 17;
  340.         }
  341.         // Tableau associatif pour faire correspondre les noms des jours en anglais avec leur équivalent en français
  342.         $daysMapping = [
  343.             'monday' => 'Lu',
  344.             'tuesday' => 'Ma',
  345.             'wednesday' => 'Me',
  346.             'thursday' => 'Je',
  347.             'friday' => 'Ve',
  348.             'saturday' => 'Sa',
  349.             'sunday' => 'Di',
  350.         ];
  351.         // Obtenir les jours en français avec les deux premières lettres où la valeur est true
  352.         $daysTrue = [];
  353.         foreach ($daysMapping as $dayEnglish => $dayFrench) {
  354.             if ($addressDelivery->{'get' ucfirst($dayEnglish)}() === true) {
  355.                 $morningTime $addressDelivery->{'getMorning' ucfirst($dayEnglish)}()->format('H:i');
  356.                 $morningEndTime $addressDelivery->{'getMorning' ucfirst($dayEnglish) . 'End'}()->format('H:i');
  357.                 $afternoonTime $addressDelivery->{'getAfternoon' ucfirst($dayEnglish)}()->format('H:i');
  358.                 $afternoonEndTime $addressDelivery->{'getAfternoon' ucfirst($dayEnglish) . 'End'}()->format('H:i');
  359.                 $daysTrue[$dayFrench] = [
  360.                     'morning' => [
  361.                         'start' => $morningTime,
  362.                         'end' => $morningEndTime,
  363.                     ],
  364.                     'afternoon' => [
  365.                         'start' => $afternoonTime,
  366.                         'end' => $afternoonEndTime,
  367.                     ],
  368.                 ];
  369.             }
  370.         }
  371.         if ($additionalInformation->getCompanyName() === null || $additionalInformation->getTva() === null || $addressDelivery->getAddress() === null) {
  372.             $this->addFlash('danger''Veuillez complèter votre profil pour continuer.');
  373.             return new JsonResponse('profile'headers: ['Content-Type' => 'application/json;charset=UTF-8']);
  374.         }
  375.         $cartFinished = new CartFinished();
  376.         if (!$checkControl) {
  377.             $cartFinished->setUser($user);
  378.         } else {
  379.             $cartFinished->setUser($checkControl->getCustomer());
  380.         }
  381.         $cartFinished->setCommandId((int) $request->query->get('idCommande'));
  382.         $cartFinished->setTotalPriceWithNoReduction(floatval($request->query->get('total-price-tvac-no-reduct')));
  383.         $deliveryAddressDb $this->manager->getRepository(DeliveryAddress::class)->find($request->query->get('deliveryAddress'));
  384.         $cartFinished->setDeliveryAddress($deliveryAddressDb);
  385.         if ($request->query->get('addressCheck') == "true") {
  386.             $cartFinished->setDeliveryBillingAddress($deliveryAddressDb);
  387.             $addressBilling $deliveryAddressDb;
  388.         } else {
  389.             $addressBilling $this->manager->getRepository(DeliveryAddress::class)->find($request->query->get('deliveryBilling'));
  390.             $cartFinished->setDeliveryBillingAddress($addressBilling);
  391.         }
  392.         if ($request->query->get('totalPriceProductLowVatHtva') != 0) {
  393.             $cartFinished->setTotalPriceProductLowVatHtva($request->query->get('totalPriceProductLowVatHtva'));
  394.             $cartFinished->setTotalPriceProductLowVatTvac($request->query->get('totalPriceProductLowVatTvac'));
  395.         } else {
  396.             $cartFinished->setTotalPriceProductLowVatHtva(0);
  397.             $cartFinished->setTotalPriceProductLowVatTvac(0);
  398.         }
  399.         if ($request->query->get('totalPriceProductHighVatHtva') != 0) {
  400.             $cartFinished->setTotalPriceProductHighVatHtva($request->query->get('totalPriceProductHighVatHtva'));
  401.             $cartFinished->setTotalPriceProductHighVatTvac($request->query->get('totalPriceProductHighVatTvac'));
  402.         } else {
  403.             $cartFinished->setTotalPriceProductHighVatHtva(0);
  404.             $cartFinished->setTotalPriceProductHighVatTvac(0);
  405.         }
  406.         $cartFinished->setTotalPriceAllProductHtva($request->query->get('totalPriceAllProductHtva'));
  407.         $cartFinished->setTotalPriceTvacWithRebate($request->query->get('totalPriceTvacWithRebate'));
  408.         $cartFinished->setTotalRebate(floatval($request->query->get('totalRemise')));
  409.         $cartFinished->setPourcentRebate($defaultRebatePercent);
  410.         $cartFinished->setTotalPaid(floatval($request->query->get('totalPriceWithVat')));
  411.         $dateFormatted date('d-m-Y'); // Récupère la date du jour formatée "d-m-Y"
  412.         $dateObject \DateTime::createFromFormat('d-m-Y'$dateFormatted);
  413.         $cartFinished->setCommandDate($dateObject);
  414.         if ($request->query->get('joker') == "true") {
  415.             $joker $this->manager->getRepository(Joker::class)->findOneBy(array('user' => $user));
  416.             if ($joker->getNumberJoker() > 0) {
  417.                 $joker->setNumberJoker($joker->getNumberJoker() - 1);
  418.                 $cartFinished->setUsedJoker(1);
  419.                 $jokerFact 'Oui';
  420.             } else {
  421.                 $cartFinished->setUsedJoker(0);
  422.                 $jokerFact 'Non';
  423.             }
  424.         } else {
  425.             $cartFinished->setUsedJoker(0);
  426.             $jokerFact 'Non';
  427.         }
  428.         $this->manager->persist($cartFinished);
  429.         foreach ($articles as $item) {
  430.             $item->setFinish(true);
  431.         }
  432.         $this->manager->flush();
  433.         $imagePath $this->getParameter('kernel.project_dir') . '/public/uploads/img/media/logo-naturamedicatrix-pro-v2.png';
  434.         // Création du PDF
  435.         $pdf = new TCPDF('P''mm''A4'true'UTF-8'false);
  436.         $pdf->SetTitle('Facture');
  437.         $pdf->SetPrintHeader(false);
  438.         $pdf->setPrintFooter(false);
  439.         $pdf->SetMargins(101010);
  440.         $pdf->AddPage();
  441.         // Ajout de l'image centrée en haut
  442.         $pdf->Image($imagePath800500'PNG''''C');
  443.         // Ajout des adresses de livraison et de facturation
  444.         $pdf->SetFont('helvetica''B'12);
  445.         $pdf->Ln(5); // Espace après l'image
  446.         $companyName $addressDelivery->getCompanyName();
  447.         // Adresse de livraison
  448.         $pdf->SetFont('helvetica''B'12);
  449.         $pdf->Cell(13010'Adresse de livraison'00'L');
  450.         $pdf->Cell(8010'Adresse de facturation'00'L');
  451.         $pdf->Ln(5);
  452.         $pdf->SetFont('helvetica'''12);
  453.         $deliveryAddress $addressDelivery->getFirstName() . ' ' $addressDelivery->getName();
  454.         $billingAddress $addressBilling->getFirstName() . ' ' $addressBilling->getName();
  455.         $pdf->Cell(13010$companyName00'L');
  456.         $pdf->Cell(8010$companyName00'L');
  457.         $pdf->Ln(5);
  458.         $pdf->Cell(13010$deliveryAddress00'L');
  459.         $pdf->Cell(8010$billingAddress00'L');
  460.         $pdf->Ln(5);
  461.         $pdf->SetFont('helvetica'''12);
  462.         $pdf->Cell(13010$addressDelivery->getAddress(), 00'L');
  463.         $pdf->Cell(8010$addressBilling->getAddress(), 00'L');
  464.         $pdf->Ln(5);
  465.         $pdf->SetFont('helvetica'''12);
  466.         $pdf->Cell(13010$addressDelivery->getTown() . ' ' $addressDelivery->getPostal() . ' ' $addressDelivery->getCountry(), 00'L');
  467.         $pdf->Cell(8010$addressBilling->getTown() . ' ' $addressDelivery->getPostal() . ' ' $addressBilling->getCountry(), 00'L');
  468.         $pdf->Ln(5);
  469.         //                $pdf->SetFont('helvetica', '', 12);
  470.         //                $pdf->Cell(130, 10, "", 0, 0, 'L');
  471.         //                $pdf->Cell(80, 10, 'TVA : ' . $additionalInformation->getTva(), 0, 0, 'L');
  472.         $pdf->Ln(5);
  473.         if ($daysTrue != null) {
  474.             $pdf->SetFont('helvetica'''12);
  475.             $pdf->Cell(1305"Préférences jours et heures de livraison :"00'L');
  476.             //                $pdf->Cell(80, 10, 'Jour livraison : ' . implode(', ', $daysTrue), 0, 0, 'L');
  477.             //                $pdf->Cell(80, 10, 'Jour livraison : ', 0, 0, 'L');
  478.             $pdf->Ln(5);
  479.             foreach ($daysTrue as $day => $hours) {
  480.                 $morningHours $hours['morning']['start'] . ' - ' $hours['morning']['end'];
  481.                 $afternoonHours $hours['afternoon']['start'] . ' - ' $hours['afternoon']['end'];
  482.                 $pdf->Cell(05$day ': Matin ' $morningHours ', Après-midi ' $afternoonHours01'L');
  483.             }
  484.             $pdf->Ln(3);
  485.         }
  486.         // Ajout du nom du client et numéro de commande
  487.         $pdf->SetFont('helvetica'''12);
  488.         //                $pdf->Ln(10); // Espace après les adresses
  489.         $pdf->Cell(1405'Client: ' $additionalInformation->getCompanyName(), 00'L');
  490.         $pdf->Cell(505'Date commande: ' $cartFinished->getCommandDate()->format('d/m/Y'), 00'L');
  491.         $pdf->Ln(5);
  492.         //                $pdf->Cell(0, 10, 'Date commande: ' . $cartFinished->getCommandDate()->format('d/m/Y'), 0, 1, 'L');
  493.         if ($defaultRebatePercent != 0) {
  494.             $pdf->Cell(05'Votre commande avec votre remise de: ' $defaultRebatePercent "%"01'L');
  495.         }
  496.         $pdf->Cell(705'Joker utilisé ? : ' $jokerFact00'L');
  497.         if ($request->get('messageNewRef') != "") {
  498.             $pdf->Ln(5);
  499.             $pdf->MultiCell(05'Nouvelle référence ? : ' $request->get('messageNewRef'), 0'L');
  500.             //                    $pdf->Cell(70, 5, 'Nouvelle référence ? : ' . $request->get('messageNewRef'), 0, 0, 'L');
  501.         }
  502.         // Ajout du tableau des articles
  503.         $pdf->SetFont('helvetica'''7);
  504.         $pdf->Ln(10); // Espace après le titre
  505.         $pdf->Cell(505'Article'10'C');
  506.         $pdf->Cell(305'n° lot'10'C');
  507.         $pdf->Cell(305'Prix professionnel remisé'10'C');
  508.         $pdf->Cell(205'Quantité'10'C');
  509.         $pdf->Cell(305'Remise augmentée'10'C');
  510.         $pdf->Cell(305'Sous-total(HTVA)'10'C');
  511.         $pdf->SetFont('helvetica'''10);
  512.         $pdf->Ln(5);
  513.         $productInfo = [];
  514.         $faReference = ['NMJ007''NMJ008''NMJ011''NMJ084''NMJ013''NMJ056''NMJ040'];
  515.         $countFaInCart 0;
  516.         foreach ($articles as $item) {
  517.             if ($item->getProducts()->getReference() != null) {
  518.                 if (in_array($item->getProducts()->getReference(), $faReference) && $item->getQuantity() > 1) {
  519.                     $countFaInCart += $item->getQuantity();
  520.                 }
  521.             }
  522.         }
  523.         $numberOfFaRef null;
  524.         if ($countFaInCart >= 2) {
  525.             $numberOfFaRef floor($countFaInCart 2);
  526.         }
  527.         $flyersProduct $this->manager->getRepository(Products::class)->findOneBy(array('reference' => 'NMZZ21'));
  528.         $excludedProducts $this->manager->getRepository(Rebate::class)->getExcludedProducts();
  529.         $lotsOrderedQuantity = [];
  530.         foreach ($articles as $article) {
  531.             $shockActions $article->getProducts()->getActionShockCalendar();
  532.             $shockAction null;
  533.             if (count($shockActions) > 0) {
  534.                 $shockAction $shockActions[0];
  535.             }
  536.             $shockActionPercent $shockAction $shockAction->getDiscountPercent() : 0;
  537.             $shockActionType $shockAction $shockAction->getType() : null;
  538.             $rebatePercent $defaultRebatePercent;
  539.             if (in_array($article->getProducts()->getReference(), $excludedProducts)) {
  540.                 $rebatePercent 0;
  541.             }
  542.             foreach ($specificRebates as $rebate) {
  543.                 if (in_array($article->getProducts()->getReference(), $rebate->getSpecificProducts()) && $article->getQuantity() >= $rebate->getMin()) {
  544.                     $rebatePercent $rebate->getPourcentRebate();
  545.                     break;
  546.                 }
  547.             }
  548.             $productIdMercator $article->getProducts()->getIdProductOnMercator();
  549.             // Déterminez si c'est une newRef
  550.             $isNewRef = !in_array($productIdMercator$content);
  551.             foreach ($request->get('lotNumbers') as $lot) {
  552.                 $checkArticle $this->manager->getRepository(LotNumber::class)->findBy(array('lotNumber' => $lot'folderMercator' => $folderMercatorValue));
  553.                 $lotss[] = $checkArticle;
  554.             }
  555.             $productName $article->getProducts()->getName();
  556.             foreach ($lotss as $lots) {
  557.                 foreach ($lots as $lot) {
  558.                     if ($lot->getProducts()->getName() == $article->getProducts()->getName()) {
  559.                         $productInfo[$productName]['noLot'] = $lot->getLotNumber();
  560.                         if (!in_array($lot->getDepot(), LotNumber::EXCLUDED_DEPOTS)) {
  561.                             $lotsOrderedQuantity[] = [
  562.                                 'product' => $article->getProducts(),
  563.                                 'lot_number' => $lot->getLotNumber(),
  564.                                 'ordered_quantity' => $article->getQuantity(),
  565.                                 'depot' => $lot->getDepot(),
  566.                                 'folderMercator' => $folderMercatorValue,
  567.                             ];
  568.                         }
  569.                     }
  570.                 }
  571.             }
  572.             $checkSpecialDiscount $this->manager->getRepository(SpecialDiscount::class)->findOneBy(array('product' => $article->getProducts()));
  573.             if ($checkSpecialDiscount != null && $article->getQuantity() > 11) {
  574.                 $productPrice $article->getProducts()->getPublicPrice();
  575.             } else {
  576.                 $productPrice $article->getProducts()->getPrice();
  577.                 $checkSpecialDiscount null;
  578.             }
  579.             $productBrandName $article->getProducts()->getBrand();
  580.             if ($productBrandName == 'NaturaMedicatrix') {
  581.                 if ($rebatePercent >= 19) {
  582.                     $pourcentNatura $this->manager->getRepository(BrandDiscount::class)->findOneBy(array('brandName' => 'NaturaMedicatrix'));
  583.                     $pourcentNatura $pourcentNatura->getRebateHeigh();
  584.                 } elseif ($rebatePercent >= 13) {
  585.                     $pourcentNatura $this->manager->getRepository(BrandDiscount::class)->findOneBy(array('brandName' => 'NaturaMedicatrix'));
  586.                     $pourcentNatura $pourcentNatura->getRebateLow();
  587.                 }
  588.             } else {
  589.                 $pourcentNatura null;
  590.             }
  591.             if ($request->get('messageNewRef') != "") {
  592.                 $article->setMessage($request->get('messageNewRef'));
  593.                 $this->manager->flush();
  594.             }
  595.             $quantity $article->getQuantity();
  596.             $actionShock $article->getProducts()->getActionShock();
  597.             $productInfo[$productName] = [
  598.                 'brand' => $productBrandName,
  599.                 'price' => $productPrice,
  600.                 'quantity' => $quantity,
  601.                 'noLot' => $productInfo[$productName]['noLot'],
  602.                 'reference' => $article->getProducts()->getReference(),
  603.                 'specialDiscount' => $checkSpecialDiscount,
  604.                 'rebatePercent' => $rebatePercent,
  605.                 'newRef' => $isNewRef,
  606.                 'actionShock' => $actionShock,
  607.                 'shockActionPercent' => $shockActionPercent,
  608.                 'shockActionType' => $shockActionType,
  609.             ];
  610.             $priceTotal $productPrice $quantity;
  611.             if ($rebatePercent != && $rebatePercent != null && !$productInfo[$productName]['actionShock'] && $quantity && $checkSpecialDiscount == null && $pourcentNatura == null) {
  612.                 $totalRebate floatval(number_format(($priceTotal 100) * ($rebatePercent + ($isNewRef 0)), 2'.'''));
  613.                 $productInfo[$productName]['priceTotal'] = floatval(number_format($priceTotal $totalRebate2'.'''));
  614.             } elseif ($rebatePercent != && $rebatePercent != null && !$productInfo[$productName]['actionShock'] && $quantity && $checkSpecialDiscount == null && $productInfo[$productName]['brand'] == "NaturaMedicatrix") {
  615.                 $totalRebate floatval(number_format(($priceTotal 100) * ($pourcentNatura +  ($isNewRef 0)), 2'.'''));
  616.                 $productInfo[$productName]['priceTotal'] = floatval(number_format($priceTotal $totalRebate2'.'''));
  617.             } elseif ($rebatePercent != && $rebatePercent != null && $productInfo[$productName]['actionShock'] && $quantity 3) {
  618.                 $totalRebate floatval(number_format(($priceTotal 100) * ($shockActionPercent + ($isNewRef 0)), 2'.'''));
  619.                 $productInfo[$productName]['priceTotal'] = floatval(number_format($priceTotal $totalRebate2'.'''));
  620.             } elseif ($productInfo[$productName]['actionShock'] && $quantity 3) {
  621.                 $totalRebate floatval(number_format(($priceTotal 100) * ($shockActionPercent + ($isNewRef 0)), 2'.'''));
  622.                 $productInfo[$productName]['priceTotal'] = floatval(number_format($priceTotal $totalRebate2'.'''));
  623.             } elseif (!$productInfo[$productName]['actionShock'] && $quantity 11 && $checkSpecialDiscount != null) {
  624.                 $totalRebate floatval(number_format(($priceTotal 100) * ($checkSpecialDiscount->getPourcentRebate() + ($isNewRef 0)), 2'.'''));
  625.                 $productInfo[$productName]['priceTotal'] = floatval(number_format($priceTotal $totalRebate2'.'''));
  626.             } elseif ($quantity && $isNewRef) {
  627.                 $productInfo[$productName]['priceTotal'] = $productPrice $quantity;
  628.                 $rebateNewRef floatval(number_format(($productInfo[$productName]['priceTotal'] / 100) * 22'.'''));
  629.                 $productInfo[$productName]['priceTotal'] = floatval(number_format($productInfo[$productName]['priceTotal'] - $rebateNewRef2'.'''));
  630.             } else {
  631.                 $productInfo[$productName]['priceTotal'] = $productPrice $quantity;
  632.             }
  633.             // Vérifier s'il y a des produits gratuits correspondant au produit actuel
  634.             foreach ($freeProducts as $freeProduct) {
  635.                 if ($freeProduct['name'] === $productName) {
  636.                     $productInfo[$productName]['free'] = $freeProduct['free'];
  637.                 }
  638.             }
  639.         }
  640.         foreach ($lotsOrderedQuantity as $ordered) {
  641.             $lotNumber $this->manager->getRepository(LotNumber::class)->findOneBy([
  642.                 'products' => $ordered['product'],
  643.                 'lotNumber' => $ordered['lot_number'],
  644.                 'depot' => $ordered['depot'],
  645.                 'folderMercator' => $ordered['folderMercator'],
  646.             ]);
  647.             if (!$lotNumber) {
  648.                 continue;
  649.             }
  650.             $lotNumber->setStock($lotNumber->getStock() - $ordered['ordered_quantity']);
  651.             $this->manager->persist($lotNumber);
  652.         }
  653.         $this->manager->flush();
  654.         // Calcul du nombre de flyers (Formule Alcalisante)
  655.         $numberOfFaRef null;
  656.         $countFaInCart 0;
  657.         $flyersProduct $this->manager->getRepository(Products::class)->findOneBy(['reference' => 'NMZZ21']);
  658.         
  659.         // Tableau des références de produits Formule Alcalisante
  660.         $faReference = ['NMJ007''NMJ008''NMJ011''NMJ084''NMJ013''NMJ056''NMJ040'];
  661.         
  662.         // Compte le nombre de Formule Alcalisante
  663.         foreach ($articles as $item) {
  664.             if (in_array($item->getProducts()->getReference(), $faReference)) {
  665.                 $countFaInCart += $item->getQuantity();
  666.             }
  667.         }
  668.         
  669.         // Calcul du nombre de flyers gratuits (1 par 2 FA)
  670.         if ($countFaInCart >= 2) {
  671.             $numberOfFaRef floor($countFaInCart 2);
  672.         }
  673.         
  674.         // Respect de la préférence utilisateur
  675.         if (!$request->getSession()->has('wantFlyers') || !$request->getSession()->get('wantFlyers')) {
  676.             $numberOfFaRef null;
  677.         }
  678.         $shockActionTypes ActionShock::TYPES;
  679.         // Fonction helper pour calculer la hauteur nécessaire pour un texte multicell
  680.         $getMultiCellHeight = function($pdf$w$txt) {
  681.             $cw $pdf->GetStringWidth($txt);
  682.             if ($cw == 0) {
  683.                 return 0;
  684.             }
  685.             
  686.             $ratio $w $cw;
  687.             $lines ceil($ratio);
  688.             return $lines 5// 5 est la hauteur de base d'une ligne
  689.         };
  690.         
  691.         // Affiche les informations dans le PDF
  692.         foreach ($productInfo as $productName => $info) {
  693.             $productRebatePercent $info['rebatePercent'];
  694.             if ($info['actionShock']) {
  695.                 $shockActionName $shockActionTypes[$info['shockActionType']->value];
  696.             }
  697.             if (isset($info['free'])) {
  698.                 if ($info['actionShock']) {
  699.                     $pdf->SetFont('helvetica'''7);
  700.                     $productText $productName ' (' $info['reference'] . ') - ' $shockActionName ' +' $info['free'] . ' gratuits';
  701.                     
  702.                     // Commence une nouvelle ligne
  703.                     $pdf->Ln(0);
  704.                     $x $pdf->GetX();
  705.                     $y $pdf->GetY();
  706.                     
  707.                     // Calcule la hauteur nécessaire pour le texte
  708.                     $height max(5$getMultiCellHeight($pdf50$productText));
  709.                     
  710.                     // Cellule pour le nom du produit avec référence
  711.                     $pdf->MultiCell(50$height$productText1'C');
  712.                     
  713.                     // Repositionne pour les cellules suivantes
  714.                     $pdf->SetXY($x 50$y);
  715.                 } elseif (!$info['actionShock'] && $info['specialDiscount'] != null && $info['quantity'] > 11) {
  716.                     $pdf->SetFont('helvetica'''7);
  717.                     $productText $productName ' (' $info['reference'] . ') - ' 'PROMO « SPECIALE »' ' +' $info['free'] . ' gratuits';
  718.                     
  719.                     // Commence une nouvelle ligne
  720.                     $pdf->Ln(0);
  721.                     $x $pdf->GetX();
  722.                     $y $pdf->GetY();
  723.                     
  724.                     // Calcule la hauteur nécessaire pour le texte
  725.                     $height max(5$getMultiCellHeight($pdf50$productText));
  726.                     
  727.                     // Cellule pour le nom du produit avec référence
  728.                     $pdf->MultiCell(50$height$productText1'C');
  729.                     
  730.                     // Repositionne pour les cellules suivantes
  731.                     $pdf->SetXY($x 50$y);
  732.                 } else {
  733.                     $pdf->SetFont('helvetica'''7);
  734.                     $productText $productName ' (' $info['reference'] . ') +' $info['free'] . ' gratuits';
  735.                     
  736.                     // Commence une nouvelle ligne
  737.                     $pdf->Ln(0);
  738.                     $x $pdf->GetX();
  739.                     $y $pdf->GetY();
  740.                     
  741.                     // Calcule la hauteur nécessaire pour le texte
  742.                     $height max(5$getMultiCellHeight($pdf50$productText));
  743.                     
  744.                     // Cellule pour le nom du produit avec référence
  745.                     $pdf->MultiCell(50$height$productText1'C');
  746.                     
  747.                     // Repositionne pour les cellules suivantes
  748.                     $pdf->SetXY($x 50$y);
  749.                 }
  750.             } else {
  751.                 if ($info['actionShock']) {
  752.                     $pdf->SetFont('helvetica'''7);
  753.                     $productText $productName ' (' $info['reference'] . ') - ' $shockActionName;
  754.                     
  755.                     // Commence une nouvelle ligne
  756.                     $pdf->Ln(0);
  757.                     $x $pdf->GetX();
  758.                     $y $pdf->GetY();
  759.                     
  760.                     // Calcule la hauteur nécessaire pour le texte
  761.                     $height max(5$getMultiCellHeight($pdf50$productText));
  762.                     
  763.                     // Cellule pour le nom du produit avec référence
  764.                     $pdf->MultiCell(50$height$productText1'C');
  765.                     
  766.                     // Repositionne pour les cellules suivantes
  767.                     $pdf->SetXY($x 50$y);
  768.                 } elseif (!$info['actionShock'] && $info['specialDiscount'] != null && $info['quantity'] > 11) {
  769.                     $pdf->SetFont('helvetica'''7);
  770.                     $productText $productName ' (' $info['reference'] . ') - ' 'PROMO « SPECIALE »';
  771.                     
  772.                     // Commence une nouvelle ligne
  773.                     $pdf->Ln(0);
  774.                     $x $pdf->GetX();
  775.                     $y $pdf->GetY();
  776.                     
  777.                     // Calcule la hauteur nécessaire pour le texte
  778.                     $height max(5$getMultiCellHeight($pdf50$productText));
  779.                     
  780.                     // Cellule pour le nom du produit avec référence
  781.                     $pdf->MultiCell(50$height$productText1'C');
  782.                     
  783.                     // Repositionne pour les cellules suivantes
  784.                     $pdf->SetXY($x 50$y);
  785.                 } else {
  786.                     $pdf->SetFont('helvetica'''7);
  787.                     $productText $productName ' (' $info['reference'] . ')';
  788.                     
  789.                     // Commence une nouvelle ligne
  790.                     $pdf->Ln(0);
  791.                     $x $pdf->GetX();
  792.                     $y $pdf->GetY();
  793.                     
  794.                     // Calcule la hauteur nécessaire pour le texte
  795.                     $height max(5$getMultiCellHeight($pdf50$productText));
  796.                     
  797.                     // Cellule pour le nom du produit avec référence
  798.                     $pdf->MultiCell(50$height$productText1'C');
  799.                     
  800.                     // Repositionne pour les cellules suivantes
  801.                     $pdf->SetXY($x 50$y);
  802.                 }
  803.             }
  804.             // Utilise la même hauteur pour les cellules suivantes
  805.             $pdf->Cell(30$height"lot : " $info['noLot'], 10'C');
  806.             $pdf->Cell(30$height$info['price'] . "€"10'C');
  807.             $pdf->Cell(20$height$info['quantity'], 10'C');
  808.             if ($info['specialDiscount'] != null && $info['quantity'] > 11) {
  809.                 $pdf->Cell(30$height$info['specialDiscount']->getPourcentRebate() . '%'10'C');
  810.             } elseif ($info['actionShock'] != null && $info['shockActionPercent']) {
  811.                 $pdf->Cell(30$height, ($info['shockActionPercent'] + ($info['newRef'] ? 0)) . '%'10'C');
  812.             } elseif ($productRebatePercent != 0) {
  813.                 $rebateNatura $this->manager->getRepository(BrandDiscount::class)->findOneBy(array('active' => true'brandName' => 'NaturaMedicatrix'));
  814.                 if ($rebateNatura && $info['brand'] == "NaturaMedicatrix" && $productRebatePercent == 13 && $info['quantity'] > 3) {
  815.                     if ($info['newRef']) {
  816.                         $pdf->Cell(30$height$rebateNatura->getRebateLow() + '%'10'C');
  817.                     } else {
  818.                         $pdf->Cell(30$height$rebateNatura->getRebateLow() . '%'10'C');
  819.                     }
  820.                 } elseif ($rebateNatura && $info['brand'] == "NaturaMedicatrix" && $productRebatePercent == 19 && $info['quantity'] > 3) {
  821.                     if ($info['newRef']) {
  822.                         $pdf->Cell(30$height$rebateNatura->getRebateHeigh() + '%'10'C');
  823.                     } else {
  824.                         $pdf->Cell(30$height$rebateNatura->getRebateHeigh() . '%'10'C');
  825.                     }
  826.                 } elseif ($info['quantity'] > 3) {
  827.                     if ($info['newRef']) {
  828.                         $pdf->Cell(30$height$productRebatePercent '%'10'C');
  829.                     } else {
  830.                         $pdf->Cell(30$height$productRebatePercent '%'10'C');
  831.                     }
  832.                 } elseif ($info['quantity'] > && $info['newRef']) {
  833.                     $pdf->Cell(30$height'2%'10'C');
  834.                 } else {
  835.                     $pdf->Cell(30$height'0' '%'10'C');
  836.                 }
  837.             } elseif ($info['newRef'] && $info['quantity'] > 1) {
  838.                 $pdf->Cell(305'2%'10'C');
  839.             } else {
  840.                 $pdf->Cell(30$height'0'10'C');
  841.             }
  842.             if ($info['newRef']) {
  843.                 $pdf->Cell(30$height$info['priceTotal'] . "€ (-2% inclus)"10'C');
  844.                 $pdf->Ln($height);
  845.             } else {
  846.                 $pdf->Cell(30$height$info['priceTotal'] . "€"10'C');
  847.                 $pdf->Ln($height);
  848.             }
  849.         }
  850.         if ((int)$numberOfFaRef 0) {
  851.             $pdf->SetFont('helvetica'''7);
  852.             $pdf->Cell(505$flyersProduct->getName(), 10'C');
  853.             $pdf->Cell(305"ref : " $flyersProduct->getReference(), 10'C');
  854.             $pdf->Cell(305"0 €"10'C');
  855.             $pdf->Cell(205, (int)$numberOfFaRef10'C');
  856.         }
  857.         $pdf->Ln(5);
  858.         $pdf->Cell(1405""00'C');
  859.         $pdf->Cell(505'Produits HTVA ' $tvaLow '%: ' floatval(number_format($request->query->get('totalPriceProductLowVatHtva'), 2'.''')) . "€"10'L');
  860.         $pdf->Ln(5);
  861.         $pdf->Cell(1405""00'C');
  862.         $pdf->Cell(505'Produits HTVA ' $tvaHigh '%: ' floatval(number_format($request->query->get('totalPriceProductHighVatHtva'), 2'.''')) . "€"10'L');
  863.         $pdf->Ln(5);
  864.         $pdf->Cell(1405""00'C');
  865.         $pdf->Cell(505'Total (HTVA): ' floatval(number_format($request->query->get('totalPriceAllProductHtva'), 2'.''')) . "€"10'L');
  866.         $pdf->Ln(5);
  867.         $pdf->Cell(1405""00'C');
  868.         $pdf->Cell(505'TVA ' $tvaLow '%: ' floatval(number_format($request->query->get('totalPriceProductLowVatTvac'), 2'.''')) . "€"10'L');
  869.         $pdf->Ln(5);
  870.         $pdf->Cell(1405""00'C');
  871.         $pdf->Cell(505'TVA ' $tvaHigh '%: ' floatval(number_format($request->query->get('totalPriceProductHighVatTvac'), 2'.''')) . "€"10'L');
  872.         $pdf->Ln(5);
  873.         if (floatval($request->query->get('totalPriceTvacWithRebate')) < floatval($costDelivery->getFrancoDelivery())) {
  874.             $pdf->Cell(1405""00'C');
  875.             $pdf->Cell(505'Frais livraison : ' $costDelivery->getCostDelivery() . '€'10'L');
  876.             $pdf->Ln(5);
  877.             // Ajout du total
  878.             $totalCost $request->query->get('totalPriceTvacWithRebate') + $costDelivery->getCostDelivery();
  879.             $pdf->SetFont('helvetica''B'12);
  880.             $pdf->Cell(1405'Total TTC'10'C');
  881.             $pdf->Cell(505$totalCost "€"11'C');
  882.         } else {
  883.             // Ajout du total
  884.             $pdf->SetFont('helvetica''B'12);
  885.             $pdf->Cell(1405'Total TTC'10'C');
  886.             $pdf->Cell(505floatval(number_format($request->query->get('totalPriceTvacWithRebate'), 2'.''')) . "€"11'C');
  887.         }
  888.         // Juste avant de sauvegarder ou de sortir le PDF, ajoutez votre pied de page
  889.         $pdf->SetY(-55); // Positionner le curseur 60 mm du bas de la page
  890.         $pdf->SetFont('helvetica'''10);
  891.         $pdf->SetFont('helvetica''B'10); // Gras pour NATURAMedicatrix
  892.         $pdf->Cell(05"NATURAMedicatrix srl"01'C');
  893.         $pdf->SetFont('helvetica'''10); // Normal pour le reste de l'adresse
  894.         $pdf->Cell(05"22, route de Fagnes, B-4190 Ferrières, Belgique"01'C');
  895.         $pdf->Cell(05"TVA BE 0543.862.766"01'C');
  896.         $pdf->Ln(4); // Un peu d'espace avant la prochaine section
  897.         $pdf->SetFont('helvetica''B'10); // Gras pour NATURAMedicatrix
  898.         $pdf->Cell(05"NATURAMedicatrix sàrl"01'C');
  899.         $pdf->SetFont('helvetica'''10); // Normal pour le reste de l'adresse
  900.         $pdf->Cell(05"8 Hannert dem Duarref, L-9772 Troine (Wincrange), Luxembourg -"01'C');
  901.         $pdf->Cell(05"TVA: LU26788281 - MATRICULE:20142414296"01'C');
  902.         // Nom du fichier PDF
  903.         $pdfFilename trim($additionalInformation->getCompanyName()) . '_' trim($user->getId()) . '_' trim(str_replace(' '''$request->query->get('idCommande'))) . '.pdf';
  904.         // Enregistrement du PDF dans le dossier public/factures/
  905.         $pdfPath $this->getParameter('factures_directory') . $pdfFilename;
  906.         $pdf->Output($pdfPath'F');
  907.         $this->createNewBilling($pdfFilename$user$request->query->get('totalPriceTvacWithRebate'), $cartFinished->getCommandDate()->format('d/m/Y'));
  908.         // E-mail du client
  909.         $clientEmail $user->getEmail();
  910.         $email = (new Email())
  911.             ->from('info@b2bnaturamedicatrix.com')
  912.             ->to($clientEmail)
  913.             ->subject('Bon de commande B2B')
  914.             ->text('Veuillez trouver ci-joint le bon de commande en pdf.')
  915.             ->attachFromPath($pdfPath$pdfFilename'application/pdf');
  916.         foreach ($orderRecipientEmails as $recipient) {
  917.             $email->addCc($recipient);
  918.         }
  919.         $mailer->send($email);
  920.         /*
  921.                 try {
  922.                 // DEBUT API ORDER
  923.                    $data = [
  924.                         'headers' => [
  925.                             'Authorization' => 'Bearer ' . $jwtToken,
  926.                         ],
  927.                         'json' => [
  928.                             "customerId" => $additionalInformation->getIdClientMercator(),
  929.                             "reference" => "",
  930.                             "mercator" => $folderMercatorValue,
  931.                             "shippingInfo" => [
  932.                                 "firstName" => $addressDelivery->getFirstName(),
  933.                                 "lastName" => $addressDelivery->getName(),
  934.                                 "company" => $addressDelivery->getCompanyName() != null ? $addressDelivery->getCompanyName() : "",
  935.                                 "address1"=> $addressDelivery->getAddress(),
  936.                                 "address2" => "",
  937.                                 "postalCode" => $addressDelivery->getPostal(),
  938.                                 "city" => $addressDelivery->getTown(),
  939.                                 "phone" => $addressDelivery->getPhoneNumber() != null ? $addressDelivery->getPhoneNumber() : "",
  940.                                 "mobile" => "",
  941.                                 "country" => $countryShip,
  942.                                 "note" => ""
  943.                             ],
  944.                             "lines" => []
  945.                         ]
  946.                     ];
  947.                     foreach ($articles as $article) {
  948.                         $lots = [];
  949.                         foreach ($request->get('lotNumbers') as $lot) {
  950.                             $checkArticle = $this->manager->getRepository(LotNumber::class)->findOneBy(array('lotNumber' => $lot, 'folderMercator' => $folderMercatorValue));
  951.                             $lots[] = $checkArticle;
  952.                         }
  953.                         $lotId = "";
  954.                         foreach ($lots as $lot) {
  955.                             if ($lot->getProducts()->getName() == $article->getProducts()->getName()) {
  956.                                 $lotId = $lot->getIdLotMercator();
  957.                                 $folderMercator = $lot->getFolderMercator();
  958.                             }
  959.                         }
  960.                         // Calcul du discount
  961.                         $discount = 0;
  962.                         $productName = $article->getProducts()->getName();
  963.                         $brandName = null;
  964.                         if (isset($productInfo[$productName])) {
  965.                             $info = $productInfo[$productName];
  966.                             if ($info['specialDiscount'] != null && $info['quantity'] > 11) {
  967.                                 $discount = $info['specialDiscount']->getPourcentRebate();
  968.                             } elseif ($info['actionShock'] != null) {
  969.                                 $actionPourcent = $this->manager->getRepository(ConfigSite::class)->findAll();
  970.                                 $discount = $actionPourcent[0]->getActionShock();
  971.                             } elseif ($defaultRebatePercent != "0" && $info['brand'] != "NaturaMedicatrix" && !$pourcentSpecialCustomer) {
  972.                                 $discount = $defaultRebatePercent;
  973.                             }elseif ($defaultRebatePercent != "0" && $info['brand'] == "NaturaMedicatrix" && !$pourcentSpecialCustomer){
  974.                                 if ($defaultRebatePercent == 13){
  975.                                     $discount = $this->manager->getRepository(BrandDiscount::class)->findOneBy(array('brandName' => 'NaturaMedicatrix'));
  976.                                     $discount = $discount->getRebateLow();
  977.                                 }elseif ($defaultRebatePercent == 19){
  978.                                     $discount = $this->manager->getRepository(BrandDiscount::class)->findOneBy(array('brandName' => 'NaturaMedicatrix'));
  979.                                     $discount = $discount->getRebateHeigh();
  980.                                 }
  981.                             }elseif ($defaultRebatePercent != "0" && $pourcentSpecialCustomer){
  982.                                 $discount = $pourcentSpecialCustomer;
  983.                             }
  984.                         }
  985.                         if ($info['specialDiscount'] != null && $info['quantity'] > 11){
  986.                             $specialPromotion = true;
  987.                         }else{
  988.                             $specialPromotion = false;
  989.                         }
  990.                         $line = [
  991.                             "productId" => strval($article->getProducts()->getIdProductOnMercator()),
  992.                             "quantity" => $article->getQuantity(),
  993.                             "discount" => intval($discount),
  994.                             "lotId" => $lotId,
  995.                             'specialPromotion' => $specialPromotion
  996.                         ];
  997.                         // Ajouter la ligne au tableau "lines" de la requête
  998.                         $data['json']['lines'][] = $line;
  999.                     }
  1000.     //            dd($data);
  1001.                 // Effectuer la requête HTTP avec le tableau $data
  1002.                 $response = $this->client->request('POST', 'https://ns3190747.ip-51-89-219.eu/Order', $data);
  1003.     //                dd($response);
  1004.                 $content = $response->getContent();  // Obtenez le contenu de la réponse
  1005.                 $statusCode = $response->getStatusCode();  // Obtenez le code de statut de la réponse
  1006.                 $datas = json_decode($content, true); // `true` pour obtenir un tableau associatif
  1007.                 ////FIN API ORDER
  1008.                 } catch (\Exception $e) {
  1009.                 } finally {
  1010.                     $this->addFlash('success', 'Commande passée avec succès.');
  1011.                     return new JsonResponse('ok', headers: ['Content-Type' => 'application/json;charset=UTF-8']);
  1012.                 }*/
  1013.         $this->addFlash('success''Commande passée avec succès.');
  1014.         return new JsonResponse('ok'headers: ['Content-Type' => 'application/json;charset=UTF-8']);
  1015.     }
  1016.     private function createNewBilling(string $billingsUser $user$totalPaid$dateOrder): void
  1017.     {
  1018.         $billing = new Billings();
  1019.         $billing->setUser($user);
  1020.         $billing->setBilling($billings);
  1021.         $billing->setTotalPaid($totalPaid);
  1022.         $commandDate \DateTime::createFromFormat('d/m/Y'$dateOrder);
  1023.         if ($commandDate) {
  1024.             $billing->setCommandDate($commandDate);
  1025.         }
  1026.         //        $billing->setCommandDate($dateOrder);
  1027.         $this->manager->persist($billing);
  1028.         $this->manager->flush();
  1029.     }
  1030.     private function checkJokerAvailable($numberItems): bool
  1031.     {
  1032.         $joker $this->manager->getRepository(Joker::class)->findOneBy(array('user' => $this->getUser()));
  1033.         if ($joker) {
  1034.             if ($numberItems <= && $joker->getNumberJoker() > 0) {
  1035.                 return true;
  1036.             } else {
  1037.                 return false;
  1038.             }
  1039.         } else {
  1040.             return false;
  1041.         }
  1042.     }
  1043.     private function checkJokerNumber(): int
  1044.     {
  1045.         $joker $this->manager->getRepository(Joker::class)->findOneBy(array('user' => $this->getUser()));
  1046.         return $joker->getNumberJoker();
  1047.     }
  1048.     private function retrieveCart(): array
  1049.     {
  1050.         $productEligibleReduction null;
  1051.         $freeProduct null;
  1052.         $pourcentSpecialCustomer null;
  1053.         $checkControl $this->manager->getRepository(CustomerControl::class)->findOneBy(array('user' => $this->getUser(), 'finish' => false));
  1054.         if (!$checkControl) {
  1055.             $user $this->getUser();
  1056.             $additionalInformations $this->manager->getRepository(AdditionalCompanyInformation::class)->findOneBy(array('user' => $this->getUser()));
  1057.         } else {
  1058.             $user $checkControl->getCustomer();
  1059.             $additionalInformations $this->manager->getRepository(AdditionalCompanyInformation::class)->findOneBy(array('user' => $checkControl->getCustomer()));
  1060.         }
  1061.         if ($user->getSpecialCustomer()) {
  1062.             $checkUserSpecialEntity $this->manager->getRepository(SpecialCustomer::class)->findOneBy(array('user' => $user'active' => true));
  1063.             if ($checkUserSpecialEntity == null) {
  1064.                 $pourcentSpecialCustomer $this->manager->getRepository(ConfigSite::class)->findAll();
  1065.                 $pourcentSpecialCustomer $pourcentSpecialCustomer[0];
  1066.             } else {
  1067.                 $pourcentSpecialCustomer $checkUserSpecialEntity->getPourcentRebate();
  1068.             }
  1069.         }
  1070.         $cart $this->manager->getRepository(Cart::class)->getAllCart($user);
  1071.         $country $additionalInformations->getCompanyCountry();
  1072.         $folderMercatorValue $country === 'Belgique' 'BE' 'LU';
  1073.         foreach ($cart as &$item) {
  1074.             $product $this->manager->getRepository(Products::class)->find($item['productId']);
  1075.             $dlus $this->manager->getRepository(LotNumber::class)->findBy(['products' => $product'folderMercator' => $folderMercatorValue]);
  1076.             // Convertir la collection en un simple tableau associatif
  1077.             $dlusArray = [];
  1078.             foreach ($dlus as $dlu) {
  1079.                 $dlusArray[] = [
  1080.                     'dlu' => $dlu->getDlu(),
  1081.                     'lotNumber' => $dlu->getLotNumber()
  1082.                     // Ajoutez d'autres propriétés de LotNumber ici si nécessaire
  1083.                     // 'property_name' => $dlu->getPropertyName(),
  1084.                 ];
  1085.             }
  1086.             // Trouver la date la plus lointaine (la plus grande) dans le tableau $dlusArray
  1087.             $maxDlu null;
  1088.             foreach ($dlusArray as $dluItem) {
  1089.                 if ($maxDlu === null || $dluItem['dlu'] > $maxDlu) {
  1090.                     $maxDlu $dluItem['dlu'];
  1091.                     $maxLotNumber $dluItem['lotNumber'];
  1092.                 }
  1093.             }
  1094.             // Mettre à jour le tableau $item avec la date la plus lointaine
  1095.             $item['dlus'] = [
  1096.                 'dlu' => $maxDlu,
  1097.                 'lotNumber' => $maxLotNumber,
  1098.             ];
  1099.             // enlever le commentaire pour avoir toutes les dlus
  1100.             //            $item['dlus'] = $dlusArray;
  1101.         }
  1102.         unset($item); // Dissocier la référence après la boucle foreach
  1103.         $count 0;
  1104.         $grandTotalPrice 0;
  1105.         foreach ($cart as $item) {
  1106.             if (intval($item['totalQuantity']) > 3) {
  1107.                 $productEligibleReduction[] = $item;
  1108.                 $count += $item['totalQuantity'];
  1109.                 $grandTotalPrice += intval($item['price']) * intval($item['totalQuantity']);
  1110.             } else {
  1111.                 $count += $item['totalQuantity'];
  1112.                 $grandTotalPrice += intval($item['price']) * intval($item['totalQuantity']);
  1113.             }
  1114.         }
  1115.         $joker $this->checkJokerAvailable($count);
  1116.         // nous renvoi le % de remise (quantité de produits)
  1117.         $rebate $this->calculateRebate($pourcentSpecialCustomer);
  1118.         $carts $this->calculatePriceHtvaWithRebateEachProduct($cart$rebate);
  1119.         $freeTransport $this->calculateFreeTransport($carts['totalPriceTvacWithRebate']);
  1120.         if ($rebate == null) {
  1121.             $rebate 0;
  1122.         } else {
  1123.             $freeProduct $this->checkFreeProduct($cart);
  1124.         }
  1125.         $count $this->calculateCountItemInCart();
  1126.         return [
  1127.             'carts' => $carts,
  1128.             'rebate' => $rebate,
  1129.             'grandTotalPrice' => $grandTotalPrice,
  1130.             'freeProduct' => $freeProduct,
  1131.             'freeTransport' => $freeTransport,
  1132.             'joker' => $joker,
  1133.             'missingItems' => $count
  1134.         ];
  1135.     }
  1136.     private function calculatePriceHtvaWithRebateEachProduct($cart$rebatePercent)
  1137.     {
  1138.         $carts = [];
  1139.         //        dd($cart);
  1140.         $checkControl $this->manager->getRepository(CustomerControl::class)->findOneBy(array('user' => $this->getUser(), 'finish' => false));
  1141.         if (!$checkControl) {
  1142.             $user $this->getUser();
  1143.             $additionalInformations $this->manager->getRepository(AdditionalCompanyInformation::class)->findOneBy(array('user' => $this->getUser()));
  1144.         } else {
  1145.             $user $checkControl->getCustomer();
  1146.             $additionalInformations $this->manager->getRepository(AdditionalCompanyInformation::class)->findOneBy(array('user' => $checkControl->getCustomer()));
  1147.         }
  1148.         $pourcentActionShock $this->manager->getRepository(ConfigSite::class)->findAll();
  1149.         $pourcentActionShock $pourcentActionShock[0];
  1150.         $pourcentSpecialCustomer null;
  1151.         $jwtToken $this->jwtMercator->getToken()->getContent();
  1152.         try {
  1153.             $response $this->client->request('GET''https://ns3190747.ip-51-89-219.eu/OrderHistory?clientId=' $additionalInformations->getIdClientMercator(), [
  1154.                 'headers' => [
  1155.                     'Authorization' => 'Bearer ' $jwtToken,
  1156.                 ],
  1157.             ]);
  1158.             $content $response->getContent();
  1159.             $content json_decode($contenttrue);
  1160.         } catch (\Exception $e) {
  1161.             $content = [];
  1162.         }
  1163.         // Vérifiez si la décodification a réussi et que le résultat est bien un tableau.
  1164.         if (is_array($content) && !empty($content)) {
  1165.             // Parcourez chaque élément du panier directement.
  1166.             foreach ($cart as $key => &$item) {
  1167.                 // Assurez-vous que $item est un tableau avant de tenter d'accéder à ses éléments.
  1168.                 if (is_array($item) && isset($item['productIdMercator'])) {
  1169.                     // Convertissez totalQuantity en nombre entier car il est stocké comme une chaîne.
  1170.                     $totalQuantity intval($item['totalQuantity']);
  1171.                     // Vérifiez si le productIdMercator de l'élément est dans le tableau $content ET que la quantité est d'au moins 2.
  1172.                     if (!in_array($item['productIdMercator'], $content) && $totalQuantity >= 2) {
  1173.                         // Si productIdMercator n'est pas dans $content et la quantité est >= 2, définissez newRef sur true.
  1174.                         $item['newRef'] = true;
  1175.                     } else {
  1176.                         // Sinon, définissez newRef sur false.
  1177.                         $item['newRef'] = false;
  1178.                     }
  1179.                 }
  1180.             }
  1181.             unset($item); // Détruisez la référence sur le dernier élément pour éviter les problèmes potentiels.
  1182.         }
  1183.         $excludedProducts $this->manager->getRepository(Rebate::class)->getExcludedProducts();
  1184.         $specificRebates $this->manager->getRepository(Rebate::class)->getActiveSpecificRebates();
  1185.         foreach ($cart as $item) {
  1186.             $isNewRef = isset($item['newRef']) && $item['newRef'] ?? false;
  1187.             $productRebatePercent $rebatePercent;
  1188.             $shockActionDiscountPercent 0;
  1189.             if ($item['shockActionDiscountPercent']) {
  1190.                 $shockActionDiscountPercent $item['shockActionDiscountPercent'] ?? 0;
  1191.             }
  1192.             // Vérifier d'abord si le produit a une promotion spéciale
  1193.             $checkProduct $this->manager->getRepository(Products::class)->find($item['productId']);
  1194.             $checkSpecialDiscount $this->manager->getRepository(SpecialDiscount::class)->findOneBy(array('product' => $checkProduct));
  1195.             
  1196.             // Si le produit est dans la liste des exclus mais qu'il a une promotion spéciale
  1197.             // et que sa quantité est inférieure à 12, on le laisse bénéficier de la remise globale
  1198.             if (in_array($item['reference'], $excludedProducts) && 
  1199.                 !($checkSpecialDiscount != null && $item['totalQuantity'] < 12)) {
  1200.                 $productRebatePercent 0;
  1201.             }
  1202.             foreach ($specificRebates as $rebate) {
  1203.                 if (in_array($item['reference'], $rebate->getSpecificProducts()) && $item['totalQuantity'] >= $rebate->getMin()) {
  1204.                     $productRebatePercent $rebate->getPourcentRebate();
  1205.                     break;
  1206.                 }
  1207.             }
  1208.             $item['rebatePercent'] = $productRebatePercent;
  1209.             $checkProduct $this->manager->getRepository(Products::class)->find($item['productId']);
  1210.             $checkSpecialDiscount $this->manager->getRepository(SpecialDiscount::class)->findOneBy(array('product' => $checkProduct));
  1211.             if ($user->getSpecialCustomer()) {
  1212.                 $checkUserSpecialEntity $this->manager->getRepository(SpecialCustomer::class)->findOneBy(array('user' => $user'active' => true));
  1213.                 if ($checkUserSpecialEntity == null) {
  1214.                     $pourcentSpecialCustomer $this->manager->getRepository(ConfigSite::class)->findAll();
  1215.                     $pourcentSpecialCustomer $pourcentSpecialCustomer[0];
  1216.                 } else {
  1217.                     $pourcentSpecialCustomer $checkUserSpecialEntity->getPourcentRebate();
  1218.                 }
  1219.             }
  1220.             // Produits sans promotion spéciale ni action choc
  1221.             if (isset($item['price']) && !$item['actionShock'] && !$checkSpecialDiscount && $pourcentSpecialCustomer == null) {
  1222.                 $totalPriceProduct $item['price'] * $item['totalQuantity'];
  1223.                 if ($item['totalQuantity'] > && $item['brand'] == "NaturaMedicatrix") {
  1224.                     $brandRebate $this->manager->getRepository(BrandDiscount::class)->findOneBy(array('brandName' => 'NaturaMedicatrix''active' => true));
  1225.                     if ($brandRebate) {
  1226.                         $totalPriceProduct $item['price'] * $item['totalQuantity'];
  1227.                         if ($productRebatePercent == 13) {
  1228.                             $totalRebate = ($totalPriceProduct 100) * ($brandRebate->getRebateLow() + ($isNewRef 0));
  1229.                             // override rebate percent if brand rebate
  1230.                             $item['rebatePercent'] = $brandRebate->getRebateLow() + ($isNewRef 0);
  1231.                             $item['totalRebate'] = floatval(number_format($totalRebate2'.'''));
  1232.                             $item['PriceRebateInclude'] = floatval(number_format($totalPriceProduct $item['totalRebate'], 2'.'''));
  1233.                             $item['reductionUniteItem'] = floatval(number_format(($item['price']) - (($item['price'] / 100) * $brandRebate->getRebateLow() + ($isNewRef 0)), 2'.'''));
  1234.                         } elseif ($productRebatePercent == 19) {
  1235.                             $totalRebate = ($totalPriceProduct 100) * ($brandRebate->getRebateHeigh() + ($isNewRef 0));
  1236.                             // override rebate percent if brand rebate
  1237.                             $item['rebatePercent'] = $brandRebate->getRebateHeigh() + ($isNewRef 0);
  1238.                             $item['totalRebate'] = floatval(number_format($totalRebate2'.'''));
  1239.                             $item['PriceRebateInclude'] = floatval(number_format($totalPriceProduct $item['totalRebate'], 2'.'''));
  1240.                             $item['reductionUniteItem'] = floatval(number_format(($item['price']) - (($item['price'] / 100) * ($brandRebate->getRebateHeigh() + ($isNewRef 0))), 2'.'''));
  1241.                         } elseif ($isNewRef && $item['totalQuantity'] > 1) {
  1242.                             $totalRebate = ($totalPriceProduct 100) * 2;
  1243.                             // override rebate percent if brand rebate
  1244.                             $item['rebatePercent'] = 2;
  1245.                             $item['totalRebate'] = floatval(number_format($totalRebate2'.'''));
  1246.                             $item['PriceRebateInclude'] = floatval(number_format($totalPriceProduct $item['totalRebate'], 2'.'''));
  1247.                             $item['reductionUniteItem'] = floatval(number_format(($item['price']) - (($item['price'] / 100) * 2), 2'.'''));
  1248.                         } else {
  1249.                             $item['PriceRebateInclude'] = floatval(number_format($totalPriceProduct2'.'''));
  1250.                             $item['reductionUniteItem'] = $item['price'];
  1251.                         }
  1252.                     } else {
  1253.                         $totalRebate = ($totalPriceProduct 100) * $productRebatePercent;
  1254.                         $item['totalRebate'] = floatval(number_format($totalRebate2'.'''));
  1255.                         $item['PriceRebateInclude'] = floatval(number_format($totalPriceProduct $item['totalRebate'], 2'.'''));
  1256.                         $item['reductionUniteItem'] = floatval(number_format(($item['price']) - (($item['price'] / 100) * $productRebatePercent), 2'.'''));
  1257.                     }
  1258.                 } elseif ($item['totalQuantity'] > 3) {
  1259.                     $totalRebate = ($totalPriceProduct 100) * ($productRebatePercent + ($isNewRef 0));
  1260.                     $item['rebatePercent'] += ($isNewRef 0);
  1261.                     $item['totalRebate'] = floatval(number_format($totalRebate2'.'''));
  1262.                     $item['PriceRebateInclude'] = floatval(number_format($totalPriceProduct $item['totalRebate'], 2'.'''));
  1263.                     $item['reductionUniteItem'] = floatval(number_format(($item['price']) - (($item['price'] / 100) * ($productRebatePercent + ($isNewRef 0))), 2'.'''));
  1264.                 } elseif ($item['totalQuantity'] > && $isNewRef) {
  1265.                     $totalRebate = ($totalPriceProduct 100) * 2;
  1266.                     $item['totalRebate'] = floatval(number_format($totalRebate2'.'''));
  1267.                     $item['PriceRebateInclude'] = floatval(number_format($totalPriceProduct $item['totalRebate'], 2'.'''));
  1268.                     $item['reductionUniteItem'] = floatval(number_format(($item['price']) - (($item['price'] / 100) * 2), 2'.'''));
  1269.                     $item['rebatePercent'] += 2;
  1270.                 } else {
  1271.                     $item['PriceRebateInclude'] = floatval(number_format($totalPriceProduct2'.'''));
  1272.                     $item['reductionUniteItem'] = $item['price'];
  1273.                 }
  1274.             } elseif (isset($item['price']) && $item['actionShock']) {
  1275.                 $totalPriceProduct $item['price'] * $item['totalQuantity'];
  1276.                 $item['rebatePercent'] = $isNewRef 0;
  1277.                 if ($item['totalQuantity'] > 3) {
  1278.                     $item['rebatePercent'] += $shockActionDiscountPercent;
  1279.                 }
  1280.                 $totalRebate = ($totalPriceProduct 100) * $item['rebatePercent'];
  1281.                 $item['totalRebate'] = floatval(number_format($totalRebate2'.'''));
  1282.                 $item['PriceRebateInclude'] = floatval(number_format($totalPriceProduct $item['totalRebate'], 2'.'''));
  1283.                 $item['reductionUniteItem'] = floatval(number_format(($item['price']) - (($item['price'] / 100) * $item['rebatePercent']), 2'.'''));
  1284.             } elseif (isset($item['price']) && !$item['actionShock'] && $checkSpecialDiscount != null) {
  1285.                 // Produits avec promotion spéciale
  1286.                 if ($item['totalQuantity'] > 11) {
  1287.                     // Si la quantité est supérieure à 11, on applique la promotion spéciale (50%)
  1288.                     $totalPriceProduct $item['publicPrice'] * $item['totalQuantity'];
  1289.                     $totalRebate = ($totalPriceProduct 100) * $checkSpecialDiscount->getPourcentRebate();
  1290.                     $item['rebatePercent'] = $checkSpecialDiscount->getPourcentRebate();
  1291.                     $item['totalRebate'] = floatval(number_format($totalRebate2'.'''));
  1292.                     $item['PriceRebateInclude'] = floatval(number_format($totalPriceProduct $item['totalRebate'], 2'.'''));
  1293.                     $item['reductionUniteItem'] = floatval(number_format(($item['publicPrice']) - (($item['publicPrice'] / 100) * floatval(number_format($checkSpecialDiscount->getPourcentRebate(), 2'.'''))), 2'.'''));
  1294.                 } elseif ($productRebatePercent 0) {
  1295.                     // Si la quantité est inférieure à 12 mais qu'une remise globale est applicable
  1296.                     // On applique la remise globale sur ce produit (13% ou 19%)
  1297.                     $totalPriceProduct $item['price'] * $item['totalQuantity'];
  1298.                     $totalRebate = ($totalPriceProduct 100) * ($productRebatePercent + ($isNewRef 0));
  1299.                     $item['rebatePercent'] = $productRebatePercent + ($isNewRef 0);
  1300.                     $item['totalRebate'] = floatval(number_format($totalRebate2'.'''));
  1301.                     $item['PriceRebateInclude'] = floatval(number_format($totalPriceProduct $item['totalRebate'], 2'.'''));
  1302.                     $item['reductionUniteItem'] = floatval(number_format(($item['price']) - (($item['price'] / 100) * ($productRebatePercent + ($isNewRef 0))), 2'.'''));
  1303.                 } else {
  1304.                     // Pas de remise globale applicable, on vérifie les remises de marque
  1305.                     $totalPriceProduct $item['price'] * $item['totalQuantity'];
  1306.                     if ($item['totalQuantity'] > && $item['brand'] == "NaturaMedicatrix") {
  1307.                         $brandRebate $this->manager->getRepository(BrandDiscount::class)->findOneBy(array('brandName' => 'NaturaMedicatrix''active' => true));
  1308.                         if ($brandRebate) {
  1309.                             $totalPriceProduct $item['price'] * $item['totalQuantity'];
  1310.                             if (isset($item['newRef']) && $item['newRef']) {
  1311.                                 $totalRebate = ($totalPriceProduct 100) * ($brandRebate->getRebateLow() + 2);
  1312.                                 $item['totalRebate'] = floatval(number_format($totalRebate2'.'''));
  1313.                                 $item['PriceRebateInclude'] = floatval(number_format($totalPriceProduct $item['totalRebate'], 2'.'''));
  1314.                                 $item['reductionUniteItem'] = floatval(number_format(($item['price']) - (($item['price'] / 100) * ($brandRebate->getRebateLow() + 2)), 2'.'''));
  1315.                             } else {
  1316.                                 $totalRebate = ($totalPriceProduct 100) * $brandRebate->getRebateLow();
  1317.                                 $item['totalRebate'] = floatval(number_format($totalRebate2'.'''));
  1318.                                 $item['PriceRebateInclude'] = floatval(number_format($totalPriceProduct $item['totalRebate'], 2'.'''));
  1319.                                 $item['reductionUniteItem'] = floatval(number_format(($item['price']) - (($item['price'] / 100) * $brandRebate->getRebateHeigh()), 2'.'''));
  1320.                             }
  1321.                             /*if ($realRebate == 13) {
  1322.                                 $totalRebate = ($totalPriceProduct / 100) * $brandRebate->getRebateLow();
  1323.                                 $item['totalRebate'] = floatval(number_format($totalRebate, 2, '.', ''));
  1324.                                 $item['PriceRebateInclude'] = floatval(number_format($totalPriceProduct - $item['totalRebate'], 2, '.', ''));
  1325.                                 $item['reductionUniteItem'] = floatval(number_format(($item['price']) - (($item['price'] / 100) * $brandRebate->getRebateLow()), 2, '.', ''));
  1326.                                 $carts[] = $item;
  1327.                             } elseif ($realRebate == 19) {
  1328.                                 $totalRebate = ($totalPriceProduct / 100) * $brandRebate->getRebateHeigh();
  1329.                                 $item['totalRebate'] = floatval(number_format($totalRebate, 2, '.', ''));
  1330.                                 $item['PriceRebateInclude'] = floatval(number_format($totalPriceProduct - $item['totalRebate'], 2, '.', ''));
  1331.                                 $item['reductionUniteItem'] = floatval(number_format(($item['price']) - (($item['price'] / 100) * $brandRebate->getRebateHeigh()), 2, '.', ''));
  1332.                                 $carts[] = $item;
  1333.                             } else {
  1334.                                 $item['PriceRebateInclude'] = floatval(number_format($totalPriceProduct, 2, '.', ''));
  1335.                                 $carts[] = $item;
  1336.                             }*/
  1337.                         } else {
  1338.                             $totalRebate = ($totalPriceProduct 100) * $productRebatePercent;
  1339.                             $item['totalRebate'] = floatval(number_format($totalRebate2'.'''));
  1340.                             $item['PriceRebateInclude'] = floatval(number_format($totalPriceProduct $item['totalRebate'], 2'.'''));
  1341.                             $item['reductionUniteItem'] = floatval(number_format(($item['price']) - (($item['price'] / 100) * $productRebatePercent), 2'.'''));
  1342.                         }
  1343.                     } else {
  1344.                         $totalRebate = ($totalPriceProduct 100) * $productRebatePercent;
  1345.                         $item['totalRebate'] = floatval(number_format($totalRebate2'.'''));
  1346.                         $item['PriceRebateInclude'] = floatval(number_format($totalPriceProduct $item['totalRebate'], 2'.'''));
  1347.                         $item['reductionUniteItem'] = floatval(number_format(($item['price']) - (($item['price'] / 100) * $productRebatePercent), 2'.'''));
  1348.                     }
  1349.                 }
  1350.             } elseif (isset($item['price']) && $pourcentSpecialCustomer != null) {
  1351.                 $totalPriceProduct $item['publicPrice'] * $item['totalQuantity'];
  1352.                 if ($item['totalQuantity'] > 11) {
  1353.                     $totalRebate = ($totalPriceProduct 100) * $checkSpecialDiscount->getPourcentRebate();
  1354.                     $item['totalRebate'] = floatval(number_format($totalRebate2'.'''));
  1355.                     $item['PriceRebateInclude'] = floatval(number_format($totalPriceProduct $item['totalRebate'], 2'.'''));
  1356.                     $item['reductionUniteItem'] = floatval(number_format(($item['publicPrice']) - (($item['publicPrice'] / 100) * floatval(number_format($pourcentSpecialCustomer->getPourcentSpecialCustomer(), 2'.'''))), 2'.'''));
  1357.                 } else {
  1358.                     $totalPriceProduct $item['price'] * $item['totalQuantity'];
  1359.                     if ($item['totalQuantity'] > 3) {
  1360.                         $totalRebate = ($totalPriceProduct 100) * $productRebatePercent;
  1361.                         $item['totalRebate'] = floatval(number_format($totalRebate2'.'''));
  1362.                         $item['PriceRebateInclude'] = floatval(number_format($totalPriceProduct $item['totalRebate'], 2'.'''));
  1363.                         $item['reductionUniteItem'] = floatval(number_format(($item['price']) - (($item['price'] / 100) * $productRebatePercent), 2'.'''));
  1364.                     } else {
  1365.                         $item['PriceRebateInclude'] = floatval(number_format($totalPriceProduct2'.'''));
  1366.                         $item['reductionUniteItem'] = $item['price'];
  1367.                     }
  1368.                 }
  1369.             }
  1370.             $carts[] = $item;
  1371.         }
  1372.         //        $this->applyDiscountOnNewRefItems($carts);
  1373.         //        dd($carts);
  1374.         $carts $this->groupItemWithVat($carts$user);
  1375.         return $carts;
  1376.     }
  1377.     private function groupItemWithVat($carts$user)
  1378.     {
  1379.         $tvaLow 0;
  1380.         $tvaHigh 0;
  1381.         $productsLowTva 0;
  1382.         $productsHighTva 0;
  1383.         $checkControl $this->manager->getRepository(CustomerControl::class)->findOneBy(array('user' => $this->getUser(), 'finish' => false));
  1384.         if (!$checkControl) {
  1385.             $user $this->getUser();
  1386.             $additionalInformation $this->manager->getRepository(AdditionalCompanyInformation::class)->findOneBy(array('user' => $this->getUser()));
  1387.         } else {
  1388.             $user $checkControl->getCustomer();
  1389.             $additionalInformation $this->manager->getRepository(AdditionalCompanyInformation::class)->findOneBy(array('user' => $checkControl->getCustomer()));
  1390.         }
  1391.         //        $additionalInformation = $this->manager->getRepository(AdditionalCompanyInformation::class)->findOneBy(array('user' => $user));
  1392.         // Determine country-specific VAT rates and which product VAT field to use
  1393.         $vatField null;
  1394.         if ($additionalInformation->getCompanyCountry() == 'Belgique') {
  1395.             $tvaLow 6;
  1396.             $tvaHigh 21;
  1397.             $vatField 'tvaBe';
  1398.         } elseif ($additionalInformation->getCompanyCountry() == 'France') {
  1399.             $tvaLow 5.5;
  1400.             $tvaHigh 20;
  1401.             $vatField 'tvaFr';
  1402.         } elseif ($additionalInformation->getCompanyCountry() == 'Luxembourg') {
  1403.             $tvaLow 3;
  1404.             $tvaHigh 17;
  1405.             $vatField 'tvaLu';
  1406.         }
  1407.         foreach ($carts as $item) {
  1408.             // Ensure we have the computed HTVA with all discounts applied
  1409.             if (!isset($item['PriceRebateInclude'])) {
  1410.                 continue;
  1411.             }
  1412.             $productVat = isset($item[$vatField]) ? $item[$vatField] : null;
  1413.             if ($productVat == $tvaLow) {
  1414.                 $productsLowTva += $item['PriceRebateInclude'];
  1415.             } else {
  1416.                 $productsHighTva += $item['PriceRebateInclude'];
  1417.             }
  1418.         }
  1419.         $carts['TotalPriceProductLowVatHtva'] = $productsLowTva;
  1420.         $carts['TotalPriceProductHighVatHtva'] = $productsHighTva;
  1421.         $carts $this->calculateTvaOnEachProduct($carts$additionalInformation);
  1422.         return $carts;
  1423.     }
  1424.     private function calculateTvaOnEachProduct($carts$additionalInformation)
  1425.     {
  1426.         $tvaLow 0;
  1427.         $tvaHigh 0;
  1428.         if ($additionalInformation->getCompanyCountry() == 'Belgique') {
  1429.             $tvaLow 6;
  1430.             $tvaHigh 21;
  1431.         } elseif ($additionalInformation->getCompanyCountry() == 'France') {
  1432.             $tvaLow 5.5;
  1433.             $tvaHigh 20;
  1434.         } elseif ($additionalInformation->getCompanyCountry() == 'Luxembourg') {
  1435.             $tvaLow 3;
  1436.             $tvaHigh 17;
  1437.         }
  1438.         $carts['TotalPriceProductLowVatTvac'] = floatval(number_format(($carts['TotalPriceProductLowVatHtva'] / 100) * $tvaLow2'.'''));
  1439.         $carts['TotalPriceProductHighVatTvac'] = floatval(number_format(($carts['TotalPriceProductHighVatHtva'] / 100) * $tvaHigh2'.'''));
  1440.         $carts['totalPriceAllProductHtva'] = floatval(number_format($carts['TotalPriceProductLowVatHtva'] + $carts['TotalPriceProductHighVatHtva'], 2'.'''));
  1441.         $carts['totalPriceTvacWithRebate'] = floatval(number_format($carts['TotalPriceProductLowVatHtva'] + $carts['TotalPriceProductHighVatHtva'] + $carts['TotalPriceProductLowVatTvac'] + $carts['TotalPriceProductHighVatTvac'], 2'.'''));
  1442.         return $carts;
  1443.     }
  1444.     private function calculateCountItemInCart()
  1445. {
  1446.     $checkControl $this->manager->getRepository(CustomerControl::class)->findOneBy(array('user' => $this->getUser(), 'finish' => false));
  1447.     if (!$checkControl) {
  1448.         $user $this->getUser();
  1449.     } else {
  1450.         $user $checkControl->getCustomer();
  1451.     }
  1452.     $carts $this->manager->getRepository(Cart::class)->getUserPendingItems($user);
  1453.     $excludedProducts $this->manager->getRepository(Rebate::class)->getExcludedProducts();
  1454.     $count 0;
  1455.     foreach ($carts as $item) {
  1456.         if (in_array($item->getProducts()->getReference(), $excludedProducts)) {
  1457.             continue;
  1458.         }
  1459.         $count += $item->getQuantity();
  1460.     }
  1461.     return $count;
  1462. }    
  1463.     private function calculateRebate($pourcentSpecialCustomer): float|int
  1464.     {
  1465.         $checkControl $this->manager->getRepository(CustomerControl::class)->findOneBy(array('user' => $this->getUser(), 'finish' => false));
  1466.         if (!$checkControl) {
  1467.             $user $this->getUser();
  1468.         } else {
  1469.             $user $checkControl->getCustomer();
  1470.         }
  1471.         $rebates $this->manager->getRepository(Rebate::class)->getActiveNormalRebates();
  1472.         $carts $this->manager->getRepository(Cart::class)->getUserPendingItems($user);
  1473.         $excludedProducts $this->manager->getRepository(Rebate::class)->getExcludedProducts();
  1474.         // Initialiser le compteur total d'articles
  1475.         $count 0;
  1476.         $productCounts = [];
  1477.         
  1478.         // Première passe : compter les produits avec promotion spéciale
  1479.         foreach ($carts as $item) {
  1480.             $productRef $item->getProducts()->getReference();
  1481.             $quantity $item->getQuantity();
  1482.             
  1483.             // Vérifier si le produit a une promotion spéciale
  1484.             $checkSpecialDiscount $this->manager->getRepository(SpecialDiscount::class)->findOneBy(array('product' => $item->getProducts()));
  1485.             
  1486.             if (!isset($productCounts[$productRef])) {
  1487.                 $productCounts[$productRef] = [
  1488.                     'quantity' => 0,
  1489.                     'hasSpecialDiscount' => ($checkSpecialDiscount != null)
  1490.                 ];
  1491.             }
  1492.             $productCounts[$productRef]['quantity'] += $quantity;
  1493.         }
  1494.         
  1495.         // Deuxième passe : calculer le total d'articles pour la remise globale
  1496.         foreach ($carts as $item) {
  1497.             $productRef $item->getProducts()->getReference();
  1498.             
  1499.             // Si le produit est dans la liste des exclusions
  1500.             if (in_array($productRef$excludedProducts)) {
  1501.                 // Cas 1: Si c'est un produit exclu sans promotion spéciale - COMPTER DANS LA REMISE 13% 19%
  1502.                 // On ne fait rien de spécial, on laisse passer pour le comptage en bas
  1503.                 
  1504.                 // Cas 2: Si c'est un produit exclu avec promotion spéciale et quantité >=12 - NE PAS compter DANS LA REMISE 13% 19%
  1505.                 if ($productCounts[$productRef]['hasSpecialDiscount'] && $productCounts[$productRef]['quantity'] >= 12) {
  1506.                     continue;
  1507.                 }
  1508.                 
  1509.                 // Cas 3: Si c'est un produit exclu avec promotion spéciale et quantité <12 - COMPTER DANS LA REMISE 13% 19%
  1510.                 // Cette ligne ne fait rien car on va passer au comptage par défaut en dessous
  1511.             } else {
  1512.                 // Produits non-exclus: Toujours compter (pas de condition spéciale)
  1513.             }
  1514.             
  1515.             // Pour tous les autres produits, ajouter leur quantité au compteur
  1516.             $count += $item->getQuantity();
  1517.         }
  1518.         $reduction 0;
  1519.         if ($pourcentSpecialCustomer != null) {
  1520.             if ($count >= 12) {
  1521.                 if (is_float($pourcentSpecialCustomer) || is_int($pourcentSpecialCustomer)) {
  1522.                     $reduction $pourcentSpecialCustomer;
  1523.                 } else {
  1524.                     $reduction $pourcentSpecialCustomer->getPourcentSpecialCustomer() ?? 0;
  1525.                 }
  1526.             }
  1527.         } else {
  1528.             foreach ($rebates as $rebate) {
  1529.                 if ($count >= $rebate->getMin()) {
  1530.                     $reduction $rebate->getPourcentRebate() ?? 0;
  1531.                     break;
  1532.                 }
  1533.             }
  1534.         }
  1535.         return (float) $reduction;
  1536.     }
  1537.     private function checkFreeProduct($cart): array
  1538.     {
  1539.         $countFreeProduct = [];
  1540.         $index 0;
  1541.         foreach ($cart as $item) {
  1542.             if (isset($item['totalQuantity']) && $item['totalQuantity'] >= 36) {
  1543.                 $countFreeProduct[$index]['free'] = floor($item['totalQuantity'] / 36);
  1544.                 $countFreeProduct[$index]['name'] = $item['name'];
  1545.             }
  1546.             $index++;
  1547.         }
  1548.         return $countFreeProduct;
  1549.     }
  1550.     #[Route('/cart/toggle-flyers'name'toggleFlyers')]
  1551.     public function toggleFlyers(Request $request): Response
  1552.     {
  1553.         // Inverser la valeur actuelle (true par défaut)
  1554.         $currentValue $request->getSession()->get('wantFlyers'true);
  1555.         $request->getSession()->set('wantFlyers', !$currentValue);
  1556.         
  1557.         return $this->redirectToRoute('cartView');
  1558.     }
  1559.     private function calculateFreeTransport($totalPrice): bool
  1560.     {
  1561.         $franco $this->manager->getRepository(ConfigSite::class)->findAll();
  1562.         if ($totalPrice >= $franco[0]->getFrancoDelivery()) {
  1563.             return true;
  1564.         } else {
  1565.             return false;
  1566.         }
  1567.     }
  1568.     #[Route('/cart/remove/product/{productID}'name'cartRemoveProduct')]
  1569.     public function removeProductFromCart($productID): RedirectResponse
  1570.     {
  1571.         $checkControl $this->manager->getRepository(CustomerControl::class)->findOneBy(array('user' => $this->getUser(), 'finish' => false));
  1572.         if (!$checkControl) {
  1573.             $user $this->getUser();
  1574.         } else {
  1575.             $user $checkControl->getCustomer();
  1576.         }
  1577.         $product $this->manager->getRepository(Products::class)->find($productID);
  1578.         $products $this->manager->getRepository(Cart::class)->findBy(array('user' => $user'finish' => false'products' => $product));
  1579.         foreach ($products as $item) {
  1580.             $this->manager->remove($item);
  1581.             $this->manager->flush();
  1582.         }
  1583.         return $this->redirectToRoute('cartView');
  1584.     }
  1585. }