Compare commits

...

3 Commits

23 changed files with 624 additions and 316 deletions

View File

@ -39,7 +39,7 @@
"symfony/string": "7.1.*", "symfony/string": "7.1.*",
"symfony/translation": "7.1.*", "symfony/translation": "7.1.*",
"symfony/twig-bundle": "7.1.*", "symfony/twig-bundle": "7.1.*",
"symfony/ux-icons": "^2.21", "symfony/ux-icons": "^2.24",
"symfony/ux-turbo": "^2.20", "symfony/ux-turbo": "^2.20",
"symfony/validator": "7.1.*", "symfony/validator": "7.1.*",
"symfony/web-link": "7.1.*", "symfony/web-link": "7.1.*",

24
composer.lock generated
View File

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "7fff997f78db4185bb53c4543a245c74", "content-hash": "d1751dd70a356412dfadda645c7118ec",
"packages": [ "packages": [
{ {
"name": "amphp/amp", "name": "amphp/amp",
@ -8164,16 +8164,16 @@
}, },
{ {
"name": "symfony/ux-icons", "name": "symfony/ux-icons",
"version": "v2.21.0", "version": "v2.24.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/ux-icons.git", "url": "https://github.com/symfony/ux-icons.git",
"reference": "c3b3fd29b3f90e977b267251ef15ea06f3cec553" "reference": "39f689b41081f7788ee9c4a188817599d546bfb2"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/ux-icons/zipball/c3b3fd29b3f90e977b267251ef15ea06f3cec553", "url": "https://api.github.com/repos/symfony/ux-icons/zipball/39f689b41081f7788ee9c4a188817599d546bfb2",
"reference": "c3b3fd29b3f90e977b267251ef15ea06f3cec553", "reference": "39f689b41081f7788ee9c4a188817599d546bfb2",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -8197,8 +8197,8 @@
"type": "symfony-bundle", "type": "symfony-bundle",
"extra": { "extra": {
"thanks": { "thanks": {
"name": "symfony/ux", "url": "https://github.com/symfony/ux",
"url": "https://github.com/symfony/ux" "name": "symfony/ux"
} }
}, },
"autoload": { "autoload": {
@ -8233,7 +8233,7 @@
"twig" "twig"
], ],
"support": { "support": {
"source": "https://github.com/symfony/ux-icons/tree/v2.21.0" "source": "https://github.com/symfony/ux-icons/tree/v2.24.0"
}, },
"funding": [ "funding": [
{ {
@ -8249,7 +8249,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2024-10-21T19:01:22+00:00" "time": "2025-04-04T17:32:18+00:00"
}, },
{ {
"name": "symfony/ux-turbo", "name": "symfony/ux-turbo",
@ -11242,7 +11242,7 @@
], ],
"aliases": [], "aliases": [],
"minimum-stability": "stable", "minimum-stability": "stable",
"stability-flags": [], "stability-flags": {},
"prefer-stable": true, "prefer-stable": true,
"prefer-lowest": false, "prefer-lowest": false,
"platform": { "platform": {
@ -11250,6 +11250,6 @@
"ext-ctype": "*", "ext-ctype": "*",
"ext-iconv": "*" "ext-iconv": "*"
}, },
"platform-dev": [], "platform-dev": {},
"plugin-api-version": "2.3.0" "plugin-api-version": "2.6.0"
} }

View File

@ -1,105 +1,107 @@
html{ /* Appliquer une police moderne */
font-family: "Quicksand Light"; !important; html {
} font-family: "Quicksand", sans-serif !important;
/* Page container */
.page-container {
width: 100%;
max-width: 600px;
margin: 20px auto;
padding: 20px;
background-color: #fff;
border-radius: 10px;
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
border: 2px solid #ff4d4d;
} }
/* Title */
.page-title { /* Titre du formulaire */
text-align: center; h1 {
font-size: 28px; font-size: 26px;
color: #ff4d4d; color: #db5559;
margin-bottom: 20px; margin-bottom: 20px;
font-weight: bold; font-weight: bold;
text-transform: uppercase; text-transform: uppercase;
letter-spacing: 1px; letter-spacing: 1.2px;
} }
/* Form styles */ /* Formulaire */
form { form {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 15px; gap: 15px;
align-items: center;
} }
/* Groupes de champs */
.form-group { .form-group {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: flex-start;
width: 100%;
} }
/* Labels */
label { label {
font-weight: bold; font-weight: bold;
color: #ff4d4d; color: #db5559;
margin-bottom: 5px; margin-bottom: 6px;
font-size: 14px;
} }
/* Champs de saisie */
input[type="text"], input[type="text"],
input[type="email"], input[type="email"],
input[type="number"], input[type="number"],
textarea, textarea,
select { select {
padding: 10px; width: 100%;
border: 1px solid #ccc; padding: 12px;
border-radius: 5px; border: 2px solid #ddd;
font-size: 14px; border-radius: 6px;
font-size: 16px;
color: #333; color: #333;
transition: border-color 0.3s ease-in-out; transition: all 0.3s ease-in-out;
background-color: #fff;
} }
input[type="text"]:focus, input:focus,
input[type="email"]:focus,
input[type="number"]:focus,
textarea:focus, textarea:focus,
select:focus { select:focus {
border-color: #ff4d4d; border-color: #db5559;
outline: none; outline: none;
box-shadow: 0 0 5px rgba(219, 85, 89, 0.5);
} }
/* Submit button */ /* Bouton d'envoi */
button { button {
background-color: #ff4d4d; background-color: #db5559;
color: white; color: white;
font-weight: bold; font-weight: bold;
padding: 12px 20px; padding: 14px;
border: none; border: none;
border-radius: 5px; border-radius: 8px;
font-size: 16px; font-size: 18px;
cursor: pointer; cursor: pointer;
text-transform: uppercase; text-transform: uppercase;
transition: background-color 0.3s ease-in-out; transition: all 0.3s ease-in-out;
width: 100%;
} }
button:hover { button:hover {
background-color: #e60000; background-color: #b52b31;
} }
/* Links */ /* Bouton de retour */
.actions { #container_modal a {
display: inline-block;
margin-top: 20px;
padding: 12px 20px;
background-color: transparent;
color: #db5559;
border: 2px solid #db5559;
border-radius: 6px;
font-size: 16px;
text-align: center; text-align: center;
margin-top: 15px;
}
.actions a {
text-decoration: none; text-decoration: none;
color: #ff4d4d; transition: all 0.3s ease-in-out;
font-weight: bold;
transition: color 0.3s ease-in-out;
} }
.actions a:hover { #container_modal a:hover {
color: #e60000; background-color: #db5559;
color: white;
} }
/* Error messages */ /* Messages d'erreur */
.error-message { .error-message {
color: #d9534f; color: #d9534f;
font-size: 14px; font-size: 14px;
@ -107,10 +109,9 @@ button:hover {
font-style: italic; font-style: italic;
} }
/* Empty space below */ /* Espacement supplémentaire */
body::after { body::after {
content: ''; content: '';
height: 20px; height: 20px;
display: block; display: block;
} }

127
public/css/Plats/plats.css Normal file
View File

@ -0,0 +1,127 @@
/* Title */
h1 {
text-align: center;
font-size: 42px;
color: #b03a2e;
margin-bottom: 20px;
}
/* Menu Grid */
.menu-container {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); /* 3 max par ligne */
gap: 20px;
justify-content: center;
}
/* Menu Card */
.menu-card {
background: white;
padding: 20px;
border-radius: 15px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15);
text-align: center;
transition: transform 0.3s ease, box-shadow 0.3s ease;
}
/* Plat Name */
.menu-card h2 {
font-size: 28px;
color: #b03a2e;
margin-bottom: 10px;
}
/* Description */
.menu-card p {
font-size: 18px;
color: #555;
margin-bottom: 10px;
}
/* Price */
.menu-card .price {
font-size: 22px;
font-weight: bold;
color: #388E3C;
margin-bottom: 15px;
}
/* Buttons */
.menu-card .actions {
display: flex;
justify-content: center;
gap: 10px;
}
/* Styles des boutons Modifier et Supprimer */
.menu-card .actions a,
.menu-card .actions button {
text-decoration: none;
font-size: 16px;
font-weight: bold;
padding: 10px 15px;
border-radius: 8px;
transition: all 0.3s ease-in-out;
border: none;
cursor: pointer;
display: inline-block; /* Pour que le bouton suppr ait le même comportement qu'un lien */
text-align: center;
}
/* Modifier */
.menu-card .edit {
background-color: #ffb74d;
color: white;
}
.menu-card .edit:hover {
background-color: #ffa726;
}
/* Supprimer */
.menu-card .delete {
background-color: #d32f2f;
color: white;
}
.menu-card .delete:hover {
background-color: #c62828;
}
.menu-card .edit {
background-color: #ffb74d;
color: white;
}
.menu-card .edit:hover {
background-color: #ffa726;
}
.menu-card .delete {
background-color: #d32f2f;
color: white;
}
.menu-card .delete:hover {
background-color: #c62828;
}
/* Button for Adding New Dish */
.add-menu {
display: block;
text-align: center;
background-color: #b03a2e;
color: white;
padding: 15px;
font-size: 20px;
margin-top: 30px;
border-radius: 10px;
width: 300px;
margin-left: auto;
margin-right: auto;
}
.add-menu:hover {
background-color: #922b21;
}

View File

@ -0,0 +1,84 @@
.calendar {
display: flex;
flex-direction: column;
}
.calendar-header {
display: flex;
}
.calendar-day {
flex: 1;
text-align: center;
font-weight: bold;
padding: 10px;
border: 1px solid #ddd;
}
.calendar-body {
display: flex;
}
.calendar-column {
flex: 1;
min-height: 400px;
border: 1px solid #ddd;
padding: 5px;
position: relative;
}
.reservation {
margin: 5px 0;
padding: 5px;
border-radius: 5px;
font-size: 14px;
text-align: center;
}
/* Conteneur pour les boutons de navigation */
.calendar-nav {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
}
/* Boutons de navigation (Semaine précédente / Semaine suivante) */
.calendar-nav a {
padding: 10px 15px;
text-decoration: none;
font-size: 16px;
font-weight: bold;
color: white;
background-color: #db5559;
border-radius: 5px;
transition: background-color 0.3s ease-in-out;
}
.calendar-nav a:hover {
background-color: #b52b31;
}
/* Conteneur pour le bouton d'ajout */
.add-reservation {
display: flex;
justify-content: center;
margin-top: 20px;
}
/* Bouton pour créer une réservation */
.add-reservation a {
padding: 12px 20px;
text-decoration: none;
font-size: 18px;
font-weight: bold;
color: white;
background-color: #4CAF50;
border-radius: 8px;
transition: background-color 0.3s ease-in-out;
}
.add-reservation a:hover {
background-color: #388E3C;
}

View File

@ -1,19 +1,22 @@
<?php <?php
// src/Controller/ClientsController.php
namespace App\Controller; namespace App\Controller;
use App\Entity\Clients; use App\Entity\Clients;
use App\Entity\Reductions;
use App\Form\ClientsType; use App\Form\ClientsType;
use App\Repository\ClientsRepository; use App\Repository\ClientsRepository;
use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route; use Symfony\Component\Routing\Annotation\Route;
#[Route('/clients')] #[Route('/clients')]
final class ClientsController extends AbstractController final class ClientsController extends AbstractController
{ {
#[Route(name: 'app_clients_index', methods: ['GET'])] #[Route(name: 'app_clients_index', methods: ['GET'])]
public function index(ClientsRepository $clientsRepository): Response public function index(ClientsRepository $clientsRepository): Response
{ {
@ -30,6 +33,12 @@ final class ClientsController extends AbstractController
$form->handleRequest($request); $form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) { if ($form->isSubmitted() && $form->isValid()) {
$montantTotal = $client->getTotalDepense();
if($montantTotal > 1000){
$this->appliquerReductionEtCreerSiNecessaire($client, $entityManager);
}
$entityManager->persist($client); $entityManager->persist($client);
$entityManager->flush(); $entityManager->flush();
@ -42,7 +51,6 @@ final class ClientsController extends AbstractController
]); ]);
} }
#[Route('/{id}/edit', name: 'app_clients_edit', methods: ['GET', 'POST'])] #[Route('/{id}/edit', name: 'app_clients_edit', methods: ['GET', 'POST'])]
public function edit(Request $request, Clients $client, EntityManagerInterface $entityManager): Response public function edit(Request $request, Clients $client, EntityManagerInterface $entityManager): Response
{ {
@ -50,6 +58,13 @@ final class ClientsController extends AbstractController
$form->handleRequest($request); $form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) { if ($form->isSubmitted() && $form->isValid()) {
$montantTotal = $client->getTotalDepense();
if($montantTotal > 1000){
$this->appliquerReductionEtCreerSiNecessaire($client, $entityManager);
}
$entityManager->flush(); $entityManager->flush();
return $this->redirectToRoute('app_clients_index', [], Response::HTTP_SEE_OTHER); return $this->redirectToRoute('app_clients_index', [], Response::HTTP_SEE_OTHER);
@ -62,13 +77,62 @@ final class ClientsController extends AbstractController
} }
#[Route('/{id}', name: 'app_clients_delete', methods: ['POST'])] #[Route('/{id}', name: 'app_clients_delete', methods: ['POST'])]
public function delete(Request $request, Clients $client, EntityManagerInterface $entityManager, int $id, ): Response public function delete(Request $request, Clients $client, EntityManagerInterface $entityManager): Response
{ {
if ($this->isCsrfTokenValid('delete'.$client->getId(), $request->getPayload()->getString('_token'))) { if ($this->isCsrfTokenValid('delete'.$client->getId(), $request->request->get('_token'))) {
$entityManager->remove($client); $entityManager->remove($client);
$entityManager->flush(); $entityManager->flush();
} }
return $this->redirectToRoute('app_clients_index', [], Response::HTTP_SEE_OTHER); return $this->redirectToRoute('app_clients_index', [], Response::HTTP_SEE_OTHER);
} }
// Méthode pour appliquer ou créer une réduction pour un client
// src/Controller/ClientsController.php
private function appliquerReductionEtCreerSiNecessaire(Clients $client, EntityManagerInterface $entityManager)
{
$montantTotal = $client->getTotalDepense();
$entityManager->persist($client);
$reductions = $entityManager->getRepository(Reductions::class)
->createQueryBuilder('r')
->where('r.montant_min <= :montantTotal')
->andWhere('r.actif = :actif')
->andWhere('r.DateDebut <= :currentDate')
->andWhere('r.DateFin >= :currentDate')
->setParameter('montantTotal', $montantTotal)
->setParameter('actif', true)
->setParameter('currentDate', new \DateTime())
->getQuery()
->getResult();
$newReduction = new Reductions();
if ($montantTotal >= 2000) {
$montantMin = 2000;
$pourcentage = 10;
} elseif ($montantTotal >= 1000) {
$montantMin = 1000;
$pourcentage = 5;
}
$newReduction->setPourcentage($pourcentage)
->setMontantMin($montantMin)
->setDateDebut(new \DateTime())
->setDateFin((new \DateTime())->modify('+1 year'))
->setActif(true)
->setClient($client);
$entityManager->persist($newReduction);
$entityManager->flush();
if (!$client->getReductions()->contains($newReduction)) {
$client->addReduction($newReduction);
}
$entityManager->flush();
}
} }

View File

@ -33,7 +33,7 @@ final class ReservationsController extends AbstractController
$entityManager->persist($reservation); $entityManager->persist($reservation);
$entityManager->flush(); $entityManager->flush();
return $this->redirectToRoute('app_reservations_index', [], Response::HTTP_SEE_OTHER); return $this->redirectToRoute('calendar_week', [], Response::HTTP_SEE_OTHER);
} }
return $this->render('reservations/new.html.twig', [ return $this->render('reservations/new.html.twig', [
@ -71,4 +71,29 @@ final class ReservationsController extends AbstractController
return $this->redirectToRoute('app_reservations_index', [], Response::HTTP_SEE_OTHER); return $this->redirectToRoute('app_reservations_index', [], Response::HTTP_SEE_OTHER);
} }
#[Route('/calendar/{year}/{week}', name: 'calendar_week', requirements: ['year' => '\d+', 'week' => '\d+'])]
public function calendar(ReservationsRepository $reservationsRepository, int $year = null, int $week = null): Response
{
if ($year === null || $week === null) {
$currentDate = new \DateTime();
$year = (int) $currentDate->format('Y');
$week = (int) $currentDate->format('W');
}
setlocale(LC_TIME, 'fr_FR.UTF-8');
$startDate = new \DateTime();
$startDate->setISODate($year, $week);
$endDate = (clone $startDate)->modify('+6 days');
$reservations = $reservationsRepository->findByDateRange($startDate, $endDate);
// dd($reservations);
return $this->render('reservations/index.html.twig', [
'reservations' => $reservations,
'startDate' => $startDate, // Passe startDate
'endDate' => $endDate, // Passe endDate
]);
}
} }

View File

@ -40,10 +40,17 @@ class Clients
#[ORM\ManyToMany(targetEntity: Commandes::class, mappedBy: 'Client')] #[ORM\ManyToMany(targetEntity: Commandes::class, mappedBy: 'Client')]
private Collection $commandes; private Collection $commandes;
#[ORM\Column]
private ?float $totalDepense = null;
#[ORM\OneToMany(targetEntity: Reductions::class, mappedBy: 'client', cascade: ['persist', 'remove'])]
private Collection $reductions;
public function __construct() public function __construct()
{ {
$this->tables = new ArrayCollection(); $this->tables = new ArrayCollection();
$this->commandes = new ArrayCollection(); $this->commandes = new ArrayCollection();
$this->reductions = new ArrayCollection();
} }
public function getId(): ?int public function getId(): ?int
@ -149,4 +156,60 @@ class Clients
return $this; return $this;
} }
public function getTotalDepense(): ?float
{
return $this->totalDepense;
}
public function setTotalDepense(float $totalDepense): static
{
$this->totalDepense = $totalDepense;
return $this;
}
// Dans l'entité Clients
public function appliquerReduction(): void
{
$montantTotal = $this->getTotalDepense();
// Vérifie s'il y a des réductions valides disponibles
$reductions = $this->getReductions(); // Récupérer toutes les réductions du client
foreach ($reductions as $reduction) {
// Vérifie si la réduction est valide (date de validité et montant minimum)
if ($reduction->getDateDebut() <= new \DateTime() && $reduction->getDateFin() >= new \DateTime()) {
if ($montantTotal >= $reduction->getMontantMin()) {
// Applique la réduction en pourcentage au total des dépenses
$reductionMontant = ($montantTotal * $reduction->getPourcentage()) / 100;
$nouveauTotal = $montantTotal - $reductionMontant; // Nouveau montant après réduction
$this->setTotalDepense($nouveauTotal); // Mise à jour du total des dépenses du client
// Met à jour l'objet client avec la réduction
break; // Si une réduction a été appliquée, on arrête
}
}
}
}
public function getReductions(): Collection
{
return $this->reductions;
}
public function addReduction(Reductions $reduction): static
{
if (!$this->reductions->contains($reduction)) {
$this->reductions->add($reduction);
}
return $this;
}
public function removeReduction(Reductions $reduction): static
{
$this->reductions->removeElement($reduction);
return $this;
}
} }

View File

@ -39,9 +39,6 @@ class Plats
#[ORM\ManyToMany(targetEntity: Commandes::class, inversedBy: 'plats')] #[ORM\ManyToMany(targetEntity: Commandes::class, inversedBy: 'plats')]
private Collection $Commande; private Collection $Commande;
#[ORM\ManyToOne(inversedBy: 'plats')]
private ?Reductions $Reduction = null;
public function __construct() public function __construct()
{ {
$this->Commande = new ArrayCollection(); $this->Commande = new ArrayCollection();
@ -147,16 +144,4 @@ class Plats
return $this; return $this;
} }
public function getReduction(): ?Reductions
{
return $this->Reduction;
}
public function setReduction(?Reductions $Reduction): static
{
$this->Reduction = $Reduction;
return $this;
}
} }

View File

@ -16,88 +16,30 @@ class Reductions
#[ORM\Column] #[ORM\Column]
private ?int $id = null; private ?int $id = null;
#[ORM\Column(length: 255)] #[ORM\Column]
private ?string $Description = null; private ?int $pourcentage = null;
#[ORM\Column] #[ORM\Column]
private ?float $Prix = null; private ?int $montant_min = null;
#[ORM\Column] #[ORM\Column]
private ?int $Pourcentage = null; private ?bool $actif = null;
#[ORM\Column(length: 255)]
private ?string $MontantFixe = null;
#[ORM\Column(type: Types::DATETIME_MUTABLE)] #[ORM\Column(type: Types::DATETIME_MUTABLE)]
private ?\DateTimeInterface $DateDebut = null; private ?\DateTimeInterface $DateDebut = null;
#[ORM\Column(type: Types::DATETIME_MUTABLE)] #[ORM\Column(type: Types::DATETIME_MUTABLE)]
private ?\DateTimeInterface $DateFin = null; private ?\DateTimeInterface $DateFin = null;
/**
* @var Collection<int, Plats>
*/
#[ORM\OneToMany(targetEntity: Plats::class, mappedBy: 'Reduction')]
private Collection $plats;
public function __construct() #[ORM\ManyToOne(targetEntity: Clients::class, inversedBy: 'reductions')]
{ #[ORM\JoinColumn(nullable: false)]
$this->plats = new ArrayCollection(); private ?Clients $client = null;
}
public function getId(): ?int public function getId(): ?int
{ {
return $this->id; return $this->id;
} }
public function getDescription(): ?string
{
return $this->Description;
}
public function setDescription(string $Description): static
{
$this->Description = $Description;
return $this;
}
public function getPrix(): ?float
{
return $this->Prix;
}
public function setPrix(float $Prix): static
{
$this->Prix = $Prix;
return $this;
}
public function getPourcentage(): ?int
{
return $this->Pourcentage;
}
public function setPourcentage(int $Pourcentage): static
{
$this->Pourcentage = $Pourcentage;
return $this;
}
public function getMontantFixe(): ?string
{
return $this->MontantFixe;
}
public function setMontantFixe(string $MontantFixe): static
{
$this->MontantFixe = $MontantFixe;
return $this;
}
public function getDateDebut(): ?\DateTimeInterface public function getDateDebut(): ?\DateTimeInterface
{ {
return $this->DateDebut; return $this->DateDebut;
@ -122,33 +64,50 @@ class Reductions
return $this; return $this;
} }
/** public function getPourcentage(): ?int
* @return Collection<int, Plats>
*/
public function getPlats(): Collection
{ {
return $this->plats; return $this->pourcentage;
} }
public function addPlat(Plats $plat): static public function setPourcentage(int $pourcentage): static
{ {
if (!$this->plats->contains($plat)) { $this->pourcentage = $pourcentage;
$this->plats->add($plat);
$plat->setReduction($this);
}
return $this; return $this;
} }
public function removePlat(Plats $plat): static public function getMontantMin(): ?int
{ {
if ($this->plats->removeElement($plat)) { return $this->montant_min;
// set the owning side to null (unless already changed) }
if ($plat->getReduction() === $this) {
$plat->setReduction(null);
}
}
public function setMontantMin(int $montant_min): static
{
$this->montant_min = $montant_min;
return $this;
}
public function isActif(): ?bool
{
return $this->actif;
}
public function setActif(bool $actif): static
{
$this->actif = $actif;
return $this;
}
public function getClient(): ?Clients
{
return $this->client;
}
public function setClient(?Clients $client): static
{
$this->client = $client;
return $this; return $this;
} }
} }

View File

@ -70,7 +70,7 @@ class Reservations
return $this->tables; return $this->tables;
} }
public function setTable(?Tables $tables): static public function setTables(?Tables $tables): static
{ {
$this->tables = $tables; $this->tables = $tables;

View File

@ -94,7 +94,7 @@ class Tables
{ {
if (!$this->reservations->contains($reservation)) { if (!$this->reservations->contains($reservation)) {
$this->reservations->add($reservation); $this->reservations->add($reservation);
$reservation->setTable($this); $reservation->setTables($this);
} }
return $this; return $this;
@ -105,7 +105,7 @@ class Tables
if ($this->reservations->removeElement($reservation)) { if ($this->reservations->removeElement($reservation)) {
// set the owning side to null (unless already changed) // set the owning side to null (unless already changed)
if ($reservation->getTables() === $this) { if ($reservation->getTables() === $this) {
$reservation->setTable(null); $reservation->setTables(null);
} }
} }

View File

@ -4,6 +4,7 @@ namespace App\Form;
use App\Entity\Clients; use App\Entity\Clients;
use App\Entity\Commandes; use App\Entity\Commandes;
use App\Entity\Reductions;
use App\Entity\Tables; use App\Entity\Tables;
use Symfony\Bridge\Doctrine\Form\Type\EntityType; use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\AbstractType;
@ -25,7 +26,7 @@ class ClientsType extends AbstractType
'multiple' => true, 'multiple' => true,
'expanded' => true, 'expanded' => true,
]) ])
->add('totalDepense')
; ;
} }

View File

@ -27,10 +27,6 @@ class PlatsType extends AbstractType
'multiple' => true, 'multiple' => true,
'expanded' => true, 'expanded' => true,
]) ])
->add('Reduction', EntityType::class, [
'class' => Reductions::class,
'choice_label' => 'description',
])
; ;
} }

View File

@ -2,7 +2,10 @@
namespace App\Form; namespace App\Form;
use App\Entity\Clients;
use App\Entity\Reductions; use App\Entity\Reductions;
use http\Client;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver; use Symfony\Component\OptionsResolver\OptionsResolver;
@ -12,16 +15,19 @@ class ReductionsType extends AbstractType
public function buildForm(FormBuilderInterface $builder, array $options): void public function buildForm(FormBuilderInterface $builder, array $options): void
{ {
$builder $builder
->add('Description') ->add('Taux')
->add('Prix')
->add('Pourcentage')
->add('MontantFixe')
->add('DateDebut', null, [ ->add('DateDebut', null, [
'widget' => 'single_text', 'widget' => 'single_text',
]) ])
->add('DateFin', null, [ ->add('DateFin', null, [
'widget' => 'single_text', 'widget' => 'single_text',
]) ])
->add('client', EntityType::class, [
'class' => Clients::class,
'choice_label' => 'nom',
'multiple' => false,
'expanded' => true,
])
; ;
} }

View File

@ -25,7 +25,7 @@ class ReservationsType extends AbstractType
]) ])
->add('utilisateurs', EntityType::class, [ ->add('utilisateurs', EntityType::class, [
'class' => Utilisateurs::class, 'class' => Utilisateurs::class,
'choice_label' => 'id', 'choice_label' => 'prenom',
'multiple' => true, 'multiple' => true,
'expanded' => true, 'expanded' => true,
]) ])

View File

@ -40,4 +40,19 @@ class ReservationsRepository extends ServiceEntityRepository
// ->getOneOrNullResult() // ->getOneOrNullResult()
// ; // ;
// } // }
// src/Repository/ReservationRepository.php
public function findByDateRange(\DateTime $startDate, \DateTime $endDate): array
{
return $this->createQueryBuilder('r')
->where('r.DateHeure BETWEEN :start AND :end')
->setParameter('start', $startDate->format('Y-m-d 00:00:00'))
->setParameter('end', $endDate->format('Y-m-d 23:59:59'))
->orderBy('r.DateHeure', 'ASC')
->getQuery()
->getResult();
}
} }

View File

@ -12,9 +12,11 @@
{% block stylesheets %} {% block stylesheets %}
<link rel="stylesheet" href="{{ asset('css/ControllerVues/list.css') }}"> <!-- Ajout du fichier CSS --> <link rel="stylesheet" href="{{ asset('css/ControllerVues/list.css') }}"> <!-- Ajout du fichier CSS -->
<link rel="stylesheet" href="{{ asset('css/Plats/plats.css') }}"> <!-- Ajout du fichier CSS -->
<link rel="stylesheet" href="{{ asset('css/Index/index.css') }}"> <!-- Ajout du fichier CSS --> <link rel="stylesheet" href="{{ asset('css/Index/index.css') }}"> <!-- Ajout du fichier CSS -->
<link rel="stylesheet" href="{{ asset('css/Compte/index.css') }}"> <!-- Ajout du fichier CSS --> <link rel="stylesheet" href="{{ asset('css/Compte/index.css') }}"> <!-- Ajout du fichier CSS -->
<link rel="stylesheet" href="{{ asset('css/GestionUtilisateurs/GestionUtilisateurs.css') }}"> <!-- Ajout du fichier CSS --> <link rel="stylesheet" href="{{ asset('css/GestionUtilisateurs/GestionUtilisateurs.css') }}"> <!-- Ajout du fichier CSS -->
<link rel="stylesheet" href="{{ asset('css/Reservations/reservationCalendar.css') }}"> <!-- Ajout du fichier CSS -->
{% endblock %} {% endblock %}
{# {% block javascripts %}#} {# {% block javascripts %}#}
@ -100,7 +102,7 @@
</a> </a>
</li> </li>
<li> <li>
<a href="/reservations" class="btn-custom icon-container"> <a href="/reservations/calendar" class="btn-custom icon-container">
<i class="icon-medium"> {{ ux_icon('fluent-mdl2:reservation-orders') }}</i> <i class="icon-medium"> {{ ux_icon('fluent-mdl2:reservation-orders') }}</i>
<span>Réservation</span> <span>Réservation</span>
</a> </a>

View File

@ -2,60 +2,59 @@
{% block title %}Client index{% endblock %} {% block title %}Client index{% endblock %}
{% block head %}
<head>
<meta charset="UTF-8">
<link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 128 128%22><text y=%221.2em%22 font-size=%2296%22>⚫️</text><text y=%221.3em%22 x=%220.2em%22 font-size=%2276%22 fill=%22%23fff%22>sf</text></svg>">
<link href="https://fonts.cdnfonts.com/css/brittany-signature" rel="stylesheet">
</head>
{% endblock %}
{% block stylesheets %}
<link rel="stylesheet" href="{{ asset('css/ControllerVues/list.css') }}"> <!-- Ajout du fichier CSS -->
<link rel="stylesheet" href="{{ asset('css/Index/index.css') }}"> <!-- Ajout du fichier CSS -->
<link rel="stylesheet" href="{{ asset('css/Compte/index.css') }}"> <!-- Ajout du fichier CSS -->
<link rel="stylesheet" href="{{ asset('css/GestionUtilisateurs/GestionUtilisateurs.css') }}"> <!-- Ajout du fichier CSS -->
{% endblock %}
{% block container_modal %} {% block container_modal %}
<div id="container_modal"> <div id="container_modal">
<h1>Clients index</h1> <h1>Clients index</h1>
<table class="table"> <table class="table">
<thead> <thead>
<tr> <tr>
<th>Id</th> <th>Id</th>
<th>Prenom</th> <th>Prenom</th>
<th>Nom</th> <th>Nom</th>
<th>Email</th> <th>Email</th>
<th>Telephone</th> <th>Telephone</th>
<th>actions</th> <th>Depense</th>
<th>Réduction Appliquée</th> <!-- Nouvelle colonne -->
<th>Actions</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{% for client in clients %} {% for client in clients %}
<tr> <tr>
<td>{{ client.id }}</td> <td>{{ client.id }}</td>
<td>{{ client.Prenom }}</td> <td>{{ client.Prenom }}</td>
<td>{{ client.Nom }}</td> <td>{{ client.Nom }}</td>
<td>{{ client.Email }}</td> <td>{{ client.Email }}</td>
<td>{{ client.Telephone }}</td> <td>{{ client.Telephone }}</td>
<td> <td>{{ client.totalDepense }}</td>
<form method="post" action="{{ path('app_clients_delete', {'id': client.id}) }}" onsubmit="return confirm('Es-tu sur de vouloir le supprimer ?');">
<input type="hidden" name="_token" value="{{ csrf_token('delete' ~ client.id) }}">
{{ include('clients/_delete_form.html.twig') }}
</form>
<a href="{{ path('app_clients_edit', {'id': client.id}) }}">Modifier</a>
</td>
</tr>
{% else %}
<tr>
<td colspan="6">no records found</td>
</tr>
{% endfor %}
</tbody>
</table>
<a href="{{ path('app_clients_new') }}">Créer un nouveau client</a> <td>
</div> {% if client.reductions|length > 0 %}
{% for reduction in client.reductions %}
<span>Réduction de {{ reduction.pourcentage }}% - Valide jusqu'à {{ reduction.DateFin|date('d/m/Y') }}</span><br>
{% endfor %}
{% else %}
Aucune réduction
{% endif %}
</td>
<td>
<form method="post" action="{{ path('app_clients_delete', {'id': client.id}) }}" onsubmit="return confirm('Es-tu sûr de vouloir le supprimer ?');">
<input type="hidden" name="_token" value="{{ csrf_token('delete' ~ client.id) }}">
{{ include('clients/_delete_form.html.twig') }}
</form>
<a href="{{ path('app_clients_edit', {'id': client.id}) }}">Modifier</a>
</td>
</tr>
{% else %}
<tr>
<td colspan="8">Aucun client trouvé</td>
</tr>
{% endfor %}
</tbody>
</table>
<a href="{{ path('app_clients_new') }}">Créer un nouveau client</a>
</div>
{% endblock %} {% endblock %}

View File

@ -13,6 +13,7 @@
{% block stylesheets %} {% block stylesheets %}
<link rel="stylesheet" href="{{ asset('css/ControllerVues/list.css') }}"> <!-- Ajout du fichier CSS --> <link rel="stylesheet" href="{{ asset('css/ControllerVues/list.css') }}"> <!-- Ajout du fichier CSS -->
<link rel="stylesheet" href="{{ asset('css/ControllerVues/edit.css') }}"> <!-- Ajout du fichier CSS --> <link rel="stylesheet" href="{{ asset('css/ControllerVues/edit.css') }}"> <!-- Ajout du fichier CSS -->
<link rel="stylesheet" href="{{ asset('css/Plats/plats.css') }}"> <!-- Ajout du fichier CSS -->
<link rel="stylesheet" href="{{ asset('css/Index/index.css') }}"> <!-- Ajout du fichier CSS --> <link rel="stylesheet" href="{{ asset('css/Index/index.css') }}"> <!-- Ajout du fichier CSS -->
<link rel="stylesheet" href="{{ asset('css/Compte/index.css') }}"> <!-- Ajout du fichier CSS --> <link rel="stylesheet" href="{{ asset('css/Compte/index.css') }}"> <!-- Ajout du fichier CSS -->
<link rel="stylesheet" href="{{ asset('css/GestionUtilisateurs/GestionUtilisateurs.css') }}"> <!-- Ajout du fichier CSS --> <link rel="stylesheet" href="{{ asset('css/GestionUtilisateurs/GestionUtilisateurs.css') }}"> <!-- Ajout du fichier CSS -->
@ -21,48 +22,28 @@
{% block container_modal %} {% block container_modal %}
<div id="container_modal"> <div id="container_modal">
<h1>Plats index</h1> <div class="menu-container">
<table class="table">
<thead>
<tr>
<th>Id</th>
<th>Nom</th>
<th>Description</th>
<th>Prix</th>
<th>Categorie</th>
<th>Statut</th>
<th>Nb_de_commande</th>
<th>actions</th>
</tr>
</thead>
<tbody>
{% for plat in plats %} {% for plat in plats %}
<tr> <div class="menu-card">
<td>{{ plat.id }}</td> <h2>{{ plat.Nom }}</h2>
<td>{{ plat.Nom }}</td> <p>{{ plat.Description }}</p>
<td>{{ plat.Description }}</td> <p class="price">{{ plat.Prix }}€</p>
<td>{{ plat.Prix }}</td> <div class="actions">
<td>{{ plat.Categorie }}</td> <a href="{{ path('app_plats_edit', {'id': plat.id}) }}" class="edit">Modifier</a>
<td>{{ plat.Statut ? 'Yes' : 'No' }}</td>
<td>{{ plat.NbDeCommande }}</td> <form method="post" action="{{ path('app_plats_delete', {'id': plat.id}) }}" onsubmit="return confirm('Es-tu sûr de vouloir le supprimer ?');" style="display:inline;">
<td> <input type="hidden" name="_token" value="{{ csrf_token('delete' ~ plat.id) }}">
<form method="post" action="{{ path('app_plats_delete', {'id': plat.id}) }}" onsubmit="return confirm('Es-tu sur de vouloir le supprimer ?');"> <button type="submit" class="delete">Supprimer</button>
<input type="hidden" name="_token" value="{{ csrf_token('delete' ~ plat.id) }}"> </form>
{{ include('plats/_delete_form.html.twig') }} </div>
</form> </div>
<a href="{{ path('app_plats_edit', {'id': plat.id}) }}">Modifier</a> {% else %}
</td> <p>Aucun plat disponible.</p>
</tr> {% endfor %}
{% else %} </div>
<tr>
<td colspan="8">Aucun enregistrement trouvé</td> <a href="{{ path('app_plats_new') }}" class="add-menu">Créer un menu</a>
</tr>
{% endfor %}
</tbody>
</table>
<a href="{{ path('app_plats_new') }}">Créer un menu</a>
</div> </div>
{% endblock %} {% endblock %}

View File

@ -27,12 +27,11 @@
<thead> <thead>
<tr> <tr>
<th>Id</th> <th>Id</th>
<th>Description</th>
<th>Prix</th>
<th>Pourcentage</th> <th>Pourcentage</th>
<th>MontantFixe</th> <th>Montant Minimum</th>
<th>DateDebut</th> <th>DateDebut</th>
<th>DateFin</th> <th>DateFin</th>
<th>Client</th>
<th>actions</th> <th>actions</th>
</tr> </tr>
</thead> </thead>
@ -40,18 +39,16 @@
{% for reduction in reductions %} {% for reduction in reductions %}
<tr> <tr>
<td>{{ reduction.id }}</td> <td>{{ reduction.id }}</td>
<td>{{ reduction.Description }}</td> <td>{{ reduction.pourcentage }}%</td>
<td>{{ reduction.Prix }}</td> <td>{{ reduction.montantMin }} €</td>
<td>{{ reduction.Pourcentage }}</td> <td>{{ reduction.DateDebut ? reduction.DateDebut|date('d/m/Y H:i:s') : 'Non spécifié' }}</td>
<td>{{ reduction.MontantFixe }}</td> <td>{{ reduction.DateFin ? reduction.DateFin|date('d/m/Y H:i:s') : 'Non spécifié' }}</td>
<td>{{ reduction.DateDebut ? reduction.DateDebut|date('Y-m-d H:i:s') : '' }}</td> <td>{{ reduction.client.nom }}</td>
<td>{{ reduction.DateFin ? reduction.DateFin|date('Y-m-d H:i:s') : '' }}</td>
<td> <td>
<form method="post" action="{{ path('app_reductions_delete', {'id': reduction.id}) }}" onsubmit="return confirm('Es-tu sur de vouloir le supprimer ?'); "> <form method="post" action="{{ path('app_reductions_delete', {'id': reduction.id}) }}" onsubmit="return confirm('Êtes-vous sûr de vouloir supprimer cette réduction ?'); ">
<input type="hidden" name="_token" value="{{ csrf_token('delete' ~ reduction.id) }}"> <input type="hidden" name="_token" value="{{ csrf_token('delete' ~ reduction.id) }}">
{{ include('reductions/_delete_form.html.twig') }} <button type="submit" class="btn btn-danger">Supprimer</button>
</form> </form>
<a href="{{ path('app_reductions_edit', {'id': reduction.id}) }}">Modifier</a>
</td> </td>
</tr> </tr>
{% else %} {% else %}
@ -61,8 +58,6 @@
{% endfor %} {% endfor %}
</tbody> </tbody>
</table> </table>
<a href="{{ path('app_reductions_new') }}">Créer une réduction</a>
</div> </div>
{% endblock %} {% endblock %}

View File

@ -13,45 +13,50 @@
{% block stylesheets %} {% block stylesheets %}
<link rel="stylesheet" href="{{ asset('css/ControllerVues/list.css') }}"> <!-- Ajout du fichier CSS --> <link rel="stylesheet" href="{{ asset('css/ControllerVues/list.css') }}"> <!-- Ajout du fichier CSS -->
<link rel="stylesheet" href="{{ asset('css/Index/index.css') }}"> <!-- Ajout du fichier CSS --> <link rel="stylesheet" href="{{ asset('css/Index/index.css') }}"> <!-- Ajout du fichier CSS -->
<link rel="stylesheet" href="{{ asset('css/Reservations/reservationCalendar.css') }}"> <!-- Ajout du fichier CSS -->
<link rel="stylesheet" href="{{ asset('css/Compte/index.css') }}"> <!-- Ajout du fichier CSS --> <link rel="stylesheet" href="{{ asset('css/Compte/index.css') }}"> <!-- Ajout du fichier CSS -->
<link rel="stylesheet" href="{{ asset('css/GestionUtilisateurs/GestionUtilisateurs.css') }}"> <!-- Ajout du fichier CSS --> <link rel="stylesheet" href="{{ asset('css/GestionUtilisateurs/GestionUtilisateurs.css') }}"> <!-- Ajout du fichier CSS -->
{% endblock %} {% endblock %}
{% block container_modal %} {% block container_modal %}
<div id="container_modal"> <div id="container_modal">
<h1>Reservations index</h1> <div class="calendar-nav">
<a href="{{ path('calendar_week', { year: startDate|date('Y'), week: startDate|date('W') - 1 }) }}">← Semaine précédente</a>
<a href="{{ path('calendar_week', { year: startDate|date('Y'), week: startDate|date('W') + 1 }) }}">Semaine suivante →</a>
</div>
<div class="calendar">
<div class="calendar-header">
{% for i in 0..6 %}
<div class="calendar-day">
{{ (startDate|date_modify("+" ~ i ~ " days"))|date('D d/m') }}
</div>
{% endfor %}
</div>
<div class="calendar-body">
{% for i in 0..6 %}
<div class="calendar-column">
{% set currentDate = startDate|date_modify("+" ~ i ~ " days") %}
{% for reservation in reservations %}
{% set res_date = reservation.dateHeure|date('Y-m-d') %}
{% set res_time = reservation.dateHeure|date('H:i') %}
{% if res_date == currentDate|date('Y-m-d') %}
<div class="reservation" style="background-color: lightblue;">
{{ res_time }} - {{ reservation.nbdeprsn }} pers.
</div>
{% endif %}
{% endfor %}
</div>
{% endfor %}
</div>
</div>
<div class="add-reservation">
<a href="{{ path('app_reservations_new') }}">+ Ajouter une réservation</a>
</div>
<table class="table">
<thead>
<tr>
<th>Id</th>
<th>DateHeure</th>
<th>Nb_de_prsn</th>
<th>actions</th>
</tr>
</thead>
<tbody>
{% for reservation in reservations %}
<tr>
<td>{{ reservation.id }}</td>
<td>{{ reservation.DateHeure ? reservation.DateHeure|date('Y-m-d H:i:s') : '' }}</td>
<td>{{ reservation.NbDePrsn }}</td>
<td>
<form method="post" action="{{ path('app_reservations_delete', {'id': reservation.id}) }}" onsubmit="return confirm('Es-tu sur de vouloir le supprimer ?');">
<input type="hidden" name="_token" value="{{ csrf_token('delete' ~ reservation.id) }}">
{{ include('reservations/_delete_form.html.twig') }}
</form>
<a href="{{ path('app_reservations_edit', {'id': reservation.id}) }}">Modifier</a>
</td>
</tr>
{% else %}
<tr>
<td colspan="4">Aucun enregistrement trouvé</td>
</tr>
{% endfor %}
</tbody>
</table>
<a href="{{ path('app_reservations_new') }}">Créer une réservation</a>
</div> </div>
{% endblock %} {% endblock %}

View File

@ -24,6 +24,6 @@
{{ include('reservations/_form.html.twig') }} {{ include('reservations/_form.html.twig') }}
<a href="{{ path('app_reservations_index') }}">Retour à la liste</a> <a href="{{ path('calendar_week') }}">Retour à la liste</a>
</div> </div>
{% endblock %} {% endblock %}