<?php
namespace App\Controller;
use App\Repository\CalendarRepository;
use App\Repository\BookedActivityRepository;
use App\Entity\Main\Calendar;
use App\Entity\Main\Formule;
use App\Entity\Main\Activity;
use App\Entity\Main\BookedActivity;
use App\Entity\Main\ActivityUnavailableSlot;
use App\Entity\Main\OperatorBooking;
use App\Entity\Main\Promos;
use App\Entity\Main\Reservation;
use App\Service\SessionService;
use App\Service\Tools;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\HttpFoundation\JsonResponse;
use ICal\ICal;
class CalendarController extends AbstractController {
private $pk = 'hTgvcDsdkl5492Pifd4z8eMMLjds44z8d24dfsqsqHGzrdf5f'; //Private Key (56f491261413b1f05ddfb33623c96b99)
public function __construct( SessionService $ss) {
$this->ss = $ss;
}
/**
* @Route("/fermetures", methods={"POST"}, name="booking_fermetures")
* Cette fonction permet de récupérer les fermetures annuelles
*/
public function getFermetures(Request $request) {
/* POST Method */
// if(md5($this->pk) != $request->request->get('key')) exit();
$em = $this->getDoctrine()->getManager();
$error = '';
$today = new \DateTime($request->request->get('date'));
/* on récupère les infos Calendar */
$disabledDates = $em->getRepository(Calendar::class)->findDisabledDates($today);
$arrayDates = array();
$arrayHours = array();
if (!$disabledDates) {
return new JsonResponse($arrayDates, JsonResponse::HTTP_CREATED);
} else {
foreach($disabledDates as $disabledDate)
{
if(!$disabledDate[0]->getActivityClosed()) {
if($disabledDate['to'] >= $today && $disabledDate['from']->diff($disabledDate['to'], true)->format('%a') > 1 ) {
$date = new \stdClass();
$date->from = $disabledDate['from']->format('Y-m-d');
$date->to = $disabledDate['to']->format('Y-m-d');
$date->msg = $disabledDate['msg'];
$arrayDates[] = $date;
}
if($disabledDate['to'] >= $today && $disabledDate['from']->diff($disabledDate['to'], true)->format('%a') == 1
|| $disabledDate['to'] == $disabledDate['from'] && $disabledDate['to'] >= $today) {
$date = new \stdClass();
$date->from = $disabledDate['from']->format('Y-m-d');
$date->to = $disabledDate['from']->format('Y-m-d');
$date->msg = $disabledDate['msg'];
$arrayDates[] = $date;
}
if($disabledDate['to'] >= $today && $disabledDate['from']->diff($disabledDate['to'], true)->format('%a') < 1
|| $disabledDate['to'] == $disabledDate['from'] && $disabledDate['to'] <= $today && $disabledDate['from'] >= $today) {
$date = new \stdClass();
$date->from = $disabledDate['from']->format('Y-m-d H:i');
$date->to = $disabledDate['to']->format('Y-m-d H:i');
$date->msg = $disabledDate['msg'];
$arrayHours[] = $date;
}
}
}
}
if ($error != '') {
return new JsonResponse(['error' => $error], JsonResponse::HTTP_CREATED);
} else {
return new JsonResponse(['dates' => $arrayDates, 'hours' => $arrayHours], JsonResponse::HTTP_CREATED);
}
}
/**
* @Route("/creneaux", methods={"POST"}, name="booking_creneaux")
* Cette fonction permet de récupérer tous les créneaux d'une activité
*/
public function getCreneaux(Request $request) {
/* POST Method */
$data = json_decode($request->request->get('data'));
// if(md5($this->pk) != $request->request->get('key')) exit();
$em = $this->getDoctrine()->getManager();
$error = '';
$dateTimeZone = new \DateTimeZone('Europe/Paris');
// $dateTimeZone = new \DateTimeZone('UTC');
$today = new \DateTime('now', $dateTimeZone);
$cart = $this->ss->get();
$date = $cart['date'];
$bookingDate = new \DateTime($date, $dateTimeZone);
$formatter = new \IntlDateFormatter('fr_FR', NULL, NULL, $dateTimeZone, NULL, 'EEEE');
$dayName = $formatter->format($bookingDate);
$dayTrueName = $formatter->format($bookingDate);
/* on récupère les infos Calendar du créneau */
$dateType = $em->getRepository(Calendar::class)->findTypeByDate($bookingDate);
$dateTrueType = "";
if ($dateType) {
$dayName = $dateType[0]['type'];
$dateTrueType = $dateType[0]['type'];
}
$activity_id = $data->activity;
$forfait_id = $data->forfait;
$nbreparticipants = $data->nbreparticipants;
/*** Récupération des forfaits déjà réservés ***/
// if(isset($cart['forfaits']) && !empty($cart['forfaits'])) $forfaits = $cart['forfaits'];
if(isset($data->reservation->forfaits) && !empty($data->reservation->forfaits)) $forfaits = $data->reservation->forfaits;
else $forfaits = null;
if($forfaits) {
$creneauxBooked = array();
$quantityBooked = 0;
foreach($forfaits as $forfait) {
if($forfait) {
$activites = $forfait->activites;
foreach($activites as $activity) {
/*** Pour chaque forfait, on compile les créneaux réservés pour d'autres activités ***/
if($activity->id != $activity_id) {
$activityDatas = new \stdClass();
if($activity->creneau) {
$activityDatas->creneau = $bookingDate->format('Y-m-d').' '.$activity->creneau;
} else {
$activityDatas->creneau = null;
}
$activityBooked = $em->getRepository(Activity::class)->find($activity->id);
if($activityBooked instanceof Activity) {
$activityDatas->temps_activite = $activityBooked->getTempsActivite();
}
$creneauxBooked[$activity->id] = $activityDatas;
}
/*** Pour chaque forfait, on vérifie le nombre de participants déjà réservés pour cette activité ***/
if($activity->id == $activity_id) $quantityBooked += $activity->quantity;
}
}
}
} else {
$creneauxBooked = array();
$quantityBooked = 0;
}
// On récupère les infos de l'activité pour créer les créneaux
$activityToBook = $em->getRepository(Activity::class)->find($activity_id);
$unavailableSlot = $em->getRepository(ActivityUnavailableSlot::class)->findOneBy(['date' => $bookingDate,'code_activity' => $activityToBook->getCode()]);
if (!$activityToBook) {
$error = 'no activity found : '. $code;
return new JsonResponse(['error' => $error], JsonResponse::HTTP_CREATED);
}
if($activityToBook instanceof Activity) {
$code = $activityToBook->getCode();
$data->is_creneau_activity = $activityToBook->getIsCreneauActivity();
$data->block_room = $activityToBook->getBlockRoom();
$data->temps_limite_resa = $activityToBook->getTempsLimiteResa();
$data->jauge_mini = $activityToBook->getJaugeMini();
$data->jauge_max_by_room = $activityToBook->getJaugeMaxi();
$data->presence_avant = $activityToBook->getPresenceAvant();
$data->espaces_jeu = $activityToBook->getEspacesJeu();
$data->nbreparticipants = $nbreparticipants;
$data->is_tarification_multiple = $activityToBook->getIsTarificationMultiple();
$openingDays = false;
$dayExceptionInfo = false;
if( !empty($activityToBook->getOpeningDays()->toArray()) ) {
$openingDays = $activityToBook->getOpeningDays()->toArray();
$dayExceptionInfo = $this->checkDayOpening($openingDays,$dayTrueName,$dateTrueType);
}
if($activityToBook->getIsCreneauActivity()) {
$data->jauge_maxi = $activityToBook->getJaugeMaxi() * $activityToBook->getEspacesJeu();
$data->temps_creneau = $activityToBook->getTempsCreneau();
if($activityToBook->getTempsActiviteJoueur() && $activityToBook->getTempsActiviteJoueur() > 0) {
// $data->temps_de_jeu = $activityToBook->getTempsActiviteJoueur() * $nbreparticipants;
$data->temps_de_jeu = $activityToBook->getTempsActiviteJoueur();
} else {
$data->temps_de_jeu = $activityToBook->getTempsActivite();
}
if($dayExceptionInfo) {
$debutCreneau = new \DateTime($date . ' ' . $dayExceptionInfo->getOpeningTime()->format('H:i:s'), $dateTimeZone);
} else {
$debutCreneau = new \DateTime($date . ' ' . $activityToBook->getHeureOuvertureCreneau()->format('H:i:s'), $dateTimeZone);
}
if($dayExceptionInfo) {
$heureFermetureCreneau = $dayExceptionInfo->getClosingTime();
} else {
$heureFermetureCreneau = $activityToBook->getHeureFermetureCreneau();
}
if(!empty($activityToBook->getOpeningDays()->toArray()) && !$dayExceptionInfo) {
$heureFermetureCreneau = $debutCreneau;
}
if($heureFermetureCreneau->format('H') >= 0 && $heureFermetureCreneau->format('H') <= 2) {
$dv = new \DateInterval('P1D');
$finCreneau = new \DateTime($date . ' ' . $heureFermetureCreneau->format('H:i:s'), $dateTimeZone);
$finCreneau->add($dv);
} else {
$finCreneau = new \DateTime($date . ' ' . $heureFermetureCreneau->format('H:i:s'), $dateTimeZone);
}
$dv2 = new \DateInterval('PT'.$activityToBook->getTempsCreneau().'M');
$finCreneau->add($dv2); // On ajoute en min le temps du jeu
$tempsTotalCreneaux = $debutCreneau->diff($finCreneau);
$nbreCreneaux = $tempsTotalCreneaux->h * 60 / $activityToBook->getTempsCreneau();
$data->heure_debut = $debutCreneau;
$data->heure_fin = $finCreneau;
$data->temps_dispo = $tempsTotalCreneaux->h * 60;
$data->nbre_creneaux = $nbreCreneaux;
$i = 0;
$data->creneaux = array();
$sumQty = array();
// for($i = 0; $i < $nbreCreneaux; $i++) {
// $data->creneaux[$i] = array();
// $data->creneaux[$i]['places_dispo'] = $data->jauge_maxi;
// }
for($i = 0; $i < $nbreCreneaux; $i++) {
$data->creneaux[$i] = array();
$dv4 = new \DateInterval('PT'.$activityToBook->getTempsCreneau() * $i.'M');
$data->creneaux[$i]['heure_debut_utc'] = new \DateTime($data->heure_debut->format('Y-m-d H:i:s'), $dateTimeZone);
$data->creneaux[$i]['heure_debut_utc']->add($dv4);
if($today > $data->creneaux[$i]['heure_debut_utc']) {
unset($data->creneaux[$i]);
continue; // Si résa le jour même, on ne charge pas les créneaux si la date et l'heure ont dépassé les créneaux de la journée
}
$data->creneaux[$i]['heure_debut'] = $data->creneaux[$i]['heure_debut_utc']->format('H\hi');
$data->creneaux[$i]['reservable'] = true;
/* on vérifie si le délai est suffisant pour réserver le créneau */
if($activityToBook->getTempsLimiteResa()) {
$dv3 = new \DateInterval('PT'.$activityToBook->getTempsLimiteResa().'M');
} else {
$dv3 = new \DateInterval('PT'.($activityToBook->getTempsCreneau()*2).'M');
}
$bookingDelay = new \DateTime('now', $dateTimeZone);
$bookingDelay->add($dv3); // On ajoute en min la limite de résa
if($bookingDelay > $data->creneaux[$i]['heure_debut_utc']) {
$data->creneaux[$i]['reservable'] = false;
}
/* on bloque le créneau s'il est déjà réservé par le client pour une autre activité */
if(is_array($creneauxBooked)) {
foreach($creneauxBooked as $creneauReserve) {
$delai1 = new \DateInterval('PT15M'); // On enlève 15min pour permettre aux clients d'arriver
$creneauNonReservable = new \DateTime($creneauReserve->creneau, $dateTimeZone);
$creneauNonReservable->sub($delai1);
// dump($creneauReserve->temps_activite);
if($creneauReserve->temps_activite) {
$temps = intval(intval($creneauReserve->temps_activite) * 1.5);
$delai2 = new \DateInterval('PT'.$temps.'M'); // On ajoute 50% de temps en plus du temps d'activité pour le temps minimum avant de pouvoir réserver un autre créneau
} else {
$delai2 = new \DateInterval('PT75M'); // On ajoute 75 min pour le temps minimum avant de pouvoir réserver un autre créneau
}
// dump($delai2);
$finCreneauNonReservable = new \DateTime($creneauReserve->creneau, $dateTimeZone);
$finCreneauNonReservable->add($delai2);
if( $data->creneaux[$i]['heure_debut_utc'] >= $creneauNonReservable && $data->creneaux[$i]['heure_debut_utc'] <= $finCreneauNonReservable ) {
$data->creneaux[$i]['reservable'] = false;
}
}
}
/* on vérifie les places déjà réservées pour ce créneau */
if($i < ($nbreCreneaux-1)) {
$next_creneau = new \DateTime($data->creneaux[$i]['heure_debut_utc']->format('H:i:s'));
$next_creneau->add(new \DateInterval('PT'.$data->temps_creneau.'M'));
}
else $next_creneau = new \DateTime('23:59:00');
$bookedActivity = $em->getRepository(BookedActivity::class)
->findSumQuantityBooked( $code,
$data->creneaux[$i]['heure_debut_utc']->format('Y-m-d'),
$data->creneaux[$i]['heure_debut_utc']->format('H:i:s'));
$operatorBooked = $em->getRepository(OperatorBooking::class)
->findSumQuantityBooked( $code,
$data->creneaux[$i]['heure_debut_utc']->format('Y-m-d'),
$next_creneau,
$data->creneaux[$i]['heure_debut_utc']);
$sumQty[$i] = !isset($sumQty[$i]) ? 0 : $sumQty[$i];
$sumActivityBooked = 0;
$ignoredCreneau = false;
if($activityToBook->getTempsCreneau() != $activityToBook->getTempsCreneauReel()
&& $activityToBook->getIgnoredCreneau()
) {
$ignoredCreneau = new \DateTime($activityToBook->getIgnoredCreneau()->format('H:i:s'));
}
$activitiesBooked = array_merge($bookedActivity,$operatorBooked);
foreach($activitiesBooked as $activityBooked) {
if( $activityBooked instanceof OperatorBooking && !$activityBooked->isDeleted() && ( $ignoredCreneau && $activityBooked->getCreneau()->format('i') != $ignoredCreneau->format('i') || !$ignoredCreneau)
|| $activityBooked instanceof BookedActivity && $activityBooked->getReservation()->getActive())
{
if($activityBooked instanceof OperatorBooking)
$qtyActivityBooked = $activityBooked->getQuantity();
else
$qtyActivityBooked = $activityBooked->getQuantity() / $activityBooked->getNbreParties();
for ($j=0; $j < $activityBooked->getNbreParties(); $j++) {
if( $data->block_room ) {
$qtyRoom = intval(ceil($qtyActivityBooked / intval($data->jauge_max_by_room)));
$sumActivityBooked += $qtyRoom;
// if($i + (1*$j) == 2) dd($data->temps_de_jeu, $data->temps_creneau);
if( ($data->temps_de_jeu * $qtyActivityBooked) > $data->temps_creneau && $activityToBook->getTempsActiviteJoueur()) {
if( !isset($sumQty[$i + (2*$j)]) ) $sumQty[$i + (2*$j)] = 0;
$sumQty[$i + (2*$j)] += ( $qtyRoom * intval($data->jauge_max_by_room) );
if( !isset($sumQty[$i + (2*$j) + 1]) ) $sumQty[$i + (2*$j) + 1] = 0;
$sumQty[$i + (2*$j) + 1] += ( $qtyRoom * intval($data->jauge_max_by_room) );
} elseif( $data->temps_de_jeu > $data->temps_creneau) {
if( !isset($sumQty[$i + (2*$j)]) ) $sumQty[$i + (2*$j)] = 0;
$sumQty[$i + (2*$j)] += ( $qtyRoom * intval($data->jauge_max_by_room) );
if( !isset($sumQty[$i + (2*$j) + 1]) ) $sumQty[$i + (2*$j) + 1] = 0;
$sumQty[$i + (2*$j) + 1] += ( $qtyRoom * intval($data->jauge_max_by_room) );
} else {
if( !isset($sumQty[$i + (1*$j)]) ) $sumQty[$i + (1*$j)] = 0;
$sumQty[$i + (1*$j)] += ( $qtyRoom * intval($data->jauge_max_by_room) );
}
// $data->temps_de_jeu
} else {
$sumActivityBooked += 1;
if( !isset($sumQty[$i + (1*$j)]) ) $sumQty[$i + (1*$j)] = 0;
$sumQty[$i + (1*$j)] += $qtyActivityBooked;
}
}
}
}
// foreach($operatorBooked as $activityBooked) {
// if(!$activityBooked->isDeleted() && ( $ignoredCreneau && $activityBooked->getCreneau()->format('i') != $ignoredCreneau->format('i') || !$ignoredCreneau)) {
// $sumActivityBooked += 1;
// $sumQty[$i] += $activityBooked->getQuantity();
// } elseif(!$activityBooked->isDeleted()) {
// $sumActivityBooked += 1;
// $sumQty[$i] += $activityBooked->getQuantity();
// }
// }
// if($data->creneaux[$i]['heure_debut_utc']->format('H:i') == '13:00') dd($sumQty[$i],$operatorBooked);
// ################################################################################################
// ################################################################################################
// TO-DO /!\ WARNING
// ################################################################################################
// ################################################################################################
if($unavailableSlot) {
$unavailableSlotNb = $unavailableSlot->getSlotUnavailable();
$sumActivityBooked += 1;
if ($activityToBook->getBlockRoom()) {
if($activityToBook->getEspacesJeuReel() && $activityToBook->getEspacesJeuReel() != $activityToBook->getEspacesJeu()) {
$espacesJeu = $activityToBook->getEspacesJeu();
$espacesJeuReel = $activityToBook->getEspacesJeuReel();
$jaugeMaxi = $activityToBook->getJaugeMaxi();
$jaugeMaxiReel = $jaugeMaxi;
// $jaugeMaxiReel = $activityToBook->getJaugeMaxiReel() ? $activityToBook->getJaugeMaxiReel() : $jaugeMaxi;
if($activityToBook->getJaugeMaxiReel())
$sumQty[$i] += ($unavailableSlotNb * $jaugeMaxi - (($jaugeMaxiReel * $espacesJeuReel) - ($jaugeMaxi * $espacesJeu)));
} else {
$sumQty[$i] += $unavailableSlotNb * $activityToBook->getJaugeMaxi();
}
} else {
if($activityToBook->getJaugeMaxiReel() && $activityToBook->getJaugeMaxiReel() != $activityToBook->getJaugeMaxi()) {
$jaugeMaxi = $activityToBook->getJaugeMaxi();
$jaugeMaxiReel = $activityToBook->getJaugeMaxiReel();
$sumQty[$i] += $unavailableSlotNb - ($jaugeMaxiReel - $jaugeMaxi);
} else {
$sumQty[$i] += $unavailableSlotNb;
}
}
}
// ################################################################################################
// ################################################################################################
// ################################################################################################
if($data->block_room && intval($sumQty[$i]) > 0) {
if($data->espaces_jeu > $sumActivityBooked) {
$data->creneaux[$i]['places_dispo'] = (intval($data->jauge_maxi) - intval($sumQty[$i])) - ((intval($data->jauge_maxi) - intval($sumQty[$i])) % intval($data->jauge_max_by_room));
// if($i == 3 ) dd($sumQty[$i], $data->espaces_jeu, $sumActivityBooked );
} else {
$data->creneaux[$i]['places_dispo'] = 0;
}
// $data->creneaux[$i]['places_dispo'] = intval($data->jauge_maxi);
} else {
$data->creneaux[$i]['places_dispo'] = intval($data->jauge_maxi) - intval($sumQty[$i]);
}
//TO-DO : à vérifier sur les pass Journée
if($data->creneaux[$i]['places_dispo'] < $data->nbreparticipants + $quantityBooked) {
$data->creneaux[$i]['reservable'] = false;
}
/* on récupère les infos Calendar pour les dates et créneaux de fermetures */
$disabledDates = $em->getRepository(Calendar::class)->findDisabledDates($today);
if($disabledDates) {
foreach($disabledDates as $disabledDate) {
if($disabledDate[0]->getActivityClosed()) $activityClosed = $disabledDate[0]->getActivityClosed();
else $activityClosed = '';
if($data->creneaux[$i]['heure_debut_utc'] >= $disabledDate['from'] && $data->creneaux[$i]['heure_debut_utc'] < $disabledDate['to'] && $activityClosed == '') {
$data->creneaux[$i]['reservable'] = false;
} else if($data->creneaux[$i]['heure_debut_utc'] >= $disabledDate['from'] && $data->creneaux[$i]['heure_debut_utc'] < $disabledDate['to'] && $activityClosed == $code) {
$data->creneaux[$i]['reservable'] = false;
}
}
}
/* on récupère les infos Calendar du créneau */
$dateType = $em->getRepository(Calendar::class)->findTypeByDate($data->creneaux[$i]['heure_debut_utc']->format('Y-m-d'));
if($dateType) {
$data->creneaux[$i]['type'] = $dateType[0]['type'];
} else {
$data->creneaux[$i]['type'] = null;
}
/* on récupère le tarif pour ce créneau */
$day = new \DateTime($data->creneaux[$i]['heure_debut_utc']->format('Y-m-d'), $dateTimeZone);
$formatter = new \IntlDateFormatter('fr_FR', NULL, NULL, $dateTimeZone, NULL, 'EEEE');
$dayName = $formatter->format($day);
if($data->creneaux[$i]['type'] != null) {
$dayName = $dateType[0]['type'];
} else {
$data->creneaux[$i]['type'] = $dayName;
}
/******** PROMOS *********/
/* On récupère les conditions de la promotion si elle existe */
$promo = $em->getRepository(Promos::class)
->findPromosByCreneau( $data->creneaux[$i]['heure_debut_utc']->format('H:i:s'),
$bookingDate,
$dayName,
$forfait_id
);
if($promo) {
$data->creneaux[$i]['promo'] = true;
} else {
$data->creneaux[$i]['promo'] = false;
}
}
} else {
/* on récupère les infos Calendar du créneau */
$dateType = $em->getRepository(Calendar::class)->findTypeByDate($bookingDate->format('Y-m-d'));
/* on récupère le tarif pour ce créneau */
$day = new \DateTime($bookingDate->format('Y-m-d'), $dateTimeZone);
$formatter = new \IntlDateFormatter('fr_FR', NULL, NULL, $dateTimeZone, NULL, 'EEEE');
$dayName = $formatter->format($day);
if($dateType) {
$dayName = $dateType[0]['type'];
}
$data->type = $dayName;
}
}
if ($error != '') {
return new JsonResponse(['error' => $error], JsonResponse::HTTP_CREATED);
} else {
return new JsonResponse($data, JsonResponse::HTTP_CREATED);
}
}
/**
* @Route("/creneaux_formules", methods={"POST"}, name="booking_creneauxformules")
* Cette fonction permet de récupérer tous les créneaux d'une activité
*/
public function getCreneauxFormules(Request $request)
{
/* POST Method */
$data = json_decode($request->request->get('data'));
// if(md5($this->pk) != $request->request->get('key')) exit();
$em = $this->getDoctrine()->getManager();
$error = '';
$dateTimeZone = new \DateTimeZone('Europe/Paris');
$today = new \DateTime('now', $dateTimeZone);
$date = $data->date;
if(strpos($date, '/') !== false) {
$date_temp = explode('/',$date);
$date = $date_temp[2].'-'.$date_temp[1].'-'.$date_temp[0];
}
$bookingDate = new \DateTime($date, $dateTimeZone);
$formatter = new \IntlDateFormatter('fr_FR', NULL, NULL, $dateTimeZone, NULL, 'EEEE');
$dayName = $formatter->format($bookingDate);
/* on récupère les infos Calendar du créneau */
$dateType = $em->getRepository(Calendar::class)->findTypeByDate($bookingDate);
if ($dateType) {
$dayName = $dateType[0]['type'];
}
$formule_id = $data->formule_id;
$formule_code = $data->formule_code;
/*** On récupère les infos de la formule pour créer les créneaux ***/
$formuleToBook = $em->getRepository(Formule::class)->find($formule_id);
if (!$formuleToBook) {
$error = 'no formule found : '. $formule_id;
return new JsonResponse(['error' => $error], JsonResponse::HTTP_CREATED);
}
if($formuleToBook instanceof Formule)
{
$code = $formuleToBook->getCode();
$data->is_creneau_activity = $formuleToBook->getIsCreneauActivity();
if($data->is_creneau_activity)
{
$data->nbre_maxi = $formuleToBook->getNbreMaxi();
$data->temps_creneau = $formuleToBook->getTempsCreneau();
$debutCreneau = new \DateTime($date . ' ' . $formuleToBook->getHeureOuvertureCreneau()->format('H:i:s'), $dateTimeZone);
if($formuleToBook->getHeureFermetureCreneau()->format('H') >= 0 && $formuleToBook->getHeureFermetureCreneau()->format('H') <= 2)
{
$dv = new \DateInterval('P1D');
$finCreneau = new \DateTime($date . ' ' . $formuleToBook->getHeureFermetureCreneau()->format('H:i:s'), $dateTimeZone);
$finCreneau->add($dv);
} else {
$finCreneau = new \DateTime($date . ' ' . $formuleToBook->getHeureFermetureCreneau()->format('H:i:s'), $dateTimeZone);
}
$dv2 = new \DateInterval('PT'.$data->temps_creneau.'M');
$finCreneau->add($dv2); // On ajoute en min le temps du jeu
$tempsTotalCreneaux = $debutCreneau->diff($finCreneau);
$nbreCreneaux = $tempsTotalCreneaux->h * 60 / $data->temps_creneau;
$data->heure_debut = $debutCreneau;
$data->heure_fin = $finCreneau;
$data->temps_dispo = $tempsTotalCreneaux->h * 60;
$data->nbre_creneaux = $nbreCreneaux;
$i = 0;
$data->creneaux = array();
for($i = 0; $i <= $nbreCreneaux; $i++) {
$data->creneaux[$i] = array();
$dv4 = new \DateInterval('PT'.$data->temps_creneau * $i.'M');
$data->creneaux[$i]['heure_debut_utc'] = new \DateTime($data->heure_debut->format('Y-m-d H:i:s'), $dateTimeZone);
$data->creneaux[$i]['heure_debut_utc']->add($dv4);
if($today > $data->creneaux[$i]['heure_debut_utc']) {
unset($data->creneaux[$i]);
continue; // Si résa le jour même, on ne charge pas les créneaux si la date et l'heure ont dépassé les créneaux de la journée
}
$data->creneaux[$i]['heure_debut'] = $data->creneaux[$i]['heure_debut_utc']->format('H\hi');
$data->creneaux[$i]['reservable'] = true;
/* on vérifie si le délai est suffisant pour réserver le créneau */
$dv3 = new \DateInterval('PT'.$formuleToBook->getTempsLimiteResa().'M');
$bookingDelay = new \DateTime('now', $dateTimeZone);
$bookingDelay->add($dv3); // On ajoute en min la limite de résa
if($bookingDelay > $data->creneaux[$i]['heure_debut_utc']) {
$data->creneaux[$i]['reservable'] = false;
}
/* on vérifie les places déjà réservées pour ce créneau */
$nbre_resa = count($em->getRepository(Reservation::class)->findByCodeAndDate($formule_code, $data->creneaux[$i]['heure_debut_utc']));
$data->creneaux[$i]['places_dispo'] = intval($data->nbre_maxi) - intval($nbre_resa);
if($data->creneaux[$i]['places_dispo'] <= 0) {
$data->creneaux[$i]['reservable'] = false;
}
/* on récupère les infos Calendar du créneau */
$dateType = $em->getRepository(Calendar::class)->findTypeByDate($data->creneaux[$i]['heure_debut_utc']->format('Y-m-d'));
if($dateType) {
$data->creneaux[$i]['type'] = $dateType[0]['type'];
} else $data->creneaux[$i]['type'] = null;
/* on récupère le tarif pour ce créneau */
$day = new \DateTime($data->creneaux[$i]['heure_debut_utc']->format('Y-m-d'), $dateTimeZone);
$formatter = new \IntlDateFormatter('fr_FR', NULL, NULL, $dateTimeZone, NULL, 'EEEE');
$dayName = $formatter->format($day);
if($data->creneaux[$i]['type'] != null) {
$dayName = $dateType[0]['type'];
} else {
$data->creneaux[$i]['type'] = $dayName;
}
// /******** PROMOS *********/
//TO-DO : vérifier si un forfait anniversaire est en promo sur le créneau
// /* On récupère les conditions de la promotion si elle existe */
// $promo = $em->getRepository(Promos::class)->findPromosByCreneau( $data->creneaux[$i]['heure_debut_utc']->format('H:i:s'),
// $bookingDate,
// $dayName,
// $forfait_id
// );
// if($promo) {
// $data->creneaux[$i]['promo'] = true;
// } else {
// $data->creneaux[$i]['promo'] = false;
// }
}
} else {
/* on récupère les infos Calendar du créneau */
$dateType = $em->getRepository(Calendar::class)->findTypeByDate($bookingDate->format('Y-m-d'));
/* on récupère le tarif pour ce créneau */
$day = new \DateTime($bookingDate->format('Y-m-d'), $dateTimeZone);
$formatter = new \IntlDateFormatter('fr_FR', NULL, NULL, $dateTimeZone, NULL, 'EEEE');
$dayName = $formatter->format($day);
if($dateType) {
$dayName = $dateType[0]['type'];
}
$data->type = $dayName;
}
}
if ($error != '') {
return new JsonResponse(['error' => $error], JsonResponse::HTTP_CREATED);
} else {
return new JsonResponse($data, JsonResponse::HTTP_CREATED);
}
}
/**
* @Route("/cron_calendar", name="calendar_cron", methods={"GET"})
*/
public function cron(Request $request, CalendarRepository $calendarRepository): Response
{
$url = array();
$url['vacances'] = 'https://fr.ftp.opendatasoft.com/openscol/fr-en-calendrier-scolaire/Zone-A.ics'; //Abonnement aux périodes de vacances N+1
// $url['feries'] = 'https://www.thunderbird.net/media/caldata/FrenchHolidays.ics'; //Fichier ICS jours fériés jusqu'en 2030
$url['feries'] = 'https://ical-holidays.com/fr/jour-ferie/france/2024/calendar'; //Fichier ICS jours fériés jusqu'en 2030
$dateTimeZone = new \DateTimeZone('Europe/Paris');
$today = new \DateTime('now', $dateTimeZone);
$year = intval($today->format("Y"));
$em = $this->getDoctrine()->getManager();
// var_dump('plop');
/* POST Method */
// if(md5($this->pk) == $request->query->get('key')) {
/* Suppression de tous les enregistrements */
$results = $calendarRepository->findBy(['type' => 'vacances']);
foreach($results as $calendar) {
$em->remove($calendar);
}
$results = $calendarRepository->findBy(['type' => 'veille']);
foreach($results as $calendar) {
$em->remove($calendar);
}
$results = $calendarRepository->findBy(['type' => 'feries']);
foreach($results as $calendar) {
$em->remove($calendar);
}
/**************************************/
/* récupération des dates de vacances */
/**************************************/
$ical = new ICal();
$ical->initUrl($url['vacances']);
$fromDateSummer = array(); //Vacances d'été
$toDateSummer = array(); //Vacances d'été
foreach($ical->events() as $event) {
$fromDate = new \DateTime($event->dtstart, $dateTimeZone);
$annee = $fromDate->format("Y");
if(isset($event->dtend) && $event->dtend != "")
$toDate = new \DateTime($event->dtend, $dateTimeZone);
else
$toDate = $fromDate;
if ($fromDate >= $today && Tools::str2url($event->description) != "prerentree-des-enseignants")
{
if(Tools::str2url($event->description) != "vacances-d-ete" && Tools::str2url($event->description) != "rentree-scolaire-des-eleves")
{
$calendar = new Calendar;
$calendar->setDesignation(Tools::str2url($event->description));
$calendar->setType('vacances');
$calendar->setFromDate($fromDate);
$calendar->setToDate($toDate);
$calendar->setPriority(1); // Vacances en priorité 1 pour l'application des tarifs
if(!$calendarRepository->findOneBy(['from_date' => $fromDate, 'to_date' => $toDate, 'type' => 'vacances'])) {
$em->persist($calendar);
$em->flush();
}
/* ajout de la veille */
$dv = new \DateInterval('P1D');
$veilleDate = new \DateTime($event->dtstart, $dateTimeZone);
$veilleDate->sub($dv); // On enlève un jour
$toDateVeille = new \DateTime($event->dtstart, $dateTimeZone);
$veille = new Calendar;
$veille->setDesignation("Veille : ".$event->description);
$veille->setType('veille');
$veille->setFromDate($veilleDate);
$veille->setToDate($toDateVeille);
$veille->setPriority(3); // Veilles de vacances en priorité 3 pour l'application des tarifs
$em->persist($veille);
$em->flush();
}
}
if(Tools::str2url($event->description) == "vacances-d-ete") $fromDateSummer[$annee] = $event->dtstart;
if(Tools::str2url($event->description) == "rentree-scolaire-des-eleves") $toDateSummer[$annee] = $event->dtstart;
}
/* Vacances d'été */
for($i = $year; $i <= $year + 1; $i++) {
if(isset($fromDateSummer[$i]) && $fromDateSummer[$i] != "")
{
$fromDate = new \DateTime($fromDateSummer[$i], $dateTimeZone);
$calendar = new Calendar;
$calendar->setDesignation("Vacances d'été");
$calendar->setType('vacances');
$calendar->setFromDate($fromDate);
$calendar->setPriority(1); // Vacances en priorité 1 pour l'application des tarifs
if(isset($toDateSummer[$i]) && $toDateSummer[$i] != "") {
$toDate = new \DateTime($toDateSummer[$i], $dateTimeZone);
$calendar->setToDate($toDate);
} else {
$calendar->setToDate(new \DateTime($i.'-08-31', $dateTimeZone));
}
$em->persist($calendar);
$em->flush();
/* ajout de la veille */
$dv = new \DateInterval('P1D');
$veilleDate = new \DateTime($fromDateSummer[$i], $dateTimeZone);
$veilleDate->sub($dv); // On enlève un jour
$toDateVeille = new \DateTime($fromDateSummer[$i], $dateTimeZone);
$veille = new Calendar;
$veille->setDesignation("Veille : Vacances d'été");
$veille->setType('veille');
$veille->setFromDate($veilleDate);
$veille->setToDate($toDateVeille);
$veille->setPriority(3); // Veilles de vacances en priorité 3 pour l'application des tarifs
$em->persist($veille);
$em->flush();
} else {
$calendar = new Calendar;
$calendar->setDesignation("Vacances d'été");
$calendar->setType('vacances');
$calendar->setFromDate(new \DateTime($i.'-07-01', $dateTimeZone));
$calendar->setToDate(new \DateTime($i.'-08-31', $dateTimeZone));
$calendar->setPriority(1); // Vacances en priorité 1 pour l'application des tarifs
$em->persist($calendar);
$em->flush();
/* ajout de la veille */
$dv = new \DateInterval('P1D');
$veilleDate = new \DateTime($i.'-07-01', $dateTimeZone);
$veilleDate->sub($dv); // On enlève un jour
$veille = new Calendar;
$veille->setDesignation("Veille : Vacances d'été");
$veille->setType('veille');
$veille->setFromDate($veilleDate);
$veille->setToDate(new \DateTime($i.'-07-01', $dateTimeZone));
$veille->setPriority(3); // Veilles de vacances en priorité 3 pour l'application des tarifs
$em->persist($veille);
$em->flush();
}
}
/******************************************/
/* récupération des dates de jours fériés */
/******************************************/
$ical = new ICal();
$ical->initUrl($url['feries']);
// dd($ical->events()[0]->dtstart, $ical->events()[0]->dtend);
foreach($ical->events() as $event) {
$fromDate = new \DateTime($event->dtstart, $dateTimeZone);
if(isset($event->dtend) && $event->dtend != "") {
$toDate = new \DateTime($event->dtend, $dateTimeZone);
if($event->dtstart == $event->dtend) {
$dv = new \DateInterval('P1D');
$toDate->add($dv);
}
} else {
$toDate = $fromDate;
}
if ($fromDate >= $today)
{
$calendar = new Calendar;
$calendar->setDesignation($event->summary);
$calendar->setType('feries');
$calendar->setFromDate($fromDate);
$calendar->setToDate($toDate);
$calendar->setPriority(2); // Fériés en priorité 2 pour l'application des tarifs
$em->persist($calendar);
$em->flush();
/* ajout de la veille */
$dv = new \DateInterval('P1D');
$veilleDate = new \DateTime($event->dtstart, $dateTimeZone);
$veilleDate->sub($dv); // On enlève un jour
$veille = new Calendar;
$veille->setDesignation("Veille : ".$event->summary);
$veille->setType('veille');
$veille->setFromDate($veilleDate);
$veille->setToDate($fromDate);
$veille->setPriority(3); // Veilles de vacances en priorité 3 pour l'application des tarifs
$em->persist($veille);
$em->flush();
}
}
// }
return $this->redirectToRoute('admin');
}
public function checkDayOpening($openingDays, $dayName, $specialDayName)
{
$return_data = false;
foreach ($openingDays as $key => $day) {
if($day->getDay() == $dayName) {
if($specialDayName == "vacances" && $day->isIsHolidays()) $return_data = $day;
if($specialDayName == "feries" && $day->isIsPublicHoliday()) $return_data = $day;
if(!$day->isIsPublicHoliday() && !$day->isIsHolidays()) $return_data = $day;
}
}
return $return_data;
}
}