diff --git a/backend/src/main/java/core/api/controller/ScheduleController.java b/backend/src/main/java/core/api/controller/ScheduleController.java index 5242b9d..d07a91c 100644 --- a/backend/src/main/java/core/api/controller/ScheduleController.java +++ b/backend/src/main/java/core/api/controller/ScheduleController.java @@ -41,7 +41,7 @@ public class ScheduleController { @GetMapping("/schedules/{taskID}") public ResponseEntity loadAllSchedulesOfTask(@PathVariable long taskID) { PermissionResult permissionResult = taskService.getTaskPermissions(taskID, SecurityContextHolder.getContext().getAuthentication().getName()); - if(!permissionResult.isHasPermissions()) { + if(permissionResult.isNoPermissions()) { return ResponseEntity.status(403).body(new SimpleStatusResponse("failed")); } @@ -72,7 +72,7 @@ public class ScheduleController { private ResponseEntity createAbstractSchedule(long taskID, ScheduleFieldInfo scheduleFieldInfo) { PermissionResult permissionResult = taskService.getTaskPermissions(taskID, SecurityContextHolder.getContext().getAuthentication().getName()); - if(!permissionResult.isHasPermissions()) { + if(permissionResult.isNoPermissions()) { return ResponseEntity.status(403).body(new SimpleStatusResponse("failed")); } @@ -111,7 +111,7 @@ public class ScheduleController { private ResponseEntity editAbstractSchedule(long scheduleID, ScheduleFieldInfo scheduleFieldInfo) { PermissionResult permissionResult = taskScheduleService.getSchedulePermissions(scheduleID, SecurityContextHolder.getContext().getAuthentication().getName()); - if(!permissionResult.isHasPermissions()) { + if(permissionResult.isNoPermissions()) { return ResponseEntity.status(403).body(new SimpleStatusResponse("failed")); } @@ -141,7 +141,7 @@ public class ScheduleController { @DeleteMapping("/schedules/{scheduleID}") public ResponseEntity deleteSchedule(@PathVariable long scheduleID) { PermissionResult permissionResult = taskScheduleService.getSchedulePermissions(scheduleID, SecurityContextHolder.getContext().getAuthentication().getName()); - if(!permissionResult.isHasPermissions()) { + if(permissionResult.isNoPermissions()) { return ResponseEntity.status(403).body(new SimpleStatusResponse("failed")); } @@ -163,7 +163,7 @@ public class ScheduleController { @PostMapping("/schedules/{taskID}/now") public ResponseEntity scheduleNow(@PathVariable long taskID) { PermissionResult permissionResult = taskService.getTaskPermissions(taskID, SecurityContextHolder.getContext().getAuthentication().getName()); - if(!permissionResult.isHasPermissions()) { + if(permissionResult.isNoPermissions()) { return ResponseEntity.status(403).body(new SimpleStatusResponse("failed")); } @@ -193,7 +193,7 @@ public class ScheduleController { @PostMapping("/schedules/{scheduleID}/activate") public ResponseEntity activateSchedule(@PathVariable long scheduleID) { PermissionResult permissionResult = taskScheduleService.getSchedulePermissions(scheduleID, SecurityContextHolder.getContext().getAuthentication().getName()); - if(!permissionResult.isHasPermissions()) { + if(permissionResult.isNoPermissions()) { return ResponseEntity.status(403).body(new SimpleStatusResponse("failed")); } @@ -217,7 +217,7 @@ public class ScheduleController { @PostMapping("/schedules/{scheduleID}/stop/{finish}") public ResponseEntity stopSchedule(@PathVariable long scheduleID, @PathVariable boolean finish) { PermissionResult permissionResult = taskScheduleService.getSchedulePermissions(scheduleID, SecurityContextHolder.getContext().getAuthentication().getName()); - if(!permissionResult.isHasPermissions()) { + if(permissionResult.isNoPermissions()) { return ResponseEntity.status(403).body(new SimpleStatusResponse("failed")); } @@ -232,7 +232,7 @@ public class ScheduleController { @PostMapping("/schedules/{taskID}/forgotten") public ResponseEntity registerForgottenSchedule(@PathVariable long taskID, @RequestBody @Valid ForgottenScheduleInfo forgottenScheduleInfo) { PermissionResult permissionResult = taskService.getTaskPermissions(taskID, SecurityContextHolder.getContext().getAuthentication().getName()); - if(!permissionResult.isHasPermissions()) { + if(permissionResult.isNoPermissions()) { return ResponseEntity.status(403).body(new SimpleStatusResponse("failed")); } @@ -259,7 +259,7 @@ public class ScheduleController { List> permissionResults = new ArrayList<>(); for(long scheduleID: scheduleIDs) { PermissionResult permissionResult = taskScheduleService.getSchedulePermissions(scheduleID, SecurityContextHolder.getContext().getAuthentication().getName()); - if(!permissionResult.isHasPermissions()) { + if(permissionResult.isNoPermissions()) { return ResponseEntity.status(403).body(new SimpleStatusResponse("failed")); } @@ -278,7 +278,7 @@ public class ScheduleController { @GetMapping("/schedules/{scheduleID}/details") public ResponseEntity loadScheduleDetails(@PathVariable long scheduleID) { PermissionResult permissionResult = taskScheduleService.getSchedulePermissions(scheduleID, SecurityContextHolder.getContext().getAuthentication().getName()); - if(!permissionResult.isHasPermissions()) { + if(permissionResult.isNoPermissions()) { return ResponseEntity.status(403).body(new SimpleStatusResponse("failed")); } @@ -292,7 +292,7 @@ public class ScheduleController { @PostMapping("/schedules/{scheduleID}/stopManual") public ResponseEntity stopManual(@PathVariable long scheduleID, @Valid @RequestBody ManualScheduleStopInfo manualScheduleStopInfo) { PermissionResult permissionResult = taskScheduleService.getSchedulePermissions(scheduleID, SecurityContextHolder.getContext().getAuthentication().getName()); - if(!permissionResult.isHasPermissions()) { + if(permissionResult.isNoPermissions()) { return ResponseEntity.status(403).body(new SimpleStatusResponse("failed")); } diff --git a/backend/src/main/java/core/api/controller/StatisticController.java b/backend/src/main/java/core/api/controller/StatisticController.java index af632be..36e2e0e 100644 --- a/backend/src/main/java/core/api/controller/StatisticController.java +++ b/backend/src/main/java/core/api/controller/StatisticController.java @@ -3,9 +3,7 @@ package core.api.controller; import core.api.models.auth.SimpleStatusResponse; import core.api.models.timemanager.history.TaskgroupActivityInfo; import core.api.models.timemanager.history.WorkingStatus; -import core.api.models.timemanager.taskgroup.TaskgroupEntityInfo; import core.entities.timemanager.AbstractSchedule; -import core.entities.timemanager.Task; import core.entities.timemanager.Taskgroup; import core.services.PermissionResult; import core.services.ServiceExitCode; @@ -14,12 +12,10 @@ import core.services.TaskgroupService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.security.core.parameters.P; import org.springframework.web.bind.annotation.*; import java.time.*; import java.time.format.DateTimeFormatter; -import java.time.temporal.TemporalAdjusters; import java.util.*; @CrossOrigin(origins = "*", maxAge = 3600) @@ -49,7 +45,7 @@ public class StatisticController { @GetMapping("/statistics/taskgroup-activity/{taskgroupID}/{startingDate}/{endingDate}/{includeSubTaskgroups}") public ResponseEntity getTaskgroupActivity(@PathVariable long taskgroupID, @PathVariable String startingDate, @PathVariable String endingDate, @PathVariable boolean includeSubTaskgroups){ PermissionResult taskgroupPermissionResult = taskgroupService.getTaskgroupByIDAndUsername(taskgroupID, SecurityContextHolder.getContext().getAuthentication().getName()); - if(!taskgroupPermissionResult.isHasPermissions()) { + if(taskgroupPermissionResult.isNoPermissions()) { return ResponseEntity.status(403).body(new SimpleStatusResponse("failed")); } else if(taskgroupPermissionResult.getExitCode() == ServiceExitCode.MISSING_ENTITY) { return ResponseEntity.status(404).body(new SimpleStatusResponse("failed")); diff --git a/backend/src/main/java/core/api/controller/TaskController.java b/backend/src/main/java/core/api/controller/TaskController.java index 0d814f0..823e1aa 100644 --- a/backend/src/main/java/core/api/controller/TaskController.java +++ b/backend/src/main/java/core/api/controller/TaskController.java @@ -64,7 +64,7 @@ public class TaskController { @GetMapping("/tasks/{taskgroupID}/{status}") public ResponseEntity listTasksOfTaskgroup(@PathVariable long taskgroupID, @PathVariable String status) { PermissionResult taskgroupPermissionResult = taskgroupService.getTaskgroupByIDAndUsername(taskgroupID, SecurityContextHolder.getContext().getAuthentication().getName()); - if(!taskgroupPermissionResult.isHasPermissions()) { + if(taskgroupPermissionResult.isNoPermissions()) { return ResponseEntity.status(403).body(new SimpleStatusResponse("failed")); } @@ -78,7 +78,7 @@ public class TaskController { @PutMapping("/tasks/{taskgroupID}") public ResponseEntity createTask(@PathVariable long taskgroupID, @RequestBody @Valid TaskFieldInfo taskFieldInfo) { PermissionResult taskgroupPermissionResult = taskgroupService.getTaskgroupByIDAndUsername(taskgroupID, SecurityContextHolder.getContext().getAuthentication().getName()); - if(!taskgroupPermissionResult.isHasPermissions()) { + if(taskgroupPermissionResult.isNoPermissions()) { return ResponseEntity.status(403).body(new SimpleStatusResponse("failed")); } @@ -101,7 +101,7 @@ public class TaskController { @PostMapping("/tasks/{taskID}") public ResponseEntity editTask(@PathVariable long taskID, @RequestBody @Valid TaskFieldInfo taskFieldInfo) { PermissionResult taskPermissionResult = taskService.getTaskPermissions(taskID, SecurityContextHolder.getContext().getAuthentication().getName()); - if (!taskPermissionResult.isHasPermissions()) { + if (taskPermissionResult.isNoPermissions()) { return ResponseEntity.status(403).body(new SimpleStatusResponse("failed")); } @@ -124,7 +124,7 @@ public class TaskController { @DeleteMapping("/tasks/{taskID}") public ResponseEntity deleteTask(@PathVariable long taskID) { PermissionResult taskPermissionResult = taskService.getTaskPermissions(taskID, SecurityContextHolder.getContext().getAuthentication().getName()); - if (!taskPermissionResult.isHasPermissions()) { + if (taskPermissionResult.isNoPermissions()) { return ResponseEntity.status(403).body(new SimpleStatusResponse("failed")); } @@ -139,7 +139,7 @@ public class TaskController { @GetMapping("/tasks/{taskID}") public ResponseEntity loadTaskDetails(@PathVariable long taskID) { PermissionResult taskPermissionResult = taskService.getTaskPermissions(taskID, SecurityContextHolder.getContext().getAuthentication().getName()); - if (!taskPermissionResult.isHasPermissions()) { + if (taskPermissionResult.isNoPermissions()) { return ResponseEntity.status(403).body(new SimpleStatusResponse("failed")); } @@ -153,7 +153,7 @@ public class TaskController { @PostMapping("/tasks/{taskID}/finish") public ResponseEntity finishTask(@PathVariable long taskID) { PermissionResult taskPermissionResult = taskService.getTaskPermissions(taskID, SecurityContextHolder.getContext().getAuthentication().getName()); - if (!taskPermissionResult.isHasPermissions()) { + if (taskPermissionResult.isNoPermissions()) { return ResponseEntity.status(403).body(new SimpleStatusResponse("failed")); } diff --git a/backend/src/main/java/core/api/controller/TaskSeriesController.java b/backend/src/main/java/core/api/controller/TaskSeriesController.java new file mode 100644 index 0000000..c2d2994 --- /dev/null +++ b/backend/src/main/java/core/api/controller/TaskSeriesController.java @@ -0,0 +1,45 @@ +package core.api.controller; + +import core.api.models.timemanager.tasks.repeatinginfo.TaskRepeatDayInfo; +import core.api.models.timemanager.tasks.repeatinginfo.TaskRepeatWeekInfo; +import core.services.ServiceExitCode; +import core.services.ServiceResult; +import core.services.TaskSeriesService; +import core.services.TaskService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.web.bind.annotation.*; + +import javax.validation.Valid; + +@CrossOrigin(origins = "*", maxAge = 3600) +@RestController +@RequestMapping("/api") +public class TaskSeriesController { + + @Autowired private TaskService taskService; + @Autowired private TaskSeriesService taskSeriesService; + + @PostMapping("/tasks/{taskID}/taskseries/weekly") + public ResponseEntity onCreateTaskSeries(@PathVariable long taskID, @Valid @RequestBody TaskRepeatWeekInfo taskRepeatWeekInfo) { + var taskPermission = taskService.getTaskPermissions(taskID, SecurityContextHolder.getContext().getAuthentication().getName()); + if(taskPermission.hasIssue()) { + return taskPermission.mapToResponseEntity(); + } else { + ServiceExitCode serviceExitCode = taskSeriesService.createTaskSeries(taskPermission.getResult(), taskRepeatWeekInfo); + return serviceExitCode.mapToResponseEntity(); + } + } + + @PostMapping("/tasks/{taskID}/taskseries/daily") + public ResponseEntity onCreateTaskSeries(@PathVariable long taskID, @Valid @RequestBody TaskRepeatDayInfo taskRepeatDayInfo) { + var taskPermission = taskService.getTaskPermissions(taskID, SecurityContextHolder.getContext().getAuthentication().getName()); + if(taskPermission.hasIssue()) { + return taskPermission.mapToResponseEntity(); + } else { + ServiceExitCode serviceExitCode = taskSeriesService.createTaskSeries(taskPermission.getResult(), taskRepeatDayInfo); + return serviceExitCode.mapToResponseEntity(); + } + } +} diff --git a/backend/src/main/java/core/api/controller/TaskgroupController.java b/backend/src/main/java/core/api/controller/TaskgroupController.java index e9cdea2..7183f13 100644 --- a/backend/src/main/java/core/api/controller/TaskgroupController.java +++ b/backend/src/main/java/core/api/controller/TaskgroupController.java @@ -11,7 +11,6 @@ import org.springframework.web.bind.annotation.*; import javax.validation.Valid; import java.util.List; -import java.util.Set; @CrossOrigin(origins = "*", maxAge = 3600) @RestController @@ -40,7 +39,7 @@ public class TaskgroupController { @PostMapping("/taskgroups/{taskgroupID}") public ResponseEntity editTaskgroup(@PathVariable long taskgroupID, @Valid @RequestBody TaskgroupFieldInfo taskgroupFieldInfo) { PermissionResult taskgroupPermissionResult = taskgroupService.getTaskgroupByIDAndUsername(taskgroupID, SecurityContextHolder.getContext().getAuthentication().getName()); - if(!taskgroupPermissionResult.isHasPermissions()) { + if(taskgroupPermissionResult.isNoPermissions()) { return ResponseEntity.status(403).body(new SimpleStatusResponse("failed")); } @@ -59,7 +58,7 @@ public class TaskgroupController { @DeleteMapping("/taskgroups/{taskgroupID}") public ResponseEntity deleteTaskgroup(@PathVariable long taskgroupID) { PermissionResult taskgroupPermissionResult = taskgroupService.getTaskgroupByIDAndUsername(taskgroupID, SecurityContextHolder.getContext().getAuthentication().getName()); - if (!taskgroupPermissionResult.isHasPermissions()) { + if (taskgroupPermissionResult.isNoPermissions()) { return ResponseEntity.status(403).body(new SimpleStatusResponse("failed")); } @@ -88,7 +87,7 @@ public class TaskgroupController { @GetMapping("/taskgroups/{taskgroupID}") public ResponseEntity getDetails(@PathVariable long taskgroupID) { PermissionResult taskgroupPermissionResult = taskgroupService.getTaskgroupByIDAndUsername(taskgroupID, SecurityContextHolder.getContext().getAuthentication().getName()); - if(!taskgroupPermissionResult.isHasPermissions()) { + if(taskgroupPermissionResult.isNoPermissions()) { return ResponseEntity.status(403).body(new SimpleStatusResponse("failed")); } @@ -102,7 +101,7 @@ public class TaskgroupController { @DeleteMapping("/taskgroups/{taskgroupID}/clear") public ResponseEntity clearTasks(@PathVariable long taskgroupID) { PermissionResult taskgroupPermissionResult = taskgroupService.getTaskgroupByIDAndUsername(taskgroupID, SecurityContextHolder.getContext().getAuthentication().getName()); - if (!taskgroupPermissionResult.isHasPermissions()) { + if (taskgroupPermissionResult.isNoPermissions()) { return ResponseEntity.status(403).body(new SimpleStatusResponse("failed")); } diff --git a/backend/src/main/java/core/api/models/timemanager/tasks/repeatinginfo/DeadlineStrategy.java b/backend/src/main/java/core/api/models/timemanager/tasks/repeatinginfo/DeadlineStrategy.java new file mode 100644 index 0000000..13d93c0 --- /dev/null +++ b/backend/src/main/java/core/api/models/timemanager/tasks/repeatinginfo/DeadlineStrategy.java @@ -0,0 +1,8 @@ +package core.api.models.timemanager.tasks.repeatinginfo; + +public enum DeadlineStrategy { + + FIX_DEADLINE, + DEADLINE_EQUAL_START, + DEADLINE_FIT_START +} diff --git a/backend/src/main/java/core/api/models/timemanager/tasks/repeatinginfo/TaskRepeatDayInfo.java b/backend/src/main/java/core/api/models/timemanager/tasks/repeatinginfo/TaskRepeatDayInfo.java new file mode 100644 index 0000000..65d91c9 --- /dev/null +++ b/backend/src/main/java/core/api/models/timemanager/tasks/repeatinginfo/TaskRepeatDayInfo.java @@ -0,0 +1,35 @@ +package core.api.models.timemanager.tasks.repeatinginfo; + +import java.time.LocalDate; + +public class TaskRepeatDayInfo { + + private int offset; + private DeadlineStrategy deadlineStrategy; + + private LocalDate endDate; + + public int getOffset() { + return offset; + } + + public void setOffset(int offset) { + this.offset = offset; + } + + public DeadlineStrategy getDeadlineStrategy() { + return deadlineStrategy; + } + + public void setDeadlineStrategy(DeadlineStrategy deadlineStrategy) { + this.deadlineStrategy = deadlineStrategy; + } + + public LocalDate getEndDate() { + return endDate; + } + + public void setEndDate(LocalDate endDate) { + this.endDate = endDate; + } +} diff --git a/backend/src/main/java/core/api/models/timemanager/tasks/repeatinginfo/TaskRepeatWeekDayInfo.java b/backend/src/main/java/core/api/models/timemanager/tasks/repeatinginfo/TaskRepeatWeekDayInfo.java new file mode 100644 index 0000000..8589f14 --- /dev/null +++ b/backend/src/main/java/core/api/models/timemanager/tasks/repeatinginfo/TaskRepeatWeekDayInfo.java @@ -0,0 +1,9 @@ +package core.api.models.timemanager.tasks.repeatinginfo; + +public class TaskRepeatWeekDayInfo { + + private int weekday; + private int offset; + + +} diff --git a/backend/src/main/java/core/api/models/timemanager/tasks/repeatinginfo/TaskRepeatWeekInfo.java b/backend/src/main/java/core/api/models/timemanager/tasks/repeatinginfo/TaskRepeatWeekInfo.java new file mode 100644 index 0000000..19a4ce8 --- /dev/null +++ b/backend/src/main/java/core/api/models/timemanager/tasks/repeatinginfo/TaskRepeatWeekInfo.java @@ -0,0 +1,40 @@ +package core.api.models.timemanager.tasks.repeatinginfo; + +import org.hibernate.validator.constraints.Length; + +import java.time.LocalDate; +import java.util.List; + +public class TaskRepeatWeekInfo { + + @Length(min = 1, max = 7) + private List weekDayInfos; + + private DeadlineStrategy deadlineStrategy; + + private LocalDate endDate; + + public List getWeekDayInfos() { + return weekDayInfos; + } + + public void setWeekDayInfos(List weekDayInfos) { + this.weekDayInfos = weekDayInfos; + } + + public DeadlineStrategy getDeadlineStrategy() { + return deadlineStrategy; + } + + public void setDeadlineStrategy(DeadlineStrategy deadlineStrategy) { + this.deadlineStrategy = deadlineStrategy; + } + + public LocalDate getEndDate() { + return endDate; + } + + public void setEndDate(LocalDate endDate) { + this.endDate = endDate; + } +} diff --git a/backend/src/main/java/core/entities/timemanager/Task.java b/backend/src/main/java/core/entities/timemanager/Task.java index b6bf550..728101b 100644 --- a/backend/src/main/java/core/entities/timemanager/Task.java +++ b/backend/src/main/java/core/entities/timemanager/Task.java @@ -22,21 +22,17 @@ public class Task { @JoinColumn(name = "taskgroup_id") private Taskgroup taskgroup; private String taskName; - private LocalDate startDate; - private LocalDate deadline; - private int eta; - private boolean finished; - private boolean finishable; - @OneToMany(mappedBy = "task", cascade = CascadeType.ALL, fetch = FetchType.EAGER, orphanRemoval = true) private List basicTaskSchedules; - private int workTime; + @ManyToOne + @JoinColumn(referencedColumnName = "taskSerieID") + private TaskSerie taskSerie; public Task() { this.basicTaskSchedules = new ArrayList<>(); @@ -52,6 +48,17 @@ public class Task { this.finishable = taskFieldInfo.isFinishable(); } + public static Task cloneTask(Task task) { + Task clonedTask = new Task(); + clonedTask.setTaskgroup(task.getTaskgroup()); + clonedTask.setTaskName(task.taskName); + clonedTask.setEta(task.eta); + clonedTask.setFinished(false); + clonedTask.setFinishable(task.finishable); + return clonedTask; + } + + public long getTaskID() { return taskID; } @@ -124,6 +131,14 @@ public class Task { this.taskID = taskID; } + public TaskSerie getTaskSerie() { + return taskSerie; + } + + public void setTaskSerie(TaskSerie taskSerie) { + this.taskSerie = taskSerie; + } + public List getBasicTaskSchedules() { if(basicTaskSchedules == null) { return new ArrayList<>(); diff --git a/backend/src/main/java/core/entities/timemanager/TaskSerie.java b/backend/src/main/java/core/entities/timemanager/TaskSerie.java new file mode 100644 index 0000000..f317f34 --- /dev/null +++ b/backend/src/main/java/core/entities/timemanager/TaskSerie.java @@ -0,0 +1,36 @@ +package core.entities.timemanager; + +import javax.persistence.*; +import java.util.ArrayList; +import java.util.List; + +@Entity +@Table(name = "task_series") +public class TaskSerie { + + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private long taskSerieID; + + @OneToMany(orphanRemoval = false, cascade = CascadeType.ALL, fetch = FetchType.EAGER, mappedBy = "taskSerie") + List tasks = new ArrayList<>(); + + + + + public long getTaskSerieID() { + return taskSerieID; + } + + public List getTasks() { + return tasks; + } + + public void setTasks(List tasks) { + this.tasks = tasks; + } + + public void addTask(Task task) { + this.tasks.add(task); + } +} diff --git a/backend/src/main/java/core/repositories/timemanager/TaskSeriesRepository.java b/backend/src/main/java/core/repositories/timemanager/TaskSeriesRepository.java new file mode 100644 index 0000000..d03fc42 --- /dev/null +++ b/backend/src/main/java/core/repositories/timemanager/TaskSeriesRepository.java @@ -0,0 +1,9 @@ +package core.repositories.timemanager; + +import core.entities.timemanager.TaskSerie; +import org.springframework.data.repository.CrudRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface TaskSeriesRepository extends CrudRepository { +} diff --git a/backend/src/main/java/core/services/PermissionResult.java b/backend/src/main/java/core/services/PermissionResult.java index aafe4ef..c7b9a76 100644 --- a/backend/src/main/java/core/services/PermissionResult.java +++ b/backend/src/main/java/core/services/PermissionResult.java @@ -1,5 +1,8 @@ package core.services; +import core.api.models.auth.SimpleStatusResponse; +import org.springframework.http.ResponseEntity; + public class PermissionResult extends ServiceResult { private boolean hasPermissions; @@ -30,11 +33,25 @@ public class PermissionResult extends ServiceResult { this.hasPermissions = hasPermissions; } - public boolean isHasPermissions() { - return hasPermissions; + public boolean isNoPermissions() { + return !hasPermissions; } public void setHasPermissions(boolean hasPermissions) { this.hasPermissions = hasPermissions; } + + @Override + public ResponseEntity mapToResponseEntity() { + if(isNoPermissions()) { + return ResponseEntity.status(403).body(new SimpleStatusResponse("failed")); + } else { + return super.mapToResponseEntity(); + } + } + + @Override + public boolean hasIssue() { + return super.hasIssue() || isNoPermissions(); + } } diff --git a/backend/src/main/java/core/services/ServiceExitCode.java b/backend/src/main/java/core/services/ServiceExitCode.java index 93cbddd..452f52c 100644 --- a/backend/src/main/java/core/services/ServiceExitCode.java +++ b/backend/src/main/java/core/services/ServiceExitCode.java @@ -1,5 +1,8 @@ package core.services; +import core.api.models.auth.SimpleStatusResponse; +import org.springframework.http.ResponseEntity; + public enum ServiceExitCode { OK, @@ -7,4 +10,13 @@ public enum ServiceExitCode { MISSING_ENTITY, INVALID_OPERATION, INVALID_PARAMETER; + + public ResponseEntity mapToResponseEntity() { + return switch (this) { + case OK -> ResponseEntity.ok(new SimpleStatusResponse("success")); + case MISSING_ENTITY -> ResponseEntity.status(404).body(new SimpleStatusResponse("failed")); + case ENTITY_ALREADY_EXIST -> ResponseEntity.status(409).body(new SimpleStatusResponse("failed")); + case INVALID_OPERATION, INVALID_PARAMETER -> ResponseEntity.status(400).body(new SimpleStatusResponse("failed")); + }; + } } diff --git a/backend/src/main/java/core/services/ServiceResult.java b/backend/src/main/java/core/services/ServiceResult.java index da9e03d..179b514 100644 --- a/backend/src/main/java/core/services/ServiceResult.java +++ b/backend/src/main/java/core/services/ServiceResult.java @@ -1,5 +1,8 @@ package core.services; +import core.api.models.auth.SimpleStatusResponse; +import org.springframework.http.ResponseEntity; + public class ServiceResult { private ServiceExitCode exitCode; @@ -34,4 +37,12 @@ public class ServiceResult { public void setResult(T result) { this.result = result; } + + public boolean hasIssue() { + return exitCode != ServiceExitCode.OK; + } + + public ResponseEntity mapToResponseEntity() { + return exitCode.mapToResponseEntity(); + } } diff --git a/backend/src/main/java/core/services/TaskSeriesService.java b/backend/src/main/java/core/services/TaskSeriesService.java new file mode 100644 index 0000000..278ecf2 --- /dev/null +++ b/backend/src/main/java/core/services/TaskSeriesService.java @@ -0,0 +1,59 @@ +package core.services; + +import core.api.models.timemanager.tasks.repeatinginfo.DeadlineStrategy; +import core.api.models.timemanager.tasks.repeatinginfo.TaskRepeatDayInfo; +import core.api.models.timemanager.tasks.repeatinginfo.TaskRepeatWeekInfo; +import core.entities.timemanager.Task; +import core.entities.timemanager.TaskSerie; +import core.repositories.timemanager.TaskRepository; +import core.repositories.timemanager.TaskSeriesRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.time.LocalDate; + +@Service +public class TaskSeriesService { + + @Autowired private TaskRepository taskRepository; + @Autowired private TaskSeriesRepository taskSeriesRepository; + + public ServiceExitCode createTaskSeries(Task rootTask, TaskRepeatWeekInfo taskRepeatInfo) { + return ServiceExitCode.OK; + } + + public ServiceExitCode createTaskSeries(Task rootTask, TaskRepeatDayInfo taskRepeatInfo) { + if(taskRepeatInfo.getDeadlineStrategy() == DeadlineStrategy.FIX_DEADLINE) { + return ServiceExitCode.INVALID_PARAMETER; + } + + LocalDate currentTaskDate = rootTask.getStartDate().plusDays(taskRepeatInfo.getOffset()); + TaskSerie taskSerie = new TaskSerie(); + int index = 1; + while(currentTaskDate.isBefore(taskRepeatInfo.getEndDate())) { + Task task = Task.cloneTask(rootTask); + task.setStartDate(currentTaskDate); + if(taskRepeatInfo.getDeadlineStrategy() == DeadlineStrategy.DEADLINE_EQUAL_START) { + task.setDeadline(currentTaskDate); + } else if(taskRepeatInfo.getDeadlineStrategy() == DeadlineStrategy.DEADLINE_FIT_START) { + task.setDeadline(currentTaskDate.plusDays(taskRepeatInfo.getOffset()-1)); + } + taskSerie.addTask(task); + task.setTaskSerie(taskSerie); + task.setTaskName(task.getTaskName().replace("${i}", convertIndexToString(index))); + currentTaskDate = currentTaskDate.plusDays(taskRepeatInfo.getOffset()); + index++; + } + + taskRepository.saveAll(taskSerie.getTasks()); + return ServiceExitCode.OK; + } + + public static String convertIndexToString(int index) { + if(index < 10) { + return "0" + index; + } else { + return String.valueOf(index); + } + } +} diff --git a/openapi.yaml b/openapi.yaml index 2001027..b83f363 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -2073,6 +2073,52 @@ paths: application/json: schema: $ref: '#/components/schemas/SimpleStatusResponse' + /tasks/{taskID}/taskseries/daily: + post: + security: + - API_TOKEN: [] + tags: + - taskseries + description: Creates a daily repeating task + summary: daily repeating task creation + parameters: + - name: taskID + in: path + description: internal id of taskgroup + required: true + schema: + type: number + example: 1 + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/TaskRepeatDayInfo' + responses: + 200: + description: Operation successfull + content: + application/json: + schema: + $ref: '#/components/schemas/SimpleStatusResponse' + 403: + description: No permission + content: + application/json: + schema: + $ref: '#/components/schemas/SimpleStatusResponse' + 404: + description: Task not found + content: + application/json: + schema: + $ref: '#/components/schemas/SimpleStatusResponse' + 400: + description: Invalid deadlineStrategy + content: + application/json: + schema: + $ref: '#/components/schemas/SimpleStatusResponse' components: @@ -2779,4 +2825,20 @@ components: example: password ntfy_token: type: string - description: token to ntfy useraccount \ No newline at end of file + description: token to ntfy useraccount + TaskRepeatDayInfo: + required: + - offset + - deadlineStrategy + additionalProperties: false + properties: + offset: + type: number + description: number repeating days + example: 7 + minimum: 1 + deadlineStrategy: + type: string + enum: + - DEADLINE_EQUAL_START + - DEADLINE_FIT_START \ No newline at end of file