diff --git a/redaction-report-service-v1/redaction-report-service-api-v1/src/main/java/com/iqser/red/service/redaction/report/v1/api/model/rss/RSSFileResponse.java b/redaction-report-service-v1/redaction-report-service-api-v1/src/main/java/com/iqser/red/service/redaction/report/v1/api/model/rss/RSSFileResponse.java new file mode 100644 index 0000000..4d6061b --- /dev/null +++ b/redaction-report-service-v1/redaction-report-service-api-v1/src/main/java/com/iqser/red/service/redaction/report/v1/api/model/rss/RSSFileResponse.java @@ -0,0 +1,20 @@ +package com.iqser.red.service.redaction.report.v1.api.model.rss; + +import java.util.Map; +import java.util.TreeMap; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class RSSFileResponse { + + private String filename; + private Map result = new TreeMap<>(); + +} diff --git a/redaction-report-service-v1/redaction-report-service-api-v1/src/main/java/com/iqser/red/service/redaction/report/v1/api/model/rss/RSSResponse.java b/redaction-report-service-v1/redaction-report-service-api-v1/src/main/java/com/iqser/red/service/redaction/report/v1/api/model/rss/RSSResponse.java new file mode 100644 index 0000000..77d8eb2 --- /dev/null +++ b/redaction-report-service-v1/redaction-report-service-api-v1/src/main/java/com/iqser/red/service/redaction/report/v1/api/model/rss/RSSResponse.java @@ -0,0 +1,19 @@ +package com.iqser.red.service.redaction.report.v1.api.model.rss; + +import java.util.ArrayList; +import java.util.List; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class RSSResponse { + + private List files = new ArrayList<>(); + +} diff --git a/redaction-report-service-v1/redaction-report-service-api-v1/src/main/java/com/iqser/red/service/redaction/report/v1/api/resource/RSSResource.java b/redaction-report-service-v1/redaction-report-service-api-v1/src/main/java/com/iqser/red/service/redaction/report/v1/api/resource/RSSResource.java new file mode 100644 index 0000000..8cafa52 --- /dev/null +++ b/redaction-report-service-v1/redaction-report-service-api-v1/src/main/java/com/iqser/red/service/redaction/report/v1/api/resource/RSSResource.java @@ -0,0 +1,25 @@ +package com.iqser.red.service.redaction.report.v1.api.resource; + +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseStatus; + +import com.iqser.red.service.redaction.report.v1.api.model.rss.RSSResponse; + +@ResponseStatus(value = HttpStatus.OK) +public interface RSSResource { + + String RSS_PATH = "/rss"; + + String DOSSIER_ID = "dossierId"; + String DOSSIER_ID_PATH_VARIABLE = "/{" + DOSSIER_ID + "}"; + + + @GetMapping(value = RSS_PATH + DOSSIER_ID_PATH_VARIABLE, produces = {MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE}) + RSSResponse getRSS(@PathVariable(DOSSIER_ID) String dossierId, + @RequestParam(value = "fileId", required = false) String fileId); + +} diff --git a/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/controller/RSSController.java b/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/controller/RSSController.java new file mode 100644 index 0000000..0f6cf9e --- /dev/null +++ b/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/controller/RSSController.java @@ -0,0 +1,26 @@ +package com.iqser.red.service.redaction.report.v1.server.controller; + +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import com.iqser.red.service.redaction.report.v1.api.model.rss.RSSResponse; +import com.iqser.red.service.redaction.report.v1.api.resource.RSSResource; +import com.iqser.red.service.redaction.report.v1.server.service.RSSService; + +import lombok.RequiredArgsConstructor; + +@RestController +@RequiredArgsConstructor +public class RSSController implements RSSResource { + + private final RSSService rSSService; + + + public RSSResponse getRSS(@PathVariable(DOSSIER_ID) String dossierId, + @RequestParam(value = "fileId", required = false) String fileId) { + + return rSSService.getRSS(dossierId, fileId); + } + +} diff --git a/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/model/ExcelModel.java b/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/model/ExcelModel.java index 274c746..8862999 100644 --- a/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/model/ExcelModel.java +++ b/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/model/ExcelModel.java @@ -25,5 +25,6 @@ public class ExcelModel { private List writtenRows = new ArrayList<>(); private boolean rowsBeforeRedactionEntryRowsAdded; + private boolean hasRssPlaceHolders; } diff --git a/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/model/PlaceholderModel.java b/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/model/PlaceholderModel.java index e546fde..def0b41 100644 --- a/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/model/PlaceholderModel.java +++ b/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/model/PlaceholderModel.java @@ -18,5 +18,6 @@ public class PlaceholderModel { private final Map dossierAttributesValueByPlaceholder; private final Map fileAttributeIdByPlaceholder; private Map fileAttributeValueByPlaceholder; + private Map rssComponentPlaceholder; } diff --git a/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/service/ExcelReportGenerationService.java b/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/service/ExcelReportGenerationService.java index baafef5..8daa217 100644 --- a/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/service/ExcelReportGenerationService.java +++ b/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/service/ExcelReportGenerationService.java @@ -22,6 +22,7 @@ import static com.iqser.red.service.redaction.report.v1.server.service.Placehold import static com.iqser.red.service.redaction.report.v1.server.service.PlaceholderService.PARAGRAPH_PLACEHOLDER; import static com.iqser.red.service.redaction.report.v1.server.service.PlaceholderService.REDACTION_ENTITY_DISPLAY_NAME_PLACEHOLDER; import static com.iqser.red.service.redaction.report.v1.server.service.PlaceholderService.REDACTION_VALUE_PLACEHOLDER; +import static com.iqser.red.service.redaction.report.v1.server.service.PlaceholderService.RSS_PLACEHOLDER_BASE; import static com.iqser.red.service.redaction.report.v1.server.service.PlaceholderService.SEEDS_FUNCTION_JUSTIFICATION_PLACEHOLDER; import static com.iqser.red.service.redaction.report.v1.server.service.PlaceholderService.SEEDS_FUNCTION_REDACTION_GROUPED_BY_JUSTIFICATION_PAGES_PLACEHOLDER; @@ -73,6 +74,7 @@ import lombok.extern.slf4j.Slf4j; @RequiredArgsConstructor public class ExcelReportGenerationService { + @Timed("redactmanager_generateExcelReport") public void generateExcelReport(List reportEntries, PlaceholderModel placeholderModel, String reportTemplateName, SXSSFWorkbook workbook, String dossierName, FileModel fileModel, ExcelModel excelModel, boolean isLastFile) { @@ -93,7 +95,9 @@ public class ExcelReportGenerationService { excelModel.setRowsBeforeRedactionEntryRowsAdded(true); } - addRedactionEntryRows(sheet, reportEntries, fileModel.getFilename(), excelModel, placeholderModel); + if(excelModel.getRedactionPlaceholderRow() != -1) { + addRedactionEntryRows(sheet, reportEntries, fileModel.getFilename(), excelModel, placeholderModel); + } if (isLastFile) { addRows(workbook, sheet, excelModel.getCellsToCopyAfterRedactionPlaceholderRow(), excelModel.getWrittenRows() @@ -156,6 +160,7 @@ public class ExcelReportGenerationService { Map columnWidths = new HashMap<>(); Map cellsToCopyBeforePlaceholderRow = new HashMap<>(); Map cellsToCopyAfterPlaceholderRow = new HashMap<>(); + boolean hasRssPlaceHolders = false; int placeholderRow = -1; for (int j = 0; j < sheet.getLastRowNum() + 1; j++) { Row actualRow = sheet.getRow(j); @@ -165,9 +170,14 @@ public class ExcelReportGenerationService { if (cell != null) { int columnWidth = sheet.getColumnWidth(i); columnWidths.put(i, columnWidth); - if (containsRedactionPlaceholder(cell.getStringCellValue())) { + String cellStringValue = cell.getStringCellValue(); - placeholderCellPos.put(i, getFunctionForPlaceHolder(cell.getStringCellValue())); + if(cellStringValue.contains(RSS_PLACEHOLDER_BASE)){ + hasRssPlaceHolders = true; + } + + if (containsRedactionPlaceholder(cellStringValue)) { + placeholderCellPos.put(i, getFunctionForPlaceHolder(cellStringValue)); placeholderRow = j; } else { if (placeholderRow == -1) { @@ -181,7 +191,7 @@ public class ExcelReportGenerationService { } } log.debug("Calculate Placeholder Cells took: {}", System.currentTimeMillis() - start); - return new ExcelModel(placeholderCellPos, placeholderRow, columnWidths, cellsToCopyBeforePlaceholderRow, cellsToCopyAfterPlaceholderRow, new ArrayList<>(), false); + return new ExcelModel(placeholderCellPos, placeholderRow, columnWidths, cellsToCopyBeforePlaceholderRow, cellsToCopyAfterPlaceholderRow, new ArrayList<>(), false, hasRssPlaceHolders); } @@ -357,6 +367,10 @@ public class ExcelReportGenerationService { return placeholderModel.getDossierAttributesValueByPlaceholder().get(placeholder); } + if (placeholderModel.getRssComponentPlaceholder() != null && placeholderModel.getRssComponentPlaceholder().containsKey(placeholder)) { + return placeholderModel.getRssComponentPlaceholder().get(placeholder); + } + return null; } diff --git a/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/service/GeneratePlaceholderService.java b/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/service/GeneratePlaceholderService.java index a066690..ef01ed1 100644 --- a/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/service/GeneratePlaceholderService.java +++ b/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/service/GeneratePlaceholderService.java @@ -7,6 +7,7 @@ import static com.iqser.red.service.redaction.report.v1.server.service.Placehold import static com.iqser.red.service.redaction.report.v1.server.service.PlaceholderService.FORMAT_DATE_ISO_PLACEHOLDER; import static com.iqser.red.service.redaction.report.v1.server.service.PlaceholderService.FORMAT_TIME_ISO_PLACEHOLDER; import static com.iqser.red.service.redaction.report.v1.server.service.PlaceholderService.IUCLID_FUNCTION_PLACEHOLDER; +import static com.iqser.red.service.redaction.report.v1.server.service.PlaceholderService.RSS_PLACEHOLDER_BASE; import static com.iqser.red.service.redaction.report.v1.server.service.PlaceholderService.SEEDS_FUNCTION_JUSTIFICATION_PLACEHOLDER; import static com.iqser.red.service.redaction.report.v1.server.service.PlaceholderService.SEEDS_FUNCTION_REDACTION_GROUPED_BY_JUSTIFICATION_PAGES_PLACEHOLDER; @@ -40,6 +41,7 @@ public class GeneratePlaceholderService { private final FileAttributesConfigClient fileAttributesClient; private final DossierAttributesClient dossierAttributesClient; private final DossierAttributesConfigClient dossierAttributesConfigClient; + private final RSSService rSSService; public PlaceholderModel buildPlaceholders(Dossier dossier) { @@ -97,6 +99,23 @@ public class GeneratePlaceholderService { } + public void resolveRssValues(FileModel fileModel, PlaceholderModel placeholderModel) { + + var rssResponse = rSSService.getRSS(fileModel.getDossierId(), fileModel.getId()); + Map rssPlaceholders = new HashMap<>(); + + if (!rssResponse.getFiles().isEmpty()) { + for (Map.Entry rssEntry : rssResponse.getFiles().get(0).getResult().entrySet()) { + rssPlaceholders.put(RSS_PLACEHOLDER_BASE + rssEntry.getKey() + "}}", rssEntry.getValue()); + } + } + + placeholderModel.setRssComponentPlaceholder(rssPlaceholders); + placeholderModel.getPlaceholders().addAll(rssPlaceholders.keySet()); + } + + + public Set getDefaultPlaceholders() { return new HashSet<>(Set.of(FILE_NAME_PLACEHOLDER, FORMAT_DATE_ISO_PLACEHOLDER, FORMAT_DATE_GER_PLACEHOLDER, FORMAT_DATE_ENG_PLACEHOLDER, FORMAT_TIME_ISO_PLACEHOLDER, DOSSIER_NAME_PLACEHOLDER, IUCLID_FUNCTION_PLACEHOLDER, SEEDS_FUNCTION_REDACTION_GROUPED_BY_JUSTIFICATION_PAGES_PLACEHOLDER, SEEDS_FUNCTION_JUSTIFICATION_PLACEHOLDER)); diff --git a/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/service/PlaceholderService.java b/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/service/PlaceholderService.java index 2a7a316..996e2f9 100644 --- a/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/service/PlaceholderService.java +++ b/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/service/PlaceholderService.java @@ -50,6 +50,7 @@ public class PlaceholderService { public static final String REDACTION_ENTITY_DISPLAY_NAME_PLACEHOLDER = "{{redaction.entity.displayName}}"; public static final String FILE_ATTRIBUTE_PLACEHOLDER_BASE = "{{file.attribute."; public static final String DOSSIER_ATTRIBUTE_PLACEHOLDER_BASE = "{{dossier.attribute."; + public static final String RSS_PLACEHOLDER_BASE = "{{component."; public static final DateTimeFormatter FORMAT_DATE_ISO = DateTimeFormatter.ofPattern("yyyy-MM-dd"); public static final DateTimeFormatter FORMAT_DATE_GER = DateTimeFormatter.ofPattern("dd.MM.yyyy"); diff --git a/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/service/RSSService.java b/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/service/RSSService.java new file mode 100644 index 0000000..1f99353 --- /dev/null +++ b/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/service/RSSService.java @@ -0,0 +1,561 @@ +package com.iqser.red.service.redaction.report.v1.server.service; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Set; +import java.util.TreeMap; +import java.util.stream.Collectors; + +import javax.annotation.PostConstruct; + +import org.springframework.stereotype.Service; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import com.iqser.red.service.persistence.service.v1.api.model.dossiertemplate.dossier.file.FileModel; +import com.iqser.red.service.redaction.report.v1.api.model.rss.RSSFileResponse; +import com.iqser.red.service.redaction.report.v1.api.model.rss.RSSResponse; +import com.iqser.red.service.redaction.report.v1.api.resource.RSSResource; +import com.iqser.red.service.redaction.report.v1.server.client.FileStatusClient; +import com.iqser.red.service.redaction.report.v1.server.client.RedactionLogClient; +import com.iqser.red.service.redaction.v1.model.ChangeType; +import com.iqser.red.service.redaction.v1.model.RedactionLog; +import com.iqser.red.service.redaction.v1.model.RedactionLogEntry; + +import lombok.RequiredArgsConstructor; + +@Service +@RequiredArgsConstructor +public class RSSService { + + private final RedactionLogClient redactionLogClient; + private final FileStatusClient statusClient; + + private final Map> guidelineMapping = new HashMap<>(); + + + @PostConstruct + public void init() { + + guidelineMapping.put("Acute Dermal Toxicity", Set.of("OECD 402", "OECD Test Guideline 402", "OECD Guidelines for the Testing of Chemicals No. 402", "OECD Guidelines for Testing of Chemicals, Procedure 402", "OPPTS 870.1200", "OPPTS Guideline Number 870.1200", "EPA 870.1200")); + guidelineMapping.put("Acute inhalation toxicity", Set.of("OECD 403", "OECD Test Guideline 403", "OECD Guidelines for the Testing of Chemicals No. 403", "OECD Guidelines for Testing of Chemicals, Procedure 403", "OECD 436", "OECD Test Guideline 436", "OECD Guidelines for the Testing of Chemicals No. 436", "OECD Guidelines for Testing of Chemicals, Procedure 436", "OPPTS 870.1300", "OPPTS Guideline Number 870.1300", "EPA 870.1300")); + guidelineMapping.put("Acute oral toxicity", Set.of("OECD 425", "OECD Test Guideline 425", "OECD Guidelines for the Testing of Chemicals No. 425", "OECD Guidelines for Testing of Chemicals, Procedure 425", "OECD 423", "OECD Test Guideline 423", "OECD Guidelines for the Testing of Chemicals No. 423", "OECD Guidelines for Testing of Chemicals, Procedure 423", "OPPTS 870.1100", "OPPTS Guideline Number 870.1100", "EPA 870.1100")); + guidelineMapping.put("Eye irritation", Set.of("OECD 437", "OECD Test Guideline 437", "OECD Guidelines for the Testing of Chemicals No. 437", "OECD Guidelines for Testing of Chemicals, Procedure 437", "OECD 405", "OECD Test Guideline 405", "OECD Guidelines for the Testing of Chemicals No. 405", "OECD Guidelines for Testing of Chemicals, Procedure 405", "OPPTS 870.2400", "OPPTS Guideline Number 870.2400", "EPA 870.2400")); + guidelineMapping.put("Skin irritation", Set.of("OECD 404", "OECD Test Guideline 404", "OECD Guidelines for the Testing of Chemicals No. 404", "OECD Guidelines for Testing of Chemicals, Procedure 404", "OECD 439", "OECD Test Guideline 439", "OECD Guidelines for the Testing of Chemicals No. 439", "OECD Guidelines for Testing of Chemicals, Procedure 439", "OPPTS 870.2500", "OPPTS Guideline Number 870.2500", "EPA 870.2500")); + guidelineMapping.put("Skin sentitization", Set.of("OECD 406", "OECD Test Guideline 406", "OECD Guidelines for the Testing of Chemicals No. 406", "OECD Guidelines for Testing of Chemicals, Procedure 406", "OECD 429", "OECD Test Guideline 429", "OECD Guidelines for the Testing of Chemicals No. 429", "OECD Guidelines for Testing of Chemicals, Procedure 429", "OPPTS 870.2600", "OPPTS Guideline Number 870.2600", "EPA 870.2600")); + } + + + public RSSResponse getRSS(String dossierId, String fileId) { + + List files = new ArrayList<>(); + if (fileId != null) { + files.add(statusClient.getFileStatus(dossierId, fileId)); + } else { + files.addAll(statusClient.getDossierStatus(dossierId)); + } + + List rssFileResponses = new ArrayList<>(); + for (FileModel file : files) { + Map resultMap = new TreeMap<>(); + var redactionLog = redactionLogClient.getRedactionLog(dossierId, file.getId(), new ArrayList<>(), true, false); + + redactionLog.getRedactionLogEntry().removeIf(r -> !r.isRedacted() || r.getChanges().get(r.getChanges().size() - 1).getType().equals(ChangeType.REMOVED)); + + resultMap.put("Attachments", getRule46Attachments(redactionLog)); + resultMap.put("Body_weight", getRule42BodyWeight(redactionLog)); + resultMap.put("Clinical_signs", getRule41ClinicalSigns(redactionLog)); + resultMap.put("Conclusions", getRule49Conclusions(redactionLog)); + resultMap.put("Data_access", getRule15DataAccess(redactionLog)); + resultMap.put("Details_of_oral_exposure", getRule31DetailsOfOralExposure(redactionLog)); + resultMap.put("Details_on_study_design", getRule35DetailsOnStudyDesign(redactionLog)); + resultMap.put("Details_on_test_animals_or_test_system_and_environmental_conditions", getRule28DetailsOnTestAnimalsTestSystemEnvironmentalConditions(redactionLog)); + resultMap.put("Doses", getRule32Doses(redactionLog)); + resultMap.put("Endpoint", getRule5Endpoint(redactionLog)); + resultMap.put("Executive_summary", getRule50ExecutiveSummary(redactionLog)); + resultMap.put("GLP_compliance", getRule19GlpCompliance(redactionLog)); + resultMap.put("Gross_pathology", getRule43GrossPathology(redactionLog)); + resultMap.put("Illustration_Picture_Graph", getRule47Illustration(redactionLog)); + resultMap.put("Limit_test", getRule21LimitTest(redactionLog)); + resultMap.put("Mortality", getRule40Mortality(redactionLog)); + resultMap.put("No_Of_animals_per_sex_per_dose", getRule33NoOfAnimalsPerSexPerDose(redactionLog)); + resultMap.put("Rationale_for_reliability_including_deficiencies", get9RationaleForReliabilityIncludingDeficiencies(redactionLog)); + resultMap.put("Reference", getRule14Reference(redactionLog)); + resultMap.put("Route_of_Administration", getRule29RouteOfAdministration(redactionLog)); + resultMap.put("Sex", getRule27Sex(redactionLog)); + resultMap.put("Species", getRule25Species(redactionLog)); + resultMap.put("Specific_details_on_test_material_used_for_the_study_Confidential", getRule24SpecificDetailsOnTestMaterial(redactionLog)); + resultMap.put("Strain", getRule26Strain(redactionLog)); + resultMap.put("Study_period", getRule7StudyPeriod(redactionLog)); + resultMap.put("Test_guideline", getRule17Guideline(redactionLog)); + resultMap.put("Test_material_information", getRule22TestMaterialInformation(redactionLog)); + resultMap.put("Test_type", getRule20TestType(redactionLog)); + resultMap.put("Vehicle", getRule30Vehicle(redactionLog)); + + rssFileResponses.add(new RSSFileResponse(file.getFilename(), resultMap)); + } + + rssFileResponses.sort(Comparator.comparing(RSSFileResponse::getFilename)); + + return new RSSResponse(rssFileResponses); + } + + + private String getRule5Endpoint(RedactionLog redactionLog) { + + var studyType = redactionLog.getRedactionLogEntry().stream().filter(r -> r.getType().equals("study_type")).map(RedactionLogEntry::getValue).findFirst(); + + if (studyType.isPresent()) { + return studyType.get(); + } + + var guideline = redactionLog.getRedactionLogEntry().stream().filter(r -> r.getType().equals("guideline")).map(RedactionLogEntry::getValue).findFirst(); + + if (guideline.isPresent()) { + return mapGuideline(guideline.get()); + } + + return ""; + } + + + private String getRule7StudyPeriod(RedactionLog redactionLog) { + + var startDate = redactionLog.getRedactionLogEntry().stream().filter(r -> r.getType().equals("experimental_start_date")).map(RedactionLogEntry::getValue).findFirst(); + + var endDate = redactionLog.getRedactionLogEntry().stream().filter(r -> r.getType().equals("experimental_end_date")).map(RedactionLogEntry::getValue).findFirst(); + + StringBuilder sb = new StringBuilder(); + startDate.ifPresent(sb::append); + endDate.ifPresent(s -> sb.append(" to ").append(s)); + + return sb.toString(); + } + + + private String get9RationaleForReliabilityIncludingDeficiencies(RedactionLog redactionLog) { + + var guideline = redactionLog.getRedactionLogEntry().stream().filter(r -> r.getType().equals("guideline")).map(RedactionLogEntry::getValue).findFirst(); + + if (guideline.isPresent()) { + return "Guideline study"; + } + + return ""; + } + + + private String getRule14Reference(RedactionLog redactionLog) { + + var title = redactionLog.getRedactionLogEntry().stream().filter(r -> r.getType().equals("title")).map(RedactionLogEntry::getValue).collect(Collectors.joining(" ")); + var author = redactionLog.getRedactionLogEntry().stream().filter(r -> r.getType().equals("author")).map(RedactionLogEntry::getValue).findFirst(); + var completionDate = redactionLog.getRedactionLogEntry().stream().filter(r -> r.getType().equals("completion_date")).map(RedactionLogEntry::getValue).findFirst(); + + StringBuilder sb = new StringBuilder("Study report/"); + sb.append(title).append('/'); + author.ifPresent(s -> sb.append('/').append(s)); + completionDate.ifPresent(s -> sb.append('/').append(s)); + + return sb.toString(); + } + + + private String getRule15DataAccess(RedactionLog redactionLog) { + + var sponsor = redactionLog.getRedactionLogEntry().stream().filter(r -> r.getType().equals("sponsor")).map(RedactionLogEntry::getValue).findFirst(); + + if (sponsor.isPresent()) { + if (sponsor.get().toLowerCase(Locale.ROOT).contains("syngenta")) { + return "Data submitter is data owner"; + } else { + return "No"; + } + } + + return ""; + } + + + private String getRule17Guideline(RedactionLog redactionLog) { + + var guidelines = redactionLog.getRedactionLogEntry().stream().filter(r -> r.getType().equals("guideline")).map(RedactionLogEntry::getValue).collect(Collectors.toSet()); + + StringBuilder stringBuilder = new StringBuilder(); + int i = 1; + + for (String guideline : guidelines) { + stringBuilder.append(i).append(") according to guideline ").append(guideline).append(" (").append(mapGuideline(guideline)).append(") "); + i++; + } + + return stringBuilder.toString(); + } + + + private String getRule19GlpCompliance(RedactionLog redactionLog) { + + var glpCompliance = redactionLog.getRedactionLogEntry().stream().filter(r -> r.getType().equals("glp_compliance")).map(RedactionLogEntry::getValue).findFirst(); + + return glpCompliance.map(s -> "Yes. " + s).orElse("No."); + + } + + + private String getRule20TestType(RedactionLog redactionLog) { + + var upAndDownProcedure = redactionLog.getRedactionLogEntry().stream().filter(r -> r.getType().equals("up_and_down_procedure")).map(RedactionLogEntry::getValue).findFirst(); + + if (upAndDownProcedure.isPresent()) { + return "Up down Procedure"; + } + + var guideline8701100 = redactionLog.getRedactionLogEntry() + .stream() + .filter(r -> r.getType().equals("guideline")) + .map(RedactionLogEntry::getValue) + .filter(g -> g.contains("870.1100")) + .findFirst(); + + if (guideline8701100.isPresent()) { + return "Up down Procedure"; + } + + return "No"; + } + + + private String getRule21LimitTest(RedactionLog redactionLog) { + + var limitTest = redactionLog.getRedactionLogEntry().stream().filter(r -> r.getType().equals("limit_test")).map(RedactionLogEntry::getValue).findFirst(); + + var noLimitTest = redactionLog.getRedactionLogEntry().stream().filter(r -> r.getType().equals("no_limit_test")).map(RedactionLogEntry::getValue).findFirst(); + + if (limitTest.isPresent() && noLimitTest.isEmpty()) { + return "Yes"; + } + + return "No"; + } + + + private String getRule22TestMaterialInformation(RedactionLog redactionLog) { + + var testSubstance = redactionLog.getRedactionLogEntry().stream().filter(r -> r.getType().equals("test_substance")).map(RedactionLogEntry::getValue).findFirst(); + + return testSubstance.map(s -> s + "/CAS number").orElse(""); + + } + + + private String getRule24SpecificDetailsOnTestMaterial(RedactionLog redactionLog) { + + var materials = redactionLog.getRedactionLogEntry().stream().filter(r -> r.getType().equals("materials")).map(RedactionLogEntry::getValue).collect(Collectors.toList()); + StringBuilder sb = new StringBuilder(); + for (var material : materials) { + sb.append(material).append(' '); + } + + return sb.toString(); + } + + + private String getRule25Species(RedactionLog redactionLog) { + + var species = redactionLog.getRedactionLogEntry().stream().filter(r -> r.getType().equals("species")).map(RedactionLogEntry::getValue).findFirst(); + + return species.orElse(""); + + } + + + private String getRule26Strain(RedactionLog redactionLog) { + + var strain = redactionLog.getRedactionLogEntry().stream().filter(r -> r.getType().equals("strain")).map(RedactionLogEntry::getValue).findFirst(); + + return strain.orElse(""); + + } + + + private String getRule27Sex(RedactionLog redactionLog) { + + var sex = redactionLog.getRedactionLogEntry().stream().filter(r -> r.getType().equals("sex")).map(RedactionLogEntry::getValue).findFirst(); + + return sex.orElse(""); + } + + + private String getRule28DetailsOnTestAnimalsTestSystemEnvironmentalConditions(RedactionLog redactionLog) { + + return redactionLog.getRedactionLogEntry() + .stream() + .filter(r -> r.getType().equals("test_animals")) + .sorted(Comparator.comparing(e -> e.getPositions().get(0).getTopLeft().getX())) + .sorted(Comparator.comparing(e -> e.getPositions().get(0).getTopLeft().getY(), Comparator.reverseOrder())) + .sorted(Comparator.comparing(e -> e.getPositions().get(0).getPage())) + .map(RedactionLogEntry::getValue) + .collect(Collectors.joining(" ")); + } + + + private String getRule29RouteOfAdministration(RedactionLog redactionLog) { + + var routeOfAdministration = redactionLog.getRedactionLogEntry() + .stream() + .filter(r -> r.getType().equals("route_of_administration")) + .map(RedactionLogEntry::getValue) + .findFirst(); + + return routeOfAdministration.orElse(""); + + } + + + private String getRule30Vehicle(RedactionLog redactionLog) { + + var vehicles = redactionLog.getRedactionLogEntry().stream().filter(r -> r.getType().equals("vehicle")).map(RedactionLogEntry::getValue).collect(Collectors.toList()); + + if (vehicles.isEmpty()) { + return "Not Applicable"; + } + + return String.join(" / ", vehicles); + } + + + private String getRule31DetailsOfOralExposure(RedactionLog redactionLog) { + + var oralExposures = redactionLog.getRedactionLogEntry() + .stream() + .filter(r -> r.getType().equals("oral_exposure")) + .map(RedactionLogEntry::getValue) + .collect(Collectors.toList()); + StringBuilder sb = new StringBuilder(); + for (var oralExposure : oralExposures) { + sb.append(oralExposure).append(" / "); + } + + return sb.toString(); + } + + + private String getRule32Doses(RedactionLog redactionLog) { + + var dosagesPerAnimal = redactionLog.getRedactionLogEntry() + .stream() + .filter(r -> r.getType().equals("dosage_per_animal")) + .map(r -> r.getValue().replaceAll("\\n", "").trim()) + .collect(Collectors.toSet()); + var dosages = redactionLog.getRedactionLogEntry() + .stream() + .filter(r -> r.getType().equals("dosage")) + .map(r -> r.getValue().replaceAll("\\n", "").trim()) + .collect(Collectors.toSet()); + + Set allDosages = new HashSet<>(); + allDosages.addAll(dosagesPerAnimal); + allDosages.addAll(dosages); + + StringBuilder sb = new StringBuilder(); + for (var dosagePerAnimal : allDosages) { + sb.append(dosagePerAnimal).append(" mg/kg bw").append(" , "); + } + + return sb.toString().trim(); + } + + + private String getRule33NoOfAnimalsPerSexPerDose(RedactionLog redactionLog) { + + var dosagesPerAnimal = redactionLog.getRedactionLogEntry() + .stream() + .filter(r -> r.getType().equals("dosage_per_animal")) + .map(RedactionLogEntry::getValue) + .collect(Collectors.toList()); + var uniqueDosagesPerAnimal = new HashSet<>(dosagesPerAnimal); + var uniqueAnimalNumbers = redactionLog.getRedactionLogEntry() + .stream() + .filter(r -> r.getType().equals("animal_number")) + .map(RedactionLogEntry::getValue) + .collect(Collectors.toSet()); + + if (uniqueDosagesPerAnimal.size() == 1 && uniqueAnimalNumbers.size() > 1) { + return uniqueAnimalNumbers.size() + " * " + uniqueDosagesPerAnimal.iterator().next() + " mg/kg bw"; + } + + Map> dosagesPerAnimalMap = new HashMap<>(); + for (var dosage : dosagesPerAnimal) { + dosagesPerAnimalMap.computeIfAbsent(dosage, (x) -> new ArrayList<>()).add(dosage); + } + + StringBuilder sb = new StringBuilder(); + for (Map.Entry> entry : dosagesPerAnimalMap.entrySet()) { + sb.append(entry.getValue().size()).append(" * ").append(entry.getKey()).append(" mg/kg bw, "); + } + + return sb.toString().trim(); + } + + + private String getRule35DetailsOnStudyDesign(RedactionLog redactionLog) { + + var necropsy = redactionLog.getRedactionLogEntry().stream().filter(r -> r.getType().equals("necropsy")).map(RedactionLogEntry::getValue).findFirst(); + var durationOfObservation = redactionLog.getRedactionLogEntry() + .stream() + .filter(r -> r.getType().equals("duration_of_observation")) + .map(RedactionLogEntry::getValue) + .findFirst(); + var frequencyOfObservation = redactionLog.getRedactionLogEntry() + .stream() + .filter(r -> r.getType().equals("frequency_of_observation")) + .map(RedactionLogEntry::getValue) + .findFirst(); + var bodyWeight = redactionLog.getRedactionLogEntry().stream().filter(r -> r.getType().equals("body_weight")).map(RedactionLogEntry::getValue).findFirst(); + + StringBuilder sb = new StringBuilder("Duration of obersvation period following administration: "); + if (durationOfObservation.isPresent()) { + sb.append(durationOfObservation.get()).append(" \n"); + } else { + sb.append("/").append(" \n"); + } + sb.append("Frequency of observations and weighing: "); + if (frequencyOfObservation.isPresent()) { + sb.append(frequencyOfObservation.get()).append(" "); + } else { + sb.append(" "); + } + if (bodyWeight.isPresent()) { + sb.append(bodyWeight.get()).append(" \n"); + } else { + sb.append(" \n"); + } + sb.append("Necropsy of survivors performed: "); + if (necropsy.isPresent()) { + sb.append("Yes. ").append(necropsy.get()); + } else { + sb.append("No"); + } + return sb.toString().trim(); + } + + + private String getRule40Mortality(RedactionLog redactionLog) { + + var mortalitys = redactionLog.getRedactionLogEntry().stream().filter(r -> r.getType().equals("mortality")).map(RedactionLogEntry::getValue).collect(Collectors.toList()); + StringBuilder sb = new StringBuilder(); + for (var mortality : mortalitys) { + sb.append(mortality).append(' '); + } + + return sb.toString(); + } + + + private String getRule41ClinicalSigns(RedactionLog redactionLog) { + + var clinicalSigns = redactionLog.getRedactionLogEntry() + .stream() + .filter(r -> r.getType().equals("clinical_signs")) + .map(RedactionLogEntry::getValue) + .collect(Collectors.toList()); + StringBuilder sb = new StringBuilder(); + for (var clinicalSign : clinicalSigns) { + sb.append(clinicalSign).append(" / "); + } + + return sb.toString(); + } + + + private String getRule42BodyWeight(RedactionLog redactionLog) { + + var bodyWeights = redactionLog.getRedactionLogEntry().stream().filter(r -> r.getType().equals("body_weight")).map(RedactionLogEntry::getValue).collect(Collectors.toList()); + StringBuilder sb = new StringBuilder(); + for (var bodyWeight : bodyWeights) { + sb.append(bodyWeight).append(" / "); + } + + return sb.toString(); + } + + + private String getRule43GrossPathology(RedactionLog redactionLog) { + + var grossPathologys = redactionLog.getRedactionLogEntry() + .stream() + .filter(r -> r.getType().equals("gross_pathology")) + .map(RedactionLogEntry::getValue) + .collect(Collectors.toList()); + StringBuilder sb = new StringBuilder(); + for (var grossPathology : grossPathologys) { + sb.append(grossPathology).append(" / "); + } + + return sb.toString(); + } + + + private String getRule46Attachments(RedactionLog redactionLog) { + + var attachments = redactionLog.getRedactionLogEntry().stream().filter(r -> r.getType().equals("attachments")).map(RedactionLogEntry::getValue).findFirst(); + + if (attachments.isPresent()) { + return "Yes"; + } + + return "None"; + } + + + private String getRule47Illustration(RedactionLog redactionLog) { + + var illustration = redactionLog.getRedactionLogEntry().stream().filter(r -> r.getType().equals("formula") || r.getType().equals("image")).findFirst(); + if (illustration.isPresent()) { + return "Yes"; + } + return "None"; + } + + + private String getRule49Conclusions(RedactionLog redactionLog) { + + var conclusions = redactionLog.getRedactionLogEntry().stream().filter(r -> r.getType().equals("conclusion")).map(RedactionLogEntry::getValue).collect(Collectors.toList()); + + if (conclusions.isEmpty()) { + return ""; + } + + return conclusions.get(conclusions.size() - 1); + } + + + private String getRule50ExecutiveSummary(RedactionLog redactionLog) { + + return redactionLog.getRedactionLogEntry() + .stream() + .filter(r -> r.getType().equals("executive_summary")) + .sorted(Comparator.comparing(e -> e.getPositions().get(0).getTopLeft().getX())) + .sorted(Comparator.comparing(e -> e.getPositions().get(0).getTopLeft().getY(), Comparator.reverseOrder())) + .sorted(Comparator.comparing(e -> e.getPositions().get(0).getPage())) + .map(RedactionLogEntry::getValue) + .collect(Collectors.joining(" ")); + } + + + private String mapGuideline(String guideline) { + + for (Map.Entry> entry : guidelineMapping.entrySet()) { + if (entry.getValue().contains(guideline)) { + return entry.getKey(); + } + } + return ""; + } + +} diff --git a/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/service/ReportGenerationService.java b/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/service/ReportGenerationService.java index dba01b1..a0a2edd 100644 --- a/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/service/ReportGenerationService.java +++ b/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/service/ReportGenerationService.java @@ -47,6 +47,7 @@ public class ReportGenerationService { private final GeneratePlaceholderService generatePlaceholderService; private final DictionaryClient dictionaryClient; private final ReportTemplateSettings reportTemplateSettings; + private final RSSService rSSService; @SneakyThrows @Timed("redactmanager_generateReports") @@ -113,6 +114,9 @@ public class ReportGenerationService { var isLastFile = j == reportMessage.getFileIds().size() - 1; for (MultiFileWorkbook multiFileWorkbook : multiFileWorkbookReportTemplates) { + if(multiFileWorkbook.getExcelModel().isHasRssPlaceHolders()){ + generatePlaceholderService.resolveRssValues(fileStatus, placeholderModel); + } excelTemplateReportGenerationService.generateExcelReport(reportEntries, placeholderModel, multiFileWorkbook.getTemplateName(), multiFileWorkbook.getWriteWorkbook(), dossier.getDossierName(), fileStatus, multiFileWorkbook.getExcelModel(), isLastFile); } @@ -177,6 +181,10 @@ public class ReportGenerationService { writeWorkbook.createSheet(sheet.getSheetName()); } var excelModel = excelTemplateReportGenerationService.calculateExcelModel(readWorkbook.getSheetAt(0)); + if(excelModel.isHasRssPlaceHolders()){ + generatePlaceholderService.resolveRssValues(fileStatus, placeholderModel); + } + excelTemplateReportGenerationService.generateExcelReport(reportEntries, placeholderModel, templateName, writeWorkbook, dossier.getDossierName(), fileStatus, excelModel, true); byte[] template = excelTemplateReportGenerationService.toByteArray(writeWorkbook); String storageId = reportStorageService.storeObject(downloadId, template); diff --git a/redaction-report-service-v1/redaction-report-service-server-v1/src/test/java/com/iqser/red/service/redaction/report/v1/server/RedactionReportIntegrationTest.java b/redaction-report-service-v1/redaction-report-service-server-v1/src/test/java/com/iqser/red/service/redaction/report/v1/server/RedactionReportIntegrationTest.java index 3228854..749fb2d 100644 --- a/redaction-report-service-v1/redaction-report-service-server-v1/src/test/java/com/iqser/red/service/redaction/report/v1/server/RedactionReportIntegrationTest.java +++ b/redaction-report-service-v1/redaction-report-service-server-v1/src/test/java/com/iqser/red/service/redaction/report/v1/server/RedactionReportIntegrationTest.java @@ -394,7 +394,7 @@ public class RedactionReportIntegrationTest { var defaultPlaceHolder = new HashSet<>(Set.of(FILE_NAME_PLACEHOLDER, FORMAT_DATE_ISO_PLACEHOLDER, FORMAT_DATE_GER_PLACEHOLDER, FORMAT_DATE_ENG_PLACEHOLDER, FORMAT_TIME_ISO_PLACEHOLDER, DOSSIER_NAME_PLACEHOLDER, IUCLID_FUNCTION_PLACEHOLDER, SEEDS_FUNCTION_REDACTION_GROUPED_BY_JUSTIFICATION_PAGES_PLACEHOLDER, SEEDS_FUNCTION_JUSTIFICATION_PLACEHOLDER)); defaultPlaceHolder.addAll(dossierAttributes.keySet()); defaultPlaceHolder.addAll(fileAttributes.keySet()); - return new PlaceholderModel(defaultPlaceHolder, imagePlaceholders, dossierAttributes, null, fileAttributes); + return new PlaceholderModel(defaultPlaceHolder, imagePlaceholders, dossierAttributes, null, fileAttributes, new HashMap<>()); } }