From d59ef5ac8cb26c70489965a5d6ac32f7ebeb956d Mon Sep 17 00:00:00 2001
From: Julian PEREZ-RAMIREZ <julian.perez-ramirez@imt-atlantique.net>
Date: Sat, 15 Mar 2025 23:06:13 +0100
Subject: [PATCH] adding endpoint to get wishList by total item purchased

---
 .../web_app/src/Controller/ItemController.php |   5 +-
 .../src/Controller/WishListController.php     | 128 +++++++++++++++++-
 .../web_app/src/Repository/ItemRepository.php |  70 ++++++++++
 .../src/Repository/WishListRepository.php     |  66 +++++----
 4 files changed, 238 insertions(+), 31 deletions(-)

diff --git a/server/web_app/src/Controller/ItemController.php b/server/web_app/src/Controller/ItemController.php
index fcbfb65..f045664 100644
--- a/server/web_app/src/Controller/ItemController.php
+++ b/server/web_app/src/Controller/ItemController.php
@@ -10,7 +10,6 @@ use Symfony\Component\Routing\Attribute\Route;
 
 use Doctrine\ORM\EntityManagerInterface;
 use Symfony\Component\HttpFoundation\Request;
-use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
 use Symfony\Component\Validator\Validator\ValidatorInterface;
 
 #[Route('/items')]
@@ -18,17 +17,15 @@ final class ItemController extends AbstractController
 {
     private EntityManagerInterface $entityManager;
     private ItemRepository $itemRepository;
-    private UserPasswordHasherInterface $passwordHasher;
     private ValidatorInterface $validator;
+    
     public function __construct(
         EntityManagerInterface $entityManager,
         ItemRepository $itemRepository,
-        UserPasswordHasherInterface $passwordHasher,
         ValidatorInterface $validator
     ) {
         $this->entityManager = $entityManager;
         $this->itemRepository = $itemRepository;
-        $this->passwordHasher = $passwordHasher;
         $this->validator = $validator;
     }
 
diff --git a/server/web_app/src/Controller/WishListController.php b/server/web_app/src/Controller/WishListController.php
index e28a0e5..0a0aa4f 100644
--- a/server/web_app/src/Controller/WishListController.php
+++ b/server/web_app/src/Controller/WishListController.php
@@ -4,16 +4,138 @@ namespace App\Controller;
 
 use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
 use Symfony\Component\HttpFoundation\JsonResponse;
+use Symfony\Component\HttpFoundation\Response;
 use Symfony\Component\Routing\Attribute\Route;
 
+use App\Repository\WishListRepository;
+use App\Repository\ItemRepository;
+use Doctrine\ORM\EntityManagerInterface;
+use Symfony\Component\Validator\Validator\ValidatorInterface;
+use Symfony\Component\HttpFoundation\Request;
+
+#[Route('/wishLists')]
 final class WishListController extends AbstractController
 {
-    #[Route('/wish/list', name: 'app_wish_list')]
-    public function index(): JsonResponse
+    private EntityManagerInterface $entityManager;
+    private WishListRepository $wishListRepository;
+    private ItemRepository $itemRepository;
+    private ValidatorInterface $validator;
+
+    public function __construct(
+        EntityManagerInterface $entityManager,
+        WishListRepository $wishListRepository,
+        ItemRepository $itemRepository,
+        ValidatorInterface $validator
+    ) {
+        $this->entityManager = $entityManager;
+        $this->wishListRepository = $wishListRepository;
+        $this->itemRepository = $itemRepository;
+        $this->validator = $validator;
+    }
+
+    #[Route('', methods: ['GET'])]
+    public function getAllWishLists(Request $request): JsonResponse
+    {
+        // Get query parameters with defaults
+        $userId = $request->query->get('userId');
+        $userId = $userId !== null ? (int) $userId : null;
+
+        $expirationDate = $request->query->get('expirationDate');
+        $expirationDate = $expirationDate !== null ? new \DateTime($expirationDate) : null;
+
+        $isActive = $request->query->get('isActive');
+        $isActive = $isActive !== null ? filter_var($isActive, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE) : null;
+
+        $sortBy = $request->query->get('sortBy', 'createdAt');
+        $sort = $request->query->get('sort', 'desc');
+
+        $max = (int) $request->query->get('max', 10); // Default 10 items per page
+        $page = (int) $request->query->get('page', 1); // Default page 1
+
+        $wishLists = $this->wishListRepository->findAllWishListsFiltered($userId, $expirationDate, $isActive, $sortBy, $sort, $max, $page);
+
+        if (!$wishLists) {
+            return new JsonResponse(['error' => 'No wishLists found'], Response::HTTP_NOT_FOUND);
+        }
+
+        $wishListArray = array_map(fn($wishList) => [
+            'id' => $wishList->getId(),
+            'user' => $wishList->getUser()->getId(),
+            'name' => $wishList->getName(),
+            'description' => $wishList->getDescription(),
+            'expirationDate' => $wishList->getExpirationDate(),
+            'isActive' => $wishList->isActive(),
+            'createdAt' => $wishList->getCreatedAt(),
+        ], $wishLists);
+
+        return $this->json([
+            'wishLists' => $wishListArray,
+            'pagination' => [
+                'max' => $max,
+                'page' => $page
+            ],
+            'path' => 'src/Controller/WishListController.php',
+        ]);
+    }
+
+
+    #[Route('/{wishListId}/items', methods: ['GET'])]
+    public function getWishListItems(int $wishListId, Request $req): JsonResponse
+    {
+        // Get query parameters with defaults
+        $isBought = $req->query->get('isBought');
+        $isBought = $isBought !== null ? filter_var($isBought, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE) : null;
+
+        $sortBy = $req->query->get('sortBy', 'createdAt');
+        $sort = $req->query->get('sort', 'desc');
+
+        $max = (int) $req->query->get('max', 10); // Default 10 items per page
+        $page = (int) $req->query->get('page', 1); // Default page 1
+
+        $items = $this->itemRepository->findAllItemsByWishListFiltered($wishListId, $isBought, $sortBy, $sort, $max, $page);
+
+        if (!$items) {
+            return new JsonResponse(['error' => 'No items found for this wishList'], Response::HTTP_NOT_FOUND);
+        }
+
+        $itemArray = array_map(fn($item) => [
+            'id' => $item->getId(),
+            'title' => $item->getTitle(),
+            'description' => $item->getDescription(),
+            'price' => $item->getPrice(),
+            'purchaseUrl' => $item->getPurchaseUrl(),
+            'createdAt' => $item->getCreatedAt(),
+        ], $items);
+
+        return $this->json([
+            'items' => $itemArray,
+            'pagination' => [
+                'max' => $max,
+                'page' => $page
+            ],
+            'path' => 'src/Controller/WishListController.php',
+        ]);
+    }
+
+    #[Route('/sortedByTotalBought', methods: ['GET'])]
+    public function getWishListsSortedByTotalBought(Request $request): JsonResponse
     {
+        $sort = $request->query->get('sort', 'desc'); // Default sorting to descending
+        $max = (int) $request->query->get('max', 10); // Default 10 per page
+        $page = (int) $request->query->get('page', 1); // Default page 1
+
+        $wishLists = $this->itemRepository->findWishListsSortedByTotalBought($sort, $max, $page);
+
         return $this->json([
-            'message' => 'Welcome to your new controller!',
+            'wishLists' => $wishLists,
+            'pagination' => [
+                'max' => $max,
+                'page' => $page
+            ],
             'path' => 'src/Controller/WishListController.php',
         ]);
     }
+
+
+
 }
diff --git a/server/web_app/src/Repository/ItemRepository.php b/server/web_app/src/Repository/ItemRepository.php
index e754446..db24cc2 100644
--- a/server/web_app/src/Repository/ItemRepository.php
+++ b/server/web_app/src/Repository/ItemRepository.php
@@ -58,6 +58,76 @@ class ItemRepository extends ServiceEntityRepository
         return $queryBuilder->getQuery()->getResult();
     }
 
+    public function findAllItemsByWishListFiltered(int $wishListId, ?bool $isBought, string $sortBy, string $sort, int $max, int $page)
+    {
+        $queryBuilder = $this->createQueryBuilder('i')
+            ->andWhere('i.wishList = :wishListId')
+            ->setParameter('wishListId', $wishListId);
+
+        // Filter by bought status (optional)
+        if ($isBought !== null) {
+            if ($isBought) {
+                $queryBuilder->innerJoin('App\Entity\Purchase', 'p', 'WITH', 'p.item = i.id'); // Only bought items
+            } else {
+                $queryBuilder->leftJoin('App\Entity\Purchase', 'p', 'WITH', 'p.item = i.id')
+                            ->andWhere('p.item IS NULL'); // Only non-bought items
+            }
+        }
+
+        // Ensure sorting by either 'createdAt' or 'price'
+        if (!in_array($sortBy, ['createdAt', 'price'])) {
+            $sortBy = 'createdAt'; // Default sorting by date
+        }
+
+        // Ensure sort order is either 'asc' or 'desc'
+        if (!in_array(strtolower($sort), ['asc', 'desc'])) {
+            $sort = 'desc'; // Default descending
+        }
+
+        $queryBuilder->orderBy("i.$sortBy", $sort)
+                    ->setMaxResults($max)
+                    ->setFirstResult(($page - 1) * $max);
+
+        return $queryBuilder->getQuery()->getResult();
+    }
+
+    public function findTotalPriceOfBoughtItemsByWishList(int $wishListId, string $sort = 'asc'): array
+    {
+        $queryBuilder = $this->createQueryBuilder('i')
+            ->select('i.wishList AS wishListId, SUM(i.price) AS totalPrice')
+            ->innerJoin('App\Entity\Purchase', 'p', 'WITH', 'p.item = i.id')
+            ->where('i.wishList = :wishListId')
+            ->setParameter('wishListId', $wishListId)
+            ->groupBy('i.wishList');
 
+        // Ensure sort order is either 'asc' or 'desc'
+        if (!in_array(strtolower($sort), ['asc', 'desc'])) {
+            $sort = 'asc'; // Default ascending order
+        }
+
+        $queryBuilder->orderBy('totalPrice', $sort);
+
+        return $queryBuilder->getQuery()->getSingleResult() ?? ['wishListId' => $wishListId, 'totalPrice' => 0];
+    }
+
+    public function findWishListsSortedByTotalBought(string $sort = 'desc', int $max = 10, int $page = 1): array
+    {
+        $queryBuilder = $this->createQueryBuilder('i')
+            ->select('w.id AS wishListId, SUM(i.price) AS totalPrice')
+            ->innerJoin('i.wishList', 'w') // Join WishList entity
+            ->innerJoin('App\Entity\Purchase', 'p', 'WITH', 'p.item = i.id') // Join Purchases
+            ->groupBy('w.id');
+
+        // Ensure sort order is either 'asc' or 'desc'
+        if (!in_array(strtolower($sort), ['asc', 'desc'])) {
+            $sort = 'desc'; // Default descending order
+        }
+
+        $queryBuilder->orderBy('totalPrice', $sort)
+                    ->setMaxResults($max)
+                    ->setFirstResult(($page - 1) * $max);
+
+        return $queryBuilder->getQuery()->getResult();
+    }
 
 }
diff --git a/server/web_app/src/Repository/WishListRepository.php b/server/web_app/src/Repository/WishListRepository.php
index 846c543..2d45f92 100644
--- a/server/web_app/src/Repository/WishListRepository.php
+++ b/server/web_app/src/Repository/WishListRepository.php
@@ -16,28 +16,46 @@ class WishListRepository extends ServiceEntityRepository
         parent::__construct($registry, WishList::class);
     }
 
-    //    /**
-    //     * @return WishList[] Returns an array of WishList objects
-    //     */
-    //    public function findByExampleField($value): array
-    //    {
-    //        return $this->createQueryBuilder('w')
-    //            ->andWhere('w.exampleField = :val')
-    //            ->setParameter('val', $value)
-    //            ->orderBy('w.id', 'ASC')
-    //            ->setMaxResults(10)
-    //            ->getQuery()
-    //            ->getResult()
-    //        ;
-    //    }
-
-    //    public function findOneBySomeField($value): ?WishList
-    //    {
-    //        return $this->createQueryBuilder('w')
-    //            ->andWhere('w.exampleField = :val')
-    //            ->setParameter('val', $value)
-    //            ->getQuery()
-    //            ->getOneOrNullResult()
-    //        ;
-    //    }
+    public function findAllItems (): array {
+        return $this->findAll();
+    }
+
+    public function findAllWishListsFiltered(?int $userId, ?\DateTime $expirationDate, ?bool $isActive, string $sortBy, string $sort, int $max, int $page): array
+    {
+        $queryBuilder = $this->createQueryBuilder('w');
+
+        // Filter by user ID if provided
+        if ($userId !== null) {
+            $queryBuilder->andWhere('w.user = :userId')
+                        ->setParameter('userId', $userId);
+        }
+
+        // Filter by expirationDate if provided
+        if ($expirationDate !== null) {
+            $queryBuilder->andWhere('w.expirationDate >= :expirationDate')
+                        ->setParameter('expirationDate', $expirationDate);
+        }
+
+        // Filter by active status if provided
+        if ($isActive !== null) {
+            $queryBuilder->andWhere('w.isActive = :isActive')
+                        ->setParameter('isActive', $isActive);
+        }
+
+        // Ensure sorting by either 'createdAt' or 'expirationDate'
+        if (!in_array($sortBy, ['createdAt', 'expirationDate'])) {
+            $sortBy = 'createdAt'; // Default sorting by date created
+        }
+
+        // Ensure sort order is either 'asc' or 'desc'
+        if (!in_array(strtolower($sort), ['asc', 'desc'])) {
+            $sort = 'desc'; // Default descending
+        }
+
+        $queryBuilder->orderBy("w.$sortBy", $sort)
+                    ->setMaxResults($max)
+                    ->setFirstResult(($page - 1) * $max);
+
+        return $queryBuilder->getQuery()->getResult();
+    }
 }
-- 
GitLab