Create Datastructures for AdvancedSchedules and create schedules for them
All checks were successful
Java CI with Maven / build (push) Successful in 1m10s

This commit is contained in:
Sebastian Böckelmann 2023-11-11 20:14:00 +01:00
parent 0e07549a65
commit e9487143c6
17 changed files with 211 additions and 41 deletions

View File

@ -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<AbstractSchedule> scheduleResult = taskScheduleService.scheduleBasic(permissionResult.getResult(), (BasicScheduleFieldInfo) scheduleFieldInfo);
return ResponseEntity.ok(scheduleResult.getResult().toScheduleInfo());
} else if(scheduleFieldInfo instanceof AdvancedScheduleFieldInfo) {
ServiceResult<AbstractSchedule> scheduleResult = taskScheduleService.scheduleAdvanced(permissionResult.getResult(), (AdvancedScheduleFieldInfo) scheduleFieldInfo);
return ResponseEntity.ok(scheduleResult.getResult().toScheduleInfo());
} else {
return ResponseEntity.status(400).body(new SimpleStatusResponse("failed"));
}

View File

@ -1,4 +0,0 @@
package core.api.models.timemanager.taskSchedule;
public abstract class ScheduleFieldInfo {
}

View File

@ -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;
}
}

View File

@ -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<TaskgroupEntityInfo> 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;
}
}

View File

@ -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;

View File

@ -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;

View File

@ -0,0 +1,4 @@
package core.api.models.timemanager.taskSchedule.scheduleInfos;
public abstract class ScheduleFieldInfo {
}

View File

@ -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;

View File

@ -1,4 +1,4 @@
package core.api.models.timemanager.taskSchedule;
package core.api.models.timemanager.taskSchedule.scheduleInfos;
public enum ScheduleType {

View File

@ -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();
}
}
}

View File

@ -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<TaskgroupEntityInfo> 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);
}
}

View File

@ -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();
}
}
}

View File

@ -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<AbstractSchedule> 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<AbstractSchedule> getSchedulePermissions(long scheduleID, String username) {
Optional<AbstractSchedule> abstractSchedule = scheduleRepository.findById(scheduleID);
return abstractSchedule.map(schedule -> new PermissionResult<>(schedule, schedule.getTask().getTaskgroup().getUser().getUsername().equals(username))).orElseGet(() -> new PermissionResult<>(ServiceExitCode.MISSING_ENTITY));

View File

@ -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<AbstractSchedule> 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<AbstractSchedule> 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<AbstractSchedule> 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<AbstractSchedule> 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<AbstractSchedule> 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();
}
}

View File

@ -6,3 +6,9 @@ VALUES (0, 1, null, null, '2010-11-11', 1, 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);
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');

View File

@ -19,3 +19,5 @@ 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 (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);
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);

View File

@ -13,3 +13,4 @@ INSERT INTO taskgroups (taskgroupid, name, parent_id, taskgroupuser) VALUES (7,
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);
INSERT INTO taskgroups (taskgroupid, name, parent_id, taskgroupuser) VALUES (10, 'Taskgroup 2', null, 3);