DeclaredExperienceServiceImpl.java
package fr.avenirsesr.portfolio.student.progress.declared.experience.domain.service;
import static fr.avenirsesr.portfolio.common.validation.domain.constraints.FieldMaxLengths.*;
import static fr.avenirsesr.portfolio.common.validation.domain.utils.FieldValidationUtils.*;
import fr.avenirsesr.portfolio.common.data.domain.model.AvenirsBaseModel;
import fr.avenirsesr.portfolio.common.data.domain.model.PageCriteria;
import fr.avenirsesr.portfolio.common.data.domain.model.PagedResult;
import fr.avenirsesr.portfolio.common.security.domain.exception.UserNotAuthorizedException;
import fr.avenirsesr.portfolio.shared.domain.port.input.LoggedInUserService;
import fr.avenirsesr.portfolio.student.progress.declared.experience.domain.exception.DeclaredExperienceNotFoundException;
import fr.avenirsesr.portfolio.student.progress.declared.experience.domain.model.DeclaredExperience;
import fr.avenirsesr.portfolio.student.progress.declared.experience.domain.model.enums.EExperienceType;
import fr.avenirsesr.portfolio.student.progress.declared.experience.domain.port.input.DeclaredExperienceService;
import fr.avenirsesr.portfolio.student.progress.declared.experience.domain.port.output.repository.DeclaredExperienceRepository;
import fr.avenirsesr.portfolio.user.domain.model.Student;
import fr.avenirsesr.portfolio.user.domain.port.output.repository.StudentRepository;
import java.time.LocalDate;
import java.util.HashSet;
import java.util.List;
import java.util.UUID;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@RequiredArgsConstructor
public class DeclaredExperienceServiceImpl implements DeclaredExperienceService {
private final LoggedInUserService loggedInUserService;
private final DeclaredExperienceRepository experienceRepository;
private final StudentRepository studentRepository;
@Override
public DeclaredExperience create(
UUID studentId,
String title,
EExperienceType experienceType,
String organization,
String activitySector,
String location,
String description,
String sourceOfInformation,
String summary,
String externalLink,
LocalDate startDate,
LocalDate endDate) {
Student student =
studentRepository.findById(studentId).orElseThrow(UserNotAuthorizedException::new);
return create(
student,
title,
experienceType,
organization,
activitySector,
location,
description,
sourceOfInformation,
summary,
externalLink,
startDate,
endDate);
}
@Override
public DeclaredExperience create(
String title,
EExperienceType experienceType,
String organization,
String activitySector,
String location,
String description,
String sourceOfInformation,
String summary,
String externalLink,
LocalDate startDate,
LocalDate endDate) {
return create(
loggedInUserService.getLoggedInStudent(),
title,
experienceType,
organization,
activitySector,
location,
description,
sourceOfInformation,
summary,
externalLink,
startDate,
endDate);
}
private DeclaredExperience create(
Student student,
String title,
EExperienceType experienceType,
String organization,
String activitySector,
String location,
String description,
String sourceOfInformation,
String summary,
String externalLink,
LocalDate startDate,
LocalDate endDate) {
log.info("DeclaredExperience creation for {}", student);
checkDeclaredExperienceDataValidity(
title,
organization,
activitySector,
location,
description,
sourceOfInformation,
summary,
externalLink,
startDate,
endDate);
var experience =
DeclaredExperience.create(
student,
title,
experienceType,
organization,
activitySector,
location,
description,
sourceOfInformation,
summary,
externalLink,
startDate,
endDate);
experience = experienceRepository.save(experience);
log.info("{} has been created", experience);
return experience;
}
@Override
public DeclaredExperience update(
UUID experienceId,
String title,
EExperienceType experienceType,
String organization,
String activitySector,
String location,
String description,
String sourceOfInformation,
String summary,
String externalLink,
LocalDate startDate,
LocalDate endDate) {
Student student = loggedInUserService.getLoggedInStudent();
log.info("Update experienceId {} by {}", experienceId, student);
var experience =
experienceRepository
.findById(experienceId)
.orElseThrow(DeclaredExperienceNotFoundException::new);
if (!experience.getStudent().equals(student)) {
throw new UserNotAuthorizedException();
}
checkDeclaredExperienceDataValidity(
title,
organization,
activitySector,
location,
description,
sourceOfInformation,
summary,
externalLink,
startDate,
endDate);
experience.setTitle(title);
experience.setExperienceType(experienceType);
experience.setOrganization(organization);
experience.setActivitySector(activitySector);
experience.setLocation(location);
experience.setDescription(description);
experience.setSourceOfInformation(sourceOfInformation);
experience.setSummary(summary);
experience.setExternalLink(externalLink);
experience.setStartDate(startDate);
experience.setEndDate(endDate);
experience = experienceRepository.save(experience);
log.info("{} updated successfully", experience);
return experience;
}
private void checkDeclaredExperienceDataValidity(
String title,
String organization,
String activitySector,
String location,
String description,
String sourceOfInformation,
String summary,
String externalLink,
LocalDate startDate,
LocalDate endDate) {
requireNotBlankAndMaxLength("title", title, TITLE_LENGTH);
requireNotBlankAndMaxLength("organization", organization, ORGANIZATION_LENGTH);
validateOptionalTextMaxLength("activitySector", activitySector, ACTIVITY_SECTOR_LENGTH);
validateOptionalTextMaxLength("location", location, LOCATION_LENGTH);
validateOptionalTextMaxLength(
"sourceOfInformation", sourceOfInformation, SOURCE_OF_INFORMATION_LENGTH);
validateOptionalTextMaxLength("description", description, DESCRIPTION_LENGTH);
validateOptionalTextMaxLength("summary", summary, SUMMARY_LENGTH);
requireNotNull("startDate", startDate);
validateDateOrder(startDate, endDate);
validateUrl(externalLink);
}
@Override
public void delete(List<UUID> experienceIds) {
Student student = loggedInUserService.getLoggedInStudent();
log.info("Deleting experienceIds {} by {}", experienceIds, student);
var experiences = experienceRepository.findAllById(experienceIds);
if (experiences.stream().anyMatch(experience -> !experience.getStudent().equals(student))) {
throw new UserNotAuthorizedException();
}
if (!new HashSet<>(experiences.stream().map(AvenirsBaseModel::getId).toList())
.containsAll(experienceIds)) {
throw new DeclaredExperienceNotFoundException();
}
experienceRepository.removeAllFromDatabase(experiences);
log.info("ExperienceIds {} successfully deleted", experienceIds);
}
@Override
public DeclaredExperience get(UUID experienceId) {
Student student = loggedInUserService.getLoggedInStudent();
log.info("Get experienceId {} by {}", experienceId, student);
var experience =
experienceRepository
.findById(experienceId)
.orElseThrow(DeclaredExperienceNotFoundException::new);
if (!experience.getStudent().equals(student)) {
throw new UserNotAuthorizedException();
}
return experience;
}
@Override
public PagedResult<DeclaredExperience> getView(PageCriteria pageCriteria) {
Student student = loggedInUserService.getLoggedInStudent();
log.info("Get experience view by {}", student);
return experienceRepository.findAllByStudent(student, pageCriteria);
}
}