<?php
namespace App\Controller;
use App\Entity\Client;
use App\Entity\ClientContact;
use App\Entity\MailDelivery;
use App\Entity\SettingsRol;
use App\Entity\ToDoLogs;
use App\Entity\User;
use App\Entity\WidgetNotes;
use App\Form\WidgetNotesType;
use App\MDS\VenuesBundle\Entity\Reservation;
use App\MDS\VenuesBundle\Entity\ReservationLoungeDetails;
use App\MDS\VenuesBundle\Entity\ReservationLoungeSimple;
use App\MDS\VenuesBundle\Entity\ReservationVisit;
use App\Service\CalendarService;
use App\Service\UserNotificationService;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Session\Session;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Contracts\Translation\TranslatorInterface;
use Google_Client;
use Google_Service_Calendar;
use Doctrine\ORM\Query;
class HomeController extends AbstractController
{
private $googleCalendar;
private $translator;
private UserNotificationService $userNotificationService;
public function __construct(TranslatorInterface $translator, UserNotificationService $userNotificationService)
{
$redirectUri = 'https://' . ($_SERVER['HTTP_HOST'] ?? '') . '/calendar/token';
$client = new Google_Client();
$client->setApplicationName('Google Calendar API');
$client->setClientId('YOUR_GOOGLE_CLIENT_ID');
$client->setClientSecret('YOUR_GOOGLE_CLIENT_SECRET');
$client->setRedirectUri($redirectUri);
$client->addScope(Google_Service_Calendar::CALENDAR);
$guzzle = new \GuzzleHttp\Client(['curl' => [CURLOPT_SSL_VERIFYPEER => false]]);
$client->setHttpClient($guzzle);
$this->googleCalendar = $client;
$this->translator = $translator;
$this->userNotificationService = $userNotificationService;
}
/**
* @Route("/", name="homepage")
*/
public function index(EntityManagerInterface $em): Response
{
$tz = new \DateTimeZone('Europe/Madrid');
$from = (new \DateTimeImmutable('today', $tz))->setTime(0, 0);
$to = $from->modify('+30 days')->setTime(23, 59, 59);
/** =======================
* RESERVAS (próx. 30 días) — SIN JOIN
* ======================= */
$rowsR = $em->createQueryBuilder()
->select('r')
->from(Reservation::class, 'r')
->where('r.dateEnd >= :from AND r.dateStart <= :to')
->setParameter('from', $from)
->setParameter('to', $to)
->orderBy('r.dateStart', 'ASC')
->getQuery()->getResult(Query::HYDRATE_ARRAY);
$upcomingReservationsTbl = [];
foreach ($rowsR as $r) {
// fechas (acepta camelCase o snake_case)
$dsRaw = $r['dateStart'] ?? $r['date_start'] ?? null;
$deRaw = $r['dateEnd'] ?? $r['date_end'] ?? null;
$ds = $dsRaw instanceof \DateTimeInterface ? $dsRaw : ($dsRaw ? new \DateTimeImmutable($dsRaw) : null);
$de = $deRaw instanceof \DateTimeInterface ? $deRaw : ($deRaw ? new \DateTimeImmutable($deRaw) : null);
// sala(s): primero loungeName; si no, name de ReservationLoungeDetails
$rooms = [];
$rlsRows = $em->createQueryBuilder()
->select('rls', 'rld')
->from(ReservationLoungeSimple::class, 'rls')
->leftJoin(ReservationLoungeDetails::class, 'rld', 'WITH', 'rld.id = rls.idLounge')
->where('rls.idReservation = :rid')
->setParameter('rid', $r['id'])
->getQuery()->getResult(Query::HYDRATE_ARRAY);
foreach ($rlsRows as $row) {
$rls = $row['rls'] ?? null;
$rld = $row['rld'] ?? null;
$name = $row['loungeName'] ?? null;
if ($name) { $rooms[$name] = true; }
}
$upcomingReservationsTbl[] = [
'title' => $r['title'] ?? '(sin título)',
'dateStart' => $ds,
'dateEnd' => $de,
'room' => $rooms ? implode(', ', array_keys($rooms)) : '-',
];
}
/** ===================
* VISITAS (próx. 30 días) — SIN JOIN
* =================== */
$rowsV = $em->createQueryBuilder()
->select('v')
->from(ReservationVisit::class, 'v')
->where('v.dateEnd >= :from AND v.dateStart <= :to')
->setParameter('from', $from)
->setParameter('to', $to)
->orderBy('v.dateStart', 'ASC')
->getQuery()->getResult(Query::HYDRATE_ARRAY);
$upcomingVisitsTbl = [];
foreach ($rowsV as $v) {
$dsRaw = $v['dateStart'] ?? $v['date_start'] ?? null;
$deRaw = $v['dateEnd'] ?? $v['date_end'] ?? null;
$ds = $dsRaw instanceof \DateTimeInterface ? $dsRaw : ($dsRaw ? new \DateTimeImmutable($dsRaw) : null);
$de = $deRaw instanceof \DateTimeInterface ? $deRaw : ($deRaw ? new \DateTimeImmutable($deRaw) : null);
// nombre sala desde ReservationLoungeDetails por idLounge
$roomName = '-';
$idLounge = $v['idLounge'] ?? $v['id_lounge'] ?? null;
if ($idLounge) {
$rld = $em->getRepository(ReservationLoungeDetails::class)->find($idLounge);
if ($rld && method_exists($rld, 'getName') && $rld->getName()) {
$roomName = $rld->getName();
}
}
$upcomingVisitsTbl[] = [
'title' => $v['title'] ?? '(sin título)',
'dateStart' => $ds,
'dateEnd' => $de,
'room' => $roomName,
];
}
$this->userNotificationService->checkRecentNotifications($this->getUser());
$notifications = $this->userNotificationService->getForModal($this->getUser());
return $this->render('home/index.html.twig', [
'upcomingReservations' => $upcomingReservationsTbl,
'upcomingVisits' => $upcomingVisitsTbl,
'from' => $from,
'to' => $to,
'notifications' => $notifications
]);
}
/**
* @Route("/calendar/global/visits", name="calendar_global_visits", methods={"GET"})
*/
public function globalVisits(Request $request, CalendarService $calendar): JsonResponse
{
$from = ($s = $request->query->get('start'))
? new \DateTimeImmutable($s) : new \DateTimeImmutable('first day of this month 00:00');
$to = ($e = $request->query->get('end'))
? new \DateTimeImmutable($e) : new \DateTimeImmutable('last day of next month 23:59');
$events = $calendar->getVisitsForCalendar(null, null, $from, $to);
return new JsonResponse($events);
}
/**
* @Route("/calendar/global/reservations", name="calendar_global_reservations", methods={"GET"})
*/
public function globalReservations(Request $request, CalendarService $calendar): JsonResponse
{
$from = ($s = $request->query->get('start'))
? new \DateTimeImmutable($s) : new \DateTimeImmutable('first day of this month 00:00');
$to = ($e = $request->query->get('end'))
? new \DateTimeImmutable($e) : new \DateTimeImmutable('last day of next month 23:59');
$events = $calendar->getReservationsForCalendar(null, null, $from, $to);
return new JsonResponse($events);
}
/**
* @Route("/connectGoogle", name="homepage_connect_google")
*/
public function connectGoogle(Request $request): Response
{
$session = new Session();
$token = $session->get('tokenGoogleCalendar');
if ($token) {
$this->googleCalendar->setAccessToken($token);
}
if ($this->googleCalendar->isAccessTokenExpired()) {
if ($this->googleCalendar->getRefreshToken()) {
$this->googleCalendar->fetchAccessTokenWithRefreshToken(
$this->googleCalendar->getRefreshToken()
);
} else {
return $this->redirect($this->googleCalendar->createAuthUrl());
}
}
return $this->redirectToRoute('homepage');
}
/**
* @Route("/ChangeLanguage/{lang}", name="change_language")
*/
public function changeLanguage(Request $request, string $lang): Response
{
$this->translator->setLocale($lang);
$request->getSession()->set('_locale', $lang);
return $this->redirect($request->headers->get('referer'));
}
/**
* @Route("/calendar-full", name="calendar_full")
*/
public function calendarFull(Request $request): Response
{
$token = $request->request->get('token');
$em = $this->getDoctrine()->getManager();
$user = $em->getRepository(User::class)->findOneByAccessKey($token);
$userId = $user->getId();
// Prepare WidgetNotes form
$wnotes = new WidgetNotes();
$wnotes->setDateAt(new \DateTime());
$form = $this->createForm(WidgetNotesType::class, $wnotes, [
'action' => $this->generateUrl('widget_notes_create'),
'method' => 'POST',
]);
// ToDo alerts
$countTodo = $em->getRepository(ToDoLogs::class)
->createQueryBuilder('td')
->select('COUNT(td.id)')
->where('td.readed = FALSE')
->andWhere('td.ownerToDoLog = :user')
->setParameter('user', $userId)
->getQuery()
->getSingleScalarResult();
$alertTodo = (int) $countTodo;
return $this->render('home/calendar-fullscreen.html.twig', [
'alertTodo' => $alertTodo,
'form' => $form->createView(),
'user' => $userId,
'token' => $token,
]);
}
/**
* @Route("/external/calendar-reservation", name="calendar_external_reservation")
*/
public function externalCalendar(): Response
{
return $this->render('home/calendar-reservation.html.twig');
}
}