Pull request #66: RED-2115: Added generating dossier status report

Merge in RED/redaction-report-service from RED-2115-rrs1 to master

* commit '1b76363316b52d21a403a69ee2f02d4e09effde3':
  RED-2115: Added generating dossier status report
This commit is contained in:
Ali Oezyetimoglu 2021-09-08 12:34:09 +02:00 committed by Dominique Eiflaender
commit 3d3d955a7b
4 changed files with 294 additions and 0 deletions

View File

@ -0,0 +1,17 @@
package com.iqser.red.service.redaction.report.v1.api.model;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class StatusReportResponse {
private byte [] report;
private String filename;
}

View File

@ -0,0 +1,20 @@
package com.iqser.red.service.redaction.report.v1.api.resource;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import com.iqser.red.service.redaction.report.v1.api.model.StatusReportResponse;
public interface StatusReportResource {
String STATUS_REPORT = "/statusReport";
String DOSSIER_ID = "dossierId";
String DOSSIER_ID_PATH_VARIABLE = "/{" + DOSSIER_ID + "}";
@GetMapping(value = STATUS_REPORT + DOSSIER_ID_PATH_VARIABLE, produces = MediaType.APPLICATION_JSON_VALUE)
StatusReportResponse generateStatusReport(@PathVariable(DOSSIER_ID) String dossierId);
}

View File

@ -0,0 +1,155 @@
package com.iqser.red.service.redaction.report.v1.server.service;
import static com.iqser.red.service.redaction.report.v1.server.service.PlaceholderService.FORMAT_DATE_ISO;
import java.io.ByteArrayOutputStream;
import java.time.OffsetDateTime;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFFont;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.stereotype.Service;
import com.iqser.red.service.configuration.v1.api.model.FileAttributeConfig;
import com.iqser.red.service.configuration.v1.api.model.FileAttributesConfig;
import com.iqser.red.service.file.management.v1.api.model.Dossier;
import com.iqser.red.service.file.management.v1.api.model.FileAttributes;
import com.iqser.red.service.file.management.v1.api.model.FileStatus;
import com.iqser.red.service.file.management.v1.api.model.Status;
import com.iqser.red.service.redaction.report.v1.server.client.DossierClient;
import com.iqser.red.service.redaction.report.v1.server.client.FileAttributesClient;
import com.iqser.red.service.redaction.report.v1.server.client.FileStatusClient;
import io.undertow.util.BadRequestException;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
@Service
@RequiredArgsConstructor
public class StatusReportGenerationService {
private final FileStatusClient fileStatusClient;
private final DossierClient dossierClient;
private final FileAttributesClient fileAttributesClient;
public byte[] generateReport(String dossierId) throws BadRequestException {
Dossier dossier;
try {
dossier = dossierClient.getDossierById(dossierId);
} catch (Exception e) {
throw new BadRequestException("Dossier not found.");
}
List<FileStatus> fileStatuses = fileStatusClient.getDossierStatus(dossierId);
List<FileAttributeConfig> fileAttributeConfigs = fileAttributesClient.getFileAttributes(dossier.getDossierTemplateId())
.getFileAttributeConfigs();
XSSFWorkbook workbook = new XSSFWorkbook();
XSSFSheet sheet = workbook.createSheet(dossier.getDossierName());
XSSFFont font = workbook.createFont();
font.setBold(true);
XSSFCellStyle style = workbook.createCellStyle();
style.setFont(font);
addHeader(sheet, style);
XSSFRow headerRow = sheet.getRow(0);
int headerCounter = 5;
Map<String, Integer> attributesAssignment = new HashMap<>();
for (FileAttributeConfig fileAttributeConfig : fileAttributeConfigs) {
sheet.setColumnWidth(headerCounter, 8000);
attributesAssignment.put(fileAttributeConfig.getId(), headerCounter);
XSSFCell cell = headerRow.createCell(headerCounter++);
cell.setCellValue(fileAttributeConfig.getLabel());
cell.setCellStyle(style);
}
for (int i = 0; i < fileStatuses.size(); i++) {
FileStatus fileStatus = fileStatuses.get(i);
String name = fileStatus.getFilename();
OffsetDateTime uploadDate = fileStatus.getLastUploaded();
String assignedTo = fileStatus.getCurrentReviewer();
Status status = fileStatus.getStatus();
int pages = fileStatus.getNumberOfPages();
FileAttributes fileAttributes = fileStatus.getFileAttributes();
XSSFRow row = sheet.createRow(i + 1);
XSSFCell cellName = row.createCell(0);
cellName.setCellValue(name);
XSSFCell cellUploadDate = row.createCell(1);
cellUploadDate.setCellValue(uploadDate.format(FORMAT_DATE_ISO));
XSSFCell cellAssignedTo = row.createCell(2);
cellAssignedTo.setCellValue(assignedTo);
XSSFCell cellStatus = row.createCell(3);
cellStatus.setCellValue(status.name());
XSSFCell cellPages = row.createCell(4);
cellPages.setCellValue(pages);
Iterator<Map.Entry<String, String>> iterator = fileAttributes.getAttributeIdToValue().entrySet().iterator();
while (iterator.hasNext()) {
var nextElement = iterator.next();
if(attributesAssignment.get(nextElement.getKey()) != null) {
XSSFCell cell = row.createCell(attributesAssignment.get(nextElement.getKey()));
cell.setCellValue(nextElement.getValue());
}
}
}
return toByteArray(workbook);
}
private void addHeader(XSSFSheet sheet, XSSFCellStyle style) {
sheet.setColumnWidth(0, 10000);
sheet.setColumnWidth(1, 4000);
sheet.setColumnWidth(2, 8000);
sheet.setColumnWidth(3, 5000);
sheet.setColumnWidth(4, 2000);
XSSFRow row = sheet.createRow(0);
XSSFCell cellName = row.createCell(0);
cellName.setCellValue("Filename");
cellName.setCellStyle(style);
XSSFCell cellUploadDate = row.createCell(1);
cellUploadDate.setCellValue("Upload date");
cellUploadDate.setCellStyle(style);
XSSFCell cellAssignedTo = row.createCell(2);
cellAssignedTo.setCellValue("Assigned to");
cellAssignedTo.setCellStyle(style);
XSSFCell cellStatus = row.createCell(3);
cellStatus.setCellValue("Status");
cellStatus.setCellStyle(style);
XSSFCell cellPages = row.createCell(4);
cellPages.setCellValue("Pages");
cellPages.setCellStyle(style);
}
@SneakyThrows
public byte[] toByteArray(XSSFWorkbook doc) {
try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()) {
doc.write(byteArrayOutputStream);
doc.close();
return byteArrayOutputStream.toByteArray();
}
}
}

View File

@ -0,0 +1,102 @@
package com.iqser.red.service.redaction.report.v1.server.service;
import static org.mockito.Mockito.when;
import java.io.FileOutputStream;
import java.io.IOException;
import java.time.OffsetDateTime;
import java.util.List;
import java.util.Map;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.springframework.test.context.junit4.SpringRunner;
import com.iqser.red.service.configuration.v1.api.model.FileAttributeConfig;
import com.iqser.red.service.configuration.v1.api.model.FileAttributesConfig;
import com.iqser.red.service.file.management.v1.api.model.Dossier;
import com.iqser.red.service.file.management.v1.api.model.FileAttributes;
import com.iqser.red.service.file.management.v1.api.model.FileStatus;
import com.iqser.red.service.file.management.v1.api.model.Status;
import com.iqser.red.service.redaction.report.v1.server.client.DossierClient;
import com.iqser.red.service.redaction.report.v1.server.client.FileAttributesClient;
import com.iqser.red.service.redaction.report.v1.server.client.FileStatusClient;
import io.undertow.util.BadRequestException;
@RunWith(SpringRunner.class)
public class StatusReportGenerationServiceTest {
@Mock
private FileStatusClient fileStatusClient;
@Mock
private DossierClient dossierClient;
@Mock
private FileAttributesClient fileAttributesClient;
@InjectMocks
private StatusReportGenerationService statusReportGenerationService;
// @MockBean
// private ExcelTemplateReportGenerationService excelTemplateReportGenerationService;
//
// @MockBean
// private ReportStorageService reportStorageService;
//
// @MockBean
// private StorageService storageService;
//
// @MockBean
// private AmazonS3 s3Client;
@Test
public void testGenerateReport() throws IOException, BadRequestException {
String dossierId = "dossierId";
Dossier dossier = Dossier.builder().dossierName("dossierName").dossierId(dossierId).build();
when(dossierClient.getDossierById(dossierId)).thenReturn(dossier);
FileAttributes fileAttributes1 = new FileAttributes(Map.of("a", "A", "config2", "B2"));
FileStatus fileStatus1 = FileStatus.builder()
.dossierId(dossierId)
.filename("file1")
.lastUploaded(OffsetDateTime.now().minusHours(2))
.currentReviewer("me")
.status(Status.APPROVED)
.numberOfPages(3)
.fileAttributes(fileAttributes1)
.build();
FileAttributes fileAttributes2 = new FileAttributes(Map.of("config1", "X1", "y", "Y"));
FileStatus fileStatus2 = FileStatus.builder()
.dossierId(dossierId)
.filename("file2")
.lastUploaded(OffsetDateTime.now())
.currentReviewer("you")
.status(Status.APPROVED)
.numberOfPages(21)
.fileAttributes(fileAttributes2)
.build();
when(fileStatusClient.getDossierStatus(dossierId)).thenReturn(List.of(fileStatus1, fileStatus2));
FileAttributeConfig fileAttributeConfig1 = FileAttributeConfig.builder().id("config1").label("Label1").build();
FileAttributeConfig fileAttributeConfig2 = FileAttributeConfig.builder().id("config2").label("Label2").build();
FileAttributesConfig fileAttributesConfig = new FileAttributesConfig(null, null, List.of(fileAttributeConfig1,fileAttributeConfig2));
when(fileAttributesClient.getFileAttributes(dossier.getDossierTemplateId())).thenReturn(fileAttributesConfig);
byte[] report = statusReportGenerationService.generateReport(dossierId);
try (FileOutputStream fileOutputStream = new FileOutputStream("/tmp/status_report.xlsx")) {
fileOutputStream.write(report);
}
}
}