src/Controller/SimulateurController.php line 98

Open in your IDE?
  1. <?php
  2. namespace App\Controller;
  3. use Dompdf\Dompdf;
  4. use Dompdf\Options;
  5. use App\Entity\Pays;
  6. use App\Entity\Zone;
  7. use App\Entity\Annee;
  8. use App\Entity\Frais;
  9. use App\Entity\Tarif;
  10. use App\Entity\Assurance;
  11. use App\Entity\TypeTarifs;
  12. use App\Entity\Restriction;
  13. use App\Entity\FournitureItem;
  14. use App\Service\BandeauService;
  15. use App\Entity\QuantiteBouteille;
  16. use App\Service\CalculTaxeService;
  17. use App\Entity\FournitureCategorie;
  18. use App\Entity\ZoneDepartementsPoids;
  19. use Doctrine\ORM\EntityManagerInterface;
  20. use PhpOffice\PhpSpreadsheet\Style\Fill;
  21. use PhpOffice\PhpSpreadsheet\Spreadsheet;
  22. use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
  23. use PhpOffice\PhpSpreadsheet\Style\Border;
  24. use PhpOffice\PhpSpreadsheet\Style\Alignment;
  25. use Symfony\Component\HttpFoundation\Request;
  26. use Symfony\Component\HttpFoundation\Response;
  27. use Symfony\Component\Routing\Annotation\Route;
  28. use Symfony\Component\HttpFoundation\JsonResponse;
  29. use Symfony\Component\HttpFoundation\StreamedResponse;
  30. use Symfony\Component\HttpFoundation\ResponseHeaderBag;
  31. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  32. class SimulateurController extends AbstractController
  33. {
  34.     private $zoneRepository;
  35.     private $paysRepository;
  36.     private $anneeRepository;
  37.     private $fraisRepository;
  38.     private $tarifRepository;
  39.     private $assuranceRepository;
  40.     private $typeTarifsRepository;
  41.     private $restrictionRepository;
  42.     private $fournitureItemRepository;
  43.     private $quantiteBouteilleRepository;
  44.     private $fournitureCategorieRepository;
  45.     private $montantDeliveredDutyPaid;
  46.     private $ZoneDepartementsPoidsRepository;
  47.     private $aRoyaumeUniId;
  48.     private $aSuisseId;
  49.     private $aNorvegeId;
  50.     private $aAustralieId;
  51.     private $aNouvelleZelandeId;
  52.     private $aSingapourId;
  53.     private $aCoreeSudId;
  54.     private $aJaponId;
  55.     private $aTaiwanId;
  56.     private $bandeauService;
  57.     private $calculTaxeService;
  58.     private $paysTaxeNonDispo;
  59.     public function __construct(EntityManagerInterface $entityManagerCalculTaxeService $calculTaxeServiceBandeauService $bandeauService)
  60.     {
  61.         $this->montantDeliveredDutyPaid 19;
  62.         $this->calculTaxeService $calculTaxeService;
  63.         $this->zoneRepository $entityManager->getRepository(Zone::class);
  64.         $this->paysRepository $entityManager->getRepository(Pays::class);
  65.         $this->anneeRepository $entityManager->getRepository(Annee::class);
  66.         $this->fraisRepository $entityManager->getRepository(Frais::class);
  67.         $this->tarifRepository $entityManager->getRepository(Tarif::class);
  68.         $this->assuranceRepository $entityManager->getRepository(Assurance::class);
  69.         $this->typeTarifsRepository $entityManager->getRepository(TypeTarifs::class);
  70.         $this->restrictionRepository $entityManager->getRepository(Restriction::class);
  71.         $this->fournitureItemRepository $entityManager->getRepository(FournitureItem::class);
  72.         $this->quantiteBouteilleRepository $entityManager->getRepository(QuantiteBouteille::class);
  73.         $this->fournitureCategorieRepository $entityManager->getRepository(FournitureCategorie::class);
  74.         $this->ZoneDepartementsPoidsRepository $entityManager->getRepository(ZoneDepartementsPoids::class);
  75.         $this->aRoyaumeUniId = [303132];
  76.         $this->aSuisseId = [92];
  77.         $this->aNorvegeId = [33];
  78.         $this->aAustralieId = [51];
  79.         $this->aNouvelleZelandeId = [57];
  80.         $this->aSingapourId = [58];
  81.         $this->aCoreeSudId = [52];
  82.         $this->aJaponId = [55];
  83.         $this->aTaiwanId = [38];
  84.         $this->aUSAParticulier = [34];
  85.         $this->bandeauService $bandeauService;
  86.         $this->paysTaxeNonDispo = ["Guadeloupe""Martinique""Afrique du sud""Quebec""Ontario""Manitoba""Colombie Britanique""Alberta""Autres provinces""Hong Kong"];
  87.     }
  88.     /**
  89.      * @Route("/simulateur", name="app_simulateur")     
  90.      */
  91.     public function index(Request $request): Response
  92.     {
  93.         $user $this->getUser();
  94.         // Vérifier si l'utilisateur est authentifié
  95.         if (!$user) {
  96.             return $this->redirectToRoute('login');
  97.         }
  98.         if ($this->isGranted('ROLE_ADMIN')) {
  99.             return $this->redirectToRoute('app_admin_index');
  100.         }
  101.         // Récupérer l'année en cours
  102.         $currentYear = (int)date('Y');
  103.         // Récupération des données
  104.         $zones $this->zoneRepository->findZonesForCurrentYear();
  105.         return $this->render('simulateur/newSimulateur.html.twig', [
  106.             'controller_name' => 'SimulateurController',
  107.             'user' => $user,
  108.             'zones' => $zones,
  109.             'currentYear' => $currentYear,
  110.             'bandeau' => $this->bandeauService->displayPopup()
  111.         ]);
  112.     }
  113.     /**
  114.      * @Route("/get_construct_simulateur/{id}", name="get_construct_simulateur", methods={"GET"})
  115.      */
  116.     public function getConstructSimulateur(Pays $paysEntityManagerInterface $entityManager): Response
  117.     {
  118.         $user $this->getUser();
  119.         // Vérifier si l'utilisateur est authentifié
  120.         if (!$user) {
  121.             return $this->redirectToRoute('login');
  122.         }
  123.         // Si le pays n'est pas trouvé, retourner une réponse 404
  124.         if (!$pays) {
  125.             return new Response("Pays non trouvé"Response::HTTP_NOT_FOUND);
  126.         }
  127.         $zone $pays->getZone();
  128.         $isUsa $zone->isIsUsa();
  129.         // Récupération des assurances
  130.         $assuranceDeBase =  $this->assuranceRepository->findOneByAssuranceBase(true);
  131.         $assurances $this->assuranceRepository->findAll();
  132.         // On récupère les emballages (si c'est une zone boolean USA alors il faut afficher uniquement les emballages compatible USA)
  133.         $emballages null;
  134.         if ($isUsa == null or $isUsa == 0) {
  135.             $emballages $this->fournitureCategorieRepository->findAll();
  136.         } else {
  137.             $emballages $this->fournitureCategorieRepository->findByCompatibleUsa(true);
  138.         }
  139.         $caisseEnBois true;
  140.         // On test si la zone ne peut pas envoyer de caisse en bois en option
  141.         if ($zone->getCaisseBoisMontantBouteilleSix() == null) {
  142.             $caisseEnBois false;
  143.         }
  144.         $typesTarifs $zone->getTypeTarifs();
  145.         // dd($typesTarifs);
  146.         $frais $zone->getFrais();
  147.         $paletteDispo false;
  148.         if ($pays->getNom() == "France") {
  149.             $paletteDispo true;
  150.         }
  151.         // //2025 : on regarde la première valeur de typetarif et on check si elle doit afficher 
  152.         // $displayCaissesPalettes = false;
  153.         // if ($typesTarifs->first()->isDisplayOptionsCaissesPalettes() == true) {
  154.         //     $displayCaissesPalettes = true;
  155.         // }
  156.         // Rendre un template partiel avec les informations du pays
  157.         return $this->render('simulateur/_show_simulateur.html.twig', [
  158.             'pays' => $pays,
  159.             'typesTarifs' => $typesTarifs,
  160.             'emballages' => $emballages,
  161.             'frais' => $frais,
  162.             'caisseEnBois' => $caisseEnBois,
  163.             'assuranceDeBase' => $assuranceDeBase,
  164.             'assurances' => $assurances,
  165.             'paletteDispo' => $paletteDispo,
  166.             // 'displayCaissesPalettes' => $displayCaissesPalettes
  167.         ]);
  168.     }
  169.     /**
  170.      * @Route("/calc_simulateur/{id}", name="calc_simulateur", methods={"POST"})
  171.      */
  172.     public function calcSimulateur(Request $requestPays $pays): Response
  173.     {
  174.         $user $this->getUser();
  175.         // Vérifier si l'utilisateur est authentifié
  176.         if (!$user) {
  177.             return $this->redirectToRoute('login');
  178.         }
  179.         // Si le pays n'est pas trouvé, retourner une réponse 404
  180.         if (!$pays) {
  181.             return new Response("Pays non trouvé"Response::HTTP_NOT_FOUND);
  182.         }
  183.         // Récupérer et décoder les données JSON envoyées
  184.         $data json_decode($request->getContent(), true);
  185.         // Assurez-vous que les données sont valides
  186.         if (!isset($data['recap']) || !is_array($data['recap'])) {
  187.             return new JsonResponse(['error' => 'Invalid data'], 400);
  188.         }
  189.         $aReturnDonnee $this->genereAllCalc($data$pays);
  190.         $taxePasDispo false;
  191.         if (in_array($pays->getNom(), $this->paysTaxeNonDispo)) {
  192.             $taxePasDispo true;
  193.         }
  194.         $usaParticulier false;
  195.         if ($pays->getNom() == "Etats-Unis vers particuliers") {
  196.             $usaParticulier true;
  197.         }
  198.         $montantTransport $aReturnDonnee["montantTransport"];
  199.         $montantEmballage $aReturnDonnee["montantEmballage"];
  200.         $montantAssurance $aReturnDonnee["montantAssurance"];
  201.         $montantTaxe $aReturnDonnee["montantTaxe"];
  202.         $montantOptions $aReturnDonnee["montantOptions"];
  203.         $montantCaisseEnBois $aReturnDonnee["montantCaisseEnBois"];
  204.         $montantSurPalette $aReturnDonnee["montantSurPalette"];
  205.         $montantTotal $aReturnDonnee["montantTotal"];
  206.         $isAssujettiTva $aReturnDonnee["isAssujettiTva"];
  207.         $errors $aReturnDonnee["errors"];
  208.         return $this->render('simulateur/_affichage_complet_simulateur.html.twig', [
  209.             'montantTransport' => $montantTransport,
  210.             'montantEmballage' => $montantEmballage,
  211.             'montantAssurance' => $montantAssurance,
  212.             'montantTaxe' => $montantTaxe,
  213.             'montantOptions' => $montantOptions,
  214.             'montantCaisseEnBois' => $montantCaisseEnBois,
  215.             'montantSurPalette' => $montantSurPalette,
  216.             'montantTotal' => $montantTotal,
  217.             'isAssujettiTva' => $isAssujettiTva,
  218.             'errors' => $errors,
  219.             'taxePasDispo' => $taxePasDispo,
  220.             'usaParticulier' => $usaParticulier
  221.         ]);
  222.     }
  223.     /**
  224.      * @Route("/generate-pdf/{id}", name="generate_pdf_simu", methods={"POST"})
  225.      */
  226.     public function generatePdf(Request $requestPays $pays): Response
  227.     {
  228.         $user $this->getUser();
  229.         // Vérifier si l'utilisateur est authentifié
  230.         if (!$user) {
  231.             return $this->redirectToRoute('login');
  232.         }
  233.         // Si le pays n'est pas trouvé, retourner une réponse 404
  234.         if (!$pays) {
  235.             return new Response("Pays non trouvé"Response::HTTP_NOT_FOUND);
  236.         }
  237.         // Récupérer et décoder les données JSON envoyées
  238.         $data json_decode($request->getContent(), true);
  239.         // Assurez-vous que les données sont valides
  240.         if (!isset($data['recap']) || !is_array($data['recap'])) {
  241.             return new JsonResponse(['error' => 'Invalid data'], 400);
  242.         }
  243.         $aReturnDonnee $this->genereAllCalc($data$pays);
  244.         $assuranceDeBase =  $this->assuranceRepository->findOneByAssuranceBase(true);
  245.         // On récupére le total des bouteilles
  246.         $totalBottles $this->calculateTotalBottles($data['recap']);
  247.         $volumeBottles $this->calculateVolumeBottles($data['recap']);
  248.         $taxePasDispo false;
  249.         if (in_array($pays->getNom(), $this->paysTaxeNonDispo)) {
  250.             $taxePasDispo true;
  251.         }
  252.         $usaParticulier false;
  253.         if ($pays->getNom() == "Etats-Unis vers particuliers") {
  254.             $usaParticulier true;
  255.         }
  256.         // Créer une instance Dompdf
  257.         $options = new Options();
  258.         $options->set('defaultFont''Arial');
  259.         $options->set('isRemoteEnabled'true);
  260.         $options->set('enable_html5_parser'true);
  261.         $dompdf = new Dompdf($options);
  262.         // Récupérer les données de la page
  263.         $html $this->renderView('pdf/export_simulateur.html.twig', [
  264.             'pays' => $pays->getNom(),
  265.             'montantTransport' => $aReturnDonnee['montantTransport'],
  266.             'montantEmballage' => $aReturnDonnee['montantEmballage'],
  267.             'montantAssurance' => $aReturnDonnee['montantAssurance'],
  268.             'montantTaxe' => $aReturnDonnee['montantTaxe'],
  269.             'montantValeur' => $aReturnDonnee['montantValeur'],
  270.             'montantOptions' => $aReturnDonnee['montantOptions'],
  271.             'montantCaisseEnBois' => $aReturnDonnee['montantCaisseEnBois'],
  272.             'montantTotal' => $aReturnDonnee['montantTotal'],
  273.             'isAssujettiTva' => $aReturnDonnee['isAssujettiTva'],
  274.             'errors' => $aReturnDonnee['errors'],
  275.             'montantSurPalette' => $aReturnDonnee['montantSurPalette'],
  276.             'nomAssurrance' => $aReturnDonnee['nomAssurrance'],
  277.             'nomEmballage' => $aReturnDonnee['nomEmballage'],
  278.             'totalBottles' => $totalBottles,
  279.             'volumeBottles' => $volumeBottles,
  280.             'assuranceDeBase' => $assuranceDeBase,
  281.             'assuranceComp' => $aReturnDonnee["assuranceComp"],
  282.             'nomLivraison' => $aReturnDonnee["nomLivraison"],
  283.             'descLivraison' => $aReturnDonnee["descLivraison"],
  284.             'poidsSurPalette' => $aReturnDonnee["poidsSurPalette"],
  285.             'departementSurPalettetext' => $aReturnDonnee["departementSurPalettetext"],
  286.             'taxePasDispo' => $taxePasDispo,
  287.             'usaParticulier' => $usaParticulier
  288.         ]);
  289.         // Charger le HTML dans Dompdf
  290.         $dompdf->loadHtml($html);
  291.         // (Facultatif) Définir les dimensions du papier
  292.         $dompdf->setPaper('A4''portrait');
  293.         // Générer le PDF
  294.         $dompdf->render();
  295.         // Retourner le PDF sous forme de réponse HTTP
  296.         return new Response($dompdf->output(), 200, [
  297.             'Content-Type' => 'application/pdf',
  298.             'Content-Disposition' => 'inline; filename="page.pdf"',
  299.         ]);
  300.     }
  301.     public function genereAllCalc($data$pays)
  302.     {
  303.         // On récupère la zone
  304.         $zone $pays->getZone();
  305.         // On récupère le boolean pour assujetti à la tva ou non
  306.         $isAssujettiTva $zone->isAssujettiTva();
  307.         $errors = array();
  308.         $recap $data['recap']; // Tableau des volumes et quantités
  309.         $checkedAssurances $data['checkedAssurances']; // Tableau récap des assurances check
  310.         $checkedEmballages $data['checkedEmballages']; // Tableau récap des emballages check
  311.         $checkedLivraisons $data['checkedLivraisons']; // Tableau récap des livraisons check
  312.         $checkedDeliveredDutyPaid $data['checkedDeliveredDutyPaid']; // // Check option DDP
  313.         $checkedCaisseEnBois $data['checkedCaisseEnBois']; // Check option caisse en bois
  314.         $checkedSurPalette $data['checkedSurPalette']; // Check option sur palette
  315.         $montantValeur $data['montantValeur'];
  316.         $poidsSurPalette $data['poidsSurPalette']; //poids palette
  317.         $departementSurPalette $data['departementSurPalette']; //département palette
  318.         $departementSurPalettetext $data['departementSurPalettetext']; //département palette text
  319.         $montantTransport 0;
  320.         $montantEmballage 0;
  321.         $montantAssurance 0;
  322.         $montantTaxe 0;
  323.         $montantOptions 0;
  324.         $montantCaisseEnBois 0;
  325.         $montantSurPalette 0;
  326.         $montantTotal null;
  327.         // Espace variables pour PDF
  328.         $nomAssurrance "";
  329.         $nomEmballage "";
  330.         $assuranceComp "";
  331.         $nomLivraison "";
  332.         $descLivraison "";
  333.         // On récupére le total des bouteilles
  334.         $calculateTotalBottles $this->calculateTotalBottles($recap);
  335.         if (!empty($checkedEmballages)) {
  336.             $emballageIdFront $checkedEmballages[0];
  337.             $emballageChoisi $this->fournitureCategorieRepository->findOneById($emballageIdFront);
  338.             // var_dump($emballageIdFront);
  339.             // exit();
  340.             // Trier par nbBouteille
  341.             $itemsByNbBouteille $this->fournitureItemRepository->findPartByCategorieAndNbBouteilleDesc($emballageIdFront);
  342.             // Trier par nbMagnum
  343.             $itemsByNbMagnum $this->fournitureItemRepository->findPartByCategorieAndNbMagnumDesc($emballageIdFront);
  344.             // Trier par nbJeroboam
  345.             $itemsByNbJeroboam $this->fournitureItemRepository->findPartByCategorieAndNbJeroboamDesc($emballageIdFront);
  346.             $tableauReturnTarifs $this->calculateTarifs($recap$itemsByNbBouteille$itemsByNbMagnum$itemsByNbJeroboam);
  347.             // echo '<pre>';
  348.             // var_dump($tableauReturnTarifs);
  349.             // echo '</pre>';            
  350.             // exit();
  351.             $montantEmballage $tableauReturnTarifs['montant_total'];
  352.             $nomEmballage $emballageChoisi->getTitre() . ' - ' $emballageChoisi->getSousTitre() . ' - ' $emballageChoisi->getMarque();
  353.         }
  354.         $zone $pays->getZone();
  355.         if (!empty($checkedLivraisons)) {
  356.             $livraisonIdFront $checkedLivraisons[0];
  357.             $typeTarif $this->typeTarifsRepository->findOneById($livraisonIdFront);
  358.             $nomLivraison $typeTarif->getTitre();
  359.             $descLivraison $typeTarif->getDescription();
  360.             // On récupère les quantités bouteilles potentielles
  361.             $quantiteBouteilleLaPlusProche $this->quantiteBouteilleRepository->findPartByBottleCountAndZone($calculateTotalBottles$zone->getId());
  362.             if ($pays->getNom() == "France") {
  363.                 $message "Il n'est pas possible d'envoyer cette quantité de bouteilles pour ce pays et avec cet emballage. 
  364.                 Vous pouvez configurer le <a href='#' id='transport_palette'>transport par palette</a>.
  365.                 <br> Sinon, vous pouvez consulter l'offre complète avec les différentes restrictions ci-dessous.";
  366.             } else {
  367.                 $message "Il n'est pas possible d'envoyer cette quantité de bouteilles pour ce pays et avec cet emballage. <br> Vous pouvez consulter l'offre complète avec les différentes restrictions ci-dessous.";
  368.             }
  369.             if (sizeof($quantiteBouteilleLaPlusProche) == 0) {
  370.                 if ($calculateTotalBottles 0) {
  371.                     //si france, on regarde si l'option palette a été utilisée
  372.                     if ($pays->getNom() == "France") {
  373.                         if ($checkedSurPalette) {
  374.                             //si le poids et le département sont remplis (France seulement)
  375.                             if (!empty($poidsSurPalette) and (!empty($departementSurPalette))) {
  376.                                 $montantSurPalette $this->getMontantPaletteByDepartement($poidsSurPalette$departementSurPalette);
  377.                                 //si le montent existe on écrase montantTransport
  378.                                 $montantTransport $montantSurPalette;
  379.                             } else {
  380.                                 $errors[] = $message;
  381.                             }
  382.                         } else {
  383.                             $errors[] = $message;
  384.                         }
  385.                     } else {
  386.                         $errors[] = $message;
  387.                     }
  388.                 } else {
  389.                     $errors[] = $message;
  390.                 }
  391.             } else {
  392.                 $montantTransportObject $this->tarifRepository->findPartByTypeTarifAndQuantiteBouteille($typeTarif->getId(), $quantiteBouteilleLaPlusProche[0]->getId());
  393.                 $montantTransport $montantTransportObject->getMontant();
  394.                 if ($montantTransport == null) {
  395.                     $message "Il n'est pas possible d'envoyer cette quantité de bouteilles avec cette livraison, veuillez choisir un autre type de livraison. <br> Vous pouvez consulter l'offre complète avec les différentes restrictions ci-dessous.";
  396.                     $errors[] = $message;
  397.                 }
  398.             }
  399.         }
  400.         if ($checkedCaisseEnBois) {
  401.             $totalBouteillesClassiques $this->calculateTotalBottlesClassique($recap);
  402.             /*
  403.             * lots_of_12
  404.             * lots_of_6
  405.             * remaining_bottles
  406.             * total_costs        
  407.             */
  408.             $aCaisseEnBoisCalcul $this->calculateCaisseEnBois($totalBouteillesClassiques$zone->getCaisseBoisMontantBouteillesDouze(), $zone->getCaisseBoisMontantBouteilleSix());
  409.             $montantCaisseEnBois $aCaisseEnBoisCalcul["total_costs"];
  410.             //si le montent existe on écrase montantTransport
  411.             $montantTransport $montantCaisseEnBois;
  412.         }
  413.         if ($checkedDeliveredDutyPaid) {
  414.             $montantOptions $montantOptions $this->montantDeliveredDutyPaid;
  415.         }
  416.         if ($checkedSurPalette) {
  417.             //si le poids et le département sont remplis (France seulement)
  418.             if (!empty($poidsSurPalette) and (!empty($departementSurPalette))) {
  419.                 $montantSurPalette $this->getMontantPaletteByDepartement($poidsSurPalette$departementSurPalette);
  420.                 //si le montent existe on écrase montantTransport
  421.                 $montantTransport $montantSurPalette;
  422.             }
  423.         }
  424.         if (sizeof($errors) == 0) {
  425.             $montantTaxe $this->handleCountryById($pays->getId(), $montantValeur$calculateTotalBottles$montantTransport);
  426.             if ($montantTaxe == null) {
  427.                 $montantTaxe 0;
  428.             } else {
  429.                 $montantTaxe $montantTaxe["montantAvecMarge"];
  430.             }            
  431.             // Traitement de l'asssurance
  432.             if (!empty($checkedAssurances)) {
  433.                 $assuranceIdFront $checkedAssurances[0];
  434.                 $assuranceComp $this->assuranceRepository->findOneById($assuranceIdFront);
  435.                 $montantAssurance = ($montantValeur $montantTotal) * ($assuranceComp->getTaux() / 100);
  436.                 $nomAssurrance $assuranceComp->getTitre();
  437.             }
  438.             $montantTotal $montantTransport $montantEmballage $montantAssurance $montantTaxe $montantOptions /*+ $montantCaisseEnBois + $montantSurPalette*/;
  439.         }
  440.         $aReturnDonnee = array();
  441.         $aReturnDonnee["montantTransport"] = $montantTransport;
  442.         $aReturnDonnee["montantEmballage"] = $montantEmballage;
  443.         $aReturnDonnee["montantAssurance"] = $montantAssurance;
  444.         $aReturnDonnee["montantTaxe"] = $montantTaxe;
  445.         $aReturnDonnee["montantOptions"] = $montantOptions;
  446.         $aReturnDonnee["montantCaisseEnBois"] = $montantCaisseEnBois;
  447.         $aReturnDonnee["montantTotal"] = $montantTotal;
  448.         $aReturnDonnee["isAssujettiTva"] = $isAssujettiTva;
  449.         $aReturnDonnee["errors"] = $errors;
  450.         $aReturnDonnee["nomAssurrance"] = $nomAssurrance;
  451.         $aReturnDonnee["nomEmballage"] = $nomEmballage;
  452.         $aReturnDonnee["montantSurPalette"] = $montantSurPalette;
  453.         $aReturnDonnee["montantValeur"] = $montantValeur;
  454.         $aReturnDonnee["assuranceComp"] = $assuranceComp;
  455.         $aReturnDonnee["nomLivraison"] = $nomLivraison;
  456.         $aReturnDonnee["descLivraison"] = $descLivraison;
  457.         $aReturnDonnee["poidsSurPalette"] = $poidsSurPalette;
  458.         $aReturnDonnee["departementSurPalettetext"] = $departementSurPalettetext;
  459.         return $aReturnDonnee;
  460.     }
  461.     // Fonction permettant de calculer le nombre de bouteilles (3L = 4, 1.5L = 2, 0.75L = 1, 0.5L = 1)
  462.     function calculateTotalBottles(array $recap): int
  463.     {
  464.         // Définitions des équivalences volume => nombre de bouteilles
  465.         $volumeToBottleCount = [
  466.             "0.5" => 1,
  467.             "0.75" => 1,
  468.             "1.5" => 2,
  469.             "3" => 4
  470.         ];
  471.         $totalBottles 0;
  472.         // Parcourir le tableau de récap
  473.         foreach ($recap as $volume => $quantity) {
  474.             // Vérifier si le volume existe dans les équivalences
  475.             if (isset($volumeToBottleCount[$volume])) {
  476.                 // Multiplier la quantité par le nombre de bouteilles correspondant au volume
  477.                 $totalBottles += $quantity $volumeToBottleCount[$volume];
  478.             }
  479.         }
  480.         return $totalBottles;
  481.     }
  482.     // Fonction permettant de retourner le tarif en fonction du poids et du departement (France seulement)
  483.     function getMontantPaletteByDepartement($poids$departement): float
  484.     {
  485.         //on va chercher le resultat dans le repository
  486.         $tarif $this->ZoneDepartementsPoidsRepository->findOneByPoidsAndDepartement($poids$departement);
  487.         if ($tarif == null) {
  488.             return 0;
  489.         }
  490.         return $tarif->getMontant();
  491.     }
  492.     // Fonction permettant de calculer le nombre de bouteilles de 0.75L
  493.     function calculateTotalBottlesClassique(array $recap): int
  494.     {
  495.         $totalBottles 0;
  496.         // Parcourir le tableau de récap
  497.         foreach ($recap as $volume => $quantity) {
  498.             // Vérifier si c'est le volume 0.75
  499.             if ($volume == "0.75") {
  500.                 $totalBottles += $quantity;
  501.             }
  502.         }
  503.         return $totalBottles;
  504.     }
  505.     // Fonction permettant de calculer le volume de bouteilles (3L = 4, 1.5L = 2, 0.75L = 1, 0.5L = 1)
  506.     function calculateVolumeBottles(array $recap): float
  507.     {
  508.         $volumeTotal 0;
  509.         // Parcourir le tableau de récap
  510.         foreach ($recap as $volume => $quantity) {
  511.             $volumeTotal += $quantity $volume;
  512.         }
  513.         return $volumeTotal;
  514.     }
  515.     // Fonction permettant de calculer les tarifs en dégressif suivant le nombre de bouteilles
  516.     function calculateTarifs($recap$itemsByNbBouteille$itemsByNbMagnum$itemsByNbJeroboam)
  517.     {
  518.         $result = [];
  519.         $totalCost 0// Montant final global
  520.         // Parcourir chaque volume dans le récapitulatif
  521.         foreach ($recap as $volume => $totalBottles) {
  522.             $volumeResult = [
  523.                 'volume' => $volume,
  524.                 'nb_bouteille' => 0,
  525.                 'nb_magnum' => 0,
  526.                 'nb_jeroboam' => 0,
  527.                 'tarif_details' => [],
  528.                 'montant_volume' => // Montant total pour ce volume
  529.             ];
  530.             // Sélectionner les items appropriés en fonction du volume
  531.             $items = [];
  532.             if ($volume == '0.75' || $volume == '0.5') {
  533.                 $items $itemsByNbBouteille;
  534.             } elseif ($volume == '1.5') {
  535.                 $items $itemsByNbMagnum;
  536.             } elseif ($volume == '3') {
  537.                 $items $itemsByNbJeroboam;
  538.             }
  539.             // Parcourir les items triés pour emballer les bouteilles
  540.             foreach ($items as $item) {
  541.                 $nbBouteillesParCarton $item->getNbBouteille() ?? $item->getNbMagnum() ?? $item->getNbJeroboam();
  542.                 $montantUnitaire $item->getMontantUnitaire();
  543.                 while ($totalBottles >= $nbBouteillesParCarton) {
  544.                     $volumeResult['tarif_details'][] = [
  545.                         'montant_unitaire' => $montantUnitaire,
  546.                         'nb_bouteilles' => $nbBouteillesParCarton
  547.                     ];
  548.                     $totalBottles -= $nbBouteillesParCarton;
  549.                     // Ajouter au montant total pour ce volume
  550.                     $volumeResult['montant_volume'] += $montantUnitaire;
  551.                     // Incrementer les compteurs correspondants
  552.                     if ($volume == '0.75' || $volume == '0.5') {
  553.                         $volumeResult['nb_bouteille'] += $nbBouteillesParCarton;
  554.                     } elseif ($volume == '1.5') {
  555.                         $volumeResult['nb_magnum'] += $nbBouteillesParCarton;
  556.                     } elseif ($volume == '3') {
  557.                         $volumeResult['nb_jeroboam'] += $nbBouteillesParCarton;
  558.                     }
  559.                 }
  560.             }
  561.             // Si des bouteilles restantes ne trouvent pas d'emballage
  562.             if ($totalBottles 0) {
  563.                 $volumeResult['tarif_details'][] = [
  564.                     'montant_unitaire' => null,
  565.                     'nb_bouteilles' => $totalBottles
  566.                 ];
  567.                 if ($volume == '0.75' || $volume == '0.5') {
  568.                     $volumeResult['nb_bouteille'] += $totalBottles;
  569.                 } elseif ($volume == '1.5') {
  570.                     $volumeResult['nb_magnum'] += $totalBottles;
  571.                 } elseif ($volume == '3') {
  572.                     $volumeResult['nb_jeroboam'] += $totalBottles;
  573.                 }
  574.             }
  575.             // Ajouter le montant de ce volume au montant total global
  576.             $totalCost += $volumeResult['montant_volume'];
  577.             $result[] = $volumeResult;
  578.         }
  579.         return [
  580.             'result' => $result,
  581.             'montant_total' => $totalCost
  582.         ];
  583.     }
  584.     // Permet de calculer le nombre de caisse en bois
  585.     function calculateCaisseEnBois($totalBottles$pricePer12$pricePer6)
  586.     {
  587.         if ($totalBottles <= 0) {
  588.             return [
  589.                 'lots_of_12' => 0,
  590.                 'lots_of_6' => 0,
  591.                 'remaining_bottles' => 0,
  592.                 'total_cost' => 0
  593.             ];
  594.         }
  595.         // Calculer les lots de 12 bouteilles
  596.         $lotsOf12 intdiv($totalBottles12);
  597.         $remainingAfter12 $totalBottles 12;
  598.         // Calculer les lots de 6 bouteilles avec le reste
  599.         $lotsOf6 intdiv($remainingAfter126);
  600.         $remainingBottles $remainingAfter12 6;
  601.         // Si les bouteilles restantes sont inférieures à 6 mais différentes de 0,
  602.         // on ajoute une caisse supplémentaire de 6 bouteilles
  603.         if ($remainingBottles 0) {
  604.             $lotsOf6++;
  605.             $remainingBottles 0// Toutes les bouteilles restantes sont incluses dans la caisse supplémentaire
  606.         }
  607.         // Calculer le montant total
  608.         $totalCost = ($lotsOf12 $pricePer12) + ($lotsOf6 $pricePer6);
  609.         //dd($lotsOf12);
  610.         return [
  611.             'lots_of_12' => $lotsOf12,
  612.             'lots_of_6' => $lotsOf6,
  613.             'remaining_bottles' => $remainingBottles,
  614.             'total_costs' => $totalCost
  615.         ];
  616.     }
  617.     function handleCountryById(int $idfloat $totalInvoiceint $numberOfBottlesfloat $transportCost)
  618.     {
  619.         //fix taxe : on va chercher le min ID du pays
  620.         $pays $this->paysRepository->findOneById($id);
  621.         $old_pays $this->paysRepository->findMinIdByName($pays->getNom());
  622.         if ($old_pays != null) {
  623.             $min_id $old_pays['id'];
  624.         } else {
  625.             $min_id $id;
  626.         }
  627.         // Vérification et appel de la méthode correspondante
  628.         if (in_array($min_id$this->aRoyaumeUniId)) {
  629.             return $this->calculTaxeService->calculateRoyaumeUni($totalInvoice$numberOfBottles);
  630.         } elseif (in_array($min_id$this->aSuisseId)) {
  631.             return $this->calculTaxeService->calculateSuisse($totalInvoice$numberOfBottles);
  632.         } elseif (in_array($min_id$this->aNorvegeId)) {
  633.             return $this->calculTaxeService->calculateNorvege($totalInvoice$numberOfBottles$transportCost);
  634.         } elseif (in_array($min_id$this->aAustralieId)) {
  635.             return $this->calculTaxeService->calculateAustralie($totalInvoice$numberOfBottles$transportCost);
  636.         } elseif (in_array($min_id$this->aNouvelleZelandeId)) {
  637.             return $this->calculTaxeService->calculateNouvelleZelande($totalInvoice$numberOfBottles$transportCost);
  638.         } elseif (in_array($min_id$this->aSingapourId)) {
  639.             return $this->calculTaxeService->calculateSingapour($totalInvoice$numberOfBottles);
  640.         } elseif (in_array($min_id$this->aCoreeSudId)) {
  641.             return $this->calculTaxeService->calculateCoreeSud($totalInvoice$numberOfBottles$transportCost);
  642.         } elseif (in_array($min_id$this->aJaponId)) {
  643.             return $this->calculTaxeService->calculateJapon($totalInvoice$numberOfBottles$transportCost);
  644.         } elseif (in_array($min_id$this->aTaiwanId)) {
  645.             return $this->calculTaxeService->calculateTaiwan($totalInvoice$numberOfBottles$transportCost);
  646.         } elseif (in_array($min_id$this->aUSAParticulier)) {
  647.             return $this->calculTaxeService->calculateUSAparticulier($totalInvoice);
  648.         }
  649.         return null;
  650.     }
  651. }