PMT-43: Separate Validation Logic
This commit is contained in:
parent
5ca3603f65
commit
3af49e2466
3 changed files with 59 additions and 23 deletions
|
@ -9,6 +9,7 @@ import de.hmmh.pmt.employee.api.EmployeeControllerApi;
|
||||||
import de.hmmh.pmt.employee.dtos.EmployeeResponseDTO;
|
import de.hmmh.pmt.employee.dtos.EmployeeResponseDTO;
|
||||||
import de.hmmh.pmt.oas.DefaultApi;
|
import de.hmmh.pmt.oas.DefaultApi;
|
||||||
import de.hmmh.pmt.util.Mapper;
|
import de.hmmh.pmt.util.Mapper;
|
||||||
|
import de.hmmh.pmt.util.Validator;
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
|
@ -30,6 +31,10 @@ public class ApiController implements DefaultApi {
|
||||||
@Autowired
|
@Autowired
|
||||||
private ApiClientFactory apiClientFactory;
|
private ApiClientFactory apiClientFactory;
|
||||||
@Autowired
|
@Autowired
|
||||||
|
private Validator validator;
|
||||||
|
@Autowired
|
||||||
|
private ApiTools apiTools;
|
||||||
|
@Autowired
|
||||||
private ProjectRepository projectRepository;
|
private ProjectRepository projectRepository;
|
||||||
@Autowired
|
@Autowired
|
||||||
AllocationRepository allocationRepository;
|
AllocationRepository allocationRepository;
|
||||||
|
@ -87,7 +92,7 @@ public class ApiController implements DefaultApi {
|
||||||
}
|
}
|
||||||
|
|
||||||
Project project = mapper.map(body);
|
Project project = mapper.map(body);
|
||||||
if (!project.isValid()) {
|
if (!validator.isValidProject(project)) {
|
||||||
return new ResponseEntity<>(HttpStatus.UNPROCESSABLE_ENTITY);
|
return new ResponseEntity<>(HttpStatus.UNPROCESSABLE_ENTITY);
|
||||||
}
|
}
|
||||||
projectRepository.save(project);
|
projectRepository.save(project);
|
||||||
|
@ -121,16 +126,11 @@ public class ApiController implements DefaultApi {
|
||||||
return new ResponseEntity<>(HttpStatus.UNPROCESSABLE_ENTITY);
|
return new ResponseEntity<>(HttpStatus.UNPROCESSABLE_ENTITY);
|
||||||
}
|
}
|
||||||
|
|
||||||
long start = project.getStart().toEpochSecond(ZoneOffset.UTC);
|
if (validator.areAllocationTimeRangesOverlapping(
|
||||||
long plannedEnd = project.getPlannedEnd().toEpochSecond(ZoneOffset.UTC);
|
project.getStart(),
|
||||||
List<Allocation> allocations = allocationRepository.findAllByEmployeeId(body.getEmployeeId());
|
project.getPlannedEnd(),
|
||||||
if (allocations.stream()
|
allocationRepository.findAllByEmployeeId(body.getEmployeeId())
|
||||||
.map(Allocation::getProject)
|
)) {
|
||||||
.anyMatch(allocatedProject -> {
|
|
||||||
long allocatedStart = allocatedProject.getStart().toEpochSecond(ZoneOffset.UTC);
|
|
||||||
long allocatedPlannedEnd = allocatedProject.getPlannedEnd().toEpochSecond(ZoneOffset.UTC);
|
|
||||||
return Math.max(start, allocatedStart) <= Math.min(plannedEnd, allocatedPlannedEnd);
|
|
||||||
})) {
|
|
||||||
return new ResponseEntity<>(HttpStatus.UNPROCESSABLE_ENTITY);
|
return new ResponseEntity<>(HttpStatus.UNPROCESSABLE_ENTITY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -47,16 +47,4 @@ public class Project {
|
||||||
private LocalDateTime plannedEnd;
|
private LocalDateTime plannedEnd;
|
||||||
|
|
||||||
private LocalDateTime realEnd; // Cant be named just "end" because it's and SQL Keyword
|
private LocalDateTime realEnd; // Cant be named just "end" because it's and SQL Keyword
|
||||||
|
|
||||||
|
|
||||||
public boolean isValid() {
|
|
||||||
Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
|
|
||||||
Set<ConstraintViolation<Project>> violations = validator.validate(this);
|
|
||||||
|
|
||||||
return violations.isEmpty() &&
|
|
||||||
plannedEnd.isAfter(start) &&
|
|
||||||
(realEnd == null || realEnd.isAfter(start));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
48
src/main/java/de/hmmh/pmt/util/Validator.java
Normal file
48
src/main/java/de/hmmh/pmt/util/Validator.java
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
package de.hmmh.pmt.util;
|
||||||
|
|
||||||
|
import de.hmmh.pmt.db.Allocation;
|
||||||
|
import de.hmmh.pmt.db.Project;
|
||||||
|
import jakarta.validation.ConstraintViolation;
|
||||||
|
import jakarta.validation.Validation;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.ZoneOffset;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class Validator {
|
||||||
|
|
||||||
|
public boolean isValidProject(Project project) {
|
||||||
|
jakarta.validation.Validator validator = Validation
|
||||||
|
.buildDefaultValidatorFactory()
|
||||||
|
.getValidator();
|
||||||
|
Set<ConstraintViolation<Project>> violations = validator.validate(project);
|
||||||
|
|
||||||
|
LocalDateTime start = project.getStart();
|
||||||
|
LocalDateTime plannedEnd = project.getPlannedEnd();
|
||||||
|
LocalDateTime realEnd = project.getRealEnd();
|
||||||
|
|
||||||
|
return violations.isEmpty() &&
|
||||||
|
plannedEnd.isAfter(start) &&
|
||||||
|
(realEnd == null || realEnd.isAfter(start));
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean areAllocationTimeRangesOverlapping(
|
||||||
|
LocalDateTime start,
|
||||||
|
LocalDateTime plannedEnd,
|
||||||
|
List<Allocation> allocations
|
||||||
|
){
|
||||||
|
long startUnix = start.toEpochSecond(ZoneOffset.UTC);
|
||||||
|
long plannedEndUnix = plannedEnd.toEpochSecond(ZoneOffset.UTC);
|
||||||
|
return allocations.stream()
|
||||||
|
.map(Allocation::getProject)
|
||||||
|
.anyMatch(allocatedProject -> {
|
||||||
|
long allocatedStart = allocatedProject.getStart().toEpochSecond(ZoneOffset.UTC);
|
||||||
|
long allocatedPlannedEnd = allocatedProject.getPlannedEnd().toEpochSecond(ZoneOffset.UTC);
|
||||||
|
return Math.max(startUnix, allocatedStart) <= Math.min(plannedEndUnix, allocatedPlannedEnd);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in a new issue