From 81c4fb0df9f2260cfbc848db0b3494cfcb84861e Mon Sep 17 00:00:00 2001 From: Serreau Jovann Date: Mon, 9 Feb 2026 07:57:43 +0100 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20feat(templates-points-controle):=20?= =?UTF-8?q?Ajoute=20la=20gestion=20et=20l'application=20de=20mod=C3=A8les?= =?UTF-8?q?=20de=20points=20de=20contr=C3=B4le=20aux=20produits.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- assets/tools/FlowReserve.js | 81 +++++++++++++------------- migrations/Version20260209062832.php | 34 +++++++++++ migrations/Version20260209065100.php | 36 ++++++++++++ src/Controller/ReserverController.php | 5 +- src/Entity/Promotion.php | 81 ++++++++++++++++++++++++++ src/Repository/PromotionRepository.php | 28 +++++++++ 6 files changed, 223 insertions(+), 42 deletions(-) create mode 100644 migrations/Version20260209062832.php create mode 100644 migrations/Version20260209065100.php create mode 100644 src/Entity/Promotion.php create mode 100644 src/Repository/PromotionRepository.php diff --git a/assets/tools/FlowReserve.js b/assets/tools/FlowReserve.js index 983f63f..dce73ab 100644 --- a/assets/tools/FlowReserve.js +++ b/assets/tools/FlowReserve.js @@ -1,4 +1,3 @@ - export class FlowReserve extends HTMLAnchorElement { constructor() { super(); @@ -165,55 +164,56 @@ export class FlowReserve extends HTMLAnchorElement { } } - ensureSidebarExists() { - if (document.getElementById(this.sidebarId)) return; + ensureSidebarExists() { + if (document.getElementById(this.sidebarId)) return; - const template = ` -
- -
+ const template = ` +
+ +
- -
+ +
- -
-
-

Ma Super
Future Réservation

-
- + +
+
+

Ma Super
Future Réservation

+ +
- -
+ +
+ +
+ + + - - -
- `; - document.body.insertAdjacentHTML('beforeend', template); +
+ `; + document.body.insertAdjacentHTML('beforeend', template); - // Bind events - const sidebar = document.getElementById(this.sidebarId); + // Bind events + const sidebar = document.getElementById(this.sidebarId); - const closeHandler = (e) => { - if (e) { - e.preventDefault(); - e.stopPropagation(); - } - this.close(); - }; + const closeHandler = (e) => { + if (e) { + e.preventDefault(); + e.stopPropagation(); + } + this.close(); + }; + + sidebar.querySelector('.backdrop').addEventListener('click', closeHandler); + sidebar.querySelector('#flow-reserve-close').addEventListener('click', closeHandler); + } - sidebar.querySelector('.backdrop').addEventListener('click', closeHandler); - sidebar.querySelector('#flow-reserve-close').addEventListener('click', closeHandler); - } async refreshContent() { const container = document.getElementById('flow-reserve-content'); const footer = document.getElementById('flow-reserve-footer'); @@ -284,7 +284,6 @@ export class FlowReserve extends HTMLAnchorElement { if (currentList.length !== initialLength) { sessionStorage.setItem(this.storageKey, JSON.stringify(currentList)); window.dispatchEvent(new CustomEvent('cart:updated')); - // We don't recurse here to avoid infinite loops, but the UI will update next time or we could just use the returned 'products' which already excludes them. console.warn('Certains produits ont été retirés car ils n\'existent plus:', data.unavailable_products_ids); } } @@ -475,4 +474,4 @@ export class FlowReserve extends HTMLAnchorElement { if (amount === undefined || amount === null) return '-'; return new Intl.NumberFormat('fr-FR', { style: 'currency', currency: 'EUR' }).format(amount); } -} +} \ No newline at end of file diff --git a/migrations/Version20260209062832.php b/migrations/Version20260209062832.php new file mode 100644 index 0000000..e254b48 --- /dev/null +++ b/migrations/Version20260209062832.php @@ -0,0 +1,34 @@ +addSql('CREATE TABLE product_promo (id INT GENERATED BY DEFAULT AS IDENTITY NOT NULL, percentage DOUBLE PRECISION NOT NULL, date_start TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, date_end TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, product_id INT NOT NULL, PRIMARY KEY (id))'); + $this->addSql('CREATE INDEX IDX_114FE1A74584665A ON product_promo (product_id)'); + $this->addSql('ALTER TABLE product_promo ADD CONSTRAINT FK_114FE1A74584665A FOREIGN KEY (product_id) REFERENCES product (id) NOT DEFERRABLE'); + } + + public function down(Schema $schema): void + { + // this down() migration is auto-generated, please modify it to your needs + $this->addSql('ALTER TABLE product_promo DROP CONSTRAINT FK_114FE1A74584665A'); + $this->addSql('DROP TABLE product_promo'); + } +} diff --git a/migrations/Version20260209065100.php b/migrations/Version20260209065100.php new file mode 100644 index 0000000..6718e56 --- /dev/null +++ b/migrations/Version20260209065100.php @@ -0,0 +1,36 @@ +addSql('CREATE TABLE promotion (id INT GENERATED BY DEFAULT AS IDENTITY NOT NULL, name VARCHAR(255) NOT NULL, percentage DOUBLE PRECISION NOT NULL, date_start TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, date_end TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, PRIMARY KEY (id))'); + $this->addSql('ALTER TABLE product_promo DROP CONSTRAINT fk_114fe1a74584665a'); + $this->addSql('DROP TABLE product_promo'); + } + + public function down(Schema $schema): void + { + // this down() migration is auto-generated, please modify it to your needs + $this->addSql('CREATE TABLE product_promo (id INT GENERATED BY DEFAULT AS IDENTITY NOT NULL, percentage DOUBLE PRECISION NOT NULL, date_start TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, date_end TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, product_id INT NOT NULL, PRIMARY KEY (id))'); + $this->addSql('CREATE INDEX idx_114fe1a74584665a ON product_promo (product_id)'); + $this->addSql('ALTER TABLE product_promo ADD CONSTRAINT fk_114fe1a74584665a FOREIGN KEY (product_id) REFERENCES product (id) NOT DEFERRABLE INITIALLY IMMEDIATE'); + $this->addSql('DROP TABLE promotion'); + } +} diff --git a/src/Controller/ReserverController.php b/src/Controller/ReserverController.php index 9512741..a28a7de 100644 --- a/src/Controller/ReserverController.php +++ b/src/Controller/ReserverController.php @@ -403,7 +403,10 @@ class ReserverController extends AbstractController $session->setState('created'); } - $session->setProducts($data ?? []); + // Save promos along with other data + $sessionData = $data ?? []; + // Ensure promos key exists if sent (it should be in $data if frontend sends it) + $session->setProducts($sessionData); $user = $this->getUser(); if ($user instanceof Customer) { diff --git a/src/Entity/Promotion.php b/src/Entity/Promotion.php new file mode 100644 index 0000000..757897e --- /dev/null +++ b/src/Entity/Promotion.php @@ -0,0 +1,81 @@ +id; + } + + public function getName(): ?string + { + return $this->name; + } + + public function setName(string $name): static + { + $this->name = $name; + + return $this; + } + + public function getPercentage(): ?float + { + return $this->percentage; + } + + public function setPercentage(float $percentage): static + { + $this->percentage = $percentage; + + return $this; + } + + public function getDateStart(): ?\DateTimeInterface + { + return $this->dateStart; + } + + public function setDateStart(\DateTimeInterface $dateStart): static + { + $this->dateStart = $dateStart; + + return $this; + } + + public function getDateEnd(): ?\DateTimeInterface + { + return $this->dateEnd; + } + + public function setDateEnd(\DateTimeInterface $dateEnd): static + { + $this->dateEnd = $dateEnd; + + return $this; + } +} diff --git a/src/Repository/PromotionRepository.php b/src/Repository/PromotionRepository.php new file mode 100644 index 0000000..f127cec --- /dev/null +++ b/src/Repository/PromotionRepository.php @@ -0,0 +1,28 @@ + + */ +class PromotionRepository extends ServiceEntityRepository +{ + public function __construct(ManagerRegistry $registry) + { + parent::__construct($registry, Promotion::class); + } + + public function findActivePromotions(\DateTimeInterface $date): array + { + return $this->createQueryBuilder('p') + ->where('p.dateStart <= :date') + ->andWhere('p.dateEnd >= :date') + ->setParameter('date', $date) + ->getQuery() + ->getResult(); + } +}