Commit d40c97e7 authored by Guillaume Jimenez's avatar Guillaume Jimenez

REcalculate TAT with business days only.

parent 8dce99d5
......@@ -3,14 +3,19 @@ package utsw.bicf.nucliavault.controller;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.Period;
import java.time.temporal.TemporalUnit;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.YamlProcessor.MatchStatus;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
......@@ -32,6 +37,7 @@ import utsw.bicf.nucliavault.controller.serialization.zingchart.TATOrdersByMonth
import utsw.bicf.nucliavault.controller.serialization.zingchart.TimeTakenPerOrderZingChartData;
import utsw.bicf.nucliavault.dao.ModelDAO;
import utsw.bicf.nucliavault.dao.SampleDAO;
import utsw.bicf.nucliavault.model.Holidays;
import utsw.bicf.nucliavault.model.Threshold;
import utsw.bicf.nucliavault.model.hybrid.FailureRateYearOnlyTable;
import utsw.bicf.nucliavault.model.hybrid.MonthlySampleTAT;
......@@ -106,6 +112,25 @@ public class HomeController {
public String getTATOrdersByMonthChartData(Model model, HttpSession session) {
try {
List<MonthlySampleTAT> tats = modelDAO.getTatOrdersByMonth();
List<Holidays> holidays = modelDAO.getAllHolidays(2017, LocalDate.now().getYear());
//calculate the avg number of business day
for (MonthlySampleTAT tat : tats) {
List<Integer> labDays = new ArrayList<Integer>();
List<Integer> analysisDays = new ArrayList<Integer>();
for (int i = 0; i < tat.getMaxAssessionDates().size(); i++) {
LocalDate maxAssessionDate = tat.getMaxAssessionDates().get(i);
LocalDate maxAlignDate = tat.getMaxAlignDates().get(i);
LocalDate maxRunDate = tat.getMaxRunDates().get(i);
calcBusinessDays(holidays, maxAssessionDate, maxRunDate, labDays);
calcBusinessDays(holidays, maxAlignDate, maxRunDate, analysisDays);
}
Double avgLabTAT = labDays.stream().mapToDouble(a -> a).average().getAsDouble();
Double avgAnalysisTAT = analysisDays.stream().mapToDouble(a -> a).average().getAsDouble();
tat.setAvgTATLab(avgLabTAT);
tat.setAvgTATAnalysis(avgAnalysisTAT);
}
tats = fillGaps(tats);
TATOrdersByMonthZingChartData chartData = new TATOrdersByMonthZingChartData(tats);
return chartData.createVuetifyObjectJSON();
......@@ -115,11 +140,55 @@ public class HomeController {
}
}
private static void calcBusinessDays(List<Holidays> holidays, LocalDate startDate, LocalDate endDate, List<Integer> daysCount) {
int holidayCount = 0;
int weekdayCount = 0;
LocalDate start, end;
//holidays for the lab
if (startDate.isBefore(endDate)) {
start = startDate;
end = endDate;
}
else {
start = endDate;
end = startDate;
}
LocalDate currentIteration = start;
while (currentIteration.isBefore(end.plusDays(1))) {
if (currentIteration.getDayOfWeek() != DayOfWeek.SATURDAY
&& currentIteration.getDayOfWeek() != DayOfWeek.SUNDAY){
weekdayCount++;
}
currentIteration = currentIteration.plusDays(1);
}
for (Holidays h : holidays) {
//holidays count
if (start.isBefore(h.getHolidayDate()) && end.isAfter(h.getHolidayDate())) {
holidayCount++;
}
}
daysCount.add(weekdayCount - holidayCount );
}
@RequestMapping("/getTATPerSampleData")
@ResponseBody
public String getTATPerSampleData(Model model, HttpSession session, String chartOrTable) {
try {
List<SampleTAT> tats = sampleDAO.getSampleTATs();
List<Holidays> holidays = modelDAO.getAllHolidays(2017, LocalDate.now().getYear());
for (SampleTAT tat : tats) {
LocalDate assesionDate = tat.getAccessionDate();
LocalDate runDate = tat.getRunDate();
LocalDate alignDate = tat.getAlignDate();
List<Integer> labDays = new ArrayList<Integer>();
List<Integer> analysisDays = new ArrayList<Integer>();
calcBusinessDays(holidays, assesionDate, runDate, labDays);
calcBusinessDays(holidays, alignDate, runDate, analysisDays);
tat.setTatLab(labDays.get(0));
tat.setTatAnalysis(analysisDays.get(0));
}
if ("chart".equals(chartOrTable)) {
SampleTATZingChartData chartData = new SampleTATZingChartData(tats);
return chartData.createVuetifyObjectJSON();
......@@ -185,8 +254,8 @@ public class HomeController {
MonthlySampleTAT emptyTAT = new MonthlySampleTAT();
emptyTAT.setAssessionDate(expectedNextFullTatDate);
emptyTAT.setSubjectCount(BigInteger.ZERO);
emptyTAT.setAvgTATAnalysis(new BigDecimal(0));
emptyTAT.setAvgTATLab(new BigDecimal(0));
emptyTAT.setAvgTATAnalysis(0d);
emptyTAT.setAvgTATLab(0d);
emptyTAT.setMonthLabel(expectedNextFullTatDate.format(TypeUtils.shortMonthYearFormatter).toUpperCase());
return emptyTAT;
}
......
......@@ -22,7 +22,7 @@ public class TATOrdersByMonthZingChartData extends ZingChartData {
//Initialize Series
this.series = new ArrayList<Values>();
//Sample Count
this.series.add(createSeries(tats, itemsSize, "Order Count", "getSubjectCount"));
this.series.add(createSeries(tats, itemsSize, "Case Count", "getSubjectCount"));
//TAT Lab
this.series.add(createSeries(tats, itemsSize, "Avg. Lab TAT (days)", "getAvgTATLabRounded"));
//TAT Analysis
......
......@@ -510,22 +510,42 @@ public class ModelDAO {
public List<MonthlySampleTAT> getTatOrdersByMonth() {
StringBuilder sql = new StringBuilder();
sql.append(
" select concat(upper(substring(monthname(assessionFirstDayOfMonth), 1, 3)),' ', year(assessionFirstDayOfMonth)) as monthLabel, ")
.append(" subjectCount, assessionFirstDayOfMonth as assessionDate, avgTATLab, avgTATAnalysis ")
.append(" from ( ")
.append(" select count(subject_id) subjectCount, date_add(date_add(last_day(max_assession_date), interval 1 day), interval -1 month) as assessionFirstDayOfMonth, ")
.append(" avg(abs(datediff(max_assession_date, max_run_date))) as avgTATLab, ")
.append(" avg(abs(datediff(max_align_date, max_run_date))) as avgTATAnalysis ").append(" from ( ")
.append(" select su.subject_id, max(sa.assession_date) as max_assession_date, max(se.run_date) as max_run_date, max(al.align_date) as max_align_date, ")
.append(" year(max(sa.assession_date)) as assessionYear, month(max(sa.assession_date)) as assessionMonth ")
.append(" from sample sa, demultiplex d, seq_run se, alignment al, subject su ")
.append(" where d.sample_id = sa.sample_id ").append(" and se.seq_run_id = d.seq_run_id ")
.append(" and al.sample_id = sa.sample_id ").append(" and sa.subject_id = su.subject_id ")
.append(" and sa.assession_date is not null ").append(" and se.run_date is not null ")
.append(" group by su.subject_id ").append(" ) uniques ")
.append(" group by assessionYear, assessionMonth, assessionFirstDayOfMonth ")
.append(" order by assessionYear, assessionMonth) subquery; ");
// sql.append(
// " select concat(upper(substring(monthname(assessionFirstDayOfMonth), 1, 3)),' ', year(assessionFirstDayOfMonth)) as monthLabel, ")
// .append(" subjectCount, assessionFirstDayOfMonth as assessionDate, avgTATLab, avgTATAnalysis ")
// .append(" from ( ")
// .append(" select count(subject_id) subjectCount, date_add(date_add(last_day(max_assession_date), interval 1 day), interval -1 month) as assessionFirstDayOfMonth, ")
// .append(" avg(abs(datediff(max_assession_date, max_run_date))) as avgTATLab, ")
// .append(" avg(abs(datediff(max_align_date, max_run_date))) as avgTATAnalysis ").append(" from ( ")
// .append(" select su.subject_id, max(sa.assession_date) as max_assession_date, max(se.run_date) as max_run_date, max(al.align_date) as max_align_date, ")
// .append(" year(max(sa.assession_date)) as assessionYear, month(max(sa.assession_date)) as assessionMonth ")
// .append(" from sample sa, demultiplex d, seq_run se, alignment al, subject su ")
// .append(" where d.sample_id = sa.sample_id ").append(" and se.seq_run_id = d.seq_run_id ")
// .append(" and al.sample_id = sa.sample_id ").append(" and sa.subject_id = su.subject_id ")
// .append(" and sa.assession_date is not null ").append(" and se.run_date is not null ")
// .append(" group by su.subject_id ").append(" ) uniques ")
// .append(" group by assessionYear, assessionMonth, assessionFirstDayOfMonth ")
// .append(" order by assessionYear, assessionMonth) subquery; ");
sql.append(" select concat(upper(substring(monthname(assessionFirstDayOfMonth), 1, 3)),' ', year(assessionFirstDayOfMonth)) as monthLabel, ")
.append(" subjectCount, assessionFirstDayOfMonth as assessionDate, allTATLab, allTATAnalysis, max_assession_dates, max_align_dates, max_run_dates ")
.append(" from ( ")
.append(" select count(subject_id) subjectCount, date_add(date_add(last_day(max_assession_date), interval 1 day), interval -1 month) as assessionFirstDayOfMonth, ")
.append(" group_concat(abs(datediff(max_assession_date, max_run_date))) as allTATLab, ")
.append(" group_concat(abs(datediff(max_align_date, max_run_date))) as allTATAnalysis, ")
.append(" group_concat(max_assession_date) as max_assession_dates, ")
.append(" group_concat(max_run_date) as max_run_dates, ")
.append(" group_concat(max_align_date) as max_align_dates ")
.append(" from ( ")
.append(" select su.subject_id, max(sa.assession_date) as max_assession_date, max(se.run_date) as max_run_date, max(al.align_date) as max_align_date, ")
.append(" year(max(sa.assession_date)) as assessionYear, month(max(sa.assession_date)) as assessionMonth ")
.append(" from sample sa, demultiplex d, seq_run se, alignment al, subject su ")
.append(" where d.sample_id = sa.sample_id and se.seq_run_id = d.seq_run_id ")
.append(" and al.sample_id = sa.sample_id and sa.subject_id = su.subject_id ")
.append(" and sa.assession_date is not null and se.run_date is not null ")
.append(" group by su.subject_id ) uniques ")
.append(" group by assessionYear, assessionMonth, assessionFirstDayOfMonth ")
.append(" order by assessionYear, assessionMonth) subquery; ");
Query<MonthlySampleTAT> query = sessionFactory.getCurrentSession().createNativeQuery(sql.toString());
return query.setResultTransformer(new ResultTransformer() {
......
......@@ -412,6 +412,7 @@ public class SampleDAO {
StringBuilder sql = new StringBuilder();
//TODO only count business days
sql.append("select * from ( select distinct su.subject_acc as projectName, su.lims_id as limsId, sa.sample_lab_name as sampleName, ")
.append(" sa.assession_date as accessionDate, se.run_date as runDate, al.align_date as alignDate, ")
.append(" abs(datediff(se.run_date,sa.assession_date)) as tatLab, ")
......
......@@ -5,6 +5,11 @@ import java.math.BigInteger;
import java.sql.Date;
import java.text.ParseException;
import java.time.LocalDate;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import org.hibernate.type.descriptor.java.LocalDateJavaDescriptor;
import utsw.bicf.nucliavault.clarity.api.utils.TypeUtils;
......@@ -19,10 +24,12 @@ import utsw.bicf.nucliavault.clarity.api.utils.TypeUtils;
public class MonthlySampleTAT {
BigInteger subjectCount;
BigDecimal avgTATLab;
BigDecimal avgTATAnalysis;
Double avgTATLab;
Double avgTATAnalysis;
String monthLabel;
LocalDate assessionDate;
List<Integer> allTATLab, allTATAnalysis;
List<LocalDate> maxAssessionDates, maxAlignDates, maxRunDates;
public MonthlySampleTAT() {
super();
......@@ -33,10 +40,13 @@ public class MonthlySampleTAT {
String label = (String) labels[i];
switch(label) {
case "subjectCount": subjectCount = (BigInteger) values[i]; break;
case "avgTATLab": avgTATLab = (BigDecimal) values[i]; break;
case "avgTATAnalysis": avgTATAnalysis = (BigDecimal) values[i]; break;
// case "avgTATLab": avgTATLab = (BigDecimal) values[i]; break;
// case "avgTATAnalysis": avgTATAnalysis = (BigDecimal) values[i]; break;
case "monthLabel": monthLabel = (String) values[i]; break;
case "assessionDate": assessionDate = TypeUtils.parseSQLDateToLocalDate((Date) values[i]) ; break;
case "max_assession_dates": maxAssessionDates = Arrays.asList(((String) values[i]).split(",")).stream().map(item -> LocalDate.parse(item, TypeUtils.monthFormatter) ).collect(Collectors.toList()); break;
case "max_align_dates": maxAlignDates = Arrays.asList(((String) values[i]).split(",")).stream().map(item -> LocalDate.parse(item, TypeUtils.monthFormatter) ).collect(Collectors.toList()); break;
case "max_run_dates": maxRunDates = Arrays.asList(((String) values[i]).split(",")).stream().map(item -> LocalDate.parse(item, TypeUtils.monthFormatter) ).collect(Collectors.toList()); break;
}
}
}
......@@ -49,7 +59,7 @@ public class MonthlySampleTAT {
this.subjectCount = subjectCount;
}
public BigDecimal getAvgTATLab() {
public Double getAvgTATLab() {
return avgTATLab;
}
......@@ -57,11 +67,11 @@ public class MonthlySampleTAT {
return (float) Math.round(avgTATLab.floatValue() * 100) / 100;
}
public void setAvgTATLab(BigDecimal avgTATLab) {
public void setAvgTATLab(Double avgTATLab) {
this.avgTATLab = avgTATLab;
}
public BigDecimal getAvgTATAnalysis() {
public Double getAvgTATAnalysis() {
return avgTATAnalysis;
}
......@@ -69,7 +79,7 @@ public class MonthlySampleTAT {
return (float) Math.round(avgTATAnalysis.floatValue() * 100) / 100;
}
public void setAvgTATAnalysis(BigDecimal avgTATAnalysis) {
public void setAvgTATAnalysis(Double avgTATAnalysis) {
this.avgTATAnalysis = avgTATAnalysis;
}
......@@ -89,5 +99,45 @@ public class MonthlySampleTAT {
this.assessionDate = assessionDate;
}
public List<Integer> getAllTATLab() {
return allTATLab;
}
public void setAllTATLab(List<Integer> allTATLab) {
this.allTATLab = allTATLab;
}
public List<Integer> getAllTATAnalysis() {
return allTATAnalysis;
}
public void setAllTATAnalysis(List<Integer> allTATAnalysis) {
this.allTATAnalysis = allTATAnalysis;
}
public List<LocalDate> getMaxAssessionDates() {
return maxAssessionDates;
}
public void setMaxAssessionDates(List<LocalDate> maxAssessionDates) {
this.maxAssessionDates = maxAssessionDates;
}
public List<LocalDate> getMaxAlignDates() {
return maxAlignDates;
}
public void setMaxAlignDates(List<LocalDate> maxAlignDates) {
this.maxAlignDates = maxAlignDates;
}
public List<LocalDate> getMaxRunDates() {
return maxRunDates;
}
public void setMaxRunDates(List<LocalDate> maxRunDates) {
this.maxRunDates = maxRunDates;
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment