package gr.cite.notification.service.inappnotification; import gr.cite.commons.web.authz.service.AuthorizationService; import gr.cite.notification.authorization.Permission; import gr.cite.notification.common.enums.NotificationInAppTracking; import gr.cite.notification.common.scope.user.UserScope; import gr.cite.notification.data.InAppNotificationEntity; import gr.cite.notification.data.TenantScopedEntityManager; import gr.cite.notification.model.deleter.InAppNotificationDeleter; import gr.cite.notification.query.InAppNotificationQuery; import gr.cite.tools.data.deleter.DeleterFactory; import gr.cite.tools.data.query.QueryFactory; import gr.cite.tools.exception.MyForbiddenException; import gr.cite.tools.logging.DataLogEntry; import gr.cite.tools.logging.LoggerService; import jakarta.persistence.Query; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.web.context.annotation.RequestScope; import javax.management.InvalidApplicationException; import java.time.Instant; import java.util.List; import java.util.UUID; @Service @RequestScope public class InAppNotificationServiceImpl implements InAppNotificationService { private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(InAppNotificationServiceImpl.class)); private final QueryFactory queryFactory; private final TenantScopedEntityManager entityManager; private final AuthorizationService authService; private final DeleterFactory deleterFactory; private final UserScope userScope; @Autowired public InAppNotificationServiceImpl(QueryFactory queryFactory, TenantScopedEntityManager entityManager, AuthorizationService authService, DeleterFactory deleterFactory, UserScope userScope) { this.queryFactory = queryFactory; this.entityManager = entityManager; this.authService = authService; this.deleterFactory = deleterFactory; this.userScope = userScope; } public void markAsRead(UUID id) { this.markAsRead(List.of(id)); } public void markAsRead(List ids) { try { logger.debug(new DataLogEntry("marking as read in-app notifications", ids)); UUID userId = this.userScope.getUserId(); List items = this.queryFactory.query(InAppNotificationQuery.class) .ids(ids) .userId(userId) .collect(); Instant now = Instant.now(); for (InAppNotificationEntity item : items) { item.setTrackingState(NotificationInAppTracking.DELIVERED); item.setUpdatedAt(now); item.setReadTime(now); this.entityManager.merge(item); this.entityManager.persist(item); } } catch (InvalidApplicationException e) { logger.error(e.getMessage(), e); } } public void markAsReadAllUserNotification(UUID userId) { String entity = InAppNotificationEntity.class.getSimpleName(); String sqlQuery = "UPDATE " + entity + " as e SET " + InAppNotificationEntity._trackingState + " = :trackingState, " + InAppNotificationEntity._updatedAt + "= :updatedAt, " + InAppNotificationEntity._readTime + " = :readTime " + "WHERE e." + InAppNotificationEntity._trackingState + " = :trackingStateCondition AND e." + InAppNotificationEntity._userId + " = :userId"; Query query = this.entityManager.createQuery(sqlQuery) .setParameter("trackingState", NotificationInAppTracking.DELIVERED) .setParameter("updatedAt", Instant.now()) .setParameter("readTime", Instant.now()) .setParameter("userId", userId) .setParameter("trackingStateCondition", NotificationInAppTracking.STORED); int updateCount = query.executeUpdate(); } public void deleteAndSave(UUID id) throws MyForbiddenException, InvalidApplicationException { logger.debug("deleting in-app notification: {}", id); this.authService.authorizeForce(Permission.DeleteInAppNotification); this.deleterFactory.deleter(InAppNotificationDeleter.class).deleteAndSaveByIds(List.of(id)); } }