From e9487143c640a578c4179abf1a2bb7243354df61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20B=C3=B6ckelmann?= Date: Sat, 11 Nov 2023 20:14:00 +0100 Subject: [PATCH 01/15] Create Datastructures for AdvancedSchedules and create schedules for them --- .../api/controller/ScheduleController.java | 7 ++- .../taskSchedule/ScheduleFieldInfo.java | 4 -- .../AdvancedScheduleFieldInfo.java | 36 ++++++++++++++++ .../scheduleInfos/AdvancedScheduleInfo.java | 35 +++++++++++++++ .../BasicScheduleFieldInfo.java | 2 +- .../BasicScheduleInfo.java | 2 +- .../scheduleInfos/ScheduleFieldInfo.java | 4 ++ .../{ => scheduleInfos}/ScheduleInfo.java | 3 +- .../{ => scheduleInfos}/ScheduleType.java | 2 +- .../timemanager/AbstractSchedule.java | 15 ++++++- .../timemanager/AdvancedTaskSchedule.java | 40 +++++++++++++++-- .../timemanager/BasicTaskSchedule.java | 21 ++------- .../core/services/TaskScheduleService.java | 23 +++++++++- .../core/schedules/ScheduleServiceTest.java | 43 +++++++++++++++++-- .../test/resources/basicScheduleEntries.sql | 8 +++- .../test/resources/taskRepositoryEntries.sql | 4 +- .../taskgroupRepositoryTestEntries.sql | 3 +- 17 files changed, 211 insertions(+), 41 deletions(-) delete mode 100644 backend/src/main/java/core/api/models/timemanager/taskSchedule/ScheduleFieldInfo.java create mode 100644 backend/src/main/java/core/api/models/timemanager/taskSchedule/scheduleInfos/AdvancedScheduleFieldInfo.java create mode 100644 backend/src/main/java/core/api/models/timemanager/taskSchedule/scheduleInfos/AdvancedScheduleInfo.java rename backend/src/main/java/core/api/models/timemanager/taskSchedule/{ => scheduleInfos}/BasicScheduleFieldInfo.java (89%) rename backend/src/main/java/core/api/models/timemanager/taskSchedule/{ => scheduleInfos}/BasicScheduleInfo.java (93%) create mode 100644 backend/src/main/java/core/api/models/timemanager/taskSchedule/scheduleInfos/ScheduleFieldInfo.java rename backend/src/main/java/core/api/models/timemanager/taskSchedule/{ => scheduleInfos}/ScheduleInfo.java (92%) rename backend/src/main/java/core/api/models/timemanager/taskSchedule/{ => scheduleInfos}/ScheduleType.java (52%) diff --git a/backend/src/main/java/core/api/controller/ScheduleController.java b/backend/src/main/java/core/api/controller/ScheduleController.java index d488c6b..face804 100644 --- a/backend/src/main/java/core/api/controller/ScheduleController.java +++ b/backend/src/main/java/core/api/controller/ScheduleController.java @@ -3,12 +3,14 @@ package core.api.controller; import core.api.models.auth.SimpleStatusResponse; import core.api.models.timemanager.taskSchedule.*; +import core.api.models.timemanager.taskSchedule.scheduleInfos.AdvancedScheduleFieldInfo; +import core.api.models.timemanager.taskSchedule.scheduleInfos.BasicScheduleFieldInfo; +import core.api.models.timemanager.taskSchedule.scheduleInfos.ScheduleFieldInfo; import core.entities.timemanager.AbstractSchedule; import core.entities.timemanager.BasicTaskSchedule; import core.entities.timemanager.Task; import core.services.*; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; import org.springframework.http.ResponseEntity; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.web.bind.annotation.*; @@ -63,6 +65,9 @@ public class ScheduleController { if(scheduleFieldInfo instanceof BasicScheduleFieldInfo) { ServiceResult scheduleResult = taskScheduleService.scheduleBasic(permissionResult.getResult(), (BasicScheduleFieldInfo) scheduleFieldInfo); return ResponseEntity.ok(scheduleResult.getResult().toScheduleInfo()); + } else if(scheduleFieldInfo instanceof AdvancedScheduleFieldInfo) { + ServiceResult scheduleResult = taskScheduleService.scheduleAdvanced(permissionResult.getResult(), (AdvancedScheduleFieldInfo) scheduleFieldInfo); + return ResponseEntity.ok(scheduleResult.getResult().toScheduleInfo()); } else { return ResponseEntity.status(400).body(new SimpleStatusResponse("failed")); } diff --git a/backend/src/main/java/core/api/models/timemanager/taskSchedule/ScheduleFieldInfo.java b/backend/src/main/java/core/api/models/timemanager/taskSchedule/ScheduleFieldInfo.java deleted file mode 100644 index d7dba9c..0000000 --- a/backend/src/main/java/core/api/models/timemanager/taskSchedule/ScheduleFieldInfo.java +++ /dev/null @@ -1,4 +0,0 @@ -package core.api.models.timemanager.taskSchedule; - -public abstract class ScheduleFieldInfo { -} diff --git a/backend/src/main/java/core/api/models/timemanager/taskSchedule/scheduleInfos/AdvancedScheduleFieldInfo.java b/backend/src/main/java/core/api/models/timemanager/taskSchedule/scheduleInfos/AdvancedScheduleFieldInfo.java new file mode 100644 index 0000000..6b45422 --- /dev/null +++ b/backend/src/main/java/core/api/models/timemanager/taskSchedule/scheduleInfos/AdvancedScheduleFieldInfo.java @@ -0,0 +1,36 @@ +package core.api.models.timemanager.taskSchedule.scheduleInfos; + +import javax.validation.constraints.NotNull; +import java.time.LocalDateTime; + +public class AdvancedScheduleFieldInfo extends ScheduleFieldInfo { + + @NotNull + private LocalDateTime scheduleStartTime; + @NotNull + private LocalDateTime scheduleStopTime; + + public AdvancedScheduleFieldInfo(LocalDateTime scheduleStartTime, LocalDateTime scheduleStopTime) { + this.scheduleStartTime = scheduleStartTime; + this.scheduleStopTime = scheduleStopTime; + } + + public AdvancedScheduleFieldInfo() { + } + + public LocalDateTime getScheduleStartTime() { + return scheduleStartTime; + } + + public void setScheduleStartTime(LocalDateTime scheduleStartTime) { + this.scheduleStartTime = scheduleStartTime; + } + + public LocalDateTime getScheduleStopTime() { + return scheduleStopTime; + } + + public void setScheduleStopTime(LocalDateTime scheduleStopTime) { + this.scheduleStopTime = scheduleStopTime; + } +} diff --git a/backend/src/main/java/core/api/models/timemanager/taskSchedule/scheduleInfos/AdvancedScheduleInfo.java b/backend/src/main/java/core/api/models/timemanager/taskSchedule/scheduleInfos/AdvancedScheduleInfo.java new file mode 100644 index 0000000..6fd291b --- /dev/null +++ b/backend/src/main/java/core/api/models/timemanager/taskSchedule/scheduleInfos/AdvancedScheduleInfo.java @@ -0,0 +1,35 @@ +package core.api.models.timemanager.taskSchedule.scheduleInfos; + +import core.api.models.timemanager.taskgroup.TaskgroupEntityInfo; +import core.entities.timemanager.Task; + +import java.time.LocalDateTime; +import java.util.List; + +public class AdvancedScheduleInfo extends ScheduleInfo { + + private LocalDateTime plannedStartTime; + private LocalDateTime plannedStopTime; + + public AdvancedScheduleInfo(long scheduleID, ScheduleType scheduleType, LocalDateTime startTime, LocalDateTime stopTime, int activeMinutes, Task task, List taskgroupPath, LocalDateTime plannedStartTime, LocalDateTime plannedStopTime) { + super(scheduleID, scheduleType, startTime, stopTime, activeMinutes, task, taskgroupPath); + this.plannedStartTime = plannedStartTime; + this.plannedStopTime = plannedStopTime; + } + + public LocalDateTime getPlannedStartTime() { + return plannedStartTime; + } + + public void setPlannedStartTime(LocalDateTime plannedStartTime) { + this.plannedStartTime = plannedStartTime; + } + + public LocalDateTime getPlannedStopTime() { + return plannedStopTime; + } + + public void setPlannedStopTime(LocalDateTime plannedStopTime) { + this.plannedStopTime = plannedStopTime; + } +} diff --git a/backend/src/main/java/core/api/models/timemanager/taskSchedule/BasicScheduleFieldInfo.java b/backend/src/main/java/core/api/models/timemanager/taskSchedule/scheduleInfos/BasicScheduleFieldInfo.java similarity index 89% rename from backend/src/main/java/core/api/models/timemanager/taskSchedule/BasicScheduleFieldInfo.java rename to backend/src/main/java/core/api/models/timemanager/taskSchedule/scheduleInfos/BasicScheduleFieldInfo.java index 8f7a90a..5f9c438 100644 --- a/backend/src/main/java/core/api/models/timemanager/taskSchedule/BasicScheduleFieldInfo.java +++ b/backend/src/main/java/core/api/models/timemanager/taskSchedule/scheduleInfos/BasicScheduleFieldInfo.java @@ -1,4 +1,4 @@ -package core.api.models.timemanager.taskSchedule; +package core.api.models.timemanager.taskSchedule.scheduleInfos; import javax.validation.constraints.NotNull; import java.time.LocalDate; diff --git a/backend/src/main/java/core/api/models/timemanager/taskSchedule/BasicScheduleInfo.java b/backend/src/main/java/core/api/models/timemanager/taskSchedule/scheduleInfos/BasicScheduleInfo.java similarity index 93% rename from backend/src/main/java/core/api/models/timemanager/taskSchedule/BasicScheduleInfo.java rename to backend/src/main/java/core/api/models/timemanager/taskSchedule/scheduleInfos/BasicScheduleInfo.java index 5aff7cb..a9d1669 100644 --- a/backend/src/main/java/core/api/models/timemanager/taskSchedule/BasicScheduleInfo.java +++ b/backend/src/main/java/core/api/models/timemanager/taskSchedule/scheduleInfos/BasicScheduleInfo.java @@ -1,4 +1,4 @@ -package core.api.models.timemanager.taskSchedule; +package core.api.models.timemanager.taskSchedule.scheduleInfos; import core.api.models.timemanager.taskgroup.TaskgroupEntityInfo; import core.entities.timemanager.Task; diff --git a/backend/src/main/java/core/api/models/timemanager/taskSchedule/scheduleInfos/ScheduleFieldInfo.java b/backend/src/main/java/core/api/models/timemanager/taskSchedule/scheduleInfos/ScheduleFieldInfo.java new file mode 100644 index 0000000..9c113b8 --- /dev/null +++ b/backend/src/main/java/core/api/models/timemanager/taskSchedule/scheduleInfos/ScheduleFieldInfo.java @@ -0,0 +1,4 @@ +package core.api.models.timemanager.taskSchedule.scheduleInfos; + +public abstract class ScheduleFieldInfo { +} diff --git a/backend/src/main/java/core/api/models/timemanager/taskSchedule/ScheduleInfo.java b/backend/src/main/java/core/api/models/timemanager/taskSchedule/scheduleInfos/ScheduleInfo.java similarity index 92% rename from backend/src/main/java/core/api/models/timemanager/taskSchedule/ScheduleInfo.java rename to backend/src/main/java/core/api/models/timemanager/taskSchedule/scheduleInfos/ScheduleInfo.java index d74fe07..1d2fe62 100644 --- a/backend/src/main/java/core/api/models/timemanager/taskSchedule/ScheduleInfo.java +++ b/backend/src/main/java/core/api/models/timemanager/taskSchedule/scheduleInfos/ScheduleInfo.java @@ -1,10 +1,9 @@ -package core.api.models.timemanager.taskSchedule; +package core.api.models.timemanager.taskSchedule.scheduleInfos; import com.fasterxml.jackson.annotation.JsonProperty; import core.api.models.timemanager.taskgroup.TaskgroupEntityInfo; import core.api.models.timemanager.tasks.TaskShortInfo; import core.entities.timemanager.Task; -import core.entities.timemanager.Taskgroup; import java.time.LocalDateTime; import java.util.List; diff --git a/backend/src/main/java/core/api/models/timemanager/taskSchedule/ScheduleType.java b/backend/src/main/java/core/api/models/timemanager/taskSchedule/scheduleInfos/ScheduleType.java similarity index 52% rename from backend/src/main/java/core/api/models/timemanager/taskSchedule/ScheduleType.java rename to backend/src/main/java/core/api/models/timemanager/taskSchedule/scheduleInfos/ScheduleType.java index f86a82c..e3726ae 100644 --- a/backend/src/main/java/core/api/models/timemanager/taskSchedule/ScheduleType.java +++ b/backend/src/main/java/core/api/models/timemanager/taskSchedule/scheduleInfos/ScheduleType.java @@ -1,4 +1,4 @@ -package core.api.models.timemanager.taskSchedule; +package core.api.models.timemanager.taskSchedule.scheduleInfos; public enum ScheduleType { diff --git a/backend/src/main/java/core/entities/timemanager/AbstractSchedule.java b/backend/src/main/java/core/entities/timemanager/AbstractSchedule.java index a75389b..4a07efb 100644 --- a/backend/src/main/java/core/entities/timemanager/AbstractSchedule.java +++ b/backend/src/main/java/core/entities/timemanager/AbstractSchedule.java @@ -1,10 +1,9 @@ package core.entities.timemanager; -import core.api.models.timemanager.taskSchedule.ScheduleInfo; +import core.api.models.timemanager.taskSchedule.scheduleInfos.ScheduleInfo; import javax.persistence.*; import java.time.Duration; -import java.time.LocalDate; import java.time.LocalDateTime; import java.util.Objects; @@ -109,4 +108,16 @@ public abstract class AbstractSchedule { } public abstract boolean isMissed(LocalDateTime timeReference); + + public int calcActiveMinutes() { + if(startTime == null) { + return 0; + } else if(stopTime == null) { + Duration duration = Duration.between(startTime, LocalDateTime.now()); + return (int) duration.toMinutes(); + } else { + Duration duration = Duration.between(startTime, stopTime); + return (int) duration.toMinutes(); + } + } } diff --git a/backend/src/main/java/core/entities/timemanager/AdvancedTaskSchedule.java b/backend/src/main/java/core/entities/timemanager/AdvancedTaskSchedule.java index 49514b1..a7835ec 100644 --- a/backend/src/main/java/core/entities/timemanager/AdvancedTaskSchedule.java +++ b/backend/src/main/java/core/entities/timemanager/AdvancedTaskSchedule.java @@ -1,10 +1,15 @@ package core.entities.timemanager; -import core.api.models.timemanager.taskSchedule.ScheduleInfo; +import core.api.models.timemanager.taskSchedule.scheduleInfos.AdvancedScheduleInfo; +import core.api.models.timemanager.taskSchedule.scheduleInfos.ScheduleInfo; +import core.api.models.timemanager.taskSchedule.scheduleInfos.ScheduleType; +import core.api.models.timemanager.taskgroup.TaskgroupEntityInfo; import javax.persistence.DiscriminatorValue; import javax.persistence.Entity; import java.time.LocalDateTime; +import java.util.List; + @Entity @DiscriminatorValue("1") public class AdvancedTaskSchedule extends AbstractSchedule { @@ -12,13 +17,42 @@ public class AdvancedTaskSchedule extends AbstractSchedule { private LocalDateTime scheduleStart; private LocalDateTime scheduleEnd; + public AdvancedTaskSchedule(LocalDateTime scheduleStart, LocalDateTime scheduleEnd) { + this.scheduleStart = scheduleStart; + this.scheduleEnd = scheduleEnd; + } + + public AdvancedTaskSchedule(Task task, LocalDateTime startTime, LocalDateTime stopTime, LocalDateTime scheduleStart, LocalDateTime scheduleEnd) { + super(task, startTime, stopTime); + this.scheduleStart = scheduleStart; + this.scheduleEnd = scheduleEnd; + } + + public AdvancedTaskSchedule(Task task, LocalDateTime startTime, LocalDateTime scheduleStart, LocalDateTime scheduleEnd) { + super(task, startTime); + this.scheduleStart = scheduleStart; + this.scheduleEnd = scheduleEnd; + } + + public AdvancedTaskSchedule(Task task, LocalDateTime scheduleStart, LocalDateTime scheduleEnd) { + super(task); + this.scheduleStart = scheduleStart; + this.scheduleEnd = scheduleEnd; + } + + public AdvancedTaskSchedule() { + + } + @Override public ScheduleInfo toScheduleInfo() { - return null; + int activeMinutes = calcActiveMinutes(); + List taskgroupEntityInfos = Taskgroup.getAncestorList(task.getTaskgroup()).stream().map(TaskgroupEntityInfo::new).toList(); + return new AdvancedScheduleInfo(scheduleID, ScheduleType.ADVANCED, startTime, stopTime, activeMinutes, task, taskgroupEntityInfos, scheduleStart, scheduleEnd); } @Override public boolean isMissed(LocalDateTime timeReference) { - return false; + return startTime == null && scheduleEnd.isBefore(timeReference); } } diff --git a/backend/src/main/java/core/entities/timemanager/BasicTaskSchedule.java b/backend/src/main/java/core/entities/timemanager/BasicTaskSchedule.java index 759ee2e..14d8a9c 100644 --- a/backend/src/main/java/core/entities/timemanager/BasicTaskSchedule.java +++ b/backend/src/main/java/core/entities/timemanager/BasicTaskSchedule.java @@ -1,17 +1,14 @@ package core.entities.timemanager; -import core.api.models.timemanager.taskSchedule.BasicScheduleInfo; -import core.api.models.timemanager.taskSchedule.ScheduleInfo; -import core.api.models.timemanager.taskSchedule.ScheduleType; +import core.api.models.timemanager.taskSchedule.scheduleInfos.BasicScheduleInfo; +import core.api.models.timemanager.taskSchedule.scheduleInfos.ScheduleInfo; +import core.api.models.timemanager.taskSchedule.scheduleInfos.ScheduleType; import core.api.models.timemanager.taskgroup.TaskgroupEntityInfo; -import core.api.models.timemanager.tasks.TaskEntityInfo; import javax.persistence.*; -import java.time.Duration; import java.time.LocalDate; import java.time.LocalDateTime; import java.util.List; -import java.util.Objects; @Entity @DiscriminatorValue("0") @@ -55,16 +52,4 @@ public class BasicTaskSchedule extends AbstractSchedule{ public boolean isMissed(LocalDateTime timeReference) { return startTime == null && scheduleDate.isBefore(timeReference.toLocalDate()); } - - public int calcActiveMinutes() { - if(startTime == null) { - return 0; - } else if(stopTime == null) { - Duration duration = Duration.between(startTime, LocalDateTime.now()); - return (int) duration.toMinutes(); - } else { - Duration duration = Duration.between(startTime, stopTime); - return (int) duration.toMinutes(); - } - } } diff --git a/backend/src/main/java/core/services/TaskScheduleService.java b/backend/src/main/java/core/services/TaskScheduleService.java index b5e0941..cdd47d5 100644 --- a/backend/src/main/java/core/services/TaskScheduleService.java +++ b/backend/src/main/java/core/services/TaskScheduleService.java @@ -1,8 +1,11 @@ package core.services; -import core.api.models.timemanager.taskSchedule.BasicScheduleFieldInfo; +import core.api.models.timemanager.taskSchedule.scheduleInfos.AdvancedScheduleFieldInfo; +import core.api.models.timemanager.taskSchedule.scheduleInfos.AdvancedScheduleInfo; +import core.api.models.timemanager.taskSchedule.scheduleInfos.BasicScheduleFieldInfo; import core.api.models.timemanager.taskSchedule.ForgottenScheduleInfo; import core.entities.timemanager.AbstractSchedule; +import core.entities.timemanager.AdvancedTaskSchedule; import core.entities.timemanager.BasicTaskSchedule; import core.entities.timemanager.Task; import core.repositories.UserRepository; @@ -41,6 +44,24 @@ public class TaskScheduleService { return new ServiceResult<>(basicTaskSchedule); } + public ServiceResult scheduleAdvanced(Task task, AdvancedScheduleFieldInfo scheduleFieldInfo) { + LocalDate startDate = scheduleFieldInfo.getScheduleStartTime().toLocalDate(); + LocalDate endDate = scheduleFieldInfo.getScheduleStopTime().toLocalDate(); + + if(task.isFinished() || startDate.isBefore(LocalDate.now()) || endDate.isBefore(LocalDate.now())) { + return new ServiceResult<>(ServiceExitCode.INVALID_OPERATION); + } + + if(scheduleFieldInfo.getScheduleStartTime().isAfter(scheduleFieldInfo.getScheduleStopTime())) { + return new ServiceResult<>(ServiceExitCode.INVALID_PARAMETER); + } + + AdvancedTaskSchedule advancedTaskSchedule = new AdvancedTaskSchedule(task, scheduleFieldInfo.getScheduleStartTime(), scheduleFieldInfo.getScheduleStopTime()); + scheduleRepository.save(advancedTaskSchedule); + + return new ServiceResult<>(advancedTaskSchedule); + } + public PermissionResult getSchedulePermissions(long scheduleID, String username) { Optional abstractSchedule = scheduleRepository.findById(scheduleID); return abstractSchedule.map(schedule -> new PermissionResult<>(schedule, schedule.getTask().getTaskgroup().getUser().getUsername().equals(username))).orElseGet(() -> new PermissionResult<>(ServiceExitCode.MISSING_ENTITY)); diff --git a/backend/src/test/java/core/schedules/ScheduleServiceTest.java b/backend/src/test/java/core/schedules/ScheduleServiceTest.java index 1dc8810..0ef9dd5 100644 --- a/backend/src/test/java/core/schedules/ScheduleServiceTest.java +++ b/backend/src/test/java/core/schedules/ScheduleServiceTest.java @@ -1,16 +1,15 @@ package core.schedules; -import core.api.models.timemanager.taskSchedule.BasicScheduleFieldInfo; -import core.api.models.timemanager.taskSchedule.BasicScheduleInfo; +import core.api.models.timemanager.taskSchedule.scheduleInfos.AdvancedScheduleFieldInfo; +import core.api.models.timemanager.taskSchedule.scheduleInfos.BasicScheduleFieldInfo; import core.api.models.timemanager.taskSchedule.ForgottenScheduleInfo; import core.entities.timemanager.AbstractSchedule; +import core.entities.timemanager.AdvancedTaskSchedule; import core.entities.timemanager.BasicTaskSchedule; import core.entities.timemanager.Task; -import core.repositories.timemanager.TaskgroupRepository; import core.services.ServiceExitCode; import core.services.ServiceResult; import core.services.TaskScheduleService; -import core.services.TaskgroupService; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; @@ -234,4 +233,40 @@ public class ScheduleServiceTest { void getAllMissedSchedulesOfUser() { assertEquals(1, taskScheduleService.getAllMissedSchedulesOfUser(username).size()); } + + @Test + @SqlGroup({ + @Sql("classpath:taskgroupRepositoryTestEntries.sql"), + @Sql("classpath:taskRepositoryEntries.sql"), + @Sql("classpath:basicScheduleEntries.sql") + }) + void scheduleAdvanced() { + //Situation 1: Schedule finished Task + ServiceResult result_1 = taskScheduleService.scheduleAdvanced(entityManager.find(Task.class, 18L), + new AdvancedScheduleFieldInfo(LocalDateTime.now().plusHours(1L), LocalDateTime.now().plusHours(2L))); + assertEquals(ServiceExitCode.INVALID_OPERATION, result_1.getExitCode()); + + //Situation 2: Schedule Start is before today + ServiceResult result_2 = taskScheduleService.scheduleAdvanced(entityManager.find(Task.class, 17L), + new AdvancedScheduleFieldInfo(LocalDateTime.now().minusDays(1L), LocalDateTime.now().plusHours(2L))); + assertEquals(ServiceExitCode.INVALID_OPERATION, result_2.getExitCode()); + + //Situation 3: Schedule End is before today + ServiceResult result_3 = taskScheduleService.scheduleAdvanced(entityManager.find(Task.class, 17L), + new AdvancedScheduleFieldInfo(LocalDateTime.now().minusDays(2L), LocalDateTime.now().minusDays(1L))); + assertEquals(ServiceExitCode.INVALID_OPERATION, result_3.getExitCode()); + + //Situation 4: Start after stop + ServiceResult result_4 = taskScheduleService.scheduleAdvanced(entityManager.find(Task.class, 17L), + new AdvancedScheduleFieldInfo(LocalDateTime.now().plusHours(2L), LocalDateTime.now().plusHours(1L))); + assertEquals(ServiceExitCode.INVALID_PARAMETER, result_4.getExitCode()); + + //Situation 5: Valid schedule + ServiceResult result_5 = taskScheduleService.scheduleAdvanced(entityManager.find(Task.class, 17L), + new AdvancedScheduleFieldInfo(LocalDateTime.now(), LocalDateTime.now().plusHours(1L))); + assertEquals(ServiceExitCode.OK, result_5.getExitCode()); + assertThat(entityManager.find(AdvancedTaskSchedule.class, result_5.getResult().getScheduleID())).isNotNull(); + + + } } diff --git a/backend/src/test/resources/basicScheduleEntries.sql b/backend/src/test/resources/basicScheduleEntries.sql index 39b3b60..30fe135 100644 --- a/backend/src/test/resources/basicScheduleEntries.sql +++ b/backend/src/test/resources/basicScheduleEntries.sql @@ -5,4 +5,10 @@ VALUES (0, 1, null, null, '2010-11-11', 1, null, null), (0, 4, '2023-10-10', null, '2024-11-11', 3, null, null), (0, 5, null, null, '2024-11-11', 5, null, null), (0, 6, '2023-10-10', null, '2024-11-11', 16, null, null), - (0, 7, '2023-10-10', null, '2024-11-11', 16, null, null); \ No newline at end of file + (0, 7, '2023-10-10', null, '2024-11-11', 16, null, null); + +INSERT INTO abstract_schedule (schedule_type, scheduleid, start_time, stop_time, schedule_date, task, schedule_end, schedule_start) +VALUES (1, 8, null, null, null, 16, '2023-11-15 12:30:00.000', '2023-11-15 14:45:30.500'), + (1, 9, '2023-11-16 12:35:00.000', null, null, 17, '2023-11-16 12:30:00.000', '2023-11-16 14:45:30.500'), + (1, 10, '2023-11-17 12:35:00.000', '2023-11-17 12:45:00.000', null, 17, '2023-11-16 12:30:00.000', '2023-11-16 14:45:30.500'), + (1, 11, null, null, null, 17, '2010-11-16 12:30:00.000', '2010-11-16 14:45:30.500'); \ No newline at end of file diff --git a/backend/src/test/resources/taskRepositoryEntries.sql b/backend/src/test/resources/taskRepositoryEntries.sql index fb3e127..7a3bd21 100644 --- a/backend/src/test/resources/taskRepositoryEntries.sql +++ b/backend/src/test/resources/taskRepositoryEntries.sql @@ -18,4 +18,6 @@ INSERT INTO tasks (taskid, deadline, eta, start_date, task_name, taskgroup_id, f INSERT INTO tasks (taskid, deadline, eta, start_date, task_name, taskgroup_id, finished, work_time) VALUES (14, '2044-03-20', 0, '2022-03-20', 'Task 6', 2, true, 0); INSERT INTO tasks (taskid, deadline, eta, start_date, task_name, taskgroup_id, finished, work_time) VALUES (15, NULL, 0, NULL, 'Task 15', 2, false, 0); -INSERT INTO tasks (taskid, deadline, eta, start_date, task_name, taskgroup_id, finished, work_time) VALUES (16, NULL, 0, NULL, 'Task 15', 9, false, 0); \ No newline at end of file +INSERT INTO tasks (taskid, deadline, eta, start_date, task_name, taskgroup_id, finished, work_time) VALUES (16, NULL, 0, NULL, 'Task 15', 9, false, 0); +INSERT INTO tasks (taskid, deadline, eta, start_date, task_name, taskgroup_id, finished, work_time) VALUES (17, NULL, 0, NULL, 'Task 17', 9, false, 0); +INSERT INTO tasks (taskid, deadline, eta, start_date, task_name, taskgroup_id, finished, work_time) VALUES (18, NULL, 0, NULL, 'Task 17', 10, true, 0); \ No newline at end of file diff --git a/backend/src/test/resources/taskgroupRepositoryTestEntries.sql b/backend/src/test/resources/taskgroupRepositoryTestEntries.sql index 7a31b37..e9c5ef8 100644 --- a/backend/src/test/resources/taskgroupRepositoryTestEntries.sql +++ b/backend/src/test/resources/taskgroupRepositoryTestEntries.sql @@ -12,4 +12,5 @@ INSERT INTO taskgroups (taskgroupid, name, parent_id, taskgroupuser) VALUES (6, INSERT INTO taskgroups (taskgroupid, name, parent_id, taskgroupuser) VALUES (7, 'Taskgroup 2.2', 5, 1); INSERT INTO taskgroups (taskgroupid, name, parent_id, taskgroupuser) VALUES (8, 'Taskgroup 2.1.2', 6, 1); -INSERT INTO taskgroups (taskgroupid, name, parent_id, taskgroupuser) VALUES (9, 'Taskgroup 1', null, 3); \ No newline at end of file +INSERT INTO taskgroups (taskgroupid, name, parent_id, taskgroupuser) VALUES (9, 'Taskgroup 1', null, 3); +INSERT INTO taskgroups (taskgroupid, name, parent_id, taskgroupuser) VALUES (10, 'Taskgroup 2', null, 3); \ No newline at end of file -- 2.34.1 From 64ab22b7b0075d0ad9ce05e725251298e48e21a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20B=C3=B6ckelmann?= Date: Sat, 11 Nov 2023 20:24:03 +0100 Subject: [PATCH 02/15] Reschedule Advanced Schedules --- .../api/controller/ScheduleController.java | 9 ++++ .../core/services/TaskScheduleService.java | 20 ++++++++- .../core/schedules/ScheduleServiceTest.java | 45 +++++++++++++++++++ .../test/resources/basicScheduleEntries.sql | 3 +- 4 files changed, 75 insertions(+), 2 deletions(-) diff --git a/backend/src/main/java/core/api/controller/ScheduleController.java b/backend/src/main/java/core/api/controller/ScheduleController.java index face804..ce6a0a2 100644 --- a/backend/src/main/java/core/api/controller/ScheduleController.java +++ b/backend/src/main/java/core/api/controller/ScheduleController.java @@ -4,9 +4,11 @@ package core.api.controller; import core.api.models.auth.SimpleStatusResponse; import core.api.models.timemanager.taskSchedule.*; import core.api.models.timemanager.taskSchedule.scheduleInfos.AdvancedScheduleFieldInfo; +import core.api.models.timemanager.taskSchedule.scheduleInfos.AdvancedScheduleInfo; import core.api.models.timemanager.taskSchedule.scheduleInfos.BasicScheduleFieldInfo; import core.api.models.timemanager.taskSchedule.scheduleInfos.ScheduleFieldInfo; import core.entities.timemanager.AbstractSchedule; +import core.entities.timemanager.AdvancedTaskSchedule; import core.entities.timemanager.BasicTaskSchedule; import core.entities.timemanager.Task; import core.services.*; @@ -91,6 +93,13 @@ public class ScheduleController { } else { return ResponseEntity.ok(updatedSchedule.getResult().toScheduleInfo()); } + } else if(permissionResult.getResult() instanceof AdvancedTaskSchedule && scheduleFieldInfo instanceof AdvancedScheduleFieldInfo) { + ServiceResult updatedSchedule = taskScheduleService.editAdvancedSchedule((AdvancedTaskSchedule) permissionResult.getResult(), (AdvancedScheduleFieldInfo) scheduleFieldInfo); + if(updatedSchedule.getExitCode() == ServiceExitCode.INVALID_OPERATION) { + return ResponseEntity.status(400).body(new SimpleStatusResponse("failed")); + } else { + return ResponseEntity.ok(updatedSchedule.getResult().toScheduleInfo()); + } } return ResponseEntity.status(400).body(new SimpleStatusResponse("failed")); diff --git a/backend/src/main/java/core/services/TaskScheduleService.java b/backend/src/main/java/core/services/TaskScheduleService.java index cdd47d5..2473743 100644 --- a/backend/src/main/java/core/services/TaskScheduleService.java +++ b/backend/src/main/java/core/services/TaskScheduleService.java @@ -68,7 +68,7 @@ public class TaskScheduleService { } public ServiceResult editBasicSchedule(BasicTaskSchedule schedule, BasicScheduleFieldInfo scheduleFieldInfo) { - if(schedule.getTask().isFinished() || scheduleFieldInfo.getScheduleDate().isBefore(LocalDate.now())) { + if(schedule.getTask().isFinished() || scheduleFieldInfo.getScheduleDate().isBefore(LocalDate.now()) || schedule.isActive()) { return new ServiceResult<>(ServiceExitCode.INVALID_OPERATION); } @@ -77,6 +77,24 @@ public class TaskScheduleService { return new ServiceResult<>(schedule); } + public ServiceResult editAdvancedSchedule(AdvancedTaskSchedule schedule, AdvancedScheduleFieldInfo scheduleFieldInfo) { + LocalDate startDate = scheduleFieldInfo.getScheduleStartTime().toLocalDate(); + LocalDate endDate = scheduleFieldInfo.getScheduleStopTime().toLocalDate(); + + if(schedule.getTask().isFinished() || startDate.isBefore(LocalDate.now()) || endDate.isBefore(LocalDate.now()) || schedule.isActive()) { + return new ServiceResult<>(ServiceExitCode.INVALID_OPERATION); + } + + if(scheduleFieldInfo.getScheduleStartTime().isAfter(scheduleFieldInfo.getScheduleStopTime())) { + return new ServiceResult<>(ServiceExitCode.INVALID_PARAMETER); + } + + schedule.setStartTime(scheduleFieldInfo.getScheduleStartTime()); + schedule.setStopTime(scheduleFieldInfo.getScheduleStopTime()); + scheduleRepository.save(schedule); + return new ServiceResult<>(schedule); + } + public void deleteSchedule(AbstractSchedule schedule) { scheduleRepository.delete(schedule); } diff --git a/backend/src/test/java/core/schedules/ScheduleServiceTest.java b/backend/src/test/java/core/schedules/ScheduleServiceTest.java index 0ef9dd5..c80452a 100644 --- a/backend/src/test/java/core/schedules/ScheduleServiceTest.java +++ b/backend/src/test/java/core/schedules/ScheduleServiceTest.java @@ -1,6 +1,7 @@ package core.schedules; import core.api.models.timemanager.taskSchedule.scheduleInfos.AdvancedScheduleFieldInfo; +import core.api.models.timemanager.taskSchedule.scheduleInfos.AdvancedScheduleInfo; import core.api.models.timemanager.taskSchedule.scheduleInfos.BasicScheduleFieldInfo; import core.api.models.timemanager.taskSchedule.ForgottenScheduleInfo; import core.entities.timemanager.AbstractSchedule; @@ -96,6 +97,11 @@ public class ScheduleServiceTest { ServiceResult result_3 = taskScheduleService.editBasicSchedule(entityManager.find(BasicTaskSchedule.class, 1L), new BasicScheduleFieldInfo(LocalDate.now())); assertEquals(ServiceExitCode.OK, result_3.getExitCode()); assertNotEquals(((BasicTaskSchedule) result_3.getResult()).getScheduleDate(), oldDate); + + //Situation 4: Reschedule already running schedule + ServiceResult result_4 = taskScheduleService.editBasicSchedule(entityManager.find(BasicTaskSchedule.class, 4L), + new BasicScheduleFieldInfo(LocalDate.now())); + assertEquals(ServiceExitCode.INVALID_OPERATION, result_4.getExitCode()); } @Test @@ -269,4 +275,43 @@ public class ScheduleServiceTest { } + + @Test + @SqlGroup({ + @Sql("classpath:taskgroupRepositoryTestEntries.sql"), + @Sql("classpath:taskRepositoryEntries.sql"), + @Sql("classpath:basicScheduleEntries.sql") + }) + void editscheduleAdvanced() { + //Situation 1: Schedule finished Task + ServiceResult result_1 = taskScheduleService.editAdvancedSchedule(entityManager.find(AdvancedTaskSchedule.class, 12L), + new AdvancedScheduleFieldInfo(LocalDateTime.now().plusHours(1L), LocalDateTime.now().plusHours(2L))); + assertEquals(ServiceExitCode.INVALID_OPERATION, result_1.getExitCode()); + + //Situation 2: Schedule Start is before today + ServiceResult result_2 = taskScheduleService.editAdvancedSchedule(entityManager.find(AdvancedTaskSchedule.class, 11L), + new AdvancedScheduleFieldInfo(LocalDateTime.now().minusDays(1L), LocalDateTime.now().plusHours(2L))); + assertEquals(ServiceExitCode.INVALID_OPERATION, result_2.getExitCode()); + + //Situation 3: Schedule End is before today + ServiceResult result_3 = taskScheduleService.editAdvancedSchedule(entityManager.find(AdvancedTaskSchedule.class, 11L), + new AdvancedScheduleFieldInfo(LocalDateTime.now().minusDays(2L), LocalDateTime.now().minusDays(1L))); + assertEquals(ServiceExitCode.INVALID_OPERATION, result_3.getExitCode()); + + //Situation 4: Start after stop + ServiceResult result_4 = taskScheduleService.editAdvancedSchedule(entityManager.find(AdvancedTaskSchedule.class, 11L), + new AdvancedScheduleFieldInfo(LocalDateTime.now().plusHours(2L), LocalDateTime.now().plusHours(1L))); + assertEquals(ServiceExitCode.INVALID_PARAMETER, result_4.getExitCode()); + + //Situation 5: Valid schedule + ServiceResult result_5 = taskScheduleService.editAdvancedSchedule(entityManager.find(AdvancedTaskSchedule.class, 11L), + new AdvancedScheduleFieldInfo(LocalDateTime.now(), LocalDateTime.now().plusHours(1L))); + assertEquals(ServiceExitCode.OK, result_5.getExitCode()); + assertThat(entityManager.find(AdvancedTaskSchedule.class, result_5.getResult().getScheduleID())).isNotNull(); + + //Situation 6: reschedule already running schedule + ServiceResult result_6 = taskScheduleService.editAdvancedSchedule(entityManager.find(AdvancedTaskSchedule.class, 9L), + new AdvancedScheduleFieldInfo(LocalDateTime.now(), LocalDateTime.now().plusHours(1L))); + assertEquals(ServiceExitCode.INVALID_OPERATION, result_6.getExitCode()); + } } diff --git a/backend/src/test/resources/basicScheduleEntries.sql b/backend/src/test/resources/basicScheduleEntries.sql index 30fe135..3e1c9dd 100644 --- a/backend/src/test/resources/basicScheduleEntries.sql +++ b/backend/src/test/resources/basicScheduleEntries.sql @@ -11,4 +11,5 @@ INSERT INTO abstract_schedule (schedule_type, scheduleid, start_time, stop_time, VALUES (1, 8, null, null, null, 16, '2023-11-15 12:30:00.000', '2023-11-15 14:45:30.500'), (1, 9, '2023-11-16 12:35:00.000', null, null, 17, '2023-11-16 12:30:00.000', '2023-11-16 14:45:30.500'), (1, 10, '2023-11-17 12:35:00.000', '2023-11-17 12:45:00.000', null, 17, '2023-11-16 12:30:00.000', '2023-11-16 14:45:30.500'), - (1, 11, null, null, null, 17, '2010-11-16 12:30:00.000', '2010-11-16 14:45:30.500'); \ No newline at end of file + (1, 11, null, null, null, 17, '2010-11-16 12:30:00.000', '2010-11-16 14:45:30.500'), + (1, 12, null, null, null, 18, '2010-11-16 12:30:00.000', '2010-11-16 14:45:30.500'); \ No newline at end of file -- 2.34.1 From 234eacca0c0a52dc49be80d994269d9ae1f08255 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20B=C3=B6ckelmann?= Date: Sat, 11 Nov 2023 20:26:03 +0100 Subject: [PATCH 03/15] ScheduleNow test with running advanced Schedule --- backend/src/test/java/core/schedules/ScheduleServiceTest.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/backend/src/test/java/core/schedules/ScheduleServiceTest.java b/backend/src/test/java/core/schedules/ScheduleServiceTest.java index c80452a..737de26 100644 --- a/backend/src/test/java/core/schedules/ScheduleServiceTest.java +++ b/backend/src/test/java/core/schedules/ScheduleServiceTest.java @@ -161,6 +161,10 @@ public class ScheduleServiceTest { ServiceResult result_3 = taskScheduleService.scheduleNow(entityManager.find(Task.class, 5L)); assertEquals(ServiceExitCode.OK, result_3.getExitCode()); assertThat(entityManager.find(BasicTaskSchedule.class, result_3.getResult().getScheduleID())).isNotNull(); + + //Situation 4: Running Advanced Schedule + ServiceResult result_4 = taskScheduleService.scheduleNow(entityManager.find(Task.class, 17L)); + assertEquals(ServiceExitCode.ENTITY_ALREADY_EXIST, result_4.getExitCode()); } @Test -- 2.34.1 From 821c703e29af05c1d353f6102f05cd59227a475f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20B=C3=B6ckelmann?= Date: Sat, 11 Nov 2023 20:54:06 +0100 Subject: [PATCH 04/15] Create Advanced Scheduler and adapt Scheduler --- backend/.idea/workspace.xml | 112 +++++++++--------- frontend/src/api/.openapi-generator/FILES | 3 + frontend/src/api/api/schedule.service.ts | 25 ++-- .../api/model/advancedScheduleFieldInfo.ts | 18 +++ .../src/api/model/advancedScheduleInfo.ts | 53 +++++++++ .../api/model/advancedScheduleInfoAllOf.ts | 18 +++ frontend/src/api/model/models.ts | 3 + frontend/src/app/app.module.ts | 4 +- .../advanced-scheduler.component.css | 0 .../advanced-scheduler.component.html | 17 +++ .../advanced-scheduler.component.spec.ts | 21 ++++ .../advanced-scheduler.component.ts | 26 ++++ .../scheduler/scheduler.component.html | 2 +- .../scheduler/scheduler.component.ts | 8 +- openapi.yaml | 37 +++++- 15 files changed, 273 insertions(+), 74 deletions(-) create mode 100644 frontend/src/api/model/advancedScheduleFieldInfo.ts create mode 100644 frontend/src/api/model/advancedScheduleInfo.ts create mode 100644 frontend/src/api/model/advancedScheduleInfoAllOf.ts create mode 100644 frontend/src/app/schedules/advanced-scheduler/advanced-scheduler.component.css create mode 100644 frontend/src/app/schedules/advanced-scheduler/advanced-scheduler.component.html create mode 100644 frontend/src/app/schedules/advanced-scheduler/advanced-scheduler.component.spec.ts create mode 100644 frontend/src/app/schedules/advanced-scheduler/advanced-scheduler.component.ts diff --git a/backend/.idea/workspace.xml b/backend/.idea/workspace.xml index ebfaa2e..dce221f 100644 --- a/backend/.idea/workspace.xml +++ b/backend/.idea/workspace.xml @@ -4,13 +4,11 @@