From 2fdfbbb99e059f6f52531b69ed9e2ba0bc11cdb1 Mon Sep 17 00:00:00 2001
From: Lara Blersch <lb210@hdm-stuttgart.de>
Date: Mon, 27 Nov 2023 18:51:02 +0100
Subject: [PATCH] update: WishList #7: check for user before changing wishlist
 and filter for plants which can be planted in the current week and added
 requests to requests.http

---
 requests.http                                 | 15 ++++++
 .../controllers/WishListController.java       | 28 +++++-----
 .../exceptions/PlantAlreadyInWishList.java    | 10 ++++
 .../exceptions/PlantNotFoundException.java    |  8 +++
 .../hdm/mi/growbros/models/WishListEntry.java |  2 +-
 .../repositories/WishListRepository.java      | 38 ++++++++------
 .../mi/growbros/service/WishListService.java  | 52 +++++++++++--------
 .../hdm/mi/growbros/util/DateTimeUtils.java   | 14 +++++
 8 files changed, 117 insertions(+), 50 deletions(-)
 create mode 100644 src/main/java/hdm/mi/growbros/exceptions/PlantAlreadyInWishList.java
 create mode 100644 src/main/java/hdm/mi/growbros/exceptions/PlantNotFoundException.java
 create mode 100644 src/main/java/hdm/mi/growbros/util/DateTimeUtils.java

diff --git a/requests.http b/requests.http
index d51fde8..da3f1e5 100644
--- a/requests.http
+++ b/requests.http
@@ -21,3 +21,18 @@ content-type: application/json
   "email": "lukas.karsch@gmx.de",
   "password": "12345678"
 }
+
+### Get all plants from wishlist
+GET http://localhost:8080/api/v1/wishlist
+
+### Get amount of plants in wishlist
+GET http://localhost:8080/api/v1/wishlist/count
+
+### Add plant to wishlist
+POST http://localhost:8080/api/v1/wishlist/add/1
+
+### Remove plant from wishlist
+DELETE http://localhost:8080/api/v1/wishlist/remove/1
+
+### Remove all plants from wishlist
+DELETE http://localhost:8080/api/v1/wishlist/remove/all
\ No newline at end of file
diff --git a/src/main/java/hdm/mi/growbros/controllers/WishListController.java b/src/main/java/hdm/mi/growbros/controllers/WishListController.java
index aee0cf7..3a82701 100644
--- a/src/main/java/hdm/mi/growbros/controllers/WishListController.java
+++ b/src/main/java/hdm/mi/growbros/controllers/WishListController.java
@@ -2,10 +2,9 @@ package hdm.mi.growbros.controllers;
 
 import hdm.mi.growbros.models.plant.Plant;
 import hdm.mi.growbros.models.user.User;
-import hdm.mi.growbros.service.PlantsService;
 import hdm.mi.growbros.service.WishListService;
-import jakarta.validation.Valid;
 import lombok.RequiredArgsConstructor;
+import org.springframework.http.ResponseEntity;
 import org.springframework.security.core.annotation.AuthenticationPrincipal;
 import org.springframework.web.bind.annotation.*;
 
@@ -22,26 +21,31 @@ public class WishListController {
     @GetMapping("/")
     public Collection<Plant> getAllPlantsInWishList(@RequestParam(value = "sort", required = false) String sort,
                                                     @AuthenticationPrincipal User user) {
-        //TODO: get the user by adding (Authentication authentication) as params
         return wishListService.getWishedPlants(user, sort);
     }
 
+    @GetMapping("/count")
+    public int getWishListSize(
+            @AuthenticationPrincipal User user) {
+        return wishListService.countByUser(user);
+    }
+
 
     @PostMapping("/add/{plantId}")
-    public void addPlantToGarden(@PathVariable Long plantId,
-                                 @AuthenticationPrincipal User user) {
+    public ResponseEntity<Integer> addPlantToGarden(@PathVariable Long plantId,
+                                                   @AuthenticationPrincipal User user) {
         wishListService.addPlantToWishList(plantId, user);
+        return ResponseEntity.status(201).build();
     }
 
     @DeleteMapping("/remove/{entryId}")
-    public void removePlantFromGarden(@PathVariable Long entryId) {
-        wishListService.removeFromWishList(entryId);
+    public void removePlantFromGarden(@PathVariable Long entryId,
+                                      @AuthenticationPrincipal User user) {
+        wishListService.removeFromWishList(entryId, user);
     }
 
     @DeleteMapping("/remove/all")
-    public Long removeAllPlantsFromGarden() {
-        return wishListService.clearWishList();
+    public Long removeAllPlantsFromGarden(@AuthenticationPrincipal User user) {
+        return wishListService.clearWishList(user);
     }
-
-
-}
+}
\ No newline at end of file
diff --git a/src/main/java/hdm/mi/growbros/exceptions/PlantAlreadyInWishList.java b/src/main/java/hdm/mi/growbros/exceptions/PlantAlreadyInWishList.java
new file mode 100644
index 0000000..31a8159
--- /dev/null
+++ b/src/main/java/hdm/mi/growbros/exceptions/PlantAlreadyInWishList.java
@@ -0,0 +1,10 @@
+package hdm.mi.growbros.exceptions;
+
+import hdm.mi.growbros.models.plant.Plant;
+
+public class PlantAlreadyInWishList extends RuntimeException {
+
+    public PlantAlreadyInWishList (Plant plant) {
+        super("Plant " + plant + " not added to Wishlist because it already is in Wishlist");
+    }
+}
diff --git a/src/main/java/hdm/mi/growbros/exceptions/PlantNotFoundException.java b/src/main/java/hdm/mi/growbros/exceptions/PlantNotFoundException.java
new file mode 100644
index 0000000..7e43fc8
--- /dev/null
+++ b/src/main/java/hdm/mi/growbros/exceptions/PlantNotFoundException.java
@@ -0,0 +1,8 @@
+package hdm.mi.growbros.exceptions;
+
+public class PlantNotFoundException extends RuntimeException {
+    public PlantNotFoundException(Long id) {
+        super(String.format("Plant with id '%d' was not found", id));
+    }
+}
+
diff --git a/src/main/java/hdm/mi/growbros/models/WishListEntry.java b/src/main/java/hdm/mi/growbros/models/WishListEntry.java
index e717d16..eda6407 100644
--- a/src/main/java/hdm/mi/growbros/models/WishListEntry.java
+++ b/src/main/java/hdm/mi/growbros/models/WishListEntry.java
@@ -28,4 +28,4 @@ public class WishListEntry {
 
     @Id
     private Long id;
-}
+}
\ No newline at end of file
diff --git a/src/main/java/hdm/mi/growbros/repositories/WishListRepository.java b/src/main/java/hdm/mi/growbros/repositories/WishListRepository.java
index bf2a2d2..f1c8d56 100644
--- a/src/main/java/hdm/mi/growbros/repositories/WishListRepository.java
+++ b/src/main/java/hdm/mi/growbros/repositories/WishListRepository.java
@@ -3,6 +3,7 @@ package hdm.mi.growbros.repositories;
 import hdm.mi.growbros.models.plant.Plant;
 import hdm.mi.growbros.models.WishListEntry;
 import hdm.mi.growbros.models.user.User;
+import org.springframework.data.domain.Sort;
 import org.springframework.data.jpa.repository.JpaRepository;
 import org.springframework.data.jpa.repository.Query;
 import org.springframework.data.repository.query.Param;
@@ -14,8 +15,19 @@ import java.util.List;
 @Repository
 public interface WishListRepository extends JpaRepository<WishListEntry, Long> {
 
+    List<WishListEntry> findByUser(User user);
+
+    List<WishListEntry> findByUser(User user, Sort sort);
+
+    int countByUser(User user);
+
+    int deleteAllByUser(User user);
+
+    void deleteByIdAndUser(long entryId, User user);
+
     @Query("""
                 SELECT ge FROM WishListEntry ge
+                WHERE ge.user = :user
                 ORDER BY
                     CASE
                         WHEN :week <= ge.plant.plantWeekStart
@@ -25,21 +37,15 @@ public interface WishListRepository extends JpaRepository<WishListEntry, Long> {
                     ge.plant.name
                 ASC
             """)
-    List<WishListEntry> findAllByNearestPlantingWeek(@Param("week") int currentWeek);
-
-    boolean existsByUserAndPlant(User user, Plant plant);
-
-}
-
-
-
-
-
-
-
-
-
-
-
+    List<WishListEntry> findAllByNearestPlantingWeek(@Param("user") User user, @Param("week") int currentWeek);
 
+    @Query("""
+                SELECT ge FROM WishListEntry ge
+                WHERE ge.user = :user
+                AND ge.plant.plantWeekStart <= :week
+                AND ge.plant.plantWeekEnd >= :week
+            """)
+    List<WishListEntry> findByCurrentPlantingWeek(@Param("user") User user, @Param("week") int currentWeek);
 
+    boolean existsByUserAndPlant(User user, Plant plant);
+}
\ No newline at end of file
diff --git a/src/main/java/hdm/mi/growbros/service/WishListService.java b/src/main/java/hdm/mi/growbros/service/WishListService.java
index 8743744..c48e649 100644
--- a/src/main/java/hdm/mi/growbros/service/WishListService.java
+++ b/src/main/java/hdm/mi/growbros/service/WishListService.java
@@ -1,10 +1,13 @@
 package hdm.mi.growbros.service;
 
+import hdm.mi.growbros.exceptions.PlantAlreadyInWishList;
+import hdm.mi.growbros.exceptions.PlantNotFoundException;
 import hdm.mi.growbros.models.plant.Plant;
 import hdm.mi.growbros.models.WishListEntry;
 import hdm.mi.growbros.models.user.User;
 import hdm.mi.growbros.repositories.PlantRepository;
 import hdm.mi.growbros.repositories.WishListRepository;
+import hdm.mi.growbros.util.DateTimeUtils;
 import lombok.RequiredArgsConstructor;
 import org.springframework.data.domain.Sort;
 import org.springframework.stereotype.Service;
@@ -24,56 +27,59 @@ public class WishListService {
     private final PlantRepository plantRepository;
 
     public List<Plant> getWishedPlants(User user, String sort) {
-        //todo: check for current user?
-        if (sort == null) return getAllPlantsOrderedByName();
+        if (sort == null) return getAllPlantsOrderedByName(user);
         return switch (sort) {
-            case "createdAt" -> getAllPlantsOrderedByCreatedDate();
-            case "plantDate" -> getAllPlantsOrderedByNextPossiblePlantDate();
-            default -> getAllPlantsOrderedByName();
+            case "createdAt" -> getAllPlantsOrderedByCreatedDate(user);
+            case "plantDate" -> getAllPlantsOrderedByNextPossiblePlantDate(user);
+            case "currentPlantable" -> getCurrentPlantablePlants(user);
+            default -> getAllPlantsOrderedByName(user);
         };
     }
 
     public void addPlantToWishList(Long plantId, User user) {
-        //todo: get user
         Plant plant = plantRepository.findById(plantId).orElseThrow(() -> new PlantNotFoundException(plantId));
 
         if(!wishListRepository.existsByUserAndPlant(user, plant)) {
             WishListEntry wishListEntry = new WishListEntry();
             wishListEntry.setPlant(plant);
+            wishListEntry.setUser(user);
             wishListRepository.save(wishListEntry);
         } else {
             throw new PlantAlreadyInWishList(plant);
-            //todo: Exception erstellen
         }
     }
 
-    public void removeFromWishList(Long entryId) {
-        //TODO: only allow this if the authenticated user created the entry
-        wishListRepository.deleteById(entryId);
+    public void removeFromWishList(Long entryId, User user) {
+        wishListRepository.deleteByIdAndUser(entryId, user);
     }
 
-    public Long clearWishList() {
-        //TODO: this needs to be filtered by user
+    public Long clearWishList(User user) {
         Long deleted = wishListRepository.count();
-        wishListRepository.deleteAll();
+        wishListRepository.deleteAllByUser(user);
         return deleted;
     }
 
-    private List<Plant> getAllPlantsOrderedByName() {
+    private List<Plant> getAllPlantsOrderedByName(User user) {
         return mapWishListEntriesToPlants(
-                wishListRepository.findAll(Sort.by("plant.name"))
+                wishListRepository.findByUser(user, Sort.by("plant.name"))
         );
     }
 
-    private List<Plant> getAllPlantsOrderedByCreatedDate() {
+    private List<Plant> getAllPlantsOrderedByCreatedDate(User user) {
         return mapWishListEntriesToPlants(
-                wishListRepository.findAll(Sort.by("createdAt"))
+                wishListRepository.findByUser(user, Sort.by("createdAt"))
         );
     }
 
-    private List<Plant> getAllPlantsOrderedByNextPossiblePlantDate() {
+    private List<Plant> getAllPlantsOrderedByNextPossiblePlantDate(User user) {
         return mapWishListEntriesToPlants(
-                wishListRepository.findAllByNearestPlantingWeek(DateTimeUtils.getCurrentWeekForToday())
+                wishListRepository.findAllByNearestPlantingWeek(user, DateTimeUtils.getCurrentWeekForToday())
+        );
+    }
+
+    private List<Plant> getCurrentPlantablePlants(User user) {
+        return mapWishListEntriesToPlants(
+                wishListRepository.findByCurrentPlantingWeek(user, DateTimeUtils.getCurrentWeekForToday())
         );
     }
 
@@ -84,6 +90,11 @@ public class WishListService {
                 .toList();
     }
 
+    public int countByUser(User user) {
+        return wishListRepository.countByUser(user);
+    }
+
+
     /*public List<Plant> sort(String sortKey) {
         switch (sortKey) {
             case ("name"):
@@ -109,5 +120,4 @@ public class WishListService {
 
         return week-1;  //because in class Plant weeks are indexed at 0
     }*/
-
-}
+}
\ No newline at end of file
diff --git a/src/main/java/hdm/mi/growbros/util/DateTimeUtils.java b/src/main/java/hdm/mi/growbros/util/DateTimeUtils.java
new file mode 100644
index 0000000..5faccd3
--- /dev/null
+++ b/src/main/java/hdm/mi/growbros/util/DateTimeUtils.java
@@ -0,0 +1,14 @@
+package hdm.mi.growbros.util;
+
+import java.time.LocalDate;
+import java.time.temporal.ChronoField;
+
+public class DateTimeUtils {
+    public static int getCurrentWeekForToday() {
+        return getCurrentWeekFromDate(LocalDate.now());
+    }
+
+    public static int getCurrentWeekFromDate(LocalDate date) {
+        return date.get(ChronoField.ALIGNED_WEEK_OF_YEAR);
+    }
+}
-- 
GitLab