src/Service/KernixApiService.php line 1044

Open in your IDE?
  1. <?php
  2. namespace App\Service;
  3. use App\Entity\Document;
  4. use App\Entity\Dossier;
  5. use App\Entity\Voyage;
  6. use App\Entity\VoyageEtat;
  7. use App\Entity\VoyageDayByDay;
  8. use App\Entity\VoyageService AS VoyService;
  9. use App\Entity\VoyageActiviteEdito;
  10. use App\Entity\VoyageServiceDay;
  11. use App\Entity\VoyageActiviteEditoDay;
  12. use App\Entity\VoyageSousServices;
  13. use App\Entity\VoyagePeriode;
  14. use App\Entity\VoyageCotation;
  15. use App\Entity\VoyagePeriodeCotation;
  16. use App\Entity\Service;
  17. use App\Entity\EditorialContenu;
  18. use App\Entity\VoyagePdfPage
  19. use App\Entity\VoyagePdfModele
  20. use App\Entity\VoyagePdfPageTemplate
  21. use App\Entity\VoyagePdf;
  22. use App\Entity\VoyagePeriodePlage;
  23. use App\Entity\VoyageServiceGroupement;
  24. use App\Entity\DocumentGenerator;
  25. use App\Entity\DocumentGeneratorPage;
  26. use App\Service\CompanyService;
  27. use App\Service\ServiceService;
  28. use App\Service\VoyageServiceService;
  29. use App\Service\EditorialService;
  30. use App\Service\VoyageActiviteService;
  31. use App\Service\TraductionService;
  32. use App\Service\PatternService;
  33. use App\Service\DoliProposalService;
  34. use App\Service\DoliOrderService;
  35. use App\Service\DoliInvoiceService;
  36. use App\Service\DossierService;
  37. use App\Enum\ServiceTypeEnum;
  38. use App\Repository\VoyageServiceGroupementRepository;
  39. use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
  40. use Doctrine\ORM\EntityManagerInterface
  41. use Psr\Log\LoggerInterface;
  42. class KernixApiService {
  43.     private $em;
  44.     private $serviceService;
  45.     private $voyageServiceService;
  46.     private $voyageActiviteService;
  47.     private $editorialService;
  48.     private $patternService;
  49.     private $traductionService;
  50.     private $proposalService;
  51.     private $orderService;
  52.     private $invoiceService;
  53.     private $params;
  54.     private $logger;
  55.     private $dossierService;
  56.     private $voyageServiceGroupementRepository;
  57.     
  58.     public function __construct(
  59.         EntityManagerInterface $em
  60.         ParameterBagInterface $params,
  61.         ServiceService $serviceService,
  62.         VoyageServiceService $voyageServiceService,
  63.         VoyageActiviteService $voyageActiviteService,
  64.         EditorialService $editorialService,
  65.         PatternService $patternService,
  66.         LoggerInterface $logger,
  67.         TraductionService $traductionService,
  68.         DoliProposalService $proposalService,
  69.         DoliOrderService $orderService,
  70.         DoliInvoiceService $invoiceService,
  71.         DossierService $dossierService,
  72.         VoyageServiceGroupementRepository $voyageServiceGroupementRepository
  73.     ) {
  74.         $this->em $em;
  75.         $this->serviceService $serviceService;
  76.         $this->voyageServiceService $voyageServiceService;
  77.         $this->voyageActiviteService $voyageActiviteService;
  78.         $this->editorialService $editorialService;
  79.         $this->traductionService $traductionService;
  80.         $this->proposalService $proposalService;
  81.         $this->orderService $orderService;
  82.         $this->invoiceService $invoiceService;
  83.         $this->params $params;
  84.         $this->logger $logger;
  85.         $this->dossierService $dossierService;
  86.         $this->voyageServiceGroupementRepository $voyageServiceGroupementRepository;
  87.     }
  88.     public function getFromEnum($constant) {
  89.         $fullConstantName = \App\Enum\KernixItemEnum::class . '::' "$constant";
  90.         if (defined($fullConstantName)) {
  91.             return constant($fullConstantName);
  92.         }
  93.         return null;
  94.     }
  95.     // Exécute la requête et retourne les résultats
  96.     public function execute($item$params) {
  97.         $results  = array();
  98.         $elements $this->getConfig($item$params);
  99.         foreach ($elements as $key => $config) {
  100.             // remplace la string walkinn des tables
  101.             $key str_replace('walkinn_'''$key);
  102.             $request $this->getRequest($config$params);
  103.             $this->em->getConnection()->prepare($request);
  104.             $stmt $this->em->getConnection()->executeQuery($request);
  105.             $results[$key] = $stmt->fetchAllAssociative();
  106.         }
  107.         return $results;   
  108.     }
  109.     // Lance la requete puis execute des actions sur les résultats
  110.     public function get($item$params) {
  111.         // Sauvegarde timestamp dans une variable si fourni     
  112.         $timestamp = (array_key_exists('timestamp'$params) && null !== $params['timestamp']) ? $params['timestamp'] : null;
  113.         // Suppression du filtre timestamp
  114.         $params['timestamp'] = null;
  115.         $results $this->execute($item$params);
  116.         $data = [];
  117.         foreach ($results as $table => &$items) {
  118.             // gère les traduction dans les cas des editoriaux
  119.             if ((count($items) > 0) && (in_array('editorial_id'array_keys($items[0])))) {
  120.                 foreach ($items as $key => &$item) {
  121.             if (null !== $item['editorial_id']) {
  122.                         $item['content'] = $this->getEditorialById($item['editorial_id']);
  123.             unset($item['editorial_id']);
  124.             }
  125.                 // Filtre selon le timestamp si fourni lorsque l'item est complet
  126.             if (false === $this->hasCorrectTimestamp($timestamp$item)) {   
  127.                         unset($results[$table][$key]);
  128.                 continue;
  129.                 }
  130.                 }               
  131.         }
  132.         else {
  133.                 foreach ($items as $key => &$item) {
  134.                 // Filtre selon le timestamp si fourni
  135.             if (false === $this->hasCorrectTimestamp($timestamp$item)) {   
  136.                         unset($results[$table][$key]);
  137.                 continue;
  138.                 }
  139.                 }               
  140.         }
  141.     }
  142.     foreach ($results as $table => $items) {
  143.             $data[$table] = array_values($items);
  144.         }
  145.         return $data;   
  146.     }
  147.     public function getEditorialById($id) {
  148.         $params = array(
  149.             'conditions' => array(
  150.                 'walkinn_editorial_contenu.editorial_id = '.$id
  151.               'walkinn_editorial_contenu.actif        = 1'
  152.               'walkinn_editorial_contenu.langue IN ("FR", "GB") '
  153.           '((IFNULL(walkinn_editorial.etape,0) = 1 AND walkinn_editorial_contenu.contexte_id = '.\App\Enum\EditorialContexteEnum::ITINERAIRES.' ) OR (IFNULL(walkinn_editorial.activite, 0) = 1 AND walkinn_editorial_contenu.contexte_id = '.\App\Enum\EditorialContexteEnum::WEB.') OR (IFNULL(etape,0)=0 AND IFNULL(activite, 0)=0));'
  154.             ), 
  155.             'joins' => array(
  156.                 'LEFT JOIN walkinn_editorial ON walkinn_editorial.id = walkinn_editorial_contenu.editorial_id'
  157.             )
  158.         );
  159.         $content $this->get('editorial'$params)['editorial_contenu'];
  160.         $arr  = [];
  161.         foreach ($content as $contenu) {
  162.             $contenu['contenu']        = $this->stripHtmlAttribs($contenu['contenu']);
  163.             $arr[$contenu['langue']][] = $contenu
  164.         }
  165.         return $arr;
  166.     }
  167.     public function hasCorrectTimestamp($timestamp$row) {
  168.         if (null !== $timestamp) {
  169.             $updatedAtValues = [];
  170.             $this->extractUpdatedAt($row$updatedAtValues);
  171.             if (count($updatedAtValues) > 0) {
  172.                 $dateValue     max(array_filter($updatedAtValues));
  173.                 $dateTimestamp strtotime($dateValue);
  174.                 // Comparaison des deux timestamps
  175.                 if ($timestamp $dateTimestamp) {
  176.                     return false;
  177.                 }
  178.             }
  179.     }
  180.     return true;
  181.     }
  182.     public function getRequest($config$params) {
  183.         $request sprintf('SELECT %s 
  184.                             FROM %s 
  185.                             %s 
  186.                             WHERE %s %s'implode(', '$config['fields'])
  187.                                      , $config['table']
  188.                                      , implode(' '$config['joins'])
  189.                      , implode(' AND 'array_merge(array('1=1'), $config['conditions']))
  190.                      , ((array_key_exists('order'$config)) ? $config['order'] : ''));
  191.         return $request;
  192.     }
  193.     public function getConfig($item$params) {
  194.         $results = array();
  195.         $tables $this->getTables($item$params);
  196.         foreach ($tables as $code) {
  197.                 $results[$code] = $this->getFromEnum($code) ;
  198.             $keys = ['conditions''joins''fields''order'];
  199.             if (array_key_exists('reset'$params) && true === $params['reset']) {
  200.                 foreach ( $keys as $var) {
  201.                     if (array_key_exists($var$params)) {
  202.                           $results[$code][$var] = $params[$var];
  203.                     }
  204.                 }
  205.             } else {
  206.                 foreach ( $keys as $var) {
  207.                     if (array_key_exists($var$params)) {
  208.                       if (array_key_exists($var$results[$code])) {
  209.                               $results[$code][$var] = array_merge($results[$code][$var], $params[$var]);
  210.                           } else {
  211.                               $results[$code][$var] = $params[$var];
  212.                       }
  213.                         }
  214.                 }
  215.             }
  216.         }
  217.         return $results;
  218.     }
  219.     // retrouve les tables associées à l'item
  220.     public function getTables($item$params) {
  221.         $item strtoupper($item);
  222.         return $this->getFromEnum($item);
  223.     }
  224.     // Voyages / Séjours
  225.     public function getVoyages($item$params$includeFormule true$includeNiveauDifficulte true$includeTags true$includeDestination true$includeCircuit true$includeJours true$includeEtapes true$includeGrandItineraire true$includeBlocInfo true$includeAjustement true) {
  226.         // Sauvegarde timestamp dans une variable si fourni     
  227.         $timestamp = (array_key_exists('timestamp'$params) && null !== $params['timestamp']) ? $params['timestamp'] : null;
  228.         // Suppression du filtre timestamp
  229.     $params['timestamp'] = null;
  230.     // On récupère les données sans filtre de date
  231.         $data $this->get($item$params);
  232.         // Pour tous les voyages
  233.         foreach ($data['voyage'] as $key => &$row) {
  234.             // Voyage principal ou formule ?
  235.             $arrCode explode('-'$row['code_vertuoz']);
  236.         $isFormule = ((null !== $row['formule_ordre']) && ($row['formule_ordre'] == 1)) || ((null === $row['formule_ordre']) && (array_pop($arrCode) == 1)) ? false true;
  237.         // Supprime le code vertuoz qui a permis de trouver la formule
  238.         //unset($row['code_vertuoz']);
  239.         // ajuste les titres 
  240.             if (true === $isFormule) {
  241.                 //$row['titre']           = $row['']; // Dans le cas d'une formule le titre est alors le libellé de la formule
  242.                 //$row['libelle_formule'] = $row['formule_libelle']; // Dans le cas d'une formule le titre est alors le libellé de la formule
  243.                 $row['ordre']           = $row['formule_ordre'];
  244.         }
  245.         //unset($row['formule_libelle']);
  246.         unset($row['formule_ordre']);
  247.     
  248.             // traduit les titres
  249.         if (strlen($row['titre']) > 0) { // Au cas où... 
  250.             $row['titre'] = array_merge(array('fr_FR' => $row['titre']), $this->getDoliTraduction($row['titre']));
  251.         }
  252.         if (strlen($row['titre_court']) > 0) { // Le titre long n'est pas toujours renseigné
  253.             $row['titre_court'] = array_merge(array('fr_FR' => $row['titre_court']), $this->getDoliTraduction($row['titre_court']));
  254.             }
  255.         if (strlen($row['soustitre']) > 0) { // Le soustitre n'est pas toujours renseigné
  256.             $row['soustitre'] = array_merge(array('fr_FR' => $row['soustitre']), $this->getDoliTraduction($row['soustitre']));
  257.             }
  258.          
  259.             // Ajoute les destinations 
  260.             $row['destinations'] = $this->getDestinationsVoyage($row);
  261.         
  262.             // Ajoute les tags
  263.             if (true === $includeTags) {
  264.                 $row['tags'] = $this->getVoyagesTags($row);
  265.             }
  266.         // Ajoute les thèmes multiples
  267.             $row['themes'] = $this->getVoyageThemes($row);
  268.            
  269.             // Ajoute les blocs info 
  270.             if (true === $includeBlocInfo) {
  271.                 $this->getVoyagesBlocInfo($row);
  272.         }
  273.          
  274.             if (false === $isFormule) {
  275.                 // Ajoute les velos 
  276.                 $row['velos'] = $this->getVoyagesVelos($row);
  277.         // Ajoute les activités
  278.                 $row['activites']         = $this->getVoyageServicesActivite($row);
  279.         // Ajoute les grands itinéraires
  280.                 $row['grand_itineraires'] = $this->getVoyageGrandItineraires($row);
  281.         // TODO à priori pas besoin de description
  282.             //$row['description']       = $this->getVoyageDescription($row);
  283.             $row['description']       = []; 
  284.             // Ajoute les descriptions courtes/longues
  285.         $this->getVoyageDescriptions($row);
  286.             unset($row['descriptions_id']);
  287.         // Ajoute les informations pratiques
  288.         $this->getVoyageInformationPratique($row);
  289.             unset($row['info_pratiques_id']);
  290.         // Ajoute les forfaits
  291.         $this->getVoyageBlocForfait($row);
  292.             unset($row['bloc_forfait_id']);
  293.             }
  294.         
  295.             // Ajoute les jours 
  296.             if (true === $includeJours) {
  297.                 $row['jours' ] = $this->getVoyagesJours($row);
  298.             }
  299.             // Ajoute les périodes  
  300.             $row['periodes'] = $this->getVoyagesCotation($row);
  301.         
  302.             if (true === $includeFormule) {
  303.                 $row['formules'] = $this->getVoyagesFormules($row);
  304.             }
  305.         // Ajustements
  306.             if (true === $includeAjustement) {
  307.             $row['ajustements'] = $this->getVoyagesAjustements($row);
  308.             }
  309.         // Filtre selon le timestamp si fourni
  310.             if (null !== $timestamp) {
  311.                 $updatedAtValues = [];
  312.                 $this->extractUpdatedAt($row$updatedAtValues);
  313.                 $dateValue     max(array_filter($updatedAtValues));
  314.                 $dateTimestamp strtotime($dateValue);
  315.                 // Comparaison des deux timestamps
  316.                 if ($timestamp $dateTimestamp) {
  317.                     continue ;
  318.         }
  319.                 unset($data['voyage'][$key]);
  320.         }
  321.         }
  322.         return array('voyage' => array_values($data['voyage']));
  323.     }
  324.     // thèmes pour un séjour
  325.     public function getVoyageThemes($row$timestamp null) {
  326.         $params = array(
  327.             'conditions' => array(
  328.                 'walkinn_voyage.id = '.$row['id']
  329.             ), 
  330.             'joins' => array(
  331.                  'INNER JOIN walkinn_voyage_theme_kernix ON walkinn_voyage_theme_kernix.voyage_theme_id = walkinn_voyage_theme.id'
  332.                'INNER JOIN walkinn_voyage ON walkinn_voyage.id = walkinn_voyage_theme_kernix.voyage_id'
  333.         ),
  334.         'timestamp' => $timestamp
  335.     );
  336.         $data $this->get('theme_sejour'$params)['voyage_theme'];
  337.     foreach ($data as &$item) {
  338.            if (array_key_exists('content'$item)) {         
  339.                foreach ($item['content'] as &$langues) {
  340.                    foreach ($langues as &$element) {
  341.                        unset($element['slug']);
  342.                        unset($element['langue']);
  343.                }
  344.            }
  345.        }
  346.     }
  347.     return $data;
  348.     }
  349.     // grand-itineraires pour un séjour
  350.     public function getVoyageGrandItineraires($row$timestamp null) {
  351.         $params = array(
  352.             'conditions' => array(
  353.                 'walkinn_voyage.id = '.$row['id']
  354.             ), 
  355.             'joins' => array(
  356.                  'INNER JOIN voyage_editorial ON voyage_editorial.editorial_id = walkinn_editorial.id'
  357.                'INNER JOIN walkinn_voyage ON walkinn_voyage.id = voyage_editorial.voyage_id'
  358.         ),
  359.         'timestamp' => $timestamp
  360.     );
  361.         $data $this->get('grand_itineraire'$params)['editorial_contenu_grand_itineraire'];
  362.     foreach ($data as &$item) {
  363.            if (array_key_exists('content'$item)) {         
  364.                foreach ($item['content'] as &$langues) {
  365.                    foreach ($langues as &$element) {
  366.                        unset($element['slug']);
  367.                        unset($element['langue']);
  368.                }
  369.            }
  370.        }
  371.     }
  372.     return $data;
  373.     }
  374.     public function getUsers($params) {
  375.         // Sauvegarde timestamp dans une variable si fourni     
  376.         $timestamp = (array_key_exists('timestamp'$params) && null !== $params['timestamp']) ? $params['timestamp'] : null;
  377.         // Suppression du filtre timestamp
  378.         $params['timestamp'] = null;
  379.         $data $this->get('user'$params)['user'];
  380.         $results = [];
  381.         if (!empty($data)) {
  382.             foreach ($data as &$user) {
  383.             // Filtre selon le timestamp si fourni
  384.                 if (null !== $timestamp) {
  385.                     $updatedAtValues = [];
  386.                     $this->extractUpdatedAt($user$updatedAtValues);
  387.                     $dateValue     max(array_filter($updatedAtValues));
  388.                     $dateTimestamp strtotime($dateValue);
  389.                     // Comparaison des deux timestamps
  390.                     if ($timestamp $dateTimestamp) {
  391.                         continue ;
  392.                     }
  393.                 }
  394.                     $results[] = $this->transformUser($user);
  395.             }
  396.         }
  397.         return $results;
  398.     }
  399.     // Statut publication pour un séjour
  400.     public function getVoyagesStatutPublication($row$timestamp null) {
  401.         $params = array(
  402.             'conditions' => array(
  403.                 'walkinn_voyage.id = '.$row['id']
  404.             ), 
  405.             'joins' => array(
  406.                 'INNER JOIN walkinn_voyage ON walkinn_voyage.statut_publication_id = walkinn_voyage_statut_publication.id'
  407.         ),
  408.         'timestamp' => $timestamp
  409.     );
  410.         return $this->get('statut_publication'$params)['voyage_statut_publication'];
  411.     }
  412.     // Statut publication pour un séjour
  413.     public function getDestinationsVoyage($row$timestamp null) {
  414.         $params = array(
  415.             'conditions' => array(
  416.                 'voyage_destination.voyage_id = '.$row['id']
  417.             ), 
  418.             'joins' => array(
  419.                 'INNER JOIN voyage_destination ON walkinn_destination.id = voyage_destination.destination_id'
  420.             ),
  421.             'timestamp' => $timestamp
  422.         );
  423.         $destinations $this->get('destination'$params)['destination'];
  424.         $results = [];
  425.         foreach ($destinations as $dest) {
  426.             $results[] = (null !== $dest["slug"]) ? $dest["slug"] : "";
  427.             continue;
  428.         }
  429.         $results[] = $row['destination'];
  430.         return $results;
  431.     }
  432.     // Statut publication par id
  433.     public function getStatutPublicationById($id) {
  434.         $params = array(
  435.             'conditions' => array(
  436.                 'walkinn_voyage_statut_publication.id = '.$id
  437.             ), 
  438.     );
  439.         return $this->get('statut_publication'$params)['voyage_statut_publication'];
  440.     }
  441.     // TODO à supprimer
  442.     // Grand itinéraire pour un séjour
  443.     public function getVoyagesGrandItineraire($row$timestamp null) {
  444.         $arr  = [];
  445.         if (null !== $row['grand_itineraire_id']) {        
  446.             $params = array(
  447.                 'conditions' => array(
  448.                     'walkinn_editorial.id = '.$row['grand_itineraire_id']
  449.                 ), 
  450.                 'joins' => array(
  451.                     'INNER JOIN walkinn_editorial ON walkinn_editorial.id = walkinn_editorial_contenu.editorial_id'
  452.                 ),
  453.                 'timestamp' => $timestamp
  454.             );
  455.             $data $this->get('editorial'$params)['editorial_contenu'];
  456.             foreach ($data as $contenu) {
  457.                 $arr[$contenu['langue']][] = $contenu;
  458.             }
  459.         }
  460.         return $arr;
  461.     }
  462.     public function getVoyageInformationPratique(&$row$timestamp null) {
  463.         // Récupère les descriptions
  464.         $row['information_pratiques'] = null;
  465.         
  466.         if (null !== $row['info_pratiques_id']) {
  467.             $r             = array();
  468.             $infoPratiques $this->getEditorialById($row['info_pratiques_id']);
  469.             foreach ($infoPratiques as $lang => $i) {
  470.                 foreach ($i as $infoPratique) {
  471.                     $r[$lang] = array( 
  472.                         'libelle'    => $infoPratique['libelle'],
  473.                         'content'    => $infoPratique['contenu'],
  474.                         'created_at' => $infoPratique['created_at'],
  475.                         'updated_at' => $infoPratique['updated_at'],
  476.                     );
  477.                 }
  478.             }
  479.         $row['information_pratiques'] = $r;
  480.         unset($row['info_pratiques_id']);
  481.     }
  482.     return $row;
  483.     }
  484.     public function getVoyageDescriptions(&$row$timestamp null) {
  485.         // Récupère les descriptions
  486.         if (null !== $row['descriptions_id']) {
  487.             $r = array();
  488.             $descriptions $this->getEditorialById($row['descriptions_id']);
  489.             foreach ($descriptions as $d) {
  490.                 foreach ($d as $desc) {
  491.                     $r[$desc['slug']][$desc['langue']] = array( 
  492.                         'content'    => $desc['contenu'],
  493.                         'created_at' => $desc['created_at'],
  494.                         'updated_at' => $desc['updated_at'],
  495.                     );
  496.                 }
  497.             }
  498.             if (array_key_exists('long'$r)) {
  499.                 $row['description_longue'] = $r['long'];
  500.             }
  501.             if (array_key_exists('short'$r)) {
  502.                 $row['description_courte'] = $r['short'];
  503.             }
  504.     }
  505.     return $row;
  506.     }
  507.     public function getVoyageBlocInfo($editorialId$typeId$typeBloc null) {
  508.         $r = array();
  509.         if (null !== $editorialId) {
  510.             $blocs $this->getEditorialById($editorialId);
  511.             foreach ($blocs as $lang => $i) {
  512.                 foreach ($i as $bloc) {
  513.                     $r[$lang] = array( 
  514.                         'libelle'       => $bloc['libelle'],
  515.                         'content'       => $bloc['contenu'],
  516.                         'created_at'    => $bloc['created_at'],
  517.                         'updated_at'    => $bloc['updated_at'],
  518.                     );
  519.                 }
  520.             }
  521.     }
  522.     return array('id' => $editorialId'bloc_type_slug' => $typeBloc'content' => $r);
  523.                         
  524.     }
  525.     public function getVoyageBlocInfoBagage($row$timestamp null) {
  526.         return $this->getVoyageBlocInfo($row['bloc_info_bagage_id']
  527.             , \App\Enum\EditorialEnum::TYPE_VOYAGE_BLOC_BAGAGES
  528.             , \App\Enum\KernixItemEnum::SLUG_BLOC_BAGAGES
  529.         );
  530.     }
  531.     public function getVoyageBlocInfoVelo($row$timestamp null) {
  532.         return $this->getVoyageBlocInfo($row['bloc_info_velo_id']
  533.             , \App\Enum\EditorialEnum::TYPE_VOYAGE_BLOC_VELOS
  534.             , \App\Enum\KernixItemEnum::SLUG_BLOC_VELOS
  535.         );
  536.     }
  537.     public function getVoyageBlocInfoGps($row$timestamp null) {
  538.         return $this->getVoyageBlocInfo($row['bloc_info_gps_id']
  539.             , \App\Enum\EditorialEnum::TYPE_VOYAGE_BLOC_GPS
  540.             , \App\Enum\KernixItemEnum::SLUG_BLOC_GPS
  541.         );
  542.     }
  543.     public function getVoyageBlocInfoDocument($row$timestamp null) {
  544.         return $this->getVoyageBlocInfo($row['bloc_info_document_id']
  545.             , \App\Enum\EditorialEnum::TYPE_VOYAGE_BLOC_DOCUMENTS
  546.             , \App\Enum\KernixItemEnum::SLUG_BLOC_DOCUMENTS
  547.         );
  548.     }
  549.     public function getVoyageBlocForfait(&$row$timestamp null) {
  550.         $forfait $this->getVoyageBlocInfo($row['bloc_forfait_id'], \App\Enum\EditorialEnum::TYPE_VOYAGE_BLOC_FORFAIT);
  551.         $row['forfait']['content'] = $forfait['content'];
  552.         return $row;
  553.     }
  554.     // Grand itinéraire pour un séjour
  555.     public function getVoyagesBlocInfo(&$row$timestamp null) {
  556.         $arr = [];
  557.         $arr[] = $this->getVoyageBlocInfoBagage($row$timestamp null);
  558.     unset($row['bloc_info_bagage_id']);
  559.         $arr[] = $this->getVoyageBlocInfoVelo($row$timestamp null);
  560.     unset($row['bloc_info_velo_id']);
  561.         $arr[] = $this->getVoyageBlocInfoGps($row$timestamp null);
  562.     unset($row['bloc_info_gps_id']);
  563.         $arr[] = $this->getVoyageBlocInfoDocument($row$timestamp null);
  564.     unset($row['bloc_info_document_id']);
  565.         $row['bloc_infos'] = $arr;
  566.     return $row;
  567.     }
  568.     // Niveau de difficulté pour un séjour
  569.     public function getVoyagesNiveauDifficulte($row$timestamp null) {
  570.         $params = array(
  571.             'conditions' => array(
  572.                 'walkinn_voyage.id = '.$row['id']
  573.             ), 
  574.             'joins' => array(
  575.                 'INNER JOIN walkinn_voyage ON walkinn_voyage.niveau_id = walkinn_voyage_niveau_difficulte.id'
  576.             ),
  577.         'timestamp' => $timestamp
  578.         );
  579.         return $this->get('niveau_difficulte'$params)['voyage_niveau_difficulte'];
  580.     }
  581.     // Tags pour un séjour
  582.     public function getVoyagesTags($row$timestamp null) {
  583.         $params = array(
  584.             'conditions' => array(
  585.                 'walkinn_voyage.id = '.$row['id']
  586.             ), 
  587.             'joins' => array(
  588.                 'INNER JOIN voyage_voyage_tag ON voyage_voyage_tag.voyage_tag_id = walkinn_voyage_tag.id',
  589.                 'INNER JOIN walkinn_voyage ON walkinn_voyage.id = voyage_voyage_tag.voyage_id'
  590.             ),
  591.         'timestamp' => $timestamp
  592.         );
  593.     $tags $this->get('tag'$params)['voyage_tag'];
  594.     foreach ($tags as &$tag) {
  595.         $tag['libelle'] = array_merge(array('fr_FR' => $tag['libelle']), $this->getDoliTraduction($tag['libelle']));
  596.     }
  597.     return $tags;
  598.     }
  599.     // vélos pour un séjour
  600.     public function getVoyagesVelos($row$timestamp null) {
  601.         $params = array(
  602.             'conditions' => array(
  603.                 'walkinn_voyage.id = '.$row['id']
  604.             ), 
  605.             'joins' => array(
  606.                 'INNER JOIN walkinn_voyage_velo ON walkinn_voyage_velo.velo_id = walkinn_velo.id',
  607.                 'INNER JOIN walkinn_voyage ON walkinn_voyage.id = walkinn_voyage_velo.voyage_id'
  608.             ),
  609.         'timestamp' => $timestamp
  610.         );
  611.         $data $this->get('velo'$params);
  612.         if (array_key_exists('velo'$data)) {
  613.             $data $data['velo'];
  614.             foreach ($data as &$velo) {
  615.                 $velo['libelle'] = array_merge(array('fr_FR' => $velo['libelle']), $this->getDoliTraduction($velo['libelle']));
  616.             }
  617.         }
  618.         return $data;
  619.     }
  620.     // activités pour un séjour
  621.     public function getVoyageServicesActivite($row$timestamp null) {
  622.         $params = array(
  623.             'fields' => array(
  624.                 'walkinn_editorial.id AS editorial_id' ,
  625.                 'walkinn_editorial.id AS new_id'       // pour echanger l'id
  626.             ),            
  627.             'conditions' => array(
  628.                 'walkinn_voyage_service.voyage_id = '.$row['id'],
  629.                 'walkinn_service.type_id = '.\App\Enum\ServiceTypeEnum::ACTIVITE,
  630.                 'walkinn_editorial.activite = 1'
  631.             ), 
  632.             'joins' => array(
  633.                 'INNER JOIN walkinn_editorial ON walkinn_editorial.service_id = walkinn_service.id'
  634.             ),
  635.             'timestamp' => $timestamp
  636.         );
  637.         $services $this->get('voyage_service'$params)['voyage_service'];
  638.         // N'envoie plus les tarifs des services inclus
  639.         foreach ($services as &$service) {
  640.                 $service['service_id'] = $service['id']    ;
  641.                 $service['id']         = $service['new_id'];
  642.                 unset($service['new_id']);
  643.         }
  644.         return $services;
  645.     }
  646.     // Types de circuit pour un séjour
  647.     public function getVoyagesCircuit($row$timestamp null) {
  648.         $params = array(
  649.             'conditions' => array(
  650.                 'walkinn_voyage.id = '.$row['id']
  651.             ), 
  652.             'joins' => array(
  653.                 'INNER JOIN walkinn_voyage ON walkinn_voyage.type_circuit_id = walkinn_voyage_circuit.id'
  654.             ),
  655.         'timestamp' => $timestamp
  656.         );
  657.         return $this->get('circuit'$params)['voyage_circuit'];
  658.     }
  659.     // Destination pour un séjour
  660.     public function getVoyagesDestination($row$timestamp null) {
  661.         $results = [];    
  662.         $params = array(
  663.             'conditions' => array(
  664.                 'walkinn_voyage.id = '.$row['id']
  665.             ), 
  666.             'joins' => array(
  667.                 'INNER JOIN walkinn_voyage ON walkinn_voyage.destination_id = walkinn_destination.id'
  668.             )
  669.         );
  670.     return $this->get('destination'$params)['destination'];
  671.     }
  672.     // Les activités sont des contenus editoriaux avec une categorie sauf VELO
  673.     public function getVoyagesActivites($row) {
  674.         $params = array(
  675.             'conditions' => array(
  676.                 'walkinn_voyage_activite_edito.voyage_id = '.$row['id']
  677.               , 'we.categorie_id <> '.\App\Enum\EditorialCategorieEnum::VELO
  678.               'we.categorie_id <> '.\App\Enum\EditorialCategorieEnum::JOURNEE_LIBRE
  679.             ), 
  680.         );
  681.         $data $this->get('activite'$params)['voyage_activite'];
  682.         return $data;
  683.     }
  684.     // Les étapes sont des contenus editoriaux avec une categorie égale à VELO
  685.     public function getVoyagesEtapes($row) {
  686.         $params = array(
  687.             'conditions' => array(
  688.                  'walkinn_voyage_activite_edito.voyage_id = '.$row['id']
  689.                , '(we.categorie_id = '.\App\Enum\EditorialCategorieEnum::VELO.' OR we.categorie_id = '.\App\Enum\EditorialCategorieEnum::JOURNEE_LIBRE.' OR ISNULL(we.etape, 0) = 1 )'
  690.             ), 
  691.         );
  692.     $data $this->get('activite'$params)['voyage_activite'];
  693.     return $data;
  694.     }
  695.     // regroupe les étapes et activités sous forme de jour
  696.     public function getVoyagesJours($row) {
  697.         $results = [];
  698.         $params = array(
  699.             'conditions' => array(
  700.                 'walkinn_voyage_activite_edito.voyage_id = '.$row['id']
  701.             ), 
  702.     );
  703.     $data $this->get('activite'$params)['voyage_activite'];
  704.     foreach ($data as &$item) {
  705.             $item['jour'] = (null === $item['jour']) ? intval($item['jour']);
  706.             $item["distance"] = explode(','$item["distance"]);
  707.         $item['contenu']  = $this->stripHtmlAttribs($item['contenu']); 
  708.             //$results[intval($item['jour'])][(($item['categorie_id'] == \App\Enum\EditorialCategorieEnum::VELO) ? 'etapes' : 'activites')][$item['langue']][] = $item;
  709.             $results[$item['jour']]['etapes'][$item['langue']][] = $item;
  710.     }
  711.     // Remplacement des clés nulles
  712.         $results array_combine(
  713.             array_map(fn($k) => $k ?? '_null_'array_keys($results)),
  714.             array_values($results)
  715.         );
  716.         //ksort($results);
  717.         return $results;
  718.     
  719.     }
  720.     public function getVoyagesCotation($row) {
  721.         $results = array();
  722.         $params = array(
  723.             'conditions' => array(
  724.                 'vp.voyage_id = '.$row['id']
  725.             ), 
  726.         );
  727.     // Retrouve les cotations
  728.         $data $this->get('periode'$params)['voyage_periode_cotation'];
  729.         foreach ($data as $item) {
  730.             $cettePlage    = ['date_debut' => $item['date_debut'], 'date_fin' => $item['date_fin']];
  731.             $plages        array_merge([$cettePlage], array_filter($this->extractDateGroups($item['plages'])));
  732.         $results[$item['periode_id']]['periode_id'] = $item['periode_id'];
  733.         $results[$item['periode_id']]['libelle'] = array_merge(array('fr_FR' => $item['libelle']), $this->getDoliTraduction($item['libelle']));
  734.         if ($item['base'] == 'BASE') {
  735.             $results[$item['periode_id']]['montant']          = $item['tarif'];
  736.             $results[$item['periode_id']]['sup_single_vente'] = $item['sup_single_vente'];
  737.         } else {
  738.             $results[$item['periode_id']]['tarifs'][$item['base']] = $item['tarif'];
  739.         }
  740.         $results[$item['periode_id']]['dates'] = $plages;
  741.         }
  742.     // Faire le calcul
  743.     // Malheureusement on traite 2 fois...
  744.     foreach ($results as $periodeId => &$result) {
  745.             $result['sup_voyageur_solo'] = null;
  746.             if (array_key_exists('tarifs'$result)) {
  747.             if (array_key_exists('BASE1'$result['tarifs']) && array_key_exists('BASE2'$result['tarifs'])) {
  748.                     $result['sup_voyageur_solo'] = intval($result['tarifs']['BASE1']) - intval($result['tarifs']['BASE2']);
  749.             }
  750.         unset($result['tarifs']);
  751.             }
  752.     }
  753.         return array_values($results);
  754.     }
  755.     public function getVoyagesFormules($voyage$includeFormule false$includeNiveauDifficulte false$includeTags true$includeDestination false$includeCircuit false$includeJours false$includeEtapes false$includeGrandItineraire false$includeBlocInfo false$includeAjustement true) {
  756.         $params = array(
  757.             'conditions' => array(
  758.                 sprintf('walkinn_voyage.id <> %s'$voyage['id']),
  759.             sprintf('walkinn_voyage.code_walkinn LIKE "%s-%%"'implode('-'array_slice(explode('-'$voyage['code_vertuoz']), 03)))
  760.             ), 
  761.         );
  762.         return $this->getVoyages('voyage'$params$includeFormule$includeNiveauDifficulte$includeTags$includeDestination$includeCircuit$includeJours$includeEtapes$includeGrandItineraire$includeBlocInfo$includeAjustement)['voyage'];
  763.     }
  764.     public function getVoyagesAjustements($voyage$includeFormule false$includeNiveauDifficulte false$includeTags false$includeDestination false$includeCircuit false$includeJours false$includeEtapes false$includeGrandItineraire false$includeBlocInfo false$includeAjustement false) {
  765.         $params = array(
  766.             'fields' => array(
  767.                 'walkinn_voyage_ajustement.jour'
  768.             ),        
  769.             'conditions' => array(
  770.                 'walkinn_voyage_ajustement.voyage_id ='.$voyage['id'],
  771.             ), 
  772.             'joins' => array(
  773.                 'INNER JOIN walkinn_voyage_ajustement ON walkinn_voyage_ajustement.ajustement_id = walkinn_ajustement.id'
  774.             ),
  775.             'order' => 'GROUP BY walkinn_ajustement.id ORDER BY walkinn_voyage_ajustement.id'
  776.         );
  777.         $data $this->get('ajustement'$params)['ajustement'];
  778.         $n 0;
  779.         foreach ($data as &$item) {
  780.             if (null !== $item['prestation_id']) {
  781.                 $params = array(
  782.                     'fields' => array(
  783.                         'walkinn_voyage.code_interne'
  784.                     ), 
  785.                     'conditions' => array(
  786.                         sprintf('walkinn_voyage.id = %s'$item['prestation_id']),
  787.                     ), 
  788.                 );
  789.                 $voyage $this->getVoyages('voyage'$params$includeFormule$includeNiveauDifficulte$includeTags$includeDestination$includeCircuit$includeJours$includeEtapes$includeGrandItineraire$includeBlocInfo$includeAjustement)['voyage'];
  790.                 if ( count($voyage) > ) {
  791.                     //$item['options']    = $voyage[0];
  792.                     $item['libelle']    = $voyage[0]['titre'];
  793.                     $item['soustitre']  = $voyage[0]['soustitre'];
  794.                     $item['periodes']   = $voyage[0]['periodes'];
  795.                     $item['code']       = $voyage[0]['code_interne'];
  796.                     $item['ordre']      = $n;
  797.                     $tarifs = [];
  798.                     foreach (range(1,3) as $ordre) {
  799.                         $arr = [
  800.                            'tarif_id' => null,
  801.                            'libelle'  => "tarif".$ordre,
  802.                            'ordre'    => $ordre,
  803.                            'code'     => "",
  804.                         ];
  805.                         $tarifs[] = $arr;
  806.                     }                
  807.                     if (true == $item['envoi_tarif_service']) {
  808.                         // Ajoute les tarifs
  809.                         $params = array(
  810.                             'fields' => array(
  811.                                 'walkinn_service2.libelle AS tarif_libelle',
  812.                                 'walkinn_service2.id      AS tarif_id'     ,
  813.                             ),            
  814.                             'conditions' => array(
  815.                                 'walkinn_voyage_service.voyage_id = '.$item['prestation_id'],
  816.                                 'walkinn_service2.parent_id = walkinn_service.id',
  817.                             ), 
  818.                             'joins' => array(
  819.                                 'LEFT JOIN walkinn_service AS walkinn_service2 ON walkinn_service2.parent_id = walkinn_service.id'
  820.                             ),
  821.                         );
  822.                         $vtarifs $this->get('voyage_service'$params)['voyage_service'];
  823.                         if (count($vtarifs) > 0) {
  824.                             $tarifs $vtarifs;
  825.                             $n 1;
  826.                             foreach ($tarifs as &$tarif) {
  827.                                 $arr = [
  828.                                     'tarif_id' => $tarif['tarif_id'], 
  829.                                     'libelle'  => $tarif['tarif_libelle'],
  830.                                     'ordre'    => $n,
  831.                                     'code'     => sprintf('%s | %s | %s'$item['libelle']['fr_FR'], $tarif['libelle'], $tarif['tarif_libelle']),
  832.                                 ];
  833.                                 $tarif $arr;
  834.                                 $n++;
  835.                             }
  836.                         } 
  837.                     }
  838.                     $item['type_tarif'] = $tarifs;
  839.                 }
  840.                 unset($item['envoi_tarif_service']);
  841.                 unset($item['prestation_id']);
  842.             }
  843.             $n++;
  844.         }
  845.         return $data;
  846.     }
  847.     public function getReservations($params) {
  848.         // Sauvegarde timestamp dans une variable si fourni     
  849.         $timestamp = (array_key_exists('timestamp'$params) && null !== $params['timestamp']) ? $params['timestamp'] : null;
  850.         // Suppression du filtre timestamp
  851.         $params['timestamp'] = null;
  852.         $reservations $this->get('reservation'$params)['kernix_reservation'];
  853.         foreach($reservations as $key => &$reservation) {
  854.             $params = array(
  855.                 'conditions' => array(
  856.                     'kernix_reservation_participant.reservation_id = '.$reservation['id']
  857.                 ), 
  858.             );
  859.             $participants $this->get('reservation_participant'$params);
  860.             $reservation['participants'] = $participants['kernix_reservation_participant'];
  861.             $params = array(
  862.                 'conditions' => array(
  863.                     'kernix_reservation_ligne.reservation_id = '.$reservation['id']
  864.                 ), 
  865.             );
  866.             $lignes $this->get('reservation_ligne'$params);
  867.             $reservation['lignes'] = $lignes['kernix_reservation_ligne'];
  868.             $params = array(
  869.                 'conditions' => array(
  870.                     'kernix_reservation_facturation.reservation_id = '.$reservation['id']
  871.                 ), 
  872.             );
  873.             $facturation $this->get('reservation_facturation'$params);
  874.             $reservation['facturation'] = $facturation['kernix_reservation_facturation'];
  875.             $params = array(
  876.                 'conditions' => array(
  877.                     'kernix_reservation_livraison.reservation_id = '.$reservation['id']
  878.                 ), 
  879.             );
  880.             $livraison $this->get('reservation_livraison'$params);
  881.             $reservation['livraison'] = $livraison['kernix_reservation_livraison'];
  882.             $params = array(
  883.                 'conditions' => array(
  884.                     'kernix_reservation_ajustement.reservation_id = '.$reservation['id']
  885.                 ), 
  886.             );
  887.             $ajustements $this->get('reservation_ajustement'$params);
  888.             $reservation['ajustements'] = $ajustements['kernix_reservation_ajustement'];
  889.         // Filtre selon le timestamp si fourni
  890.         if (!$this->hasCorrectTimestamp($timestamp$reservation)) {
  891.                 unset($reservations[$key]);
  892.         }  
  893.         }
  894.         return $reservations;
  895.     }
  896. // @@@@@@@@@@@@@@@@@@@@@@@@@@@@@ DOSSIER @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
  897.     public function getDossiersByMail($email$timestamp null) {
  898.         $filters = ['email' => $email'timestamp' => $timestamp];
  899.         return $this->getDossiers($filters);
  900.     }
  901.     public function getDossiersById($id$timestamp null) {
  902.         $filters = ['id' => $id'timestamp' => $timestamp];
  903.         return $this->getDossiers($filters);
  904.     }
  905.     public function getDevis($filters = []) {
  906.          // On récupère les données sans filtre de date
  907.         $params = array(
  908.             'conditions' => array(
  909.             ), 
  910.         );
  911.         $timestamp null;
  912.         $dossiers $this->get('devis'$params)['devis'];
  913.         // Pour tous les dossiers
  914.         foreach ($dossiers as $key => &$row) {
  915.             // participants
  916.             $participants $this->em->getRepository(Dossier::class)->findParticipantsForKernix($row['id']);
  917.             $row['participants'] = count($participants);
  918.             // Filtre selon le timestamp si fourni
  919.             if (null !== $timestamp) {
  920.                 $updatedAtValues = [];
  921.                 $this->extractUpdatedAt($row$updatedAtValues);
  922.            
  923.                 $dateValue     max(array_filter($updatedAtValues));
  924.                 $dateTimestamp strtotime($dateValue);
  925.            
  926.                 // Comparaison des deux timestamps
  927.                 if ($timestamp $dateTimestamp) {
  928.                     continue ;
  929.                 }
  930.                 unset($dossiers[$key]);
  931.             }
  932.         }
  933.         return $dossiers;
  934.     }
  935.     public function getDossiers($filters = []) {
  936.          // On récupère les données sans filtre de date
  937.         $params = array(
  938.             'conditions' => array(
  939.             ), 
  940.         );
  941.         $timestamp null;
  942.         
  943.         if (count($filters) > 0) {
  944.             if (array_key_exists('timestamp'$filters)) {
  945.                 $timestamp $filters['timestamp'];    
  946.             }
  947.             if (array_key_exists('email'$filters)) {
  948.                 $params['conditions'][] = 'kr.client = "'.$filters['email'].'"';    
  949.             }
  950.             if (array_key_exists('id'$filters)) {
  951.                 $params['conditions'][] = 'walkinn_dossier.id = "'.$filters['id'].'"';    
  952.             }
  953.         }
  954.         $dossiers $this->get('dossier'$params)['dossier'];
  955.         $results = [];
  956.         // Pour tous les dossiers
  957.         foreach ($dossiers as $key => &$row) {
  958.             //$row['statut'] = $this->statutReservationDolibarrToKernix($row['statut']);
  959.             // participants
  960.             $participants $this->em->getRepository(Dossier::class)->findParticipantsForKernix($row['id']);
  961.             $row['participants'] = $participants;
  962.             $ajustements $this->em->getRepository(Dossier::class)->findAjustementsForKernix($row['id']);
  963.             $row['ajustements'] = $ajustements;
  964.             $livraison $this->em->getRepository(Dossier::class)->findLivraisonForKernix($row['id'], 'facture');
  965.             $row['livraison'] = $livraison;
  966.             $facturation $this->em->getRepository(Dossier::class)->findFacturationForKernix($row['id'], 'facture');
  967.             $row['facturation'] = $facturation;
  968.             $hebergements $this->em->getRepository(Dossier::class)->findHebergementsForKernix($row['id']);
  969.             $row['hebergements'] = $hebergements;
  970.             $activites $this->em->getRepository(Dossier::class)->findActivitesForKernix($row['id']);
  971.             $row['activites'] = $activites;
  972.             //if (array_key_exists('facture_id', $row) && null !== $row['facture_id']) {
  973.             $paiements $this->em->getRepository(Dossier::class)->findPaymentsForKernixByDossierId($row['id'], $row['pending']);
  974.             $row['paiements'] = $paiements;
  975.             unset($row['pending']);
  976.             //}
  977.             $row['supplements'] = $this->em->getRepository(Dossier::class)->findLignesForKernix($row['id'], 'supp' );
  978.             $row['reductions' ] = $this->em->getRepository(Dossier::class)->findLignesForKernix($row['id'], 'reduc');
  979.             // Filtre selon le timestamp si fourni
  980.             if (null !== $timestamp) {
  981.                 $updatedAtValues = [];
  982.                 $this->extractUpdatedAt($row$updatedAtValues);
  983.            
  984.                 $dateValue     max(array_filter($updatedAtValues));
  985.                 $dateTimestamp strtotime($dateValue);
  986.            
  987.                 // Comparaison des deux timestamps
  988.                 if ($timestamp $dateTimestamp) {
  989.                     continue ;
  990.                 }
  991.                 unset($dossiers[$key]);
  992.             }
  993.         }
  994.         return $dossiers;
  995.     }
  996.     public function getDossierDocuments($dossierId) {
  997.         $params = array(
  998.             'conditions' => array(
  999.                 'wd.id = '.$dossierId
  1000.               'walkinn_document_generator.entite = "dossier"'
  1001.             ), 
  1002.             'joins' => array(
  1003.                  'INNER JOIN walkinn_dossier_segment wds ON wds.id = walkinn_document_generator.entite_id'
  1004.                'INNER JOIN walkinn_dossier wd ON wd.id = wds.dossier_id'
  1005.             )
  1006.         );
  1007.         $data $this->get('document_itineraire'$params)['document_generator'];
  1008.         return $data;
  1009.     }
  1010.     public function getDossierDevis($rowId) {
  1011.         return $this->proposalService->downloadProposalFromRowid($rowId);
  1012.     }
  1013.     public function getDossierFacture($rowId) {
  1014.         return $this->invoiceService->downloadInvoiceFromRowid($rowId);
  1015.     }
  1016.     public function getDossierCommande($rowId) {
  1017.         return $this->orderService->downloadOrderFromRowid($rowId);
  1018.     }
  1019. // @@@@@@@@@@@@@@@@@@@@@@@@@@@@@ UTILS @@@@@@@@@@@@@@@@@@@@@@@@@@
  1020.     // Retourne la traduction
  1021.     public function getDoliTraduction($transkey) {
  1022.     $results = [];
  1023.         if (strlen($transkey) > 0) {
  1024.             $params = array(
  1025.                 'conditions' => array(
  1026.                 'doli_overwrite_trans.transkey = "'addslashes($transkey) .'"',
  1027.                     ), 
  1028.         );
  1029.         $data $this->get('doli_overwrite'$params)['doli_overwrite_trans'];
  1030.         foreach ($data as $traduction) {
  1031.                 $results[$traduction['lang']] = $traduction['transvalue'];
  1032.         }
  1033.     }
  1034.     return $results;
  1035.     }
  1036.     function getDossierDocumentItineraire($dossierId) {
  1037.         $dossier $this->em->getRepository(Dossier::class)->findOneById($dossierId);
  1038.         $basePath sprintf('%s/uploads/Dossier/%s/arbo'$this->params->get('public_path'), $dossier->getCodeWalkinn());
  1039.         $latestPdf null;
  1040.         $latestTime 0;
  1041.         
  1042.         // Ouvrir le répertoire de base
  1043.         foreach (glob($basePath '/SEGMENT-*') as $segmentDir) {
  1044.             if (!is_dir($segmentDir)) {
  1045.                 continue;
  1046.             }
  1047.         
  1048.             // Chercher tous les .pdf du dossier SEGMENT
  1049.             foreach (glob($segmentDir '/*.pdf') as $pdfFile) {
  1050.                 $fileTime filemtime($pdfFile);
  1051.                 if ($fileTime $latestTime) {
  1052.                     $latestTime $fileTime;
  1053.                     $latestPdf $pdfFile;
  1054.                 }
  1055.             }
  1056.         }
  1057.         
  1058.         if ($latestPdf) {
  1059.             if (file_exists($latestPdf)) {
  1060.                 $payload = [
  1061.                     'filename' => basename($latestPdf),
  1062.                     'content-type' => 'application/pdf',
  1063.                     'filesize' => filesize($latestPdf),
  1064.                     'content' => base64_encode(file_get_contents($latestPdf)),
  1065.                     'encoding' => 'base64',
  1066.                 ];
  1067.             
  1068.             }
  1069.             return $payload;
  1070.         }
  1071.         return null;
  1072.     }
  1073.     // Utils: les plages de date sont de la forme date1#date2|date1#date2|...
  1074.     // retourne array([date1, date2], [date1, date2], ...)
  1075.     function extractDateGroups($inputString) {
  1076.         // Initialiser un tableau pour stocker les groupes de dates
  1077.         $dateGroups = [];
  1078.     
  1079.         // Diviser la chaîne par le délimiteur '|'
  1080.         $groups explode('|'$inputString);
  1081.     
  1082.         // Parcourir chaque groupe de dates
  1083.         foreach ($groups as $group) {
  1084.             if (strlen($group) > 0) {
  1085.                 // Diviser le groupe par le délimiteur '#'
  1086.                 $dates array_filter(explode('#'$group));
  1087.     
  1088.                 // Ajouter le tableau de dates au tableau de groupes
  1089.                 $dateGroups[] = array('date_debut' => $dates[0], 'date_fin' => ((count($dates)>1) ? $dates[1] : ''));
  1090.         }
  1091.         }
  1092.     
  1093.         return $dateGroups;
  1094.     }
  1095.     // Fonction récursive pour extraire les valeurs 'updated_at'
  1096.     function extractUpdatedAt($data, &$results) {
  1097.         foreach ($data as $key => $value) {
  1098.             if (is_array($value)) {
  1099.                 $this->extractUpdatedAt($value$results);
  1100.             } elseif ((strpos($key'updated_at') !== false || strpos($key'created_at') !== false)&&(null !== $value)) {
  1101.                 $results[] = $value;
  1102.             }
  1103.         }
  1104.     }
  1105.     // Teste la validité d'un email
  1106.     function verifierEmail($email) {
  1107.         // Utilisation de la fonction filter_var pour valider l'email
  1108.         if (filter_var($emailFILTER_VALIDATE_EMAIL)) {
  1109.             return true// Email valide
  1110.         } else {
  1111.             return false// Email invalide
  1112.         }
  1113.     }
  1114.     // Teste l'existence d'un pax par son email
  1115.     function isPaxByMail($email) {
  1116.         $params = array(
  1117.             'conditions' => array(
  1118.                  sprintf('doli_societe.email = "%s"'$email)
  1119.             ), 
  1120.         );
  1121.     $data $this->get('user'$params)['user'];
  1122.     return (count($data) > 0) ? $data[0]['id'] : false;
  1123.     }
  1124.     // Teste l'existence d'un pax par son rowid
  1125.     function isPaxById($id) {
  1126.         $params = array(
  1127.             'conditions' => array(
  1128.                  sprintf('doli_societe.rowid = %s'$id)
  1129.             ), 
  1130.         );
  1131.     $data $this->get('user'$params)['user'];
  1132.     return (count($data) == 0) ? false $id;
  1133.     }
  1134.     // Teste l'existence d'un user
  1135.     // element est soit un rowid de la table societe, soit un email
  1136.     // retourne le rowid, false si non trouvé
  1137.     function isPaxExists($element) {
  1138.         $bool false;
  1139.     if (false !== $this->verifierEmail($element)) {
  1140.             return $this->isPaxByMail($element);        
  1141.     } else {
  1142.             if (intval($element) > 1) { 
  1143.                 return $this->isPaxById($element);        
  1144.             }
  1145.     }
  1146.         return $bool;
  1147.     }
  1148.     // Teste l'existence d'un voyage par son rowid
  1149.     function isVoyageExistsById($id) {
  1150.         $params = array(
  1151.             'conditions' => array(
  1152.                  sprintf('walkinn_voyage.id = %s'$id)
  1153.             ), 
  1154.         );
  1155.     $data $this->get('voyage'$params)['voyage'];
  1156.     return (count($data) == 0) ? false $id;
  1157.     }
  1158.     function stripHtmlAttribs($html) {
  1159.         $cleanHtml preg_replace('/<(\w+)(\s+[^>]+)?>/''<$1>'$html); // Supprime les attributs
  1160.         return strip_tags($cleanHtml'<br><em><p><span><table><th><tr><td><ul><ol><li><b><i><strong>'); // filtres les balises
  1161.     }
  1162.     public function transformUser(array $data): array
  1163.     {
  1164.         $result = [];
  1165.         foreach ($data as $key => $value) {
  1166.             // Nettoyage de clé (ex: "facturation_ birthday" → "facturation_birthday")
  1167.             $key str_replace(' '''$key);
  1168.             // Gestion des préfixes à regrouper
  1169.             if (preg_match('/^(facturation|livraison)_(.+)$/'$key$matches)) {
  1170.                 [$_$prefix$field] = $matches;
  1171.                 if (!isset($result[$prefix])) {
  1172.                     $result[$prefix] = [];
  1173.                 }
  1174.                 $result[$prefix][$field] = $value;
  1175.             }
  1176.             // Autres clés laissées telles quelles
  1177.             else {
  1178.                 $result[$key] = $value;
  1179.             }
  1180.         }
  1181.         return $result;
  1182.     }
  1183.     public function statutReservationDolibarrToKernix($statutDolibarr) {
  1184.     $statut 'to_progress';    
  1185.         switch ($statutDolibarr) {
  1186.         case (\App\Enum\DossierEtatEnum::EN_COURS_DE_RESERVATION) :
  1187.             $statut 'to_progress';    
  1188.                 break;
  1189.             default:
  1190.             $statut 'to_progress';    
  1191.                 break;
  1192.     }
  1193.         return $statut;
  1194.     }
  1195. }