<?php
namespace App\MDS\VenuesBundle\Controller;
use App\Constants\BusinessTypeSettingsCompanyConstants;
use App\Constants\LanguageConstants;
use App\DTO\SyncronizationsAVDTO;
use App\DTO\SyncronizationsCateringDTO;
use App\Entity\DocContract;
use App\MDS\VenuesBundle\Entity\ReservationTracing;
use App\Entity\DocContractModel;
use App\Entity\Client;
use App\Entity\ClientContact;
use App\Entity\InvoiceProformaExtraField;
use App\Entity\Space;
use App\Entity\Supplier;
use App\Entity\User;
use App\Entity\HtFile;
use App\Entity\ReservationLoungeWebDescription;
use App\Entity\SageArticle;
use App\Entity\SageVatRates;
use App\Entity\SettingsCompany;
use App\Entity\WidgetNotes;
use App\Form\InvoiceProformaExtraFieldType;
use App\Form\WidgetNotesType;
use App\MDS\AvexpressBundle\Entity\AveFiles;
use App\MDS\VenuesBundle\Entity\ReservationVisit;
use App\MDS\VenuesBundle\Entity\Reservation;
use App\MDS\VenuesBundle\Entity\ReservationDeposit;
use App\MDS\VenuesBundle\Entity\ReservationLounge;
use App\MDS\VenuesBundle\Entity\ReservationLoungeDescription;
use App\MDS\VenuesBundle\Entity\ReservationLoungeDetails;
use App\MDS\VenuesBundle\Entity\ReservationLoungePicture;
use App\MDS\VenuesBundle\Entity\ReservationLoungeProfile;
use App\MDS\VenuesBundle\Entity\ReservationLoungeSimple;
use App\MDS\VenuesBundle\Entity\ReservationLoungeVideo;
use App\MDS\VenuesBundle\Entity\ReservationMailAlertClient;
use App\MDS\VenuesBundle\Entity\ReservationPeriod;
use App\MDS\VenuesBundle\Entity\ReservationService;
use App\MDS\VenuesBundle\Entity\ReservationAlertStarted;
use App\MDS\VenuesBundle\Entity\ReservationAlertSecondDeposit;
use App\MDS\VenuesBundle\Entity\ReservationInvoice;
use App\MDS\VenuesBundle\Entity\ReservationInvoiceItems;
use App\MDS\VenuesBundle\Entity\ReservationInvoiceRec;
use App\MDS\VenuesBundle\Entity\ReservationPaymentsClient;
use App\MDS\VenuesBundle\Entity\ReservationProforma;
use App\MDS\VenuesBundle\Form\ReservationLoungeDetailsType;
use App\MDS\VenuesBundle\Form\ReservationLoungeProfileType;
use App\MDS\VenuesBundle\Form\ReservationLoungeType;
use App\MDS\VenuesBundle\Form\ReservationPeriodType;
use App\MDS\VenuesBundle\Form\ReservationType;
use App\MDS\VenuesBundle\Form\VisitEditType;
use App\Service\CalendarService;
use App\Service\ReservationService as ReservationServiceAlias;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Session\Session;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Response;
use App\Service\DocContractService;
use App\Service\SyncronizationsAVService;
use App\Service\SyncronizationsCateringService;
use Google_Client;
use Google_Service_Calendar;
use Psr\Log\LoggerInterface;
use DateTime;
use DatePeriod;
use DateInterval;
use Symfony\Contracts\Translation\TranslatorInterface;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Serializer\SerializerInterface;
use App\Service\AgendaService;
use App\MDS\VenuesBundle\Repository\ReservationAgendaItemRepository;
use App\MDS\VenuesBundle\Entity\ReservationAgendaItem;
use App\Service\AppConfigManager;
use App\Settings\AppConfig\ReservationWorkflowMode;
use App\Service\VenueService;
class ReservationsController extends AbstractController
{
private $translator;
protected $googleCalendar;
private $docContractService;
private $em;
private $session;
private $syncronizationsCateringService;
private $syncronizationsAVService;
private $agendaService;
private ReservationServiceAlias $reservationService;
public function __construct(
TranslatorInterface $translator,
DocContractService $docContractService,
EntityManagerInterface $em,
SessionInterface $session,
SyncronizationsCateringService $syncronizationsCateringService,
SyncronizationsAVService $syncronizationsAVService,
AgendaService $agendaService,
VenueService $venueService,
ReservationAgendaItemRepository $repository,
ReservationServiceAlias $reservationService
) {
$redirect_uri = 'https://' . $_SERVER['HTTP_HOST'] . '/calendar/token';
$googleCalendar = new Google_Client();
$googleCalendar->setApplicationName('Google Calendar API PHP Quickstart');
$googleCalendar->setClientId('2790497987-57qc3vu4pr7vb0s8phpub2me58pe34lb.apps.googleusercontent.com');
$googleCalendar->setClientSecret('nj2C7unaTO68DRhyORsyipSj');
$googleCalendar->setRedirectUri($redirect_uri);
$googleCalendar->addScope(Google_Service_Calendar::CALENDAR);
$guzzleClient = new \GuzzleHttp\Client(['curl' => [CURLOPT_SSL_VERIFYPEER => false]]);
$googleCalendar->setHttpClient($guzzleClient);
$this->googleCalendar = $googleCalendar;
$this->translator = $translator;
$this->docContractService = $docContractService;
$this->em = $em;
$this->session = $session;
$this->syncronizationsCateringService = $syncronizationsCateringService;
$this->syncronizationsAVService = $syncronizationsAVService;
$this->agendaService = $agendaService;
$this->repository = $repository;
$this->reservationService = $reservationService;
$this->venueService = $venueService;
}
/**
* @Route("/connectGoogle", name="homepage_Connect_Google")
*/
public function indexConnectGoogleAction(Request $request)
{
$session = new Session();
$token = $session->get('tokenGoogleCalendar');
if (!is_null($token)) {
$this->googleCalendar->setAccessToken($token);
}
// If there is no previous token or it's expired.
$data = array();
if ($this->googleCalendar->isAccessTokenExpired()) {
// Refresh the token if possible, else fetch a new one.
if ($this->googleCalendar->getRefreshToken()) {
$this->googleCalendar->fetchAccessTokenWithRefreshToken($this->googleCalendar->getRefreshToken());
} else {
// Request authorization from the user.
$authUrl = $this->googleCalendar->createAuthUrl();
return $this->redirect($authUrl);
}
}
return $this->redirectToRoute('homepage');
}
/**
* @Route("/add", name="reservations_venues_add")
*/
public function addReservationAction(Request $request)
{
return $this->redirectToRoute('reservations_venues_add_simple');
}
/**
* @Route("/create", name="reservations_venues_create")
*/
public function createAction(EntityManagerInterface $em, Request $request)
{
$reserva = new Reservation();
// // $reserva->setComAvGp(10); // Valor por defecto de ComAvGg
$form = $this->createReservationCreateForm($reserva);
$form->handleRequest($request);
/* Obtengo usuario logueado */
$user_logueado = $this->get('security.token_storage')->getToken()->getUser();
$user_id = $user_logueado->getId();
$hoy = new \DateTime("now", NULL);
if ($form->isValid()) {
$reserva->setUpdatedBy($user_id);
$reserva->setUpdatedAt($hoy);
// if (is_null($reserva->getCateringName())){
// $reserva->setSupplier(null);
// $reserva->setCateringName(null);
// } else {
// $reserva->setSupplier($reserva->getCateringName()->getId());
// $reserva->setCateringName($reserva->getCateringName()->getName());
// }
$clientId = $arrayRequest['client'] ?? null;
$reserva->setClient(
$clientId ? $em->getRepository(\App\Entity\Client::class)->find($clientId) : null
);
$reserva->setCreatedAt($hoy);
$reserva->setCreatedBy($user_id);
$reserva->setDateStart(new \DateTime('2078-01-01'));
$reserva->setDateEnd(new \DateTime('2000-01-01'));
if (is_null($reserva->getStatus())) {
$reserva->setStatus('Cotizado');
}
if (is_null($reserva->getPriority()) or empty($reserva->getPriority()) or ($reserva->getPriority() == 'Auto')) {
$reserva->setPriority(1);
}
// Buscamos la menor fecha de sala para el inicio y la mayor para determinar el fin del evento
$salas = $request->request->get('salas');
// crea una reserva sin sala. que fechas le pongo al evento
if (!is_null($salas)) {
foreach ($salas as $sala) {
if (sizeof($sala['mountingHourStart']) != 5) {
// Necesitamos la hora en formato HH:mm
switch (strlen($sala['mountingHourStart'])) {
case 0:
$sala['mountingHourStart'] = '00:00';
break; // Vacio
case 1: // H -> 0H:00
if (is_numeric($sala['mountingHourStart'])) {
$sala['mountingHourStart'] = '0' . $sala['mountingHourStart'] . ':00';
} else {
$sala['mountingHourStart'] = '00:00';
}
break;
case 2:
$sala['mountingHourStart'] = $sala['mountingHourStart'] . ':00';
break; // HH -> HH:00
case 3:
$sala['mountingHourStart'] = '0' . $sala['mountingHourStart'];
break; // Hmm -> 0H:mm
case 4:
$sala['mountingHourStart'] = substr($sala['mountingHourStart'], 0, 2) . ':' . substr($sala['mountingHourStart'], 2, 2);
break; // HHmm -> HH:mm
default:
$sala['mountingHourStart'] = '00:00';
break; // XXXXyyy
}
}
if (sizeof($sala['removalHourEnd']) != 5) {
// Necesitamos la hora en formato HH:mm
switch (strlen($sala['removalHourEnd'])) {
case 0:
$sala['removalHourEnd'] = '00:00';
break; // Vacio
case 1:
if (is_numeric($sala['removalHourEnd'])) {
$sala['removalHourEnd'] = '0' . $sala['removalHourEnd'] . ':00';
} else {
$sala['removalHourEnd'] = '00:00';
}
break; // H -> 0H:00
case 2:
$sala['removalHourEnd'] = $sala['removalHourEnd'] . ':00';
break; // HH -> HH:00
case 3:
$sala['removalHourEnd'] = '0' . $sala['removalHourEnd'];
break; // Hmm -> 0H:mm
case 4:
$sala['removalHourEnd'] = substr($sala['removalHourEnd'], 0, 2) . ':' . substr($sala['removalHourEnd'], 2, 2);
break; // HHmm -> HH:mm
default:
$sala['removalHourEnd'] = '00:00';
break; // XXXXyyy
}
}
// Verificamos el montaje
if ($reserva->getDateStart() > (new \DateTime($sala['mountingDate']))) {
$reserva->setDateStart((new \DateTime($sala['mountingDate'] . " " . $sala['mountingHourStart'])));
}
if ($reserva->getDateStart() > (new \DateTime($sala['dateStart']))) {
$reserva->setDateStart((new \DateTime($sala['dateStart'] . " " . $sala['hourStart'])));
}
if ($reserva->getDateEnd() < (new \DateTime($sala['dateEnd']))) {
$reserva->setDateEnd((new \DateTime($sala['dateEnd'] . " " . $sala['hourEnd'])));
}
//Verificamos el desmontaje
if ($reserva->getDateEnd() < (new \DateTime($sala['removalDate']))) {
$reserva->setDateEnd((new \DateTime($sala['removalDate'] . " " . $sala['removalHourEnd'])));
}
}
} else {
// No hay salas, se asigna a la reserva la fecha del dia actual
$reserva->setDateStart((new \DateTime()));
$reserva->setDateEnd((new \DateTime()));
}
// INICIO: se determina el numero de opcion o prioridad que tiene el evento
$salasTemp = $request->request->get('salas');
// Pendiente reunion con Rafa (se determina el numero de opcion o prioridad que tiene el evento)
// FIN: se determina el numero de opcion o prioridad que tiene el evento
try {
$em->persist($reserva);
$em->flush();
$event = 'The Reservation has been created.';
// $successMessage = $this->translator->trans($event);
$successMessage = 'La reserva ha sido creada.';
$this->addFlash('mensajereservation', $successMessage);
} catch (\Exception $e) {
$event = 'An error occurred: ' . $e->getMessage();
$errorMessage = $this->translator->trans($event);
$this->addFlash('mensajereservationerror', $errorMessage);
}
} else {
$errorMessagebase = $this->translator->trans('Error, some fields are empty');
$this->addFlash('mensajetracingerror', $errorMessagebase);
$periods = $em->getRepository(ReservationPeriod::class)->findAll();
return $this->render(
'MDS/VenuesBundle/reservations/add-reservations.html.twig',
array(
'form' => $form->createView(),
'periods' => $periods,
)
);
}
/* Fin Gestión de eventos en Log */
$salas = $request->request->get('salas');
// Inicio: Verificamos que hayan metido bien las salas, toda sala para poder facturar debe tener IdLounge, Fecha de inicio y fecha de fin
for ($i = 0; $i < sizeof($salas); $i++) {
if (empty($salas[$i]['idLounge']) or empty($salas[$i]['dateStart']) or empty($salas[$i]['dateEnd'])) {
unset($salas[$i]);
}
}
// Fin: Verificamos que hayan metido bien las salas, toda sala para poder facturar debe tener IdLounge, Fecha de inicio y fecha de fin
if (!is_null($reserva->getId())) {
if (!is_null($salas)) {
foreach ($salas as $sala) {
// Se guarda una sala si hay una sala seleccionada
// IdLounge es el ID en la tabla reservation profile
if (!empty(($sala['idLounge']))) {
// consulto la tabla de precios para obtener el id de salon desde el id de precios
$queryProfile = $em->getRepository(ReservationLoungeProfile::class)->findOneById($sala['idLounge']);
$reservaLounge = new ReservationLounge();
$reservaLounge->setIdLounge($queryProfile->getLoungeId());
$reservaLounge->setLoungeName(($em->getRepository(ReservationLoungeDetails::class)->findOneById($queryProfile->getLoungeId()))->getName());
$reservaLounge->setCreatedAt($hoy);
$reservaLounge->setCreatedBy($user_id);
$reservaLounge->setUpdatedAt($hoy);
$reservaLounge->setUpdatedBy($user_id);
$reservaLounge->setIdReservation($reserva->getId());
$reservaLounge->setDateStart(new \DateTime($sala['dateStart'] . " " . $sala['hourStart']));
$reservaLounge->setDateEnd(new \DateTime($sala['dateEnd'] . " " . $sala['hourEnd']));
$reservaLounge->setHourStart(substr($sala['hourStart'], 0, 2));
$reservaLounge->setMinStart(substr($sala['hourStart'], 3, 2));
$reservaLounge->setHourEnd(substr($sala['hourEnd'], 0, 2));
$reservaLounge->setMinEnd(substr($sala['hourEnd'], 3, 2));
$reservaLounge->setServicePrice($sala['servicePrice']);
// el service name es la descripcion
$reservaLounge->setServiceName($sala['serviceName']);
$reservaLounge->setIdPeriod($sala['idLoungePrice']);
if (empty($sala['servicePax'])) {
$reservaLounge->setPax(null);
} else {
$reservaLounge->setPax($sala['servicePax']);
}
$reservaLounge->setMounting($sala['serviceMounting']);
if (empty($sala['mountingPrice'])) {
$reservaLounge->setMountingPrice(0);
} else {
$reservaLounge->setMountingPrice($sala['mountingPrice']);
}
$reservaLounge->setMountingLapse($sala['mountingLapse']);
switch (strlen($sala['mountingHourStart'])) {
case 0: // Vacio
$reservaLounge->setMountingHourStart('00');
$reservaLounge->setMountingMinStart('00');
break;
case 1: // H -> 0H:00
if (is_numeric($sala['mountingHourStart'])) {
$reservaLounge->setMountingHourStart('0' . $sala['mountingHourStart']);
} else {
$reservaLounge->setMountingHourStart('00');
}
$reservaLounge->setMountingMinStart('00');
break;
case 2: // HH -> HH:00
$reservaLounge->setMountingHourStart($sala['mountingHourStart']);
$reservaLounge->setMountingMinStart('00');
break;
case 3: // Hmm -> 0H:mm
$reservaLounge->setMountingHourStart('0' . substr($sala['mountingHourStart'], 0, 1));
$reservaLounge->setMountingMinStart(substr($sala['mountingHourStart'], 1, 2));
break;
case 4: // HHmm -> HH:mm
$reservaLounge->setMountingHourStart(substr($sala['mountingHourStart'], 0, 2));
$reservaLounge->setMountingMinStart(substr($sala['mountingHourStart'], 2, 2));
break;
case 5: // HH:mm -> HH:mm
$reservaLounge->setMountingHourStart(substr($sala['mountingHourStart'], 0, 2));
$reservaLounge->setMountingMinStart(substr($sala['mountingHourStart'], 3, 2));
break;
default: // XXXXyyy
$reservaLounge->setMountingHourStart('00');
$reservaLounge->setMountingMinStart('00');
break;
}
switch (strlen($sala['mountingHourEnd'])) {
case 0: // Vacio
$reservaLounge->setMountingHourEnd('00');
$reservaLounge->setMountingMinEnd('00');
break;
case 1: // H -> 0H:00
if (is_numeric($sala['mountingHourEnd'])) {
$reservaLounge->setMountingHourEnd('0' . $sala['mountingHourEnd']);
} else {
$reservaLounge->setMountingHourEnd('00');
}
$reservaLounge->setMountingMinEnd('00');
break;
case 2: // HH -> HH:00
$reservaLounge->setMountingHourEnd($sala['mountingHourEnd']);
$reservaLounge->setMountingMinEnd('00');
break;
case 3: // Hmm -> 0H:mm
$reservaLounge->setMountingHourEnd('0' . substr($sala['mountingHourEnd'], 0, 1));
$reservaLounge->setMountingMinEnd(substr($sala['mountingHourEnd'], 1, 2));
break;
case 4: // HHmm -> HH:mm
$reservaLounge->setMountingHourEnd(substr($sala['mountingHourEnd'], 0, 2));
$reservaLounge->setMountingMinEnd(substr($sala['mountingHourEnd'], 2, 2));
break;
case 5: // HH:mm -> HH:mm
$reservaLounge->setMountingHourEnd(substr($sala['mountingHourEnd'], 0, 2));
$reservaLounge->setMountingMinEnd(substr($sala['mountingHourEnd'], 3, 2));
break;
default: // XXXXyyy
$reservaLounge->setMountingHourEnd('00');
$reservaLounge->setMountingMinEnd('00');
break;
}
$reservaLounge->setMountingDate(new \DateTime($sala['mountingDate'] . ' ' . $reservaLounge->getMountingHourStart() . ':' . $reservaLounge->getMountingMinStart()));
$reservaLounge->setRemovalLapse($sala['removalLapse']);
$reservaLounge->setRemovalDate(new \DateTime($sala['removalDate']));
switch (strlen($sala['removalHourStart'])) {
case 0: // Vacio
$reservaLounge->setRemovalHourStart('00');
$reservaLounge->setRemovalMinStart('00');
break;
case 1: // H -> 0H:00
if (is_numeric($sala['removalHourStart'])) {
$reservaLounge->setRemovalHourStart('0' . $sala['removalHourStart']);
} else {
$reservaLounge->setRemovalHourStart('00');
}
$reservaLounge->setRemovalMinStart('00');
break;
case 2: // HH -> HH:00
$reservaLounge->setRemovalHourStart($sala['removalHourStart']);
$reservaLounge->setRemovalMinStart('00');
break;
case 3: // Hmm -> 0H:mm
$reservaLounge->setRemovalHourStart('0' . substr($sala['removalHourStart'], 0, 1));
$reservaLounge->setRemovalMinStart(substr($sala['removalHourStart'], 1, 2));
break;
case 4: // HHmm -> HH:mm
$reservaLounge->setRemovalHourStart(substr($sala['removalHourStart'], 0, 2));
$reservaLounge->setRemovalMinStart(substr($sala['removalHourStart'], 2, 2));
break;
case 5: // HH:mm -> HH:mm
$reservaLounge->setRemovalHourStart(substr($sala['removalHourStart'], 0, 2));
$reservaLounge->setRemovalMinStart(substr($sala['removalHourStart'], 3, 2));
break;
default: // XXXXyyy
$reservaLounge->setRemovalHourStart('00');
$reservaLounge->setRemovalMinStart('00');
break;
}
switch (strlen($sala['removalHourEnd'])) {
case 0: // Vacio
$reservaLounge->setRemovalHourEnd('00');
$reservaLounge->setRemovalMinEnd('00');
break;
case 1: // H -> 0H:00
if (is_numeric($sala['removalHourEnd'])) {
$reservaLounge->setRemovalHourEnd('0' . $sala['removalHourEnd']);
} else {
$reservaLounge->setRemovalHourEnd('00');
}
$reservaLounge->setRemovalMinEnd('00');
break;
case 2: // HH -> HH:00
$reservaLounge->setRemovalHourEnd($sala['removalHourEnd']);
$reservaLounge->setRemovalMinEnd('00');
break;
case 3: // Hmm -> 0H:mm
$reservaLounge->setRemovalHourEnd('0' . substr($sala['removalHourEnd'], 0, 1));
$reservaLounge->setRemovalMinEnd(substr($sala['removalHourEnd'], 1, 2));
break;
case 4: // HHmm -> HH:mm
$reservaLounge->setRemovalHourEnd(substr($sala['removalHourEnd'], 0, 2));
$reservaLounge->setRemovalMinEnd(substr($sala['removalHourEnd'], 2, 2));
break;
case 5: // HH:mm -> HH:mm
$reservaLounge->setRemovalHourEnd(substr($sala['removalHourEnd'], 0, 2));
$reservaLounge->setRemovalMinEnd(substr($sala['removalHourEnd'], 3, 2));
break;
default: // XXXXyyy
$reservaLounge->setRemovalHourEnd('00');
$reservaLounge->setRemovalMinEnd('00');
break;
}
if (empty($sala['removalPrice'])) {
$reservaLounge->setRemovalPrice(0);
} else {
$reservaLounge->setRemovalPrice($sala['removalPrice']);
}
// INICIO: Verificamos si choca con otra reserva
// Si sucede se usara el booleano OtherPriceSave para indicarlo
$resFun = $this->VerificarCoflictosEnSalas($reservaLounge);
$tempBool = $resFun['bool'];
if ($tempBool) {
$reservaLounge->setOtherPriceSave(true);
$reserva->setPriority($resFun['priority']);
// Se debe modificar la prioridad de la nueva reserva, que ya se habia guardado previamente
try {
$em->persist($reserva);
$em->flush();
} catch (\Exception $e) {
$event = 'Error al actualizar la prioridad del evento ' . $e->getMessage();
/* Para el usuario */
$errorMessage = $this->translator->trans($event);
$this->addFlash('mensajereservationerror', $errorMessage);
}
} else {
$reservaLounge->setOtherPriceSave(false);
}
// FIN: Verificamos si choca con otra reserva
// INICIO: Si es necesario se actualizan fechas de inicio y fin usando dia de montaje y desmontaje
if (($reservaLounge->getMountingDate() < $reserva->getDateStart()) or ($reserva->getDateEnd() < $reservaLounge->getRemovalDate())) {
if ($reservaLounge->getMountingDate() < $reserva->getDateStart()) {
$reserva->setDateStart($reservaLounge->getMountingDate());
}
if ($reserva->getDateEnd() < $reservaLounge->getRemovalDate()) {
$reserva->setDateEnd($reservaLounge->getRemovalDate());
}
try {
$em->persist($reserva);
$em->flush();
} catch (\Exception $e) {
$event = 'Error al actualizar fechas de inicio y fin, por montaje y desmontaje de sala: ' . $e->getMessage();
$errorMessage = $this->translator->trans($event);
$this->addFlash('mensajereservationerror', $errorMessage);
}
}
// FIN: Si es necesario se actualizan fechas de inicio y fin usando dia de montaje y desmontaje
try {
$em->persist($reservaLounge);
$em->flush();
} catch (\Exception $e) {
$event = 'Al agregar la sala ha ocurrido un error: ' . $e->getMessage();
/* Para el usuario */
$errorMessage = $this->translator->trans($event);
$this->addFlash('mensajereservationerror', $errorMessage);
}
}
}
// INICIO: Verificamos la prioridad
$numeroPriority = 1;
//INICIO: Buscamos las salas que coincidan en tiempo de reserva
foreach ($salas as $sala) {
$newdateStar = $sala['dateStart'] . ' ' . $sala['hourStart'];
$newdateEnd = $sala['dateEnd'] . ' ' . $sala['hourEnd'];
$reservaProfile = $em->getRepository(ReservationLoungeProfile::class)->findOneById($sala['idLounge']);
$parameters = array(
'dateStar' => $newdateStar,
'dateEnd' => $newdateEnd,
'idLounge' => $reservaProfile->getLoungeId(),
'idRes' => $reserva->getId(),
);
$dql = 'SELECT i
FROM VenuesBundle:ReservationLounge i
WHERE (i.dateStart >= :dateStar
and i.dateStart <= :dateEnd
and i.idLounge = :idLounge
and i.idReservation != :idRes)
or
(i.dateStart <= :dateStar
and i.dateStart >= :dateEnd
and i.idLounge = :idLounge
and i.idReservation != :idRes)
';
$query = $em->createQuery($dql)->setParameters($parameters);
$reservationLounge = $query->getResult();
}
//FIN: Buscamos las salas que coincidan en tiempo de reserva
// INICIO: Buscamos el numero de opcion a asignar
$modificarPrior = false;
if (!empty($reservaLounge)) {
foreach ($reservationLounge as $resLoung) {
$reservaClash = $em->getRepository(Reservation::class)->findOneById($resLoung->getIdReservation());
$tempPrior = $reservaClash->getPriority();
if ($numeroPriority <= $tempPrior) {
// Ya tenemos una reserva con opcion de mayor relevancia (un numero de opción inferior)
$numeroPriority = $tempPrior + 1;
$modificarPrior = true;
}
}
if ($modificarPrior) {
// Se debe modificar la prioridad
$reserva->setPriority($numeroPriority);
try {
$em->persist($reserva);
$em->flush();
$event = 'The Reservation has been created.';
// $successMessage = $this->translator->trans($event);
$successMessage = 'La reserva ha sido creada.';
$this->addFlash('mensajereservation', $successMessage);
} catch (\Exception $e) {
$event = 'An error occurred: ' . $e->getMessage();
$errorMessage = $this->translator->trans($event);
$this->addFlash('mensajereservationerror', $errorMessage);
}
}
} else {
// El numero de opción asignada fue el correcto
}
// FIN: Buscamos el numero de opcion a asignar
// FIN: Verificamos la prioridad
}
} else {
$reservationsLounges = null; // Si fallo la reserva no habrá salas
}
return $this->redirectToRoute('reservations_venues_index');
}
public function VerificarCoflictosEnSalas(EntityManagerInterface $em, $nuevaSala)
{
$allSalas = $em->getRepository(ReservationLounge::class)->findAll();
$tempBool = false; //Aun no se ha detectado un conflicto
$prioridad = 1;
foreach ($allSalas as $sala) {
if ($sala->getIdReservation() == $nuevaSala->getIdReservation()) {
// No hay conflicto son de la misma reserva
$tempBool = ($tempBool or false);
} else {
if (!($sala->getIdLounge() == $nuevaSala->getIdLounge())) {
// No hay conflicto no son la misma sala
$tempBool = ($tempBool or false);
} else {
// Caso 1: F. inicio de $nuevaSala entre las feachas de $sala
if (($nuevaSala->getDateStart() > $sala->getDateStart()) and ($nuevaSala->getDateStart() < $sala->getDateEnd())) {
$tempBool = true;
// Buscamos la prioridad que tiene el evento de la sala que colisiona para determinar la nueva prioridad del evento que se está creando
$resTemp = $em->getRepository(Reservation::class)->findOneById($sala->getIdReservation());
if (($prioridad < $resTemp->getPriority()) or ($prioridad == $resTemp->getPriority())) {
$prioridad = $resTemp->getPriority() + 1;
}
}
// Caso 2: F. fin de $nuevaSala entre las feachas de $sala
if (($nuevaSala->getDateEnd() > $sala->getDateStart()) and ($nuevaSala->getDateEnd() < $sala->getDateEnd())) {
$tempBool = true;
// Buscamos la prioridad que tiene el evento de la sala que colisiona para determinar la nueva prioridad del evento que se está creando
$resTemp = $em->getRepository(Reservation::class)->findOneById($sala->getIdReservation());
if (($prioridad <= $resTemp->getPriority()) or ($prioridad == $resTemp->getPriority())) {
$prioridad = $resTemp->getPriority() + 1;
}
}
// Caso 3: F. inicio de $sala entre las feachas de $nuevaSala
if (($sala->getDateStart() > $nuevaSala->getDateStart()) and ($sala->getDateStart() < $nuevaSala->getDateEnd())) {
$tempBool = true;
// Buscamos la prioridad que tiene el evento de la sala que colisiona para determinar la nueva prioridad del evento que se está creando
$resTemp = $em->getRepository(Reservation::class)->findOneById($sala->getIdReservation());
if (($prioridad <= $resTemp->getPriority()) or ($prioridad == $resTemp->getPriority())) {
$prioridad = $resTemp->getPriority() + 1;
}
}
// Caso 4: F. fin de $sala entre las feachas de $nuevaSala
if (($sala->getDateEnd() > $nuevaSala->getDateStart()) and ($sala->getDateEnd() < $nuevaSala->getDateEnd())) {
$tempBool = true;
// Buscamos la prioridad que tiene el evento de la sala que colisiona para determinar la nueva prioridad del evento que se está creando
$resTemp = $em->getRepository(Reservation::class)->findOneById($sala->getIdReservation());
if (($prioridad <= $resTemp->getPriority()) or ($prioridad == $resTemp->getPriority())) {
$prioridad = $resTemp->getPriority() + 1;
}
}
// Caso 5: fechas iguales
if (
($nuevaSala->getDateStart() == $sala->getDateStart()) or
($nuevaSala->getDateStart() == $sala->getDateEnd()) or
($nuevaSala->getDateEnd() == $sala->getDateStart()) or
($nuevaSala->getDateEnd() == $sala->getDateEnd())
) {
$tempBool = true;
}
}
}
}
$res = array('bool' => $tempBool, 'priority' => $prioridad);
return ($res);
}
public function CalculoPrioridad(EntityManagerInterface $em, $reserva)
{
$listAllReservas = $em->getRepository(Reservation::class)->findAll();
// logico para controlar el conflicto entre salas
$logSalasError = false;
// valor original de la prioridad
$oldPriority = $reserva->getPriority();
foreach ($listAllReservas as $resv) {
$reservaSala = explode(",", $reserva->getSalas()); // Arreglo de salas para agregar
$resSala = explode(",", $resv->getSalas()); // Arreglo de salas que ya estan en
foreach ($reservaSala as $item) {
if (in_array($item, $resSala)) {
$logSalasError = ($logSalasError or true); // Este logico indica si hay conflicto entre las salas
}
}
if (
(($reserva->getDateStart() == $resv->getDateStart()) or ($reserva->getDateStart() < $resv->getDateStart())) and
($resv->getDateStart() < $reserva->getDateEnd()) and ($resv->getStatus() == 'Confirmed')
) {
if ($resv->getPriority() == $reserva->getPriority()) {
$reserva->setPriority($reserva->getPriority() - 1);
} else {
if ($resv->getPriority() < $reserva->getPriority()) {
$reserva->setPriority($resv->getPriority() - 1);
} else {
// ($resv->getPriority() > $reserva->getPriority())
// No se debe cambiar la prioridad ya que esta por debajo de la reserva ya creada
}
}
}
if (
(($resv->getDateStart() == $reserva->getDateStart()) or ($resv->getDateStart() < $reserva->getDateStart())) and
($reserva->getDateEnd() < $resv->getDateEnd()) and ($resv->getStatus() == 'Confirmed')
) {
if ($resv->getPriority() == $reserva->getPriority()) {
$reserva->setPriority($reserva->getPriority() - 1);
} else {
if ($resv->getPriority() < $reserva->getPriority()) {
$reserva->setPriority($resv->getPriority() - 1);
} else {
// ($resv->getPriority() > $reserva->getPriority())
// No se debe cambiar la prioridad ya que esta por debajo de la reserva ya creada
}
}
}
if (
(($reserva->getDateStart() == $resv->getDateStart()) or ($reserva->getDateStart() < $resv->getDateStart())) and
(($resv->getDateEnd() == $reserva->getDateEnd()) or ($resv->getDateEnd() < $reserva->getDateEnd())) and
($resv->getStatus() == 'Confirmed')
) {
if ($resv->getPriority() == $reserva->getPriority()) {
$reserva->setPriority($reserva->getPriority() - 1);
} else {
if ($resv->getPriority() < $reserva->getPriority()) {
$reserva->setPriority($resv->getPriority() - 1);
} else {
// ($resv->getPriority() > $reserva->getPriority())
// No se debe cambiar la prioridad ya que esta por debajo de la reserva ya creada
}
}
}
if (
(($resv->getDateStart() == $reserva->getDateStart()) or ($resv->getDateStart() < $reserva->getDateStart())) and
(($resv->getDateEnd() == $reserva->getDateEnd()) or ($resv->getDateEnd() < $reserva->getDateEnd())) and
($resv->getStatus() == 'Confirmed')
) {
if ($resv->getPriority() == $reserva->getPriority()) {
$reserva->setPriority($reserva->getPriority() - 1);
} else {
if ($resv->getPriority() < $reserva->getPriority()) {
$reserva->setPriority($resv->getPriority() - 1);
} else {
// ($resv->getPriority() > $reserva->getPriority())
// No se debe cambiar la prioridad ya que esta por debajo de la reserva ya creada
}
}
}
}
$priority = $reserva->getPriority();
$reserva->setPriority($oldPriority); // Se restablece el valor de origen de la prioridad
$data = array('prioridad' => $priority);
return $data;
}
public function NombreSalasPrecios(EntityManagerInterface $em)
{
$reservaLoungeDetails = $em->getRepository(ReservationLoungeDetails::class)->findAll();
$data = array();
foreach ($reservaLoungeDetails as $res) {
if (!empty($data['salas'])) {
$data['salas'] = $data['salas'] . ',' . $res->getName();
} else {
$data['salas'] = $res->getName();
}
}
$dataArray = array('-1');
foreach ($reservaLoungeDetails as $res) {
array_push($dataArray, array($res->getId(), $res->getName()));
}
unset($dataArray[0]);
$data['arraySalas'] = $dataArray;
$parameters = array();
$dql = 'SELECT p
FROM VenuesBundle:ReservationGpPrice p
ORDER BY p.idService ASC ';
$query = $em->createQuery($dql)->setParameters($parameters);
$reservaGpPrice = $query->getResult();
foreach ($reservaGpPrice as $res) {
if (!empty($data['precios'])) {
$data['precios'] = $data['precios'] . ',' . $res->getNameAndPrice();
} else {
$data['precios'] = $res->getNameAndPrice();
}
}
$dataArray = array('-1');
foreach ($reservaGpPrice as $res) {
array_push($dataArray, array($res->getIdService(), $res->getNameAndPrice()));
}
unset($dataArray[0]);
$data['arrayPrecios'] = $dataArray;
return $data;
}
private function CalculosTotalesEditSimple($id)
{
$em = $this->getDoctrine()->getManager();
$sageVatRatesRepo = $em->getRepository(SageVatRates::class);
$reservaLounges = $em->getRepository(ReservationLoungeSimple::class)->findByIdReservation($id);
$reservaServices = $em->getRepository(ReservationService::class)->findByReservationId($id);
$reserva = $em->getRepository(Reservation::class)->findOneById($id);
$reservaSucoe = (empty($reserva->isSucoe())) ? false : $reserva->isSucoe();
$data_iva = array(
'iva' => $sageVatRatesRepo->findOneBy(['sageCode' => '03'])->getIva(),
'ivaMontoVeintiUno' => 0,
'ivaMontoDiez' => 0,
'ivaMontoCero' => 0,
);
$reservationsLounge = array(
'neto' => 0,
'sumSubT' => 0,
); // Acumula sumatoria de netos y sumantoria de subtotales
$service = array(
'neto' => 0,
'sumSubT' => 0,
'sumIvas' => 0,
); // Acumula sumatoria de netos y sumantoria de subtotales
$totales_neto_all = 0;
foreach ($reservaLounges as $item) {
// dd($item);
// Si el iva es vacio se asume 21
$itemIva = $item->getSageIva();
if (empty($itemIva) && !is_numeric($itemIva)) {
$item->setSageIva($sageVatRatesRepo->findOneBy(['sageCode' => '03']));
$this->addFlash('mensajereservationerror', 'Revisa el IVA de la sala: ' . $item->getLoungeName());
}
if (is_null($item->getServicePrice()) or empty($item->getServicePrice())) {
$subtotal = 0;
$neto = 0;
$subtotalLounge = 0;
} else {
$subtotalLounge = ($reservaSucoe) ? $item->getServicePrice() : ($item->getServicePrice() * 1.21);
$subneto = $item->getServicePrice();
$subtotal = $subtotalLounge;
$neto = $subneto;
// Se lleva a 2 decimales round($totales_neto_antes,2,PHP_ROUND_HALF_UP),
$subtotal = round($subtotal, 2, PHP_ROUND_HALF_UP);
$neto = round($neto, 2, PHP_ROUND_HALF_UP);
}
// Acumula netos totales e IVA
$totales_neto_all = $totales_neto_all + $neto;
$data_iva['ivaMontoVeintiUno'] = ($reservaSucoe) ? 0 : $data_iva['ivaMontoVeintiUno'] + ($neto * 0.21);
// Se lleva a 2 decimales round($totales_neto_antes,2,PHP_ROUND_HALF_UP)
$totales_neto_all = round($totales_neto_all, 2, PHP_ROUND_HALF_UP);
$data_iva['ivaMontoVeintiUno'] = round($data_iva['ivaMontoVeintiUno'], 2, PHP_ROUND_HALF_UP);
// Acumula netos totales e IVA
$reservationsLounge['neto'] = $reservationsLounge['neto'] + $neto;
$reservationsLounge['sumSubT'] = $reservationsLounge['sumSubT'] + $subtotal;
// // Se lleva a 2 decimales round($totales_neto_antes,2,PHP_ROUND_HALF_UP)
$reservationsLounge['neto'] = round($reservationsLounge['neto'], 2, PHP_ROUND_HALF_UP);
$reservationsLounge['sumSubT'] = round($reservationsLounge['sumSubT'], 2, PHP_ROUND_HALF_UP);
}
foreach ($reservaServices as $item) {
$subtotal = 0;
$neto = 0;
$subtotalService = 0;
if (!is_null($item->getPrice()) and !empty($item->getPrice())) {
$subtotalService = $item->getPrice();
$subneto = $item->getPrice();
// Commission
if ($item->getOpCommission() == '1') {
$subtotalService = (float) $subtotalService * (1 + ((float) $item->getCommission() / 100));
$subneto = (float) $subneto * (1 + ($item->getCommission() / 100));
} else {
$subtotalService = (float) $subtotalService * (1 - ((float) $item->getCommission() / 100));
$subneto = (float) $subneto * (1 - ($item->getCommission() / 100));
}
switch ($item->getServiceCatId()) {
case 1: // Alojamiento
// el numero de noches $numNoches; precio unitario $subneto
$numNoches = (($item->getDateOutAt())->diff($item->getDateInAt()))->days;
// La personas no afectan este calculo
$subtotal = $subtotalService * $numNoches * $item->getUnits();
$subneto = $subneto * $numNoches * $item->getUnits();
break;
case 2: //Actividades
// El número de personas es considerado en el calculo
$pax = $item->getPax();
if (empty($pax) or $pax == "0") {
$pax = 1;
}
$days = ((($item->getDateOutAt())->diff($item->getDateInAt()))->days + 1);
$subtotal = $subtotalService * $days * $item->getUnits();
$subneto = $subneto * $days * $item->getUnits();
break;
case 3: // AV
$pax = $item->getPax();
if (empty($pax) or $pax == "0") {
$pax = 1;
}
$days = ((($item->getDateOutAt())->diff($item->getDateInAt()))->days + 1);
$unitsServ = $item->getUnits();
if (empty($unitsServ) or $unitsServ == "0") {
$unitsServ = 1;
}
$subtotal = $subtotalService * $days * $unitsServ * $pax;
$subneto = $subneto * $days * $unitsServ * $pax;
break;
case 4: //Creative
$pax = $item->getPax();
if (empty($pax) or $pax == "0") {
$pax = 1;
}
$days = ((($item->getDateOutAt())->diff($item->getDateInAt()))->days + 1);
$unitsServ = $item->getUnits();
if (empty($unitsServ) or $unitsServ == "0") {
$unitsServ = 1;
}
$subtotal = $subtotalService * $days * $unitsServ * $pax;
$subneto = $subneto * $days * $unitsServ * $pax;
break;
case 5: //Cruise
$pax = $item->getPax();
if (empty($pax) or $pax == "0") {
$pax = 1;
}
$days = ((($item->getDateOutAt())->diff($item->getDateInAt()))->days);
$unitsServ = $item->getUnits();
if (empty($unitsServ) or $unitsServ == "0") {
$unitsServ = 1;
}
$subtotal = $subtotalService * $days * $unitsServ * $pax;
$subneto = $subneto * $days * $unitsServ * $pax;
break;
case 6: //Entertaiment
$pax = $item->getPax();
if (empty($pax) or $pax == "0") {
$pax = 1;
}
$days = ((($item->getDateOutAt())->diff($item->getDateInAt()))->days + 1);
$unitsServ = $item->getUnits();
if (empty($unitsServ) or $unitsServ == "0") {
$unitsServ = 1;
}
$subtotal = $subtotalService * $days * $unitsServ * $pax;
$subneto = $subneto * $days * $unitsServ * $pax;
break;
case 7: // Gifts
$pax = $item->getPax();
if (empty($pax) or $pax == "0") {
$pax = 1;
}
$days = 1;
$unitsServ = $item->getUnits();
if (empty($unitsServ) or $unitsServ == "0") {
$unitsServ = 1;
}
$subtotal = $subtotalService * $days * $unitsServ * $pax;
$subneto = $subneto * $days * $unitsServ * $pax;
break;
case 8: //Guide
$pax = $item->getPax();
if (empty($pax) or $pax == "0") {
$pax = 1;
}
$days = ((($item->getDateOutAt())->diff($item->getDateInAt()))->days + 1);
$unitsServ = $item->getUnits();
if (empty($unitsServ) or $unitsServ == "0") {
$unitsServ = 1;
}
$subtotal = $subtotalService * $days * $unitsServ * $pax;
$subneto = $subneto * $days * $unitsServ * $pax;
break;
case 9: //Itineraries
$pax = $item->getPax();
if (empty($pax) or $pax == "0") {
$pax = 1;
}
$days = ((($item->getDateOutAt())->diff($item->getDateInAt()))->days + 1);
$unitsServ = $item->getUnits();
if (empty($unitsServ) or $unitsServ == "0") {
$unitsServ = 1;
}
$subtotal = $subtotalService * $days * $unitsServ * $pax;
$subneto = $subneto * $days * $unitsServ * $pax;
break;
case 10:
break; //Lounge -- No Aplica
case 11: //Menu
$pax = $item->getPax();
if (empty($pax) or $pax == "0") {
$pax = 1;
}
$days = ((($item->getDateOutAt())->diff($item->getDateInAt()))->days + 1);
$unitsServ = $item->getUnits();
if (empty($unitsServ) or $unitsServ == "0") {
$unitsServ = 1;
}
$subtotal = $subtotalService * $days * $unitsServ * $pax;
$subneto = $subneto * $days * $unitsServ * $pax;
break;
case 12: //Others
$pax = $item->getPax();
if (empty($pax) or $pax == "0") {
$pax = 1;
}
$days = ((($item->getDateOutAt())->diff($item->getDateInAt()))->days + 1);
$unitsServ = $item->getUnits();
if (empty($unitsServ) or $unitsServ == "0") {
$unitsServ = 1;
}
$subtotal = $subtotalService * $days * $unitsServ * $pax;
$subneto = $subneto * $days * $unitsServ * $pax;
break;
case 13: //Transport
$pax = $item->getPax();
if (empty($pax) or $pax == "0") {
$pax = 1;
}
$days = ((($item->getDateOutAt())->diff($item->getDateInAt()))->days + 1);
$unitsServ = $item->getUnits();
if (empty($unitsServ) or $unitsServ == "0") {
$unitsServ = 1;
}
$subtotal = $subtotalService * $days * $unitsServ * $pax;
$subneto = $subneto * $days * $unitsServ * $pax;
break;
case 14: //Technology
$pax = $item->getPax();
if (empty($pax) or $pax == "0") {
$pax = 1;
}
$days = 1;
$unitsServ = $item->getUnits();
if (empty($unitsServ) or $unitsServ == "0") {
$unitsServ = 1;
}
$subtotal = $subtotalService * $days * $unitsServ * $pax;
$subneto = $subneto * $days * $unitsServ * $pax;
break;
case 15: //Assisstant
$pax = $item->getPax();
if (empty($pax) or $pax == "0") {
$pax = 1;
}
$days = ((($item->getDateOutAt())->diff($item->getDateInAt()))->days + 1);
$unitsServ = $item->getUnits();
if (empty($unitsServ) or $unitsServ == "0") {
$unitsServ = 1;
}
$subtotalService = $subtotalService * $days * $unitsServ * $pax;
$subneto = $subneto * $days * $unitsServ * $pax;
break;
case 16: //DDR
$pax = $item->getPax();
if (empty($pax) or $pax == "0") {
$pax = 1;
}
$days = ((($item->getDateOutAt())->diff($item->getDateInAt()))->days + 1);
$unitsServ = $item->getUnits();
if (empty($unitsServ) or $unitsServ == "0") {
$unitsServ = 1;
}
$subtotal = $subtotalService * $days * $unitsServ * $pax;
$subneto = $subneto * $days * $unitsServ * $pax;
break;
default:
$pax = $item->getPax();
if (empty($pax) or $pax == "0") {
$pax = 1;
}
$days = ((($item->getDateOutAt())->diff($item->getDateInAt()))->days + 1);
$unitsServ = $item->getUnits();
if (empty($unitsServ) or $unitsServ == "0") {
$unitsServ = 1;
}
$subtotalService = $subtotalService * $days * $unitsServ * $pax;
$subneto = $subneto * $days * $unitsServ * $pax;
break;
}
// Over
if ($item->getOpOver() == '1') {
$subtotalService = $subtotalService + $item->getOver();
$subneto = $subneto + $item->getOver();
} else {
$subtotalService = $subtotalService - $item->getOver();
$subneto = $subneto - $item->getOver();
}
$itemIva = $item->getSageIva();
// IVA
if ($item->getOpIva() == '1') {
$subtotalService = ($reservaSucoe) ? $subtotalService : ($subtotalService * (1.21));
} else {
$subtotalService = $item->getPrice();
$subneto = ($reservaSucoe) ? $subneto : ($subneto * 100) / (121);
}
$subtotal += $subtotalService;
// Se lleva a 2 decimales round($totales_neto_antes,2,PHP_ROUND_HALF_UP),
$subtotal = round($subtotal, 2, PHP_ROUND_HALF_UP);
$neto = round($subneto, 2, PHP_ROUND_HALF_UP);
}
// Iva vacio se calcula al 21%
$ivaServ = ($reservaSucoe) ? 0 : $neto * 0.21;
if (!$reservaSucoe) { $data_iva['ivaMontoVeintiUno'] += $ivaServ; }
$totales_neto_all += $neto;
// Se lleva a 2 decimales round($totales_neto_antes,2,PHP_ROUND_HALF_UP)
$totales_neto_all = round($totales_neto_all, 2, PHP_ROUND_HALF_UP);
$data_iva['ivaMontoVeintiUno'] = round($data_iva['ivaMontoVeintiUno'], 2, PHP_ROUND_HALF_UP);
$data_iva['ivaMontoDiez'] = round($data_iva['ivaMontoDiez'], 2, PHP_ROUND_HALF_UP);
// Acumula netos totales e IVA
$service['neto'] += $neto;
$service['sumSubT'] += $subtotalService;
$service['sumIvas'] += $ivaServ;
// Se lleva a 2 decimales round($totales_neto_antes,2,PHP_ROUND_HALF_UP)
$service['neto'] = round($service['neto'], 2, PHP_ROUND_HALF_UP);
$service['sumSubT'] = round($service['sumSubT'], 2, PHP_ROUND_HALF_UP);
}
$data = array(
'totales_global_con_iva' => $reservationsLounge['sumSubT'],
'totales_global_iva' => $reservationsLounge['sumSubT'] - $reservationsLounge['neto'],
'totales_global_neto' => $reservationsLounge['neto'],
'totales_global_servicios_neto' => $service['neto'],
'totales_global_servicios_con_iva' => $service['sumSubT'],
'totales_global_servicios_iva' => $service['sumSubT'] - $service['neto'],
'sumatoria_totales_global_con_iva' => $reservationsLounge['sumSubT'] + $service['sumSubT'],
'sumatoria_totales_global_neto' => $reservationsLounge['neto'] + $service['neto'],
'sumatoria_totales_global_iva' => $reservationsLounge['sumSubT'] + $service['sumSubT'] - $reservationsLounge['neto'] - $service['neto'],
);
return $data;
}
/**
* @Route("/calendar/space/{id}", name="calendar_by_space")
*/
public function calendarBySpaceAction(int $id, Request $request, EntityManagerInterface $em): Response
{
$space = $em->getRepository(Space::class)->find($id);
if (!$space) {
throw $this->createNotFoundException('Espacio no encontrado');
}
$session = new Session();
$token = $session->get('tokenGoogleCalendar');
$connectGoogle = $token ? "1" : "0";
if ($token) {
$this->googleCalendar->setAccessToken($token);
}
$user = $this->get('security.token_storage')->getToken()->getUser();
return $this->render(
'MDS/VenuesBundle/calendar/calendar-space.html.twig',
[
'user' => $user->getId(),
'connectGoogle' => $connectGoogle,
'space' => $space,
]
);
}
/**
* Devuelve las RESERVAS (no visitas) para FullCalendar por espacio.
*
* FullCalendar le pasa ?start=...&end=... en ISO 8601.
*
* @Route("/calendar/space/{id}/reservations", name="calendar_reservations_by_space", methods={"GET"})
*/
public function calendarReservationsBySpace(int $id, Request $request, CalendarService $calendar): JsonResponse
{
$start = $request->query->get('start');
$end = $request->query->get('end');
$from = $start ? new \DateTimeImmutable($start) : new \DateTimeImmutable('first day of this month 00:00');
$to = $end ? new \DateTimeImmutable($end) : new \DateTimeImmutable('last day of next month 23:59');
$events = $calendar->getReservationsForCalendar(spaceId: $id, loungeId: null, from: $from, to: $to);
return new JsonResponse($events);
}
/**
* @Route("/calendar/events/space/{id}", name="calendar_events_by_space", methods={"GET"})
*/
public function calendarEventsBySpace(int $id, Request $request, CalendarService $calendar): JsonResponse
{
$start = $request->query->get('start');
$end = $request->query->get('end');
$from = $start ? new \DateTimeImmutable($start) : new \DateTimeImmutable('first day of this month 00:00');
$to = $end ? new \DateTimeImmutable($end) : new \DateTimeImmutable('last day of next month 23:59');
$events = $calendar->getVisitsForCalendar(spaceId: $id, loungeId: null, from: $from, to: $to);
return new JsonResponse($events);
}
/**
* @Route("/calendar/lounge/{id}", name="calendar_by_lounge", methods={"GET"})
*/
public function calendarByLoungeAction(int $id, Request $request, EntityManagerInterface $em): Response
{ {
$lounge = $em->getRepository(\App\MDS\VenuesBundle\Entity\ReservationLoungeDetails::class)->find($id);
if (!$lounge) {
$this->addFlash('danger', 'No se ha podido encontrar el calendario para esa sala.');
// Volver a la pantalla anterior si es del mismo host (evita open redirect)
$referer = $request->headers->get('referer');
if ($referer && parse_url($referer, PHP_URL_HOST) === $request->getHost()) {
return $this->redirect($referer);
}
// Fallback razonable (ajusta la ruta que prefieras)
return $this->redirectToRoute('app_space_index');
}
return $this->render('MDS/VenuesBundle/calendar/calendar-lounge.html.twig', [
'lounge' => $lounge,
'currentSpaceId' => $lounge->getSpace() ? $lounge->getSpace()->getId() : null,
]);
}
}
/**
* RESERVAS por sala (lounge)
* FullCalendar envía ?start=...&end=...
* Ojo con el prefijo /venues si tu controlador lo tiene a nivel de clase.
*
* @Route("/calendar/lounge/{id}/reservations", name="calendar_reservations_by_lounge", methods={"GET"})
*/
public function calendarReservationsByLounge(int $id, Request $request, CalendarService $calendar): JsonResponse
{
$start = $request->query->get('start');
$end = $request->query->get('end');
$from = $start ? new \DateTimeImmutable($start) : new \DateTimeImmutable('first day of this month 00:00');
$to = $end ? new \DateTimeImmutable($end) : new \DateTimeImmutable('last day of next month 23:59');
$events = $calendar->getReservationsForCalendar(spaceId: null, loungeId: $id, from: $from, to: $to);
return new JsonResponse($events);
}
/**
* @Route("/calendar/lounge/{id}/visits", name="calendar_visits_by_lounge", methods={"GET"})
*/
public function calendarEventsByLounge(int $id, Request $request, CalendarService $calendar): JsonResponse
{
$start = $request->query->get('start');
$end = $request->query->get('end');
$from = $start ? new \DateTimeImmutable($start) : new \DateTimeImmutable('first day of this month 00:00');
$to = $end ? new \DateTimeImmutable($end) : new \DateTimeImmutable('last day of next month 23:59');
$events = $calendar->getVisitsForCalendar(spaceId: null, loungeId: $id, from: $from, to: $to);
return new JsonResponse($events);
}
/**
* @Route("/calendar/events/all", name="calendar_events_all")
*/
public function allEvents(): Response
{
return $this->render('MDS/VenuesBundle/calendar/calendar-all.html.twig');
}
/**
* @Route("/calendar/events/visits", name="calendar_events_visits")
*/
public function visitsEventsAction(): Response
{
return $this->render('MDS/VenuesBundle/calendar/calendar-visits.html.twig');
}
/**
* @Route("/", name="reservations_venues")
*/
public function calendarReservationAction(Request $request)
{
// Enviar correos a los agentes de las reservas que se deban Cotizar
$this->notificacionReservasPorCotizar();
// Enviar correos a los agentes de las reservas que tienen depósitos pendientes por recibir
$this->notificacionReservasPendientesDelSegundoDepósito();
$session = new Session();
$token = $session->get('tokenGoogleCalendar');
if (!is_null($token)) {
$this->googleCalendar->setAccessToken($token);
$connectGoogle = "1";
} else {
$connectGoogle = "0";
}
$user_logueado = $this->get('security.token_storage')->getToken()->getUser();
$user_id = $user_logueado->getId();
$wnotes = new WidgetNotes();
$wnotes->setDateAt(new \DateTime("now"));
$form = $this->createWidgetNotesCreateForm($wnotes);
return $this->render(
'MDS/VenuesBundle/reservations/calendar-reservations.html.twig',
array(
'form' => $form->createView(),
'user' => $user_id,
'connectGoogle' => $connectGoogle,
)
);
}
private function createWidgetNotesCreateForm(WidgetNotes $entity)
{
$form = $this->createForm(WidgetNotesType::class, $entity, array(
'action' => $this->generateUrl('widget_notes_calendar_create'),
'method' => 'POST'
));
return $form;
}
/**
* @Route("/widget/notes/calendar/create/", name="widget_notes_calendar_create")
*/
public function addNotesAction(EntityManagerInterface $em, Request $request, LoggerInterface $logger)
{
$notes = $em->getRepository(WidgetNotes::class)->findAll();
$wnotes = new WidgetNotes();
$form = $this->createWidgetNotesCreateForm($wnotes);
$form->handleRequest($request);
$forAgent = $form->get('forAgent')->getData();
if (!is_null($forAgent)) {
$wnotes->setForAgent($forAgent->getId());
}
if ($form->isValid()) {
/* Obtengo usuario logueado */
$user_logueado = $this->get('security.token_storage')->getToken()->getUser();
$user_id = $user_logueado->getId();
$wnotes->setCreatedId($user_id);
$wnotes->setUpdatedId($user_id);
/* Gestión de eventos en Log */
$user_lastname = $user_logueado->getLastname();
$user_name = $user_logueado->getName();
$user_email = $user_logueado->getEmail();
$user_rol = $user_logueado->getRoles();
$event_url = $request->getPathInfo();
$event_complete = $user_name . ' ' . $user_lastname . ' - ' . $user_email . ' - ' . $user_rol[0] . ' | ' . $event_url;
try {
$em->persist($wnotes);
$em->flush();
$event = 'The Note has been created succesfully.';
$successMessage = $this->translator->trans($event);
$this->addFlash('mensaje', $successMessage);
$logger->info($event_complete . ' | ' . $event);
} catch (\Exception $e) {
$event = 'An error occurred: ' . $e->getMessage();
/* Para el log */
$logger->error($event_complete . ' | ' . $event);
/* Para el usuario */
$errorMessage = $this->translator->trans($event);
$this->addFlash('mensajeerror', $errorMessage);
}
/* Fin Gestión de eventos en Log */
} else {
$errorMessage = $this->translator->trans('Error, some fields are empty');
$this->addFlash('mensajeerror', $errorMessage);
}
return $this->redirectToRoute('homepage');
}
/**
* @Route("/list/", defaults={"idgroup" = 0}, name="reservations_venues_index")
*/
public function indexAction($idgroup, EntityManagerInterface $em, Request $request)
{
return $this->render('MDS/VenuesBundle/reservations/list-reservations.html.twig', [
'groups' => null,
'type' => 'list',
'titleView' => '',
'reservations' => [], // DataTables will load data
'dataUrl' => $this->generateUrl('reservations_venues_data', ['idgroup' => $idgroup]),
]);
}
/**
* @Route("/list/space/{idspace}", name="reservations_venues_space_index")
*/
public function indexSpaceAction(int $idspace, EntityManagerInterface $em)
{
$space = $em->getRepository(Space::class)->find($idspace);
if (!$space) {
throw $this->createNotFoundException('Espacio no encontrado');
}
return $this->render('MDS/VenuesBundle/reservations/list-reservations.html.twig', [
'groups' => null,
'type' => 'space',
'titleView' => ' de ' . $space->getName(),
'reservations' => [], // DataTables will load data
'dataUrl' => $this->generateUrl('reservations_venues_space_data', ['idspace' => $idspace]),
]);
}
/**
* @Route("/list/data/{idgroup}", defaults={"idgroup" = 0}, name="reservations_venues_data", methods={"POST", "GET"})
*/
public function dataAction($idgroup, Request $request, EntityManagerInterface $em): JsonResponse
{
/** @var \App\MDS\VenuesBundle\Repository\ReservationRepository $repo */
$repo = $em->getRepository(Reservation::class);
// Fetch ALL data
$result = $repo->findDataTablesData();
return new JsonResponse(['data' => $this->formatDataTablesData($result)]);
}
/**
* @Route("/list/space/data/{idspace}", name="reservations_venues_space_data", methods={"POST", "GET"})
*/
public function dataSpaceAction(int $idspace, Request $request, EntityManagerInterface $em): JsonResponse
{
/** @var \App\MDS\VenuesBundle\Repository\ReservationRepository $repo */
$repo = $em->getRepository(Reservation::class);
// Fetch data filtered by Space
$result = $repo->findDataTablesData($idspace);
return new JsonResponse(['data' => $this->formatDataTablesData($result)]);
}
/**
* Auxiliar para formatear datos de DataTables (DRY)
*/
private function formatDataTablesData(array $result): array
{
$data = [];
foreach ($result as $row) {
// Helper for Date formatting
$fmtDate = function ($d) {
return $d instanceof \DateTimeInterface ? $d->format('d/m/Y') : '';
};
$fmtYMD = function ($d) {
return $d instanceof \DateTimeInterface ? $d->format('Y/m/d') : '';
};
$getTimestamp = function ($d) {
return $d instanceof \DateTimeInterface ? $d->getTimestamp() : 0;
};
// Date Start Logic
$dateStartDisplay = $fmtDate($row['dateStart']);
$dateStartTimestamp = $getTimestamp($row['dateStart']);
if ($row['dateStart'] instanceof \DateTimeInterface && $fmtYMD($row['dateStart']) === '2078/01/01') {
$dateStartDisplay = 'SIN ASIGNAR';
$dateStartTimestamp = 0;
}
// Date End Logic
$dateEndDisplay = $fmtDate($row['dateEnd']);
$dateEndTimestamp = $getTimestamp($row['dateEnd']);
if ($row['dateEnd'] instanceof \DateTimeInterface && $fmtYMD($row['dateEnd']) === '2000/01/01') {
$dateEndDisplay = 'SIN ASIGNAR';
$dateEndTimestamp = 0;
}
$statusLabel = match ($row['status']) {
'Bloqueo' => 'BLOQUEO',
'Confirmed' => 'CONFIRMADO',
'Invoiced' => 'FACTURADO',
'Cotizado' => 'COTIZADO',
'Deleted' => 'CANCELADO',
default => 'INICIADO',
};
$actions = '<div class="btn-group">
<a href="/venues/edit/' . $row['id'] . '" class="btn btn-sm bg-btn-vivid_sky_blue">
<i class="glyphicon glyphicon-pencil"></i>
</a>
<a href="/venues/delete/' . $row['id'] . '" class="btn btn-sm bg-btn-trash">
<i class="glyphicon glyphicon-trash"></i>
</a>
</div>';
$data[] = [
'createdAt' => [
'display' => $fmtDate($row['createdAt']),
'timestamp' => $getTimestamp($row['createdAt'])
],
'id' => $row['id'],
'dateStart' => [
'display' => $dateStartDisplay,
'timestamp' => $dateStartTimestamp
],
'dateEnd' => [
'display' => $dateEndDisplay,
'timestamp' => $dateEndTimestamp
],
'title' => $row['title'],
'client' => $row['clientName'],
'createdBy' => $row['creatorName'],
'status' => $statusLabel,
'actions' => $actions
];
}
return $data;
}
/**
* @Route("/listcanceled/{idgroup}", defaults={"idgroup" = 0}, name="reservations_canceled")
*/
public function indexCanceledAction(EntityManagerInterface $em, $idgroup, Request $request)
{
return $this->render(
'MDS/VenuesBundle/reservations/list-reservations.html.twig',
array(
'groups' => null,
'type' => 'canceled',
'titleView' => ' Canceladas',
'reservations' => [],
'dataUrl' => $this->generateUrl('reservations_canceled_data', ['idgroup' => $idgroup])
)
);
}
/**
* @Route("/list/canceled/data/{idgroup}", defaults={"idgroup" = 0}, name="reservations_canceled_data", methods={"POST", "GET"})
*/
public function canceledDataAction($idgroup, Request $request, EntityManagerInterface $em): JsonResponse
{
/** @var \App\MDS\VenuesBundle\Repository\ReservationRepository $repo */
$repo = $em->getRepository(Reservation::class);
// Fetch ALL data (Client-side handling)
$result = $repo->findDataTablesCanceledData();
$data = [];
foreach ($result as $row) {
// Helper for Date formatting
$fmtDate = function ($d) {
return $d instanceof \DateTimeInterface ? $d->format('d/m/Y') : '';
};
$fmtYMD = function ($d) {
return $d instanceof \DateTimeInterface ? $d->format('Y/m/d') : '';
};
$getTimestamp = function ($d) {
return $d instanceof \DateTimeInterface ? $d->getTimestamp() : 0;
};
// Date Start Logic
$dateStartDisplay = $fmtDate($row['dateStart']);
$dateStartTimestamp = $getTimestamp($row['dateStart']);
if ($row['dateStart'] instanceof \DateTimeInterface && $fmtYMD($row['dateStart']) === '2078/01/01') {
$dateStartDisplay = 'SIN ASIGNAR';
$dateStartTimestamp = 0;
}
// Date End Logic
$dateEndDisplay = $fmtDate($row['dateEnd']);
$dateEndTimestamp = $getTimestamp($row['dateEnd']);
if ($row['dateEnd'] instanceof \DateTimeInterface && $fmtYMD($row['dateEnd']) === '2000/01/01') {
$dateEndDisplay = 'SIN ASIGNAR';
$dateEndTimestamp = 0;
}
// Status is always Deleted
$statusLabel = 'CANCELADO';
$actions = '<div class="btn-group">
<a href="/venues/edit/' . $row['id'] . '" class="btn btn-sm bg-btn-vivid_sky_blue">
<i class="glyphicon glyphicon-pencil"></i>
</a>
<a href="/venues/delete/' . $row['id'] . '" class="btn btn-sm bg-btn-trash">
<i class="glyphicon glyphicon-trash"></i>
</a>
</div>';
$data[] = [
'createdAt' => [
'display' => $fmtDate($row['createdAt']),
'timestamp' => $getTimestamp($row['createdAt'])
],
'id' => $row['id'],
'dateStart' => [
'display' => $dateStartDisplay,
'timestamp' => $dateStartTimestamp
],
'dateEnd' => [
'display' => $dateEndDisplay,
'timestamp' => $dateEndTimestamp
],
'title' => $row['title'],
'client' => $row['clientName'],
'createdBy' => $row['creatorName'],
'status' => $statusLabel,
'actions' => $actions
];
}
return new JsonResponse(['data' => $data]);
}
/**
* @Route("/listquoted/{idgroup}", defaults={"idgroup" = 0}, name="reservations_quoted")
*/
public function indexQuotedAction(EntityManagerInterface $em, $idgroup, Request $request)
{
$parameters = array('status' => 'Cotizado');
$dql = 'SELECT i
FROM VenuesBundle:Reservation i
WHERE i.status = :status
ORDER BY i.createdAt ASC';
$query = $em->createQuery($dql)->setParameters($parameters);
$ref = array();
$reservas = $query->getResult();
foreach ($reservas as $res) {
$client = $em->getRepository(Client::class)->findOneById($res->getClient());
if (!empty($client)) {
$res->setClient($client->getName());
} else {
$res->setClient(null);
}
$res->setCreatedBy(
($em->getRepository(User::class)->findOneById($res->getCreatedBy()))->getName() . ' ' .
($em->getRepository(User::class)->findOneById($res->getCreatedBy()))->getLastName()
);
$ref[$res->getId()] = '#' . ($res->getCreatedAt())->format('ymdHi');
}
$reservasZero = array();
foreach ($reservas as $res) {
$data = $this->CalculosTotalesEditSimple($res->getId());
$reservasZero[] = array(
'dateStart' => $res->getDateStart(),
'dateEnd' => $res->getDateEnd(),
'id' => $res->getId(),
'title' => $res->getTitle(),
'client' => $res->getClient(),
'sales' => $data['sumatoria_totales_global_con_iva'],
'ref' => $ref[$res->getId()],
'createdAt' => $res->getCreatedAt(),
);
}
$reservas = $reservasZero;
return $this->render(
'MDS/VenuesBundle/reservations/list-reservations-quotation.html.twig',
array(
'groups' => null,
'titleView' => ' Cotizadas',
'reservations' => $reservas
)
);
}
/**
* @Route("/edit/{id}", name="reservations_venues_edit")
*/
public function editAction($id)
{
return $this->redirectToRoute('reservations_venues_edit_simple', array('id' => $id, 'token' => null));
}
private function createEditReservationsForm(Reservation $entity, $id)
{
$form = $this->createForm(ReservationType::class, $entity, array('action' => $this->generateUrl('reservations_update', array('id' => $id)), 'method' => 'PUT'));
return $form;
}
/**
* @Route("/update/{id}", name="reservations_update")
*/
public function update(int $id, Request $request, EntityManagerInterface $em, Security $security, TranslatorInterface $translator, DocContractService $docContractService): Response
{
$reserva = $em->getRepository(Reservation::class)->find($id);
// --- 1. ELIMINADO EL DD($request) PARA QUE EJECUTE EL GUARDADO ---
if (!$reserva) {
throw $this->createNotFoundException('Reserva no encontrada');
}
// 1. Guardar estados previos necesarios para lógica de negocio
$oldPriority = $reserva->getPriority();
$oldStatus = $reserva->getStatus();
$user = $security->getUser();
// 2. Crear formulario pasando las opciones necesarias
$invoiceRepository = $em->getRepository(ReservationInvoice::class);
$invoiceRecRepository = $em->getRepository(ReservationInvoiceRec::class);
$hasInvoices = !empty($invoiceRepository->findByReservationId($id)) || !empty($invoiceRecRepository->findByReservationId($id));
$form = $this->createForm(ReservationType::class, $reserva, [
'confirmable' => $this->laReservaEsConfirmable($id),
'cotizable' => $this->laReservaEsCotizable($id),
'invoiced' => $hasInvoices,
]);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
/** @var Reservation $reserva */
$reserva = $form->getData();
$now = new \DateTime();
// 3. Auditoría básica
$reserva->setUpdatedBy($user->getId());
$reserva->setUpdatedAt($now);
// 4. Lógica de Prioridad
if ($this->isGranted('ROLE_USER') && !$this->isGranted('ROLE_ADMIN')) {
$reserva->setPriority($oldPriority);
}
if (!$reserva->getPriority()) {
$reserva->setPriority(1);
}
// 5. Manejo de Contacto No Registrado
// ESTA FUNCIÓN ES LA QUE GUARDA EN BASE DE DATOS EL CONTACTO NUEVO
$this->handleUnregisteredContact($form, $reserva, $user, $em);
// 6. Manejo de Status "Bloqueo"
$newStatusFromForm = $reserva->getStatus();
$this->handleBlockStatus($form, $reserva, $user, $em);
// 7. Verificación final de Status
$verifiedStatus = $this->verificarStatusInicialyFinal($id, $user->getId(), $oldStatus, $newStatusFromForm);
$reserva->setStatus($verifiedStatus);
// 8. Lógica de Cancelación
if ($verifiedStatus === 'Deleted' && $verifiedStatus !== 'Bloqueo') {
$this->handleCancellationAlert($id, $reserva, $em);
}
// 9. Recalcular fechas
$this->reservationService->updateReservationDates($reserva);
// 10. Valores por defecto
if (!$reserva->getStatus()) {
$reserva->setStatus('Cotizado');
}
try {
$em->persist($reserva);
$em->flush();
$this->addFlash('mensajereservation', 'La reserva ha sido actualizada.');
// --- ACTUALIZACIÓN DE LA AGENDA ---
$agendaLineTitle = $em->getRepository(ReservationAgendaItem::class)->findBy(array('reservationId' => $reserva->getId(), 'sourceType' => 'Reservation'));
$user = $this->getUser();
if (empty($agendaLineTitle)) {
// Creamos la linea
$newItem = new ReservationAgendaItem();
$newItem->setReservationId($id);
$newItem->setRankListing(1);
$newItem->setTitleOne('EVENTO: ' . $reserva->getTitle());
$newItem->setTitleTwo(null);
$newItem->setTitleThree(null);
$newItem->setDescription('.');
$newItem->setSourceId($id);
$newItem->setSourceType('Reservation');
$newItem->setCreatedId($user->getId());
$newItem->setUpdatedId($user->getId());
$newItem->setCreatedAt(new \DateTime());
$newItem->setUpdatedAt(new \DateTime());
$this->repository->add($newItem, true);
} else {
// Actualizamos la linea
$agendaLineTitle[0]->setTitleOne('EVENTO: ' . $reserva->getTitle());
$agendaLineTitle[0]->setUpdatedId($user->getId());
$agendaLineTitle[0]->setUpdatedAt(new \DateTime());
$this->repository->add($agendaLineTitle[0], true);
}
// --- CORRECCIÓN IMPORTANTE AQUÍ ---
// Leemos los datos DEL FORMULARIO, no de la entidad reserva,
// porque son campos mapped => false
$nameUnreg = $form->get('nameContactUnregistered')->getData();
$phoneUnreg = $form->get('phoneContactUnregistered')->getData();
$emailUnreg = $form->get('contactUnregistered')->getData();
$contactString = '';
if (!empty($nameUnreg)) {
$contactString .= $nameUnreg;
} else {
$contactString .= 'No se pudo determinar el nombre';
}
if (!empty($phoneUnreg)) {
$contactString .= ' / ' . $phoneUnreg;
} else {
$contactString .= ' / No se pudo determinar el teléfono';
}
if (!empty($emailUnreg)) {
$contactString .= ' / ' . $emailUnreg;
} else {
$contactString .= ' / No se pudo determinar el email';
}
$agenda = $this->agendaService->updateClientContactLine($reserva->getId(), $contactString, $user->getId());
// ----------------------------------
// 11. Redirecciones especiales post-guardado
if ($verifiedStatus === 'Confirmed') {
$this->_actualizarSalasYServicios($reserva);
// Asignación automática de contratos
$docContractService->autoAssignContracts($reserva, $user);
if ($verifiedStatus !== $oldStatus) {
return $this->redirectToRoute('reservations_venues_send_confirmation_request_mail', ['id' => $id]);
}
}
$this->_actualizarSalasYServicios($reserva);
return $this->redirectToRoute('reservations_venues_edit_simple', ['id' => $id, 'token' => null]);
} catch (\Exception $e) {
$this->addFlash('mensajereservationerror', $translator->trans('An error occurred: ' . $e->getMessage()));
}
}
return $this->redirectToRoute('reservations_venues_edit_simple', ['id' => $id, 'token' => null]);
}
/**
* @Route("/delete/{id}", name="reservations_delete")
*/
public function deleteAction($id, EntityManagerInterface $em, Request $request)
{
$reserva = $em->getRepository(Reservation::class)->findOneById($id);
$hoy = new \DateTime("now", NULL);
$user_logueado = $this->get('security.token_storage')->getToken()->getUser();
$user_id = $user_logueado->getId();
$reserva->setUpdatedBy($user_id);
$reserva->setUpdatedAt($hoy);
$reserva->setStatus('Deleted');
try {
$em->persist($reserva);
$em->flush();
$successMessage = 'La reserva ha sido actualizada.';
// $successMessage = $this->translator->trans($event);
$this->addFlash('mensajereservation', $successMessage);
} catch (\Exception $e) {
$event = 'An error occurred: ' . $e->getMessage();
$errorMessage = $this->translator->trans($event);
$this->addFlash('mensajereservationerror', $errorMessage);
}
return $this->redirectToRoute('reservations_venues_index');
}
/**
* @Route("/listgpprices", name="reservations_venues_prices")
*/
public function indexPricesAction(EntityManagerInterface $em, Request $request)
{
$prices = $em->getRepository(ReservationLoungeProfile::class)->findBy(
array(),
array('id' => 'ASC')
);
$data = [];
foreach ($prices as $price) {
$periodSql = $em->getRepository(ReservationPeriod::class)->findOneById($price->getPeriodId());
$price->setPeriodId($periodSql->getName());
$reservationsLoungeTemp = $em->getRepository(ReservationLoungeDetails::class)->findOneById($price->getLoungeId());
if (!is_null($reservationsLoungeTemp)) {
$price->setLoungeId($reservationsLoungeTemp->getName());
}
$data[] = $price;
}
$reserv = new ReservationLoungeProfile();
$form = $this->createReservationLoungeProfileCreateForm($reserv);
return $this->render(
'MDS/VenuesBundle/reservations/list-reservations-gp-prices.html.twig',
array(
'groups' => null,
'prices' => $data,
'form' => $form->createView()
)
);
}
/**
* @Route("/deletegpprice/{id}", name="reservations_price_delete")
*/
public function deletePriceAction($id, EntityManagerInterface $em, Request $request)
{
$price = $em->getRepository(ReservationLoungeProfile::class)->findOneById($id);
try {
$em->remove($price);
$em->flush();
$event = 'The Item has been Deleted.';
$successMessage = $this->translator->trans($event);
$this->addFlash('mensajereservation', $successMessage);
} catch (\Exception $e) {
$event = 'An error occurred: ' . $e->getMessage();
/* Para el usuario */
$errorMessage = $this->translator->trans($event);
$this->addFlash('mensajereservationerror', $errorMessage);
}
return $this->redirectToRoute('reservations_venues_prices');
}
/**
* @Route("/addgpprice/", name="reservations_venues_addgpprice")
*/
public function addReservationGpPriceAction(EntityManagerInterface $em, Request $request)
{
$reserv = new ReservationLoungeProfile();
$form = $this->createReservationLoungeProfileCreateForm($reserv);
$gpPrices = $em->getRepository(ReservationLoungeProfile::class)->findAll();
return $this->render('MDS/VenuesBundle/reservations/add-reservations-gp-price.html.twig', array('form' => $form->createView(), 'gpPrices' => $gpPrices));
}
private function createReservationLoungeProfileCreateForm(ReservationLoungeProfile $entity)
{
$form = $this->createForm(ReservationLoungeProfileType::class, $entity, array(
'action' => $this->generateUrl('reservations_venues_price_create'),
'method' => 'POST'
));
return $form;
}
/**
* @Route("/creategpprice", name="reservations_venues_price_create")
*/
public function createGpPriceAction(EntityManagerInterface $em, Request $request)
{
$reservaGpPrice = new ReservationLoungeProfile();
$form = $this->createReservationLoungeProfileCreateForm($reservaGpPrice);
$form->handleRequest($request);
$user_logueado = $this->get('security.token_storage')->getToken()->getUser();
$user_id = $user_logueado->getId();
$hoy = new \DateTime("now", NULL);
$reservaGpPrice->setCreatedAt($hoy);
$reservaGpPrice->setCreatedId($user_id);
$reservaGpPrice->setUpdatedAt($hoy);
$reservaGpPrice->setUpdatedId($user_id);
$periodSql = $em->getRepository(ReservationPeriod::class)->findOneById($form->get('periodId')->getData());
if (!empty($periodSql)) {
$descTemp = $periodSql->getName();
} else {
$descTemp = null;
}
$reservaGpPrice->setPeriodId($reservaGpPrice->getPeriodId()->getId());
$reservaGpPrice->setLoungeId($reservaGpPrice->getLoungeId()->getId());
if ((!is_null($reservaGpPrice->getLoungeId())) and (!is_null($descTemp))) {
$descriptionSql = $em->getRepository(ReservationLoungeDetails::class)->findOneById($form->get('loungeId')->getData());
$description = $descriptionSql->getName() . ' - ' . $descTemp;
$reservaGpPrice->setDescription($description);
} else {
$reservaGpPrice->setDescription(null);
}
if ($form->isValid()) {
try {
$em->persist($reservaGpPrice);
$em->flush();
$event = 'The Item Price has been created.';
$successMessage = $this->translator->trans($event);
$this->addFlash('mensajereservation', $successMessage);
} catch (\Exception $e) {
$event = 'An error occurred: ' . $e->getMessage();
$errorMessage = $this->translator->trans($event);
$this->addFlash('mensajereservationerror', $errorMessage);
}
} else {
$errorMessage = $this->translator->trans('Error, some fields are empty');
$this->addFlash('mensajereservationerror', $errorMessage);
}
return $this->redirectToRoute('reservations_venues_prices');
}
/**
* @Route("/getReservationLoungeProfile", name="get_reservation_lounge_profile")
*/
public function getReservationLoungeProfileAction(EntityManagerInterface $em, Request $request)
{
$codProfile = $_POST['idprofile'];
$salasPorPerfil = $em->getRepository(ReservationLoungeProfile::class)->findBy(array('periodId' => $codProfile));
$datos = [];
if (!empty($salasPorPerfil)) {
foreach ($salasPorPerfil as $sala) {
$datos[] = array(
"id" => $sala->getId(),
"idlounge" => $sala->getLoungeId(),
"nameDescription" => $sala->getDescription(),
"price" => $sala->getPrice(),
);
}
}
$return = array('salasPerfil' => $datos, 'id' => $codProfile, );
$response = new JsonResponse($return);
return $response;
}
/**
* @Route("/getReservationPeriod", name="get_reservation_Period")
*/
public function getReservationPeriodAction(EntityManagerInterface $em, Request $request)
{
$id = $_POST['id'];
$period = $em->getRepository(ReservationPeriod::class)->findOneById($id);
$datos = array();
if (!empty($period)) {
$datos = array(
"id" => $period->getId(),
"hourStart" => is_null($period->getHourStart()) ? "" : $period->getHourStart()->format('H:i'),
"hourEnd" => is_null($period->getHourEnd()) ? "" : $period->getHourEnd()->format('H:i'),
);
}
$return = $datos;
$response = new JsonResponse($return);
return $response;
}
/**
* @Route("/getReservationLoungePrice", name="get_reservation_lounge_price")
*/
public function getReservationLoungePriceAction(EntityManagerInterface $em, Request $request)
{
$id = $_POST['id'];
$precio = $em->getRepository(ReservationLoungeProfile::class)->findOneById($id);
$datos = array();
if (!empty($precio)) {
$datos = array("id" => $precio->getId(), "price" => $precio->getPrice());
}
$return = $datos;
$response = new JsonResponse($return);
return $response;
}
/**
* @Route("/addloungedetails/", name="reservations_venues_addloungedetails")
*/
public function addReservationLoungeDetailsAction(Request $request)
{
$reservationsLounge = new ReservationLoungeDetails();
$form = $this->createReservationLoungeDetailsCreateForm($reservationsLounge);
return $this->render('MDS/VenuesBundle/reservations/add-reservations-lounge-details.html.twig', array('form' => $form->createView()));
}
private function createReservationLoungeDetailsCreateForm(ReservationLoungeDetails $entity)
{
$form = $this->createForm(ReservationLoungeDetailsType::class, $entity, array(
'action' => $this->generateUrl('reservations_venues_lounge_details_create'),
'method' => 'POST'
));
return $form;
}
/**
* @Route("/createloungedetails", name="reservations_venues_lounge_details_create")
*/
public function createLoungeDetailsAction(EntityManagerInterface $em, Request $request)
{
$reservationsLounge = new ReservationLoungeDetails();
$form = $this->createReservationLoungeDetailsCreateForm($reservationsLounge);
$form->handleRequest($request);
/* Obtengo usuario logueado */
$user_logueado = $this->get('security.token_storage')->getToken()->getUser();
$user_id = $user_logueado->getId();
$hoy = new \DateTime("now", NULL);
$reservationsLounge->setCreatedAt($hoy);
$reservationsLounge->setCreatedId($user_id);
$reservationsLounge->setUpdatedAt($hoy);
$reservationsLounge->setUpdatedId($user_id);
if ($form->isValid()) {
try {
$em->persist($reservationsLounge);
$em->flush();
$event = 'The Lounge has been created.';
$successMessage = $this->translator->trans($event);
$this->addFlash('mensajereservation', $successMessage);
$this->reordenarSalas($reservationsLounge->getRankLounge(), $reservationsLounge->getId());
} catch (\Exception $e) {
$event = 'An error occurred: ' . $e->getMessage();
/* Para el usuario */
$errorMessage = $this->translator->trans($event);
$this->addFlash('mensajereservationerror', $errorMessage);
}
} else {
$errorMessage = $this->translator->trans('Error, some fields are empty');
$this->addFlash('mensajereservationerror', $errorMessage);
}
return $this->redirectToRoute('reservations_venues_list_lounges');
}
/**
* @Route("/listloungedetails", name="reservations_venues_list_lounges")
*/
public function indexLoungesAction(EntityManagerInterface $em, Request $request)
{
$salas = $em->getRepository(ReservationLoungeDetails::class)->findAll();
$reservationsLounge = new ReservationLoungeDetails();
$form = $this->createReservationLoungeDetailsCreateForm($reservationsLounge);
return $this->render(
'MDS/VenuesBundle/reservations/list-reservations-lounges-details.html.twig',
array(
'groups' => null,
'salas' => $salas,
'form' => $form->createView()
)
);
}
/**
* @Route("/editloungedetails/{id}", name="reservations_lounge_details")
*/
public function editLoungeDetailsAction($id, EntityManagerInterface $em, Request $request)
{
$reservationsLounge = $em->getRepository(ReservationLoungeDetails::class)->findOneById($id);
$reservationsLoungePictures = $em->getRepository(ReservationLoungePicture::class)->findBy(array('loungeId' => $id, 'title' => null, ));
$reservationsLoungeVideos = $em->getRepository(ReservationLoungeVideo::class)->findByLoungeId($id);
$reservationsLoungeDescriptions = $em->getRepository(ReservationLoungeDescription::class)->findByLoungeId($id);
$reservationsLoungeWebDescriptions = $em->getRepository(ReservationLoungeWebDescription::class)->findByLounge($reservationsLounge);
$descriptionsByLanguage = [];
foreach ($reservationsLoungeWebDescriptions as $description) {
$descriptionsByLanguage[$description->getLanguage()] = $description;
}
/* Obtengo usuario logueado */
$user_logueado = $this->get('security.token_storage')->getToken()->getUser();
$user_id = $user_logueado->getId();
/* Gestión de eventos en Log */
$user_lastname = $user_logueado->getLastname();
$user_name = $user_logueado->getName();
$user_email = $user_logueado->getEmail();
$user_rol = $user_logueado->getRoles();
$event_url = $request->getPathInfo();
$event_complete = $user_name . ' ' . $user_lastname . ' - ' . $user_email . ' - ' . $user_rol[0] . ' | ' . $event_url;
$hoy = new \DateTime("now", NULL);
$form = $this->createEditReservationLoungeDetailsForm($reservationsLounge, $id);
// Para evitar le duplicidad de idiomas en las descripciones
$reservationsLoungeDescriptionsPreexistentes = $em->getRepository(ReservationLoungeDescription::class)->findByLoungeId($id);
$idiomasPreexistentes = array();
foreach ($reservationsLoungeDescriptionsPreexistentes as $item) {
$idiomasPreexistentes[] = $item->getLanguage();
}
$datos_videos = array();
foreach ($reservationsLoungeVideos as $video) {
$urvideo_final = '<iframe class="embed-responsive-item" src="' . $video->getVideo() . '"></iframe>';
$datos_videos[] = array(
'id' => $video->getId(),
'urlvideo' => $urvideo_final
);
}
$blueprints = $em->getRepository(ReservationLoungePicture::class)->findBy(array('loungeId' => $id, 'title' => 'Blueprint', ));
$pictTeatro = $em->getRepository(ReservationLoungePicture::class)->findBy(array('loungeId' => $id, 'title' => 'Teatro', ));
if (sizeof($pictTeatro) == 0) {
$pictTeatro = null;
}
$pictCoctel = $em->getRepository(ReservationLoungePicture::class)->findBy(array('loungeId' => $id, 'title' => 'Coctel', ));
if (sizeof($pictCoctel) == 0) {
$pictCoctel = null;
}
$pictEscuela = $em->getRepository(ReservationLoungePicture::class)->findBy(array('loungeId' => $id, 'title' => 'Escuela', ));
if (sizeof($pictEscuela) == 0) {
$pictEscuela = null;
}
$picsMontaje = array(
'pictTeatro' => $pictTeatro,
'pictCoctel' => $pictCoctel,
'pictEscuela' => $pictEscuela
);
if (empty($picsMontaje['pictTeatro']) and empty($picsMontaje['pictCoctel']) and empty($picsMontaje['pictEscuela'])) {
$picsMontaje = null;
}
$reservationsLoungedimmensions = $em->getRepository(ReservationLoungeDetails::class)->findOneById($id);
return $this->render(
'MDS/VenuesBundle/reservations/edit-reservations-lounge-details.html.twig',
array(
'id' => $id,
'hoy' => $hoy,
'lounge' => $reservationsLounge,
'descriptions' => $reservationsLoungeDescriptions,
'loungeWebDesctiptions' => $descriptionsByLanguage,
'languagesWeb' => LanguageConstants::getAvailableLanguages(),
'pictures' => $reservationsLoungePictures,
'blueprints' => $blueprints,
'picsMontaje' => $picsMontaje,
'loungedimmensions' => $reservationsLoungedimmensions,
'videos' => $datos_videos,
'idiomasPreexistentes' => $idiomasPreexistentes,
'form' => $form->createView()
)
);
}
private function createEditReservationLoungeDetailsForm(ReservationLoungeDetails $entity, $id)
{
$form = $this->createForm(
ReservationLoungeDetailsType::class,
$entity,
array(
'action' => $this->generateUrl(
'reservations_lounge_details_update',
array(
'id' => $id,
'price' => $entity
)
),
'method' => 'PUT'
)
);
return $form;
}
/**
* @Route("/updateloungedetails/{id}", name="reservations_lounge_details_update")
*/
public function updateLoungeDetailsAction($id, Request $request)
{
$em = $this->getDoctrine()->getManager();
$reservationsLounge = $em->getRepository(ReservationLoungeDetails::class)->findOneById($id);
$reservationsLounge->setName($request->request->get('mds_venuesbundle_reservationloungedetails')['name']);
$preNumber = $reservationsLounge->getRankLounge();
$postNumber = $request->request->get('mds_venuesbundle_reservationloungedetails')['rankLounge'];
$hoy = new \DateTime("now", NULL);
$form = $this->createEditReservationLoungeDetailsForm($reservationsLounge, $id);
$form->handleRequest($request);
if ($form->isValid()) {
/* Obtengo usuario logueado */
$user_logueado = $this->get('security.token_storage')->getToken()->getUser();
$user_id = $user_logueado->getId();
/* Gestión de eventos en Log */
$user_lastname = $user_logueado->getLastname();
$user_name = $user_logueado->getName();
$user_email = $user_logueado->getEmail();
$user_rol = $user_logueado->getRoles();
$event_url = $request->getPathInfo();
$event_complete = $user_name . ' ' . $user_lastname . ' - ' . $user_email . ' - ' . $user_rol[0] . ' | ' . $event_url;
$reservationsLounge->setUpdatedId($user_id);
$reservationsLounge->setUpdatedAt($hoy);
try {
// Reordenar salas si se ha cambiado el rank number de la sala
if (!($preNumber == $postNumber)) {
$this->reordenarSalas($postNumber, $reservationsLounge->getId());
}
$em->persist($reservationsLounge);
$em->flush();
$event = 'The lounge has been Updated. Now';
$successMessage = $this->translator->trans($event);
$this->addFlash('mensajereservation', $successMessage);
} catch (\Exception $e) {
$event = 'An error occurred: ' . $e->getMessage();
/* Para el usuario */
$errorMessage = $this->translator->trans($event);
$this->addFlash('mensajereservationerror', $errorMessage);
}
/* Fin Gestión de eventos en Log */
return $this->redirectToRoute('reservations_venues_list_lounges');
} else {
$errorMessage = $this->translator->trans('Error, some fields are empty');
$this->addFlash('mensajereservationerror', $errorMessage);
}
return $this->render(
'MDS/VenuesBundle/reservations/edit-reservations-lounge-details.html.twig',
array(
'id' => $reservationsLounge->getId(),
'lounge' => $reservationsLounge,
'form' => $form->createView()
)
);
}
/**
* @Route("/deleteloungedetails/{id}", name="reservations_lounge_details_delete")
*/
public function deleteLoungeDetailsAction($id, EntityManagerInterface $em, Request $request)
{
$reservationsLounge = $em->getRepository(ReservationLoungeDetails::class)->findOneById($id);
try {
$em->remove($reservationsLounge);
$em->flush();
// INICIO: Eliminamos los precios asociados a la sala
$profiles = $em->getRepository(ReservationLoungeProfile::class)->findByLoungeId($id);
foreach ($profiles as $item) {
$em->remove($item);
$em->flush();
}
// FIN: Eliminamos los precios asociados a la sala
$event = 'The Reservation has been Deleted. Now';
$successMessage = $this->translator->trans($event);
$this->addFlash('mensajereservation', $successMessage);
} catch (\Exception $e) {
$event = 'An error occurred: ' . $e->getMessage();
/* Para el usuario */
$errorMessage = $this->translator->trans($event);
$this->addFlash('mensajereservationerror', $errorMessage);
}
/* Fin Gestión de eventos en Log */
return $this->redirectToRoute('reservations_venues_list_lounges');
}
/**
* @Route("/deleteloungeelement/{idlounge}/{idtype}/{idelement}", name="reservations_lounge_element_delete")
*/
public function deleteLoungeElementAction($idlounge, $idtype, $idelement, EntityManagerInterface $em, Request $request)
{
switch ($idtype) {
case 1:
$item = $em->getRepository(ReservationLoungeDescription::class)->findOneById($idelement);
break; //Descripcion
case 2:
$item = $em->getRepository(ReservationLoungePicture::class)->findOneById($idelement);
break; //Imagenes
case 3:
$item = $em->getRepository(ReservationLoungeVideo::class)->findOneById($idelement);
break; //Videos
default:
$item = null;
break;
}
try {
$em->remove($item);
$em->flush();
$event = 'The Item has been Deleted. Now';
$successMessage = $this->translator->trans($event);
$this->addFlash('mensajereservation', $successMessage);
} catch (\Exception $e) {
$event = 'An error occurred: ' . $e->getMessage();
/* Para el usuario */
$errorMessage = $this->translator->trans($event);
$this->addFlash('mensajereservationerror', $errorMessage);
}
/* Fin Gestión de eventos en Log */
return $this->redirectToRoute('reservations_lounge_details', array('id' => $idlounge));
}
/**
*@Route("/exclamation", name="get_exclamation")
*/
public function exclamationAction(EntityManagerInterface $em, Request $request)
{
$dateStar = $request->request->get('dateStar');
$dateEnd = $request->request->get('dateEnd');
$hourStar = $request->request->get('hourStar');
$hourEnd = $request->request->get('hourEnd');
$profileId = $request->request->get('profileId');
$mountingDate = $request->request->get('mountingDate');
$mountingHourStart = $request->request->get('mountingHourStart');
$removalDate = $request->request->get('removalDate');
$removalHourEnd = $request->request->get('removalHourEnd');
// INICIO: Si hay montaje o desmontaje en el evento nuevo las fechas a utilizar son estas y no las del evento
if (!empty($mountingDate)) {
$dateStar = $mountingDate;
if (!empty($mountingHourStart)) {
$hourStar = $mountingHourStart;
}
}
if (!empty($removalDate)) {
$dateEnd = $removalDate;
if (!empty($removalHourEnd)) {
$hourEnd = $removalHourEnd;
}
}
// FIN: Si hay montaje o desmontaje en el evento nuevo las fechas a utilizar son estas y no las del evento
$reservationsLoungeId = $em->getRepository(ReservationLoungeProfile::class)->findOneById($profileId);
$newdateStar = $dateStar . ' ' . $hourStar . ':00';
$newdateEnd = $dateEnd . ' ' . $hourEnd . ':00';
$parameters = array(
'dateStar' => $newdateStar,
'dateEnd' => $newdateEnd,
'idLounge' => $reservationsLoungeId->getLoungeId(),
);
$dql = 'SELECT i
FROM VenuesBundle:ReservationLounge i
WHERE i.dateStart >= :dateStar
and i.dateStart <= :dateEnd
and i.idLounge = :idLounge';
$query = $em->createQuery($dql)->setParameters($parameters);
$reservationLounge1 = $query->getResult();
$dql = 'SELECT i
FROM VenuesBundle:ReservationLounge i
WHERE i.dateEnd >= :dateStar
and i.dateEnd <= :dateEnd
and i.idLounge = :idLounge';
$query = $em->createQuery($dql)->setParameters($parameters);
$reservationLounge2 = $query->getResult();
$parameters = array(
'dateStar' => $newdateStar,
'idLounge' => $reservationsLoungeId->getLoungeId()
);
$dql = 'SELECT i
FROM VenuesBundle:ReservationLounge i
WHERE :dateStar >= i.dateStart
and :dateStar <= i.dateEnd
and i.idLounge = :idLounge';
$query = $em->createQuery($dql)->setParameters($parameters);
$reservationLounge3 = $query->getResult();
$parameters = array(
'dateEnd' => $newdateEnd,
'idLounge' => $reservationsLoungeId->getLoungeId(),
);
$dql = 'SELECT i
FROM VenuesBundle:ReservationLounge i
WHERE :dateEnd >= i.dateStart
and :dateEnd <= i.dateEnd
and i.idLounge = :idLounge';
$query = $em->createQuery($dql)->setParameters($parameters);
$reservationLounge4 = $query->getResult();
// INICIO: Si hay montaje o desmontaje en los eventos de la BD, las fechas a utilizar son estas y no las del evento
$parameters = array(
'dateStar' => $newdateStar,
'dateEnd' => $newdateEnd,
'idLounge' => $reservationsLoungeId->getLoungeId(),
);
$dql = 'SELECT i
FROM VenuesBundle:ReservationLounge i
WHERE i.mountingDate >= :dateStar
and i.mountingDate <= :dateEnd
and i.idLounge = :idLounge';
$query = $em->createQuery($dql)->setParameters($parameters);
$reservationLounge5 = $query->getResult();
// FIN: Si hay montaje o desmontaje en los eventos de la BD, las fechas a utilizar son estas y no las del evento
$reservationLounge = array_merge($reservationLounge1, $reservationLounge2, $reservationLounge3, $reservationLounge4);
$data = array();
foreach ($reservationLounge as $res) {
$reservation = $em->getRepository(Reservation::class)->findOneById($res->getIdReservation());
$user = $em->getRepository(User::class)->findOneById($reservation->getCreatedBy());
$data[] = array(
'name' => 'Id Venues',
'idproposal' => $reservation->getId(),
'title' => $reservation->getTitle(),
'Agent' => $user->getName() . ' ' . $user->getLastname(),
);
}
$return = array('reservation' => $data, );
$response = new JsonResponse($return);
return $response;
}
/**
* @Route("/addperiod/", name="reservations_venues_addperiod")
*/
public function addReservationPeriodAction(Request $request)
{
$period = new ReservationPeriod();
$form = $this->createReservationperiodCreateForm($period);
return $this->render('MDS/VenuesBundle/reservations/list-reservations-period.html.twig', array('form' => $form->createView()));
}
private function createReservationperiodCreateForm(Reservationperiod $entity)
{
$form = $this->createForm(ReservationPeriodType::class, $entity, array(
'action' => $this->generateUrl('reservations_venues_period_create'),
'method' => 'POST'
));
return $form;
}
/**
* @Route("/createperiod", name="reservations_venues_period_create")
*/
public function createPeriodAction(EntityManagerInterface $em, Request $request)
{
$period = new ReservationPeriod();
$form = $this->createReservationPeriodCreateForm($period);
$form->handleRequest($request);
/* Obtengo usuario logueado */
$user_logueado = $this->get('security.token_storage')->getToken()->getUser();
$user_id = $user_logueado->getId();
$hoy = new \DateTime("now", NULL);
$period->setCreatedAt($hoy);
$period->setCreatedId($user_id);
$period->setUpdatedAt($hoy);
$period->setUpdatedId($user_id);
if ($form->isValid()) {
try {
$em->persist($period);
$em->flush();
$event = 'The Period has been created.';
$successMessage = $this->translator->trans($event);
$this->addFlash('mensajereservation', $successMessage);
} catch (\Exception $e) {
$event = 'An error occurred: ' . $e->getMessage();
/* Para el usuario */
$errorMessage = $this->translator->trans($event);
$this->addFlash('mensajereservationerror', $errorMessage);
}
} else {
$errorMessage = $this->translator->trans('Error, some fields are empty');
$this->addFlash('mensajereservationerror', $errorMessage);
}
return $this->redirectToRoute('reservations_venues_list_period');
}
/**
* @Route("/listperiod", name="reservations_venues_list_period")
*/
public function indexPeriodAction(EntityManagerInterface $em, Request $request)
{
$periods = $em->getRepository(ReservationPeriod::class)->findAll();
$period = new ReservationPeriod();
$form = $this->createReservationPeriodCreateForm($period);
return $this->render(
'MDS/VenuesBundle/reservations/list-reservations-period.html.twig',
array(
'groups' => null,
'form' => $form->createView(),
'periods' => $periods
)
);
}
/**
* @Route("/deleteperiod/{id}", name="reservations_period_delete")
*/
public function deletePeriodAction(EntityManagerInterface $em, $id, Request $request)
{
$period = $em->getRepository(ReservationPeriod::class)->findOneById($id);
try {
$em->remove($period);
$em->flush();
$event = 'The Reservation has been Deleted. Now';
$successMessage = $this->translator->trans($event);
$this->addFlash('mensajereservation', $successMessage);
} catch (\Exception $e) {
$event = 'An error occurred: ' . $e->getMessage();
/* Para el usuario */
$errorMessage = $this->translator->trans($event);
$this->addFlash('mensajereservationerror', $errorMessage);
}
/* Fin Gestión de eventos en Log */
return $this->redirectToRoute('reservations_venues_list_period');
}
/**
* @Route("/editperiod/{id}", name="reservations_edit_period")
*/
public function editPeriodAction($id, EntityManagerInterface $em, Request $request)
{
$period = $em->getRepository(ReservationPeriod::class)->findOneById($id);
/* Obtengo usuario logueado */
$user_logueado = $this->get('security.token_storage')->getToken()->getUser();
/* Gestión de eventos en Log */
$user_lastname = $user_logueado->getLastname();
$user_name = $user_logueado->getName();
$user_email = $user_logueado->getEmail();
$user_rol = $user_logueado->getRoles();
$event_url = $request->getPathInfo();
$event_complete = $user_name . ' ' . $user_lastname . ' - ' . $user_email . ' - ' . $user_rol[0] . ' | ' . $event_url;
$hoy = new \DateTime("now", NULL);
$form = $this->createEditPeriodForm($period, $id);
return $this->render(
'MDS/VenuesBundle/reservations/edit-reservations-period.html.twig',
array(
'id' => $id,
'hoy' => $hoy,
'period' => $period,
'form' => $form->createView()
)
);
}
private function createEditPeriodForm(ReservationPeriod $entity, $id)
{
$form = $this->createForm(
ReservationPeriodType::class,
$entity,
array(
'action' => $this->generateUrl(
'reservations_period_update',
array(
'id' => $id,
'period' => $entity
)
),
'method' => 'PUT'
)
);
return $form;
}
/**
* @Route("/updateperiod/{id}", name="reservations_period_update")
*/
public function updatePeriodAction($id, EntityManagerInterface $em, Request $request)
{
$period = $em->getRepository(ReservationPeriod::class)->findOneById($id);
$newName = $request->request->get('mds_venuesbundle_reservationperiod')['name'];
$period->setName($newName);
$hoy = new \DateTime("now", NULL);
$form = $this->createEditPeriodForm($period, $id);
$form->handleRequest($request);
if ($form->isValid()) {
/* Obtengo usuario logueado */
$user_logueado = $this->get('security.token_storage')->getToken()->getUser();
$user_id = $user_logueado->getId();
/* Gestión de eventos en Log */
$user_lastname = $user_logueado->getLastname();
$user_name = $user_logueado->getName();
$user_email = $user_logueado->getEmail();
$user_rol = $user_logueado->getRoles();
$event_url = $request->getPathInfo();
$event_complete = $user_name . ' ' . $user_lastname . ' - ' . $user_email . ' - ' . $user_rol[0] . ' | ' . $event_url;
$period->setUpdatedId($user_id);
$period->setUpdatedAt($hoy);
try {
$em->persist($period);
$em->flush();
$event = 'The period has been Updated. Now';
$successMessage = $this->translator->trans($event);
$this->addFlash('mensajereservation', $successMessage);
} catch (\Exception $e) {
$event = 'An error occurred: ' . $e->getMessage();
/* Para el usuario */
$errorMessage = $this->translator->trans($event);
$this->addFlash('mensajereservationerror', $errorMessage);
}
/* Fin Gestión de eventos en Log */
return $this->redirectToRoute('reservations_venues_list_period');
} else {
$errorMessage = $this->translator->trans('Error, some fields are empty');
$this->addFlash('mensajereservationerror', $errorMessage);
}
return $this->render(
'MDS/VenuesBundle/reservations/edit-reservations-period.html.twig',
array(
'id' => $id,
'hoy' => $hoy,
'period' => $period,
'form' => $form->createView()
)
);
}
/**
* @Route("/getperiodos/", name="reservations_venues_get_periods")
*/
public function addReservationPeriodsAction(EntityManagerInterface $em, Request $request)
{
$periods = $em->getRepository(ReservationPeriod::class)->findAll();
$data = array();
foreach ($periods as $items) {
$data[] = array('id' => $items->getId(), 'name' => $items->getName(), );
}
$return = array('periods' => $data, );
$response = new JsonResponse($return);
return $response;
}
/**
* @Route("/addsimple/", name="reservations_venues_add_simple")
*/
public function addReservationSimpleAction(EntityManagerInterface $em, Request $request)
{
$reserv = new Reservation();
$form = $this->createReservationCreateForm($reserv, ['cotizable' => true]);
return $this->render(
'MDS/VenuesBundle/reservations/add-reservations-simple.html.twig',
array(
'form' => $form->createView(),
'clientsContact' => '',
)
);
}
private function createReservationCreateForm(Reservation $entity, array $options = [])
{
$id = $entity->getId();
$hasInvoices = false;
if ($id) {
$invoiceRepository = $this->em->getRepository(ReservationInvoice::class);
$invoiceRecRepository = $this->em->getRepository(ReservationInvoiceRec::class);
$hasInvoices = !empty($invoiceRepository->findByReservationId($id)) || !empty($invoiceRecRepository->findByReservationId($id));
}
$form = $this->createForm(ReservationType::class, $entity, array(
'action' => $this->generateUrl('reservations_venues_create_simple'),
'method' => 'POST',
'confirmable' => $options['confirmable'] ?? false,
'cotizable' => $options['cotizable'] ?? false,
'invoiced' => $hasInvoices,
));
return $form;
}
/**
* @Route("/createsimple", name="reservations_venues_create_simple")
*/
public function createSimpleAction(EntityManagerInterface $em, Request $request)
{
$clientContact = $request->request->get('clientContact');
$contactUnregistered = trim((string) $request->request->get('contactUnregistered'));
$nameContactUnregistered = trim((string) $request->request->get('nameContactUnregistered'));
$phoneContactUnregistered = trim((string) $request->request->get('phoneContactUnregistered'));
$reserva = new Reservation();
$form = $this->createReservationCreateForm($reserva);
$form->handleRequest($request);
/* Obtengo usuario logueado */
$user_logueado = $this->getUser();
$user_id = $user_logueado->getId();
$hoy = new \DateTime("now", NULL);
if ($form->isValid()) {
$clientId = $request->request->get('mds_venuesbundle_reservation')['client'] ?? null;
if ($clientId) {
$client = $em->getRepository(Client::class)->find($clientId);
}
$reserva->setClient(
$clientId ? $client : null
);
$reserva->setCreatedAt($hoy);
$reserva->setCreatedBy($user_id);
if (empty($reserva->getDaysBlock()) or !(is_numeric($reserva->getDaysBlock()))) {
$reserva->setDaysBlock(7);
}
if (is_null($reserva->getPriority()) or empty($reserva->getPriority()) or ($reserva->getPriority() == 'Auto')) {
$reserva->setPriority(1);
} else {
// Se ha establecido una prioridad y todas las prioridades que coincidan con este evento deben ser alteradas
// PENDIENTE A HABLAR CON RAFA
}
// No hay salas, se asigna a la reserva la fecha del dia actual
$reserva->setDateStart(new \DateTime('2078-01-01'));
$reserva->setDateEnd(new \DateTime('2000-01-01'));
// Si viene información de un contacto no registrado, creamos el contrato y lo vinculamos al cliente y luego al expediente
if ($clientId && $contactUnregistered !== '' && $nameContactUnregistered !== '' && $phoneContactUnregistered !== '') {
$existClientContact = $em->getRepository(ClientContact::class)->findOneBy(['email' => $contactUnregistered]);
if ($existClientContact) {
// Si ya existe un contacto con ese email, lo vinculamos al expediente
$reserva->setClientContact($existClientContact->getId());
} else {
$newClientContact = new ClientContact();
$newClientContact->setClientId($client->getId());
$newClientContact->setTypeclient('Business Travel');
$newClientContact->setAssignedAgent($user_id);
$newClientContact->setName($nameContactUnregistered);
$newClientContact->setLastName('');
$newClientContact->setPosition('');
$newClientContact->setSituation('CLIENT');
$newClientContact->setStatus('');
$newClientContact->setEmail($contactUnregistered);
$newClientContact->setPhone($phoneContactUnregistered);
$newClientContact->setCreatedId($user_id);
$newClientContact->setUpdatedId($user_id);
$em->persist($newClientContact);
$em->flush();
$reserva->setClientContact($newClientContact->getId());
}
}
if (!empty($clientContact) && $clientContact != '0') {
$reserva->setClientContact($clientContact);
}
if (empty($reserva->getStatus())) {
$reserva->setStatus('Iniciado');
} else {
//No se debe crear un evento con estado confirmado. Salva y Rafa seran quienes confirmen los eventos
if (($reserva->getStatus() == 'Confirmed')) {
// $reserva->setStatus('Cotizado'); //Ya no es necesario que Rafa o Salva confirmen
}
}
// Genera un token único utilizando la función uniqid() de PHP
$token = uniqid();
$reserva->setToken($token);
$reserva->setCreatedBy($user_id);
$reserva->setUpdatedBy($user_id);
try {
$em->persist($reserva);
$em->flush();
$event = 'The Reservation has been created.';
$successMessage = $this->translator->trans($event);
$this->addFlash('mensajereservation', $successMessage);
} catch (\Exception $e) {
dd($e);
$event = 'An error occurred: ' . $e->getMessage();
$errorMessage = $this->translator->trans($event);
$this->addFlash('mensajereservationerror', $errorMessage);
}
//Envio de correo al cliente y al agente si es un bloqueo
if (is_null($reserva->getStatus())) {
$reserva->setStatus('Cotizado');
$em->persist($reserva);
$em->flush();
} else {
if (($reserva->getStatus() == 'Bloqueo')) {
if (empty($reserva->getDays())) {
$now = new \DateTime("now");
$dateLimit = date("Y-m-d H:i", strtotime($now->format('Y-m-d H:i') . "+" . $reserva->getDaysBlock() . " days"));
$dateLimit = new \DateTime($dateLimit);
$reserva->setDays($dateLimit);
}
if ((!empty($reserva->getClient())) or (!empty($reserva->getClientContact())) or (!empty($reserva->getContactUnregistered()))) {
//Solo se envia correo de notificacion del correo si hay cliente o contacto o contacto no registrado
$client = $reserva->getClient();
$mailAddressTo = null;
// if (!empty($client) and (!empty($client->getEmail()))){ $mailAddressTo = $client->getEmail(); } // Si hay cliente con correo se le envia a este
// if (!empty($reserva->getClientContact())){
// $contacto = $em->getRepository(ClientContact::class)->findOneById($reserva->getClientContact());
// if (!empty($contacto) and (!empty($contacto->getEmail()))){ $mailAddressTo = $contacto->getEmail(); } // Si hay un contacto seleccionado tiene prioridad sobre el contacto de cliente
// }
// if (!empty($reserva->getContactUnregistered())){ $mailAddressTo = $reserva->getContactUnregistered(); } // Si hay correo de contacto no registrado este tiene prioridad sobre todos
if (!empty($mailAddressTo)) {
$agente = $em->getRepository(User::class)->findOneById($user_id);
$mailAddressFrom = $agente->getEmail();
$mailSubject = 'Notificación de Bloqueo - Reserva de espacio en Venues';
$mailBody = 'Estimado cliente,' .
'<br><br> Nos ponemos en contacto con usted para confirmarle que su reserva ha quedado registrada en Venues para la realización de su próximo evento.' .
'<br>Le recordamos que esta reserva tiene una validez de ' . $reserva->getDaysBlock() . ' días. Si pasado este tiempo no hemos recibido confirmación de vuestra parte, procederemos a la cancelación de la misma.' .
'<br><br>Reserva: ' . $reserva->getId() . ' - ' . $reserva->getTitle();
$mailBody = $mailBody . '<br><br><br>Muchas gracias por su colaboración.<br><br><br>';
//Se envia el correo al cliente y al agente
$this->sendMail($mailAddressFrom, $mailAddressTo, $mailSubject, $mailBody);
//Se genera el control de la alerta
$this->makeAlert($reserva->getId(), $client?->getId(), $mailAddressTo, $agente->getId(), $agente->getEmail());
}
}
}
}
} else {
$errorMessagebase = $this->translator->trans('Error, some fields are empty');
$this->addFlash('mensajetracingerror', $errorMessagebase);
$periods = $em->getRepository(ReservationPeriod::class)->findAll();
return $this->render(
'MDS/VenuesBundle/reservations/add-reservations.html.twig',
array(
'form' => $form->createView(),
'periods' => $periods,
)
);
}
$id = $reserva->getId();
// Actualizamos la agenda
$newItem = new ReservationAgendaItem();
$newItem->setReservationId($id);
$newItem->setRankListing(1);
$newItem->setTitleOne('EVENTO: ' . $reserva->getTitle());
$newItem->setTitleTwo(null);
$newItem->setTitleThree(null);
$newItem->setDescription('.');
$newItem->setDateStart(null);
$newItem->setDateEnd(null);
$newItem->setPicture(null);
$newItem->setSourceId($id);
$newItem->setSourceType('Reservation');
$user = $this->getUser();
$newItem->setCreatedId($user->getId());
$newItem->setUpdatedId($user->getId());
$newItem->setCreatedAt(new \DateTime());
$newItem->setUpdatedAt(new \DateTime());
$this->repository->add($newItem, true);
//Actualizamos el contacto de la Agenda
$contactString = null;
if (!empty($reserva->getNameContactUnregistered())) {
$contactString .= $reserva->getNameContactUnregistered();
} else {
$contactString .= 'No se pudo determinar el nombre';
}
if (!empty($reserva->getPhoneContactUnregistered())) {
$contactString .= ' / ' . $reserva->getPhoneContactUnregistered();
} else {
$contactString .= ' / No se pudo determinar el teléfono';
}
if (!empty($reserva->getContactUnregistered())) {
$contactString .= ' / ' . $reserva->getContactUnregistered();
} else {
$contactString .= ' / No se pudo determinar el email';
}
$agenda = $this->agendaService->updateClientContactLine($reserva->getId(), $contactString, $user->getId());
// Sincronización con Av Express
$cotizable = $this->laReservaEsCotizable($reserva->getId());
if ($cotizable) {
// Rafa indico que siempre se sincronice al abrir un expediente de GP
// if (in_array($reserva->getStatus(), ['Confirmed', 'Invoiced', 'Iniciado', 'Cotizado', 'Bloqueo'])) {
// $AveFile = $em->getRepository(AveFiles::class)->findByReservation($reserva);
// if (empty($AveFile)) {
// // Si no se ha creado aun el expediente de Av Express debemos crearlo
// return $this->redirectToRoute('sinc_gp_ave', array('id' => $id,));
// }
// }
}
return $this->redirectToRoute('reservations_venues_edit_simple', array('id' => $id, 'token' => null));
}
/**
* @Route("/editsimple/{id}", name="reservations_venues_edit_simple")
*/
public function editReservationSimpleItemsAction(int $id, EntityManagerInterface $em, TokenStorageInterface $tokenStorage): Response
{
// 1. Carga inicial de datos críticos (Fail Fast)
$reserva = $em->getRepository(Reservation::class)->find($id);
if (!$reserva) {
throw new NotFoundHttpException('Reserva no encontrada.');
}
$client = $reserva->getClient();
$clientId = $client?->getId() ?? 0;
// Settings Company
$settingsCompany = $em->getRepository(SettingsCompany::class)->findOneBy([
'businessType' => BusinessTypeSettingsCompanyConstants::VENUE
]);
// 2. Preparación de Formularios (Objetos vacíos para crear)
$reservationsLounge = new ReservationLounge();
$reservationsLounge->setIdReservation($id);
$monDesmon = new ReservationLounge();
$monDesmon->setIdReservation($id);
$options['confirmable'] = $this->laReservaEsConfirmable($id);
$options['cotizable'] = $this->laReservaEsCotizable($id);
$form1 = $this->createReservationCreateForm($reserva, $options);
// =================================================================================
// CORRECCIÓN: Rellenar los campos "mapped => false" si ya existe un contacto guardado
// =================================================================================
$savedContactId = $reserva->getClientContact();
if ($savedContactId) {
// Buscamos la entidad del contacto real
$savedContact = $em->getRepository(ClientContact::class)->find($savedContactId);
if ($savedContact) {
// 1. Rellenamos el Email
$form1->get('contactUnregistered')->setData($savedContact->getEmail());
// 2. Rellenamos el Nombre (concatenando apellido si lo hubiera)
$fullName = $savedContact->getName();
if (!empty($savedContact->getLastName())) {
$fullName .= ' ' . $savedContact->getLastName();
}
$form1->get('nameContactUnregistered')->setData($fullName);
// 3. Rellenamos el Teléfono
$form1->get('phoneContactUnregistered')->setData($savedContact->getPhone());
// 4. Aseguramos que el selector (campo hidden) tenga el valor correcto
// para que la lógica de JavaScript y el controlador funcionen bien al volver a guardar.
$form1->get('clientContact')->setData($savedContactId);
}
}
// =================================================================================
$form2 = $this->createReservationLoungeCreateForm($reservationsLounge);
$form3 = $this->createReservationLoungeMonDesCreateForm($monDesmon);
// 3. Procesamiento de Salas (Lounges)
$reservationsLoungesSimple = $em->getRepository(ReservationLoungeSimple::class)->findByIdReservation($id);
$loungesData = $this->processLounges($reservationsLoungesSimple);
// 4. Cálculos Totales (Método existente en tu controlador)
$data = $this->CalculosTotalesEditSimple($id);
// 5. Proveedores y Catering
$caterings = $this->getCateringSuppliers($em);
// 6. Usuarios y Creador
$userCreatedBy = $em->getRepository(User::class)->find($reserva->getCreatedBy());
$createdBy = $userCreatedBy ? ($userCreatedBy->getName() . ' ' . $userCreatedBy->getLastName()) : '';
// 7. Facturación y Finanzas (Lógica compleja refactorizada)
$invoicesData = $this->calculateInvoicesData($id, $reserva, $client, $em);
// 8. Pagos
$paymentsAll = $em->getRepository(ReservationPaymentsClient::class)->findByReservationId($id);
$paymentNotIvoiced = $this->filterUninvoicedPayments($id, $paymentsAll, $em);
// 9. Contactos y Usuarios Activos
$userLogueado = $tokenStorage->getToken()?->getUser();
$userId = $userLogueado instanceof User ? $userLogueado->getId() : null;
$clientsContact = $em->getRepository(ClientContact::class)->findBy(
['clientId' => $clientId],
['name' => 'ASC']
);
$allUsersActive = $this->getAllActiveUsersAndFreelancers($em);
// 10. Alertas de Correo
$nextMailAlert = $this->getNextMailAlertDate($id, $em);
// 11. Datos Adicionales (Servicios, Clientes Venues, Depósitos)
$reservationsLounges = $em->getRepository(ReservationLounge::class)->findByIdReservation($id);
$services = $em->getRepository(ReservationService::class)->findByReservationId($id);
$datax = $this->benefitForReservation($id); // Método existente
// Clientes filtrados por SettingsCompany
$clients = $em->getRepository(Client::class)
->createQueryBuilder('c')
->innerJoin('c.settingsCompany', 'sc')
->where('sc.id = :settingsCompanyId')
->setParameter('settingsCompanyId', $settingsCompany?->getId())
->orderBy('c.name', 'ASC')
->getQuery()
->getResult();
// Depósitos y Proformas
$depositsData = $this->getDepositsAndProformas($id, $em);
// Todas las proformas de la reserva (Evita N+1 ya que se consultan de golpe sin relaciones pesadas)
$allReservationProformas = $em->getRepository(ReservationProforma::class)->findBy(
['reservationId' => $id],
['id' => 'DESC']
);
// Salas Predefinidas y Nombres
$reservationsLoungesPre = $em->createQueryBuilder()
->select('p')
->from('VenuesBundle:ReservationLoungeDetails', 'p') // Ajustar si el bundle name es distinto
->orderBy('p.rankLounge', 'ASC')
->getQuery()
->getResult();
$reservationsLoungesNames = $em->getRepository(ReservationLoungeDetails::class)->findAll();
$listSupplier = $em->getRepository(Supplier::class)->findAll();
// Flags finales
$urlCotizacion = "https://cotizacion.greenpatio.es/index.php?token=" . $reserva->getToken();
$languagesWeb = LanguageConstants::getAvailableLanguages();
$agenda = $this->agendaService->getAgendaForView($id);
// Obtener el HtFile asociado
$htFile = $reserva->getHtFile();
// Obtener el AveFile asociado
$aveFile = $reserva->getAveFile();
// Obtener historial de seguimientos
$tracings = $em->getRepository(ReservationTracing::class)->findBy(
['reservationId' => $id],
['createdAt' => 'DESC']
);
return $this->render('MDS/VenuesBundle/reservations/edit-reservations-simple.html.twig', [
'form' => $form1->createView(),
'form2' => $form2->createView(),
'form3' => $form3->createView(),
'id' => $id,
'clients' => $clients,
'clientId' => $clientId,
'caterings' => $caterings,
'loungesPre' => $reservationsLoungesPre,
'loungesNames' => $reservationsLoungesNames,
'arrayLoungesInFile' => $loungesData['arrayLoungesInFile'],
'facturas' => $invoicesData['allInvoiced'],
'numeroItems' => count($loungesData['arrayLoungesByDay']),
'arrayLoungesByDay' => $loungesData['arrayLoungesByDay'],
// Totales globales (usando nullsafe operator para arrays si $data no garantiza claves)
'totales_global_con_iva' => $data['totales_global_con_iva'] ?? 0,
'totales_global_iva' => $data['totales_global_iva'] ?? 0,
'totales_global_neto' => $data['totales_global_neto'] ?? 0,
'totales_global_servicios_con_iva' => $data['totales_global_servicios_con_iva'] ?? 0,
'totales_global_servicios_neto' => $data['totales_global_servicios_neto'] ?? 0,
'totales_global_servicios_iva' => $data['totales_global_servicios_iva'] ?? 0,
'sumatoria_totales_global_con_iva' => $data['sumatoria_totales_global_con_iva'] ?? 0,
'sumatoria_totales_global_neto' => $data['sumatoria_totales_global_neto'] ?? 0,
'sumatoria_totales_global_iva' => $data['sumatoria_totales_global_iva'] ?? 0,
'reserva' => $reserva,
'createdBy' => $createdBy,
'arraySalas' => null,
'lounges' => $reservationsLounges,
'salasReserva' => $reservationsLounges,
'periods' => null,
'services' => $services,
'loungesNumbers' => count($reservationsLounges),
'listSupplier' => $listSupplier,
'resultados' => $invoicesData['resultados'],
'paymentsAll' => $paymentsAll,
'paymentNotIvoiced' => $paymentNotIvoiced,
'allUsersActive' => $allUsersActive,
'userLog' => $userId,
'clientsContact' => $clientsContact,
'nextMailAlert' => $nextMailAlert,
'benefit' => $datax['benefit'],
'percBenefit' => $datax['percBenefit'],
'payedLounges' => $datax['payedLounges'],
'payedServices' => $datax['payedServices'],
'unPayedServices' => $datax['unPayedServices'],
'depositsAll' => $depositsData['depositsAll'],
'sumsByProforma' => $depositsData['sumsByProforma'],
'proformas' => $depositsData['proformas'],
'allReservationProformas' => $allReservationProformas,
'urlCotizacion' => $urlCotizacion,
'reservationContracts' => $reserva->getDocContracts(),
'viewContract' => !$reserva->getDocContracts()->isEmpty(),
'languagesWeb' => $languagesWeb,
'sageVatRates' => $em->getRepository(SageVatRates::class)->findAll(),
'arregloLineasAgenda' => $agenda,
'htFile' => $htFile,
'aveFile' => $aveFile,
'tracings' => $tracings,
]);
}
/**
* @Route("/tracing/add/{id}", name="reservations_venues_tracing_ajax_add", methods={"POST"})
* @param int $id
* @param Request $request
* @param EntityManagerInterface $em
* @return \Symfony\Component\HttpFoundation\JsonResponse
*/
public function addTracingAjaxAction(int $id, Request $request, EntityManagerInterface $em)
{
$reserva = $em->getRepository(Reservation::class)->find($id);
if (!$reserva) {
return new \Symfony\Component\HttpFoundation\JsonResponse(['status' => 'error', 'msg' => 'Reserva no encontrada'], 404);
}
$dateStr = $request->request->get('tracingDate');
$text = $request->request->get('tracingText');
if (empty($dateStr) || empty($text)) {
return new \Symfony\Component\HttpFoundation\JsonResponse(['status' => 'error', 'msg' => 'Faltan parámetros'], 400);
}
try {
$date = new \DateTime($dateStr);
$user = $this->getUser();
$tracing = new ReservationTracing();
$tracing->setReservationId($reserva->getId());
$tracing->setDateAt($date);
$tracing->setText($text);
$tracing->setAgentId($user->getId());
$tracing->setViewed('NO');
$tracing->setCreatedId($user->getId());
$tracing->setUpdatedId($user->getId());
$tracing->setCreatedAt(new \DateTime());
$tracing->setUpdatedAt(new \DateTime());
$em->persist($tracing);
$em->flush();
return new \Symfony\Component\HttpFoundation\JsonResponse(['status' => 'ok']);
} catch (\Exception $e) {
return new \Symfony\Component\HttpFoundation\JsonResponse(['status' => 'error', 'msg' => $e->getMessage()], 500);
}
}
private function createReservationLoungeCreateForm(ReservationLounge $entity)
{
$form = $this->createForm(ReservationLoungeType::class, $entity, array(
'action' => $this->generateUrl(
'reservations_venues_create_simple_lounge',
array(
'id' => $entity->getIdReservation(),
)
),
'method' => 'POST'
));
return $form;
}
private function createReservationLoungeMonDesCreateForm(ReservationLounge $entity)
{
$form = $this->createForm(ReservationLoungeType::class, $entity, array(
'action' => $this->generateUrl(
'reservations_venues_create_simple_lounge_mondes',
array(
'id' => $entity->getIdReservation(),
)
),
'method' => 'POST'
));
return $form;
}
/**
* @Route("/contract/{id}", name="reservations_contract")
*/
public function goContractAction($id): Response
{
$dataContract = $this->docContractService->renderContractTemplate($id);
return $this->render(
'MDS/VenuesBundle/reservations/print-contract-gp.html.twig',
array(
'dataContract' => $dataContract,
)
);
}
/**
* @Route("/contract/{id}/save", name="reservations_contract_save", methods={"POST"})
*/
public function saveContractAction(int $id, Request $request, EntityManagerInterface $em): JsonResponse
{
// 1. Obtener el contrato por su propio ID (ya no por ID de reserva)
$docContract = $em->getRepository(DocContract::class)->find($id);
if (!$docContract) {
return new JsonResponse(['status' => 'error', 'message' => 'Contrato no encontrado'], 404);
}
// 2. Obtener el contenido enviado por AJAX
$content = $request->request->get('content');
if (empty($content)) {
return new JsonResponse(['status' => 'error', 'message' => 'El contenido no puede estar vacío'], 400);
}
// 3. Actualizar y Guardar
$docContract->setContractualDocument($content);
$em->flush();
return new JsonResponse(['status' => 'success', 'message' => 'Contrato guardado correctamente']);
}
/**
* Muestra el contenido actual del contrato en una vista simple.
* Se usa para abrir la "copia de seguridad" en una nueva pestaña.
*
* @Route("/contract/{id}/show-current", name="reservations_contract_show_current", methods={"GET"})
*/
public function showCurrentContractAction(int $id, EntityManagerInterface $em): Response
{
$docContract = $em->getRepository(DocContract::class)->find($id);
if (!$docContract) {
throw $this->createNotFoundException('El contrato no existe.');
}
return $this->render('MDS/VenuesBundle/reservations/show_raw_contract.html.twig', [
'contract_content' => $docContract->getContractualDocument()
]);
}
/**
* Resincroniza el contrato desde su modelo original.
*
* @Route("/contract/{id}/resync", name="reservations_contract_resync", methods={"POST"})
*/
public function resyncContractAction(int $id, DocContractService $docContractService, EntityManagerInterface $em): JsonResponse
{
try {
$docContract = $em->getRepository(DocContract::class)->find($id);
if (!$docContract) {
return new JsonResponse(['status' => 'error', 'message' => 'Contrato no encontrado'], 404);
}
$newContent = $docContractService->renderContractModelTemplate($docContract);
// Actualizamos la entidad y guardamos en la BBDD.
// $docContract->setContractualDocument($newContent);
// $em->flush();
// 4. Devolvemos el nuevo contenido al frontend.
return new JsonResponse([
'status' => 'success',
'newContent' => $newContent
]);
} catch (\Exception $e) {
// Captura cualquier error que pueda ocurrir durante el renderizado.
return new JsonResponse(['status' => 'error', 'message' => $e->getMessage()], 500);
}
}
/**
* @Route("/updateloungegrid", name="reservations_venues_updateloungegrid", methods={"POST"})
*/
public function updateLoungeGridAction(
EntityManagerInterface $em,
Request $request,
TokenStorageInterface $tokenStorage
): Response {
// 1. Obtención y validación de datos iniciales
$reservationsLoungeGrid = $request->request->all('lounge');
$reservationGlobalLounge = $request->request->all('reservation_global_lounge');
$id = $request->request->get('reservationId');
$reserva = $em->getRepository(Reservation::class)->find($id);
if (!$reserva) {
throw new NotFoundHttpException('Reserva no encontrada.');
}
$userLogueado = $tokenStorage->getToken()?->getUser();
$userId = $userLogueado instanceof User ? $userLogueado->getId() : null;
// 2. Pre-carga de datos para evitar consultas en bucle (Optimization N+1)
// Mapeamos LoungeDetails por nombre para acceso rápido
$loungeDetailsMap = [];
$allLoungeDetails = $em->getRepository(ReservationLoungeDetails::class)->findAll();
foreach ($allLoungeDetails as $detail) {
$loungeDetailsMap[$detail->getName()] = $detail;
}
// Cargamos la tasa de IVA por defecto
$defaultSageVatRate = $em->getRepository(SageVatRates::class)->findOneBy(['sageCode' => '03']);
// Cache y arreglo diferido de agendas
$sageArticlesCache = [];
$agendasToProcess = [];
// Carga masiva (Batch Pre-load) de Entidades ReservationLoungeSimple
$loungeSimplesCache = [];
if (is_array($reservationsLoungeGrid)) {
$loungeIdsToFetch = array_filter(array_keys($reservationsLoungeGrid), function($id) {
return is_numeric($id) && $id > 0;
});
if (!empty($loungeIdsToFetch)) {
$loungesInDb = $em->getRepository(ReservationLoungeSimple::class)->findBy(['id' => $loungeIdsToFetch]);
foreach ($loungesInDb as $lounge) {
$loungeSimplesCache[$lounge->getId()] = $lounge;
}
}
}
// 3. Inicialización de fechas extremas para recalcular el rango de la reserva
// Usamos variables locales para no modificar la entidad Reserva hasta el final
$minDateStart = new DateTime('2999-01-01');
$maxDateEnd = new DateTime('2000-01-01');
$hasItems = false; // Flag para saber si procesamos algo
$updatedCount = 0;
// 4. Procesamiento del Grid
if (is_array($reservationsLoungeGrid)) {
foreach ($reservationsLoungeGrid as $idReservationLounge => $reservationsLoungeData) {
if (!is_array($reservationsLoungeData)) {
continue;
}
// Basado en la estructura recibida, cada ID tiene un único día y una única sala
$dia = key($reservationsLoungeData);
$items = $reservationsLoungeData[$dia] ?? null;
if (!is_array($items)) {
continue;
}
$name = key($items);
$item = $items[$name] ?? null;
if (!is_array($item)) {
continue;
}
// Buscar o Crear entidad (usando Identity Map en memoria)
if (array_key_exists($idReservationLounge, $loungeSimplesCache)) {
$reservationLounge = $loungeSimplesCache[$idReservationLounge];
} else {
$reservationLounge = new ReservationLoungeSimple();
// Asignamos ID solo si es nuevo y persistimos implícitamente al final
// Lo añadimos al cache para evitar crear múltiples objetos vacíos si el mismo "fake id" itera en otro dia
$loungeSimplesCache[$idReservationLounge] = $reservationLounge;
}
// Parseo de horas (Refactorizado a método privado)
$startData = $this->reservationService->formatTimeInput($item['dateHourMinStart'] ?? '');
$endData = $this->reservationService->formatTimeInput($item['dateHourMinEnd'] ?? '');
$dateStartStr = ($item['newDate'] ?? '') . ' ' . $startData['formatted'];
$dateEndStr = ($item['newDate'] ?? '') . ' ' . $endData['formatted'];
// Validaciones de lógica de negocio (Sage)
/** @var ReservationLoungeDetails|null $loungeDetail */
$loungeDetail = $loungeDetailsMap[$name] ?? null;
// Determinar IVA y Artículo Sage
$targetVat = $defaultSageVatRate;
if (array_key_exists('iva', $item) && !empty($item['iva']) && is_numeric($item['iva'])) {
// Si viene un ID de IVA, tendríamos que buscar la entidad.
// Asumo que $item['iva'] es el ID o la entidad si Symfony lo mapea,
// pero para seguridad buscamos la referencia si es un ID.
$targetVat = $em->getReference(SageVatRates::class, $item['iva']);
}
// Buscamos el artículo. Esto sigue siendo una query por iteración si varía mucho,
// pero es necesario ya que depende de la combinación VAT + Nombre.
$sageArticle = null;
// Si el modulo de Sage no está activo no se hace
if ($this->session->get('_config')['msage']) {
if ($loungeDetail) {
$cacheKey = $targetVat->getId() . '_' . $loungeDetail->getName();
if (!array_key_exists($cacheKey, $sageArticlesCache)) {
$sageArticlesCache[$cacheKey] = $em->getRepository(SageArticle::class)->findOneBy([
'vatType' => $targetVat,
'name' => $loungeDetail->getName()
]);
}
$sageArticle = $sageArticlesCache[$cacheKey];
}
if (!$sageArticle && $loungeDetail) {
// Intento fallback con default VAT si falló el específico
$cacheKeyFallback = $defaultSageVatRate->getId() . '_' . $loungeDetail->getName();
if (!array_key_exists($cacheKeyFallback, $sageArticlesCache)) {
$sageArticlesCache[$cacheKeyFallback] = $em->getRepository(SageArticle::class)->findOneBy([
'vatType' => $defaultSageVatRate,
'name' => $loungeDetail->getName()
]);
}
$sageArticle = $sageArticlesCache[$cacheKeyFallback];
}
if (!$sageArticle) {
$this->addFlash('mensajereservationerror', 'No se ha encontrado el artículo de Sage para la sala: ' . $name);
continue;
}
}
// Asignación de datos
$reservationLounge->setIdReservation((int) $id);
// Datos heredados de ReservationGlobalLounge
if ($loungeDetail && isset($reservationGlobalLounge[$loungeDetail->getId()])) {
$globalData = $reservationGlobalLounge[$loungeDetail->getId()];
$reservationLounge->setIdLounge($loungeDetail->getId());
$reservationLounge->setImportantDescription($globalData['importantDescription'] ?? null);
$reservationLounge->setImportantDescGeneralText($globalData['importantDescGeneralText'] ?? null);
$reservationLounge->setImportantDescSchedules($globalData['importantDescSchedules'] ?? null);
$reservationLounge->setImportantDescParking($globalData['importantDescParking'] ?? null);
} else {
$reservationLounge->setIdLounge(0);
}
// Seteo de valores simples
$price = $item['price'] ?? 0;
$pax = !empty($item['pax']) ? $item['pax'] : 0;
// if(!array_key_exists('type', $item)){
// dd($item);
// }
// dump($item['type']);
if (!array_key_exists('type', $item)){
$type = empty($item['pax']) ? ($item['type'] ?? null) : null; // Lógica original invertida para type
} else{
$type = $item['type'];
}
try {
$dtStart = new DateTime($dateStartStr);
$dtEnd = new DateTime($dateEndStr);
$reservationLounge->setDateStart($dtStart);
$reservationLounge->setDateEnd($dtEnd);
// Actualizar rango global
if ($dtStart < $minDateStart) {
$minDateStart = clone $dtStart;
$hasItems = true;
}
if ($dtEnd > $maxDateEnd) {
$maxDateEnd = clone $dtEnd;
$hasItems = true;
}
} catch (\Exception $e) {
// Ignorar fechas inválidas
}
$reservationLounge->setType($type);
$reservationLounge->setPax($pax);
$reservationLounge->setServicePrice($price);
$reservationLounge->setSageIva($targetVat);
$reservationLounge->setOpIva(1);
$reservationLounge->setLoungeName($name);
// Horas desglosadas
$reservationLounge->setHourStart($startData['hour']);
$reservationLounge->setMinStart($startData['min']);
$reservationLounge->setHourEnd($endData['hour']);
$reservationLounge->setMinEnd($endData['min']);
$reservationLounge->setLanguage($reservationGlobalLounge['language'] ?? 'es'); // Default 'es' por seguridad
$reservationLounge->setUpdatedBy($userId);
$reservationLounge->setCreatedBy($userId); // Nota: Originalmente sobreescribe createdBy al editar
$reservationLounge->setSageArticle($sageArticle);
$em->persist($reservationLounge);
$updatedCount++;
// Guardamos en memoria para procesar en bloque después del flush global
$agendasToProcess[] = $reservationLounge;
}
}
// 5. Persistencia y Actualización Diferida (Salas y Agendas)
try {
if ($updatedCount > 0) {
// Solo actualizamos las fechas de la reserva si procesamos items válidos
// y si las fechas calculadas expanden el rango actual (según lógica original).
if ($hasItems) {
$this->reservationService->updateReservationDates($reserva);
}
// Flush GLOBAL para guardar salas y evitar llamadas continuas a BD
$em->flush();
// --- Post Procesamiento Diferido de Agenda ---
foreach ($agendasToProcess as $rLounge) {
$this->agendaService->createAgendaFromSource(
$rLounge->getIdReservation(),
'SALAS A UTILIZAR',
null,
null,
$rLounge->getDateStart(),
$rLounge->getDateEnd(),
$rLounge->getLoungename(),
$rLounge->getId(),
'ReservationLoungeSimple',
$rLounge->getUpdatedBy(),
false // $doFlush = false para englobarlo en el último flush
);
}
// Se llama al servicio para actualizar en la agenda de las fechas
$this->agendaService->updateDatesLine($id, $userId);
// Actualizamos el Pax de la Agenda
$paxAge = $this->agendaService->calculatePaxForReservation($id);
$this->agendaService->updatePaxLine($id, $paxAge, $userId);
// Ultimo Flush global para aplicar la agenda calculada sin latencias
$em->flush();
$this->addFlash('mensajereservation', 'The Item has been updated.');
}
} catch (\Exception $e) {
$this->addFlash('mensajereservationerror', 'An error occurred: ' . $e->getMessage());
}
// Creamos la Snapshot de las salas y servicios del sistema (LOG)
$version = $this->venueService->createSnapshot($reserva);
return $this->redirectToRoute('reservations_venues_edit_simple', [
'id' => $id,
'token' => null,
'_fragment' => 'btn_quotes'
]);
}
/**
* @Route("/deleteitemservice/{idService}/{idReservation}", name="reservations_venues_deleteitemservice")
*/
public function deleteItemServiceAction($idService, $idReservation, EntityManagerInterface $em, Request $request)
{
$service = $em->getRepository(ReservationService::class)->findOneById($idService);
$em->remove($service);
$em->flush();
$event = 'The Item has been deleted.';
$successMessage = $this->translator->trans($event);
$this->addFlash('mensajereservation', $successMessage);
return $this->redirectToRoute('reservations_venues_edit_simple', array('id' => $idReservation, 'token' => null));
}
/**
* @Route("/updateservicegrid/{id}", name="reservations_venues_updateservicegrid", requirements={"id"="\d+"}, methods={"POST"})
*/
public function updateServiceGridAction(
int $id,
EntityManagerInterface $em,
Request $request,
TokenStorageInterface $tokenStorage,
TranslatorInterface $translator,
SyncronizationsCateringService $syncCateringService,
SyncronizationsAVService $syncAVService,
AppConfigManager $configManager
): Response {
$servicesInput = $request->request->all('services');
if (!is_array($servicesInput)) {
$servicesInput = [];
}
$reserva = $em->getRepository(Reservation::class)->find($id);
if (!$reserva) {
throw new NotFoundHttpException('Reservation not found');
}
$userLogueado = $tokenStorage->getToken()?->getUser();
$userId = $userLogueado instanceof User ? $userLogueado->getId() : null;
$agendaSecurity = null;
// 1. Pre-carga de configuraciones y datos globales
$sessionConfig = $request->getSession()->get('_config', []);
$mcatering = !empty($sessionConfig['mcatering']);
$mav = !empty($sessionConfig['mav']);
$msage = !empty($sessionConfig['msage']);
$cachedSuppliers = [];
// Datos para Sincronización
$htFile = $em->getRepository(HtFile::class)->findByReservation($reserva);
$aveFile = $em->getRepository(AveFiles::class)->findByReservation($reserva);
// Determinamos el VAT Rate base (Lógica original SUCOE como valor por defecto)
$sageIvaCode = ($reserva->IsSucoe()) ? '00' : '03';
$defaultSageVatRate = $em->getRepository(SageVatRates::class)->findOneBy(['sageCode' => $sageIvaCode]);
$updatedCount = 0;
foreach ($servicesInput as $idService => $serviceData) {
$serviceEntity = $em->getRepository(ReservationService::class)->find($idService);
if (!$serviceEntity) {
$serviceEntity = new ReservationService();
$serviceEntity->setReservationId($id);
}
// --- 1. Datos Básicos ---
$supplierId = isset($serviceData['supplier']) ? (int) $serviceData['supplier'] : null;
$serviceEntity->setSupplierId($supplierId);
// --- 2. Agente / Nombre ---
$this->resolveAgentAndName($serviceEntity, $serviceData, $em);
// --- 3. Precios y Numéricos ---
$serviceEntity->setPrice($this->parseCurrency($serviceData['price'] ?? null, (float) $serviceEntity->getPrice()));
$serviceEntity->setCommission($this->parseCurrency($serviceData['commission'] ?? null, (float) $serviceEntity->getCommission(), true));
$serviceEntity->setOver($this->parseCurrency($serviceData['over'] ?? null, (float) $serviceEntity->getOver()));
$serviceEntity->setCurrency($serviceData['currency'] ?? null);
$serviceEntity->setUnits($serviceData['units'] ?? null);
$serviceEntity->setPax($serviceData['pax'] ?? null);
$serviceEntity->setOpCommission($serviceData['opCommission'] ?? null);
$serviceEntity->setOpOver($serviceData['opOver'] ?? null);
$serviceEntity->setOpIva($serviceData['opIva'] ?? null);
// --- 4. Flags ---
$serviceEntity->setToinvoice(array_key_exists('toinvoice', $serviceData));
$serviceEntity->setViewInfo(array_key_exists('viewinfo', $serviceData));
// --- 5. Fechas ---
try {
$startStr = ($serviceData['dateInAt'] ?? '') . ' ' . ($serviceData['start'] ?? '00:00');
$endStr = ($serviceData['dateOutAt'] ?? '') . ' ' . ($serviceData['end'] ?? '00:00');
$serviceEntity->setDateInAt(new DateTime($startStr));
$serviceEntity->setDateOutAt(new DateTime($endStr));
} catch (\Exception $e) {
// Error de fecha silenciado según lógica original
}
$serviceEntity->setUpdatedId($userId);
$serviceEntity->setUpdatedAt(new DateTime('now'));
// --- 6. LÓGICA DE IVA Y ARTÍCULO SAGE (MODIFICADO) ---
$catName = $serviceEntity->getServiceCatName();
// 6.1 Priorizar el IVA enviado desde el formulario
if (isset($serviceData['iva']) && !empty($serviceData['iva'])) {
$selectedVat = $em->getRepository(SageVatRates::class)->find($serviceData['iva']);
if ($selectedVat) {
$serviceEntity->setSageIva($selectedVat);
}
} else {
// Si no se envía IVA (o el select estaba vacío), aplicamos el SUCOE/Default
$serviceEntity->setSageIva($defaultSageVatRate);
}
// 6.2 Buscar el artículo Sage basándonos en el IVA asignado arriba
$sageArticle = $em->getRepository(SageArticle::class)->findOneBy([
'vatType' => $serviceEntity->getSageIva(),
'name' => $catName
]);
if (!$sageArticle && $msage) {
$this->addFlash(
'mensajereservationerror',
'No se ha encontrado el artículo de Sage para el servicio: ' . $catName . ' con el IVA ' . $serviceEntity->getSageIva()?->getIva() . '%. No se ha podido actualizar.'
);
return $this->redirectToRoute('reservations_venues_edit_simple', [
'id' => $id,
'_fragment' => 'btn_srv'
]);
}
$serviceEntity->setSageArticle($sageArticle);
$em->persist($serviceEntity);
if (($serviceEntity->getServiceCatId() == 17)) {
$agendaSecurity[] = array(
'units' => $serviceEntity->getUnits(),
'pax' => $serviceEntity->getPax(),
'dateStart' => $serviceEntity->getDateInAt(),
'dateEnd' => $serviceEntity->getDateOutAt(),
);
}
$updatedCount++;
// --- 7. Sincronizaciones ---
if ($supplierId) {
if (!isset($cachedSuppliers[$supplierId])) {
$cachedSuppliers[$supplierId] = $em->getRepository(Supplier::class)->find($supplierId);
}
$supplier = $cachedSuppliers[$supplierId];
if ($supplier) {
$this->handleSynchronization(
$reserva,
$serviceEntity,
$supplier,
$mcatering,
$mav,
$htFile,
$aveFile,
$userLogueado,
$syncCateringService,
$syncAVService,
$em,
$configManager
);
}
}
}
// Actualizamos la línea de Seguridad
if ($agendaSecurity) {
$this->agendaService->updateSecurityLine($id, $agendaSecurity, $userId);
}
try {
if ($updatedCount > 0) {
$em->flush();
$this->addFlash('mensajereservation', $translator->trans('The Item has been updated.'));
}
} catch (\Exception $e) {
$this->addFlash('mensajereservationerror', $translator->trans('An error occurred: ' . $e->getMessage()));
}
$this->venueService->createSnapshot($reserva);
return $this->redirectToRoute('reservations_venues_edit_simple', [
'id' => $id,
'token' => null,
'_fragment' => 'btn_srv'
]);
}
/**
* @Route("/addloungegeneral", name="reservations_venues_add_lounge_general")
*/
public function addLoungeGeneralAction(EntityManagerInterface $em, Request $request)
{
$reservationsLounge = $request->request->get('lounge_price');
$yaExisteLounge = $em->getRepository(ReservationLoungeDetails::class)->findOneByName($reservationsLounge['name']);
if (!empty($yaExisteLounge)) {
//Si ya existe la sala con ese nombre se envia a la pantalla de edicion de la sala en cuestion
$id = $yaExisteLounge->getId();
return $this->redirectToRoute('reservations_lounge_details', array('id' => $id));
}
$user_logueado = $this->get('security.token_storage')->getToken()->getUser();
$user_id = $user_logueado->getId();
$now = new DateTime('now');
$reservationsLoungeNew = new ReservationLoungeDetails();
$reservationsLoungeNew->setName($reservationsLounge['name']);
$reservationsLoungeNew->setMeters($reservationsLounge['meters']);
$reservationsLoungeNew->setLength($reservationsLounge['length']);
$reservationsLoungeNew->setWidth($reservationsLounge['width']);
$reservationsLoungeNew->setHeight($reservationsLounge['height']);
$reservationsLoungeNew->setCapSchool($reservationsLounge['capschool']);
$reservationsLoungeNew->setCapTheater($reservationsLounge['captheater']);
$reservationsLoungeNew->setCapCocktail($reservationsLounge['capcocktail']);
$reservationsLoungeNew->setCapBanquet($reservationsLounge['capbanquet']);
$reservationsLoungeNew->setCapImperial($reservationsLounge['capimperial']);
$reservationsLoungeNew->setCreatedId($user_id);
$reservationsLoungeNew->setCreatedAt($now);
$reservationsLoungeNew->setUpdatedId($user_id);
$reservationsLoungeNew->setUpdatedAt($now);
try {
$em->persist($reservationsLoungeNew);
$em->flush();
$event = 'The Item has been created.';
$successMessage = $this->translator->trans($event);
$this->addFlash('mensajereservation', $successMessage);
} catch (\Exception $e) {
$event = 'An error occurred: ' . $e->getMessage();
$errorMessage = $this->translator->trans($event);
$this->addFlash('mensajereservationerror', $errorMessage);
}
if (!empty($reservationsLoungeNew->getId())) {
// Esto pertenece a otra entidad
$reservationsLoungeNewDescription = new ReservationLoungeDescription();
$reservationsLoungeNewDescription->setLoungeId($reservationsLoungeNew->getId());
$reservationsLoungeNewDescription->setLanguage($reservationsLounge['language']);
$reservationsLoungeNewDescription->setDescription($reservationsLounge['description']);
$reservationsLoungeNewDescription->setCreatedId($user_id);
$reservationsLoungeNewDescription->setCreatedAt($now);
$reservationsLoungeNewDescription->setUpdatedId($user_id);
$reservationsLoungeNewDescription->setUpdatedAt($now);
try {
$em->persist($reservationsLoungeNewDescription);
$em->flush();
$event = 'The Item has been created.';
$successMessage = $this->translator->trans($event);
$this->addFlash('mensajereservation', $successMessage);
} catch (\Exception $e) {
$event = 'An error occurred: ' . $e->getMessage();
$errorMessage = $this->translator->trans($event);
$this->addFlash('mensajereservationerror', $errorMessage);
}
return $this->redirectToRoute('reservations_lounge_details', array('id' => $reservationsLoungeNew->getId()));
}
return $this->redirectToRoute('reservations_venues_edit_general');
}
/**
* @Route("/addloungedescription/{id}", name="reservations_venues_add_lounge_description")
*/
public function addLoungeDescriptionAction($id, Request $request)
{
$em = $this->getDoctrine()->getManager();
/* Obtengo usuario logueado */
$user_logueado = $this->get('security.token_storage')->getToken()->getUser();
$user_id = $user_logueado->getId();
$now = new DateTime('now');
$reservationsLoungeDescriptoin = $request->request->get('lounge_description');
// $reservationsLoungeDetail = $em->getRepository(ReservationLoungeDetails::class)->findOneById($id);
// $reservationsLoungeDetail->setImportantDescription($reservationsLoungeDescriptoin['importantDescription']);
//
// $em->persist($reservationsLoungeDetail);
// $em->flush();
if (empty($reservationsLoungeDescriptoin['language']) or empty($reservationsLoungeDescriptoin['description'])) {
return $this->redirectToRoute('reservations_lounge_details', array('id' => $id));
}
$newLoungeDescription = new reservationLoungeDescription();
$newLoungeDescription->setLoungeId($id);
$newLoungeDescription->setLanguage($reservationsLoungeDescriptoin['language']);
$newLoungeDescription->setDescription($reservationsLoungeDescriptoin['description']);
$newLoungeDescription->setCreatedId($user_id);
$newLoungeDescription->setUpdatedId($user_id);
$newLoungeDescription->setCreatedAt($now);
$newLoungeDescription->setUpdatedAt($now);
try {
$em->persist($newLoungeDescription);
$em->flush();
$event = 'The Item has been created.';
// $successMessage = $this->translator->trans($event);
$successMessage = 'El elemento ha sido creado.';
$this->addFlash('mensajereservation', $successMessage);
} catch (\Exception $e) {
$event = 'An error occurred: ' . $e->getMessage();
$errorMessage = $this->translator->trans($event);
$this->addFlash('mensajereservationerror', $errorMessage);
}
return $this->redirectToRoute('reservations_lounge_details', array('id' => $id));
}
/**
* @Route("/addwebinfo/{id}", name="reservations_venues_add_web_info")
* Actualiza la información de la sala a presentar en la web, que esta almacenada por defecto
* Actualiza la información del contrato
*/
public function addLoungeWebInfoAction($id, EntityManagerInterface $em, Request $request)
{
$user_logueado = $this->get('security.token_storage')->getToken()->getUser();
$user_id = $user_logueado->getId();
$now = new \DateTimeImmutable('now');
$reservationsLounge = $em->getRepository(ReservationLoungeDetails::class)->findOneById($id);
if (empty($reservationsLounge)) {
$this->addFlash('mensajereservationerror', 'Error, no se ha encontrado la sala con ID: ' . $id);
return $this->redirectToRoute('reservations_venues_edit_general');
}
$reservationsLoungeWebDescription = $request->request->get('lounge_web_description') ?? [];
foreach ($reservationsLoungeWebDescription as $key => $descriptions) {
$reservationsLoungeDetail = $em->getRepository(ReservationLoungeWebDescription::class)->findOneBy(array('lounge' => $reservationsLounge, 'language' => $key));
if (empty($reservationsLoungeDetail)) {
$reservationsLoungeDetail = new ReservationLoungeWebDescription();
$reservationsLoungeDetail->setLounge($reservationsLounge);
$reservationsLoungeDetail->setLanguage($key);
$reservationsLoungeDetail->setCreatedId($user_logueado);
}
$reservationsLoungeDetail->setImportantDescription($descriptions['importantDescription']);
$reservationsLoungeDetail->setImportantDescGeneralText($descriptions['importantDescGeneralText']);
$reservationsLoungeDetail->setImportantDescSchedules($descriptions['importantDescSchedules']);
$reservationsLoungeDetail->setImportantDescParking($descriptions['importantDescParking']);
$reservationsLoungeDetail->setUpdatedId($user_logueado);
$em->persist($reservationsLoungeDetail);
}
$em->flush();
return $this->redirectToRoute('reservations_lounge_details', array('id' => $id));
}
/**
* @Route("/updatedescritiongrid/{id}", name="reservations_venues_updatedescriptiongrid")
*/
public function updateDescriptionGridAction($id, Request $request)
{
$descriptions = $request->request->get('description');
$em = $this->getDoctrine()->getManager();
/* Obtengo usuario logueado */
$user_logueado = $this->get('security.token_storage')->getToken()->getUser();
$user_id = $user_logueado->getId();
foreach ($descriptions as $idDesc => $description) {
$descriptionOriginal = $em->getRepository(ReservationLoungeDescription::class)->findOneById($idDesc);
$descriptionOriginal->setLanguage($description['language']);
$descriptionOriginal->setDescription($description['text']);
$descriptionOriginal->setUpdatedId($user_id);
$descriptionOriginal->setUpdatedAt(new DateTime('now'));
try {
$em->persist($descriptionOriginal);
$em->flush();
$event = 'The Item has been updated.';
// $successMessage = $this->translator->trans($event);
$successMessage = 'El elemento ha sido actualizado.';
$this->addFlash('mensajereservation', $successMessage);
} catch (\Exception $e) {
$event = 'An error occurred: ' . $e->getMessage();
$errorMessage = $this->translator->trans($event);
$this->addFlash('mensajereservationerror', $errorMessage);
}
}
return $this->redirectToRoute('reservations_lounge_details', array('id' => $id));
}
/**
* @Route("/addloungepicture/{id}", name="reservations_venues_add_lounge_picture")
*/
public function addLoungePictureAction($id, EntityManagerInterface $em, Request $request) //, LoggerInterface $logger)
{
/* Obtengo usuario logueado */
$user_logueado = $this->get('security.token_storage')->getToken()->getUser();
$user_id = $user_logueado->getId();
$now = new DateTime('now');
$picturefiles = $request->files->all();
$reservationsLoungeId = $id;
$imagenes = $picturefiles['loungepicturegallery'];
$data = $reservationsLoungeId;
if (!empty($imagenes['image1']) || !empty($imagenes['image2']) || !empty($imagenes['image3']) || !empty($imagenes['image4']) || !empty($imagenes['image5'])) {
$num = 0;
foreach ($imagenes as $img) {
$num = 1 + $num;
if (!is_null($img)) {
$data = $this->CargarImgGalleryAction($reservationsLoungeId, $img, $num, $request);
} //, $logger);
}
} else {
$errorMessage = $this->translator->trans('Error, some fields are empty');
$this->addFlash('mensajegalleryerror', $errorMessage);
}
return $this->redirectToRoute('reservations_lounge_details', array('id' => $id));
}
protected function CargarImgGalleryAction($reservationsLoungeId, $image, $num, Request $request) //, LoggerInterface $logger)
{
$gallery = new ReservationLoungePicture();
$gallery->setLoungeId($reservationsLoungeId);
$gallery->setCreatedAt(new DateTime('now'));
$gallery->setUpdatedAt(new DateTime('now'));
$gallery->setTitle(null);
if ($num == -1) {
$gallery->setTitle('Blueprint');
}
if ($num == 'TEATRO') {
$gallery->setTitle('Teatro');
}
if ($num == 'COCTEL') {
$gallery->setTitle('Coctel');
}
if ($num == 'ESCUELA') {
$gallery->setTitle('Escuela');
}
$id = $reservationsLoungeId;
/* Carga de imagenes */
$calidad = "90";
$calidadpng = "9";
$imageName = md5(rand() * time());
$camino = "assets/images/venues/lounges/";
$extension = $image->guessExtension();
$entrada = 'si';
$image_id = $imageName . '.' . $extension;
$image_temp = $id . '-' . $imageName . '.' . $extension;
$image->move($camino, $image_temp);
// Nombres image
$s = "small-";
$m = "medium-";
$l = "large-";
########################
# Copiar imagen 300 x Altura
########################
$datos = getimagesize($camino . $image_temp);
$anchura = "300";
$altura = "190";
$thumb = imagecreatetruecolor($anchura, $altura);
switch ($extension) {
case 'jpeg':
$img = imagecreatefromjpeg($camino . $image_temp);
imagecopyresampled($thumb, $img, 0, 0, 0, 0, $anchura, $altura, $datos[0], $datos[1]);
imagejpeg($thumb, $camino . $s . $image_id, $calidad);
break;
case 'png':
$img = imagecreatefrompng($camino . $image_temp);
imagecopyresampled($thumb, $img, 0, 0, 0, 0, $anchura, $altura, $datos[0], $datos[1]);
imagepng($thumb, $camino . $s . $image_id, $calidadpng);
break;
case 'gif':
$img = imagecreatefromgif($camino . $image_temp);
imagecopyresampled($thumb, $img, 0, 0, 0, 0, $anchura, $altura, $datos[0], $datos[1]);
imagegif($thumb, $camino . $s . $image_id);
break;
}
########################
# Copiar imagen 600 x Altura
########################
$datos2 = getimagesize($camino . $image_temp);
$anchura2 = "600";
$ratio2 = ($datos2[0] / $anchura2);
$altura2 = round($datos2[1] / $ratio2);
$thumb2 = imagecreatetruecolor($anchura2, $altura2);
switch ($extension) {
case 'jpeg':
$img2 = imagecreatefromjpeg($camino . $image_temp);
imagecopyresampled($thumb2, $img2, 0, 0, 0, 0, $anchura2, $altura2, $datos2[0], $datos2[1]);
imagejpeg($thumb2, $camino . $m . $image_id, $calidad);
break;
case 'png':
$img2 = imagecreatefrompng($camino . $image_temp);
imagecopyresampled($thumb2, $img2, 0, 0, 0, 0, $anchura2, $altura2, $datos2[0], $datos2[1]);
imagepng($thumb2, $camino . $m . $image_id, $calidadpng);
break;
case 'gif':
$img2 = imagecreatefromgif($camino . $image_temp);
imagecopyresampled($thumb2, $img2, 0, 0, 0, 0, $anchura2, $altura2, $datos2[0], $datos2[1]);
imagegif($thumb2, $camino . $m . $image_id);
break;
}
########################
# Copiar imagen 1600 x Altura
########################
$datos3 = getimagesize($camino . $image_temp);
$anchura3 = "1600";
$ratio3 = ($datos3[0] / $anchura3);
$altura3 = round($datos3[1] / $ratio3);
$thumb3 = imagecreatetruecolor($anchura3, $altura3);
switch ($extension) {
case 'jpeg':
$img3 = imagecreatefromjpeg($camino . $image_temp);
imagecopyresampled($thumb3, $img3, 0, 0, 0, 0, $anchura3, $altura3, $datos3[0], $datos3[1]);
imagejpeg($thumb3, $camino . $l . $image_id, $calidad);
break;
case 'png':
$img3 = imagecreatefrompng($camino . $image_temp);
imagecopyresampled($thumb3, $img3, 0, 0, 0, 0, $anchura3, $altura3, $datos3[0], $datos3[1]);
imagepng($thumb3, $camino . $l . $image_id, $calidadpng);
break;
case 'gif':
$img3 = imagecreatefromgif($camino . $image_temp);
imagecopyresampled($thumb3, $img3, 0, 0, 0, 0, $anchura3, $altura3, $datos3[0], $datos3[1]);
imagegif($thumb3, $camino . $l . $image_id);
break;
}
########################
# borrar imagen original
########################
$imagen_borrar = $camino . $image_temp;
unlink($imagen_borrar);
$gallery->setImageSmall($s . $image_id);
$gallery->setImageMedium($m . $image_id);
$gallery->setImageLarge($l . $image_id);
/* Fin Carga de imagenes */
/* Obtengo usuario logueado */
$user_logueado = $this->get('security.token_storage')->getToken()->getUser();
$user_id = $user_logueado->getId();
$gallery->setCreatedId($user_id);
$gallery->setUpdatedId($user_id);
$em = $this->getDoctrine()->getManager();
/* Gestión de eventos en Log */
$user_lastname = $user_logueado->getLastname();
$user_name = $user_logueado->getName();
$user_email = $user_logueado->getEmail();
$user_rol = $user_logueado->getRoles();
$event_url = $request->getPathInfo();
$event_complete = $user_name . ' ' . $user_lastname . ' - ' . $user_email . ' - ' . $user_rol[0] . ' | ' . $event_url;
try {
$em->persist($gallery);
$em->flush();
$event = 'Images from this supplier have been uploaded.';
$successMessage = $this->translator->trans($event);
$this->addFlash('mensajegallery', $successMessage);
} catch (\Exception $e) {
$event = 'An error occurred: ' . $e->getMessage() . ' | transport';
/* Para el usuario */
$errorMessage = $this->translator->trans($event);
$this->addFlash('mensajegalleryerror', $errorMessage);
}
/* Fin Gestión de eventos en Log */
return $id;
}
/**
* @Route("/addloungevideo/{id}", name="reservations_venues_add_lounge_video")
*/
public function addLoungeVideoAction($id, EntityManagerInterface $em, Request $request) //, LoggerInterface $logger)
{
/* Obtengo usuario logueado */
$user_logueado = $this->get('security.token_storage')->getToken()->getUser();
$user_id = $user_logueado->getId();
$now = new DateTime('now');
$urlvideo = $request->request->get('loungevideo');
$urlvideo = $urlvideo['urlvideo'];
$reservationsLoungeId = $id;
if (!empty($urlvideo)) {
switch (true) {
case strpos($urlvideo, 'youtube'):
$patron = '%^ (?:https?://)? (?:www\.)? (?: youtu\.be/ | youtube\.com (?: /embed/ | /v/ | /watch\?v= ) ) ([\w-]{10,12}) ($|&).* $%x';
preg_match($patron, $urlvideo, $parte);
$urvideo_final = 'https://www.youtube.com/embed/' . $parte[1];
break;
case strpos($urlvideo, 'youtu'):
$patron = '%^ (?:https?://)? (?:www\.)? (?: youtu\.be/ | youtube\.com (?: /embed/ | /v/ | /watch\?v= ) ) ([\w-]{10,12}) ($|&).* $%x';
preg_match($patron, $urlvideo, $parte);
$urvideo_final = 'https://www.youtube.com/embed/' . $parte[1];
break;
case strpos($urlvideo, 'vimeo'):
$patron = '%^https?:\/\/(?:www\.|player\.)?vimeo.com\/(?:channels\/(?:\w+\/)?|groups\/([^\/]*)\/videos\/|album\/(\d+)\/video\/|video\/|)(\d+)(?:$|\/|\?)(?:[?]?.*)$%im';
preg_match($patron, $urlvideo, $parte);
$urvideo_final = 'https://player.vimeo.com/video/' . $parte[3];
break;
}
if (!empty($urlvideo) && !empty($urvideo_final)) {
$video = new ReservationLoungeVideo();
$video->setCreatedId($user_id);
$video->setUpdatedId($user_id);
$video->setVideo($urvideo_final);
$video->setLoungeId($reservationsLoungeId);
$video->setCreatedAt($now);
$video->setUpdatedAt($now);
$em->persist($video);
$em->flush();
}
}
if (empty($urlvideo)) {
$errorMessage = $this->translator->trans('Error, some fields are empty');
$this->addFlash('mensajegalleryerror', $errorMessage);
}
return $this->redirectToRoute('reservations_lounge_details', array('id' => $id));
}
/**
* @Route("/deleteloungevideo/{id}", name="reservations_venues_delete_lounge_video")
*/
public function deleteLoungeVideoAction($id, EntityManagerInterface $em, Request $request) //, LoggerInterface $logger)
{
$video = $em->getRepository(ReservationLoungeVideo::class)->findOneById($id);
$idLounge = $video->getLoungeId();
try {
$em->remove($video);
$em->flush();
// $event = 'The Item has been deleted.';
$successMessage = 'El elemento ha sido eliminado.';
// $successMessage = $this->translator->trans($event);
$this->addFlash('mensajereservation', $successMessage);
} catch (\Exception $e) {
$event = 'An error occurred: ' . $e->getMessage();
$errorMessage = $this->translator->trans($event);
$this->addFlash('mensajereservationerror', $errorMessage);
}
return $this->redirectToRoute('reservations_lounge_details', array('id' => $idLounge));
}
/**
* @Route("/addloungeblueprints/{id}", name="reservations_venues_add_lounge_blueprints")
*/
public function addLoungeBlueprintsAction($id, EntityManagerInterface $em, Request $request) //, LoggerInterface $logger)
{
/* Obtengo usuario logueado */
$user_logueado = $this->get('security.token_storage')->getToken()->getUser();
$user_id = $user_logueado->getId();
$now = new DateTime('now');
$picturefiles = $request->files->all();
$reservationsLoungeId = $id;
$imagen = $picturefiles['loungepicturegalleryblueprints'];
$data = $reservationsLoungeId;
if (!empty($imagen)) {
$num = -1;
$data = $this->CargarImgGalleryAction($reservationsLoungeId, $imagen, $num, $request); //, $logger);
} else {
$errorMessage = $this->translator->trans('Error, some fields are empty');
$this->addFlash('mensajegalleryerror', $errorMessage);
}
return $this->redirectToRoute('reservations_lounge_details', array('id' => $id));
}
/**
* @Route("/addpicturemounting/{id}", name="reservations_venues_add_lounge_picture_mounting")
*/
public function addLoungePictureMountingAction($id, EntityManagerInterface $em, Request $request) //, LoggerInterface $logger)
{
/* Obtengo usuario logueado */
$user_logueado = $this->get('security.token_storage')->getToken()->getUser();
$user_id = $user_logueado->getId();
$now = new DateTime('now');
$picturefiles = $request->files->all();
$reservationsLoungeId = $id;
$imagen = $picturefiles['picturemounting'];
$data = $reservationsLoungeId;
if (!empty($imagen)) {
$num = $request->request->get('picturemounting');
$num = $num['type'];
$data = $this->CargarImgGalleryAction($reservationsLoungeId, $imagen, $num, $request); //, $logger);
} else {
$errorMessage = $this->translator->trans('Error, some fields are empty');
$this->addFlash('mensajegalleryerror', $errorMessage);
}
return $this->redirectToRoute('reservations_lounge_details', array('id' => $id));
}
/**
* @Route("/updatedimmensions/{id}", name="update_dimmensions")
*/
public function updateDimmensionsAction($id, EntityManagerInterface $em, Request $request)
{
$reservationsLounge = $em->getRepository(ReservationLoungeDetails::class)->findOneById($id);
$newData = $request->request->get('loungedimmensions');
$reservationsLounge->setMeters($newData['meters']);
$reservationsLounge->setLength($newData['length']);
$reservationsLounge->setWidth($newData['width']);
$reservationsLounge->setHeight($newData['height']);
$reservationsLounge->setCapSchool($newData['capSchool']);
$reservationsLounge->setCapTheater($newData['capTheater']);
$reservationsLounge->setCapCocktail($newData['capCocktail']);
$reservationsLounge->setCapBanquet($newData['capBanquet']);
$reservationsLounge->setCapImperial($newData['capImperial']);
/* Obtengo usuario logueado */
$user_logueado = $this->get('security.token_storage')->getToken()->getUser();
$user_id = $user_logueado->getId();
$now = new DateTime('now');
$reservationsLounge->setUpdatedId($user_id);
$reservationsLounge->setUpdatedAt($now);
try {
$em->persist($reservationsLounge);
$em->flush();
$event = 'The Note has been created succesfully.';
$successMessage = $this->translator->trans($event);
$this->addFlash('mensaje', $successMessage);
} catch (\Exception $e) {
$event = 'An error occurred: ' . $e->getMessage();
/* Para el usuario */
$errorMessage = $this->translator->trans($event);
$this->addFlash('mensajeerror', $errorMessage);
}
return $this->redirectToRoute('reservations_lounge_details', array('id' => $id));
}
/**
* @Route("/get_lounges_by_space", name="venues_get_lounges_by_space", methods={"GET"})
*/
public function getLoungesBySpaceAction(Request $request, EntityManagerInterface $em): JsonResponse
{
$spaceId = $request->query->get('space_id');
$lounges = [];
if ($spaceId) {
$repo = $em->getRepository(ReservationLoungeDetails::class);
$results = $repo->findBy(['space' => $spaceId], ['name' => 'ASC']);
foreach ($results as $lounge) {
$lounges[] = [
'id' => $lounge->getId(),
'name' => $lounge->getName()
];
}
}
return new JsonResponse($lounges);
}
/**
* @Route("/addvisit", name="reservations_venues_addvisit", methods={"GET", "POST"})
*/
public function addVisitAction(EntityManagerInterface $em, Request $request)
{
$visit = new ReservationVisit();
$visit->setDateStart(new \DateTime());
// REFACTORIZACIÓN: El array 'agent_choices' ya no es necesario.
$form = $this->createForm(VisitEditType::class, $visit);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
// Al estar la lógica dentro de la Entidad, esto ya guarda ambos IDs automáticamente
return $this->processVisitForm($form, $visit, $em, $request, true);
}
// Listado de visitas (para la tabla inferior)
$visitas = $em->getRepository(ReservationVisit::class)
->createQueryBuilder('v')
->leftJoin('v.agent', 'a')
->addSelect('a')
->orderBy('v.dateStart', 'DESC')
->setMaxResults(50)
->getQuery()
->getResult();
return $this->render('MDS/VenuesBundle/reservations/add-visit.html.twig', [
'visitas' => $visitas,
'form' => $form->createView(),
]);
}
/**
* @Route("/editvisit/{id}", name="venues_edit_visit", methods={"GET", "POST"})
*/
public function editVisitAction(Request $request, EntityManagerInterface $em, int $id): Response
{
$visit = $em->getRepository(\App\MDS\VenuesBundle\Entity\ReservationVisit::class)->find($id);
if (!$visit) {
throw $this->createNotFoundException('Visita no encontrada');
}
// REFACTORIZACIÓN: Ya no necesitamos pasar el array de 'agent_choices'
$form = $this->createForm(\App\MDS\VenuesBundle\Form\VisitEditType::class, $visit);
// Preload manual fields (fechas)
if ($visit->getDateStart() instanceof \DateTimeInterface) {
$form->get('visit_date')->setData($visit->getDateStart());
$form->get('visit_time')->setData($visit->getDateStart()->format('H:i'));
}
// REFACTORIZACIÓN: Todo el bloque de "Agent mapping" SE ELIMINA.
// Symfony ahora hace el mapeo automáticamente porque quitamos el 'mapped' => false del formulario.
// Space / Lounge mapping
$loungeId = $visit->getIdLounge();
$loadedLounge = null;
if ($loungeId) {
$loadedLounge = $em->getRepository(ReservationLoungeDetails::class)->find($loungeId);
if ($loadedLounge) {
$form->get('lounge')->setData($loadedLounge);
// Force space from lounge
if ($loadedLounge->getSpace()) {
$form->get('space')->setData($loadedLounge->getSpace());
}
}
}
if (!$loadedLounge && $visit->getSpace()) {
$form->get('space')->setData($visit->getSpace());
}
// Reservation mapping
if ($visit->getIdReservation()) {
$res = $em->getRepository(Reservation::class)->find($visit->getIdReservation());
if ($res) {
$form->get('reservation')->setData($res);
}
}
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
return $this->processVisitForm($form, $visit, $em, $request, false);
}
return $this->render('MDS/VenuesBundle/reservations/edit-visit.html.twig', [
'form' => $form->createView(),
'visit' => $visit,
]);
}
/**
* @Route("/createvisit", name="reservations_venues_createvisit", methods={"GET", "POST"})
*/
public function createVisitAction(EntityManagerInterface $em, Request $request)
{
// Redirect logic to addVisitAction to use the same form handling
return $this->addVisitAction($em, $request);
}
private function getAgentChoices(EntityManagerInterface $em): array
{
$users = $em->getRepository(\App\Entity\User::class)
->createQueryBuilder('u')
->select('partial u.{id, name, lastname}')
// AÑADIMOS EL FILTRO POR EQUIPOS AQUÍ
->where('u.team IN (:teams)')
->setParameter('teams', [4, 16])
->orderBy('u.id', 'ASC')
->getQuery()
->getResult();
$agentChoices = [];
foreach ($users as $u) {
// PHP 8.1: Uso del operador nullsafe (?->) para simplificar la lógica
$label = $u->getFullName() ?: ($u->getName() ?: 'Usuario #' . $u->getId());
$agentChoices[$label] = $u->getId();
}
return $agentChoices;
}
private function processVisitForm($form, $visit, EntityManagerInterface $em, Request $request, bool $isNew)
{
/* Obtengo usuario logueado */
$user_logueado = $this->getUser();
// 1. Agent
$selAgentId = $form->get('agent')->getData();
if ($selAgentId) {
$agent = $em->getRepository(\App\Entity\User::class)->find($selAgentId);
$visit->setAgent($agent);
}
// 2. Date/Time -> dateStart / dateEnd
$selDate = $form->get('visit_date')->getData(); // DateTime object
$selTime = $form->get('visit_time')->getData(); // String "H:i"
if ($selDate && $selTime) {
[$h, $m] = explode(':', $selTime);
$start = (clone $selDate)->setTime((int) $h, (int) $m, 0);
$visit->setDateStart($start);
$visit->setDateEnd($start);
// Legacy hour/min fields
$visit->setHourStart($h);
$visit->setMinStart($m);
$visit->setHourEnd(sprintf('%02d', (int) $h + 1));
$visit->setMinEnd($m);
}
// 3. Space (mapped=true, handled automatically)
// Ensure space is set on entity.
// 4. Lounge (mapped=false)
$lounge = $form->get('lounge')->getData(); // ReservationLoungeDetails entity
if ($lounge) {
$visit->setIdLounge($lounge->getId());
} else {
$visit->setIdLounge(null); // or 0
}
// 5. Reservation
$res = $form->get('reservation')->getData();
if ($res) {
$visit->setIdReservation($res->getId());
// Append title if creating? Legacy logic did: $title . ' - ' . $res->getTitle()
// But title is mapped field now.
// Maybe we should append only if it's not already there?
// Leaving title as user typed it in form.
} else {
$visit->setIdReservation(null);
}
if ($isNew) {
$visit->setType('Visit');
$visit->setCreatedAt(new \DateTime());
$visit->setCreatedId($user_logueado->getId());
$visit->setUpdatedAt(new \DateTime());
$visit->setUpdatedId($user_logueado->getId());
$em->persist($visit);
$msg = 'Visita creada correctamente';
$route = 'reservations_venues_addvisit';
} else {
$visit->setUpdatedAt(new \DateTime());
// $visit->setUpdatedId($user_logueado->getId()); // if method exists
$msg = 'Visita actualizada correctamente';
$route = 'reservations_venues_addvisit';
}
$em->flush();
$this->addFlash('mensajeclient', $msg);
return $this->redirectToRoute($route);
}
/**
* @Route("/deletevisit/{id}", name="get_reservations_deletevisit")
*/
public function deleteVisitAction($id, EntityManagerInterface $em, Request $request)
{
$visit = $em->getRepository(ReservationVisit::class)->findOneById($id);
if (!empty($visit)) {
$em->remove($visit);
$em->flush();
}
return $this->redirectToRoute('reservations_venues_addvisit');
}
/**
* @Route("/sendconfirmationrequestmail/{id}", name="reservations_venues_send_confirmation_request_mail")
* Enviar correo a Salvador y Rafael Guerrero para que la reserva (id) pase al estado confirmado
*/
public function sendConfirmationRequestMailAction($id, EntityManagerInterface $em, Request $request)
{
$user_logueado = $this->get('security.token_storage')->getToken()->getUser();
$user_id = $user_logueado->getId();
$mailArrayTo = [];
$mailAlert = [];
// $mailArrayTo['salvador@avexpress.tv'] = 'salvador@avexpress.tv';
$mailArrayTo['rafael.guerrero@inout-travel.com'] = 'rafael.guerrero@inout-travel.com';
//
// $dataGP = $this->disponibilidadVenues($id);
// $dataAV = $this->disponibilidadAvExpress($id);
$dataLounges = array();
// foreach ($dataGP as $item){
// $reservationsLounges = $em->getRepository(ReservationLoungeSimple::class)->findBy(array('idReservation'=>$item->getId(),'type'=>null));
// foreach ($reservationsLounges as $elem){ $dataLounges[$item->getId()][] = $elem; }
// }
$dataLounges = [];
$dataLounges[$id] = $em->getRepository(ReservationLoungeSimple::class)
->findBy(['idReservation' => $id, 'type' => null]);
$reserva = $em->getRepository(Reservation::class)->findOneById($id);
$agente = $em->getRepository(User::class)->findOneById($user_id);
$mailAddressFrom = $agente->getEmail();
$mailSubject = 'Confirmación de reserva: ' . $reserva->getTitle();
$mensajePopup = '';
$mailBody = 'Estimado administrador,' .
'<br><br>' . $agente->getName() . ' ' . $agente->getLastName() . ' ha solicitado la confirmación de la reserva:' .
'<br><br>' . $reserva->getTitle() . ' con ID: ' . $reserva->getId() .
'<br>Este evento incia el día ' . $reserva->getDateStart()->format('d/m/Y') . ' a las ' . $reserva->getDateStart()->format('H:i') . ' y finaliza el día ' . $reserva->getDateEnd()->format('d/m/Y') . ' a las ' . $reserva->getDateEnd()->format('H:i') . '<br><br><br>';
if (!empty($dataGP) or !empty($dataAV)) {
if (!empty($dataGP)) {
$mensajePopup .= 'No se puede CONFIRMAR, conflicto con:' . '<br><br>';
// Conflictos con otros eventos en Venues
$mailSubject = '⚠️ ALERTA️ ‼️ DOBLE CONFIRMADO MISMA SALA' . $mailSubject;
$mailBody = $mailBody . 'Este evento coincide con la(s) reserva(s): <br>';
foreach ($dataGP as $res) {
$mailBody = $mailBody . 'Reserva: ' . $res->getTitle() . ', con ID: ' . $res->getId() . ', fecha de inicio: ' . $res->getDateStart()->format('d/m/Y') . ' a las ' . $res->getDateStart()->format('H:i') . ', fecha de finalización: ' . $res->getDateEnd()->format('d/m/Y') . ' a las ' . $res->getDateEnd()->format('H:i');
if (!empty($dataLounges[$res->getId()])) {
$mailBody = $mailBody . ', Salas: ';
foreach ($dataLounges[$res->getId()] as $reservationsLoungeItem) {
$mailBody = $mailBody . $reservationsLoungeItem->getLoungeName() . ', ';
}
$mailBody = $mailBody . '<br>';
}
$mensajePopup .= 'Reserva: ' . $res->getTitle() . ', con ID: ' . $res->getId() . '<br>';
}
$mailBody = $mailBody . '<br><br>';
}
if (!empty($dataAV)) {
// Conflictos con otros eventos de AvExpress
$mailBody = $mailBody . 'Este evento coincide en AV con el expediente(s): <br>';
foreach ($dataAV as $file) {
$mailBody = $mailBody . 'Expediente: ' . $file->getTitle() . ', con ID: ' . $file->getId() . ', fecha de inicio: ' . $file->getDateStart()->format('d/m/Y H:i') . ', fecha de finalización: ' . $file->getDateEnd()->format('d/m/Y H:i') . '<br>';
}
}
$mailAlert = array('mailBody' => $mailBody, 'mailSubject' => $mailSubject);
}
$mailBody = $mailBody . '<br><br><a href="https://mantevenues.mante.solutions/venues/">CALENDARIO GREEN PATIO</a>';
$mailBody = $mailBody . '<br><br> <a href="https://mantevenues.mante.solutions/venues/adminconfirmres/y/' . $id . '">"SI"</a> deseo confirmar la reserva.';
$mailBody = $mailBody . '<br><br> <a href="https://mantevenues.mante.solutions/venues/adminconfirmres/n/' . $id . '">"NO"</a> deseo confirmar la reserva.';
$mailBody = $mailBody . '<br><br><br> <a href="https://inout.mante.solutions">"PARA QUE LOS ENLACES FUNCIONEN, ANTES DEBES INCIAR SESION"</a><br><br>';
// Se envia el correo pidiendo la confirmacion
$this->sendMailLot($mailAddressFrom, $mailArrayTo, $mailSubject, $mailBody);
//Alerta a Gabriela, Agente modificador del expediente y Mariale
if (!empty($dataGP)) {
$mailArrayTo = [];
$agentAlert = $em->getRepository(User::class)->findOneById($reserva->getUpdatedBy());
if (!empty($agentAlert) and ($agentAlert->getStatus() == 1)) {
$mailArrayTo[$agentAlert->getEmail()] = $agentAlert->getEmail();
}
$agentAlert = $em->getRepository(User::class)->findOneById(82); // Gabriela Bracho
if (!empty($agentAlert) and ($agentAlert->getStatus() == 1)) {
$mailArrayTo[$agentAlert->getEmail()] = $agentAlert->getEmail();
}
$agentAlert = $em->getRepository(User::class)->findOneById(129); // Maria Alejandra Martinez
if (!empty($agentAlert) and ($agentAlert->getStatus() == 1)) {
$mailArrayTo[$agentAlert->getEmail()] = $agentAlert->getEmail();
}
$this->sendMailLot($mailAddressFrom, $mailArrayTo, $mailSubject, $mailAlert['mailBody']);
}
if (!empty($mensajePopup)) {
$this->addFlash('mensajereservationerror', $mensajePopup);
}
return $this->redirectToRoute('reservations_venues_edit_simple', array('id' => $id, 'token' => null));
}
/**
* @Route("/adminconfirmres/{op}/{id}", name="reservations_venues_admin_confirm_res")
* Confirmacion del administrador, positiva o negativa (op) de la reserva (id)
*/
public function adminConfirmationReservationAction($op, $id, EntityManagerInterface $em, Request $request)
{
/* Obtengo usuario logueado */
$user_logueado = $this->get('security.token_storage')->getToken()->getUser();
$user_id = $user_logueado->getId();
$reserva = $em->getRepository(Reservation::class)->findOneById($id);
$mailArrayTo = array();
$mailArrayTo['salvador@avexpress.tv'] = 'salvador@avexpress.tv';
$mailArrayTo['rafael.guerrero@inout-travel.com'] = 'rafael.guerrero@inout-travel.com';
$mailArrayTo['comercial@venues.es'] = 'comercial@venues.es';
$mailArrayTo['comercial2@venues.es'] = 'comercial2@venues.es';
// $mailArrayTo['gustavo.ayala@develup.solutions'] = 'gustavo.ayala@develup.solutions';
$agente = $em->getRepository(User::class)->findOneById($user_id);
$mailAddressFrom = $agente->getEmail();
$mailSubject = 'Confirmación de reserva: ' . $reserva->getTitle();
switch ($op) {
case 'y':
// Se va a Confirmar la reserva
$reserva->setStatus('Confirmed');
$reserva->setUpdatedBy($user_id);
$reserva->setUpdatedAt(new DateTime('now'));
$em->persist($reserva);
$em->flush();
$mailBody = 'Estimado agente,' .
'<br><br>' . $agente->getName() . ' ' . $agente->getLastName() . ' ha confirmado la reserva:' .
'<br><br>' . $reserva->getTitle() . ' con ID: ' . $reserva->getId() .
'<br>Este evento incia el día ' . $reserva->getDateStart()->format('d/m/Y H:i') . ' y finaliza el día ' . $reserva->getDateEnd()->format('d/m/Y H:i') . '<br><br><br>';
// $mailBody = $mailBody .'<br><br> <a href="http://127.0.0.1:8000/venues/editsimple/'.$id.'">Ir a la reserva</a>';
$mailBody = $mailBody . '<br><br> <a href="https://mantevenues.mante.solutions/venues/editsimple/' . $id . '">Ir a la reserva</a>';
break;
case 'n':
// No se va a Confirmar la reserva - Pasa a un editar (para ajustar fechas etc)
$reserva->setStatus('Cotizado');
$reserva->setUpdatedBy($user_id);
$reserva->setUpdatedAt(new DateTime('now'));
$em->persist($reserva);
$em->flush();
$mailBody = 'Estimado agente,' .
'<br><br>' . $agente->getName() . ' ' . $agente->getLastName() . ' ha rechazado la confirmación de la reserva:' .
'<br><br>' . $reserva->getTitle() . ' con ID: ' . $reserva->getId() .
'<br>Este evento inciaba el día ' . $reserva->getDateStart()->format('d/m/Y H:i') . ' y finalizaba el día ' . $reserva->getDateEnd()->format('d/m/Y H:i') . '<br><br><br>' .
'<br>POR FAVOR, PONGANSE EN CONTACTO PARA DETEMINAR UN NUEVO HORARIO<br><br><br>';
// $mailBody = $mailBody .'<br><br> <a href="http://127.0.0.1:8000/venues/editsimple/'.$id.'">Ir a la reserva</a>';
$mailBody = $mailBody . '<br><br> <a href="http://inout.mante.solutions/venues/editsimple/' . $id . '">Ir a la reserva</a>';
break;
default:
break;
}
// Enviar correo al agente (envia a las 2 agentes? enviar al creador de la reserva?)
$this->sendMailLot($mailAddressFrom, $mailArrayTo, $mailSubject, $mailBody);
echo 'Ha finalizado correctamente su sesión. Puede cerrar la aplicación';
exit();
}
/**
* @Route("/viewcontract/{id}", name="reservations_venues_view_contract")
* Vista del contrato de la reserva (id)
*/
public function viewContractReservationAction($id, EntityManagerInterface $em, Request $request)
{
// El cliente es obligatorio y no puede ser null
// El contacto es obligatorio y no puede ser null, será el representante del cliente en el contrato
// En el expediente solo deben estar las salas definitivas para el contrato
$reserva = $em->getRepository(Reservation::class)->findOneById($id);
$contractOrigin = $reserva->getContract();
$dateStart = $reserva->getDateStart();
$dateEnd = $reserva->getDateEnd();
//Buscamos el representante
$representante = $reserva->getClientContact();
$representante = $em->getRepository(ClientContact::class)->findOneById($representante);
$representanteCorreo = $representante->getEmail();
$representante = $representante->getName() . ' ' . $representante->getLastName();
//Buscamos el cliente
$client = $reserva->getClient();
$client = $em->getRepository(Client::class)->findOneById($client);
// La fecha de inicio y fin del evento incluyen montaje y desmontaje
// Determinamos el primer y ultimo dia del evento y lo modificamos en la reserva sin tocar la base de datos
$allOnlySalasReservadas = $em->getRepository(ReservationLoungeSimple::class)->findBy(array('idReservation' => $id, 'type' => null));
if (!empty($allOnlySalasReservadas)) {
$reserva->setDateStart($allOnlySalasReservadas[0]->getDateStart());
$reserva->setDateEnd($allOnlySalasReservadas[0]->getDateEnd());
foreach ($allOnlySalasReservadas as $item) {
if ($item->getDateStart() < $reserva->getDateStart()) {
$reserva->setDateStart($item->getDateStart());
}
if ($item->getDateEnd() > $reserva->getDateEnd()) {
$reserva->setDateEnd($item->getDateEnd());
}
}
}
//Generamos la fecha actual
$fechaActual = new DateTime('now');
$mesActual = $fechaActual->format('m');
switch ($mesActual) {
case '01':
$mesActual = 'enero';
break;
case '02':
$mesActual = 'febrero';
break;
case '03':
$mesActual = 'marzo';
break;
case '04':
$mesActual = 'abril';
break;
case '05':
$mesActual = 'mayo';
break;
case '06':
$mesActual = 'jumio';
break;
case '07':
$mesActual = 'julio';
break;
case '08':
$mesActual = 'agosto';
break;
case '09':
$mesActual = 'septiembre';
break;
case '10':
$mesActual = 'octubre';
break;
case '11':
$mesActual = 'noviembre';
break;
case '12':
$mesActual = 'diciembre';
break;
default:
$mesActual = '';
break;
}
$contract00 = '';
$contract01 = '';
$contract02 = '';
$contract03 = '';
$contract04 = '';
$contract05 = '';
//Generamos la fecha de inicio
$fechaInicio = $reserva->getDateStart()->format('m');
switch ($fechaInicio) {
case '01':
$mesInicio = 'enero';
break;
case '02':
$mesInicio = 'febrero';
break;
case '03':
$mesInicio = 'marzo';
break;
case '04':
$mesInicio = 'abril';
break;
case '05':
$mesInicio = 'mayo';
break;
case '06':
$mesInicio = 'jumio';
break;
case '07':
$mesInicio = 'julio';
break;
case '08':
$mesInicio = 'agosto';
break;
case '09':
$mesInicio = 'septiembre';
break;
case '10':
$mesInicio = 'octubre';
break;
case '11':
$mesInicio = 'noviembre';
break;
case '12':
$mesInicio = 'diciembre';
break;
default:
$mesInicio = '';
break;
}
$fechaInicio = $reserva->getDateStart()->format('d') . ' de ' . $mesInicio . ' del ' . $reserva->getDateStart()->format('Y') . ' ';
$contract06 = '';
$horaInicio = $reserva->getDateStart()->format('H:i') . ' ';
$contract07 = '';
//Generamos la fecha de fin
$fechaFin = $reserva->getDateEnd()->format('m');
switch ($fechaFin) {
case '01':
$mesFin = 'enero';
break;
case '02':
$mesFin = 'febrero';
break;
case '03':
$mesFin = 'marzo';
break;
case '04':
$mesFin = 'abril';
break;
case '05':
$mesFin = 'mayo';
break;
case '06':
$mesFin = 'jumio';
break;
case '07':
$mesFin = 'julio';
break;
case '08':
$mesFin = 'agosto';
break;
case '09':
$mesFin = 'septiembre';
break;
case '10':
$mesFin = 'octubre';
break;
case '11':
$mesFin = 'noviembre';
break;
case '12':
$mesFin = 'diciembre';
break;
default:
$mesFin = '';
break;
}
if ($reserva->getDateStart()->format('ymd') != $reserva->getDateEnd()->format('ymd')) {
$fechaFin = ' el día ' . $reserva->getDateEnd()->format('d') . ' de ' . $mesFin . ' del ' . $reserva->getDateEnd()->format('Y') . ' a las ' . $reserva->getDateEnd()->format('H:i') . ' ';
$contractAlfa = '';
$contract08 = $fechaFin . $contractAlfa;
} else {
// El evento empieza y termina el mismo dia
$horaFin = ' las ' . $reserva->getDateEnd()->format('H:i') . ' ';
$contractAlfa = '';
$contract08 = $horaFin . $contractAlfa;
}
// Buscamos las salas
$allSalasReservadas = $em->getRepository(ReservationLoungeSimple::class)->findByIdReservation($id);
$arrayTextoSalas = array();
foreach ($allSalasReservadas as $item) {
$arrayTextoSalas[$item->getIdLounge()] = $item->getIdLounge();
}
$textoSalas = '';
$logAllGreen = false; // Si se asigna el edificio completo no hay que verificar mas salas
foreach ($arrayTextoSalas as $item) {
$sala = $em->getRepository(ReservationLoungeDetails::class)->findOneById($item);
switch ($sala->getId()) {
case '1':
$textoSalas = '<b>TODO EL EDIFICIO EN EXCLUSIVA</b>';
$logAllGreen = true;
break;
case '16':
if (empty($textoSalas)) {
$textoSalas = '<b>Sala Plenaria La Imprenta, Sala Invernadero</b>';
} else {
$textoSalas = $textoSalas . '<b>Sala Plenaria La Imprenta, Sala Invernadero</b>';
}
break;
case '17':
if (empty($textoSalas)) {
$textoSalas = '<b>Sala Plenaria La Imprenta, Sala Invernadero, Sala Escenario</b>';
} else {
$textoSalas = $textoSalas . '<b>Sala Plenaria La Imprenta, Sala Invernadero, Sala Escenario</b>';
}
break;
default:
if (!$logAllGreen) {
if (empty($textoSalas)) {
$textoSalas = '<b>' . $sala->getName() . '</b>';
} else {
$textoSalas = $textoSalas . '<b>, ' . $sala->getName() . '</b>';
}
}
break;
}
}
$contract09 = '';
$cierre = $reserva->getDateEnd()->format('H:i') . ' horas del día ' . $reserva->getDateEnd()->format('d') . ' de ' . $mesFin . ' del ' . $reserva->getDateEnd()->format('Y');
$contract10 = '';
$pax = $reserva->getPax();
$contract11 = '';
$contract12 = '</span></span><b><span lang="ES-TRAD" style="font-size:12.0pt"><o:p></o:p></span></b></font></p><p class="MsoListParagraph"><!--[if !supportLists]--><font face="Arial"><span lang="ES-TRAD" style="font-size:12.0pt">-<span style="font-variant-numeric: normal; font-variant-east-asian: normal; font-stretch: normal; font-size: 7pt; line-height: normal;"> </span></span><!--[endif]--><span class="Hyperlink1"><span lang="ES-TRAD" style="font-size:12.0pt">Salas a utilizar: </span></span><span class="Ninguno"><b><u><span lang="ES-TRAD">';
$contract13 = '</span></u></b></span><b><span lang="ES-TRAD" style="font-size:12.0pt"><o:p></o:p></span></b></font></p>';
// Se asume que los montajes seran como maximo de dos dias
$montaje = array();
$mesInicioMontaje = '';
$mesFinMontaje = '';
foreach ($allSalasReservadas as $item) {
if ($item->getType() == 'Montaje') {
if (empty($montaje)) {
$montaje[0] = $item->getDateStart();
switch ($item->getDateStart()->format('m')) {
case '01':
$mesInicioMontaje = 'enero';
break;
case '02':
$mesInicioMontaje = 'febrero';
break;
case '03':
$mesInicioMontaje = 'marzo';
break;
case '04':
$mesInicioMontaje = 'abril';
break;
case '05':
$mesInicioMontaje = 'mayo';
break;
case '06':
$mesInicioMontaje = 'jumio';
break;
case '07':
$mesInicioMontaje = 'julio';
break;
case '08':
$mesInicioMontaje = 'agosto';
break;
case '09':
$mesInicioMontaje = 'septiembre';
break;
case '10':
$mesInicioMontaje = 'octubre';
break;
case '11':
$mesInicioMontaje = 'noviembre';
break;
case '12':
$mesInicioMontaje = 'diciembre';
break;
default:
$mesInicioMontaje = '';
break;
}
} else {
$montaje[1] = $item->getDateEnd();
switch ($item->getDateEnd()->format('m')) {
case '01':
$mesFinMontaje = 'enero';
break;
case '02':
$mesFinMontaje = 'febrero';
break;
case '03':
$mesFinMontaje = 'marzo';
break;
case '04':
$mesFinMontaje = 'abril';
break;
case '05':
$mesFinMontaje = 'mayo';
break;
case '06':
$mesFinMontaje = 'jumio';
break;
case '07':
$mesFinMontaje = 'julio';
break;
case '08':
$mesFinMontaje = 'agosto';
break;
case '09':
$mesFinMontaje = 'septiembre';
break;
case '10':
$mesFinMontaje = 'octubre';
break;
case '11':
$mesFinMontaje = 'noviembre';
break;
case '12':
$mesFinMontaje = 'diciembre';
break;
default:
$mesFinMontaje = '';
break;
}
}
}
}
switch (sizeof($montaje)) {
case 1:
$textoMontaje = $montaje[0]->format('d') . ' de ' . $mesInicioMontaje . ' del ' . $montaje[0]->format('Y');
break;
case 2:
if ($mesInicioMontaje == $mesFinMontaje) {
// Dos dias de montaje en el mismo mes
$textoMontaje = $montaje[0]->format('d') . ' y ' . $montaje[1]->format('d') . ' de ' . $mesInicioMontaje . ' del ' . $montaje[0]->format('Y');
} else {
// Dos dias de montaje con diferentes meses, ejemplo 31/03 y 01/04
$textoMontaje = $montaje[0]->format('d') . ' de ' . $mesInicioMontaje . ' y ' . $montaje[1]->format('d') . ' de ' . $mesFinMontaje . ' del ' . $montaje[0]->format('Y');
}
break;
default:
$textoMontaje = null;
break;
}
if (!empty($textoMontaje)) {
$textoMontaje = '<p class="MsoListParagraph"><!--[if !supportLists]--><font face="Arial"><span lang="ES-TRAD" style="font-size:12.0pt">-<span style="font-variant-numeric: normal; font-variant-east-asian: normal; font-stretch: normal; font-size: 7pt; line-height: normal;"> </span></span><!--[endif]--><span class="Hyperlink1"><span lang="ES-TRAD" style="font-size:12.0pt">MONTAJE: ' . $textoMontaje . '</span></span><b><span lang="ES-TRAD" style="font-size:12.0pt"><o:p></o:p></span></b></font></p>';
}
// Se asume que los desmontajes seran como maximo de dos dias
$desmontaje = array();
$mesInicioDesmontaje = '';
$mesFinDesmontaje = '';
foreach ($allSalasReservadas as $item) {
if ($item->getType() == 'Desmontaje') {
if (empty($desmontaje)) {
$desmontaje[0] = $item->getDateStart();
switch ($item->getDateStart()->format('m')) {
case '01':
$mesInicioDesmontaje = 'enero';
break;
case '02':
$mesInicioDesmontaje = 'febrero';
break;
case '03':
$mesInicioDesmontaje = 'marzo';
break;
case '04':
$mesInicioDesmontaje = 'abril';
break;
case '05':
$mesInicioDesmontaje = 'mayo';
break;
case '06':
$mesInicioDesmontaje = 'jumio';
break;
case '07':
$mesInicioDesmontaje = 'julio';
break;
case '08':
$mesInicioDesmontaje = 'agosto';
break;
case '09':
$mesInicioDesmontaje = 'septiembre';
break;
case '10':
$mesInicioDesmontaje = 'octubre';
break;
case '11':
$mesInicioDesmontaje = 'noviembre';
break;
case '12':
$mesInicioDesmontaje = 'diciembre';
break;
default:
$mesInicioDesmontaje = '';
break;
}
} else {
$desmontaje[1] = $item->getDateEnd();
switch ($item->getDateEnd()->format('m')) {
case '01':
$mesFinDesmontaje = 'enero';
break;
case '02':
$mesFinDesmontaje = 'febrero';
break;
case '03':
$mesFinDesmontaje = 'marzo';
break;
case '04':
$mesFinDesmontaje = 'abril';
break;
case '05':
$mesFinDesmontaje = 'mayo';
break;
case '06':
$mesFinDesmontaje = 'jumio';
break;
case '07':
$mesFinDesmontaje = 'julio';
break;
case '08':
$mesFinDesmontaje = 'agosto';
break;
case '09':
$mesFinDesmontaje = 'septiembre';
break;
case '10':
$mesFinDesmontaje = 'octubre';
break;
case '11':
$mesFinDesmontaje = 'noviembre';
break;
case '12':
$mesFinDesmontaje = 'diciembre';
break;
default:
$mesFinDesmontaje = '';
break;
}
}
}
}
switch (sizeof($desmontaje)) {
case 1:
$textoDesmontaje = $desmontaje[0]->format('d') . ' de ' . $mesInicioDesmontaje . ' del ' . $desmontaje[0]->format('Y');
break;
case 2:
if ($mesInicioDesmontaje == $mesFinDesmontaje) {
// Dos dias de montaje en el mismo mes
$textoDesmontaje = $desmontaje[0]->format('d') . ' y ' . $desmontaje[1]->format('d') . ' de ' . $mesInicioDesmontaje . ' del ' . $desmontaje[0]->format('Y');
} else {
// Dos dias de montaje con diferentes meses, ejemplo 31/03 y 01/04
$textoDesmontaje = $desmontaje[0]->format('d') . ' de ' . $mesInicioDesmontaje . ' y ' . $desmontaje[1]->format('d') . ' de ' . $mesFinDesmontaje . ' del ' . $desmontaje[0]->format('Y');
}
break;
default:
$textoDesmontaje = 'Mismo día al finalizar el evento desde las 17 horas hasta las 00:00 horas';
break;
}
if (!empty($textoDesmontaje)) {
$textoDesmontaje = '';
}
$contract14 = '';
if (empty($mesInicioMontaje)) {
switch ($dateStart->format('m')) {
case '01':
$mesInicioMontajeZ = 'enero';
break;
case '02':
$mesInicioMontajeZ = 'febrero';
break;
case '03':
$mesInicioMontajeZ = 'marzo';
break;
case '04':
$mesInicioMontajeZ = 'abril';
break;
case '05':
$mesInicioMontajeZ = 'mayo';
break;
case '06':
$mesInicioMontajeZ = 'jumio';
break;
case '07':
$mesInicioMontajeZ = 'julio';
break;
case '08':
$mesInicioMontajeZ = 'agosto';
break;
case '09':
$mesInicioMontajeZ = 'septiembre';
break;
case '10':
$mesInicioMontajeZ = 'octubre';
break;
case '11':
$mesInicioMontajeZ = 'noviembre';
break;
case '12':
$mesInicioMontajeZ = 'diciembre';
break;
default:
$mesInicioMontajeZ = '';
break;
}
$tiempoCedido = $dateStart->format('H:i') . ' horas del día ' . $dateStart->format('d') . ' de ' . $mesInicioMontajeZ . ' del ' . $dateStart->format('Y') . ' hasta las ';
} else {
$tiempoCedido = $dateStart->format('H:i') . ' horas del día ' . $dateStart->format('d') . ' de ' . $mesInicioMontaje . ' del ' . $dateStart->format('Y') . ' hasta las ';
}
if (empty($mesInicioDesmontaje)) {
switch ($dateStart->format('m')) {
case '01':
$mesInicioDesmontajeZ = 'enero';
break;
case '02':
$mesInicioDesmontajeZ = 'febrero';
break;
case '03':
$mesInicioDesmontajeZ = 'marzo';
break;
case '04':
$mesInicioDesmontajeZ = 'abril';
break;
case '05':
$mesInicioDesmontajeZ = 'mayo';
break;
case '06':
$mesInicioDesmontajeZ = 'jumio';
break;
case '07':
$mesInicioDesmontajeZ = 'julio';
break;
case '08':
$mesInicioDesmontajeZ = 'agosto';
break;
case '09':
$mesInicioDesmontajeZ = 'septiembre';
break;
case '10':
$mesInicioDesmontajeZ = 'octubre';
break;
case '11':
$mesInicioDesmontajeZ = 'noviembre';
break;
case '12':
$mesInicioDesmontajeZ = 'diciembre';
break;
default:
$mesInicioDesmontajeZ = '';
break;
}
$tiempoCedido = $tiempoCedido . $dateEnd->format('H:i') . ' horas del día ' . $dateEnd->format('d') . ' de ' . $mesInicioDesmontajeZ . ' del ' . $dateEnd->format('Y');
} else {
$tiempoCedido = $tiempoCedido . $dateEnd->format('H:i') . ' horas del día ' . $dateEnd->format('d') . ' de ' . $mesInicioDesmontaje . ' del ' . $dateEnd->format('Y');
}
$contract15 = '';
// 5. Normas de Seguridad
$contract16 = '';
// 6. Coste, plazo y forma de pago
$data = $this->CalculosTotalesEditSimple($reserva->getId());
$contract17 = '';
// 8. Reserva
$contract18 = '';
// 9. Confidencialidad y publicidad
// 11. Derechos de imagen y propiedad intelectual
// 12. Prevencion de la corrupcion
// 13. Proteccion de datos personales
// 14. Responsabilidad
$contract19 = '';
// 15. Comunicaciones
$contract20 = '';
// 16. Cesión
// 17. Nulidad Parcial
// 18. Fuerza Mayor
// 19. Acuerdo Completo
$contract21 = '';
// Normas de uso
$contract22 = '';
// Logotipo de Venues centrado
$contract23 = '
<div class="col-md-4 col-xs-6" ></div><div class="col-md-4 col-xs-6" ><p class="MsoNormal" align="right" style="margin-bottom: background-image: initial; background-position: initial; background-size: initial; background-repeat: initial; background-attachment: initial; background-origin: initial; background-clip: initial;"><b><span lang="EN-US" style="font-size: 9pt;"><font face="Arial"><o:p><br></o:p></font></span></b></p><p class="MsoNormal" align="right" style="margin-bottom: 7.5pt; text-align: right; background-image: initial; background-position: initial; background-size: initial; background-repeat: initial; background-attachment: initial; background-origin: initial; background-clip: initial;"><b><span lang="EN-US" style="font-size: 9pt;"><font face="Arial"><o:p><br></o:p></font></span></b></p><p class="MsoNormal" align="right" style="margin-bottom: 7.5pt; text-align: right; background-image: initial; background-position: initial; background-size: initial; background-repeat: initial; background-attachment: initial; background-origin: initial; background-clip: initial;"><img src="data:image/png;base64,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fZ00cOlJabFBKCM9wqH1T8ZwI+pwdXgQ8q5GCnSwAPJnIX1P5iPDmP+VSN8o7rVJYEWZlhKB9XTUUfDUF1lzUP5R/C0IRCh3syynDg5C0NkN8+gdegLBOsorZBIcqw6sCID1mPa7OlgWllNeM7tbg1UkLHt4f1AHS0K5dsz7Sh0Moad7IJbpceQ3aFYBTHMSxn1dByuC7XsElvdr+Csnr62w/Bmky4vbot4KWKuDkaRNo8y1OlgA9f8txhU85JR9gzYqD1zvwbIfJe0Df7+F4fO0yCDk34Q0TwdpS4XG8ani142EBBU00v2GBhc0sK1xsO2Jj8MOfjTG3fVjxeTAlnlLgJHPxZfHeXLwYDkLehF6/6zgfVqBZZR3Moc9jMnDch4ul6zyGeX2k9e98LEggMo6l6pDlhHzKHhwIsNy8BW/+iPbqriskhODzHdwO8o20G1bNcxj2+LtU47sdyzDR3VwGKlTkg6WNH/+/J2jer2zZ8/epVT9sg3l5KKDlZosl+VYpp3kM/b9QcXbW1SyHVGHvIdasP3zpH5sm2HvIyN/R+RPlfvx8u4sPh8tD3N19CAJukM7I0RERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERFuKSZP+F0vlO4rFICMJAAAAAElFTkSuQmCC" alt="" style="float: left;"></p><p class="MsoNormal" style="margin-bottom: 7.5pt; text-indent: 3pt; background-image: initial; background-position: initial; background-size: initial; background-repeat: initial; background-attachment: initial; background-origin: initial; background-clip: initial;"></p></div></div></div></div><div class="col-md-4 col-xs-6" ></div>
';
//Generamos el contrato
$contract = $contract00 . '<b>' . ' ' . $client->getName() . '</b>' . ' ' . $contract01 . 'CIF ' . $client->getIdDocument() . ' ' .
$contract02 . '<b>' . ' ' . $client->getAddress() . '</b>' . ',' . $contract03 . ' ' . $representante . '.' .
$contract04 . $reserva->getTitle() . $contract05 . $fechaInicio . $contract06 . $horaInicio . $contract07 .
$contract08 . $textoSalas . $contract09 . $cierre . $contract10 . $pax . $contract11 . $fechaInicio .
$contract12 . $textoSalas . $contract13 . $textoMontaje . $textoDesmontaje . $contract14 . $tiempoCedido .
$contract15 . $contract16 . $contract17 . $contract18 . $contract19 . $contract20 . $contract21 . $contract22 . $contract23;
// Si no habia contracto originalmente en la reserva se actualiza
if (empty($contractOrigin)) {
$reserva->setContract($contract);
$em->persist($reserva);
$em->flush();
} else {
$contract = $contractOrigin;
}
return $this->render('MDS/VenuesBundle/reservations/view-contract-reservation.html.twig', array('id' => $id, 'contract' => $contract, ));
}
/**
* @Route("/createdeposit/{id}", name="reservations_venues_createdeposit")
*/
public function createDepositAction($id, EntityManagerInterface $em, Request $request)
{
$newRequest = $request->request->get('reservation_deposit');
/* Obtengo usuario logueado */
$user_logueado = $this->get('security.token_storage')->getToken()->getUser();
$user_id = $user_logueado->getId();
$newDeposit = new ReservationDeposit();
$newDeposit->setReservationId($id);
if (empty($newRequest['date'])) {
$newDeposit->setDate(new DateTime('now'));
} else {
$newDeposit->setDate(new DateTime($newRequest['date']));
}
if (empty($newRequest['description'])) {
$newDeposit->setDescription(null);
} else {
$newDeposit->setDescription($newRequest['description']);
}
if (empty($newRequest['amount'])) {
$newDeposit->setAmount(null);
} else {
$newDeposit->setAmount($newRequest['amount']);
}
if (array_key_exists('isDone', $newRequest)) {
$newDeposit->setIsDone(true);
} else {
$newDeposit->setIsDone(false);
}
$newDeposit->setCreatedId($user_id);
$newDeposit->setUpdatedId($user_id);
$em->persist($newDeposit);
$em->flush();
return $this->redirectToRoute('reservations_venues_edit_simple', array('id' => $id, 'token' => null, '_fragment' => 'btn_dpt'));
}
/**
* @Route("/depositupdate/{id}", name="reservations_venues_deposit_update")
*/
public function depositUpdateAction($id, EntityManagerInterface $em, Request $request)
{
$newRequest = $request->request->get('reservation_deposit_isdone_pending');
$depósito = $em->getRepository(ReservationDeposit::class)->findOneById($id);
if (array_key_exists('isDone', $newRequest)) {
$depósito->setIsDone(true);
} else {
$depósito->setIsDone(false);
}
/* Obtengo usuario logueado */
$user_logueado = $this->get('security.token_storage')->getToken()->getUser();
$user_id = $user_logueado->getId();
$depósito->setUpdatedAt(new DateTime('now'));
$depósito->setUpdatedId($user_id);
$em->persist($depósito);
$em->flush();
return $this->redirectToRoute('reservations_venues_edit_simple', array('id' => $depósito->getReservationId(), 'token' => null, '_fragment' => 'btn_dpt'));
}
/**
* @Route("/loadedreservations", name="reservations_venues_loaded_reservations")
*/
public function loadedReservationsAction(EntityManagerInterface $em, Request $request)
{
$hoy = new DateTime('now');
$diaInicio = new DateTime($hoy->format('Y-m') . '-01');
// Se buscan las reservas creadas desde el inicio de mes
$parameters = array('diaInicio' => $diaInicio, );
$dql = 'SELECT i
FROM VenuesBundle:Reservation i
WHERE i.createdAt > :diaInicio';
$query = $em->createQuery($dql)->setParameters($parameters);
$reservas = $query->getResult();
return $this->render('MDS/VenuesBundle/reservations/list-loaded-reservations.html.twig', array('reservations' => $reservas, 'itemsOfSearch' => '', ));
}
/**
* @Route("/searchreservations", name="reservations_venues_search_reservations")
*/
public function searchReservationsAction(EntityManagerInterface $em, Request $request)
{
$searchloaded = $request->request->get('searchloaded');
$dateStart = new \DateTime($searchloaded['date_start']);
$dateEnd = new \DateTime($searchloaded['date_end']);
$itemsOfSearch = ' Entre las fechas: ' . $dateStart->format('d/m/Y') . ' y ' . $dateEnd->format('d/m/Y');
// Se buscan las reservas creadas en las fechas solicitadas
$parameters = array('diaInicio' => $dateStart, 'diaFin' => $dateEnd, );
$dql = 'SELECT i
FROM VenuesBundle:Reservation i
WHERE i.createdAt BETWEEN :diaInicio AND :diaFin';
$query = $em->createQuery($dql)->setParameters($parameters);
$reservas = $query->getResult();
return $this->render('MDS/VenuesBundle/reservations/list-loaded-reservations.html.twig', array('reservations' => $reservas, 'itemsOfSearch' => $itemsOfSearch, ));
}
/**
* Cambia las descripciones de las reservas al idioma seleccionado
* @Route("/changeLanguage/{id}/{idLanguage}", name="reservations_venues_change_language", methods={"GET"})
*/
public function changeLanguageAction(int $id, int $idLanguage, EntityManagerInterface $em, SerializerInterface $serializerInterface): JsonResponse
{
$descriptions = $em->getRepository(ReservationLoungeSimple::class)->findBy(array('idReservation' => $id));
$idiomas = array();
foreach ($descriptions as $description) {
$reservationsLoungeDetails = $em->getRepository(ReservationLoungeDetails::class)->findOneById($description->getIdLounge());
$idiomas[$description->getIdLounge()] = $em->getRepository(ReservationLoungeWebDescription::class)->findOneBy(array('lounge' => $reservationsLoungeDetails, 'language' => $idLanguage));
}
$idiomas = $serializerInterface->serialize($idiomas, 'json', [
'groups' => ['reservation_lounge_web_description:read']
]);
$idiomas = json_decode($idiomas, true);
return $this->json([
'status' => JsonResponse::HTTP_OK,
'idiomas' => $idiomas,
], JsonResponse::HTTP_OK);
}
private function sendMail($mailAddressFrom, $mailAddressTo, $mailSubject, $mailBody)
{
$em = $this->getDoctrine()->getManager();
$agent = $em->getRepository(User::class)->findOneByEmail($mailAddressFrom);
$client = $em->getRepository(Client::class)->findOneByEmail($mailAddressTo);
if (empty($client)) {
$client = $em->getRepository(ClientContact::class)->findOneByEmail($mailAddressTo);
} // Si el cliente era null puede ser un client contact
if (!empty($client)) {
$replyTo = array(
$client->getEmail() => $client->getName(),
$agent->getEmail() => $agent->getName() . ' ' . $agent->getLastName(),
);
} else {
// El AddressTo es un contacto no registrado
$replyTo = array(
$mailAddressTo => $mailAddressTo,
$agent->getEmail() => $agent->getName() . ' ' . $agent->getLastName(),
);
}
$agentMail = $mailAddressFrom;
$mailAgent = $agentMail;
//Se prepara el correo con los agentes a notificar
$firmGmail = $agent->getFirmGmail();
$data = array(
'body' => $mailBody,
'firm' => $firmGmail,
);
// EJECUTAR ENVIO DE ALERTA PARA EL AGENTE
$transporter = new \Swift_SmtpTransport();
$transporter->setHost('smtp.gmail.com')
->setEncryption('ssl') //ssl / tls
->setPort(465) // 465 / 587
->setUsername('desarrollo@develup.solutions')
->setPassword('utvh hzoi wfdo ztjs');
// ->setPassword('MeDITeRRANeAN_Develup30102023#');
$mailer = new \Swift_Mailer($transporter);
$message = new \Swift_Message();
$message->setSubject($mailSubject)
->setSender($agentMail)
->setFrom(array("desarrollo@develup.solutions" => "Venues"))
->setReplyTo($agentMail)
->setTo($replyTo)
->setBody(
$this->renderView(
'mail/structure-mail.html.twig',
array('data' => $data)
),
'text/html'
);
// $mailer->send($message); Rafa dijo que no queria envío de correos con el cliente ya que se haría mediante la cotización Web (04/02/2025)
return true;
}
private function makeAlert($reservaId, $clientId, $clientMail, $agentId, $agentMail)
{
$em = $this->getDoctrine()->getManager();
$alertaPrevia = $em->getRepository(ReservationMailAlertClient::class)->findOneByReservationId($reservaId);
$reserva = $em->getRepository(Reservation::class)->findOneById($reservaId);
$dias = $reserva->getDaysBlock();
if (empty($dias) or !(is_numeric($dias))) {
$dias = 7;
}
$diasMenosDos = $dias - 2;
/* Obtengo usuario logueado */
$user_logueado = $this->get('security.token_storage')->getToken()->getUser();
$user_id = $user_logueado->getId();
$hoy = new \DateTime("now", NULL);
$hoyMasCinco = $hoy;
$hoyMasCinco->add(new DateInterval('P' . $diasMenosDos . 'D')); // 5 dias despues, 48 horas antes de la cancelacion (o los especificados)
$hoyMasCinco->add(new DateInterval("PT2H")); // Ajustamos la diferencia con el reloj del servidor
$hoy = new \DateTime("now", NULL);
$hoyMasSiete = $hoy;
$hoyMasSiete->add(new DateInterval('P' . $dias . 'D')); // Siete dias despues (o los especificados)
$hoyMasSiete->add(new DateInterval("PT2H"));
//Si no hay una alerta previa se hace la alerta
if (empty($alertaPrevia)) {
$alerta = new ReservationMailAlertClient();
$alerta->setReservationId($reservaId);
$alerta->setClientId($clientId);
$alerta->setClientMail($clientMail);
$alerta->setAgentId($agentId);
$alerta->setAgentMail($agentMail);
$alerta->setAlertDateTime($hoyMasCinco); // A los 5 dias se alerta (o los especificados)
$alerta->setAlertSended(false);
$alerta->setCancelDateTime($hoyMasSiete); // A los 7 dias se cancela (o los especificados)
$alerta->setCancelSended(false);
$alerta->setOldReservationId(null); // Aqui se guardara el Id de reserva cuando se vaya a eliminar el registro (solo se pondra reservationId a 0)
$alerta->setCreatedAt($hoy);
$alerta->setCreatedId($user_id);
$em->persist($alerta);
$em->flush();
}
return true;
}
private function benefitForReservation($id)
{
$em = $this->getDoctrine()->getManager();
$reserva = $em->getRepository(Reservation::class)->findOneById($id);
$reservationsLounges = $em->getRepository(ReservationLoungeSimple::class)->findByIdReservation($id);
$services = $em->getRepository(ReservationService::class)->findByReservationId($id);
$payedLounges = array();
$payedServices = array();
$unPayedServices = array();
// Salas
foreach ($reservationsLounges as $item) {
// Si la sala esta en ReservationInvoiceItems se encuentra facturado, en caso contraio, no lo esta o ha sido rectificado
$reservationsLoungeInvoicedItem = $em->getRepository(ReservationInvoiceItems::class)->findOneByLngControlId($item->getId());
if (!empty($reservationsLoungeInvoicedItem)) {
$payedLounges[] = $item;
} // Esta facturado el Item
}
// Servicios
foreach ($services as $item) {
// Si el servicio esta en ReservationInvoiceItems se encuentra facturado, en caso contraio, no lo esta o ha sido rectificado
$serviceInvoicedItem = $em->getRepository(ReservationInvoiceItems::class)->findOneBySrvControlId($item->getId());
if (!empty($serviceInvoicedItem)) {
// Esta facturado el Item
$payedServices[] = $item;
} else {
// No esta facturado el Item o fue rectificado
$unPayedServices[] = $item;
}
}
$benefit = 0;
$payed = 0;
// Se suman los pagos
foreach ($payedLounges as $item) {
$benefit = $benefit + (float) $item->getServicePrice();
$payed = $payed + (float) $item->getServicePrice();
}
foreach ($payedServices as $item) {
$benefit = $benefit + (float) $item->getPrice();
$payed = $payed + (float) $item->getPrice();
}
// Se restan los impagos
foreach ($unPayedServices as $item) {
// Se verifica el check de toinvoice por si el servicio se facturara a futuro (Requisito de Rafa)
if ($item->getToinvoice()) {
$benefit += (float) $item->getPrice();
$payed += (float) $item->getPrice();
} else {
// No esta pagado y no esta marcado "Para facturar"
$benefit = $benefit - (float) $item->getPrice();
}
}
// Porcentaje de beneficio
$percBenefit = ($benefit * 100);
if (!($payed == 0)) {
$percBenefit = $percBenefit / $payed;
} else {
$percBenefit = 0;
}
;
return array(
'benefit' => $benefit,
'percBenefit' => $percBenefit,
'payedLounges' => $payedLounges,
'payedServices' => $payedServices,
'unPayedServices' => $unPayedServices,
);
}
private function verificarStatusInicialyFinal($id, $user_id, $estadoInicial, $estadoFinal)
{
$em = $this->getDoctrine()->getManager();
// Nueva validación: No permitir pasar a 'Invoiced' manualmente si no hay facturas
if ($estadoFinal === 'Invoiced' && $estadoInicial !== 'Invoiced') {
$invoiceRepository = $em->getRepository(ReservationInvoice::class);
$invoiceRecRepository = $em->getRepository(ReservationInvoiceRec::class);
$hasInvoices = !empty($invoiceRepository->findByReservationId($id)) || !empty($invoiceRecRepository->findByReservationId($id));
if (!$hasInvoices) {
$this->addFlash('mensajereservationerror', 'No se puede cambiar el estado a FACTURADO si la reserva no tiene facturas.');
return $estadoInicial;
}
}
$reserva = $em->getRepository(Reservation::class)->findOneById($id);
$user_logueado = $em->getRepository(User::class)->findOneById($user_id);
$newStatus = 'Pendiente';
//Este Switch ya no es necesario
switch ($estadoInicial) {
case 'Bloqueo':
// De bloqueo solo se sale si el usuario es Salvador o un Admin O si se va a Cancelar "Deleted" o "Cotizado"
// if (($user_logueado->getRole() == 'ROLE_ADMIN') or ($user_id == 14) or $estadoFinal == 'Deleted' or $estadoFinal == 'Cotizado'){
if ($estadoFinal == 'Deleted' or $estadoFinal == 'Cotizado') {
$newStatus = $estadoFinal;
} else {
// No se cambia el estado
$newStatus = $estadoInicial;
}
break;
case 'Pendiente':
// De Pendiente solo se sale si el usuario es Salvador o un Admin O si se va a Cancelar "Deleted"
$newStatus = $estadoFinal;
// if (($user_logueado->getRole() == 'ROLE_ADMIN') or ($user_id == 14) or $estadoFinal == 'Deleted'){
if ($estadoFinal == 'Deleted') {
$newStatus = $estadoFinal;
} else {
// No se cambia el estado
$newStatus = $estadoInicial;
}
break;
case 'Deleted':
// De Cancelado solo se sale si el usuario es Salvador o un Admin O "Bloqueo" o "Pendiente"
// if (($user_logueado->getRole() == 'ROLE_ADMIN') or ($user_id == 14) or $estadoFinal == 'Bloqueo' or $estadoFinal == 'Pendiente'or $estadoFinal == 'Cotizado'){
if ($estadoFinal == 'Bloqueo' or $estadoFinal == 'Pendiente' or $estadoFinal == 'Cotizado') {
$newStatus = $estadoFinal;
} else {
// No se cambia el estado
$newStatus = $estadoInicial;
}
break;
case 'Cotizado':
$newStatus = $estadoFinal;
// De Cotizado solo se sale si el usuario es Salvador o un Admin O a O "Bloqueo" o "Pendiente" o "Cancelado"
// if (($user_logueado->getRole() == 'ROLE_ADMIN') or ($user_id == 14) or $estadoFinal == 'Bloqueo' or $estadoFinal == 'Pendiente' or $estadoFinal == 'Deleted'){
if ($estadoFinal == 'Bloqueo' or $estadoFinal == 'Pendiente' or $estadoFinal == 'Deleted' or $estadoFinal == 'Confirmed') {
$newStatus = $estadoFinal;
}
break;
case 'Invoiced':
// De Facturado no se debe salir a menos que se rectifique
// Si todas las facturas del expediente se encuentran rectificadas pasamos al estado "Confirmado" sino seguimos en "Facturado"
$reservaInvoices = $em->getRepository(ReservationInvoice::class)->findByReservationId($id);
$estanTodasRectificadas = true;
foreach ($reservaInvoices as $item) {
$reservaInvoiceRect = $em->getRepository(ReservationInvoiceRec::class)->findOneByInvoiceToRec($item->getId());
if (empty($reservaInvoiceRect)) {
$estanTodasRectificadas = false;
} else {
$estanTodasRectificadas = ($estanTodasRectificadas and true);
}
}
if ($estanTodasRectificadas) {
$newStatus = 'Confirmed';
} else {
$newStatus = $estadoInicial;
}
break;
case 'Confirmed':
// Se puede ir a cualquier estado
$newStatus = $estadoFinal;
break;
default:
// No hacer nada con el campo Status
$newStatus = $estadoInicial;
break;
}
$newStatus = $estadoFinal;
return $newStatus;
}
private function disponibilidadVenues($id)
{
// $id Id de la reserva
$em = $this->getDoctrine()->getManager();
$reserva = $em->getRepository(Reservation::class)->findOneById($id);
// $reservationsLounges = $em->getRepository(ReservationLoungeSimple::class)->findByIdReservation($id);
//Buscamos salas que tengamos entre el inicio y fin del evento a confirmar
//Sumamos un dia ya que por solicitud de Salva deseamos saber que eventos hay un dia antes y un dia despues
$fechaInicio = new \DateTime($reserva->getDateStart()->format('Y-m-d H:i:s'));
// $fechaInicio->sub(new \DateInterval("P1D"));
$fechaFin = new \Datetime($reserva->getDateEnd()->format('Y-m-d H:i:s'));
// $fechaFin->add(new \DateInterval("P1D"));
// Los eventos que debemos verificar son los Confirmados y Facturados
// $parameters = array(
// 'reservaId' => $id,
// 'dateStart' => $fechaInicio,
// 'dateEnd' => $fechaFin,
// 'facturado' => 'Invoiced',
// 'confirmado' => 'Confirmed',
// );
// $dql = 'SELECT r
// FROM VenuesBundle:Reservation r
// INNER JOIN VenuesBundle:ReservationLoungeSimple l WITH r.id = l.idReservation
// WHERE (r.status = :facturado OR r.status = :confirmado)
// AND (not(r.id = :reservaId))
// AND ((l.dateStart >= :dateStart and l.dateStart <= :dateEnd))';
//
// $query = $em->createQuery($dql)->setParameters($parameters);
// $reservationInDates = $query->getResult();
$parameters = array(
'dateStart' => $fechaInicio,
'dateEnd' => $fechaFin,
'facturado' => 'Invoiced',
'confirmado' => 'Confirmed',
);
$dql = 'SELECT r
FROM VenuesBundle:Reservation r
INNER JOIN VenuesBundle:ReservationLoungeSimple l WITH r.id = l.idReservation
WHERE (r.status = :facturado OR r.status = :confirmado)
AND (
l.dateStart <= :dateEnd
AND l.dateEnd >= :dateStart
)';
$query = $em->createQuery($dql)->setParameters($parameters);
$reservationsInConflict = $query->getResult();
$arrayUso = [];
$arrayAlert = [];
$arrayAlertMontDesmont = []; // Nuevo array para almacenar conflictos de montaje y desmontaje
if (sizeof($reservationsInConflict) > 1) {
foreach ($reservationsInConflict as $resConflict) {
$reservationsLoungesConflict = $em->getRepository(ReservationLoungeSimple::class)->findByIdReservation($resConflict->getId());
foreach ($reservationsLoungesConflict as $item) {
$type = $item->getType(); // Puede ser NULL, "Montaje" o "Desmontaje"
$dateKey = $item->getDateStart()->format('Ymd');
$reservationsLoungeId = $item->getIdLounge();
$reservationId = $item->getIdReservation();
if (in_array($reservationsLoungeId, [2, 4, 9])) {
// Plenaria, Invernadero y Escenario se consideran la misma sala
$arrayUso[2][$dateKey][$reservationId] = empty($type) ? 'Sala' : $type;
$arrayUso[4][$dateKey][$reservationId] = empty($type) ? 'Sala' : $type;
;
$arrayUso[9][$dateKey][$reservationId] = empty($type) ? 'Sala' : $type;
;
} else {
$lngDetails = $em->getRepository(ReservationLoungeDetails::class)->findOneById($reservationsLoungeId);
if (empty($lngDetails->getCombo())) {
$arrayUso[$reservationsLoungeId][$dateKey][$reservationId] = empty($type) ? 'Sala' : $type;
} else {
$arrayComboLounges = explode(",", $lngDetails->getCombo());
foreach ($arrayComboLounges as $indLounge) {
$arrayUso[$indLounge][$dateKey][$reservationId] = empty($type) ? 'Sala' : $type;
}
}
}
}
}
foreach ($arrayUso as $idLounge => $dates) {
foreach ($dates as $dateKey => $reservations) {
// Si el ID de la reserva está presente, obtener su dato
$datoId = isset($reservations[$id]) ? $reservations[$id] : 0;
foreach ($reservations as $reservationId => $dato) {
if ($reservationId != $id) {
if ($datoId === "Sala" && $dato === "Sala") {
$arrayAlert[$reservationId][] = array('dateKey' => $dateKey, 'idLounge' => $idLounge, 'reservationId' => $reservationId);
} elseif (($datoId === "Montaje" || $datoId === "Desmontaje") && ($dato === "Montaje" || $dato === "Desmontaje")) {
$arrayAlertMontDesmont[$reservationId][] = array('dateKey' => $dateKey, 'idLounge' => $idLounge, 'reservationId' => $reservationId);
} elseif ($datoId === "Sala" && ($dato === "Montaje" || $dato === "Desmontaje")) {
$arrayAlert[$reservationId][] = array('dateKey' => $dateKey, 'idLounge' => $idLounge, 'reservationId' => $reservationId);
} elseif (($datoId === "Montaje" || $datoId === "Desmontaje") && $dato === "Sala") {
$arrayAlert[$reservationId][] = array('dateKey' => $dateKey, 'idLounge' => $idLounge, 'reservationId' => $reservationId);
}
}
}
}
}
}
$reservationInDates = [];
if (!empty($arrayAlert)) {
foreach ($arrayAlert as $key => $item) {
$resvConf = $em->getRepository(Reservation::class)->findOneById($key);
$reservationInDates[] = $resvConf;
}
// La reserva no puede pasar a confirmada
$reserva->setStatus('Cotizado');
$em->persist($reserva);
$em->flush();
} else {
$mensajeWarning = '<br>';
if (!empty($arrayAlertMontDesmont)) {
foreach ($arrayAlertMontDesmont as $key => $item) {
$mensajeWarning .= 'Reserva ID: ' . $key . '<br>';
}
$this->addFlash('mensajereservationerror', 'ADVERTENCIA, se han guardado los cambios, pero hay coincidencias en los Montajes y/o Desmontajes' . $mensajeWarning);
$reservationInDates = [];
}
}
return $reservationInDates;
}
// private function disponibilidadAvExpress($id){
// // $id Id de la reserva de Venues que vamos a confirmar
// $em = $this->getDoctrine()->getManager();
// $reserva = $em->getRepository(Reservation::class)->findOneById($id);
//
// //Sumamos un dia ya que por solicitud de Salva deseamos saber que eventos hay un dia antes y un dia despues
// $fechaInicio = new \Datetime($reserva->getDateStart()->format('Y-m-d'));
// $fechaInicio->sub(new \DateInterval("P1D"));
// $fechaFin = new \Datetime($reserva->getDateEnd()->format('Y-m-d 23:59'));
// $fechaFin->add(new \DateInterval("P1D"));
//
// $parameters = array( 'dateStart' => $fechaInicio, 'dateEnd' => $fechaFin, );
//
// $dql = 'SELECT i
// FROM AvexpressBundle:AveFiles i
// WHERE (i.dateStart <= i.dateEnd)
// AND (
// (i.dateStart <= :dateStart AND i.dateEnd >= :dateEnd)
// OR (i.dateEnd = :dateStart)
// OR (i.dateEnd > :dateStart AND i.dateEnd <= :dateEnd)
// OR (i.dateStart = :dateStart)
// OR (i.dateStart > :dateStart AND i.dateStart <= :dateEnd)
// OR (i.dateStart = :dateEnd)
// )
// ORDER BY i.dateStart ASC';
//
// $query = $em->createQuery($dql)->setParameters($parameters);
// $avFilesInDates = $query->getResult();
//
// return $avFilesInDates;
// }
private function sendMailLot($mailAddressFrom, $mailArrayTo, $mailSubject, $mailBody)
{
$em = $this->getDoctrine()->getManager();
$agent = $em->getRepository(User::class)->findOneByEmail($mailAddressFrom);
$replyTo = array();
// Verificamos que los correos sean validos
foreach ($mailArrayTo as $item) {
if (filter_var($item, FILTER_VALIDATE_EMAIL)) {
$replyTo[$item] = $item;
}
}
$agentMail = $mailAddressFrom;
$mailAgent = $agentMail;
//Se prepara el correo con los agentes a notificar
$firmGmail = $agent->getFirmGmail();
$data = array('body' => $mailBody, 'firm' => $firmGmail, );
// EJECUTAR ENVIO DE ALERTA PARA EL AGENTE
$transporter = new \Swift_SmtpTransport();
$transporter->setHost('smtp.gmail.com')
->setEncryption('ssl') //ssl / tls
->setPort(465) // 465 / 587
->setUsername('desarrollo@develup.solutions')
->setPassword('utvh hzoi wfdo ztjs');
// ->setPassword('MeDITeRRANeAN_Develup30102023#');
$mailer = new \Swift_Mailer($transporter);
$message = new \Swift_Message();
$message->setSubject($mailSubject)
->setSender($agentMail)
->setFrom(array("desarrollo@develup.solutions" => "System Mante 3.0"))
->setReplyTo($agentMail)
->setTo($replyTo)
->setBody(
$this->renderView(
'mail/structure-mail.html.twig',
array('data' => $data)
),
'text/html'
);
$mailer->send($message);
return true;
}
private function notificacionReservasPorCotizar()
{
// Se buscan las reservas en estado "Iniciado" y se notifica a todos los
// agentes de Venues, Solo se notifica 1 vez por dia
// Solo se mantendran las alertas de los ultimos 6 meses
$em = $this->getDoctrine()->getManager();
$alertas = $em->getRepository(ReservationAlertStarted::class)->findAll();
if (!empty($alertas)) {
$ultimaAlerta = end($alertas);
} else {
$ultimaAlerta = null;
}
$alertas = $em->getRepository(ReservationAlertStarted::class)->findAll();
$agentesVenues = $em->getRepository(User::class)->findByUserrol(48);
$hoy = new DateTime('now');
$fechaLimite = new DateTime('now');
$fechaLimite->modify('-180 day');
if (!empty($ultimaAlerta)) {
$mismaFecha = $ultimaAlerta->getAlertDate()->format('Ymd') == $hoy->format('Ymd');
} else {
$mismaFecha = false;
}
if ($mismaFecha) {
// No se debe notificar, la ultima alerta es del dia de hoy
} else {
// Hay que notificar
if (empty($agentesVenues)) {
return true;
}
$mailAddressFrom = $agentesVenues[0]->getEmail();
$mailArrayTo = array();
foreach ($agentesVenues as $agente) {
$mailArrayTo[$agente->getEmail()] = $agente->getEmail();
}
$mailSubject = 'EXPENDIENTES POR COTIZAR';
$reservasIniciado = $em->getRepository(Reservation::class)->findByStatus('Iniciado');
$mailBody = null;
foreach ($reservasIniciado as $reserva) {
$agenteReserva = $em->getRepository(User::class)->findOneById($reserva->getCreatedBy());
$agenteReserva = $agenteReserva->getName() . ' ' . $agenteReserva->getLastName();
$mailBody = $mailBody . '<br>Evento: ' . $reserva->getId() . '<br>Nombre del Evento: ' . $reserva->getTitle() . '<br>Agente: ' . $agenteReserva . '<br>Enlace al Evento: <a href="https://mantevenues.mante.solutions/venues/editsimple/' . $reserva->getId() . '">"IR AL EXPEDIENTE"</a><br><br>';
}
if (!empty($mailBody)) {
$this->sendMailLot($mailAddressFrom, $mailArrayTo, $mailSubject, $mailBody);
// Creamos la alerta del dia
$alertToday = new ReservationAlertStarted();
$alertToday->setAlertDate($hoy);
$alertToday->setMessage($mailBody);
$em->persist($alertToday);
$em->flush();
}
}
// Eliminamos las alertas con mas de 6 meses de antiguedad
foreach ($alertas as $alerta) {
if ($alerta->getAlertDate() < $fechaLimite) {
$em->remove($alerta);
$em->flush();
}
}
return true;
}
private function reordenarSalas($number, $idLounge)
{
// number es el numero de la sala editada
$em = $this->getDoctrine()->getManager();
$number--;
$parameters = array('idLounge' => $idLounge, 'rankLounge' => $number, );
$dql = 'SELECT i
FROM VenuesBundle:ReservationLoungeDetails i
WHERE i.rankLounge > :rankLounge AND i.id <> :idLounge';
$query = $em->createQuery($dql)->setParameters($parameters);
$salasParaReordenar = $query->getResult();
foreach ($salasParaReordenar as $sala) {
$sala->setRankLounge(($sala->getRankLounge() + 1));
$em->persist($sala);
$em->flush();
}
return empty($resInv);
}
private function laReservaEsConfirmable($id)
{
$confirmable = false;
// Una reserva se puede confirmar solo cuando tiene un depósito realizado
$em = $this->getDoctrine()->getManager();
$depósitos = $em->getRepository(ReservationDeposit::class)->findBy(array('reservationId' => $id, 'isDone' => true));
$depósitos = true; // Rafa indica que este requisito no se usara por el momento 24/02/2025
// Si la reserva no tiene ninguna sala asignada, no se puede pasar a confirmado
$salas = $em->getRepository(ReservationLoungeSimple::class)->findBy(array('idReservation' => $id));
if (!empty($depósitos) and !empty($salas)) {
$confirmable = true;
}
return $confirmable;
}
private function laReservaEsCotizable($id)
{
// Una reserva se puede cotizar solo cuando tiene al menos una sala agregada
$em = $this->getDoctrine()->getManager();
$salas = $em->getRepository(ReservationLoungeSimple::class)->findBy(array('idReservation' => $id));
return true; // Se pidio que siempre se sincronizara con Av
}
private function notificacionReservasPendientesDelSegundoDepósito()
{
// Se buscan las reservas con depósitos y se notifica a todos los
// agentes de Venues si no tienen el segundo depósito y faltan 30 días
// o menos para el evento, Solo se notifica 1 vez por dia
$em = $this->getDoctrine()->getManager();
$depósitosHechos = $em->getRepository(ReservationDeposit::class)->findByIsDone(true);
$arrayDepósitos = array();
$arrayReservasPemdientesSegunDepósitos = array();
$today = new \Datetime('now');
$todayPlusMonth = new \Datetime('+ 30 days');
// Se agrupan los depósitos por reservas
foreach ($depósitosHechos as $item) {
$arrayDepósitos[$item->getReservationId()][] = $item;
}
foreach ($arrayDepósitos as $item) {
if (sizeof($item) < 2) {
// Solo nos interesan reservas con un depósito
$reserva = $em->getRepository(Reservation::class)->findOneById($item[0]->getReservationId());
if ($reserva->getStatus() == 'Confirmed') {
// Solo nos interesan reservas confirmadas
if (($reserva->getDateStart() < $todayPlusMonth) and ($reserva->getDateStart() > $today)) {
// Solo nos interesan reservas que inician en 30 dias
$arrayReservasPemdientesSegunDepósitos[] = $reserva;
}
}
}
}
$alertas = $em->getRepository(ReservationAlertSecondDeposit::class)->findAll();
if (!empty($alertas)) {
$ultimaAlerta = end($alertas);
} else {
$ultimaAlerta = null;
}
$agentesVenues = $em->getRepository(User::class)->findByUserrol(48);
$hoy = new DateTime('now');
$fechaLimite = new DateTime('now');
$fechaLimite->modify('-180 day');
if (!empty($ultimaAlerta)) {
$mismaFecha = $ultimaAlerta->getAlertDate()->format('Ymd') == $hoy->format('Ymd');
} else {
$mismaFecha = false;
}
if ($mismaFecha) {
// No se debe notificar, la ultima alerta es del dia de hoy
} else {
// Hay que notificar
if (empty($agentesVenues)) {
return true;
}
$mailAddressFrom = $agentesVenues[0]->getEmail();
$mailArrayTo = array();
foreach ($agentesVenues as $agente) {
$mailArrayTo[$agente->getEmail()] = $agente->getEmail();
}
$mailSubject = 'EXPENDIENTES CON DEPÓSITOS PENDIENTES';
$reservasIniciado = $arrayReservasPemdientesSegunDepósitos;
$mailBody = null;
foreach ($reservasIniciado as $reserva) {
$agenteReserva = $em->getRepository(User::class)->findOneById($reserva->getCreatedBy());
$agenteReserva = $agenteReserva->getName() . ' ' . $agenteReserva->getLastName();
$mailBody = $mailBody . '<br>Evento: ' . $reserva->getId() . '<br>Nombre del Evento: ' . $reserva->getTitle() . '<br>Agente: ' . $agenteReserva . '<br>Enlace al Evento: <a href="https://mantevenues.mante.solutions/venues/editsimple/' . $reserva->getId() . '">"IR AL EXPEDIENTE"</a><br><br>';
}
if (!empty($mailBody)) {
$this->sendMailLot($mailAddressFrom, $mailArrayTo, $mailSubject, $mailBody);
// Creamos la alerta del dia
$alertToday = new ReservationAlertSecondDeposit();
$alertToday->setAlertDate($hoy);
$alertToday->setMessage($mailBody);
$em->persist($alertToday);
$em->flush();
}
}
// Eliminamos las alertas con mas de 6 meses de antiguedad
foreach ($alertas as $alerta) {
if ($alerta->getAlertDate() < $fechaLimite) {
$em->remove($alerta);
$em->flush();
}
}
return true;
}
/**
* Actualiza las salas y servicios de la reserva.
*/
private function _actualizarSalasYServicios(Reservation $reserva)
{
$msage = $this->session->get('_config')['msage'];
// Si no es sucoe, cogemos el IVA del 21% y si lo es, entonces el del 0%
if (!$reserva->isSucoe()) {
$sageVatRate = $this->em->getRepository(SageVatRates::class)->findOneBy(array('sageCode' => '03'));
} else {
$sageVatRate = $this->em->getRepository(SageVatRates::class)->findOneBy(array('sageCode' => '00'));
}
// Coger todas las salas de la reserva
$reservationsLounges = $this->em->getRepository(ReservationLoungeSimple::class)->findByIdReservation($reserva->getId());
foreach ($reservationsLounges as $reservationsLounge) {
// Si el módulo de Sage está activo, asignar el artículo correspondientec
if ($msage) {
$sageArticle = $this->em->getRepository(SageArticle::class)->findOneBy(array('vatType' => $sageVatRate, 'name' => $reservationsLounge->getLoungeName()));
if (!$sageArticle) {
throw new \Exception('No se ha encontrado el artículo Sage para la sala: ' . $reservationsLounge->getLoungeName());
}
$reservationsLounge->setSageArticle($sageArticle);
}
$reservationsLounge->setSageIva($sageVatRate);
$this->em->persist($reservationsLounge);
}
// Coger todos los servicios de la reserva
$services = $this->em->getRepository(ReservationService::class)->findByReservationId($reserva->getId());
foreach ($services as $service) {
// Si el módulo de Sage está activo, asignar el artículo correspondiente
if ($msage) {
$sageArticle = $this->em->getRepository(SageArticle::class)->findOneBy(array('vatType' => $sageVatRate, 'name' => $service->getServiceCatName()));
if (!$sageArticle) {
throw new \Exception('No se ha encontrado el artículo Sage para el servicio: ' . $service->getServiceCatName());
}
$service->setSageArticle($sageArticle);
}
$service->setSageIva($sageVatRate);
$this->em->persist($service);
}
// Persistimos los cambios
$this->em->flush();
}
/**
* Procesa los lounges simples para agruparlos por día y generar el array para el archivo.
*/
private function processLounges(array $reservationsLoungesSimple): array
{
$arrayLoungesByDay = [];
$arrayLoungesInFile = [];
foreach ($reservationsLoungesSimple as $item) {
$dateStart = $item->getDateStart()->format('Ymd');
$rank = $item->getRankQuote();
$arrayLoungesByDay[$rank][$dateStart][] = $item;
ksort($arrayLoungesByDay[$rank]);
// Ignorar montajes y desmontajes. Ignorar los montajes y desmontajes, parece ser un error, genera un arraglo vacio (arrayLoungesInFile) en editSimple
// if (empty($item->getType())) {
// NOTA: $dataContract no existía en el código original antes de este punto.
// Se asume vacío para evitar error de variable indefinida.
$fullContract = '';
$arrayLoungesInFile[$rank][$item->getIdLounge()] = [
'rankQuote' => $rank,
'idLounge' => $item->getIdLounge(),
'loungeName' => $item->getLoungeName(),
'loungeImportantDescription' => $item->getImportantDescription(),
'loungeImportantDescGeneralText' => $item->getImportantDescGeneralText(),
'loungeImportantDescSchedules' => $item->getImportantDescSchedules(),
'loungeImportantDescParking' => $item->getImportantDescParking(),
'loungeDocFullContract' => $fullContract,
'language' => $item->getLanguage(),
];
// }
}
return [
'arrayLoungesByDay' => $arrayLoungesByDay,
'arrayLoungesInFile' => $arrayLoungesInFile
];
}
/**
* Obtiene proveedores de Catering con la lógica de ordenamiento específica.
*/
private function getCateringSuppliers(EntityManagerInterface $em): array
{
$caterings = $em->createQueryBuilder()
->select('p')
->from(Supplier::class, 'p')
->where('p.tags LIKE :tags')
->andWhere('p.company <> :company')
->orderBy('p.company', 'ASC')
->setParameters([
'tags' => '%CATERING%', // Aseguramos el wildcard si es necesario o se mantiene estricto según lógica original
'company' => 'HIGO & TRIGO, S.L.'
])
->getQuery()
->getResult();
// Agregamos Higo & Trigo al principio (Hardcoded ID según código original)
$catHigoTrigo = $em->getRepository(Supplier::class)->find(4765);
if ($catHigoTrigo) {
array_unshift($caterings, $catHigoTrigo);
}
return $caterings;
}
/**
* Lógica optimizada para facturas. Evita consultas dentro del bucle.
*/
private function calculateInvoicesData(int $reservationId, Reservation $reserva, ?Client $client, EntityManagerInterface $em): array
{
$invoices = $em->getRepository(ReservationInvoice::class)->findByReservationId($reservationId);
$invoicesRec = $em->getRepository(ReservationInvoiceRec::class)->findByReservationId($reservationId);
// Merge de facturas normales y rectificativas
$allInvoicesEntities = array_merge($invoices, $invoicesRec);
// --- INICIO PRE-CARGA PARA RESOLVER N+1 ---
$depositInvoiceIds = [];
$invoiceToRecIds = [];
foreach ($allInvoicesEntities as $item) {
if ($item->getType() === 'Invoice Deposit') {
$depositInvoiceIds[] = $item->getId();
} elseif (in_array($item->getType(), ['Invoice Rec', 'Invoice Deposit Rec'], true) && $item->getId()) {
$invoiceToRecIds[] = $item->getInvoiceToRec();
}
}
$depositInvoiceIds = array_filter(array_unique($depositInvoiceIds));
$invoiceToRecIds = array_filter(array_unique($invoiceToRecIds));
$paymentItemsByInvoiceId = [];
$invoiceElementItemsByPaymentId = [];
$invoicesById = [];
if (!empty($depositInvoiceIds)) {
$qbPayments = $em->createQueryBuilder();
$paymentItems = $qbPayments->select('p')
->from(ReservationPaymentsClient::class, 'p')
->where($qbPayments->expr()->in('p.invoiceId', ':invoiceIds'))
->setParameter('invoiceIds', $depositInvoiceIds)
->getQuery()
->getResult();
$paymentIds = [];
foreach ($paymentItems as $paymentItem) {
// Emulamos el comportamiento de findOneBy asignando solo la primera coincidencia
if (!isset($paymentItemsByInvoiceId[$paymentItem->getInvoiceId()])) {
$paymentItemsByInvoiceId[$paymentItem->getInvoiceId()] = $paymentItem;
$paymentIds[] = $paymentItem->getId();
}
}
$paymentIds = array_filter(array_unique($paymentIds));
if (!empty($paymentIds)) {
$qbItems = $em->createQueryBuilder();
$invoiceElementItems = $qbItems->select('i')
->from(ReservationInvoiceItems::class, 'i')
->where($qbItems->expr()->in('i.payControlId', ':paymentIds'))
->setParameter('paymentIds', $paymentIds)
->getQuery()
->getResult();
$invoiceIdsToFetch = [];
foreach ($invoiceElementItems as $invoiceElementItem) {
if (!isset($invoiceElementItemsByPaymentId[$invoiceElementItem->getPayControlId()])) {
$invoiceElementItemsByPaymentId[$invoiceElementItem->getPayControlId()] = $invoiceElementItem;
$invoiceIdsToFetch[] = $invoiceElementItem->getInvoiceId();
}
}
$invoiceIdsToFetch = array_filter(array_unique($invoiceIdsToFetch));
if (!empty($invoiceIdsToFetch)) {
$qbInvoices = $em->createQueryBuilder();
$fetchedInvoices = $qbInvoices->select('inv')
->from(ReservationInvoice::class, 'inv')
->where($qbInvoices->expr()->in('inv.id', ':invoiceIds'))
->setParameter('invoiceIds', $invoiceIdsToFetch)
->getQuery()
->getResult();
foreach ($fetchedInvoices as $inv) {
$invoicesById[$inv->getId()] = $inv;
}
}
}
}
if (!empty($invoiceToRecIds)) {
$qbInvoicesRec = $em->createQueryBuilder();
$fetchedInvoicesToRec = $qbInvoicesRec->select('inv')
->from(ReservationInvoice::class, 'inv')
->where($qbInvoicesRec->expr()->in('inv.id', ':invoiceToRecIds'))
->setParameter('invoiceToRecIds', $invoiceToRecIds)
->getQuery()
->getResult();
foreach ($fetchedInvoicesToRec as $inv) {
$invoicesById[$inv->getId()] = $inv;
}
}
// --- FIN PRE-CARGA ---
$sumNet = 0.0;
$sumVat = 0.0;
$sumTotal = 0.0;
$allInvoicedData = [];
foreach ($allInvoicesEntities as $item) {
// Lógica de Balance para Invoice Deposit utilizando datos cacheados
if ($item->getType() === 'Invoice Deposit') {
$paymentItem = $paymentItemsByInvoiceId[$item->getId()] ?? null;
if ($paymentItem) {
$invoiceElementItem = $invoiceElementItemsByPaymentId[$paymentItem->getId()] ?? null;
if ($invoiceElementItem) {
$invoiceOfItem = $invoicesById[$invoiceElementItem->getInvoiceId()] ?? null;
if ($invoiceOfItem?->getType() === 'Invoice') {
$item->setBalance(0);
}
}
}
}
// Factura rectificativa relacionada utilizando datos cacheados
$invoiceToRec = null;
if (in_array($item->getType(), ['Invoice Rec', 'Invoice Deposit Rec'], true) && $item->getId()) {
$invoiceToRec = $invoicesById[$item->getInvoiceToRec()] ?? null;
}
$clientInvoice = [
'name' => $item->getClientName(),
'address' => $item->getClientAddress(),
'clientDocument' => $item->getClientDocument(),
];
$allInvoicedData[] = [
'dateAt' => $item->getDateAt(),
'type' => $item->getType(),
'id' => $item->getId(),
'invoiceToRec' => $invoiceToRec,
'clientType' => $item->getClientType(),
'reservationId' => $item->getReservationId(),
'number' => $item->getNumber(),
'totalNet' => $item->getTotalNet(),
'total' => $item->getTotal(),
'vat' => $item->getVat(),
'balance' => $item->getBalance(),
'client' => $clientInvoice, // Reutilizamos el cliente ya cargado
'reservation' => $reserva, // Reutilizamos la reserva ya cargada
];
// Cálculos acumulativos
$isDeposit = in_array($item->getType(), ['Invoice Deposit', 'Invoice Deposit Rec'], true);
if (!$isDeposit) {
// Las facturas rectificativas suelen tener valores negativos en DB, por lo que sumar es correcto.
$sumNet += $item->getTotalNet();
$sumVat += $item->getVat();
$sumTotal += $item->getTotal();
}
// Si es depósito, se suma 0 (no computa), por lo que no hacemos nada.
}
return [
'allInvoiced' => $allInvoicedData,
'resultados' => [
'totalNeto' => $sumNet,
'vat' => $sumVat,
'total' => $sumTotal,
]
];
}
/**
* Filtra pagos no facturados.
*/
private function filterUninvoicedPayments(int $reservationId, array $payments, EntityManagerInterface $em): array
{
$notInvoiced = [];
foreach ($payments as $payment) {
// Esto sigue siendo una consulta en bucle, pero es difícil de optimizar sin cambiar la lógica de InvoiceItems.
// Se mantiene por seguridad "sin inventar", pero idealmente InvoiceItems debería cargarse en bloque.
$isInvoiced = $em->getRepository(ReservationInvoiceItems::class)->findBy([
'reservationId' => $reservationId,
'payControlId' => $payment->getId()
]);
if (empty($isInvoiced)) {
$notInvoiced[] = $payment;
}
}
return $notInvoiced;
}
/**
* Obtiene usuarios activos y añade freelancers.
*/
private function getAllActiveUsersAndFreelancers(EntityManagerInterface $em): array
{
$users = $em->createQueryBuilder()
->select('u')
->from(User::class, 'u')
->where('u.status = :status')
->andWhere('u.team = :team')
->orderBy('u.name', 'ASC')
->setParameter('status', 1)
->setParameter('team', 16)
->getQuery()
->getResult();
$freeLances = []; // $em->getRepository(ExternalUser::class)->findAll();
// Lcl Freelance logic removed
return $users;
}
/**
* Calcula la fecha de la próxima alerta de correo.
*/
private function getNextMailAlertDate(int $reservationId, EntityManagerInterface $em): ?\DateTimeInterface
{
$alert = $em->getRepository(ReservationMailAlertClient::class)->findOneByReservationId($reservationId);
if (!$alert) {
return null;
}
if (!$alert->getAlertSended()) {
return $alert->getAlertDateTime();
}
if (!$alert->getCancelSended()) {
return $alert->getCancelDateTime();
}
return null;
}
/**
* Obtiene depósitos y calcula sumas por proforma.
*/
private function getDepositsAndProformas(int $reservationId, EntityManagerInterface $em): array
{
$depositsAll = $em->getRepository(ReservationDeposit::class)->findByReservationId($reservationId);
$proformaIds = [];
$proformas = [];
foreach ($depositsAll as $d) {
$p = $d->getProformaDeposit();
if ($p && !$p->getInvoice()) {
$pid = $p->getId();
$proformaIds[$pid] = true;
$proformas[$pid] = $p;
}
}
$ids = array_keys($proformaIds);
$sums = [];
if (!empty($ids)) {
// Asumiendo que sumsByProformaIds maneja un array vacío correctamente, si no, el if protege.
$sums = $em->getRepository(ReservationDeposit::class)->sumsByProformaIds($ids);
}
return [
'depositsAll' => $depositsAll,
'sumsByProforma' => $sums,
'proformas' => $proformas
];
}
/**
* Helper para parsear los formatos de hora manuales del input.
* Devuelve array con 'hour', 'min' y 'formatted' (HH:mm).
*/
/**
* Resuelve el nombre del servicio y el ID del asistente.
*/
private function resolveAgentAndName(ReservationService $service, array $data, EntityManagerInterface $em): void
{
// ID 15 parece ser "Personal" o similar en tu lógica de negocio
if ($service->getServiceCatId() == 15 && array_key_exists('agent', $data)) {
$agentId = (int) $data['agent'];
if ($agentId > 0) {
$user = $em->getRepository(User::class)->find($agentId);
if ($user) {
$service->setName(trim($user->getName() . ' ' . $user->getLastName()));
$service->setAssistantId($agentId);
return;
}
}
// Fallback si viene 'agent' pero es 0 o no se encuentra usuario
$service->setName($data['name'] ?? null);
$service->setAssistantId(null);
} else {
// No es categoría 15 o no viene agente
$service->setName($data['name'] ?? null);
}
}
/**
* Parsea valores monetarios manejando comas y puntos.
*/
private function parseCurrency(?string $input, float $fallback, bool $onlyComma = false): float
{
if ($input === null) {
return 0.0;
}
if ($onlyComma) {
// Caso especial para comisiones: solo reemplaza coma por punto
$val = str_replace(',', '.', $input);
} else {
// Caso general: elimina puntos (miles), cambia coma a punto (decimal)
$val = str_replace(['.', ','], ['', '.'], $input);
}
return is_numeric($val) ? (float) $val : $fallback;
}
/**
* Maneja la lógica compleja de sincronización para Catering y AV.
*/
private function handleSynchronization(
Reservation $reserva,
ReservationService $service,
Supplier $supplier,
bool $mcatering,
bool $mav,
array $htFiles, // Array de HtFile encontrados
array $aveFiles, // Array de AveFiles encontrados
$user,
SyncronizationsCateringService $cateringService,
SyncronizationsAVService $avService,
EntityManagerInterface $em,
AppConfigManager $configManager
): void {
$companyName = $supplier->getCompany();
if (!$companyName) {
return;
}
$mode = $configManager->getSettings()->workflow->reservationMode;
// --- CATERING ---
if ($mcatering) {
// Verificamos si este proveedor es de tipo Catering buscando en SettingsCompany
// Optimización: Usamos una consulta simple, idealmente esto se cachearía a nivel de clase si son pocos settings.
$isCatering = $em->getRepository(SettingsCompany::class)->findOneBy([
'businessType' => BusinessTypeSettingsCompanyConstants::CATERING,
'company' => $companyName
]);
if ($isCatering) {
$dto = new SyncronizationsCateringDTO();
$dto->setDateStart($service->getDateInAt());
$dto->setDateEnd($service->getDateOutAt());
$dto->setReservation($reserva);
if (empty($htFiles)) {
// Crear expediente HT solo si NO estamos en modo Automático (que ya los crea al iniciar)
// O si estamos en modo Clásico (implícito)
if ($mode !== ReservationWorkflowMode::ON_RESERVATION_CREATION) {
$dto->setClient($reserva->getClient());
$dto->setClientContName($reserva->getClientContact());
$dto->setUser($user);
$dto->setTitle($reserva->getTitle());
$dto->setPax($reserva->getPax());
$dto->setDescription($reserva->getDescription());
$dto->setContactUnregistered($reserva->getContactUnregistered());
$dto->setNameContactUnregistered($reserva->getNameContactUnregistered());
$dto->setPhoneContactUnregistered($reserva->getPhoneContactUnregistered());
$cateringService->syncVenues($dto);
}
} else {
// Actualizar fechas
$cateringService->updateCateringDate($dto);
}
}
}
// --- AUDIOVISUAL ---
if ($mav) {
$isAV = $em->getRepository(SettingsCompany::class)->findOneBy([
'businessType' => BusinessTypeSettingsCompanyConstants::AUDIOVISUAL,
'company' => $companyName
]);
if ($isAV) {
$dto = new SyncronizationsAVDTO();
$dto->setDateStart($service->getDateInAt());
$dto->setDateEnd($service->getDateOutAt());
$dto->setReservation($reserva);
if (empty($aveFiles)) {
// Crear expediente AV - Misma lógica
if ($mode !== ReservationWorkflowMode::ON_RESERVATION_CREATION) {
$dto->setClient($reserva->getClient());
$dto->setUser($user);
$dto->setTitle($reserva->getTitle());
$dto->setPax($reserva->getPax());
$dto->setDescription($reserva->getDescription());
$avService->syncVenues($dto);
}
} else {
// Actualizar fechas
$avService->updateAVDate($dto);
}
}
}
}
private function handleUnregisteredContact($form, Reservation $reserva, User $user, EntityManagerInterface $em): void
{
// 1. Ahora leemos los datos directamente de la entidad Reserva
// (Como quitamos mapped=>false, el form ya los ha puesto aquí)
$email = $reserva->getContactUnregistered();
$name = $reserva->getNameContactUnregistered();
$phone = $reserva->getPhoneContactUnregistered();
// Obtener el objeto Cliente del formulario
$client = $form->get('client')->getData();
$contactHandled = false;
// 2. Si hay datos escritos a mano, tienen PRIORIDAD
if ($client && !empty($email) && !empty($name)) {
// Verificamos si ya existe ese email en la tabla de contactos
$existClientContact = $em->getRepository(ClientContact::class)->findOneBy(['email' => $email]);
if ($existClientContact) {
// CASO A: Ya existía -> Solo vinculamos su ID
$reserva->setClientContact($existClientContact->getId());
} else {
// CASO B: No existía -> Lo creamos en la tabla de contactos para el futuro
$newContact = new ClientContact();
$newContact->setClientId($client->getId());
$newContact->setTypeclient('Business Travel');
$newContact->setAssignedAgent($user->getId());
$newContact->setName($name);
$newContact->setLastName('');
$newContact->setPosition(''); // Evitamos error SQL "position cannot be null"
$newContact->setSituation('CLIENT');
$newContact->setEmail($email);
$newContact->setPhone($phone ?? '');
// Auditoría
$newContact->setCreatedId($user->getId());
$newContact->setUpdatedId($user->getId());
if (method_exists($newContact, 'setCreated')) {
$newContact->setCreated(new \DateTime());
}
$em->persist($newContact);
$em->flush(); // Guardamos para obtener el ID
// Vinculamos el nuevo ID a la reserva
$reserva->setClientContact($newContact->getId());
}
$contactHandled = true;
}
// 3. Si NO escribió nada a mano, miramos el desplegable (campo oculto clientContact)
if (!$contactHandled) {
$manualContactId = $form->get('clientContact')->getData();
// Si viene un ID válido del selector
if (!empty($manualContactId) && $manualContactId !== '0') {
$reserva->setClientContact((int) $manualContactId);
}
}
}
/**
* Lógica específica cuando el estado es "Bloqueo"
*/
private function handleBlockStatus($form, Reservation $reserva, User $user, EntityManagerInterface $em): void
{
$status = $reserva->getStatus();
if ($status === 'Bloqueo') {
// 1. Calcular fecha límite si no existe
if (!$reserva->getDays()) {
$daysBlock = $reserva->getDaysBlock() ?? 7; // Valor por defecto
$dateLimit = (new \DateTime())->modify("+$daysBlock days");
$reserva->setDays($dateLimit);
}
// 2. Envío de Correos (Simplificado manteniendo tu lógica)
// NOTA: Aquí deberías refactorizar para usar un Servicio de Mailing,
// pero mantengo la llamada a $this->sendMail() y lógica local por restricción del prompt.
if ($reserva->getClient() || $reserva->getClientContact() || $form->get('contactUnregistered')->getData()) {
// ... Tu lógica de envío de correo de bloqueo ...
// $this->sendMail(...)
}
// 3. Modificar fecha de notificación (Next Mail Alert)
$newDateAlert = $form->get('dateNextMailAlert')->getData(); // Campo mapped => false o true en tu type nuevo
if ($newDateAlert && $newDateAlert > new \DateTime('now')) {
$alertRepo = $em->getRepository(ReservationMailAlertClient::class);
$nextAlert = $alertRepo->findOneByReservationId($reserva->getId());
if ($nextAlert) {
$newAlertDt = clone $newDateAlert;
$newAlertDt->setTime(15, 0);
if ($nextAlert->getAlertSended() == 0) {
$newCancelDt = (clone $newAlertDt)->modify('+2 days');
$nextAlert->setAlertDateTime($newAlertDt);
$nextAlert->setCancelDateTime($newCancelDt);
} else {
// Solo modificar cancelación
$nextAlert->setCancelDateTime($newAlertDt);
}
$em->persist($nextAlert);
}
}
} else {
// Si NO es bloqueo, limpiar la fecha límite
if ($reserva->getDays()) {
$reserva->setDays(null);
}
}
}
/**
* Maneja el envío de correo de cancelación si existía una alerta previa
*/
private function handleCancellationAlert(int $id, Reservation $reserva, EntityManagerInterface $em): void
{
$alert = $em->getRepository(ReservationMailAlertClient::class)->findOneByReservationId($id);
if ($alert) {
$agent = $em->getRepository(User::class)->find($alert->getAgentId());
// Configurar datos del correo
$mailTo = $alert->getClientMail();
$mailFrom = $alert->getAgentMail();
$subject = 'Notificación de Bloqueo - Reserva de espacio en Venues';
$body = 'Estimado cliente,<br><br>Nos ponemos en contacto con usted para informarle de que su reserva ha sido cancelada.<br><br>Reserva: ' . $reserva->getId() . ' - ' . $reserva->getTitle();
// Llamada a tu método existente
// $this->sendMail($mailFrom, $mailTo, $subject, $body);
// Actualizar la entidad de alerta
$alert->setOldReservationId($alert->getReservationId());
$alert->setReservationId(0);
$alert->setCancelSended(1);
$em->persist($alert);
}
}
/**
* Recalcula fecha inicio y fin basado en las salas (Lounges)
*/
/**
* Gestiona la creación o actualización del DocContract basado en el modelo seleccionado.
*/
private function handleContractLogic(
?DocContractModel $selectedModel,
?DocContract $currentDocContract,
Reservation $reserva,
User $user,
EntityManagerInterface $em
): void {
// Si no se seleccionó nada, no hacemos nada (o podrías decidir borrar el contrato si existía)
if (!$selectedModel) {
return;
}
// Verificamos si ha cambiado el modelo o si no existía contrato previo
$modelHasChanged = !$currentDocContract || ($currentDocContract->getModel()?->getId() !== $selectedModel->getId());
if ($modelHasChanged) {
// Opción A: Actualizar el contrato existente (para mantener el ID y no llenar la BD de basura)
// Opción B: Crear uno nuevo siempre (si necesitas histórico estricto).
// Usaremos Opción A (Actualizar o Crear si no existe) por eficiencia.
if (!$currentDocContract) {
$currentDocContract = new DocContract();
$currentDocContract->setReservation($reserva);
$currentDocContract->setCreatedAt(new \DateTime());
$currentDocContract->setCreatedId($user->getId());
}
// Actualizamos los datos con la nueva plantilla
$currentDocContract->setModel($selectedModel);
// Copiamos el texto de la plantilla al contrato real
// Ajusta 'getContractualDocument()' al método real de tu entidad DocContractModel
if (method_exists($selectedModel, 'getContractualDocument')) {
$currentDocContract->setContractualDocument($selectedModel->getContractualDocument());
}
// Datos de auditoría / actualización
$currentDocContract->setUpdatedAt(new \DateTime());
$currentDocContract->setUpdatedId($user->getId());
$currentDocContract->setDateAt(new \DateTime()); // Fecha del contrato = ahora
$em->persist($currentDocContract);
}
}
}