diff --git a/src/main/java/com/javanauta/ts/taskscheduler/business/TaskService.java b/src/main/java/com/javanauta/ts/taskscheduler/business/TaskService.java index c03cf73..06ac2e3 100644 --- a/src/main/java/com/javanauta/ts/taskscheduler/business/TaskService.java +++ b/src/main/java/com/javanauta/ts/taskscheduler/business/TaskService.java @@ -5,13 +5,15 @@ import com.javanauta.ts.taskscheduler.business.mapper.TaskUpdateConverter; import com.javanauta.ts.taskscheduler.infrastructure.entity.Task; import com.javanauta.ts.taskscheduler.infrastructure.enums.NotificationStatusEnum; +import com.javanauta.ts.taskscheduler.infrastructure.exception.InvalidTimeZoneException; import com.javanauta.ts.taskscheduler.infrastructure.exception.ResourceNotFoundException; import com.javanauta.ts.taskscheduler.infrastructure.repository.TaskRepository; import com.javanauta.ts.taskscheduler.infrastructure.security.JwtUtil; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; -import java.time.LocalDateTime; +import java.time.Instant; +import java.time.ZoneId; import java.util.List; @Service @@ -25,16 +27,23 @@ public class TaskService { public TaskDTO saveTask(String token, TaskDTO taskDTO) { taskDTO.setUserEmail(jwtUtil.extractUsername(token.substring(7))); - taskDTO.setCreationDateTime(LocalDateTime.now()); + taskDTO.setCreationDateTime(Instant.now()); taskDTO.setNotificationStatusEnum(NotificationStatusEnum.PENDING); + validateTimeZoneId(taskDTO.getTimeZoneId()); Task task = taskConverter.toTask(taskDTO); return taskConverter.toTaskDTO(taskRepository.save(task)); } - public List findTaskByTimePeriod(LocalDateTime initialDateTime, LocalDateTime finalDateTime) { - return taskConverter.toTaskDTOList(taskRepository.findByDueDateTimeBetween(initialDateTime, finalDateTime)); + private void validateTimeZoneId(String timeZoneId) { + if (!ZoneId.getAvailableZoneIds().contains(timeZoneId)) { + throw new InvalidTimeZoneException("Invalid time zone ID: " + timeZoneId); + } + } + + public List findTaskByTimePeriod(Instant initialDateTime, Instant finalDateTime) { + return taskConverter.toTaskDTOList(taskRepository.findByScheduledDateTimeBetween(initialDateTime, finalDateTime)); } public List findTaskByUserEmail(String token) { @@ -52,6 +61,7 @@ public void deleteTaskById(String id) { public TaskDTO modifyTaskStatusById (NotificationStatusEnum notificationStatusEnum, String id) { Task task = taskRepository.findById(id).orElseThrow(() -> new ResourceNotFoundException(String.format("Task with ID '%s' not found.", id))); task.setNotificationStatusEnum(notificationStatusEnum); + task.setModificationDateTime(Instant.now()); return taskConverter.toTaskDTO(taskRepository.save(task)); } @@ -60,6 +70,9 @@ public TaskDTO updateTaskById (TaskDTO taskDTO, String id) { Task task = taskRepository.findById(id).orElseThrow(() -> new ResourceNotFoundException(String.format("Task with ID '%s' not found.", id))); taskUpdateConverter.updateTasks(taskDTO, task); + validateTimeZoneId(task.getTimeZoneId()); + task.setModificationDateTime(Instant.now()); + return taskConverter.toTaskDTO(taskRepository.save(task)); } } diff --git a/src/main/java/com/javanauta/ts/taskscheduler/business/dto/TaskDTO.java b/src/main/java/com/javanauta/ts/taskscheduler/business/dto/TaskDTO.java index b306202..9504214 100644 --- a/src/main/java/com/javanauta/ts/taskscheduler/business/dto/TaskDTO.java +++ b/src/main/java/com/javanauta/ts/taskscheduler/business/dto/TaskDTO.java @@ -1,10 +1,9 @@ package com.javanauta.ts.taskscheduler.business.dto; -import com.fasterxml.jackson.annotation.JsonFormat; import com.javanauta.ts.taskscheduler.infrastructure.enums.NotificationStatusEnum; import lombok.*; -import java.time.LocalDateTime; +import java.time.Instant; @Getter @Setter @@ -16,12 +15,10 @@ public class TaskDTO { private String id; private String name; private String description; - @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd-MM-yyyy HH:mm:ss") - private LocalDateTime creationDateTime; - @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd-MM-yyyy HH:mm:ss") - private LocalDateTime dueDateTime; + private Instant creationDateTime; + private Instant scheduledDateTime; private String userEmail; - @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd-MM-yyyy HH:mm:ss") - private LocalDateTime modificationDateTime; + private Instant modificationDateTime; private NotificationStatusEnum notificationStatusEnum; + private String timeZoneId; } diff --git a/src/main/java/com/javanauta/ts/taskscheduler/controller/GlobalExceptionHandler.java b/src/main/java/com/javanauta/ts/taskscheduler/controller/GlobalExceptionHandler.java index 4db8fac..9d8693a 100644 --- a/src/main/java/com/javanauta/ts/taskscheduler/controller/GlobalExceptionHandler.java +++ b/src/main/java/com/javanauta/ts/taskscheduler/controller/GlobalExceptionHandler.java @@ -1,5 +1,6 @@ package com.javanauta.ts.taskscheduler.controller; +import com.javanauta.ts.taskscheduler.infrastructure.exception.InvalidTimeZoneException; import com.javanauta.ts.taskscheduler.infrastructure.exception.ResourceNotFoundException; import com.javanauta.ts.taskscheduler.infrastructure.exception.UnauthorizedException; import org.springframework.http.HttpStatus; @@ -19,4 +20,9 @@ public ResponseEntity handlerResourceNotFoundException(ResourceNotFoundE public ResponseEntity handlerUnauthorizedException(UnauthorizedException ex) { return new ResponseEntity<>(ex.getMessage(), HttpStatus.UNAUTHORIZED); } + + @ExceptionHandler(InvalidTimeZoneException.class) + public ResponseEntity handlerInvalidTimeZoneId(InvalidTimeZoneException ex) { + return new ResponseEntity<>(ex.getMessage(), HttpStatus.BAD_REQUEST); + } } diff --git a/src/main/java/com/javanauta/ts/taskscheduler/controller/TaskController.java b/src/main/java/com/javanauta/ts/taskscheduler/controller/TaskController.java index 0032a1f..3eb38a8 100644 --- a/src/main/java/com/javanauta/ts/taskscheduler/controller/TaskController.java +++ b/src/main/java/com/javanauta/ts/taskscheduler/controller/TaskController.java @@ -8,6 +8,7 @@ import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; +import java.time.Instant; import java.time.LocalDateTime; import java.util.List; @@ -24,7 +25,7 @@ public ResponseEntity saveTask(@RequestBody TaskDTO taskDTO, @RequestHe } @GetMapping("/events") - public ResponseEntity> findTaskListByPeriod(@RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime initialDateTime, @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime finalDateTime) { + public ResponseEntity> findTaskListByPeriod(@RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) Instant initialDateTime, @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) Instant finalDateTime) { return ResponseEntity.ok(taskService.findTaskByTimePeriod(initialDateTime, finalDateTime)); } diff --git a/src/main/java/com/javanauta/ts/taskscheduler/infrastructure/entity/Task.java b/src/main/java/com/javanauta/ts/taskscheduler/infrastructure/entity/Task.java index a814029..ef0afeb 100644 --- a/src/main/java/com/javanauta/ts/taskscheduler/infrastructure/entity/Task.java +++ b/src/main/java/com/javanauta/ts/taskscheduler/infrastructure/entity/Task.java @@ -5,6 +5,7 @@ import org.springframework.data.annotation.Id; import org.springframework.data.mongodb.core.mapping.Document; +import java.time.Instant; import java.time.LocalDateTime; @Setter @@ -19,9 +20,10 @@ public class Task { private String id; private String name; private String description; - private LocalDateTime creationDateTime; - private LocalDateTime dueDateTime; + private Instant creationDateTime; + private Instant scheduledDateTime; private String userEmail; - private LocalDateTime modificationDateTime; + private Instant modificationDateTime; private NotificationStatusEnum notificationStatusEnum; + private String timeZoneId; } diff --git a/src/main/java/com/javanauta/ts/taskscheduler/infrastructure/exception/InvalidTimeZoneException.java b/src/main/java/com/javanauta/ts/taskscheduler/infrastructure/exception/InvalidTimeZoneException.java new file mode 100644 index 0000000..067eab1 --- /dev/null +++ b/src/main/java/com/javanauta/ts/taskscheduler/infrastructure/exception/InvalidTimeZoneException.java @@ -0,0 +1,10 @@ +package com.javanauta.ts.taskscheduler.infrastructure.exception; + +public class InvalidTimeZoneException extends RuntimeException { + public InvalidTimeZoneException(String message) { + super(message); + } + public InvalidTimeZoneException(String message, Throwable throwable) { + super(message, throwable); + } +} diff --git a/src/main/java/com/javanauta/ts/taskscheduler/infrastructure/repository/TaskRepository.java b/src/main/java/com/javanauta/ts/taskscheduler/infrastructure/repository/TaskRepository.java index c912480..13ea63b 100644 --- a/src/main/java/com/javanauta/ts/taskscheduler/infrastructure/repository/TaskRepository.java +++ b/src/main/java/com/javanauta/ts/taskscheduler/infrastructure/repository/TaskRepository.java @@ -4,11 +4,11 @@ import org.springframework.data.mongodb.repository.MongoRepository; import org.springframework.stereotype.Repository; -import java.time.LocalDateTime; +import java.time.Instant; import java.util.List; @Repository public interface TaskRepository extends MongoRepository { - List findByDueDateTimeBetween(LocalDateTime initialDateTime, LocalDateTime finalDateTime); + List findByScheduledDateTimeBetween(Instant initialDateTime, Instant finalDateTime); List findByUserEmail(String userEmail); }