From 80e638fa9d203f8e31db77eb00677b923a35acee Mon Sep 17 00:00:00 2001 From: rabeaM Date: Wed, 4 Dec 2024 12:40:29 +0100 Subject: [PATCH] Added delete/update/partialUpdate User-Message --- .../numportal/domain/dto/MessageDto.java | 7 +- .../domain/repository/MessageRepository.java | 6 +- .../domain/templates/ExceptionsTemplate.java | 2 + .../numportal/service/MessageService.java | 92 +++++++++++++++---- .../web/controller/MessageController.java | 52 ++++++++++- 5 files changed, 133 insertions(+), 26 deletions(-) diff --git a/src/main/java/org/highmed/numportal/domain/dto/MessageDto.java b/src/main/java/org/highmed/numportal/domain/dto/MessageDto.java index a99b24c4..2dfe28f2 100644 --- a/src/main/java/org/highmed/numportal/domain/dto/MessageDto.java +++ b/src/main/java/org/highmed/numportal/domain/dto/MessageDto.java @@ -19,17 +19,18 @@ @AllArgsConstructor public class MessageDto { - @NotNull Long id; - private String title; - @NotNull @NotEmpty + private String title; + private String text; + @NotNull private LocalDateTime startDate; + @NotNull private LocalDateTime endDate; @NotNull diff --git a/src/main/java/org/highmed/numportal/domain/repository/MessageRepository.java b/src/main/java/org/highmed/numportal/domain/repository/MessageRepository.java index 0a6419aa..47cc4ddf 100644 --- a/src/main/java/org/highmed/numportal/domain/repository/MessageRepository.java +++ b/src/main/java/org/highmed/numportal/domain/repository/MessageRepository.java @@ -2,10 +2,14 @@ import org.highmed.numportal.domain.model.Message; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.repository.PagingAndSortingRepository; import org.springframework.stereotype.Repository; @Repository -public interface MessageRepository extends JpaRepository, CustomProjectRepository { +public interface MessageRepository extends JpaRepository, PagingAndSortingRepository { + Page findMessages(Pageable pageable); } diff --git a/src/main/java/org/highmed/numportal/domain/templates/ExceptionsTemplate.java b/src/main/java/org/highmed/numportal/domain/templates/ExceptionsTemplate.java index 0f30892b..346edabb 100644 --- a/src/main/java/org/highmed/numportal/domain/templates/ExceptionsTemplate.java +++ b/src/main/java/org/highmed/numportal/domain/templates/ExceptionsTemplate.java @@ -86,6 +86,8 @@ public class ExceptionsTemplate { public static final String CANNOT_DELETE_PROJECT_INVALID_STATUS = "Cannot delete project: %s, invalid status: %s"; public static final String CANNOT_UPDATE_PROJECT_INVALID_PROJECT_STATUS = "Cannot update project: %s, invalid project status: %s"; public static final String CANNOT_UPDATE_MESSAGE_INVALID = "Cannot update message: %s, invalid: %s"; + public static final String CANNOT_HANDLE_DATE = "Cannot handle date: %s"; + public static final String CANNOT_DELETE_MESSAGE = "Cannot delete this message: %s"; public static final String NO_PERMISSIONS_TO_EDIT_THIS_PROJECT = "No permissions to edit this project"; public static final String CANNOT_ACCESS_THIS_RESOURCE_USER_IS_NOT_OWNER = "Cannot access this resource. User is not owner."; public static final String DATA_EXPLORER_AVAILABLE_FOR_PUBLISHED_PROJECTS_ONLY = "Data explorer available for published projects only"; diff --git a/src/main/java/org/highmed/numportal/service/MessageService.java b/src/main/java/org/highmed/numportal/service/MessageService.java index 51613c6d..0c31274d 100644 --- a/src/main/java/org/highmed/numportal/service/MessageService.java +++ b/src/main/java/org/highmed/numportal/service/MessageService.java @@ -9,10 +9,14 @@ import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; import java.time.LocalDateTime; +import static org.highmed.numportal.domain.templates.ExceptionsTemplate.CANNOT_DELETE_MESSAGE; +import static org.highmed.numportal.domain.templates.ExceptionsTemplate.CANNOT_HANDLE_DATE; import static org.highmed.numportal.domain.templates.ExceptionsTemplate.CANNOT_UPDATE_MESSAGE_INVALID; import static org.highmed.numportal.domain.templates.ExceptionsTemplate.MESSAGE_NOT_FOUND; @@ -30,45 +34,93 @@ public class MessageService { public MessageDto createUserMessage(MessageDto messageDto, String userId) { Message message = messageMapper.convertToEntity(messageDto); userDetailsService.checkIsUserApproved(userId); - validateDates(message.getStartDate(), message.getEndDate()); + validateDates(message.getStartDate(), message.getEndDate(), LocalDateTime.now().minusMinutes(5)); Message savedMessage = messageRepository.save(message); return messageMapper.convertToDTO(savedMessage); } - public MessageDto updateUserMessage(Long id, MessageDto messageDto, String userId) { + public Page getMessages(String userId, Pageable pageable) { userDetailsService.checkIsUserApproved(userId); + Page messagePage = messageRepository.findMessages(pageable); + return messagePage.map(message -> messageMapper.convertToDTO(message)); + } + public MessageDto updateUserMessage(Long id, MessageDto messageDto, String userId) { + userDetailsService.checkIsUserApproved(userId); + LocalDateTime now = LocalDateTime.now().minusMinutes(5); Message messageToUpdate = messageRepository.findById(id) .orElseThrow(() -> new ResourceNotFound(MessageService.class, MESSAGE_NOT_FOUND, String.format(MESSAGE_NOT_FOUND, id))); - validateDates(messageDto.getStartDate(), messageDto.getEndDate()); - //Todo: Gibt es neben dem Datum weitere Einschränkungen, wann eine Message geupdated werden kann - messageToUpdate.setTitle(messageDto.getTitle()); - messageToUpdate.setText(messageDto.getText()); - messageToUpdate.setStartDate(messageDto.getStartDate()); - messageToUpdate.setEndDate(messageDto.getEndDate()); - messageToUpdate.setType(messageDto.getType()); + if (isInactiveMessage(messageToUpdate, now)) { + throw new BadRequestException(MessageService.class, CANNOT_UPDATE_MESSAGE_INVALID, + String.format(CANNOT_UPDATE_MESSAGE_INVALID, messageToUpdate.getId(), "message is not shown anymore")); + } + if (isActiveMessage(messageDto, messageToUpdate, now)) { + messageToUpdate.setEndDate(messageDto.getEndDate()); + } else { + validateDates(messageDto.getStartDate(), messageDto.getEndDate(), now); + + messageToUpdate.setTitle(messageDto.getTitle()); + messageToUpdate.setText(messageDto.getText()); + messageToUpdate.setStartDate(messageDto.getStartDate()); + messageToUpdate.setEndDate(messageDto.getEndDate()); + messageToUpdate.setType(messageDto.getType()); + } Message savedMessage = messageRepository.save(messageToUpdate); return messageMapper.convertToDTO(savedMessage); } - private void validateDates(LocalDateTime startDate, LocalDateTime endDate) { - if (startDate == null && endDate == null) { - return; + public MessageDto partialUpdateUserMessage(Long id, LocalDateTime endDate, String userId) { + userDetailsService.checkIsUserApproved(userId); + LocalDateTime now = LocalDateTime.now().minusMinutes(5); + Message messageToUpdate = messageRepository.findById(id) + .orElseThrow(() -> new ResourceNotFound(MessageService.class, MESSAGE_NOT_FOUND, + String.format(MESSAGE_NOT_FOUND, id))); + if (isInactiveMessage(messageToUpdate, now) && isPlannedMessage(messageToUpdate, now)) { + throw new BadRequestException(MessageService.class, CANNOT_UPDATE_MESSAGE_INVALID, + String.format(CANNOT_UPDATE_MESSAGE_INVALID, messageToUpdate, "Message is not active")); } - LocalDateTime now = LocalDateTime.now(); - if (startDate != null && startDate.isBefore(now)) { - throw new BadRequestException(MessageService.class, CANNOT_UPDATE_MESSAGE_INVALID); + messageToUpdate.setEndDate(endDate); + Message savedMessage = messageRepository.save(messageToUpdate); + return messageMapper.convertToDTO(savedMessage); + } + + public void deleteUserMessage(Long id, String userId) { + LocalDateTime now = LocalDateTime.now().minusMinutes(5); + userDetailsService.checkIsUserApproved(userId); + Message messageToDelete = messageRepository.findById(id) + .orElseThrow(() -> new ResourceNotFound(MessageService.class, MESSAGE_NOT_FOUND, + String.format(MESSAGE_NOT_FOUND, id))); + if (messageToDelete.getStartDate().isBefore(now) || messageToDelete.getEndDate().isAfter(now)) { + throw new BadRequestException(MessageService.class, CANNOT_DELETE_MESSAGE, + String.format(CANNOT_DELETE_MESSAGE, messageToDelete.getId())); } - if (endDate != null && endDate.isBefore(now)) { - throw new BadRequestException(MessageService.class, CANNOT_UPDATE_MESSAGE_INVALID); + messageRepository.deleteById(id); + } + + private static boolean isInactiveMessage(Message messageToUpdate, LocalDateTime now) { + return messageToUpdate.getEndDate().isBefore(now); + } + + private static boolean isActiveMessage(MessageDto messageDto, Message messageToUpdate, LocalDateTime now) { + return messageToUpdate.getStartDate().isBefore(now) && messageDto.getEndDate().isAfter(now); + } + + private static boolean isPlannedMessage(Message messageToUpdate, LocalDateTime now) { + return messageToUpdate.getStartDate().isAfter(now); + } + + private void validateDates(LocalDateTime startDate, LocalDateTime endDate, LocalDateTime now) { + if (startDate.isBefore(now)) { + throw new BadRequestException(MessageService.class, CANNOT_HANDLE_DATE, + String.format(CANNOT_HANDLE_DATE, startDate)); } - if (startDate != null && endDate != null - && (startDate.isAfter(endDate) || startDate.isEqual(endDate))) { - throw new BadRequestException(MessageService.class, CANNOT_UPDATE_MESSAGE_INVALID); + if (startDate.isAfter(endDate) || startDate.isEqual(endDate)) { + throw new BadRequestException(MessageService.class, CANNOT_HANDLE_DATE, + String.format(CANNOT_HANDLE_DATE, endDate)); } } } diff --git a/src/main/java/org/highmed/numportal/web/controller/MessageController.java b/src/main/java/org/highmed/numportal/web/controller/MessageController.java index f9f57fa4..c90d803f 100644 --- a/src/main/java/org/highmed/numportal/web/controller/MessageController.java +++ b/src/main/java/org/highmed/numportal/web/controller/MessageController.java @@ -1,6 +1,7 @@ package org.highmed.numportal.web.controller; import org.highmed.numportal.domain.dto.MessageDto; +import org.highmed.numportal.mapper.MessageMapper; import org.highmed.numportal.service.MessageService; import org.highmed.numportal.service.logger.ContextLog; import org.highmed.numportal.web.config.Role; @@ -10,17 +11,27 @@ import jakarta.validation.Valid; import jakarta.validation.constraints.NotNull; import lombok.AllArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.web.PageableDefault; +import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.security.oauth2.jwt.Jwt; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PatchMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; +import java.time.LocalDateTime; + @RestController @AllArgsConstructor @RequestMapping(value = "/message", produces = "application/json") @@ -28,6 +39,7 @@ public class MessageController { private final MessageService messageService; + private final MessageMapper messageMapper; @ContextLog(type = "MessageManagement", description = "Create user message") @PostMapping() @@ -40,10 +52,20 @@ public ResponseEntity createUserMessage( return ResponseEntity.ok(messageService.createUserMessage(messageDto, principal.getSubject())); } - @ContextLog(type = "MessageManagement", description = "Update a message") + @GetMapping() + @Operation( + description = "Get list of all pageable user messages sorted default by startdate") + @PreAuthorize(Role.CONTENT_ADMIN) + public ResponseEntity> getUserMessages( + @AuthenticationPrincipal @NotNull Jwt principal, + @PageableDefault(size = 100, sort = "startDate") Pageable pageable) { + return ResponseEntity.ok(messageService.getMessages(principal.getSubject(), pageable)); + } + + @ContextLog(type = "MessageManagement", description = "Update a user message") @PutMapping(value = "/{id}") @Operation( - description = "Update a message") + description = "Update a user message") @PreAuthorize(Role.CONTENT_ADMIN) public ResponseEntity updateUserMessage( @PathVariable("id") Long id, @@ -51,4 +73,30 @@ public ResponseEntity updateUserMessage( @Valid @NotNull @RequestBody MessageDto messageDto) { return ResponseEntity.ok(messageService.updateUserMessage(id, messageDto, principal.getSubject())); } + + @ContextLog(type = "MessageManagement", description = "Extend End date of a user message") + @PatchMapping(value = "/{id}") + @Operation( + description = "Extend End date of a user message") + @PreAuthorize(Role.CONTENT_ADMIN) + public ResponseEntity partialUpdateUserMessage( + @PathVariable("id") Long id, + @AuthenticationPrincipal @NotNull Jwt principal, + @Valid @NotNull @RequestParam LocalDateTime endDate) { + return ResponseEntity.ok(messageService.partialUpdateUserMessage(id, endDate, principal.getSubject())); + } + + @ContextLog(type = "MessageManagement", description = "Delete a user message") + @DeleteMapping(value = "/{id}") + @Operation( + description = "Delete a user message") + @PreAuthorize(Role.CONTENT_ADMIN) + public ResponseEntity deleteUserMessage( + @PathVariable("id") Long id, + @AuthenticationPrincipal @NotNull Jwt principal) { + messageService.deleteUserMessage(id, principal.getSubject()); + return ResponseEntity.ok().build(); + } } + +