Skip to content

Commit

Permalink
comments implemented
Browse files Browse the repository at this point in the history
  • Loading branch information
wuall826 committed Apr 1, 2024
1 parent 6dbc3af commit 9c63cf5
Show file tree
Hide file tree
Showing 5 changed files with 250 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import ca.on.oicr.gsi.dimsum.service.CaseService;
import ca.on.oicr.gsi.dimsum.util.reporting.Report;
import ca.on.oicr.gsi.dimsum.util.reporting.ReportFormat;
import ca.on.oicr.gsi.dimsum.util.reporting.reports.CaseTatReport;
import ca.on.oicr.gsi.dimsum.util.reporting.reports.DareInputSheet;
import ca.on.oicr.gsi.dimsum.util.reporting.reports.FullDepthSummary;
import ca.on.oicr.gsi.dimsum.util.reporting.reports.TglTrackingReport;
Expand Down Expand Up @@ -55,6 +56,8 @@ private static Report getReport(String reportName) {
return FullDepthSummary.INSTANCE;
case "dare-input-sheet":
return DareInputSheet.INSTANCE;
case "case-tat-report":
return CaseTatReport.INSTANCE;
default:
throw new BadRequestException("Invalid report name");
}
Expand Down
19 changes: 19 additions & 0 deletions src/main/java/ca/on/oicr/gsi/dimsum/util/reporting/Column.java
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,25 @@ public String getDelimitedColumnString(String delimiter, T object) {
};
}

public static <T> Column<T> forInteger(String title, Function<T, Integer> getter) {
return new Column<T>(title) {

@Override
public void writeExcelCell(Cell cell, T object) {
Integer value = getter.apply(object);
if (value != null) {
cell.setCellValue(value.doubleValue());
}
}

@Override
public String getDelimitedColumnString(String delimiter, T object) {
Integer value = getter.apply(object);
return value != null ? value.toString() : "";
}
};
}

private final String title;

public Column(String title) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@
package ca.on.oicr.gsi.dimsum.util.reporting.reports;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import ca.on.oicr.gsi.cardea.data.Case;
import ca.on.oicr.gsi.cardea.data.CaseDeliverable;
import ca.on.oicr.gsi.cardea.data.CaseRelease;
import ca.on.oicr.gsi.cardea.data.Requisition;
import ca.on.oicr.gsi.cardea.data.Sample;
import ca.on.oicr.gsi.cardea.data.Test;
import ca.on.oicr.gsi.dimsum.service.CaseService;
import ca.on.oicr.gsi.dimsum.service.filtering.CaseFilter;
import ca.on.oicr.gsi.dimsum.service.filtering.CaseFilterKey;
import ca.on.oicr.gsi.dimsum.util.SampleUtils;
import ca.on.oicr.gsi.dimsum.util.reporting.Column;
import ca.on.oicr.gsi.dimsum.util.reporting.Report;
import ca.on.oicr.gsi.dimsum.util.reporting.ReportSection;
import ca.on.oicr.gsi.dimsum.util.reporting.ReportSection.TableReportSection;

public class CaseTatReport extends Report {

private static class RowData {
private final Case kase;
private final Test test;

public RowData(Case kase, Test test) {
this.kase = kase;
this.test = test;
}

public Case getCase() {
return kase;
}

public Test getTest() {
return test;
}
}

private static final ReportSection<RowData> caseSection = new TableReportSection<>(
"Case Report",
Arrays.asList(
Column.forString("Case ID", x -> x.getCase().getId()),
Column.forString("Projects",
x -> getSortedProjectNameAndPipeline(x.getCase()).stream()
.map(str -> str.split(" - ")[0])
.collect(Collectors.joining(", "))),
Column.forString("Pipeline",
x -> getSortedProjectNameAndPipeline(x.getCase()).stream()
.map(str -> str.split(" - ")[1])
.collect(Collectors.joining(", "))),
Column.forString("Requisition", x -> x.getCase().getRequisition().getName()),
Column.forString("Assay", x -> x.getCase().getAssayName()),
Column.forString("Start Date",
x -> x.getCase().getStartDate()
.format(DateTimeFormatter.ISO_LOCAL_DATE)),
Column.forString("Receipt Completed Date", x -> Optional
.ofNullable(findLatestCompletionDate(x.getCase().getReceipts()))
.map(date -> date.format(DateTimeFormatter.ISO_LOCAL_DATE))
.orElse("")),
Column.forInteger("Receipt Days", x -> x.getCase().getReceiptDaysSpent()),
Column.forString("Test", x -> x.getTest().getName()),
Column.forString("Supplemental Only",
x -> isSupplementalOnly(x.getTest(), x.getCase().getRequisition())
? "Yes"
: "No"),
Column.forString("Extraction Completed Date", x -> Optional
.ofNullable(findLatestCompletionDate(x.getTest().getExtractions()))
.map(date -> date.format(DateTimeFormatter.ISO_LOCAL_DATE))
.orElse("")),
Column.forInteger("Extraction Days", x -> x.getTest().getExtractionDaysSpent()),
Column.forString("Library Prep Completed Date", x -> Optional.ofNullable(
findLatestCompletionDate(x.getTest().getLibraryPreparations()))
.map(date -> date.format(DateTimeFormatter.ISO_LOCAL_DATE))
.orElse("")),
Column.forInteger("Library Prep. Days",
x -> x.getTest().getLibraryPreparationDaysSpent()),
Column.forString("Library Qual Completed Date", x -> Optional.ofNullable(
findLatestCompletionDate(x.getTest().getLibraryQualifications()))
.map(date -> date.format(DateTimeFormatter.ISO_LOCAL_DATE))
.orElse("")),
Column.forInteger("Library Qual. Days",
x -> x.getTest().getLibraryQualificationDaysSpent()),
Column.forString("Full Depth Completed Date", x -> Optional
.ofNullable(
findLatestCompletionDate(x.getTest().getFullDepthSequencings()))
.map(date -> date.format(DateTimeFormatter.ISO_LOCAL_DATE))
.orElse("")),
Column.forInteger("Full-Depth Days",
x -> x.getTest().getFullDepthSequencingDaysSpent()),
Column.forString("Analysis Review Completed",
x -> x.getCase().getDeliverables().stream()
.map(CaseDeliverable::getAnalysisReviewQcDate)
.filter(Objects::nonNull)
.max(LocalDate::compareTo)
.map(date -> date.format(DateTimeFormatter.ISO_LOCAL_DATE))
.orElse("")),
Column.forInteger("Analysis Review Days",
x -> x.getCase().getAnalysisReviewDaysSpent()),
Column.forString("Release Approval Completed",
x -> x.getCase().getDeliverables().stream()
.map(CaseDeliverable::getReleaseApprovalQcDate)
.filter(Objects::nonNull)
.max(LocalDate::compareTo)
.map(date -> date.format(DateTimeFormatter.ISO_LOCAL_DATE))
.orElse("")),
Column.forInteger("Release Approval Days",
x -> x.getCase().getReleaseApprovalDaysSpent()),
Column.forString("Completion Date", x -> getCompletionDate(x.getCase())),
Column.forInteger("Total Days", x -> x.getCase().getCaseDaysSpent()))) {
@Override
public List<RowData> getData(CaseService caseService, Map<String, String> parameters) {
List<CaseFilter> filters = convertParametersToFilters(parameters);
return caseService.getCaseStream(filters)
.flatMap(kase -> kase.getTests().stream()
.map(test -> new RowData(kase, test)))
.collect(Collectors.toList());
}
};

public static final CaseTatReport INSTANCE = new CaseTatReport();

private CaseTatReport() {
super("Case TAT Report", caseSection);
}

private static Collection<String> getSortedProjectNameAndPipeline(Case case1) {
return case1.getProjects()
.stream()
.map(project -> project.getName() + " - " + project.getPipeline())
.sorted(Comparator
.comparing(str -> !str.contains("Accredited with Clinical Report")))
.collect(Collectors.toList());
}

private static List<CaseFilter> convertParametersToFilters(Map<String, String> parameters) {
List<CaseFilter> filters = new ArrayList<>();
parameters.forEach((key, value) -> {
CaseFilterKey filterKey = CaseFilterKey.valueOf(key.toUpperCase());
CaseFilter filter = new CaseFilter(filterKey, value);
filters.add(filter);
});
return filters;
}

private static boolean isSupplementalOnly(Test test, Requisition requisition) {
if (test == null || test.getExtractions().isEmpty()) {
return false;
}
return test.getExtractions().stream()
.allMatch(sample -> !sample.getRequisitionId().equals(requisition.getId()));
}

private static LocalDate findLatestCompletionDate(List<Sample> samples) {
return samples.stream()
.filter(SampleUtils::isPassed)
.map(sample -> {
if (sample.getRun() != null) {
LocalDate sampleReviewDate = sample.getDataReviewDate();
LocalDate runReviewDate = sample.getRun().getDataReviewDate();
return Stream.of(sampleReviewDate, runReviewDate)
.filter(Objects::nonNull)
.max(LocalDate::compareTo)
.orElse(null);
} else {
return sample.getQcDate();
}
})
.filter(Objects::nonNull)
.max(LocalDate::compareTo)
.orElse(null);
}

private static String getCompletionDate(Case x) {
if (x.isStopped()) {
return "STOPPED";
}
List<CaseDeliverable> deliverables = x.getDeliverables();
if (deliverables.isEmpty()) {
return null;
}
List<CaseRelease> releases = deliverables.get(0).getReleases();
if (releases.isEmpty()) {
return null;
}
if (releases.stream()
.anyMatch(release -> release.getQcPassed() == null || !release.getQcPassed())) {
return null;
}
LocalDate latestQcDate = releases.stream()
.map(CaseRelease::getQcDate)
.max(LocalDate::compareTo)
.orElse(null);
return latestQcDate != null ? latestQcDate.toString() : null;
}
}
6 changes: 4 additions & 2 deletions ts/component/table-builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ export interface FilterDefinition {

export interface StaticAction {
title: string;
handler: () => void;
handler: (filters: { key: string; value: string }[]) => void;
}

export interface BulkAction<ParentType> {
Expand Down Expand Up @@ -316,7 +316,9 @@ export class TableBuilder<ParentType, ChildType> {
}
if (this.definition.staticActions) {
this.definition.staticActions.forEach((action) => {
addActionButton(container, action.title, action.handler);
addActionButton(container, action.title, () =>
action.handler(this.acceptedFilters)
);
});
}
}
Expand Down
19 changes: 18 additions & 1 deletion ts/data/case.ts
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,24 @@ export const caseDefinition: TableDefinition<Case, Test> = {
}
return null;
},
staticActions: [legendAction],
staticActions: [
legendAction,
{
title: "TAT Report",
handler: (filters: { key: string; value: string }[]) => {
const currentFilters: { [key: string]: any } = {};
for (const filter of filters) {
if (filter.value !== undefined && filter.value !== null) {
currentFilters[filter.key] = filter.value;
}
}
postDownload(
urls.rest.downloads.reports("case-tat-report"),
currentFilters
);
},
},
],
bulkActions: [
{
title: "Download",
Expand Down

0 comments on commit 9c63cf5

Please sign in to comment.