src/Flexy/ShopBundle/Service/FlexyShopProvider.php line 1000

  1. <?php
  2. namespace App\Flexy\ShopBundle\Service;
  3. use App\Entity\Settings;
  4. use App\Flexy\ShopBundle\Entity\Customer\Customer;
  5. use App\Flexy\ShopBundle\Entity\Order\Order;
  6. use App\Flexy\ShopBundle\Entity\Promotion\Coupon;
  7. use DateTime;
  8. use Doctrine\ORM\EntityManagerInterface;
  9. use Symfony\Component\HttpFoundation\RequestStack;
  10. class FlexyShopProvider{
  11.     private $messages = [];
  12.     public function __construct(
  13.         private readonly EntityManagerInterface $em, 
  14.         private readonly RequestStack $requestStack,
  15.         private readonly FlexyShippingProvider $flexyShippingProvider
  16.         )
  17.     {
  18.     }
  19.     public function useCoupon(Order $order,$codeCoupon = null){
  20.         $coupon = $this->em->getRepository(Coupon::class)->findOneBy(["code"=>$codeCoupon]);
  21.         $currentDate = new \DateTime();
  22.         $isCouponOkey=false;
  23.         $result = [
  24.             "coupon"=>$coupon,
  25.             "type"=>"applyCoupon",
  26.             "message"=>"Aucun coupon trouvé",
  27.             "messageHTML"=>'<div class="alert alert-warning" >Aucun coupon trouvé !</div>'
  28.             ];
  29.         if($coupon){
  30.             if(!$order->getCustomer()){
  31.                 $result = [
  32.                     "coupon"=>$coupon,
  33.                     "type"=>"applyCoupon",
  34.                     "message"=>"Merci de choisir un client",
  35.                     "messageHTML"=>'<div class="alert alert-warning" >Merci de choisir un client !</div>'
  36.                     ];
  37.             }
  38.             if($coupon->getType() == "once_eachuser"){
  39.                 if(count($coupon->getAllowedCustomers()) > 0){
  40.                     
  41.                 }
  42.                 
  43.                 if($coupon->getAllowedCustomers()->contains($order->getCustomer())){
  44.                     $isCouponOkey = true;
  45.                 }
  46.             }else{
  47.                 $isCouponOkey = true;
  48.             }
  49.           
  50.             
  51.             if(
  52.                 ( $coupon->getUsageLimit() != null and count($coupon->getOrders()) < $coupon->getUsageLimit() )   or 
  53.                 ( $coupon->getEndAt() != null and $currentDate < $coupon->getEndAt() )
  54.             ){
  55.                 if($isCouponOkey){
  56.                     $result=[
  57.                         "coupon"=>$coupon,
  58.                         "type"=>"applyCoupon",
  59.                         "message"=>"Coupon Appliqué",
  60.                         "messageHTML"=>'<div class="alert alert-success" >Code coupon Appliqué  !</div>'
  61.                     ];
  62.                     $order->setCoupon($coupon);
  63.                 }
  64.                 
  65.             }else{
  66.                 $result=[
  67.                     "coupon"=>null,
  68.                     "type"=>"applyCoupon",
  69.                     "message"=>"Coupon exipré",
  70.                     "messageHTML"=>'<div class="alert alert-danger" >Code coupon expiré  !</div>'
  71.                 ];
  72.                 
  73.             }
  74.         }
  75.         return $result;
  76.     }
  77.     
  78.     public function getOrderExtraInfosOLD(Order $order,$initDates = false){
  79.         $settings =  $this->em->getRepository(Settings::class)->findOneBy(["code"=>"main"]);
  80.         $excludeDates = array_column($settings->getExcludeDates(), 'date');
  81.         
  82.         $daysInFrench = [
  83.                 
  84.             "Monday"=>"Lundi",
  85.             "Tuesday"=>"Mardi",
  86.             "Wednesday"=>"Mercredi",
  87.             "Thursday"=>"Jeudi",
  88.             "Friday"=>"Vendredi",
  89.             "Saturday"=>"Samedi",
  90.             "Sunday"=>"Dimanche",
  91.         ];
  92.         
  93.         
  94.         if($order->getStartProcessingAt() and $order->getShippingMethod()){
  95.             
  96.             //$processingDuration = $order->getShippingMethod()->getProcessingDuration();
  97.             //$preparationDuration = $order->getShippingMethod()->getPreparationDuration();
  98.             //$shippingDurationDuration = $order->getShippingMethod()->getShippingDuration();
  99.             $currentDateTime = new \DateTime();
  100.             $shippingDurationToMinutes = $order->getShippingMethod()->getShippingDuration() * 60;
  101.             
  102.             
  103.             $preparationDurationToMinutes = $order->getShippingMethod()->getPreparationDuration() * 60;
  104.             
  105.             // NOTE : Check If ShippingMethod or DeliveryType Changed
  106.             //dd($this->requestStack->getSession()->get("shippingMethodId"));
  107.             
  108.             
  109.             if(
  110.                 $this->requestStack->getSession()->get("shippingMethodId") != $order->getShippingMethod()->getId() or 
  111.                 $this->requestStack->getSession()->get("deliveryType") != $order->getDeliveryType() or 
  112.                 $this->requestStack->getSession()->get("orderStartProcessingAt") != $order->getStartProcessingAt()
  113.                 
  114.             )
  115.                 {
  116.                    
  117.                     //$order->setStartProcessingAt(new \DateTime());
  118.                     //dd($deliveryAt_process);
  119.                 }
  120.                 $deliveryAt_process = clone $order->getStartProcessingAt();
  121.             
  122.                
  123.             
  124.             //
  125.             
  126.             if( $order->getStartProcessingAt()->format("Y-m-d") == $currentDateTime->format("Y-m-d") and 
  127.             ($order->getStartProcessingAt() < $currentDateTime) ){
  128.                 $deliveryAt_process->modify($currentDateTime->format("H:i"));
  129.             }
  130.              
  131.             
  132.             
  133.             
  134.             
  135.             if($deliveryAt_process->format("H:i") == "00:00" and  $deliveryAt_process->format("d") == $currentDateTime->format("d") ){
  136.                 $deliveryAt_process->modify($currentDateTime->format("H:i"));
  137.             }
  138.             
  139.            
  140.             
  141.             if(
  142.                 (int)$deliveryAt_process->format("d") > (int)$currentDateTime->format("d") and 
  143.                 (int)$deliveryAt_process->format("H") < (int)$settings->getStartWorkAt()->format("H") 
  144.                 ){
  145.                 $deliveryAt_process->modify($settings->getStartWorkAt()->format("H:i"));
  146.             }
  147.             
  148.             
  149.             
  150.             
  151.             
  152.             
  153.             if($deliveryAt_process->format("i") != "00" ){
  154.                 $deliveryAt_process->modify(" + 1 hours ". $deliveryAt_process->format("H").":00");
  155.                 //$deliveryAt_process->modify(" + ".$preparationDurationToMinutes." minutes");
  156.             }
  157.             
  158.             
  159.             //dd( $deliveryAt_process);
  160.             
  161.             //dd($deliveryAt_process);
  162.             $startDateTimeWorkChecker = clone $deliveryAt_process;
  163.             
  164.             $startDateTimeWorkChecker->modify($settings->getStartWorkAt()->format("H:i"));
  165.             $startDateTimeWorkCheckerNextDay = clone $startDateTimeWorkChecker;
  166.             $startDateTimeWorkCheckerNextDay->modify("next day ".$settings->getStartWorkAt()->format("H:i"));
  167.             $endDateTimeWorkChecker = clone $deliveryAt_process;
  168.             $endDateTimeWorkChecker->modify($settings->getEndWorkAt()->format("H:i"));
  169.            
  170.             if(
  171.                 (int)$deliveryAt_process->format("H") >= 0 and
  172.                  (int)$deliveryAt_process->format("H") < (int)$settings->getEndWorkAt()->format("H") and 
  173.                  (int)$deliveryAt_process->format("H") < (int)$settings->getStartWorkAt()->format("H")
  174.                  
  175.                  ){
  176.                 $deliveryAt_process->modify($settings->getStartWorkAt()->format("H:i"));
  177.             }
  178.             
  179.             
  180.             if(($order->getDeliveryType() == "collecte-and-delivery" || $order->getDeliveryType() == "collecte") 
  181.              
  182.             ){
  183.                 $deliveryAt_process->modify(" + " . $order->getShippingMethod()->getPreparationDuration() . " hours");
  184.             }
  185.             
  186.             
  187.             $deliveryAt_process_max = clone $deliveryAt_process;
  188.             $deliveryAt_process_max->modify(" + " . $shippingDurationToMinutes . " minutes");
  189.             if($deliveryAt_process_max >= $endDateTimeWorkChecker and $deliveryAt_process_max < $startDateTimeWorkCheckerNextDay ){
  190.             
  191.                 $deliveryAt_process = clone $startDateTimeWorkCheckerNextDay;
  192.                 
  193.              if(($order->getDeliveryType() == "collecte-and-delivery" || $order->getDeliveryType() == "collecte") 
  194.              ){
  195.                  $deliveryAt_process->modify(" + " . $order->getShippingMethod()->getPreparationDuration() . " hours");
  196.              }
  197.             
  198.             
  199.            
  200.             
  201.             
  202.                 $deliveryAt_process_max = clone $deliveryAt_process;
  203.                 
  204.                 $deliveryAt_process_max->modify(" + " . $shippingDurationToMinutes . " minutes");
  205.                 
  206.             }
  207.             
  208.             
  209.             
  210.             while ( in_array($deliveryAt_process->format("l"),$settings->getExcludeDays()) or  in_array($deliveryAt_process->format("Y-m-d"),$excludeDates) ) {
  211.                 $keyExcludedDateProccessing = array_search($deliveryAt_process->format("Y-m-d"), array_column($settings->getExcludeDates(), 'date'));
  212.                 $excludedDateProccessing = $settings->getExcludeDates()[$keyExcludedDateProccessing];
  213.                 
  214.                 $keyExcludedDateShipping = array_search($deliveryAt_process->format("Y-m-d"), array_column($settings->getExcludeDates(), 'date'));
  215.                 if(in_array($deliveryAt_process->format("l"),$settings->getExcludeDays())){
  216.                     $this->messages[]="<b><i>".$daysInFrench[$deliveryAt_process->format("l")] . "</i></b> Est un jour de repos, Collecte a été décalé pour le jour suivant";
  217.                 }else{
  218.                     $this->messages[]="Date <b><i>".$deliveryAt_process->format("d-m-Y")."</i></b> pour la collecte a été décalé pour le jour suivant, a l'occasion de <b><i>".$excludedDateProccessing["label"]."</i></b>";
  219.                 }
  220.                 $deliveryAt_process->modify("+ 1 day");
  221.                 $deliveryAt_process_max->modify("+ 1 day");
  222.             }
  223.             if($order->getDeliveryType() == "on-store" ){
  224.             while ( 
  225.                 in_array($deliveryAt_process->format("H"),$settings->getExcludeHours()) || 
  226.                 in_array($deliveryAt_process_max->format("H"),$settings->getExcludeHours()) 
  227.                 ) {
  228.                 $deliveryAt_process->modify("+ 1 Hour");
  229.                 $deliveryAt_process_max->modify("+ 1 Hour");
  230.             }
  231.         }
  232.             
  233.             
  234.             
  235.             
  236.             $deliveryAt_prep = clone $deliveryAt_process_max;
  237.             $deliveryAt_prep->modify("+ ".$order->getShippingMethod()->getProcessingDuration()." hours");
  238.             // Note : Add preperationDuration after the ProcessingDuration exp : Classic add 4h after 48h, Express add 2h after 7h
  239.             // if($order->getDeliveryType() == "collecte-and-delivery" || $order->getDeliveryType() == "delivery"){
  240.             //     $totalHoursShipping = $order->getShippingMethod()->getProcessingDuration() + $order->getShippingMethod()->getPreparationDuration();
  241.             //     $deliveryAt_prep->modify("+ ".$totalHoursShipping." hours");
  242.             // }
  243.             
  244.             
  245.             $intervalHoursCounter = $order->getShippingMethod()->getProcessingDuration();
  246.             $intervalDatesEndWork=0;
  247.             $differenceHours=0;
  248.             
  249.             
  250.             
  251.             
  252.             
  253.             
  254.             
  255.             
  256.             $deliveryAt_shipping = clone $deliveryAt_prep;
  257.             //dd($deliveryAt_shipping);
  258.             if((int)$deliveryAt_process->format("d") < (int)$deliveryAt_shipping->format("d")){
  259.                 $deliveryAt_shipping->modify($deliveryAt_process->format("H:i"));
  260.             }
  261.             
  262.             
  263.             if($order->getDeliveryType() == "collecte-and-delivery" || $order->getDeliveryType() == "delivery" ){
  264.                 //$deliveryAt_shipping->modify(" + " . $order->getShippingMethod()->getPreparationDuration() . " hours");
  265.                 
  266.             }
  267.             
  268.            
  269.             
  270.             $deliveryAt_shipping_max = clone $deliveryAt_shipping;
  271.             $deliveryAt_shipping_max->modify(" + " . $shippingDurationToMinutes . " minutes");
  272.             $deliveryAt_shipping_max_checker = clone $deliveryAt_shipping_max;
  273.             $deliveryAt_shipping_max_checker->modify($endDateTimeWorkChecker->format("H:i"));
  274.             
  275.             
  276.             
  277.            
  278.             
  279.             $startDateTimeWorkCheckerLastDay = clone $deliveryAt_shipping_max;
  280.             $startDateTimeWorkCheckerLastDay->modify("next day ".$settings->getStartWorkAt()->format("H:i"));
  281.             
  282.             $endDateTimeWorkCheckerLastDay = clone $deliveryAt_shipping_max;
  283.             $endDateTimeWorkCheckerLastDay->modify($settings->getEndWorkAt()->format("H:i"));
  284.             
  285.             //dd($deliveryAt_shipping_max);
  286.             if(
  287.                 ($deliveryAt_shipping_max > $endDateTimeWorkCheckerLastDay and $deliveryAt_shipping_max < $startDateTimeWorkCheckerLastDay) or
  288.                 ($deliveryAt_shipping_max->format("d")==$startDateTimeWorkCheckerLastDay->format("d") )
  289.                 ){
  290.                 $deliveryAt_shipping = clone $startDateTimeWorkCheckerLastDay;
  291.                 //$deliveryAt_shipping->modify(" + ".$differenceHours." hours");
  292.                 
  293.             }
  294.             
  295.             // add interval rest
  296.             $counterHours = 0;
  297.             $currentHour =  (int)$deliveryAt_process_max->format("H");
  298.             $limitHour = (int)$settings->getEndWorkAt()->format("H");
  299.             
  300.             while($currentHour < $limitHour){
  301.                 $counterHours =$counterHours + 1;
  302.                 $currentHour = $currentHour + 1;
  303.             }
  304.             
  305.             // For example Express shipping 7h
  306.             if($intervalHoursCounter > $counterHours and $intervalHoursCounter < 24){
  307.                 $deliveryAt_shipping = clone $deliveryAt_process_max;
  308.                 $deliveryAt_shipping->modify("next day ".$settings->getStartWorkAt()->format("H:i"));
  309.                 $difference = $intervalHoursCounter - $counterHours;
  310.                 $deliveryAt_shipping->modify("+ ".$difference." hours");
  311.             }
  312.             //dd($counterHours);
  313.             
  314.             
  315.             $deliveryAt_shipping_max = clone $deliveryAt_shipping;
  316.             $deliveryAt_shipping_max->modify(" + " . $shippingDurationToMinutes . " minutes");
  317.             
  318.             //dd($order->getStartDeliveryAt());
  319.             /*
  320.             if($order->getStartDeliveryAt()>$deliveryAt_shipping_max){
  321.                 $deliveryAt_shipping->modify($order->getStartDeliveryAt()->format("Y-m-d"));
  322.                 $deliveryAt_shipping_max->modify($order->getStartDeliveryAt()->format("Y-m-d"));
  323.             }*/
  324.             
  325.             while ( in_array($deliveryAt_shipping->format("l"),$settings->getExcludeDays()) or in_array($deliveryAt_shipping->format("Y-m-d"),$excludeDates) ) {
  326.                 $keyExcludedDateShipping = array_search($deliveryAt_shipping->format("Y-m-d"), array_column($settings->getExcludeDates(), 'date'));
  327.                 $excludedDateShipping = $settings->getExcludeDates()[$keyExcludedDateShipping];
  328.                 if(in_array($deliveryAt_shipping->format("l"),$settings->getExcludeDays())){
  329.                     $this->messages[]= "<b><i>".$daysInFrench[$deliveryAt_shipping->format("l")] . "</i></b> Est un jour de repos, Livraison a été décalé pour le jour suivant";
  330.                 }else{
  331.                     $this->messages[]="Date <b><i>".$deliveryAt_shipping->format("d-m-Y")."</i></b> pour la livraison a été décalé pour le jour suivant, a l'occasion de <b><i>".$excludedDateShipping["label"]."</i></b>";
  332.                 }
  333.                 
  334.                 
  335.                 
  336.                 $deliveryAt_shipping->modify("+ 1 day");
  337.                 $deliveryAt_shipping_max->modify("+ 1 day");
  338.             }
  339.             if($order->getDeliveryType() == "on-store" ){
  340.             while ( 
  341.                 in_array($deliveryAt_shipping->format("H"),$settings->getExcludeHours()) || 
  342.                 in_array($deliveryAt_shipping_max->format("H"),$settings->getExcludeHours()) 
  343.                 ) {
  344.                 $deliveryAt_shipping->modify("+ 1 Hour");
  345.                 $deliveryAt_shipping_max->modify("+ 1 Hour");
  346.             }
  347.         }
  348.         $interval = $deliveryAt_shipping->diff($deliveryAt_process);
  349.             
  350.             $intevalHours = $interval->h ;
  351.             $intevalDaysToHours = $interval->d * 24;
  352.             $totalIntervalHours = $intevalHours + $intevalDaysToHours;
  353.             if($totalIntervalHours >  $order->getShippingMethod()->getProcessingDuration() and $totalIntervalHours > 24){
  354.                 $deliveryAt_shipping->modify($settings->getStartWorkAt()->format("H:i"));
  355.             }
  356.             $ifDelayMoreThanEnough = false;
  357.             /**
  358.              * BySamir Test Init Time Before
  359.              */
  360.  
  361.  
  362.             if($deliveryAt_process < $order->getStartProcessingAt()){
  363.              $deliveryAt_process = clone $order->getStartProcessingAt();
  364.              $deliveryAt_process_max = clone $deliveryAt_process;
  365.              $deliveryAt_process_max->modify(" + " . $shippingDurationToMinutes . " minutes");
  366.  
  367.          }
  368.      if($this->requestStack->getSession()->get("orderStartProcessingAt")  ){
  369.  
  370.          //dd($this->requestStack->getSession()->get("orderStartProcessingAt"));
  371.  
  372.          if(
  373.              $deliveryAt_shipping < $order->getStartDeliveryAt() and 
  374.              $this->requestStack->getSession()->get("orderStartProcessingAt") == $order->getStartProcessingAt()
  375.          ){
  376.              $deliveryAt_shipping = clone $order->getStartDeliveryAt();
  377.              $deliveryAt_shipping_max = clone $deliveryAt_shipping;
  378.              $deliveryAt_shipping_max->modify(" + " . $shippingDurationToMinutes . " minutes");
  379.  
  380.          }
  381.      }
  382.            
  383.             
  384.             
  385.             $arrayCollectSelection = [];
  386.             $arrayCollectSelectionHTML = "";
  387.             $deliveryAt_processChoicesFrom = clone $deliveryAt_process;
  388.             //dd($deliveryAt_process);
  389.             if(
  390.                 (int)$deliveryAt_process->format("d") > (int)$currentDateTime->format("d") 
  391.                 and ($order->getDeliveryType() != "collecte-and-delivery" and $order->getDeliveryType() != "collecte")
  392.              ){
  393.                 
  394.                 $deliveryAt_processChoicesFrom->modify($settings->getStartWorkAt()->format("H:i"));
  395.             }
  396.             $deliveryAt_processChoicesTo = clone $deliveryAt_processChoicesFrom;
  397.             while(
  398.                 (int)$deliveryAt_processChoicesFrom->format("H") < (int)$settings->getEndWorkAt()->format("H") 
  399.                 ){
  400.                     
  401.                     $deliveryAt_processChoicesTo = clone $deliveryAt_processChoicesFrom;
  402.                     if($shippingDurationToMinutes > 60){
  403.                         $stepDurationByMinutes = 60;
  404.                     }else{
  405.                         $stepDurationByMinutes = $shippingDurationToMinutes;
  406.                     }
  407.                     $deliveryAt_processChoicesTo->modify(" + ".$stepDurationByMinutes." minutes");
  408.                     
  409.                     if(
  410.                     (int)$deliveryAt_processChoicesTo->format("Hi") > (int)$settings->getEndWorkAt()->format("Hi")){
  411.                         break;
  412.                     }   
  413.                     if(
  414.                         in_array($deliveryAt_processChoicesFrom->format("H"),$settings->getExcludeHours()) 
  415.                         ){
  416.                         $deliveryAt_processChoicesFrom = clone $deliveryAt_processChoicesTo;
  417.                         //dd($deliveryAt_processChoicesFrom);
  418.                         continue;
  419.                     }
  420.                     if($shippingDurationToMinutes > 60){
  421.                         $deliveryAt_processChoicesTo->modify(" + ".$stepDurationByMinutes." minutes");
  422.                     }
  423.                     if(
  424.                         (int)$deliveryAt_processChoicesTo->format("Hi") > (int)$settings->getEndWorkAt()->format("Hi")){
  425.                             break;
  426.                         }  
  427.                     $arrayCollectSelection[]=[
  428.                         "from"=>$deliveryAt_processChoicesFrom->format("H:i"),
  429.                         "to"=>$deliveryAt_processChoicesTo->format("H:i"),
  430.                         "label"=>$deliveryAt_processChoicesFrom->format("H:i")." - ".$deliveryAt_processChoicesTo->format("H:i"),
  431.                     ];
  432.                     $arrayCollectSelectionHTML= $arrayCollectSelectionHTML .  "<option value='".$deliveryAt_processChoicesFrom->format("H:i")."'>".$deliveryAt_processChoicesFrom->format("H:i")." - ".$deliveryAt_processChoicesTo->format("H:i")."</option>";
  433.                     
  434.                     $deliveryAt_processChoicesFrom = clone $deliveryAt_processChoicesTo;
  435.                     
  436.             }
  437.             //$startDeliveryAt = new \DateTime($order->getDeliveryAt());
  438.            // dd();
  439.           
  440.            
  441.             //dd($deliveryAt_prep);
  442.             $arrayShippingSelection = [];
  443.             $arrayShippingSelectionHTML = "";
  444.             
  445.             
  446.             $deliveryAt_shippingChoicesFrom = clone $deliveryAt_shipping;
  447.             
  448.             //dd($deliveryAt_shipping);
  449.             if((int)$deliveryAt_prep->format("md") < (int)$deliveryAt_shipping->format("md") ){
  450.                 $deliveryAt_shippingChoicesFrom->modify($settings->getStartWorkAt()->format("H:i"));
  451.             }
  452.             //dd($deliveryAt_shippingChoicesFrom);
  453.             $deliveryAt_shippingChoicesTo = clone $deliveryAt_shippingChoicesFrom;
  454.             while(
  455.                 (int)$deliveryAt_shippingChoicesFrom->format("Hi") < (int)$settings->getEndWorkAt()->format("Hi") 
  456.                 ){
  457.                     
  458.                     $deliveryAt_shippingChoicesTo = clone $deliveryAt_shippingChoicesFrom;
  459.                     if($shippingDurationToMinutes > 60){
  460.                         $stepDurationByMinutes = 60;
  461.                     }else{
  462.                         $stepDurationByMinutes = $shippingDurationToMinutes;
  463.                     }
  464.                     $deliveryAt_shippingChoicesTo->modify(" + ".$stepDurationByMinutes." minutes");
  465.                     
  466.                     if(
  467.                     (int)$deliveryAt_shippingChoicesTo->format("Hi") > (int)$settings->getEndWorkAt()->format("Hi")){
  468.                         break;
  469.                     }   
  470.                     if(
  471.                         in_array($deliveryAt_shippingChoicesFrom->format("H"),$settings->getExcludeHours()) 
  472.                         ){
  473.                         $deliveryAt_shippingChoicesFrom = clone $deliveryAt_shippingChoicesTo;
  474.                         //dd($deliveryAt_shippingChoicesFrom);
  475.                         continue;
  476.                     }
  477.                     if($shippingDurationToMinutes > 60){
  478.                         $deliveryAt_shippingChoicesTo->modify(" + ".$stepDurationByMinutes." minutes");
  479.                     }
  480.                     if(
  481.                         (int)$deliveryAt_shippingChoicesTo->format("H") > (int)$settings->getEndWorkAt()->format("H")){
  482.                             break;
  483.                         }  
  484.                     $arrayShippingSelection[]=[
  485.                         "from"=>$deliveryAt_shippingChoicesFrom->format("H:i"),
  486.                         "to"=>$deliveryAt_shippingChoicesTo->format("H:i"),
  487.                         "label"=>$deliveryAt_shippingChoicesFrom->format("H:i")." - ".$deliveryAt_shippingChoicesTo->format("H:i"),
  488.                         "value"=>$deliveryAt_shippingChoicesFrom->format("H:i"),
  489.                     ];
  490.                     $checkIfSelectedOption="";
  491.                     if($order->getStartDeliveryAt()){
  492.                         if(
  493.                             $deliveryAt_shippingChoicesFrom->format("H:i") == $order->getStartDeliveryAt()->format("H:i") and 
  494.                             $this->requestStack->getSession()->get("orderStartProcessingAt") == $order->getStartProcessingAt()
  495.                             ){
  496.                             $checkIfSelectedOption =" selected='selected' ";
  497.                         }
  498.                     }
  499.                     
  500.                     $arrayShippingSelectionHTML = $arrayShippingSelectionHTML . "<option ".$checkIfSelectedOption." value='".$deliveryAt_shippingChoicesFrom->format("H:i")."'>".$deliveryAt_shippingChoicesFrom->format("H:i")." - ".$deliveryAt_shippingChoicesTo->format("H:i")."</option>";
  501.                     
  502.                     $deliveryAt_shippingChoicesFrom = clone $deliveryAt_shippingChoicesTo;
  503.                     
  504.             }
  505.             /**
  506.              * BySamir Test Fix Time After
  507.              */
  508.             //dd($deliveryAt_shipping);
  509.             if($deliveryAt_process < $order->getStartProcessingAt()){
  510.                 $deliveryAt_process = clone $order->getStartProcessingAt();
  511.                 $deliveryAt_process_max = clone $deliveryAt_process;
  512.                 $deliveryAt_process_max->modify(" + " . $shippingDurationToMinutes . " minutes");
  513.             }
  514.         if($this->requestStack->getSession()->get("orderStartProcessingAt")  ){
  515.             //dd($this->requestStack->getSession()->get("orderStartProcessingAt"));
  516.             if(
  517.                 $deliveryAt_shipping < $order->getStartDeliveryAt() and 
  518.                 $this->requestStack->getSession()->get("orderStartProcessingAt") == $order->getStartProcessingAt()
  519.             ){
  520.                 $deliveryAt_shipping = clone $order->getStartDeliveryAt();
  521.                 $deliveryAt_shipping_max = clone $deliveryAt_shipping;
  522.                 $deliveryAt_shipping_max->modify(" + " . $shippingDurationToMinutes . " minutes");
  523.             }
  524.         }
  525.             
  526.         
  527.             $shippingFees = $this->flexyShippingProvider->getFees(null,null,$order);
  528.             
  529.             $shippingFees = array_sum($shippingFees);
  530.             
  531.             
  532.             //Remember startProcessingAt,shippingMethodId & deliveryType
  533.             $this->requestStack->getSession()->set("orderStartProcessingAt",$order->getStartProcessingAt());
  534.             $this->requestStack->getSession()->set("shippingMethodId",$order->getShippingMethod()->getId());
  535.             $this->requestStack->getSession()->set("deliveryType",$order->getDeliveryType());
  536.             
  537.             
  538.             $minDateShipping = clone $deliveryAt_prep;
  539.             $minDateShipping->modify("previous day");
  540.             
  541.             
  542.             $orderInfos = [
  543.                 "differenceHours"=>$differenceHours,
  544.                "intervalDatesEndWork"=>$intervalDatesEndWork,
  545.                 "shippingMode"=> $order->getShippingMethod()->getName(),
  546.                 "startDateTimeWorkChecker"=> $startDateTimeWorkChecker,
  547.                 "endDateTimeWorkChecker"=> $endDateTimeWorkChecker,
  548.                 "getStartProcessingAt"=> $order->getStartProcessingAt(),
  549.                 "deliveryAt_process"=> $deliveryAt_process,
  550.                 "deliveryAt_process_max"=>$deliveryAt_process_max,
  551.                 "deliveryAt_prep"=>$deliveryAt_prep,
  552.                 "deliveryAt_shipping"=>$deliveryAt_shipping,
  553.                 "deliveryAt_shipping_max"=>$deliveryAt_shipping_max,
  554.                 
  555.                 "dataResponse"=>[
  556.                     "minDateShipping"=> $minDateShipping->format("Y-m-d"),
  557.                     "shippingFees"=>$shippingFees,
  558.                     "collectHoursHTML"=>$arrayCollectSelectionHTML,
  559.                     "collectHours"=>$arrayCollectSelection,
  560.                     "shippingHoursHTML"=>$arrayShippingSelectionHTML,
  561.                     "shippingHours"=>$arrayShippingSelection,
  562.                     "collectDate"=>$deliveryAt_process->format("Y-m-d"),
  563.                     "shippingDate"=>$deliveryAt_shipping->format("Y-m-d"),
  564.                     "intervalShipping"=> $shippingDurationToMinutes,
  565.                     "startWorkLimit"=>$settings->getStartWorkAt()->format("H:i"),
  566.                     "endWorkLimit"=>$settings->getEndWorkAt()->format("H:i"),
  567.                     "messages"=>$this->messages
  568.                     
  569.                 ]
  570.             ];
  571.     
  572.     
  573.            return $orderInfos;
  574.         }
  575.         return [];
  576.     }
  577.     public function getOrderExtraInfos(
  578.         Order $order,
  579.         $collectDateTimePreview=new \DateTime(),
  580.         $shippingDateTimePreview=new \DateTime(),
  581.         $editMode = false
  582.         
  583.         ){
  584.         $settings =  $this->em->getRepository(Settings::class)->findOneBy(["code"=>"main"]);
  585.         $preparationDuration = $order->getShippingMethod()->getPreparationDuration() * 60;
  586.         $processingDuration = $order->getShippingMethod()->getProcessingDuration()* 60; 
  587.         $shippingDuration = $order->getShippingMethod()->getShippingDuration() * 60;
  588.         
  589.         $excludeDates = array_column($settings->getExcludeDates(), 'date');
  590.         
  591.         $daysInFrench = [
  592.                 
  593.             "Monday"=>"Lundi",
  594.             "Tuesday"=>"Mardi",
  595.             "Wednesday"=>"Mercredi",
  596.             "Thursday"=>"Jeudi",
  597.             "Friday"=>"Vendredi",
  598.             "Saturday"=>"Samedi",
  599.             "Sunday"=>"Dimanche",
  600.         ];
  601.         
  602.         
  603.         if($order->getStartProcessingAt() and $order->getShippingMethod()){
  604.             $currentDateTime = new \DateTime();
  605.             if($editMode){
  606.                 //$currentDateTime = clone $order->getStartProcessingAt();
  607.                 $collectDateTimePreview->modify($order->getStartProcessingAt()->format("Y-m-d"));
  608.                 //$shippingDateTimePreview->modify($order->getStartDeliveryAt()->format("Y-m-d"));
  609.                 
  610.             }
  611.             if($currentDateTime->format("i") != "00"){
  612.                 $currentDateTime->modify($currentDateTime->format("H").":00");
  613.                 $currentDateTime->modify("+ 1 hour");
  614.             }
  615.            
  616.            
  617.             $collectDateTime = clone $collectDateTimePreview;
  618.             $shippingDateTime = clone $collectDateTimePreview;
  619.             
  620.             
  621.             $todayEndOfTime =  clone $collectDateTimePreview;
  622.             
  623.             $todayEndOfTime->modify($settings->getEndWorkAt()->format("H:i"));
  624.             // if($order->getStartProcessingAt()){
  625.             //     if($order->getStartProcessingAt()->format("i") != "00"){
  626.             //         $order->getStartProcessingAt()->modify($currentDateTime->format("H").":00");
  627.             //         $order->getStartProcessingAt()->modify("+ 1 hour");
  628.             //     }
  629.             //     $collectDateTime->modify($order->getStartProcessingAt()->format("H:i"));
  630.             // }
  631.             
  632.             if(
  633.                 (
  634.                 $collectDateTime > $todayEndOfTime 
  635.                     # Note : Jai mis cette condition pour une raison
  636.                 
  637.                 and !$editMode)
  638.                 //or ($collectDateTime < $currentDateTime and !$editMode)
  639.                 ){
  640.                 
  641.                 $collectDateTime->modify("next day");
  642.                 $shippingDateTime->modify("next day");
  643.             }
  644.             
  645.             
  646.             
  647.             $collectDateTime->modify($settings->getStartWorkAt()->format("H:i"));
  648.             
  649.             if($collectDateTime < $currentDateTime and !$editMode){
  650.                 $collectDateTime->modify($currentDateTime->format("H:i"));
  651.             }
  652.             
  653.             
  654.             if( $order->getDeliveryType()=="collecte-and-delivery" || $order->getDeliveryType()=="collecte" ){
  655.                 $collectDateTime->modify(" + ".$preparationDuration." minutes ");
  656.             }
  657.             
  658.             
  659.             
  660.             
  661.             $arrayCollectSlots = [];
  662.             $arrayShippingSlots = [];
  663.             $arrayCollectSelectionHTML = null;
  664.             $arrayShippingSelectionHTML = null ;
  665.             
  666.             //$arrayCollectDate["date"] = $collectDateTime->format("Y-m-d");
  667.             
  668.             // ### EXCLUDE DATES AND HOURS : START #####
  669.             $collectDateTime = $this->excludeDatesChecker($collectDateTime);
  670.             // ### EXCLUDE DATES AND HOURS : END #####
  671.             
  672.             
  673.             
  674.             $resultCollectSlots = $this->loopStotForCollect($collectDateTime,$currentDateTime,$order,$settings,$editMode);
  675.             if(count($resultCollectSlots["slots"]) == 0)
  676.             {
  677.                     $collectDateTime->modify("next day");
  678.                     $collectDateTime->modify($settings->getStartWorkAt()->format("H:i"));
  679.                     $resultCollectSlots = $this->loopStotForCollect($collectDateTime,$currentDateTime,$order,$settings,$editMode);
  680.             }
  681.             
  682.             $shippingDateTime->modify($resultCollectSlots["slots"][0]["from"]);
  683.             
  684.             
  685.             
  686.             $shippingDateTime->modify(" + ".$processingDuration." minutes");
  687.             
  688.             
  689.             
  690.             if($shippingDateTimePreview){
  691.                 if($shippingDateTimePreview > $shippingDateTime){
  692.                     $shippingDateTime = clone $shippingDateTimePreview;
  693.                     $shippingDateTime->modify($settings->getStartWorkAt()->format("H:i"));
  694.                 }
  695.             }
  696.             
  697.             
  698.             
  699.             
  700.             
  701.             
  702.             
  703.             
  704.             
  705.             
  706.           // ### EXCLUDE DATES AND HOURS : START #####
  707.           $shippingDateTime = $this->excludeDatesChecker($shippingDateTime,"livraison");
  708.           // ### EXCLUDE DATES AND HOURS : END #####
  709.            $resultShippingSlots = $this->loopSlotForShipping($shippingDateTime,$collectDateTimePreview,$order);
  710.            if(count($resultShippingSlots["slots"]) == 0)
  711.             {
  712.                     $shippingDateTime->modify("next day");
  713.                     $shippingDateTime->modify($settings->getStartWorkAt()->format("H:i"));
  714.                     $resultShippingSlots = $this->loopSlotForShipping($shippingDateTime,$collectDateTimePreview,$order);
  715.             }
  716.             
  717.             
  718.             
  719.             
  720.            
  721.             $allSlots["collect"]=$resultCollectSlots["slots"];
  722.             $allSlots["shipping"]=$resultShippingSlots["slots"];
  723.             $arrayCollectSelectionHTML = $resultCollectSlots["optionsHtml"];
  724.             $arrayShippingSelectionHTML = $resultShippingSlots["optionsHtml"];
  725.             
  726.             
  727.             
  728.             $shippingFees = $this->flexyShippingProvider->getFees(null,null,$order);
  729.             
  730.             $shippingFees = array_sum($shippingFees);
  731.             $minShippingDate = $allSlots["shipping"][0]["date"];
  732.             
  733.             
  734.             
  735.             
  736.             $orderInfos = [
  737.                 "differenceHours"=>0,
  738.                "intervalDatesEndWork"=>0,
  739.                 "shippingMode"=> $order->getShippingMethod()->getName(),
  740.                 "startDateTimeWorkChecker"=> new \DateTime(),
  741.                 "endDateTimeWorkChecker"=> new \DateTime(),
  742.                 "getStartProcessingAt"=> $order->getStartProcessingAt(),
  743.                 "deliveryAt_process"=> $collectDateTimePreview,
  744.                 "deliveryAt_process_max"=>$collectDateTimePreview,
  745.                 "deliveryAt_prep"=>new \DateTime(),
  746.                 "deliveryAt_shipping"=>$shippingDateTimePreview,
  747.                 "deliveryAt_shipping_max"=>$allSlots["shipping"][0]["date"],
  748.                 
  749.                 "dataResponse"=>[
  750.                     "minDateCollect"=>  $collectDateTime->format("Y-m-d") ,
  751.                     "minDateShipping"=>  $collectDateTime->format("Y-m-d") ,
  752.                     "shippingFees"=>$shippingFees,
  753.                     "collectHoursHTML"=>$arrayCollectSelectionHTML,
  754.                     "collectHours"=>$allSlots["collect"],
  755.                     "shippingHoursHTML"=>$arrayShippingSelectionHTML,
  756.                     "shippingHours"=>$allSlots["shipping"],
  757.                     "collectDate"=>$collectDateTime->format("Y-m-d"),
  758.                     "shippingDate"=>$allSlots["shipping"][0]["date"]->format("Y-m-d"),
  759.                     "intervalShipping"=> 0,
  760.                     "startWorkLimit"=>$settings->getStartWorkAt()->format("H:i"),
  761.                     "endWorkLimit"=>$settings->getEndWorkAt()->format("H:i"),
  762.                     "messages"=>$this->messages
  763.                     
  764.                 ]
  765.             ];
  766.     
  767.     
  768.            return $orderInfos;
  769.         }
  770.         return [];
  771.     }
  772.     public function getCustomerById($id){
  773.         return $this->em->getRepository(Customer::class)->find((int)$id);
  774.     }
  775.     public function getOrderById($id){
  776.         return $this->em->getRepository(Order::class)->find((int)$id);
  777.     }
  778.     // Functions
  779.     function time_diff_in_minutes($start_time, $end_time) {
  780.         $start_timestamp = strtotime($start_time);
  781.         $end_timestamp = strtotime($end_time);
  782.         $diff_seconds = abs($end_timestamp - $start_timestamp);
  783.         $diff_minutes = round($diff_seconds / 60);
  784.         return $diff_minutes;
  785.     }
  786.     function date_diff_in_minutes($date1, $date2) {
  787.         $datetime1 = new DateTime($date1);
  788.         $datetime2 = new DateTime($date2);
  789.         $interval = $datetime1->diff($datetime2);
  790.         $minutes = $interval->i + ($interval->h * 60) + ($interval->d * 24 * 60);
  791.         return $minutes;
  792.     }
  793.     function is_between_night($date_time_str, $start_time_str, $end_time_str) {
  794.         $date_time = new DateTime($date_time_str);
  795.         
  796.         // Get the time as a string in the format "H:i"
  797.         $time_str = $date_time->format("H:i");
  798.         
  799.         // Get the date as a string in the format "Y-m-d"
  800.         $date_str = $date_time->format("Y-m-d");
  801.         
  802.         // Get the datetime for the start time of the same day
  803.         $start_datetime_str = $date_str . " " . $start_time_str;
  804.         $start_datetime = new DateTime($start_datetime_str);
  805.         
  806.         // Get the datetime for the end time of the same day
  807.         $end_datetime_str = $date_str . " " . $end_time_str;
  808.         $end_datetime = new DateTime($end_datetime_str);
  809.         
  810.         // Adjust the start and end dates if the start time is after the end time
  811.         if ($start_datetime >= $end_datetime) {
  812.           if ($time_str >= $start_time_str) {
  813.             $start_datetime->modify("-1 day");
  814.           } else {
  815.             $end_datetime->modify("+1 day");
  816.           }
  817.         }
  818.         
  819.         // Check if the input datetime is between the start and end datetimes
  820.         return $date_time >= $start_datetime && $date_time < $end_datetime;
  821.       }
  822.       function isDaytime($time) {
  823.         $hour = (int) date('H', strtotime($time));
  824.         return ($hour >= 8 && $hour < 20);
  825.       }
  826.     
  827.     
  828.       
  829.       function loopStotForCollect ($collectDateTime,$currentDateTime,$order,$settings,$editMode=false){
  830.        
  831.         
  832.         $preparationDuration = $order->getShippingMethod()->getPreparationDuration() * 60;
  833.         $processingDuration = $order->getShippingMethod()->getProcessingDuration()* 60; 
  834.         $shippingDuration = $order->getShippingMethod()->getShippingDuration() * 60;
  835.         $arrayCollectSelectionHTML = null;
  836.         $arrayCollectSlots = [];
  837.         while((int)$collectDateTime->format("H") < (int)$settings->getEndWorkAt()->format("H") ){
  838.                 
  839.             
  840.             while ( 
  841.                 in_array($collectDateTime->format("H"),$settings->getExcludeHours()) || 
  842.                 in_array($collectDateTime->format("H"),$settings->getExcludeHours()) 
  843.                 ) {
  844.                 $collectDateTime->modify("+ 1 Hour");
  845.                 $collectDateTime->modify("+ 1 Hour");
  846.             }
  847.             $collectFrom =  $collectDateTime->format("H:i");
  848.             if(
  849.                 $collectDateTime < $currentDateTime and !$editMode
  850.                 
  851.                 
  852.                 ){
  853.                 $collectDateTime->modify(" +  ".$shippingDuration." minutes ");
  854.                 continue;
  855.             }
  856.             
  857.             
  858.             $collectDateTime->modify(" +  ".$shippingDuration." minutes ");
  859.             $collectTo =  $collectDateTime->format("H:i");
  860.             $collectStotLabel = $collectFrom." - ".$collectTo;
  861.             $arrayCollectSelectionHTML= $arrayCollectSelectionHTML .  "<option value='".$collectFrom."'>".$collectFrom." - ".$collectTo."</option>";
  862.             $arrayCollectSlots[] = [
  863.                 "label"=>$collectStotLabel,
  864.                 "from"=>$collectFrom,
  865.                 "to"=>$collectTo,
  866.                 "value"=>$collectFrom,
  867.                 "date"=>new \DateTime($collectDateTime->format("Y-m-d") . " ".$collectFrom),
  868.             ];
  869.             
  870.         }
  871.         
  872.         return [
  873.             "optionsHtml"=>$arrayCollectSelectionHTML,
  874.             "slots" => $arrayCollectSlots
  875.          ];
  876.       }
  877.       
  878.       function loopSlotForShipping($shippingDateTime,$collectDateTimePreview,$order){
  879.         $settings =  $this->em->getRepository(Settings::class)->findOneBy(["code"=>"main"]);
  880.         $preparationDuration = $order->getShippingMethod()->getPreparationDuration() * 60;
  881.         $processingDuration = $order->getShippingMethod()->getProcessingDuration()* 60; 
  882.         $shippingDuration = $order->getShippingMethod()->getShippingDuration() * 60;
  883.         $arrayShippingSelectionHTML=null;
  884.         $arrayShippingSlots=[];
  885.         $dateChecker = clone $collectDateTimePreview;
  886.         
  887.         $dateChecker->modify(" + ".$processingDuration." minutes ");
  888.         
  889.         
  890.         while( (int)$shippingDateTime->format("H") < (int)$settings->getEndWorkAt()->format("H") ){
  891.             while ( 
  892.                 in_array($shippingDateTime->format("H"),$settings->getExcludeHours()) || 
  893.                 in_array($shippingDateTime->format("H"),$settings->getExcludeHours()) 
  894.                 ) {
  895.                 $shippingDateTime->modify("+ 1 Hour");
  896.                 $shippingDateTime->modify("+ 1 Hour");
  897.             }     
  898.                 
  899.                 
  900.             $difference = $this->time_diff_in_minutes($shippingDateTime->format("H:i"),$collectDateTimePreview->format("H:i"));
  901.             
  902.             
  903.             $differenceDatesInMinutes = $this->date_diff_in_minutes($shippingDateTime->format("Y-m-d H:i"),$collectDateTimePreview->format("Y-m-d H:i"));
  904.             $pureDiff =  $differenceDatesInMinutes - $processingDuration ;
  905.           
  906.             
  907.             
  908.             
  909.             
  910.             $shippingFrom =  $shippingDateTime->format("H:i");
  911.             
  912.          
  913.             
  914.             
  915.              if( 
  916.                 ($difference < $processingDuration and $shippingDateTime->format("d") == $collectDateTimePreview->format("d"))
  917.                 or ($pureDiff < 0)
  918.                 
  919.              ){
  920.                  $shippingDateTime->modify(" +  ".$shippingDuration." minutes ");
  921.                  continue;
  922.              }
  923.              
  924.             
  925.              
  926.           
  927.              
  928.              
  929.              
  930.              $shippingDateTime->modify(" +  ".$shippingDuration." minutes ");
  931.              $shippingTo =  $shippingDateTime->format("H:i");
  932.              $shippingStotLabel = $shippingFrom." - ".$shippingTo;
  933.              $arrayShippingSelectionHTML= $arrayShippingSelectionHTML .  "<option value='".$shippingFrom."'>".$shippingFrom." - ".$shippingTo."</option>";
  934.              $arrayShippingSlots[] = [
  935.                  "label"=>$shippingStotLabel,
  936.                  "from"=>$shippingFrom,
  937.                  "to"=>$shippingTo,
  938.                  "value"=>$shippingFrom,
  939.                  "date"=>new \DateTime($shippingDateTime->format("Y-m-d") . " ".$shippingFrom),
  940.              ];
  941.              
  942.          }
  943.          return [
  944.             "optionsHtml"=>$arrayShippingSelectionHTML,
  945.             "slots" => $arrayShippingSlots
  946.          ];
  947.       }
  948.       
  949.       public function excludeDatesChecker($date,$deliveryType="collect"){
  950.         $daysInFrench = [
  951.                 
  952.             "Monday"=>"Lundi",
  953.             "Tuesday"=>"Mardi",
  954.             "Wednesday"=>"Mercredi",
  955.             "Thursday"=>"Jeudi",
  956.             "Friday"=>"Vendredi",
  957.             "Saturday"=>"Samedi",
  958.             "Sunday"=>"Dimanche",
  959.         ];
  960.         $settings =  $this->em->getRepository(Settings::class)->findOneBy(["code"=>"main"]);
  961.         $excludeDates = array_column($settings->getExcludeDates(), 'date');
  962.         while ( in_array($date->format("l"),$settings->getExcludeDays()) or  in_array($date->format("Y-m-d"),$excludeDates) ) {
  963.             $keyExcludedDate = array_search($date->format("Y-m-d"), array_column($settings->getExcludeDates(), 'date'));
  964.             $excludedDate = $settings->getExcludeDates()[$keyExcludedDate];
  965.             if(in_array($date->format("l"),$settings->getExcludeDays())){
  966.                 $this->messages[]="<b><i>".$daysInFrench[$date->format("l")] . "</i></b> Est un jour de repos, ".$deliveryType." a été décalé pour le jour suivant";
  967.             }else{
  968.                 $this->messages[]="Date <b><i>".$date->format("d-m-Y")."</i></b> pour la ".$deliveryType." a été décalé pour le jour suivant, a l'occasion de <b><i>".$excludedDate["label"]."</i></b>";
  969.             }
  970.             $date->modify("+ 1 day");
  971.         }
  972.         return $date;
  973.       }
  974.       
  975.       
  976. }