<?php
namespace App\Controller\Website;
use App\Entity\Client;
use Psr\Log\LoggerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Doctrine\ORM\EntityManagerInterface;
use App\Entity\Tarif;
use App\Entity\Transaction;
use App\Entity\Commande;
use App\Entity\BonCommande;
use App\Service\EntitySaver;
use App\Service\SogecommerceService;
use IntlDateFormatter;
use App\Entity\PlanningReservation;
class FrontController extends AbstractController
{
private $requestStack;
private EntitySaver $entitySaver;
private $sogecommerceService;
public function __construct(RequestStack $requestStack, EntitySaver $entitySaver, SogecommerceService $sogecommerceService)
{
$this->requestStack = $requestStack;
$this->entitySaver = $entitySaver;
$this->sogecommerceService = $sogecommerceService;
}
#[Route('/reservation', name: 'front_reserve')]
public function reserver(Request $request, EntityManagerInterface $entityManager): Response
{
$urlPrecedente = $request->headers->get('referer');
$user = $this->getUser();
$content = [
'title' => 'Choisissez vos réservations'
];
$step = $request->query->get('step');
$datas = [];
$repositoryTrf = $entityManager->getRepository(Tarif::class);
$tarifsDb = $repositoryTrf->findAll();
$tarifs = [];
foreach($tarifsDb as $item){
$tarifs[$item->getId()] = $item;
}
if($step == 'recap' && !empty($user)){
$bon_commande_id = $this->entitySaver->getBonCommandeEncours($user->getId(), $entityManager);
$conditions = [
'client_id' => $user->getId(),
'statut_id' => 1,
'bon_commande_id' => $bon_commande_id
];
$repositoryDb = $entityManager->getRepository(Commande::class);
$cmd = $repositoryDb->findByFilters($conditions);
$datas['commandes'] = $cmd;
$content['title'] = 'Récapitulatif';
$bon_commande_id = 0;
// On boucle la commande pour avoir la totalité
if(!empty($cmd)){
$total = 0;
foreach($cmd as $itemCmd){
$total += $itemCmd->qte * $tarifs[$itemCmd->tarif_id]->pu;
$bon_commande_id = $itemCmd->getBonCommandeId();
}
// Convertir en chaîne pour s'assurer de la compatibilité
if (strlen((string)$bon_commande_id) < 6) {
$bon_commande_id = str_pad($bon_commande_id, 6, '0', STR_PAD_LEFT);
}
// 20% designe le TVA
$total = $total + $total * 0.20;
$form = $this->sogecommerceService->generatePaymentForm([
'vads_amount' => $total * 100, // Amount in cents
'vads_failure_url' => 'https://preprod.panda-coworking.com'.$this->generateUrl('payment_failure', [], true),
'vads_cust_name' => $user->getPrenom() . ' ' . $user->getNom(),
'vads_url_return' => 'https://preprod.panda-coworking.com'.$this->generateUrl('front_retour', [], true),
'vads_trans_id' => $bon_commande_id, // Unique transaction ID
]);
$datas['paymentForm'] = $form;
}
}
if ($request->isMethod('POST')) {
$commandes = $this->entitySaver->getCommandesEncours();
$cmd = $request->request->get('data');
foreach($cmd as $tarifId => $nb){
if($nb){
$commandes[] = [
'tarif_id' => $tarifId,
'qte' => $nb,
'date_commande' => date('Y-m-d H:i:s')
];
}
}
if(!empty($commandes)){
// si le client n'est pas connecté on stocke dans une variable de session on force à logguer ou créer un compte
if(empty($user)){
$commandes = $this->entitySaver->setCommandes($commandes);
return $this->redirectToRoute('login', [null, 'pm' => base64_encode(serialize(['datetime' => strtotime(Date('Y-m-d H:i:s'))]))]);
die;
}
// Sinon on affiche le récapitulatif et on procède au processus de paiement ...
else {
// Récupération du bon de commande
$bon_commande_id = $this->entitySaver->getBonCommandeEncours($user->getId(), $entityManager);
// Enregistrement des informations de commandes + redirection de la liste des commandes en cours
foreach($commandes as &$item){
$item['client_id'] = $user->getId();
$commande = new Commande();
$commande->setTarifId($item['tarif_id']);
$commande->setQte($item['qte']);
$commande->setClientId($item['client_id']);
$commande->setBonCommandeId($bon_commande_id);
$commande->setDateCommande($item['date_commande']);
$commande->setStatutId(1);
$commande->setCreated();
$commande->setChanged();
$tmp[] = $commande;
}
$this->entitySaver->saveMany($tmp);
$this->entitySaver->initCommandes();
// Rédirection vers le recapitulatif
return $this->redirectToRoute('front_reserve', [null, 'step' => 'recap']);
die;
}
}
}
// Rah ohatra ka m'post anle commande izy eto
// Si le client est déjà connecté => on redirige vers le paiement + enregistrement des commandes
// Sinon on affiche la page pour la Création d'un compte et login + enregistrement dans une variable de Session
// PROCESSUS DANS L'AUTRE FONCTION
// Si le client à déjà un compte => après avoir logguer on enregistre les commandes et on supprime la variable de Session et on le redirige vers l'interface de paiement
// Sinon il crée son propre compte puis on le force à se logguer + enregistrement des commandes + suppression variable de session >> redirection ver l'interface de paiment
// Liste des reservations pour cette semaine
// Date actuelle
$dateFiltre = $request->query->get('d');
$date = new \DateTime();
if(!empty($dateFiltre)){
$date = new \DateTime($dateFiltre);
}
$formatter = new IntlDateFormatter(
'fr_FR', // Locale en français
IntlDateFormatter::LONG, // Format long (ex. "février 2025")
IntlDateFormatter::NONE, // Pas besoin de l'heure
null,
null,
'MMMM' // Format uniquement pour afficher le mois en toutes lettres
);
$date1 = $date;
$mois_annee = $formatter->format($date1->modify('this week sunday'));
$date_lundi = $date->modify('this week monday')->format('Y-m-d');
$date_mardi = $date->modify('this week tuesday')->format('Y-m-d');
$date_mercred = $date->modify('this week wednesday')->format('Y-m-d');
$date_jeudi = $date->modify('this week thursday')->format('Y-m-d');
$date_vendredi = $date->modify('this week friday')->format('Y-m-d');
$date_samedi = $date->modify('this week saturday')->format('Y-m-d');
$date_dimanche = $date->modify('this week sunday')->format('Y-m-d');
$titre_tableau = 'Semaine du '.$date->modify('this week monday')->format('d').' au '.$date->modify('this week sunday')->format('d').' '.$mois_annee;
$dateNext = $date->modify('next week monday')->format('Y-m-d');
$dateLast = $date->modify('-14 days')->format('Y-m-d');
$options = [
'statut_id' => 1
];
$dates = [$date_lundi, $date_dimanche];
$repository = $entityManager->getRepository(PlanningReservation::class);
$plannings = $repository->findByFilters($options, $dates);
// Regroupement en PHP
$groupedByDate = [];
foreach ($plannings as $event) {
$dateKey = $event->getDateReservation()->format('Y-m-d');
$timeValue = $event->getHeureDebut();
// Initialiser la clé si elle n'existe pas
if (!isset($groupedByDate[$dateKey])) {
$groupedByDate[$dateKey] = [];
}
// Ajouter les données de l'événement et du client
$groupedByDate[$dateKey][] = [
'time' => $timeValue,
'client_id' => $event->getClientId(),
'id' => $event->getId()
];
}
$modal = $request->query->get('modal');
// récupère les données comme $titre, $reservations, etc.
$template = $modal ? 'front/disponibilites_fragment.html.twig' : 'front/reserver.html.twig';
return $this->render($template, [
'tarifs' => $tarifs,
'content' => $content,
'step' => $step,
'datas' => $datas,
'referer' => $urlPrecedente,
'titre' => 'Disponibilité de la salle de réunion',
'reservations' => $groupedByDate, // pas de json_encode
'titre_tableau' => $titre_tableau,
'date_next' => $dateNext,
'date_last' => $dateLast,
'dates' => [$date_lundi, $date_mardi, $date_mercred, $date_jeudi, $date_vendredi, $date_samedi, $date_dimanche]
]);
}
#[Route('/retour-commande', name: 'front_retour', methods: ['GET', 'POST'])]
public function returnCommande(Request $request, EntityManagerInterface $entityManager, LoggerInterface $logger): Response
{
$user = $this->getUser();
$step = "";
$transStatus = $request->get('vads_trans_status');
$resultCode = $request->get('vads_result');
$authResult = $request->get('vads_auth_result');
$logger->info('Retour de paiement Sogecommerce :', $request->query->all());
if (!empty($user)) {
// --- Cas commande annulée ---
if ($transStatus === 'ABANDONED' || $resultCode === '17') {
$step = "annulation";
$bon_commande = $entityManager->getRepository(BonCommande::class)->findOneBy([
'statut_id' => 1,
'client_id' => $user->getId()
]);
if (!empty($bon_commande)) {
$bon_commande->setStatutId(3);
$bon_commande->setChanged();
$entityManager->persist($bon_commande);
$conditions = [
'statut_id' => 1,
'bon_commande_id' => $bon_commande->getId()
];
$repository = $entityManager->getRepository(Commande::class);
$commandes = $repository->findByFilters($conditions);
foreach ($commandes as $commande) {
$commande->setStatutId(3);
$commande->setChanged();
$entityManager->persist($commande);
}
$entityManager->flush();
$this->entitySaver->initCommandes();
}
}
// --- Cas paiement accepté ---
elseif ($resultCode === '00' && $transStatus === 'AUTHORISED' && $authResult === '00') {
// Vérifie si le bon de commande est bien passé au statut "payé" (= 2)
$bon_commande = $entityManager->getRepository(BonCommande::class)->findOneBy([
'statut_id' => 2,
'client_id' => $user->getId()
]);
if ($bon_commande) {
$step = "confirmation";
} else {
$step = "erreur"; // ou "attente de traitement"
}
}
}
return $this->render('front/retour.html.twig', [
'step' => $step,
]);
}
#[Route('/reservation/disponibilite-salle-reunion', name: 'app_disponibilite_salle')]
public function voirDisponibilitesSalleReunion(Request $request, EntityManagerInterface $entityManager): Response
{
// Liste des reservations pour cette semaine
// Date actuelle
$dateFiltre = $request->query->get('d');
$date = new \DateTime();
if(!empty($dateFiltre)){
$date = new \DateTime($dateFiltre);
}
$formatter = new IntlDateFormatter(
'fr_FR', // Locale en français
IntlDateFormatter::LONG, // Format long (ex. "février 2025")
IntlDateFormatter::NONE, // Pas besoin de l'heure
null,
null,
'MMMM' // Format uniquement pour afficher le mois en toutes lettres
);
$date1 = $date;
$mois_annee = $formatter->format($date1->modify('this week sunday'));
$date_lundi = $date->modify('this week monday')->format('Y-m-d');
$date_mardi = $date->modify('this week tuesday')->format('Y-m-d');
$date_mercred = $date->modify('this week wednesday')->format('Y-m-d');
$date_jeudi = $date->modify('this week thursday')->format('Y-m-d');
$date_vendredi = $date->modify('this week friday')->format('Y-m-d');
$date_samedi = $date->modify('this week saturday')->format('Y-m-d');
$date_dimanche = $date->modify('this week sunday')->format('Y-m-d');
// $titre_tableau = 'Semaine du '.$date->modify('this week monday')->format('d').' au '.$date->modify('this week sunday')->format('d').' '.$date->modify('this week sunday')->format('F Y');
$titre_tableau = 'Semaine du '.$date->modify('this week monday')->format('d').' au '.$date->modify('this week sunday')->format('d').' '.$mois_annee;
$dateNext = $date->modify('next week monday')->format('Y-m-d');
$dateLast = $date->modify('-14 days')->format('Y-m-d');
$options = [
'statut_id' => 1
];
$dates = [$date_lundi, $date_dimanche];
$repository = $entityManager->getRepository(PlanningReservation::class);
$plannings = $repository->findByFilters($options, $dates);
// Regroupement en PHP
$groupedByDate = [];
foreach ($plannings as $event) {
$dateKey = $event->getDateReservation()->format('Y-m-d');
$timeValue = $event->getHeureDebut();
// Initialiser la clé si elle n'existe pas
if (!isset($groupedByDate[$dateKey])) {
$groupedByDate[$dateKey] = [];
}
// Ajouter les données de l'événement et du client
$groupedByDate[$dateKey][] = [
'time' => $timeValue,
'client_id' => $event->getClientId(),
'id' => $event->getId()
];
}
return $this->render('front/disponibilites.html.twig', [
'titre'=>'Disponibilité de la salle de réunion',
'reservations' => json_encode($groupedByDate),
'titre_tableau' => $titre_tableau,
'date_next' => $dateNext,
'date_last' => $dateLast,
'dates' => json_encode([$date_lundi, $date_mardi, $date_mercred, $date_jeudi, $date_vendredi, $date_samedi, $date_dimanche])
]);
}
}