diff --git a/src/main/java/com/example/demo/controller/TasksController.java b/src/main/java/com/example/demo/controller/TasksController.java index eb252c4c4defbcf50f84cf025b26a0fcf0849eb3..dd556456ee1b397931f3db74f5899875a46220fc 100644 --- a/src/main/java/com/example/demo/controller/TasksController.java +++ b/src/main/java/com/example/demo/controller/TasksController.java @@ -30,11 +30,10 @@ import javax.validation.Valid; @RequestMapping(value = "/training-definitions/{definitionId}/phases/{phaseId}/tasks", produces = MediaType.APPLICATION_JSON_VALUE) @CrossOrigin(origins = "*", allowCredentials = "true", allowedHeaders = "*", methods = {RequestMethod.GET, RequestMethod.POST, RequestMethod.DELETE, RequestMethod.PUT}) -@Api(value = "/training-definitions/{definitionId}/phases", +@Api(value = "/training-definitions/{definitionId}/tasks", tags = "Tasks", consumes = MediaType.APPLICATION_JSON_VALUE, authorizations = @Authorization(value = "bearerAuth")) - public class TasksController { @Autowired @@ -161,4 +160,23 @@ public class TasksController { return ResponseEntity.ok().build(); } + + @ApiOperation(httpMethod = "PUT", + value = "Move task to specified order", + nickname = "moveTaskToSpecifiedOrder", + produces = MediaType.APPLICATION_JSON_VALUE + ) + @ApiResponses(value = { + @ApiResponse(code = 200, message = "Task moved to specified order"), + @ApiResponse(code = 500, message = "Unexpected application error") + }) + @PutMapping(value = "/{taskIdFrom}/move-to/{newPosition}", produces = MediaType.APPLICATION_JSON_VALUE) + public ResponseEntity<Void> moveTaskToSpecifiedOrder( + @ApiParam(value = "Task ID - from", required = true) @PathVariable(name = "taskIdFrom") Long taskIdFrom, + @ApiParam(value = "Position (order) to which the task should be moved", required = true) @PathVariable(name = "newPosition") int newPosition) { + + taskService.moveTaskToSpecifiedOrder(taskIdFrom, newPosition); + + return ResponseEntity.ok().build(); + } } diff --git a/src/main/java/com/example/demo/repository/TaskRepository.java b/src/main/java/com/example/demo/repository/TaskRepository.java index 91642c889971b857b736931955735b71521ba2a6..584402d4f487a173fc7ec2cd6147f82967ebb12d 100644 --- a/src/main/java/com/example/demo/repository/TaskRepository.java +++ b/src/main/java/com/example/demo/repository/TaskRepository.java @@ -12,6 +12,26 @@ public interface TaskRepository extends JpaRepository<Task, Long> { @Query("SELECT COALESCE(MAX(g.order), -1) FROM Task g WHERE g.trainingPhase.id = :phaseId") Integer getCurrentMaxOrder(@Param("phaseId") Long phaseId); + @Modifying + @Query("UPDATE Task t SET t.order = t.order - 1 " + + "WHERE t.trainingPhase.id = :trainingPhaseId " + + "AND t.order > :lowerBound " + + "AND t.order <= :upperBound ") + void decreaseOrderOfTasksOnInterval(@Param("trainingPhaseId") Long trainingPhaseId, + @Param("lowerBound") int lowerBound, + @Param("upperBound") int upperBound); + + + @Modifying + @Query("UPDATE Task t SET t.order = t.order + 1 " + + "WHERE t.trainingPhase.id = :trainingPhaseId " + + "AND t.order >= :lowerBound " + + "AND t.order < :upperBound ") + void increaseOrderOfTasksOnInterval(@Param("trainingPhaseId") Long trainingPhaseId, + @Param("lowerBound") int lowerBound, + @Param("upperBound") int upperBound); + + @Transactional @Modifying @Query("UPDATE Task t SET t.order = t.order - 1 " + diff --git a/src/main/java/com/example/demo/service/TaskService.java b/src/main/java/com/example/demo/service/TaskService.java index a4092e653bab27da9c080a38b7a25235aab60e7a..2d87bcb823939ca8686cc16fd7faa15e4e6278df 100644 --- a/src/main/java/com/example/demo/service/TaskService.java +++ b/src/main/java/com/example/demo/service/TaskService.java @@ -14,6 +14,7 @@ import org.slf4j.LoggerFactory; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import java.util.ArrayList; import java.util.List; @@ -133,4 +134,25 @@ public class TaskService { taskRepository.delete(task); } + + @Transactional + public void moveTaskToSpecifiedOrder(Long taskIdFrom, int newPosition) { + Task task = taskRepository.findById(taskIdFrom) + .orElseThrow(() -> new RuntimeException("Task was not found")); + // TODO throw proper exception once kypo2-training is migrated + + int fromOrder = task.getOrder(); + + if (fromOrder < newPosition) { + taskRepository.decreaseOrderOfTasksOnInterval(task.getTrainingPhase().getId(), fromOrder, newPosition); + } else if (fromOrder > newPosition) { + taskRepository.increaseOrderOfTasksOnInterval(task.getTrainingPhase().getId(), newPosition, fromOrder); + } else { + // nothing should be changed, no further actions needed + return; + } + + task.setOrder(newPosition); + taskRepository.save(task); + } }