Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ public ResponseEntity<TrajectoryDTO> uploadTrajectory(@RequestParam("trajectoryT
String trajectoryToUse,
@RequestParam("horizon") @Pattern(regexp = "^\\d{4}-\\d{4}$")
@Parameter(description = "example of horizon : 2020-2021") String horizon,
@RequestParam("studyId") Integer studyId) throws IOException {
@RequestParam(value = "studyId", required = false) Integer studyId) throws IOException {
return new ResponseEntity<>(toTrajectoryDTO(trajectoryService.processTrajectory(trajectoryType, trajectoryToUse, horizon, studyId)), HttpStatus.CREATED);
}

Expand All @@ -72,7 +72,7 @@ public ResponseEntity<TrajectoryDTO> uploadTrajectory(@RequestParam("area") Stri
@RequestParam("trajectoryToUse") String trajectoryToUse,
@RequestParam("horizon") @Pattern(regexp = "^\\d{4}-\\d{4}$")
@Parameter(description = "example of horizon : 2020-2021") String horizon,
@RequestParam("studyId") Integer studyId) throws IOException {
@RequestParam(value = "studyId",required = false) Integer studyId) throws IOException {
return new ResponseEntity<>(toTrajectoryDTO(trajectoryService.processLoadTrajectory(area, trajectoryToUse, horizon, studyId)), HttpStatus.CREATED);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import java.util.stream.Collectors;

import static com.rte_france.antares.datamanager_back.util.Utils.*;
import static java.util.Objects.nonNull;


/**
Expand Down Expand Up @@ -70,9 +71,7 @@ public TrajectoryEntity processLinkFile(Path path, String horizon, Integer study
);
String createdBy = userService.getCurrentUserDetails().getNni();

List<String> areaNames = findListArea(studyId);

List<LinkEntity> listLink = buildLinkList(path, horizon, areaNames);
List<LinkEntity> listLink = buildLinkList(path, horizon);

TrajectoryEntity trajectory;
if (trajectoryEntity.isPresent() && checkTrajectoryVersion(path, trajectoryEntity.get())) {
Expand All @@ -81,14 +80,17 @@ public TrajectoryEntity processLinkFile(Path path, String horizon, Integer study
trajectory = buildTrajectory(path, 0, horizon, createdBy, TrajectoryType.LINK);
}

validateLinksAlphabeticalOrder(path, horizon, studyId, trajectory);
if (nonNull(studyId)) {
List<String> areaNames = findListArea(studyId);

TrajectoryEntity secondTrajectory = trajectoryRepository.findByTypeAndStudyId(TrajectoryType.AREA.name(), studyId).stream().findFirst().orElse(null);
String userNni = findUserNni();
TrajectoryEntity secondTrajectory = trajectoryRepository.findByTypeAndStudyId(TrajectoryType.AREA.name(), studyId).stream().findFirst().orElse(null);
String userNni = findUserNni();
validateLinksAlphabeticalOrder(path, horizon, studyId, trajectory);

checkForWarnings(path, horizon, studyId, warningMessageEntities, userNni, trajectory);
checkConsistencyTrajectoryLinkAndArea(listLink, areaNames, warningMessageEntities, studyId, trajectory.getId(), secondTrajectory, userNni);
checkForWarnings(path, horizon, studyId, warningMessageEntities, userNni, trajectory);
checkConsistencyTrajectoryLinkAndArea(listLink, areaNames, warningMessageEntities, studyId, trajectory.getId(), secondTrajectory, userNni);

}
return saveTrajectory(trajectory, listLink, warningMessageEntities);
}

Expand Down Expand Up @@ -186,7 +188,7 @@ public TrajectoryEntity saveTrajectory(TrajectoryEntity trajectory, List<LinkEnt
* @param path the path to the file to process
* @return a list of area configurations
*/
private List<LinkEntity> buildLinkList(Path path, String horizon, List<String> listArea) throws IOException {
private List<LinkEntity> buildLinkList(Path path, String horizon) throws IOException {
List<LinkEntity> linkEntities = new ArrayList<>();
try (InputStream inputStream = Files.newInputStream(path);
Workbook workbook = WorkbookFactory.create(inputStream)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import java.util.stream.Collectors;

import static com.rte_france.antares.datamanager_back.util.Utils.*;
import static java.util.Objects.nonNull;


@Slf4j
Expand Down Expand Up @@ -70,9 +71,54 @@ public class TrajectoryServiceImpl implements TrajectoryService {
@Transactional
@Override
public TrajectoryEntity processLoadTrajectory(String area, String trajectoryToUse, String horizon, Integer studyId) throws IOException {
return saveLoadTrajectoriesInDb(area, trajectoryToUse, horizon, studyId);

String userNni = Optional.ofNullable(userService.getCurrentUserDetails())
.map(UserInfoDto::getNni)
.orElseThrow(() ->
BusinessException.builder()
.message("User NNI could not be determined")
.httpStatus(HttpStatus.BAD_REQUEST)
.build());

Optional<TrajectoryEntity> existingTrajectoryOpt = trajectoryRepository
.findFirstByFileNameAndHorizonAndLoadAreaOrderByVersionDesc(trajectoryToUse, horizon, area);


if(nonNull(studyId)){
return saveLoadTrajectoriesInDb(area, trajectoryToUse, horizon, studyId, existingTrajectoryOpt, userNni);
}
else
return saveLoadTrajectoryWithoutStudyId(area,trajectoryToUse,horizon,existingTrajectoryOpt, userNni);

}

private TrajectoryEntity saveLoadTrajectoryWithoutStudyId(String area, String trajectoryToUse, String horizon,
Optional<TrajectoryEntity> existingTrajectoryOpt, String userNni) throws IOException {
Path trajectoryPath = buildTrajectoryPath(trajectoryToUse);


if (existingTrajectoryOpt.isPresent()) {
TrajectoryEntity existingTrajectory = existingTrajectoryOpt.get();
if (isSameLoadTrajectory(trajectoryPath, existingTrajectory) || area.equals(OTHER_AREA))
{
throw BusinessException.builder()
.message("Trajectory already uploaded")
.httpStatus(HttpStatus.BAD_REQUEST)
.build();
}

// Update a version and save new trajectory
TrajectoryEntity newTrajectory = buildNewLoadTrajectory(trajectoryToUse, horizon, trajectoryPath, userNni);
newTrajectory.setVersion(existingTrajectory.getVersion() + 1);
return buildAndSaveLoadTrajectory(area, horizon, trajectoryPath, newTrajectory, null, null);

}
TrajectoryEntity newTrajectory = buildNewLoadTrajectory(trajectoryToUse, horizon, trajectoryPath, userNni);
return buildAndSaveLoadTrajectory(area, horizon, trajectoryPath, newTrajectory, null, null);

}


/**
* Processes a load trajectory file based on the given area, trajectory name, and horizon.
*
Expand All @@ -82,17 +128,18 @@ public TrajectoryEntity processLoadTrajectory(String area, String trajectoryToUs
* @return the processed TrajectoryEntity
* @throws IOException if an I/O error occurs
*/
public TrajectoryEntity saveLoadTrajectoriesInDb(String area, String trajectoryToUse, String horizon, Integer studyId) throws IOException {
public TrajectoryEntity saveLoadTrajectoriesInDb(String area, String trajectoryToUse, String horizon, Integer studyId,
Optional<TrajectoryEntity> existingTrajectoryOpt, String userNni) throws IOException {
Set<WarningMessageEntity> warningMessageEntities = new HashSet<>();
if (area == null || trajectoryToUse == null || horizon == null) {
throw
BusinessException.builder()
.message("Area, trajectory name, and horizon must not be null")
.httpStatus(HttpStatus.BAD_REQUEST)
.build();

}


if (!area.equals(OTHER_AREA)) {
areaRepository.findAreaByNameAndStudyId(area, studyId).orElseThrow(() ->
BusinessException.builder()
Expand All @@ -102,22 +149,10 @@ public TrajectoryEntity saveLoadTrajectoriesInDb(String area, String trajectoryT
.build());
}

String userNni = Optional.ofNullable(userService.getCurrentUserDetails())
.map(UserInfoDto::getNni)
.orElseThrow(() ->
BusinessException.builder()
.message("User NNI could not be determined")
.httpStatus(HttpStatus.BAD_REQUEST)
.build());

// Build and normalize the trajectory path
Path trajectoryPath = buildTrajectoryPath(trajectoryToUse);


// Try to find existing trajectory
Optional<TrajectoryEntity> existingTrajectoryOpt = trajectoryRepository
.findFirstByFileNameAndHorizonAndLoadAreaOrderByVersionDesc(trajectoryToUse, horizon, area);

if (existingTrajectoryOpt.isPresent()) {
TrajectoryEntity existingTrajectory = existingTrajectoryOpt.get();
if ((isSameLoadTrajectory(trajectoryPath, existingTrajectory) && !area.equals(OTHER_AREA))
Expand Down Expand Up @@ -213,15 +248,21 @@ private TrajectoryEntity buildNewLoadTrajectory(String trajectoryToUse, String h

private TrajectoryEntity buildAndSaveLoadTrajectory(String area, String horizon, Path trajectoryPath, TrajectoryEntity loadTrajectory, Integer studyId, Set<WarningMessageEntity> warningMessageEntities) throws IOException {
List<String> listCustomLoadFilesAlreadyChoosed = new ArrayList<>();
if (area.equals(OTHER_AREA)) {
if (area.equals(OTHER_AREA) && studyId != null) {
listCustomLoadFilesAlreadyChoosed = trajectoryRepository.findByTypeAndStudyId(TrajectoryType.LOAD.name(), studyId)
.stream()
.map(TrajectoryEntity::getLoadArea)
.filter(loadArea -> !loadArea.equals(OTHER_AREA))
.map(String::toLowerCase)
.toList();
}
List<String> areaWithStudy = areaRepository.findAllByStudyId(studyId).stream().map(areaStudy->areaStudy.getName().toLowerCase()).toList();

List<String> areaWithStudy = new ArrayList<>();
if (studyId != null) {
areaWithStudy = areaRepository.findAllByStudyId(studyId).stream()
.map(areaStudy -> areaStudy.getName().toLowerCase())
.toList();
}

List<String> loadsFile = getValidLoadFileNamesWithHorizon(trajectoryPath, area, horizon, listCustomLoadFilesAlreadyChoosed, areaWithStudy);
if (loadsFile.isEmpty()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import lombok.experimental.UtilityClass;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.poi.ss.usermodel.*;
import org.springframework.http.HttpStatus;

Expand All @@ -36,6 +37,8 @@
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static java.util.Objects.nonNull;


/**
* Utility class for file and trajectory related operations.
Expand Down Expand Up @@ -113,9 +116,14 @@ public static List<String> getValidLoadFileNamesWithHorizon(Path dir, String are
}

private static boolean isValidLoadFile(String horizon, String expectedHorizon, String areaFromFile, List<String> areaLoadAlreadyChosen, List<String> areaWithStudy) {
if(!CollectionUtils.isEmpty(areaWithStudy)){
boolean isAreaValid = areaWithStudy.contains(areaFromFile.toLowerCase());
boolean isAreaNotChosen = areaLoadAlreadyChosen.isEmpty() || !areaLoadAlreadyChosen.contains(areaFromFile.toLowerCase());
return horizon.equals(expectedHorizon) && isAreaValid && isAreaNotChosen;
} else {
boolean isAreaNotChosen = areaLoadAlreadyChosen.isEmpty() || !areaLoadAlreadyChosen.contains(areaFromFile.toLowerCase());
return horizon.equals(expectedHorizon) && isAreaNotChosen;
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -507,4 +507,58 @@ void testCheckConsistencyTrajectoryLinkAndArea_WithException_StopsExecution() {



@Test
void processLinkFile_whenStudyIdIsNull() throws IOException {
// Create test Excel file
tempFile = CreateExcelTestUtil.createExcelFileWithTwoSheets(
tempDir,
"TestNullStudyId.xlsx",
List.of("parameters", "2035-2036"),
List.of(
List.of("", "2035-2036"),
List.of("Name", "Winter_HP_Direct_MW", "Winter_HP_Indirect_MW",
"Winter_HC_Direct_MW", "Winter_HC_Indirect_MW",
"Summer_HP_Direct_MW", "Summer_HP_Indirect_MW",
"Summer_HC_Direct_MW", "Summer_HC_Indirect_MW",
"Flowbased_perimeter", "HVDC", "Specific_TS", "Forced_Outage_HVAC")
),
List.of(
List.of(List.of("Hurdle Costs", 0, 5)),
List.of(
List.of("CH-FR", 10, 20, 30, 40, 50, 60, 70, 80, "TRUE", "FALSE", "TRUE", "FALSE"),
List.of("FR-IT", 15, 25, 35, 45, 55, 65, 75, 85, "TRUE", "FALSE", "TRUE", "FALSE")
)
));

// Setup mocks
TrajectoryEntity trajectory = new TrajectoryEntity();
trajectory.setFileName("TestNullStudyId.xlsx");
trajectory.setVersion(1);

when(userService.getCurrentUserDetails()).thenReturn(UserInfoDto.builder().nni("CF001").build());
when(trajectoryRepository.findFirstByFileNameAndHorizonAndTypeOrderByVersionDesc("TestNullStudyId.xlsx", "2035-2036", TrajectoryType.LINK.name()))
.thenReturn(Optional.of(trajectory));

// Mock the save method to return the trajectory
when(trajectoryRepository.save(any(TrajectoryEntity.class))).thenReturn(trajectory);

// Call the method with null studyId
TrajectoryEntity result = linkFileProcessorService.processLinkFile(tempFile, "2035-2036", null);

// Verify that the trajectory was saved
verify(trajectoryRepository, times(1)).save(any(TrajectoryEntity.class));

// Verify that findByTypeAndStudyId was called with AREA and null
verify(trajectoryRepository, never()).findByTypeAndStudyId(TrajectoryType.AREA.name(), null);

// Verify that studyRepository.findById was never called (since studyId is null)
verify(studyRepository, never()).findById(any());

// Verify that warningService.getMessage was never called (since warnings are only checked when studyId is not null)
verify(warningService, never()).getMessage(anyString(), anyString());

// Verify that the result is not null
assertNotNull(result);
}

}
Loading