src/Aviatur/HotelBundle/Controller/HotelRestController.php line 157

Open in your IDE?
  1. <?php
  2. namespace Aviatur\HotelBundle\Controller;
  3. use Aviatur\AgencyBundle\Entity\Agency;
  4. use Aviatur\GeneralBundle\Services\AviaturAthServices;
  5. use Aviatur\GeneralBundle\Services\AviaturRestService;
  6. use Aviatur\GeneralBundle\Services\PointRedemptionService;
  7. use GuzzleHttp\Promise\Utils;
  8. use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
  9. use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
  10. use Aviatur\GeneralBundle\Entity\Metatransaction;
  11. use Aviatur\GeneralBundle\Services\AviaturErrorHandler;
  12. use Aviatur\HotelBundle\Models\HotelModel;
  13. use FOS\UserBundle\Model\UserInterface;
  14. use Doctrine\Persistence\ManagerRegistry;
  15. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  16. use Symfony\Component\HttpFoundation\Cookie;
  17. use Symfony\Component\HttpFoundation\JsonResponse;
  18. use Symfony\Component\Routing\Annotation\Route;
  19. use Symfony\Component\HttpFoundation\RedirectResponse;
  20. use Symfony\Component\HttpFoundation\Request;
  21. use Symfony\Component\HttpFoundation\Response;
  22. use Symfony\Component\HttpFoundation\Session\SessionInterface;
  23. use Symfony\Component\Routing\RouterInterface;
  24. use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
  25. use Knp\Snappy\Pdf;
  26. use Aviatur\GeneralBundle\Entity\FormUserInfo;
  27. use Exception;
  28. use Symfony\Component\Security\Core\Exception\AccountStatusException;
  29. use FOS\UserBundle\Security\LoginManager;
  30. use Aviatur\GeneralBundle\Controller\OrderController;
  31. use Aviatur\AdminBundle\Services\QseCommission;
  32. use Aviatur\TwigBundle\Services\TwigFolder;
  33. use Aviatur\PaymentBundle\Services\TokenizerService;
  34. use Aviatur\PaymentBundle\Services\CustomerMethodPaymentService;
  35. use Aviatur\PaymentBundle\Controller\P2PController;
  36. use Aviatur\GeneralBundle\Services\PayoutExtraService;
  37. use Aviatur\CustomerBundle\Services\ValidateSanctionsRenewal;
  38. use Aviatur\GeneralBundle\Services\AviaturMailer;
  39. use Aviatur\GeneralBundle\Services\QuotationUtils;
  40. use Aviatur\HotelBundle\Services\UrlService;
  41. use Aviatur\HotelBundle\Services\DateValidatorService;
  42. use Aviatur\HotelBundle\Services\MarkupService;
  43. use Aviatur\GeneralBundle\Services\AviaturPixeles;
  44. use Aviatur\GeneralBundle\Services\AviaturWebService;
  45. use Aviatur\GeneralBundle\Services\ExceptionLog;
  46. use Aviatur\GeneralBundle\Services\AviaturLogSave;
  47. use Aviatur\GeneralBundle\Services\AviaturEncoder;
  48. use Aviatur\MultiBundle\Services\MultiHotelDiscount;
  49. // use Aviatur\GeneralBundle\Services\AviaturUpdateBestprices;
  50. // use Aviatur\HotelBundle\Services\SearchHotelCookie;
  51. use Aviatur\SearchBundle\Controller\TravelDestinationController;
  52. use Aviatur\SearchBundle\Entity\TravelDestination;
  53. use Aviatur\SearchBundle\Entity\SearchCities;
  54. use Aviatur\SearchBundle\Entity\TravelCountry;
  55. use Aviatur\SearchBundle\Entity\SearchAirports;
  56. use GuzzleHttp\Client;
  57. use GuzzleHttp\Promise;
  58. use Symfony\Component\HttpFoundation\StreamedResponse;
  59. use Aviatur\CustomerBundle\Models\CustomerModel;
  60. use Symfony\Component\HttpFoundation\RequestStack;
  61. class HotelRestController extends AbstractController
  62. {
  63.     /**
  64.      * @var \Doctrine\Persistence\ObjectManager
  65.      */
  66.     protected $em;
  67.     /**
  68.      * @var SessionInterface
  69.      */
  70.     protected $session;
  71.     /**
  72.      * @var Agency|object|null
  73.      */
  74.     protected $agency;
  75.     /**
  76.      * @var DateValidatorService
  77.      */
  78.     protected $dateValidator;
  79.     /**
  80.      * @var AviaturRestService
  81.      */
  82.     protected $aviaturRestService;
  83.     /**
  84.      * @var MarkupService
  85.      */
  86.     protected $markupService;
  87.     /**
  88.      * @var PointRedemptionService
  89.      */
  90.     protected $redemptionService;
  91.     /**
  92.      * @var AviaturAthServices
  93.      */
  94.     protected $aviaturAthServices;
  95.     /**
  96.      * @var bool
  97.      */
  98.     protected $isAval;
  99.     /**
  100.      * @param ManagerRegistry $registry
  101.      * @param SessionInterface $session
  102.      * @param AviaturRestService $aviaturRestService
  103.      * @param DateValidatorService $dateValidator
  104.      * @param MarkupService $markupService
  105.      * @param PointRedemptionService $redemptionService
  106.      */
  107.     public function __construct(ManagerRegistry $registrySessionInterface $sessionAviaturRestService $aviaturRestServiceDateValidatorService $dateValidatorMarkupService $markupServicePointRedemptionService $redemptionServiceAviaturAthServices $athServicesRequestStack $requestStack)
  108.     {
  109.         $this->em $registry->getManager();
  110.         $this->registry $registry;
  111.         $this->session $session;
  112.         $this->dateValidator $dateValidator;
  113.         $this->agency $this->em->getRepository(Agency::class)->find($session->get('agencyId'));
  114.         $this->aviaturRestService $aviaturRestService;
  115.         $this->markupService $markupService;
  116.         $this->redemptionService $redemptionService;
  117.         $this->aviaturAthServices $athServices;
  118.         $this->requestStack $requestStack;
  119.         // Validación para agencia Aval
  120.         if ($this->agency->getAssetsFolder() == 'aval') {
  121.             $this->isAval true;
  122.         } else {
  123.             $this->isAval false;
  124.         }
  125.     }
  126.     public function searchAction()
  127.     {
  128.         return $this->redirect($this->generateUrl('aviatur_search_hotels',[]));
  129.     }
  130.     /**
  131.      * Metodo encargado de consultar la disponibilidad hotelera, pendiente de conectar con el Qs
  132.      * Instancia la clase hotel, obtiene el dummy de RQ de disponibilidad, Asigna el id del provedor de hoteles
  133.      * Envia al metodo encargado de la logica de consumo de los servicios.
  134.      *
  135.      * @return Response
  136.      */
  137.     public function availAction(
  138.         Request $fullRequest,
  139.         TwigFolder $twigFolder,
  140.         ParameterBagInterface $parameterBag,
  141.         AviaturWebService $aviaturWebService,
  142.         AviaturErrorHandler $aviaturErrorHandler,
  143.         UrlService $urlService,
  144.         QseCommission $Qse,
  145.         $location,
  146.         $latitude,
  147.         $longitude,
  148.         $rooms,
  149.         $checkin,
  150.         $checkout,
  151.         $online
  152.     ) {
  153.         
  154.         $destinationExist $this->em->getRepository(TravelDestination::class)->findOneBy([
  155.             'latitude' => $latitude,
  156.             'longitude' => $longitude
  157.         ]);
  158.         if(!is_null($destinationExist)){
  159.             $resultPopularity TravelDestinationController::updateTravelDestinationPopularity($this->em$destinationExist->getId());
  160.         }
  161.         $agency $this->agency;
  162.         $agencyFolder $twigFolder->twigFlux();
  163.         $session $this->session;
  164.         $isFront $session->has('operatorId');
  165.         $transactionIdSessionName $parameterBag->get('transaction_id_session_name');
  166.         $roomsParam explode('/room='ltrim($rooms'/'));  // Elimina '/' inicial y divide en 'rooms'
  167.         $parsedRooms = [];
  168.         $radius "25";
  169.         $radius "25";
  170.         $session->set('[hotel]destinationtext'$location);
  171.         // Procesar los parámetros de cada habitación
  172.         foreach ($roomsParam as $room) {
  173.             parse_str($room$roomParams);
  174.             // Procesar el parámetro `children`
  175.             $childrenAges = [];
  176.             if (isset($roomParams['children']) && $roomParams['children'] !== 'n') {
  177.                 $childrenAges array_map('intval'explode(' '$roomParams['children']));
  178.             }
  179.             // Agregar los datos procesados de la habitación
  180.             $parsedRooms[] = [
  181.                 'room' => isset($roomParams['room']) ? (int) $roomParams['room'] : null,
  182.                 'adults' => isset($roomParams['adults']) ? (int) $roomParams['adults'] : 0,
  183.                 'childrenAges' => $childrenAges,
  184.             ];
  185.         }
  186.         // Crear la estructura de habitaciones en base a los parámetros de adultos y niños
  187.         $roomslist = [];
  188.         foreach ($parsedRooms as $index => $room) {
  189.             $adults $room['adults'];
  190.             $childrenAges $room['childrenAges'];
  191.             // Definir las edades de los pasajeros
  192.             $passengerAges array_fill(0$adults30); // 30 años para adultos
  193.             if (!empty($childrenAges)) {
  194.                 $passengerAges array_merge($passengerAges$childrenAges); // Agregar las edades de los niños
  195.             }
  196.             // Añadir la habitación solo si tiene pasajeros (adultos o niños)
  197.             if ($adults || !empty($childrenAges)) {
  198.                 $roomslist[] = [
  199.                     "index" => $index 1,  // Índice de la habitación (1-based)
  200.                     "passengerAges" => $passengerAges
  201.                 ];
  202.             }
  203.         }
  204.         $urlAvailability $twigFolder->twigExists('@AviaturTwig/' $agencyFolder '/Hotel/Default/results.html.twig');
  205.         $AvailabilityArray = [
  206.             'cityName' => 'cityName',
  207.             'countryCode' => 'countryCode',
  208.             'StartDate' => $checkin,
  209.             'EndDate' => $checkout,
  210.             'Rooms' => count($parsedRooms),
  211.             'Destination' => $location,
  212.             'Nights' => (strtotime($checkin) - strtotime($checkout)) / 86400,
  213.         ];
  214.         $services = [];
  215.         $countAdults 0;
  216.         $countChildren 0;
  217.         // Recorrer las habitaciones procesadas
  218.         foreach ($parsedRooms as $index => $room) {
  219.             // Obtener número de adultos
  220.             $roomAdults $room['adults'] ?? 0;
  221.             // Obtener edades de niños (ya procesadas como un array en `$parsedRooms`)
  222.             $childAges $room['childrenAges'] ?? [];
  223.             $childrenCount count($childAges);
  224.             // Sumar al total general de adultos y niños
  225.             $countAdults += $roomAdults;
  226.             $countChildren += $childrenCount;
  227.             // Crear la estructura de servicios para cada habitación
  228.             $services[] = [
  229.                 'adults' => $roomAdults,
  230.                 'children' => $childAges,
  231.             ];
  232.             // Crear la estructura de disponibilidad para cada habitación
  233.             $AvailabilityArray[$index 1] = [
  234.                 'Children' => $childrenCount,
  235.                 'Adults' => $roomAdults,
  236.             ];
  237.         }
  238.         $validationResult $this->dateValidator->validateDates($checkin$checkout);
  239.         if (!empty($validationResult)) {
  240.             // Modal Error dispo el mismo dia
  241.             // Contadores para adultos y niños
  242.             $totalRooms 0;
  243.             $totalChildren 0;
  244.             $totalAdults 0;
  245.             foreach ($roomslist as $room) {
  246.                 foreach ($room['passengerAges'] as $age) {
  247.                     if ($age >= 18) {
  248.                         $totalAdults++;
  249.                     } else {
  250.                         $totalChildren++;
  251.                     }
  252.                 }
  253.                 $totalRooms++;
  254.             }
  255.             // Decodificar la URL
  256.             $fullUrl urldecode($fullRequest->getUri());
  257.             // Extraer los componentes
  258.             $urlParts explode('/'$fullUrl);
  259.             // dd($urlParts)
  260.             // Obtener ubicación
  261.             $location urldecode($urlParts[5]);
  262.             // Extraer fechas
  263.             $dates $urlParts[7];
  264.             list($date1$date2) = explode(' '$dates);
  265.             // Parsear parámetros de habitaciones
  266.             parse_str($urlParts[6], $params);
  267.             $locationRedirection trim(explode(','$location)[0]);
  268.             $whatsappUrl "https://wa.me/send?phone=5713821616&text=" urlencode(
  269.                 "Hola, quiero hacer una reserva en " $locationRedirection .
  270.                 " del " $date1 " al " $date2 .
  271.                 ", con (" $totalRooms ") habitaciones, " $totalAdults " adulto(s), " $totalChildren " niño(s)" .
  272.                 ". No he podido completar la reserva en línea debido a que es para el día de hoy. ¿Podrías ayudarme a gestionarla? ¡Gracias!"
  273.             );
  274.             return $this->redirect($aviaturErrorHandler->errorRedirectNoEmail($this->generateUrl('aviatur_search_hotels', []), 'Recomendación Automática'$validationResult['redirectText'],''$whatsappUrl ));
  275.         }
  276.         // Agregar el total de adultos y niños al final del array de disponibilidad
  277.         $AvailabilityArray['Children'] = $countChildren;
  278.         $AvailabilityArray['Adults'] = $countAdults;
  279.         $dateIn strtotime($checkin);
  280.         $dateOut strtotime($checkout);
  281.         $safeUrl 'https://'.$agency->getDomainsecure();
  282.         $makeLogin true;
  283.         if ($fullRequest->query->has('transactionMulti')) {
  284.             $transactionId base64_decode($fullRequest->query->get('transactionMulti'));
  285.             $session->set($transactionIdSessionName$transactionId);
  286.             $makeLogin false;
  287.             $requestMultiHotelDiscountInfo true;
  288.         }
  289.         if ($online == 'destination') {
  290.             $hoteltype 'HotelCollect';
  291.         } else {
  292.             $hoteltype 'HotelOnly';
  293.         }
  294.         // if ($session->get($session->get($transactionIdSessionName).'[crossed]'.'[url-hotel]')) { $makeLogin = false; }
  295.         if ($makeLogin) {
  296.             $transactionIdResponse $aviaturWebService->loginService('SERVICIO_MPT''dummy|http://www.aviatur.com.co/dummy/', []);
  297.             if ('error' == $transactionIdResponse || is_array($transactionIdResponse)) {
  298.                 $aviaturErrorHandler->errorRedirect('''Error MPA''No se creo Login!');
  299.                 // return new Response('Estamos experimentando dificultades técnicas en este momento.');
  300.                 return (new JsonResponse())->setData([
  301.                             'error' => true,
  302.                             'message' => 'Estamos experimentando dificultades técnicas en este momento.',
  303.                 ]);
  304.             }
  305.             $transactionId = (string) $transactionIdResponse;
  306.             $session->set($transactionIdSessionName$transactionId);
  307.         }
  308.         preg_match('/\((.*?)\)/'$location$matches);
  309.         $countryCode = isset($matches) ? $matches[1] : null;
  310.         // Verificamos si $locationLower contiene "cartagena" y si $countryCode es "co".
  311.         if (strpos(strtolower($location), 'cartagena') !== false && strtolower($countryCode) === 'co') {
  312.             $radius "60";
  313.         }
  314.         $jsonHotelAvailrq $urlService->jsonHotelAvailability($checkin$checkout'CUN'strtoupper($countryCode) , $latitude$longitude$radius$roomslist$transactionId$hoteltype);
  315.         $jsonHotelAvail = [
  316.             'HotelRq' => $jsonHotelAvailrq,
  317.             'payment' => $online,
  318.         ];
  319.         $ajaxParameters base64_encode(json_encode($jsonHotelAvail));
  320.         $processQse $Qse->getQse($fullRequest->attributes->get('providerid'));
  321.         $QSE $session->get($transactionId.'[QSE]');
  322.         $configHotelAgency $this->em->getRepository(\Aviatur\HotelBundle\Entity\ConfigHotelAgency::class)->findProviderForHotelsWithAgency($agency,'destination');
  323.         $destination = !empty($configHotelAgency) ? true false;
  324.         $response $this->render($urlAvailability, [
  325.             'ajaxParameters' => $ajaxParameters,
  326.             'availableArrayHotel' => $AvailabilityArray,
  327.             'inlineEngine' => true,
  328.             'safeUrl' => $safeUrl,
  329.             'cityName' => $location,
  330.             'checkin' => date('c'$dateIn),
  331.             'roomsconsulturl' => $rooms,
  332.             'checkout' => date('c'$dateOut),
  333.             'countrycode' => 'country='.$countryCode,
  334.             'online' => $online,
  335.             'isFront' => $isFront,
  336.             'isAval' => $this->isAval,
  337.             'destination' => $destination,
  338.             'QSE' => isset($QSE) ? $QSE null,
  339.             // 'cookieLastSearch' => '',
  340.             // 'availabilityHasDiscount' => $requestMultiHotelDiscountInfo,
  341.             // 'urlDescription' => $urlDescription,
  342.             // 'pointRedemption' => [],
  343.             // 'pixel_info' => $pixelInfo,
  344.         ]);
  345.         // $response->headers->setCookie(new Cookie('_availability_array[hotel]', base64_encode(json_encode($cookieArray)), (time() + 3600 * 24 * 7), '/'));
  346.         return $response;
  347.     }
  348.     
  349.     /**
  350.      * asyncFetchHotelProviders
  351.      *
  352.      * @param  mixed $twigFolder
  353.      * @return json
  354.      */
  355.     public function asyncFetchHotelProviders(Request $request): JsonResponse{
  356.         try {
  357.             $postData json_decode($request->getContent(), true);
  358.             $jsonHotelRequest json_decode(base64_decode($postData["data"]), true);
  359.             $agency $this->agency;
  360.             $configsHotelAgency $this->em
  361.                 ->getRepository(\Aviatur\HotelBundle\Entity\ConfigHotelAgency::class)
  362.                 ->findProviderForHotelsWithAgency($agency,$jsonHotelRequest['payment']);
  363.             $providers = [];
  364.             foreach ($configsHotelAgency as $config) {
  365.                 $provider $config->getProvider();
  366.                 array_push($providers, (Object)[
  367.                     "id" => $provider->getId(),
  368.                     "providerId" => $provider->getProvideridentifier(),
  369.                     "name" => $provider->getName()
  370.                 ]);
  371.             }
  372.             $response = (Object)[
  373.                 "providers" => $providers,
  374.                 "status" => (Object)[
  375.                     "message" => "success",
  376.                     "code" => 200
  377.                 ]
  378.             ];
  379.             return new JsonResponse(
  380.                 $response
  381.                 Response::HTTP_OK,
  382.             );
  383.         } catch (\Throwable $th) {
  384.             // TODOSG Comment errors 
  385.             $response = array(
  386.                 "providers" => [],
  387.                 "status" => (Object)[
  388.                     "error"  => $th->getMessage(). " - " $th->getLine(),
  389.                     "message" => "Error: En la búsqueda de proveedores de hoteles",
  390.                     "code" => 503
  391.                 ]
  392.             );
  393.             return new JsonResponse(
  394.                 $response
  395.                 Response::HTTP_SERVICE_UNAVAILABLE,
  396.             );
  397.         }
  398.     }
  399.     
  400.     /**
  401.      * fetchHotelProvider
  402.      *
  403.      * @param  string $url
  404.      * @param  mixed  $jsonHotelRequestInfo
  405.      * @param  string $payload
  406.      * @return mixed  $response
  407.      */
  408.     public function fetchHotelProvider($url$jsonHotelRequestInfo$payload 'GetAvail'){
  409.         $curl curl_init();
  410.         curl_setopt_array($curl, array(
  411.             CURLOPT_URL =>  $url.$payload,
  412.             CURLOPT_RETURNTRANSFER => true,
  413.             CURLOPT_SSL_VERIFYPEER => false,
  414.             CURLOPT_SSL_VERIFYHOST => false
  415.             CURLOPT_ENCODING => '',
  416.             CURLOPT_MAXREDIRS => 10,
  417.             CURLOPT_TIMEOUT => 0,
  418.             CURLOPT_FOLLOWLOCATION => true,
  419.             CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  420.             CURLOPT_CUSTOMREQUEST => 'POST',
  421.             CURLOPT_POSTFIELDS => json_encode($jsonHotelRequestInfo),
  422.             CURLOPT_HTTPHEADER => array(
  423.                 'Content-Type: application/json'
  424.             ),
  425.         ));
  426.         $filterEntities = [];
  427.         $filterEntities['provider'] = [];
  428.         $response curl_exec($curl);
  429.         curl_close($curl);
  430.         
  431.         return $response;
  432.     }
  433.     
  434.     /**
  435.      * asyncFetchAvailabilityRest
  436.      *
  437.      * @param  Request $request
  438.      * @param  AviaturLogSave $aviaturLogSave
  439.      * @return JsonResponse
  440.      */
  441.     public function asyncFetchAvailabilityRest(Request $requestAviaturLogSave $aviaturLogSave): JsonResponse{
  442.         $data = [];
  443.         try {
  444.             $postData json_decode($request->getContent(), true);
  445.             $agency $this->agency;
  446.             $agencyId $this->agency->getId();
  447.             
  448.             $jsonHotelRequestInfos json_decode(base64_decode($postData["ajaxHotelParameters"]), true);
  449.             $jsonHotelRequestInfo $jsonHotelRequestInfos['HotelRq'];
  450.             $transactionId $jsonHotelRequestInfo['TransactionIdentifier'];
  451.             $requestedProvider $postData["providerId"];
  452.             $configsHotelAgency $this->em
  453.                 ->getRepository(\Aviatur\HotelBundle\Entity\ConfigHotelAgency::class)
  454.                 ->findProviderByAgencyAndProvider($agencyId$requestedProvider); 
  455.             if(empty($configsHotelAgency)){
  456.                 throw new Exception("Hotel provider bad request");
  457.             }
  458.             
  459.             $url $configsHotelAgency->getWsUrl();
  460.             $hotelProviderEntity $configsHotelAgency->getProvider();
  461.             $hotelProviderIdentifier $hotelProviderEntity->getProviderIdentifier();
  462.             $hotelProviderName $hotelProviderEntity->getName();
  463.             // Save provider-request
  464.             $aviaturLogSave->logSave(json_encode($jsonHotelRequestInfo), 'HotelAvail'$hotelProviderIdentifier '_RQ'$transactionId);
  465.             $providerResponse self::fetchHotelProvider($url$jsonHotelRequestInfo);
  466.             $data json_decode($providerResponsetrue);
  467.             
  468.             if(
  469.                 empty($data) || 
  470.                 json_last_error() !== JSON_ERROR_NONE ||
  471.                 !is_array($data
  472.                 ){
  473.                 throw new Exception("Sin respuesta del proveedor $hotelProviderName");
  474.             }
  475.             // Save provider-response
  476.             $aviaturLogSave->logSave(json_encode($data), 'HotelAvail'$hotelProviderIdentifier '_RS'$transactionId);
  477.             if(isset($data['status']) && $data['status'] != 200){
  478.                 //data.filterEntities.provider[126]
  479.                 throw new Exception("Ocurrió un error en la respuesta del proveedor $hotelProviderName");
  480.             }
  481.             $markups $this->markupService->Markup($agency);
  482.             $destinationCode $data['data']['hotels']['hotels'][0]['location']['destination']['code'];
  483.             $hotelBlacklistArray = [];
  484.             $hotelBlacklist $this->em->getRepository(\Aviatur\HotelBundle\Entity\HotelHomologation::class)->findBySearchCities([null]);
  485.             // should be filtered by the adapters
  486.             foreach ($hotelBlacklist as $hotelBlacklisted) {
  487.                 foreach (json_decode($hotelBlacklisted->getHotelcodes()) as $hotelCode) {
  488.                     $hotelBlacklistArray[$hotelCode] = $hotelBlacklisted->getPreferredcode();
  489.                 }
  490.             }
  491.             foreach ($data['data']['hotels']['hotels'] as &$hotels) {
  492.                 $hotelIdentifier = (string) $hotelProviderIdentifier '-' . (string) $hotels['code'];
  493.                 $hotels['Show'] = '1';
  494.                 if (array_key_exists($hotelIdentifier$hotelBlacklistArray) && ($hotelBlacklistArray[$hotelIdentifier] != $hotelIdentifier)) {
  495.                     $hotels['Show'] = '0';
  496.                 } else {
  497.                     $hotelEntity $this->em->getRepository(\Aviatur\HotelBundle\Entity\Hotel::class)->findOneByCodhotel($hotelCode);
  498.                     $hotel null != $hotelEntity $hotelEntity->getId() : null;
  499.                     if (count($hotels['rates']) > 0) {
  500.                         $roomRate $hotels['rates'][0];
  501.                         $markup false;
  502.                         foreach ($markups['markups'] as $markupItem) {
  503.                             if (
  504.                                 ($markupItem['hotel_id'] == $hotel || $markupItem['hotel_id'] === null) &&
  505.                                 ($markups['providerOfConfig'][$markupItem['config_hotel_agency_id']] == (string) $hotelProviderIdentifier)
  506.                             ) {
  507.                                 if ($markups['typeOfConfig'][$markupItem['config_hotel_agency_id']] == 'N') {
  508.                                     $aviaturMarkup = (float) round($roomRate['net']) * $markupItem['value'] / (100 $markupItem['value']);
  509.                                 } else {
  510.                                     $aviaturMarkup 0;
  511.                                 }
  512.                                 $hotels['providerName'] = $markups['providerNames'][$markupItem['config_hotel_agency_id']];
  513.                                 $roomRate['AmountAviaturMarkup'] = round($aviaturMarkup);
  514.                                 $hotels['minRate'] = round($roomRate['net']) + $roomRate['AmountAviaturMarkup'];
  515.                                 $markup true;
  516.                                 break;
  517.                             }
  518.                         }
  519.                     }
  520.                     $filterEntities = [];
  521.                     $filterEntities['provider'] = [];
  522.                     // Nuevo $filterEntities para incluir códigos de proveedores de Hoteles
  523.                     if(!isset($filterEntities['provider'][$hotels['providers'][0]])){
  524.                         $filterEntities['provider'][$hotels['providers'][0]] = $hotels['providerName'];
  525.                     }
  526.                 }
  527.             }
  528.             $response = (Object)[
  529.                 "data" => (Object)[
  530.                     'provider' => $hotelProviderIdentifier,
  531.                     'filterEntities' => $filterEntities,
  532.                     'results' => $data,
  533.                 ],
  534.                 "status" => (Object)[
  535.                     "message" => "success",
  536.                     "code" => 200
  537.                 ]
  538.             ];
  539.             return new JsonResponse(
  540.                 $response
  541.                 Response::HTTP_OK,
  542.             );
  543.         } catch (\Throwable $th) {
  544.             $response = array(
  545.                 "data" => [],
  546.                 "status" => (Object)[
  547.                     "error"  => $th->getMessage(). " - " $th->getLine(),
  548.                     "message" => "Error: En la búsqueda de proveedores de hoteles",
  549.                     "code" => 503
  550.                 ]
  551.             );
  552.             return new JsonResponse(
  553.                 $response
  554.                 Response::HTTP_SERVICE_UNAVAILABLE,  
  555.             );
  556.         }
  557.     }
  558.     public function availabilityRest(Request $request,TwigFolder $twigFolderAviaturLogSave $aviaturLogSavestring $params): StreamedResponse
  559.     {
  560.         $payload =  'GetAvail';
  561.         $agency $this->agency;
  562.         $agencyFolder $twigFolder->twigFlux();
  563.         $jsonHotelAvails json_decode(base64_decode($params), true);
  564.         $jsonHotelAvail $jsonHotelAvails['HotelRq'];
  565.         $transactionId $jsonHotelAvail['TransactionIdentifier'];
  566.         // Obtener configuraciones activas de proveedores
  567.         $configsHotelAgency $this->em
  568.             ->getRepository(\Aviatur\HotelBundle\Entity\ConfigHotelAgency::class)
  569.             ->findProviderForHotelsWithAgency($agency,$jsonHotelAvails['payment']);
  570.         $response = new StreamedResponse(function () use ($agency$agencyFolder,$twigFolder$configsHotelAgency$payload$jsonHotelAvail$aviaturLogSave$transactionId) {
  571.             // Configurar encabezados para SSE
  572.             header('Content-Type: text/event-stream');
  573.             header('Cache-Control: no-cache');
  574.             header('Connection: keep-alive');
  575.             ob_implicit_flush(true);
  576.             // Para los filtros de proveedor
  577.             $filterEntities = [];
  578.             $filterEntities['provider'] = [];
  579.             // Instanciar el cliente HTTP
  580.             $client = new Client([
  581.                 'curl' => [
  582.                     CURLOPT_RETURNTRANSFER => true,
  583.                     CURLOPT_SSL_VERIFYPEER => false,
  584.                     CURLOPT_SSL_VERIFYHOST => false,  
  585.                     CURLOPT_ENCODING => '',
  586.                 ]
  587.             ]);
  588.             // Almacenar las promesas de los llamados
  589.             $promises = [];
  590.             // Configurar las solicitudes a cada proveedor
  591.             foreach ($configsHotelAgency as $config) {
  592.                 $url $config->getWsUrl();
  593.                 $providerId $config->getProvider();
  594.                 // Registrar la solicitud en el log
  595.                 $aviaturLogSave->logSave(json_encode($jsonHotelAvail), 'HotelAvail'$providerId->getProviderIdentifier() . '_RQ'$transactionId);
  596.                 // Crear la promesa para la solicitud HTTP
  597.                 $promises[$providerId->getProviderIdentifier()] = $client->postAsync($url.$payload, [
  598.                     'json' => $jsonHotelAvail,
  599.                 ]);
  600.             }
  601.             // Procesar cada respuesta tan pronto como se resuelvan
  602.             foreach (Utils::settle($promises)->wait() as $providerId => $result) {
  603.                 if ($result['state'] === 'fulfilled') {
  604.                     $response $result['value'];
  605.                     $data json_decode($response->getBody(), true);
  606.                     if($data['title'] == 'No hay disponibilidad para la fecha seleccionada' || $data['title'] == 'NotExistsAvailability') {
  607.                          echo "data: " json_encode([
  608.                             'provider' => $providerId,
  609.                             'error' => $data['detail'],
  610.                         ]) . "\n\n";
  611.                         // $renderTwig = $twigFolder->twigExists('@AviaturTwig/'.$agencyFolder.'/Hotel/Default/availability_no_result.html.twig');
  612.                         // return $this->render($renderTwig, [
  613.                         //     'error' => 'Hubo un problema al obtener los resultados de disponibilidad. Por favor, inténtelo nuevamente más tarde.',
  614.                         //     'isMulti' => false
  615.                         // ]);
  616.                         $aviaturLogSave->logSave(json_encode($data), 'HotelAvail'$providerId '_RS'$transactionId);
  617.                         continue;
  618.                     }
  619.                     // Registrar la respuesta en el log
  620.                     $aviaturLogSave->logSave(json_encode($data), 'HotelAvail'$providerId '_RS'$transactionId);
  621.                     $markups $this->markupService->Markup($agency);
  622.                     /* Busca por la ciudad de destino para depurar la consulta, de lo contrario buscará en todos los registros de homologación */
  623.                     $destinationCode $data['data']['hotels']['hotels'][0]['location']['destination']['code'];
  624.                     $destinationObject $this->em->getRepository(\Aviatur\SearchBundle\Entity\SearchCities::class)->findOneByIata($destinationCode);
  625.                     $homologationObjects $this->em->getRepository(\Aviatur\HotelBundle\Entity\HotelHomologation::class)->findBySearchCities([null]);
  626.                     $hotelHomologationArray = [];
  627.                     foreach ($homologationObjects as $homologationObject) {
  628.                         foreach (json_decode($homologationObject->getHotelcodes()) as $hotelCode) {
  629.                             $hotelHomologationArray[$hotelCode] = $homologationObject->getPreferredcode();
  630.                         }
  631.                     }
  632.                     // Verificar el estado de la respuesta
  633.                     if (isset($data['status']) && $data['status'] == 200) {
  634.                         foreach ($data['data']['hotels']['hotels'] as &$hotels) {
  635.                             $hotelIdentifier = (string) $providerId '-' . (string) $hotels['code'];
  636.                             $hotels['Show'] = '1';
  637.                             if (array_key_exists($hotelIdentifier$hotelHomologationArray) && ($hotelHomologationArray[$hotelIdentifier] != $hotelIdentifier)) {
  638.                                 $hotels['Show'] = '0';
  639.                             } else {
  640.                                 $hotelEntity $this->em->getRepository(\Aviatur\HotelBundle\Entity\Hotel::class)->findOneByCodhotel($hotelCode);
  641.                                 $hotel null != $hotelEntity $hotelEntity->getId() : null;
  642.                                 if (count($hotels['rates']) > 0) {
  643.                                     $roomRate $hotels['rates'][0];
  644.                                     $i 0;
  645.                                     $markup false;
  646.                                     while (!$markup) {
  647.                                         if (($markups['markups'][$i]['hotel_id'] == $hotel || null == $markups['markups'][$i]['hotel_id']) && ($markups['providerOfConfig'][$markups['markups'][$i]['config_hotel_agency_id']] == (string) $providerId)) {
  648.                                             if ('N' == $markups['typeOfConfig'][$markups['markups'][$i]['config_hotel_agency_id']]) {
  649.                                                 $aviaturMarkup = (float) round($roomRate['net']) * $markups['markups'][$i]['value'] / (100 $markups['markups'][$i]['value']);
  650.                                             } else {
  651.                                                 $aviaturMarkup 0;
  652.                                             }
  653.                                             $hotels['providerName'] = $markups['providerNames'][$markups['markups'][$i]['config_hotel_agency_id']];
  654.                                             $roomRate['AmountAviaturMarkup'] = round($aviaturMarkup);
  655.                                             $hotels['minRate'] = round($roomRate['net']) + $roomRate['AmountAviaturMarkup'];
  656.                                             //$hotels['rates'][0] = $roomRate;
  657.                                             $markup true;
  658.                                         }
  659.                                         ++$i;
  660.                                     }
  661.                                 }
  662.                                 /* Nuevo $filterEntities para incluir códigos de proveedores de Hoteles */
  663.                                 if(!isset($filterEntities['provider'][$hotels['providers'][0]])){
  664.                                     $filterEntities['provider'][$hotels['providers'][0]] = $hotels['providerName'];
  665.                                 }
  666.                             }
  667.                         }
  668.                     
  669.                         echo "data: " json_encode([
  670.                             'provider' => $providerId,
  671.                             'filterEntities' => $filterEntities,
  672.                             'results' => $data ?? []
  673.                         ]) . "\n\n";
  674.                     } else {
  675.                         // Enviar mensaje de error si aplica
  676.                         echo "data: " json_encode([
  677.                             'provider' => $providerId,
  678.                             'filterEntities' => [],
  679.                             'error' => $data['message'] ?? $data['title'] ?? 'Unknown error',
  680.                         ]) . "\n\n";
  681.                     }
  682.                 } else {
  683.                     //dd($result['value'], $result['reason']->getMessage());
  684.                     $aviaturLogSave->logSave($result['reason']->getResponse()->getBody()->getContents(), 'HotelAvail'$providerId '_RS'$transactionId);
  685.                     // Manejar errores en la solicitud
  686.                     echo "data: " json_encode([
  687.                         'provider' => $providerId,
  688.                         'filterEntities' => [],
  689.                         'error' => $result['reason']->getMessage(),
  690.                     ]) . "\n\n";
  691.                 }
  692.                 flush(); // Enviar respuesta al cliente
  693.             }
  694.             // Indicar que todas las respuestas se han enviado
  695.             echo "event: complete\n";
  696.             echo "data: {\"message\": \"All providers responded.\"}\n\n";
  697.         });
  698.         return $response;
  699.     }
  700.     /**
  701.      * @param $roomlist
  702.      * @return array
  703.      */
  704.     public function getInfoAndRoomsData($roomlist): array
  705.     {
  706.         $info $roomsData = [];
  707.         if (isset($roomlist['data']['hotelRoomlist'])) {
  708.             $info = isset($roomlist['data']['hotelRoomlist']['hotels']) ? $roomlist['data']['hotelRoomlist']['hotels'][0] : [];
  709.             $roomsData $roomlist['data']['hotelRoomlist']['rooms'] ?? [];
  710.         } elseif (isset($roomlist['data']['hotelRoomList'])) {
  711.             $info = isset($roomlist['data']['hotelRoomList']['hotels']) ? $roomlist['data']['hotelRoomList']['hotels'][0] : [];
  712.             $roomsData $roomlist['data']['hotelRoomList']['rooms'] ?? [];
  713.         }
  714.         return [$info$roomsData];
  715.     }
  716.     /**
  717.      * @param array $paymentOptions
  718.      * @param $paymentMethodAgency
  719.      * @return array
  720.      */
  721.     public function getCybersource(array $paymentOptions$paymentMethodAgency): array
  722.     {
  723.         $cybersource = [];
  724.         if (in_array('cybersource'$paymentOptions)) {
  725.             $cybersource['merchant_id'] = $paymentMethodAgency->getSitecode();
  726.             $cybersource['org_id'] = $paymentMethodAgency->getTrankey();
  727.         }
  728.         foreach ($paymentOptions as $key => $paymentOption) {
  729.             if ($paymentOption == 'cybersource') {
  730.                 unset($paymentOptions[$key]); // strip from other renderizable payment methods
  731.             }
  732.         }
  733.         return [$cybersource$paymentOptions];
  734.     }
  735.     protected function authenticateUser(UserInterface $userLoginManager $loginManager)
  736.     {
  737.         try {
  738.             $loginManager->loginUser(
  739.                 'main',
  740.                 $user
  741.             );
  742.         } catch (AccountStatusException $ex) {
  743.             // We simply do not authenticate users which do not pass the user
  744.             // checker (not enabled, expired, etc.).
  745.         }
  746.     }
  747.     public function roomListAction(
  748.         Request $fullRequest,
  749.         RouterInterface $router,
  750.         TwigFolder $twigFolder,
  751.         ParameterBagInterface $parameterBag,
  752.         AviaturErrorHandler $aviaturErrorHandler,
  753.         AviaturLogSave $aviaturLogSave,
  754.         QseCommission $Qse,
  755.         $rooms,
  756.         $hotelcode,
  757.         $checkIn,
  758.         $checkOut,
  759.         $providerid,
  760.         $countrycode,
  761.         $online 'online',
  762.         AviaturWebService $aviaturWebService,
  763.         $isFlightHotel false
  764.     )
  765.     {
  766.         $transactionIdSessionName $parameterBag->get('transaction_id_session_name');
  767.         $correlationIdSessionName $parameterBag->get('correlation_id_session_name');
  768.         $session $this->session;
  769.         $response = [];
  770.         $transactionId null;
  771.         $flux null;
  772.         // $provider = null;
  773.         $responseHotelDetail = [];
  774.         $guestsInfo null;
  775.         $fullPricing = [];
  776.         $pixel = [];
  777.         $em $this->em;
  778.         $session $this->session;
  779.         $agency $this->agency;
  780.         $request $fullRequest->request;
  781.         $server $fullRequest->server;
  782.         $domain $fullRequest->getHost();
  783.         $route $router->match(str_replace($fullRequest->getSchemeAndHttpHost(), ''$fullRequest->getUri()));
  784.         $returnUrl $twigFolder->pathWithLocale('aviatur_general_homepage');
  785.         $makeLogin false;
  786.         if($isFlightHotel && $session->has($transactionIdSessionName)) {
  787.             $transactionId $session->get($transactionIdSessionName);
  788.         } else {
  789.             $makeLogin true;
  790.         }
  791.         if ($makeLogin) {
  792.             $transactionIdResponse $aviaturWebService->loginService('SERVICIO_MPT''dummy|http://www.aviatur.com.co/dummy/', []);
  793.             if ('error' == $transactionIdResponse || is_array($transactionIdResponse)) {
  794.                 $aviaturErrorHandler->errorRedirect('''Error MPA''No se creo Login!');
  795.                 // return new Response('Estamos experimentando dificultades técnicas en este momento.');
  796.                 return (new JsonResponse())->setData([
  797.                             'error' => true,
  798.                             'message' => 'Estamos experimentando dificultades técnicas en este momento.',
  799.                 ]);
  800.             }
  801.             $transactionId = (string) $transactionIdResponse;
  802.             $session->set($transactionIdSessionName$transactionId);
  803.         }
  804.         $roomsParam explode('/room='ltrim($rooms'/'));  // Elimina '/' inicial y divide en 'rooms'
  805.         $parsedRooms = [];
  806.         $agencyFolder $twigFolder->twigFlux();
  807.         // Procesar los parámetros de cada habitación
  808.         foreach ($roomsParam as $room) {
  809.             parse_str($room$roomParams);
  810.             // Procesar el parámetro `children`
  811.             $childrenAges = [];
  812.             if (isset($roomParams['children']) && $roomParams['children'] !== 'n') {
  813.                 $childrenAges array_map('intval'explode(' '$roomParams['children']));
  814.             }
  815.             // Agregar los datos procesados de la habitación
  816.             $parsedRooms[] = [
  817.                 'room' => isset($roomParams['room']) ? (int) $roomParams['room'] : null,
  818.                 'adults' => isset($roomParams['adults']) ? (int) $roomParams['adults'] : 0,
  819.                 'childrenAges' => $childrenAges,
  820.             ];
  821.         }
  822.         // Crear la estructura de habitaciones en base a los parámetros de adultos y niños
  823.         $roomslist = [];
  824.         foreach ($parsedRooms as $index => $room) {
  825.             $adults $room['adults'];
  826.             $childrenAges $room['childrenAges'];
  827.             // Definir las edades de los pasajeros
  828.             $passengerAges array_fill(0$adults30); // 30 años para adultos
  829.             if (!empty($childrenAges)) {
  830.                 $passengerAges array_merge($passengerAges$childrenAges); // Agregar las edades de los niños
  831.             }
  832.             // Añadir la habitación solo si tiene pasajeros (adultos o niños)
  833.             if ($adults || !empty($childrenAges)) {
  834.                 $roomslist[] = [
  835.                     "index" => $index 1,  // Índice de la habitación (1-based)
  836.                     "passengerAges" => $passengerAges
  837.                 ];
  838.             }
  839.         }
  840.         if (true === $request->has('transactionID')) {
  841.             $transactionId $request->get('transactionID');
  842.             if (false !== strpos($transactionId'||')) {
  843.                 $explodedTransaction explode('||'$transactionId);
  844.                 $transactionId $explodedTransaction[0];
  845.                 $request->set('transactionID'$transactionId);
  846.                 $metaseachId $explodedTransaction[1];
  847.                 $session->set('generals[metasearch]'$metaseachId);
  848.                 $metatransaction $em->getRepository(\Aviatur\GeneralBundle\Entity\Metatransaction::class)->findOneByTransactionId($transactionId);
  849.                 if (null == $metatransaction) {
  850.                     $metasearch $em->getRepository(\Aviatur\GeneralBundle\Entity\Metasearch::class)->find($metaseachId);
  851.                     if (null == $metasearch) {
  852.                         $response['error'] = 'Por favor selecciona nuevamente tu itinerario de viaje';
  853.                         return $this->redirect($aviaturErrorHandler->errorRedirectNoEmail($returnUrl'Ha ocurrido un error en la validación'$response['error']));
  854.                     }
  855.                     $metatransaction = new Metatransaction();
  856.                     $metatransaction->setTransactionId((string) $transactionId);
  857.                     $metatransaction->setDatetime(new \DateTime());
  858.                     $metatransaction->setIsactive(true);
  859.                     $metatransaction->setMetasearch($metasearch);
  860.                     $em->persist($metatransaction);
  861.                     $em->flush();
  862.                 }
  863.                 $d1 $metatransaction->getDatetime();
  864.                 $d2 = new \DateTime(date('Y-m-d H:i:s'time() - (15 60)));
  865.                 if (false == $metatransaction->getIsactive()) {
  866.                     $response['error'] = 'Por favor selecciona nuevamente tu itinerario de viaje';
  867.                     return $this->redirect($aviaturErrorHandler->errorRedirectNoEmail($returnUrl''$response['error']));
  868.                 } elseif ($d1 $d2) {
  869.                     $response['error'] = 'Por favor selecciona nuevamente tu itinerario de viaje';
  870.                     return $this->redirect($aviaturErrorHandler->errorRedirectNoEmail($returnUrl'Tu consulta fue realizada hace mas de 15 minutos'$response['error']));
  871.                 } else {
  872.                     $metatransaction->setIsactive(false);
  873.                     $em->persist($metatransaction);
  874.                     $em->flush();
  875.                 }
  876.             } else {
  877.                 $session->set($transactionIdSessionName$transactionId);
  878.             }
  879.         } elseif (true === $session->has($transactionIdSessionName)) {
  880.             $transactionId $session->get($transactionIdSessionName);
  881.         }
  882.         $additional base64_encode($transactionId.'/'.$session->get($transactionId.'[hotel]['.$correlationIdSessionName.']'));
  883.         $country explode("="$countrycode);    
  884.         $session->set($transactionId.'[hotel]destinationtext'count($country) > $country[1] : " ");
  885.         // $provider = $em->getRepository(\Aviatur\MpaBundle\Entity\Provider::class)->find($session->get($transactionId.'[hotel][provider]'));
  886.         $dateIn strtotime($checkIn);
  887.         $dateOut strtotime($checkOut);
  888.         $hotel $hotelcode;
  889.         //$session->get($transactionId.'[availability_url]')
  890.         $rs $this->roomListCall($aviaturLogSave ,$checkIn$checkOut$hotel$roomslist ,$transactionId,$providerid,$online$isFlightHotel);
  891.         $fileName $aviaturLogSave->logSave($rs'HotelRoomList''RS',$transactionId);
  892.         $detail json_decode($rs);
  893.         $roomlist json_decode($rstrue);
  894.         if(isset($roomlist['errorP'])){
  895.             return $this->redirect($aviaturErrorHandler->errorRedirectNoEmail($returnUrl'Ha ocurrido un error'$roomlist['errorP']));
  896.         }
  897.         if (
  898.             isset($detail->data->hotelRoomlist->hotels) &&
  899.             is_countable($detail->data->hotelRoomlist->hotels) &&
  900.             count($detail->data->hotelRoomlist->hotels) > 0
  901.         ){
  902.             [$responseHotel] = $detail->data->hotelRoomlist->hotels;
  903.             $hotelInfo = (Object)[];
  904.             $hotelInfo->latitude $responseHotel->location->coordinates->latitude;
  905.             $hotelInfo->longitude $responseHotel->location->coordinates->longitude;
  906.             $hotelInfo->countryIata str_replace("country="""$countrycode);
  907.             $hotelInfo->providerId $responseHotel->providers[0];
  908.             $hotelInfo->hotelname $responseHotel->name;
  909.             
  910.             $storeResult TravelDestinationController::fetchAndStoreHotelLocation($this->registry$hotelInfo);
  911.             /* $xmlReport = TravelDestinationController::fetchHotelXmlReportFromTravelDestinations(
  912.                 $this->em,
  913.                 $responseHotel->name, 
  914.                 $responseHotel->location->coordinates->latitude, 
  915.                 $responseHotel->location->coordinates->longitude, 
  916.                 $responseHotel->providers[0],
  917.             );
  918.             dd($storeResult, $xmlReport); */
  919.         }
  920.         // $providerid= $detail->data->hotelRoomlist->hotels[0]->providers[0];
  921.         $provider $em->getRepository(\Aviatur\MpaBundle\Entity\Provider::class)->findOneByProvideridentifier($providerid);
  922.         $session->set($transactionId.'[hotel][provider]'$provider->getId());
  923.         //markup Roomlist
  924.         $markups $this->markupService->Markup($agency);
  925.         if (!empty($roomlist['data']['hotelRoomlist']['hotels'][0]['rates'])) {
  926.             foreach ($roomlist['data']['hotelRoomlist']['hotels'][0]['rates'] as &$rate ) {
  927.                 $i 0;
  928.                 $markup false;
  929.                 $appliedIndex null;
  930.                 while (!$markup) {
  931.                     if (($markups['providerOfConfig'][$markups['markups'][$i]['config_hotel_agency_id']] == (string) $providerid)) {
  932.                         if ('N' == $markups['typeOfConfig'][$markups['markups'][$i]['config_hotel_agency_id']]) {
  933.                             $aviaturMarkup = (float) round($rate['net']) * $markups['markups'][$i]['value'] / (100 $markups['markups'][$i]['value']);
  934.                             $taxMarkup = (float) round($rate['tax']) * $markups['markups'][$i]['value'] / (100 $markups['markups'][$i]['value']);
  935.                         } else {
  936.                             $aviaturMarkup 0;
  937.                             $taxMarkup 0;
  938.                         }
  939.                         $rate['providerName'] = $markups['providerNames'][$markups['markups'][$i]['config_hotel_agency_id']];
  940.                         $rate['AmountAviaturMarkup'] = round($aviaturMarkup);
  941.                         $rate['net'] = round($rate['net']) + $rate['AmountAviaturMarkup'];
  942.                         $rate['tax'] = round($rate['tax'] + $taxMarkup);
  943.                         //$hotels['rates'][0] = $roomRate;
  944.                         $markup true;
  945.                         $appliedIndex $i;
  946.                     }
  947.                     ++$i;
  948.                 }
  949.             if (!is_null($appliedIndex)) {
  950.                 $valor $markups['markups'][$appliedIndex]['value'];
  951.             }
  952.             }
  953.         }
  954.         // else {
  955.         //     $view = $twigFolder->twigExists('@AviaturTwig/' . $agencyFolder . '/Hotel/Includes/noAvailabilityRooms_card.html.twig');
  956.         //     return $this->render($view, []);
  957.         // }
  958.         //datos para el ordercontroller
  959.         // informacion que me deben de enviar
  960.         /*$markup = $em->getRepository(\Aviatur\HotelBundle\Entity\Markup::class)->find(262);
  961.         $markupValue = $markup->getValue();
  962.         $markupId = $markup->getId();
  963.         $roomRate = $detail->data->hotelRoomlist->hotels[0]->rates[0];
  964.         $aviaturMarkup = (float) $roomRate->net * $markupValue / (100 - $markupValue);
  965.         $roomRate->TotalAviatur['Markup'] = $aviaturMarkup;
  966.         $roomRate->TotalAviatur['MarkupType'] = $markup->getConfigHotelAgency()->getType();
  967.         $nights = floor(($dateOut - $dateIn) / (24 * 60 * 60));
  968.         $roomRate->TotalAviatur['AmountTax'] = 0;
  969.         $roomRate->TotalAviatur['calcBasePrice'] = (float)  $roomRate->net * $nights;
  970.         $roomRate->TotalAviatur['calcTripPrice'] = (float)  $roomRate->net * $nights;
  971.         $roomRate->TotalAviatur['AmountTotal'] = (float)  $roomRate->net + $roomRate->TotalAviatur['AmountTax'];
  972.         $fullPricing = [
  973.             'total' => ((float) $roomRate->TotalAviatur['AmountTotal'] * $nights) ,
  974.             'totalPerNight' => (float) $roomRate->TotalAviatur['AmountTotal'],
  975.             'totalWithoutService' => (((float) $roomRate->TotalAviatur['AmountTotal'] - (float) $roomRate->net) * $nights),
  976.             'currency' => (string) "COP" ,//$currency,
  977.         ];
  978.         $roomRate->TotalAviatur['FullPricing'] = base64_encode(json_encode($fullPricing)) ;
  979.         */
  980.         $session->set($transactionId.'[hotel][detail]',json_encode($detail));
  981.         // Contadores para adultos y niños
  982.         $totalAdults 0;
  983.         $totalChildren 0;
  984.         $countGuestRooms = [];
  985.         foreach ($roomslist as $index => $room) {
  986.             $roomCounterGuest = [
  987.                 'adults' => 0,
  988.                 'children' => 0,
  989.             ];
  990.             foreach ($room['passengerAges'] as $age) {
  991.                 if ($age >= 18) {
  992.                     $totalAdults++;
  993.                     $roomCounterGuest['adults']++;
  994.                 } else {
  995.                     $totalChildren++;
  996.                     $roomCounterGuest['children']++;
  997.                 }
  998.             }
  999.             $roomslist[$index]['countGuestRooms'] = $roomCounterGuest;
  1000.         }
  1001.         $session->set($transactionId.'[hotel][totalAdults]'$totalAdults);
  1002.         $session->set($transactionId.'[hotel][totalChildren]'$totalChildren);
  1003.         /* Se debe validar por medio del objeto que quedará como propiedad info, 
  1004.             si la fecha de cancelación de cada habitación es mayor a la fecha actual
  1005.             para que la pueda mostrar en la vista del roomlist; de lo contrario,
  1006.             se debe mostrar una indicación de que la tarifa es no reembolsable.
  1007.         */
  1008.         list($info$roomsData) = $this->getInfoAndRoomsData($roomlist);
  1009.         $info $roomlist['data']['hotelRoomlist']['hotels'][0];
  1010.         $this->validateCancellationDates($info);
  1011.         /* Agrupar habitaciones para elegir las mas economicas */
  1012.         foreach($info['rates'] as &$room) {
  1013.             $room['suggestedCount'] = 0;
  1014.         }
  1015.         $acomodationRooms = [];
  1016.         foreach ($roomslist as $roomRequired) {
  1017.             $roomsMatch = [];
  1018.             foreach ($info['rates'] as &$roomAvailable) {
  1019.                 if ($roomAvailable['adults'] == $roomRequired['countGuestRooms']['adults'] && $roomAvailable['children'] == $roomRequired['countGuestRooms']['children'] && $roomAvailable['suggestedCount'] < $roomAvailable['allotment'] ) {
  1020.                     $roomsMatch[] = $roomAvailable;
  1021.                 }
  1022.             }
  1023.             usort($roomsMatch, function($a$b) {
  1024.                 return $a['net'] <=> $b['net'];
  1025.             });
  1026.             foreach ($info['rates'] as &$roomAvailable) {
  1027.                 if(count($roomsMatch) > && $roomsMatch[0]['rateKey'] == $roomAvailable['rateKey']){
  1028.                     $roomAvailable['suggestedCount'] += 1;
  1029.                     $acomodationRooms[] = $roomAvailable;
  1030.                 }
  1031.             }
  1032.         }
  1033.         $markup = (float) $valor;
  1034.         $processQse $Qse->getQse($fullRequest->attributes->get('providerid'));
  1035.         $QSE $session->get($transactionId.'[QSE]');
  1036.         $comissionAgent $Qse->getQseComission();
  1037.         $qseMoney $session->get($transactionId.'[qseMoney]');
  1038.         $qsePercentage $session->get($transactionId.'[qsePercentage]');
  1039.         $qseActive $session->get($transactionId.'[qseActive]');
  1040.         $responseHotelDetail = [
  1041.             'twig_readonly' => false,
  1042.             'referer' => $isFlightHotel '/multi' '/hoteles',
  1043.             'checkIn' => $checkIn,
  1044.             'checkOut' => $checkOut,
  1045.             'roomsQuantity' => count($roomslist),
  1046.             'nights' => floor(($dateOut $dateIn) / (24 60 60)),
  1047.             'adults' => $totalAdults,
  1048.             'childs' => $totalChildren,
  1049.             'info' => $info,
  1050.             'roomsData' => $roomsData,
  1051.             'additional' => $additional,
  1052.             'paymentsSaved' => isset($paymentsSaved) ? $paymentsSaved['info'] : null,
  1053.             'transactionId' => $transactionId,
  1054.             'guestForRooms' => $roomslist,
  1055.             'countryCode' => $countrycode,
  1056.             'isMulti' => $isFlightHotel,
  1057.             'acomodationRooms' => $acomodationRooms,
  1058.             'payment' => $online,
  1059.             'QSE' => isset($QSE) ? $QSE null,
  1060.             'markup' => isset($markup) ? $markup null,
  1061.             'comissionAgent' => isset($comissionAgent) ? $comissionAgent null,
  1062.             'qseMoney' => isset($qseMoney) ? $qseMoney null,
  1063.             'qsePercentage' => isset($qsePercentage) ? $qsePercentage null,
  1064.             'qseActive' => isset($qseActive) ? $qseActive null,
  1065.         ];
  1066.         $view $twigFolder->twigExists('@AviaturTwig/' $agencyFolder '/Hotel/Default/roomlist.html.twig');
  1067.         if($isFlightHotel){
  1068.             return new JsonResponse($responseHotelDetail);
  1069.         }
  1070.         return $this->render($view$responseHotelDetail);
  1071.     }
  1072.     public function checkoutAction(
  1073.         Request $request,
  1074.         ParameterBagInterface $parameterBag,
  1075.         TwigFolder $twigFolder,
  1076.         SessionInterface $session,
  1077.         AviaturErrorHandler $aviaturErrorHandler,
  1078.         RouterInterface $router,
  1079.         AviaturWebService $aviaturWebService,
  1080.         QseCommission $Qse,
  1081.         $isFlightHotel false
  1082.     ) {
  1083.         $em $this->em;
  1084.         $agency $this->agency;
  1085.         $passangerTypes = [];
  1086.         $agencyFolder $twigFolder->twigFlux();
  1087.         $transactionIdSessionName $parameterBag->get('transaction_id_session_name');
  1088.         $correlationIdSessionName $parameterBag->get('correlation_id_session_name');
  1089.         $server $request->server;
  1090.         if (true === $session->has($transactionIdSessionName)) {
  1091.             $transactionId $session->get($transactionIdSessionName);
  1092.             // $referer = $router->match(parse_url($server->get('HTTP_REFERER'), PHP_URL_PATH));
  1093.             // if (true === $session->has($transactionId.'[availability_url]')) {
  1094.             //     return $this->redirect($aviaturErrorHandler->errorRedirect($session->get($transactionId.'[availability_url]'), 'Página no accesible', 'No puedes acceder al detalle sin disponibilidad'));
  1095.             // } elseif (false !== strpos($referer['_controller'], 'availabilityAction')) {
  1096.             //     return $this->redirect($aviaturErrorHandler->errorRedirect($server->get('HTTP_REFERER'), '', 'Error en la respuesta de nuestro proveedor de servicios, inténtalo nuevamente'));
  1097.             // } else {
  1098.             //     return $this->redirect($aviaturErrorHandler->errorRedirect($twigFolder->pathWithLocale('aviatur_general_homepage'), 'Página no accesible', 'No puedes acceder al detalle sin disponibilidad'));
  1099.             // }
  1100.         } else {
  1101.             return $this->redirect($aviaturErrorHandler->errorRedirect($twigFolder->pathWithLocale('aviatur_general_homepage'), 'Página no accesible''No puedes acceder al detalle sin disponibilidad'));
  1102.         }
  1103.         $hotelRQ $request->get('HT');
  1104.         //Valida si existe un transaccion en el formulario.
  1105.         $transactionId = isset($hotelRQ['transactionId'])  ? $hotelRQ['transactionId'] : $transactionId ;
  1106.         $session->set($transactionIdSessionName$transactionId );
  1107.         $countryCode = isset($hotelRQ['countryCode']) ? $hotelRQ['countryCode'] : $session->get($transactionId.'[hotel][countryCode]') ;
  1108.         $session->set($transactionId.'[hotel][countryCode]'$countryCode);
  1109.         $alertsValidation $request->get('alertsValidation');
  1110.         $session->set($transactionId.'[hotel][alertsValidation]'$alertsValidation);
  1111.         $paymentOn = isset($hotelRQ['payment']) ? $hotelRQ['payment'] : $session->get($transactionId.'[hotel][paymentOn]') ;
  1112.         $session->set($transactionId.'[hotel][paymentOn]'$paymentOn);
  1113.         $roomsSelection $request->get('HT') !== null $request->get('HT') : $session->get($transactionId.'[hotel][roomsdata]');
  1114.         $optionRate $roomsSelection["optionRate"] ?? "";
  1115.         $hotelRoomsJsonDataSelection = [];
  1116.         if (isset($roomsSelection['rooms'])) {
  1117.             $session->set($transactionId.'[hotel][roomsdata]'$roomsSelection);
  1118.             $jsonString urldecode($roomsSelection['rooms']);
  1119.             $hotelRoomsJsonDataSelection json_decode($jsonStringtrue);
  1120.         }
  1121.         // Extraer solo los 'rateKey' de cada habitación seleccionada
  1122.         $selectedRateKeys array_map(function ($room) {
  1123.             return $room['rateKey'] ?? null;
  1124.         }, $hotelRoomsJsonDataSelection);
  1125.         // Filtrar valores nulos por si 'rateKey' no existe en alguna habitación
  1126.         $selectedRateKeys array_filter($selectedRateKeys);
  1127.         // Guardar los 'rateKey' seleccionados en la sesión
  1128.         $session->set($transactionId.'[hotel][selected_rooms]'$selectedRateKeys);
  1129.         $totalAdults $session->get($transactionId.'[hotel][totalAdults]');
  1130.         $totalChildren =$session->get($transactionId.'[hotel][totalChildren]');
  1131.         $additional base64_encode($transactionId.'/'.$session->get($transactionId.'[hotel]['.$correlationIdSessionName.']'));
  1132.         $detail json_decode($session->get($transactionId.'[hotel][detail]'));
  1133.         $hotelInfo $detail->data->hotelRoomlist->hotels[0];
  1134.         $checkIn $detail->data->hotelRoomlist->stay->checkIn;
  1135.         $checkOut $detail->data->hotelRoomlist->stay->checkOut;
  1136.         // Convertir las fechas en objetos DateTime
  1137.         $dateCheckIn = new \DateTime($checkIn);
  1138.         $dateCheckOut = new \DateTime($checkOut);
  1139.         $interval $dateCheckIn->diff($dateCheckOut);
  1140.         $nigths $interval->days;
  1141.         $totalPrice 0;
  1142.         $totalTax 0;
  1143.         $totalOnsite 0;
  1144.         $totalOnsiteLocal 0;
  1145.         $currencylocal 'false';
  1146.         $currencyex 'cop';
  1147.         // Extraer los rates de $hotelInfo
  1148.         $hotelRates $hotelInfo->rates;
  1149.         // Contar las veces que aparece cada rateKey en $selectedRateKeys
  1150.         $rateKeyCounts array_count_values($selectedRateKeys);
  1151.         // Filtrar los rates y agregar la cuenta de habitaciones seleccionadas
  1152.         $roomsSelection array_filter($hotelRates, function ($rate) use ($rateKeyCounts) {
  1153.             // Solo incluir el rate si su rateKey está en el array de conteos
  1154.             if (isset($rateKeyCounts[$rate->rateKey])) {
  1155.                 // Agregar la cuenta como una nueva propiedad en el objeto rate
  1156.                 $rate->count $rateKeyCounts[$rate->rateKey];
  1157.                 return true;
  1158.             }
  1159.             return false;
  1160.         });
  1161.         // provider aqui
  1162.         $prov $session->get($transactionId.'[hotel][provider]');
  1163.         $provider $em->getRepository(\Aviatur\MpaBundle\Entity\Provider::class)->findOneById($prov);
  1164.         $provId $provider->getProviderIdentifier();
  1165.         $markups $this->markupService->Markup($agency);
  1166.         foreach ($roomsSelection as $room) {
  1167.             $roomSum =0;
  1168.             $taxSum=0;
  1169.             for ($j 0$j $room->count$j++) {
  1170.             $i 0;
  1171.             $markup false;
  1172.             $aviaturMarkup 0;
  1173.             $appliedIndex null;
  1174.             while (!$markup) {
  1175.                 if (($markups['providerOfConfig'][$markups['markups'][$i]['config_hotel_agency_id']] == (string) $provId )) {
  1176.                     if ('N' == $markups['typeOfConfig'][$markups['markups'][$i]['config_hotel_agency_id']]) {
  1177.                         $aviaturMarkup = (float) round($room->net) * $markups['markups'][$i]['value'] / (100 $markups['markups'][$i]['value']);
  1178.                         $taxMarkup = (float) round($room->tax) * $markups['markups'][$i]['value'] / (100 $markups['markups'][$i]['value']);
  1179.                     } else {
  1180.                         $aviaturMarkup 0;
  1181.                         $taxMarkup 0;
  1182.                     }
  1183.                     $markup true;
  1184.                     $appliedIndex $i;
  1185.                 }
  1186.                ++$i;
  1187.             }
  1188.             if (!is_null($appliedIndex)) {
  1189.                 $valor $markups['markups'][$appliedIndex]['value'];
  1190.             }
  1191.             $roomSum += round($room->net) + round($aviaturMarkup);
  1192.             $taxSum += round($room->tax) + round($taxMarkup);
  1193.             }
  1194.             $room->net $roomSum;
  1195.             $room->tax $taxSum;
  1196.             $totalPrice += $room->net;
  1197.             $totalTax += $room->tax;
  1198.             if (isset($room->fareDetails)){
  1199.             $totalOnsite += $room->fareDetails->propertyFees->requestedCurrency->value;
  1200.             $currencyex $room->fareDetails->propertyFees->requestedCurrency->currency;
  1201.             $totalOnsiteLocal  += $room->fareDetails->propertyFees->localCurrency->value;
  1202.             $currencylocal $room->fareDetails->propertyFees->localCurrency->currency;
  1203.             }
  1204.         }
  1205.         // Reindexar el array para asegurar índices consecutivos
  1206.         $roomsSelection array_values($roomsSelection);
  1207.         $typeDocument $em->getRepository(\Aviatur\CustomerBundle\Entity\DocumentType::class)->findAll();
  1208.         $typeGender $em->getRepository(\Aviatur\CustomerBundle\Entity\Gender::class)->findAll();
  1209.         $repositoryDocumentType $em->getRepository(\Aviatur\CustomerBundle\Entity\DocumentType::class);
  1210.         $queryDocumentType $repositoryDocumentType
  1211.             ->createQueryBuilder('p')
  1212.             ->where('p.paymentcode != :paymentcode')
  1213.             ->setParameter('paymentcode''')
  1214.             ->getQuery();
  1215.         $documentPaymentType $queryDocumentType->getResult();
  1216.         $paymentMethodAgency $em->getRepository(\Aviatur\GeneralBundle\Entity\PaymentMethodAgency::class)->findBy(['agency' => $agency'isactive' => 1]);
  1217.         $paymentOptions = [];
  1218.         foreach ($paymentMethodAgency as $payMethod) {
  1219.             $paymentCode $payMethod->getPaymentMethod()->getCode();
  1220.             if (!in_array($paymentCode$paymentOptions) && 'p2p' == $paymentCode || 'cybersource' == $paymentCode) {
  1221.                 $paymentOptions[] = $paymentCode;
  1222.             }
  1223.         }
  1224.         $cards $em->getRepository(\Aviatur\GeneralBundle\Entity\Card::class)->findBy(['isactive' => 1]);
  1225.         $payment_type_form_name $provider->getPaymentType()->getTwig();
  1226.         $passangerTypes[1] = [
  1227.             'ADT' => count($selectedRateKeys) > $totalAdults ? (int) $totalAdults + (count($selectedRateKeys) - $totalAdults) : (int) $totalAdults,
  1228.             'CHD' => (int) $totalChildren,
  1229.             'INF' => 0,
  1230.         ];
  1231.         $conditions $em->getRepository(\Aviatur\GeneralBundle\Entity\HistoricalInfo::class)->findMessageByAgencyOrNull($agency'reservation_conditions_for_hotels');
  1232.         $totalsite = [
  1233.             'total' => $totalOnsite ,
  1234.             'currency' => $currencyex,
  1235.             'totallocal' => $totalOnsiteLocal,
  1236.             'currencyLocal'=> $currencylocal,
  1237.             'totaldest' => $totalPrice,
  1238.         ] ;
  1239.         $session->set($transactionId.'[hotel][chargesData]'$totalsite);
  1240.         $markup = (float) $valor;
  1241.         $QSE $session->get($transactionId.'[QSE]');
  1242.         $comissionAgent $Qse->getQseComission();
  1243.         $qseMoney $session->get($transactionId.'[qseMoney]');
  1244.         $qsePercentage $session->get($transactionId.'[qsePercentage]');
  1245.         $qseActive $session->get($transactionId.'[qseActive]');
  1246.         $renderCheckoutParameters = [
  1247.             'twig_readonly' => false// readonly for retry
  1248.             'referer' => '/hoteles',
  1249.             'payment_type_form_name' => $payment_type_form_name,
  1250.             'cards' => $cards,
  1251.             'payment_doc_type' => $documentPaymentType,
  1252.             'paymentOptions' => $paymentOptions,
  1253.             'doc_type' => $typeDocument,
  1254.             'services' => $passangerTypes,
  1255.             'gender' => $typeGender,
  1256.             'checkIn' => $checkIn,
  1257.             'checkOut' => $checkOut,
  1258.             'nights' => $nigths,
  1259.             'adults' => $totalAdults,
  1260.             'childs' => $totalChildren,
  1261.             'totalPrice' => $totalPrice,
  1262.             'totalTax'=> $totalTax,
  1263.             'info' => $hotelInfo,
  1264.             'countryCode' => $countryCode,
  1265.             'roomsSelection' => $roomsSelection,
  1266.             'conditions' => $conditions,
  1267.             'additional' => $additional,
  1268.             'paymentsSaved' => isset($paymentsSaved) ? $paymentsSaved['info'] : null,
  1269.             'option_rate' => $optionRate,
  1270.             'payment' => $paymentOn,
  1271.             'totalOnsite' => $totalsite,
  1272.             'QSE' => isset($QSE) ? $QSE null,
  1273.             'markup' => isset($markup) ? $markup null,
  1274.             'comissionAgent' => isset($comissionAgent) ? $comissionAgent null,
  1275.             'qseMoney' => isset($qseMoney) ? $qseMoney null,
  1276.             'qsePercentage' => isset($qsePercentage) ? $qsePercentage null,
  1277.             'qseActive' => isset($qseActive) ? $qseActive null,
  1278.             'alertsValidation' => $request->get('alertsValidation')
  1279.         ];
  1280.         /* Aplicando para vuelo, pero teniendo cuidado con los otros productos */
  1281.         /* Necesitamos crear un arreglo que tenga todos los rangos de IIN asociados a su franquicia y a sus límites de número de tarjeta */
  1282.         $iinRecordsArray $aviaturWebService->getIINRanges($em);
  1283.         $renderCheckoutParameters["ccranges"] = $iinRecordsArray["ccranges"];
  1284.         $renderCheckoutParameters["ccfranchises"] = $iinRecordsArray["ccfranchises"];
  1285.         if ($isFlightHotel) {
  1286.             return new JsonResponse($renderCheckoutParameters);
  1287.         }
  1288.         if ($this->isAval) {
  1289.             list($cybersource$paymentOptions) = $this->getCybersource($paymentOptions$paymentMethodAgency[array_search('cybersource'$paymentOptions)]);
  1290.             $pointRedemption $em->getRepository(\Aviatur\GeneralBundle\Entity\PointRedemption::class)->findPointRedemptionWithAgency($agency);
  1291.             $renderCheckoutParameters['pointRedemption'] = $pointRedemption;
  1292.             $renderCheckoutParameters['message'] = (string) utf8_encode($pointRedemption['DobleFactor']['Message']);
  1293.             $renderCheckoutParameters['hotelProvidersId'] = [(string) $provider->getProvideridentifier()];
  1294.             $renderCheckoutParameters['cybersource'] = $cybersource;
  1295.             $renderCheckoutParameters['paymentOptions'] = $paymentOptions;
  1296.             $renderCheckoutParameters['points'] = 0;
  1297.             $renderCheckoutParameters['detailHotel'] = $hotelInfo;
  1298.             $renderCheckoutParameters['payoutExtras'] = null;
  1299.             $renderTwig $twigFolder->twigExists('@AviaturTwig/' $agencyFolder '/Hotel/Hotel/detail.html.twig');
  1300.         } else {
  1301.             $renderTwig $twigFolder->twigExists('@AviaturTwig/' $agencyFolder '/Hotel/Default/checkout.html.twig');
  1302.         }
  1303.         return $this->render($renderTwig$renderCheckoutParameters);
  1304.     }
  1305.     public function thankYouPageAction(
  1306.         Request $fullRequest,
  1307.         RouterInterface $router,
  1308.         TwigFolder $twigFolder,
  1309.         ParameterBagInterface $parameterBag,
  1310.         SessionInterface $session,
  1311.         $on,
  1312.         $pn
  1313.         )
  1314.         {
  1315.         $em $this->em;
  1316.         
  1317.         $route $router->match(str_replace($fullRequest->getSchemeAndHttpHost(), ''$fullRequest->getUri()));
  1318.         $isMulti false !== strpos($route['_route'], 'multi') ? true false;
  1319.         $orderId str_replace('ON'''$on);
  1320.         $orderEntity $em->getRepository(\Aviatur\GeneralBundle\Entity\Order::class)->find($orderId);
  1321.         $transactionId $session->get('transactionId');
  1322.  
  1323.         //$countryCode = $session->get($transactionId.'[hotel][countryCode]');
  1324.         $reservation json_decode($session->get($transactionId.'[hotel][reservation]'));
  1325.         $commentsRes $reservation->booking->hotel->comments ?? '';
  1326.         //$alertsValidation = $session->get($transactionId.'[hotel][alertsValidation]');
  1327.         $orderProduct $em->getRepository(\Aviatur\GeneralBundle\Entity\OrderProduct::class)->find(str_replace('PN'''$pn));
  1328.         $emailData json_decode($orderProduct->getEmail(), true);
  1329.         $agencyFolder $twigFolder->twigFlux();
  1330.         $viewParams $emailData;
  1331.         $viewParams['status'] = $orderProduct->getEmissiondata() == 'No Reservation' 'NoReservation' $orderProduct->getStatus() ;
  1332.         $viewParams['principalColor'] = (strpos($agencyFolder'aval') !== false || strpos($agencyFolder'tuPlus') !== false) ? "#54DFC8" "#005CB9";
  1333.         $viewParams['isAval'] = $this->isAval;
  1334.         //$viewParams['countryCode'] = $countryCode;
  1335.         $viewParams['QSE'] = $session->get($transactionId.'[QSE]');
  1336.         $viewParams['qseActive'] = $session->get($transactionId.'[qseActive]');
  1337.         //$viewParams['alertsValidation'] = $alertsValidation;
  1338.         $viewParams['comments'] = $commentsRes;
  1339.         
  1340.         if($isMulti) {
  1341.             return new JsonResponse($viewParams);
  1342.         }
  1343.         $view $twigFolder->twigExists('@AviaturTwig/' $agencyFolder '/Hotel/Default/thank-you-page.html.twig');
  1344.         return $this->render($view$viewParams);
  1345.     }
  1346.     public function hotelAvailability($checkIn$checkOut$destinationCode$countryCode$latitude$longitude$radius$rooms) {
  1347.         /* Prueba para pasar la nueva respuesta al front */
  1348.         // $jsonUrl = 'https://s3.amazonaws.com/fenix-public.aviatecnologia.com/Hotels/ModeloRespuestaHoteles.json';
  1349.         // $jsonContent = file_get_contents($jsonUrl);
  1350.         // return $jsonContent;
  1351.         // $jsonData = json_decode($jsonContent, true);
  1352.         // Configurar la URL del endpoint
  1353.         $url 'https://ecomm5.grupoaviatur.com:8443/Aviatur.HotelBedsV2.Adapter/Api/GetAvail';
  1354.         //$url = 'https://danubio3.testaviatur.local/Aviatur.HotelBedsV2.Adapter/Api/GetAvail';
  1355.         // Configurar el identificador de transacción
  1356.         $transactionIdentifier "eyJlIjoiMTcyNjY5MTQ4N19iY2hoIn0.PMNkXsLQB54wXrfsU7gMjrEboCcjyL3cLCPHoT4Jupc";
  1357.         // Estructurar el cuerpo de la solicitud
  1358.         $data = [
  1359.             "TransactionIdentifier" => $transactionIdentifier,
  1360.             "hotelAvailability" => [
  1361.                 "checkIn" => $checkIn,
  1362.                 "checkOut" => $checkOut,
  1363.                 "destination" => [
  1364.                     "type" => "RANGE",
  1365.                     "destinationCode" => $destinationCode,
  1366.                     "countryCode" => $countryCode,
  1367.                     "range" => [
  1368.                         "coordinate" => [
  1369.                             "latitude" => $latitude,
  1370.                             "longitude" => $longitude
  1371.                         ],
  1372.                         "radius" => $radius
  1373.                     ]
  1374.                 ],
  1375.                 "rooms" => $rooms
  1376.             ],
  1377.             "providers" => [
  1378.                 [
  1379.                     "id" => 23,
  1380.                     "officeId" => "BOGVU28AT",
  1381.                     "externalId" => "BOGVU2308"
  1382.                 ]
  1383.             ]
  1384.         ];
  1385.         // Iniciar cURL
  1386.         $ch curl_init($url);
  1387.         // Configurar opciones cURL
  1388.         curl_setopt($chCURLOPT_HTTPHEADER, [
  1389.             'accept: text/plain',
  1390.             'Content-Type: application/json'
  1391.         ]);
  1392.         curl_setopt($chCURLOPT_RETURNTRANSFERtrue);
  1393.         curl_setopt($chCURLOPT_SSL_VERIFYPEERfalse);
  1394.         curl_setopt($chCURLOPT_CONNECTTIMEOUT100000);
  1395.         curl_setopt($chCURLOPT_POSTtrue);
  1396.         curl_setopt($chCURLOPT_POSTFIELDSjson_encode($data));
  1397.         // Ejecutar la solicitud
  1398.         $response curl_exec($ch);
  1399.         // Manejar errores
  1400.         if (curl_errno($ch)) {
  1401.             echo 'Error:' curl_error($ch);
  1402.         }
  1403.         // Cerrar cURL
  1404.         curl_close($ch);
  1405.         // Devolver la respuesta
  1406.         return $response;
  1407.     }
  1408.     public function roomListCall(AviaturLogSave $aviaturLogSave,$checkIn$checkOut$hotel$rooms$transactionId,$providerid,$online$isFlightHotel) {
  1409.         
  1410.         $payload =  'GetRoomList';
  1411.         $url null;
  1412.         $agency $this->agency;
  1413.         $configsHotelAgency $this->em
  1414.         ->getRepository(\Aviatur\HotelBundle\Entity\ConfigHotelAgency::class)
  1415.         ->findProviderForHotelsWithAgency($agency);
  1416.         foreach ($configsHotelAgency as $config) {
  1417.             if(($config->getProvider())->getProviderIdentifier() == $providerid /*$providerId*/){
  1418.                 $url $config->getWsUrl();
  1419.                 break;
  1420.             }
  1421.         }
  1422.         if ($url === null) {
  1423.             return json_encode(array(
  1424.                 "errorP" => "No disponible"
  1425.             ));
  1426.         }
  1427.         // Configurar el identificador de transacción
  1428.         $transactionIdentifier $transactionId;
  1429.         
  1430.         // Estructurar el cuerpo de la solicitud
  1431.         $data = [
  1432.             "transactionIdentifier" => $transactionIdentifier,
  1433.             "hotelRoomList" => [
  1434.                 "checkIn" => $checkIn,
  1435.                 "checkOut" => $checkOut,
  1436.                 "hotel" => $hotel,
  1437.                 "rooms" => $rooms,
  1438.                 "TPA_Extensions" => [
  1439.                     "salesEnvironment"=> ($online == 'destination') ? 'HotelCollect' : ($isFlightHotel 'HotelPackage' 'HotelOnly')
  1440.                     ]
  1441.             ],
  1442.             "providers" => [
  1443.                 [
  1444.                     "id" => $providerid,
  1445.                     "officeId" => "BOGVU28AT",
  1446.                     "externalId" => "BOGVU2308"
  1447.                 ]
  1448.             ]
  1449.         ];
  1450.         $aviaturLogSave->logSave(json_encode($data), 'HotelRoomList''RQ');
  1451.         $result $this->aviaturRestService->callRestWebService($url$payload$data);
  1452.         return json_encode($result);
  1453.     }
  1454.     public function bookingCall(AviaturLogSave $aviaturLogSave,$passangers$rooms$transactionIdentifier,SessionInterface $session,$providerId,$userEmail,$dbState "0",$payment ) {
  1455.         $payload =  'Booking';
  1456.         $url null;
  1457.         $agency $this->agency;
  1458.         $configsHotelAgency $this->em
  1459.         ->getRepository(\Aviatur\HotelBundle\Entity\ConfigHotelAgency::class)
  1460.         ->findProviderForHotelsWithAgency($agency);
  1461.         foreach ($configsHotelAgency as $config) {
  1462.             if(($config->getProvider())->getProviderIdentifier() == $providerId){
  1463.                 $url $config->getWsUrl();
  1464.                 break;
  1465.             }
  1466.         }
  1467.         if ($url === null) {
  1468.             return json_encode(array(
  1469.                 "errorP" => "No disponible"
  1470.             ));
  1471.         }
  1472.         $holder = [
  1473.             "name" => $passangers[0]['name'],
  1474.             "surname" => $passangers[0]['surname'],
  1475.             "documentType" => $passangers[0]['documentType'],
  1476.             "documentNumber" => $passangers[0]['documentNumber'],
  1477.             "birthDate" => $passangers[0]['birthDate'],
  1478.             "gender" => $passangers[0]['gender'],
  1479.             "indexContact" => $passangers[0]['indexContact'],
  1480.         ];
  1481.         
  1482.         $paymentType $payment["payment"];
  1483.         if ($paymentType == 'destination') {
  1484.             $holder["paymentCard"] = [
  1485.                 "cardNumber" => $payment['paymentData']->card_values->card_num_token,
  1486.                 "expirationMonth" => $payment['paymentData']->exp_month ,
  1487.                 "expirationYear" => $payment['paymentData']->exp_year ,
  1488.                 "securityCode" => $payment['paymentData']->card_code,
  1489.             ];
  1490.         }
  1491.         $data = [
  1492.            "transactionIdentifier" => $transactionIdentifier,
  1493.            "hotelRest" => [
  1494.                 "holder" => $holder,
  1495.                "contact" =>[ [
  1496.                    "index" => $passangers[0]['indexContact'],
  1497.                    "telephone" => $passangers[0]['telephone'],
  1498.                    "telephoneCountryCode" => '57',
  1499.                    "email" => $passangers[0]['email'],
  1500.                    "address" => [
  1501.                        "AddressLine" => empty($passangersDataArray['address_1_1']) ? 'Cl 19 N 4 62' $passangers['address_1_1'],
  1502.                        "cityName" => "Bogota",
  1503.                        "postalCode" => "110810",
  1504.                        "stateProv" => "Cundinamarca",
  1505.                        "countryName" => "Colombia"
  1506.                    ],
  1507.                ]
  1508.             ],
  1509.                "rooms" => $rooms ,
  1510.                "TPA_Extensions" => [
  1511.                     "usuario" => $userEmail,
  1512.                     "estadoBD" => $dbState
  1513.                ]
  1514.            ],
  1515.            "clientReference" => "IntegrationAgency",
  1516.            "providers" => [
  1517.                [
  1518.                    "id" => 23,
  1519.                    "officeId" => "BOGVU28AT",
  1520.                    "externalId" => "BOGVU2308"
  1521.                ]
  1522.            ]
  1523.        ];
  1524.        $logData $data;
  1525.         if ($paymentType == 'destination') {
  1526.             // Enmascarar para almacenar en el log 
  1527.             //$logData['hotelRest']['holder']['paymentCard']['cardNumber'] = '************' . substr($data['hotelRest']['holder']['paymentCard']['cardNumber'], -4);
  1528.             $logData['hotelRest']['holder']['paymentCard']['securityCode'] = '***';
  1529.         }
  1530.         $aviaturLogSave->logSave(json_encode($logData), 'HotelRes''RQ');  // almacenamiento del log
  1531.         //return "error";
  1532.         //return  '{"data":{"auditData":{"transactionIdentifier":"eyJlIjoiMTczMzE3NzY2M19MbUswIn0.wYRaYFWqZWyDttyd41_w3BipB8hJ2pnUX6prYqMUN9A","providers":"117","processTime":"883","timestamp":"2024-12-02 20:17:50.637","requestHost":"3.213.114.62, 18.68.30.82, 10.214.57.231, 10.214.34.9","serverId":"ip-10-214-37-108.eu-central-1.compute.internal#A+","environment":"[awseucentral1, awseucentral1b, ip_10_214_37_108, eucentral1, secret]","release":"","token":"83199D72135C4B3F9CB226C1008EA18A","internal":"0|07~A-SIC~2216f39f~-1025155925~N~~~NOR~~FB73CB44E44D483173317046420905AACO000100010003052216f39f|CO|05|1|1|||||||||||R|1|1|~1~1~0|0|1||3|d83fbd9520b1342e73a18afe556e2cf3||||"},"booking":{"reference":"69-7317465","clientReference":"INTEGRATIONAGENCY","creationDate":"2024-12-02","status":"CONFIRMED","modificationPolicies":{"cancellation":true,"modification":true},"creationUser":"d83fbd9520b1342e73a18afe556e2cf3","holder":{"name":"Natalia","surname":"Vasquez","documentType":"CC","documentNumber":"1026585550","birthDate":"1995-11-02","gender":"Female"},"hotel":{"code":7896,"name":"Hotel Dos Playas Faranda Cancun","categoryCode":"3EST","categoryName":"3 ESTRELLAS","destinationCode":"CUN","destinationName":"Cancun (y alrededores)","zoneCode":10,"zoneName":"Zona hotelera","latitude":"21.14009500000000000000","longitude":"-86.77059700000000000000","minRate":"455583.33","maxRate":"828799.28","currency":"COP","comments":["  Importe total estimado de tasas y recargos para esta reserva:76.00 Mexican Peso pagaderas a la llegada. Fee Ecológico: Cantidad sujeta a modificación por tipo de cambio, pudiera aumentar sin previo aviso. Aparcamiento SI (Con notas de cargo adicionales).Salida anticipada.Hora de entrada 18:00-."],"rooms":[{"code":"SGL.ST","name":"Single Standard","rates":[{"rateKey":"20250506|20250507|W|69|7896|SGL.ST|GAR RO|RO||1~1~0||N@07~A-SIC~2216f39f~-1025155925~N~~~NOR~~FB73CB44E44D483173317046420905AACO000100010003052216f39f","rateClass":"NOR","rateType":"BOOKABLE","net":455583.33,"tax":0,"allotment":155,"paymentType":"AT_WEB","packaging":false,"boardCode":"RO","boardName":"SOLO HABITACIÓN","cancellationPolicies":[{"amount":"455583.33","from":"2025-04-28T23:59:00-05:00"}],"taxes":0,"rooms":1,"adults":1,"children":0,"promotions":null,"childrenAges":null,"offers":null,"sellingRate":null,"hotelMandatory":null,"rateCommentsId":"  Importe total estimado de tasas y recargos para esta reserva:76.00 Mexican Peso pagaderas a la llegada. Fee Ecológico: Cantidad sujeta a modificación por tipo de cambio, pudiera aumentar sin previo aviso. Aparcamiento SI (Con notas de cargo adicionales).Salida anticipada.Hora de entrada 18:00-."}]}]},"remark":null,"invoiceCompany":{"company":"BEDSONLINE USA"},"totalNet":455583.33,"totalNetUsd":0,"currency":"COP"}},"type":"Booking","title":null,"status":200,"detail":"Reserva Exitosa","instance":null}';   
  1533.         //expedia
  1534.         //return '{"type":"OK","title":null,"status":200,"detail":null,"instance":null,"data":{"auditData":{"transactionIdentifier":"eyJlIjoiMTc1MTkwMzQ4N19zTGJpIn0.74eS8Dzf8-MCf-zpLcCglj1N3dNT44noRHd-nm8TRO4","providers":"167","processTime":null,"timestamp":"7/7/2025 8:52:41 AM","requestHost":"10.100.245.89","serverId":"DANUBIO3","environment":"develop","release":null,"token":"23b84620-1be1-4ef9-9c27-fe47ca3b7c3e","_internal":"23b84620-1be1-4ef9-9c27-fe47ca3b7c3e"},"booking":[{"status":"Success","message":"Reserva exitosa","reference":"7046783433728","clientReference":"R3oWcE5nukyGZZBCa6kYZg","creationDate":"2025-07-07","modificationPolicies":{"cancellation":true,"modification":true},"creationUser":"aviatursym.com|Nicolas.pineros@aviatur.com","hotel":{"code":"92114371","name":"Grand ilama Hotel","categoryCode":"3","categoryName":null,"destinationCode":null,"destinationName":"Cali","zoneCode":"Valle del cauca","zoneName":"Valle del cauca","latitude":"3.472902","longitude":"-76.508222","minRate":null,"maxRate":null,"phone":"57-3023803001","currency":"COP","comments":null,"rooms":[{"code":"324588239","name":"Habitación económica","checkIn":"2025-10-09","checkOut":"2025-10-10","mainPaxName":"asa","mainPaxSurname":"asa","rates":[{"rateKey":"395007378|1ADT|0CHD","rateClass":"NOR","rateType":null,"currency":"COP","net":59697.54,"tax":0,"allotment":0,"paymentType":null,"packaging":false,"boardCode":null,"boardName":"Desayuno incluido","cancellationPolicies":[{"amount":"59697.54","from":"2025-10-06T18:00:00.000-05:00"}],"nonRefundableDates":null,"rooms":1,"adults":1,"children":0,"promotions":null,"childrenAges":null,"offers":null,"sellingRate":null,"hotelMandatory":null,"rateCommentsId":null,"fareDetails":{"total_fare":{"requestedCurrency":{"value":"59697.54","currency":"COP"},"localCurrency":{"value":"59697.54","currency":"COP"}},"base_fare":{"requestedCurrency":{"value":"59697.54","currency":"COP"},"localCurrency":{"value":"59697.54","currency":"COP"}},"taxes":{"requestedCurrency":{"value":"0.00","currency":"COP"},"localCurrency":{"value":"0.00","currency":"COP"}},"propertyFees":{"requestedCurrency":{"value":"0","currency":null},"localCurrency":{"value":"0","currency":null}},"discount":{"requestedCurrency":{"value":"0","currency":null},"localCurrency":{"value":"0","currency":null}},"commission":{"requestedCurrency":{"value":"0","currency":null},"localCurrency":{"value":"0","currency":null}}}}]}]},"holder":{"name":"asa","surname":"asa","documentType":"CC","documentNumber":"1030111111","birthDate":"1996-12-05","gender":"Female"},"remark":null,"invoiceCompany":{"company":"EXPEDIA"},"totalNet":59697.54,"totalNetUsd":null,"exchange":null,"currency":"COP"},{"status":"Success","message":"Reserva exitosa","reference":"7568286028355","clientReference":"7vCJ-RXAz02iMITm5mfj2A","creationDate":"2025-07-07","modificationPolicies":{"cancellation":true,"modification":true},"creationUser":"aviatursym.com|Nicolas.pineros@aviatur.com","hotel":{"code":"92114371","name":"Grand ilama Hotel","categoryCode":"3","categoryName":null,"destinationCode":null,"destinationName":"Cali","zoneCode":"Valle del cauca","zoneName":"Valle del cauca","latitude":"3.472902","longitude":"-76.508222","minRate":null,"maxRate":null,"phone":"57-3023803001","currency":"COP","comments":null,"rooms":[{"code":"321894601","name":"Habitación doble estándar","checkIn":"2025-10-09","checkOut":"2025-10-10","mainPaxName":"Avia","mainPaxSurname":"Tur","rates":[{"rateKey":"389750356|1ADT|0CHD","rateClass":"NOR","rateType":null,"currency":"COP","net":69647.13,"tax":0,"allotment":0,"paymentType":null,"packaging":false,"boardCode":null,"boardName":"Desayuno incluido","cancellationPolicies":[{"amount":"69647.13","from":"2025-10-06T18:00:00.000-05:00"}],"nonRefundableDates":null,"rooms":1,"adults":1,"children":0,"promotions":null,"childrenAges":null,"offers":null,"sellingRate":null,"hotelMandatory":null,"rateCommentsId":null,"fareDetails":{"total_fare":{"requestedCurrency":{"value":"69647.13","currency":"COP"},"localCurrency":{"value":"69647.13","currency":"COP"}},"base_fare":{"requestedCurrency":{"value":"69647.13","currency":"COP"},"localCurrency":{"value":"69647.13","currency":"COP"}},"taxes":{"requestedCurrency":{"value":"0.00","currency":"COP"},"localCurrency":{"value":"0.00","currency":"COP"}},"propertyFees":{"requestedCurrency":{"value":"0","currency":null},"localCurrency":{"value":"0","currency":null}},"discount":{"requestedCurrency":{"value":"0","currency":null},"localCurrency":{"value":"0","currency":null}},"commission":{"requestedCurrency":{"value":"0","currency":null},"localCurrency":{"value":"0","currency":null}}}}]}]},"holder":{"name":"asa","surname":"asa","documentType":"CC","documentNumber":"1030111111","birthDate":"1996-12-05","gender":"Female"},"remark":null,"invoiceCompany":{"company":"EXPEDIA"},"totalNet":69647.13,"totalNetUsd":null,"exchange":null,"currency":"COP"},{"status":"ERROR","message":"Ha ocurrido un error generando reserva con proveedor","reference":null,"clientReference":null,"creationDate":null,"modificationPolicies":null,"creationUser":null,"hotel":{"code":"54756","name":"Lancaster House","categoryCode":"4","categoryName":null,"destinationCode":null,"destinationName":"Bogotá","zoneCode":"Distrito Capital","zoneName":"Distrito Capital","latitude":"4.695018","longitude":"-74.055464","minRate":null,"maxRate":null,"phone":"57-1-6291100","currency":null,"comments":null,"rooms":[{"code":null,"name":"Suite junior, 1 habitación","checkIn":null,"checkOut":null,"mainPaxName":null,"mainPaxSurname":null,"rates":[{"rateKey":"385459168|1ADT|0CHD","rateClass":"NRF","rateType":null,"currency":null,"net":398676.6,"tax":0,"allotment":0,"paymentType":null,"packaging":false,"boardCode":null,"boardName":"Desayuno buffet","cancellationPolicies":[{"amount":"398676.60","from":"2025-07-27T16:26:27.403-05:00"}],"nonRefundableDates":[{"from":"2026-03-04","until":"2026-03-05"}],"rooms":0,"adults":1,"children":0,"promotions":null,"childrenAges":null,"offers":null,"sellingRate":null,"hotelMandatory":null,"rateCommentsId":null,"fareDetails":null}]}]},"holder":{"name":"daniel","surname":"galvis","documentType":"CC","documentNumber":"80199025","birthDate":"1984-05-14","gender":"Male"},"remark":null,"invoiceCompany":{"company":"EXPEDIA"},"totalNet":398676.6,"totalNetUsd":null,"exchange":null,"currency":null}]}}';
  1535.         //return '{"type":"OK","title":null,"status":200,"detail":null,"instance":null,"data":{"auditData":{"transactionIdentifier":"eyJlIjoiMTc1MTkwMzQ4N19zTGJpIn0.74eS8Dzf8-MCf-zpLcCglj1N3dNT44noRHd-nm8TRO4","providers":"167","processTime":null,"timestamp":"7/7/2025 8:52:41 AM","requestHost":"10.100.245.89","serverId":"DANUBIO3","environment":"develop","release":null,"token":"23b84620-1be1-4ef9-9c27-fe47ca3b7c3e","_internal":"23b84620-1be1-4ef9-9c27-fe47ca3b7c3e"},"booking":[{"status":"Success","message":"Reserva exitosa","reference":"7046783433728","clientReference":"R3oWcE5nukyGZZBCa6kYZg","creationDate":"2025-07-07","modificationPolicies":{"cancellation":true,"modification":true},"creationUser":"aviatursym.com|Nicolas.pineros@aviatur.com","hotel":{"code":"92114371","name":"Grand ilama Hotel","categoryCode":"3","categoryName":null,"destinationCode":null,"destinationName":"Cali","zoneCode":"Valle del cauca","zoneName":"Valle del cauca","latitude":"3.472902","longitude":"-76.508222","minRate":null,"maxRate":null,"phone":"57-3023803001","currency":"COP","comments":null,"rooms":[{"code":"324588239","name":"Habitación económica","checkIn":"2025-10-09","checkOut":"2025-10-10","mainPaxName":"asa","mainPaxSurname":"asa","rates":[{"rateKey":"395007378|1ADT|0CHD","rateClass":"NOR","rateType":null,"currency":"COP","net":59697.54,"tax":0,"allotment":0,"paymentType":null,"packaging":false,"boardCode":null,"boardName":"Desayuno incluido","cancellationPolicies":[{"amount":"59697.54","from":"2025-10-06T18:00:00.000-05:00"}],"nonRefundableDates":null,"rooms":1,"adults":1,"children":0,"promotions":null,"childrenAges":null,"offers":null,"sellingRate":null,"hotelMandatory":null,"rateCommentsId":null,"fareDetails":{"total_fare":{"requestedCurrency":{"value":"59697.54","currency":"COP"},"localCurrency":{"value":"59697.54","currency":"COP"}},"base_fare":{"requestedCurrency":{"value":"59697.54","currency":"COP"},"localCurrency":{"value":"59697.54","currency":"COP"}},"taxes":{"requestedCurrency":{"value":"0.00","currency":"COP"},"localCurrency":{"value":"0.00","currency":"COP"}},"propertyFees":{"requestedCurrency":{"value":"0","currency":null},"localCurrency":{"value":"0","currency":null}},"discount":{"requestedCurrency":{"value":"0","currency":null},"localCurrency":{"value":"0","currency":null}},"commission":{"requestedCurrency":{"value":"0","currency":null},"localCurrency":{"value":"0","currency":null}}}}]}]},"holder":{"name":"asa","surname":"asa","documentType":"CC","documentNumber":"1030111111","birthDate":"1996-12-05","gender":"Female"},"remark":null,"invoiceCompany":{"company":"EXPEDIA"},"totalNet":59697.54,"totalNetUsd":null,"exchange":null,"currency":"COP"},{"status":"Success","message":"Reserva exitosa","reference":"7568286028355","clientReference":"7vCJ-RXAz02iMITm5mfj2A","creationDate":"2025-07-07","modificationPolicies":{"cancellation":true,"modification":true},"creationUser":"aviatursym.com|Nicolas.pineros@aviatur.com","hotel":{"code":"92114371","name":"Grand ilama Hotel","categoryCode":"3","categoryName":null,"destinationCode":null,"destinationName":"Cali","zoneCode":"Valle del cauca","zoneName":"Valle del cauca","latitude":"3.472902","longitude":"-76.508222","minRate":null,"maxRate":null,"phone":"57-3023803001","currency":"COP","comments":null,"rooms":[{"code":"321894601","name":"Habitación doble estándar","checkIn":"2025-10-09","checkOut":"2025-10-10","mainPaxName":"Avia","mainPaxSurname":"Tur","rates":[{"rateKey":"389750356|1ADT|0CHD","rateClass":"NOR","rateType":null,"currency":"COP","net":69647.13,"tax":0,"allotment":0,"paymentType":null,"packaging":false,"boardCode":null,"boardName":"Desayuno incluido","cancellationPolicies":[{"amount":"69647.13","from":"2025-10-06T18:00:00.000-05:00"}],"nonRefundableDates":null,"rooms":1,"adults":1,"children":0,"promotions":null,"childrenAges":null,"offers":null,"sellingRate":null,"hotelMandatory":null,"rateCommentsId":null,"fareDetails":{"total_fare":{"requestedCurrency":{"value":"69647.13","currency":"COP"},"localCurrency":{"value":"69647.13","currency":"COP"}},"base_fare":{"requestedCurrency":{"value":"69647.13","currency":"COP"},"localCurrency":{"value":"69647.13","currency":"COP"}},"taxes":{"requestedCurrency":{"value":"0.00","currency":"COP"},"localCurrency":{"value":"0.00","currency":"COP"}},"propertyFees":{"requestedCurrency":{"value":"0","currency":null},"localCurrency":{"value":"0","currency":null}},"discount":{"requestedCurrency":{"value":"0","currency":null},"localCurrency":{"value":"0","currency":null}},"commission":{"requestedCurrency":{"value":"0","currency":null},"localCurrency":{"value":"0","currency":null}}}}]}]},"holder":{"name":"asa","surname":"asa","documentType":"CC","documentNumber":"1030111111","birthDate":"1996-12-05","gender":"Female"},"remark":null,"invoiceCompany":{"company":"EXPEDIA"},"totalNet":69647.13,"totalNetUsd":null,"exchange":null,"currency":"COP"}]}}';
  1536.         $result $this->aviaturRestService->callRestWebService($url$payload$data);
  1537.        return json_encode($result,JSON_UNESCAPED_SLASHES);
  1538.     }
  1539.     public function sendEmailThankYouPageAction(
  1540.         SessionInterface $session,
  1541.         TwigFolder $twigFolder,
  1542.         \Swift_Mailer $mailer,
  1543.         Pdf $pdf,
  1544.         $pn
  1545.     ) {
  1546.         try {
  1547.             $em $this->em;
  1548.             $productId str_replace('PN'''$pn);
  1549.             $orderProduct $em->getRepository(\Aviatur\GeneralBundle\Entity\OrderProduct::class)->find($productId);
  1550.             $emailData json_decode($orderProduct->getEmail(), true);
  1551.             $agencyFolder $twigFolder->twigFlux();
  1552.             $emailData['travelers'] = [];
  1553.             $clientEmail $emailData["paymentResume"]['client_email'];
  1554.             $setTo $clientEmail;
  1555.             $bccMails =  ['soportepagoelectronico@aviatur.com.co''soptepagelectronic@aviatur.com''sebastian.huertas@aviatur.com','supervisorescallcenter@aviatur.com'];
  1556.             $infoPdfHotel = [
  1557.                 'retry_count' => 1,
  1558.                 // 'paymentResume' => $paymentResume,
  1559.                 // 'facturationResume' => $facturationResume,
  1560.                 'agencyData' => $emailData['agencyData'],
  1561.                 'journeySummary' => $emailData['journeySummary'],
  1562.                 // 'transactionID' => $transactionId,
  1563.                 // 'rooms' => $rooms,
  1564.                 // 'traveller' => $traveller,
  1565.                 'travelers' => [],
  1566.                 // 'agent' => $responseOrder,
  1567.                 'pdfGenerator' => true,
  1568.                 // dd($rooms),
  1569.             ];
  1570.             // $pdf->generateFromHtml(
  1571.             //     $this->renderView($urlResume, $infoPdfHotel),
  1572.             //     $voucherFile
  1573.             // );
  1574.             $emailData['status'] = $orderProduct->getStatus();
  1575.             $setSubject 'Aviatur - Gracias por su compra';
  1576.             $message = (new \Swift_Message())
  1577.                 ->setContentType('text/html')
  1578.                 ->setFrom($session->get('emailNoReply'))
  1579.                 ->setTo($setTo)
  1580.                 ->setBcc($bccMails)
  1581.                 ->setSubject($setSubject)
  1582.                 // ->attach(\Swift_Attachment::fromPath($voucherFile))
  1583.                 ->setBody(
  1584.                     $this->renderView($twigFolder->twigExists('@AviaturTwig/' $agencyFolder '/Hotel/Default/email.html.twig'), $emailData)
  1585.                 );
  1586.             $mailer->send($message);
  1587.             return $this->render($twigFolder->twigExists('@AviaturTwig/' $agencyFolder '/Hotel/Default/email.html.twig'), $emailData);
  1588.         } catch (\Exception $e) {
  1589.             dd($e);
  1590.             return $e;
  1591.         }
  1592.     }
  1593.     public function prePaymentStep1Action(Request $requestTokenizerService $tokenizerServiceCustomerMethodPaymentService $customerMethodPaymentTokenStorageInterface $tokenStorageAviaturWebService $aviaturWebServiceAviaturErrorHandler $aviaturErrorHandlerRouterInterface $routerAviaturEncoder $aviaturEncoderTwigFolder $twigFolderSessionInterface $sessionManagerRegistry $registryParameterBagInterface $parameterBag)
  1594.     {
  1595.         $transactionIdSessionName $parameterBag->get('transaction_id_session_name');
  1596.         //$correlationIdSessionName = $parameterBag->get('correlation_id_session_name');
  1597.         //$startTime = microtime(true);
  1598.         //$session->set('executiontime', $startTime);
  1599.         if ($request->isXmlHttpRequest()) {
  1600.             $request $request->request;
  1601.             $quotation $request->get('QT');
  1602.             $transactionId $session->get($transactionIdSessionName);
  1603.             $billingData $request->get('BD');
  1604.             // $roomsSelection = $request->get('HT');
  1605.             // $hotelRoomsJsonDataSelection = [];
  1606.             // if (isset($roomsSelection['rooms'])) {
  1607.             //     $jsonString = urldecode($roomsSelection['rooms']);
  1608.             //     $hotelRoomsJsonDataSelection = json_decode($jsonString, true);
  1609.             // }
  1610.             // Extraer solo los 'rateKey' de cada habitación seleccionada
  1611.             // $selectedRateKeys = array_map(function ($room) {
  1612.             //     return $room['rateKey'] ?? null;
  1613.             // }, $hotelRoomsJsonDataSelection);
  1614.             // Filtrar valores nulos por si 'rateKey' no existe en alguna habitación
  1615.             // $selectedRateKeys = array_filter($selectedRateKeys);
  1616.             // Guardar los 'rateKey' seleccionados en la sesión
  1617.             // $session->set($transactionId.'[hotel][selected_rooms]', $selectedRateKeys);
  1618.             $em $this->em;
  1619.             $postData $request->all();
  1620.             $publicKey $aviaturEncoder->aviaturRandomKey();
  1621.             $session->remove('register-extra-data');
  1622.             if (isset($postData['PD']['card_num'])) {
  1623.                 $postDataInfo $postData;
  1624.                 if (isset($postDataInfo['PD']['cusPOptSelected'])) {
  1625.                     $customerLogin $tokenStorage->getToken()->getUser();
  1626.                     $infoMethodPaymentByClient $customerMethodPayment->getMethodsByCustomer($customerLogintrue);
  1627.                     $cardToken $infoMethodPaymentByClient['info'][$postDataInfo['PD']['cusPOptSelected']]['token'];
  1628.                     $postDataInfo['PD']['card_num'] = $cardToken;
  1629.                 } else {
  1630.                     $postDataInfo['PD']['card_num'] = $tokenizerService->getToken($postData['PD']['card_num']);
  1631.                 }
  1632.                 $postData['PD']['card_values'] = ['card_num_token' => $postDataInfo['PD']['card_num'], 'card_num' => $postData['PD']['card_num']];
  1633.             }
  1634.             $encodedInfo $aviaturEncoder->AviaturEncode(json_encode($postDataInfo ?? $postData), $publicKey);
  1635.             $formUserInfo = new FormUserInfo();
  1636.             $formUserInfo->setInfo($encodedInfo);
  1637.             $formUserInfo->setPublicKey($publicKey);
  1638.             $em->persist($formUserInfo);
  1639.             $em->flush();
  1640.             $session->set($transactionId.'[hotel][user_info]'$formUserInfo->getId());
  1641.                 if (true === $session->has($transactionId.'[hotel][detail]')) {
  1642.                     //$postData = $request->all();
  1643.                     $isFront $session->has('operatorId');
  1644.                     $session->set($transactionId.'[hotel][detail_data_hotel]'json_encode($postData));  //
  1645.                     $passangersData $request->get('PI');
  1646.                     $passangerNames = [];
  1647.                     for ($i 1$i <= $passangersData['person_count_1']; ++$i) {
  1648.                         $passangerNames[] = mb_strtolower($passangersData['first_name_1_'.$i]);
  1649.                         $passangerNames[] = mb_strtolower($passangersData['last_name_1_'.$i]);
  1650.                     }
  1651.                     if (($isFront) && ('0' == $quotation['quotation_check'])) {
  1652.                         $nameWhitelist $em->getRepository(\Aviatur\GeneralBundle\Entity\NameWhitelist::class)->findLikeWhitelist($passangerNames);
  1653.                         if (== sizeof($nameWhitelist)) {
  1654.                             $nameBlacklist $em->getRepository(\Aviatur\GeneralBundle\Entity\NameBlacklist::class)->findLikeBlacklist($passangerNames);
  1655.                             if ((sizeof(preg_grep("/^[a-z- *\.]+$/"$passangerNames)) != (sizeof($passangerNames))) ||
  1656.                                 (sizeof($nameBlacklist)) ||
  1657.                                 (sizeof(preg_grep('/(([b-df-hj-np-tv-xz])(?!\2)){4}/'$passangerNames)))
  1658.                             ) {
  1659.                                 return $this->json(['error' => 'error''message' => 'nombre inválido']);
  1660.                             }
  1661.                         }
  1662.                     }
  1663.                     if ($isFront) {
  1664.                         $customer null;
  1665.                         $ordersProduct null;
  1666.                     } else {
  1667.                         $customer $em->getRepository(\Aviatur\CustomerBundle\Entity\Customer::class)->find($billingData['id']);
  1668.                         $ordersProduct $em->getRepository(\Aviatur\GeneralBundle\Entity\OrderProduct::class)->getOrderProductsPending($customer);
  1669.                     }
  1670.                     if (null == $ordersProduct) {
  1671.                         $documentTypes $em->getRepository(\Aviatur\CustomerBundle\Entity\DocumentType::class)->findAll();
  1672.                         $arrayDocumentTypes = [];
  1673.                         foreach ($documentTypes as $documentType) {
  1674.                             $arrayDocumentTypes[$documentType->getExternalCode()] = $documentType->getId();
  1675.                         }
  1676.                         $genders $em->getRepository(\Aviatur\CustomerBundle\Entity\Gender::class)->findAll();
  1677.                         $arrayGenders = [];
  1678.                         foreach ($genders as $gender) {
  1679.                             $arrayGenders[$gender->getCode()] = $gender->getExternalCode();
  1680.                         }
  1681.                         $hotelInformation $request->get('HI'); // validar en que parte del roomlist viene    HI[ratePlan] HI[refundInfo]
  1682.                         $gender $em->getRepository(\Aviatur\CustomerBundle\Entity\Gender::class)->findOneByCode($passangersData['gender_1_1']);
  1683.                         $country $em->getRepository(\Aviatur\GeneralBundle\Entity\Country::class)->findOneByIatacode($passangersData['nationality_1_1']);
  1684.                             $ajaxUrl $this->generateUrl('aviatur_hotel_prepayment_step_2_secureN');
  1685.                                 return $this->json(['ajax_url' => $ajaxUrl]);
  1686.                     } else {
  1687.                         $booking = [];
  1688.                         $cus = [];
  1689.                         foreach ($ordersProduct as $orderProduct) {
  1690.                             $productResponse $aviaturEncoder->AviaturDecode($orderProduct->getPayResponse(), $orderProduct->getPublicKey());
  1691.                             $paymentResponse json_decode($productResponse);
  1692.                             array_push($booking'ON'.$orderProduct->getOrder()->getId().'-PN'.$orderProduct->getId());
  1693.                             if (isset($paymentResponse->x_approval_code)) {
  1694.                                 array_push($cus$paymentResponse->x_approval_code);
  1695.                             } elseif (isset($paymentResponse->createTransactionResult->trazabilityCode)) {
  1696.                                 array_push($cus$paymentResponse->createTransactionResult->trazabilityCode);
  1697.                             }
  1698.                         }
  1699.                         return $this->json([
  1700.                                     'error' => 'pending payments',
  1701.                                     'message' => 'pending_payments',
  1702.                                     'booking' => $booking'domain' => $domain ?? null'agencyId' => $agencyId ?? null'operatorId' => $operatorId ?? null,
  1703.                                     'cus' => $cus,
  1704.                         ]);
  1705.                     }
  1706.                 } else {
  1707.                     return $this->json(['error' => 'fatal''message' => $aviaturErrorHandler->errorRedirect($session->get($transactionId.'[availability_url]'), '''No encontramos información del detalle de tu búsqueda, por favor vuelve a intentarlo')]);
  1708.                 }
  1709.         } else {
  1710.             return $this->redirect($aviaturErrorHandler->errorRedirect($twigFolder->pathWithLocale('aviatur_general_homepage'), '''Acceso no autorizado'));
  1711.         }
  1712.     }
  1713.     public function prePaymentStep2Action(Request $requestOrderController $orderControllerAuthorizationCheckerInterface $authorizationCheckerAviaturErrorHandler $aviaturErrorHandlerTwigFolder $twigFolderManagerRegistry $registry, \Swift_Mailer $mailerRouterInterface $routerAviaturWebService $aviaturWebServiceParameterBagInterface $parameterBagAviaturLogSave $aviaturLogSave)
  1714.     {
  1715.         $transactionIdSessionName $parameterBag->get('transaction_id_session_name');
  1716.         $order = [];
  1717.         if ($request->isXmlHttpRequest()) {
  1718.             $request $request->request;
  1719.             $em $this->em;
  1720.             $session $this->session;
  1721.             $agency $this->agency;
  1722.             $billingData $request->get('BD');
  1723.             $detailEncodedData $request->get('DD');
  1724.             $detailData explode('/'base64_decode($detailEncodedData['additional']));
  1725.             $transactionId $detailData[0];
  1726.             $session->set($transactionId.'[hotel][prepayment_check]'true);
  1727.             if (true !== $session->has($transactionId.'[hotel][order]')) {
  1728.                 if (true === $session->has($transactionId.'[hotel][detail]')) {
  1729.                     $session->set($transactionIdSessionName$transactionId);
  1730.                     $isFront $session->has('operatorId');
  1731.                     if ($isFront) {
  1732.                         $customer $billingData;
  1733.                         $customer['isFront'] = true;
  1734.                         $status 'B2T';
  1735.                     } else {
  1736.                         $customer $em->getRepository(\Aviatur\CustomerBundle\Entity\Customer::class)->find($billingData['id']);
  1737.                         $status 'waiting';
  1738.                     }
  1739.                     if (isset($agency)) {
  1740.                         $productType $em->getRepository(\Aviatur\MpaBundle\Entity\ProductType::class)->findByCode('HOTELREST');
  1741.                         $orderIdentifier '{order_product_num}';
  1742.                         $order $orderController->createAction($agency$customer$productType$orderIdentifier$status);
  1743.                         $orderId str_replace('ON'''$order['order']);
  1744.                         $orderEntity $em->getRepository(\Aviatur\GeneralBundle\Entity\Order::class)->find($orderId);
  1745.                         $formUserInfo $em->getRepository(\Aviatur\GeneralBundle\Entity\FormUserInfo::class)->find($session->get($transactionId.'[hotel][user_info]'));
  1746.                         $formUserInfo->setOrder($orderEntity);
  1747.                         $em->persist($formUserInfo);
  1748.                         $em->flush();
  1749.                         // destination 
  1750.                          $payment $session->get($transactionId.'[hotel][paymentOn]');
  1751.                         
  1752.                         if ($isFront) {
  1753.                             $bookingReservation =  $this->bookingReservation($session$mailer$aviaturWebService$aviaturErrorHandler$router$registry$parameterBag$aviaturLogSave$transactionIdnull);
  1754.                             if($bookingReservation instanceof AviaturErrorHandler)
  1755.                                return $this->redirect($bookingReservation);
  1756.                            $order['url'] = $bookingReservation;
  1757.                         } else if($payment == 'destination'){
  1758.                             $bookingReservation =  $this->bookingReservation($session$mailer$aviaturWebService$aviaturErrorHandler$router$registry$parameterBag$aviaturLogSave$transactionIdnull,$payment);
  1759.                             if($bookingReservation instanceof AviaturErrorHandler)
  1760.                                return $this->redirect($bookingReservation);
  1761.                            $order['url'] = $this->generateUrl('aviatur_hotel_reservation_success_secureN');
  1762.                         }
  1763.                          else {
  1764.                             $order['url'] = $this->generateUrl('aviatur_hotel_payment_secureN');
  1765.                         }
  1766.                         return $this->json($order);
  1767.                     } else {
  1768.                         return $this->redirect($aviaturErrorHandler->errorRedirect($twigFolder->pathWithLocale('aviatur_general_homepage'), '''No se encontró la agencia con el dominio: '.$request->getHost()));
  1769.                     }
  1770.                 } else {
  1771.                     return $this->json(['error' => 'fatal''message' => $aviaturErrorHandler->errorRedirect($session->get($transactionId.'[availability_url]'), '''No encontramos información del detalle de tu búsqueda, por favor vuelve a intentarlo')]);
  1772.                 }
  1773.             } else {
  1774.                 $order['url'] = $this->generateUrl('aviatur_hotel_payment_secureN');
  1775.                 return $this->json($order);
  1776.             }
  1777.         } else {
  1778.             return $this->redirect($aviaturErrorHandler->errorRedirect($twigFolder->pathWithLocale('aviatur_general_homepage'), '''Acceso no autorizado'));
  1779.         }
  1780.     }
  1781.     public function paymentAction(Request $request, \Swift_Mailer $mailer,P2PController $p2pPaymentControllerMultiHotelDiscount $multiHotelDiscountPayoutExtraService $payoutExtraServiceAviaturErrorHandler $aviaturErrorHandlerRouterInterface $routerTwigFolder $twigFolderManagerRegistry $registrySessionInterface $sessionParameterBagInterface $parameterBagTokenizerService $tokenizerServiceCustomerMethodPaymentService $customerMethodPaymentAviaturLogSave $aviaturLogSaveOrderController $orderController)
  1782.     {
  1783.         $transactionIdSessionName $parameterBag->get('transaction_id_session_name');
  1784.         $aviaturPaymentOnline $parameterBag->get('aviatur_payment_online');
  1785.         $aviaturPaymentOnRequest $parameterBag->get('aviatur_payment_on_request');
  1786.         $emailNotification $parameterBag->get('email_notification');
  1787.         $orderProduct = [];
  1788.         $roomRate = [];
  1789.         $paymentResponse null;
  1790.         $return null;
  1791.         $emissionData = [];
  1792.         $response null;
  1793.         $array = [];
  1794.         $em $this->em;
  1795.         $session $this->session;
  1796.         $parameters json_decode($session->get($request->getHost().'[parameters]'));
  1797.         $aviaturPaymentIva = (float) $parameters->aviatur_payment_iva;
  1798.         $transactionId $session->get($transactionIdSessionName);
  1799.         $provider $em->getRepository(\Aviatur\MpaBundle\Entity\Provider::class)->find($session->get($transactionId.'[hotel][provider]'));
  1800.         $providerId $provider->getProvideridentifier();
  1801.         $route $router->match(str_replace($request->getSchemeAndHttpHost(), ''$request->getUri()));
  1802.         //$isMulti = false !== strpos($route['_route'], 'multi') ? true : false;
  1803.         if ($provider->getPaymentType()->getCode() == $aviaturPaymentOnRequest) {
  1804.             // pago en destino
  1805.             return $this->redirect($this->generateUrl('aviatur_hotel_confirmation'));
  1806.         } elseif ($provider->getPaymentType()->getcode() == $aviaturPaymentOnline) {
  1807.             // pago online
  1808.             $detailInfo json_decode($session->get($transactionId.'[hotel][detail]'));
  1809.             $postData json_decode($session->get($transactionId.'[hotel][detail_data_hotel]'));
  1810.             $paymentData $postData->PD;
  1811.             if ($this->isAval) {
  1812.                 $redemptionPointParams $em->getRepository(\Aviatur\GeneralBundle\Entity\PointRedemption::class)->findPointRedemptionWithAgency($this->agency);
  1813.                 $pointRedemptionValue $redemptionPointParams['Config']['Amount']['PointVal'];
  1814.                 $pointRedemptionComplete = isset($postData->pointRedemptionComplete);
  1815.                 if ($session->has($transactionId '[remainingPoints]')) {
  1816.                     $pointsInfo $session->get($transactionId '[remainingPoints]');
  1817.                     $avalPoints $pointsInfo[0];
  1818.                     $valueAval $pointsInfo[1];
  1819.                 } else {
  1820.                     if (!$session->has($transactionId '[hotel][pointRedemptionValue]')) {
  1821.                         $requestAvalPoints = isset($paymentData->pointRedemptionValue) ? str_replace('.'''$paymentData->pointRedemptionValue) : 0;
  1822.                         if ($requestAvalPoints <= $redemptionPointParams['Config']['Amount']['MinStep'] && $requestAvalPoints 0) {
  1823.                             $session->set($transactionId '[hotel][pointRedemptionValue]'$redemptionPointParams['Config']['Amount']['MinStep']);
  1824.                         } else {
  1825.                             $session->set($transactionId '[hotel][pointRedemptionValue]'$requestAvalPoints);
  1826.                         }
  1827.                     }
  1828.                     $avalPoints $session->get($transactionId '[hotel][pointRedemptionValue]');
  1829.                     $valueAval $avalPoints $pointRedemptionValue;
  1830.                 }
  1831.             }
  1832.             if ($session->has($transactionId.'[crossed]'.'[url-hotel]')) {
  1833.                 $urlAvailability $session->get($transactionId.'[crossed]'.'[url-hotel]');
  1834.             } elseif ($session->has($transactionId.'[hotel][availability_url]')) {
  1835.                 $urlAvailability $session->get($transactionId.'[hotel][availability_url]');
  1836.             } else {
  1837.                 $urlAvailability $session->get($transactionId.'[availability_url]');
  1838.             }
  1839.             $routeParsed parse_url($urlAvailability);
  1840.             if ($session->has($transactionId.'external')) {
  1841.                 $routeParsed['path'] = $session->get('routePath');
  1842.             }
  1843.             $availabilityUrl $router->match($routeParsed['path']);
  1844.             $hotelName $detailInfo->data->hotelRoomlist->hotels[0]->name;
  1845.             $orderInfo json_decode($session->get($transactionId.'[hotel][order]'));
  1846.             $productId str_replace('PN'''$orderInfo->products);
  1847.             $orderProduct[] = $em->getRepository(\Aviatur\GeneralBundle\Entity\OrderProduct::class)->find($productId);
  1848.             $hotelInfo $postData->HI;
  1849.             foreach ($detailInfo->data->hotelRoomlist->hotels[0]->rates as $roomRatePlan) {
  1850.                 if ($roomRatePlan->rateKey == $hotelInfo->ratePlan) {
  1851.                     $roomRate $roomRatePlan;
  1852.                 }
  1853.             }
  1854.             $roomtotal $session->get($transactionId.'[hotel][roomsInfo]');
  1855.             // $roomsSelection = $request->get('HT');
  1856.             // $hotelRoomsJsonDataSelection = [];
  1857.             // if (isset($roomsSelection['rooms'])) {
  1858.             //     $jsonString = urldecode($roomsSelection['rooms']);
  1859.             //     $hotelRoomsJsonDataSelection = json_decode($jsonString, true);
  1860.             // }
  1861.             // $roomRate = $hotelRoomsJsonDataSelection;
  1862.             $startDate strtotime((string) $detailInfo->data->hotelRoomlist->stay->checkIn);
  1863.             $endDate strtotime((string) $detailInfo->data->hotelRoomlist->stay->checkOut);
  1864.             $nights floor(($endDate $startDate) / (60 60 24));
  1865.             //$location = explode(",", $session->get('[hotel]destinationtext'));
  1866.             $destination $detailInfo->data->hotelRoomlist->hotels[0]->location->destination->name;
  1867.             //$destination = $session->get('[hotel]destinationtext') /*$availabilityUrl['destination1'] ?? $availabilityUrl['destination']*/;  //validar de donde sacar ahora esro
  1868.             //Agregar todos los cuartos a la descripción!!!!!!!!!!!!!!!!!
  1869.             $description 'Hotel - '.(string) $hotelName.'('.(string) implode(", "$roomtotal->description)./*' '.(string) $roomRate['RatePlanCategory'].*/') - '.$destination.'('.date('d/m/Y'$startDate).' - '.date('d/m/Y'$endDate).')';
  1870.             $datediff $endDate $startDate;
  1871.             $travelDays floor($datediff / (60 60 24));
  1872.             // COLLECT INFORMATION TO PERSIST OrderProduct->Email
  1873.             $this->generate_email($session$registry$parameterBag$orderProduct[0], $detailInfo,true$startDate$endDate);
  1874.             $discountTransactionID $session->get('currentHotelDiscountSession');
  1875.             $discountAmount 0;
  1876.             $discountTax 0;
  1877.             $_x_tax 0;
  1878.            /* $payoutExtrasValues = null;
  1879.             if (isset($postData->payoutExtrasSelection) && !$isMulti) {
  1880.                 $payoutExtrasValues = $payoutExtraService->getPayoutExtrasValues($postData->payoutExtrasSelection, $transactionId);
  1881.             }*/
  1882.             $minimumAmount 1000;
  1883.             $qseAmount 0;
  1884.             if ('p2p' == $paymentData->type || 'world' == $paymentData->type) {
  1885.                 $customer $em->getRepository(\Aviatur\CustomerBundle\Entity\Customer::class)->find($postData->BD->id);
  1886.                 if (false !== strpos($paymentData->address'***')) {
  1887.                     $paymentData->address $customer->getAddress();
  1888.                 }
  1889.                 if (false !== strpos($paymentData->phone'***')) {
  1890.                     $paymentData->phone $customer->getPhone();
  1891.                 }
  1892.                 if (false !== strpos($paymentData->email'***')) {
  1893.                     $paymentData->email $customer->getEmail();
  1894.                 }
  1895.                 $x_amount_total = (float) ($roomtotal->AmountTotal) - $discountAmount;
  1896.                 $x_amount_total $x_amount_total $qseAmount;
  1897.                 if ($x_amount_total $minimumAmount) {
  1898.                     $x_amount_total $minimumAmount;
  1899.                 }
  1900.                 $ivaExcludedCitiesParameter $em->getRepository(\Aviatur\GeneralBundle\Entity\Parameter::class)->findOneByName('iva_exclude');
  1901.                 $excludedCitiesList $ivaExcludedCitiesParameter->getValue();
  1902.                 $excludedCities array_map('trim'explode(','$excludedCitiesList));
  1903.                 $countryCode $session->get($transactionId.'[hotel]destinationtext');
  1904.                 $x_amount_tax 0;
  1905.                 $x_amount_base 0;
  1906.                 $HotelProvider $em->getRepository(\Aviatur\HotelBundle\Entity\HotelProvider::class)->findBillingprovider($provider->getId());
  1907.                 $ivaincl $HotelProvider->getIvaIncl();
  1908.                 if (strtoupper($countryCode) == "CO" && !in_array($destination$excludedCities)) {
  1909.                     $baseAmount $roomtotal->AmountTotal 1.19;
  1910.                     if ($ivaincl != 2) {
  1911.                         $x_amount_tax = isset($roomtotal->AmountTotal) && $roomtotal->AmountTotal != round($baseAmount 0.19) : 0;
  1912.                         $x_amount_base = isset($roomtotal->AmountTotal) && $roomtotal->AmountTotal != round($roomtotal->AmountTotal 1.19) : 0;
  1913.                     } else {
  1914.                         $x_amount_tax 0;
  1915.                         $x_amount_base = isset($roomtotal->AmountTotal) && $roomtotal->AmountTotal != $roomtotal->AmountTotal 0;
  1916.                     }
  1917.                 }
  1918.                 
  1919.                 if (!empty($session->get($transactionId.'[QSE]'))) {
  1920.                     $x_amount_total = ($session->get($transactionId.'[qseActive]') == 1) ? ((($x_amount_total $nights $session->get($transactionId.'[QSE]')) * $nights) + $x_amount_total) : $x_amount_total $session->get($transactionId.'[QSE]');
  1921.                 }
  1922.                 $array = [
  1923.                     'x_currency_code' => (string)"COP" /*$roomRate->TotalAviatur->CurrencyCode  agregarlo de algun lado */,
  1924.                     'x_amount' => $x_amount_total,
  1925.                     'x_tax' => number_format($x_amount_tax2'.'''),
  1926.                     'x_amount_base' => number_format($x_amount_base2'.'''),
  1927.                     'x_invoice_num' => $orderInfo->order.'-'.$orderInfo->products,
  1928.                     'x_first_name' => $paymentData->first_name,
  1929.                     'x_last_name' => $paymentData->last_name,
  1930.                     'x_description' => $description,
  1931.                     'x_city' => $customer->getCity()->getIatacode(),
  1932.                     'x_country_id' => $customer->getCountry()->getIatacode(),
  1933.                     'x_cust_id' => $paymentData->doc_type.' '.$paymentData->doc_num,
  1934.                     'x_address' => $paymentData->address,
  1935.                     'x_phone' => $paymentData->phone,
  1936.                     'x_email' => $paymentData->email,
  1937.                     'x_card_num' => $paymentData->card_num,
  1938.                     'x_exp_date' => $paymentData->exp_month.$paymentData->exp_year,
  1939.                     'x_card_code' => $paymentData->card_code,
  1940.                     'x_differed' => $paymentData->differed,
  1941.                     'x_client_id' => $postData->BD->id,
  1942.                     'product_type' => 'hotel',
  1943.                     'productId' => str_replace('PN'''$orderInfo->products),
  1944.                     'orderId' => str_replace('ON'''$orderInfo->order),
  1945.                     'franchise' => $paymentData->franquise,
  1946.                     'worldpay_validate' => true,
  1947.                 ];
  1948.                 if (isset($paymentData->card_values)) {
  1949.                     $array['card_values'] = (array) $paymentData->card_values;
  1950.                 }
  1951.                 /*
  1952.                 if ($payoutExtrasValues && !(bool) $session->get($transactionId.'[PayoutExtras][Processed]')) {
  1953.                     foreach ($payoutExtrasValues as $payoutExtraValues) {
  1954.                         $array['x_amount'] += round((float) $payoutExtraValues->values->fare->total);
  1955.                         $array['x_tax'] += round((float) $payoutExtraValues->values->fare->tax);
  1956.                         $array['x_amount_base'] += round((float) $payoutExtraValues->values->fare->base);
  1957.                     }
  1958.                     $array['x_amount'] = $array['x_amount'] + $qseAmount;
  1959.                 }
  1960.                 $payoutExtrasValues = $payoutExtraService->setPayoutExtrasAsProcessed($transactionId);
  1961.                 */
  1962.                 //AVAL POINT REDEMPTION
  1963.                 if ($this->isAval) {
  1964.                     if ($session->has($transactionId '[alreadyRedimed]')) {
  1965.                         $array['putDistribution'] = true;
  1966.                     }
  1967.                     if ($valueAval && !$session->has($transactionId '[alreadyRedimed]')) {
  1968.                         $redemption $this->redemptionService->hotelAvalPointsRedemption(
  1969.                             $session$pointRedemptionValue$avalPoints$pointRedemptionComplete$array,
  1970.                             $redemptionPointParams$transactionId$parameters$orderProduct$productId
  1971.                         );
  1972.                         if (isset($redemption['availability_url'])) {
  1973.                             $this->redirect($aviaturErrorHandler->errorRedirect($redemption['availability_url'], ''$redemption['response']['error']['text']['StatusDesc'] ?? $redemption['response']['ok']['text']['StatusDesc']));
  1974.                         }
  1975.                         $array $redemption;
  1976.                     } elseif ($valueAval == && $session->has($transactionId '[alreadyRedimed]')) {
  1977.                         $array['onlyRedemption'] = true;
  1978.                     }
  1979.                 }
  1980.                 //END AVAL REDEMPTION
  1981.                 $array['x_cancelation_date'] = (string) $detailInfo->data->hotelRoomlist->hotels[0]->rates[0]->cancellationPolicies[0]->from;
  1982.                 if (isset($paymentData->cusPOptSelected)) {
  1983.                     $array['isToken'] = (string) $paymentData->card_values->card_num_token;
  1984.                 }
  1985.                 if ('p2p' == $paymentData->type) {
  1986.                     if (isset($paymentData->savePaymProc)) {
  1987.                         $array['x_provider_id'] = 1;
  1988.                     } elseif (isset($paymentData->cusPOptSelected)) {
  1989.                         if (isset($paymentData->cusPOptSelectedStatus)) {
  1990.                             if ('NOTVERIFIED' == $paymentData->cusPOptSelectedStatus) {
  1991.                                 $array['x_provider_id'] = 1;
  1992.                             } else {
  1993.                                 $array['x_provider_id'] = 2;
  1994.                             }
  1995.                         } else {
  1996.                             $array['x_provider_id'] = 2;
  1997.                         }
  1998.                     }
  1999.                 }
  2000.                 if ('p2p' == $paymentData->type) {
  2001.                     $paymentResponse $p2pPaymentController->placetopayAction($parameterBag$tokenizerService$customerMethodPayment$mailer$aviaturLogSave$array$combination false$segment nullfalse);
  2002.                     $return $this->redirect($this->generateUrl('aviatur_hotel_payment_p2p_return_url_secureN', [], true));
  2003.                 }
  2004.                 unset($array['x_client_id']);
  2005.                 if (null != $paymentResponse) {
  2006.                     /* Cancelar puntos si el pago no fue exitoso */
  2007.                     if (isset($paymentResponse['x_response_code']) && $paymentResponse['x_response_code'] === '2') {
  2008.                         if ($this->isAval) {
  2009.                             if (!empty($array['redemptionPoints']) && $array['redemptionPoints'] > 0) {
  2010.                                 $this->aviaturAthServices->cancelRedemptionPoints($redemption['redemption']);
  2011.                             }
  2012.                         }
  2013.                     } elseif (isset($paymentResponse['error'])) {
  2014.                         if (!empty($array['redemptionPoints']) && $array['redemptionPoints'] > 0) {
  2015.                             $this->aviaturAthServices->cancelRedemptionPoints($redemption['redemption']);
  2016.                         }
  2017.                     }
  2018.                     /* fin cancelacion */
  2019.                     return $return;
  2020.                 } else {
  2021.                     $orderProduct[0]->setStatus('pending');
  2022.                     $em->persist($orderProduct[0]);
  2023.                     $em->flush();
  2024.                     return $this->redirect($aviaturErrorHandler->errorRedirect($this->generateUrl('aviatur_hotel_retry_secure'), '''No hay respuesta por parte del servicio de pago, por favor intenta nuevamente o comunícate con nosotros para finalizar tu transacción'));
  2025.                 }
  2026.             }else {
  2027.                 return $this->redirect($aviaturErrorHandler->errorRedirect($this->generateUrl('aviatur_hotel_retry_secure'), '''El tipo de pago es invalido'));
  2028.             }
  2029.         } else {
  2030.             return $this->redirect($aviaturErrorHandler->errorRedirect($this->generateUrl('aviatur_hotel_retry_secure'), '''El provedor arrojó un método de pago inesperado'));
  2031.         }
  2032.     }
  2033.     public function p2pCallbackAction(OrderController $orderControllerValidateSanctionsRenewal $validateSanctionsTokenStorageInterface $tokenStorageCustomerMethodPaymentService $customerMethodPaymentAviaturMailer $aviaturMailerPayoutExtraService $payoutExtraServiceAviaturEncoder $aviaturEncoderAviaturErrorHandler $aviaturErrorHandlerManagerRegistry $registryParameterBagInterface $parameterBagAviaturWebService $aviaturWebServiceRouterInterface $router, \Swift_Mailer $mailer,AviaturLogSave $aviaturLogSave)
  2034.     {
  2035.         $transactionIdSessionName $parameterBag->get('transaction_id_session_name');
  2036.         $em $this->em;
  2037.         $session $this->session;
  2038.         $transactionId $session->get($transactionIdSessionName);
  2039.         $orderProductCode $session->get($transactionId.'[hotel][order]');
  2040.         $productId str_replace('PN'''json_decode($orderProductCode)->products);
  2041.         $orderProduct $em->getRepository(\Aviatur\GeneralBundle\Entity\OrderProduct::class)->find($productId);
  2042.         $decodedRequest json_decode($aviaturEncoder->AviaturDecode($orderProduct->getPayrequest(), $orderProduct->getPublicKey()));
  2043.         $decodedResponse json_decode($aviaturEncoder->AviaturDecode($orderProduct->getPayresponse(), $orderProduct->getPublicKey()));
  2044.         if (null != $decodedResponse) {
  2045.             $agency $orderProduct->getOrder()->getAgency();
  2046.             $prepaymentInfo json_decode($session->get($transactionId.'[hotel][prepayment]'));
  2047.             $twig '';
  2048.             $additionalQS '';
  2049.             $retryCount = (int) $session->get($transactionId.'[hotel][retry]');
  2050.             $jsonSendEmail $em->getRepository(\Aviatur\GeneralBundle\Entity\Parameter::class)->findOneByName('send_email');
  2051.             if (isset(json_decode($jsonSendEmail->getDescription())->email)) {
  2052.                 $email json_decode($jsonSendEmail->getDescription())->email->CallBack;
  2053.             }
  2054.             $reference str_replace('{"order":"'''$orderProductCode);
  2055.             $reference str_replace('","products":"''-'$reference);
  2056.             $reference str_replace('"}'''$reference);
  2057.             $references $reference;
  2058.             $bookings $orderProduct->getBooking();
  2059.             switch ($decodedResponse->x_response_code) {
  2060.                 case isset($decodedResponse->x_response_code_cyber) && (== $decodedResponse->x_response_code_cyber):
  2061.                     //rechazado cybersource
  2062.                     $parameters $em->getRepository(\Aviatur\GeneralBundle\Entity\Parameter::class)->findOneByName('aviatur_switch_rechazada_cyber');
  2063.                     if ($parameters) {
  2064.                         if (== $parameters->getValue()) {
  2065.                             if (== $decodedResponse->x_response_code) {
  2066.                                 $postData json_decode($session->get($transactionId '[hotel][detail_data_hotel]'));
  2067.                                 if (isset($postData->PD->savePaymProc)) {
  2068.                                     $customerLogin $tokenStorage->getToken()->getUser();
  2069.                                     $customerMethodPayment->setMethodsByCustomer($customerLoginjson_decode(json_encode($postData), true));
  2070.                                 }
  2071.                                 if (isset($postData->PD->cusPOptSelected)) {
  2072.                                     if (isset($postData->PD->cusPOptSelectedStatus)) {
  2073.                                         if ('NOTVERIFIED' == $postData->PD->cusPOptSelectedStatus) {
  2074.                                             $postData->PD->cusPOptSelectedStatus 'ACTIVE';
  2075.                                             $customerLogin $tokenStorage->getToken()->getUser();
  2076.                                             $customerMethodPayment->setMethodsByCustomer($customerLoginjson_decode(json_encode($postData), true));
  2077.                                         }
  2078.                                     }
  2079.                                 }
  2080.                             }
  2081.                         }
  2082.                     }
  2083.                     // Aquí NO se hace la reserva en ningún caso
  2084.                     $twig 'aviatur_hotel_payment_rejected_secureN';  //enviar a la pantalla de rechazado
  2085.                     // no break
  2086.                 case 3:// pendiente p2p
  2087.                     $twig '' != $twig $twig 'aviatur_hotel_payment_pending_secureN';  //enviar a la pantalla de pago pendiente
  2088.                     $emissionData 'No Reservation';
  2089.                     $orderProduct->setEmissiondata(json_encode($emissionData));
  2090.                     $orderProduct->setUpdatingdate(new \DateTime());
  2091.                     $em->persist($orderProduct);
  2092.                     $em->flush();
  2093.                     $retryCount 1;
  2094.                     break;
  2095.                 case 0:// error p2p
  2096.                     $twig 'aviatur_hotel_payment_error_secureN';
  2097.                     if (isset($email)) {
  2098.                         $from $session->get('emailNoReply');
  2099.                         $error $twig;
  2100.                         $subject $orderProduct->getDescription().':Error en el proceso de pago de Aviatur';
  2101.                         $body '</br>El proceso de pago a retornado un error </br>Referencia: '.$references.'</br>Reserva:'.$bookings;
  2102.                         $aviaturMailer->sendEmailGeneral($from$email$subject$body);
  2103.                     }
  2104.                     // no break
  2105.                 case 2:// rechazada p2p
  2106.                     $twig '' != $twig $twig 'aviatur_hotel_payment_rejected_secureN';
  2107.                     if (isset($email)) {
  2108.                         $from $session->get('emailNoReply');
  2109.                         $error $twig;
  2110.                         $subject $orderProduct->getDescription().':Transacción rechazada';
  2111.                         $body '</br>El pago fue rechazado </br>Referencia: '.$references.'</br>Reserva:'.$bookings;
  2112.                         $aviaturMailer->sendEmailGeneral($from$email$subject$body);
  2113.                     }
  2114.                     break;
  2115.                 case 1:// aprobado p2p
  2116.                     $postData json_decode($session->get($transactionId.'[hotel][detail_data_hotel]'));
  2117.                     $customer $em->getRepository(\Aviatur\CustomerBundle\Entity\Customer::class)->find($postData->BD->id);
  2118.                     if (isset($postData->PD->savePaymProc)) {
  2119.                         $customerLogin $tokenStorage->getToken()->getUser();
  2120.                         $customerMethodPayment->setMethodsByCustomer($customerLoginjson_decode(json_encode($postData), true));
  2121.                     }
  2122.                     if (isset($postData->PD->cusPOptSelected)) {
  2123.                         if (isset($postData->PD->cusPOptSelectedStatus)) {
  2124.                             if ('NOTVERIFIED' == $postData->PD->cusPOptSelectedStatus) {
  2125.                                 $postData->PD->cusPOptSelectedStatus 'ACTIVE';
  2126.                                 $customerLogin $tokenStorage->getToken()->getUser();
  2127.                                 $customerMethodPayment->setMethodsByCustomer($customerLoginjson_decode(json_encode($postData), true));
  2128.                             }
  2129.                         }
  2130.                     }
  2131.                     $decodedRequest->product_type 'hotel';
  2132.                     $decodedResponse->product_type 'hotel';
  2133.                     $encodedRequest $aviaturEncoder->AviaturEncode(json_encode($decodedRequest), $orderProduct->getPublicKey());
  2134.                     $encodedResponse $aviaturEncoder->AviaturEncode(json_encode($decodedResponse), $orderProduct->getPublicKey());
  2135.                     $orderProduct->setPayrequest($encodedRequest);
  2136.                     $orderProduct->setPayresponse($encodedResponse);
  2137.                     $twig 'aviatur_hotel_reservation_success_secureN';
  2138.                     if ('rappi' == $orderProduct->getOrder()->getAgency()->getAssetsFolder()) {
  2139.                         $additionalQS '?bookingid='.$orderProduct->getBooking().'&total='.$decodedRequest->x_amount;
  2140.                     }
  2141.                     //Reemplazar por consumo de reserva!!!!
  2142.                     $provider $em->getRepository(\Aviatur\MpaBundle\Entity\Provider::class)->find($session->get($transactionId.'[hotel][provider]'));
  2143.                     $providerId $provider->getProvideridentifier();
  2144.                     $orderController->updatePaymentAction($orderProductfalsenull);
  2145.                     if(is_null($orderProduct->getEmissiondata())){
  2146.                         $rs $this->bookingReservation($session$mailer$aviaturWebService$aviaturErrorHandler$router$registry$parameterBag,$aviaturLogSave$transactionId1);
  2147.                     }
  2148.                     $reservationInfo json_decode($session->get($transactionId.'[hotel][reservation]'));
  2149.                     $reservationId2 'PN'.$orderProduct->getId();
  2150.                     // $orderUpdatePayment = str_replace(
  2151.                     //     ['{web_book_id}', '{hotel_book_id}'],
  2152.                     //     ['PN'.$orderProduct->getId(), (string) $reservationId2],
  2153.                     //     $orderProduct->getUpdatePaymentData()
  2154.                     // );
  2155.                     /*$orderUpdatePayment = str_replace(
  2156.                         ['{web_book_id}', '{hotel_book_id}'],
  2157.                         ['PN'.$orderProduct->getId(), $orderProduct->getBooking()],
  2158.                         $orderProduct->getUpdatePaymentData()
  2159.                     );
  2160.                     $orderProduct->setUpdatePaymentData($orderUpdatePayment);
  2161.                     $em->persist($orderProduct);
  2162.                     $em->flush();*/
  2163.                     break;
  2164.             }
  2165.             // Update Payment
  2166.             $orderController->updatePaymentAction($orderProductfalsenull);
  2167.             $orderUpdatePayment str_replace(
  2168.                 ['{web_book_id}''{hotel_book_id}'],
  2169.                 ['PN'.$orderProduct->getId(), $orderProduct->getBooking()],
  2170.                 $orderProduct->getUpdatePaymentData()
  2171.             );
  2172.             $orderProduct->setUpdatePaymentData($orderUpdatePayment);
  2173.             $em->persist($orderProduct);
  2174.             $em->flush($orderProduct);
  2175.             $payoutExtraService->payoutExtrasCallback($twig$transactionId'hotel'$agency);
  2176.             $session->set($transactionId.'[hotel][retry]'$retryCount 1);
  2177.             $urlResume $this->generateUrl($twig);
  2178.             $urlResume .= $additionalQS;
  2179.             /* Pero solo si hay condicionados (no bloqueados) y que paguen con Tarjeta */
  2180.             if ($session->has('Marked_users')) {
  2181.                 $product 'Hotel';
  2182.                 $validateSanctions->sendMarkedEmail($orderProductCode$session$agency$orderProduct$transactionId$product);
  2183.             }
  2184.             return $this->redirect($urlResume);
  2185.         } else {
  2186.             $orderProduct->setStatus('pending');
  2187.             $em->persist($orderProduct);
  2188.             $em->flush();
  2189.             return $this->redirect($aviaturErrorHandler->errorRedirect($this->generateUrl('aviatur_hotel_retry_secure'), '''No hay respuesta por parte del servicio de pago'));
  2190.         }
  2191.     }
  2192.     private function bookingReservation(SessionInterface $session, \Swift_Mailer $mailerAviaturWebService $aviaturWebServiceAviaturErrorHandler $aviaturErrorHandlerRouterInterface $routerManagerRegistry $registryParameterBagInterface $parameterBag,AviaturLogSave $aviaturLogSave$transactionId$stateDb null$payment ='online')
  2193.     {
  2194.         //$startTime = $session->get('executiontime');
  2195.         $isFront $session->has('operatorId');
  2196.         $correlationIdSessionName $parameterBag->get('correlation_id_session_name');
  2197.         $detail json_decode((string) $session->get($transactionId.'[hotel][detail]'));
  2198.         //validar lo de la url
  2199.         if ($session->has($transactionId.'[crossed]'.'[url-hotel]')) {
  2200.             $urlAvailability $session->get($transactionId.'[crossed]'.'[url-hotel]');
  2201.         } elseif ($session->has($transactionId.'[hotel][availability_url]')) {
  2202.             $urlAvailability $session->get($transactionId.'[hotel][availability_url]');
  2203.         } else {
  2204.             $urlAvailability $session->get($transactionId.'[availability_url]');
  2205.         }
  2206.         $routeParsed parse_url($urlAvailability);
  2207.         if ($session->has($transactionId.'external')) {
  2208.             $routeParsed['path'] = $session->get('routePath');
  2209.         }
  2210.         $availabilityUrl $router->match($routeParsed['path']);
  2211.         $currentRequest $this->requestStack->getCurrentRequest();
  2212.         $referenceUrl $currentRequest $currentRequest->headers->get('referer') : null;
  2213.         $route $currentRequest $router->match(str_replace($currentRequest->getSchemeAndHttpHost(), ''$currentRequest->getUri())) : [];
  2214.         $isMulti = ($referenceUrl && strpos($referenceUrl'multi') !== false) || (isset($route['_route']) && strpos($route['_route'], 'multi') !== false);
  2215.         $postData json_decode($session->get($transactionId.'[hotel][detail_data_hotel]'));
  2216.         $passangersData $postData->PI;
  2217.         if ($isFront) {
  2218.             $payData '';
  2219.         } else {
  2220.             $payData $postData->PD;
  2221.         }
  2222.         $paymentData = [
  2223.             "payment" => $payment,
  2224.             "paymentData" => $payData
  2225.         ];
  2226.         $hotelInformation $session->get($transactionId.'[hotel][roomsInfo]');
  2227.         $em $this->em;
  2228.         //$gender = $em->getRepository(\Aviatur\CustomerBundle\Entity\Gender::class)->findOneByCode($passangersData->gender_1_1);
  2229.         //$country = $em->getRepository(\Aviatur\GeneralBundle\Entity\Country::class)->findOneByIatacode($passangersData->nationality_1_1);
  2230.         if ($isFront) {
  2231.             $customer $postData->BD;
  2232.             $dbState "0";
  2233.             $usuario $session->get('operatorId');
  2234.             $customerModel = new CustomerModel();
  2235.             $userData null;
  2236.             try {
  2237.                 $userData $aviaturWebService->callWebService('GENERALLAVE''dummy|http://www.aviatur.com.co/dummy/'$customerModel->getXmlAgent($usuario));
  2238.                 $session->set($transactionId '[user]'$userData->asXml());
  2239.                 $userEmail = (string) $userData->CORREO_ELECTRONICO;
  2240.             } catch (\Exception $e) {
  2241.                 $userEmail $session->get('domain') . '@' $session->get('domain');
  2242.             }
  2243.         } else {
  2244.             $customer $em->getRepository(\Aviatur\CustomerBundle\Entity\Customer::class)->find($postData->BD->id);
  2245.             $dbState "1";
  2246.             $userEmail $session->get('domain') . '|' $customer->getEmail();
  2247.         }
  2248.         if (false !== strpos($passangersData->first_name_1_1'***')) {
  2249.             $passangersData->first_name_1_1 $customer->getFirstname();
  2250.             $passangersData->last_name_1_1 $customer->getLastname();
  2251.             $passangersData->phone_1_1 = !empty($customer->getPhone()) ? $customer->getPhone() : '6012861616';
  2252.             $passangersData->email_1_1 $customer->getEmail();
  2253.             $passangersData->address_1_1 = !empty($customer->getAddress()) ? $customer->getAddress() : "Av 19 4-62 ";
  2254.             $passangersData->doc_num_1_1 $customer->getDocumentnumber();
  2255.         }
  2256.         $orderProductCode $session->get($transactionId.'[hotel][order]');
  2257.         $productId str_replace('PN'''json_decode($orderProductCode)->products);
  2258.         $orderProduct $em->getRepository(\Aviatur\GeneralBundle\Entity\OrderProduct::class)->find($productId);
  2259.         $detailInfo json_decode((string) $session->get($transactionId.'[hotel][detail]'));
  2260.         //$prepaymentInfo = json_decode((string) $session->get($transactionId.'[hotel][prepayment]'));
  2261.         $startDate strtotime((string)$detailInfo->data->hotelRoomlist->stay->checkIn);
  2262.         $endDate strtotime((string) $detailInfo->data->hotelRoomlist->stay->checkOut);
  2263.         $this->generate_email($session$registry,$parameterBag$orderProduct$detailInfonull$startDate$endDate);
  2264.         $orderRequestArray explode('<FILTRO>'str_replace('</FILTRO>''<FILTRO>'$orderProduct->getAddproductdata()));
  2265.         // $orderRequest = \simplexml_load_string($orderRequestArray[1]);
  2266.         $provider $em->getRepository(\Aviatur\MpaBundle\Entity\Provider::class)->find($session->get($transactionId.'[hotel][provider]'));
  2267.         $passangersDataArray json_decode(json_encode($passangersData), true);
  2268.         $totalGuests $passangersDataArray['person_count_1'];
  2269.         for ($i 1$i <= $totalGuests; ++$i) {
  2270.             $gender $em->getRepository(\Aviatur\CustomerBundle\Entity\Gender::class)->findOneByCode($passangersDataArray['gender_1'.'_'.$i]);
  2271.             $country $em->getRepository(\Aviatur\GeneralBundle\Entity\Country::class)->findOneByIatacode($passangersDataArray['nationality_1'.'_'.$i]);
  2272.             $passangersDataArray['DocType_1'.'_'.$i] = $passangersDataArray['doc_type_1'.'_'.$i];
  2273.             $variable['doc_num_1'.'_'.$i] = $passangersDataArray['doc_num_1'.'_'.$i];
  2274.             $variable['first_name_1'.'_'.$i] = $passangersDataArray['first_name_1'.'_'.$i];
  2275.             $variable['last_name_1'.'_'.$i] = $passangersDataArray['last_name_1'.'_'.$i];
  2276.             $variable['birthday_1'.'_'.$i] = $passangersDataArray['birthday_1'.'_'.$i];
  2277.             $variable['gender_1'.'_'.$i] = $gender->getExternalcode();
  2278.             $variable['nationality_1'.'_'.$i] = $country->getIatacode();
  2279.             $variable['DocType_1'.'_'.$i] = $passangersDataArray['doc_type_1'.'_'.$i];
  2280.             $variable['passanger_type_1'.'_'.$i] = $passangersDataArray['passanger_type_1'.'_'.$i];
  2281.         }
  2282.         if ($isFront) {
  2283.             $passangersDataArray['address_1_1'] = !empty($passangersDataArray['address_1_1']) ? $passangersDataArray['address_1_1'] : "Av 19 4-62";
  2284.         }else{
  2285.             $passangersDataArray['address_1_1'] = !empty($passangersDataArray['address_1_1']) ? $passangersDataArray['address_1_1'] : (!empty($customer->getAddress()) ? $customer->getAddress() : "Av 19 4-62");
  2286.         }
  2287.         $roomsCount count($hotelInformation->rateKey);  // Número de habitaciones
  2288.         $rooms = [];
  2289.         $adultIndex 0;
  2290.         $childIndex 0;
  2291.         $providerId $provider->getProvideridentifier();//$hotelInformation->provider;  // Obtener el provider
  2292.         $adults = [];
  2293.         $children = [];
  2294.         // Recopilamos la información de los pasajeros
  2295.         for ($i 1$i <= $totalGuests; ++$i) {
  2296.             if ($variable['passanger_type_1' '_' $i] === "ADT") {
  2297.                 $adult = [
  2298.                     "type" => "ADT",
  2299.                     "name" => $variable['first_name_1' '_' $i],
  2300.                     "surname" => $variable['last_name_1' '_' $i],
  2301.                     "documentType" => $variable['DocType_1' '_' $i],
  2302.                     "documentNumber" => $variable['doc_num_1' '_' $i],
  2303.                     "nationality" => $variable['nationality_1' '_' $i],
  2304.                     "birthDate" => $variable['birthday_1' '_' $i],
  2305.                     "gender" => $variable['gender_1' '_' $i],
  2306.                     "indexContact" => "1",
  2307.                     "telephone" => !empty($passangersDataArray['phone_1_1'])
  2308.                     ? $passangersDataArray['phone_1_1']
  2309.                     : $postData->CD->phone,
  2310.                     "email" => $passangersDataArray['email_1_1'],
  2311.                     "address" => [
  2312.                         "AddressLine" => empty($passangersDataArray['address_1_1']) ? 'Cl 19 N 4 62' $passangersDataArray['address_1_1'],
  2313.                         "CityName" => "Bogota",
  2314.                         "PostalCode" => "110810",
  2315.                         "StateProv" => "Cundinamarca",
  2316.                         "CountryName" => "Colombia"
  2317.                     ]
  2318.                 ];
  2319.                 $adults[] = $adult;
  2320.             }
  2321.             if (($variable['passanger_type_1' '_' $i] === "CHD") || ($isMulti && $variable['passanger_type_1' '_' $i] === "INF")) {
  2322.                 $child = [
  2323.                     "type" => "CHD",
  2324.                     "name" => $variable['first_name_1' '_' $i],
  2325.                     "surname" => $variable['last_name_1' '_' $i],
  2326.                     "documentType" => $variable['DocType_1' '_' $i],
  2327.                     "documentNumber" => $variable['doc_num_1' '_' $i],
  2328.                     "nationality" => $variable['nationality_1' '_' $i],
  2329.                     "birthDate" => $variable['birthday_1' '_' $i],
  2330.                     "gender" => $variable['gender_1' '_' $i],
  2331.                     "indexContact" => "1",
  2332.                     "telephone" => !empty($passangersDataArray['phone_1_1'])
  2333.                     ? $passangersDataArray['phone_1_1']
  2334.                     : $postData->CD->phone,
  2335.                     "email" => $passangersDataArray['email_1_1'],
  2336.                     "address" => [
  2337.                         "AddressLine" => empty($passangersDataArray['address_1_1']) ? 'Cl 19 N 4 62' $passangersDataArray['address_1_1'],
  2338.                         "CityName" => "Bogota",
  2339.                         "PostalCode" => "110810",
  2340.                         "StateProv" => "Cundinamarca",
  2341.                         "CountryName" => "Colombia"
  2342.                     ]
  2343.                 ];
  2344.                 $children[] = $child;
  2345.             }
  2346.         }
  2347.         $rooms = [];
  2348.         $roomIndex 0;
  2349.         $adultsCount count($adults);
  2350.         $childrenCount count($children);
  2351.         $adultsPerRoom $hotelInformation->adults;
  2352.         $childrenPerRoom $hotelInformation->children;
  2353.         $hotelAdultsCount count($hotelInformation->adults);
  2354.         if ($providerId == 124) {
  2355.             while ($adultIndex $adultsCount && $roomIndex $roomsCount){
  2356.                 $room = [
  2357.                     "roomId" => $roomIndex 1,
  2358.                     "rateKey" => !empty($hotelInformation->rateKey[$roomIndex]) ? $hotelInformation->rateKey[$roomIndex] : " ",
  2359.                     "paxes" => []
  2360.                 ];
  2361.                 $room['paxes'][] = $adults[$adultIndex];
  2362.                 $adultIndex++;
  2363.                 $rooms[] = $room;
  2364.                 $roomIndex++;
  2365.             }
  2366.         } else {
  2367.             for ($roomIndex 0$adultIndex $adultsCount && $roomIndex <  $hotelAdultsCount$roomIndex++) {
  2368.                 $room = [
  2369.                     "roomId" => $roomIndex 1,
  2370.                     "rateKey" => !empty($hotelInformation->rateKey[$roomIndex]) ? $hotelInformation->rateKey[$roomIndex] : " ",
  2371.                     "paxes" => []
  2372.                 ];
  2373.                 $maxAdultsPerRoom $adultsPerRoom[$roomIndex];
  2374.                 $maxChildrenPerRoom $childrenPerRoom[$roomIndex];
  2375.                 // Asignar adultos a la habitación
  2376.                 if ($adultIndex $adultsCount) {
  2377.                     $room['paxes'][] = $adults[$adultIndex];
  2378.                     $adultIndex++;
  2379.                 }
  2380.                 // Asignar niños a la habitación
  2381.                 $childrenAssigned 0;
  2382.                 while ($childrenAssigned $maxChildrenPerRoom && $childIndex $childrenCount) {
  2383.                     $room['paxes'][] = $children[$childIndex];
  2384.                     $childIndex++;
  2385.                     $childrenAssigned++;
  2386.                 }
  2387.                 $rooms[] = $room;
  2388.             }
  2389.             // Asignar los adultos restantes a las habitaciones
  2390.             while ($adultIndex $adultsCount) {
  2391.                 foreach ($rooms as $roomIndex => &$room) {
  2392.                     $maxAdultsPerRoom $hotelInformation->adults[$roomIndex];
  2393.                     $adultsInRoom array_filter($room['paxes'], function($pax) {
  2394.                         return $pax['type'] === 'ADT';  // Filtrar solo los pasajeros de tipo 'adult'
  2395.                     });
  2396.                     if ( count($adultsInRoom) < $maxAdultsPerRoom) {
  2397.                         // Agregar un adulto a la habitación
  2398.                         $room['paxes'][] = $adults[$adultIndex];
  2399.                         $adultIndex++;
  2400.                         // Si ya se alcanzó el límite de adultos en la habitación, salir del ciclo
  2401.                         if ( count($adultsInRoom) > $maxAdultsPerRoom) {
  2402.                             break;
  2403.                         }
  2404.                     }
  2405.                 }
  2406.             }
  2407.         }
  2408.        
  2409.         $rs $this->bookingCall($aviaturLogSave,$adults$rooms$transactionId,$session$providerId,$userEmail,$dbState,$paymentData);
  2410.         $aviaturLogSave->logSave($rs'HotelRes''RS');
  2411.         $response json_decode($rs);
  2412.         $response = isset($response->data) ? $response->data $response;
  2413.         $validateStatus json_decode($rs true);
  2414.         // if ($validateStatus["status"] != 200) {
  2415.         //     $message = 'Ha ocurrido un error realizando la reserva del hotel.' . chr(10) . $validateStatus["status"]  . chr(10) . $validateStatus["detail"]; ;
  2416.         //     return $aviaturErrorHandler->errorRedirectNoEmail('/buscar/hoteles', 'Error al reservar', $message . $validateStatus["status"]);
  2417.         // }
  2418.         // if ($validateStatus["status"] != 200) {
  2419.         //     $message = 'Ha ocurrido un error realizando la reserva del hotel.' . chr(10) . $validateStatus["status"]  . chr(10) . $validateStatus["detail"]; ;
  2420.         //     return $aviaturErrorHandler->errorRedirectNoEmail('/buscar/hoteles', 'Error al reservar', $message . $validateStatus["status"]);
  2421.         // }
  2422.         $references = [];
  2423.         $error false;
  2424.         if (isset($response->booking)) {
  2425.             if (is_array($response->booking)) {
  2426.                 foreach ($response->booking as $booking) {
  2427.                     if (isset($booking->status) && $booking->status != 'ERROR') {
  2428.                         $references[] = $booking->reference;
  2429.                     } else {
  2430.                        $error true;
  2431.                     }
  2432.                 }
  2433.                 $reservationId implode('*'$references);
  2434.             } else {
  2435.                 $reservationId = (string) $response->booking->reference;
  2436.             }
  2437.         } else {
  2438.             $error true;
  2439.         }
  2440.         if (!$error) {
  2441.             $session->set($transactionId.'[hotel][reservation]'json_encode($response));
  2442.             $this->generate_email($session$registry,$parameterBag$orderProduct$detailInfo$response$startDate$endDate);
  2443.             
  2444.             $orderProduct->setEmissiondata($reservationId);
  2445.             $orderProduct->setUpdatingdate(new \DateTime());
  2446.             $reservationId2 ""/* (string) $response->Message->OTA_HotelResRS->HotelReservations->HotelReservation->ResGlobalInfo->HotelReservationIDs->HotelReservationID['ResID_Value']*/;  //preguntar cual es esta 
  2447.             $contactNumber is_array($response->booking)
  2448.                 ? ($response->booking[0]->hotel->phone ?? 'No info')
  2449.                 : ($response->booking->hotel->phone ?? 'No info');
  2450.             $company is_array($response->booking)
  2451.                 ? $response->booking[0]->invoiceCompany->company 
  2452.                 $response->booking->invoiceCompany->company;
  2453.             $commentsRes $response->booking->hotel->comments ?? '';
  2454.            /* if (isset($response->Message->OTA_HotelResRS->HotelReservations->HotelReservation->RoomStays->RoomStay->BasicPropertyInfo->ContactNumbers) && isset($response->Message->OTA_HotelResRS->HotelReservations->HotelReservation->RoomStays->RoomStay->BasicPropertyInfo->ContactNumbers->ContactNumber['PhoneNumber'])) {
  2455.                 $contactNumber = (string) $response->Message->OTA_HotelResRS->HotelReservations->HotelReservation->RoomStays->RoomStay->BasicPropertyInfo->ContactNumbers->ContactNumber['PhoneNumber'];
  2456.             }*/
  2457.             $search = ['{order_product_reservation}''{order_product_reservation_2}''{property_name_2}''{contact_number}',  'PN' . (string) $orderProduct->getId(), '{product_notes}'];
  2458.             $replace = [$reservationId$reservationId2, (string) $company$contactNumber$reservationId$commentsRes];
  2459.             $orderXml str_replace($search$replace$orderProduct->getAddProductData());
  2460.             $orderProduct->setAddProductData($orderXml);
  2461.             $orderProduct->setBooking($reservationId);
  2462.             if ($paymentData["payment"] == 'destination') {
  2463.                 $status 'approved_hotel';
  2464.                 $orderProduct->setStatus($status);
  2465.                 $orderProduct->getOrder()->setStatus($status);
  2466.             }
  2467.             $em->persist($orderProduct);
  2468.             $em->flush();
  2469.             if($isFront){
  2470.                 $customerId $customer->id;
  2471.                 $customerEmail $passangersDataArray['email_1_1'];
  2472.                 try {
  2473.                     $responseOrder $aviaturWebService->busWebServiceAmadeus(nullnull$orderXml);
  2474.                 } catch (\Exception $e) {
  2475.                 }
  2476.                 return $this->generateUrl('aviatur_hotel_reservation_success_secureN');
  2477.             } else {
  2478.                 $customerId $customer->getId();
  2479.                 $customerEmail $customer->getEmail();
  2480.             }
  2481.             if (!$isFront) {
  2482.                 $emailContent 'Hotel reservation '.$orderProduct->getEmissiondata().', the product id is: '.$orderProduct->getId().', the customer id is: '.$customerId.'</b> Email customer new DB: <b>'.$customerEmail.'</b>, the info is: '.$orderProduct->getEmail();
  2483.                 $message = (new \Swift_Message())
  2484.                         ->setContentType('text/html')
  2485.                         ->setFrom('noreply@aviatur.com.co')
  2486.                         ->setSubject('Hotel Reservation')
  2487.                         ->setTo(['soptepagelectronic@aviatur.com''soportepagoelectronico@aviatur.com.co'])
  2488.                         ->setCc(['supervisorescallcenter@aviatur.com''hotelesenlineaaviatur@aviatur.com'])
  2489.                         ->setBcc(['notificacionessitioweb@aviatur.com''nicolas.pineros@aviatur.com'])
  2490.                         ->setBody($emailContent);
  2491.                 $mailer->send($message);
  2492.             }
  2493.             // if (!$isFront) {se mueve este tramo de codigo por legivilidad xd 
  2494.             //     return $this->generateUrl('aviatur_hotel_reservation_success_secureN');
  2495.             // } else {
  2496.                 return true;
  2497.             // }
  2498.         } else {
  2499.             $this->generate_email($session$registry,$parameterBag$orderProduct$detailInfotrue$startDate$endDate);
  2500.             $orderProduct->setEmissiondata('No Reservation');
  2501.             $orderProduct->setUpdatingdate(new \DateTime());
  2502.             if ($paymentData["payment"] == 'destination') {
  2503.                 $status 'rejected_hotel';
  2504.                 $orderProduct->setStatus($status);
  2505.                 $orderProduct->getOrder()->setStatus($status);
  2506.             }
  2507.             $em->persist($orderProduct);
  2508.             $em->flush();
  2509.             $message 'Ha ocurrido un error realizando la reserva del hotel, por favor intenta nuevamente o comunícate con nosotros para finalizar tu transacción';
  2510.             if (isset($response->ProviderResults->ProviderResult['Message']) && isset($response->ProviderResults->ProviderResult['Provider'])) {
  2511.                 if ('71' == $response->ProviderResults->ProviderResult['Provider']) {
  2512.                     $message $response->ProviderResults->ProviderResult['Message'];
  2513.                 }
  2514.             }
  2515.             if($providerId == 127 && $response->status == "Error") {
  2516.                 $message $response->message;
  2517.             }
  2518.             if (!$isFront && isset($paymentData["payment"]) && $paymentData["payment"] == 'online') {
  2519.                 $emailContent '
  2520.                 <b>No se realizó la reserva de hotel, tiene pago aprobado.</b><br/>
  2521.                 Info:<br/>
  2522.                 Referer in posaereos: '.$orderProduct->getBooking().'<br/>
  2523.                 The product id is: '.$orderProduct->getId().'<br/>
  2524.                 The customer id is: '.$customer->getId().'<br/></b>
  2525.                 Email customer DB: <b>'.$customer->getEmail().'</b>,<br/>
  2526.                 The info is: '.$orderProduct->getEmail();
  2527.                 $emailMessage = (new \Swift_Message())
  2528.                         ->setContentType('text/html')
  2529.                         ->setFrom('noreply@aviatur.com.co')
  2530.                         ->setSubject('Hotel reservation failed with payment approved')
  2531.                         ->setTo(['soptepagelectronic@aviatur.com''soportepagoelectronico@aviatur.com.co'])
  2532.                         ->setCc(['supervisorescallcenter@aviatur.com''hotelesenlineaaviatur@aviatur.com'])
  2533.                         ->setBcc(['notificacionessitioweb@aviatur.com''nicolas.pineros@aviatur.com'])
  2534.                         ->setBody($emailContent);
  2535.                 $mailer->send($emailMessage);
  2536.                 return false;
  2537.             } elseif( !$isFront && isset($paymentData["payment"]) && $paymentData["payment"] == 'destination'){
  2538.                  
  2539.                 $reservationId;
  2540.                 if($reservationId == ''){
  2541.                 $emailContent '
  2542.                 <b>No se realizó la reserva de hotel con pago en destino.</b><br/>
  2543.                 Info:<br/>
  2544.                 Referer in posaereos: '.$orderProduct->getBooking().'<br/>
  2545.                 The product id is: '.$orderProduct->getId().'<br/>
  2546.                 The customer id is: '.$customer->getId().'<br/></b>
  2547.                 Email customer DB: <b>'.$customer->getEmail().'</b>,<br/>
  2548.                 The info is: '.$orderProduct->getEmail();
  2549.                 }else{
  2550.                 $emailContent '
  2551.                 <b>No se realizó alguna de las reservas de hotel con pago en destino.</b><br/>
  2552.                 Info:<br/>
  2553.                 Reservas realizadas: '.$reservationId.'<br/>
  2554.                 Referer in posaereos: '.$orderProduct->getBooking().'<br/>
  2555.                 The product id is: '.$orderProduct->getId().'<br/>
  2556.                 The customer id is: '.$customer->getId().'<br/></b>
  2557.                 Email customer DB: <b>'.$customer->getEmail().'</b>,<br/>
  2558.                 The info is: '.$orderProduct->getEmail();
  2559.                 }
  2560.                 $emailMessage = (new \Swift_Message())
  2561.                         ->setContentType('text/html')
  2562.                         ->setFrom('noreply@aviatur.com.co')
  2563.                         ->setSubject('Hotel reservation failed with payment approved')
  2564.                         ->setTo(['soptepagelectronic@aviatur.com''soportepagoelectronico@aviatur.com.co'])
  2565.                         ->setCc(['supervisorescallcenter@aviatur.com''hotelesenlineaaviatur@aviatur.com'])
  2566.                         ->setBcc(['notificacionessitioweb@aviatur.com''nicolas.pineros@aviatur.com'])
  2567.                         ->setBody($emailContent);
  2568.                 $mailer->send($emailMessage);
  2569.                 return false;
  2570.             }
  2571.             return $aviaturErrorHandler->errorRedirectNoEmail('/buscar/hoteles''Erro al reservar'$message " Front");
  2572.         }
  2573.     }
  2574.     public function generate_email(SessionInterface $sessionManagerRegistry $registryParameterBagInterface $parameterBag$orderProduct$detailInfo$prepaymentInfo$startDate$endDate)
  2575.     {
  2576.         $transactionIdSessionName $parameterBag->get('transaction_id_session_name');
  2577.         $transactionId $session->get($transactionIdSessionName);
  2578.         $em $registry->getManager();
  2579.         $agency $em->getRepository(\Aviatur\AgencyBundle\Entity\Agency::class)->find($session->get('agencyId'));
  2580.         $agencyData = [
  2581.             'agency_name' => $agency->getName(),
  2582.             'agency_nit' => $agency->getNit(),
  2583.             'agency_phone' => $agency->getPhone(),
  2584.             'agency_email' => $agency->getMailContact(),
  2585.         ];
  2586.         $emailInfos $detailInfo->data->hotelRoomlist->hotels[0];
  2587.         $selectedRateKeys $session->get($transactionId.'[hotel][selected_rooms]');
  2588.         // Inicializar un array vacío para almacenar las tarifas con 'rateKey' como clave
  2589.         $indexedRoomRates = [];
  2590.         // Recorrer las tarifas y almacenar cada una usando 'rateKey' como clave
  2591.         foreach ($detailInfo->data->hotelRoomlist->hotels[0]->rates as $rate) {
  2592.             if (isset($rate->rateKey)) { // Asegúrate de que 'rateKey' existe
  2593.                 $indexedRoomRates[$rate->rateKey] = $rate;
  2594.             }
  2595.         }
  2596.         // Ahora puedes acceder a las tarifas indexadas por 'rateKey'
  2597.         $roomRate $indexedRoomRates;
  2598.         $roomRates = [];
  2599.         // Ejemplo de acceso a un rate específico usando un 'rateKey' de $selectedRateKeys
  2600.         foreach ($selectedRateKeys as $key) {
  2601.             if (isset($roomRate[$key])) {
  2602.                 // Aquí puedes trabajar con $roomRate[$key] para cada 'rateKey' seleccionado
  2603.                 array_push($roomRates, clone $roomRate[$key]);
  2604.             }
  2605.         }
  2606.         $conditionsEx = [
  2607.             'checkInInfo' => isset($emailInfos->checkInInfo) ? $emailInfos->checkInInfo null,
  2608.             'checkOutInfo' =>  isset($emailInfos->checkOutInfo) ? $emailInfos->checkOutInfo null,
  2609.             'policies' =>  isset($emailInfos->policies) ? $emailInfos->policies null,
  2610.             'onSitePaymentMethods' => isset($emailInfos->onSitePaymentMethods) ? $emailInfos->onSitePaymentMethods null,
  2611.             'mandatoryFees'=>  isset($emailInfos->mandatoryFees) ? $emailInfos->mandatoryFees null,
  2612.             'optionalFees'=>  isset($emailInfos->optionalFees) ? $emailInfos->optionalFees null,
  2613.         ];
  2614.         //$emailInfos2 = $detailInfo->Message->OTA_HotelRoomListRS->HotelRoomLists->HotelRoomList->RoomStays->RoomStay->TPA_Extensions->HotelInfo;
  2615.         $i 0;
  2616.         $pictures = [];
  2617.         foreach ($emailInfos->gallery as $picture) {
  2618.             if ($i 3) {
  2619.                 $pictures[] = (string) $picture->url;
  2620.             }
  2621.             ++$i;
  2622.         }
  2623.         if (== sizeof($pictures)) {
  2624.             $domain 'https://'.$agency->getDomain();
  2625.             $pictures[0] = $domain.'/assets/aviatur_assets/img/error/noHotelPicture.jpg';
  2626.         }
  2627.         $cancelPolicies = (string) '';
  2628.         foreach ($roomRates as $index => $room){
  2629.             $cancelPolicies .= '. Habitacion '.($index+1).' ('.$room->description.') Si cancelas despues del : '.$room->cancellationPolicies[0]->from.', se aplicarán gastos del 100%, del valor de la reserva';
  2630.         }
  2631.         $checkinInstructions ='';
  2632.         if($prepaymentInfo != null && $prepaymentInfo == true ){
  2633.             //Genera el markup solo en el ultimo llamado
  2634.             // provider aqui
  2635.             $prov $session->get($transactionId.'[hotel][provider]');
  2636.             $provider $em->getRepository(\Aviatur\MpaBundle\Entity\Provider::class)->findOneById($prov);
  2637.             $provId $provider->getProviderIdentifier();
  2638.             $markups $this->markupService->Markup($agency);
  2639.             foreach ($roomRates as $index => $room) {
  2640.                 $i 0;
  2641.                 $markup false;
  2642.                 $aviaturMarkup 0;
  2643.                 while (!$markup) {
  2644.                     if (($markups['providerOfConfig'][$markups['markups'][$i]['config_hotel_agency_id']] == (string) $provId )) {
  2645.                         if ('N' == $markups['typeOfConfig'][$markups['markups'][$i]['config_hotel_agency_id']]) {
  2646.                             $aviaturMarkup = (float) round($roomRates[$index]->net) * $markups['markups'][$i]['value'] / (100 $markups['markups'][$i]['value']);
  2647.                         } else {
  2648.                             $aviaturMarkup 0;
  2649.                         }
  2650.                         $markup true;
  2651.                     }
  2652.                    ++$i;
  2653.                 }
  2654.                 $roomRates[$index]->net round($roomRates[$index]->net) + round($aviaturMarkup);
  2655.             }
  2656.         }
  2657.         if (isset($prepaymentInfo->booking)) {
  2658.             $bookings is_array($prepaymentInfo->booking) ? $prepaymentInfo->booking : [$prepaymentInfo->booking];
  2659.             foreach ($bookings as $booking) {
  2660.                 if (isset($booking->hotel->comments)) {
  2661.                     if (is_array($booking->hotel->comments)) {
  2662.                         $checkinInstructions .= implode(", "$booking->hotel->comments);
  2663.                     } else {
  2664.                         $checkinInstructions .= $booking->hotel->comments;
  2665.                     }
  2666.                 }
  2667.             }
  2668.         } else {
  2669.             $checkinInstructions '{rateComments}';
  2670.         }
  2671.         $payable = isset($prepaymentInfo->booking
  2672.         ? (is_array($prepaymentInfo->booking)
  2673.             ? $prepaymentInfo->booking[0]->invoiceCompany->company 
  2674.             $prepaymentInfo->booking->invoiceCompany->company)
  2675.         : "{payable}";
  2676.         
  2677.         $journeySummary = [
  2678.             'hotelName' => (string) $emailInfos->name,
  2679.             'stars' => (string) $emailInfos->categoryCode,
  2680.             'startDate' => $startDate,
  2681.             'endDate' => $endDate,
  2682.             'address' => (string) $emailInfos->location->address.', '.(string) $emailInfos->location->destination->name,
  2683.             'phone' => (string) isset($emailInfos->phone) ? $emailInfos->phone :"",
  2684.             'email' => (string) "",//$emailInfos2->Email,
  2685.             'pictures' => $pictures,
  2686.             'latitude' => (string) $emailInfos->location->coordinates->latitude,
  2687.             'longitude' => (string) $emailInfos->location->coordinates->longitude,
  2688.             'cancelPolicies' => $cancelPolicies,
  2689.             'conditions' => $conditionsEx,
  2690.             'checkinInstructions' => $checkinInstructions,
  2691.             'payable' => $payable,
  2692.         ];
  2693.         $emailData = [
  2694.             'agencyData' => $agencyData,
  2695.             'journeySummary' => $journeySummary,
  2696.             'rooms' => $roomRates,
  2697.         ];
  2698.         $orderProduct->setEmail(json_encode($emailData));
  2699.         $em->persist($orderProduct);
  2700.         $em->flush();
  2701.     }
  2702.     public function paymentOutputAction(Request $requestExceptionLog $exceptionLog, \Swift_Mailer $mailerAviaturPixeles $aviaturPixelesPdf $pdfAuthorizationCheckerInterface $authorizationCheckerRouterInterface $routerAviaturEncoder $aviaturEncoderTwigFolder $twigFolderParameterBagInterface $parameterBag,AviaturErrorHandler $aviaturErrorHandler)
  2703.     {
  2704.         $projectDir $parameterBag->get('kernel.project_dir');
  2705.         $transactionIdSessionName $parameterBag->get('transaction_id_session_name');
  2706.         $emailNotification $parameterBag->get('email_notification');
  2707.         $clientFranquice = [];
  2708.         $paymentResume = [];
  2709.         $voucherFile null;
  2710.         $em $this->em;
  2711.         $session $this->session;
  2712.         $agency $this->agency;
  2713.         $UserFront simplexml_load_string ($session->get('front_user'));
  2714.         
  2715.         $transactionId $session->get($transactionIdSessionName);
  2716.         $validations $session->get($transactionId.'[hotel][alertsValidation]');
  2717.         $travellerInfo json_decode($session->get($transactionId.'[hotel][detail_data_hotel]'));
  2718.         if ($session->has($transactionId.'[crossed]'.'[url-hotel]') && !$session->has($transactionId.'[multi]'.'[validation]')) {
  2719.             $urlAvailability $session->get($transactionId.'[crossed]'.'[url-hotel]');
  2720.         } elseif ($session->has($transactionId.'[hotel][availability_url]')) {
  2721.             $urlAvailability $session->get($transactionId.'[hotel][availability_url]');
  2722.         } else {
  2723.             $urlAvailability $session->get($transactionId.'[availability_url]');
  2724.         }
  2725.         $routeParsed parse_url($urlAvailability);
  2726.         if ($session->has($transactionId.'external')) {
  2727.             $routeParsed['path'] = $session->get('routePath');
  2728.         }
  2729.         $availabilityUrl $router->match($routeParsed['path']);
  2730.         $hotelInformation $session->get($transactionId.'[hotel][roomsInfo]');
  2731.         $traveller = [];
  2732.         $traveller['firstName'] = $travellerInfo->PI->first_name_1_1;
  2733.         $traveller['lastName'] = $travellerInfo->PI->last_name_1_1;
  2734.         if (false !== strpos($traveller['firstName'], '*')) {
  2735.             $postDataJson $session->get($transactionId.'[hotel][detail_data_hotel]');
  2736.             $paymentData json_decode($postDataJson);
  2737.             $customer $em->getRepository(\Aviatur\CustomerBundle\Entity\Customer::class)->find($paymentData->BD->id);
  2738.             $traveller['firstName'] = $customer->getFirstname();
  2739.             $traveller['lastName'] = $customer->getLastname();
  2740.         }
  2741.         $orderProductCode $session->get($transactionId.'[hotel][order]');
  2742.         $productId str_replace('PN'''json_decode($orderProductCode)->products);
  2743.         $orderProduct $em->getRepository(\Aviatur\GeneralBundle\Entity\OrderProduct::class)->find($productId);
  2744.         $emailData json_decode($orderProduct->getEmail(), true);
  2745.         if ($session->has($transactionId.'[hotel][reservation]')) {
  2746.             $reservationInfo json_decode($session->get($transactionId.'[hotel][reservation]'));
  2747.             $reservationId '';
  2748.             if (is_array($reservationInfo->booking)) {
  2749.                 $references array_map(function ($booking) {
  2750.                     return $booking->reference;
  2751.                 }, $reservationInfo->booking);
  2752.                 $reservationId = (string) implode('*'$references);
  2753.             } else {
  2754.                 $reservationId = (string) $reservationInfo->booking->reference;
  2755.             }
  2756.             $reservationId2 = (string) "";// $reservationInfo->Message->OTA_HotelResRS->HotelReservations->HotelReservation->ResGlobalInfo->HotelReservationIDs->HotelReservationID['ResID_Value'];
  2757.             $traveller['ReservationID'] = $reservationId;
  2758.             $traveller['HotelReservationID'] = $reservationId2;
  2759.             /*
  2760.             if (('' == $emailData['journeySummary']['phone']) && isset($reservationInfo->Message->OTA_HotelResRS->HotelReservations->HotelReservation->RoomStays->RoomStay->BasicPropertyInfo->ContactNumbers) && isset($reservationInfo->Message->OTA_HotelResRS->HotelReservations->HotelReservation->RoomStays->RoomStay->BasicPropertyInfo->ContactNumbers->ContactNumber['PhoneNumber'])) {
  2761.                 $emailData['journeySummary']['phone'] = (string) $reservationInfo->Message->OTA_HotelResRS->HotelReservations->HotelReservation->RoomStays->RoomStay->BasicPropertyInfo->ContactNumbers->ContactNumber['PhoneNumber'];
  2762.             }*/
  2763.         } else {
  2764.             $traveller['ReservationID'] = null;
  2765.         }
  2766.         $rooms = [];
  2767.         $response json_decode($session->get($transactionId.'[hotel][detail]'));
  2768.         //esto depende de la url
  2769.         /*for ($i = 1; $i <= $availabilityUrl['rooms']; ++$i) {
  2770.             if ('n' == $availabilityUrl['child'.$i]) {
  2771.                 $[$i]['child'] = 0;
  2772.             } else {rooms
  2773.                 $rooms[$i]['child'] = substr_count($availabilityUrl['child'.$i], '-') + 1;
  2774.                 $rooms[$i]['childAges'] = $availabilityUrl['child'.$i];
  2775.             }
  2776.             $rooms[$i]['adult'] = $availabilityUrl['adult'.$i];
  2777.         }*/
  2778.         $postDataJson $session->get($transactionId.'[hotel][detail_data_hotel]');
  2779.         $paymentData json_decode($postDataJson);
  2780.         $opRequestInitial json_decode($aviaturEncoder->AviaturDecode($orderProduct->getPayrequest(), $orderProduct->getPublicKey()));
  2781.         $opRequest $opRequestInitial->multi_transaction_hotel ?? $opRequestInitial;
  2782.         $opResponse json_decode($aviaturEncoder->AviaturDecode($orderProduct->getPayResponse(), $orderProduct->getPublicKey()));
  2783.         if ((null != $opRequest) && (null != $opResponse)) {
  2784.             $customer $em->getRepository(\Aviatur\CustomerBundle\Entity\Customer::class)->find($paymentData->BD->id);
  2785.             if (isset($opResponse->x_description)) {
  2786.                 $paymentResume = [
  2787.                     'transaction_state' => $opResponse->x_response_code,
  2788.                     'ta_transaction_state' => $opResponse->x_ta_response_code,
  2789.                     'id' => $orderProduct->getBooking(),
  2790.                     'id_context' => $opRequest->x_invoice_num,
  2791.                     'total_amount' => $opResponse->x_amount,
  2792.                     'currency' => $opResponse->x_bank_currency,
  2793.                     'amount' => != $opRequest->x_amount_base $opRequest->x_amount_base $opResponse->x_amount,
  2794.                     'iva' => $opRequest->x_tax,
  2795.                     'ip_address' => $opRequest->x_customer_ip,
  2796.                     'bank_name' => $opResponse->x_bank_name,
  2797.                     'cuotas' => $opRequest->x_differed,
  2798.                     'card_num' => '************'.substr($opRequest->x_card_numstrlen($opRequest->x_card_num) - 4),
  2799.                     'reference' => $opResponse->x_transaction_id,
  2800.                     'auth' => $opResponse->x_approval_code,
  2801.                     'transaction_date' => $opResponse->x_transaction_date,
  2802.                     'description' => $opResponse->x_description,
  2803.                     'reason_code' => $opResponse->x_response_reason_code,
  2804.                     'reason_description' => $opResponse->x_response_reason_text,
  2805.                     'client_names' => $opResponse->x_first_name.' '.$opResponse->x_last_name,
  2806.                     'client_email' => $opResponse->x_email,
  2807.                 ];
  2808.             }
  2809.         } else {
  2810.             $customer null;
  2811.             $paymentResume['id'] = $orderProduct->getBooking();
  2812.             $paymentResume['id_context'] = json_decode($orderProductCode)->order."-".json_decode($orderProductCode)->products;
  2813.         }
  2814.         $paymentResume['transaction_state_cyber'] = $opResponse->x_response_code_cyber ?? '1';
  2815.         if (false !== strpos($paymentData->BD->first_name'***')) {
  2816.             $customer $em->getRepository(\Aviatur\CustomerBundle\Entity\Customer::class)->find($paymentData->BD->id);
  2817.             $facturationResume = [
  2818.                 'customer_names' => $customer->getFirstname().' '.$customer->getLastname(),
  2819.                 'customer_address' => $customer->getAddress(),
  2820.                 'customer_doc_num' => $customer->getDocumentnumber(),
  2821.                 'customer_phone' => $customer->getPhone(),
  2822.                 'customer_email' => $customer->getEmail(),
  2823.             ];
  2824.         } else {
  2825.             $facturationResume = [
  2826.                 'customer_names' => $paymentData->BD->first_name.' '.$paymentData->BD->last_name,
  2827.                 'customer_address' => $paymentData->BD->address ?? null,
  2828.                 'customer_doc_num' => $paymentData->BD->doc_num,
  2829.                 'customer_phone' => $paymentData->BD->phone,
  2830.                 'customer_email' => $paymentData->BD->email ?? null,
  2831.             ];
  2832.         }
  2833.         $paymentOnline $session->get($transactionId.'[hotel][paymentOn]');
  2834.         $clientFranquice '';
  2835.         $retryCount = (int) $session->get($transactionId.'[hotel][retry]');
  2836.         if ($session->has($transactionId.'[user]')) {
  2837.             $responseOrder = \simplexml_load_string($session->get($transactionId.'[user]'));
  2838.         } else {
  2839.             $responseOrder null;
  2840.         }
  2841.         $postdata json_decode($session->get($transactionId.'[hotel][detail_data_hotel]'));
  2842.         $passenger $postdata->PI;
  2843.         $em $this->em;
  2844.         //$gender = $em->getRepository(\Aviatur\CustomerBundle\Entity\Gender::class)->findOneByCode($passangersData->gender_1_1);
  2845.         //$country = $em->getRepository(\Aviatur\GeneralBundle\Entity\Country::class)->findOneByIatacode($passangersData->nationality_1_1);
  2846.         $customer $em->getRepository(\Aviatur\CustomerBundle\Entity\Customer::class)->find($postdata->BD->id);
  2847.         //$dbState = (null != $stateDb) ? $stateDb : 2; //pending of payment with same day autocancelation
  2848.         //$passangersData->DocType_1_1 = $passangersData->doc_type_1_1;  quitar el comentario luego
  2849.         if (false !== strpos($passenger->first_name_1_1'***')) {
  2850.             $passenger->first_name_1_1 $customer->getFirstname();
  2851.             $passenger->last_name_1_1 $customer->getLastname();
  2852.             $passenger->phone_1_1 $customer->getPhone();
  2853.             $passenger->email_1_1 $customer->getEmail();
  2854.             $passenger->address_1_1 $customer->getAddress();
  2855.             $passenger->doc_num_1_1 $customer->getDocumentnumber();
  2856.         }
  2857.         $passangersDataArray json_decode(json_encode($passenger), true);
  2858.         $totalGuests $passangersDataArray['person_count_1'];
  2859.         $guest = [];
  2860.         for ($i 1$i <= $totalGuests; ++$i) {
  2861.             $guestData = [];
  2862.             $guestData['first_name'] = $passangersDataArray['first_name_1'.'_'.$i];
  2863.             $guestData['last_name'] = $passangersDataArray['last_name_1'.'_'.$i];
  2864.             $guestData['passanger_type'] = $passangersDataArray['passanger_type_1'.'_'.$i];
  2865.             array_push($guest,$guestData);
  2866.         }
  2867.         
  2868.         $totalsite $session->get($transactionId.'[hotel][chargesData]');
  2869.         $countryCode $session->get($transactionId.'[hotel][countryCode]');
  2870.         $reservation json_decode($session->get($transactionId.'[hotel][reservation]'));
  2871.         $bookRooms =[];
  2872.         if (isset($reservation) and is_array($reservation->booking)) {
  2873.             foreach ($reservation->booking as $book) {
  2874.                 $rateKey $book->hotel->rooms[0]->rates[0]->rateKey;
  2875.                 $reference $book->reference;
  2876.                 if (!isset($bookRooms[$rateKey])) {
  2877.                     $bookRooms[$rateKey] = [];
  2878.                 }
  2879.                 $bookRooms[$rateKey][] = $reference;
  2880.             }
  2881.             $rateKeyCounters = [];
  2882.             foreach ($emailData['rooms'] as &$book) {
  2883.                 $rateKey $book["rateKey"];
  2884.                 if (isset($bookRooms[$rateKey])) {
  2885.                     if (!isset($rateKeyCounters[$rateKey])) {
  2886.                         $rateKeyCounters[$rateKey] = 0;
  2887.                     }
  2888.                     $index $rateKeyCounters[$rateKey];
  2889.                     if (isset($bookRooms[$rateKey][$index])) {
  2890.                         $book["reservation"] = $bookRooms[$rateKey][$index];
  2891.                         $book["passenger"] = $guest[0]["first_name"] . " " $guest[0]["last_name"];
  2892.                         $rateKeyCounters[$rateKey]++;
  2893.                     }
  2894.                 }
  2895.             }
  2896.         }
  2897.         
  2898.         $emailData += [
  2899.             'retry_count' => $retryCount,
  2900.             'paymentResume' => $paymentResume,
  2901.             'currency' => isset($paymentResume['currency']) ? $paymentResume['currency'] : '',
  2902.             'facturationResume' => $facturationResume,
  2903.             'agencyData' => $emailData['agencyData'],
  2904.             'journeySummary' => $emailData['journeySummary'],
  2905.             'transactionID' => $transactionId,
  2906.             'rooms' => $rooms,
  2907.             'traveller' => $traveller,
  2908.             'ratePlan' => implode(" , " ,$hotelInformation->rateKey),
  2909.             'passengers' => $passenger ,
  2910.             'agent' => $responseOrder,
  2911.             'guests' => $guest,
  2912.             'paymentOn' => $paymentOnline == 'online' true false,
  2913.             'totalOnsite' => $totalsite,
  2914.             'countryCode' => $countryCode,
  2915.             'alertsValidation' => $validations,
  2916.             'payment' => $paymentOnline
  2917.         ];
  2918.         //validacion de parametros vacios usando en twig
  2919.         $emailData["paymentResume"]["reason_description"] = isset($emailData["paymentResume"]["reason_description"]) ? $emailData["paymentResume"]["reason_description"] : "";
  2920.         $emailData["paymentResume"]["auth"] = isset($emailData["paymentResume"]["auth"]) ? $emailData["paymentResume"]["auth"] : "";
  2921.         $emailData["paymentResume"]["reason_code"] = isset($emailData["paymentResume"]["reason_code"]) ? $emailData["paymentResume"]["reason_code"] : "";
  2922.         $emailData["paymentResume"]["reference"] = isset($emailData["paymentResume"]["reference"]) ? $emailData["paymentResume"]["reference"] : "";
  2923.         $emailData["paymentResume"]["total_amount"] = isset($emailData["paymentResume"]["total_amount"]) ? $emailData["paymentResume"]["total_amount"] : "";
  2924.         $emailData["paymentResume"]["currency"] = isset($emailData["paymentResume"]["currency"]) ? $emailData["paymentResume"]["currency"] : "";
  2925.         $orderProduct->setEmail(json_encode($emailData));
  2926.         $em->persist($orderProduct);
  2927.         $em->flush();
  2928.         $routeName $request->get('_route');
  2929.         $agencyFolder $twigFolder->twigFlux();
  2930.         $viewParams $emailData;
  2931.         $viewParams['status'] = $orderProduct->getStatus();
  2932.         $route $router->match(str_replace($request->getSchemeAndHttpHost(), ''$request->getUri()));
  2933.         $isMulti false !== strpos($route['_route'], 'multi') ? true false;
  2934.         // if ("aviatur_hotel_reservation_success_secureN" == $routeName) {
  2935.             $bccMails = [$agency->getMailvouchers()];
  2936.             $emissionData $orderProduct->getEmissiondata();
  2937.             $emailData json_decode($orderProduct->getEmail(), true);
  2938.             $viewParams $emailData;
  2939.             $emailData['status'] = $orderProduct->getStatus();
  2940.             $viewParams['status'] = $orderProduct->getStatus();
  2941.             $bccMails[] = 'supervisorescallcenter@aviatur.com';
  2942.             if (isset($UserFront->CORREO_ELECTRONICO)) {
  2943.                 $setTo = (String) $UserFront->CORREO_ELECTRONICO;
  2944.             } elseif (('No Reservation' != $emissionData) && ('' != $emissionData) && (null != $emissionData)) {
  2945.                 $setTo = (null == $customer) ? null $customer->getEmail();
  2946.             } else {
  2947.                 $clientEmail $emailData["facturationResume"]['customer_email'];
  2948.                 $setTo $clientEmail;
  2949.             }
  2950.             if (isset($UserFront->CORREO_ELECTRONICO)) {
  2951.                 $bccMails null;
  2952.                 $bccMails[] = 'notificacionessitioweb@aviatur.com';
  2953.             } elseif ($session->has('whitemark')) {
  2954.                 $whitemarkMail $session->get('whitemarkMail');
  2955.                 if (!empty($whitemarkMail) && !$session->has('operatorId')) {
  2956.                     $bccMails[] = $whitemarkMail;
  2957.                     $bccMails[] = 'negocioselectronicos@aviatur.com.co';
  2958.                     $bccMails[] = 'soportepagoelectronico@aviatur.com.co';
  2959.                     $bccMails[] = 'soptepagelectronic@aviatur.com';
  2960.                 }
  2961.             }
  2962.         if ($emailData['status'] != 'rejected_hotel') {
  2963.             if ($session->has('operatorId')) {
  2964.                 $urlResume $twigFolder->twigExists('@AviaturTwig/' $agencyFolder '/Hotel/Default/email_rest.html.twig');
  2965.             } else {
  2966.                 $urlResume $twigFolder->twigExists('@AviaturTwig/' $agencyFolder '/Hotel/Default/email.html.twig');
  2967.             }
  2968.             if ($session->has('operatorId')) {
  2969.                 $setSubject 'Gracias su reserva se ha generado con exito';
  2970.             } else {
  2971.                 $setSubject 'Gracias por su compra';
  2972.             }
  2973.             // dd($viewParams , $urlResume);
  2974.             try {
  2975.                 $message = (new \Swift_Message())
  2976.                     ->setContentType('text/html')
  2977.                     ->setFrom($session->get('emailNoReply'))
  2978.                     ->setTo($setTo)
  2979.                     ->setBcc($bccMails)
  2980.                     ->setSubject($session->get('agencyShortName') . ' - ' $setSubject)
  2981.                     ->setBody(
  2982.                         $this->renderView($urlResume$viewParams)
  2983.                     );
  2984.             } catch (\Exception $e) {
  2985.                 $bccMails[] = 'lida.lugo@aviatur.com';
  2986.                 $emissionData $orderProduct->getEmissiondata();
  2987.                 if (('No Reservation' != $emissionData) && ('' != $emissionData) && (null != $emissionData)) {
  2988.                     $setTo = (null == $customer) ? null $customer->getEmail();
  2989.                 } else {
  2990.                     $setTo 'soptepagelectronic@aviatur.com';
  2991.                 }
  2992.                 $setSubject 'Gracias por su compra';
  2993.                 $message = (new \Swift_Message())
  2994.                     ->setContentType('text/html')
  2995.                     ->setFrom($session->get('emailNoReply'))
  2996.                     ->setTo($setTo)
  2997.                     ->setBcc($bccMails)
  2998.                     ->setSubject($session->get('agencyShortName') . ' - ' $setSubject)
  2999.                     ->setBody(
  3000.                         $this->renderView($urlResume$emailData)
  3001.                     );
  3002.             }
  3003.             try {
  3004.                 if (!$isMulti) {
  3005.                     $mailer->send($message);
  3006.                 }
  3007.                 // $session->set($transactionId . '[emission_email]', 'emailed');
  3008.             } catch (Exception $ex) {
  3009.                 $exceptionLog->log(
  3010.                     var_dump($message),
  3011.                     $ex
  3012.                 );
  3013.             }
  3014.             // }
  3015.             if (isset($paymentResume['transaction_state']) && == $paymentResume['transaction_state'] && $session->has($transactionId '[crossed]' '[url-hotel]')) {
  3016.                 $session->remove($transactionId '[hotel]' '[retry]');
  3017.                 $session->remove($transactionId '[hotel]' '[prepayment_check]');
  3018.                 $session->remove($transactionId '[hotel]' '[order]');
  3019.             }
  3020.             if ($isMulti) {
  3021.                 return new JsonResponse([
  3022.                     'emailData' => $emailData,
  3023.                     'viewParams' => $viewParams,
  3024.                     'emissionData' => $emissionData
  3025.                 ]);
  3026.             }
  3027.             $urlResume $this->generateUrl('thank_you_page_success_secure', ['on' => $orderProduct->getOrder(), 'pn' => 'PN' $productId]);
  3028.             return $this->redirect($urlResume);
  3029.         }else{
  3030.             $message 'La reserva no pudo ser realizada';
  3031.             $linkWA 'https://api.whatsapp.com/send?phone=5713821616&text=';
  3032.             //$urlAvailability = $session->get($transactionId . '[availability_url]');
  3033.             return $this->redirect($aviaturErrorHandler->errorRedirectNoEmail($this->generateUrl('aviatur_search_hotels', []), 'Error al generar la reserva'$message ,''$linkWA ));
  3034.         }
  3035.     }
  3036.     /**
  3037.      * validateCancellationDates()
  3038.      * Valida si las fechas de cancelación de las reservas son anteriores a la fecha actual.
  3039.      * 
  3040.      * Esta función recibe un array de reservas (Calcula internamente la fecha actual). Recorre cada reserva
  3041.      * y valida si la fecha de cancelación es anterior a la fecha actual. Si alguna fecha de cancelación
  3042.      * no es válida, la asigna como null. Si todas las fechas de cancelación son válidas, las conserva.
  3043.      * 
  3044.      * @param array &$info - Un array de listado de habitaciones (modificable), donde cada reserva contiene una fecha de cancelación.
  3045.      * @return array &$info - Retorna el mismo array modificado en caso de aplicarse.
  3046.      * @author Ing. David Rincón
  3047.      * @version 1.0
  3048.      * @date 2025-01-24
  3049.      * @mail david.rincon@aviatur.com
  3050.      */
  3051.     private function validateCancellationDates(&$info){
  3052.         $todayDate date('Y-m-d');
  3053.         $totalIndex sizeof($info['rates']);
  3054.         for($ii 0$ii $totalIndex$ii++){
  3055.             if(isset($info['rates'][$ii]['cancellationPolicies'])){
  3056.                 if(sizeof($info['rates'][$ii]['cancellationPolicies']) > 0){
  3057.                     if(isset($info['rates'][$ii]['cancellationPolicies'][0]['from'])){
  3058.                         $cancelDate substr($info['rates'][$ii]['cancellationPolicies'][0]['from'], 010);
  3059.                         if($cancelDate $todayDate){
  3060.                             $info['rates'][$ii]['cancellationPolicies'][0]['from'] = null;
  3061.                         }
  3062.                     }
  3063.                 }
  3064.             }
  3065.         }
  3066.     }
  3067.     /**
  3068.      * quotationAction()
  3069.      * Esta función maneja la acción de cotización de hoteles. Recibe una solicitud HTTP, procesa los datos
  3070.      * necesarios para realizar la cotización y retorna una respuesta en formato JSON con los resultados de la cotización.
  3071.      * @param Request $request - La solicitud HTTP que contiene los datos necesarios para realizar la cotización.
  3072.      * @param AviaturLogSave $aviaturLogSave - Guardado de logs.
  3073.      * @param AviaturWebService $aviaturWebService - Empleo de las webservices locales de Aviatur.
  3074.      * @param AviaturErrorHandler $aviaturErrorHandler - Manejo local de los errores.
  3075.      * @param \Swift_Mailer $mailer - Envío de correos.
  3076.      * @param ExceptionLog $exceptionLog - Manejo del log de excepciones.
  3077.      * @param Pdf $pdf - Empleo del PDF.
  3078.      * @param RouterInterface $router - Funciones para enrutamiento
  3079.      * @param TwigFolder $twigFolder - Manejo de las carpetas de plantillas
  3080.      * @param ManagerRegistry $registry - Manejo de los objetos de Bases de Datos
  3081.      * @param ParameterBagInterface $parameterBag - Manejo de los parámetros de configuración
  3082.      * @return AbstractController - Retorna una plantilla informativa
  3083.      * @throws \Exception - Lanza una excepción si ocurre un error durante el proceso de cotización.
  3084.      * @author Ing. David Rincón <david.rincon@aviatur.com> 2025-01-29
  3085.      * @version 1.0
  3086.      */
  3087.     public function quotationAction(Request $fullRequestAviaturLogSave $aviaturLogSaveAviaturWebService $aviaturWebServiceAviaturErrorHandler $aviaturErrorHandler, \Swift_Mailer $mailerExceptionLog $exceptionLogPdf $pdfRouterInterface $routerTwigFolder $twigFolderManagerRegistry $registryParameterBagInterface $parameterBag ,QuotationUtils $QuotationUtils)
  3088.     {
  3089.         $projectDir $parameterBag->get('kernel.project_dir');
  3090.         $transactionIdSessionName $parameterBag->get('transaction_id_session_name');
  3091.         $codImg null;
  3092.         $session $this->session;
  3093.         $agency $this->agency;
  3094.         $transactionId $session->get($transactionIdSessionName);
  3095.         $prepaymentInfo = \simplexml_load_string($session->get($transactionId '[hotel][prepayment]'));
  3096.         $agencyFolder $twigFolder->twigFlux();
  3097.         $response json_decode($session->get($transactionId '[hotel][detail]'));
  3098.         $additionalUserFront simplexml_load_string($session->get('front_user_additionals'));
  3099.         $datosAgente simplexml_load_string($session->get('front_user'));
  3100.         /* Si no hay información de prepayment, se debe crear una de apoyo */
  3101.         if(false === $prepaymentInfo){
  3102.             $prepaymentInfo = [];
  3103.             /* Fecha y Hora de Gasto, tomada del timestamp (se debe formatear) */
  3104.             $timeStamp $this->getObjectsTimeStamp($response->data->auditData->timestamp);
  3105.             $prepaymentInfo['Message']['OTA_HotelResRS']['HotelReservations']['RoomStays']['TPA_Extensions']['CancellationPolicy']['FechaEntradaGasto'] = $timeStamp['date'];
  3106.             $prepaymentInfo['Message']['OTA_HotelResRS']['HotelReservations']['RoomStays']['TPA_Extensions']['CancellationPolicy']['HoraFechaEntradaGasto'] = $timeStamp['time'];
  3107.             $prepaymentInfo['Message']['HotelReservations']['HotelReservation']['RoomStays']['RoomStay']['BasicPropertyInfo']['HotelCode'] = $response->data->hotelRoomlist->hotels[0]->code;
  3108.             $prepaymentInfo['Message']['HotelReservations']['HotelReservation']['RoomStays']['RoomStay']['Total']['CurrencyCode'] = $response->data->hotelRoomlist->hotels[0]->currency;
  3109.             $prepaymentInfo['Message']['HotelReservations']['HotelReservation']['RoomStays']['RoomStay']['TimeSpan']['End'] = $response->data->hotelRoomlist->stay->checkOut;
  3110.             $prepaymentInfo['Message']['HotelReservations']['HotelReservation']['RoomStays']['RoomStay']['TimeSpan']['Start'] = $response->data->hotelRoomlist->stay->checkIn;
  3111.             $prepaymentInfo['Message']['HotelReservations']['HotelReservation']['RoomStays']['RoomStay']['BasicPropertyInfo']['HotelName'] = $response->data->hotelRoomlist->hotels[0]->name;
  3112.             $prepaymentInfo['ProviderResults']['ProviderResult']['Provider'] = trim(explode(","$response->data->auditData->providers)[0]);
  3113.         }
  3114.         $detailHotelRaw $response->data->hotelRoomlist->hotels[0];
  3115.         $locationHotel $response->data->hotelRoomlist->hotels[0]->location->coordinates;  /* Información estándar y general */
  3116.         $dateIn strtotime((string) $response->data->hotelRoomlist->stay->checkIn);
  3117.         $dateOut strtotime((string) $response->data->hotelRoomlist->stay->checkOut);
  3118.         if ($session->has($transactionId '[crossed]' '[url-hotel]')) {
  3119.             $urlAvailability $session->get($transactionId '[crossed]' '[url-hotel]');
  3120.         } elseif ($session->has($transactionId '[hotel][availability_url]')) {
  3121.             $urlAvailability $session->get($transactionId '[hotel][availability_url]');
  3122.         } else {
  3123.             $urlAvailability $session->get($transactionId '[availability_url]');
  3124.         }
  3125.         $rooms = [];
  3126.         if(!is_null($urlAvailability)){
  3127.             $routeParsed parse_url($urlAvailability);
  3128.             $availabilityUrl $router->match($routeParsed['path']);
  3129.             for ($i 1$i <= $availabilityUrl['rooms']; ++$i) {
  3130.                 $adult $availabilityUrl['adult' $i];
  3131.                 $child = [];
  3132.                 if ('n' != $availabilityUrl['child' $i]) {
  3133.                     $child sizeof(explode('-'$availabilityUrl['child' $i]));
  3134.                 }
  3135.                 $rooms[$i] = ['adult' => $adult'child' => $child];
  3136.             }
  3137.         } else {
  3138.             /* Otra alternativa por medio del contenido de la URL de la disponibilidad pero como un valor de formulario virtual */
  3139.             $availabilityUrl $fullRequest->request->get('urlAvailability');
  3140.             $arrayAvailabilityUrl explode('/'$availabilityUrl);
  3141.             foreach ($arrayAvailabilityUrl as $segmentAvailabilityUrl) {
  3142.                 if(strpos($segmentAvailabilityUrl'room=') !== false){
  3143.                     $arrayPeople explode('&'$segmentAvailabilityUrl);
  3144.                     $agesChild str_replace('children='''$arrayPeople[2]);
  3145.                     if($agesChild == "n"){
  3146.                         $listChild = [];
  3147.                     } else {
  3148.                         $listChild explode('+'$agesChild);
  3149.                     }
  3150.                     $agesAdult str_replace('adults='''$arrayPeople[1]);
  3151.                     $ordRoom str_replace('room='''$arrayPeople[0]);
  3152.                     $rooms[$ordRoom] = ['adult' => $agesAdult'child' => $listChild];
  3153.                 }
  3154.             }
  3155.         }
  3156.         $codImg $QuotationUtils->curlImg($session'_front');
  3157.         /* Aquí se deben comenzar a definir cálculos que se asocian a las opciones seleccionadas */
  3158.         $selectedRates $fullRequest->request->get('selectedRates');
  3159.         $arraySelectedRates explode(','$selectedRates);
  3160.         $selectedRatesLength sizeof($arraySelectedRates);
  3161.         $totalMinRate 0;
  3162.         $totalAdults 0;
  3163.         $totalChildren 0;
  3164.         $totalRooms 0;
  3165.         for($ii 0$ii $selectedRatesLength$ii++){
  3166.             $totalMinRate += (double)$detailHotelRaw->rates[$arraySelectedRates[$ii]]->net;
  3167.             $totalAdults += (int)$detailHotelRaw->rates[$arraySelectedRates[$ii]]->adults;
  3168.             $totalChildren += (int)$detailHotelRaw->rates[$arraySelectedRates[$ii]]->children;
  3169.             $totalRooms += (int)$detailHotelRaw->rates[$arraySelectedRates[$ii]]->rooms;
  3170.         }
  3171.         $totalMinRate round($totalMinRate);
  3172.         /* Objeto con datos básicos de referencia */
  3173.         $addressObject = new \stdClass();
  3174.         $addressObject->CityName $detailHotelRaw->location->destination->name;
  3175.         $addressObject->HotelName $detailHotelRaw->name;
  3176.         /* Vamos a revisar los datos del asesor, en caso de que se puedan obtener directo de la consulta por endpoint, sino solo se dejan nombre y correo desde XML, y otros datos por defecto de la agencia asociada */
  3177.         $userNameAgent $datosAgente->NOMBRE_AGENTE;
  3178.         $mailAgent $datosAgente->CORREO_ELECTRONICO;
  3179.         $phoneAgent $additionalUserFront->TELEFONO_SUCURSAL ?? $session->get('agencyDataInfo')['agency_phone'];
  3180.         $addressAgent $additionalUserFront->DIRECCION_SUCURSAL ?? $datosAgente->NOMBRE_OFICINA_PERTENECE;
  3181.         $selectedRates $fullRequest->request->get('selectedRates');
  3182.         $arraySelectedRates explode(','$selectedRates);
  3183.         $arraySelectedRoomsInformation = array();
  3184.         foreach($arraySelectedRates as $selectedRate){
  3185.             $arraySelectedRoomsInformation[] = json_decode($session->get($transactionId.'[hotel][detail]'))->data->hotelRoomlist->hotels[0]->rates[$selectedRate];
  3186.         }
  3187.         $detailHotel = [
  3188.             'dateIn' => $dateIn,
  3189.             'dateOut' => $dateOut,
  3190.             'roomInformation' => $rooms,
  3191.             'dateInStr' => (string) $response->data->hotelRoomlist->stay->checkIn,
  3192.             'dateOutStr' => (string) $response->data->hotelRoomlist->stay->checkOut,
  3193.             'nights' => floor(($dateOut $dateIn) / (24 60 60)),
  3194.             'adults' => (string) $totalAdults,
  3195.             'children' => (string) $totalChildren,
  3196.             'rooms' => (string) $totalRooms,
  3197.             'timeSpan' => $response->data->auditData->timestamp,
  3198.             'basicInfos' => $addressObject,
  3199.             'total' => $totalMinRate,
  3200.             'category' => $detailHotelRaw->categoryCode,
  3201.             'description' => (string) $detailHotelRaw->description,
  3202.             'email' => ""/* No hay campo con la información del correo */
  3203.             'services' => $detailHotelRaw->services,
  3204.             'photos' => $detailHotelRaw->gallery[0],
  3205.             'agentName' => ucwords(strtolower(($additionalUserFront->NOMBRE_USUARIO ?? '') . ' ' . ($additionalUserFront->APELLIDOS_USUARIO ?? '') ?: $datosAgente->NOMBRE_AGENTE)),
  3206.             'agentMail' => $mailAgent,
  3207.             'agentPhone' => $phoneAgent,
  3208.             'agentAddress' => $addressAgent,
  3209.             'prepaymentsInfo' => $prepaymentInfo,
  3210.             'namesClient' => $fullRequest->request->get('quotationName'),
  3211.             'lastnamesClient' => $fullRequest->request->get('quotationLastname'),
  3212.             'emailClient' => $fullRequest->request->get('quotationEmail'),
  3213.             'priceTotalQuotation' => $fullRequest->request->get('quotationPriceTotal'),
  3214.             'priceCurrency' => $fullRequest->request->get('quotationCurrency'),
  3215.             'typeRoom' => $fullRequest->request->get('typeRoom'),
  3216.             'desctiptionRoom' => $arraySelectedRoomsInformation[0]->boardName,
  3217.             'infoTerms' => $fullRequest->request->get('quotationTerms'),
  3218.             'infoComments' => $fullRequest->request->get('quotationComments'),
  3219.             'longitude' => $locationHotel->longitude,
  3220.             'latitude' => $locationHotel->latitude,
  3221.             'codImg' => $codImg,
  3222.             'selectedRoomsInformation' => $arraySelectedRoomsInformation,
  3223.             'agentCity' => $datosAgente->CIUDAD
  3224.         ];
  3225.         $html $twigFolder->twigExists('@AviaturTwig/' $agencyFolder '/Hotel/Hotel/quotation_rest.html.twig');
  3226.         $namefilepdf 'Aviatur_cotizacion_hotel_' $transactionId '.pdf';
  3227.         $voucherHotelFile $projectDir '/app/quotationLogs/hotelQuotation/' $namefilepdf;
  3228.         if (!file_exists($voucherHotelFile)) {
  3229.             $pdf->setOption('page-size''Letter');
  3230.             $pdf->setOption('margin-top'15);
  3231.             $pdf->setOption('margin-right'0);
  3232.             $pdf->setOption('margin-bottom'15);
  3233.             $pdf->setOption('margin-left'0);
  3234.             $pdf->setOption('orientation''portrait');
  3235.             $pdf->setOption('enable-javascript'true);
  3236.             $pdf->setOption('no-stop-slow-scripts'true);
  3237.             $pdf->setOption('no-background'false);
  3238.             $pdf->setOption('lowquality'false);
  3239.             $pdf->setOption('encoding''utf-8');
  3240.             $pdf->setOption('images'true);
  3241.             $pdf->setOption('dpi'300);
  3242.             $pdf->setOption('enable-external-links'true);
  3243.             $pdf->setOption('enable-internal-links'true);
  3244.             $pdf->generateFromHtml($this->renderView($html$detailHotel), $voucherHotelFile);
  3245.         }    
  3246.         $nameProduct str_replace(["cotizacion""/""check-conditions" "rest"], ""$fullRequest->getPathInfo());
  3247.         $QuotationUtils->sendQuotation($nameProduct,$voucherHotelFile$mailer$session$twigFolder$codImg$fullRequest,$parameterBag $aviaturWebService ,$pdf $exceptionLog);
  3248.         if (file_exists($voucherHotelFile)) {
  3249.             unlink($voucherHotelFile);
  3250.         } 
  3251.         $this->saveInformationCGS($aviaturLogSave$aviaturWebService$aviaturErrorHandler$registry$detailHotel$fullRequest$additionalUserFront$agency);
  3252.         /* Se devolverá a la nueva plantilla indicando que se visualice el correo para ver el PDF adjunto */
  3253.         return $this->render('@AviaturTwig/' $agencyFolder '/Hotel/Default/resume_quotation.html.twig', ['nameProduct' => $nameProduct,]);        
  3254.     }
  3255.     /**
  3256.      * saveInformationCGS()
  3257.      * Guarda la información de CGS (Customer Global Service).
  3258.      * Esta función recibe la información de la cotización de un hotel y la guarda en el sistema CGS.
  3259.      * @param AviaturLogSave $aviaturLogSave - Guardado de logs.
  3260.      * @param AviaturWebService $aviaturWebService - Empleo de las webservices locales de Aviatur.
  3261.      * @param AviaturErrorHandler $aviaturErrorHandler - Manejo local de los errores.
  3262.      * @param ManagerRegistry $registry - Manejo de los objetos de Bases de Datos
  3263.      * @param array $data - Información de la cotización del hotel.
  3264.      * @param Customer $customer - Información del cliente.
  3265.      * @param Agency $agency - Información de la agencia.
  3266.      * @author Ing. David Rincón <david.rincon@aviatur.com> 2025-01-30
  3267.      * @version 1.0
  3268.      */
  3269.     public function saveInformationCGS(AviaturLogSave $aviaturLogSaveAviaturWebService $aviaturWebServiceAviaturErrorHandler $aviaturErrorHandlerManagerRegistry $registry$data$dataRequest$customer$agency)
  3270.     {
  3271.         $parametersLogin $registry->getRepository(\Aviatur\GeneralBundle\Entity\Parameter::class)->findParameters($agency'aviatur_service_login_cgs');
  3272.         $urlLoginCGS $parametersLogin[0]['value'];
  3273.         $parametersProduct $registry->getRepository(\Aviatur\GeneralBundle\Entity\Parameter::class)->findParameters($agency'aviatur_service_hotel_cgs');
  3274.         $urlAddProductHotel $parametersProduct[0]['value'];
  3275.         /*
  3276.          * get token api autentication
  3277.          */
  3278.         $userLoginCGS $aviaturWebService->encryptUser(trim(strtolower($customer->CODIGO_USUARIO)), 'AviaturCGSMTK');
  3279.         $jsonReq json_encode(['username' => $userLoginCGS]);
  3280.         //print_r(json_encode($data)); die;
  3281.         $curl curl_init();
  3282.         curl_setopt_array($curl, [
  3283.             CURLOPT_URL => $urlLoginCGS,
  3284.             CURLOPT_RETURNTRANSFER => true,
  3285.             CURLOPT_SSL_VERIFYPEER => false,
  3286.             CURLOPT_ENCODING => '',
  3287.             CURLOPT_MAXREDIRS => 10,
  3288.             CURLOPT_TIMEOUT => 0,
  3289.             CURLOPT_FOLLOWLOCATION => true,
  3290.             CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  3291.             CURLOPT_CUSTOMREQUEST => 'POST',
  3292.             CURLOPT_POSTFIELDS => $jsonReq,
  3293.             CURLOPT_HTTPHEADER => [
  3294.                 'Content-Type: application/json',
  3295.             ],
  3296.         ]);
  3297.         $response curl_exec($curl);
  3298.         $httpcode curl_getinfo($curlCURLINFO_HTTP_CODE);
  3299.         curl_close($curl);
  3300.         if (200 != $httpcode) {
  3301.             $aviaturLogSave->logSave('HTTPCODE: ' $httpcode ' Error usuario: ' strtolower($customer->CODIGO_USUARIO), 'CGS''CGSHOTEL_ERRORLOGIN');
  3302.             $aviaturLogSave->logSave(print_r($responsetrue), 'CGS''responseHotelCGS');
  3303.             return $this->redirect($aviaturErrorHandler->errorRedirectNoEmail('/buscar/hoteles''Error Login''Error Login'));
  3304.         } else {
  3305.             $tokenInfoApiQuotation json_decode($response);
  3306.             $tokenApiQuotation $tokenInfoApiQuotation->TOKEN;
  3307.         }
  3308.         /**
  3309.          * Begin API data send.
  3310.          */
  3311.         $ages '';
  3312.         $roms '';
  3313.         $separate '';
  3314.         for ($i 1$i <= (is_countable($data['roomInformation']) ? count($data['roomInformation']) : 0); ++$i) {
  3315.             $ages '';
  3316.             for ($a 0$a < (is_countable($data['roomInformation'][$i]['child']) ? count($data['roomInformation'][$i]['child']) : 0); ++$a) {
  3317.                 if (!== $a) {
  3318.                     $ages .= ',' '"' $data['roomInformation'][$i]['child'][$a] . '"';
  3319.                 } else {
  3320.                     $ages .= '"' $data['roomInformation'][$i]['child'][$a] . '"';
  3321.                 }
  3322.             }
  3323.             if (!== $i) {
  3324.                 $separate ',';
  3325.             } else {
  3326.                 $separate '';
  3327.             }
  3328.             $roms .= $separate '{
  3329.                 "adultOcupancy": ' $data['roomInformation'][$i]['adult'] . ',
  3330.                 "availCount": null,
  3331.                 "boardCode": null,
  3332.                 "boardName": null,
  3333.                 "boardShortName": null,
  3334.                 "boardType": null,
  3335.                 "cancellationPolicies": [
  3336.                     {
  3337.                         "amount": null,
  3338.                         "dateFrom": "' . (isset($data['prepaymentsInfo']['Message']['OTA_HotelResRS']['HotelReservations']['RoomStays']['TPA_Extensions']['CancellationPolicy']['FechaEntradaGasto']) ? $data['prepaymentsInfo']['Message']['OTA_HotelResRS']['HotelReservations']['RoomStays']['TPA_Extensions']['CancellationPolicy']['FechaEntradaGasto'] : '') . '",
  3339.                         "respaldoFechaSalida": "' $data['dateOutStr'] . '",
  3340.                         "time": "' . (isset($data['prepaymentsInfo']['Message']['OTA_HotelResRS']['HotelReservations']['RoomStays']['TPA_Extensions']['CancellationPolicy']['HoraFechaEntradaGasto']) ? $data['prepaymentsInfo']['Message']['OTA_HotelResRS']['HotelReservations']['RoomStays']['TPA_Extensions']['CancellationPolicy']['HoraFechaEntradaGasto'] : '') . '"
  3341.                     }
  3342.                 ],
  3343.                 "childAges": [
  3344.                     ' $ages '
  3345.                 ],
  3346.                 "childOcupancy": ' . (is_countable($data['roomInformation'][$i]['child']) ? count($data['roomInformation'][$i]['child']) : 0) . ',
  3347.                 "onRequest": null,
  3348.                 "price": null,
  3349.                 "roomCharacteristic": null,
  3350.                 "roomCharacteristicCode": null,
  3351.                 "roomCode": null,
  3352.                 "roomCount": null,
  3353.                 "roomType": null,
  3354.                 "shrui": null
  3355.             }';
  3356.         }
  3357.         $data_send '{
  3358.                         "customer":{
  3359.                             "billingInformations":[
  3360.                                 {
  3361.                                     "active": true,
  3362.                                     "agencyContact": "string",
  3363.                                     "city": "' $data['basicInfos']->CityName '",
  3364.                                     "colony": "string",
  3365.                                     "country": "string",
  3366.                                     "dateCreated": "2020-05-21T23:20:30.441Z",
  3367.                                     "email": "string",
  3368.                                     "extNumber": "string",
  3369.                                     "id": 0,
  3370.                                     "intNumber": "string",
  3371.                                     "lastUpdated": "2020-05-21T23:20:30.441Z",
  3372.                                     "official": "string",
  3373.                                     "phone": {
  3374.                                     "active": true,
  3375.                                     "dateCreated": "2020-05-21T23:20:30.441Z",
  3376.                                     "id": 0,
  3377.                                     "lastUpdated": "2020-05-21T23:20:30.441Z",
  3378.                                     "number": "string",
  3379.                                     "type": "string",
  3380.                                     "version": 0
  3381.                                 },
  3382.                                 "postalCode": "string",
  3383.                                 "representation": "string",
  3384.                                 "rfc": "string",
  3385.                                 "state": "string",
  3386.                                 "status": "string",
  3387.                                 "street": "string",
  3388.                                 "taxRegime": "string",
  3389.                                 "version": 0
  3390.                             ],
  3391.                             "birthDate":"true",
  3392.                             "city": "' $data['basicInfos']->CityName '",
  3393.                             "dateCreated":"0001-01-01T00:00:00",
  3394.                             "dateOfBirth":"0001-01-01T00:00:00",
  3395.                             "document":null,
  3396.                             "emails":[
  3397.                                 {
  3398.                                     "active": true,
  3399.                                     "dateCreated": "' date('Y-m-d') . '",
  3400.                                     "emailAddress": "' $data['emailClient'] . '",
  3401.                                     "id": 0,
  3402.                                     "lastUpdated": "' date('Y-m-d') . '",
  3403.                                     "version": 0
  3404.                                 }
  3405.                             ],
  3406.                             "exchangeRateInformations":null,
  3407.                             "firstName":"' $data['namesClient'] . '",
  3408.                             "fullName":"' $data['namesClient'] . ' ' $data['lastnamesClient'] . '",
  3409.                             "gender":null,
  3410.                             "id":null,
  3411.                             "idAccount":null,
  3412.                             "idIntelisis":null,
  3413.                             "idUserOwner":null,
  3414.                             "identify":null,
  3415.                             "interestsForExpo":null,
  3416.                             "lastName":"' $data['lastnamesClient'] . '",
  3417.                             "lastUpdated":"0001-01-01T00:00:00",
  3418.                             "mothersName":null,
  3419.                             "phones":[
  3420.                                 {
  3421.                                     "active":false,
  3422.                                     "dateCreated":"0001-01-01T00:00:00",
  3423.                                     "id":0,
  3424.                                     "lastUpdated":"0001-01-01T00:00:00",
  3425.                                     "number":null,
  3426.                                     "type":null,
  3427.                                     "version":0
  3428.                                 }
  3429.                             ],
  3430.                             "typeContact":null
  3431.                         },
  3432.                         "quote":null,
  3433.                         "selectedProduct":{
  3434.                             "associatedProductIndex":null,
  3435.                             "category": "' $data['category'] . '",
  3436.                                 "complementProductList": null,
  3437.                             "deleteInfo":null,
  3438.                             "description":"' $data['description'] . '",
  3439.                             "packageName":"' $data['basicInfos']->HotelName '",
  3440.                             "discount":null,
  3441.                             "emit":false,
  3442.                             "fareData":{
  3443.                                 "aditionalFee":0.0,
  3444.                                 "airpotService":null,
  3445.                                 "baseFare":' str_replace('.'''$data['priceTotalQuotation']) . ',
  3446.                                 "cO":0.0,
  3447.                                 "commission":0.0,
  3448.                                 "commissionPercentage":0.0,
  3449.                                 "complements":null,
  3450.                                 "currency":{
  3451.                                     "type":"' $data['priceCurrency'] . '"
  3452.                                 },
  3453.                                 "equivFare":0.0,
  3454.                                 "iva":0.0,
  3455.                                 "otherDebit":null,
  3456.                                 "otherTax":null,
  3457.                                 "price":' str_replace('.'''$data['priceTotalQuotation']) . ',
  3458.                                 "providerPrice":0.0,
  3459.                                 "qSe":0.0,
  3460.                                 "qSeIva":0.0,
  3461.                                 "qse":null,
  3462.                                 "revenue":0.0,
  3463.                                 "serviceCharge":0.0,
  3464.                                 "sureCancel":null,
  3465.                                 "tA":0.0,
  3466.                                 "taIva":0.0,
  3467.                                 "tax":0.0,
  3468.                                 "total":' str_replace('.'''$data['priceTotalQuotation']) . ',
  3469.                                 "yQ":0.0,
  3470.                                 "yQiva":0.0
  3471.                             },
  3472.                             "foodPlan":null,
  3473.                             "hotelDetail":{
  3474.                                 "nightCount": ' $data['nights'] . ',
  3475.                                 "roomCount": ' $data['rooms'] . '
  3476.                             },
  3477.                             "index":null,
  3478.                             "itinerary": {
  3479.                                 "availToken": null,
  3480.                                 "category": null,
  3481.                                 "cdChain": null,
  3482.                                 "code": "' . (isset($data['prepaymentsInfo']['Message']['HotelReservations']['HotelReservation']['RoomStays']['RoomStay']['BasicPropertyInfo']['HotelCode']) ? $data['prepaymentsInfo']['Message']['HotelReservations']['HotelReservation']['RoomStays']['RoomStay']['BasicPropertyInfo']['HotelCode'] : '') . '",
  3483.                                 "codeCurrency": "' . (isset($data['prepaymentsInfo']['Message']['HotelReservations']['HotelReservation']['RoomStays']['RoomStay']['Total']['CurrencyCode']) ? $data['prepaymentsInfo']['Message']['HotelReservations']['HotelReservation']['RoomStays']['RoomStay']['Total']['CurrencyCode'] : '') . '",
  3484.                                 "contractIncommingOffice": null,
  3485.                                 "contractName": null,
  3486.                                 "dateFrom": "' . (isset($data['prepaymentsInfo']['Message']['HotelReservations']['HotelReservation']['RoomStays']['RoomStay']['TimeSpan']['End']) ? $data['prepaymentsInfo']['Message']['HotelReservations']['HotelReservation']['RoomStays']['RoomStay']['TimeSpan']['End'] : '') . '",
  3487.                                 "dateTo": "' . (isset($data['prepaymentsInfo']['Message']['HotelReservations']['HotelReservation']['RoomStays']['RoomStay']['TimeSpan']['Start']) ? $data['prepaymentsInfo']['Message']['HotelReservations']['HotelReservation']['RoomStays']['RoomStay']['TimeSpan']['Start'] : '') . '",
  3488.                                 "echoToken": null,
  3489.                                 "issueFrom": null,
  3490.                                 "issueTo": null,
  3491.                                 "location": [],
  3492.                                 "nbChain": null,
  3493.                                 "nuStars": "' $data['category'] . '",
  3494.                                 "pointOfInterest": null,
  3495.                                 "promo": null,
  3496.                                 "rooms": [
  3497.                                     ' $roms '
  3498.                                 ],
  3499.                                 "topSale": null,
  3500.                                 "txDescription": "' $data['description'] . '",
  3501.                                 "txDestination": "' $data['basicInfos']->CityName '",
  3502.                                 "txImage": "' . (isset($data['photos']->url) ? $data['photos']->url '') . '",
  3503.                                 "txIssues": null,
  3504.                                 "txName": "' . (isset($data['prepaymentsInfo']['Message']['HotelReservations']['HotelReservation']['RoomStays']['RoomStay']['BasicPropertyInfo']['HotelName']) ? $data['prepaymentsInfo']['Message']['HotelReservations']['HotelReservation']['RoomStays']['RoomStay']['BasicPropertyInfo']['HotelName'] : '') . '",
  3505.                                 "txPrice": "' $data['priceTotalQuotation'] . '",
  3506.                                 "txZone": null
  3507.                             },
  3508.                             "locatorList":[],
  3509.                             "passengerDataList":[
  3510.                                 {
  3511.                                     "age":"0",
  3512.                                     "birthday":"1899-12-31T19:00:00-05:00",
  3513.                                     "fareData":{
  3514.                                         "aditionalFee":0.0,
  3515.                                         "airpotService":null,
  3516.                                         "baseFare":0.0,
  3517.                                         "cO":0.0,
  3518.                                         "commission":0.0,
  3519.                                         "commissionPercentage":0.0,
  3520.                                         "complements":null,
  3521.                                         "currency":null,
  3522.                                         "equivFare":0.0,
  3523.                                         "iva":0.0,
  3524.                                         "otherDebit":null,
  3525.                                         "otherTax":null,
  3526.                                         "price":0.0,
  3527.                                         "providerPrice":0.0,
  3528.                                         "qSe":0.0,
  3529.                                         "qSeIva":0.0,
  3530.                                         "qse":null,
  3531.                                         "revenue":0.0,
  3532.                                         "serviceCharge":0.0,
  3533.                                         "sureCancel":null,
  3534.                                         "tA":0.0,
  3535.                                         "taIva":0.0,
  3536.                                         "tax":0.0,
  3537.                                         "total": ' str_replace('.'''$data['priceTotalQuotation']) . ',
  3538.                                         "yQ":0.0,
  3539.                                         "yQiva":0.0
  3540.                                     },
  3541.                                     "gender":"",
  3542.                                     "id":"",
  3543.                                     "lastName":"",
  3544.                                     "mail":"",
  3545.                                     "mothersName":"",
  3546.                                     "name":"",
  3547.                                     "passengerCode":{
  3548.                                         "accountCode":"",
  3549.                                         "promo":false,
  3550.                                         "realType":"ADT",
  3551.                                         "type":"ADT"
  3552.                                     },
  3553.                                     "passengerContact":null,
  3554.                                     "passengerInsuranceInfo":null,
  3555.                                     "phone":null
  3556.                                 }
  3557.                             ],
  3558.                             "priority":"",
  3559.                             "productType":{
  3560.                                 "description":"Hotel",
  3561.                                 "typeProduct":"Hotel"
  3562.                             },
  3563.                             "quoteHost":null,
  3564.                             "reservationInfo":null,
  3565.                             "reserveProductLogList":null,
  3566.                             "roomType": null,
  3567.                             "route":{
  3568.                                 "arrivalDate": "' $data['dateOutStr'] . '",
  3569.                                 "arrivalDateString": "' $data['dateOutStr'] . '",
  3570.                                 "arrivalDescription": "' $data['basicInfos']->CityName '",
  3571.                                 "arrivalIATA": null,
  3572.                                 "departureDate": "' $data['dateInStr'] . '",
  3573.                                 "departureDateString": "' $data['dateInStr'] . '",
  3574.                                 "departureDescription": null,
  3575.                                 "departureIATA": null,
  3576.                                 "destination": "' $data['basicInfos']->CityName '",
  3577.                                 "flightTime": null,
  3578.                                 "origin": null,
  3579.                                 "providerCode": null,
  3580.                                 "subRoutes": null
  3581.                             },
  3582.                             "savedPassenger":false,
  3583.                             "searchHost":null,
  3584.                             "selected":false,
  3585.                             "serviceProvider": {
  3586.                                 "code": "' . (isset($data['prepaymentsInfo']['ProviderResults']['ProviderResult']['Provider']) ? $data['prepaymentsInfo']['ProviderResults']['ProviderResult']['Provider'] : '') . '"
  3587.                             },
  3588.                             "stayTime":null
  3589.                         },
  3590.                         "quote": {"channel":"B2C WEB"}
  3591.                     }';
  3592.         //API URL
  3593.         $url $urlAddProductHotel;
  3594.         //create a new cURL resource
  3595.         $ch curl_init($url);
  3596.         //setup request to send json via POST
  3597.         $payload $data_send;
  3598.         //attach encoded JSON string to the POST fields
  3599.         curl_setopt($chCURLOPT_POSTFIELDS$payload);
  3600.         //set the content type to application/json
  3601.         curl_setopt($chCURLOPT_HTTPHEADER, [
  3602.             'accept: application/json',
  3603.             'authorization: Bearer ' $tokenApiQuotation,
  3604.             'content-type: application/json',
  3605.         ]);
  3606.         curl_setopt($chCURLOPT_CUSTOMREQUEST'POST');
  3607.         curl_setopt($chCURLOPT_SSL_VERIFYPEERfalse);
  3608.         curl_setopt($chCURLOPT_MAXREDIRS10);
  3609.         curl_setopt($chCURLOPT_TIMEOUT0);
  3610.         curl_setopt($chCURLOPT_FOLLOWLOCATIONtrue);
  3611.         curl_setopt($chCURLOPT_HTTP_VERSIONCURL_HTTP_VERSION_1_1);
  3612.         //return response instead of outputting
  3613.         curl_setopt($chCURLOPT_RETURNTRANSFERtrue);
  3614.         //execute the POST request
  3615.         $result curl_exec($ch);
  3616.         //close CURL resource
  3617.         curl_close($ch);
  3618.         /*
  3619.          * End API data send
  3620.          */
  3621.     }
  3622.     /**
  3623.      * Obtiene la marca de tiempo (timestamp) de los objetos.
  3624.      * 
  3625.      * Esta función recibe un array de objetos y retorna un array con las marcas de tiempo (timestamps) de cada objeto.
  3626.      * 
  3627.      * @param datetime $timeStamp - Un array de objetos que contienen una fecha y hora en formato m/d/Y HH:ii:ss.
  3628.      * @return array - Retorna un array con las marcas de tiempo (timestamps) de cada objeto.
  3629.      * @author Ing. David Rincón <david.rincon@aviatur.com> 2025-02-03
  3630.      * @version 1.0
  3631.      */
  3632.     private function getObjectsTimeStamp($timeStamp){
  3633.         $originalTimeStamp = (String)$timeStamp;
  3634.         $arrayTimeStamp explode(" "$originalTimeStamp);
  3635.         $originalDate $arrayTimeStamp[0];
  3636.         $arrayOriginalDate explode("/"$originalDate);
  3637.         if(sizeof($arrayOriginalDate) <= 1){
  3638.             $arrayOriginalDate explode("-"$originalDate);
  3639.         }
  3640.         $newDate $arrayOriginalDate[2] . "-" str_pad($arrayOriginalDate[0], 2"0"STR_PAD_LEFT) . "-" str_pad($arrayOriginalDate[1], 2"0"STR_PAD_LEFT); /* Formato YYYY-mm-dd, antes venía en m-d-Y */
  3641.         $originalTime $arrayTimeStamp[1];
  3642.         if(isset($arrayTimeStamp[2])){
  3643.             $arrayOriginalTime explode(":"$originalTime);
  3644.             if($arrayTimeStamp[2] == "AM" && (int)$arrayOriginalTime[0] == 12){
  3645.                 $arrayOriginalTime[0] = 0;
  3646.             } elseif($arrayTimeStamp[2] == "PM" && (int)$arrayOriginalTime[0] < 12){
  3647.                 $arrayOriginalTime[0] += 12;
  3648.             }
  3649.         } else {
  3650.             $arrayOriginalTime explode(":"$originalTime);
  3651.             $arrayOriginalTime[2] = substr($arrayOriginalTime[2], 02);    /* Para remover milésimas de segundo */
  3652.         }
  3653.         $newTime str_pad($arrayOriginalTime[0], 2"0"STR_PAD_LEFT) . ":" str_pad($arrayOriginalTime[1], 2"0"STR_PAD_LEFT) . ":" str_pad($arrayOriginalTime[2], 2"0"STR_PAD_LEFT); /* Formato HH:ii:ss */
  3654.         $formattedTimeStamp $newDate " " $newTime;
  3655.         $newTimeStamp strtotime($formattedTimeStamp);
  3656.         $date date('Y-m-d'$newTimeStamp);
  3657.         $time date('H:i:s'$newTimeStamp);
  3658.         return ['date' => $date'time' => $time];
  3659.     }
  3660.     
  3661.     /**
  3662.      * @Route("/build-url/{iata}/{checkIn}+{checkOut}/{adults}+{children}", name="redirect_to_coordinates")
  3663.      */
  3664.     public function redirectToCoordinates(
  3665.         string $iata,
  3666.         string $checkIn,
  3667.         string $checkOut,
  3668.         string $adults,
  3669.         string $children
  3670.     ): Response {
  3671.         $homeRedirect $this->redirect('/hoteles');
  3672.         try {
  3673.             $iata strtoupper($iata);
  3674.             $city null;
  3675.             $countryCode null;
  3676.             $latitude null;
  3677.             $longitude null;
  3678.             // 1. Buscar en search_cities
  3679.             $searchCity $this->em->getRepository(SearchCities::class)->findOneBy(['iata' => $iata]);
  3680.             if ($searchCity) {
  3681.                 $city $searchCity->getCity();
  3682.                 $countryCode strtolower($searchCity->getCountryCode());
  3683.                 // Coordenadas desde JSON
  3684.                 $coordinates json_decode($searchCity->getCoordinates(), true);
  3685.                 if ($coordinates && isset($coordinates['latitude'], $coordinates['longitude'])) {
  3686.                     $latitude $coordinates['latitude'];
  3687.                     $longitude $coordinates['longitude'];
  3688.                 }
  3689.             } else {
  3690.                 // 2. Buscar en search_airports como fallback
  3691.                 $searchAirport $this->em->getRepository(SearchAirports::class)->findOneBy(['iata' => $iata]);
  3692.                 if (!$searchAirport) {
  3693.                     throw new \InvalidArgumentException("No se encontró ciudad ni aeropuerto para el IATA {$iata}");
  3694.                 }
  3695.                 $city $searchAirport->getCity();
  3696.                 $countryCode strtolower($searchAirport->getCountryCode());
  3697.                 // No usamos coordenadas aquí porque no están disponibles en SearchAirports
  3698.                 throw new \RuntimeException("El aeropuerto {$iata} no tiene coordenadas disponibles.");
  3699.             }
  3700.             if (!$latitude || !$longitude) {
  3701.                 throw new \RuntimeException("No se pudieron obtener las coordenadas para el IATA {$iata}");
  3702.             }
  3703.             // Construir destino
  3704.             $destinationLabel sprintf('%s(%s)'$city$countryCode);
  3705.             $destinationLabelEncoded str_replace(['%28''%29'], ['('')'], rawurlencode($destinationLabel));
  3706.             $coordinateString "{$latitude},{$longitude}";
  3707.             $destinationUrl sprintf(
  3708.                 '/hoteles/avail/%s/%s/%s+%s/room=1&adults=%s&children=%s/online',
  3709.                 $destinationLabelEncoded,
  3710.                 $coordinateString,
  3711.                 $checkIn,
  3712.                 $checkOut,
  3713.                 $adults,
  3714.                 $children
  3715.             );
  3716.             return $this->redirect($destinationUrl);
  3717.         } catch (\Throwable $e) {
  3718.             return $homeRedirect;
  3719.         }
  3720.     }
  3721. }