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.oas.DefaultApi;
|
||||
import de.hmmh.pmt.util.Mapper;
|
||||
import de.hmmh.pmt.util.Validator;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.HttpStatus;
|
||||
|
@ -30,6 +31,10 @@ public class ApiController implements DefaultApi {
|
|||
@Autowired
|
||||
private ApiClientFactory apiClientFactory;
|
||||
@Autowired
|
||||
private Validator validator;
|
||||
@Autowired
|
||||
private ApiTools apiTools;
|
||||
@Autowired
|
||||
private ProjectRepository projectRepository;
|
||||
@Autowired
|
||||
AllocationRepository allocationRepository;
|
||||
|
@ -87,7 +92,7 @@ public class ApiController implements DefaultApi {
|
|||
}
|
||||
|
||||
Project project = mapper.map(body);
|
||||
if (!project.isValid()) {
|
||||
if (!validator.isValidProject(project)) {
|
||||
return new ResponseEntity<>(HttpStatus.UNPROCESSABLE_ENTITY);
|
||||
}
|
||||
projectRepository.save(project);
|
||||
|
@ -121,16 +126,11 @@ public class ApiController implements DefaultApi {
|
|||
return new ResponseEntity<>(HttpStatus.UNPROCESSABLE_ENTITY);
|
||||
}
|
||||
|
||||
long start = project.getStart().toEpochSecond(ZoneOffset.UTC);
|
||||
long plannedEnd = project.getPlannedEnd().toEpochSecond(ZoneOffset.UTC);
|
||||
List<Allocation> allocations = allocationRepository.findAllByEmployeeId(body.getEmployeeId());
|
||||
if (allocations.stream()
|
||||
.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);
|
||||
})) {
|
||||
if (validator.areAllocationTimeRangesOverlapping(
|
||||
project.getStart(),
|
||||
project.getPlannedEnd(),
|
||||
allocationRepository.findAllByEmployeeId(body.getEmployeeId())
|
||||
)) {
|
||||
return new ResponseEntity<>(HttpStatus.UNPROCESSABLE_ENTITY);
|
||||
}
|
||||
|
||||
|
|
|
@ -47,16 +47,4 @@ public class Project {
|
|||
private LocalDateTime plannedEnd;
|
||||
|
||||
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