src/MDS/VenuesBundle/Controller/ReservationsQuoteController.php line 322

Open in your IDE?
  1. <?php
  2. namespace App\MDS\VenuesBundle\Controller;
  3. use App\Entity\HtFile;
  4. use App\Entity\ReservationLoungeWebDescription;
  5. use App\Entity\SageArticle;
  6. use App\Entity\SageVatRates;
  7. use App\Entity\WidgetNotes;
  8. use App\Form\WidgetNotesType;
  9. use App\MDS\AvexpressBundle\Entity\AveFiles;
  10. use App\MDS\VenuesBundle\Entity\Reservation;
  11. use App\MDS\VenuesBundle\Entity\ReservationAvailability;
  12. use App\MDS\VenuesBundle\Entity\ReservationInvoiceItems;
  13. use App\MDS\VenuesBundle\Entity\ReservationLoungeSimple;
  14. use App\MDS\VenuesBundle\Entity\ReservationLoungeSimpleServiceLog;
  15. use App\MDS\VenuesBundle\Entity\ReservationService;
  16. use App\MDS\VenuesBundle\Entity\ReservationGpPrice;
  17. use App\MDS\VenuesBundle\Entity\ReservationLounge;
  18. use App\MDS\VenuesBundle\Entity\ReservationLoungeDetails;
  19. use App\MDS\VenuesBundle\Entity\ReservationLoungeProfile;
  20. use App\MDS\VenuesBundle\Entity\ReservationPeriod;
  21. use App\MDS\VenuesBundle\Form\ReservationGpPriceType;
  22. use App\MDS\VenuesBundle\Form\ReservationLoungeDetailsType;
  23. use App\MDS\VenuesBundle\Form\ReservationLoungeProfileType;
  24. use App\MDS\VenuesBundle\Form\ReservationPeriodType;
  25. use App\MDS\VenuesBundle\Form\ReservationType;
  26. use App\Service\ReservationConflictService;
  27. use Doctrine\ORM\EntityManagerInterface;
  28. use Symfony\Component\Routing\Annotation\Route;
  29. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  30. use Symfony\Component\HttpFoundation\Request;
  31. use DateTime;
  32. use DatePeriod;
  33. use DateInterval;
  34. use Google_Client;
  35. use Google_Service_Calendar;
  36. use Symfony\Component\HttpFoundation\JsonResponse;
  37. use Symfony\Contracts\Translation\TranslatorInterface;
  38. use App\Service\AgendaService;
  39. use App\Service\VenueService;
  40. use Symfony\Component\HttpFoundation\Session\SessionInterface;
  41. class ReservationsQuoteController extends AbstractController
  42. {
  43.     private Google_Client $googleCalendar;
  44.     private TranslatorInterface $translator;
  45.     private AgendaService $agendaService;
  46.     private SessionInterface $session;
  47.     private VenueService $venueService;
  48.     private \App\Service\ReservationService $reservationService;
  49.     private \App\Service\DocContractService $docContractService;
  50.     public function __construct(
  51.         TranslatorInterface $translator,
  52.         AgendaService $agendaService,
  53.         VenueService $venueService,
  54.         SessionInterface $session,
  55.         \App\Service\ReservationService $reservationService,
  56.         \App\Service\DocContractService $docContractService
  57.     ) {
  58.         $redirect_uri = 'https://' . $_SERVER['HTTP_HOST'] . '/calendar/token';
  59.         $googleCalendar = new Google_Client();
  60.         $googleCalendar->setApplicationName('Google Calendar API PHP Quickstart');
  61.         //campos a extraer de la base de datos User
  62.         $googleCalendar->setClientId('2790497987-57qc3vu4pr7vb0s8phpub2me58pe34lb.apps.googleusercontent.com');
  63.         $googleCalendar->setClientSecret('nj2C7unaTO68DRhyORsyipSj');
  64.         //fin campos user
  65. //        $api_key = "AIzaSyBR84cS1IU2BPvk5V3VnbqdkJESlv440Ac";
  66. //        $client->setDeveloperKey($api_key);
  67.         $googleCalendar->setRedirectUri($redirect_uri);
  68.         $googleCalendar->addScope(Google_Service_Calendar::CALENDAR);
  69.         $guzzleClient = new \GuzzleHttp\Client(array('curl' => array(CURLOPT_SSL_VERIFYPEER => false)));
  70.         $googleCalendar->setHttpClient($guzzleClient);
  71.         $this->googleCalendar = $googleCalendar;
  72.         $this->translator = $translator;
  73.         $this->agendaService = $agendaService;
  74.         $this->venueService = $venueService;
  75.         $this->session = $session;
  76.         $this->reservationService = $reservationService;
  77.         $this->docContractService = $docContractService;
  78.     }
  79.     /**
  80.      * @Route("/createsimplelounge/{id}", name="reservations_venues_create_simple_lounge")
  81.      * Crea un Reservation Lounge Simple en la cotizacion
  82.      */
  83.     public function createSimpleLoungeAction($id, EntityManagerInterface $em, ReservationConflictService $conflictService, Request $request)
  84.     {
  85.         $simpleLounge = $request->request->all()['reservation_sala'] ?? [];
  86.         // Sala precargada
  87.         $loungeProfile = $em->getRepository(ReservationLoungeDetails::class)
  88.             ->findOneById($simpleLounge['salaPrecargadas'] ?? null);
  89.         if (!$loungeProfile) {
  90.             $this->addFlash('mensajereservationerror', 'La sala seleccionada no existe.');
  91.             return $this->redirectToRoute('reservations_venues_edit', ['id' => $id]);
  92.         }
  93.         $loungeId = $loungeProfile->getId();
  94.         $loungeDetails = $em->getRepository(ReservationLoungeDetails::class)->findOneById($loungeId);
  95.         // Nombre de sala, necesario para Sage
  96.         $loungeName = '';
  97.         if ($loungeDetails && method_exists($loungeDetails, 'getName')) {
  98.             $loungeName = (string) $loungeDetails->getName();
  99.         } elseif (!empty($simpleLounge['loungeName'])) {
  100.             $loungeName = (string) $simpleLounge['loungeName'];
  101.         }
  102.         if ($loungeName === '') {
  103.             $this->addFlash('mensajereservationerror', 'No se pudo determinar el nombre de la sala.');
  104.             return $this->redirectToRoute('reservations_venues_edit', ['id' => $id]);
  105.         }
  106.         // ¿Existe ya esta sala en la misma reserva y rank?
  107.         $previusLoungeSimple = $em->getRepository(ReservationLoungeSimple::class)->findOneBy([
  108.             'idLounge' => $loungeId,
  109.             'idReservation' => $id,
  110.             'rankQuote' => $simpleLounge['idQuote'] ?? null
  111.         ]);
  112.         // Heredar idioma si existe alguna sala previa en la reserva
  113.         $anyLoungeSimple = $em->getRepository(ReservationLoungeSimple::class)->findOneBy([
  114.             'idLounge' => $loungeId,
  115.             'idReservation' => $id
  116.         ]);
  117.         $idioma = $anyLoungeSimple ? (int) $anyLoungeSimple->getLanguage() : 1;
  118.         // Descripciones web por sala/idioma con fallbacks
  119.         $loungeWebDescriptionRepo = $em->getRepository(ReservationLoungeWebDescription::class);
  120.         $loungeWebDescription = $loungeWebDescriptionRepo->findOneBy([
  121.             'lounge' => $loungeProfile,
  122.             'language' => $idioma
  123.         ]) ?? ($idioma !== 1 ? $loungeWebDescriptionRepo->findOneBy([
  124.                 'lounge' => $loungeProfile,
  125.                 'language' => 1
  126.             ]) : null) ?? $loungeWebDescriptionRepo->findOneBy(['lounge' => $loungeProfile]);
  127.         // Summary recibido del formulario (opcional)
  128.         $loungeSummaryDescription = is_array($simpleLounge) && array_key_exists('importantDescription', $simpleLounge)
  129.             ? (string) $simpleLounge['importantDescription']
  130.             : null;
  131.         if (empty($previusLoungeSimple)) {
  132.             // Sin anterior, tiramos de WebDescription si existe
  133.             $loungeImportantDescGeneralText = $loungeWebDescription ? $loungeWebDescription->getImportantDescGeneralText() : '';
  134.             $loungeImportantDescSchedules = $loungeWebDescription ? $loungeWebDescription->getImportantDescSchedules() : '';
  135.             $loungeImportantDescParking = $loungeWebDescription ? $loungeWebDescription->getImportantDescParking() : '';
  136.             if (empty($loungeSummaryDescription)) {
  137.                 $loungeSummaryDescription = $loungeWebDescription ? $loungeWebDescription->getImportantDescription() : '';
  138.             }
  139.         } else {
  140.             // Heredamos de la simple existente
  141.             $loungeSummaryDescription = $previusLoungeSimple->getImportantDescription();
  142.             $loungeImportantDescGeneralText = $previusLoungeSimple->getImportantDescGeneralText();
  143.             $loungeImportantDescSchedules = $previusLoungeSimple->getImportantDescSchedules();
  144.             $loungeImportantDescParking = $previusLoungeSimple->getImportantDescParking();
  145.         }
  146.         // Reserva para calcular sucoe e IVA
  147.         $reservation = $em->getRepository(Reservation::class)->findOneById($id);
  148.         if (!$reservation) {
  149.             $this->addFlash('mensajereservationerror', 'No se encontró la reserva.');
  150.             return $this->redirectToRoute('reservations_venues_edit', ['id' => $id]);
  151.         }
  152.         $sucoe = (bool) $reservation->isSucoe();
  153.         $sageVatRate = $em->getRepository(SageVatRates::class)->findOneBy([
  154.             'sageCode' => $sucoe ? '00' : '03'
  155.         ]);
  156.         // Artículo Sage por nombre de sala + tipo IVA
  157.         $sageArticle = $em->getRepository(SageArticle::class)->findOneBy([
  158.             'vatType' => $sageVatRate,
  159.             'name' => $loungeName
  160.         ]);
  161.         // Solo salta el error si no se ha encontrado el artículo y está el modulo de Sage activo
  162.         if (!$sageArticle && $this->session->get('_config')['msage']) {
  163.             $this->addFlash('mensajereservationerror', 'No se ha encontrado el artículo de Sage para la sala: ' . $loungeName);
  164.             return $this->redirectToRoute('reservations_venues_edit', ['id' => $id]);
  165.         }
  166.         // Normalización horas desde POST
  167.         $hourMinStart = (string) ($simpleLounge['hourStart'] ?? '');
  168.         $hourMinEnd = (string) ($simpleLounge['hourEnd'] ?? '');
  169.         // Normalización horas desde POST usando el servicio
  170.         $startData = $this->reservationService->formatTimeInput((string) ($simpleLounge['hourStart'] ?? ''));
  171.         $endData = $this->reservationService->formatTimeInput((string) ($simpleLounge['hourEnd'] ?? ''));
  172.         $hourStart = $startData['hour'];
  173.         $minStart = $startData['min'];
  174.         $hourEnd = $endData['hour'];
  175.         $minEnd = $endData['min'];
  176.         $dateStart = new \DateTime(($simpleLounge['dateStart'] ?? date('Y-m-d')) . ' ' . $startData['formatted']);
  177.         $dateEnd = new \DateTime(($simpleLounge['dateStart'] ?? date('Y-m-d')) . ' ' . $endData['formatted']); // un solo día
  178.         $servicePrice = (float) ($simpleLounge['servicePrice'] ?? 0);
  179.         $idReservation = (int) $id;
  180.         // Usuario
  181.         $user_logueado = $this->get('security.token_storage')->getToken()->getUser();
  182.         $user_id = $user_logueado ? $user_logueado->getId() : null;
  183.         $createdAt = new \DateTime('now');
  184.         $updatedAt = new \DateTime('now');
  185.         $pax = (int) ($simpleLounge['pax'] ?? 0);
  186.         // Rank de cotización
  187.         $qb = $em->getRepository(ReservationLoungeSimple::class)->createQueryBuilder('r');
  188.         $reservationAll = $qb->where('r.idReservation = :idReservation')
  189.             ->setParameter('idReservation', $id)
  190.             ->orderBy('r.rankQuote', 'ASC')
  191.             ->getQuery()
  192.             ->getResult();
  193.         $newRankId = (!empty($reservationAll)) ? (end($reservationAll)->getRankQuote() + 1) : 1;
  194.         if (!empty($simpleLounge['idQuote']) && is_numeric($simpleLounge['idQuote'])) {
  195.             $newRankId = (int) $simpleLounge['idQuote'];
  196.         }
  197.         // Tipo: Dia de evento (null), Montaje o Desmontaje
  198.         $typeXLounge = empty($simpleLounge['type']) ? null : $simpleLounge['type'];
  199.         // Crear la entidad
  200.         $lounge = new ReservationLoungeSimple();
  201.         $lounge->setIdLounge($loungeId);
  202.         $lounge->setHourStart($hourStart);
  203.         $lounge->setMinStart($minStart);
  204.         $lounge->setHourEnd($hourEnd);
  205.         $lounge->setMinEnd($minEnd);
  206.         $lounge->setLoungeName($loungeName);
  207.         $lounge->setDateStart($dateStart);
  208.         $lounge->setDateEnd($dateEnd);
  209.         $lounge->setRankQuote($newRankId);
  210.         $lounge->setIdReservation($idReservation);
  211.         $lounge->setType($typeXLounge);
  212.         $lounge->setSageIva($sageVatRate);
  213.         $lounge->setOpIva(1);
  214.         $lounge->setCreatedAt($createdAt);
  215.         $lounge->setCreatedBy($user_id);
  216.         $lounge->setUpdatedAt($updatedAt);
  217.         $lounge->setUpdatedBy($user_id);
  218.         $lounge->setPax($pax);
  219.         $lounge->setImportantDescription($loungeSummaryDescription ?? '');
  220.         $lounge->setImportantDescGeneralText($loungeImportantDescGeneralText ?? '');
  221.         $lounge->setImportantDescSchedules($loungeImportantDescSchedules ?? '');
  222.         $lounge->setImportantDescParking($loungeImportantDescParking ?? '');
  223.         // Precio tarifario
  224.         $price = $this->reservationService->getTariffPrice($dateStart, $loungeId, $servicePrice);
  225.         $lounge->setServicePrice($price);
  226.         // Vincular la sala al artículo
  227.         $lounge->setSageArticle($sageArticle);
  228.         // El paquete de Audiovisuales generalmente se mostrará
  229.         $lounge->setShowAudiovisualPackage(true);
  230.         try {
  231.             // Verificamos si se puede agregar la sala sin generar conflictos
  232.             $conflictos = $conflictService->checkSingleLoungeConflict($lounge, $id);
  233.             if (empty($conflictos)) {
  234.                 $em->persist($lounge);
  235.                 $em->flush();
  236.                 $event = 'Se ha agregado la nueva sala';
  237.                 $successMessage = $this->translator->trans($event);
  238.                 $this->addFlash('mensajereservation', $successMessage);
  239.             } else {
  240.                 $event = 'Agregar esta sala genera conflicto con la reserva: '. $conflictos[0]['reservationId'].' - '.$conflictos[0]['reservationTitle'];
  241.                 $errorMessage = $this->translator->trans($event);
  242.                 $this->addFlash('mensajereservationerror', $errorMessage);
  243.                 return $this->redirectToRoute(
  244.                     'reservations_venues_edit_simple',
  245.                     array(
  246.                         'id' => $id,
  247.                         'token' => null,
  248.                         '_fragment' => null
  249.                     )
  250.                 );
  251.             }
  252.         } catch (\Exception $e) {
  253.             $event = 'An error occurred: ' . $e->getMessage();
  254.             $errorMessage = $this->translator->trans($event);
  255.             $this->addFlash('mensajereservationerror', $errorMessage);
  256.         }
  257.         //Se llama al servicio para crear la entrada en la agenda y actualizar el Pax de la agenda
  258.         $loungeNameAgenda = empty($typeXLounge) ? $loungeName : $loungeName . ' ( ' . $typeXLounge . ' ) ';
  259.         $agenda = $this->agendaService->createAgendaFromSource($idReservation, 'SALAS A UTILIZAR', null, null, $dateStart, $dateEnd, $loungeNameAgenda, $lounge->getId(), 'ReservationLoungeSimple', $user_id);
  260.         $paxAge = $this->agendaService->calculatePaxForReservation($idReservation);
  261.         $agenda = $this->agendaService->updatePaxLine($idReservation, $paxAge, $user_id);
  262.         // Actualizar fechas de la reserva usando el servicio
  263.         if ($reservation) {
  264.             $this->reservationService->updateReservationDates($reservation);
  265.             //Se llama al servicio para crear la entrada en la agenda de las fechas
  266.             $this->agendaService->updateDatesLine($idReservation, $user_id);
  267.         }
  268.         // Creamos la Snapshot de las salas y servicios del sistema (LOG)
  269.         $version = $this->venueService->createSnapshot($reservation);
  270.         // Sincronizar contratos si está confirmado
  271.         if ($reservation->getStatus() === 'Confirmed') {
  272.             $this->docContractService->autoAssignContracts($reservation, $user_logueado);
  273.         }
  274.         // Redirección para agregar servicio de limpieza
  275.         return $this->redirectToRoute('reservations_white_addservices_cleaning', [
  276.             'resid' => $id,
  277.             'loungesimpleid' => $lounge->getId(),
  278.         ]);
  279.     }
  280.     /**
  281.      * @Route("/api/get-price", name="get_reservations_price_to_view", methods={"GET"})
  282.      */
  283.     public function getPrice(Request $request)
  284.     {
  285.         $loungeId = $request->query->get('sala');
  286.         $dateStart = $request->query->get('date');
  287.         if (!$loungeId || !$dateStart) {
  288.             return new JsonResponse(['error' => 'Missing parameters'], 400);
  289.         }
  290.         try {
  291.             $dateStartObj = new \DateTime($dateStart);
  292.         } catch (\Exception $e) {
  293.             return new JsonResponse(['error' => 'Invalid date'], 400);
  294.         }
  295.         $price = $this->reservationService->getTariffPrice($dateStartObj, $loungeId, 0);
  296.         return new JsonResponse(['price' => $price]);
  297.     }
  298.     /**
  299.      * @Route("/createsimpleloungemondes/{id}", name="reservations_venues_create_simple_lounge_mondes")
  300.      * Se crea un dia de montaje o desmontaje
  301.      */
  302.     public function createSimpleLoungeMonDesAction($id, EntityManagerInterface $em, Request $request)
  303.     {
  304.         $simpleLounge = $request->request->get('reservation_sala_mondes');
  305.         $loungeId = $simpleLounge['idLounge'];
  306.         $loungeDetails = $em->getRepository(ReservationLoungeDetails::class)->findOneById($loungeId);
  307.         $previusLoungeSimple = $em->getRepository(ReservationLoungeSimple::class)->findOneBy(array('idLounge' => $loungeId, 'idReservation' => $id, 'rankQuote' => $simpleLounge['idQuote']));
  308.         $loungeName = $loungeDetails->getName();
  309.         $hourMinStart = $simpleLounge['hourStart'];
  310.         $hourMinEnd = $simpleLounge['hourEnd'];
  311.         // Buscamos la reserva que es para saber si es sucoe o no
  312.         $reservation = $em->getRepository(Reservation::class)->findOneById($id);
  313.         $sucoe = $reservation->isSucoe();
  314.         // Si no es sucoe, cogemos el IVA del 21% y si lo es, entonces el del 0%
  315.         if (!$sucoe) {
  316.             $sageVatRate = $em->getRepository(SageVatRates::class)->findOneBy(['sageCode' => '03']);
  317.         } else {
  318.             $sageVatRate = $em->getRepository(SageVatRates::class)->findOneBy(['sageCode' => '00']);
  319.         }
  320.         $sageArticle = $em->getRepository(SageArticle::class)->findOneBy(['vatType' => $sageVatRate, 'name' => $loungeName]);
  321.         // Si no se ha encontrado el artículo de Sage.
  322.         if (empty($sageArticle)) {
  323.             $this->addFlash('mensajereservationerror', 'No se ha encontrado el artículo de Sage para la sala: ' . $loungeName);
  324.             return $this->redirectToRoute('reservations_venues_edit', array(
  325.                 'id' => $id,
  326.             ));
  327.         }
  328.         if (empty($previusLoungeSimple)) {
  329.             $loungeSummaryDescription = $loungeDetails->getImportantDescription();
  330.             $loungeImportantDescGeneralText = $loungeDetails->getImportantDescGeneralText();
  331.             $loungeImportantDescSchedules = $loungeDetails->getImportantDescSchedules();
  332.             $loungeImportantDescParking = $loungeDetails->getImportantDescParking();
  333.         } else {
  334.             $loungeSummaryDescription = $previusLoungeSimple->getImportantDescription();
  335.             $loungeImportantDescGeneralText = $previusLoungeSimple->getImportantDescGeneralText();
  336.             $loungeImportantDescSchedules = $previusLoungeSimple->getImportantDescSchedules();
  337.             $loungeImportantDescParking = $previusLoungeSimple->getImportantDescParking();
  338.         }
  339.         $qb = $em->getRepository(ReservationLoungeSimple::class)->createQueryBuilder('r');
  340.         $reservationAll = $qb->where('r.idReservation = :idReservation')
  341.             ->setParameter('idReservation', $id)
  342.             ->orderBy('r.rankQuote', 'ASC')
  343.             ->getQuery()
  344.             ->getResult();
  345.         $newRankId = (!empty($reservationAll)) ? (end($reservationAll)->getRankQuote() + 1) : 1;
  346.         if (!empty($simpleLounge['idQuote'])) {
  347.             if (is_numeric($simpleLounge['idQuote'])) {
  348.                 $newRankId = $simpleLounge['idQuote'];
  349.             }
  350.         }
  351.         // Normalización horas desde POST usando el servicio
  352.         $startData = $this->reservationService->formatTimeInput((string) ($simpleLounge['hourStart'] ?? ''));
  353.         $endData = $this->reservationService->formatTimeInput((string) ($simpleLounge['hourEnd'] ?? ''));
  354.         $hourStart = $startData['hour'];
  355.         $minStart = $startData['min'];
  356.         $hourEnd = $endData['hour'];
  357.         $minEnd = $endData['min'];
  358.         $hourMinStart = $startData['formatted'];
  359.         $hourMinEnd = $endData['formatted'];
  360.         $dateStart = new DateTime($simpleLounge['dateStart'] . ' ' . $hourMinStart);
  361.         $dateEnd = new DateTime($simpleLounge['dateStart'] . ' ' . $hourMinEnd);   // Se usa DateStart por que solo hay un dia en el formulario
  362.         $servicePrice = empty($simpleLounge['servicePrice']) ? 0 : $simpleLounge['servicePrice'];
  363.         $idReservation = $id;
  364.         /* Obtengo usuario logueado */
  365.         $user_logueado = $this->get('security.token_storage')->getToken()->getUser();
  366.         $user_id = $user_logueado->getId();
  367.         $createdAt = new DateTime('now');
  368.         $createdBy = $user_id;
  369.         $updatedAt = new DateTime('now');
  370.         $updatedBy = $user_id;
  371.         $lounge = new ReservationLoungeSimple();
  372.         if ($simpleLounge['type'] == 'Montaje') {
  373.             $lounge->setType('Montaje');
  374.         } else {
  375.             $lounge->setType('Desmontaje');
  376.         }
  377.         $pax = 0;
  378.         $lounge->setIdLounge($loungeId);
  379.         $lounge->setHourStart($hourStart);
  380.         $lounge->setMinStart($minStart);
  381.         $lounge->setHourEnd($hourEnd);
  382.         $lounge->setMinEnd($minEnd);
  383.         $lounge->setLoungeName($loungeName);
  384.         $lounge->setDateStart($dateStart);
  385.         $lounge->setDateEnd($dateEnd);
  386.         $lounge->setRankQuote(1);
  387.         $lounge->setSageIva($sageArticle->getVatType());
  388.         $lounge->setOpIva(1);
  389.         $lounge->setIdReservation($idReservation);
  390.         $lounge->setCreatedAt($createdAt);
  391.         $lounge->setCreatedBy($createdBy);
  392.         $lounge->setUpdatedAt($updatedAt);
  393.         $lounge->setUpdatedBy($updatedBy);
  394.         $lounge->setPax($pax);
  395.         $lounge->setRankQuote($newRankId);
  396.         $lounge->setImportantDescription($loungeSummaryDescription);
  397.         $lounge->setImportantDescGeneralText($loungeImportantDescGeneralText);
  398.         $lounge->setImportantDescSchedules($loungeImportantDescSchedules);
  399.         $lounge->setImportantDescParking($loungeImportantDescParking);
  400.         $price = 0; // Se asume 0 según lógica de precioPorFecha original que era inalcanzable
  401.         $servicePrice = ($price == 0) ? $servicePrice : $price;
  402.         $lounge->setServicePrice($servicePrice);
  403.         // Vincular la sala al artículo
  404.         $lounge->setSageArticle($sageArticle);
  405.         try {
  406.             $em->persist($lounge);
  407.             $em->flush();
  408.             $event = 'The Reservation has been updated.';
  409.             $successMessage = $this->translator->trans($event);
  410.             $this->addFlash('mensajereservation', $successMessage);
  411.         } catch (\Exception $e) {
  412.             $event = 'An error occurred: ' . $e->getMessage();
  413.             $errorMessage = $this->translator->trans($event);
  414.             $this->addFlash('mensajereservationerror', $errorMessage);
  415.         }
  416.         $reservax = $em->getRepository(Reservation::class)->findOneById($idReservation);
  417.         if ($reservax) {
  418.             $this->reservationService->updateReservationDates($reservax);
  419.             
  420.             // Sincronizar contratos si está confirmado
  421.             if ($reservax->getStatus() === 'Confirmed') {
  422.                 $this->docContractService->autoAssignContracts($reservax, $user_logueado);
  423.             }
  424.         }
  425.         // FIN: Verificamos si es necesario actualizar las fechas de la reserva
  426.         return $this->redirectToRoute(
  427.             'reservations_venues_edit_simple',
  428.             array(
  429.                 'id' => $id,
  430.                 'token' => null,
  431.                 '_fragment' => 'btn_quotes'
  432.             )
  433.         );
  434.     }
  435.     /**
  436.      * @Route("/duplicateday/{id}/{dayduplicate}/{idRankQuote}", name="reservations_venues_duplicate_day")
  437.      * Duplica un elemento de la cotizacion para el dia siguiente
  438.      */
  439.     public function duplicateDayAction($id, $dayduplicate, $idRankQuote, EntityManagerInterface $em, Request $request)
  440.     {
  441.         $loungeSimples = $em->getRepository(ReservationLoungeSimple::class)->findByIdReservation($id);
  442.         $reservax = $em->getRepository(Reservation::class)->findOneById($id);
  443.         $vatRepo = $em->getRepository(SageVatRates::class);
  444.         /* Usuario logueado */
  445.         $user = $this->get('security.token_storage')->getToken()->getUser();
  446.         $user_id = $user ? $user->getId() : null;
  447.         $createdAt = new \DateTime('now');
  448.         $updatedAt = new \DateTime('now');
  449.         $createdBy = $user_id;
  450.         $updatedBy = $user_id;
  451.         if (!empty($loungeSimples)) {
  452.             foreach ($loungeSimples as $item) {
  453.                 if (
  454.                     $item->getDateStart() &&
  455.                     $item->getDateStart()->format('d-m-Y') == $dayduplicate &&
  456.                     $item->getRankQuote() == $idRankQuote
  457.                 ) {
  458.                     // Se duplica y suma un día (sin mutar el original)
  459.                     $newLoungeSimple = new ReservationLoungeSimple();
  460.                     $newLoungeSimple->setDateStart((clone $item->getDateStart())->modify('+1 day'));
  461.                     $newLoungeSimple->setDateEnd((clone $item->getDateEnd())->modify('+1 day'));
  462.                     $newLoungeSimple->setHourStart($item->getHourStart());
  463.                     $newLoungeSimple->setHourEnd($item->getHourEnd());
  464.                     $newLoungeSimple->setMinStart($item->getMinStart());
  465.                     $newLoungeSimple->setMinEnd($item->getMinEnd());
  466.                     $newLoungeSimple->setIdLounge($item->getIdLounge());
  467.                     $newLoungeSimple->setIdReservation($item->getIdReservation());
  468.                     $newLoungeSimple->setLoungeName($item->getLoungeName());
  469.                     $newLoungeSimple->setPax($item->getPax());
  470.                     $newLoungeSimple->setServicePrice($item->getServicePrice());
  471.                     // IVA (string)
  472.                     $newLoungeSimple->setIva($item->getIva());
  473.                     // Relación SageVatRates (entidad)
  474.                     $vatEntity = method_exists($item, 'getSageIva') ? $item->getSageIva() : null;
  475.                     if (!$vatEntity) {
  476.                         $rawRate = $item->getIva();
  477.                         if ($rawRate !== null && $rawRate !== '') {
  478.                             $rate = (float) $rawRate;
  479.                             // Normaliza si en BD está como fracción (0.21)
  480.                             if ($rate > 1) {
  481.                                 $rate = $rate / 100;
  482.                             }
  483.                             // Ajusta 'rate' si tu campo en SageVatRates tiene otro nombre
  484.                             $vatEntity = $vatRepo->findOneBy(['rate' => $rate]);
  485.                         }
  486.                     }
  487.                     $newLoungeSimple->setSageIva($vatEntity);
  488.                     $newLoungeSimple->setOpIva($item->getOpIva());
  489.                     $newLoungeSimple->setType($item->getType());
  490.                     $newLoungeSimple->setLoungeDescription($item->getLoungeDescription());
  491.                     $newLoungeSimple->setImportantDescription($item->getImportantDescription());
  492.                     $newLoungeSimple->setImportantDescGeneralText($item->getImportantDescGeneralText());
  493.                     $newLoungeSimple->setImportantDescSchedules($item->getImportantDescSchedules());
  494.                     $newLoungeSimple->setImportantDescParking($item->getImportantDescParking());
  495.                     $newLoungeSimple->setRankQuote($idRankQuote);
  496.                     $newLoungeSimple->setCreatedAt($createdAt);
  497.                     $newLoungeSimple->setCreatedBy($createdBy);
  498.                     $newLoungeSimple->setUpdatedAt($updatedAt);
  499.                     $newLoungeSimple->setUpdatedBy($updatedBy);
  500.                     try {
  501.                         $em->persist($newLoungeSimple);
  502.                         $em->flush();
  503.                         $event = 'The Item has been duplicated.';
  504.                         $successMessage = $this->translator->trans($event);
  505.                         $this->addFlash('mensajereservation', $successMessage);
  506.                     } catch (\Exception $e) {
  507.                         $event = 'An error occurred: ' . $e->getMessage();
  508.                         $errorMessage = $this->translator->trans($event);
  509.                         $this->addFlash('mensajereservationerror', $errorMessage);
  510.                     }
  511.                     // Actualiza fechas de la reserva si procede
  512.                     $boolReserva = false;
  513.                     if ($newLoungeSimple->getDateStart() < $reservax->getDateStart()) {
  514.                         $reservax->setDateStart($newLoungeSimple->getDateStart());
  515.                         $boolReserva = true;
  516.                     }
  517.                     if ($reservax->getDateEnd() < $newLoungeSimple->getDateEnd()) {
  518.                         $reservax->setDateEnd($newLoungeSimple->getDateEnd());
  519.                         $boolReserva = true;
  520.                     }
  521.                     if ($boolReserva) {
  522.                         $em->persist($reservax);
  523.                         $em->flush();
  524.                     }
  525.                 }
  526.             }
  527.         } else {
  528.             // Registro antiguo: transformar a los nuevos y luego duplicar
  529.             $loungeOld = $em->getRepository(ReservationLounge::class)->findByIdReservation($id);
  530.             foreach ($loungeOld as $item) {
  531.                 if ($item->getDateStart()->format('Y-m-d') == $item->getDateEnd()->format('Y-m-d')) {
  532.                     // Mismo día → simple
  533.                     $newLoungeSimple = new ReservationLoungeSimple();
  534.                     $newLoungeSimple->setDateStart(clone $item->getDateStart());
  535.                     $newLoungeSimple->setDateEnd(clone $item->getDateEnd());
  536.                     $newLoungeSimple->setHourStart($item->getHourStart());
  537.                     $newLoungeSimple->setHourEnd($item->getHourEnd());
  538.                     $newLoungeSimple->setMinStart($item->getMinStart());
  539.                     $newLoungeSimple->setMinEnd($item->getMinEnd());
  540.                     $newLoungeSimple->setIdLounge($item->getIdLounge());
  541.                     $newLoungeSimple->setIdReservation($item->getIdReservation());
  542.                     $newLoungeSimple->setLoungeName($item->getLoungeName());
  543.                     $newLoungeSimple->setPax($item->getPax());
  544.                     $newLoungeSimple->setServicePrice($item->getServicePrice());
  545.                     // IVA (string)
  546.                     $newLoungeSimple->setIva($item->getIva());
  547.                     // Resolver SageVatRates desde el string
  548.                     $rawRate = $item->getIva();
  549.                     $vatEnt = null;
  550.                     if ($rawRate !== null && $rawRate !== '') {
  551.                         $rate = (float) $rawRate;
  552.                         if ($rate > 1) {
  553.                             $rate = $rate / 100;
  554.                         }
  555.                         $vatEnt = $vatRepo->findOneBy(['rate' => $rate]);
  556.                     }
  557.                     $newLoungeSimple->setSageIva($vatEnt);
  558.                     $newLoungeSimple->setOpIva($item->getOpIva());
  559.                     $newLoungeSimple->setType($item->getType());
  560.                     $newLoungeSimple->setRankQuote($item->getRankQuote());
  561.                     $newLoungeSimple->setLoungeDescription($item->getLoungeDescription());
  562.                     $newLoungeSimple->setImportantDescription($item->getImportantDescription());
  563.                     $newLoungeSimple->setCreatedAt($createdAt);
  564.                     $newLoungeSimple->setCreatedBy($createdBy);
  565.                     $newLoungeSimple->setUpdatedAt($updatedAt);
  566.                     $newLoungeSimple->setUpdatedBy($updatedBy);
  567.                     try {
  568.                         $em->persist($newLoungeSimple);
  569.                         $em->flush();
  570.                         $event = 'The Item has been duplicated.';
  571.                         $successMessage = $this->translator->trans($event);
  572.                         $this->addFlash('mensajereservation', $successMessage);
  573.                     } catch (\Exception $e) {
  574.                         $event = 'An error occurred: ' . $e->getMessage();
  575.                         $errorMessage = $this->translator->trans($event);
  576.                         $this->addFlash('mensajereservationerror', $errorMessage);
  577.                     }
  578.                     // Actualiza fechas de la reserva si procede
  579.                     $boolReserva = false;
  580.                     if ($newLoungeSimple->getDateStart() < $reservax->getDateStart()) {
  581.                         $reservax->setDateStart($newLoungeSimple->getDateStart());
  582.                         $boolReserva = true;
  583.                     }
  584.                     if ($reservax->getDateEnd() < $newLoungeSimple->getDateEnd()) {
  585.                         $reservax->setDateEnd($newLoungeSimple->getDateEnd());
  586.                         $boolReserva = true;
  587.                     }
  588.                     if ($boolReserva) {
  589.                         $em->persist($reservax);
  590.                         $em->flush();
  591.                     }
  592.                 } else {
  593.                     // Varios días → trocear en simples
  594.                     $firstDay = new \DateTime($item->getDateStart()->format('Y-m-d'));
  595.                     $lastDay = new \DateTime($item->getDateEnd()->format('Y-m-d'));
  596.                     $numDays = ($lastDay->diff($firstDay))->days + 1;
  597.                     $actualDay = clone $item->getDateStart();
  598.                     $actualStartDay = clone $item->getDateStart();
  599.                     $actualEndDay = clone $item->getDateEnd();
  600.                     for ($i = 0; $i < $numDays; $i++) {
  601.                         $newLoungeSimple = new ReservationLoungeSimple();
  602.                         if ($i === 0) {
  603.                             // Primer día
  604.                             $newLoungeSimple->setDateStart(clone $actualStartDay);
  605.                             $newLoungeSimple->setDateEnd(new \DateTime($actualStartDay->format('Y-m-d') . ' 23:59'));
  606.                             $newLoungeSimple->setHourStart($item->getHourStart());
  607.                             $newLoungeSimple->setHourEnd('23');
  608.                             $newLoungeSimple->setMinStart($item->getMinStart());
  609.                             $newLoungeSimple->setMinEnd('59');
  610.                         } elseif (($i + 1) === $numDays) {
  611.                             // Último día
  612.                             $newLoungeSimple->setDateStart(new \DateTime($actualEndDay->format('Y-m-d') . ' 00:00'));
  613.                             $newLoungeSimple->setDateEnd(clone $actualEndDay);
  614.                             $newLoungeSimple->setHourStart('00');
  615.                             $newLoungeSimple->setHourEnd($item->getHourEnd());
  616.                             $newLoungeSimple->setMinStart('00');
  617.                             $newLoungeSimple->setMinEnd($item->getMinEnd());
  618.                         } else {
  619.                             // Día intermedio
  620.                             $newLoungeSimple->setDateStart(new \DateTime($actualDay->format('Y-m-d') . ' 00:00'));
  621.                             $newLoungeSimple->setDateEnd(new \DateTime($actualDay->format('Y-m-d') . ' 23:59'));
  622.                             $newLoungeSimple->setHourStart('00');
  623.                             $newLoungeSimple->setHourEnd('23');
  624.                             $newLoungeSimple->setMinStart('00');
  625.                             $newLoungeSimple->setMinEnd('59');
  626.                         }
  627.                         $newLoungeSimple->setIdLounge($item->getIdLounge());
  628.                         $newLoungeSimple->setIdReservation($item->getIdReservation());
  629.                         $newLoungeSimple->setLoungeName($item->getLoungeName());
  630.                         $newLoungeSimple->setPax($item->getPax());
  631.                         $newLoungeSimple->setServicePrice($item->getServicePrice());
  632.                         // IVA (string) + entidad
  633.                         $newLoungeSimple->setIva($item->getIva());
  634.                         $rawRate = $item->getIva();
  635.                         $vatEnt = null;
  636.                         if ($rawRate !== null && $rawRate !== '') {
  637.                             $rate = (float) $rawRate;
  638.                             if ($rate > 1) {
  639.                                 $rate = $rate / 100;
  640.                             }
  641.                             $vatEnt = $vatRepo->findOneBy(['rate' => $rate]);
  642.                         }
  643.                         $newLoungeSimple->setSageIva($vatEnt);
  644.                         $newLoungeSimple->setOpIva($item->getOpIva());
  645.                         $newLoungeSimple->setType($item->getType());
  646.                         $newLoungeSimple->setRankQuote($item->getRankQuote());
  647.                         $newLoungeSimple->setLoungeDescription($item->getLoungeDescription());
  648.                         $newLoungeSimple->setImportantDescription($item->getImportantDescription());
  649.                         $newLoungeSimple->setCreatedAt($createdAt);
  650.                         $newLoungeSimple->setCreatedBy($createdBy);
  651.                         $newLoungeSimple->setUpdatedAt($updatedAt);
  652.                         $newLoungeSimple->setUpdatedBy($updatedBy);
  653.                         // Avanza el día (sin perder la referencia)
  654.                         $actualDay = (clone $actualDay)->modify('+1 day');
  655.                         try {
  656.                             $em->persist($newLoungeSimple);
  657.                             $em->flush();
  658.                             $event = 'The Item has been updated.';
  659.                             $successMessage = $this->translator->trans($event);
  660.                             $this->addFlash('mensajereservation', $successMessage);
  661.                         } catch (\Exception $e) {
  662.                             $event = 'An error occurred: ' . $e->getMessage();
  663.                             $errorMessage = $this->translator->trans($event);
  664.                             $this->addFlash('mensajereservationerror', $errorMessage);
  665.                         }
  666.                         // Actualiza fechas de la reserva si procede
  667.                         $boolReserva = false;
  668.                         if ($newLoungeSimple->getDateStart() < $reservax->getDateStart()) {
  669.                             $reservax->setDateStart($newLoungeSimple->getDateStart());
  670.                             $boolReserva = true;
  671.                         }
  672.                         if ($reservax->getDateEnd() < $newLoungeSimple->getDateEnd()) {
  673.                             $reservax->setDateEnd($newLoungeSimple->getDateEnd());
  674.                             $boolReserva = true;
  675.                         }
  676.                         if ($boolReserva) {
  677.                             $em->persist($reservax);
  678.                             $em->flush();
  679.                         }
  680.                     }
  681.                 }
  682.                 // Re-llama al mismo controlador ahora con la nueva tabla poblada
  683.                 return $this->redirectToRoute('reservations_venues_duplicate_day', [
  684.                     'id' => $id,
  685.                     'dayduplicate' => $dayduplicate,
  686.                 ]);
  687.             }
  688.         }
  689.         //Se llama al servicio para crear la entrada en la agenda y actualizar el Pax de la agenda
  690.         $agenda = $this->agendaService->createAgendaFromSource($newLoungeSimple->getIdReservation(), 'SALAS A UTILIZAR', null, null, $newLoungeSimple->getDateStart(), $newLoungeSimple->getDateEnd(), $newLoungeSimple->getLoungeName(), $newLoungeSimple->getId(), 'ReservationLoungeSimple', $updatedBy);
  691.         $reserva = $em->getRepository(Reservation::class)->findOneById($newLoungeSimple->getIdReservation());
  692.         //Se llama al servicio para crear la entrada en la agenda de las fechas
  693.         $agenda = $this->agendaService->updateDatesLine($reserva->getId(), $updatedBy);
  694.         // Creamos la Snapshot de las salas y servicios del sistema (LOG)
  695.         $version = $this->venueService->createSnapshot($reservax);
  696.         /* Obtengo usuario logueado */
  697.         $user = $this->get('security.token_storage')->getToken()->getUser();
  698.         // Sincronizar contratos si está confirmado
  699.         if ($reservax->getStatus() === 'Confirmed') {
  700.             $this->docContractService->autoAssignContracts($reservax, $user);
  701.         }
  702.         // Redirige para agregar Servicio de limpieza
  703.         return $this->redirectToRoute('reservations_white_addservices_cleaning', [
  704.             'resid' => $id,
  705.             'loungesimpleid' => isset($newLoungeSimple) ? $newLoungeSimple->getId() : null,
  706.         ]);
  707.     }
  708.     /**
  709.      * @Route("/deleteitemsimple/{id}/{daydelete}", name="reservations_venues_delete_simple_lounge")
  710.      * Elimina un Reservation Simple Lounge de la cotizacion
  711.      */
  712.     public function deleteSimpleLoungeAction($id, $daydelete, EntityManagerInterface $em, ReservationConflictService $conflictService, Request $request)
  713.     {
  714.         $loungeSimple = $em->getRepository(ReservationLoungeSimple::class)->findOneById($id);
  715.         if (!empty($loungeSimple)) {
  716.             //Se llama al servicio para eliminar la entrada en la agenda
  717.             $agenda = $this->agendaService->deleteAgendaBySource($loungeSimple->getId(), 'ReservationLoungeSimple');
  718.         }
  719.         $id = $loungeSimple->getIdReservation();
  720.         $reserva = $em->getRepository(Reservation::class)->findOneById($loungeSimple->getIdReservation());
  721.         try {
  722.             $em->remove($loungeSimple);
  723.             $em->flush();
  724.             $event = 'The item has been deleted.';
  725.             $successMessage = $this->translator->trans($event);
  726.             $this->addFlash('mensajereservation', $successMessage);
  727.         } catch (\Exception $e) {
  728.             $event = 'An error occurred: ' . $e->getMessage();
  729.             $errorMessage = $this->translator->trans($event);
  730.             $this->addFlash('mensajereservationerror', $errorMessage);
  731.         }
  732.         // Se llama al servicio para verificar si el remove Resolvió una ReservationAvailability
  733.         $conflicts = $conflictService->checkDeletedLoungeConflictsQuotes($reserva, $loungeSimple);
  734.         /* Obtengo usuario logueado */
  735.         $user_logueado = $this->get('security.token_storage')->getToken()->getUser();
  736.         // Recalcular fechas de la reserva usando el servicio
  737.         if ($reserva) {
  738.             $this->reservationService->updateReservationDates($reserva);
  739.             
  740.             // Sincronizar contratos si está confirmado
  741.             if ($reserva->getStatus() === 'Confirmed') {
  742.                 $this->docContractService->autoAssignContracts($reserva, $user_logueado);
  743.             }
  744.         }
  745.         $user_id = $user_logueado->getId();
  746.         //Se llama al servicio para crear la entrada en la agenda de las fechas
  747.         $agenda = $this->agendaService->updateDatesLine($reserva->getId(), $user_id);
  748.         //Se llama al servicio para actualizar Pax en la agenda
  749.         $paxAge = $this->agendaService->calculatePaxForReservation($reserva->getId());
  750.         $agenda = $this->agendaService->updatePaxLine($reserva->getId(), $paxAge, $user_id);
  751.         // Se elimina el servicio de horas de limpieza de la sala
  752.         return $this->redirectToRoute(
  753.             'reservations_venues_delete_simple_lounge_cleaning',
  754.             array(
  755.                 'idRes' => $id,
  756.                 'idLng' => $loungeSimple->getIdLounge(),
  757.                 'dateInAt' => $loungeSimple->getDateStart()->format('Y-m-d\TH:i'),
  758.                 'dateOutAt' => $loungeSimple->getDateEnd()->format('Y-m-d\TH:i'),
  759.             )
  760.         );
  761.     }
  762.     /**
  763.      * @Route("/deletequote/{idRes}/{idQuote}", name="reservations_delete_quote")
  764.      * Eliminar una cotizancion
  765.      */
  766.     public function deleteQuoteAction(
  767.         $idRes,
  768.         $idQuote,
  769.         EntityManagerInterface $em,
  770.         ReservationConflictService $conflictService,
  771.         Request $request
  772.     ) {
  773.         try {
  774.             $this->removeQuote(
  775.                 $idRes,
  776.                 $idQuote,
  777.                 $em,
  778.                 $conflictService
  779.             );
  780.             $em->flush();
  781.             $this->addFlash(
  782.                 'mensajereservation',
  783.                 $this->translator->trans(
  784.                     'Se ha eliminado la cotización'
  785.                 )
  786.             );
  787.         } catch (\Exception $e) {
  788.             $this->addFlash(
  789.                 'mensajereservationerror',
  790.                 $this->translator->trans(
  791.                     'An error occurred: ' . $e->getMessage()
  792.                 )
  793.             );
  794.         }
  795.         // Actualizar agenda
  796.         $user = $this
  797.             ->get('security.token_storage')
  798.             ->getToken()
  799.             ->getUser();
  800.         $userId = $user->getId();
  801.         $paxAge = $this
  802.             ->agendaService
  803.             ->calculatePaxForReservation($idRes);
  804.         $this->agendaService->updatePaxLine(
  805.             $idRes,
  806.             $paxAge,
  807.             $userId
  808.         );
  809.         $this->agendaService->updateDatesLine(
  810.             $idRes,
  811.             $userId
  812.         );
  813.         // Recalcular fechas
  814.         $reservaEntity = $em
  815.             ->getRepository(Reservation::class)
  816.             ->find($idRes);
  817.         if ($reservaEntity) {
  818.             $this->reservationService
  819.                 ->updateReservationDates($reservaEntity);
  820.         }
  821.         return $this->redirectToRoute(
  822.             'reservations_venues_edit_simple',
  823.             [
  824.                 'id' => $idRes,
  825.                 'token' => null,
  826.                 '_fragment' => 'btn_quotes'
  827.             ]
  828.         );
  829.     }
  830.     /**
  831.      * @Route("/checkquote/{idRes}/{idQuote}", name="reservations_check_quote")
  832.      * Confirmación de que se ha aceptado la cotizancion, se eliminaran las otras cotizaciones del expediente
  833.      */
  834.     public function checkQuoteAction($idRes, $idQuote, EntityManagerInterface $em, ReservationConflictService $conflictService, Request $request)
  835.     {
  836.         $qb = $em->getRepository(ReservationLoungeSimple::class)->createQueryBuilder('r');
  837.         $reservation = $qb->where('r.rankQuote <> :rankQuote')
  838.             ->andWhere('r.idReservation = :idReservation')
  839.             ->setParameter('idReservation', $idRes)
  840.             ->setParameter('rankQuote', $idQuote)
  841.             ->getQuery()
  842.             ->getResult();
  843.         $reserva = $em->getRepository(Reservation::class)->findOneById($idRes);
  844.         foreach ($reservation as $item) {
  845.             try {
  846.                 if (!empty($item)) {
  847.                     //Se llama al servicio para eliminar la entrada en la agenda
  848.                     $agenda = $this->agendaService->deleteAgendaBySource($item->getId(), 'ReservationLoungeSimple');
  849.                 }
  850.                 $em->remove($item);
  851.                 $em->flush();
  852.                 $event = 'Se han eliminado las otras cotizaciones';
  853.                 $successMessage = $this->translator->trans($event);
  854.                 $this->addFlash('mensajereservation', $successMessage);
  855.                 // Se llama al servicio para verificar si el remove Resolvió una ReservationAvailability
  856.                 $conflicts = $conflictService->checkDeletedLoungeConflictsQuotes($reserva, $item);
  857.             } catch (\Exception $e) {
  858.                 $event = 'An error occurred: ' . $e->getMessage();
  859.                 $errorMessage = $this->translator->trans($event);
  860.                 $this->addFlash('mensajereservationerror', $errorMessage);
  861.             }
  862.         }
  863.         // Actualizar fechas de la reserva usando el servicio
  864.         $reservation = $em->getRepository(Reservation::class)->findOneById($idRes);
  865.         $this->reservationService->updateReservationDates($reservation);
  866.         /* Obtengo usuario logueado */
  867.         $user_logueado = $this->get('security.token_storage')->getToken()->getUser();
  868.         $user_id = $user_logueado->getId();
  869.         //Se llama al servicio para actualizar Pax en la agenda
  870.         $paxAge = $this->agendaService->calculatePaxForReservation($idRes);
  871.         $agenda = $this->agendaService->updatePaxLine($idRes, $paxAge, $user_id);
  872.         //Se llama al servicio para actualizar Fechas en la agenda
  873.         $agenda = $this->agendaService->updateDatesLine($idRes, $user_id);
  874.         return $this->redirectToRoute(
  875.             'reservations_venues_edit_simple',
  876.             array(
  877.                 'id' => $idRes,
  878.                 'token' => null,
  879.                 '_fragment' => 'btn_quotes'
  880.             )
  881.         );
  882.     }
  883.     /**
  884.      * @Route("/duplicatequoteOLD", name="reservations_duplicate_quote_OLD")
  885.      * Duplicar una cotizacion
  886.      */
  887.     public function duplicateQuoteActionOLD(EntityManagerInterface $em, ReservationConflictService $conflictService, Request $request)
  888.     {
  889.         $user_logueado = $this->get('security.token_storage')->getToken()->getUser();
  890.         $user_id = $user_logueado->getId();
  891.         $hoy = new \DateTime("now", NULL);
  892.         $reqDuplicateQuote = $request->request->get('addquote');
  893.         $reserva = $em->getRepository(Reservation::class)->findOneById($reqDuplicateQuote['reservationId']);
  894.         $newLounge = $em->getRepository(ReservationLoungeDetails::class)->findOneById($reqDuplicateQuote['salaPrecargadas']);
  895.         if (($reserva->getStatus() == 'Confirmed') or ($reserva->getStatus() == 'Invoiced')){
  896.             // No se pueden duplicar opciones si ya esta confirmado o facturado porque podria generar conflicto de salas
  897.             $event = 'No se duplican opciones en una reserva CONFIRMADA o FACTURADA';
  898.             $errorMessage = $this->translator->trans($event);
  899.             $this->addFlash('mensajereservationerror', $errorMessage);
  900.             return $this->redirectToRoute(
  901.                 'reservations_venues_edit_simple',
  902.                 array(
  903.                     'id' => $reqDuplicateQuote['reservationId'],
  904.                     'token' => null,
  905.                     '_fragment' => null
  906.                 )
  907.             );
  908.         }
  909.         $qb = $em->getRepository(ReservationLoungeSimple::class)->createQueryBuilder('r');
  910.         $reservationAll = $qb->where('r.idReservation = :idReservation')
  911.             ->setParameter('idReservation', $reqDuplicateQuote['reservationId'])
  912.             ->orderBy('r.rankQuote', 'ASC')
  913.             ->getQuery()
  914.             ->getResult();
  915.         $newRankId = (!empty($reservationAll)) ? (end($reservationAll)->getRankQuote() + 1) : 1;
  916.         if (empty($reqDuplicateQuote['idQuote'])) {
  917.             $reqDuplicateQuote['idQuote'] = reset($reservationAll)->getRankQuote();
  918.         }   //Si no elige cotización se duplica la primera
  919.         $qb = $em->getRepository(ReservationLoungeSimple::class)->createQueryBuilder('r');
  920.         $reservation = $qb->where('r.rankQuote = :rankQuote')
  921.             ->andWhere('r.idReservation = :idReservation')
  922.             ->setParameter('idReservation', $reqDuplicateQuote['reservationId'])
  923.             ->setParameter('rankQuote', $reqDuplicateQuote['idQuote'])
  924.             ->getQuery()
  925.             ->getResult();
  926.         // Descripciones web por sala/idioma con fallbacks
  927.         $loungeProfile = $newLounge;
  928.         // Heredar idioma si existe alguna sala previa en la reserva
  929.         $idioma = empty($reservationAll) ? 1: $reservationAll[0]->getLanguage();
  930.         $loungeWebDescriptionRepo = $em->getRepository(ReservationLoungeWebDescription::class);
  931.         $loungeWebDescription = $loungeWebDescriptionRepo->findOneBy([
  932.                 'lounge' => $loungeProfile,
  933.                 'language' => $idioma
  934.             ]) ?? ($idioma !== 1 ? $loungeWebDescriptionRepo->findOneBy([
  935.                 'lounge' => $loungeProfile,
  936.                 'language' => 1
  937.             ]) : null) ?? $loungeWebDescriptionRepo->findOneBy(['lounge' => $loungeProfile]);
  938.         $loungeImportantDescGeneralText = $loungeWebDescription ? $loungeWebDescription->getImportantDescGeneralText() : '';
  939.         $loungeImportantDescSchedules = $loungeWebDescription ? $loungeWebDescription->getImportantDescSchedules() : '';
  940.         $loungeImportantDescParking = $loungeWebDescription ? $loungeWebDescription->getImportantDescParking() : '';
  941.         $loungeSummaryDescription = $loungeWebDescription ? $loungeWebDescription->getImportantDescription() : '';
  942.         foreach ($reservation as $item) {
  943.             $newLoungeSimple = new ReservationLoungeSimple();
  944.             $newLoungeSimple->setDateStart($item->getDateStart());
  945.             $newLoungeSimple->setDateEnd($item->getDateEnd());
  946.             $newLoungeSimple->setIdReservation($reqDuplicateQuote['reservationId']);
  947.             $newLoungeSimple->setPax($item->getPax());
  948.             $newLoungeSimple->setType($item->getType());
  949.             $newLoungeSimple->setCreatedAt($hoy);
  950.             $newLoungeSimple->setCreatedBy($user_id);
  951.             $newLoungeSimple->setUpdatedAt($hoy);
  952.             $newLoungeSimple->setUpdatedBy($user_id);
  953.             $newLoungeSimple->setHourStart($item->getHourStart());
  954.             $newLoungeSimple->setMinStart($item->getMinStart());
  955.             $newLoungeSimple->setHourEnd($item->getHourEnd());
  956.             $newLoungeSimple->setMinEnd($item->getMinEnd());
  957.             $newLoungeSimple->setRankQuote($newRankId);
  958.             $newLoungeSimple->setIva($item->getIva());
  959.             $newLoungeSimple->setOpIva($item->getOpIva());
  960.             $newLoungeSimple->setIdLounge($newLounge->getId());
  961.             $newLoungeSimple->setLoungename($newLounge->getName());
  962.             //            $newLoungeSimple->setLoungeDescription($item->getLoungeDescription());
  963.             $newLoungeSimple->setImportantDescription($loungeSummaryDescription);
  964.             $newLoungeSimple->setImportantDescGeneralText($loungeImportantDescGeneralText);
  965.             $newLoungeSimple->setImportantDescSchedules($loungeImportantDescSchedules);
  966.             $newLoungeSimple->setImportantDescParking($loungeImportantDescParking);
  967.             $newLoungeSimple->setLanguage($item->getLanguage());
  968.             $newLoungeSimple->setSageArticle($item->getSageArticle());
  969.             $newLoungeSimple->setSentToSage($item->isSentToSage());
  970.             $newLoungeSimple->setSageIva($item->getSageIva());
  971.             $newLoungeSimple->setShowAudiovisualPrice($item->isShowAudiovisualPrice());
  972.             $newLoungeSimple->setShowAudiovisualPackage($item->isShowAudiovisualPackage());
  973.             if (!empty($reqDuplicateQuote['salaPrice'])) {
  974.                 $newLoungeSimple->setServicePrice($reqDuplicateQuote['salaPrice']);
  975.             } else {
  976.                 $newLoungeSimple->setServicePrice($item->getServicePrice());
  977.             }
  978.             try {
  979.                 // Verificamos si se puede agregar la sala sin generar conflictos
  980.                 $conflictos = $conflictService->checkSingleLoungeConflict($newLoungeSimple, $reqDuplicateQuote['reservationId']);
  981.                 if (empty($conflictos)) {
  982.                     $em->persist($newLoungeSimple);
  983.                     $em->flush();
  984.                     $event = 'Se ha agregado la nueva cotización';
  985.                     $successMessage = $this->translator->trans($event);
  986.                     $this->addFlash('mensajereservation', $successMessage);
  987.                 } else {
  988.                     $event = 'Agregar esta sala genera conflicto con la reserva: '. $conflictos[0]['reservationId'].' - '.$conflictos[0]['reservationTitle'];
  989.                     $errorMessage = $this->translator->trans($event);
  990.                     $this->addFlash('mensajereservationerror', $errorMessage);
  991.                 }
  992.             } catch (\Exception $e) {
  993.                 $event = 'An error occurred: ' . $e->getMessage();
  994.                 $errorMessage = $this->translator->trans($event);
  995.                 $this->addFlash('mensajereservationerror', $errorMessage);
  996.             }
  997.             //Se llama al servicio para crear la entrada en la agenda
  998.             $agenda = $this->agendaService->createAgendaFromSource(
  999.                 $newLoungeSimple->getIdReservation(),
  1000.                 'SALAS A UTILIZAR',
  1001.                 null,
  1002.                 null,
  1003.                 $newLoungeSimple->getDateStart(),
  1004.                 $newLoungeSimple->getDateEnd(),
  1005.                 $newLoungeSimple->getLoungename(),
  1006.                 $newLoungeSimple->getId(),
  1007.                 'ReservationLoungeSimple',
  1008.                 $newLoungeSimple->getUpdatedBy()
  1009.             );
  1010.             // Se debe agregar el servicio de limpieza por cada sala que se agregue
  1011.             $resLoungeSimple = $newLoungeSimple;
  1012.             $service = new ReservationService();
  1013.             $service->setReservationId($reqDuplicateQuote['reservationId']);
  1014.             $service->setSupplierId(0);
  1015.             $service->setDateInAt($resLoungeSimple->getDateStart());
  1016.             $service->setDateOutAt($resLoungeSimple->getDateEnd());
  1017.             /* Obtengo usuario logueado */
  1018.             $user_logueado = $this->get('security.token_storage')->getToken()->getUser();
  1019.             $user_id = $user_logueado->getId();
  1020.             $service->setCreatedId($user_id);
  1021.             $service->setUpdatedId($user_id);
  1022.             $service->setCreatedAt(new \DateTime("now"));
  1023.             $service->setUpdatedAt(new \DateTime("now"));
  1024.             $service->setServiceCatId('21');
  1025.             $service->setServiceCatName('Limpieza');
  1026.             $service->setContcolor('green-300');
  1027.             $service->setName('HORAS ( ' . $resLoungeSimple->getLoungeName() . ' )');
  1028.             $service->setPrice('14');
  1029.             $service->setCurrency('Euro');
  1030.             $service->setUnits('8');
  1031.             $service->setCommission('0');
  1032.             $service->setPax('0');
  1033.             $service->setOver('0');
  1034.             $service->setIva('21');
  1035.             $service->setOpIva('1');
  1036.             $service->setOpCommission('1');
  1037.             $service->setCommission('57.14');
  1038.             $service->setViewInfo(0);
  1039.             $service->setToinvoice(0);
  1040.             $service->setServiceId(0);
  1041.             $em->persist($service);
  1042.             $em->flush();
  1043.         }
  1044.         // Creamos la Snapshot de las salas y servicios del sistema (LOG)
  1045.         $version = $this->venueService->createSnapshot($reserva);
  1046.         return $this->redirectToRoute(
  1047.             'reservations_venues_edit_simple',
  1048.             array(
  1049.                 'id' => $reqDuplicateQuote['reservationId'],
  1050.                 'token' => null,
  1051.                 '_fragment' => 'btn_quotes'
  1052.             )
  1053.         );
  1054.     }
  1055.     /**
  1056.      * @Route(
  1057.      *     "/duplicatequote",
  1058.      *     name="reservations_duplicate_quote",
  1059.      *     methods={"POST"}
  1060.      * )
  1061.      * Duplicar una cotización en una o varias salas
  1062.      */
  1063.     public function duplicateQuoteAction(
  1064.         EntityManagerInterface $em,
  1065.         ReservationConflictService $conflictService,
  1066.         Request $request
  1067.     ) {
  1068.         $user = $this->get('security.token_storage')->getToken()->getUser();
  1069.         $userId = $user->getId();
  1070.         $now = new \DateTime('now');
  1071.         $data = $request->request->get('addquote', []);
  1072.         $reservationId = !empty($data['reservationId'])
  1073.             ? (int) $data['reservationId']
  1074.             : 0;
  1075.         $sourceRankQuote = isset($data['idQuote']) && $data['idQuote'] !== ''
  1076.             ? (int) $data['idQuote']
  1077.             : null;
  1078.         $deleteSource = !empty($data['deleteSource']);
  1079.         $selectedLounges = isset($data['salas']) && is_array($data['salas'])
  1080.             ? $data['salas']
  1081.             : [];
  1082.         /*
  1083.          * ---------------------------------------------------------
  1084.          * 1. Validaciones básicas
  1085.          * ---------------------------------------------------------
  1086.          */
  1087.         if (!$reservationId) {
  1088.             $this->addFlash(
  1089.                 'mensajereservationerror',
  1090.                 $this->translator->trans('La reserva no es válida.')
  1091.             );
  1092.             return $this->redirectToRoute(
  1093.                 'reservations_venues_edit_simple',
  1094.                 [
  1095.                     'id' => $reservationId,
  1096.                     'token' => null,
  1097.                     '_fragment' => 'btn_quotes'
  1098.                 ]
  1099.             );
  1100.         }
  1101.         /*
  1102.          * Obtener todas las cotizaciones de la reserva
  1103.          */
  1104.         $reservationAll = $em
  1105.             ->getRepository(ReservationLoungeSimple::class)
  1106.             ->createQueryBuilder('r')
  1107.             ->where('r.idReservation = :idReservation')
  1108.             ->setParameter('idReservation', $reservationId)
  1109.             ->orderBy('r.rankQuote', 'ASC')
  1110.             ->getQuery()
  1111.             ->getResult();
  1112.         if (empty($reservationAll)) {
  1113.             $this->addFlash(
  1114.                 'mensajereservationerror',
  1115.                 $this->translator->trans(
  1116.                     'No existen cotizaciones para esta reserva.'
  1117.                 )
  1118.             );
  1119.             return $this->redirectToRoute(
  1120.                 'reservations_venues_edit_simple',
  1121.                 [
  1122.                     'id' => $reservationId,
  1123.                     'token' => null,
  1124.                     '_fragment' => 'btn_quotes'
  1125.                 ]
  1126.             );
  1127.         }
  1128.         /*
  1129.          * Si no se indica cotización origen,
  1130.          * utilizamos la primera, igual que hacía el código original.
  1131.          */
  1132.         if (empty($sourceRankQuote)) {
  1133.             $sourceRankQuote = $reservationAll[0]->getRankQuote();
  1134.         }
  1135.         /*
  1136.          * ---------------------------------------------------------
  1137.          * 2. Obtener las líneas de la cotización origen
  1138.          * ---------------------------------------------------------
  1139.          */
  1140.         $sourceItems = $em
  1141.             ->getRepository(ReservationLoungeSimple::class)
  1142.             ->createQueryBuilder('r')
  1143.             ->where('r.idReservation = :idReservation')
  1144.             ->andWhere('r.rankQuote = :rankQuote')
  1145.             ->setParameter('idReservation', $reservationId)
  1146.             ->setParameter('rankQuote', $sourceRankQuote)
  1147.             ->orderBy('r.id', 'ASC')
  1148.             ->getQuery()
  1149.             ->getResult();
  1150.         if (empty($sourceItems)) {
  1151.             $this->addFlash(
  1152.                 'mensajereservationerror',
  1153.                 $this->translator->trans(
  1154.                     'No se ha encontrado la cotización origen.'
  1155.                 )
  1156.             );
  1157.             return $this->redirectToRoute(
  1158.                 'reservations_venues_edit_simple',
  1159.                 [
  1160.                     'id' => $reservationId,
  1161.                     'token' => null,
  1162.                     '_fragment' => 'btn_quotes'
  1163.                 ]
  1164.             );
  1165.         }
  1166.         /*
  1167.          * Guardamos los IDs de las salas que pertenecen
  1168.          * a la cotización origen.
  1169.          *
  1170.          * Así evitamos que el usuario seleccione como destino
  1171.          * una de las mismas salas de origen.
  1172.          */
  1173.         $sourceLoungeIds = [];
  1174.         foreach ($sourceItems as $sourceItem) {
  1175.             $sourceLoungeIds[] = (int) $sourceItem->getIdLounge();
  1176.         }
  1177.         $sourceLoungeIds = array_unique($sourceLoungeIds);
  1178.         /*
  1179.          * ---------------------------------------------------------
  1180.          * 3. Procesar las salas seleccionadas
  1181.          * ---------------------------------------------------------
  1182.          *
  1183.          * Esperamos:
  1184.          *
  1185.          * addquote[salas][ID_SALA][selected] = 1
  1186.          * addquote[salas][ID_SALA][price] = 150
  1187.          */
  1188.         $destinations = [];
  1189.         foreach ($selectedLounges as $loungeId => $loungeData) {
  1190.             if (empty($loungeData['selected'])) {
  1191.                 continue;
  1192.             }
  1193.             $loungeId = (int) $loungeId;
  1194.             /*
  1195.              * No permitimos volver a seleccionar como destino
  1196.              * una sala que ya pertenece a la cotización origen.
  1197.              */
  1198.             if (in_array($loungeId, $sourceLoungeIds, true)) {
  1199.                 $this->addFlash(
  1200.                     'mensajereservationerror',
  1201.                     $this->translator->trans(
  1202.                         'No puedes seleccionar como destino una sala de la cotización origen.'
  1203.                     )
  1204.                 );
  1205.                 return $this->redirectToRoute(
  1206.                     'reservations_venues_edit_simple',
  1207.                     [
  1208.                         'id' => $reservationId,
  1209.                         'token' => null,
  1210.                         '_fragment' => 'btn_quotes'
  1211.                     ]
  1212.                 );
  1213.             }
  1214.             /*
  1215.              * Buscamos la sala en BD.
  1216.              *
  1217.              * No debemos confiar únicamente en el ID enviado
  1218.              * por POST.
  1219.              */
  1220.             $lounge = $em
  1221.                 ->getRepository(ReservationLoungeDetails::class)
  1222.                 ->find($loungeId);
  1223.             if (!$lounge) {
  1224.                 $this->addFlash(
  1225.                     'mensajereservationerror',
  1226.                     $this->translator->trans(
  1227.                         'Una de las salas seleccionadas no existe.'
  1228.                     )
  1229.                 );
  1230.                 return $this->redirectToRoute(
  1231.                     'reservations_venues_edit_simple',
  1232.                     [
  1233.                         'id' => $reservationId,
  1234.                         'token' => null,
  1235.                         '_fragment' => 'btn_quotes'
  1236.                     ]
  1237.                 );
  1238.             }
  1239.             /*
  1240.              * Precio:
  1241.              *
  1242.              * - Si viene informado -> utilizamos ese precio.
  1243.              * - Si viene vacío -> heredamos el precio de la línea origen.
  1244.              */
  1245.             $price = null;
  1246.             if (
  1247.                 isset($loungeData['price']) &&
  1248.                 $loungeData['price'] !== ''
  1249.             ) {
  1250.                 $priceString = str_replace(
  1251.                     ',',
  1252.                     '.',
  1253.                     trim((string) $loungeData['price'])
  1254.                 );
  1255.                 if (!is_numeric($priceString)) {
  1256.                     $this->addFlash(
  1257.                         'mensajereservationerror',
  1258.                         $this->translator->trans(
  1259.                             'El precio indicado para una de las salas no es válido.'
  1260.                         )
  1261.                     );
  1262.                     return $this->redirectToRoute(
  1263.                         'reservations_venues_edit_simple',
  1264.                         [
  1265.                             'id' => $reservationId,
  1266.                             'token' => null,
  1267.                             '_fragment' => 'btn_quotes'
  1268.                         ]
  1269.                     );
  1270.                 }
  1271.                 $price = (float) $priceString;
  1272.                 if ($price < 0) {
  1273.                     $this->addFlash(
  1274.                         'mensajereservationerror',
  1275.                         $this->translator->trans(
  1276.                             'El precio no puede ser negativo.'
  1277.                         )
  1278.                     );
  1279.                     return $this->redirectToRoute(
  1280.                         'reservations_venues_edit_simple',
  1281.                         [
  1282.                             'id' => $reservationId,
  1283.                             'token' => null,
  1284.                             '_fragment' => 'btn_quotes'
  1285.                         ]
  1286.                     );
  1287.                 }
  1288.             }
  1289.             $destinations[] = [
  1290.                 'lounge' => $lounge,
  1291.                 'price' => $price,
  1292.             ];
  1293.         }
  1294.         /*
  1295.          * Debe haber al menos una sala destino.
  1296.          */
  1297.         if (empty($destinations)) {
  1298.             $this->addFlash(
  1299.                 'mensajereservationerror',
  1300.                 $this->translator->trans(
  1301.                     'Debes seleccionar al menos una sala destino.'
  1302.                 )
  1303.             );
  1304.             return $this->redirectToRoute(
  1305.                 'reservations_venues_edit_simple',
  1306.                 [
  1307.                     'id' => $reservationId,
  1308.                     'token' => null,
  1309.                     '_fragment' => 'btn_quotes'
  1310.                 ]
  1311.             );
  1312.         }
  1313.         /*
  1314.          * Si se quiere eliminar el origen,
  1315.          * obligatoriamente tiene que existir al menos un destino.
  1316.          *
  1317.          * En realidad ya lo hemos validado arriba, pero dejamos
  1318.          * esta condición explícita porque es una regla de negocio.
  1319.          */
  1320.         if ($deleteSource && empty($destinations)) {
  1321.             $this->addFlash(
  1322.                 'mensajereservationerror',
  1323.                 $this->translator->trans(
  1324.                     'No se puede eliminar la cotización origen si no existe ninguna sala destino.'
  1325.                 )
  1326.             );
  1327.             return $this->redirectToRoute(
  1328.                 'reservations_venues_edit_simple',
  1329.                 [
  1330.                     'id' => $reservationId,
  1331.                     'token' => null,
  1332.                     '_fragment' => 'btn_quotes'
  1333.                 ]
  1334.             );
  1335.         }
  1336.         /*
  1337.          * ---------------------------------------------------------
  1338.          * 4. Obtener el último rankQuote
  1339.          * ---------------------------------------------------------
  1340.          *
  1341.          * Cada sala destino será una nueva cotización.
  1342.          *
  1343.          * Ejemplo:
  1344.          *
  1345.          * Cádiz       -> rankQuote 3
  1346.          * Madrid      -> rankQuote 5
  1347.          * Barcelona   -> rankQuote 6
  1348.          * Sevilla     -> rankQuote 7
  1349.          */
  1350.         $lastRankQuote = 0;
  1351.         foreach ($reservationAll as $reservationItem) {
  1352.             if ((int) $reservationItem->getRankQuote() > $lastRankQuote) {
  1353.                 $lastRankQuote = (int) $reservationItem->getRankQuote();
  1354.             }
  1355.         }
  1356.         /*
  1357.          * ---------------------------------------------------------
  1358.          * 5. Reserva
  1359.          * ---------------------------------------------------------
  1360.          */
  1361.         $reserva = $em
  1362.             ->getRepository(Reservation::class)
  1363.             ->findOneById($reservationId);
  1364.         if (!$reserva) {
  1365.             $this->addFlash(
  1366.                 'mensajereservationerror',
  1367.                 $this->translator->trans(
  1368.                     'No se ha encontrado la reserva.'
  1369.                 )
  1370.             );
  1371.             return $this->redirectToRoute(
  1372.                 'reservations_venues_edit_simple',
  1373.                 [
  1374.                     'id' => $reservationId,
  1375.                     'token' => null,
  1376.                     '_fragment' => 'btn_quotes'
  1377.                 ]
  1378.             );
  1379.         }
  1380.         /*
  1381.          * ---------------------------------------------------------
  1382.          * 6. TRANSACTION
  1383.          * ---------------------------------------------------------
  1384.          */
  1385.         $connection = $em->getConnection();
  1386.         $newLoungeSimples = [];
  1387.         $sourceItemsToDelete = [];
  1388.         try {
  1389.             $connection->beginTransaction();
  1390.             /*
  1391.              * =====================================================
  1392.              * CREAR LAS NUEVAS COTIZACIONES
  1393.              * =====================================================
  1394.              */
  1395.             foreach ($destinations as $destination) {
  1396.                 /** @var ReservationLoungeDetails $newLounge */
  1397.                 $newLounge = $destination['lounge'];
  1398.                 $customPrice = $destination['price'];
  1399.                 /*
  1400.                  * Cada sala destino tendrá su propio rankQuote.
  1401.                  */
  1402.                 $lastRankQuote++;
  1403.                 $newRankQuote = $lastRankQuote;
  1404.                 /*
  1405.                  * =================================================
  1406.                  * Copiamos TODAS las líneas de la cotización origen
  1407.                  * =================================================
  1408.                  */
  1409.                 foreach ($sourceItems as $item) {
  1410.                     /*
  1411.                      * ---------------------------------------------
  1412.                      * Descripciones web
  1413.                      * ---------------------------------------------
  1414.                      *
  1415.                      * Utilizamos el idioma de cada línea origen.
  1416.                      */
  1417.                     $idioma = $item->getLanguage();
  1418.                     $loungeWebDescriptionRepo = $em->getRepository(
  1419.                         ReservationLoungeWebDescription::class
  1420.                     );
  1421.                     $loungeWebDescription = $loungeWebDescriptionRepo->findOneBy([
  1422.                         'lounge' => $newLounge,
  1423.                         'language' => $idioma
  1424.                     ]);
  1425.                     /*
  1426.                      * Fallback al idioma 1.
  1427.                      */
  1428.                     if (!$loungeWebDescription && $idioma != 1) {
  1429.                         $loungeWebDescription = $loungeWebDescriptionRepo->findOneBy([
  1430.                             'lounge' => $newLounge,
  1431.                             'language' => 1
  1432.                         ]);
  1433.                     }
  1434.                     /*
  1435.                      * Último fallback: cualquier idioma.
  1436.                      */
  1437.                     if (!$loungeWebDescription) {
  1438.                         $loungeWebDescription = $loungeWebDescriptionRepo->findOneBy([
  1439.                             'lounge' => $newLounge
  1440.                         ]);
  1441.                     }
  1442.                     $loungeImportantDescGeneralText =
  1443.                         $loungeWebDescription
  1444.                             ? $loungeWebDescription->getImportantDescGeneralText()
  1445.                             : '';
  1446.                     $loungeImportantDescSchedules =
  1447.                         $loungeWebDescription
  1448.                             ? $loungeWebDescription->getImportantDescSchedules()
  1449.                             : '';
  1450.                     $loungeImportantDescParking =
  1451.                         $loungeWebDescription
  1452.                             ? $loungeWebDescription->getImportantDescParking()
  1453.                             : '';
  1454.                     $loungeSummaryDescription =
  1455.                         $loungeWebDescription
  1456.                             ? $loungeWebDescription->getImportantDescription()
  1457.                             : '';
  1458.                     /*
  1459.                      * ---------------------------------------------
  1460.                      * Crear nueva ReservationLoungeSimple
  1461.                      * ---------------------------------------------
  1462.                      */
  1463.                     $newLoungeSimple = new ReservationLoungeSimple();
  1464.                     $newLoungeSimple->setDateStart(
  1465.                         $item->getDateStart()
  1466.                     );
  1467.                     $newLoungeSimple->setDateEnd(
  1468.                         $item->getDateEnd()
  1469.                     );
  1470.                     $newLoungeSimple->setIdReservation(
  1471.                         $reservationId
  1472.                     );
  1473.                     $newLoungeSimple->setPax(
  1474.                         $item->getPax()
  1475.                     );
  1476.                     $newLoungeSimple->setType(
  1477.                         $item->getType()
  1478.                     );
  1479.                     $newLoungeSimple->setCreatedAt(
  1480.                         $now
  1481.                     );
  1482.                     $newLoungeSimple->setCreatedBy(
  1483.                         $userId
  1484.                     );
  1485.                     $newLoungeSimple->setUpdatedAt(
  1486.                         $now
  1487.                     );
  1488.                     $newLoungeSimple->setUpdatedBy(
  1489.                         $userId
  1490.                     );
  1491.                     $newLoungeSimple->setHourStart(
  1492.                         $item->getHourStart()
  1493.                     );
  1494.                     $newLoungeSimple->setMinStart(
  1495.                         $item->getMinStart()
  1496.                     );
  1497.                     $newLoungeSimple->setHourEnd(
  1498.                         $item->getHourEnd()
  1499.                     );
  1500.                     $newLoungeSimple->setMinEnd(
  1501.                         $item->getMinEnd()
  1502.                     );
  1503.                     /*
  1504.                      * NUEVO rankQuote.
  1505.                      */
  1506.                     $newLoungeSimple->setRankQuote(
  1507.                         $newRankQuote
  1508.                     );
  1509.                     /*
  1510.                      * Datos fiscales.
  1511.                      */
  1512.                     $newLoungeSimple->setIva(
  1513.                         $item->getIva()
  1514.                     );
  1515.                     $newLoungeSimple->setOpIva(
  1516.                         $item->getOpIva()
  1517.                     );
  1518.                     /*
  1519.                      * NUEVA SALA.
  1520.                      */
  1521.                     $newLoungeSimple->setIdLounge(
  1522.                         $newLounge->getId()
  1523.                     );
  1524.                     $newLoungeSimple->setLoungename(
  1525.                         $newLounge->getName()
  1526.                     );
  1527.                     /*
  1528.                      * Nuevas descripciones de la sala.
  1529.                      */
  1530.                     $newLoungeSimple->setImportantDescription(
  1531.                         $loungeSummaryDescription
  1532.                     );
  1533.                     $newLoungeSimple->setImportantDescGeneralText(
  1534.                         $loungeImportantDescGeneralText
  1535.                     );
  1536.                     $newLoungeSimple->setImportantDescSchedules(
  1537.                         $loungeImportantDescSchedules
  1538.                     );
  1539.                     $newLoungeSimple->setImportantDescParking(
  1540.                         $loungeImportantDescParking
  1541.                     );
  1542.                     /*
  1543.                      * Resto de datos heredados.
  1544.                      */
  1545.                     $newLoungeSimple->setLanguage(
  1546.                         $item->getLanguage()
  1547.                     );
  1548.                     $newLoungeSimple->setSageArticle(
  1549.                         $item->getSageArticle()
  1550.                     );
  1551.                     $newLoungeSimple->setSentToSage(
  1552.                         $item->isSentToSage()
  1553.                     );
  1554.                     $newLoungeSimple->setSageIva(
  1555.                         $item->getSageIva()
  1556.                     );
  1557.                     $newLoungeSimple->setShowAudiovisualPrice(
  1558.                         $item->isShowAudiovisualPrice()
  1559.                     );
  1560.                     $newLoungeSimple->setShowAudiovisualPackage(
  1561.                         $item->isShowAudiovisualPackage()
  1562.                     );
  1563.                     /*
  1564.                      * ---------------------------------------------
  1565.                      * PRECIO
  1566.                      * ---------------------------------------------
  1567.                      *
  1568.                      * Si el usuario ha indicado un precio para
  1569.                      * esta sala, utilizamos ese.
  1570.                      *
  1571.                      * Si lo deja vacío, heredamos el de origen.
  1572.                      */
  1573.                     if ($customPrice !== null) {
  1574.                         $newLoungeSimple->setServicePrice(
  1575.                             $customPrice
  1576.                         );
  1577.                     } else {
  1578.                         $newLoungeSimple->setServicePrice(
  1579.                             $item->getServicePrice()
  1580.                         );
  1581.                     }
  1582.                     /*
  1583.                      * Persistimos.
  1584.                      */
  1585.                     $em->persist($newLoungeSimple);
  1586.                     /*
  1587.                      * Guardamos referencia para agenda/limpieza.
  1588.                      */
  1589.                     $newLoungeSimples[] = $newLoungeSimple;
  1590.                 }
  1591.             }
  1592.             /*
  1593.              * =====================================================
  1594.              * FLUSH DE LAS NUEVAS ReservationLoungeSimple
  1595.              * =====================================================
  1596.              *
  1597.              * Necesitamos que tengan ID antes de crear la agenda.
  1598.              */
  1599.             $em->flush();
  1600.             /*
  1601.              * =====================================================
  1602.              * CREAR AGENDA + LIMPIEZA
  1603.              * =====================================================
  1604.              */
  1605.             foreach ($newLoungeSimples as $newLoungeSimple) {
  1606.                 /*
  1607.                  * -------------------------------------------------
  1608.                  * AGENDA
  1609.                  * -------------------------------------------------
  1610.                  *
  1611.                  * IMPORTANTE:
  1612.                  *
  1613.                  * Aquí dejamos doFlush = true.
  1614.                  *
  1615.                  * createAgendaFromSource() calcula el rankListing
  1616.                  * consultando la BD. Si hiciéramos varias llamadas
  1617.                  * con false, podría calcular el mismo rank para
  1618.                  * varias líneas porque todavía no estarían
  1619.                  * visibles en BD.
  1620.                  *
  1621.                  * Estos flush siguen estando dentro de la
  1622.                  * transaction, por lo que un rollback los deshace.
  1623.                  */
  1624.                 $agendaCreated = $this->agendaService->createAgendaFromSource(
  1625.                     $newLoungeSimple->getIdReservation(),
  1626.                     'SALAS A UTILIZAR',
  1627.                     null,
  1628.                     null,
  1629.                     $newLoungeSimple->getDateStart(),
  1630.                     $newLoungeSimple->getDateEnd(),
  1631.                     $newLoungeSimple->getLoungename(),
  1632.                     $newLoungeSimple->getId(),
  1633.                     'ReservationLoungeSimple',
  1634.                     $newLoungeSimple->getUpdatedBy(),
  1635.                     true
  1636.                 );
  1637.                 if (!$agendaCreated) {
  1638.                     throw new \RuntimeException(
  1639.                         'No se pudo crear la agenda para la sala ' .
  1640.                         $newLoungeSimple->getLoungename()
  1641.                     );
  1642.                 }
  1643.                 /*
  1644.                  * -------------------------------------------------
  1645.                  * SERVICIO DE LIMPIEZA
  1646.                  * -------------------------------------------------
  1647.                  *
  1648.                  * Esto estaba comentado en tu duplicateQuoteAction
  1649.                  * original. Aquí lo activamos porque tu
  1650.                  * deleteQuoteAction() contempla explícitamente
  1651.                  * estos servicios.
  1652.                  */
  1653.                 $service = new ReservationService();
  1654.                 $service->setReservationId(
  1655.                     $reservationId
  1656.                 );
  1657.                 $service->setSupplierId(0);
  1658.                 $service->setDateInAt(
  1659.                     $newLoungeSimple->getDateStart()
  1660.                 );
  1661.                 $service->setDateOutAt(
  1662.                     $newLoungeSimple->getDateEnd()
  1663.                 );
  1664.                 $service->setCreatedId(
  1665.                     $userId
  1666.                 );
  1667.                 $service->setUpdatedId(
  1668.                     $userId
  1669.                 );
  1670.                 $service->setCreatedAt(
  1671.                     new \DateTime('now')
  1672.                 );
  1673.                 $service->setUpdatedAt(
  1674.                     new \DateTime('now')
  1675.                 );
  1676.                 $service->setServiceCatId('21');
  1677.                 $service->setServiceCatName('Limpieza');
  1678.                 $service->setContcolor('green-300');
  1679.                 $service->setName(
  1680.                     'HORAS ( ' .
  1681.                     $newLoungeSimple->getLoungeName() .
  1682.                     ' )'
  1683.                 );
  1684.                 $service->setPrice('14');
  1685.                 $service->setCurrency('Euro');
  1686.                 $service->setUnits('8');
  1687.                 $service->setCommission('0');
  1688.                 $service->setPax('0');
  1689.                 $service->setOver('0');
  1690.                 $service->setIva('21');
  1691.                 $service->setOpIva('1');
  1692.                 $service->setOpCommission('1');
  1693.                 $service->setCommission('57.14');
  1694.                 $service->setViewInfo(0);
  1695.                 $service->setToinvoice(0);
  1696.                 $service->setServiceId(0);
  1697.                 $em->persist($service);
  1698.             }
  1699.             /*
  1700.              * =====================================================
  1701.              * ELIMINAR COTIZACIÓN ORIGEN
  1702.              * =====================================================
  1703.              *
  1704.              * Solo llegamos aquí si:
  1705.              *
  1706.              * - todas las nuevas líneas se han creado
  1707.              * - las agendas se han creado correctamente
  1708.              *
  1709.              * Por tanto, si falla algo después, el rollback
  1710.              * también recuperará el origen.
  1711.              */
  1712.             if ($deleteSource) {
  1713.                 foreach ($sourceItems as $item) {
  1714.                     /*
  1715.                      * Eliminar entrada de agenda del origen.
  1716.                      */
  1717.                     $this->agendaService->deleteAgendaBySource(
  1718.                         $item->getId(),
  1719.                         'ReservationLoungeSimple'
  1720.                     );
  1721.                     /*
  1722.                      * Guardamos la línea para comprobar conflictos
  1723.                      * después del flush.
  1724.                      */
  1725.                     $sourceItemsToDelete[] = $item;
  1726.                     /*
  1727.                      * ---------------------------------------------
  1728.                      * Eliminar servicio de limpieza del origen
  1729.                      * ---------------------------------------------
  1730.                      */
  1731.                     $loungeDetails = $em
  1732.                         ->getRepository(ReservationLoungeDetails::class)
  1733.                         ->findOneById(
  1734.                             $item->getIdLounge()
  1735.                         );
  1736.                     if ($loungeDetails) {
  1737.                         $stringName =
  1738.                             'HORAS ( ' .
  1739.                             $loungeDetails->getName() .
  1740.                             ' )';
  1741.                         $dateInAt = new \DateTime(
  1742.                             $item->getDateStart()->format('Y-m-d\TH:i')
  1743.                         );
  1744.                         $dateOutAt = new \DateTime(
  1745.                             $item->getDateEnd()->format('Y-m-d\TH:i')
  1746.                         );
  1747.                         $serviceClean = $em
  1748.                             ->getRepository(ReservationService::class)
  1749.                             ->createQueryBuilder('rs')
  1750.                             ->where('rs.reservationId = :id')
  1751.                             ->andWhere('rs.name = :name')
  1752.                             ->andWhere('rs.dateInAt = :dateInAt')
  1753.                             ->andWhere('rs.dateOutAt = :dateOutAt')
  1754.                             ->andWhere('rs.serviceCatId = :serviceCatId')
  1755.                             ->setParameter(
  1756.                                 'id',
  1757.                                 $reservationId
  1758.                             )
  1759.                             ->setParameter(
  1760.                                 'name',
  1761.                                 $stringName
  1762.                             )
  1763.                             ->setParameter(
  1764.                                 'dateInAt',
  1765.                                 $dateInAt
  1766.                             )
  1767.                             ->setParameter(
  1768.                                 'dateOutAt',
  1769.                                 $dateOutAt
  1770.                             )
  1771.                             ->setParameter(
  1772.                                 'serviceCatId',
  1773.                                 21
  1774.                             )
  1775.                             ->getQuery()
  1776.                             ->getResult();
  1777.                         foreach ($serviceClean as $cleanService) {
  1778.                             $em->remove($cleanService);
  1779.                         }
  1780.                     }
  1781.                     /*
  1782.                      * Finalmente marcamos para eliminar la línea
  1783.                      * ReservationLoungeSimple.
  1784.                      */
  1785.                     $em->remove($item);
  1786.                 }
  1787.                 /*
  1788.                  * Aplicamos los remove().
  1789.                  */
  1790.                 $em->flush();
  1791.                 /*
  1792.                  * ---------------------------------------------
  1793.                  * Comprobar conflictos
  1794.                  * ---------------------------------------------
  1795.                  *
  1796.                  * Lo hacemos DESPUÉS del flush para mantener
  1797.                  * el mismo comportamiento que tenía tu
  1798.                  * deleteQuoteAction().
  1799.                  */
  1800.                 foreach ($sourceItemsToDelete as $deletedItem) {
  1801.                     $conflictService->checkDeletedLoungeConflictsQuotes(
  1802.                         $reserva,
  1803.                         $deletedItem
  1804.                     );
  1805.                 }
  1806.                 /*
  1807.                  * Si el servicio de conflictos ha hecho cambios
  1808.                  * en entidades Doctrine, los guardamos.
  1809.                  */
  1810.                 $em->flush();
  1811.             } else {
  1812.                 /*
  1813.                  * Si no eliminamos origen, guardamos los servicios
  1814.                  * de limpieza que acabamos de persistir.
  1815.                  */
  1816.                 $em->flush();
  1817.             }
  1818.             /*
  1819.              * =====================================================
  1820.              * COMMIT
  1821.              * =====================================================
  1822.              */
  1823.             $connection->commit();
  1824.         } catch (\Throwable $e) {
  1825.             /*
  1826.              * =====================================================
  1827.              * ROLLBACK
  1828.              * =====================================================
  1829.              */
  1830.             if ($connection->isTransactionActive()) {
  1831.                 $connection->rollBack();
  1832.             }
  1833.             /*
  1834.              * Limpiamos el EntityManager para evitar trabajar
  1835.              * posteriormente con entidades que hayan quedado
  1836.              * en estado inconsistente.
  1837.              */
  1838.             $em->clear();
  1839.             /*
  1840.              * Log opcional.
  1841.              */
  1842.             if (method_exists($this, 'get')) {
  1843.                 try {
  1844.                     $logger = $this->get('logger');
  1845.                     if ($logger) {
  1846.                         $logger->error(
  1847.                             'Error duplicando cotización',
  1848.                             [
  1849.                                 'reservationId' => $reservationId,
  1850.                                 'sourceRankQuote' => $sourceRankQuote,
  1851.                                 'exception' => $e
  1852.                             ]
  1853.                         );
  1854.                     }
  1855.                 } catch (\Throwable $loggerException) {
  1856.                     // No hacemos nada si no existe logger.
  1857.                 }
  1858.             }
  1859.             $this->addFlash(
  1860.                 'mensajereservationerror',
  1861.                 $this->translator->trans(
  1862.                     'No se ha podido duplicar la cotización. No se han aplicado los cambios.'
  1863.                 )
  1864.             );
  1865.             return $this->redirectToRoute(
  1866.                 'reservations_venues_edit_simple',
  1867.                 [
  1868.                     'id' => $reservationId,
  1869.                     'token' => null,
  1870.                     '_fragment' => 'btn_quotes'
  1871.                 ]
  1872.             );
  1873.         }
  1874.         /*
  1875.          * =========================================================
  1876.          * PROCESOS POSTERIORES AL COMMIT
  1877.          * =========================================================
  1878.          *
  1879.          * Estos procesos trabajan ya sobre el estado definitivo
  1880.          * de la reserva.
  1881.          */
  1882.         try {
  1883.             /*
  1884.              * Usuario logueado
  1885.              */
  1886.             $user_logueado = $this
  1887.                 ->get('security.token_storage')
  1888.                 ->getToken()
  1889.                 ->getUser();
  1890.             $user_id = $user_logueado->getId();
  1891.             /*
  1892.              * -----------------------------------------------------
  1893.              * Actualizar PAX de agenda
  1894.              * -----------------------------------------------------
  1895.              */
  1896.             $paxAge = $this->agendaService->calculatePaxForReservation(
  1897.                 $reservationId
  1898.             );
  1899.             $this->agendaService->updatePaxLine(
  1900.                 $reservationId,
  1901.                 $paxAge,
  1902.                 $user_id
  1903.             );
  1904.             /*
  1905.              * -----------------------------------------------------
  1906.              * Actualizar fechas de agenda
  1907.              * -----------------------------------------------------
  1908.              */
  1909.             $this->agendaService->updateDatesLine(
  1910.                 $reservationId,
  1911.                 $user_id
  1912.             );
  1913.             /*
  1914.              * -----------------------------------------------------
  1915.              * Recalcular fechas de la reserva
  1916.              * -----------------------------------------------------
  1917.              */
  1918.             $reservaEntity = $em
  1919.                 ->getRepository(Reservation::class)
  1920.                 ->find($reservationId);
  1921.             if ($reservaEntity) {
  1922.                 $this->reservationService->updateReservationDates(
  1923.                     $reservaEntity
  1924.                 );
  1925.             }
  1926.             /*
  1927.              * -----------------------------------------------------
  1928.              * Snapshot
  1929.              * -----------------------------------------------------
  1930.              */
  1931.             if ($reservaEntity) {
  1932.                 $this->venueService->createSnapshot(
  1933.                     $reservaEntity
  1934.                 );
  1935.             }
  1936.         } catch (\Throwable $e) {
  1937.             /*
  1938.              * La duplicación ya se ha realizado correctamente.
  1939.              *
  1940.              * Si falla una actualización secundaria, no hacemos
  1941.              * rollback de la duplicación.
  1942.              */
  1943.             $this->addFlash(
  1944.                 'mensajereservationerror',
  1945.                 $this->translator->trans(
  1946.                     'La cotización se ha duplicado, pero ha ocurrido un error al actualizar algunos datos de la reserva.'
  1947.                 )
  1948.             );
  1949.             return $this->redirectToRoute(
  1950.                 'reservations_venues_edit_simple',
  1951.                 [
  1952.                     'id' => $reservationId,
  1953.                     'token' => null,
  1954.                     '_fragment' => 'btn_quotes'
  1955.                 ]
  1956.             );
  1957.         }
  1958.         /*
  1959.          * =========================================================
  1960.          * MENSAJE FINAL
  1961.          * =========================================================
  1962.          */
  1963.         if ($deleteSource) {
  1964.             $event =
  1965.                 'La cotización se ha duplicado correctamente y la opción origen ha sido eliminada.';
  1966.         } else {
  1967.             $event =
  1968.                 'La cotización se ha duplicado correctamente.';
  1969.         }
  1970.         $successMessage = $this->translator->trans($event);
  1971.         $this->addFlash(
  1972.             'mensajereservation',
  1973.             $successMessage
  1974.         );
  1975.         /*
  1976.          * =========================================================
  1977.          * REDIRECT
  1978.          * =========================================================
  1979.          */
  1980.         return $this->redirectToRoute(
  1981.             'reservations_venues_edit_simple',
  1982.             [
  1983.                 'id' => $reservationId,
  1984.                 'token' => null,
  1985.                 '_fragment' => 'btn_quotes'
  1986.             ]
  1987.         );
  1988.     }
  1989.     /**
  1990.      * @Route("/loghistoric/{id}", name="reservations_log_historic")
  1991.      * Log del historico de la cotizacion de la reserva id
  1992.      */
  1993.     public function logHistoricQuoteAction($id, EntityManagerInterface $em, Request $request){
  1994.         $reservaLogs = $em->getRepository(ReservationLoungeSimpleServiceLog::class)->findByReservaId($id);
  1995.         return $this->render(
  1996.             'MDS/VenuesBundle/reservations/list-reservations-log-historic.html.twig',
  1997.             array(
  1998.                 'id' => $id,
  1999.                 'reservaLogs' => $reservaLogs,
  2000.             )
  2001.         );
  2002.     }
  2003.     /**
  2004.      * @Route("/logrecover/{reservationId}/{versionId}", name="reservations_log_recover")
  2005.      * Recuperar desde Log de historico una versión de una reserva. Se eliminaran salas y servicios del expediente no facturados
  2006.      */
  2007.     public function logRecoverQuoteAction($reservationId, $versionId, EntityManagerInterface $em, Request $request){
  2008.         $reservaLogs = $em->getRepository(ReservationLoungeSimpleServiceLog::class)->findBy(array('reservaId' => $reservationId, 'version' => $versionId));
  2009.         $reservationsLounges = $em->getRepository(ReservationLoungeSimple::class)->findBy(array('idReservation' => $reservationId));
  2010.         $reservationsLoungesInvoiced = $em->getRepository(ReservationInvoiceItems::class)->findBy(array('reservationId' => $reservationId, 'itemType' => 'LOUNGE'));
  2011.         $reservationsServices = $em->getRepository(ReservationService::class)->findBy(array('reservationId' => $reservationId));
  2012.         $reservationsServicesInvoiced = $em->getRepository(ReservationInvoiceItems::class)->findBy(array('reservationId' => $reservationId, 'itemType' => 'SERVICE'));
  2013.         $sageIva = $em->getRepository(SageVatRates::class)->findOneBySageCode('03');
  2014.         /* Obtengo usuario logueado */
  2015.         $user = $this->get('security.token_storage')->getToken()->getUser();
  2016.         // 1. Obtener los IDs de los items que SÍ están facturados
  2017.         $invoicedLoungeIds = [];
  2018.         foreach ($reservationsLoungesInvoiced as $invoiceLounge) {
  2019.             $invoicedLoungeIds[] = $invoiceLounge->getLngControlId();
  2020.         }
  2021.         $invoicedServiceIds = [];
  2022.         foreach ($reservationsServicesInvoiced as $invoiceService) {
  2023.             $invoicedServiceIds[] = $invoiceService->getSrvControlId();
  2024.         }
  2025.         // 2. Eliminar los Lounges (Salas) que NO están facturados
  2026.         foreach ($reservationsLounges as $lounge) {
  2027.             if (!in_array($lounge->getId(), $invoicedLoungeIds)) {
  2028.                 $em->remove($lounge);
  2029.             }
  2030.         }
  2031.         // 2.1 Eliminar los Servicios que NO están facturados
  2032.         foreach ($reservationsServices as $service) {
  2033.             if (!in_array($service->getId(), $invoicedServiceIds)) {
  2034.                 $em->remove($service);
  2035.             }
  2036.         }
  2037.         // 3. Generar las nuevas entidades a partir del Log
  2038.         foreach ($reservaLogs as $log) {
  2039.             if ($log->getItemType() === 'lounge') {
  2040.                 $newLounge = new ReservationLoungeSimple();
  2041.                 $newLounge->setIdReservation($log->getReservaId());
  2042.                 $newLounge->setIdLounge($log->getIdLounge());
  2043.                 $newLounge->setLoungeName($log->getItemName());
  2044.                 $newLounge->setDateStart($log->getDateStart());
  2045.                 $newLounge->setDateEnd($log->getDateEnd());
  2046.                 $newLounge->setPax($log->getPax());
  2047.                 $newLounge->setRankQuote($log->getRankQuote());
  2048.                 $newLounge->setServicePrice((string)$log->getPrice());
  2049.                 $newLounge->setSageIva($sageIva);
  2050.                 $newLounge->setCreatedBy($log->getAgentId());
  2051.                 $newLounge->setUpdatedBy($log->getAgentId());
  2052.                 // Mapear el desglose de horas para la sala
  2053.                 if ($log->getDateStart()) {
  2054.                     $newLounge->setHourStart($log->getDateStart()->format('H'));
  2055.                     $newLounge->setMinStart($log->getDateStart()->format('i'));
  2056.                 }
  2057.                 if ($log->getDateEnd()) {
  2058.                     $newLounge->setHourEnd($log->getDateEnd()->format('H'));
  2059.                     $newLounge->setMinEnd($log->getDateEnd()->format('i'));
  2060.                 }
  2061.                 $loungeProfile = $em->getRepository(ReservationLoungeDetails::class)->findOneById($log->getIdLounge());
  2062.                 $idioma = 1;
  2063.                 // Descripciones web por sala/idioma con fallbacks
  2064.                 $loungeWebDescriptionRepo = $em->getRepository(ReservationLoungeWebDescription::class);
  2065.                 $loungeWebDescription = $loungeWebDescriptionRepo->findOneBy([
  2066.                         'lounge' => $loungeProfile,
  2067.                         'language' => $idioma
  2068.                     ]) ?? ($idioma !== 1 ? $loungeWebDescriptionRepo->findOneBy([
  2069.                         'lounge' => $loungeProfile,
  2070.                         'language' => 1
  2071.                     ]) : null) ?? $loungeWebDescriptionRepo->findOneBy(['lounge' => $loungeProfile]);
  2072.                 $loungeSummaryDescription = null;
  2073.                 $loungeImportantDescGeneralText = $loungeWebDescription ? $loungeWebDescription->getImportantDescGeneralText() : '';
  2074.                 $loungeImportantDescSchedules = $loungeWebDescription ? $loungeWebDescription->getImportantDescSchedules() : '';
  2075.                 $loungeImportantDescParking = $loungeWebDescription ? $loungeWebDescription->getImportantDescParking() : '';
  2076.                 $loungeSummaryDescription = $loungeWebDescription ? $loungeWebDescription->getImportantDescription() : '';
  2077.                 $newLounge->setImportantDescription($loungeSummaryDescription ?? '');
  2078.                 $newLounge->setImportantDescGeneralText($loungeImportantDescGeneralText ?? '');
  2079.                 $newLounge->setImportantDescSchedules($loungeImportantDescSchedules ?? '');
  2080.                 $newLounge->setImportantDescParking($loungeImportantDescParking ?? '');
  2081.                 $em->persist($newLounge);
  2082.             } elseif ($log->getItemType() === 'service') {
  2083.                 $newService = new ReservationService();
  2084.                 $newService->setReservationId($log->getReservaId());
  2085.                 $newService->setServiceId($log->getItemId());
  2086.                 $newService->setName($log->getItemName());
  2087.                 $newService->setPrice((string)$log->getPrice());
  2088.                 $newService->setPax((string)$log->getPax());
  2089.                 $newService->setDateInAt($log->getDateStart());
  2090.                 $newService->setDateOutAt($log->getDateEnd());
  2091.                 // Mapeo específico de servicios
  2092.                 $newService->setUnits($log->getUnits() ?? '1');
  2093.                 $newService->setOpCommission($log->getOpCommission());
  2094.                 $newService->setCommission($log->getCommission() ?? '0');
  2095.                 $newService->setOver($log->getPriceOver());
  2096.                 $newService->setToinvoice($log->getToinvoice());
  2097.                 $newService->setViewInfo($log->getViewInfo() ?? false);
  2098.                 $newService->setServiceCatId($log->getServiceCatId());
  2099.                 $newService->setServiceCatName($log->getServiceCatName());
  2100.                 $newService->setCreatedId($user->getId());
  2101.                 $newService->setUpdatedId($user->getId());
  2102.                 $newService->setSageIva($sageIva);
  2103.                 $newService->setIva(21);
  2104.                 if ($log->getDateStart()) {
  2105.                     $newService->setHour($log->getDateStart()->format('H:i'));
  2106.                 }
  2107.                 // VALORES POR DEFECTO REQUERIDOS
  2108.                 $newService->setSupplierId(0);
  2109.                 $newService->setContcolor('#000000');
  2110.                 $em->persist($newService);
  2111.             }
  2112.         }
  2113.         // 4. Ejecutar todas las eliminaciones e inserciones en la BBDD
  2114.         $em->flush();
  2115.         return $this->redirectToRoute(
  2116.             'reservations_venues_edit_simple',
  2117.             array(
  2118.                 'id' => $reservationId,
  2119.                 'token' => null,
  2120.                 '_fragment' => 'btn_quotes'
  2121.             )
  2122.         );
  2123.     }
  2124.     /**
  2125.      * @Route("/productfileavlist/{id}",  name="reservations_list_multiple_productfile_av")
  2126.      * Listar productos de Av para agregar en el servicio id
  2127.      */
  2128.     public function listMultipleProductAvAction( $id, Request $request){
  2129.         $em = $this->getDoctrine()->getManager();
  2130.         $parameters = [];
  2131.         $dql = 'SELECT i
  2132.                 FROM AvexpressBundle:AveProduct i
  2133.                 ORDER BY i.name ASC';
  2134.         $query = $em->createQuery($dql)->setParameters($parameters);
  2135.         $avs = $query->getResult();
  2136.         $dql = 'SELECT i
  2137.                 FROM AvexpressBundle:AvePackageTemplate i
  2138.                 ORDER BY i.name ASC';
  2139.         $query = $em->createQuery($dql)->setParameters($parameters);
  2140.         $avsPack = $query->getResult();
  2141.         $data_av = [];
  2142.         foreach ($avsPack as $item) {
  2143.             $productNames = [];
  2144.             $parameters = ['packId' => $item->getId()];
  2145.             $dql = 'SELECT i
  2146.                 FROM AvexpressBundle:AvePackageTemplateItems i
  2147.                 WHERE i.packId = :packId
  2148.                 ORDER BY i.rankAvPack ASC';
  2149.             $query = $em->createQuery($dql)->setParameters($parameters);
  2150.             $avsPackProducts = $query->getResult();
  2151.             foreach ($avsPackProducts as $product) { $productNames[] = $product->getProductName(); }
  2152.             $packageName = $item->getName();
  2153.             if (!empty($productNames)) { $packageName .= ' (' . implode(', ', $productNames) . ')'; }
  2154.             $data_av[] = array(
  2155.                 'id'    => $item->getId(),
  2156.                 'name'  => $packageName,
  2157.                 'type'  => 'Paquete',
  2158.                 'price' => $item->getPricePackage(),
  2159.             );
  2160.         }
  2161.         foreach($avs as $av){
  2162.             $data_av[] = array(
  2163.                 'id' => $av->getId(),
  2164.                 'name' => $av->getName(),
  2165.                 'type' => $av->getType(),
  2166.                 'price' => $av->getPrice(),
  2167.             );
  2168.         }
  2169.         $resService = $em->getRepository(ReservationService::class)->findOneById($id);
  2170.         return $this->render('MDS/VenuesBundle/reservations/add-services-avs.html.twig',
  2171.             array(
  2172.                 'id' => $id,
  2173.                 'idRes' => empty($resService) ? 0 : $resService->getReservationId(),
  2174.                 'avs' => $data_av,
  2175.             ));
  2176.     }
  2177.     /**
  2178.      * @Route("/productfileavadd/{id}",  name="reservations_add_multiple_productfile_av")
  2179.      * Agregar productos de Av para agregar en el servicio id
  2180.      */
  2181.     public function addMultipleProductAvAction( $id, Request $request){
  2182.         $em = $this->getDoctrine()->getManager();
  2183.         $resService = $em->getRepository(ReservationService::class)->findOneById($id);
  2184.         $prodSelected = $request->request->get('details');
  2185.         $serviceName = '';
  2186.         $servicePrice = 0;
  2187.         foreach ($prodSelected as $item){
  2188.             if(empty($serviceName)){
  2189.                 $serviceName .= $item['name'];
  2190.             } else {
  2191.                 $serviceName .= ' + '. $item['name'];
  2192.             }
  2193.             $servicePrice += $item['total_price'];
  2194.         }
  2195.         $resService->setName($serviceName);
  2196.         $resService->setPrice($servicePrice);
  2197.         $resService->setToInvoice(1);
  2198.         $resService->setOpIva(1);
  2199.         $resService->setIva(21);
  2200.         try {
  2201.             $em->persist($resService);
  2202.             $em->flush();
  2203.             $event = 'The Reservation has been updated.';
  2204.             $successMessage = $this->translator->trans($event);
  2205.             $this->addFlash('mensajereservation', $successMessage);
  2206.         } catch (\Exception $e) {
  2207.             $event = 'An error occurred: ' . $e->getMessage();
  2208.             $errorMessage = $this->translator->trans($event);
  2209.             $this->addFlash('mensajereservationerror', $errorMessage);
  2210.         }
  2211.         return $this->redirectToRoute('reservations_venues_edit_simple', [
  2212.             'id' => $resService->getReservationId(),
  2213.             'token' => null,
  2214.             '_fragment' => 'btn_srv'
  2215.         ]);
  2216.     }
  2217.     /**
  2218.      * @Route("/reschedule/{reservationId}/{newDate}", name="reservations_reschedule", methods={"POST"})
  2219.      * Reprogramar todas las fechas del evento, incluido reservations, reservationLoungeSimple y reservationService
  2220.      */
  2221.     public function rescheduleQuoteAction($reservationId, $newDate, EntityManagerInterface $em, Request $request)
  2222.     {
  2223.         try {
  2224.             $reservation = $em->getRepository(Reservation::class)->find($reservationId);
  2225.             if (!$reservation) {
  2226.                 return new JsonResponse(['status' => 'error', 'message' => 'Reserva no encontrada.'], 404);
  2227.             }
  2228.             $oldStartDate = $reservation->getDateStart();
  2229.             if (!$oldStartDate) {
  2230.                 return new JsonResponse(['status' => 'error', 'message' => 'La reserva actual no tiene una fecha de inicio configurada.'], 400);
  2231.             }
  2232.             // Establecemos las horas a las 00:00:00 para calcular los días exactos sin afectar los husos horarios
  2233.             $oldStartMidnight = clone $oldStartDate;
  2234.             $oldStartMidnight->setTime(0, 0, 0);
  2235.             $newStartMidnight = new \DateTime($newDate);
  2236.             $newStartMidnight->setTime(0, 0, 0);
  2237.             // Calculamos la diferencia en días
  2238.             $interval = $oldStartMidnight->diff($newStartMidnight);
  2239.             $daysDiff = $interval->days;
  2240.             $invert = $interval->invert; // 1 si la fecha nueva es pasada, 0 si es futura
  2241.             if ($daysDiff === 0) {
  2242.                 return new JsonResponse(['status' => 'error', 'message' => 'La fecha seleccionada es igual a la actual.'], 400);
  2243.             }
  2244.             // Función anónima para aplicar la suma/resta de días a una fecha conservando su hora original
  2245.             $applyInterval = function(?\DateTime $date) use ($daysDiff, $invert) {
  2246.                 if (!$date) return null;
  2247.                 $clonedDate = clone $date;
  2248.                 $intervalStr = 'P' . $daysDiff . 'D'; // P[N]D = Period N Days
  2249.                 if ($invert) {
  2250.                     $clonedDate->sub(new \DateInterval($intervalStr));
  2251.                 } else {
  2252.                     $clonedDate->add(new \DateInterval($intervalStr));
  2253.                 }
  2254.                 return $clonedDate;
  2255.             };
  2256.             // 1. Reprogramar la Reserva
  2257.             // Asignamos la nueva fecha (preservando la hora del inicio antiguo, si tuviera alguna)
  2258.             $reservation->setDateStart($applyInterval($reservation->getDateStart()));
  2259.             if ($reservation->getDateEnd()) {
  2260.                 $reservation->setDateEnd($applyInterval($reservation->getDateEnd()));
  2261.             }
  2262.             // 2. Reprogramar las Salas (ReservationLoungeSimple)
  2263.             $lounges = $em->getRepository(ReservationLoungeSimple::class)->findBy(['idReservation' => $reservationId]);
  2264.             foreach ($lounges as $lounge) {
  2265.                 $lounge->setDateStart($applyInterval($lounge->getDateStart()));
  2266.                 $lounge->setDateEnd($applyInterval($lounge->getDateEnd()));
  2267.             }
  2268.             // 3. Reprogramar los Servicios (ReservationService)
  2269.             $services = $em->getRepository(ReservationService::class)->findBy(['reservationId' => $reservationId]);
  2270.             foreach ($services as $service) {
  2271.                 $service->setDateInAt($applyInterval($service->getDateInAt()));
  2272.                 $service->setDateOutAt($applyInterval($service->getDateOutAt()));
  2273.             }
  2274.             $em->flush();
  2275.             // Creamos la Snapshot de las salas y servicios del sistema (LOG)
  2276.             $version = $this->venueService->createSnapshot($reservation);
  2277.             return new JsonResponse([
  2278.                 'status' => 'success',
  2279.                 'message' => 'Las fechas del evento han sido reprogramadas correctamente.'
  2280.             ]);
  2281.         } catch (\Exception $e) {
  2282.             return new JsonResponse([
  2283.                 'status' => 'error',
  2284.                 'message' => 'Ocurrió un error en el servidor: ' . $e->getMessage()
  2285.             ], 500);
  2286.         }
  2287.     }
  2288.     /**
  2289.      * @Route("/registerFormGpWeb/{token}", name="registerformgpweb", defaults={"token"=null})
  2290.      * Crear una reserva con la información que llega desde la web
  2291.      * Crear la sala segun los datos ingresados
  2292.      * Generar un modelo de correo electronico para enviar la propuesta de cotización al cliente
  2293.      */
  2294.     public function registerFormWebApiAction($token, Request $request, EntityManagerInterface $em)
  2295.     {
  2296.         // ==========================================
  2297.         // 0. VALIDACIONES DE USUARIO Y RESERVA
  2298.         // ==========================================
  2299.         $user_logueado = $this->get('security.token_storage')->getToken()->getUser();
  2300.         if (!($user_logueado)){
  2301.             return $this->redirectToRoute('login');
  2302.         } else {
  2303.             $user_id = $user_logueado->getId();
  2304.         }
  2305.         $reservaPrevia = $em->getRepository(Reservation::class)->findOneByToken($token);
  2306.         if (!empty($reservaPrevia)){
  2307.             // Ya se ha creado la reserva previamente
  2308.             return $this->redirectToRoute('reservations_venues_edit_simple', array(
  2309.                 'id' => $reservaPrevia->getId(),
  2310.                 'token' => null,
  2311.                 '_fragment' => null
  2312.             ));
  2313.         }
  2314.         // ==========================================
  2315.         // 1. DESCIFRAR Y VALIDAR EL TOKEN
  2316.         // ==========================================
  2317.         if (empty($token)) {
  2318.             $this->addFlash('mensajereservationerror', 'No se ha proporcionado ningún token en la URL.');
  2319.             // Ajusta la ruta de retorno en caso de error
  2320.             return $this->redirectToRoute('reservations_greenpatio_index');
  2321.         }
  2322.         $base64Key = 'x4BMAcZUEQLNWgLB4NRHprTyySUZtcs4F1FCn9EKwJ4=';
  2323.         $key = base64_decode($base64Key);
  2324.         $parts = explode('.', $token);
  2325.         if (count($parts) !== 4 || $parts[0] !== 'v1') {
  2326.             $this->addFlash('mensajereservationerror', 'El formato del token no es válido.');
  2327.             return $this->redirectToRoute('reservations_greenpatio_index');
  2328.         }
  2329.         // Función auxiliar para decodificar Base64 URL-safe
  2330.         $base64UrlDecode = function($data) {
  2331.             $remainder = strlen($data) % 4;
  2332.             if ($remainder) {
  2333.                 $data .= str_repeat('=', 4 - $remainder);
  2334.             }
  2335.             return base64_decode(strtr($data, '-_', '+/'));
  2336.         };
  2337.         $iv         = $base64UrlDecode($parts[1]);
  2338.         $tag        = $base64UrlDecode($parts[2]);
  2339.         $ciphertext = $base64UrlDecode($parts[3]);
  2340.         $aad        = 'greenpatio-register-v1';
  2341.         // Descifrar usando AES-256-GCM
  2342.         $decrypted = openssl_decrypt(
  2343.             $ciphertext,
  2344.             'aes-256-gcm',
  2345.             $key,
  2346.             OPENSSL_RAW_DATA,
  2347.             $iv,
  2348.             $tag,
  2349.             $aad
  2350.         );
  2351.         if ($decrypted === false) {
  2352.             $this->addFlash('mensajereservationerror', 'No se pudo descifrar la información del token.');
  2353.             return $this->redirectToRoute('reservations_greenpatio_index');
  2354.         }
  2355.         $data = json_decode($decrypted, true);
  2356.         if (json_last_error() !== JSON_ERROR_NONE) {
  2357.             $this->addFlash('mensajereservationerror', 'El token no contiene datos válidos.');
  2358.             return $this->redirectToRoute('reservations_greenpatio_index');
  2359.         }
  2360.         // Opcional: Validar fecha de expiración si viene en el token
  2361.         if (isset($data['expiresAt']) && time() > $data['expiresAt']) {
  2362.             $this->addFlash('mensajereservationerror', 'El enlace de reserva ha expirado.');
  2363.             return $this->redirectToRoute('reservations_greenpatio_index');
  2364.         }
  2365.         // ==========================================
  2366.         // 2. EXTRAER LAS VARIABLES DEL TOKEN
  2367.         // ==========================================
  2368.         $yourName         = $data['name'] ?? '';
  2369.         $yourPhone        = $data['phone'] ?? '';
  2370.         $yourEmail        = $data['email'] ?? '';
  2371.         $yourReferral     = $data['referral'] ?? '';
  2372.         $eventDateString  = $data['eventDate'] ?? 'now';
  2373.         $yourEventDate    = \DateTime::createFromFormat('d/m/Y', trim($eventDateString));
  2374.         $yourAttendees    = $data['attendees'] ?? null;
  2375.         $eventSpace       = $data['eventSpace'] ?? '';
  2376.         $yourEventDetails = $data['eventDetails'] ?? '';
  2377.         // ==========================================
  2378.         // 3. CREAMOS LA RESERVA
  2379.         // ==========================================
  2380.         $hoy = new \DateTime("now", NULL);
  2381.         $reserva = new Reservation();
  2382.         $reserva->setTitle('Reserva ingresada en la web para el día: '. $yourEventDate->format('d/m/Y'));
  2383.         $reserva->setClient(null);
  2384.         $reserva->setCreatedAt($hoy);
  2385.         $reserva->setPriority(1);
  2386. //        $reserva->setDateStart(new \DateTime('2078-01-01'));
  2387.         $reserva->setDateStart($yourEventDate);
  2388. //        $reserva->setDateEnd(new \DateTime('2000-01-01'));
  2389.         $reserva->setDateEnd($yourEventDate);
  2390.         $reserva->setCreatedBy($user_id);
  2391.         $reserva->setSupplier(4765);        // Higo&Trigo
  2392.         $reserva->setStatus('Cotizado');
  2393.         $reserva->setUpdatedAt($hoy);
  2394.         $reserva->setUpdatedBy($user_id);
  2395.         $reserva->setDaysBlock(7);
  2396.         if (!empty($yourAttendees) and is_numeric($yourAttendees)){ $reserva->setPax($yourAttendees); } else { $reserva->setPax(null); }
  2397.         $reserva->setAccessKey(null);
  2398.         $reserva->setClientContact(null);
  2399.         $reserva->setContactUnregistered($yourEmail);       // Desde la web es requerido
  2400.         $reserva->setDays(null);
  2401.         $reserva->setContract(null);
  2402.         if (!empty($yourName)){ $reserva->setNameContactUnregistered($yourName); } else { $reserva->setNameContactUnregistered(null); }
  2403.         if (!empty($yourPhone)){ $reserva->setPhoneContactUnregistered($yourPhone); } else { $reserva->setPhoneContactUnregistered(null); }
  2404.         $reserva->setToken($token);
  2405.         $reserva->setComAvGp(10);
  2406.         $reserva->setComHtGp(14);
  2407.         $reserva->setInfoFormWeb($yourEmail .' || '. $yourReferral .' || '. $yourEventDate->format('d/m/Y') .' || '. $yourName .' || '. $yourPhone .' || '. $yourAttendees .' || '. $eventSpace);
  2408.         if (!empty($yourEventDetails)){ $reserva->setDescription($yourEventDetails); } else { $reserva->setDescription(null); }
  2409.         // --- Generamos la info del correo electronico y la agregamos a la descripción para que el agente copie y pegue
  2410.         $nombreArray = explode(' ', trim($yourName));
  2411.         $primerNombre = $nombreArray[0];
  2412.         // Definimos las URLs de los enlaces
  2413. //        $urlProposal = "https://cotizacion.greenpatio.es/index.php?token=" . $reserva->getToken();
  2414.         $urlProposal = "https://develup.solutions/cotizacion/?token=" . $reserva->getToken();
  2415.         $urlLegends = "https://drive.google.com/file/d/1_zc43gcvyajig-VRJyNXfe-0E8bhhQGZ/view";
  2416.         $urlCatering = "https://drive.google.com/drive/folders/1ihGR2yGWGgdtJeRsAI5LoUuEqkApAcXU";
  2417.         $urlCateringTwo = "https://www.instagram.com/sublimearomagastro/";
  2418.         // Construimos el HTML en la variable $xMail
  2419. //        $xMail = <<<HTML
  2420. //<div style="font-family: Arial, Helvetica, sans-serif; font-size: 14px; color: #222222; line-height: 1.6;">
  2421. //    <p>Hola {$primerNombre}, ¡un placer de saludarte!</p>
  2422. //    <p><em>A continuación te dejo el link con las opciones disponibles para la fecha solicitada:</em></p>
  2423. //
  2424. //    <p style="padding-left: 40px; margin-bottom: 20px;">
  2425. //        <strong><em style="color: #5b9e43; font-size: 16px;">CLICK AQUÍ --&gt;:</em></strong>
  2426. //        <a href="{$urlProposal}" style="color: #1155cc; font-size: 18px; text-decoration: underline;">PROPOSAL</a>
  2427. //    </p>
  2428. //
  2429. //    <p><strong style="text-decoration: underline;"><em>HACER CLICK para ver los <span style="color: #5b9e43;">"DOSSIERES"</span> de los espacios:</em></strong></p>
  2430. //    <ul style="margin-top: 5px; margin-bottom: 20px;">
  2431. //        <li><a href="{$urlLegends}" style="color: #1155cc; font-weight: bold; text-decoration: underline;">LEGENDS BY GREEN PATIO</a></li>
  2432. //    </ul>
  2433. //
  2434. //    <p><strong style="text-decoration: underline;"><em>PROVEEDORES EN EXCLUSIVA:</em></strong></p>
  2435. //    <ul style="margin-top: 5px; margin-bottom: 20px;">
  2436. //        <li><a href="{$urlCatering}" style="color: #1155cc; font-weight: bold; text-decoration: underline;">Catering Higo &amp; Trigo</a> - Te lo cotizamos desde Green Patio</li>
  2437. //        <li><strong>AV EXPRESS</strong> - Te lo cotiza directamente: Salvador Guerrero: <a href="tel:620956367" style="color: #222222; text-decoration: none;">620956367</a> // <a href="mailto:salvador@avexpress.tv" style="color: #222222; text-decoration: none;">salvador@avexpress.tv</a></li>
  2438. //    </ul>
  2439. //
  2440. //    <p><strong><span style="color: #5b9e43; text-decoration: underline;">IMPORTANTE:</span></strong></p>
  2441. //    <ul style="margin-top: 5px; margin-bottom: 25px;">
  2442. //        <li>Todas nuestras condiciones, horarios, y demás información están en la parte de <strong><span style="color: #5b9e43;">"IMPORTANTE"</span></strong> en el link enviado (justo debajo del precio de cada sala).</li>
  2443. //        <li>Dada la demanda de dicha fecha, en caso de desear bloqueo de la sala, será bloqueo en opción compartida, es decir: para el primer cliente que reserve en firme.</li>
  2444. //    </ul>
  2445. //
  2446. //    <p>Cualquier cosita no dudes en decirme,</p>
  2447. //    <p>Quedo atenta y mil gracias nuevamente!</p>
  2448. //</div>
  2449. //HTML;
  2450.         // Construimos el HTML en la variable $xMail
  2451.         $xMail = <<<HTML
  2452. <div style="font-family: Arial, Helvetica, sans-serif; font-size: 14px; color: #222222; line-height: 1.6;">
  2453.     <p>Hola {$primerNombre}, ¡un placer de saludarte!</p>
  2454.     <p><em>A continuación te dejo el link con las opciones disponibles para la fecha solicitada:</em></p>
  2455.     
  2456.     <p style="padding-left: 40px; margin-bottom: 20px;">
  2457.         <strong><em style="color: #5b9e43; font-size: 16px;">CLICK AQUÍ --&gt;:</em></strong> 
  2458.         <a href="{$urlProposal}" style="color: #1155cc; font-size: 18px; text-decoration: underline;">PROPOSAL</a>
  2459.     </p>
  2460.     
  2461.     <ul style="margin-top: 5px; margin-bottom: 25px;">
  2462.         <li style="margin-bottom: 5px;">
  2463.             <strong style="text-decoration: underline;"><em>ADJUNTO: los dossieres de los espacios</em></strong>
  2464.         </li>
  2465.         <li>
  2466.             <strong style="text-decoration: underline;"><em>PROVEEDORES EN EXCLUSIVA:</em></strong>
  2467.             <div style="margin-left: 15px; margin-top: 5px; line-height: 1.8;">
  2468.                 - <strong style="text-decoration: underline;">Av express</strong> (Te lo cotizan directamente: <a href="mailto:produccion@avexpress.tv" style="color: #222222; text-decoration: none;">produccion@avexpress.tv</a> )<br>
  2469.                 - <strong style="text-decoration: underline;">CATERINGS:</strong> <a href="{$urlCatering}" style="color: #1155cc; font-weight: bold; text-decoration: underline;">Catering Higo &amp; Trigo</a> &amp; <a href="{$urlCateringTwo}" style="color: #1155cc; font-weight: bold; text-decoration: underline;">Sublime Aroma Gastró</a> (alto standing) - Ambos los cotizamos desde Green Patio -<br>
  2470.                 *Puedes descargar los dossieres de ambos proveedores en el link de la propuesta en la parte de <strong style="color: #5b9e43;">"DOSSIERES"</strong>
  2471.             </div>
  2472.         </li>
  2473.     </ul>
  2474.     
  2475.     <p style="margin-bottom: 20px;">
  2476.         ⚠️ <strong>Importante:</strong> por la demanda de la fecha, el bloqueo será en <strong>opción compartida</strong> y se confirmará para el primer cliente que reserve en firme.
  2477.     </p>
  2478.     
  2479.     <p>Cualquier cosita, no dudes en escribirme 😊</p>
  2480.     
  2481.     <p>¡Mil gracias!</p>
  2482. </div>
  2483. HTML;
  2484.         $reserva->setMailToClient($xMail);
  2485.         try{
  2486.             $em->persist($reserva);
  2487.             $em->flush();
  2488.             $event = 'The Reservation has been updated.';
  2489.             $successMessage = $this->translator->trans($event);
  2490.             $this->addFlash('mensajereservation', $successMessage);
  2491.         } catch (\Exception $e){
  2492.             $event = 'An error occurred: '.$e->getMessage();
  2493.             $errorMessage = $this->translator->trans($event);
  2494.             $this->addFlash('mensajereservationerror', $errorMessage);
  2495.         }
  2496.         $id = $reserva->getId();
  2497.         // Normalizamos el texto antes del switc para el caso del guión largo
  2498.         $eventSpace = str_replace('–', '-', $eventSpace);
  2499.         switch ($eventSpace) {
  2500.             case 'La Imprenta - Sala Plenaria': $simpleLounge = 2; break;
  2501.             case 'La Imprenta - Invernadero': $simpleLounge = 39; break;
  2502.             case 'La Imprenta - Escenario': $simpleLounge = 40; break;
  2503.             case 'La Imprenta - Sala Cristal': $simpleLounge = 13; break;
  2504.             case "La Imprenta - L'Atelier": $simpleLounge = 14; break;
  2505.             case 'Covarrubias The One - Sala White': $simpleLounge = 24; break;
  2506.             case 'Covarrubias The One - Sala Black': $simpleLounge = 25; break;
  2507.             case 'Sala 25': $simpleLounge = 19; break;
  2508.             case 'Lima Rooms': $simpleLounge = 3; break;
  2509.             case 'Espacio Legends': $simpleLounge = 42; break;
  2510.             default: $simpleLounge = 0; break;
  2511.         }
  2512.         $loungeDetails = $em->getRepository(ReservationLoungeDetails::class)->findOneById($simpleLounge);
  2513.         $loungeId = $loungeDetails->getId();
  2514.         $previusLoungeSimple = null;
  2515.         $anyLoungeSimple = null;
  2516.         $idioma = 1;
  2517.         if($anyLoungeSimple){
  2518.             $idioma = $anyLoungeSimple->getLanguage();
  2519.         }
  2520.         $loungeWebDescription = $em->getRepository(ReservationLoungeWebDescription::class)->findOneBy(array('lounge' => $simpleLounge, 'language' => $idioma));
  2521.         $loungeName = $loungeDetails->getName();
  2522.         $loungeSummaryDescription = null;
  2523.         if (empty($previusLoungeSimple)) {
  2524.             if (empty($loungeSummaryDescription)) { $loungeSummaryDescription = empty($loungeWebDescription) ? null : $loungeWebDescription->getImportantDescription(); }
  2525.             $loungeImportantDescGeneralText = empty($loungeWebDescription) ? null : $loungeWebDescription->getImportantDescGeneralText();
  2526.             $loungeImportantDescSchedules = empty($loungeWebDescription) ? null : $loungeWebDescription->getImportantDescSchedules();
  2527.             $loungeImportantDescParking = empty($loungeWebDescription) ? null : $loungeWebDescription->getImportantDescParking();
  2528.         }
  2529.         $iva = 21;
  2530.         $newRankId = 1;
  2531.         $hourStart = '12'; $minStart = '00'; $hourMinStart = '12:00';
  2532.         $hourEnd = '20'; $minEnd = '00'; $hourMinEnd = '20:00';
  2533.         $dateStart = clone $yourEventDate; [$hour, $minute] = explode(':', $hourMinStart); $dateStart->setTime((int)$hour, (int)$minute);
  2534.         $dateEnd = clone $yourEventDate; [$hour, $minute] = explode(':', $hourMinEnd); $dateEnd->setTime((int)$hour, (int)$minute);
  2535.         $servicePrice = 0;
  2536.         $idReservation = $id;
  2537.         $createdAt = new DateTime('now');
  2538.         $createdBy = $user_id;
  2539.         $updatedAt = new DateTime('now');
  2540.         $updatedBy = $user_id;
  2541.         $pax = empty($yourAttendees) ? 0 : $yourAttendees;
  2542.         $lounge = new ReservationLoungeSimple();
  2543.         $lounge->setIdLounge ($loungeId);
  2544.         $lounge->setHourStart ($hourStart);
  2545.         $lounge->setMinStart ($minStart);
  2546.         $lounge->setHourEnd ($hourEnd);
  2547.         $lounge->setMinEnd ($minEnd);
  2548.         $lounge->setLoungeName ($loungeName);
  2549.         $lounge->setDateStart ($dateStart);
  2550.         $lounge->setDateEnd ($dateEnd);
  2551.         $lounge->setRankQuote(1);
  2552.         $lounge->setIdReservation ($idReservation);
  2553.         $lounge->setIva($iva);
  2554.         $lounge->setOpIva(1);
  2555.         $lounge->setCreatedAt ($createdAt);
  2556.         $lounge->setCreatedBy ($createdBy);
  2557.         $lounge->setUpdatedAt ($updatedAt);
  2558.         $lounge->setUpdatedBy ($updatedBy);
  2559.         $lounge->setPax ($pax);
  2560.         $lounge->setRankQuote($newRankId);
  2561.         $lounge->setShowAudiovisualPackage(true);
  2562.         $sageVatRate = $em->getRepository(SageVatRates::class)->findOneBy([ 'sageCode' => '03' ]);
  2563.         $lounge->setSageIva($sageVatRate);         // Iva de Sage al 21%
  2564.         $lounge->setImportantDescription($loungeSummaryDescription);
  2565.         $lounge->setImportantDescGeneralText($loungeImportantDescGeneralText);
  2566.         $lounge->setImportantDescSchedules($loungeImportantDescSchedules);
  2567.         $lounge->setImportantDescParking($loungeImportantDescParking);
  2568.         $price = $this->precioTarifario($dateStart, $loungeId, $servicePrice);
  2569.         $lounge->setServicePrice($price);
  2570.         try{
  2571.             $em->persist($lounge);
  2572.             $em->flush();
  2573.             $event = 'The Reservation has been updated.';
  2574.             $successMessage = $this->translator->trans($event);
  2575.             $this->addFlash('mensajereservation', $successMessage);
  2576.         } catch (\Exception $e){
  2577.             $event = 'An error occurred: '.$e->getMessage();
  2578.             $errorMessage = $this->translator->trans($event);
  2579.             $this->addFlash('mensajereservationerror', $errorMessage);
  2580.         }
  2581.         // Agregar el servicio de limpieza
  2582.         $service = new ReservationService();
  2583.         $service->setReservationId($idReservation);
  2584.         $service->setSupplierId(0);
  2585.         $service->setDateInAt($lounge->getDateStart());
  2586.         $service->setDateOutAt($lounge->getDateEnd());
  2587.         $service->setCreatedId($user_id);
  2588.         $service->setUpdatedId($user_id);
  2589.         $service->setCreatedAt(new \DateTime("now"));
  2590.         $service->setUpdatedAt(new \DateTime("now"));
  2591.         $service->setServiceCatId('21');
  2592.         $service->setServiceCatName('Limpieza');
  2593.         $service->setContcolor('green-300');
  2594.         $service->setName('HORAS ( '.$lounge->getLoungeName().' )');
  2595.         $service->setPrice('14');
  2596.         $service->setCurrency('Euro');
  2597.         $service->setUnits('8');
  2598.         $service->setCommission('0');
  2599.         $service->setPax('0');
  2600.         $service->setOver('0');
  2601.         // Busco la reserva para saber si es sucoe o no
  2602.         // $sucoe = $reserva->isSucoe();
  2603.         // Sino es sucoe, cogemos el IVA del 21
  2604.         // if(! $sucoe) {
  2605.         //      $sageVatRate = $em->getRepository(SageVatRates::class)->findOneBy(['sageCode' => '03']);
  2606.         // } else {
  2607.         //      $sageVatRate = $em->getRepository(SageVatRates::class)->findOneBy(['sageCode' => '00']);
  2608.         // }
  2609.         $sageArticle = null;
  2610.         // Si el módulo de Sage está activo, buscamos el artículo. Si no, lo dejamos en null y se mostrará un error en la vista.
  2611.         // if ($this->session->get('_config')['msage']) {
  2612.         //      $sageArticle = $em->getRepository(SageArticle::class)->findOneBy(['vatType' => $sageVatRate, 'name' => $service->getServiceCatName()]);
  2613.         //      Si no se ha encontrado el artículo de Sage.
  2614.         //      if (empty($sageArticle)) {
  2615.         //          $this->addFlash('mensajereservationerror', 'No se ha encontrado el artículo de Sage para el servicio: ' . $service->getServiceCatName() . '. No se ha podido crear el servicio para la sala.');
  2616.         //      }
  2617.         // }
  2618.         // $service->setSageIva($sageVatRate);
  2619.         $service->setOpIva('1');
  2620.         $service->setOpCommission('1');
  2621.         $service->setCommission('57.14');
  2622.         $service->setViewInfo(0);
  2623.         $service->setToinvoice(0);
  2624.         $service->setServiceId(0);
  2625.         // Vincular el artículo de Sage al servicio
  2626.         // $service->setSageArticle($sageArticle);
  2627.         $em->persist($service);
  2628.         $em->flush();
  2629.         // Sincronización con HT
  2630.         if (!empty($reserva)) {
  2631.             if (in_array($reserva->getStatus(), [null, '', 'Confirmed', 'Invoiced', 'Iniciado', 'Cotizado', 'Bloqueo'])) {
  2632. //                if ($reserva->getCateringName() == 'HIGO & TRIGO, S.L.') {
  2633.                     $htFile = $em->getRepository(HtFile::class)->findByReservation($reserva);
  2634.                     if (empty($htFile)) { return $this->redirectToRoute('sinc_gp_ht', array('id' => $id,)); }
  2635. //                }
  2636.             }
  2637.         }
  2638.         // Sincronización con AV
  2639.         if (!empty($reserva)) {
  2640.             if (in_array($reserva->getStatus(), [null, '', 'Confirmed', 'Invoiced', 'Iniciado', 'Cotizado', 'Bloqueo'])) {
  2641.                 $aveFile = $em->getRepository(AveFiles::class)->findByReservation($reserva);
  2642.                 if (empty($aveFile)) { return $this->redirectToRoute('sinc_gp_ave', array('id' => $id,)); }
  2643.             }
  2644.         }
  2645.         return $this->redirectToRoute('reservations_venues_edit_simple', array(
  2646.             'id' => $id,
  2647.             'token' => null,
  2648.             '_fragment' => 'btn_quotes'
  2649.         ));
  2650.     }
  2651.     private function precioPorFecha($date, $loungeId)
  2652.     {
  2653.         return array('price' => 0, );
  2654.         $em = $this->getDoctrine()->getManager();
  2655.         $price0 = null;
  2656.         // Buscamos por año
  2657.         $parameters = array('dateYear' => $date->format('Y'), 'loungeId' => $loungeId, 'priceIsActive' => true, );
  2658.         $dql = 'SELECT i
  2659.                 FROM VenuesBundle:ReservationLoungeProfile i
  2660.                 WHERE  ((i.year1 <= :dateYear and i.year2 >= :dateYear) ) and i.loungeId = :loungeId and i.priceIsActive = :priceIsActive';
  2661.         $query = $em->createQuery($dql)->setParameters($parameters);
  2662.         $price1 = $query->getResult();
  2663.         // Buscamos por año y mes
  2664.         $parameters = array('dateYear' => $date->format('Y'), 'month' => true, 'loungeId' => $loungeId, 'priceIsActive' => true, );
  2665.         switch ($date->format('m')) {
  2666.             case '01': //Enero
  2667.                 $dql = 'SELECT i
  2668.                     FROM VenuesBundle:ReservationLoungeProfile i
  2669.                     WHERE (
  2670.                     ((i.year1 <= :dateYear and i.year2 >= :dateYear) or (i.year1 = :dateYear) or (i.year2 = :dateYear))
  2671.                           AND (i.month1 = :month)) and i.loungeId = :loungeId and i.priceIsActive = :priceIsActive
  2672.                       ';
  2673.                 break;
  2674.             case '02': //Febrero
  2675.                 $dql = 'SELECT i
  2676.                     FROM VenuesBundle:ReservationLoungeProfile i
  2677.                     WHERE (
  2678.                     ((i.year1 <= :dateYear and i.year2 >= :dateYear) or (i.year1 = :dateYear) or (i.year2 = :dateYear))
  2679.                           AND (i.month2 = :month)) and i.loungeId = :loungeId and i.priceIsActive = :priceIsActive
  2680.                       ';
  2681.                 break;
  2682.             case '03': //Marzo
  2683.                 $dql = 'SELECT i
  2684.                     FROM VenuesBundle:ReservationLoungeProfile i
  2685.                     WHERE (
  2686.                     ((i.year1 <= :dateYear and i.year2 >= :dateYear) or (i.year1 = :dateYear) or (i.year2 = :dateYear))
  2687.                           AND (i.month3 = :month)) and i.loungeId = :loungeId and i.priceIsActive = :priceIsActive
  2688.                       ';
  2689.                 break;
  2690.             case '04': //Abril
  2691.                 $dql = 'SELECT i
  2692.                     FROM VenuesBundle:ReservationLoungeProfile i
  2693.                     WHERE (
  2694.                     ((i.year1 <= :dateYear and i.year2 >= :dateYear) or (i.year1 = :dateYear) or (i.year2 = :dateYear))
  2695.                           AND (i.month4 = :month)) and i.loungeId = :loungeId and i.priceIsActive = :priceIsActive
  2696.                       ';
  2697.                 break;
  2698.             case '05': //Mayo
  2699.                 $dql = 'SELECT i
  2700.                     FROM VenuesBundle:ReservationLoungeProfile i
  2701.                     WHERE (
  2702.                     ((i.year1 <= :dateYear and i.year2 >= :dateYear) or (i.year1 = :dateYear) or (i.year2 = :dateYear))
  2703.                           AND (i.month5 = :month)) and i.loungeId = :loungeId and i.priceIsActive = :priceIsActive
  2704.                       ';
  2705.                 break;
  2706.             case '06': //Junio
  2707.                 $dql = 'SELECT i
  2708.                     FROM VenuesBundle:ReservationLoungeProfile i
  2709.                     WHERE (
  2710.                     ((i.year1 <= :dateYear and i.year2 >= :dateYear) or (i.year1 = :dateYear) or (i.year2 = :dateYear))
  2711.                           AND (i.month6 = :month)) and i.loungeId = :loungeId and i.priceIsActive = :priceIsActive
  2712.                       ';
  2713.                 break;
  2714.             case '07': //Julio
  2715.                 $dql = 'SELECT i
  2716.                     FROM VenuesBundle:ReservationLoungeProfile i
  2717.                     WHERE (
  2718.                     ((i.year1 <= :dateYear and i.year2 >= :dateYear) or (i.year1 = :dateYear) or (i.year2 = :dateYear))
  2719.                           AND (i.month7 = :month)) and i.loungeId = :loungeId and i.priceIsActive = :priceIsActive
  2720.                       ';
  2721.                 break;
  2722.             case '08': //Agosto
  2723.                 $dql = 'SELECT i
  2724.                     FROM VenuesBundle:ReservationLoungeProfile i
  2725.                     WHERE (
  2726.                     ((i.year1 <= :dateYear and i.year2 >= :dateYear) or (i.year1 = :dateYear) or (i.year2 = :dateYear))
  2727.                           AND (i.month8 = :month)) and i.loungeId = :loungeId and i.priceIsActive = :priceIsActive
  2728.                       ';
  2729.                 break;
  2730.             case '09': //Septiembre
  2731.                 $dql = 'SELECT i
  2732.                     FROM VenuesBundle:ReservationLoungeProfile i
  2733.                     WHERE (
  2734.                     ((i.year1 <= :dateYear and i.year2 >= :dateYear) or (i.year1 = :dateYear) or (i.year2 = :dateYear))
  2735.                           AND (i.month9 = :month)) and i.loungeId = :loungeId and i.priceIsActive = :priceIsActive
  2736.                       ';
  2737.                 break;
  2738.             case '10': //Octubre
  2739.                 $dql = 'SELECT i
  2740.                     FROM VenuesBundle:ReservationLoungeProfile i
  2741.                     WHERE (
  2742.                     ((i.year1 <= :dateYear and i.year2 >= :dateYear) or (i.year1 = :dateYear) or (i.year2 = :dateYear))
  2743.                           AND (i.month10 = :month)) and i.loungeId = :loungeId and i.priceIsActive = :priceIsActive
  2744.                       ';
  2745.                 break;
  2746.             case '11': //Noviembre
  2747.                 $dql = 'SELECT i
  2748.                     FROM VenuesBundle:ReservationLoungeProfile i
  2749.                     WHERE (
  2750.                     ((i.year1 <= :dateYear and i.year2 >= :dateYear) or (i.year1 = :dateYear) or (i.year2 = :dateYear))
  2751.                           AND (i.month11 = :month)) and i.loungeId = :loungeId and i.priceIsActive = :priceIsActive
  2752.                       ';
  2753.                 break;
  2754.             case '12': //Diciembre
  2755.                 $dql = 'SELECT i
  2756.                     FROM VenuesBundle:ReservationLoungeProfile i
  2757.                     WHERE (
  2758.                     ((i.year1 <= :dateYear and i.year2 >= :dateYear) or (i.year1 = :dateYear) or (i.year2 = :dateYear))
  2759.                           AND (i.month12 = :month)) and i.loungeId = :loungeId and i.priceIsActive = :priceIsActive
  2760.                       ';
  2761.                 break;
  2762.             default:
  2763.                 break;
  2764.         }
  2765.         $query = $em->createQuery($dql)->setParameters($parameters);
  2766.         $price2 = $query->getResult();
  2767.         // Buscamos por año, mes y dia de la semana
  2768.         $parameters = array('dateYear' => $date->format('Y'), 'month' => true, 'day' => true, 'loungeId' => $loungeId, 'priceIsActive' => true, );
  2769.         switch ($date->format('m')) {
  2770.             case '01': //Enero
  2771.                 switch ($date->format('l')) {
  2772.                     case 'Monday': //Lunes
  2773.                         $dql = 'SELECT i
  2774.                                     FROM VenuesBundle:ReservationLoungeProfile i
  2775.                                     WHERE (
  2776.                                     ((i.year1 <= :dateYear and i.year2 >= :dateYear) or (i.year1 = :dateYear) or (i.year2 = :dateYear))
  2777.                                           AND (i.month1 = :month) AND (i.day1 = :day)) and i.loungeId = :loungeId and i.priceIsActive = :priceIsActive
  2778.                                       ';
  2779.                         break;
  2780.                     case 'Tuesday': //Martes
  2781.                         $dql = 'SELECT i
  2782.                                     FROM VenuesBundle:ReservationLoungeProfile i
  2783.                                     WHERE (
  2784.                                     ((i.year1 <= :dateYear and i.year2 >= :dateYear) or (i.year1 = :dateYear) or (i.year2 = :dateYear))
  2785.                                           AND (i.month1 = :month) AND (i.day2 = :day)) and i.loungeId = :loungeId and i.priceIsActive = :priceIsActive
  2786.                                       ';
  2787.                         break;
  2788.                     case 'Wednesday': //Miercoles
  2789.                         $dql = 'SELECT i
  2790.                                     FROM VenuesBundle:ReservationLoungeProfile i
  2791.                                     WHERE (
  2792.                                     ((i.year1 <= :dateYear and i.year2 >= :dateYear) or (i.year1 = :dateYear) or (i.year2 = :dateYear))
  2793.                                           AND (i.month1 = :month) AND (i.day3 = :day)) and i.loungeId = :loungeId and i.priceIsActive = :priceIsActive
  2794.                                       ';
  2795.                         break;
  2796.                     case 'Thursday': //Jueves
  2797.                         $dql = 'SELECT i
  2798.                                     FROM VenuesBundle:ReservationLoungeProfile i
  2799.                                     WHERE (
  2800.                                     ((i.year1 <= :dateYear and i.year2 >= :dateYear) or (i.year1 = :dateYear) or (i.year2 = :dateYear))
  2801.                                           AND (i.month1 = :month) AND (i.day4 = :day)) and i.loungeId = :loungeId and i.priceIsActive = :priceIsActive
  2802.                                       ';
  2803.                         break;
  2804.                     case 'Friday': //Viernes
  2805.                         $dql = 'SELECT i
  2806.                                     FROM VenuesBundle:ReservationLoungeProfile i
  2807.                                     WHERE (
  2808.                                     ((i.year1 <= :dateYear and i.year2 >= :dateYear) or (i.year1 = :dateYear) or (i.year2 = :dateYear))
  2809.                                           AND (i.month1 = :month) AND (i.day5 = :day)) and i.loungeId = :loungeId and i.priceIsActive = :priceIsActive
  2810.                                       ';
  2811.                         break;
  2812.                     case 'Saturday': //Sabado
  2813.                         $dql = 'SELECT i
  2814.                                     FROM VenuesBundle:ReservationLoungeProfile i
  2815.                                     WHERE (
  2816.                                     ((i.year1 <= :dateYear and i.year2 >= :dateYear) or (i.year1 = :dateYear) or (i.year2 = :dateYear))
  2817.                                           AND (i.month1 = :month) AND (i.day6 = :day)) and i.loungeId = :loungeId and i.priceIsActive = :priceIsActive
  2818.                                       ';
  2819.                         break;
  2820.                     case 'Sunday': //Domingo
  2821.                         $dql = 'SELECT i
  2822.                                     FROM VenuesBundle:ReservationLoungeProfile i
  2823.                                     WHERE (
  2824.                                     ((i.year1 <= :dateYear and i.year2 >= :dateYear) or (i.year1 = :dateYear) or (i.year2 = :dateYear))
  2825.                                           AND (i.month1 = :month) AND (i.day7 = :day)) and i.loungeId = :loungeId and i.priceIsActive = :priceIsActive
  2826.                                       ';
  2827.                         break;
  2828.                     default:
  2829.                         break;
  2830.                 }
  2831.                 break;
  2832.             case '02': //Febrero
  2833.                 switch ($date->format('l')) {
  2834.                     case 'Monday': //Lunes
  2835.                         $dql = 'SELECT i
  2836.                                     FROM VenuesBundle:ReservationLoungeProfile i
  2837.                                     WHERE (
  2838.                                     ((i.year1 <= :dateYear and i.year2 >= :dateYear) or (i.year1 = :dateYear) or (i.year2 = :dateYear))
  2839.                                           AND (i.month2 = :month) AND (i.day1 = :day)) and i.loungeId = :loungeId and i.priceIsActive = :priceIsActive
  2840.                                       ';
  2841.                         break;
  2842.                     case 'Tuesday': //Martes
  2843.                         $dql = 'SELECT i
  2844.                                     FROM VenuesBundle:ReservationLoungeProfile i
  2845.                                     WHERE (
  2846.                                     ((i.year1 <= :dateYear and i.year2 >= :dateYear) or (i.year1 = :dateYear) or (i.year2 = :dateYear))
  2847.                                           AND (i.month2 = :month) AND (i.day2 = :day)) and i.loungeId = :loungeId and i.priceIsActive = :priceIsActive
  2848.                                       ';
  2849.                         break;
  2850.                     case 'Wednesday': //Miercoles
  2851.                         $dql = 'SELECT i
  2852.                                     FROM VenuesBundle:ReservationLoungeProfile i
  2853.                                     WHERE (
  2854.                                     ((i.year1 <= :dateYear and i.year2 >= :dateYear) or (i.year1 = :dateYear) or (i.year2 = :dateYear))
  2855.                                           AND (i.month2 = :month) AND (i.day3 = :day)) and i.loungeId = :loungeId and i.priceIsActive = :priceIsActive
  2856.                                       ';
  2857.                         break;
  2858.                     case 'Thursday': //Jueves
  2859.                         $dql = 'SELECT i
  2860.                                     FROM VenuesBundle:ReservationLoungeProfile i
  2861.                                     WHERE (
  2862.                                     ((i.year1 <= :dateYear and i.year2 >= :dateYear) or (i.year1 = :dateYear) or (i.year2 = :dateYear))
  2863.                                           AND (i.month2 = :month) AND (i.day4 = :day)) and i.loungeId = :loungeId and i.priceIsActive = :priceIsActive
  2864.                                       ';
  2865.                         break;
  2866.                     case 'Friday': //Viernes
  2867.                         $dql = 'SELECT i
  2868.                                     FROM VenuesBundle:ReservationLoungeProfile i
  2869.                                     WHERE (
  2870.                                     ((i.year1 <= :dateYear and i.year2 >= :dateYear) or (i.year1 = :dateYear) or (i.year2 = :dateYear))
  2871.                                           AND (i.month2 = :month) AND (i.day5 = :day)) and i.loungeId = :loungeId and i.priceIsActive = :priceIsActive
  2872.                                       ';
  2873.                         break;
  2874.                     case 'Saturday': //Sabado
  2875.                         $dql = 'SELECT i
  2876.                                     FROM VenuesBundle:ReservationLoungeProfile i
  2877.                                     WHERE (
  2878.                                     ((i.year1 <= :dateYear and i.year2 >= :dateYear) or (i.year1 = :dateYear) or (i.year2 = :dateYear))
  2879.                                           AND (i.month2 = :month) AND (i.day6 = :day)) and i.loungeId = :loungeId and i.priceIsActive = :priceIsActive
  2880.                                       ';
  2881.                         break;
  2882.                     case 'Sunday': //Domingo
  2883.                         $dql = 'SELECT i
  2884.                                     FROM VenuesBundle:ReservationLoungeProfile i
  2885.                                     WHERE (
  2886.                                     ((i.year1 <= :dateYear and i.year2 >= :dateYear) or (i.year1 = :dateYear) or (i.year2 = :dateYear))
  2887.                                           AND (i.month2 = :month) AND (i.day7 = :day)) and i.loungeId = :loungeId and i.priceIsActive = :priceIsActive
  2888.                                       ';
  2889.                         break;
  2890.                     default:
  2891.                         break;
  2892.                 }
  2893.                 break;
  2894.             case '03': //Marzo
  2895.                 switch ($date->format('l')) {
  2896.                     case 'Monday': //Lunes
  2897.                         $dql = 'SELECT i
  2898.                                     FROM VenuesBundle:ReservationLoungeProfile i
  2899.                                     WHERE (
  2900.                                     ((i.year1 <= :dateYear and i.year2 >= :dateYear) or (i.year1 = :dateYear) or (i.year2 = :dateYear))
  2901.                                           AND (i.month3 = :month) AND (i.day1 = :day)) and i.loungeId = :loungeId and i.priceIsActive = :priceIsActive
  2902.                                       ';
  2903.                         break;
  2904.                     case 'Tuesday': //Martes
  2905.                         $dql = 'SELECT i
  2906.                                     FROM VenuesBundle:ReservationLoungeProfile i
  2907.                                     WHERE (
  2908.                                     ((i.year1 <= :dateYear and i.year2 >= :dateYear) or (i.year1 = :dateYear) or (i.year2 = :dateYear))
  2909.                                           AND (i.month3 = :month) AND (i.day2 = :day)) and i.loungeId = :loungeId and i.priceIsActive = :priceIsActive
  2910.                                       ';
  2911.                         break;
  2912.                     case 'Wednesday': //Miercoles
  2913.                         $dql = 'SELECT i
  2914.                                     FROM VenuesBundle:ReservationLoungeProfile i
  2915.                                     WHERE (
  2916.                                     ((i.year1 <= :dateYear and i.year2 >= :dateYear) or (i.year1 = :dateYear) or (i.year2 = :dateYear))
  2917.                                           AND (i.month3 = :month) AND (i.day3 = :day)) and i.loungeId = :loungeId and i.priceIsActive = :priceIsActive
  2918.                                       ';
  2919.                         break;
  2920.                     case 'Thursday': //Jueves
  2921.                         $dql = 'SELECT i
  2922.                                     FROM VenuesBundle:ReservationLoungeProfile i
  2923.                                     WHERE (
  2924.                                     ((i.year1 <= :dateYear and i.year2 >= :dateYear) or (i.year1 = :dateYear) or (i.year2 = :dateYear))
  2925.                                           AND (i.month3 = :month) AND (i.day4 = :day)) and i.loungeId = :loungeId and i.priceIsActive = :priceIsActive
  2926.                                       ';
  2927.                         break;
  2928.                     case 'Friday': //Viernes
  2929.                         $dql = 'SELECT i
  2930.                                     FROM VenuesBundle:ReservationLoungeProfile i
  2931.                                     WHERE (
  2932.                                     ((i.year1 <= :dateYear and i.year2 >= :dateYear) or (i.year1 = :dateYear) or (i.year2 = :dateYear))
  2933.                                           AND (i.month3 = :month) AND (i.day5 = :day)) and i.loungeId = :loungeId and i.priceIsActive = :priceIsActive
  2934.                                       ';
  2935.                         break;
  2936.                     case 'Saturday': //Sabado
  2937.                         $dql = 'SELECT i
  2938.                                     FROM VenuesBundle:ReservationLoungeProfile i
  2939.                                     WHERE (
  2940.                                     ((i.year1 <= :dateYear and i.year2 >= :dateYear) or (i.year1 = :dateYear) or (i.year2 = :dateYear))
  2941.                                           AND (i.month3 = :month) AND (i.day6 = :day)) and i.loungeId = :loungeId and i.priceIsActive = :priceIsActive
  2942.                                       ';
  2943.                         break;
  2944.                     case 'Sunday': //Domingo
  2945.                         $dql = 'SELECT i
  2946.                                     FROM VenuesBundle:ReservationLoungeProfile i
  2947.                                     WHERE (
  2948.                                     ((i.year1 <= :dateYear and i.year2 >= :dateYear) or (i.year1 = :dateYear) or (i.year2 = :dateYear))
  2949.                                           AND (i.month3 = :month) AND (i.day7 = :day)) and i.loungeId = :loungeId and i.priceIsActive = :priceIsActive
  2950.                                       ';
  2951.                         break;
  2952.                     default:
  2953.                         break;
  2954.                 }
  2955.                 break;
  2956.             case '04': //Abril
  2957.                 switch ($date->format('l')) {
  2958.                     case 'Monday': //Lunes
  2959.                         $dql = 'SELECT i
  2960.                                     FROM VenuesBundle:ReservationLoungeProfile i
  2961.                                     WHERE (
  2962.                                     ((i.year1 <= :dateYear and i.year2 >= :dateYear) or (i.year1 = :dateYear) or (i.year2 = :dateYear))
  2963.                                           AND (i.month4 = :month) AND (i.day1 = :day)) and i.loungeId = :loungeId and i.priceIsActive = :priceIsActive
  2964.                                       ';
  2965.                         break;
  2966.                     case 'Tuesday': //Martes
  2967.                         $dql = 'SELECT i
  2968.                                     FROM VenuesBundle:ReservationLoungeProfile i
  2969.                                     WHERE (
  2970.                                     ((i.year1 <= :dateYear and i.year2 >= :dateYear) or (i.year1 = :dateYear) or (i.year2 = :dateYear))
  2971.                                           AND (i.month4 = :month) AND (i.day2 = :day)) and i.loungeId = :loungeId and i.priceIsActive = :priceIsActive
  2972.                                       ';
  2973.                         break;
  2974.                     case 'Wednesday': //Miercoles
  2975.                         $dql = 'SELECT i
  2976.                                     FROM VenuesBundle:ReservationLoungeProfile i
  2977.                                     WHERE (
  2978.                                     ((i.year1 <= :dateYear and i.year2 >= :dateYear) or (i.year1 = :dateYear) or (i.year2 = :dateYear))
  2979.                                           AND (i.month4 = :month) AND (i.day3 = :day)) and i.loungeId = :loungeId and i.priceIsActive = :priceIsActive
  2980.                                       ';
  2981.                         break;
  2982.                     case 'Thursday': //Jueves
  2983.                         $dql = 'SELECT i
  2984.                                     FROM VenuesBundle:ReservationLoungeProfile i
  2985.                                     WHERE (
  2986.                                     ((i.year1 <= :dateYear and i.year2 >= :dateYear) or (i.year1 = :dateYear) or (i.year2 = :dateYear))
  2987.                                           AND (i.month4 = :month) AND (i.day4 = :day)) and i.loungeId = :loungeId and i.priceIsActive = :priceIsActive
  2988.                                       ';
  2989.                         break;
  2990.                     case 'Friday': //Viernes
  2991.                         $dql = 'SELECT i
  2992.                                     FROM VenuesBundle:ReservationLoungeProfile i
  2993.                                     WHERE (
  2994.                                     ((i.year1 <= :dateYear and i.year2 >= :dateYear) or (i.year1 = :dateYear) or (i.year2 = :dateYear))
  2995.                                           AND (i.month4 = :month) AND (i.day5 = :day)) and i.loungeId = :loungeId and i.priceIsActive = :priceIsActive
  2996.                                       ';
  2997.                         break;
  2998.                     case 'Saturday': //Sabado
  2999.                         $dql = 'SELECT i
  3000.                                     FROM VenuesBundle:ReservationLoungeProfile i
  3001.                                     WHERE (
  3002.                                     ((i.year1 <= :dateYear and i.year2 >= :dateYear) or (i.year1 = :dateYear) or (i.year2 = :dateYear))
  3003.                                           AND (i.month4 = :month) AND (i.day6 = :day)) and i.loungeId = :loungeId and i.priceIsActive = :priceIsActive
  3004.                                       ';
  3005.                         break;
  3006.                     case 'Sunday': //Domingo
  3007.                         $dql = 'SELECT i
  3008.                                     FROM VenuesBundle:ReservationLoungeProfile i
  3009.                                     WHERE (
  3010.                                     ((i.year1 <= :dateYear and i.year2 >= :dateYear) or (i.year1 = :dateYear) or (i.year2 = :dateYear))
  3011.                                           AND (i.month4 = :month) AND (i.day7 = :day)) and i.loungeId = :loungeId and i.priceIsActive = :priceIsActive
  3012.                                       ';
  3013.                         break;
  3014.                     default:
  3015.                         break;
  3016.                 }
  3017.                 break;
  3018.             case '05': //Mayo
  3019.                 switch ($date->format('l')) {
  3020.                     case 'Monday': //Lunes
  3021.                         $dql = 'SELECT i
  3022.                                     FROM VenuesBundle:ReservationLoungeProfile i
  3023.                                     WHERE (
  3024.                                     ((i.year1 <= :dateYear and i.year2 >= :dateYear) or (i.year1 = :dateYear) or (i.year2 = :dateYear))
  3025.                                           AND (i.month5 = :month) AND (i.day1 = :day)) and i.loungeId = :loungeId and i.priceIsActive = :priceIsActive
  3026.                                       ';
  3027.                         break;
  3028.                     case 'Tuesday': //Martes
  3029.                         $dql = 'SELECT i
  3030.                                     FROM VenuesBundle:ReservationLoungeProfile i
  3031.                                     WHERE (
  3032.                                     ((i.year1 <= :dateYear and i.year2 >= :dateYear) or (i.year1 = :dateYear) or (i.year2 = :dateYear))
  3033.                                           AND (i.month5 = :month) AND (i.day2 = :day)) and i.loungeId = :loungeId and i.priceIsActive = :priceIsActive
  3034.                                       ';
  3035.                         break;
  3036.                     case 'Wednesday': //Miercoles
  3037.                         $dql = 'SELECT i
  3038.                                     FROM VenuesBundle:ReservationLoungeProfile i
  3039.                                     WHERE (
  3040.                                     ((i.year1 <= :dateYear and i.year2 >= :dateYear) or (i.year1 = :dateYear) or (i.year2 = :dateYear))
  3041.                                           AND (i.month5 = :month) AND (i.day3 = :day)) and i.loungeId = :loungeId and i.priceIsActive = :priceIsActive
  3042.                                       ';
  3043.                         break;
  3044.                     case 'Thursday': //Jueves
  3045.                         $dql = 'SELECT i
  3046.                                     FROM VenuesBundle:ReservationLoungeProfile i
  3047.                                     WHERE (
  3048.                                     ((i.year1 <= :dateYear and i.year2 >= :dateYear) or (i.year1 = :dateYear) or (i.year2 = :dateYear))
  3049.                                           AND (i.month5 = :month) AND (i.day4 = :day)) and i.loungeId = :loungeId and i.priceIsActive = :priceIsActive
  3050.                                       ';
  3051.                         break;
  3052.                     case 'Friday': //Viernes
  3053.                         $dql = 'SELECT i
  3054.                                     FROM VenuesBundle:ReservationLoungeProfile i
  3055.                                     WHERE (
  3056.                                     ((i.year1 <= :dateYear and i.year2 >= :dateYear) or (i.year1 = :dateYear) or (i.year2 = :dateYear))
  3057.                                           AND (i.month5 = :month) AND (i.day5 = :day)) and i.loungeId = :loungeId and i.priceIsActive = :priceIsActive
  3058.                                       ';
  3059.                         break;
  3060.                     case 'Saturday': //Sabado
  3061.                         $dql = 'SELECT i
  3062.                                     FROM VenuesBundle:ReservationLoungeProfile i
  3063.                                     WHERE (
  3064.                                     ((i.year1 <= :dateYear and i.year2 >= :dateYear) or (i.year1 = :dateYear) or (i.year2 = :dateYear))
  3065.                                           AND (i.month5 = :month) AND (i.day6 = :day)) and i.loungeId = :loungeId and i.priceIsActive = :priceIsActive
  3066.                                       ';
  3067.                         break;
  3068.                     case 'Sunday': //Domingo
  3069.                         $dql = 'SELECT i
  3070.                                     FROM VenuesBundle:ReservationLoungeProfile i
  3071.                                     WHERE (
  3072.                                     ((i.year1 <= :dateYear and i.year2 >= :dateYear) or (i.year1 = :dateYear) or (i.year2 = :dateYear))
  3073.                                           AND (i.month5 = :month) AND (i.day7 = :day)) and i.loungeId = :loungeId and i.priceIsActive = :priceIsActive
  3074.                                       ';
  3075.                         break;
  3076.                     default:
  3077.                         break;
  3078.                 }
  3079.                 break;
  3080.             case '06': //Junio
  3081.                 switch ($date->format('l')) {
  3082.                     case 'Monday': //Lunes
  3083.                         $dql = 'SELECT i
  3084.                                     FROM VenuesBundle:ReservationLoungeProfile i
  3085.                                     WHERE (
  3086.                                     ((i.year1 <= :dateYear and i.year2 >= :dateYear) or (i.year1 = :dateYear) or (i.year2 = :dateYear))
  3087.                                           AND (i.month6 = :month) AND (i.day1 = :day)) and i.loungeId = :loungeId and i.priceIsActive = :priceIsActive
  3088.                                       ';
  3089.                         break;
  3090.                     case 'Tuesday': //Martes
  3091.                         $dql = 'SELECT i
  3092.                                     FROM VenuesBundle:ReservationLoungeProfile i
  3093.                                     WHERE (
  3094.                                     ((i.year1 <= :dateYear and i.year2 >= :dateYear) or (i.year1 = :dateYear) or (i.year2 = :dateYear))
  3095.                                           AND (i.month6 = :month) AND (i.day2 = :day)) and i.loungeId = :loungeId and i.priceIsActive = :priceIsActive
  3096.                                       ';
  3097.                         break;
  3098.                     case 'Wednesday': //Miercoles
  3099.                         $dql = 'SELECT i
  3100.                                     FROM VenuesBundle:ReservationLoungeProfile i
  3101.                                     WHERE (
  3102.                                     ((i.year1 <= :dateYear and i.year2 >= :dateYear) or (i.year1 = :dateYear) or (i.year2 = :dateYear))
  3103.                                           AND (i.month6 = :month) AND (i.day3 = :day)) and i.loungeId = :loungeId and i.priceIsActive = :priceIsActive
  3104.                                       ';
  3105.                         break;
  3106.                     case 'Thursday': //Jueves
  3107.                         $dql = 'SELECT i
  3108.                                     FROM VenuesBundle:ReservationLoungeProfile i
  3109.                                     WHERE (
  3110.                                     ((i.year1 <= :dateYear and i.year2 >= :dateYear) or (i.year1 = :dateYear) or (i.year2 = :dateYear))
  3111.                                           AND (i.month6 = :month) AND (i.day4 = :day)) and i.loungeId = :loungeId and i.priceIsActive = :priceIsActive
  3112.                                       ';
  3113.                         break;
  3114.                     case 'Friday': //Viernes
  3115.                         $dql = 'SELECT i
  3116.                                     FROM VenuesBundle:ReservationLoungeProfile i
  3117.                                     WHERE (
  3118.                                     ((i.year1 <= :dateYear and i.year2 >= :dateYear) or (i.year1 = :dateYear) or (i.year2 = :dateYear))
  3119.                                           AND (i.month6 = :month) AND (i.day5 = :day)) and i.loungeId = :loungeId and i.priceIsActive = :priceIsActive
  3120.                                       ';
  3121.                         break;
  3122.                     case 'Saturday': //Sabado
  3123.                         $dql = 'SELECT i
  3124.                                     FROM VenuesBundle:ReservationLoungeProfile i
  3125.                                     WHERE (
  3126.                                     ((i.year1 <= :dateYear and i.year2 >= :dateYear) or (i.year1 = :dateYear) or (i.year2 = :dateYear))
  3127.                                           AND (i.month6 = :month) AND (i.day6 = :day)) and i.loungeId = :loungeId and i.priceIsActive = :priceIsActive
  3128.                                       ';
  3129.                         break;
  3130.                     case 'Sunday': //Domingo
  3131.                         $dql = 'SELECT i
  3132.                                     FROM VenuesBundle:ReservationLoungeProfile i
  3133.                                     WHERE (
  3134.                                     ((i.year1 <= :dateYear and i.year2 >= :dateYear) or (i.year1 = :dateYear) or (i.year2 = :dateYear))
  3135.                                           AND (i.month6 = :month) AND (i.day7 = :day)) and i.loungeId = :loungeId and i.priceIsActive = :priceIsActive
  3136.                                       ';
  3137.                         break;
  3138.                     default:
  3139.                         break;
  3140.                 }
  3141.                 break;
  3142.             case '07': //Julio
  3143.                 switch ($date->format('l')) {
  3144.                     case 'Monday': //Lunes
  3145.                         $dql = 'SELECT i
  3146.                                     FROM VenuesBundle:ReservationLoungeProfile i
  3147.                                     WHERE (
  3148.                                     ((i.year1 <= :dateYear and i.year2 >= :dateYear) or (i.year1 = :dateYear) or (i.year2 = :dateYear))
  3149.                                           AND (i.month7 = :month) AND (i.day1 = :day)) and i.loungeId = :loungeId and i.priceIsActive = :priceIsActive
  3150.                                       ';
  3151.                         break;
  3152.                     case 'Tuesday': //Martes
  3153.                         $dql = 'SELECT i
  3154.                                     FROM VenuesBundle:ReservationLoungeProfile i
  3155.                                     WHERE (
  3156.                                     ((i.year1 <= :dateYear and i.year2 >= :dateYear) or (i.year1 = :dateYear) or (i.year2 = :dateYear))
  3157.                                           AND (i.month7 = :month) AND (i.day2 = :day)) and i.loungeId = :loungeId and i.priceIsActive = :priceIsActive
  3158.                                       ';
  3159.                         break;
  3160.                     case 'Wednesday': //Miercoles
  3161.                         $dql = 'SELECT i
  3162.                                     FROM VenuesBundle:ReservationLoungeProfile i
  3163.                                     WHERE (
  3164.                                     ((i.year1 <= :dateYear and i.year2 >= :dateYear) or (i.year1 = :dateYear) or (i.year2 = :dateYear))
  3165.                                           AND (i.month7 = :month) AND (i.day3 = :day)) and i.loungeId = :loungeId and i.priceIsActive = :priceIsActive
  3166.                                       ';
  3167.                         break;
  3168.                     case 'Thursday': //Jueves
  3169.                         $dql = 'SELECT i
  3170.                                     FROM VenuesBundle:ReservationLoungeProfile i
  3171.                                     WHERE (
  3172.                                     ((i.year1 <= :dateYear and i.year2 >= :dateYear) or (i.year1 = :dateYear) or (i.year2 = :dateYear))
  3173.                                           AND (i.month7 = :month) AND (i.day4 = :day)) and i.loungeId = :loungeId and i.priceIsActive = :priceIsActive
  3174.                                       ';
  3175.                         break;
  3176.                     case 'Friday': //Viernes
  3177.                         $dql = 'SELECT i
  3178.                                     FROM VenuesBundle:ReservationLoungeProfile i
  3179.                                     WHERE (
  3180.                                     ((i.year1 <= :dateYear and i.year2 >= :dateYear) or (i.year1 = :dateYear) or (i.year2 = :dateYear))
  3181.                                           AND (i.month7 = :month) AND (i.day5 = :day)) and i.loungeId = :loungeId and i.priceIsActive = :priceIsActive
  3182.                                       ';
  3183.                         break;
  3184.                     case 'Saturday': //Sabado
  3185.                         $dql = 'SELECT i
  3186.                                     FROM VenuesBundle:ReservationLoungeProfile i
  3187.                                     WHERE (
  3188.                                     ((i.year1 <= :dateYear and i.year2 >= :dateYear) or (i.year1 = :dateYear) or (i.year2 = :dateYear))
  3189.                                           AND (i.month7 = :month) AND (i.day6 = :day)) and i.loungeId = :loungeId and i.priceIsActive = :priceIsActive
  3190.                                       ';
  3191.                         break;
  3192.                     case 'Sunday': //Domingo
  3193.                         $dql = 'SELECT i
  3194.                                     FROM VenuesBundle:ReservationLoungeProfile i
  3195.                                     WHERE (
  3196.                                     ((i.year1 <= :dateYear and i.year2 >= :dateYear) or (i.year1 = :dateYear) or (i.year2 = :dateYear))
  3197.                                           AND (i.month7 = :month) AND (i.day7 = :day)) and i.loungeId = :loungeId and i.priceIsActive = :priceIsActive
  3198.                                       ';
  3199.                         break;
  3200.                     default:
  3201.                         break;
  3202.                 }
  3203.                 break;
  3204.             case '08': //Agosto
  3205.                 switch ($date->format('l')) {
  3206.                     case 'Monday': //Lunes
  3207.                         $dql = 'SELECT i
  3208.                                     FROM VenuesBundle:ReservationLoungeProfile i
  3209.                                     WHERE (
  3210.                                     ((i.year1 <= :dateYear and i.year2 >= :dateYear) or (i.year1 = :dateYear) or (i.year2 = :dateYear))
  3211.                                           AND (i.month8 = :month) AND (i.day1 = :day)) and i.loungeId = :loungeId and i.priceIsActive = :priceIsActive
  3212.                                       ';
  3213.                         break;
  3214.                     case 'Tuesday': //Martes
  3215.                         $dql = 'SELECT i
  3216.                                     FROM VenuesBundle:ReservationLoungeProfile i
  3217.                                     WHERE (
  3218.                                     ((i.year1 <= :dateYear and i.year2 >= :dateYear) or (i.year1 = :dateYear) or (i.year2 = :dateYear))
  3219.                                           AND (i.month8 = :month) AND (i.day2 = :day)) and i.loungeId = :loungeId and i.priceIsActive = :priceIsActive
  3220.                                       ';
  3221.                         break;
  3222.                     case 'Wednesday': //Miercoles
  3223.                         $dql = 'SELECT i
  3224.                                     FROM VenuesBundle:ReservationLoungeProfile i
  3225.                                     WHERE (
  3226.                                     ((i.year1 <= :dateYear and i.year2 >= :dateYear) or (i.year1 = :dateYear) or (i.year2 = :dateYear))
  3227.                                           AND (i.month8 = :month) AND (i.day3 = :day)) and i.loungeId = :loungeId and i.priceIsActive = :priceIsActive
  3228.                                       ';
  3229.                         break;
  3230.                     case 'Thursday': //Jueves
  3231.                         $dql = 'SELECT i
  3232.                                     FROM VenuesBundle:ReservationLoungeProfile i
  3233.                                     WHERE (
  3234.                                     ((i.year1 <= :dateYear and i.year2 >= :dateYear) or (i.year1 = :dateYear) or (i.year2 = :dateYear))
  3235.                                           AND (i.month8 = :month) AND (i.day4 = :day)) and i.loungeId = :loungeId and i.priceIsActive = :priceIsActive
  3236.                                       ';
  3237.                         break;
  3238.                     case 'Friday': //Viernes
  3239.                         $dql = 'SELECT i
  3240.                                     FROM VenuesBundle:ReservationLoungeProfile i
  3241.                                     WHERE (
  3242.                                     ((i.year1 <= :dateYear and i.year2 >= :dateYear) or (i.year1 = :dateYear) or (i.year2 = :dateYear))
  3243.                                           AND (i.month8 = :month) AND (i.day5 = :day)) and i.loungeId = :loungeId and i.priceIsActive = :priceIsActive
  3244.                                       ';
  3245.                         break;
  3246.                     case 'Saturday': //Sabado
  3247.                         $dql = 'SELECT i
  3248.                                     FROM VenuesBundle:ReservationLoungeProfile i
  3249.                                     WHERE (
  3250.                                     ((i.year1 <= :dateYear and i.year2 >= :dateYear) or (i.year1 = :dateYear) or (i.year2 = :dateYear))
  3251.                                           AND (i.month8 = :month) AND (i.day6 = :day)) and i.loungeId = :loungeId and i.priceIsActive = :priceIsActive
  3252.                                       ';
  3253.                         break;
  3254.                     case 'Sunday': //Domingo
  3255.                         $dql = 'SELECT i
  3256.                                     FROM VenuesBundle:ReservationLoungeProfile i
  3257.                                     WHERE (
  3258.                                     ((i.year1 <= :dateYear and i.year2 >= :dateYear) or (i.year1 = :dateYear) or (i.year2 = :dateYear))
  3259.                                           AND (i.month8 = :month) AND (i.day7 = :day)) and i.loungeId = :loungeId and i.priceIsActive = :priceIsActive
  3260.                                       ';
  3261.                         break;
  3262.                     default:
  3263.                         break;
  3264.                 }
  3265.                 break;
  3266.             case '09': //Septiembre
  3267.                 switch ($date->format('l')) {
  3268.                     case 'Monday': //Lunes
  3269.                         $dql = 'SELECT i
  3270.                                     FROM VenuesBundle:ReservationLoungeProfile i
  3271.                                     WHERE (
  3272.                                     ((i.year1 <= :dateYear and i.year2 >= :dateYear) or (i.year1 = :dateYear) or (i.year2 = :dateYear))
  3273.                                           AND (i.month9 = :month) AND (i.day1 = :day)) and i.loungeId = :loungeId and i.priceIsActive = :priceIsActive
  3274.                                       ';
  3275.                         break;
  3276.                     case 'Tuesday': //Martes
  3277.                         $dql = 'SELECT i
  3278.                                     FROM VenuesBundle:ReservationLoungeProfile i
  3279.                                     WHERE (
  3280.                                     ((i.year1 <= :dateYear and i.year2 >= :dateYear) or (i.year1 = :dateYear) or (i.year2 = :dateYear))
  3281.                                           AND (i.month9 = :month) AND (i.day2 = :day)) and i.loungeId = :loungeId and i.priceIsActive = :priceIsActive
  3282.                                       ';
  3283.                         break;
  3284.                     case 'Wednesday': //Miercoles
  3285.                         $dql = 'SELECT i
  3286.                                     FROM VenuesBundle:ReservationLoungeProfile i
  3287.                                     WHERE (
  3288.                                     ((i.year1 <= :dateYear and i.year2 >= :dateYear) or (i.year1 = :dateYear) or (i.year2 = :dateYear))
  3289.                                           AND (i.month9 = :month) AND (i.day3 = :day)) and i.loungeId = :loungeId and i.priceIsActive = :priceIsActive
  3290.                                       ';
  3291.                         break;
  3292.                     case 'Thursday': //Jueves
  3293.                         $dql = 'SELECT i
  3294.                                     FROM VenuesBundle:ReservationLoungeProfile i
  3295.                                     WHERE (
  3296.                                     ((i.year1 <= :dateYear and i.year2 >= :dateYear) or (i.year1 = :dateYear) or (i.year2 = :dateYear))
  3297.                                           AND (i.month9 = :month) AND (i.day4 = :day)) and i.loungeId = :loungeId and i.priceIsActive = :priceIsActive
  3298.                                       ';
  3299.                         break;
  3300.                     case 'Friday': //Viernes
  3301.                         $dql = 'SELECT i
  3302.                                     FROM VenuesBundle:ReservationLoungeProfile i
  3303.                                     WHERE (
  3304.                                     ((i.year1 <= :dateYear and i.year2 >= :dateYear) or (i.year1 = :dateYear) or (i.year2 = :dateYear))
  3305.                                           AND (i.month9 = :month) AND (i.day5 = :day)) and i.loungeId = :loungeId and i.priceIsActive = :priceIsActive
  3306.                                       ';
  3307.                         break;
  3308.                     case 'Saturday': //Sabado
  3309.                         $dql = 'SELECT i
  3310.                                     FROM VenuesBundle:ReservationLoungeProfile i
  3311.                                     WHERE (
  3312.                                     ((i.year1 <= :dateYear and i.year2 >= :dateYear) or (i.year1 = :dateYear) or (i.year2 = :dateYear))
  3313.                                           AND (i.month9 = :month) AND (i.day6 = :day)) and i.loungeId = :loungeId and i.priceIsActive = :priceIsActive
  3314.                                       ';
  3315.                         break;
  3316.                     case 'Sunday': //Domingo
  3317.                         $dql = 'SELECT i
  3318.                                     FROM VenuesBundle:ReservationLoungeProfile i
  3319.                                     WHERE (
  3320.                                     ((i.year1 <= :dateYear and i.year2 >= :dateYear) or (i.year1 = :dateYear) or (i.year2 = :dateYear))
  3321.                                           AND (i.month9 = :month) AND (i.day7 = :day)) and i.loungeId = :loungeId and i.priceIsActive = :priceIsActive
  3322.                                       ';
  3323.                         break;
  3324.                     default:
  3325.                         break;
  3326.                 }
  3327.                 break;
  3328.             case '10': //Octubre
  3329.                 switch ($date->format('l')) {
  3330.                     case 'Monday': //Lunes
  3331.                         $dql = 'SELECT i
  3332.                                     FROM VenuesBundle:ReservationLoungeProfile i
  3333.                                     WHERE (
  3334.                                     ((i.year1 <= :dateYear and i.year2 >= :dateYear) or (i.year1 = :dateYear) or (i.year2 = :dateYear))
  3335.                                           AND (i.month10 = :month) AND (i.day1 = :day)) and i.loungeId = :loungeId and i.priceIsActive = :priceIsActive
  3336.                                       ';
  3337.                         break;
  3338.                     case 'Tuesday': //Martes
  3339.                         $dql = 'SELECT i
  3340.                                     FROM VenuesBundle:ReservationLoungeProfile i
  3341.                                     WHERE (
  3342.                                     ((i.year1 <= :dateYear and i.year2 >= :dateYear) or (i.year1 = :dateYear) or (i.year2 = :dateYear))
  3343.                                           AND (i.month10 = :month) AND (i.day2 = :day)) and i.loungeId = :loungeId and i.priceIsActive = :priceIsActive
  3344.                                       ';
  3345.                         break;
  3346.                     case 'Wednesday': //Miercoles
  3347.                         $dql = 'SELECT i
  3348.                                     FROM VenuesBundle:ReservationLoungeProfile i
  3349.                                     WHERE (
  3350.                                     ((i.year1 <= :dateYear and i.year2 >= :dateYear) or (i.year1 = :dateYear) or (i.year2 = :dateYear))
  3351.                                           AND (i.month10 = :month) AND (i.day3 = :day)) and i.loungeId = :loungeId and i.priceIsActive = :priceIsActive
  3352.                                       ';
  3353.                         break;
  3354.                     case 'Thursday': //Jueves
  3355.                         $dql = 'SELECT i
  3356.                                     FROM VenuesBundle:ReservationLoungeProfile i
  3357.                                     WHERE (
  3358.                                     ((i.year1 <= :dateYear and i.year2 >= :dateYear) or (i.year1 = :dateYear) or (i.year2 = :dateYear))
  3359.                                           AND (i.month10 = :month) AND (i.day4 = :day)) and i.loungeId = :loungeId and i.priceIsActive = :priceIsActive
  3360.                                       ';
  3361.                         break;
  3362.                     case 'Friday': //Viernes
  3363.                         $dql = 'SELECT i
  3364.                                     FROM VenuesBundle:ReservationLoungeProfile i
  3365.                                     WHERE (
  3366.                                     ((i.year1 <= :dateYear and i.year2 >= :dateYear) or (i.year1 = :dateYear) or (i.year2 = :dateYear))
  3367.                                           AND (i.month10 = :month) AND (i.day5 = :day)) and i.loungeId = :loungeId and i.priceIsActive = :priceIsActive
  3368.                                       ';
  3369.                         break;
  3370.                     case 'Saturday': //Sabado
  3371.                         $dql = 'SELECT i
  3372.                                     FROM VenuesBundle:ReservationLoungeProfile i
  3373.                                     WHERE (
  3374.                                     ((i.year1 <= :dateYear and i.year2 >= :dateYear) or (i.year1 = :dateYear) or (i.year2 = :dateYear))
  3375.                                           AND (i.month10 = :month) AND (i.day6 = :day)) and i.loungeId = :loungeId and i.priceIsActive = :priceIsActive
  3376.                                       ';
  3377.                         break;
  3378.                     case 'Sunday': //Domingo
  3379.                         $dql = 'SELECT i
  3380.                                     FROM VenuesBundle:ReservationLoungeProfile i
  3381.                                     WHERE (
  3382.                                     ((i.year1 <= :dateYear and i.year2 >= :dateYear) or (i.year1 = :dateYear) or (i.year2 = :dateYear))
  3383.                                           AND (i.month10 = :month) AND (i.day7 = :day)) and i.loungeId = :loungeId and i.priceIsActive = :priceIsActive
  3384.                                       ';
  3385.                         break;
  3386.                     default:
  3387.                         break;
  3388.                 }
  3389.                 break;
  3390.             case '11': //Noviembre
  3391.                 switch ($date->format('l')) {
  3392.                     case 'Monday': //Lunes
  3393.                         $dql = 'SELECT i
  3394.                                     FROM VenuesBundle:ReservationLoungeProfile i
  3395.                                     WHERE (
  3396.                                     ((i.year1 <= :dateYear and i.year2 >= :dateYear) or (i.year1 = :dateYear) or (i.year2 = :dateYear))
  3397.                                           AND (i.month11 = :month) AND (i.day1 = :day)) and i.loungeId = :loungeId and i.priceIsActive = :priceIsActive
  3398.                                       ';
  3399.                         break;
  3400.                     case 'Tuesday': //Martes
  3401.                         $dql = 'SELECT i
  3402.                                     FROM VenuesBundle:ReservationLoungeProfile i
  3403.                                     WHERE (
  3404.                                     ((i.year1 <= :dateYear and i.year2 >= :dateYear) or (i.year1 = :dateYear) or (i.year2 = :dateYear))
  3405.                                           AND (i.month11 = :month) AND (i.day2 = :day)) and i.loungeId = :loungeId and i.priceIsActive = :priceIsActive
  3406.                                       ';
  3407.                         break;
  3408.                     case 'Wednesday': //Miercoles
  3409.                         $dql = 'SELECT i
  3410.                                     FROM VenuesBundle:ReservationLoungeProfile i
  3411.                                     WHERE (
  3412.                                     ((i.year1 <= :dateYear and i.year2 >= :dateYear) or (i.year1 = :dateYear) or (i.year2 = :dateYear))
  3413.                                           AND (i.month11 = :month) AND (i.day3 = :day)) and i.loungeId = :loungeId and i.priceIsActive = :priceIsActive
  3414.                                       ';
  3415.                         break;
  3416.                     case 'Thursday': //Jueves
  3417.                         $dql = 'SELECT i
  3418.                                     FROM VenuesBundle:ReservationLoungeProfile i
  3419.                                     WHERE (
  3420.                                     ((i.year1 <= :dateYear and i.year2 >= :dateYear) or (i.year1 = :dateYear) or (i.year2 = :dateYear))
  3421.                                           AND (i.month11 = :month) AND (i.day4 = :day)) and i.loungeId = :loungeId and i.priceIsActive = :priceIsActive
  3422.                                       ';
  3423.                         break;
  3424.                     case 'Friday': //Viernes
  3425.                         $dql = 'SELECT i
  3426.                                     FROM VenuesBundle:ReservationLoungeProfile i
  3427.                                     WHERE (
  3428.                                     ((i.year1 <= :dateYear and i.year2 >= :dateYear) or (i.year1 = :dateYear) or (i.year2 = :dateYear))
  3429.                                           AND (i.month11 = :month) AND (i.day5 = :day)) and i.loungeId = :loungeId and i.priceIsActive = :priceIsActive
  3430.                                       ';
  3431.                         break;
  3432.                     case 'Saturday': //Sabado
  3433.                         $dql = 'SELECT i
  3434.                                     FROM VenuesBundle:ReservationLoungeProfile i
  3435.                                     WHERE (
  3436.                                     ((i.year1 <= :dateYear and i.year2 >= :dateYear) or (i.year1 = :dateYear) or (i.year2 = :dateYear))
  3437.                                           AND (i.month11 = :month) AND (i.day6 = :day)) and i.loungeId = :loungeId and i.priceIsActive = :priceIsActive
  3438.                                       ';
  3439.                         break;
  3440.                     case 'Sunday': //Domingo
  3441.                         $dql = 'SELECT i
  3442.                                     FROM VenuesBundle:ReservationLoungeProfile i
  3443.                                     WHERE (
  3444.                                     ((i.year1 <= :dateYear and i.year2 >= :dateYear) or (i.year1 = :dateYear) or (i.year2 = :dateYear))
  3445.                                           AND (i.month11 = :month) AND (i.day7 = :day)) and i.loungeId = :loungeId and i.priceIsActive = :priceIsActive
  3446.                                       ';
  3447.                         break;
  3448.                     default:
  3449.                         break;
  3450.                 }
  3451.                 break;
  3452.             case '12': //Diciembre
  3453.                 switch ($date->format('l')) {
  3454.                     case 'Monday': //Lunes
  3455.                         $dql = 'SELECT i
  3456.                                     FROM VenuesBundle:ReservationLoungeProfile i
  3457.                                     WHERE (
  3458.                                     ((i.year1 <= :dateYear and i.year2 >= :dateYear) or (i.year1 = :dateYear) or (i.year2 = :dateYear))
  3459.                                           AND (i.month12 = :month) AND (i.day1 = :day)) and i.loungeId = :loungeId and i.priceIsActive = :priceIsActive
  3460.                                       ';
  3461.                         break;
  3462.                     case 'Tuesday': //Martes
  3463.                         $dql = 'SELECT i
  3464.                                     FROM VenuesBundle:ReservationLoungeProfile i
  3465.                                     WHERE (
  3466.                                     ((i.year1 <= :dateYear and i.year2 >= :dateYear) or (i.year1 = :dateYear) or (i.year2 = :dateYear))
  3467.                                           AND (i.month12 = :month) AND (i.day2 = :day)) and i.loungeId = :loungeId and i.priceIsActive = :priceIsActive
  3468.                                       ';
  3469.                         break;
  3470.                     case 'Wednesday': //Miercoles
  3471.                         $dql = 'SELECT i
  3472.                                     FROM VenuesBundle:ReservationLoungeProfile i
  3473.                                     WHERE (
  3474.                                     ((i.year1 <= :dateYear and i.year2 >= :dateYear) or (i.year1 = :dateYear) or (i.year2 = :dateYear))
  3475.                                           AND (i.month12 = :month) AND (i.day3 = :day)) and i.loungeId = :loungeId and i.priceIsActive = :priceIsActive
  3476.                                       ';
  3477.                         break;
  3478.                     case 'Thursday': //Jueves
  3479.                         $dql = 'SELECT i
  3480.                                     FROM VenuesBundle:ReservationLoungeProfile i
  3481.                                     WHERE (
  3482.                                     ((i.year1 <= :dateYear and i.year2 >= :dateYear) or (i.year1 = :dateYear) or (i.year2 = :dateYear))
  3483.                                           AND (i.month12 = :month) AND (i.day4 = :day)) and i.loungeId = :loungeId and i.priceIsActive = :priceIsActive
  3484.                                       ';
  3485.                         break;
  3486.                     case 'Friday': //Viernes
  3487.                         $dql = 'SELECT i
  3488.                                     FROM VenuesBundle:ReservationLoungeProfile i
  3489.                                     WHERE (
  3490.                                     ((i.year1 <= :dateYear and i.year2 >= :dateYear) or (i.year1 = :dateYear) or (i.year2 = :dateYear))
  3491.                                           AND (i.month12 = :month) AND (i.day5 = :day)) and i.loungeId = :loungeId and i.priceIsActive = :priceIsActive
  3492.                                       ';
  3493.                         break;
  3494.                     case 'Saturday': //Sabado
  3495.                         $dql = 'SELECT i
  3496.                                     FROM VenuesBundle:ReservationLoungeProfile i
  3497.                                     WHERE (
  3498.                                     ((i.year1 <= :dateYear and i.year2 >= :dateYear) or (i.year1 = :dateYear) or (i.year2 = :dateYear))
  3499.                                           AND (i.month12 = :month) AND (i.day6 = :day)) and i.loungeId = :loungeId and i.priceIsActive = :priceIsActive
  3500.                                       ';
  3501.                         break;
  3502.                     case 'Sunday': //Domingo
  3503.                         $dql = 'SELECT i
  3504.                                     FROM VenuesBundle:ReservationLoungeProfile i
  3505.                                     WHERE (
  3506.                                     ((i.year1 <= :dateYear and i.year2 >= :dateYear) or (i.year1 = :dateYear) or (i.year2 = :dateYear))
  3507.                                           AND (i.month12 = :month) AND (i.day7 = :day)) and i.loungeId = :loungeId and i.priceIsActive = :priceIsActive
  3508.                                       ';
  3509.                         break;
  3510.                     default:
  3511.                         break;
  3512.                 }
  3513.                 break;
  3514.             default:
  3515.                 break;
  3516.         }
  3517.         $query = $em->createQuery($dql)->setParameters($parameters);
  3518.         $price3 = $query->getResult();
  3519.         foreach ($price3 as $item) {
  3520.             if (empty($price0)) {
  3521.                 $price0 = $item;
  3522.             } else {
  3523.                 //Si los precios coinciden en fechas se tomara el que se haya cargado mas reciente en el sistema
  3524.                 if ($item->getCreatedAt() > $price0->getCreatedAt()) {
  3525.                     $price0 = $item;
  3526.                 }
  3527.             }
  3528.         }
  3529.         if (empty($price0)) {
  3530.             $price = 0;
  3531.         } else {
  3532.             $price = $price0->getPrice();
  3533.         }
  3534.         return array('price' => $price, );
  3535.     }
  3536.     /*
  3537.      * Se busca el precio a Sugerir
  3538.      * $dateStart Fecha
  3539.      * $loungeId Id de  la sala
  3540.      * $servicePrice Preciointroducido por elusuario
  3541.      * */
  3542.     private function precioTarifario($dateStart, $loungeId, $servicePrice)
  3543.     {
  3544.         $em = $this->getDoctrine()->getManager();
  3545.         $dateToFind = clone $dateStart;
  3546.         $dateToFind->setTime(0, 0, 0);
  3547.         $parameters = array(
  3548.             'loungeId' => $loungeId,
  3549.             'typePrice' => 'DIARIA',
  3550.             'dateToFind' => $dateToFind,
  3551.         );
  3552.         $dql = 'SELECT p
  3553.                 FROM VenuesBundle:ReservationLoungeProfile p
  3554.                 WHERE p.typePrice = :typePrice AND p.dateStart = :dateToFind AND p.loungeId = :loungeId
  3555.                 ORDER BY p.levelPrice DESC';
  3556.         $query = $em->createQuery($dql)->setParameters($parameters);
  3557.         $loungesPeriodsDaily = $query->getResult();
  3558.         $priceTarifa = empty($loungesPeriodsDaily) ? 0 : $loungesPeriodsDaily[0]->getPrice();
  3559.         $price = ($servicePrice == 0) ? $priceTarifa : $servicePrice;
  3560.         return $price;
  3561.     }
  3562.     /**
  3563.      * Elimina todos los elementos pertenecientes a una cotización.
  3564.      *
  3565.      * No hace flush. El flush/commit debe realizarlo el proceso que llama
  3566.      * a este método.
  3567.      */
  3568.     private function removeQuote(
  3569.         int $idRes,
  3570.         int $idQuote,
  3571.         EntityManagerInterface $em,
  3572.         ReservationConflictService $conflictService
  3573.     ): void {
  3574.         $reservation = $em
  3575.             ->getRepository(ReservationLoungeSimple::class)
  3576.             ->createQueryBuilder('r')
  3577.             ->where('r.rankQuote = :rankQuote')
  3578.             ->andWhere('r.idReservation = :idReservation')
  3579.             ->setParameter('idReservation', $idRes)
  3580.             ->setParameter('rankQuote', $idQuote)
  3581.             ->getQuery()
  3582.             ->getResult();
  3583.         $reserva = $em
  3584.             ->getRepository(Reservation::class)
  3585.             ->findOneById($idRes);
  3586.         foreach ($reservation as $item) {
  3587.              // ------------------------------------------------------
  3588.              //  1. Eliminar entrada de agenda
  3589.              // ------------------------------------------------------
  3590.             $this->agendaService->deleteAgendaBySource( $item->getId(), 'ReservationLoungeSimple' );
  3591.             // ------------------------------------------------------
  3592.             // 2. Comprobar conflictos
  3593.             // ------------------------------------------------------
  3594.             if ($reserva) { $conflictService->checkDeletedLoungeConflictsQuotes( $reserva, $item ); }
  3595.             // ------------------------------------------------------
  3596.             // 3. Eliminar servicio de limpieza
  3597.             // ------------------------------------------------------
  3598.             $loungeDetails = $em
  3599.                 ->getRepository(ReservationLoungeDetails::class)
  3600.                 ->findOneById($item->getIdLounge());
  3601.             if ($loungeDetails) {
  3602.                 $stringName = 'HORAS ( ' . $loungeDetails->getName() . ' )';
  3603.                 $serviceCatIdClean = 21;
  3604.                 $dateInAt = new \DateTime( $item->getDateStart()->format('Y-m-d\TH:i') );
  3605.                 $dateOutAt = new \DateTime( $item->getDateEnd()->format('Y-m-d\TH:i') );
  3606.                 $serviceClean = $em
  3607.                     ->getRepository(ReservationService::class)
  3608.                     ->createQueryBuilder('rs')
  3609.                     ->where('rs.reservationId = :id')
  3610.                     ->andWhere('rs.name = :name')
  3611.                     ->andWhere('rs.dateInAt = :dateInAt')
  3612.                     ->andWhere('rs.dateOutAt = :dateOutAt')
  3613.                     ->andWhere('rs.serviceCatId = :serviceCatId')
  3614.                     ->setParameter('id', $idRes)
  3615.                     ->setParameter('name', $stringName)
  3616.                     ->setParameter('dateInAt', $dateInAt)
  3617.                     ->setParameter('dateOutAt', $dateOutAt)
  3618.                     ->setParameter('serviceCatId', $serviceCatIdClean)
  3619.                     ->getQuery()
  3620.                     ->getResult();
  3621.                 foreach ($serviceClean as $service) {
  3622.                     $em->remove($service);
  3623.                 }
  3624.             }
  3625.             // ------------------------------------------------------
  3626.             // 4. Eliminar ReservationLoungeSimple
  3627.             // ------------------------------------------------------
  3628.             $em->remove($item);
  3629.         }
  3630.     }
  3631. }