From d323195eeb662f77449f2f4622df5ab18731d9d5 Mon Sep 17 00:00:00 2001
From: Florent POITTEVIN <poittevin.florent@gmail.com>
Date: Tue, 15 Jun 2021 16:47:39 +0200
Subject: [PATCH] feat(notification): [AOU-639] allow to filter notification to
 retrieve only unread notification

---
 .../controller/admin/NotificationController.java    | 11 +++++++++--
 .../specification/NotificationSpecification.java    | 13 +++++++++++++
 .../ch/unige/aou/business/NotificationService.java  |  4 ++--
 .../aou/repository/NotificationRepository.java      |  5 ++++-
 4 files changed, 28 insertions(+), 5 deletions(-)

diff --git a/AoU-Admin/src/main/java/ch/unige/aou/controller/admin/NotificationController.java b/AoU-Admin/src/main/java/ch/unige/aou/controller/admin/NotificationController.java
index 2af3c8ca5..d852da160 100644
--- a/AoU-Admin/src/main/java/ch/unige/aou/controller/admin/NotificationController.java
+++ b/AoU-Admin/src/main/java/ch/unige/aou/controller/admin/NotificationController.java
@@ -90,7 +90,14 @@ public class NotificationController extends ResourceController<Notification> {
   @GetMapping(SolidifyConstants.URL_SEP + AouActionName.INBOX)
   @SuppressWarnings("squid:S4684")
   public HttpEntity<Collection<Notification>> listInboxNotification(@ModelAttribute Notification search, Pageable pageable) {
-    final Page<Notification> listItem = ((NotificationService) (this.itemService)).listInboxNotification(this.userService.getCurrentUser(), search, null, null, pageable);
+    return listInboxNotification(false, search, pageable);
+  }
+
+  @UserPermissions
+  @GetMapping(path = SolidifyConstants.URL_SEP + AouActionName.INBOX, params = "onlyWithNullReadTime")
+  @SuppressWarnings("squid:S4684")
+  public HttpEntity<Collection<Notification>> listInboxNotification(@RequestParam boolean onlyWithNullReadTime, @ModelAttribute Notification search, Pageable pageable) {
+    final Page<Notification> listItem = ((NotificationService) (this.itemService)).listInboxNotification(this.userService.getCurrentUser(), search, null, null, onlyWithNullReadTime, pageable);
     final Collection<Notification> collection = this.addRemainingLinks(listItem, pageable);
     return new ResponseEntity<>(collection, HttpStatus.OK);
   }
@@ -100,7 +107,7 @@ public class NotificationController extends ResourceController<Notification> {
   public HttpEntity<Collection<Notification>> advancedSearch(@ModelAttribute Notification notification,
           @RequestParam(value="structureId", required = false) String structureId,
           @RequestParam(value = "researchGroupId", required = false) String researchGroupId, Pageable pageable) {
-    final Page<Notification> listItem = ((NotificationService) (this.itemService)).listInboxNotification(this.userService.getCurrentUser(), notification, structureId, researchGroupId, pageable);
+    final Page<Notification> listItem = ((NotificationService) (this.itemService)).listInboxNotification(this.userService.getCurrentUser(), notification, structureId, researchGroupId, false, pageable);
     final Collection<Notification> collection = this.addRemainingLinks(listItem, pageable);
     return new ResponseEntity<>(collection, HttpStatus.OK);
   }
diff --git a/AoU-Model/src/main/java/ch/unige/aou/specification/NotificationSpecification.java b/AoU-Model/src/main/java/ch/unige/aou/specification/NotificationSpecification.java
index 543ce4d08..da132c32b 100644
--- a/AoU-Model/src/main/java/ch/unige/aou/specification/NotificationSpecification.java
+++ b/AoU-Model/src/main/java/ch/unige/aou/specification/NotificationSpecification.java
@@ -20,6 +20,7 @@ public class NotificationSpecification extends SolidifySpecification<Notificatio
   private OffsetDateTime createdDateMinValue = null;
   private OffsetDateTime createdDateMaxValue = null;
   private boolean onlyWithNullSentTime = false;
+  private boolean onlyWithNullReadTime = false;
 
   public NotificationSpecification(Notification criteria) {
     super(criteria);
@@ -49,6 +50,10 @@ public class NotificationSpecification extends SolidifySpecification<Notificatio
     if (this.onlyWithNullSentTime) {
       predicatesList.add(criteriaBuilder.isNull(root.get("sentTime")));
     }
+
+    if (this.onlyWithNullReadTime) {
+      predicatesList.add(criteriaBuilder.isNull(root.get("readTime")));
+    }
   }
 
   private void setNotificationTypeCriteria(Root<Notification> root, CriteriaBuilder criteriaBuilder, List<Predicate> listPredicate,
@@ -82,4 +87,12 @@ public class NotificationSpecification extends SolidifySpecification<Notificatio
   public void setOnlyWithNullSentTime(boolean onlyWithNullSentTime) {
     this.onlyWithNullSentTime = onlyWithNullSentTime;
   }
+
+  public boolean isOnlyWithNullReadTime() {
+    return this.onlyWithNullReadTime;
+  }
+
+  public void setOnlyWithNullReadTime(boolean onlyWithNullReadTime) {
+    this.onlyWithNullReadTime = onlyWithNullReadTime;
+  }
 }
diff --git a/AoU-ResourceServerCommon/src/main/java/ch/unige/aou/business/NotificationService.java b/AoU-ResourceServerCommon/src/main/java/ch/unige/aou/business/NotificationService.java
index c158d0c73..4abbcfb4d 100644
--- a/AoU-ResourceServerCommon/src/main/java/ch/unige/aou/business/NotificationService.java
+++ b/AoU-ResourceServerCommon/src/main/java/ch/unige/aou/business/NotificationService.java
@@ -72,7 +72,7 @@ public class NotificationService extends AouResourceService<Notification> {
   }
 
   public Page<Notification> listInboxNotification(User currentUser, Notification search, String structureId, String researchGroupId,
-          Pageable pageable) {
+          boolean onlyWithNullReadTime, Pageable pageable) {
     if (currentUser == null) {
       throw new SolidifyRuntimeException("The current user is null");
     }
@@ -90,7 +90,7 @@ public class NotificationService extends AouResourceService<Notification> {
     String personId = currentPerson.getResId();
     int userRoleLevel = currentUser.getApplicationRole().getLevel();
     return this.notificationRepository.findInboxNotificationByPersonAndEvent(personId, notificationType,
-            event, userRoleLevel, structureId, researchGroupId, pageable);
+            event, userRoleLevel, structureId, researchGroupId, onlyWithNullReadTime, pageable);
   }
 
   /**
diff --git a/AoU-ResourceServerCommon/src/main/java/ch/unige/aou/repository/NotificationRepository.java b/AoU-ResourceServerCommon/src/main/java/ch/unige/aou/repository/NotificationRepository.java
index ee858b518..fa1d8ffd3 100644
--- a/AoU-ResourceServerCommon/src/main/java/ch/unige/aou/repository/NotificationRepository.java
+++ b/AoU-ResourceServerCommon/src/main/java/ch/unige/aou/repository/NotificationRepository.java
@@ -31,6 +31,7 @@ public interface NotificationRepository extends SolidifyRepository<Notification>
                  + "     WHERE ((nt.notifiedApplicationRole IS NOT NULL AND :userApplicationRoleLevel <= nar.level)"
                  + "      OR (nt.notifiedRoleStructure IS NOT NULL AND 20 = nour.level AND stpr.resId = :personId))"
                  + "     AND (n.event = :event OR :event IS NULL)"
+                 + "     AND (n.readTime IS NULL OR :onlyWithNullReadTime IS FALSE)"
                  + "     AND (str.resId = :structureId OR :structureId IS NULL)"
                  + "     AND (n.notificationType = :notificationType OR :notificationType IS NULL))"
                  + " OR n.resId in ("
@@ -49,6 +50,7 @@ public interface NotificationRepository extends SolidifyRepository<Notification>
                  + "     WHERE ((nt.notifiedApplicationRole IS NOT NULL AND :userApplicationRoleLevel <= nar.level)"
                  + "      OR (nt.notifiedRoleStructure IS NOT NULL AND 10 = nour.level AND strvrps.resId = nep.subtype AND strvrp.resId = :personId))"
                  + "     AND (n.event = :event OR :event IS NULL)"
+                 + "     AND (n.readTime IS NULL OR :onlyWithNullReadTime IS FALSE)"
                  + "     AND (str.resId = :structureId OR :structureId IS NULL)"
                  + "     AND (n.notificationType = :notificationType OR :notificationType IS NULL))"
                  + " OR n.resId in ("
@@ -64,10 +66,11 @@ public interface NotificationRepository extends SolidifyRepository<Notification>
                  + "     WHERE ((nt.notifiedApplicationRole IS NOT NULL AND :userApplicationRoleLevel <= nar.level)"
                  + "        OR (nt.notifiedRoleStructure IS NOT NULL AND nrgp.resId = :personId))"
                  + "     AND (n.event = :event OR :event IS NULL)"
+                 + "     AND (n.readTime IS NULL OR :onlyWithNullReadTime IS FALSE)"
                  + "     AND (nrg.resId = :researchGroupId OR :structureId IS NULL)"
                  + "     AND (n.notificationType = :notificationType OR :notificationType IS NULL))")
   Page<Notification> findInboxNotificationByPersonAndEvent(String personId, NotificationType notificationType,
-          Event event, int userApplicationRoleLevel, String structureId, String researchGroupId, Pageable pageable);
+          Event event, int userApplicationRoleLevel, String structureId, String researchGroupId, boolean onlyWithNullReadTime, Pageable pageable);
 
   @Query("SELECT DISTINCT n"
                  + " FROM Notification n"
-- 
GitLab