src/Controller/PageController.php line 156

Open in your IDE?
  1. <?php
  2. namespace App\Controller;
  3. use App\Entity\AifredRestaurants;
  4. use App\Entity\GiftCards;
  5. use App\Entity\QrRedirection;
  6. use App\Entity\User;
  7. use App\Entity\UserRestaurant;
  8. use App\Repository\RestaurantsRepository;
  9. use App\Services\EventLog;
  10. use App\Services\Postgre;
  11. use DateTime;
  12. use Doctrine\ORM\EntityManagerInterface;
  13. use Dompdf\Dompdf;
  14. use Dompdf\Options;
  15. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  16. use Symfony\Component\HttpFoundation\JsonResponse;
  17. use Symfony\Component\HttpFoundation\RedirectResponse;
  18. use Symfony\Component\HttpFoundation\Response;
  19. use Symfony\Component\HttpFoundation\Session\SessionInterface;
  20. use Symfony\Component\Routing\Annotation\Route;
  21. use Symfony\Component\Security\Core\Security;
  22. use App\Repository\UserRepository;
  23. use Symfony\Component\HttpFoundation\Request;
  24. use Symfony\Component\HttpKernel\HttpKernelInterface;
  25. use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
  26. use Symfony\Component\Validator\Constraints\Date;
  27. class PageController extends AbstractController
  28. {
  29.     private $user;
  30.     private $user_vendor;
  31.     private $userCurrent;
  32.     private $user_vendors=[];
  33.     private $urid_selected="";
  34.     private $user_restaurants=[];
  35.     private $user_restaurant=[];
  36.     private $nav=[];
  37.     /**
  38.      * PageController constructor.
  39.      * @param Security $security
  40.      * @param UserRepository $userRepository
  41.      * @param Postgre $postgre
  42.      */
  43.     public function __construct(Security $security,  EntityManagerInterface $em){
  44.         $this->user $security->getUser();
  45.         
  46.         $this->userCurrent =  $this->user ;
  47.       //  dd($this->user);
  48.         //  $this->user =  $this->getDoctrine()->getRepository(User::class)->find($securityUser->id);
  49.         if (!is_null($this->user)) {
  50.             // recuperer les userRestaurant par order de num_order ou id
  51.             $this->userCurrent $this->user;
  52.             if(in_array(User::ROLE_ADMIN,$this->user->getRoles())){
  53.                 $this->userCurrent =$em->getRepository(User::class)->find($this->userCurrent->getUserId());
  54.             }
  55.             $UserRestaurants =  $em->getRepository(UserRestaurant::class)->findBy(['user'=>$this->userCurrent],["num_order"=>"ASC","id"=>"ASC"]);
  56.             //recuperation de tous les restaurants associer (aifred ou corporate)
  57.             $this->user_restaurants=[];
  58.             foreach (  $UserRestaurants as  $uResto){
  59.                 $key $uResto->getId();
  60.                 $this->user_restaurants[$key]["id"]=$uResto->getId();
  61.                 $this->user_restaurants[$key]["corporate"]=[];
  62.                 $this->user_restaurants[$key]["michelin"]=[];
  63.                 $this->user_restaurants[$key]["user"]["name"]=$uResto->getUser()->getEmail();
  64.                 $this->user_restaurants[$key]["user"]["ur_id"]=$uResto->getUser()->getUrId();
  65.                 if(!is_null($uResto->getRestaurant())){
  66.                     $this->user_restaurants[$key]["corporate"]["name"]=$uResto->getRestaurant()->getName();
  67.                     $this->user_restaurants[$key]["corporate"]["prefix"]=$uResto->getRestaurant()->getShopCode();
  68.                     $this->user_restaurants[$key]["corporate"]["vendor"]=$uResto->getRestaurant()->getShopifyVendorName();
  69.                     $this->user_restaurants[$key]["corporate"]["id"]=$uResto->getRestaurant()->getId();
  70.                     $this->user_restaurants[$key]["corporate"]["city"]=$uResto->getRestaurant()->getCity();
  71.                     $this->user_restaurants[$key]["corporate"]["report"]=''// que sur aifred_restaurant
  72.                 }
  73.                 if(!is_null($uResto->getAiRestaurant())){
  74.                     $this->user_restaurants[$key]["michelin"]["name"]=$uResto->getAiRestaurant()->getName();
  75.                     $this->user_restaurants[$key]["michelin"]["prefix"]=$uResto->getAiRestaurant()->getTrigram();
  76.                     $this->user_restaurants[$key]["michelin"]["vendor"]=$uResto->getAiRestaurant()->getShopifyVendor();
  77.                     $this->user_restaurants[$key]["michelin"]["id"]=$uResto->getAiRestaurant()->getId();
  78.                     $this->user_restaurants[$key]["michelin"]["city"]=$uResto->getAiRestaurant()->getCity();
  79.                     $this->user_restaurants[$key]["michelin"]["report"]=$uResto->getAiRestaurant()->getLookerStudioUrl();
  80.                     $this->user_restaurants[$key]["michelin"]["typeform_password"]=$uResto->getAiRestaurant()->getTypeformPassword();
  81.                 }
  82.             }
  83.             //   dd($UserRestaurants,$this->user_restaurants);
  84.             if ($this->user == "NULL") {
  85.                 return $this->redirectToRoute("app_login");
  86.             }
  87.             $UserRestaurants  =  $this->user_restaurants ;
  88.             $UserRestaurant  =  array_shift($this->user_restaurants) ;
  89.             $urid_selected =  $UserRestaurant["id"]??null;
  90.             if(null !== $this->user->getUrId()){
  91.                 $urid_selected $this->user->getUrId();
  92.                 $UserRestaurant  $UserRestaurants[$this->user->getUrId()] ;
  93.             }
  94.             /*
  95.                    dd([
  96.                        'userCurrent'=>$this->userCurrent->getUrId(),
  97.                        'user'=>$this->user->getUrId(),
  98.                        '$UserRestaurant'=>$UserRestaurant,
  99.                        'UserRestaurants'=>$UserRestaurants
  100.                    ]);
  101.             */
  102.             $this->user_restaurant $UserRestaurant;
  103.             if(null !== $UserRestaurant ){
  104.                 $vendor_name = !empty($UserRestaurant["michelin"])?$UserRestaurant["michelin"]["name"] :$UserRestaurant["corporate"]["name"];
  105.                 $vendor_city = !empty($UserRestaurant["michelin"])?$UserRestaurant["michelin"]["city"] :$UserRestaurant["corporate"]["city"];
  106.                 $vendor_prefix $UserRestaurant["michelin"] ? $UserRestaurant["michelin"]['prefix']:$UserRestaurant["corporate"]['prefix'];
  107.             }else{
  108.                 $vendor_name $this->user->getUsername();
  109.                 $vendor_city ="";
  110.                 $vendor_prefix ="";
  111.             }
  112.             // $vendorsCurrent  = $this->user->getShopifyVendorName();
  113.             //$resultStripe = $postgre->query("SELECT stripe_connect_account_id FROM restaurants WHERE shopify_vendor_name='".str_replace("'","''",$this->user_vendor)."'");
  114.             // $resultStripe =[];
  115.             $this->nav = [
  116.                 'user_restaurants' =>  $UserRestaurants,
  117.                 'user_restaurant' =>    $UserRestaurant,
  118.                 'urid_selected' =>    $urid_selected,
  119.                 'vendor_name' =>    $vendor_name,
  120.                 'vendor_city' =>    $vendor_city,
  121.                 'prefix' =>$vendor_prefix,
  122.                 //  'stripe_id' =>   (!empty($resultStripe[0]) ?$resultStripe[0]["stripe_connect_account_id"]:""),
  123.                 'user' => $this->user,
  124.                 'userCurrent' => $this->userCurrent
  125.             ];
  126.         }
  127.         $this->em $em;
  128.         //instance
  129.        // $this->EventLog = new EventLog($em, $this->user );
  130.     }
  131.     public function renderHtml($view$params=[]){
  132.         $params array_merge($params,$this->nav);
  133.         return $this->render($view$params);
  134.     }
  135.     /**
  136.      * @Route("/", name="home")
  137.      * @param UserRepository $userRepository
  138.      * @param Postgre $postgre
  139.      * @return Response
  140.      */
  141.     public function index(UserRepository $userRepository)
  142.     {
  143.         $members=[];
  144.         if(in_array(User::ROLE_ADMIN,$this->user->getRoles())) {
  145.             // $members = $this->em->getRepository(User::class)->findAllByMemberUR();
  146.             //   $members = $this->em->getRepository(User::class)->findUsersWithRestaurants();
  147.             $members $this->em->getRepository(User::class)->findEmailsGroupedByRestaurant();
  148.         }
  149.         $vendors $userRepository->getVendors();
  150.         return $this->renderHtml('page/index.html.twig', [
  151.             'members' =>   $members,
  152.             'vendors' =>   $vendors,
  153.             'user' => $this->user
  154.         ]);
  155.         //  }
  156.         //return $this->renderHtml('page/stats.html.twig');
  157.     }
  158.     /**
  159.      * @Route("/gestion-des-comptes", name="manage_users")
  160.      */
  161.     public function manage_users(UserRepository $membresEntity):Response
  162.     {
  163.         if (!isset($this->user) || empty($this->user)) {
  164.             return $this->redirectToRoute("app_login");
  165.         }
  166.         if(!in_array(User::ROLE_DEV,$this->user->getRoles())){
  167.             return $this->redirectToRoute("home");
  168.         }
  169.         //recuperer les users
  170.         $membres $membresEntity->findBy(array(), array('id' => 'DESC'));
  171.         return $this->renderHtml('page/members.html.twig', [
  172.             'members' => $membres,
  173.             'user' => $this->user
  174.         ]);
  175.     }
  176.     /**
  177.      * @Route("/gestion-des-comptes/{action}/{id?}", name="manage_user")
  178.      */
  179.     public function manage_user(string $actionUser $membreEntity=null):Response
  180.     {
  181.         //edit , add, delete
  182.         if (!isset($this->user) || empty($this->user)) {
  183.             return $this->redirectToRoute("app_login");
  184.         }
  185.         if(!in_array(User::ROLE_DEV,$this->user->getRoles())){
  186.             return $this->redirectToRoute("home");
  187.         }
  188.         $url="";
  189.         $is_url=false;
  190.         if($membreEntity !==null && $membreEntity->getToken()!==null){
  191.             $url=  $this->generateUrl('resetting', ['id' => $membreEntity->getId(), 'token' => $membreEntity->getToken()],  UrlGeneratorInterface::ABSOLUTE_URL);
  192.             $is_url=ResettingController::isRequestInTime($membreEntity->getPasswordRequestedAt());
  193.         }
  194.         return $this->renderHtml('page/member.html.twig', [
  195.             'member' => $membreEntity,
  196.             'url'=>$url,
  197.             'is_url'=> $is_url ,
  198.             'action'=>$action,
  199.             'user' => $this->user
  200.         ]);
  201.     }
  202.     /**
  203.      * @Route("/user/saving", name="update_user")
  204.      */
  205.     public function update_user(Request $request):RedirectResponse{
  206.         if (!isset($this->user) || empty($this->user)) {
  207.             return $this->redirectToRoute("app_login");
  208.         }
  209.         $formDatas $request->request->all();
  210.         $formDatas["vendor"] = join("|",$formDatas["vendors"]);
  211.         unset( $formDatas["vendors"]);
  212.         if( $formDatas["password"]===""){
  213.             unset( $formDatas["password"]);
  214.         }
  215.         $formDatas["save"]=true;
  216.         $rep $this->controllerApiTiptoque('postRegister', [], json_encode(["user"=>$formDatas]));
  217.         // dd( json_encode(["user"=>$formDatas]),$rep);
  218.         if(isset($rep['user']['id'])){
  219.             return $this->redirectToRoute("manage_user",['action'=>'edit','id'=>$rep['user']['id']]);
  220.         }else{
  221.             return $this->redirectToRoute("manage_users");
  222.         }
  223.     }
  224.     /**
  225.      * @Route("/rapport", name="rapport_seo")
  226.      */
  227.     public function rapport_seo(SessionInterface $session,Request $request):Response
  228.     {
  229.         if (!isset($this->user) || empty($this->user)) {
  230.             return $this->redirectToRoute("app_login");
  231.         }
  232.         $choices_date $session->get("choices_date"'last_30_days');
  233.         $mode_display $session->get("mode_display""STANDARD");
  234.         $formDatas $request->request->all();
  235.         if(isset($formDatas["format_date"]) &&  $formDatas["format_date"]!==""){
  236.             $choices_date $formDatas["format_date"];
  237.         }
  238.         
  239.         if(isset($formDatas["mode_display"])){
  240.             $mode_display $formDatas["mode_display"]; 
  241.             // ALL_GIFTCARD , STANDARD ou DEBUG
  242.         }
  243.         $session->set("choices_date"$choices_date);
  244.         $session->set("mode_display"$mode_display);
  245.         $now = new DateTime();
  246.         switch ($choices_date){
  247.             case "now":
  248.                 $date_start $now->format('Y-m-d 00:00:00');
  249.                 $date_end $now->format('Y-m-d 23:59:59');
  250.                 break;
  251.             case "yesterday":
  252.                 $yesterday $now->modify('-1 day');
  253.                 $date_start $yesterday->format('Y-m-d 00:00:00');
  254.                 $date_end $yesterday->format('Y-m-d 23:59:59');
  255.                 break;
  256.             case "last_30_days":
  257.                 $date_end =  $now->modify('+1 days')->format('Y-m-d h:i:s'); // Revenir à aujourd'hui pour la fin
  258.                 $date_start $now->modify('-30 days')->format('Y-m-d 00:00:00');
  259.                 break;
  260.             case "last_12_months":
  261.                 $date_end =  $now->modify('+1 days')->format('Y-m-d h:i:s'); // Revenir à aujourd'hui pour la fin
  262.                 $date_start $now->modify('-12 months')->format('Y-m-d 00:00:00');
  263.                 break;
  264.                 
  265.             case "last_24_months":
  266.                 $date_end =  $now->modify('+1 days')->format('Y-m-d h:i:s'); // Revenir à aujourd'hui pour la fin
  267.                 $date_start $now->modify('-24 months')->format('Y-m-d 00:00:00');
  268.                 break;
  269.             default:
  270.                 // Valeurs par défaut si aucune correspondance
  271.                 $date_start $now->format('Y-m-d 00:00:00');
  272.                 $date_end $now->format('Y-m-d 23:59:59');
  273.                 break;
  274.         }
  275.         $restaurant_id =  isset( $this->user_restaurant["corporate"]['id']) ?$this->user_restaurant["corporate"]['id'] : null;
  276.         $airestaurant_id =  isset( $this->user_restaurant["michelin"]['id']) ?$this->user_restaurant["michelin"]['id'] : null;
  277.         if(in_array(User::ROLE_ALL_GIFTCARD ,$this->user->getRoles() ) && !in_array(User::ROLE_ADMIN ,$this->user->getRoles() )){
  278.             $mode_display "ALL_GIFTCARD";
  279.         }
  280.        // dd( $mode_display);
  281.         $giftCards $this->em->getRepository(GiftCards::class)->getGiftCardTransactions(
  282.             $restaurant_id,$airestaurant_id,
  283.             $date_start,$date_end,$mode_display);
  284.           
  285.         /*
  286.         $userRestaurant = $this->em->getRepository(UserRestaurant::class)->findBy(['user'=>$this->user]);
  287.         ancienne version avec le iframe par looker studioUrl
  288.         $lookerStudioUrl ="";
  289.         if(!empty($userRestaurant)){
  290.             $lookerStudioUrl = $this->user_restaurant["michelin"]["report"];
  291.         }
  292.            
  293.         */
  294.         //recuperer les giftcards avec 2 tables
  295.            // dd($this->userCurrent);
  296.         //ou trouver le rapport ....
  297.         return $this->renderHtml('page/rapport.html.twig', [
  298.             "giftCards"=>$giftCards,
  299.             "choices_date"=>$choices_date,
  300.             "mode_display"=>$mode_display
  301.         ]);
  302.     }
  303.     /**
  304.      * @Route("/rapport/pdf/{order_id}", name="invoice_pdf")
  305.      */
  306.     public function invoice_pdf(string $order_id):Response{
  307.         if (!isset($this->user) || empty($this->user)) {
  308.             return $this->redirectToRoute("app_login");
  309.         }
  310.         // verifier si l invoice est que pour ce user
  311.         // Exemple de données pour la facture
  312.         $invoiceData = [
  313.             'id' => $order_id,
  314.             'date' => (new \DateTime())->format('Y-m-d'),
  315.             'customer' => 'John Doe',
  316.             'items' => [
  317.                 ['description' => 'Produit A''quantity' => 2'price' => 50],
  318.                 ['description' => 'Produit B''quantity' => 1'price' => 100],
  319.             ],
  320.             'total' => 200,
  321.         ];
  322.         // Options de configuration pour Dompdf
  323.         $options = new Options();
  324.         $options->set('defaultFont''Arial');
  325.         $dompdf = new Dompdf($options);
  326.         // Génération du contenu HTML pour le PDF
  327.         $html $this->render('pdf/invoice.html.twig', [
  328.             'invoice' => $invoiceData,
  329.         ]);
  330.         // Charger le HTML dans Dompdf
  331.         $dompdf->loadHtml($html);
  332.         // (Optionnel) Définir la taille et l'orientation de la page
  333.         $dompdf->setPaper('A4''portrait');
  334.         // Générer le PDF
  335.         $dompdf->render();
  336.         // Créer une réponse HTTP avec le contenu du PDF
  337.         return new Response(
  338.             $dompdf->output(),
  339.             200,
  340.             [
  341.                 'Content-Type' => 'application/pdf',
  342.                 'Content-Disposition' => 'inline; filename="invoice_' $order_id '.pdf"',
  343.             ]
  344.         );
  345.     }
  346.     /**
  347.      * @Route("/rapport/csv", name="rapport_csv")
  348.      */
  349.     public function rapport_csv(SessionInterface $session):Response{
  350.         if (!isset($this->user) || empty($this->user)) {
  351.             return $this->redirectToRoute("app_login");
  352.         }
  353.         $choices_date $session->get("choices_date"'last_12_days');
  354.         $mode_display $session->get("mode_display""STANDARD");
  355.         $now = new DateTime();
  356.         switch ($choices_date){
  357.             case "now":
  358.                 $date_start $now->format('Y-m-d 00:00:00');
  359.                 $date_end $now->format('Y-m-d 23:59:59');
  360.                 $title_csv $now->format('Y-m-d');
  361.                 break;
  362.             case "yesterday":
  363.                 $yesterday $now->modify('-1 day');
  364.                 $date_start $yesterday->format('Y-m-d 00:00:00');
  365.                 $date_end $yesterday->format('Y-m-d 23:59:59');
  366.                 $title_csv $now->format('Y-m-d');
  367.                 break;
  368.             case "last_30_days":
  369.                 $date_end $now->format('Y-m-d h:i:s'); // Revenir à aujourd'hui pour la fin
  370.                 $title_csv $now->format('Y-m-d');
  371.                 $date_start $now->modify('-30 days')->format('Y-m-d 00:00:00');
  372.                 $title_csv .="_".$now->format('Y-m-d');
  373.                 break;
  374.             case "last_12_months":
  375.                 $date_end =  $now->format('Y-m-d h:i:s'); // Revenir à aujourd'hui pour la fin
  376.                 $title_csv $now->format('Y-m-d');
  377.                 $date_start $now->modify('-12 months')->format('Y-m-d 00:00:00');
  378.                 $title_csv .= "_".$now->format('Y-m-d');
  379.                 break;
  380.                 case "last_24_months":
  381.                     $date_end =  $now->format('Y-m-d h:i:s'); // Revenir à aujourd'hui pour la fin
  382.                     $title_csv $now->format('Y-m-d');
  383.                     $date_start $now->modify('-24 months')->format('Y-m-d 00:00:00');
  384.                     $title_csv .= "_".$now->format('Y-m-d');
  385.                 break;
  386.             default:
  387.                 // Valeurs par défaut si aucune correspondance
  388.                 $date_start $now->format('Y-m-d 00:00:00');
  389.                 $date_end $now->format('Y-m-d 23:59:59');
  390.                 break;
  391.         }
  392.         
  393.         if(in_array(User::ROLE_ALL_GIFTCARD ,$this->user->getRoles() )){
  394.             $mode_display "ALL_GIFTCARD";
  395.         }
  396.         $restaurant_id =  isset( $this->user_restaurant["corporate"]['id']) ?$this->user_restaurant["corporate"]['id'] : null;
  397.         $airestaurant_id =  isset( $this->user_restaurant["michelin"]['id']) ?$this->user_restaurant["michelin"]['id'] : null;
  398.         $giftCards $this->em->getRepository(GiftCards::class)->getGiftCardTransactions(
  399.             $restaurant_id,$airestaurant_id,
  400.             $date_start,$date_end$mode_display);
  401.         $data=[
  402.             ["Date""N° de commande""Code de la carte""Montant""Date de règlement""Statut du règlement"]
  403.         ];
  404.         foreach ($giftCards as $giftCard){
  405.             if($giftCard['echange_code'] != ""){
  406.                 continue;
  407.             }
  408.             
  409.             $dateTransaction = new DateTime($giftCard['transaction_date']);
  410.             $dateCreation = new DateTime($giftCard['creation_date']);
  411.             array_push($data,[
  412.                 $mode_display == "STANDARD" ?$dateTransaction->format('d/m/Y'):$dateCreation->format('d/m/Y')
  413.                 ,
  414.                 $giftCard['orders_name'],
  415.                 $giftCard['transaction_id'] =='' "En attente de validation":  $giftCard['code'],
  416.                 $giftCard['original_balance'],
  417.                 $giftCard['transaction_id'] ==''  ?"":$dateTransaction->format('d/m/Y'),
  418.                 $giftCard['transaction_id'] =='' ?"non utilisé":"payé"
  419.             ]);
  420.         }
  421.         // Génération du contenu CSV
  422.         $csvContent $this->generateCsv($data);
  423.         // Création d'une réponse HTTP pour le téléchargement du fichier
  424.         $response = new Response($csvContent);
  425.         // Configuration des en-têtes pour le fichier CSV
  426.         $response->headers->set('Content-Type''text/csv; charset=UTF-8');
  427.         $response->headers->set('Content-Disposition''attachment; filename="rapport_' $title_csv '.csv"');
  428.         return $response;
  429.     }
  430.     /**
  431.      * Génère le contenu CSV à partir d'un tableau de données
  432.      */
  433.     private function generateCsv(array $data): string
  434.     {
  435.         // Utilisation de la fonction PHP output buffering pour générer le CSV
  436.         ob_start();
  437.         $output fopen('php://output''w');
  438.         foreach ($data as $row) {
  439.             fputcsv($output$row);
  440.         }
  441.         fclose($output);
  442.         return ob_get_clean();
  443.     }
  444.     /**
  445.      * @Route("/carte_cadeau", name="gift_card")
  446.      */
  447.     public function gift_card(Request $request):Response
  448.     {
  449.         if (empty($this->user)) {
  450.             return $this->redirectToRoute("app_login");
  451.         }
  452.         //  $userCurrent = $this->em->getRepository(UserRestaurant::class)->findBy(["user"=>$this->user]);
  453.         $giftcard=[];
  454.         if($request->getMethod()=="POST"){
  455.             // cree l url du typeform dans qr_redirection
  456.             $code $request->request->get("code");
  457.             $code trim($code);
  458.             if($code !==''){
  459.                 /** @var GiftCards[] $giftcards */
  460.                 $giftcards $this->em->getRepository(GiftCards::class)->findBy(['code'=>$code]);
  461.                 $giftcard=   $giftcards[0]??[];
  462.                 if($giftcard!==[]){
  463.                     $shopCode $giftcard->getShopCode();
  464.                     if($shopCode==="CCT"){
  465.                         $shopCode $shopCode.'_LOGGED';
  466.                     }
  467.                     $qrRedir $this->em->getRepository(QrRedirection::class)->find('GCA'.$shopCode);
  468.                     $gcaUrl $qrRedir->getTarget();
  469.                     /*
  470.                     https://tiptoque.typeform.com/to/x9iRwMho#num_carte_cadeau=FAH_6148510482774_0
  471.                     &solde_restant=362
  472.                     &vendor=Chef Kelly Rangama
  473.                     &restaurant=Faham
  474.                     &expiration=Non
  475.                     &date_expiration=04/07/2025
  476.                     &prid=1670321471830
  477.                     &nomcarte=Menu Insulaire (4 séquences) - accords mets et vins
  478.                   
  479.                     erreur
  480.                     https://tiptoque.typeform.com/to/ToCWEu4A#
  481.                     num_carte_cadeau=LODASROUEN_11411244286336_0
  482.                     &amp;solde_restant=190
  483.                     &amp;vendor=Restaurant L Odas - Rouen
  484.                     &amp;restaurant=L'Odas&amp;expiration=Non
  485.                     &amp;date_expiration=05/01/2026
  486.                     &amp;prid=14957864550784
  487.                     &amp;nomcarte=DE L’ODAS EN 5 SERVICES - 2 personnes
  488.                     
  489.                   dans un autre script
  490.                       $page_to='https://tiptoque.typeform.com/to/ToCWEu4A#
  491.                         num_carte_cadeau='.$gift_card[0]['code'].
  492.                         '&product_name='.$product_name.
  493.                         '&solde_restant='.$gift_card[0]['balance'].
  494.                         '&vendor='.$gift_card[0]['vendor'].
  495.                         '&restaurant='.$password_restaurant[0]['name'].
  496.                         '&date_expiration='.$formatted_date.
  497.                         '&nomcarte='.$gift_card[0]['code'];
  498.                         -->GCACCT_LOGGED
  499.                         https://tiptoque.typeform.com/to/ToCWEu4A#num_carte_cadeau=__CARD_NUM__
  500.                         
  501.                         &solde_restant=__BALANCE__
  502.                         &vendor=__VENDOR__
  503.                         &restaurant=__RESTAURANT__
  504.                         &expiration=__EXPIRED__
  505.                         &date_expiration=__EXPIRATION__
  506.                         &prid=__PRID__
  507.                         &product_name=__PNAME__
  508.                         &nomcarte=__PNAME__
  509.                     * */
  510.                     $restaurantName =$this->user_restaurant["michelin"] ? $this->user_restaurant["michelin"]['name']:$this->user_restaurant["corporate"]['name'];
  511.                     $dateNow = new \DateTime();
  512.                     $isExpired = ($dateNow->getTimestamp()>$giftcard->getExpirationDate()->getTimestamp())?"Oui":"Non";
  513.                     $gcaUrl=str_replace"__CARD_NUM__",$giftcard->getCode(),$gcaUrl);
  514.                     $gcaUrl=str_replace"__BALANCE__",$giftcard->getBalance(),$gcaUrl);
  515.                     $gcaUrl=str_replace"__VENDOR__",$giftcard->getVendor(),$gcaUrl);
  516.                     $gcaUrl=str_replace"__RESTAURANT__",$restaurantName,$gcaUrl);
  517.                     $gcaUrl=str_replace"__EXPIRED__",$isExpired,$gcaUrl);
  518.                     $gcaUrl=str_replace"__EXPIRATION__",$giftcard->getExpirationDate()->format("d/m/Y"),$gcaUrl);
  519.                     $gcaUrl=str_replace"__PRID__",$giftcard->getProductsId(),$gcaUrl);
  520.                     $gcaUrl=str_replace"__PNAME__",$giftcard->getProductName(),$gcaUrl);
  521.                     if(isset($this->user_restaurant["michelin"])){
  522.                         $gcaUrl=str_replace"__PASSWORD__",$this->user_restaurant["michelin"]['typeform_password'],$gcaUrl);
  523.                     }
  524.                 }
  525.             }
  526.         }
  527.         //   dd($formDatas);
  528.         //ou trouver le rapport ....
  529.         return $this->renderHtml('page/giftcard.html.twig', [
  530.             'giftcard' =>$giftcard,
  531.             'gcaUrl' =>$gcaUrl ?? '',
  532.             'prefix' =>$this->user_restaurant["michelin"] ? $this->user_restaurant["michelin"]['prefix']:$this->user_restaurant["corporate"]['prefix']
  533.         ]);
  534.     }
  535.     /**
  536.      * @Route("/user/deleted/{id}", name="delete_user")
  537.      */
  538.     public function delete_user(int $id):RedirectResponse{
  539.         if (!isset($this->user) || empty($this->user)) {
  540.             return $this->redirectToRoute("app_login");
  541.         }
  542.         // dd( json_encode(["user"=>$formDatas]),$rep);
  543.         $entityManager $this->getDoctrine()->getManager();
  544.         $member $entityManager->getRepository(User::class)->find($id);
  545.         $entityManager->remove($member);
  546.         $entityManager->flush();
  547.         return $this->redirectToRoute("manage_users");
  548.     }
  549.     /**
  550.      * @Route("/mes-commandes", name="orders")
  551.      */
  552.     public function orders():Response
  553.     {
  554.         $dateDujour explode("/",date("Y/m/d/"));
  555.         $dateDemain explode("/",date("Y/m/d/",strtotime("+1 DAY")));
  556.         return $this->renderHtml('tcd/index.html.twig', [
  557.             'annee_n'=>$dateDujour[0],
  558.             'mois_n'=>$dateDujour[1],
  559.             'jour_n'=>$dateDujour[2],
  560.             'annee_t'=>$dateDemain[0],
  561.             'mois_t'=>$dateDemain[1],
  562.             'jour_t'=>$dateDemain[2]
  563.         ]);
  564.     }
  565.     /**
  566.      * @Route("/mes-commandes/{annee}/{mois}/{jour}", name="orders_date")
  567.      * @param $annee
  568.      * @param $mois
  569.      * @param $jour
  570.      * @return Response
  571.      */
  572.     public function orders_date($annee$mois$jour):Response
  573.     {
  574.         return $this->renderHtml('tcd/date.html.twig', ['annee' => $annee'mois' => $mois'jour' => $jour]);
  575.     }
  576.     /**
  577.      * @Route("/change-vendor", name="change_vendor")
  578.      * @param Request $request
  579.      * @return RedirectResponse
  580.      */
  581.     public function changeVendor(Request $request):RedirectResponse
  582.     {
  583.         if (!isset($this->user) || empty($this->user)) {
  584.             return $this->redirectToRoute("app_login");
  585.         }
  586.         $urSelected $request->request->get("urid");
  587.         //  dd($urSelected);
  588.         // exit($urSelected);
  589.         $this->user->setUrId($urSelected);
  590.         $this->em->persist($this->user);
  591.         $this->em->flush();
  592.         return $this->redirectToRoute("home");
  593.     }
  594.     /**
  595.      * @Route("/change-member", name="change_member")
  596.      * @param Request $request
  597.      * @return RedirectResponse
  598.      */
  599.     public function changeMember(Request $request):RedirectResponse
  600.     {
  601.       
  602.         if (!isset($this->user) || empty($this->user)) {
  603.             return $this->redirectToRoute("app_login");
  604.         }
  605.         if(!in_array(User::ROLE_ADMIN,$this->user->getRoles())){
  606.             return $this->redirectToRoute("home");
  607.         }
  608.         $userSelected $request->request->get("user_id");
  609.         $this->user->setUrId(null);
  610.         $this->user->setUserId($userSelected);
  611.         $this->em->persist($this->user);
  612.         $this->em->flush();
  613.         return $this->redirectToRoute("home");
  614.     }
  615.     /**
  616.      * @Route("/cache/init", name="initCacheProduct")
  617.      * @param Request $request
  618.      * @return RedirectResponse
  619.      */
  620.     public function initCacheProduct(Request $request):RedirectResponse
  621.     {
  622.         $dirCacheJson '../var/cache/' $_ENV['APP_ENV'] . '/products';
  623.         $fileCacheJson $dirCacheJson '/' ApiController::strToHandle($this->user_vendor) . '.json';
  624.         if (\is_file($fileCacheJson)) {
  625.             unlink($fileCacheJson);
  626.         }
  627.         //recharge le json
  628.         $this->forward(ApiController::class . '::getProducts');
  629.         return $this->redirectToRoute("home");
  630.     }
  631.     /**
  632.      * @Route("/mes_menus_et_mes_cartes", name="products")
  633.      * @param UserRepository $userRepository
  634.      * @return Response
  635.      */
  636.     public function products(UserRepository $userRepository):Response
  637.     {
  638.         if(in_array(User::ROLE_USER_OPS,$this->user->getRoles())){
  639.             return $this->redirectToRoute("home");
  640.         }
  641.         //prepare dossier temporaire pour les updload image
  642.         $directoryTmp $this->getParameter("upload_tmp");
  643.         if (!is_dir($directoryTmp)) {
  644.             mkdir($directoryTmp);
  645.         }
  646.         $directoryTmpVendor $directoryTmp ApiController::strToHandle($this->user_vendor) . '/';
  647.         if (is_dir($directoryTmp)) {
  648.             $this->deleteDirectory($directoryTmpVendor);
  649.         }
  650.         $responseJson $this->forward(ApiController::class . '::getSettings', ["type" => "allergens"]);
  651.         $allergens json_decode($responseJson->getContent(), true);
  652.         $vendors $userRepository->getVendors();
  653.         $daysWeek = ["Lundi""Mardi""Mercredi""Jeudi""Vendredi""Samedi""Dimanche"];
  654.         $daysWeekMin = ["Lu""Ma""Me""Je""Ve""Sa""Di"];
  655.         $timesSlot = ["10h - 12h""12h - 14h""14h - 16h""16h - 18h""18h - 20h"];
  656.         $intervalsSlot = [[1011], [1213], [1415], [1617], [1819]];
  657.         //recuperer les produits avec le json de apiController
  658.         $responseJson $this->forward(ApiController::class . '::getProducts');
  659.         $datas json_decode($responseJson->getContent(), true);
  660.         // $types = json_decode($this->forward(ApiController::class . '::getCategories')->getContent(), true);
  661.         $types ApiController::getTypes();
  662.         //  $gammes = ApiController::getTypes();
  663.         //supprimer les produits autres
  664.         $types array_filter($types, function ($element) {
  665.             return ($element["code"] != "XX" && $element["code"] != "09");
  666.         });
  667.         if (!isset($datas["products"])) {
  668.             $datas["products"] = [];
  669.         }
  670.         $typesProductOrder = [
  671.             ["show" => true"title" => "Mes menus""type_slug" => "menu""type" => "Menu""sort" => ["Menu"]],
  672.             ["show" => false"title" => "A la carte""type_slug" => "a-la-carte""type" => "A la carte""sort" => ["Entrée""Plat""Dessert"]],
  673.             ["show" => false"title" => "A partager""type_slug" => "a-partager""type" => "A partager""sort" => ["A partager"]],
  674.             ["show" => false"title" => "Autres articles""type_slug" => "autre-article""type" => "Autre article""sort" => ["Autre article"]],
  675.             ["show" => false"title" => "Vins, sipiritueux et autres alcools""type_slug" => "boissons-alcoolise""type" =>  "Boissons alcoolisé"  "sort" => [ "Vin blanc","Vin rosé","Vin rouge","Bière","Champagne et bulle","Spiritueux","Autre boisson alcoolisée"]],
  676.             ["show" => false"title" => "Boissons non alcoolisees""type_slug" => "boissons-non-alcoolise""type" => "Boissons non alcoolisé""sort" => ["Eau minérale","Soft"]],
  677.         ];
  678.         $listeTypeProducts = [];
  679.         foreach ($typesProductOrder as $type_index => $typesorder) {
  680.             $cptProduct 0;
  681.             $listeTypeProducts[$type_index]["types"] = $typesorder["sort"];
  682.             $listeTypeProducts[$type_index]["type"] = $typesorder["type"];
  683.             $listeTypeProducts[$type_index]["type_slug"] = $typesorder["type_slug"];
  684.             $listeTypeProducts[$type_index]["title"] = $typesorder["title"];
  685.             $listeTypeProducts[$type_index]["show"] = $typesorder["show"];
  686.             foreach ($typesorder["sort"] as $typeorder) {
  687.                 if (isset($datas["types"][$typeorder]) && !empty($datas["types"][$typeorder])) {
  688.                     foreach ($datas["types"][$typeorder] as $product_id) {
  689.                         if (empty($datas["products"][$product_id]["tags"]) || in_array(ApiController::TAG_MENU_ITEM$datas["products"][$product_id]["tags"])) {
  690.                             continue;
  691.                         }
  692.                         // obliger d avoir l offre particulier
  693.                         if(in_array(ApiController::TAG_OFFRE_PARTICULIER$datas["products"][$product_id]["tags"])) {
  694.                             $listeTypeProducts[$type_index]["products"][$product_id] = $datas["products"][$product_id];
  695.                             $cptProduct++;
  696.                         }
  697.                     }
  698.                 }
  699.             }
  700.             $listeTypeProducts[$type_index]["total"] =   $cptProduct;
  701.         }
  702.         return $this->renderHtml('page/products.html.twig', [
  703.             'tag_particulier'=>ApiController::TAG_OFFRE_PARTICULIER,
  704.             'vendors' => $vendors,
  705.             'daysWeekMin' => $daysWeekMin,
  706.             'daysWeek' => $daysWeek,
  707.             'timesSlot' => $timesSlot,
  708.             'intervalsSlot' => $intervalsSlot,
  709.             'allergens' => $allergens,
  710.             'menuItems' => $datas["products"],
  711.             'types_products' => $listeTypeProducts
  712.         ]);
  713.     }
  714.     /**
  715.      * @Route("/mes_jours_d_ouvertures", name="disponibility")
  716.      * @param UserRepository $userRepository
  717.      * @return Response
  718.      */
  719.     public function disponibility(UserRepository $userRepository):Response
  720.     {
  721.         //prepare dossier temporaire pour les updload image
  722.         $directoryTmp $this->getParameter("upload_tmp");
  723.         if (!is_dir($directoryTmp)) {
  724.             mkdir($directoryTmp);
  725.         }
  726.         $directoryTmpVendor $directoryTmp ApiController::strToHandle($this->user_vendor) . '/';
  727.         if (is_dir($directoryTmp)) {
  728.             $this->deleteDirectory($directoryTmpVendor);
  729.         }
  730.         $responseJson $this->forward(ApiController::class . '::getSettings', ["type" => "allergens"]);
  731.         $vendors $userRepository->getVendors();
  732.         $daysWeek = ["Lundi""Mardi""Mercredi""Jeudi""Vendredi""Samedi""Dimanche"];
  733.         $daysWeekMin = ["Lu""Ma""Me""Je""Ve""Sa""Di"];
  734.         //TODO reflechir a gerer les horaires par une base de donnée en postgre pour des configs special pour ic_configs (label,value)?
  735.         $timesSlot = ["10h - 12h""12h - 14h""14h - 16h""16h - 18h""18h - 20h"];//, "20h - 22h"
  736.         $intervalToString = [
  737.             "10-11" => "10h - 12h",
  738.             "12-13" => "12h - 14h",
  739.             "14-15" => "14h - 16h",
  740.             "16-17" => "16h - 18h",
  741.             "18-19" => "18h - 20h"
  742.         ];
  743.         /*,"20-21" => "20h - 22h"*/
  744.         //INFO liste interval autoriser pour la page des disponiblités
  745.         $intervalsSlot = [[1011], [1213], [1415], [1617], [1819]];//, [20, 21]
  746.         //recuperer les produits avec le json de apiController
  747.         $responseJson $this->forward(ApiController::class . '::getProducts');
  748.         $datas json_decode($responseJson->getContent(), true);
  749.         // $types = json_decode($this->forward(ApiController::class . '::getCategories')->getContent(), true);
  750.         $types ApiController::getTypes();
  751.         //supprimer les produits autres
  752.         $types array_filter($types, function ($element) {
  753.             return ($element["code"] != "XX" && $element["code"] != "09");
  754.         });
  755.         if (!isset($datas["products"])) {
  756.             $datas["products"] = [];
  757.         }
  758.         //preparer de l arborescence pour generer un tableau pour le formulaire
  759.         $disponibility = [];
  760.         if (isset($datas["disponibilities"]) && !empty($datas["disponibilities"])) {
  761.             foreach ($datas["disponibilities"] as $type => $dispoDays) {
  762.                 foreach ($intervalsSlot as $intervalSlot) {
  763.                     foreach ($daysWeek as $day) {
  764.                         $index_interval join("-"$intervalSlot);
  765.                         if (isset($dispoDays[$day]) && !empty($dispoDays[$day])) {
  766.                             $dispoHours $dispoDays[$day]["hours"];
  767.                             if(isset( $dispoHours) && !empty( $dispoHours)){
  768.                                 foreach ($dispoHours as $hour) {
  769.                                     if (intVal($hour) >= $intervalSlot[0]  && intVal($hour) < $intervalSlot[1] || intVal($hour) == $intervalSlot[1] ) {
  770.                                         // $disponibility[$type][$keyTimeSlot][$keyDay]["status"]  = true;
  771.                                         $disponibility[$day][$index_interval][$type] = true;
  772.                                     } else {
  773.                                         if (!isset($disponibility[$day][$index_interval][$type])) {
  774.                                             // $disponibility[$type][$keyTimeSlot][$keyDay]["status"] = false;
  775.                                             $disponibility[$day][$index_interval][$type] = false;
  776.                                         }
  777.                                     }
  778.                                 }
  779.                             }else{
  780.                                 $disponibility[$day][$index_interval][$type] = false;
  781.                             }
  782.                         } else {
  783.                             $disponibility[$day][$index_interval][$type]  = false;
  784.                         }
  785.                     }
  786.                 }
  787.             }
  788.         }
  789.         return $this->renderHtml('page/disponibilities.html.twig', [
  790.             'vendors' => $vendors,
  791.             'daysWeekMin' => $daysWeekMin,
  792.             'daysWeek' => $daysWeek,
  793.             'timesSlot' => $timesSlot,
  794.             'intervalToString' => $intervalToString,
  795.             'disponibility' => $disponibility
  796.         ]);
  797.     }
  798.     /**
  799.      * @Route("/mes_menus_et_mes_cartes/edit/{id?}", name="product_edit")
  800.      * @param null $id
  801.      * @param UserRepository $userRepository
  802.      * @return Response
  803.      */
  804.     public function productForm($id nullUserRepository $userRepository):Response
  805.     {
  806.         if(in_array(User::ROLE_USER_OPS,$this->user->getRoles())){
  807.             return $this->redirectToRoute("home");
  808.         }
  809.         $directoryTmp $this->getParameter("upload_tmp");
  810.         if (!is_dir($directoryTmp)) {
  811.             mkdir($directoryTmp);
  812.         }
  813.         $directoryTmpVendor $directoryTmp ApiController::strToHandle($this->user_vendor) . '/';
  814.         if (is_dir($directoryTmp)) {
  815.             $this->deleteDirectory($directoryTmpVendor);
  816.         }
  817.         $title_page "Ajouter un produit";
  818.         $theme $_GET["t"] ?? "autre-article";
  819.         $typesProductOrder = [
  820.             "add" => "Ajouter un produit",
  821.             "menu" => "ajouter un menu",
  822.             "a-la-carte" => "ajouter un produit à la carte",
  823.             "entree" => "ajouter un produit à la carte",
  824.             "plat" => "ajouter un produit à la carte",
  825.             "dessert" => "ajouter un produit à la carte",
  826.             "a-partager" => "ajouter un produit à partager",
  827.             "autre-article" => "ajouter un produit",
  828.             "boissons-alcoolise" => "ajouter un vin, sipiritueux et autre alcool",
  829.             "boissons-non-alcoolise" => "ajouter une boisson non alcoolisée"
  830.         ];
  831.         //recuperer les produits avec le json de apiController
  832.         $responseJson $this->forward(ApiController::class . '::getProducts');
  833.         $datas json_decode($responseJson->getContent(), true);
  834.         $types ApiController::getTypes();
  835.         $menu_items = [];
  836.         if (is_null($id) || !isset($datas["products"][$id]) || empty($datas["products"][$id])) {
  837.             if ($theme != "a-la-carte") {
  838.                 $types_selected array_filter($types, function ($type) use ($theme) {
  839.                     return $type["slug"] ==  $theme;
  840.                 });
  841.                 $types_selected array_shift($types_selected);
  842.             }
  843.             $product = ["id" => "Add","title" => "","disponibility_dates" => "","max_per_day" => "","price" => "","type" =>   $types_selected["type"] ?? "","allergens" => "","pack" => [],"description" => ""];
  844.             $title_page =  $typesProductOrder[$theme];
  845.         } else {
  846.             $product $datas["products"][$id];
  847.             $product["allergens"] = array_unique($product["allergens"]);
  848.             $list_menu_items = isset($datas["menu_item"]) && !empty($datas["menu_item"]) ? $datas["menu_item"] : [];
  849.             $menu_items array_filter(
  850.                 $datas["products"],
  851.                 function ($prod) use ($list_menu_items) {
  852.                     return in_array($prod["id"], $list_menu_items);
  853.                 }
  854.             );
  855.             $title_page =   $typesProductOrder[$product["type_slug"]] ?? $title_page;
  856.             $theme $product["type_slug"];
  857.         }
  858.         $types_theme = [];
  859.         switch ($theme){
  860.             case "a-la-carte":
  861.                 $types_theme array_filter($types, function ($type) {
  862.                     return $type["slug"] == "a-la-carte";
  863.                 });
  864.                 break;
  865.             case "boissons-alcoolise":
  866.                 $types_theme array_filter($types, function ($type) {
  867.                     return $type["slug"] == "boissons-alcoolise";
  868.                 });
  869.                 break;
  870.             case "boissons-non-alcoolise":
  871.                 $types_theme array_filter($types, function ($type) {
  872.                     return $type["slug"] == "boissons-non-alcoolise";
  873.                 });
  874.                 break;
  875.             case "autre-article":
  876.                 $types_theme $types;
  877.                 break;
  878.         }
  879.         $types_menuitem = ["Entrée","Plat","Dessert","A partager","Autre boisson alcoolisée","Bière","Champagne et bulle","Cocktail","Vin blanc","Vin rosé","Vin rouge","Spiritueux","Eau minérale","Soft"];
  880.         $types_title=["Menu"=>"Nos Menus","A partager"=> "A partager","Entrée"=>"Nos Entrées","Plat"=>"Nos Plats","Dessert"=>"Nos Desserts","Vin blanc"=>"Nos Vins Blancs","Vin rosé"=>"Nos Vins Rosés","Vin rouge"=>"Nos Vins Rouges","Soft"=>"Nos softs et eaux minérales","Eau minérale"=>"Nos softs et eaux minérales","Champagne et bulle"=>"Nos champagnes et bulles","Spiritueux"=>"Nos spiritueux et autres boissons","Bière"=>"Nos spiritueux et autres boissons","Autre boisson alcoolisée"=>"Nos spiritueux et autres boissons","Autre article"=>"Nos autres articles"];
  881.         //  "Menu"=>"Nos autres articles"
  882.         return $this->renderHtml('page/product_form.html.twig', [
  883.             'user' =>  $this->user,
  884.             'types' =>  $types,
  885.             'types_theme' => $types_theme,
  886.             'types_menuitem' => $types_menuitem,
  887.             'product' =>  $product,
  888.             'theme' =>  $theme,
  889.             'title_page' =>  $title_page,
  890.             'types_title' =>  $types_title,
  891.             'menu_items' =>  $menu_items
  892.         ]);
  893.     }
  894.     /**
  895.      * @Route("/mes_menus_et_mes_cartes/update", name="update_product")
  896.      * @param Request $request
  897.      * @return RedirectResponse
  898.      */
  899.     public function updateProduct(Request $request):RedirectResponse
  900.     {
  901.         //Check l autorisation
  902.         if (!isset($this->user) || empty($this->user)) {
  903.             return $this->redirectToRoute("app_login");
  904.         }
  905.         if(in_array(User::ROLE_USER_OPS,$this->user->getRoles())){
  906.             return $this->redirectToRoute("home");
  907.         }
  908.         //recuperation des informations du formulaire
  909.         $formDatas $request->request->all();
  910.         $formDatas["tags"] = explode("|"$formDatas["tags"]);
  911.         if (isset($formDatas["allergens"]) && !empty($formDatas["allergens"])) {
  912.             foreach ($formDatas["allergens"] as $allergen) {
  913.                 $formDatas["tags"][] = ApiController::TAG_PREFIX_ALLERGEN $allergen;
  914.             }
  915.             unset($formDatas["allergens"]);
  916.         }
  917.         // translate dataform shelfs to tags shopify
  918.         if (isset($formDatas["shelfs"]) && !empty($formDatas["shelfs"])) {
  919.             foreach ($formDatas["shelfs"] as $shelf) {
  920.                 $formDatas["tags"][] = ApiController::TAG_PREFIX_SHELF $shelf;
  921.             }
  922.             unset($formDatas["shelfs"]);
  923.         }
  924.         // Changer les virgule dans les titre en 2 underscores
  925.         if (isset($formDatas["title"]) && !empty($formDatas["title"])   && strpos($formDatas["title"],",")!==-1) {
  926.             $formDatas["title"]= str_replace(",","__",$formDatas["title"]);
  927.         }
  928.         //init variable
  929.         $reps = [];
  930.         //si pack existe
  931.         $pack_tags = [];
  932.         $packsDel=[];
  933.         $post_menu_item = [];
  934.         //si pack existe
  935.         if (isset($formDatas["pack"]) && !empty($formDatas["pack"])) {
  936.             $oldPack=[];
  937.             if(isset($formDatas["id"]) && !empty($formDatas["id"])){
  938.                 $allTagsPackTmp =   $this->controllerApiTiptoque('getTags', ["type" => "pack"]);
  939.                 if(isset( $allTagsPackTmp[$formDatas["id"]]) && !empty(isset($allTagsPackTmp[$formDatas["id"]]))){
  940.                     $oldPack$allTagsPackTmp[$formDatas["id"]];
  941.                 }
  942.             }
  943.             $newPack array_keys($formDatas["pack"]);
  944.             $packsDel array_diff($oldPack,$newPack);
  945.             foreach ($formDatas["pack"] as $menuItem) {
  946.                 if(!isset($menuItem["title"])){
  947.                     continue;
  948.                 }
  949.                 $menuItem["tags"][] = ApiController::TAG_MENU_ITEM;
  950.                 $menuItem["tags"][] = ApiController::TAG_OFFRE_PARTICULIER;
  951.                 if(isset($formDatas["id"]) && !empty($formDatas["id"])){
  952.                     $menuItem["tags"][] = ApiController::TAG_PREFIX_MAIN.$formDatas["id"];
  953.                 }
  954.                 //si menu_item id ajout du produit dans shopify et mise en place de reps pour le json
  955.                 if (isset($menuItem["id"]) && !empty($menuItem["id"])) {
  956.                     $menuItem_id $menuItem["id"];
  957.                     $pack_tags[] = ApiController::TAG_PREFIX_PACK $menuItem["index"] . "|" $menuItem_id "_" $menuItem["handle"];
  958.                     unset($menuItem["id"]);
  959.                     $datasJson["product"] = $menuItem;
  960.                     //TODO faut il verifier si le produit a ete modifier?
  961.                     $reps[] =  $this->controllerApiTiptoque('putProduct', ["id" => $menuItem_id], json_encode($datasJson));
  962.                 } else {
  963.                     $datasJson["product"] = $menuItem;
  964.                     $resProduit $this->controllerApiTiptoque('postProduct', [], json_encode($datasJson));
  965.                     $pack_tags[] = ApiController::TAG_PREFIX_PACK $menuItem["index"] . "|" $resProduit["product"]["id"] . "_" $resProduit["product"]["handle"];
  966.                     $reps[] = $resProduit;
  967.                     //variable pour preparer l update avec le tags MAIN|%id product%
  968.                     $post_menu_item[]=$resProduit["product"];
  969.                 }
  970.             }
  971.             $formDatas["tags"] = array_merge($formDatas["tags"], $pack_tags);
  972.             unset($formDatas["pack"]);
  973.         }
  974.         //preparation des valeur pour le produit principal
  975.         $formDatas["max_per_day"] = ($formDatas["max_per_day"] == "") ? "-1" $formDatas["max_per_day"];
  976.         $formDatas["disponibility_dates"] = $formDatas["dispo_date"];
  977.         unset($formDatas["dispo_date_start"]);
  978.         unset($formDatas["dispo_date_end"]);
  979.         unset($formDatas["put_product"]);
  980.         if (isset($formDatas["id"]) && !empty($formDatas["id"])) {
  981.             $pId $formDatas["id"];
  982.             unset($formDatas["id"]);
  983.             $datasJson["product"] = $formDatas;
  984.             $prodMain  $reps[] =   $this->controllerApiTiptoque('putProduct', ["id" => $pId], json_encode($datasJson));
  985.             //info Suppression des menu_items qui sont supprimer
  986.             if(isset($packsDel) && !empty($packsDel)){
  987.                 foreach ($packsDel as $packDel){
  988.                     $this->controllerApiTiptoque('delProduct', ["id" => $packDel"force" => true]);//
  989.                 }
  990.             }
  991.         } else {
  992.             $datasJson["product"] = $formDatas;
  993.             $prodMain  $reps[] =  $this->controllerApiTiptoque('postProduct', [], json_encode($datasJson));
  994.             //info update les pack avec le tag MAIN|%id%
  995.             if (isset($post_menu_item) && !empty($post_menu_item)) {
  996.                 foreach ($post_menu_item as $menuItem) {
  997.                     $menuItem["tags"][] = ApiController::TAG_PREFIX_MAIN.$prodMain["product"]["id"];
  998.                     $datasJson["product"] = $menuItem;
  999.                     $this->controllerApiTiptoque('putProduct', ["id" => $menuItem["id"]], json_encode($datasJson));
  1000.                 }
  1001.             }
  1002.         }
  1003.         if((strpos(  $prodMain["product"]["type"],"Dispo")===false)){
  1004.             return $this->redirectToRoute("product_edit",["id"=>$prodMain["product"]["id"]]);
  1005.         }else{
  1006.             return $this->redirectToRoute("products");
  1007.         }
  1008.     }
  1009.     /**
  1010.      * @Route("/mes_menus_et_mes_cartes/delete", name="delete_product")
  1011.      * @param Request $request
  1012.      * @return RedirectResponse
  1013.      */
  1014.     public function deleteProduct(Request $request):RedirectResponse
  1015.     {
  1016.         if (!isset($this->user) || empty($this->user)) {
  1017.             return $this->redirectToRoute("app_login");
  1018.         }
  1019.         if(in_array(User::ROLE_USER_OPS,$this->user->getRoles())){
  1020.             return $this->redirectToRoute("home");
  1021.         }
  1022.         $pId $request->query->get("product_id"null);
  1023.         //info récupérer le produit et verifier si il y a des menus_items pour les supprimer en cascade
  1024.         $responseProduct $this->controllerApiTiptoque('getProduct',["id"=>$pId]);
  1025.         if(isset($responseProduct["product"]["pack"]) && !empty($responseProduct["product"]["pack"])){
  1026.             foreach ($responseProduct["product"]["pack"] as $menu_item_id){
  1027.                 $this->controllerApiTiptoque("delProduct", ["id" => $menu_item_id"force" => true]);
  1028.             }
  1029.         }
  1030.         $this->controllerApiTiptoque('delProduct', ["id" => $pId"force" => true]);
  1031.         return $this->redirectToRoute("products");
  1032.     }
  1033.     /**
  1034.      * @Route("/imageDelete", name="imageDelete")
  1035.      * @param Request $request
  1036.      * @return JsonResponse
  1037.      */
  1038.     public function imageDelete(Request $request):JsonResponse
  1039.     {
  1040.         //supprimer image d'un produit
  1041.         $image_id $request->request->get("iid");
  1042.         $produit_id $request->request->get("pid");
  1043.         if (is_numeric($image_id)) {
  1044.             // var_dump("delete image shopify", $produit_id, $image_id);
  1045.             $reponseDeleteImage $this->controllerApiTiptoque('delImage', ["pid" => $produit_id"id" => $image_id]);
  1046.             if(is_null($reponseDeleteImage)){
  1047.                 return $this->json(["error"=> ["pid" => $produit_id"id" => $image_id,"reponse"=>$reponseDeleteImage]], 404 );
  1048.             }
  1049.             return $this->json(["message"=>$reponseDeleteImage], 200);
  1050.             //  return $this->json(["message" => "suppression de image id:" . $image_id], 200);
  1051.         } else {
  1052.             $directoryTmp $this->getParameter("upload_tmp");
  1053.             $directoryTmpVendor $directoryTmp ApiController::strToHandle($this->user_vendor) . '/';
  1054.             $directoryTmpVendorProduct $directoryTmpVendor $produit_id '/';
  1055.             unlink($directoryTmpVendorProduct $image_id);
  1056.             //si le dossier vide le supprimer ??
  1057.             $countImg count(scandir($directoryTmpVendorProduct ))-2;
  1058.             if( $countImg === 0){
  1059.                 $this->deleteDirectory$directoryTmpVendor);
  1060.             }
  1061.             return $this->json(["message" => "suppression de image " $image_id " dans le cache"], 200);
  1062.         }
  1063.     }
  1064.     /**
  1065.      * @Route("/file-upload", name="tmpUploadFile")
  1066.      * @param Request $request
  1067.      * @return JsonResponse
  1068.      */
  1069.     public function tmpUploadFile(Request $request):JsonResponse
  1070.     {
  1071.         $produit_id $request->request->get("pid"null);
  1072.         $produit_id = ($produit_id == "_add" || $produit_id == "Add")  ? "add" $produit_id;
  1073.         $directoryTmp $this->getParameter("upload_tmp");
  1074.         if (!is_dir($directoryTmp)) {
  1075.             mkdir($directoryTmp);
  1076.         }
  1077.         $directoryTmpVendor $directoryTmp ApiController::strToHandle($this->user_vendor);
  1078.         if (!is_dir($directoryTmpVendor)) {
  1079.             mkdir($directoryTmpVendor);
  1080.         }
  1081.         $directoryTmpVendorProduct $directoryTmpVendor '/' $produit_id;
  1082.         if (!is_dir($directoryTmpVendorProduct)) {
  1083.             mkdir($directoryTmpVendorProduct);
  1084.         }
  1085.         if (is_null($produit_id)) {
  1086.             $produit_id "add";
  1087.         }
  1088.         $file =  $request->files->get("file");
  1089.         $file->move($directoryTmpVendorProduct,$file->getClientOriginalName());
  1090.         return $this->json(["dir"=> $directoryTmpVendor,"filename" => $file->getClientOriginalName() , "id" => $produit_id], 200);
  1091.     }
  1092.     /**
  1093.      * suppression d'un dossier et ses fichiers
  1094.      * @param $dir
  1095.      * @return bool
  1096.      */
  1097.     private function deleteDirectory($dir):bool
  1098.     {
  1099.         if (!file_exists($dir)) {return true;}
  1100.         if (!is_dir($dir)) { return unlink($dir); }
  1101.         foreach (scandir($dir) as $item) {
  1102.             if ($item == '.' || $item == '..') {
  1103.                 continue;
  1104.             }
  1105.             if (!$this->deleteDirectory($dir DIRECTORY_SEPARATOR $item)) {
  1106.                 return false;
  1107.             }
  1108.         }
  1109.         return rmdir($dir);
  1110.     }
  1111.     /**
  1112.      * @param string $function
  1113.      * @param array $path
  1114.      * @param array $datasJson
  1115.      * @return mixed
  1116.      */
  1117.     private function controllerApiTiptoque($function "getProducts",$path = [],$datasJson = [])
  1118.     {
  1119.         $request = new Request([], [], [], [], [], [], $datasJson);
  1120.         $request->headers->set('content-type'"application/json");
  1121.         $path['_controller'] = ApiController::class . '::' $function;
  1122.         $subRequest $request->duplicate([], null$path);
  1123.         $response $this->container->get('http_kernel')->handle($subRequestHttpKernelInterface::SUB_REQUEST);
  1124.         // $response = $this->forward(ApiController::class . '::' . $function, $path);
  1125.         // var_dump($response->getContent());exit();
  1126.         return isset($response) && !empty($response) ? \json_decode($response->getContent(), true) : \json_decode('{"message":"Error not response"}'true);
  1127.     }
  1128.     /**
  1129.      * @param string $entree
  1130.      * @param string $plat
  1131.      * @param string $dessert
  1132.      * @return string
  1133.      */
  1134.     public function menuToDescription(string $entree,string $plat,string $dessert): string
  1135.     {
  1136.         $description "";
  1137.         if ($entree != "") {
  1138.             $description .= "<entree><span>Entrée :</span> <descr>" $entree "</descr></entree><br>";
  1139.         }
  1140.         if ($plat != "") {
  1141.             $description .= "<plat><span>Plat :</span> <descr>" $plat "</descr></plat><br>";
  1142.         }
  1143.         if ($dessert != "") {
  1144.             $description .= "<dessert><span>Dessert :</span> <descr>" $dessert "</descr></dessert>";
  1145.         }
  1146.         return $description;
  1147.     }
  1148. }