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