TraceServiceImpl.java
package fr.avenirsesr.portfolio.trace.domain.service;
import fr.avenirsesr.portfolio.backoffice.configuration.trace.domain.model.TraceConfiguration;
import fr.avenirsesr.portfolio.backoffice.configuration.trace.domain.port.input.TraceConfigurationService;
import fr.avenirsesr.portfolio.shared.domain.model.PageCriteria;
import fr.avenirsesr.portfolio.shared.domain.model.PagedResult;
import fr.avenirsesr.portfolio.shared.domain.model.enums.ELanguage;
import fr.avenirsesr.portfolio.shared.domain.model.enums.EPortfolioType;
import fr.avenirsesr.portfolio.student.progress.domain.model.StudentProgress;
import fr.avenirsesr.portfolio.student.progress.domain.port.output.repository.StudentProgressRepository;
import fr.avenirsesr.portfolio.trace.domain.exception.TraceNotFoundException;
import fr.avenirsesr.portfolio.trace.domain.model.ETraceStatus;
import fr.avenirsesr.portfolio.trace.domain.model.Trace;
import fr.avenirsesr.portfolio.trace.domain.model.UnassociatedTracesSummary;
import fr.avenirsesr.portfolio.trace.domain.port.input.TraceService;
import fr.avenirsesr.portfolio.trace.domain.port.output.repository.TraceRepository;
import fr.avenirsesr.portfolio.user.domain.exception.UserNotAuthorizedException;
import fr.avenirsesr.portfolio.user.domain.model.User;
import java.time.Duration;
import java.time.Instant;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@AllArgsConstructor
public class TraceServiceImpl implements TraceService {
private static final int MAX_TRACES_OVERVIEW = 3;
private final TraceRepository traceRepository;
private final StudentProgressRepository studentProgressRepository;
private final TraceConfigurationService traceConfigurationService;
@Override
public String programNameOfTrace(Trace trace) {
List<StudentProgress> studentProgresses =
studentProgressRepository.findStudentProgressesBySkillLevelProgresses(
trace.getSkillLevels());
return studentProgresses.stream()
.filter(sp -> sp.getTrainingPath().getProgram().isAPC())
.map(sp -> sp.getTrainingPath().getProgram().getName())
.findAny()
.orElse(EPortfolioType.LIFE_PROJECT.name());
}
@Override
public List<Trace> lastTracesOf(User user) {
return traceRepository.findLastsOf(user, MAX_TRACES_OVERVIEW);
}
@Override
public PagedResult<Trace> getTracesView(
User user, PageCriteria pageCriteria, ETraceStatus status) {
PagedResult<Trace> pagedResult = traceRepository.findAll(user, pageCriteria, status);
return new PagedResult<>(pagedResult.content(), pagedResult.pageInfo());
}
@Override
public void deleteById(User user, UUID id) {
Trace trace = traceRepository.findById(id).orElseThrow(TraceNotFoundException::new);
if (!trace.getUser().getId().equals(user.getId())) {
throw new UserNotAuthorizedException();
}
trace.setAmses(List.of());
trace.setSkillLevels(List.of());
trace.setDeletedAt(Instant.now());
traceRepository.save(trace);
log.info("Deleted trace {}", trace);
}
@Override
public UnassociatedTracesSummary getUnassociatedTracesSummary(User user) {
List<Trace> unassociatedTraces = traceRepository.findAllUnassociated(user);
TraceConfiguration traceConfiguration = traceConfigurationService.getTraceConfiguration();
int criticalCount =
unassociatedTraces.stream()
.filter(
t ->
Duration.between(t.getCreatedAt(), Instant.now())
.minus(Duration.ofDays(traceConfiguration.maxRemainingDays()))
.plus(Duration.ofDays(traceConfiguration.maxRemainingDaysBeforeCritical()))
.isPositive())
.toList()
.size();
int warningCount =
unassociatedTraces.stream()
.filter(
t ->
Duration.between(t.getCreatedAt(), Instant.now())
.minus(Duration.ofDays(traceConfiguration.maxRemainingDays()))
.plus(Duration.ofDays(traceConfiguration.maxRemainingDaysBeforeWarning()))
.isPositive())
.toList()
.size();
return new UnassociatedTracesSummary(unassociatedTraces.size(), warningCount, criticalCount);
}
@Override
public Trace createTrace(
User user,
String title,
ELanguage language,
boolean isGroup,
String personalNote,
String aiJustification) {
var trace =
Trace.create(
UUID.randomUUID(), user, title, language, isGroup, aiJustification, personalNote);
traceRepository.save(trace);
return trace;
}
@Override
public Optional<LocalDate> getWillBeDeletedAt(Trace trace) {
var config = traceConfigurationService.getTraceConfiguration();
return trace.isUnassociated()
? Optional.of(
trace
.getCreatedAt()
.plus(Duration.ofDays(config.maxRemainingDays()))
.atZone(ZoneId.systemDefault())
.toLocalDate())
: Optional.empty();
}
}