<?php
namespace Aviatur\HotelBundle\Controller;
use Aviatur\AgencyBundle\Entity\Agency;
use Aviatur\GeneralBundle\Services\AviaturAthServices;
use Aviatur\GeneralBundle\Services\AviaturRestService;
use Aviatur\GeneralBundle\Services\PointRedemptionService;
use GuzzleHttp\Promise\Utils;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Aviatur\GeneralBundle\Entity\Metatransaction;
use Aviatur\GeneralBundle\Services\AviaturErrorHandler;
use Aviatur\HotelBundle\Models\HotelModel;
use FOS\UserBundle\Model\UserInterface;
use Doctrine\Persistence\ManagerRegistry;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Cookie;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\Routing\RouterInterface;
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
use Knp\Snappy\Pdf;
use Aviatur\GeneralBundle\Entity\FormUserInfo;
use Exception;
use Symfony\Component\Security\Core\Exception\AccountStatusException;
use FOS\UserBundle\Security\LoginManager;
use Aviatur\GeneralBundle\Controller\OrderController;
use Aviatur\AdminBundle\Services\QseCommission;
use Aviatur\TwigBundle\Services\TwigFolder;
use Aviatur\PaymentBundle\Services\TokenizerService;
use Aviatur\PaymentBundle\Services\CustomerMethodPaymentService;
use Aviatur\PaymentBundle\Controller\P2PController;
use Aviatur\GeneralBundle\Services\PayoutExtraService;
use Aviatur\CustomerBundle\Services\ValidateSanctionsRenewal;
use Aviatur\GeneralBundle\Services\AviaturMailer;
use Aviatur\GeneralBundle\Services\QuotationUtils;
use Aviatur\HotelBundle\Services\UrlService;
use Aviatur\HotelBundle\Services\DateValidatorService;
use Aviatur\HotelBundle\Services\MarkupService;
use Aviatur\GeneralBundle\Services\AviaturPixeles;
use Aviatur\GeneralBundle\Services\AviaturWebService;
use Aviatur\GeneralBundle\Services\ExceptionLog;
use Aviatur\GeneralBundle\Services\AviaturLogSave;
use Aviatur\GeneralBundle\Services\AviaturEncoder;
use Aviatur\MultiBundle\Services\MultiHotelDiscount;
// use Aviatur\GeneralBundle\Services\AviaturUpdateBestprices;
// use Aviatur\HotelBundle\Services\SearchHotelCookie;
use Aviatur\SearchBundle\Controller\TravelDestinationController;
use Aviatur\SearchBundle\Entity\TravelDestination;
use Aviatur\SearchBundle\Entity\SearchCities;
use Aviatur\SearchBundle\Entity\TravelCountry;
use Aviatur\SearchBundle\Entity\SearchAirports;
use GuzzleHttp\Client;
use GuzzleHttp\Promise;
use Symfony\Component\HttpFoundation\StreamedResponse;
use Aviatur\CustomerBundle\Models\CustomerModel;
use Symfony\Component\HttpFoundation\RequestStack;
class HotelRestController extends AbstractController
{
/**
* @var \Doctrine\Persistence\ObjectManager
*/
protected $em;
/**
* @var SessionInterface
*/
protected $session;
/**
* @var Agency|object|null
*/
protected $agency;
/**
* @var DateValidatorService
*/
protected $dateValidator;
/**
* @var AviaturRestService
*/
protected $aviaturRestService;
/**
* @var MarkupService
*/
protected $markupService;
/**
* @var PointRedemptionService
*/
protected $redemptionService;
/**
* @var AviaturAthServices
*/
protected $aviaturAthServices;
/**
* @var bool
*/
protected $isAval;
/**
* @param ManagerRegistry $registry
* @param SessionInterface $session
* @param AviaturRestService $aviaturRestService
* @param DateValidatorService $dateValidator
* @param MarkupService $markupService
* @param PointRedemptionService $redemptionService
*/
public function __construct(ManagerRegistry $registry, SessionInterface $session, AviaturRestService $aviaturRestService, DateValidatorService $dateValidator, MarkupService $markupService, PointRedemptionService $redemptionService, AviaturAthServices $athServices, RequestStack $requestStack)
{
$this->em = $registry->getManager();
$this->registry = $registry;
$this->session = $session;
$this->dateValidator = $dateValidator;
$this->agency = $this->em->getRepository(Agency::class)->find($session->get('agencyId'));
$this->aviaturRestService = $aviaturRestService;
$this->markupService = $markupService;
$this->redemptionService = $redemptionService;
$this->aviaturAthServices = $athServices;
$this->requestStack = $requestStack;
// Validación para agencia Aval
if ($this->agency->getAssetsFolder() == 'aval') {
$this->isAval = true;
} else {
$this->isAval = false;
}
}
public function searchAction()
{
return $this->redirect($this->generateUrl('aviatur_search_hotels',[]));
}
/**
* Metodo encargado de consultar la disponibilidad hotelera, pendiente de conectar con el Qs
* Instancia la clase hotel, obtiene el dummy de RQ de disponibilidad, Asigna el id del provedor de hoteles
* Envia al metodo encargado de la logica de consumo de los servicios.
*
* @return Response
*/
public function availAction(
Request $fullRequest,
TwigFolder $twigFolder,
ParameterBagInterface $parameterBag,
AviaturWebService $aviaturWebService,
AviaturErrorHandler $aviaturErrorHandler,
UrlService $urlService,
QseCommission $Qse,
$location,
$latitude,
$longitude,
$rooms,
$checkin,
$checkout,
$online
) {
$destinationExist = $this->em->getRepository(TravelDestination::class)->findOneBy([
'latitude' => $latitude,
'longitude' => $longitude
]);
if(!is_null($destinationExist)){
$resultPopularity = TravelDestinationController::updateTravelDestinationPopularity($this->em, $destinationExist->getId());
}
$agency = $this->agency;
$agencyFolder = $twigFolder->twigFlux();
$session = $this->session;
$isFront = $session->has('operatorId');
$transactionIdSessionName = $parameterBag->get('transaction_id_session_name');
$roomsParam = explode('/room=', ltrim($rooms, '/')); // Elimina '/' inicial y divide en 'rooms'
$parsedRooms = [];
$radius = "25";
$radius = "25";
$session->set('[hotel]destinationtext', $location);
// Procesar los parámetros de cada habitación
foreach ($roomsParam as $room) {
parse_str($room, $roomParams);
// Procesar el parámetro `children`
$childrenAges = [];
if (isset($roomParams['children']) && $roomParams['children'] !== 'n') {
$childrenAges = array_map('intval', explode(' ', $roomParams['children']));
}
// Agregar los datos procesados de la habitación
$parsedRooms[] = [
'room' => isset($roomParams['room']) ? (int) $roomParams['room'] : null,
'adults' => isset($roomParams['adults']) ? (int) $roomParams['adults'] : 0,
'childrenAges' => $childrenAges,
];
}
// Crear la estructura de habitaciones en base a los parámetros de adultos y niños
$roomslist = [];
foreach ($parsedRooms as $index => $room) {
$adults = $room['adults'];
$childrenAges = $room['childrenAges'];
// Definir las edades de los pasajeros
$passengerAges = array_fill(0, $adults, 30); // 30 años para adultos
if (!empty($childrenAges)) {
$passengerAges = array_merge($passengerAges, $childrenAges); // Agregar las edades de los niños
}
// Añadir la habitación solo si tiene pasajeros (adultos o niños)
if ($adults > 0 || !empty($childrenAges)) {
$roomslist[] = [
"index" => $index + 1, // Índice de la habitación (1-based)
"passengerAges" => $passengerAges
];
}
}
$urlAvailability = $twigFolder->twigExists('@AviaturTwig/' . $agencyFolder . '/Hotel/Default/results.html.twig');
$AvailabilityArray = [
'cityName' => 'cityName',
'countryCode' => 'countryCode',
'StartDate' => $checkin,
'EndDate' => $checkout,
'Rooms' => count($parsedRooms),
'Destination' => $location,
'Nights' => (strtotime($checkin) - strtotime($checkout)) / 86400,
];
$services = [];
$countAdults = 0;
$countChildren = 0;
// Recorrer las habitaciones procesadas
foreach ($parsedRooms as $index => $room) {
// Obtener número de adultos
$roomAdults = $room['adults'] ?? 0;
// Obtener edades de niños (ya procesadas como un array en `$parsedRooms`)
$childAges = $room['childrenAges'] ?? [];
$childrenCount = count($childAges);
// Sumar al total general de adultos y niños
$countAdults += $roomAdults;
$countChildren += $childrenCount;
// Crear la estructura de servicios para cada habitación
$services[] = [
'adults' => $roomAdults,
'children' => $childAges,
];
// Crear la estructura de disponibilidad para cada habitación
$AvailabilityArray[$index + 1] = [
'Children' => $childrenCount,
'Adults' => $roomAdults,
];
}
$validationResult = $this->dateValidator->validateDates($checkin, $checkout);
if (!empty($validationResult)) {
// Modal Error dispo el mismo dia
// Contadores para adultos y niños
$totalRooms = 0;
$totalChildren = 0;
$totalAdults = 0;
foreach ($roomslist as $room) {
foreach ($room['passengerAges'] as $age) {
if ($age >= 18) {
$totalAdults++;
} else {
$totalChildren++;
}
}
$totalRooms++;
}
// Decodificar la URL
$fullUrl = urldecode($fullRequest->getUri());
// Extraer los componentes
$urlParts = explode('/', $fullUrl);
// dd($urlParts)
// Obtener ubicación
$location = urldecode($urlParts[5]);
// Extraer fechas
$dates = $urlParts[7];
list($date1, $date2) = explode(' ', $dates);
// Parsear parámetros de habitaciones
parse_str($urlParts[6], $params);
$locationRedirection = trim(explode(',', $location)[0]);
$whatsappUrl = "https://wa.me/send?phone=5713821616&text=" . urlencode(
"Hola, quiero hacer una reserva en " . $locationRedirection .
" del " . $date1 . " al " . $date2 .
", con (" . $totalRooms . ") habitaciones, " . $totalAdults . " adulto(s), " . $totalChildren . " niño(s)" .
". 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!"
);
return $this->redirect($aviaturErrorHandler->errorRedirectNoEmail($this->generateUrl('aviatur_search_hotels', []), 'Recomendación Automática', $validationResult['redirectText'],'', $whatsappUrl ));
}
// Agregar el total de adultos y niños al final del array de disponibilidad
$AvailabilityArray['Children'] = $countChildren;
$AvailabilityArray['Adults'] = $countAdults;
$dateIn = strtotime($checkin);
$dateOut = strtotime($checkout);
$safeUrl = 'https://'.$agency->getDomainsecure();
$makeLogin = true;
if ($fullRequest->query->has('transactionMulti')) {
$transactionId = base64_decode($fullRequest->query->get('transactionMulti'));
$session->set($transactionIdSessionName, $transactionId);
$makeLogin = false;
$requestMultiHotelDiscountInfo = true;
}
if ($online == 'destination') {
$hoteltype = 'HotelCollect';
} else {
$hoteltype = 'HotelOnly';
}
// if ($session->get($session->get($transactionIdSessionName).'[crossed]'.'[url-hotel]')) { $makeLogin = false; }
if ($makeLogin) {
$transactionIdResponse = $aviaturWebService->loginService('SERVICIO_MPT', 'dummy|http://www.aviatur.com.co/dummy/', []);
if ('error' == $transactionIdResponse || is_array($transactionIdResponse)) {
$aviaturErrorHandler->errorRedirect('', 'Error MPA', 'No se creo Login!');
// return new Response('Estamos experimentando dificultades técnicas en este momento.');
return (new JsonResponse())->setData([
'error' => true,
'message' => 'Estamos experimentando dificultades técnicas en este momento.',
]);
}
$transactionId = (string) $transactionIdResponse;
$session->set($transactionIdSessionName, $transactionId);
}
preg_match('/\((.*?)\)/', $location, $matches);
$countryCode = isset($matches) ? $matches[1] : null;
// Verificamos si $locationLower contiene "cartagena" y si $countryCode es "co".
if (strpos(strtolower($location), 'cartagena') !== false && strtolower($countryCode) === 'co') {
$radius = "60";
}
$jsonHotelAvailrq = $urlService->jsonHotelAvailability($checkin, $checkout, 'CUN', strtoupper($countryCode) , $latitude, $longitude, $radius, $roomslist, $transactionId, $hoteltype);
$jsonHotelAvail = [
'HotelRq' => $jsonHotelAvailrq,
'payment' => $online,
];
$ajaxParameters = base64_encode(json_encode($jsonHotelAvail));
$processQse = $Qse->getQse($fullRequest->attributes->get('providerid'));
$QSE = $session->get($transactionId.'[QSE]');
$configHotelAgency = $this->em->getRepository(\Aviatur\HotelBundle\Entity\ConfigHotelAgency::class)->findProviderForHotelsWithAgency($agency,'destination');
$destination = !empty($configHotelAgency) ? true : false;
$response = $this->render($urlAvailability, [
'ajaxParameters' => $ajaxParameters,
'availableArrayHotel' => $AvailabilityArray,
'inlineEngine' => true,
'safeUrl' => $safeUrl,
'cityName' => $location,
'checkin' => date('c', $dateIn),
'roomsconsulturl' => $rooms,
'checkout' => date('c', $dateOut),
'countrycode' => 'country='.$countryCode,
'online' => $online,
'isFront' => $isFront,
'isAval' => $this->isAval,
'destination' => $destination,
'QSE' => isset($QSE) ? $QSE : null,
// 'cookieLastSearch' => '',
// 'availabilityHasDiscount' => $requestMultiHotelDiscountInfo,
// 'urlDescription' => $urlDescription,
// 'pointRedemption' => [],
// 'pixel_info' => $pixelInfo,
]);
// $response->headers->setCookie(new Cookie('_availability_array[hotel]', base64_encode(json_encode($cookieArray)), (time() + 3600 * 24 * 7), '/'));
return $response;
}
/**
* asyncFetchHotelProviders
*
* @param mixed $twigFolder
* @return json
*/
public function asyncFetchHotelProviders(Request $request): JsonResponse{
try {
$postData = json_decode($request->getContent(), true);
$jsonHotelRequest = json_decode(base64_decode($postData["data"]), true);
$agency = $this->agency;
$configsHotelAgency = $this->em
->getRepository(\Aviatur\HotelBundle\Entity\ConfigHotelAgency::class)
->findProviderForHotelsWithAgency($agency,$jsonHotelRequest['payment']);
$providers = [];
foreach ($configsHotelAgency as $config) {
$provider = $config->getProvider();
array_push($providers, (Object)[
"id" => $provider->getId(),
"providerId" => $provider->getProvideridentifier(),
"name" => $provider->getName()
]);
}
$response = (Object)[
"providers" => $providers,
"status" => (Object)[
"message" => "success",
"code" => 200
]
];
return new JsonResponse(
$response,
Response::HTTP_OK,
);
} catch (\Throwable $th) {
// TODOSG Comment errors
$response = array(
"providers" => [],
"status" => (Object)[
"error" => $th->getMessage(). " - " . $th->getLine(),
"message" => "Error: En la búsqueda de proveedores de hoteles",
"code" => 503
]
);
return new JsonResponse(
$response,
Response::HTTP_SERVICE_UNAVAILABLE,
);
}
}
/**
* fetchHotelProvider
*
* @param string $url
* @param mixed $jsonHotelRequestInfo
* @param string $payload
* @return mixed $response
*/
public function fetchHotelProvider($url, $jsonHotelRequestInfo, $payload = 'GetAvail'){
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => $url.$payload,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_SSL_VERIFYHOST => false,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => json_encode($jsonHotelRequestInfo),
CURLOPT_HTTPHEADER => array(
'Content-Type: application/json'
),
));
$filterEntities = [];
$filterEntities['provider'] = [];
$response = curl_exec($curl);
curl_close($curl);
return $response;
}
/**
* asyncFetchAvailabilityRest
*
* @param Request $request
* @param AviaturLogSave $aviaturLogSave
* @return JsonResponse
*/
public function asyncFetchAvailabilityRest(Request $request, AviaturLogSave $aviaturLogSave): JsonResponse{
$data = [];
try {
$postData = json_decode($request->getContent(), true);
$agency = $this->agency;
$agencyId = $this->agency->getId();
$jsonHotelRequestInfos = json_decode(base64_decode($postData["ajaxHotelParameters"]), true);
$jsonHotelRequestInfo = $jsonHotelRequestInfos['HotelRq'];
$transactionId = $jsonHotelRequestInfo['TransactionIdentifier'];
$requestedProvider = $postData["providerId"];
$configsHotelAgency = $this->em
->getRepository(\Aviatur\HotelBundle\Entity\ConfigHotelAgency::class)
->findProviderByAgencyAndProvider($agencyId, $requestedProvider);
if(empty($configsHotelAgency)){
throw new Exception("Hotel provider bad request");
}
$url = $configsHotelAgency->getWsUrl();
$hotelProviderEntity = $configsHotelAgency->getProvider();
$hotelProviderIdentifier = $hotelProviderEntity->getProviderIdentifier();
$hotelProviderName = $hotelProviderEntity->getName();
// Save provider-request
$aviaturLogSave->logSave(json_encode($jsonHotelRequestInfo), 'HotelAvail', $hotelProviderIdentifier . '_RQ', $transactionId);
$providerResponse = self::fetchHotelProvider($url, $jsonHotelRequestInfo);
$data = json_decode($providerResponse, true);
if(
empty($data) ||
json_last_error() !== JSON_ERROR_NONE ||
!is_array($data)
){
throw new Exception("Sin respuesta del proveedor $hotelProviderName");
}
// Save provider-response
$aviaturLogSave->logSave(json_encode($data), 'HotelAvail', $hotelProviderIdentifier . '_RS', $transactionId);
if(isset($data['status']) && $data['status'] != 200){
//data.filterEntities.provider[126]
throw new Exception("Ocurrió un error en la respuesta del proveedor $hotelProviderName");
}
$markups = $this->markupService->Markup($agency);
$destinationCode = $data['data']['hotels']['hotels'][0]['location']['destination']['code'];
$hotelBlacklistArray = [];
$hotelBlacklist = $this->em->getRepository(\Aviatur\HotelBundle\Entity\HotelHomologation::class)->findBySearchCities([null]);
// should be filtered by the adapters
foreach ($hotelBlacklist as $hotelBlacklisted) {
foreach (json_decode($hotelBlacklisted->getHotelcodes()) as $hotelCode) {
$hotelBlacklistArray[$hotelCode] = $hotelBlacklisted->getPreferredcode();
}
}
foreach ($data['data']['hotels']['hotels'] as &$hotels) {
$hotelIdentifier = (string) $hotelProviderIdentifier . '-' . (string) $hotels['code'];
$hotels['Show'] = '1';
if (array_key_exists($hotelIdentifier, $hotelBlacklistArray) && ($hotelBlacklistArray[$hotelIdentifier] != $hotelIdentifier)) {
$hotels['Show'] = '0';
} else {
$hotelEntity = $this->em->getRepository(\Aviatur\HotelBundle\Entity\Hotel::class)->findOneByCodhotel($hotelCode);
$hotel = null != $hotelEntity ? $hotelEntity->getId() : null;
if (count($hotels['rates']) > 0) {
$roomRate = $hotels['rates'][0];
$markup = false;
foreach ($markups['markups'] as $markupItem) {
if (
($markupItem['hotel_id'] == $hotel || $markupItem['hotel_id'] === null) &&
($markups['providerOfConfig'][$markupItem['config_hotel_agency_id']] == (string) $hotelProviderIdentifier)
) {
if ($markups['typeOfConfig'][$markupItem['config_hotel_agency_id']] == 'N') {
$aviaturMarkup = (float) round($roomRate['net']) * $markupItem['value'] / (100 - $markupItem['value']);
} else {
$aviaturMarkup = 0;
}
$hotels['providerName'] = $markups['providerNames'][$markupItem['config_hotel_agency_id']];
$roomRate['AmountAviaturMarkup'] = round($aviaturMarkup);
$hotels['minRate'] = round($roomRate['net']) + $roomRate['AmountAviaturMarkup'];
$markup = true;
break;
}
}
}
$filterEntities = [];
$filterEntities['provider'] = [];
// Nuevo $filterEntities para incluir códigos de proveedores de Hoteles
if(!isset($filterEntities['provider'][$hotels['providers'][0]])){
$filterEntities['provider'][$hotels['providers'][0]] = $hotels['providerName'];
}
}
}
$response = (Object)[
"data" => (Object)[
'provider' => $hotelProviderIdentifier,
'filterEntities' => $filterEntities,
'results' => $data,
],
"status" => (Object)[
"message" => "success",
"code" => 200
]
];
return new JsonResponse(
$response,
Response::HTTP_OK,
);
} catch (\Throwable $th) {
$response = array(
"data" => [],
"status" => (Object)[
"error" => $th->getMessage(). " - " . $th->getLine(),
"message" => "Error: En la búsqueda de proveedores de hoteles",
"code" => 503
]
);
return new JsonResponse(
$response,
Response::HTTP_SERVICE_UNAVAILABLE,
);
}
}
public function availabilityRest(Request $request,TwigFolder $twigFolder, AviaturLogSave $aviaturLogSave, string $params): StreamedResponse
{
$payload = 'GetAvail';
$agency = $this->agency;
$agencyFolder = $twigFolder->twigFlux();
$jsonHotelAvails = json_decode(base64_decode($params), true);
$jsonHotelAvail = $jsonHotelAvails['HotelRq'];
$transactionId = $jsonHotelAvail['TransactionIdentifier'];
// Obtener configuraciones activas de proveedores
$configsHotelAgency = $this->em
->getRepository(\Aviatur\HotelBundle\Entity\ConfigHotelAgency::class)
->findProviderForHotelsWithAgency($agency,$jsonHotelAvails['payment']);
$response = new StreamedResponse(function () use ($agency, $agencyFolder,$twigFolder, $configsHotelAgency, $payload, $jsonHotelAvail, $aviaturLogSave, $transactionId) {
// Configurar encabezados para SSE
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
header('Connection: keep-alive');
ob_implicit_flush(true);
// Para los filtros de proveedor
$filterEntities = [];
$filterEntities['provider'] = [];
// Instanciar el cliente HTTP
$client = new Client([
'curl' => [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_SSL_VERIFYHOST => false,
CURLOPT_ENCODING => '',
]
]);
// Almacenar las promesas de los llamados
$promises = [];
// Configurar las solicitudes a cada proveedor
foreach ($configsHotelAgency as $config) {
$url = $config->getWsUrl();
$providerId = $config->getProvider();
// Registrar la solicitud en el log
$aviaturLogSave->logSave(json_encode($jsonHotelAvail), 'HotelAvail', $providerId->getProviderIdentifier() . '_RQ', $transactionId);
// Crear la promesa para la solicitud HTTP
$promises[$providerId->getProviderIdentifier()] = $client->postAsync($url.$payload, [
'json' => $jsonHotelAvail,
]);
}
// Procesar cada respuesta tan pronto como se resuelvan
foreach (Utils::settle($promises)->wait() as $providerId => $result) {
if ($result['state'] === 'fulfilled') {
$response = $result['value'];
$data = json_decode($response->getBody(), true);
if($data['title'] == 'No hay disponibilidad para la fecha seleccionada' || $data['title'] == 'NotExistsAvailability') {
echo "data: " . json_encode([
'provider' => $providerId,
'error' => $data['detail'],
]) . "\n\n";
// $renderTwig = $twigFolder->twigExists('@AviaturTwig/'.$agencyFolder.'/Hotel/Default/availability_no_result.html.twig');
// return $this->render($renderTwig, [
// 'error' => 'Hubo un problema al obtener los resultados de disponibilidad. Por favor, inténtelo nuevamente más tarde.',
// 'isMulti' => false
// ]);
$aviaturLogSave->logSave(json_encode($data), 'HotelAvail', $providerId . '_RS', $transactionId);
continue;
}
// Registrar la respuesta en el log
$aviaturLogSave->logSave(json_encode($data), 'HotelAvail', $providerId . '_RS', $transactionId);
$markups = $this->markupService->Markup($agency);
/* Busca por la ciudad de destino para depurar la consulta, de lo contrario buscará en todos los registros de homologación */
$destinationCode = $data['data']['hotels']['hotels'][0]['location']['destination']['code'];
$destinationObject = $this->em->getRepository(\Aviatur\SearchBundle\Entity\SearchCities::class)->findOneByIata($destinationCode);
$homologationObjects = $this->em->getRepository(\Aviatur\HotelBundle\Entity\HotelHomologation::class)->findBySearchCities([null]);
$hotelHomologationArray = [];
foreach ($homologationObjects as $homologationObject) {
foreach (json_decode($homologationObject->getHotelcodes()) as $hotelCode) {
$hotelHomologationArray[$hotelCode] = $homologationObject->getPreferredcode();
}
}
// Verificar el estado de la respuesta
if (isset($data['status']) && $data['status'] == 200) {
foreach ($data['data']['hotels']['hotels'] as &$hotels) {
$hotelIdentifier = (string) $providerId . '-' . (string) $hotels['code'];
$hotels['Show'] = '1';
if (array_key_exists($hotelIdentifier, $hotelHomologationArray) && ($hotelHomologationArray[$hotelIdentifier] != $hotelIdentifier)) {
$hotels['Show'] = '0';
} else {
$hotelEntity = $this->em->getRepository(\Aviatur\HotelBundle\Entity\Hotel::class)->findOneByCodhotel($hotelCode);
$hotel = null != $hotelEntity ? $hotelEntity->getId() : null;
if (count($hotels['rates']) > 0) {
$roomRate = $hotels['rates'][0];
$i = 0;
$markup = false;
while (!$markup) {
if (($markups['markups'][$i]['hotel_id'] == $hotel || null == $markups['markups'][$i]['hotel_id']) && ($markups['providerOfConfig'][$markups['markups'][$i]['config_hotel_agency_id']] == (string) $providerId)) {
if ('N' == $markups['typeOfConfig'][$markups['markups'][$i]['config_hotel_agency_id']]) {
$aviaturMarkup = (float) round($roomRate['net']) * $markups['markups'][$i]['value'] / (100 - $markups['markups'][$i]['value']);
} else {
$aviaturMarkup = 0;
}
$hotels['providerName'] = $markups['providerNames'][$markups['markups'][$i]['config_hotel_agency_id']];
$roomRate['AmountAviaturMarkup'] = round($aviaturMarkup);
$hotels['minRate'] = round($roomRate['net']) + $roomRate['AmountAviaturMarkup'];
//$hotels['rates'][0] = $roomRate;
$markup = true;
}
++$i;
}
}
/* Nuevo $filterEntities para incluir códigos de proveedores de Hoteles */
if(!isset($filterEntities['provider'][$hotels['providers'][0]])){
$filterEntities['provider'][$hotels['providers'][0]] = $hotels['providerName'];
}
}
}
echo "data: " . json_encode([
'provider' => $providerId,
'filterEntities' => $filterEntities,
'results' => $data ?? []
]) . "\n\n";
} else {
// Enviar mensaje de error si aplica
echo "data: " . json_encode([
'provider' => $providerId,
'filterEntities' => [],
'error' => $data['message'] ?? $data['title'] ?? 'Unknown error',
]) . "\n\n";
}
} else {
//dd($result['value'], $result['reason']->getMessage());
$aviaturLogSave->logSave($result['reason']->getResponse()->getBody()->getContents(), 'HotelAvail', $providerId . '_RS', $transactionId);
// Manejar errores en la solicitud
echo "data: " . json_encode([
'provider' => $providerId,
'filterEntities' => [],
'error' => $result['reason']->getMessage(),
]) . "\n\n";
}
flush(); // Enviar respuesta al cliente
}
// Indicar que todas las respuestas se han enviado
echo "event: complete\n";
echo "data: {\"message\": \"All providers responded.\"}\n\n";
});
return $response;
}
/**
* @param $roomlist
* @return array
*/
public function getInfoAndRoomsData($roomlist): array
{
$info = $roomsData = [];
if (isset($roomlist['data']['hotelRoomlist'])) {
$info = isset($roomlist['data']['hotelRoomlist']['hotels']) ? $roomlist['data']['hotelRoomlist']['hotels'][0] : [];
$roomsData = $roomlist['data']['hotelRoomlist']['rooms'] ?? [];
} elseif (isset($roomlist['data']['hotelRoomList'])) {
$info = isset($roomlist['data']['hotelRoomList']['hotels']) ? $roomlist['data']['hotelRoomList']['hotels'][0] : [];
$roomsData = $roomlist['data']['hotelRoomList']['rooms'] ?? [];
}
return [$info, $roomsData];
}
/**
* @param array $paymentOptions
* @param $paymentMethodAgency
* @return array
*/
public function getCybersource(array $paymentOptions, $paymentMethodAgency): array
{
$cybersource = [];
if (in_array('cybersource', $paymentOptions)) {
$cybersource['merchant_id'] = $paymentMethodAgency->getSitecode();
$cybersource['org_id'] = $paymentMethodAgency->getTrankey();
}
foreach ($paymentOptions as $key => $paymentOption) {
if ($paymentOption == 'cybersource') {
unset($paymentOptions[$key]); // strip from other renderizable payment methods
}
}
return [$cybersource, $paymentOptions];
}
protected function authenticateUser(UserInterface $user, LoginManager $loginManager)
{
try {
$loginManager->loginUser(
'main',
$user
);
} catch (AccountStatusException $ex) {
// We simply do not authenticate users which do not pass the user
// checker (not enabled, expired, etc.).
}
}
public function roomListAction(
Request $fullRequest,
RouterInterface $router,
TwigFolder $twigFolder,
ParameterBagInterface $parameterBag,
AviaturErrorHandler $aviaturErrorHandler,
AviaturLogSave $aviaturLogSave,
QseCommission $Qse,
$rooms,
$hotelcode,
$checkIn,
$checkOut,
$providerid,
$countrycode,
$online = 'online',
AviaturWebService $aviaturWebService,
$isFlightHotel = false
)
{
$transactionIdSessionName = $parameterBag->get('transaction_id_session_name');
$correlationIdSessionName = $parameterBag->get('correlation_id_session_name');
$session = $this->session;
$response = [];
$transactionId = null;
$flux = null;
// $provider = null;
$responseHotelDetail = [];
$guestsInfo = null;
$fullPricing = [];
$pixel = [];
$em = $this->em;
$session = $this->session;
$agency = $this->agency;
$request = $fullRequest->request;
$server = $fullRequest->server;
$domain = $fullRequest->getHost();
$route = $router->match(str_replace($fullRequest->getSchemeAndHttpHost(), '', $fullRequest->getUri()));
$returnUrl = $twigFolder->pathWithLocale('aviatur_general_homepage');
$makeLogin = false;
if($isFlightHotel && $session->has($transactionIdSessionName)) {
$transactionId = $session->get($transactionIdSessionName);
} else {
$makeLogin = true;
}
if ($makeLogin) {
$transactionIdResponse = $aviaturWebService->loginService('SERVICIO_MPT', 'dummy|http://www.aviatur.com.co/dummy/', []);
if ('error' == $transactionIdResponse || is_array($transactionIdResponse)) {
$aviaturErrorHandler->errorRedirect('', 'Error MPA', 'No se creo Login!');
// return new Response('Estamos experimentando dificultades técnicas en este momento.');
return (new JsonResponse())->setData([
'error' => true,
'message' => 'Estamos experimentando dificultades técnicas en este momento.',
]);
}
$transactionId = (string) $transactionIdResponse;
$session->set($transactionIdSessionName, $transactionId);
}
$roomsParam = explode('/room=', ltrim($rooms, '/')); // Elimina '/' inicial y divide en 'rooms'
$parsedRooms = [];
$agencyFolder = $twigFolder->twigFlux();
// Procesar los parámetros de cada habitación
foreach ($roomsParam as $room) {
parse_str($room, $roomParams);
// Procesar el parámetro `children`
$childrenAges = [];
if (isset($roomParams['children']) && $roomParams['children'] !== 'n') {
$childrenAges = array_map('intval', explode(' ', $roomParams['children']));
}
// Agregar los datos procesados de la habitación
$parsedRooms[] = [
'room' => isset($roomParams['room']) ? (int) $roomParams['room'] : null,
'adults' => isset($roomParams['adults']) ? (int) $roomParams['adults'] : 0,
'childrenAges' => $childrenAges,
];
}
// Crear la estructura de habitaciones en base a los parámetros de adultos y niños
$roomslist = [];
foreach ($parsedRooms as $index => $room) {
$adults = $room['adults'];
$childrenAges = $room['childrenAges'];
// Definir las edades de los pasajeros
$passengerAges = array_fill(0, $adults, 30); // 30 años para adultos
if (!empty($childrenAges)) {
$passengerAges = array_merge($passengerAges, $childrenAges); // Agregar las edades de los niños
}
// Añadir la habitación solo si tiene pasajeros (adultos o niños)
if ($adults > 0 || !empty($childrenAges)) {
$roomslist[] = [
"index" => $index + 1, // Índice de la habitación (1-based)
"passengerAges" => $passengerAges
];
}
}
if (true === $request->has('transactionID')) {
$transactionId = $request->get('transactionID');
if (false !== strpos($transactionId, '||')) {
$explodedTransaction = explode('||', $transactionId);
$transactionId = $explodedTransaction[0];
$request->set('transactionID', $transactionId);
$metaseachId = $explodedTransaction[1];
$session->set('generals[metasearch]', $metaseachId);
$metatransaction = $em->getRepository(\Aviatur\GeneralBundle\Entity\Metatransaction::class)->findOneByTransactionId($transactionId);
if (null == $metatransaction) {
$metasearch = $em->getRepository(\Aviatur\GeneralBundle\Entity\Metasearch::class)->find($metaseachId);
if (null == $metasearch) {
$response['error'] = 'Por favor selecciona nuevamente tu itinerario de viaje';
return $this->redirect($aviaturErrorHandler->errorRedirectNoEmail($returnUrl, 'Ha ocurrido un error en la validación', $response['error']));
}
$metatransaction = new Metatransaction();
$metatransaction->setTransactionId((string) $transactionId);
$metatransaction->setDatetime(new \DateTime());
$metatransaction->setIsactive(true);
$metatransaction->setMetasearch($metasearch);
$em->persist($metatransaction);
$em->flush();
}
$d1 = $metatransaction->getDatetime();
$d2 = new \DateTime(date('Y-m-d H:i:s', time() - (15 * 60)));
if (false == $metatransaction->getIsactive()) {
$response['error'] = 'Por favor selecciona nuevamente tu itinerario de viaje';
return $this->redirect($aviaturErrorHandler->errorRedirectNoEmail($returnUrl, '', $response['error']));
} elseif ($d1 < $d2) {
$response['error'] = 'Por favor selecciona nuevamente tu itinerario de viaje';
return $this->redirect($aviaturErrorHandler->errorRedirectNoEmail($returnUrl, 'Tu consulta fue realizada hace mas de 15 minutos', $response['error']));
} else {
$metatransaction->setIsactive(false);
$em->persist($metatransaction);
$em->flush();
}
} else {
$session->set($transactionIdSessionName, $transactionId);
}
} elseif (true === $session->has($transactionIdSessionName)) {
$transactionId = $session->get($transactionIdSessionName);
}
$additional = base64_encode($transactionId.'/'.$session->get($transactionId.'[hotel]['.$correlationIdSessionName.']'));
$country = explode("=", $countrycode);
$session->set($transactionId.'[hotel]destinationtext', count($country) > 1 ? $country[1] : " ");
// $provider = $em->getRepository(\Aviatur\MpaBundle\Entity\Provider::class)->find($session->get($transactionId.'[hotel][provider]'));
$dateIn = strtotime($checkIn);
$dateOut = strtotime($checkOut);
$hotel = $hotelcode;
//$session->get($transactionId.'[availability_url]')
$rs = $this->roomListCall($aviaturLogSave ,$checkIn, $checkOut, $hotel, $roomslist ,$transactionId,$providerid,$online, $isFlightHotel);
$fileName = $aviaturLogSave->logSave($rs, 'HotelRoomList', 'RS',$transactionId);
$detail = json_decode($rs);
$roomlist = json_decode($rs, true);
if(isset($roomlist['errorP'])){
return $this->redirect($aviaturErrorHandler->errorRedirectNoEmail($returnUrl, 'Ha ocurrido un error', $roomlist['errorP']));
}
if (
isset($detail->data->hotelRoomlist->hotels) &&
is_countable($detail->data->hotelRoomlist->hotels) &&
count($detail->data->hotelRoomlist->hotels) > 0
){
[$responseHotel] = $detail->data->hotelRoomlist->hotels;
$hotelInfo = (Object)[];
$hotelInfo->latitude = $responseHotel->location->coordinates->latitude;
$hotelInfo->longitude = $responseHotel->location->coordinates->longitude;
$hotelInfo->countryIata = str_replace("country=", "", $countrycode);
$hotelInfo->providerId = $responseHotel->providers[0];
$hotelInfo->hotelname = $responseHotel->name;
$storeResult = TravelDestinationController::fetchAndStoreHotelLocation($this->registry, $hotelInfo);
/* $xmlReport = TravelDestinationController::fetchHotelXmlReportFromTravelDestinations(
$this->em,
$responseHotel->name,
$responseHotel->location->coordinates->latitude,
$responseHotel->location->coordinates->longitude,
$responseHotel->providers[0],
);
dd($storeResult, $xmlReport); */
}
// $providerid= $detail->data->hotelRoomlist->hotels[0]->providers[0];
$provider = $em->getRepository(\Aviatur\MpaBundle\Entity\Provider::class)->findOneByProvideridentifier($providerid);
$session->set($transactionId.'[hotel][provider]', $provider->getId());
//markup Roomlist
$markups = $this->markupService->Markup($agency);
if (!empty($roomlist['data']['hotelRoomlist']['hotels'][0]['rates'])) {
foreach ($roomlist['data']['hotelRoomlist']['hotels'][0]['rates'] as &$rate ) {
$i = 0;
$markup = false;
$appliedIndex = null;
while (!$markup) {
if (($markups['providerOfConfig'][$markups['markups'][$i]['config_hotel_agency_id']] == (string) $providerid)) {
if ('N' == $markups['typeOfConfig'][$markups['markups'][$i]['config_hotel_agency_id']]) {
$aviaturMarkup = (float) round($rate['net']) * $markups['markups'][$i]['value'] / (100 - $markups['markups'][$i]['value']);
$taxMarkup = (float) round($rate['tax']) * $markups['markups'][$i]['value'] / (100 - $markups['markups'][$i]['value']);
} else {
$aviaturMarkup = 0;
$taxMarkup = 0;
}
$rate['providerName'] = $markups['providerNames'][$markups['markups'][$i]['config_hotel_agency_id']];
$rate['AmountAviaturMarkup'] = round($aviaturMarkup);
$rate['net'] = round($rate['net']) + $rate['AmountAviaturMarkup'];
$rate['tax'] = round($rate['tax'] + $taxMarkup);
//$hotels['rates'][0] = $roomRate;
$markup = true;
$appliedIndex = $i;
}
++$i;
}
if (!is_null($appliedIndex)) {
$valor = $markups['markups'][$appliedIndex]['value'];
}
}
}
// else {
// $view = $twigFolder->twigExists('@AviaturTwig/' . $agencyFolder . '/Hotel/Includes/noAvailabilityRooms_card.html.twig');
// return $this->render($view, []);
// }
//datos para el ordercontroller
// informacion que me deben de enviar
/*$markup = $em->getRepository(\Aviatur\HotelBundle\Entity\Markup::class)->find(262);
$markupValue = $markup->getValue();
$markupId = $markup->getId();
$roomRate = $detail->data->hotelRoomlist->hotels[0]->rates[0];
$aviaturMarkup = (float) $roomRate->net * $markupValue / (100 - $markupValue);
$roomRate->TotalAviatur['Markup'] = $aviaturMarkup;
$roomRate->TotalAviatur['MarkupType'] = $markup->getConfigHotelAgency()->getType();
$nights = floor(($dateOut - $dateIn) / (24 * 60 * 60));
$roomRate->TotalAviatur['AmountTax'] = 0;
$roomRate->TotalAviatur['calcBasePrice'] = (float) $roomRate->net * $nights;
$roomRate->TotalAviatur['calcTripPrice'] = (float) $roomRate->net * $nights;
$roomRate->TotalAviatur['AmountTotal'] = (float) $roomRate->net + $roomRate->TotalAviatur['AmountTax'];
$fullPricing = [
'total' => ((float) $roomRate->TotalAviatur['AmountTotal'] * $nights) ,
'totalPerNight' => (float) $roomRate->TotalAviatur['AmountTotal'],
'totalWithoutService' => (((float) $roomRate->TotalAviatur['AmountTotal'] - (float) $roomRate->net) * $nights),
'currency' => (string) "COP" ,//$currency,
];
$roomRate->TotalAviatur['FullPricing'] = base64_encode(json_encode($fullPricing)) ;
*/
$session->set($transactionId.'[hotel][detail]',json_encode($detail));
// Contadores para adultos y niños
$totalAdults = 0;
$totalChildren = 0;
$countGuestRooms = [];
foreach ($roomslist as $index => $room) {
$roomCounterGuest = [
'adults' => 0,
'children' => 0,
];
foreach ($room['passengerAges'] as $age) {
if ($age >= 18) {
$totalAdults++;
$roomCounterGuest['adults']++;
} else {
$totalChildren++;
$roomCounterGuest['children']++;
}
}
$roomslist[$index]['countGuestRooms'] = $roomCounterGuest;
}
$session->set($transactionId.'[hotel][totalAdults]', $totalAdults);
$session->set($transactionId.'[hotel][totalChildren]', $totalChildren);
/* Se debe validar por medio del objeto que quedará como propiedad info,
si la fecha de cancelación de cada habitación es mayor a la fecha actual
para que la pueda mostrar en la vista del roomlist; de lo contrario,
se debe mostrar una indicación de que la tarifa es no reembolsable.
*/
list($info, $roomsData) = $this->getInfoAndRoomsData($roomlist);
$info = $roomlist['data']['hotelRoomlist']['hotels'][0];
$this->validateCancellationDates($info);
/* Agrupar habitaciones para elegir las mas economicas */
foreach($info['rates'] as &$room) {
$room['suggestedCount'] = 0;
}
$acomodationRooms = [];
foreach ($roomslist as $roomRequired) {
$roomsMatch = [];
foreach ($info['rates'] as &$roomAvailable) {
if ($roomAvailable['adults'] == $roomRequired['countGuestRooms']['adults'] && $roomAvailable['children'] == $roomRequired['countGuestRooms']['children'] && $roomAvailable['suggestedCount'] < $roomAvailable['allotment'] ) {
$roomsMatch[] = $roomAvailable;
}
}
usort($roomsMatch, function($a, $b) {
return $a['net'] <=> $b['net'];
});
foreach ($info['rates'] as &$roomAvailable) {
if(count($roomsMatch) > 0 && $roomsMatch[0]['rateKey'] == $roomAvailable['rateKey']){
$roomAvailable['suggestedCount'] += 1;
$acomodationRooms[] = $roomAvailable;
}
}
}
$markup = (float) $valor;
$processQse = $Qse->getQse($fullRequest->attributes->get('providerid'));
$QSE = $session->get($transactionId.'[QSE]');
$comissionAgent = $Qse->getQseComission();
$qseMoney = $session->get($transactionId.'[qseMoney]');
$qsePercentage = $session->get($transactionId.'[qsePercentage]');
$qseActive = $session->get($transactionId.'[qseActive]');
$responseHotelDetail = [
'twig_readonly' => false,
'referer' => $isFlightHotel ? '/multi' : '/hoteles',
'checkIn' => $checkIn,
'checkOut' => $checkOut,
'roomsQuantity' => count($roomslist),
'nights' => floor(($dateOut - $dateIn) / (24 * 60 * 60)),
'adults' => $totalAdults,
'childs' => $totalChildren,
'info' => $info,
'roomsData' => $roomsData,
'additional' => $additional,
'paymentsSaved' => isset($paymentsSaved) ? $paymentsSaved['info'] : null,
'transactionId' => $transactionId,
'guestForRooms' => $roomslist,
'countryCode' => $countrycode,
'isMulti' => $isFlightHotel,
'acomodationRooms' => $acomodationRooms,
'payment' => $online,
'QSE' => isset($QSE) ? $QSE : null,
'markup' => isset($markup) ? $markup : null,
'comissionAgent' => isset($comissionAgent) ? $comissionAgent : null,
'qseMoney' => isset($qseMoney) ? $qseMoney : null,
'qsePercentage' => isset($qsePercentage) ? $qsePercentage : null,
'qseActive' => isset($qseActive) ? $qseActive : null,
];
$view = $twigFolder->twigExists('@AviaturTwig/' . $agencyFolder . '/Hotel/Default/roomlist.html.twig');
if($isFlightHotel){
return new JsonResponse($responseHotelDetail);
}
return $this->render($view, $responseHotelDetail);
}
public function checkoutAction(
Request $request,
ParameterBagInterface $parameterBag,
TwigFolder $twigFolder,
SessionInterface $session,
AviaturErrorHandler $aviaturErrorHandler,
RouterInterface $router,
AviaturWebService $aviaturWebService,
QseCommission $Qse,
$isFlightHotel = false
) {
$em = $this->em;
$agency = $this->agency;
$passangerTypes = [];
$agencyFolder = $twigFolder->twigFlux();
$transactionIdSessionName = $parameterBag->get('transaction_id_session_name');
$correlationIdSessionName = $parameterBag->get('correlation_id_session_name');
$server = $request->server;
if (true === $session->has($transactionIdSessionName)) {
$transactionId = $session->get($transactionIdSessionName);
// $referer = $router->match(parse_url($server->get('HTTP_REFERER'), PHP_URL_PATH));
// if (true === $session->has($transactionId.'[availability_url]')) {
// return $this->redirect($aviaturErrorHandler->errorRedirect($session->get($transactionId.'[availability_url]'), 'Página no accesible', 'No puedes acceder al detalle sin disponibilidad'));
// } elseif (false !== strpos($referer['_controller'], 'availabilityAction')) {
// return $this->redirect($aviaturErrorHandler->errorRedirect($server->get('HTTP_REFERER'), '', 'Error en la respuesta de nuestro proveedor de servicios, inténtalo nuevamente'));
// } else {
// return $this->redirect($aviaturErrorHandler->errorRedirect($twigFolder->pathWithLocale('aviatur_general_homepage'), 'Página no accesible', 'No puedes acceder al detalle sin disponibilidad'));
// }
} else {
return $this->redirect($aviaturErrorHandler->errorRedirect($twigFolder->pathWithLocale('aviatur_general_homepage'), 'Página no accesible', 'No puedes acceder al detalle sin disponibilidad'));
}
$hotelRQ = $request->get('HT');
//Valida si existe un transaccion en el formulario.
$transactionId = isset($hotelRQ['transactionId']) ? $hotelRQ['transactionId'] : $transactionId ;
$session->set($transactionIdSessionName, $transactionId );
$countryCode = isset($hotelRQ['countryCode']) ? $hotelRQ['countryCode'] : $session->get($transactionId.'[hotel][countryCode]') ;
$session->set($transactionId.'[hotel][countryCode]', $countryCode);
$alertsValidation = $request->get('alertsValidation');
$session->set($transactionId.'[hotel][alertsValidation]', $alertsValidation);
$paymentOn = isset($hotelRQ['payment']) ? $hotelRQ['payment'] : $session->get($transactionId.'[hotel][paymentOn]') ;
$session->set($transactionId.'[hotel][paymentOn]', $paymentOn);
$roomsSelection = $request->get('HT') !== null ? $request->get('HT') : $session->get($transactionId.'[hotel][roomsdata]');
$optionRate = $roomsSelection["optionRate"] ?? "";
$hotelRoomsJsonDataSelection = [];
if (isset($roomsSelection['rooms'])) {
$session->set($transactionId.'[hotel][roomsdata]', $roomsSelection);
$jsonString = urldecode($roomsSelection['rooms']);
$hotelRoomsJsonDataSelection = json_decode($jsonString, true);
}
// Extraer solo los 'rateKey' de cada habitación seleccionada
$selectedRateKeys = array_map(function ($room) {
return $room['rateKey'] ?? null;
}, $hotelRoomsJsonDataSelection);
// Filtrar valores nulos por si 'rateKey' no existe en alguna habitación
$selectedRateKeys = array_filter($selectedRateKeys);
// Guardar los 'rateKey' seleccionados en la sesión
$session->set($transactionId.'[hotel][selected_rooms]', $selectedRateKeys);
$totalAdults = $session->get($transactionId.'[hotel][totalAdults]');
$totalChildren =$session->get($transactionId.'[hotel][totalChildren]');
$additional = base64_encode($transactionId.'/'.$session->get($transactionId.'[hotel]['.$correlationIdSessionName.']'));
$detail = json_decode($session->get($transactionId.'[hotel][detail]'));
$hotelInfo = $detail->data->hotelRoomlist->hotels[0];
$checkIn = $detail->data->hotelRoomlist->stay->checkIn;
$checkOut = $detail->data->hotelRoomlist->stay->checkOut;
// Convertir las fechas en objetos DateTime
$dateCheckIn = new \DateTime($checkIn);
$dateCheckOut = new \DateTime($checkOut);
$interval = $dateCheckIn->diff($dateCheckOut);
$nigths = $interval->days;
$totalPrice = 0;
$totalTax = 0;
$totalOnsite = 0;
$totalOnsiteLocal = 0;
$currencylocal = 'false';
$currencyex = 'cop';
// Extraer los rates de $hotelInfo
$hotelRates = $hotelInfo->rates;
// Contar las veces que aparece cada rateKey en $selectedRateKeys
$rateKeyCounts = array_count_values($selectedRateKeys);
// Filtrar los rates y agregar la cuenta de habitaciones seleccionadas
$roomsSelection = array_filter($hotelRates, function ($rate) use ($rateKeyCounts) {
// Solo incluir el rate si su rateKey está en el array de conteos
if (isset($rateKeyCounts[$rate->rateKey])) {
// Agregar la cuenta como una nueva propiedad en el objeto rate
$rate->count = $rateKeyCounts[$rate->rateKey];
return true;
}
return false;
});
// provider aqui
$prov = $session->get($transactionId.'[hotel][provider]');
$provider = $em->getRepository(\Aviatur\MpaBundle\Entity\Provider::class)->findOneById($prov);
$provId = $provider->getProviderIdentifier();
$markups = $this->markupService->Markup($agency);
foreach ($roomsSelection as $room) {
$roomSum =0;
$taxSum=0;
for ($j = 0; $j < $room->count; $j++) {
$i = 0;
$markup = false;
$aviaturMarkup = 0;
$appliedIndex = null;
while (!$markup) {
if (($markups['providerOfConfig'][$markups['markups'][$i]['config_hotel_agency_id']] == (string) $provId )) {
if ('N' == $markups['typeOfConfig'][$markups['markups'][$i]['config_hotel_agency_id']]) {
$aviaturMarkup = (float) round($room->net) * $markups['markups'][$i]['value'] / (100 - $markups['markups'][$i]['value']);
$taxMarkup = (float) round($room->tax) * $markups['markups'][$i]['value'] / (100 - $markups['markups'][$i]['value']);
} else {
$aviaturMarkup = 0;
$taxMarkup = 0;
}
$markup = true;
$appliedIndex = $i;
}
++$i;
}
if (!is_null($appliedIndex)) {
$valor = $markups['markups'][$appliedIndex]['value'];
}
$roomSum += round($room->net) + round($aviaturMarkup);
$taxSum += round($room->tax) + round($taxMarkup);
}
$room->net = $roomSum;
$room->tax = $taxSum;
$totalPrice += $room->net;
$totalTax += $room->tax;
if (isset($room->fareDetails)){
$totalOnsite += $room->fareDetails->propertyFees->requestedCurrency->value;
$currencyex = $room->fareDetails->propertyFees->requestedCurrency->currency;
$totalOnsiteLocal += $room->fareDetails->propertyFees->localCurrency->value;
$currencylocal = $room->fareDetails->propertyFees->localCurrency->currency;
}
}
// Reindexar el array para asegurar índices consecutivos
$roomsSelection = array_values($roomsSelection);
$typeDocument = $em->getRepository(\Aviatur\CustomerBundle\Entity\DocumentType::class)->findAll();
$typeGender = $em->getRepository(\Aviatur\CustomerBundle\Entity\Gender::class)->findAll();
$repositoryDocumentType = $em->getRepository(\Aviatur\CustomerBundle\Entity\DocumentType::class);
$queryDocumentType = $repositoryDocumentType
->createQueryBuilder('p')
->where('p.paymentcode != :paymentcode')
->setParameter('paymentcode', '')
->getQuery();
$documentPaymentType = $queryDocumentType->getResult();
$paymentMethodAgency = $em->getRepository(\Aviatur\GeneralBundle\Entity\PaymentMethodAgency::class)->findBy(['agency' => $agency, 'isactive' => 1]);
$paymentOptions = [];
foreach ($paymentMethodAgency as $payMethod) {
$paymentCode = $payMethod->getPaymentMethod()->getCode();
if (!in_array($paymentCode, $paymentOptions) && 'p2p' == $paymentCode || 'cybersource' == $paymentCode) {
$paymentOptions[] = $paymentCode;
}
}
$cards = $em->getRepository(\Aviatur\GeneralBundle\Entity\Card::class)->findBy(['isactive' => 1]);
$payment_type_form_name = $provider->getPaymentType()->getTwig();
$passangerTypes[1] = [
'ADT' => count($selectedRateKeys) > $totalAdults ? (int) $totalAdults + (count($selectedRateKeys) - $totalAdults) : (int) $totalAdults,
'CHD' => (int) $totalChildren,
'INF' => 0,
];
$conditions = $em->getRepository(\Aviatur\GeneralBundle\Entity\HistoricalInfo::class)->findMessageByAgencyOrNull($agency, 'reservation_conditions_for_hotels');
$totalsite = [
'total' => $totalOnsite ,
'currency' => $currencyex,
'totallocal' => $totalOnsiteLocal,
'currencyLocal'=> $currencylocal,
'totaldest' => $totalPrice,
] ;
$session->set($transactionId.'[hotel][chargesData]', $totalsite);
$markup = (float) $valor;
$QSE = $session->get($transactionId.'[QSE]');
$comissionAgent = $Qse->getQseComission();
$qseMoney = $session->get($transactionId.'[qseMoney]');
$qsePercentage = $session->get($transactionId.'[qsePercentage]');
$qseActive = $session->get($transactionId.'[qseActive]');
$renderCheckoutParameters = [
'twig_readonly' => false, // readonly for retry
'referer' => '/hoteles',
'payment_type_form_name' => $payment_type_form_name,
'cards' => $cards,
'payment_doc_type' => $documentPaymentType,
'paymentOptions' => $paymentOptions,
'doc_type' => $typeDocument,
'services' => $passangerTypes,
'gender' => $typeGender,
'checkIn' => $checkIn,
'checkOut' => $checkOut,
'nights' => $nigths,
'adults' => $totalAdults,
'childs' => $totalChildren,
'totalPrice' => $totalPrice,
'totalTax'=> $totalTax,
'info' => $hotelInfo,
'countryCode' => $countryCode,
'roomsSelection' => $roomsSelection,
'conditions' => $conditions,
'additional' => $additional,
'paymentsSaved' => isset($paymentsSaved) ? $paymentsSaved['info'] : null,
'option_rate' => $optionRate,
'payment' => $paymentOn,
'totalOnsite' => $totalsite,
'QSE' => isset($QSE) ? $QSE : null,
'markup' => isset($markup) ? $markup : null,
'comissionAgent' => isset($comissionAgent) ? $comissionAgent : null,
'qseMoney' => isset($qseMoney) ? $qseMoney : null,
'qsePercentage' => isset($qsePercentage) ? $qsePercentage : null,
'qseActive' => isset($qseActive) ? $qseActive : null,
'alertsValidation' => $request->get('alertsValidation')
];
/* Aplicando para vuelo, pero teniendo cuidado con los otros productos */
/* 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 */
$iinRecordsArray = $aviaturWebService->getIINRanges($em);
$renderCheckoutParameters["ccranges"] = $iinRecordsArray["ccranges"];
$renderCheckoutParameters["ccfranchises"] = $iinRecordsArray["ccfranchises"];
if ($isFlightHotel) {
return new JsonResponse($renderCheckoutParameters);
}
if ($this->isAval) {
list($cybersource, $paymentOptions) = $this->getCybersource($paymentOptions, $paymentMethodAgency[array_search('cybersource', $paymentOptions)]);
$pointRedemption = $em->getRepository(\Aviatur\GeneralBundle\Entity\PointRedemption::class)->findPointRedemptionWithAgency($agency);
$renderCheckoutParameters['pointRedemption'] = $pointRedemption;
$renderCheckoutParameters['message'] = (string) utf8_encode($pointRedemption['DobleFactor']['Message']);
$renderCheckoutParameters['hotelProvidersId'] = [(string) $provider->getProvideridentifier()];
$renderCheckoutParameters['cybersource'] = $cybersource;
$renderCheckoutParameters['paymentOptions'] = $paymentOptions;
$renderCheckoutParameters['points'] = 0;
$renderCheckoutParameters['detailHotel'] = $hotelInfo;
$renderCheckoutParameters['payoutExtras'] = null;
$renderTwig = $twigFolder->twigExists('@AviaturTwig/' . $agencyFolder . '/Hotel/Hotel/detail.html.twig');
} else {
$renderTwig = $twigFolder->twigExists('@AviaturTwig/' . $agencyFolder . '/Hotel/Default/checkout.html.twig');
}
return $this->render($renderTwig, $renderCheckoutParameters);
}
public function thankYouPageAction(
Request $fullRequest,
RouterInterface $router,
TwigFolder $twigFolder,
ParameterBagInterface $parameterBag,
SessionInterface $session,
$on,
$pn
)
{
$em = $this->em;
$route = $router->match(str_replace($fullRequest->getSchemeAndHttpHost(), '', $fullRequest->getUri()));
$isMulti = false !== strpos($route['_route'], 'multi') ? true : false;
$orderId = str_replace('ON', '', $on);
$orderEntity = $em->getRepository(\Aviatur\GeneralBundle\Entity\Order::class)->find($orderId);
$transactionId = $session->get('transactionId');
//$countryCode = $session->get($transactionId.'[hotel][countryCode]');
$reservation = json_decode($session->get($transactionId.'[hotel][reservation]'));
$commentsRes = $reservation->booking->hotel->comments ?? '';
//$alertsValidation = $session->get($transactionId.'[hotel][alertsValidation]');
$orderProduct = $em->getRepository(\Aviatur\GeneralBundle\Entity\OrderProduct::class)->find(str_replace('PN', '', $pn));
$emailData = json_decode($orderProduct->getEmail(), true);
$agencyFolder = $twigFolder->twigFlux();
$viewParams = $emailData;
$viewParams['status'] = $orderProduct->getEmissiondata() == 'No Reservation' ? 'NoReservation' : $orderProduct->getStatus() ;
$viewParams['principalColor'] = (strpos($agencyFolder, 'aval') !== false || strpos($agencyFolder, 'tuPlus') !== false) ? "#54DFC8" : "#005CB9";
$viewParams['isAval'] = $this->isAval;
//$viewParams['countryCode'] = $countryCode;
$viewParams['QSE'] = $session->get($transactionId.'[QSE]');
$viewParams['qseActive'] = $session->get($transactionId.'[qseActive]');
//$viewParams['alertsValidation'] = $alertsValidation;
$viewParams['comments'] = $commentsRes;
if($isMulti) {
return new JsonResponse($viewParams);
}
$view = $twigFolder->twigExists('@AviaturTwig/' . $agencyFolder . '/Hotel/Default/thank-you-page.html.twig');
return $this->render($view, $viewParams);
}
public function hotelAvailability($checkIn, $checkOut, $destinationCode, $countryCode, $latitude, $longitude, $radius, $rooms) {
/* Prueba para pasar la nueva respuesta al front */
// $jsonUrl = 'https://s3.amazonaws.com/fenix-public.aviatecnologia.com/Hotels/ModeloRespuestaHoteles.json';
// $jsonContent = file_get_contents($jsonUrl);
// return $jsonContent;
// $jsonData = json_decode($jsonContent, true);
// Configurar la URL del endpoint
$url = 'https://ecomm5.grupoaviatur.com:8443/Aviatur.HotelBedsV2.Adapter/Api/GetAvail';
//$url = 'https://danubio3.testaviatur.local/Aviatur.HotelBedsV2.Adapter/Api/GetAvail';
// Configurar el identificador de transacción
$transactionIdentifier = "eyJlIjoiMTcyNjY5MTQ4N19iY2hoIn0.PMNkXsLQB54wXrfsU7gMjrEboCcjyL3cLCPHoT4Jupc";
// Estructurar el cuerpo de la solicitud
$data = [
"TransactionIdentifier" => $transactionIdentifier,
"hotelAvailability" => [
"checkIn" => $checkIn,
"checkOut" => $checkOut,
"destination" => [
"type" => "RANGE",
"destinationCode" => $destinationCode,
"countryCode" => $countryCode,
"range" => [
"coordinate" => [
"latitude" => $latitude,
"longitude" => $longitude
],
"radius" => $radius
]
],
"rooms" => $rooms
],
"providers" => [
[
"id" => 23,
"officeId" => "BOGVU28AT",
"externalId" => "BOGVU2308"
]
]
];
// Iniciar cURL
$ch = curl_init($url);
// Configurar opciones cURL
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'accept: text/plain',
'Content-Type: application/json'
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 100000);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
// Ejecutar la solicitud
$response = curl_exec($ch);
// Manejar errores
if (curl_errno($ch)) {
echo 'Error:' . curl_error($ch);
}
// Cerrar cURL
curl_close($ch);
// Devolver la respuesta
return $response;
}
public function roomListCall(AviaturLogSave $aviaturLogSave,$checkIn, $checkOut, $hotel, $rooms, $transactionId,$providerid,$online, $isFlightHotel) {
$payload = 'GetRoomList';
$url = null;
$agency = $this->agency;
$configsHotelAgency = $this->em
->getRepository(\Aviatur\HotelBundle\Entity\ConfigHotelAgency::class)
->findProviderForHotelsWithAgency($agency);
foreach ($configsHotelAgency as $config) {
if(($config->getProvider())->getProviderIdentifier() == $providerid /*$providerId*/){
$url = $config->getWsUrl();
break;
}
}
if ($url === null) {
return json_encode(array(
"errorP" => "No disponible"
));
}
// Configurar el identificador de transacción
$transactionIdentifier = $transactionId;
// Estructurar el cuerpo de la solicitud
$data = [
"transactionIdentifier" => $transactionIdentifier,
"hotelRoomList" => [
"checkIn" => $checkIn,
"checkOut" => $checkOut,
"hotel" => $hotel,
"rooms" => $rooms,
"TPA_Extensions" => [
"salesEnvironment"=> ($online == 'destination') ? 'HotelCollect' : ($isFlightHotel ? 'HotelPackage' : 'HotelOnly')
]
],
"providers" => [
[
"id" => $providerid,
"officeId" => "BOGVU28AT",
"externalId" => "BOGVU2308"
]
]
];
$aviaturLogSave->logSave(json_encode($data), 'HotelRoomList', 'RQ');
$result = $this->aviaturRestService->callRestWebService($url, $payload, $data);
return json_encode($result);
}
public function bookingCall(AviaturLogSave $aviaturLogSave,$passangers, $rooms, $transactionIdentifier,SessionInterface $session,$providerId,$userEmail,$dbState = "0",$payment ) {
$payload = 'Booking';
$url = null;
$agency = $this->agency;
$configsHotelAgency = $this->em
->getRepository(\Aviatur\HotelBundle\Entity\ConfigHotelAgency::class)
->findProviderForHotelsWithAgency($agency);
foreach ($configsHotelAgency as $config) {
if(($config->getProvider())->getProviderIdentifier() == $providerId){
$url = $config->getWsUrl();
break;
}
}
if ($url === null) {
return json_encode(array(
"errorP" => "No disponible"
));
}
$holder = [
"name" => $passangers[0]['name'],
"surname" => $passangers[0]['surname'],
"documentType" => $passangers[0]['documentType'],
"documentNumber" => $passangers[0]['documentNumber'],
"birthDate" => $passangers[0]['birthDate'],
"gender" => $passangers[0]['gender'],
"indexContact" => $passangers[0]['indexContact'],
];
$paymentType = $payment["payment"];
if ($paymentType == 'destination') {
$holder["paymentCard"] = [
"cardNumber" => $payment['paymentData']->card_values->card_num_token,
"expirationMonth" => $payment['paymentData']->exp_month ,
"expirationYear" => $payment['paymentData']->exp_year ,
"securityCode" => $payment['paymentData']->card_code,
];
}
$data = [
"transactionIdentifier" => $transactionIdentifier,
"hotelRest" => [
"holder" => $holder,
"contact" =>[ [
"index" => $passangers[0]['indexContact'],
"telephone" => $passangers[0]['telephone'],
"telephoneCountryCode" => '57',
"email" => $passangers[0]['email'],
"address" => [
"AddressLine" => empty($passangersDataArray['address_1_1']) ? 'Cl 19 N 4 62' : $passangers['address_1_1'],
"cityName" => "Bogota",
"postalCode" => "110810",
"stateProv" => "Cundinamarca",
"countryName" => "Colombia"
],
]
],
"rooms" => $rooms ,
"TPA_Extensions" => [
"usuario" => $userEmail,
"estadoBD" => $dbState
]
],
"clientReference" => "IntegrationAgency",
"providers" => [
[
"id" => 23,
"officeId" => "BOGVU28AT",
"externalId" => "BOGVU2308"
]
]
];
$logData = $data;
if ($paymentType == 'destination') {
// Enmascarar para almacenar en el log
//$logData['hotelRest']['holder']['paymentCard']['cardNumber'] = '************' . substr($data['hotelRest']['holder']['paymentCard']['cardNumber'], -4);
$logData['hotelRest']['holder']['paymentCard']['securityCode'] = '***';
}
$aviaturLogSave->logSave(json_encode($logData), 'HotelRes', 'RQ'); // almacenamiento del log
//return "error";
//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}';
//expedia
//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}]}}';
//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"}]}}';
$result = $this->aviaturRestService->callRestWebService($url, $payload, $data);
return json_encode($result,JSON_UNESCAPED_SLASHES);
}
public function sendEmailThankYouPageAction(
SessionInterface $session,
TwigFolder $twigFolder,
\Swift_Mailer $mailer,
Pdf $pdf,
$pn
) {
try {
$em = $this->em;
$productId = str_replace('PN', '', $pn);
$orderProduct = $em->getRepository(\Aviatur\GeneralBundle\Entity\OrderProduct::class)->find($productId);
$emailData = json_decode($orderProduct->getEmail(), true);
$agencyFolder = $twigFolder->twigFlux();
$emailData['travelers'] = [];
$clientEmail = $emailData["paymentResume"]['client_email'];
$setTo = $clientEmail;
$bccMails = ['soportepagoelectronico@aviatur.com.co', 'soptepagelectronic@aviatur.com', 'sebastian.huertas@aviatur.com','supervisorescallcenter@aviatur.com'];
$infoPdfHotel = [
'retry_count' => 1,
// 'paymentResume' => $paymentResume,
// 'facturationResume' => $facturationResume,
'agencyData' => $emailData['agencyData'],
'journeySummary' => $emailData['journeySummary'],
// 'transactionID' => $transactionId,
// 'rooms' => $rooms,
// 'traveller' => $traveller,
'travelers' => [],
// 'agent' => $responseOrder,
'pdfGenerator' => true,
// dd($rooms),
];
// $pdf->generateFromHtml(
// $this->renderView($urlResume, $infoPdfHotel),
// $voucherFile
// );
$emailData['status'] = $orderProduct->getStatus();
$setSubject = 'Aviatur - Gracias por su compra';
$message = (new \Swift_Message())
->setContentType('text/html')
->setFrom($session->get('emailNoReply'))
->setTo($setTo)
->setBcc($bccMails)
->setSubject($setSubject)
// ->attach(\Swift_Attachment::fromPath($voucherFile))
->setBody(
$this->renderView($twigFolder->twigExists('@AviaturTwig/' . $agencyFolder . '/Hotel/Default/email.html.twig'), $emailData)
);
$mailer->send($message);
return $this->render($twigFolder->twigExists('@AviaturTwig/' . $agencyFolder . '/Hotel/Default/email.html.twig'), $emailData);
} catch (\Exception $e) {
dd($e);
return $e;
}
}
public function prePaymentStep1Action(Request $request, TokenizerService $tokenizerService, CustomerMethodPaymentService $customerMethodPayment, TokenStorageInterface $tokenStorage, AviaturWebService $aviaturWebService, AviaturErrorHandler $aviaturErrorHandler, RouterInterface $router, AviaturEncoder $aviaturEncoder, TwigFolder $twigFolder, SessionInterface $session, ManagerRegistry $registry, ParameterBagInterface $parameterBag)
{
$transactionIdSessionName = $parameterBag->get('transaction_id_session_name');
//$correlationIdSessionName = $parameterBag->get('correlation_id_session_name');
//$startTime = microtime(true);
//$session->set('executiontime', $startTime);
if ($request->isXmlHttpRequest()) {
$request = $request->request;
$quotation = $request->get('QT');
$transactionId = $session->get($transactionIdSessionName);
$billingData = $request->get('BD');
// $roomsSelection = $request->get('HT');
// $hotelRoomsJsonDataSelection = [];
// if (isset($roomsSelection['rooms'])) {
// $jsonString = urldecode($roomsSelection['rooms']);
// $hotelRoomsJsonDataSelection = json_decode($jsonString, true);
// }
// Extraer solo los 'rateKey' de cada habitación seleccionada
// $selectedRateKeys = array_map(function ($room) {
// return $room['rateKey'] ?? null;
// }, $hotelRoomsJsonDataSelection);
// Filtrar valores nulos por si 'rateKey' no existe en alguna habitación
// $selectedRateKeys = array_filter($selectedRateKeys);
// Guardar los 'rateKey' seleccionados en la sesión
// $session->set($transactionId.'[hotel][selected_rooms]', $selectedRateKeys);
$em = $this->em;
$postData = $request->all();
$publicKey = $aviaturEncoder->aviaturRandomKey();
$session->remove('register-extra-data');
if (isset($postData['PD']['card_num'])) {
$postDataInfo = $postData;
if (isset($postDataInfo['PD']['cusPOptSelected'])) {
$customerLogin = $tokenStorage->getToken()->getUser();
$infoMethodPaymentByClient = $customerMethodPayment->getMethodsByCustomer($customerLogin, true);
$cardToken = $infoMethodPaymentByClient['info'][$postDataInfo['PD']['cusPOptSelected']]['token'];
$postDataInfo['PD']['card_num'] = $cardToken;
} else {
$postDataInfo['PD']['card_num'] = $tokenizerService->getToken($postData['PD']['card_num']);
}
$postData['PD']['card_values'] = ['card_num_token' => $postDataInfo['PD']['card_num'], 'card_num' => $postData['PD']['card_num']];
}
$encodedInfo = $aviaturEncoder->AviaturEncode(json_encode($postDataInfo ?? $postData), $publicKey);
$formUserInfo = new FormUserInfo();
$formUserInfo->setInfo($encodedInfo);
$formUserInfo->setPublicKey($publicKey);
$em->persist($formUserInfo);
$em->flush();
$session->set($transactionId.'[hotel][user_info]', $formUserInfo->getId());
if (true === $session->has($transactionId.'[hotel][detail]')) {
//$postData = $request->all();
$isFront = $session->has('operatorId');
$session->set($transactionId.'[hotel][detail_data_hotel]', json_encode($postData)); //
$passangersData = $request->get('PI');
$passangerNames = [];
for ($i = 1; $i <= $passangersData['person_count_1']; ++$i) {
$passangerNames[] = mb_strtolower($passangersData['first_name_1_'.$i]);
$passangerNames[] = mb_strtolower($passangersData['last_name_1_'.$i]);
}
if (($isFront) && ('0' == $quotation['quotation_check'])) {
$nameWhitelist = $em->getRepository(\Aviatur\GeneralBundle\Entity\NameWhitelist::class)->findLikeWhitelist($passangerNames);
if (0 == sizeof($nameWhitelist)) {
$nameBlacklist = $em->getRepository(\Aviatur\GeneralBundle\Entity\NameBlacklist::class)->findLikeBlacklist($passangerNames);
if ((sizeof(preg_grep("/^[a-z- *\.]+$/", $passangerNames)) != (sizeof($passangerNames))) ||
(sizeof($nameBlacklist)) ||
(sizeof(preg_grep('/(([b-df-hj-np-tv-xz])(?!\2)){4}/', $passangerNames)))
) {
return $this->json(['error' => 'error', 'message' => 'nombre inválido']);
}
}
}
if ($isFront) {
$customer = null;
$ordersProduct = null;
} else {
$customer = $em->getRepository(\Aviatur\CustomerBundle\Entity\Customer::class)->find($billingData['id']);
$ordersProduct = $em->getRepository(\Aviatur\GeneralBundle\Entity\OrderProduct::class)->getOrderProductsPending($customer);
}
if (null == $ordersProduct) {
$documentTypes = $em->getRepository(\Aviatur\CustomerBundle\Entity\DocumentType::class)->findAll();
$arrayDocumentTypes = [];
foreach ($documentTypes as $documentType) {
$arrayDocumentTypes[$documentType->getExternalCode()] = $documentType->getId();
}
$genders = $em->getRepository(\Aviatur\CustomerBundle\Entity\Gender::class)->findAll();
$arrayGenders = [];
foreach ($genders as $gender) {
$arrayGenders[$gender->getCode()] = $gender->getExternalCode();
}
$hotelInformation = $request->get('HI'); // validar en que parte del roomlist viene HI[ratePlan] HI[refundInfo]
$gender = $em->getRepository(\Aviatur\CustomerBundle\Entity\Gender::class)->findOneByCode($passangersData['gender_1_1']);
$country = $em->getRepository(\Aviatur\GeneralBundle\Entity\Country::class)->findOneByIatacode($passangersData['nationality_1_1']);
$ajaxUrl = $this->generateUrl('aviatur_hotel_prepayment_step_2_secureN');
return $this->json(['ajax_url' => $ajaxUrl]);
} else {
$booking = [];
$cus = [];
foreach ($ordersProduct as $orderProduct) {
$productResponse = $aviaturEncoder->AviaturDecode($orderProduct->getPayResponse(), $orderProduct->getPublicKey());
$paymentResponse = json_decode($productResponse);
array_push($booking, 'ON'.$orderProduct->getOrder()->getId().'-PN'.$orderProduct->getId());
if (isset($paymentResponse->x_approval_code)) {
array_push($cus, $paymentResponse->x_approval_code);
} elseif (isset($paymentResponse->createTransactionResult->trazabilityCode)) {
array_push($cus, $paymentResponse->createTransactionResult->trazabilityCode);
}
}
return $this->json([
'error' => 'pending payments',
'message' => 'pending_payments',
'booking' => $booking, 'domain' => $domain ?? null, 'agencyId' => $agencyId ?? null, 'operatorId' => $operatorId ?? null,
'cus' => $cus,
]);
}
} else {
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')]);
}
} else {
return $this->redirect($aviaturErrorHandler->errorRedirect($twigFolder->pathWithLocale('aviatur_general_homepage'), '', 'Acceso no autorizado'));
}
}
public function prePaymentStep2Action(Request $request, OrderController $orderController, AuthorizationCheckerInterface $authorizationChecker, AviaturErrorHandler $aviaturErrorHandler, TwigFolder $twigFolder, ManagerRegistry $registry, \Swift_Mailer $mailer, RouterInterface $router, AviaturWebService $aviaturWebService, ParameterBagInterface $parameterBag, AviaturLogSave $aviaturLogSave)
{
$transactionIdSessionName = $parameterBag->get('transaction_id_session_name');
$order = [];
if ($request->isXmlHttpRequest()) {
$request = $request->request;
$em = $this->em;
$session = $this->session;
$agency = $this->agency;
$billingData = $request->get('BD');
$detailEncodedData = $request->get('DD');
$detailData = explode('/', base64_decode($detailEncodedData['additional']));
$transactionId = $detailData[0];
$session->set($transactionId.'[hotel][prepayment_check]', true);
if (true !== $session->has($transactionId.'[hotel][order]')) {
if (true === $session->has($transactionId.'[hotel][detail]')) {
$session->set($transactionIdSessionName, $transactionId);
$isFront = $session->has('operatorId');
if ($isFront) {
$customer = $billingData;
$customer['isFront'] = true;
$status = 'B2T';
} else {
$customer = $em->getRepository(\Aviatur\CustomerBundle\Entity\Customer::class)->find($billingData['id']);
$status = 'waiting';
}
if (isset($agency)) {
$productType = $em->getRepository(\Aviatur\MpaBundle\Entity\ProductType::class)->findByCode('HOTELREST');
$orderIdentifier = '{order_product_num}';
$order = $orderController->createAction($agency, $customer, $productType, $orderIdentifier, $status);
$orderId = str_replace('ON', '', $order['order']);
$orderEntity = $em->getRepository(\Aviatur\GeneralBundle\Entity\Order::class)->find($orderId);
$formUserInfo = $em->getRepository(\Aviatur\GeneralBundle\Entity\FormUserInfo::class)->find($session->get($transactionId.'[hotel][user_info]'));
$formUserInfo->setOrder($orderEntity);
$em->persist($formUserInfo);
$em->flush();
// destination
$payment = $session->get($transactionId.'[hotel][paymentOn]');
if ($isFront) {
$bookingReservation = $this->bookingReservation($session, $mailer, $aviaturWebService, $aviaturErrorHandler, $router, $registry, $parameterBag, $aviaturLogSave, $transactionId, null);
if($bookingReservation instanceof AviaturErrorHandler)
return $this->redirect($bookingReservation);
$order['url'] = $bookingReservation;
} else if($payment == 'destination'){
$bookingReservation = $this->bookingReservation($session, $mailer, $aviaturWebService, $aviaturErrorHandler, $router, $registry, $parameterBag, $aviaturLogSave, $transactionId, null,$payment);
if($bookingReservation instanceof AviaturErrorHandler)
return $this->redirect($bookingReservation);
$order['url'] = $this->generateUrl('aviatur_hotel_reservation_success_secureN');
}
else {
$order['url'] = $this->generateUrl('aviatur_hotel_payment_secureN');
}
return $this->json($order);
} else {
return $this->redirect($aviaturErrorHandler->errorRedirect($twigFolder->pathWithLocale('aviatur_general_homepage'), '', 'No se encontró la agencia con el dominio: '.$request->getHost()));
}
} else {
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')]);
}
} else {
$order['url'] = $this->generateUrl('aviatur_hotel_payment_secureN');
return $this->json($order);
}
} else {
return $this->redirect($aviaturErrorHandler->errorRedirect($twigFolder->pathWithLocale('aviatur_general_homepage'), '', 'Acceso no autorizado'));
}
}
public function paymentAction(Request $request, \Swift_Mailer $mailer,P2PController $p2pPaymentController, MultiHotelDiscount $multiHotelDiscount, PayoutExtraService $payoutExtraService, AviaturErrorHandler $aviaturErrorHandler, RouterInterface $router, TwigFolder $twigFolder, ManagerRegistry $registry, SessionInterface $session, ParameterBagInterface $parameterBag, TokenizerService $tokenizerService, CustomerMethodPaymentService $customerMethodPayment, AviaturLogSave $aviaturLogSave, OrderController $orderController)
{
$transactionIdSessionName = $parameterBag->get('transaction_id_session_name');
$aviaturPaymentOnline = $parameterBag->get('aviatur_payment_online');
$aviaturPaymentOnRequest = $parameterBag->get('aviatur_payment_on_request');
$emailNotification = $parameterBag->get('email_notification');
$orderProduct = [];
$roomRate = [];
$paymentResponse = null;
$return = null;
$emissionData = [];
$response = null;
$array = [];
$em = $this->em;
$session = $this->session;
$parameters = json_decode($session->get($request->getHost().'[parameters]'));
$aviaturPaymentIva = (float) $parameters->aviatur_payment_iva;
$transactionId = $session->get($transactionIdSessionName);
$provider = $em->getRepository(\Aviatur\MpaBundle\Entity\Provider::class)->find($session->get($transactionId.'[hotel][provider]'));
$providerId = $provider->getProvideridentifier();
$route = $router->match(str_replace($request->getSchemeAndHttpHost(), '', $request->getUri()));
//$isMulti = false !== strpos($route['_route'], 'multi') ? true : false;
if ($provider->getPaymentType()->getCode() == $aviaturPaymentOnRequest) {
// pago en destino
return $this->redirect($this->generateUrl('aviatur_hotel_confirmation'));
} elseif ($provider->getPaymentType()->getcode() == $aviaturPaymentOnline) {
// pago online
$detailInfo = json_decode($session->get($transactionId.'[hotel][detail]'));
$postData = json_decode($session->get($transactionId.'[hotel][detail_data_hotel]'));
$paymentData = $postData->PD;
if ($this->isAval) {
$redemptionPointParams = $em->getRepository(\Aviatur\GeneralBundle\Entity\PointRedemption::class)->findPointRedemptionWithAgency($this->agency);
$pointRedemptionValue = $redemptionPointParams['Config']['Amount']['PointVal'];
$pointRedemptionComplete = isset($postData->pointRedemptionComplete);
if ($session->has($transactionId . '[remainingPoints]')) {
$pointsInfo = $session->get($transactionId . '[remainingPoints]');
$avalPoints = $pointsInfo[0];
$valueAval = $pointsInfo[1];
} else {
if (!$session->has($transactionId . '[hotel][pointRedemptionValue]')) {
$requestAvalPoints = isset($paymentData->pointRedemptionValue) ? str_replace('.', '', $paymentData->pointRedemptionValue) : 0;
if ($requestAvalPoints <= $redemptionPointParams['Config']['Amount']['MinStep'] && $requestAvalPoints > 0) {
$session->set($transactionId . '[hotel][pointRedemptionValue]', $redemptionPointParams['Config']['Amount']['MinStep']);
} else {
$session->set($transactionId . '[hotel][pointRedemptionValue]', $requestAvalPoints);
}
}
$avalPoints = $session->get($transactionId . '[hotel][pointRedemptionValue]');
$valueAval = $avalPoints * $pointRedemptionValue;
}
}
if ($session->has($transactionId.'[crossed]'.'[url-hotel]')) {
$urlAvailability = $session->get($transactionId.'[crossed]'.'[url-hotel]');
} elseif ($session->has($transactionId.'[hotel][availability_url]')) {
$urlAvailability = $session->get($transactionId.'[hotel][availability_url]');
} else {
$urlAvailability = $session->get($transactionId.'[availability_url]');
}
$routeParsed = parse_url($urlAvailability);
if ($session->has($transactionId.'external')) {
$routeParsed['path'] = $session->get('routePath');
}
$availabilityUrl = $router->match($routeParsed['path']);
$hotelName = $detailInfo->data->hotelRoomlist->hotels[0]->name;
$orderInfo = json_decode($session->get($transactionId.'[hotel][order]'));
$productId = str_replace('PN', '', $orderInfo->products);
$orderProduct[] = $em->getRepository(\Aviatur\GeneralBundle\Entity\OrderProduct::class)->find($productId);
$hotelInfo = $postData->HI;
foreach ($detailInfo->data->hotelRoomlist->hotels[0]->rates as $roomRatePlan) {
if ($roomRatePlan->rateKey == $hotelInfo->ratePlan) {
$roomRate = $roomRatePlan;
}
}
$roomtotal = $session->get($transactionId.'[hotel][roomsInfo]');
// $roomsSelection = $request->get('HT');
// $hotelRoomsJsonDataSelection = [];
// if (isset($roomsSelection['rooms'])) {
// $jsonString = urldecode($roomsSelection['rooms']);
// $hotelRoomsJsonDataSelection = json_decode($jsonString, true);
// }
// $roomRate = $hotelRoomsJsonDataSelection;
$startDate = strtotime((string) $detailInfo->data->hotelRoomlist->stay->checkIn);
$endDate = strtotime((string) $detailInfo->data->hotelRoomlist->stay->checkOut);
$nights = floor(($endDate - $startDate) / (60 * 60 * 24));
//$location = explode(",", $session->get('[hotel]destinationtext'));
$destination = $detailInfo->data->hotelRoomlist->hotels[0]->location->destination->name;
//$destination = $session->get('[hotel]destinationtext') /*$availabilityUrl['destination1'] ?? $availabilityUrl['destination']*/; //validar de donde sacar ahora esro
//Agregar todos los cuartos a la descripción!!!!!!!!!!!!!!!!!
$description = 'Hotel - '.(string) $hotelName.'('.(string) implode(", ", $roomtotal->description)./*' '.(string) $roomRate['RatePlanCategory'].*/') - '.$destination.'('.date('d/m/Y', $startDate).' - '.date('d/m/Y', $endDate).')';
$datediff = $endDate - $startDate;
$travelDays = floor($datediff / (60 * 60 * 24));
// COLLECT INFORMATION TO PERSIST OrderProduct->Email
$this->generate_email($session, $registry, $parameterBag, $orderProduct[0], $detailInfo,true, $startDate, $endDate);
$discountTransactionID = $session->get('currentHotelDiscountSession');
$discountAmount = 0;
$discountTax = 0;
$_x_tax = 0;
/* $payoutExtrasValues = null;
if (isset($postData->payoutExtrasSelection) && !$isMulti) {
$payoutExtrasValues = $payoutExtraService->getPayoutExtrasValues($postData->payoutExtrasSelection, $transactionId);
}*/
$minimumAmount = 1000;
$qseAmount = 0;
if ('p2p' == $paymentData->type || 'world' == $paymentData->type) {
$customer = $em->getRepository(\Aviatur\CustomerBundle\Entity\Customer::class)->find($postData->BD->id);
if (false !== strpos($paymentData->address, '***')) {
$paymentData->address = $customer->getAddress();
}
if (false !== strpos($paymentData->phone, '***')) {
$paymentData->phone = $customer->getPhone();
}
if (false !== strpos($paymentData->email, '***')) {
$paymentData->email = $customer->getEmail();
}
$x_amount_total = (float) ($roomtotal->AmountTotal) - $discountAmount;
$x_amount_total = $x_amount_total + $qseAmount;
if ($x_amount_total < $minimumAmount) {
$x_amount_total = $minimumAmount;
}
$ivaExcludedCitiesParameter = $em->getRepository(\Aviatur\GeneralBundle\Entity\Parameter::class)->findOneByName('iva_exclude');
$excludedCitiesList = $ivaExcludedCitiesParameter->getValue();
$excludedCities = array_map('trim', explode(',', $excludedCitiesList));
$countryCode = $session->get($transactionId.'[hotel]destinationtext');
$x_amount_tax = 0;
$x_amount_base = 0;
$HotelProvider = $em->getRepository(\Aviatur\HotelBundle\Entity\HotelProvider::class)->findBillingprovider($provider->getId());
$ivaincl = $HotelProvider->getIvaIncl();
if (strtoupper($countryCode) == "CO" && !in_array($destination, $excludedCities)) {
$baseAmount = $roomtotal->AmountTotal / 1.19;
if ($ivaincl != 2) {
$x_amount_tax = isset($roomtotal->AmountTotal) && $roomtotal->AmountTotal != 0 ? round($baseAmount * 0.19) : 0;
$x_amount_base = isset($roomtotal->AmountTotal) && $roomtotal->AmountTotal != 0 ? round($roomtotal->AmountTotal / 1.19) : 0;
} else {
$x_amount_tax = 0;
$x_amount_base = isset($roomtotal->AmountTotal) && $roomtotal->AmountTotal != 0 ? $roomtotal->AmountTotal : 0;
}
}
if (!empty($session->get($transactionId.'[QSE]'))) {
$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]');
}
$array = [
'x_currency_code' => (string)"COP" /*$roomRate->TotalAviatur->CurrencyCode agregarlo de algun lado */,
'x_amount' => $x_amount_total,
'x_tax' => number_format($x_amount_tax, 2, '.', ''),
'x_amount_base' => number_format($x_amount_base, 2, '.', ''),
'x_invoice_num' => $orderInfo->order.'-'.$orderInfo->products,
'x_first_name' => $paymentData->first_name,
'x_last_name' => $paymentData->last_name,
'x_description' => $description,
'x_city' => $customer->getCity()->getIatacode(),
'x_country_id' => $customer->getCountry()->getIatacode(),
'x_cust_id' => $paymentData->doc_type.' '.$paymentData->doc_num,
'x_address' => $paymentData->address,
'x_phone' => $paymentData->phone,
'x_email' => $paymentData->email,
'x_card_num' => $paymentData->card_num,
'x_exp_date' => $paymentData->exp_month.$paymentData->exp_year,
'x_card_code' => $paymentData->card_code,
'x_differed' => $paymentData->differed,
'x_client_id' => $postData->BD->id,
'product_type' => 'hotel',
'productId' => str_replace('PN', '', $orderInfo->products),
'orderId' => str_replace('ON', '', $orderInfo->order),
'franchise' => $paymentData->franquise,
'worldpay_validate' => true,
];
if (isset($paymentData->card_values)) {
$array['card_values'] = (array) $paymentData->card_values;
}
/*
if ($payoutExtrasValues && !(bool) $session->get($transactionId.'[PayoutExtras][Processed]')) {
foreach ($payoutExtrasValues as $payoutExtraValues) {
$array['x_amount'] += round((float) $payoutExtraValues->values->fare->total);
$array['x_tax'] += round((float) $payoutExtraValues->values->fare->tax);
$array['x_amount_base'] += round((float) $payoutExtraValues->values->fare->base);
}
$array['x_amount'] = $array['x_amount'] + $qseAmount;
}
$payoutExtrasValues = $payoutExtraService->setPayoutExtrasAsProcessed($transactionId);
*/
//AVAL POINT REDEMPTION
if ($this->isAval) {
if ($session->has($transactionId . '[alreadyRedimed]')) {
$array['putDistribution'] = true;
}
if ($valueAval > 0 && !$session->has($transactionId . '[alreadyRedimed]')) {
$redemption = $this->redemptionService->hotelAvalPointsRedemption(
$session, $pointRedemptionValue, $avalPoints, $pointRedemptionComplete, $array,
$redemptionPointParams, $transactionId, $parameters, $orderProduct, $productId
);
if (isset($redemption['availability_url'])) {
$this->redirect($aviaturErrorHandler->errorRedirect($redemption['availability_url'], '', $redemption['response']['error']['text']['StatusDesc'] ?? $redemption['response']['ok']['text']['StatusDesc']));
}
$array = $redemption;
} elseif ($valueAval == 0 && $session->has($transactionId . '[alreadyRedimed]')) {
$array['onlyRedemption'] = true;
}
}
//END AVAL REDEMPTION
$array['x_cancelation_date'] = (string) $detailInfo->data->hotelRoomlist->hotels[0]->rates[0]->cancellationPolicies[0]->from;
if (isset($paymentData->cusPOptSelected)) {
$array['isToken'] = (string) $paymentData->card_values->card_num_token;
}
if ('p2p' == $paymentData->type) {
if (isset($paymentData->savePaymProc)) {
$array['x_provider_id'] = 1;
} elseif (isset($paymentData->cusPOptSelected)) {
if (isset($paymentData->cusPOptSelectedStatus)) {
if ('NOTVERIFIED' == $paymentData->cusPOptSelectedStatus) {
$array['x_provider_id'] = 1;
} else {
$array['x_provider_id'] = 2;
}
} else {
$array['x_provider_id'] = 2;
}
}
}
if ('p2p' == $paymentData->type) {
$paymentResponse = $p2pPaymentController->placetopayAction($parameterBag, $tokenizerService, $customerMethodPayment, $mailer, $aviaturLogSave, $array, $combination = false, $segment = null, false);
$return = $this->redirect($this->generateUrl('aviatur_hotel_payment_p2p_return_url_secureN', [], true));
}
unset($array['x_client_id']);
if (null != $paymentResponse) {
/* Cancelar puntos si el pago no fue exitoso */
if (isset($paymentResponse['x_response_code']) && $paymentResponse['x_response_code'] === '2') {
if ($this->isAval) {
if (!empty($array['redemptionPoints']) && $array['redemptionPoints'] > 0) {
$this->aviaturAthServices->cancelRedemptionPoints($redemption['redemption']);
}
}
} elseif (isset($paymentResponse['error'])) {
if (!empty($array['redemptionPoints']) && $array['redemptionPoints'] > 0) {
$this->aviaturAthServices->cancelRedemptionPoints($redemption['redemption']);
}
}
/* fin cancelacion */
return $return;
} else {
$orderProduct[0]->setStatus('pending');
$em->persist($orderProduct[0]);
$em->flush();
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'));
}
}else {
return $this->redirect($aviaturErrorHandler->errorRedirect($this->generateUrl('aviatur_hotel_retry_secure'), '', 'El tipo de pago es invalido'));
}
} else {
return $this->redirect($aviaturErrorHandler->errorRedirect($this->generateUrl('aviatur_hotel_retry_secure'), '', 'El provedor arrojó un método de pago inesperado'));
}
}
public function p2pCallbackAction(OrderController $orderController, ValidateSanctionsRenewal $validateSanctions, TokenStorageInterface $tokenStorage, CustomerMethodPaymentService $customerMethodPayment, AviaturMailer $aviaturMailer, PayoutExtraService $payoutExtraService, AviaturEncoder $aviaturEncoder, AviaturErrorHandler $aviaturErrorHandler, ManagerRegistry $registry, ParameterBagInterface $parameterBag, AviaturWebService $aviaturWebService, RouterInterface $router, \Swift_Mailer $mailer,AviaturLogSave $aviaturLogSave)
{
$transactionIdSessionName = $parameterBag->get('transaction_id_session_name');
$em = $this->em;
$session = $this->session;
$transactionId = $session->get($transactionIdSessionName);
$orderProductCode = $session->get($transactionId.'[hotel][order]');
$productId = str_replace('PN', '', json_decode($orderProductCode)->products);
$orderProduct = $em->getRepository(\Aviatur\GeneralBundle\Entity\OrderProduct::class)->find($productId);
$decodedRequest = json_decode($aviaturEncoder->AviaturDecode($orderProduct->getPayrequest(), $orderProduct->getPublicKey()));
$decodedResponse = json_decode($aviaturEncoder->AviaturDecode($orderProduct->getPayresponse(), $orderProduct->getPublicKey()));
if (null != $decodedResponse) {
$agency = $orderProduct->getOrder()->getAgency();
$prepaymentInfo = json_decode($session->get($transactionId.'[hotel][prepayment]'));
$twig = '';
$additionalQS = '';
$retryCount = (int) $session->get($transactionId.'[hotel][retry]');
$jsonSendEmail = $em->getRepository(\Aviatur\GeneralBundle\Entity\Parameter::class)->findOneByName('send_email');
if (isset(json_decode($jsonSendEmail->getDescription())->email)) {
$email = json_decode($jsonSendEmail->getDescription())->email->CallBack;
}
$reference = str_replace('{"order":"', '', $orderProductCode);
$reference = str_replace('","products":"', '-', $reference);
$reference = str_replace('"}', '', $reference);
$references = $reference;
$bookings = $orderProduct->getBooking();
switch ($decodedResponse->x_response_code) {
case isset($decodedResponse->x_response_code_cyber) && (2 == $decodedResponse->x_response_code_cyber):
//rechazado cybersource
$parameters = $em->getRepository(\Aviatur\GeneralBundle\Entity\Parameter::class)->findOneByName('aviatur_switch_rechazada_cyber');
if ($parameters) {
if (1 == $parameters->getValue()) {
if (1 == $decodedResponse->x_response_code) {
$postData = json_decode($session->get($transactionId . '[hotel][detail_data_hotel]'));
if (isset($postData->PD->savePaymProc)) {
$customerLogin = $tokenStorage->getToken()->getUser();
$customerMethodPayment->setMethodsByCustomer($customerLogin, json_decode(json_encode($postData), true));
}
if (isset($postData->PD->cusPOptSelected)) {
if (isset($postData->PD->cusPOptSelectedStatus)) {
if ('NOTVERIFIED' == $postData->PD->cusPOptSelectedStatus) {
$postData->PD->cusPOptSelectedStatus = 'ACTIVE';
$customerLogin = $tokenStorage->getToken()->getUser();
$customerMethodPayment->setMethodsByCustomer($customerLogin, json_decode(json_encode($postData), true));
}
}
}
}
}
}
// Aquí NO se hace la reserva en ningún caso
$twig = 'aviatur_hotel_payment_rejected_secureN'; //enviar a la pantalla de rechazado
// no break
case 3:// pendiente p2p
$twig = '' != $twig ? $twig : 'aviatur_hotel_payment_pending_secureN'; //enviar a la pantalla de pago pendiente
$emissionData = 'No Reservation';
$orderProduct->setEmissiondata(json_encode($emissionData));
$orderProduct->setUpdatingdate(new \DateTime());
$em->persist($orderProduct);
$em->flush();
$retryCount = 1;
break;
case 0:// error p2p
$twig = 'aviatur_hotel_payment_error_secureN';
if (isset($email)) {
$from = $session->get('emailNoReply');
$error = $twig;
$subject = $orderProduct->getDescription().':Error en el proceso de pago de Aviatur';
$body = '</br>El proceso de pago a retornado un error </br>Referencia: '.$references.'</br>Reserva:'.$bookings;
$aviaturMailer->sendEmailGeneral($from, $email, $subject, $body);
}
// no break
case 2:// rechazada p2p
$twig = '' != $twig ? $twig : 'aviatur_hotel_payment_rejected_secureN';
if (isset($email)) {
$from = $session->get('emailNoReply');
$error = $twig;
$subject = $orderProduct->getDescription().':Transacción rechazada';
$body = '</br>El pago fue rechazado </br>Referencia: '.$references.'</br>Reserva:'.$bookings;
$aviaturMailer->sendEmailGeneral($from, $email, $subject, $body);
}
break;
case 1:// aprobado p2p
$postData = json_decode($session->get($transactionId.'[hotel][detail_data_hotel]'));
$customer = $em->getRepository(\Aviatur\CustomerBundle\Entity\Customer::class)->find($postData->BD->id);
if (isset($postData->PD->savePaymProc)) {
$customerLogin = $tokenStorage->getToken()->getUser();
$customerMethodPayment->setMethodsByCustomer($customerLogin, json_decode(json_encode($postData), true));
}
if (isset($postData->PD->cusPOptSelected)) {
if (isset($postData->PD->cusPOptSelectedStatus)) {
if ('NOTVERIFIED' == $postData->PD->cusPOptSelectedStatus) {
$postData->PD->cusPOptSelectedStatus = 'ACTIVE';
$customerLogin = $tokenStorage->getToken()->getUser();
$customerMethodPayment->setMethodsByCustomer($customerLogin, json_decode(json_encode($postData), true));
}
}
}
$decodedRequest->product_type = 'hotel';
$decodedResponse->product_type = 'hotel';
$encodedRequest = $aviaturEncoder->AviaturEncode(json_encode($decodedRequest), $orderProduct->getPublicKey());
$encodedResponse = $aviaturEncoder->AviaturEncode(json_encode($decodedResponse), $orderProduct->getPublicKey());
$orderProduct->setPayrequest($encodedRequest);
$orderProduct->setPayresponse($encodedResponse);
$twig = 'aviatur_hotel_reservation_success_secureN';
if ('rappi' == $orderProduct->getOrder()->getAgency()->getAssetsFolder()) {
$additionalQS = '?bookingid='.$orderProduct->getBooking().'&total='.$decodedRequest->x_amount;
}
//Reemplazar por consumo de reserva!!!!
$provider = $em->getRepository(\Aviatur\MpaBundle\Entity\Provider::class)->find($session->get($transactionId.'[hotel][provider]'));
$providerId = $provider->getProvideridentifier();
$orderController->updatePaymentAction($orderProduct, false, null);
if(is_null($orderProduct->getEmissiondata())){
$rs = $this->bookingReservation($session, $mailer, $aviaturWebService, $aviaturErrorHandler, $router, $registry, $parameterBag,$aviaturLogSave, $transactionId, 1);
}
$reservationInfo = json_decode($session->get($transactionId.'[hotel][reservation]'));
$reservationId2 = 'PN'.$orderProduct->getId();
// $orderUpdatePayment = str_replace(
// ['{web_book_id}', '{hotel_book_id}'],
// ['PN'.$orderProduct->getId(), (string) $reservationId2],
// $orderProduct->getUpdatePaymentData()
// );
/*$orderUpdatePayment = str_replace(
['{web_book_id}', '{hotel_book_id}'],
['PN'.$orderProduct->getId(), $orderProduct->getBooking()],
$orderProduct->getUpdatePaymentData()
);
$orderProduct->setUpdatePaymentData($orderUpdatePayment);
$em->persist($orderProduct);
$em->flush();*/
break;
}
// Update Payment
$orderController->updatePaymentAction($orderProduct, false, null);
$orderUpdatePayment = str_replace(
['{web_book_id}', '{hotel_book_id}'],
['PN'.$orderProduct->getId(), $orderProduct->getBooking()],
$orderProduct->getUpdatePaymentData()
);
$orderProduct->setUpdatePaymentData($orderUpdatePayment);
$em->persist($orderProduct);
$em->flush($orderProduct);
$payoutExtraService->payoutExtrasCallback($twig, $transactionId, 'hotel', $agency);
$session->set($transactionId.'[hotel][retry]', $retryCount - 1);
$urlResume = $this->generateUrl($twig);
$urlResume .= $additionalQS;
/* Pero solo si hay condicionados (no bloqueados) y que paguen con Tarjeta */
if ($session->has('Marked_users')) {
$product = 'Hotel';
$validateSanctions->sendMarkedEmail($orderProductCode, $session, $agency, $orderProduct, $transactionId, $product);
}
return $this->redirect($urlResume);
} else {
$orderProduct->setStatus('pending');
$em->persist($orderProduct);
$em->flush();
return $this->redirect($aviaturErrorHandler->errorRedirect($this->generateUrl('aviatur_hotel_retry_secure'), '', 'No hay respuesta por parte del servicio de pago'));
}
}
private function bookingReservation(SessionInterface $session, \Swift_Mailer $mailer, AviaturWebService $aviaturWebService, AviaturErrorHandler $aviaturErrorHandler, RouterInterface $router, ManagerRegistry $registry, ParameterBagInterface $parameterBag,AviaturLogSave $aviaturLogSave, $transactionId, $stateDb = null, $payment ='online')
{
//$startTime = $session->get('executiontime');
$isFront = $session->has('operatorId');
$correlationIdSessionName = $parameterBag->get('correlation_id_session_name');
$detail = json_decode((string) $session->get($transactionId.'[hotel][detail]'));
//validar lo de la url
if ($session->has($transactionId.'[crossed]'.'[url-hotel]')) {
$urlAvailability = $session->get($transactionId.'[crossed]'.'[url-hotel]');
} elseif ($session->has($transactionId.'[hotel][availability_url]')) {
$urlAvailability = $session->get($transactionId.'[hotel][availability_url]');
} else {
$urlAvailability = $session->get($transactionId.'[availability_url]');
}
$routeParsed = parse_url($urlAvailability);
if ($session->has($transactionId.'external')) {
$routeParsed['path'] = $session->get('routePath');
}
$availabilityUrl = $router->match($routeParsed['path']);
$currentRequest = $this->requestStack->getCurrentRequest();
$referenceUrl = $currentRequest ? $currentRequest->headers->get('referer') : null;
$route = $currentRequest ? $router->match(str_replace($currentRequest->getSchemeAndHttpHost(), '', $currentRequest->getUri())) : [];
$isMulti = ($referenceUrl && strpos($referenceUrl, 'multi') !== false) || (isset($route['_route']) && strpos($route['_route'], 'multi') !== false);
$postData = json_decode($session->get($transactionId.'[hotel][detail_data_hotel]'));
$passangersData = $postData->PI;
if ($isFront) {
$payData = '';
} else {
$payData = $postData->PD;
}
$paymentData = [
"payment" => $payment,
"paymentData" => $payData
];
$hotelInformation = $session->get($transactionId.'[hotel][roomsInfo]');
$em = $this->em;
//$gender = $em->getRepository(\Aviatur\CustomerBundle\Entity\Gender::class)->findOneByCode($passangersData->gender_1_1);
//$country = $em->getRepository(\Aviatur\GeneralBundle\Entity\Country::class)->findOneByIatacode($passangersData->nationality_1_1);
if ($isFront) {
$customer = $postData->BD;
$dbState = "0";
$usuario = $session->get('operatorId');
$customerModel = new CustomerModel();
$userData = null;
try {
$userData = $aviaturWebService->callWebService('GENERALLAVE', 'dummy|http://www.aviatur.com.co/dummy/', $customerModel->getXmlAgent($usuario));
$session->set($transactionId . '[user]', $userData->asXml());
$userEmail = (string) $userData->CORREO_ELECTRONICO;
} catch (\Exception $e) {
$userEmail = $session->get('domain') . '@' . $session->get('domain');
}
} else {
$customer = $em->getRepository(\Aviatur\CustomerBundle\Entity\Customer::class)->find($postData->BD->id);
$dbState = "1";
$userEmail = $session->get('domain') . '|' . $customer->getEmail();
}
if (false !== strpos($passangersData->first_name_1_1, '***')) {
$passangersData->first_name_1_1 = $customer->getFirstname();
$passangersData->last_name_1_1 = $customer->getLastname();
$passangersData->phone_1_1 = !empty($customer->getPhone()) ? $customer->getPhone() : '6012861616';
$passangersData->email_1_1 = $customer->getEmail();
$passangersData->address_1_1 = !empty($customer->getAddress()) ? $customer->getAddress() : "Av 19 4-62 ";
$passangersData->doc_num_1_1 = $customer->getDocumentnumber();
}
$orderProductCode = $session->get($transactionId.'[hotel][order]');
$productId = str_replace('PN', '', json_decode($orderProductCode)->products);
$orderProduct = $em->getRepository(\Aviatur\GeneralBundle\Entity\OrderProduct::class)->find($productId);
$detailInfo = json_decode((string) $session->get($transactionId.'[hotel][detail]'));
//$prepaymentInfo = json_decode((string) $session->get($transactionId.'[hotel][prepayment]'));
$startDate = strtotime((string)$detailInfo->data->hotelRoomlist->stay->checkIn);
$endDate = strtotime((string) $detailInfo->data->hotelRoomlist->stay->checkOut);
$this->generate_email($session, $registry,$parameterBag, $orderProduct, $detailInfo, null, $startDate, $endDate);
$orderRequestArray = explode('<FILTRO>', str_replace('</FILTRO>', '<FILTRO>', $orderProduct->getAddproductdata()));
// $orderRequest = \simplexml_load_string($orderRequestArray[1]);
$provider = $em->getRepository(\Aviatur\MpaBundle\Entity\Provider::class)->find($session->get($transactionId.'[hotel][provider]'));
$passangersDataArray = json_decode(json_encode($passangersData), true);
$totalGuests = $passangersDataArray['person_count_1'];
for ($i = 1; $i <= $totalGuests; ++$i) {
$gender = $em->getRepository(\Aviatur\CustomerBundle\Entity\Gender::class)->findOneByCode($passangersDataArray['gender_1'.'_'.$i]);
$country = $em->getRepository(\Aviatur\GeneralBundle\Entity\Country::class)->findOneByIatacode($passangersDataArray['nationality_1'.'_'.$i]);
$passangersDataArray['DocType_1'.'_'.$i] = $passangersDataArray['doc_type_1'.'_'.$i];
$variable['doc_num_1'.'_'.$i] = $passangersDataArray['doc_num_1'.'_'.$i];
$variable['first_name_1'.'_'.$i] = $passangersDataArray['first_name_1'.'_'.$i];
$variable['last_name_1'.'_'.$i] = $passangersDataArray['last_name_1'.'_'.$i];
$variable['birthday_1'.'_'.$i] = $passangersDataArray['birthday_1'.'_'.$i];
$variable['gender_1'.'_'.$i] = $gender->getExternalcode();
$variable['nationality_1'.'_'.$i] = $country->getIatacode();
$variable['DocType_1'.'_'.$i] = $passangersDataArray['doc_type_1'.'_'.$i];
$variable['passanger_type_1'.'_'.$i] = $passangersDataArray['passanger_type_1'.'_'.$i];
}
if ($isFront) {
$passangersDataArray['address_1_1'] = !empty($passangersDataArray['address_1_1']) ? $passangersDataArray['address_1_1'] : "Av 19 4-62";
}else{
$passangersDataArray['address_1_1'] = !empty($passangersDataArray['address_1_1']) ? $passangersDataArray['address_1_1'] : (!empty($customer->getAddress()) ? $customer->getAddress() : "Av 19 4-62");
}
$roomsCount = count($hotelInformation->rateKey); // Número de habitaciones
$rooms = [];
$adultIndex = 0;
$childIndex = 0;
$providerId = $provider->getProvideridentifier();//$hotelInformation->provider; // Obtener el provider
$adults = [];
$children = [];
// Recopilamos la información de los pasajeros
for ($i = 1; $i <= $totalGuests; ++$i) {
if ($variable['passanger_type_1' . '_' . $i] === "ADT") {
$adult = [
"type" => "ADT",
"name" => $variable['first_name_1' . '_' . $i],
"surname" => $variable['last_name_1' . '_' . $i],
"documentType" => $variable['DocType_1' . '_' . $i],
"documentNumber" => $variable['doc_num_1' . '_' . $i],
"nationality" => $variable['nationality_1' . '_' . $i],
"birthDate" => $variable['birthday_1' . '_' . $i],
"gender" => $variable['gender_1' . '_' . $i],
"indexContact" => "1",
"telephone" => !empty($passangersDataArray['phone_1_1'])
? $passangersDataArray['phone_1_1']
: $postData->CD->phone,
"email" => $passangersDataArray['email_1_1'],
"address" => [
"AddressLine" => empty($passangersDataArray['address_1_1']) ? 'Cl 19 N 4 62' : $passangersDataArray['address_1_1'],
"CityName" => "Bogota",
"PostalCode" => "110810",
"StateProv" => "Cundinamarca",
"CountryName" => "Colombia"
]
];
$adults[] = $adult;
}
if (($variable['passanger_type_1' . '_' . $i] === "CHD") || ($isMulti && $variable['passanger_type_1' . '_' . $i] === "INF")) {
$child = [
"type" => "CHD",
"name" => $variable['first_name_1' . '_' . $i],
"surname" => $variable['last_name_1' . '_' . $i],
"documentType" => $variable['DocType_1' . '_' . $i],
"documentNumber" => $variable['doc_num_1' . '_' . $i],
"nationality" => $variable['nationality_1' . '_' . $i],
"birthDate" => $variable['birthday_1' . '_' . $i],
"gender" => $variable['gender_1' . '_' . $i],
"indexContact" => "1",
"telephone" => !empty($passangersDataArray['phone_1_1'])
? $passangersDataArray['phone_1_1']
: $postData->CD->phone,
"email" => $passangersDataArray['email_1_1'],
"address" => [
"AddressLine" => empty($passangersDataArray['address_1_1']) ? 'Cl 19 N 4 62' : $passangersDataArray['address_1_1'],
"CityName" => "Bogota",
"PostalCode" => "110810",
"StateProv" => "Cundinamarca",
"CountryName" => "Colombia"
]
];
$children[] = $child;
}
}
$rooms = [];
$roomIndex = 0;
$adultsCount = count($adults);
$childrenCount = count($children);
$adultsPerRoom = $hotelInformation->adults;
$childrenPerRoom = $hotelInformation->children;
$hotelAdultsCount = count($hotelInformation->adults);
if ($providerId == 124) {
while ($adultIndex < $adultsCount && $roomIndex < $roomsCount){
$room = [
"roomId" => $roomIndex + 1,
"rateKey" => !empty($hotelInformation->rateKey[$roomIndex]) ? $hotelInformation->rateKey[$roomIndex] : " ",
"paxes" => []
];
$room['paxes'][] = $adults[$adultIndex];
$adultIndex++;
$rooms[] = $room;
$roomIndex++;
}
} else {
for ($roomIndex = 0; $adultIndex < $adultsCount && $roomIndex < $hotelAdultsCount; $roomIndex++) {
$room = [
"roomId" => $roomIndex + 1,
"rateKey" => !empty($hotelInformation->rateKey[$roomIndex]) ? $hotelInformation->rateKey[$roomIndex] : " ",
"paxes" => []
];
$maxAdultsPerRoom = $adultsPerRoom[$roomIndex];
$maxChildrenPerRoom = $childrenPerRoom[$roomIndex];
// Asignar adultos a la habitación
if ($adultIndex < $adultsCount) {
$room['paxes'][] = $adults[$adultIndex];
$adultIndex++;
}
// Asignar niños a la habitación
$childrenAssigned = 0;
while ($childrenAssigned < $maxChildrenPerRoom && $childIndex < $childrenCount) {
$room['paxes'][] = $children[$childIndex];
$childIndex++;
$childrenAssigned++;
}
$rooms[] = $room;
}
// Asignar los adultos restantes a las habitaciones
while ($adultIndex < $adultsCount) {
foreach ($rooms as $roomIndex => &$room) {
$maxAdultsPerRoom = $hotelInformation->adults[$roomIndex];
$adultsInRoom = array_filter($room['paxes'], function($pax) {
return $pax['type'] === 'ADT'; // Filtrar solo los pasajeros de tipo 'adult'
});
if ( count($adultsInRoom) < $maxAdultsPerRoom) {
// Agregar un adulto a la habitación
$room['paxes'][] = $adults[$adultIndex];
$adultIndex++;
// Si ya se alcanzó el límite de adultos en la habitación, salir del ciclo
if ( count($adultsInRoom) > $maxAdultsPerRoom) {
break;
}
}
}
}
}
$rs = $this->bookingCall($aviaturLogSave,$adults, $rooms, $transactionId,$session, $providerId,$userEmail,$dbState,$paymentData);
$aviaturLogSave->logSave($rs, 'HotelRes', 'RS');
$response = json_decode($rs);
$response = isset($response->data) ? $response->data : $response;
$validateStatus = json_decode($rs , true);
// if ($validateStatus["status"] != 200) {
// $message = 'Ha ocurrido un error realizando la reserva del hotel.' . chr(10) . $validateStatus["status"] . chr(10) . $validateStatus["detail"]; ;
// return $aviaturErrorHandler->errorRedirectNoEmail('/buscar/hoteles', 'Error al reservar', $message . $validateStatus["status"]);
// }
// if ($validateStatus["status"] != 200) {
// $message = 'Ha ocurrido un error realizando la reserva del hotel.' . chr(10) . $validateStatus["status"] . chr(10) . $validateStatus["detail"]; ;
// return $aviaturErrorHandler->errorRedirectNoEmail('/buscar/hoteles', 'Error al reservar', $message . $validateStatus["status"]);
// }
$references = [];
$error = false;
if (isset($response->booking)) {
if (is_array($response->booking)) {
foreach ($response->booking as $booking) {
if (isset($booking->status) && $booking->status != 'ERROR') {
$references[] = $booking->reference;
} else {
$error = true;
}
}
$reservationId = implode('*', $references);
} else {
$reservationId = (string) $response->booking->reference;
}
} else {
$error = true;
}
if (!$error) {
$session->set($transactionId.'[hotel][reservation]', json_encode($response));
$this->generate_email($session, $registry,$parameterBag, $orderProduct, $detailInfo, $response, $startDate, $endDate);
$orderProduct->setEmissiondata($reservationId);
$orderProduct->setUpdatingdate(new \DateTime());
$reservationId2 = ""/* (string) $response->Message->OTA_HotelResRS->HotelReservations->HotelReservation->ResGlobalInfo->HotelReservationIDs->HotelReservationID['ResID_Value']*/; //preguntar cual es esta
$contactNumber = is_array($response->booking)
? ($response->booking[0]->hotel->phone ?? 'No info')
: ($response->booking->hotel->phone ?? 'No info');
$company = is_array($response->booking)
? $response->booking[0]->invoiceCompany->company
: $response->booking->invoiceCompany->company;
$commentsRes = $response->booking->hotel->comments ?? '';
/* 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'])) {
$contactNumber = (string) $response->Message->OTA_HotelResRS->HotelReservations->HotelReservation->RoomStays->RoomStay->BasicPropertyInfo->ContactNumbers->ContactNumber['PhoneNumber'];
}*/
$search = ['{order_product_reservation}', '{order_product_reservation_2}', '{property_name_2}', '{contact_number}', 'PN' . (string) $orderProduct->getId(), '{product_notes}'];
$replace = [$reservationId, $reservationId2, (string) $company, $contactNumber, $reservationId, $commentsRes];
$orderXml = str_replace($search, $replace, $orderProduct->getAddProductData());
$orderProduct->setAddProductData($orderXml);
$orderProduct->setBooking($reservationId);
if ($paymentData["payment"] == 'destination') {
$status = 'approved_hotel';
$orderProduct->setStatus($status);
$orderProduct->getOrder()->setStatus($status);
}
$em->persist($orderProduct);
$em->flush();
if($isFront){
$customerId = $customer->id;
$customerEmail = $passangersDataArray['email_1_1'];
try {
$responseOrder = $aviaturWebService->busWebServiceAmadeus(null, null, $orderXml);
} catch (\Exception $e) {
}
return $this->generateUrl('aviatur_hotel_reservation_success_secureN');
} else {
$customerId = $customer->getId();
$customerEmail = $customer->getEmail();
}
if (!$isFront) {
$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();
$message = (new \Swift_Message())
->setContentType('text/html')
->setFrom('noreply@aviatur.com.co')
->setSubject('Hotel Reservation')
->setTo(['soptepagelectronic@aviatur.com', 'soportepagoelectronico@aviatur.com.co'])
->setCc(['supervisorescallcenter@aviatur.com', 'hotelesenlineaaviatur@aviatur.com'])
->setBcc(['notificacionessitioweb@aviatur.com', 'nicolas.pineros@aviatur.com'])
->setBody($emailContent);
$mailer->send($message);
}
// if (!$isFront) {se mueve este tramo de codigo por legivilidad xd
// return $this->generateUrl('aviatur_hotel_reservation_success_secureN');
// } else {
return true;
// }
} else {
$this->generate_email($session, $registry,$parameterBag, $orderProduct, $detailInfo, true, $startDate, $endDate);
$orderProduct->setEmissiondata('No Reservation');
$orderProduct->setUpdatingdate(new \DateTime());
if ($paymentData["payment"] == 'destination') {
$status = 'rejected_hotel';
$orderProduct->setStatus($status);
$orderProduct->getOrder()->setStatus($status);
}
$em->persist($orderProduct);
$em->flush();
$message = 'Ha ocurrido un error realizando la reserva del hotel, por favor intenta nuevamente o comunícate con nosotros para finalizar tu transacción';
if (isset($response->ProviderResults->ProviderResult['Message']) && isset($response->ProviderResults->ProviderResult['Provider'])) {
if ('71' == $response->ProviderResults->ProviderResult['Provider']) {
$message = $response->ProviderResults->ProviderResult['Message'];
}
}
if($providerId == 127 && $response->status == "Error") {
$message = $response->message;
}
if (!$isFront && isset($paymentData["payment"]) && $paymentData["payment"] == 'online') {
$emailContent = '
<b>No se realizó la reserva de hotel, tiene pago aprobado.</b><br/>
Info:<br/>
Referer in posaereos: '.$orderProduct->getBooking().'<br/>
The product id is: '.$orderProduct->getId().'<br/>
The customer id is: '.$customer->getId().'<br/></b>
Email customer DB: <b>'.$customer->getEmail().'</b>,<br/>
The info is: '.$orderProduct->getEmail();
$emailMessage = (new \Swift_Message())
->setContentType('text/html')
->setFrom('noreply@aviatur.com.co')
->setSubject('Hotel reservation failed with payment approved')
->setTo(['soptepagelectronic@aviatur.com', 'soportepagoelectronico@aviatur.com.co'])
->setCc(['supervisorescallcenter@aviatur.com', 'hotelesenlineaaviatur@aviatur.com'])
->setBcc(['notificacionessitioweb@aviatur.com', 'nicolas.pineros@aviatur.com'])
->setBody($emailContent);
$mailer->send($emailMessage);
return false;
} elseif( !$isFront && isset($paymentData["payment"]) && $paymentData["payment"] == 'destination'){
$reservationId;
if($reservationId == ''){
$emailContent = '
<b>No se realizó la reserva de hotel con pago en destino.</b><br/>
Info:<br/>
Referer in posaereos: '.$orderProduct->getBooking().'<br/>
The product id is: '.$orderProduct->getId().'<br/>
The customer id is: '.$customer->getId().'<br/></b>
Email customer DB: <b>'.$customer->getEmail().'</b>,<br/>
The info is: '.$orderProduct->getEmail();
}else{
$emailContent = '
<b>No se realizó alguna de las reservas de hotel con pago en destino.</b><br/>
Info:<br/>
Reservas realizadas: '.$reservationId.'<br/>
Referer in posaereos: '.$orderProduct->getBooking().'<br/>
The product id is: '.$orderProduct->getId().'<br/>
The customer id is: '.$customer->getId().'<br/></b>
Email customer DB: <b>'.$customer->getEmail().'</b>,<br/>
The info is: '.$orderProduct->getEmail();
}
$emailMessage = (new \Swift_Message())
->setContentType('text/html')
->setFrom('noreply@aviatur.com.co')
->setSubject('Hotel reservation failed with payment approved')
->setTo(['soptepagelectronic@aviatur.com', 'soportepagoelectronico@aviatur.com.co'])
->setCc(['supervisorescallcenter@aviatur.com', 'hotelesenlineaaviatur@aviatur.com'])
->setBcc(['notificacionessitioweb@aviatur.com', 'nicolas.pineros@aviatur.com'])
->setBody($emailContent);
$mailer->send($emailMessage);
return false;
}
return $aviaturErrorHandler->errorRedirectNoEmail('/buscar/hoteles', 'Erro al reservar', $message . " Front");
}
}
public function generate_email(SessionInterface $session, ManagerRegistry $registry, ParameterBagInterface $parameterBag, $orderProduct, $detailInfo, $prepaymentInfo, $startDate, $endDate)
{
$transactionIdSessionName = $parameterBag->get('transaction_id_session_name');
$transactionId = $session->get($transactionIdSessionName);
$em = $registry->getManager();
$agency = $em->getRepository(\Aviatur\AgencyBundle\Entity\Agency::class)->find($session->get('agencyId'));
$agencyData = [
'agency_name' => $agency->getName(),
'agency_nit' => $agency->getNit(),
'agency_phone' => $agency->getPhone(),
'agency_email' => $agency->getMailContact(),
];
$emailInfos = $detailInfo->data->hotelRoomlist->hotels[0];
$selectedRateKeys = $session->get($transactionId.'[hotel][selected_rooms]');
// Inicializar un array vacío para almacenar las tarifas con 'rateKey' como clave
$indexedRoomRates = [];
// Recorrer las tarifas y almacenar cada una usando 'rateKey' como clave
foreach ($detailInfo->data->hotelRoomlist->hotels[0]->rates as $rate) {
if (isset($rate->rateKey)) { // Asegúrate de que 'rateKey' existe
$indexedRoomRates[$rate->rateKey] = $rate;
}
}
// Ahora puedes acceder a las tarifas indexadas por 'rateKey'
$roomRate = $indexedRoomRates;
$roomRates = [];
// Ejemplo de acceso a un rate específico usando un 'rateKey' de $selectedRateKeys
foreach ($selectedRateKeys as $key) {
if (isset($roomRate[$key])) {
// Aquí puedes trabajar con $roomRate[$key] para cada 'rateKey' seleccionado
array_push($roomRates, clone $roomRate[$key]);
}
}
$conditionsEx = [
'checkInInfo' => isset($emailInfos->checkInInfo) ? $emailInfos->checkInInfo : null,
'checkOutInfo' => isset($emailInfos->checkOutInfo) ? $emailInfos->checkOutInfo : null,
'policies' => isset($emailInfos->policies) ? $emailInfos->policies : null,
'onSitePaymentMethods' => isset($emailInfos->onSitePaymentMethods) ? $emailInfos->onSitePaymentMethods : null,
'mandatoryFees'=> isset($emailInfos->mandatoryFees) ? $emailInfos->mandatoryFees : null,
'optionalFees'=> isset($emailInfos->optionalFees) ? $emailInfos->optionalFees : null,
];
//$emailInfos2 = $detailInfo->Message->OTA_HotelRoomListRS->HotelRoomLists->HotelRoomList->RoomStays->RoomStay->TPA_Extensions->HotelInfo;
$i = 0;
$pictures = [];
foreach ($emailInfos->gallery as $picture) {
if ($i < 3) {
$pictures[] = (string) $picture->url;
}
++$i;
}
if (0 == sizeof($pictures)) {
$domain = 'https://'.$agency->getDomain();
$pictures[0] = $domain.'/assets/aviatur_assets/img/error/noHotelPicture.jpg';
}
$cancelPolicies = (string) '';
foreach ($roomRates as $index => $room){
$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';
}
$checkinInstructions ='';
if($prepaymentInfo != null && $prepaymentInfo == true ){
//Genera el markup solo en el ultimo llamado
// provider aqui
$prov = $session->get($transactionId.'[hotel][provider]');
$provider = $em->getRepository(\Aviatur\MpaBundle\Entity\Provider::class)->findOneById($prov);
$provId = $provider->getProviderIdentifier();
$markups = $this->markupService->Markup($agency);
foreach ($roomRates as $index => $room) {
$i = 0;
$markup = false;
$aviaturMarkup = 0;
while (!$markup) {
if (($markups['providerOfConfig'][$markups['markups'][$i]['config_hotel_agency_id']] == (string) $provId )) {
if ('N' == $markups['typeOfConfig'][$markups['markups'][$i]['config_hotel_agency_id']]) {
$aviaturMarkup = (float) round($roomRates[$index]->net) * $markups['markups'][$i]['value'] / (100 - $markups['markups'][$i]['value']);
} else {
$aviaturMarkup = 0;
}
$markup = true;
}
++$i;
}
$roomRates[$index]->net = round($roomRates[$index]->net) + round($aviaturMarkup);
}
}
if (isset($prepaymentInfo->booking)) {
$bookings = is_array($prepaymentInfo->booking) ? $prepaymentInfo->booking : [$prepaymentInfo->booking];
foreach ($bookings as $booking) {
if (isset($booking->hotel->comments)) {
if (is_array($booking->hotel->comments)) {
$checkinInstructions .= implode(", ", $booking->hotel->comments);
} else {
$checkinInstructions .= $booking->hotel->comments;
}
}
}
} else {
$checkinInstructions = '{rateComments}';
}
$payable = isset($prepaymentInfo->booking)
? (is_array($prepaymentInfo->booking)
? $prepaymentInfo->booking[0]->invoiceCompany->company
: $prepaymentInfo->booking->invoiceCompany->company)
: "{payable}";
$journeySummary = [
'hotelName' => (string) $emailInfos->name,
'stars' => (string) $emailInfos->categoryCode,
'startDate' => $startDate,
'endDate' => $endDate,
'address' => (string) $emailInfos->location->address.', '.(string) $emailInfos->location->destination->name,
'phone' => (string) isset($emailInfos->phone) ? $emailInfos->phone :"",
'email' => (string) "",//$emailInfos2->Email,
'pictures' => $pictures,
'latitude' => (string) $emailInfos->location->coordinates->latitude,
'longitude' => (string) $emailInfos->location->coordinates->longitude,
'cancelPolicies' => $cancelPolicies,
'conditions' => $conditionsEx,
'checkinInstructions' => $checkinInstructions,
'payable' => $payable,
];
$emailData = [
'agencyData' => $agencyData,
'journeySummary' => $journeySummary,
'rooms' => $roomRates,
];
$orderProduct->setEmail(json_encode($emailData));
$em->persist($orderProduct);
$em->flush();
}
public function paymentOutputAction(Request $request, ExceptionLog $exceptionLog, \Swift_Mailer $mailer, AviaturPixeles $aviaturPixeles, Pdf $pdf, AuthorizationCheckerInterface $authorizationChecker, RouterInterface $router, AviaturEncoder $aviaturEncoder, TwigFolder $twigFolder, ParameterBagInterface $parameterBag,AviaturErrorHandler $aviaturErrorHandler)
{
$projectDir = $parameterBag->get('kernel.project_dir');
$transactionIdSessionName = $parameterBag->get('transaction_id_session_name');
$emailNotification = $parameterBag->get('email_notification');
$clientFranquice = [];
$paymentResume = [];
$voucherFile = null;
$em = $this->em;
$session = $this->session;
$agency = $this->agency;
$UserFront = simplexml_load_string ($session->get('front_user'));
$transactionId = $session->get($transactionIdSessionName);
$validations = $session->get($transactionId.'[hotel][alertsValidation]');
$travellerInfo = json_decode($session->get($transactionId.'[hotel][detail_data_hotel]'));
if ($session->has($transactionId.'[crossed]'.'[url-hotel]') && !$session->has($transactionId.'[multi]'.'[validation]')) {
$urlAvailability = $session->get($transactionId.'[crossed]'.'[url-hotel]');
} elseif ($session->has($transactionId.'[hotel][availability_url]')) {
$urlAvailability = $session->get($transactionId.'[hotel][availability_url]');
} else {
$urlAvailability = $session->get($transactionId.'[availability_url]');
}
$routeParsed = parse_url($urlAvailability);
if ($session->has($transactionId.'external')) {
$routeParsed['path'] = $session->get('routePath');
}
$availabilityUrl = $router->match($routeParsed['path']);
$hotelInformation = $session->get($transactionId.'[hotel][roomsInfo]');
$traveller = [];
$traveller['firstName'] = $travellerInfo->PI->first_name_1_1;
$traveller['lastName'] = $travellerInfo->PI->last_name_1_1;
if (false !== strpos($traveller['firstName'], '*')) {
$postDataJson = $session->get($transactionId.'[hotel][detail_data_hotel]');
$paymentData = json_decode($postDataJson);
$customer = $em->getRepository(\Aviatur\CustomerBundle\Entity\Customer::class)->find($paymentData->BD->id);
$traveller['firstName'] = $customer->getFirstname();
$traveller['lastName'] = $customer->getLastname();
}
$orderProductCode = $session->get($transactionId.'[hotel][order]');
$productId = str_replace('PN', '', json_decode($orderProductCode)->products);
$orderProduct = $em->getRepository(\Aviatur\GeneralBundle\Entity\OrderProduct::class)->find($productId);
$emailData = json_decode($orderProduct->getEmail(), true);
if ($session->has($transactionId.'[hotel][reservation]')) {
$reservationInfo = json_decode($session->get($transactionId.'[hotel][reservation]'));
$reservationId = '';
if (is_array($reservationInfo->booking)) {
$references = array_map(function ($booking) {
return $booking->reference;
}, $reservationInfo->booking);
$reservationId = (string) implode('*', $references);
} else {
$reservationId = (string) $reservationInfo->booking->reference;
}
$reservationId2 = (string) "";// $reservationInfo->Message->OTA_HotelResRS->HotelReservations->HotelReservation->ResGlobalInfo->HotelReservationIDs->HotelReservationID['ResID_Value'];
$traveller['ReservationID'] = $reservationId;
$traveller['HotelReservationID'] = $reservationId2;
/*
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'])) {
$emailData['journeySummary']['phone'] = (string) $reservationInfo->Message->OTA_HotelResRS->HotelReservations->HotelReservation->RoomStays->RoomStay->BasicPropertyInfo->ContactNumbers->ContactNumber['PhoneNumber'];
}*/
} else {
$traveller['ReservationID'] = null;
}
$rooms = [];
$response = json_decode($session->get($transactionId.'[hotel][detail]'));
//esto depende de la url
/*for ($i = 1; $i <= $availabilityUrl['rooms']; ++$i) {
if ('n' == $availabilityUrl['child'.$i]) {
$[$i]['child'] = 0;
} else {rooms
$rooms[$i]['child'] = substr_count($availabilityUrl['child'.$i], '-') + 1;
$rooms[$i]['childAges'] = $availabilityUrl['child'.$i];
}
$rooms[$i]['adult'] = $availabilityUrl['adult'.$i];
}*/
$postDataJson = $session->get($transactionId.'[hotel][detail_data_hotel]');
$paymentData = json_decode($postDataJson);
$opRequestInitial = json_decode($aviaturEncoder->AviaturDecode($orderProduct->getPayrequest(), $orderProduct->getPublicKey()));
$opRequest = $opRequestInitial->multi_transaction_hotel ?? $opRequestInitial;
$opResponse = json_decode($aviaturEncoder->AviaturDecode($orderProduct->getPayResponse(), $orderProduct->getPublicKey()));
if ((null != $opRequest) && (null != $opResponse)) {
$customer = $em->getRepository(\Aviatur\CustomerBundle\Entity\Customer::class)->find($paymentData->BD->id);
if (isset($opResponse->x_description)) {
$paymentResume = [
'transaction_state' => $opResponse->x_response_code,
'ta_transaction_state' => $opResponse->x_ta_response_code,
'id' => $orderProduct->getBooking(),
'id_context' => $opRequest->x_invoice_num,
'total_amount' => $opResponse->x_amount,
'currency' => $opResponse->x_bank_currency,
'amount' => 0 != $opRequest->x_amount_base ? $opRequest->x_amount_base : $opResponse->x_amount,
'iva' => $opRequest->x_tax,
'ip_address' => $opRequest->x_customer_ip,
'bank_name' => $opResponse->x_bank_name,
'cuotas' => $opRequest->x_differed,
'card_num' => '************'.substr($opRequest->x_card_num, strlen($opRequest->x_card_num) - 4),
'reference' => $opResponse->x_transaction_id,
'auth' => $opResponse->x_approval_code,
'transaction_date' => $opResponse->x_transaction_date,
'description' => $opResponse->x_description,
'reason_code' => $opResponse->x_response_reason_code,
'reason_description' => $opResponse->x_response_reason_text,
'client_names' => $opResponse->x_first_name.' '.$opResponse->x_last_name,
'client_email' => $opResponse->x_email,
];
}
} else {
$customer = null;
$paymentResume['id'] = $orderProduct->getBooking();
$paymentResume['id_context'] = json_decode($orderProductCode)->order."-".json_decode($orderProductCode)->products;
}
$paymentResume['transaction_state_cyber'] = $opResponse->x_response_code_cyber ?? '1';
if (false !== strpos($paymentData->BD->first_name, '***')) {
$customer = $em->getRepository(\Aviatur\CustomerBundle\Entity\Customer::class)->find($paymentData->BD->id);
$facturationResume = [
'customer_names' => $customer->getFirstname().' '.$customer->getLastname(),
'customer_address' => $customer->getAddress(),
'customer_doc_num' => $customer->getDocumentnumber(),
'customer_phone' => $customer->getPhone(),
'customer_email' => $customer->getEmail(),
];
} else {
$facturationResume = [
'customer_names' => $paymentData->BD->first_name.' '.$paymentData->BD->last_name,
'customer_address' => $paymentData->BD->address ?? null,
'customer_doc_num' => $paymentData->BD->doc_num,
'customer_phone' => $paymentData->BD->phone,
'customer_email' => $paymentData->BD->email ?? null,
];
}
$paymentOnline = $session->get($transactionId.'[hotel][paymentOn]');
$clientFranquice = '';
$retryCount = (int) $session->get($transactionId.'[hotel][retry]');
if ($session->has($transactionId.'[user]')) {
$responseOrder = \simplexml_load_string($session->get($transactionId.'[user]'));
} else {
$responseOrder = null;
}
$postdata = json_decode($session->get($transactionId.'[hotel][detail_data_hotel]'));
$passenger = $postdata->PI;
$em = $this->em;
//$gender = $em->getRepository(\Aviatur\CustomerBundle\Entity\Gender::class)->findOneByCode($passangersData->gender_1_1);
//$country = $em->getRepository(\Aviatur\GeneralBundle\Entity\Country::class)->findOneByIatacode($passangersData->nationality_1_1);
$customer = $em->getRepository(\Aviatur\CustomerBundle\Entity\Customer::class)->find($postdata->BD->id);
//$dbState = (null != $stateDb) ? $stateDb : 2; //pending of payment with same day autocancelation
//$passangersData->DocType_1_1 = $passangersData->doc_type_1_1; quitar el comentario luego
if (false !== strpos($passenger->first_name_1_1, '***')) {
$passenger->first_name_1_1 = $customer->getFirstname();
$passenger->last_name_1_1 = $customer->getLastname();
$passenger->phone_1_1 = $customer->getPhone();
$passenger->email_1_1 = $customer->getEmail();
$passenger->address_1_1 = $customer->getAddress();
$passenger->doc_num_1_1 = $customer->getDocumentnumber();
}
$passangersDataArray = json_decode(json_encode($passenger), true);
$totalGuests = $passangersDataArray['person_count_1'];
$guest = [];
for ($i = 1; $i <= $totalGuests; ++$i) {
$guestData = [];
$guestData['first_name'] = $passangersDataArray['first_name_1'.'_'.$i];
$guestData['last_name'] = $passangersDataArray['last_name_1'.'_'.$i];
$guestData['passanger_type'] = $passangersDataArray['passanger_type_1'.'_'.$i];
array_push($guest,$guestData);
}
$totalsite = $session->get($transactionId.'[hotel][chargesData]');
$countryCode = $session->get($transactionId.'[hotel][countryCode]');
$reservation = json_decode($session->get($transactionId.'[hotel][reservation]'));
$bookRooms =[];
if (isset($reservation) and is_array($reservation->booking)) {
foreach ($reservation->booking as $book) {
$rateKey = $book->hotel->rooms[0]->rates[0]->rateKey;
$reference = $book->reference;
if (!isset($bookRooms[$rateKey])) {
$bookRooms[$rateKey] = [];
}
$bookRooms[$rateKey][] = $reference;
}
$rateKeyCounters = [];
foreach ($emailData['rooms'] as &$book) {
$rateKey = $book["rateKey"];
if (isset($bookRooms[$rateKey])) {
if (!isset($rateKeyCounters[$rateKey])) {
$rateKeyCounters[$rateKey] = 0;
}
$index = $rateKeyCounters[$rateKey];
if (isset($bookRooms[$rateKey][$index])) {
$book["reservation"] = $bookRooms[$rateKey][$index];
$book["passenger"] = $guest[0]["first_name"] . " " . $guest[0]["last_name"];
$rateKeyCounters[$rateKey]++;
}
}
}
}
$emailData += [
'retry_count' => $retryCount,
'paymentResume' => $paymentResume,
'currency' => isset($paymentResume['currency']) ? $paymentResume['currency'] : '',
'facturationResume' => $facturationResume,
'agencyData' => $emailData['agencyData'],
'journeySummary' => $emailData['journeySummary'],
'transactionID' => $transactionId,
'rooms' => $rooms,
'traveller' => $traveller,
'ratePlan' => implode(" , " ,$hotelInformation->rateKey),
'passengers' => $passenger ,
'agent' => $responseOrder,
'guests' => $guest,
'paymentOn' => $paymentOnline == 'online' ? true : false,
'totalOnsite' => $totalsite,
'countryCode' => $countryCode,
'alertsValidation' => $validations,
'payment' => $paymentOnline
];
//validacion de parametros vacios usando en twig
$emailData["paymentResume"]["reason_description"] = isset($emailData["paymentResume"]["reason_description"]) ? $emailData["paymentResume"]["reason_description"] : "";
$emailData["paymentResume"]["auth"] = isset($emailData["paymentResume"]["auth"]) ? $emailData["paymentResume"]["auth"] : "";
$emailData["paymentResume"]["reason_code"] = isset($emailData["paymentResume"]["reason_code"]) ? $emailData["paymentResume"]["reason_code"] : "";
$emailData["paymentResume"]["reference"] = isset($emailData["paymentResume"]["reference"]) ? $emailData["paymentResume"]["reference"] : "";
$emailData["paymentResume"]["total_amount"] = isset($emailData["paymentResume"]["total_amount"]) ? $emailData["paymentResume"]["total_amount"] : "";
$emailData["paymentResume"]["currency"] = isset($emailData["paymentResume"]["currency"]) ? $emailData["paymentResume"]["currency"] : "";
$orderProduct->setEmail(json_encode($emailData));
$em->persist($orderProduct);
$em->flush();
$routeName = $request->get('_route');
$agencyFolder = $twigFolder->twigFlux();
$viewParams = $emailData;
$viewParams['status'] = $orderProduct->getStatus();
$route = $router->match(str_replace($request->getSchemeAndHttpHost(), '', $request->getUri()));
$isMulti = false !== strpos($route['_route'], 'multi') ? true : false;
// if ("aviatur_hotel_reservation_success_secureN" == $routeName) {
$bccMails = [$agency->getMailvouchers()];
$emissionData = $orderProduct->getEmissiondata();
$emailData = json_decode($orderProduct->getEmail(), true);
$viewParams = $emailData;
$emailData['status'] = $orderProduct->getStatus();
$viewParams['status'] = $orderProduct->getStatus();
$bccMails[] = 'supervisorescallcenter@aviatur.com';
if (isset($UserFront->CORREO_ELECTRONICO)) {
$setTo = (String) $UserFront->CORREO_ELECTRONICO;
} elseif (('No Reservation' != $emissionData) && ('' != $emissionData) && (null != $emissionData)) {
$setTo = (null == $customer) ? null : $customer->getEmail();
} else {
$clientEmail = $emailData["facturationResume"]['customer_email'];
$setTo = $clientEmail;
}
if (isset($UserFront->CORREO_ELECTRONICO)) {
$bccMails = null;
$bccMails[] = 'notificacionessitioweb@aviatur.com';
} elseif ($session->has('whitemark')) {
$whitemarkMail = $session->get('whitemarkMail');
if (!empty($whitemarkMail) && !$session->has('operatorId')) {
$bccMails[] = $whitemarkMail;
$bccMails[] = 'negocioselectronicos@aviatur.com.co';
$bccMails[] = 'soportepagoelectronico@aviatur.com.co';
$bccMails[] = 'soptepagelectronic@aviatur.com';
}
}
if ($emailData['status'] != 'rejected_hotel') {
if ($session->has('operatorId')) {
$urlResume = $twigFolder->twigExists('@AviaturTwig/' . $agencyFolder . '/Hotel/Default/email_rest.html.twig');
} else {
$urlResume = $twigFolder->twigExists('@AviaturTwig/' . $agencyFolder . '/Hotel/Default/email.html.twig');
}
if ($session->has('operatorId')) {
$setSubject = 'Gracias su reserva se ha generado con exito';
} else {
$setSubject = 'Gracias por su compra';
}
// dd($viewParams , $urlResume);
try {
$message = (new \Swift_Message())
->setContentType('text/html')
->setFrom($session->get('emailNoReply'))
->setTo($setTo)
->setBcc($bccMails)
->setSubject($session->get('agencyShortName') . ' - ' . $setSubject)
->setBody(
$this->renderView($urlResume, $viewParams)
);
} catch (\Exception $e) {
$bccMails[] = 'lida.lugo@aviatur.com';
$emissionData = $orderProduct->getEmissiondata();
if (('No Reservation' != $emissionData) && ('' != $emissionData) && (null != $emissionData)) {
$setTo = (null == $customer) ? null : $customer->getEmail();
} else {
$setTo = 'soptepagelectronic@aviatur.com';
}
$setSubject = 'Gracias por su compra';
$message = (new \Swift_Message())
->setContentType('text/html')
->setFrom($session->get('emailNoReply'))
->setTo($setTo)
->setBcc($bccMails)
->setSubject($session->get('agencyShortName') . ' - ' . $setSubject)
->setBody(
$this->renderView($urlResume, $emailData)
);
}
try {
if (!$isMulti) {
$mailer->send($message);
}
// $session->set($transactionId . '[emission_email]', 'emailed');
} catch (Exception $ex) {
$exceptionLog->log(
var_dump($message),
$ex
);
}
// }
if (isset($paymentResume['transaction_state']) && 1 == $paymentResume['transaction_state'] && $session->has($transactionId . '[crossed]' . '[url-hotel]')) {
$session->remove($transactionId . '[hotel]' . '[retry]');
$session->remove($transactionId . '[hotel]' . '[prepayment_check]');
$session->remove($transactionId . '[hotel]' . '[order]');
}
if ($isMulti) {
return new JsonResponse([
'emailData' => $emailData,
'viewParams' => $viewParams,
'emissionData' => $emissionData
]);
}
$urlResume = $this->generateUrl('thank_you_page_success_secure', ['on' => $orderProduct->getOrder(), 'pn' => 'PN' . $productId]);
return $this->redirect($urlResume);
}else{
$message = 'La reserva no pudo ser realizada';
$linkWA = 'https://api.whatsapp.com/send?phone=5713821616&text=';
//$urlAvailability = $session->get($transactionId . '[availability_url]');
return $this->redirect($aviaturErrorHandler->errorRedirectNoEmail($this->generateUrl('aviatur_search_hotels', []), 'Error al generar la reserva', $message ,'', $linkWA ));
}
}
/**
* validateCancellationDates()
* Valida si las fechas de cancelación de las reservas son anteriores a la fecha actual.
*
* Esta función recibe un array de reservas (Calcula internamente la fecha actual). Recorre cada reserva
* y valida si la fecha de cancelación es anterior a la fecha actual. Si alguna fecha de cancelación
* no es válida, la asigna como null. Si todas las fechas de cancelación son válidas, las conserva.
*
* @param array &$info - Un array de listado de habitaciones (modificable), donde cada reserva contiene una fecha de cancelación.
* @return array &$info - Retorna el mismo array modificado en caso de aplicarse.
* @author Ing. David Rincón
* @version 1.0
* @date 2025-01-24
* @mail david.rincon@aviatur.com
*/
private function validateCancellationDates(&$info){
$todayDate = date('Y-m-d');
$totalIndex = sizeof($info['rates']);
for($ii = 0; $ii < $totalIndex; $ii++){
if(isset($info['rates'][$ii]['cancellationPolicies'])){
if(sizeof($info['rates'][$ii]['cancellationPolicies']) > 0){
if(isset($info['rates'][$ii]['cancellationPolicies'][0]['from'])){
$cancelDate = substr($info['rates'][$ii]['cancellationPolicies'][0]['from'], 0, 10);
if($cancelDate < $todayDate){
$info['rates'][$ii]['cancellationPolicies'][0]['from'] = null;
}
}
}
}
}
}
/**
* quotationAction()
* Esta función maneja la acción de cotización de hoteles. Recibe una solicitud HTTP, procesa los datos
* necesarios para realizar la cotización y retorna una respuesta en formato JSON con los resultados de la cotización.
* @param Request $request - La solicitud HTTP que contiene los datos necesarios para realizar la cotización.
* @param AviaturLogSave $aviaturLogSave - Guardado de logs.
* @param AviaturWebService $aviaturWebService - Empleo de las webservices locales de Aviatur.
* @param AviaturErrorHandler $aviaturErrorHandler - Manejo local de los errores.
* @param \Swift_Mailer $mailer - Envío de correos.
* @param ExceptionLog $exceptionLog - Manejo del log de excepciones.
* @param Pdf $pdf - Empleo del PDF.
* @param RouterInterface $router - Funciones para enrutamiento
* @param TwigFolder $twigFolder - Manejo de las carpetas de plantillas
* @param ManagerRegistry $registry - Manejo de los objetos de Bases de Datos
* @param ParameterBagInterface $parameterBag - Manejo de los parámetros de configuración
* @return AbstractController - Retorna una plantilla informativa
* @throws \Exception - Lanza una excepción si ocurre un error durante el proceso de cotización.
* @author Ing. David Rincón <david.rincon@aviatur.com> 2025-01-29
* @version 1.0
*/
public function quotationAction(Request $fullRequest, AviaturLogSave $aviaturLogSave, AviaturWebService $aviaturWebService, AviaturErrorHandler $aviaturErrorHandler, \Swift_Mailer $mailer, ExceptionLog $exceptionLog, Pdf $pdf, RouterInterface $router, TwigFolder $twigFolder, ManagerRegistry $registry, ParameterBagInterface $parameterBag ,QuotationUtils $QuotationUtils)
{
$projectDir = $parameterBag->get('kernel.project_dir');
$transactionIdSessionName = $parameterBag->get('transaction_id_session_name');
$codImg = null;
$session = $this->session;
$agency = $this->agency;
$transactionId = $session->get($transactionIdSessionName);
$prepaymentInfo = \simplexml_load_string($session->get($transactionId . '[hotel][prepayment]'));
$agencyFolder = $twigFolder->twigFlux();
$response = json_decode($session->get($transactionId . '[hotel][detail]'));
$additionalUserFront = simplexml_load_string($session->get('front_user_additionals'));
$datosAgente = simplexml_load_string($session->get('front_user'));
/* Si no hay información de prepayment, se debe crear una de apoyo */
if(false === $prepaymentInfo){
$prepaymentInfo = [];
/* Fecha y Hora de Gasto, tomada del timestamp (se debe formatear) */
$timeStamp = $this->getObjectsTimeStamp($response->data->auditData->timestamp);
$prepaymentInfo['Message']['OTA_HotelResRS']['HotelReservations']['RoomStays']['TPA_Extensions']['CancellationPolicy']['FechaEntradaGasto'] = $timeStamp['date'];
$prepaymentInfo['Message']['OTA_HotelResRS']['HotelReservations']['RoomStays']['TPA_Extensions']['CancellationPolicy']['HoraFechaEntradaGasto'] = $timeStamp['time'];
$prepaymentInfo['Message']['HotelReservations']['HotelReservation']['RoomStays']['RoomStay']['BasicPropertyInfo']['HotelCode'] = $response->data->hotelRoomlist->hotels[0]->code;
$prepaymentInfo['Message']['HotelReservations']['HotelReservation']['RoomStays']['RoomStay']['Total']['CurrencyCode'] = $response->data->hotelRoomlist->hotels[0]->currency;
$prepaymentInfo['Message']['HotelReservations']['HotelReservation']['RoomStays']['RoomStay']['TimeSpan']['End'] = $response->data->hotelRoomlist->stay->checkOut;
$prepaymentInfo['Message']['HotelReservations']['HotelReservation']['RoomStays']['RoomStay']['TimeSpan']['Start'] = $response->data->hotelRoomlist->stay->checkIn;
$prepaymentInfo['Message']['HotelReservations']['HotelReservation']['RoomStays']['RoomStay']['BasicPropertyInfo']['HotelName'] = $response->data->hotelRoomlist->hotels[0]->name;
$prepaymentInfo['ProviderResults']['ProviderResult']['Provider'] = trim(explode(",", $response->data->auditData->providers)[0]);
}
$detailHotelRaw = $response->data->hotelRoomlist->hotels[0];
$locationHotel = $response->data->hotelRoomlist->hotels[0]->location->coordinates; /* Información estándar y general */
$dateIn = strtotime((string) $response->data->hotelRoomlist->stay->checkIn);
$dateOut = strtotime((string) $response->data->hotelRoomlist->stay->checkOut);
if ($session->has($transactionId . '[crossed]' . '[url-hotel]')) {
$urlAvailability = $session->get($transactionId . '[crossed]' . '[url-hotel]');
} elseif ($session->has($transactionId . '[hotel][availability_url]')) {
$urlAvailability = $session->get($transactionId . '[hotel][availability_url]');
} else {
$urlAvailability = $session->get($transactionId . '[availability_url]');
}
$rooms = [];
if(!is_null($urlAvailability)){
$routeParsed = parse_url($urlAvailability);
$availabilityUrl = $router->match($routeParsed['path']);
for ($i = 1; $i <= $availabilityUrl['rooms']; ++$i) {
$adult = $availabilityUrl['adult' . $i];
$child = [];
if ('n' != $availabilityUrl['child' . $i]) {
$child = sizeof(explode('-', $availabilityUrl['child' . $i]));
}
$rooms[$i] = ['adult' => $adult, 'child' => $child];
}
} else {
/* Otra alternativa por medio del contenido de la URL de la disponibilidad pero como un valor de formulario virtual */
$availabilityUrl = $fullRequest->request->get('urlAvailability');
$arrayAvailabilityUrl = explode('/', $availabilityUrl);
foreach ($arrayAvailabilityUrl as $segmentAvailabilityUrl) {
if(strpos($segmentAvailabilityUrl, 'room=') !== false){
$arrayPeople = explode('&', $segmentAvailabilityUrl);
$agesChild = str_replace('children=', '', $arrayPeople[2]);
if($agesChild == "n"){
$listChild = [];
} else {
$listChild = explode('+', $agesChild);
}
$agesAdult = str_replace('adults=', '', $arrayPeople[1]);
$ordRoom = str_replace('room=', '', $arrayPeople[0]);
$rooms[$ordRoom] = ['adult' => $agesAdult, 'child' => $listChild];
}
}
}
$codImg = $QuotationUtils->curlImg($session, '_front');
/* Aquí se deben comenzar a definir cálculos que se asocian a las opciones seleccionadas */
$selectedRates = $fullRequest->request->get('selectedRates');
$arraySelectedRates = explode(',', $selectedRates);
$selectedRatesLength = sizeof($arraySelectedRates);
$totalMinRate = 0;
$totalAdults = 0;
$totalChildren = 0;
$totalRooms = 0;
for($ii = 0; $ii < $selectedRatesLength; $ii++){
$totalMinRate += (double)$detailHotelRaw->rates[$arraySelectedRates[$ii]]->net;
$totalAdults += (int)$detailHotelRaw->rates[$arraySelectedRates[$ii]]->adults;
$totalChildren += (int)$detailHotelRaw->rates[$arraySelectedRates[$ii]]->children;
$totalRooms += (int)$detailHotelRaw->rates[$arraySelectedRates[$ii]]->rooms;
}
$totalMinRate = round($totalMinRate);
/* Objeto con datos básicos de referencia */
$addressObject = new \stdClass();
$addressObject->CityName = $detailHotelRaw->location->destination->name;
$addressObject->HotelName = $detailHotelRaw->name;
/* 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 */
$userNameAgent = $datosAgente->NOMBRE_AGENTE;
$mailAgent = $datosAgente->CORREO_ELECTRONICO;
$phoneAgent = $additionalUserFront->TELEFONO_SUCURSAL ?? $session->get('agencyDataInfo')['agency_phone'];
$addressAgent = $additionalUserFront->DIRECCION_SUCURSAL ?? $datosAgente->NOMBRE_OFICINA_PERTENECE;
$selectedRates = $fullRequest->request->get('selectedRates');
$arraySelectedRates = explode(',', $selectedRates);
$arraySelectedRoomsInformation = array();
foreach($arraySelectedRates as $selectedRate){
$arraySelectedRoomsInformation[] = json_decode($session->get($transactionId.'[hotel][detail]'))->data->hotelRoomlist->hotels[0]->rates[$selectedRate];
}
$detailHotel = [
'dateIn' => $dateIn,
'dateOut' => $dateOut,
'roomInformation' => $rooms,
'dateInStr' => (string) $response->data->hotelRoomlist->stay->checkIn,
'dateOutStr' => (string) $response->data->hotelRoomlist->stay->checkOut,
'nights' => floor(($dateOut - $dateIn) / (24 * 60 * 60)),
'adults' => (string) $totalAdults,
'children' => (string) $totalChildren,
'rooms' => (string) $totalRooms,
'timeSpan' => $response->data->auditData->timestamp,
'basicInfos' => $addressObject,
'total' => $totalMinRate,
'category' => $detailHotelRaw->categoryCode,
'description' => (string) $detailHotelRaw->description,
'email' => "", /* No hay campo con la información del correo */
'services' => $detailHotelRaw->services,
'photos' => $detailHotelRaw->gallery[0],
'agentName' => ucwords(strtolower(($additionalUserFront->NOMBRE_USUARIO ?? '') . ' ' . ($additionalUserFront->APELLIDOS_USUARIO ?? '') ?: $datosAgente->NOMBRE_AGENTE)),
'agentMail' => $mailAgent,
'agentPhone' => $phoneAgent,
'agentAddress' => $addressAgent,
'prepaymentsInfo' => $prepaymentInfo,
'namesClient' => $fullRequest->request->get('quotationName'),
'lastnamesClient' => $fullRequest->request->get('quotationLastname'),
'emailClient' => $fullRequest->request->get('quotationEmail'),
'priceTotalQuotation' => $fullRequest->request->get('quotationPriceTotal'),
'priceCurrency' => $fullRequest->request->get('quotationCurrency'),
'typeRoom' => $fullRequest->request->get('typeRoom'),
'desctiptionRoom' => $arraySelectedRoomsInformation[0]->boardName,
'infoTerms' => $fullRequest->request->get('quotationTerms'),
'infoComments' => $fullRequest->request->get('quotationComments'),
'longitude' => $locationHotel->longitude,
'latitude' => $locationHotel->latitude,
'codImg' => $codImg,
'selectedRoomsInformation' => $arraySelectedRoomsInformation,
'agentCity' => $datosAgente->CIUDAD
];
$html = $twigFolder->twigExists('@AviaturTwig/' . $agencyFolder . '/Hotel/Hotel/quotation_rest.html.twig');
$namefilepdf = 'Aviatur_cotizacion_hotel_' . $transactionId . '.pdf';
$voucherHotelFile = $projectDir . '/app/quotationLogs/hotelQuotation/' . $namefilepdf;
if (!file_exists($voucherHotelFile)) {
$pdf->setOption('page-size', 'Letter');
$pdf->setOption('margin-top', 15);
$pdf->setOption('margin-right', 0);
$pdf->setOption('margin-bottom', 15);
$pdf->setOption('margin-left', 0);
$pdf->setOption('orientation', 'portrait');
$pdf->setOption('enable-javascript', true);
$pdf->setOption('no-stop-slow-scripts', true);
$pdf->setOption('no-background', false);
$pdf->setOption('lowquality', false);
$pdf->setOption('encoding', 'utf-8');
$pdf->setOption('images', true);
$pdf->setOption('dpi', 300);
$pdf->setOption('enable-external-links', true);
$pdf->setOption('enable-internal-links', true);
$pdf->generateFromHtml($this->renderView($html, $detailHotel), $voucherHotelFile);
}
$nameProduct = str_replace(["cotizacion", "/", "check-conditions" , "rest"], "", $fullRequest->getPathInfo());
$QuotationUtils->sendQuotation($nameProduct,$voucherHotelFile, $mailer, $session, $twigFolder, $codImg, $fullRequest,$parameterBag , $aviaturWebService ,$pdf , $exceptionLog);
if (file_exists($voucherHotelFile)) {
unlink($voucherHotelFile);
}
$this->saveInformationCGS($aviaturLogSave, $aviaturWebService, $aviaturErrorHandler, $registry, $detailHotel, $fullRequest, $additionalUserFront, $agency);
/* Se devolverá a la nueva plantilla indicando que se visualice el correo para ver el PDF adjunto */
return $this->render('@AviaturTwig/' . $agencyFolder . '/Hotel/Default/resume_quotation.html.twig', ['nameProduct' => $nameProduct,]);
}
/**
* saveInformationCGS()
* Guarda la información de CGS (Customer Global Service).
* Esta función recibe la información de la cotización de un hotel y la guarda en el sistema CGS.
* @param AviaturLogSave $aviaturLogSave - Guardado de logs.
* @param AviaturWebService $aviaturWebService - Empleo de las webservices locales de Aviatur.
* @param AviaturErrorHandler $aviaturErrorHandler - Manejo local de los errores.
* @param ManagerRegistry $registry - Manejo de los objetos de Bases de Datos
* @param array $data - Información de la cotización del hotel.
* @param Customer $customer - Información del cliente.
* @param Agency $agency - Información de la agencia.
* @author Ing. David Rincón <david.rincon@aviatur.com> 2025-01-30
* @version 1.0
*/
public function saveInformationCGS(AviaturLogSave $aviaturLogSave, AviaturWebService $aviaturWebService, AviaturErrorHandler $aviaturErrorHandler, ManagerRegistry $registry, $data, $dataRequest, $customer, $agency)
{
$parametersLogin = $registry->getRepository(\Aviatur\GeneralBundle\Entity\Parameter::class)->findParameters($agency, 'aviatur_service_login_cgs');
$urlLoginCGS = $parametersLogin[0]['value'];
$parametersProduct = $registry->getRepository(\Aviatur\GeneralBundle\Entity\Parameter::class)->findParameters($agency, 'aviatur_service_hotel_cgs');
$urlAddProductHotel = $parametersProduct[0]['value'];
/*
* get token api autentication
*/
$userLoginCGS = $aviaturWebService->encryptUser(trim(strtolower($customer->CODIGO_USUARIO)), 'AviaturCGSMTK');
$jsonReq = json_encode(['username' => $userLoginCGS]);
//print_r(json_encode($data)); die;
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => $urlLoginCGS,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => $jsonReq,
CURLOPT_HTTPHEADER => [
'Content-Type: application/json',
],
]);
$response = curl_exec($curl);
$httpcode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
curl_close($curl);
if (200 != $httpcode) {
$aviaturLogSave->logSave('HTTPCODE: ' . $httpcode . ' Error usuario: ' . strtolower($customer->CODIGO_USUARIO), 'CGS', 'CGSHOTEL_ERRORLOGIN');
$aviaturLogSave->logSave(print_r($response, true), 'CGS', 'responseHotelCGS');
return $this->redirect($aviaturErrorHandler->errorRedirectNoEmail('/buscar/hoteles', 'Error Login', 'Error Login'));
} else {
$tokenInfoApiQuotation = json_decode($response);
$tokenApiQuotation = $tokenInfoApiQuotation->TOKEN;
}
/**
* Begin API data send.
*/
$ages = '';
$roms = '';
$separate = '';
for ($i = 1; $i <= (is_countable($data['roomInformation']) ? count($data['roomInformation']) : 0); ++$i) {
$ages = '';
for ($a = 0; $a < (is_countable($data['roomInformation'][$i]['child']) ? count($data['roomInformation'][$i]['child']) : 0); ++$a) {
if (0 !== $a) {
$ages .= ',' . '"' . $data['roomInformation'][$i]['child'][$a] . '"';
} else {
$ages .= '"' . $data['roomInformation'][$i]['child'][$a] . '"';
}
}
if (1 !== $i) {
$separate = ',';
} else {
$separate = '';
}
$roms .= $separate . '{
"adultOcupancy": ' . $data['roomInformation'][$i]['adult'] . ',
"availCount": null,
"boardCode": null,
"boardName": null,
"boardShortName": null,
"boardType": null,
"cancellationPolicies": [
{
"amount": null,
"dateFrom": "' . (isset($data['prepaymentsInfo']['Message']['OTA_HotelResRS']['HotelReservations']['RoomStays']['TPA_Extensions']['CancellationPolicy']['FechaEntradaGasto']) ? $data['prepaymentsInfo']['Message']['OTA_HotelResRS']['HotelReservations']['RoomStays']['TPA_Extensions']['CancellationPolicy']['FechaEntradaGasto'] : '') . '",
"respaldoFechaSalida": "' . $data['dateOutStr'] . '",
"time": "' . (isset($data['prepaymentsInfo']['Message']['OTA_HotelResRS']['HotelReservations']['RoomStays']['TPA_Extensions']['CancellationPolicy']['HoraFechaEntradaGasto']) ? $data['prepaymentsInfo']['Message']['OTA_HotelResRS']['HotelReservations']['RoomStays']['TPA_Extensions']['CancellationPolicy']['HoraFechaEntradaGasto'] : '') . '"
}
],
"childAges": [
' . $ages . '
],
"childOcupancy": ' . (is_countable($data['roomInformation'][$i]['child']) ? count($data['roomInformation'][$i]['child']) : 0) . ',
"onRequest": null,
"price": null,
"roomCharacteristic": null,
"roomCharacteristicCode": null,
"roomCode": null,
"roomCount": null,
"roomType": null,
"shrui": null
}';
}
$data_send = '{
"customer":{
"billingInformations":[
{
"active": true,
"agencyContact": "string",
"city": "' . $data['basicInfos']->CityName . '",
"colony": "string",
"country": "string",
"dateCreated": "2020-05-21T23:20:30.441Z",
"email": "string",
"extNumber": "string",
"id": 0,
"intNumber": "string",
"lastUpdated": "2020-05-21T23:20:30.441Z",
"official": "string",
"phone": {
"active": true,
"dateCreated": "2020-05-21T23:20:30.441Z",
"id": 0,
"lastUpdated": "2020-05-21T23:20:30.441Z",
"number": "string",
"type": "string",
"version": 0
},
"postalCode": "string",
"representation": "string",
"rfc": "string",
"state": "string",
"status": "string",
"street": "string",
"taxRegime": "string",
"version": 0
],
"birthDate":"true",
"city": "' . $data['basicInfos']->CityName . '",
"dateCreated":"0001-01-01T00:00:00",
"dateOfBirth":"0001-01-01T00:00:00",
"document":null,
"emails":[
{
"active": true,
"dateCreated": "' . date('Y-m-d') . '",
"emailAddress": "' . $data['emailClient'] . '",
"id": 0,
"lastUpdated": "' . date('Y-m-d') . '",
"version": 0
}
],
"exchangeRateInformations":null,
"firstName":"' . $data['namesClient'] . '",
"fullName":"' . $data['namesClient'] . ' ' . $data['lastnamesClient'] . '",
"gender":null,
"id":null,
"idAccount":null,
"idIntelisis":null,
"idUserOwner":null,
"identify":null,
"interestsForExpo":null,
"lastName":"' . $data['lastnamesClient'] . '",
"lastUpdated":"0001-01-01T00:00:00",
"mothersName":null,
"phones":[
{
"active":false,
"dateCreated":"0001-01-01T00:00:00",
"id":0,
"lastUpdated":"0001-01-01T00:00:00",
"number":null,
"type":null,
"version":0
}
],
"typeContact":null
},
"quote":null,
"selectedProduct":{
"associatedProductIndex":null,
"category": "' . $data['category'] . '",
"complementProductList": null,
"deleteInfo":null,
"description":"' . $data['description'] . '",
"packageName":"' . $data['basicInfos']->HotelName . '",
"discount":null,
"emit":false,
"fareData":{
"aditionalFee":0.0,
"airpotService":null,
"baseFare":' . str_replace('.', '', $data['priceTotalQuotation']) . ',
"cO":0.0,
"commission":0.0,
"commissionPercentage":0.0,
"complements":null,
"currency":{
"type":"' . $data['priceCurrency'] . '"
},
"equivFare":0.0,
"iva":0.0,
"otherDebit":null,
"otherTax":null,
"price":' . str_replace('.', '', $data['priceTotalQuotation']) . ',
"providerPrice":0.0,
"qSe":0.0,
"qSeIva":0.0,
"qse":null,
"revenue":0.0,
"serviceCharge":0.0,
"sureCancel":null,
"tA":0.0,
"taIva":0.0,
"tax":0.0,
"total":' . str_replace('.', '', $data['priceTotalQuotation']) . ',
"yQ":0.0,
"yQiva":0.0
},
"foodPlan":null,
"hotelDetail":{
"nightCount": ' . $data['nights'] . ',
"roomCount": ' . $data['rooms'] . '
},
"index":null,
"itinerary": {
"availToken": null,
"category": null,
"cdChain": null,
"code": "' . (isset($data['prepaymentsInfo']['Message']['HotelReservations']['HotelReservation']['RoomStays']['RoomStay']['BasicPropertyInfo']['HotelCode']) ? $data['prepaymentsInfo']['Message']['HotelReservations']['HotelReservation']['RoomStays']['RoomStay']['BasicPropertyInfo']['HotelCode'] : '') . '",
"codeCurrency": "' . (isset($data['prepaymentsInfo']['Message']['HotelReservations']['HotelReservation']['RoomStays']['RoomStay']['Total']['CurrencyCode']) ? $data['prepaymentsInfo']['Message']['HotelReservations']['HotelReservation']['RoomStays']['RoomStay']['Total']['CurrencyCode'] : '') . '",
"contractIncommingOffice": null,
"contractName": null,
"dateFrom": "' . (isset($data['prepaymentsInfo']['Message']['HotelReservations']['HotelReservation']['RoomStays']['RoomStay']['TimeSpan']['End']) ? $data['prepaymentsInfo']['Message']['HotelReservations']['HotelReservation']['RoomStays']['RoomStay']['TimeSpan']['End'] : '') . '",
"dateTo": "' . (isset($data['prepaymentsInfo']['Message']['HotelReservations']['HotelReservation']['RoomStays']['RoomStay']['TimeSpan']['Start']) ? $data['prepaymentsInfo']['Message']['HotelReservations']['HotelReservation']['RoomStays']['RoomStay']['TimeSpan']['Start'] : '') . '",
"echoToken": null,
"issueFrom": null,
"issueTo": null,
"location": [],
"nbChain": null,
"nuStars": "' . $data['category'] . '",
"pointOfInterest": null,
"promo": null,
"rooms": [
' . $roms . '
],
"topSale": null,
"txDescription": "' . $data['description'] . '",
"txDestination": "' . $data['basicInfos']->CityName . '",
"txImage": "' . (isset($data['photos']->url) ? $data['photos']->url : '') . '",
"txIssues": null,
"txName": "' . (isset($data['prepaymentsInfo']['Message']['HotelReservations']['HotelReservation']['RoomStays']['RoomStay']['BasicPropertyInfo']['HotelName']) ? $data['prepaymentsInfo']['Message']['HotelReservations']['HotelReservation']['RoomStays']['RoomStay']['BasicPropertyInfo']['HotelName'] : '') . '",
"txPrice": "' . $data['priceTotalQuotation'] . '",
"txZone": null
},
"locatorList":[],
"passengerDataList":[
{
"age":"0",
"birthday":"1899-12-31T19:00:00-05:00",
"fareData":{
"aditionalFee":0.0,
"airpotService":null,
"baseFare":0.0,
"cO":0.0,
"commission":0.0,
"commissionPercentage":0.0,
"complements":null,
"currency":null,
"equivFare":0.0,
"iva":0.0,
"otherDebit":null,
"otherTax":null,
"price":0.0,
"providerPrice":0.0,
"qSe":0.0,
"qSeIva":0.0,
"qse":null,
"revenue":0.0,
"serviceCharge":0.0,
"sureCancel":null,
"tA":0.0,
"taIva":0.0,
"tax":0.0,
"total": ' . str_replace('.', '', $data['priceTotalQuotation']) . ',
"yQ":0.0,
"yQiva":0.0
},
"gender":"",
"id":"",
"lastName":"",
"mail":"",
"mothersName":"",
"name":"",
"passengerCode":{
"accountCode":"",
"promo":false,
"realType":"ADT",
"type":"ADT"
},
"passengerContact":null,
"passengerInsuranceInfo":null,
"phone":null
}
],
"priority":"",
"productType":{
"description":"Hotel",
"typeProduct":"Hotel"
},
"quoteHost":null,
"reservationInfo":null,
"reserveProductLogList":null,
"roomType": null,
"route":{
"arrivalDate": "' . $data['dateOutStr'] . '",
"arrivalDateString": "' . $data['dateOutStr'] . '",
"arrivalDescription": "' . $data['basicInfos']->CityName . '",
"arrivalIATA": null,
"departureDate": "' . $data['dateInStr'] . '",
"departureDateString": "' . $data['dateInStr'] . '",
"departureDescription": null,
"departureIATA": null,
"destination": "' . $data['basicInfos']->CityName . '",
"flightTime": null,
"origin": null,
"providerCode": null,
"subRoutes": null
},
"savedPassenger":false,
"searchHost":null,
"selected":false,
"serviceProvider": {
"code": "' . (isset($data['prepaymentsInfo']['ProviderResults']['ProviderResult']['Provider']) ? $data['prepaymentsInfo']['ProviderResults']['ProviderResult']['Provider'] : '') . '"
},
"stayTime":null
},
"quote": {"channel":"B2C WEB"}
}';
//API URL
$url = $urlAddProductHotel;
//create a new cURL resource
$ch = curl_init($url);
//setup request to send json via POST
$payload = $data_send;
//attach encoded JSON string to the POST fields
curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
//set the content type to application/json
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'accept: application/json',
'authorization: Bearer ' . $tokenApiQuotation,
'content-type: application/json',
]);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_MAXREDIRS, 10);
curl_setopt($ch, CURLOPT_TIMEOUT, 0);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
//return response instead of outputting
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
//execute the POST request
$result = curl_exec($ch);
//close CURL resource
curl_close($ch);
/*
* End API data send
*/
}
/**
* Obtiene la marca de tiempo (timestamp) de los objetos.
*
* Esta función recibe un array de objetos y retorna un array con las marcas de tiempo (timestamps) de cada objeto.
*
* @param datetime $timeStamp - Un array de objetos que contienen una fecha y hora en formato m/d/Y HH:ii:ss.
* @return array - Retorna un array con las marcas de tiempo (timestamps) de cada objeto.
* @author Ing. David Rincón <david.rincon@aviatur.com> 2025-02-03
* @version 1.0
*/
private function getObjectsTimeStamp($timeStamp){
$originalTimeStamp = (String)$timeStamp;
$arrayTimeStamp = explode(" ", $originalTimeStamp);
$originalDate = $arrayTimeStamp[0];
$arrayOriginalDate = explode("/", $originalDate);
if(sizeof($arrayOriginalDate) <= 1){
$arrayOriginalDate = explode("-", $originalDate);
}
$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 */
$originalTime = $arrayTimeStamp[1];
if(isset($arrayTimeStamp[2])){
$arrayOriginalTime = explode(":", $originalTime);
if($arrayTimeStamp[2] == "AM" && (int)$arrayOriginalTime[0] == 12){
$arrayOriginalTime[0] = 0;
} elseif($arrayTimeStamp[2] == "PM" && (int)$arrayOriginalTime[0] < 12){
$arrayOriginalTime[0] += 12;
}
} else {
$arrayOriginalTime = explode(":", $originalTime);
$arrayOriginalTime[2] = substr($arrayOriginalTime[2], 0, 2); /* Para remover milésimas de segundo */
}
$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 */
$formattedTimeStamp = $newDate . " " . $newTime;
$newTimeStamp = strtotime($formattedTimeStamp);
$date = date('Y-m-d', $newTimeStamp);
$time = date('H:i:s', $newTimeStamp);
return ['date' => $date, 'time' => $time];
}
/**
* @Route("/build-url/{iata}/{checkIn}+{checkOut}/{adults}+{children}", name="redirect_to_coordinates")
*/
public function redirectToCoordinates(
string $iata,
string $checkIn,
string $checkOut,
string $adults,
string $children
): Response {
$homeRedirect = $this->redirect('/hoteles');
try {
$iata = strtoupper($iata);
$city = null;
$countryCode = null;
$latitude = null;
$longitude = null;
// 1. Buscar en search_cities
$searchCity = $this->em->getRepository(SearchCities::class)->findOneBy(['iata' => $iata]);
if ($searchCity) {
$city = $searchCity->getCity();
$countryCode = strtolower($searchCity->getCountryCode());
// Coordenadas desde JSON
$coordinates = json_decode($searchCity->getCoordinates(), true);
if ($coordinates && isset($coordinates['latitude'], $coordinates['longitude'])) {
$latitude = $coordinates['latitude'];
$longitude = $coordinates['longitude'];
}
} else {
// 2. Buscar en search_airports como fallback
$searchAirport = $this->em->getRepository(SearchAirports::class)->findOneBy(['iata' => $iata]);
if (!$searchAirport) {
throw new \InvalidArgumentException("No se encontró ciudad ni aeropuerto para el IATA {$iata}");
}
$city = $searchAirport->getCity();
$countryCode = strtolower($searchAirport->getCountryCode());
// No usamos coordenadas aquí porque no están disponibles en SearchAirports
throw new \RuntimeException("El aeropuerto {$iata} no tiene coordenadas disponibles.");
}
if (!$latitude || !$longitude) {
throw new \RuntimeException("No se pudieron obtener las coordenadas para el IATA {$iata}");
}
// Construir destino
$destinationLabel = sprintf('%s(%s)', $city, $countryCode);
$destinationLabelEncoded = str_replace(['%28', '%29'], ['(', ')'], rawurlencode($destinationLabel));
$coordinateString = "{$latitude},{$longitude}";
$destinationUrl = sprintf(
'/hoteles/avail/%s/%s/%s+%s/room=1&adults=%s&children=%s/online',
$destinationLabelEncoded,
$coordinateString,
$checkIn,
$checkOut,
$adults,
$children
);
return $this->redirect($destinationUrl);
} catch (\Throwable $e) {
return $homeRedirect;
}
}
}