Skip to content
Draft
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 @@ -188,6 +188,33 @@ public HttpResponse<StreamedFile> generateDArTFile(@PathVariable UUID programId,
}
}

@Get("/programs/{programId}/submissions/{submissionId}/export")
@ProgramSecured(roleGroups = {ProgramSecuredRoleGroup.PROGRAM_SCOPED_ROLES})
@Produces(value={"text/csv", "application/vnd.ms-excel", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "application/octet-stream"})
public HttpResponse<StreamedFile> sampleSubmissionExport(@PathVariable UUID programId, @PathVariable UUID submissionId) {
try {
Optional<Program> program = programService.getById(programId);
if(program.isEmpty()) {
return HttpResponse.notFound();
}
Optional<DownloadFile> downloadFile = sampleSubmissionService.exportSubmission(program.get(), submissionId);
if(downloadFile.isEmpty()) {
return HttpResponse.notFound();
}
HttpResponse<StreamedFile> response = HttpResponse
.ok(downloadFile.get().getStreamedFile())
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=" + downloadFile.get().getFileName());
return response;
} catch (ApiException e) {
log.error(Utilities.generateApiExceptionLogMessage(e), e);
return HttpResponse.serverError();
} catch (IOException e) {
log.error("Error exporting Sample Submission file", e);
HttpResponse response = HttpResponse.status(HttpStatus.INTERNAL_SERVER_ERROR, "Error exporting Sample Submission file").contentType(MediaType.TEXT_PLAIN).body("Error exporting Sample Submission file");
return response;
}
}

@Get("/programs/{programId}/submissions/{submissionId}/lookup")
@ProgramSecured(roleGroups = {ProgramSecuredRoleGroup.PROGRAM_SCOPED_ROLES})
@Produces(value={"text/csv", "application/vnd.ms-excel", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "application/octet-stream"})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
public class SampleSubmissionService {

private static final String COLUMN_GENOTYPE = "Genotype";
public static final String COLUMN_SAMPLE_NAME = "Sample Name";
private static final String VENDOR_NOT_SUBMITTED_STATUS = "NOT SUBMITTED";
private static final String VENDOR_SUBMITTED_STATUS = "SUBMITTED";
private final String referenceSource;
Expand Down Expand Up @@ -214,20 +215,71 @@ public Optional<DownloadFile> generateDArTFile(Program program, UUID submissionI
columns.add(Column.builder().value(SampleSubmissionImport.Columns.TISSUE).dataType(Column.ColumnDataType.STRING).build());
columns.add(Column.builder().value(SampleSubmissionImport.Columns.COMMENTS).dataType(Column.ColumnDataType.STRING).build());

//Sort samples first. May be updated to use BrAPI server sorting after cache removal changes are merged
submission.get().getSamples().sort(Comparator.comparing(BrAPISample::getPlateName)
sortSamples(submission.get().getSamples());

List<Map<String, Object>> rows = new ArrayList<>();
submission.get().getSamples().forEach(sample -> {
Map<String, Object> row = new HashMap<>();
row.put(SampleSubmissionImport.Columns.PLATE_ID, sample.getPlateName());
row.put(SampleSubmissionImport.Columns.ROW, sample.getRow());
row.put(SampleSubmissionImport.Columns.COLUMN, sample.getColumn());
row.put(SampleSubmissionImport.Columns.ORGANISM, sample.getAdditionalInfo().get(BrAPIAdditionalInfoFields.SAMPLE_ORGANISM).getAsString());
row.put(SampleSubmissionImport.Columns.SPECIES, sample.getAdditionalInfo().has(BrAPIAdditionalInfoFields.SAMPLE_SPECIES) ? sample.getAdditionalInfo().get(BrAPIAdditionalInfoFields.SAMPLE_SPECIES).getAsString() : "");
row.put(COLUMN_GENOTYPE, sample.getSampleName());
row.put(SampleSubmissionImport.Columns.TISSUE, sample.getTissueType());
row.put(SampleSubmissionImport.Columns.COMMENTS, sample.getSampleDescription());

rows.add(row);
});


return Optional.of(new DownloadFile(filename, FileUtil.writeToStreamedFile(columns, rows, FileType.CSV, "Data")));
}

//Helper method to sort samples. May be updated to use BrAPI server sorting after cache removal changes are merged
public void sortSamples(List<BrAPISample> samples) {
samples.sort(Comparator.comparing(BrAPISample::getPlateName)
.thenComparing(BrAPISample::getColumn)
.thenComparing(BrAPISample::getRow));
}

public Optional<DownloadFile> exportSubmission(Program program, UUID submissionId) throws ApiException, IOException {
Optional<SampleSubmission> submission = getSampleSubmission(program, submissionId, true);
if (submission.isEmpty()) {
return Optional.empty();
}

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd_hh-mm-ssZ");
String timestamp = formatter.format(OffsetDateTime.now());
String filename = Utilities.makePortableFilename(String.format("%s_SampleSubmission_%s.csv", submission.get().getName(), timestamp));

List<Column> columns = new ArrayList<>();
columns.add(Column.builder().value(SampleSubmissionImport.Columns.GERMPLASM_NAME).dataType(Column.ColumnDataType.STRING).build());
columns.add(Column.builder().value(SampleSubmissionImport.Columns.GERMPLASM_GID).dataType(Column.ColumnDataType.STRING).build());
columns.add(Column.builder().value(SampleSubmissionImport.Columns.OBS_UNIT_ID).dataType(Column.ColumnDataType.STRING).build());
columns.add(Column.builder().value(COLUMN_SAMPLE_NAME).dataType(Column.ColumnDataType.STRING).build());
columns.add(Column.builder().value(SampleSubmissionImport.Columns.PLATE_ID).dataType(Column.ColumnDataType.STRING).build());
columns.add(Column.builder().value(SampleSubmissionImport.Columns.ROW).dataType(Column.ColumnDataType.STRING).build());
columns.add(Column.builder().value(SampleSubmissionImport.Columns.COLUMN).dataType(Column.ColumnDataType.INTEGER).build());
columns.add(Column.builder().value(SampleSubmissionImport.Columns.ORGANISM).dataType(Column.ColumnDataType.STRING).build());
columns.add(Column.builder().value(SampleSubmissionImport.Columns.SPECIES).dataType(Column.ColumnDataType.STRING).build());
columns.add(Column.builder().value(SampleSubmissionImport.Columns.TISSUE).dataType(Column.ColumnDataType.STRING).build());
columns.add(Column.builder().value(SampleSubmissionImport.Columns.COMMENTS).dataType(Column.ColumnDataType.STRING).build());

sortSamples(submission.get().getSamples());

List<Map<String, Object>> rows = new ArrayList<>();
submission.get().getSamples().forEach(sample -> {
Map<String, Object> row = new HashMap<>();
row.put(SampleSubmissionImport.Columns.GERMPLASM_NAME, sample.getAdditionalInfo().get(BrAPIAdditionalInfoFields.GERMPLASM_NAME).getAsString());
row.put(SampleSubmissionImport.Columns.GERMPLASM_GID, sample.getAdditionalInfo().get(BrAPIAdditionalInfoFields.GID).getAsString());
row.put(SampleSubmissionImport.Columns.OBS_UNIT_ID, sample.getObservationUnitDbId());
row.put(COLUMN_SAMPLE_NAME, sample.getSampleName());
row.put(SampleSubmissionImport.Columns.PLATE_ID, sample.getPlateName());
row.put(SampleSubmissionImport.Columns.ROW, sample.getRow());
row.put(SampleSubmissionImport.Columns.COLUMN, sample.getColumn());
row.put(SampleSubmissionImport.Columns.ORGANISM, sample.getAdditionalInfo().get(BrAPIAdditionalInfoFields.SAMPLE_ORGANISM).getAsString());
row.put(SampleSubmissionImport.Columns.SPECIES, sample.getAdditionalInfo().has(BrAPIAdditionalInfoFields.SAMPLE_SPECIES) ? sample.getAdditionalInfo().get(BrAPIAdditionalInfoFields.SAMPLE_SPECIES).getAsString() : "");
row.put(COLUMN_GENOTYPE, sample.getSampleName());
row.put(SampleSubmissionImport.Columns.TISSUE, sample.getTissueType());
row.put(SampleSubmissionImport.Columns.COMMENTS, sample.getSampleDescription());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,48 @@ public void testGenerateDArTFile() throws IOException, InterruptedException, Par
assertEquals("Genotype", lookupTable.column(5).name());
assertEquals(Columns.TISSUE, lookupTable.column(6).name());
assertEquals(Columns.COMMENTS, lookupTable.column(7).name());

//Check sorting
assertEquals("valid_1", lookupTable.column(0).get(1));
assertEquals("A1", lookupTable.column(1).get(1));
assertEquals(0, lookupTable.column(2).get(1));
}

@Test
public void testExportSampleSubmission() throws IOException, InterruptedException, ParsingException {
Pair<SampleSubmission, List<Map<String, Object>>> uploadedSubmission = createSubmission(program);

Flowable<HttpResponse<byte[]>> call = client.exchange(
GET(String.format("/programs/%s/submissions/%s/export",
program.getId().toString(), uploadedSubmission.getLeft().getId()))
.cookie(new NettyCookie("phylo-token", "test-registered-user")), byte[].class
);
HttpResponse<byte[]> response = call.blockingFirst();

assertEquals(HttpStatus.OK, response.getStatus());

ByteArrayInputStream bodyStream = new ByteArrayInputStream(Objects.requireNonNull(response.body()));
Table lookupTable = FileUtil.parseTableFromCsv(bodyStream);
assertEquals(11, lookupTable.columnCount());

//Check columns correct
assertEquals(Columns.GERMPLASM_NAME, lookupTable.column(0).name());
assertEquals(Columns.GERMPLASM_GID, lookupTable.column(1).name());
assertEquals(Columns.OBS_UNIT_ID, lookupTable.column(2).name());
assertEquals("Sample Name", lookupTable.column(3).name());
assertEquals(Columns.PLATE_ID, lookupTable.column(4).name());
assertEquals(Columns.ROW, lookupTable.column(5).name());
assertEquals(Columns.COLUMN, lookupTable.column(6).name());
assertEquals(Columns.ORGANISM, lookupTable.column(7).name());
assertEquals(Columns.SPECIES, lookupTable.column(8).name());
assertEquals(Columns.TISSUE, lookupTable.column(9).name());
assertEquals(Columns.COMMENTS, lookupTable.column(10).name());

//Check sorting
assertEquals(2, lookupTable.column(1).get(1));
assertEquals("valid_1", lookupTable.column(4).get(1));
assertEquals("A1", lookupTable.column(5).get(1));
assertEquals(0, lookupTable.column(6).get(1));
}

@Test
Expand Down
Loading