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 bd0be22..4e9c79b 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 @@ -52,6 +52,10 @@ public class PlaceholderService { public static final String IUCLID_FUNCTION_PLACEHOLDER = "{{function.iuclidreport}}"; + public static final String SEEDS_FUNCTION_REDACTION_GROUPED_BY_JUSTIFICATION_PAGES_PLACEHOLDER = "{{function.seeds.redactionGroupedByJustification.pages}}"; + public static final String SEEDS_FUNCTION_JUSTIFICATION_PLACEHOLDER = "{{function.seeds.justification}}"; + + private final ReportTemplateClient reportTemplateClient; private final ReportStorageService reportStorageService; @@ -60,7 +64,7 @@ public class PlaceholderService { public List getGeneralPlaceholders() { - return List.of(FILE_NAME_PLACEHOLDER, PAGE_PLACEHOLDER, PARAGRAPH_PLACEHOLDER, JUSTIFICATION_PLACEHOLDER, EXCERPT_PLACEHOLDER, FORMAT_DATE_ISO_PLACEHOLDER, FORMAT_DATE_GER_PLACEHOLDER, FORMAT_DATE_ENG_PLACEHOLDER, FORMAT_TIME_ISO_PLACEHOLDER, DOSSIER_NAME_PLACEHOLDER, IUCLID_FUNCTION_PLACEHOLDER, REDACTION_VALUE_PLACEHOLDER, JUSTIFICATION_LEGAL_BASIS_PLACEHOLDER, JUSTIFICATION_TEXT_PLACEHOLDER); + return List.of(FILE_NAME_PLACEHOLDER, PAGE_PLACEHOLDER, PARAGRAPH_PLACEHOLDER, JUSTIFICATION_PLACEHOLDER, EXCERPT_PLACEHOLDER, FORMAT_DATE_ISO_PLACEHOLDER, FORMAT_DATE_GER_PLACEHOLDER, FORMAT_DATE_ENG_PLACEHOLDER, FORMAT_TIME_ISO_PLACEHOLDER, DOSSIER_NAME_PLACEHOLDER, IUCLID_FUNCTION_PLACEHOLDER, REDACTION_VALUE_PLACEHOLDER, JUSTIFICATION_LEGAL_BASIS_PLACEHOLDER, JUSTIFICATION_TEXT_PLACEHOLDER, SEEDS_FUNCTION_REDACTION_GROUPED_BY_JUSTIFICATION_PAGES_PLACEHOLDER, SEEDS_FUNCTION_JUSTIFICATION_PLACEHOLDER); } public Set getPlaceholdersOfTemplate(String dossierTemplateId, String reportTemplateId) { diff --git a/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/service/WordReportGenerationService.java b/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/service/WordReportGenerationService.java index 6c197a8..11d6bd0 100644 --- a/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/service/WordReportGenerationService.java +++ b/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/service/WordReportGenerationService.java @@ -20,24 +20,24 @@ import static com.iqser.red.service.redaction.report.v1.server.service.Placehold import static com.iqser.red.service.redaction.report.v1.server.service.PlaceholderService.PAGE_PLACEHOLDER; 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_VALUE_PLACEHOLDER; +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; import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; -import java.time.Instant; -import java.time.LocalDate; import java.time.OffsetDateTime; -import java.time.ZoneOffset; -import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.Arrays; import java.util.Base64; +import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; +import java.util.stream.Collectors; import javax.imageio.ImageIO; @@ -136,7 +136,7 @@ public class WordReportGenerationService { for (ImagePlaceholder imagePlaceholder : imagePlaceholders) { replaceImagePlaceholders(doc, imagePlaceholder); } - addTableRows(doc, reportEntries, fileStatus.getFilename()); + addTableRows(doc, reportEntries, fileStatus.getFilename(), fileStatus, fileAttributePlaceholders); for (String placeholder : placeholders) { String placeholderValue = getPlaceholderValue(placeholder, dossier, fileStatus, fileAttributePlaceholders, dossierAttributesPlaceholder, reportEntries); if (placeholderValue != null) { @@ -169,7 +169,7 @@ public class WordReportGenerationService { private List getDefaultPlaceholders() { List defPlaceholders = new ArrayList<>(); - defPlaceholders.addAll(Arrays.asList(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)); + defPlaceholders.addAll(Arrays.asList(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)); return defPlaceholders; } @@ -218,13 +218,13 @@ public class WordReportGenerationService { if (fileStatus.getFileAttributes().containsKey(id)) { return fileStatus.getFileAttributes().get(id); } else { - return null; + return ""; } } if (dossierAttributesPlaceholders.containsKey(placeholder)) { return dossierAttributesPlaceholders.get(placeholder); } - throw new RuntimeException("unknown placeholder"); + return ""; } @@ -310,7 +310,7 @@ public class WordReportGenerationService { for (XWPFTable tbl : doc.getTables()) { String tblText = tbl.getText(); - if (tblText.contains(PAGE_PLACEHOLDER) || tblText.contains(PARAGRAPH_PLACEHOLDER) || tblText.contains(JUSTIFICATION_PLACEHOLDER) || tblText.contains(EXCERPT_PLACEHOLDER) || tblText.contains(JUSTIFICATION_PARAGRAPH_PLACEHOLDER) || tblText.contains(JUSTIFICATION_REASON_PLACEHOLDER) || tblText.contains(JUSTIFICATION_LEGAL_BASIS_PLACEHOLDER) || tblText.contains(JUSTIFICATION_TEXT_PLACEHOLDER)) { + if (tblText.contains(PAGE_PLACEHOLDER) || tblText.contains(PARAGRAPH_PLACEHOLDER) || tblText.contains(JUSTIFICATION_PLACEHOLDER) || tblText.contains(EXCERPT_PLACEHOLDER) || tblText.contains(JUSTIFICATION_PARAGRAPH_PLACEHOLDER) || tblText.contains(JUSTIFICATION_REASON_PLACEHOLDER) || tblText.contains(JUSTIFICATION_LEGAL_BASIS_PLACEHOLDER) || tblText.contains(JUSTIFICATION_TEXT_PLACEHOLDER) || tblText.contains(SEEDS_FUNCTION_REDACTION_GROUPED_BY_JUSTIFICATION_PAGES_PLACEHOLDER) || tblText.contains(SEEDS_FUNCTION_JUSTIFICATION_PLACEHOLDER)) { return tbl; } } @@ -320,11 +320,12 @@ public class WordReportGenerationService { private boolean containsRedactionPlaceholder(String text) { - return text.contains(FILE_NAME_PLACEHOLDER) || text.contains(PAGE_PLACEHOLDER) || text.contains(PARAGRAPH_PLACEHOLDER) || text.contains(JUSTIFICATION_PLACEHOLDER) || text.contains(EXCERPT_PLACEHOLDER) || text.contains(JUSTIFICATION_PARAGRAPH_PLACEHOLDER) || text.contains(JUSTIFICATION_REASON_PLACEHOLDER) || text.contains(REDACTION_VALUE_PLACEHOLDER) || text.contains(JUSTIFICATION_LEGAL_BASIS_PLACEHOLDER) || text.contains(JUSTIFICATION_TEXT_PLACEHOLDER); + return text.contains(FILE_NAME_PLACEHOLDER) || text.contains(PAGE_PLACEHOLDER) || text.contains(PARAGRAPH_PLACEHOLDER) || text.contains(JUSTIFICATION_PLACEHOLDER) || text.contains(EXCERPT_PLACEHOLDER) || text.contains(JUSTIFICATION_PARAGRAPH_PLACEHOLDER) || text.contains(JUSTIFICATION_REASON_PLACEHOLDER) || text.contains(REDACTION_VALUE_PLACEHOLDER) || text.contains(JUSTIFICATION_LEGAL_BASIS_PLACEHOLDER) || text.contains(JUSTIFICATION_TEXT_PLACEHOLDER) || text.contains(SEEDS_FUNCTION_REDACTION_GROUPED_BY_JUSTIFICATION_PAGES_PLACEHOLDER) || text.contains(SEEDS_FUNCTION_JUSTIFICATION_PLACEHOLDER) || text.contains("{{") && text.contains("}}"); } - private void addTableRows(XWPFDocument doc, List reportEntries, String filename) { + private void addTableRows(XWPFDocument doc, List reportEntries, String filename, + FileModel fileStatus, Map fileAttributePlaceholders) { XWPFTable table = getRedactionTable(doc); if (table == null) { @@ -347,16 +348,30 @@ public class WordReportGenerationService { } table.removeRow(placeholderRow); - reportEntries.forEach(entry -> { - XWPFTableRow row = table.createRow(); - for (Map.Entry entry1 : placeholderCellPos.entrySet()) { - if (!entry1.getValue().isEmpty()) { - setText(row.getCell(entry1.getKey()), replaceTextPlaceholderWithEntries(entry, filename, entry1.getValue())); - } else { - setText(row.getCell(entry1.getKey()), ""); + if (placeholderCellPos.containsValue(SEEDS_FUNCTION_REDACTION_GROUPED_BY_JUSTIFICATION_PAGES_PLACEHOLDER)) { + var redactionsPerJustification = getRedactionsPerJustification(reportEntries); + for (Map.Entry> entry : redactionsPerJustification.entrySet()) { + XWPFTableRow row = table.createRow(); + for (Map.Entry entry1 : placeholderCellPos.entrySet()) { + if (!entry1.getValue().isEmpty()) { + setText(row.getCell(entry1.getKey()), replaceSeedsPlaceholder(entry, filename, entry1.getValue(), fileStatus, fileAttributePlaceholders)); + } else { + setText(row.getCell(entry1.getKey()), ""); + } } } - }); + } else { + reportEntries.forEach(entry -> { + XWPFTableRow row = table.createRow(); + for (Map.Entry entry1 : placeholderCellPos.entrySet()) { + if (!entry1.getValue().isEmpty()) { + setText(row.getCell(entry1.getKey()), replaceTextPlaceholderWithEntries(entry, filename, entry1.getValue())); + } else { + setText(row.getCell(entry1.getKey()), ""); + } + } + }); + } } @@ -396,6 +411,37 @@ public class WordReportGenerationService { } + private String replaceSeedsPlaceholder(Map.Entry> entry, String filename, + String placeholder, FileModel fileStatus, + Map fileAttributePlaceholders) { + + if (placeholder.equals(SEEDS_FUNCTION_REDACTION_GROUPED_BY_JUSTIFICATION_PAGES_PLACEHOLDER)) { + return entry.getValue() + .stream() + .map(ReportRedactionEntry::getPage) + .distinct() + .map(Object::toString) + .collect(Collectors.joining(", ")); + } + if (placeholder.equals(SEEDS_FUNCTION_JUSTIFICATION_PLACEHOLDER)) { + return entry.getKey(); + } + if (placeholder.equals(FILE_NAME_PLACEHOLDER)) { + return filename; + } + if (fileAttributePlaceholders.containsKey(placeholder)) { + String id = fileAttributePlaceholders.get(placeholder); + + if (fileStatus.getFileAttributes().containsKey(id)) { + return fileStatus.getFileAttributes().get(id); + } else { + return null; + } + } + return ""; + } + + private Dimension2DDouble getImageDimension(ByteArrayInputStream bais) throws IOException { BufferedImage bufImg = ImageIO.read(bais); @@ -428,6 +474,10 @@ public class WordReportGenerationService { return new ColoredText(textForLine, null); } + private Map> getRedactionsPerJustification(List reportRedactionEntryList) { + return reportRedactionEntryList.stream().sorted(Comparator.comparing(ReportRedactionEntry::getPage)).collect(Collectors.groupingBy(ReportRedactionEntry::getJustification)); + } + private byte[] toByteArray(XWPFDocument doc) throws IOException { diff --git a/redaction-report-service-v1/redaction-report-service-server-v1/src/test/java/com/iqser/red/service/redaction/report/v1/server/PlaceholderTest.java b/redaction-report-service-v1/redaction-report-service-server-v1/src/test/java/com/iqser/red/service/redaction/report/v1/server/PlaceholderTest.java index 8fccb49..3071870 100644 --- a/redaction-report-service-v1/redaction-report-service-server-v1/src/test/java/com/iqser/red/service/redaction/report/v1/server/PlaceholderTest.java +++ b/redaction-report-service-v1/redaction-report-service-server-v1/src/test/java/com/iqser/red/service/redaction/report/v1/server/PlaceholderTest.java @@ -61,7 +61,7 @@ public class PlaceholderTest { // Assert Assert.assertNotNull(placeholders); - Assert.assertEquals(placeholders.size(), 14); + Assert.assertEquals(placeholders.size(), 16); } @Test 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 3f0cadc..0823db3 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 @@ -149,14 +149,14 @@ public class RedactionReportIntegrationTest { .builder() .id("3e9b9569-5d2e-4619-848b-dd0a3e96527f") .label("Document Title") - .placeholder("{{file.attribute.placeholder}}") + .placeholder("{{file.attribute.Path}}") .type(FileAttributeType.TEXT) .build(); when(fileAttributesConfigClient.getFileAttributeConfigs(dossierTemplateId)).thenReturn(List.of(fileAttributeConfig1)); - FileModel fileStatus = FileModel.builder().filename("filename").fileAttributes(Map.of("3e9b9569-5d2e-4619-848b-dd0a3e96527f", "Test")).build(); + FileModel fileStatus = FileModel.builder().filename("FileABCD").fileAttributes(Map.of("3e9b9569-5d2e-4619-848b-dd0a3e96527f", "Test")).build(); Dossier project = Dossier.builder().id("dossierId").dossierName("projectName").build(); @@ -167,7 +167,7 @@ public class RedactionReportIntegrationTest { .storageId(storageId) .build()); - ClassPathResource templateResource = new ClassPathResource("templates/Justification Appendix A1.docx"); + ClassPathResource templateResource = new ClassPathResource("templates/Seeds - New Justification Form.docx"); when(reportStorageService.getReportTemplate(storageId)).thenReturn(IOUtils.toByteArray(templateResource.getInputStream())); ReportTemplate reportTemplate = ReportTemplate.builder() .dossierTemplateId("dossierTemplateId") @@ -523,4 +523,50 @@ public class RedactionReportIntegrationTest { } } + + @Test + @SneakyThrows + public void testSeedsFunctionService() { + String dossierTemplateId = "dossierTemplateId"; + + ClassPathResource redactionLogResource = new ClassPathResource("files/redactionLog2817.json"); + RedactionLog redactionLog = objectMapper.readValue(redactionLogResource.getInputStream(), RedactionLog.class); + + ClassPathResource legalBasisMappingResource = new ClassPathResource("files/legalBasisMappingNew.json"); + List legalBasisMapping = objectMapper.readValue(legalBasisMappingResource.getInputStream(), new TypeReference<>() { + }); + + List reportEntries = redactionLogConverterService.convertAndSort(redactionLog, legalBasisMapping); + + when(dossierAttributesConfigClient.getDossierAttributes(dossierTemplateId)).thenReturn(new ArrayList<>()); + when(dossierAttributesClient.getDossierAttributes("dossierId")).thenReturn(new ArrayList<>()); + when(fileAttributesConfigClient.getFileAttributeConfigs(dossierTemplateId)).thenReturn(new ArrayList<>()); + + + FileModel fileStatus = FileModel.builder().filename("VV123456").build(); + + Dossier project = Dossier.builder().id("dossierId").dossierName("projectName").build(); + + String templateId = "templateId"; + String storageId = "storageId"; + when(reportTemplateClient.getReportTemplate(dossierTemplateId, templateId)).thenReturn(ReportTemplate.builder() + .dossierTemplateId(dossierTemplateId) + .storageId(storageId) + .build()); + + ClassPathResource templateResource = new ClassPathResource("templates/Seeds - New Justification Form.docx"); + when(reportStorageService.getReportTemplate(storageId)).thenReturn(IOUtils.toByteArray(templateResource.getInputStream())); + ReportTemplate reportTemplate = ReportTemplate.builder() + .dossierTemplateId("dossierTemplateId") + .templateId("templateId") + .fileName("fileName") + .storageId("storageId") + .uploadDate(OffsetDateTime.now()) + .build(); + byte[] report = wordReportGenerationService.generateReport(ReportType.WORD_SINGLE_FILE, reportEntries, dossierTemplateId, reportTemplate, fileStatus, project); + + try (FileOutputStream fileOutputStream = new FileOutputStream(getTemporaryDirectory() + "/seedsReport.docx")) { + fileOutputStream.write(report); + } + } } diff --git a/redaction-report-service-v1/redaction-report-service-server-v1/src/test/resources/templates/Seeds - New Justification Form.docx b/redaction-report-service-v1/redaction-report-service-server-v1/src/test/resources/templates/Seeds - New Justification Form.docx new file mode 100644 index 0000000..f2cdbe6 Binary files /dev/null and b/redaction-report-service-v1/redaction-report-service-server-v1/src/test/resources/templates/Seeds - New Justification Form.docx differ