From e31e32bcfa6e17a02d3b1de1f23475924d3ec27c Mon Sep 17 00:00:00 2001
From: Chad Sebranek
Date: Fri, 6 Sep 2024 14:19:04 -0500
Subject: [PATCH 01/13] Add blood graph along with queries to support it, as
well as new column for blood avail including thirty days in the future
---
.../BloodSchedule/Blood Schedule.qview.xml | 1 +
.../queries/study/Current Blood.query.xml | 3 +
.../resources/queries/study/Current Blood.sql | 18 +-
.../queries/study/Current Blood/.qview.xml | 2 +
.../queries/study/bloodDrawChanges.sql | 66 ++
.../queries/study/bloodSummary.query.xml | 3 +
.../resources/queries/study/bloodSummary.sql | 39 +-
.../queries/study/currentBloodDraws.sql | 85 +++
.../web/wnprc_ehr/panel/BloodSummaryPanel.js | 570 ++++++++++++++++++
.../resources/web/wnprc_ehr/wnprcReports.js | 30 +
.../org/labkey/wnprc_ehr/WNPRC_EHRModule.java | 1 +
11 files changed, 781 insertions(+), 37 deletions(-)
create mode 100644 WNPRC_EHR/resources/queries/study/bloodDrawChanges.sql
create mode 100644 WNPRC_EHR/resources/queries/study/currentBloodDraws.sql
create mode 100644 WNPRC_EHR/resources/web/wnprc_ehr/panel/BloodSummaryPanel.js
diff --git a/WNPRC_EHR/resources/queries/study/BloodSchedule/Blood Schedule.qview.xml b/WNPRC_EHR/resources/queries/study/BloodSchedule/Blood Schedule.qview.xml
index a889616dc..04e7ac58e 100644
--- a/WNPRC_EHR/resources/queries/study/BloodSchedule/Blood Schedule.qview.xml
+++ b/WNPRC_EHR/resources/queries/study/BloodSchedule/Blood Schedule.qview.xml
@@ -56,6 +56,7 @@
+
diff --git a/WNPRC_EHR/resources/queries/study/Current Blood.query.xml b/WNPRC_EHR/resources/queries/study/Current Blood.query.xml
index a37953f2a..f5116e3eb 100644
--- a/WNPRC_EHR/resources/queries/study/Current Blood.query.xml
+++ b/WNPRC_EHR/resources/queries/study/Current Blood.query.xml
@@ -62,6 +62,9 @@
Volume Remaining After Draw (mL)
+
+ /WNPRC/EHR/ehr-animalHistory.view#subjects:${Id}&inputType:singleSubject&showReport:1&activeReport:BloodSummary
+
BloodLast30
diff --git a/WNPRC_EHR/resources/queries/study/Current Blood.sql b/WNPRC_EHR/resources/queries/study/Current Blood.sql
index 6187c80ed..54195ace4 100644
--- a/WNPRC_EHR/resources/queries/study/Current Blood.sql
+++ b/WNPRC_EHR/resources/queries/study/Current Blood.sql
@@ -5,23 +5,14 @@
*/
SELECT
bq.*,
- cast(CASE
- WHEN bq.species = 'Marmoset'
- THEN round(bq.weight*0.15*60, 1)
- ELSE
- round(bq.weight*0.2*60, 1)
- END as numeric) AS MaxBlood,
- cast(CASE
- WHEN bq.species = 'Marmoset'
- THEN round((bq.weight*0.15*60) - bq.BloodLast30, 1)
- ELSE
- round((bq.weight*0.2*60) - bq.BloodLast30, 1)
- END AS numeric) AS AvailBlood
+ cast(round(bq.weight*species.max_draw_pct*species.blood_per_kg, 1) as numeric) AS MaxBlood,
+ cast(round((bq.weight*species.max_draw_pct*species.blood_per_kg) - bq.BloodLast30, 1) AS numeric) AS AvailBlood,
+ cast(round((bq.weight*species.max_draw_pct*species.blood_per_kg) - (bq.BloodLast30 + bq.BloodNext30), 1) AS numeric) AS BloodAvailPlusThirty
FROM
(
SELECT
b.*,
- (select species from study.demographics d where d.id = b.id) as species,
+ (d.species) as species,
(
CONVERT (
(SELECT AVG(w.weight) AS _expr
@@ -109,5 +100,6 @@ FROM
--WHERE b.id.status.status = 'Alive'
) bi
) b
+ JOIN study.demographics d ON d.id=b.id
) bq
diff --git a/WNPRC_EHR/resources/queries/study/Current Blood/.qview.xml b/WNPRC_EHR/resources/queries/study/Current Blood/.qview.xml
index 33013bb26..f75cd0a18 100644
--- a/WNPRC_EHR/resources/queries/study/Current Blood/.qview.xml
+++ b/WNPRC_EHR/resources/queries/study/Current Blood/.qview.xml
@@ -23,6 +23,8 @@
+
+
diff --git a/WNPRC_EHR/resources/queries/study/bloodDrawChanges.sql b/WNPRC_EHR/resources/queries/study/bloodDrawChanges.sql
new file mode 100644
index 000000000..d358fe95e
--- /dev/null
+++ b/WNPRC_EHR/resources/queries/study/bloodDrawChanges.sql
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2016 LabKey Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+--this query is designed to return any dates when allowable blood draw volume changes
+--this includes dates of blood draws, plus the date those draws drop off
+PARAMETERS(DATE_INTERVAL INTEGER)
+
+SELECT
+ b2.id,
+ b2.dateOnly,
+ b2.quantity,
+ DATE_INTERVAL as blood_draw_interval,
+ TIMESTAMPADD('SQL_TSI_DAY', (-1 * DATE_INTERVAL), b2.dateOnly) as minDate,
+ TIMESTAMPADD('SQL_TSI_DAY', DATE_INTERVAL, b2.dateOnly) as maxDate,
+
+FROM (
+ SELECT
+ b.id,
+ b.dateOnly,
+ sum(b.quantity) as quantity
+
+ FROM (
+ --find all blood draws within the interval, looking backwards
+ SELECT
+ b.id,
+ b.dateOnly,
+ b.quantity,
+ FROM study.blood b
+ WHERE b.dateOnly > timestampadd('SQL_TSI_DAY', -1 * DATE_INTERVAL, curdate()) AND b.project.research = TRUE
+
+ UNION ALL
+
+ --join 1 row for the current date
+ SELECT
+ d1.id,
+ curdate() as dateOnly,
+ 0 as quantity,
+ FROM study.demographics d1
+ WHERE d1.calculated_status = 'Alive'
+
+ UNION ALL
+
+ --add one row for each date when the draw drops off the record
+ SELECT
+ b.id,
+ timestampadd('SQL_TSI_DAY', DATE_INTERVAL, b.dateOnly),
+ 0 as quantity,
+ FROM study.blood b
+ WHERE timestampadd('SQL_TSI_DAY', DATE_INTERVAL, b.dateOnly) >= timestampadd('SQL_TSI_DAY', -1 * DATE_INTERVAL, curdate()) AND b.project.research = TRUE
+
+ ) b
+
+ GROUP BY b.id, b.dateOnly
+) b2
\ No newline at end of file
diff --git a/WNPRC_EHR/resources/queries/study/bloodSummary.query.xml b/WNPRC_EHR/resources/queries/study/bloodSummary.query.xml
index b8a667e34..7d3c1c2a2 100644
--- a/WNPRC_EHR/resources/queries/study/bloodSummary.query.xml
+++ b/WNPRC_EHR/resources/queries/study/bloodSummary.query.xml
@@ -28,6 +28,9 @@
query.sort=-Date&
+
+ /WNPRC/EHR/ehr-animalHistory.view#subjects:${Id}&inputType:singleSubject&showReport:1&activeReport:BloodSummary
+
BloodLast30
diff --git a/WNPRC_EHR/resources/queries/study/bloodSummary.sql b/WNPRC_EHR/resources/queries/study/bloodSummary.sql
index 29754e3f8..c38ff59ff 100644
--- a/WNPRC_EHR/resources/queries/study/bloodSummary.sql
+++ b/WNPRC_EHR/resources/queries/study/bloodSummary.sql
@@ -12,26 +12,15 @@ SELECT
bq.weight,
bq.lastWeighDate,
cast(bq.BloodLast30 as numeric) as BloodLast30,
--- bq.BloodNext30,
--- round(bq.weight*0.2*60, 1) AS MaxBlood,
--- round((bq.weight*0.2*60) - bq.BloodLast30, 1) AS AvailBlood
- cast(CASE
- WHEN bq.species = 'Marmoset'
- THEN round(bq.weight*0.15*60, 1)
- ELSE
- round(bq.weight*0.2*60, 1)
- END as numeric) AS MaxBlood,
- cast(CASE
- WHEN bq.species = 'Marmoset'
- THEN round((bq.weight*0.15*60) - bq.BloodLast30, 1)
- ELSE
- round((bq.weight*0.2*60) - bq.BloodLast30, 1)
- END AS numeric) AS AvailBlood
+ bq.BloodNext30,
+ cast(round(bq.weight*species.max_draw_pct*species.blood_per_kg, 1) as numeric) AS MaxBlood,
+ cast(round((bq.weight*species.max_draw_pct*species.blood_per_kg) - bq.BloodLast30, 1) AS numeric) AS AvailBlood,
+ cast(round((bq.weight*species.max_draw_pct*species.blood_per_kg) - (bq.BloodLast30 + bq.BloodNext30), 1) AS numeric) AS BloodAvailNowPlusThirtyDays
FROM
(
SELECT
b.*,
- (select species from study.demographics d where d.id = b.id) as species,
+ (d.species) as species,
(
CONVERT (
(SELECT AVG(w.weight) AS _expr
@@ -65,16 +54,18 @@ FROM
--AND draws.qcstate.publicdata = true
), 0 )
) AS BloodLast30
--- , ( COALESCE (
--- (SELECT SUM(draws.quantity) AS _expr
--- FROM study."Blood Draws" draws
--- WHERE draws.id=bi.id
--- AND draws.date BETWEEN TIMESTAMPADD('SQL_TSI_DAY', 30, bi.date) AND bi.date
--- AND (draws.qcstate.metadata.DraftData = true OR draws.qcstate.publicdata = true)
--- ), 0 )
--- ) AS BloodNext30
+ , ( COALESCE (
+ (SELECT SUM(coalesce(draws.quantity, 0)) AS _expr
+ FROM study."Blood Draws" draws
+ WHERE draws.id=bi.id
+ AND (cast(draws.date as date) >= cast(TIMESTAMPADD('SQL_TSI_DAY', 29, bi.date) as date) AND cast(draws.date as date) <= cast(bi.date as date))
+ AND cast(draws.date as date) >= bi.date
+ AND (draws.qcstate.metadata.DraftData = true OR draws.qcstate.publicdata = true)
+ ), 0 )
+ ) AS BloodNext30
FROM study.blood bi
--WHERE (bi.qcstate.metadata.DraftData = true OR bi.qcstate.publicdata = true)
) b
+ JOIN study.demographics d ON d.id=b.id
) bq
diff --git a/WNPRC_EHR/resources/queries/study/currentBloodDraws.sql b/WNPRC_EHR/resources/queries/study/currentBloodDraws.sql
new file mode 100644
index 000000000..feda25ea5
--- /dev/null
+++ b/WNPRC_EHR/resources/queries/study/currentBloodDraws.sql
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2016 LabKey Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+SELECT
+ t.id,
+ t.date,
+ cast(t.quantity as double) as quantity,
+ t.species,
+ t.max_draw_pct,
+ t.blood_draw_interval,
+ t.blood_per_kg,
+ t.mostRecentWeight,
+ t.mostRecentWeightDate,
+ t.death,
+ cast(t.allowableBlood as double) as maxAllowableBlood,
+ cast(t.bloodPrevious as double) as bloodPrevious,
+ cast((t.allowableBlood - t.bloodPrevious) as double) as allowablePrevious,
+
+ cast(t.bloodFuture as double) as bloodFuture,
+ cast((t.allowableBlood - t.bloodFuture) as double) as allowableFuture,
+
+ --if the draw is historic, always consider previous draws only.
+ --otherwise, look both forward and backwards, then take the interval with the highest volume
+ cast(case
+ WHEN t.date < curdate() THEN (t.allowableBlood - t.bloodPrevious)
+ WHEN t.bloodPrevious < t.bloodFuture THEN (t.allowableBlood - t.bloodFuture)
+ ELSE (t.allowableBlood - t.bloodPrevious)
+ end as double) as allowableBlood,
+ t.minDate,
+ t.maxDate
+
+FROM (
+
+SELECT
+ bd.id,
+ bd.dateOnly as date,
+ bd.quantity,
+ d.species,
+ d.death,
+ d.id.mostRecentWeight.MostRecentWeight,
+ d.id.mostRecentWeight.MostRecentWeightDate,
+ d.species.blood_per_kg,
+ d.species.max_draw_pct,
+ bd.blood_draw_interval,
+(d.id.mostRecentWeight.MostRecentWeight * d.species.blood_per_kg * d.species.max_draw_pct)
+ as allowableBlood,
+ bd.minDate,
+ bd.maxDate,
+ COALESCE(
+ (SELECT SUM(coalesce(draws.quantity, 0)) AS _expr
+ FROM study."Blood Draws" draws
+ WHERE draws.id = bd.id AND draws.project.research = true
+ AND draws.dateOnly > bd.minDate
+ AND draws.dateOnly <= bd.dateOnly
+ --NOTE: this has been changed to include pending/non-approved draws
+ AND draws.countsAgainstVolume = true
+ ), 0) AS BloodPrevious,
+
+ COALESCE(
+ (SELECT SUM(coalesce(draws.quantity, 0)) AS _expr
+ FROM study."Blood Draws" draws
+ WHERE draws.id = bd.id AND draws.project.research = true
+ AND draws.dateOnly < bd.maxDate
+ AND draws.dateOnly >= bd.dateOnly
+ --NOTE: this has been changed to include pending/non-approved draws
+ AND draws.countsAgainstVolume = true
+ ), 0) AS BloodFuture
+
+FROM study.bloodDrawChanges bd
+JOIN study.demographics d ON (d.id = bd.id)
+
+) t
\ No newline at end of file
diff --git a/WNPRC_EHR/resources/web/wnprc_ehr/panel/BloodSummaryPanel.js b/WNPRC_EHR/resources/web/wnprc_ehr/panel/BloodSummaryPanel.js
new file mode 100644
index 000000000..c4c298ee8
--- /dev/null
+++ b/WNPRC_EHR/resources/web/wnprc_ehr/panel/BloodSummaryPanel.js
@@ -0,0 +1,570 @@
+/*
+ * Copyright (c) 2016-2019 LabKey Corporation
+ *
+ * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0
+ */
+/*
+ * Title: BloodSummaryPanel
+ * Description: This will generate the blood report plot for each subject ID passed in. Provides a hook to add
+ * additional items in the report.
+ * Config: {
+ * subjects: Array of animal IDs,
+ * getSubjectItems(optional): Function returning an array of items to add for each subject ID after the plot
+ * }
+ */
+
+Ext4.define('WNPRC.panel.BloodSummaryPanel', {
+ extend: 'Ext.panel.Panel',
+ alias: 'widget.wnprc-bloodsummarypanel',
+ intervals: {},
+ plotHeight: 400,
+
+ bloodPerKgCol: 'species/blood_per_kg',
+ bloodMaxDrawPctCol: 'species/max_draw_pct',
+ bloodDrawIntervalCol: 'species/blood_draw_interval',
+
+ initComponent: function(){
+ Ext4.apply(this, {
+ border: false,
+ defaults: {
+ border: false
+ },
+ items: [{
+ html: 'Loading...'
+ }]
+ });
+
+ this.callParent();
+
+ if(!Ext4.isDefined(this.subjects) || !Ext4.isArray(this.subjects))
+ console.log("Must pass in an array of animal IDs as subjects.")
+ else
+ this.loadData();
+ },
+
+ loadData: function(){
+ var demoCols = 'id,species,id/MostRecentWeight/mostRecentWeight,id/MostRecentWeight/mostRecentWeightDate,Id/demographics/calculated_status,Id/demographics/calculated_status/meaning'
+ + ',' + this.bloodPerKgCol + ',' + this.bloodMaxDrawPctCol + ',' + this.bloodDrawIntervalCol;
+
+ LABKEY.Query.selectRows({
+ schemaName: 'study',
+ queryName: 'demographics',
+ filterArray: [LABKEY.Filter.create('id', this.subjects.join(';'), LABKEY.Filter.Types.EQUALS_ONE_OF)],
+ columns: demoCols,
+ requiredVersion: 9.1,
+ sort: 'id',
+ scope: this,
+ failure: LDK.Utils.getErrorCallback(),
+ success: function(results){
+ this.demographicsMap = {};
+ this.intervals = {};
+
+ Ext4.each(results.rows, function(row){
+ var map = new LDK.SelectRowsRow(row);
+ var interval = row[this.bloodDrawIntervalCol].value;
+ this.demographicsMap[map.getValue('id')] = map;
+
+ if(!interval) {
+ interval = 42;
+ }
+ if( this.intervals.hasOwnProperty(interval) ) {
+ this.intervals[interval].push(row.Id.value)
+ } else {
+ this.intervals[interval] = [row.Id.value];
+ }
+
+ }, this);
+
+ this.loadBloodData();
+ }
+ });
+ },
+
+ loadBloodData: function() {
+ var multi = new LABKEY.MultiRequest();
+
+ for(var interval in this.intervals) {
+ if (this.intervals.hasOwnProperty(interval)) {
+
+ multi.add(LABKEY.Ajax.request, {
+ url: LABKEY.ActionURL.buildURL("ehr", "bloodPlotData"),
+ params: {
+ ids: this.intervals[interval],
+ interval: interval
+ },
+ method : 'POST',
+ requiredVersion: 9.1,
+ scope: this,
+ failure: LDK.Utils.getErrorCallback(),
+ success: function (response)
+ {
+ var results = JSON.parse(response.responseText);
+ console.log(results);
+
+ var meta = results.metaData.fields;
+ for(var i = 0; i dDate) {
+ return;
+ }
+ }
+ //End TODO
+ if (rDate && Ext4.Date.format(rDate, LABKEY.extDefaultDateFormat) == Ext4.Date.format(new Date(), LABKEY.extDefaultDateFormat)) {
+ row.isToday = {value: true};
+ }
+ }
+
+ if (!this.currentBloodMap[id])
+ this.currentBloodMap[id] = [];
+
+ this.currentBloodMap[id].push(row);
+ }, this);
+
+ if(this.bloodDrawResults) {
+ this.bloodDrawResults.rows = this.bloodDrawResults.rows.concat(results.rows);
+ } else {
+ this.bloodDrawResults = results;
+ }
+ }
+ });
+ }
+ }
+
+ multi.send(this.onLoad, this);
+ },
+
+ onLoad: function(results){
+ var toAdd = [];
+ Ext4.each(this.subjects, function(subject){
+ var dd = this.demographicsMap[subject];
+ var bds = this.currentBloodMap[subject];
+
+ var cfg = {
+ xtype: 'ldk-webpartpanel',
+ style: 'margin-bottom: 20px;',
+ title: 'Blood Summary: ' + subject,
+ defaults: {
+ border: false
+ },
+ items: []
+ };
+
+ if (!dd){
+ cfg.items.push({
+ html: 'Either species or weight information is missing for this animal'
+ });
+ }
+ else {
+ var status = dd.getValue('Id/demographics/calculated_status/meaning') || dd.getValue('Id/demographics/calculated_status');
+ cfg.items.push({
+ html: 'Id: ' + dd.getValue('Id') + (status ? ' (' + status + ')' : '') + ''
+ });
+
+ cfg.items.push({
+ html: '
'
+ });
+
+ if(status != null && status.toLowerCase() === "dead") {
+ cfg.items.push({
+ html: 'No current blood draw information for dead animal.',
+ border: false
+ });
+ }
+ else if (!bds || bds.length === 1) {
+ var maxDraw = dd.getValue(this.bloodPerKgCol) * dd.getValue(this.bloodMaxDrawPctCol) * dd.getValue('id/MostRecentWeight/mostRecentWeight');
+ cfg.items.push({
+ html: 'There are no previous blood draws within the relevant time frame. A maximum amount of ' + Ext4.util.Format.round(maxDraw, 2) + ' mL can be drawn.',
+ border: false
+ });
+ }
+ else {
+ cfg.items = cfg.items.concat(this.getGraphCfg(dd, bds));
+ }
+ }
+
+ toAdd.push(cfg);
+ }, this);
+
+ this.removeAll();
+ if (toAdd.length){
+ this.add(toAdd);
+ }
+ else {
+ this.add({
+ html: 'No records found'
+ });
+ }
+
+ this.addAdditionalGraphOptions();
+ },
+
+ addAdditionalGraphOptions: function() {
+ var svgs = d3.selectAll('svg');
+ var patternHeight = 8;
+
+ // Add shading pattern
+ var defs = svgs.selectAll('defs')
+ .append('pattern')
+ .attr('id', 'diag-pattern')
+ .attr('patternUnits', 'userSpaceOnUse')
+ .attr('x', 0)
+ .attr('y', 0)
+ .attr('width', 3)
+ .attr('height', patternHeight)
+ .attr('patternTransform', 'rotate(30)')
+ .append('rect')
+ .attr('x', 0)
+ .attr('y', 0)
+ .attr('width',.5)
+ .attr('height', patternHeight)
+ .attr('style', 'stroke:none;')
+ .attr('fill', 'red');
+
+
+ // Add under zero shading
+ Ext4.each(svgs[0], function(svg) {
+ var ticks = svg.getElementsByClassName('axis')[1].getElementsByClassName('tick-text')[0].getElementsByTagName('g');
+ Ext4.each(ticks, function(tick) {
+ if(tick.getElementsByTagName('text')[0].textContent === '0') {
+ var axis = d3.select(tick.parentElement.parentElement);
+ var tickText = d3.select(tick.parentElement);
+ axis.append('rect')
+ .attr('x', tick.getBBox().x + 16)
+ .attr('y', tick.getBBox().y + 11)
+ .attr('width', axis[0][0].getBBox().width - tickText[0][0].getBBox().width - 10)
+ .attr('height', this.plotHeight - tick.getBBox().y - 60)
+ .attr('fill-opacity',.5)
+ .attr('fill', 'url(#diag-pattern)');
+ }
+ },this)
+ },this);
+
+ var points = d3.selectAll('a.point');
+ var todayPoints = points.filter(function(d) {
+ return (d.isToday && d.isToday == true);
+ });
+
+ // Add Today line and text
+ todayPoints.append(function(d,i) {
+
+ // Hijack the loop to setup line
+ var yAxis = d3.selectAll('svg').select('g.grid-line path')[0][i];
+ var path = yAxis.getAttribute('d');
+ var bottom = Number(path.substring(path.indexOf(',')+1, path.indexOf('L')));
+ var top = Number(path.substring(path.indexOf(',', path.indexOf(',')+1)+1, path.indexOf('Z')));
+ var ht = bottom - top;
+ this.getElementsByTagName('path')[0]
+ .setAttribute('d', "M0 " + (ht + 68 - this.getBBox().y) + " l0 -" + (ht-1));
+
+ var text = document.createElementNS(d3.ns.prefix.svg, 'text');
+ text.setAttribute("x", this.getBBox().x - 18);
+ text.setAttribute("y", this.getBBox().y - 3);
+ text.setAttribute("style", "font-weight:bold;font-family:Arial;font-size:11px;");
+ text.setAttribute("fill", "black");
+ text.setAttribute("visibility", "visible");
+ text.textContent = "Today";
+
+ return text;
+ });
+ },
+ getMaxBloodAvailValue: function(rows){
+
+ var allowableBloodVals = [];
+ for (var i = 0; i < rows.length; i++){
+ allowableBloodVals.push(rows[i].allowableDisplay.value);
+ }
+
+ return Math.round(allowableBloodVals.reduce((a, b) => Math.max(a, b), -Infinity)) + 10;
+ },
+
+ getTickValues: function(rows){
+ var ticks = [], msPerDay = 86400000, totalTicks = 10;
+ var minDate = Date.parse(rows[0].date.value);
+ var minDateGmt = Date.parse(rows[0].date.value.concat(" GMT"));
+ var maxDate = Date.parse(rows[rows.length - 1].date.value);
+ var diff = maxDate - minDate;
+ var daysTotal = diff/msPerDay;
+ var daysPerTick = Math.ceil(daysTotal/totalTicks);
+ var newTotal = Math.ceil(daysTotal/daysPerTick);
+
+ ticks[0] = (Math.ceil(minDate/msPerDay) * msPerDay)
+ - (msPerDay - (minDate - minDateGmt)); // Offset timezone
+ for(var i=1; iTotal volume of blood collected in the past ' + currentRow.blood_draw_interval.value + ' days: '
+ + Ext4.util.Format.round(currentRow.bloodPrevious.value, 1) + ' mL. '
+ + 'The amount of blood available if drawn today is: ' + Ext4.util.Format.round(currentRow.allowableDisplay.value, 1) + ' mL.
'
+ + 'The graph below shows how the amount of blood available will change over time, including when previous draws will drop off. Hover over the timepoints for more information.
',
+ border: false,
+ style: 'margin-bottom: 20px'
+ });
+ }
+
+ var layerName = "Volume";
+ toAdd.push({
+ xtype: 'container',
+ items: [{
+ xtype: 'ldk-graphpanel',
+ margin: '0 0 0 0',
+ plotConfig: {
+ results: results,
+ title: 'Blood Available To Be Drawn: ' + subject,
+ height: this.plotHeight,
+ width: this.getWidth() - 50,
+ yLabel: 'Available Blood (mL)',
+ xLabel: 'Date',
+ xField: 'date',
+ grouping: ['seriesId'],
+ scales: {
+ shape: {
+ scaleType: 'discrete',
+ range: [LABKEY.vis.Scale.Shape()[1], LABKEY.vis.Scale.Shape()[0],
+ LABKEY.vis.Scale.Shape()[4], LABKEY.vis.Scale.Shape()[0]],
+ domain: ["0 " + layerName, "1 " + layerName, "2 " + layerName, "3 " + layerName]
+ },
+ color: {
+ scaleType: 'discrete',
+ range: [LABKEY.vis.Scale.ColorDiscrete()[1], LABKEY.vis.Scale.ColorDiscrete()[0], "#2fad24", "red", "black"],
+ domain: ["0 " + layerName, "1 " + layerName, "2 " + layerName, "3 " + layerName]
+ }
+ ,
+ size: {
+ scaleType: 'discrete',
+ range: [5, 7],
+ domain: ["0 " + layerName, "1 " + layerName]
+ },
+ x: {
+ tickValues: this.getTickValues(results.rows)
+ },
+ y: {
+ domain: [0, this.getMaxBloodAvailValue(results.rows)],
+ }
+ },
+ layers: [{
+ y: 'allowableBlood',
+ hoverText: function(row){
+ var lines = [];
+
+ if(row.isDeath) {
+ lines.push('DEATH');
+ }
+ lines.push('Date: ' + Ext4.Date.format(row.date, LABKEY.extDefaultDateFormat));
+ lines.push('Drawn on this Date: ' + row.quantity);
+ lines.push('Volume Available on this Date: ' + LABKEY.Utils.roundNumber(row.allowableDisplay, 1) + ' mL');
+
+ lines.push('Current Weight: ' + row.mostRecentWeight + ' kg (' + Ext4.Date.format(row.mostRecentWeightDate, LABKEY.extDefaultDateFormat) + ')');
+
+ lines.push('Drawn in Previous ' + row.blood_draw_interval + ' days: ' + LABKEY.Utils.roundNumber(row.bloodPrevious, 1));
+
+ if (new Date(row.date) < new Date() && !row.isToday)
+ lines.push('Drawn in Next ' + row.blood_draw_interval + ' days: ' + LABKEY.Utils.roundNumber(row.bloodFuture, 1));
+
+
+ return lines.join('\n');
+ },
+ name: layerName
+ }]
+ },
+ getPlotConfig: function(){
+ var cfg = LDK.panel.GraphPanel.prototype.getPlotConfig.call(this);
+ cfg.legendData = [
+ {
+ color:'#FC8D62',
+ text:'Scheduled Blood Draw Status',
+ shape: LABKEY.vis.Scale.Shape()[1]
+ },
+ {
+ color:'#66C2A5',
+ text:'Non-scheduled Blood Draw Status',
+ shape: LABKEY.vis.Scale.Shape()[0]
+ }
+ ]
+ cfg.aes.color = null;
+ cfg.aes.shape = null;
+
+ return cfg;
+ },
+
+ //@Override
+ appendLayer: function(plot, layerConfig){
+ var meta = this.findMetadata(layerConfig.y);
+ plot.addLayer(new LABKEY.vis.Layer({
+ geom: new LABKEY.vis.Geom.Point({size: 5}),
+ name: layerConfig.name || meta.caption,
+ aes: {
+ y: function(row){
+ if (row.isHidden)
+ return null;
+
+ return row[layerConfig.y]
+ },
+ hoverText: layerConfig.hoverText,
+ shape: function(row){
+ if(row.isDeath)
+ return 2;
+ if(row.isToday)
+ return 3;
+ if(row.quantity > 0) {
+ return 0;
+ }
+ return 1;
+ },
+ color: function(row){
+ if(row.isToday)
+ return 4;
+ if(row.isDeath)
+ return 4;
+
+ if(row.quantity > 0) {
+ return 0;
+ }
+
+ return 1;
+ },
+ size: function(row) {
+ if(row.isToday)
+ return 1;
+ if(row.isDeath)
+ return 1;
+
+ return 0;
+ }
+ }
+ }));
+
+ //now add segments. this is an odd way to accomplish grouping, but
+ //otherwise Vis will give each segment a different color
+ Ext4.each(seriesIds, function(seriesId){
+ plot.addLayer(new LABKEY.vis.Layer({
+ geom: new LABKEY.vis.Geom.Path({size: 5, opacity: 2}),
+ name: layerConfig.name || meta.caption,
+ aes: {
+ y: function(row){
+ if (row.seriesId != seriesId)
+ return null;
+
+ return row[layerConfig.y];
+ },
+ group: 'none'
+ }
+ }));
+ }, this);
+ }
+ }]
+ });
+
+ // If defined, add additional items below plot
+ if(Ext4.isDefined(this.getSubjectItems) && Ext4.isFunction(this.getSubjectItems)) {
+ toAdd = toAdd.concat(this.getSubjectItems(subject, dd));
+ }
+ else if(Ext4.isDefined(this.getSubjectItems) && !Ext4.isFunction(this.getSubjectItems)) {
+ console.log("getSubjectItems must be a function returning an array of items to append after the plot")
+ }
+
+
+ return toAdd;
+ }
+
+
+});
\ No newline at end of file
diff --git a/WNPRC_EHR/resources/web/wnprc_ehr/wnprcReports.js b/WNPRC_EHR/resources/web/wnprc_ehr/wnprcReports.js
index b9e718175..003e278f0 100644
--- a/WNPRC_EHR/resources/web/wnprc_ehr/wnprcReports.js
+++ b/WNPRC_EHR/resources/web/wnprc_ehr/wnprcReports.js
@@ -1247,6 +1247,36 @@ EHR.reports['abstract'] = function(panel, tab){
EHR.reports.weightGraph(panel, tab);
};
+EHR.reports.BloodSummary = function(panel, tab){
+ var filterArray = panel.getFilterArray(tab);
+ var title = panel.getTitleSuffix();
+
+ tab.add({
+ html: 'This report summarizes the blood available for the animals below. ' +
+ '
If there have been recent blood draws for the animal, a graph will show the available blood over time. On the graph, dots indicate dates when either blood was drawn or a previous blood draw fell off. The horizontal lines indicate the maximum allowable blood that can be drawn on that date.',
+ border: false,
+ style: 'padding-bottom: 20px;'
+ });
+
+ var subjects = tab.filters.subjects || [];
+
+ if (subjects.length){
+ tab.add({
+ xtype: 'wnprc-bloodsummarypanel',
+ subjects: subjects
+ });
+ }
+ else
+ {
+ panel.resolveSubjectsFromHousing(tab, function(subjects, tab){
+ tab.add({
+ xtype: 'wnprc-bloodsummarypanel',
+ subjects: subjects
+ });
+ }, this);
+ }
+};
+
(function() {
var abstractReport = EHR.reports['abstract'];
diff --git a/WNPRC_EHR/src/org/labkey/wnprc_ehr/WNPRC_EHRModule.java b/WNPRC_EHR/src/org/labkey/wnprc_ehr/WNPRC_EHRModule.java
index 215aac420..e9bb96249 100644
--- a/WNPRC_EHR/src/org/labkey/wnprc_ehr/WNPRC_EHRModule.java
+++ b/WNPRC_EHR/src/org/labkey/wnprc_ehr/WNPRC_EHRModule.java
@@ -233,6 +233,7 @@ protected void doStartupAfterSpringConfig(ModuleContext moduleContext)
EHRService.get().registerClientDependency(ClientDependency.supplierFromPath("wnprc_ehr/reports/AfternoonTreatmentsReport.js"), this);
EHRService.get().registerClientDependency(ClientDependency.supplierFromPath("wnprc_ehr/reports/EveningTreatmentsReport.js"), this);
EHRService.get().registerClientDependency(ClientDependency.supplierFromPath("wnprc_ehr/reports/MasterTreatmentsReport.js"), this);
+ EHRService.get().registerClientDependency(ClientDependency.supplierFromPath("wnprc_ehr/panel/BloodSummaryPanel.js"), this);
EHRService.get().registerClientDependency(ClientDependency.supplierFromPath("wnprc_ehr/Inroom.js"), this);
EHRService.get().registerReportLink(EHRService.REPORT_LINK_TYPE.housing, "List Single-housed Animals", this, DetailsURL.fromString("/query/executeQuery.view?schemaName=study&query.queryName=Demographics&query.viewName=Single%20Housed"), "Commonly Used Queries");
From f9f9e93026a92a5955fd990b141761ea8f53d775 Mon Sep 17 00:00:00 2001
From: Chad Sebranek
Date: Wed, 11 Sep 2024 11:34:25 -0500
Subject: [PATCH 02/13] exclude today for next 30 days calculation of blood,
fix blood summary calc, adjust labels
---
.../queries/study/BloodSchedule/Blood Schedule.qview.xml | 6 +++++-
WNPRC_EHR/resources/queries/study/Current Blood.query.xml | 3 ++-
WNPRC_EHR/resources/queries/study/Current Blood.sql | 2 +-
WNPRC_EHR/resources/queries/study/bloodSummary.sql | 5 +++--
4 files changed, 11 insertions(+), 5 deletions(-)
diff --git a/WNPRC_EHR/resources/queries/study/BloodSchedule/Blood Schedule.qview.xml b/WNPRC_EHR/resources/queries/study/BloodSchedule/Blood Schedule.qview.xml
index 04e7ac58e..3e8dccc9f 100644
--- a/WNPRC_EHR/resources/queries/study/BloodSchedule/Blood Schedule.qview.xml
+++ b/WNPRC_EHR/resources/queries/study/BloodSchedule/Blood Schedule.qview.xml
@@ -56,7 +56,11 @@
-
+
+
+
+
+
diff --git a/WNPRC_EHR/resources/queries/study/Current Blood.query.xml b/WNPRC_EHR/resources/queries/study/Current Blood.query.xml
index f5116e3eb..34ccca609 100644
--- a/WNPRC_EHR/resources/queries/study/Current Blood.query.xml
+++ b/WNPRC_EHR/resources/queries/study/Current Blood.query.xml
@@ -26,7 +26,7 @@
- Next 30 Days (inclusive)
+ Next 30 Days (excluding today)
/query/executeQuery.view?schemaName=study&
query.queryName=Blood Draws&
query.viewName=Blood Summary&
@@ -63,6 +63,7 @@
Volume Remaining After Draw (mL)
+ Volume Remaining Over Next 30 Days
/WNPRC/EHR/ehr-animalHistory.view#subjects:${Id}&inputType:singleSubject&showReport:1&activeReport:BloodSummary
diff --git a/WNPRC_EHR/resources/queries/study/Current Blood.sql b/WNPRC_EHR/resources/queries/study/Current Blood.sql
index 54195ace4..c99ee0b0f 100644
--- a/WNPRC_EHR/resources/queries/study/Current Blood.sql
+++ b/WNPRC_EHR/resources/queries/study/Current Blood.sql
@@ -51,7 +51,7 @@ FROM
FROM study."Blood Draws" draws
WHERE draws.id=bi.id
AND draws.date <= TIMESTAMPADD('SQL_TSI_DAY', 29, bi.date)
- AND cast(draws.date as date) >= bi.date
+ AND cast(draws.date as date) > bi.date
--AND draws.date BETWEEN bi.date AND TIMESTAMPADD('SQL_TSI_DAY', 29, bi.date)
AND (draws.qcstate.metadata.DraftData = true OR draws.qcstate.publicdata = true)
--when counting forwards, dont include this date
diff --git a/WNPRC_EHR/resources/queries/study/bloodSummary.sql b/WNPRC_EHR/resources/queries/study/bloodSummary.sql
index c38ff59ff..bf8e1eb85 100644
--- a/WNPRC_EHR/resources/queries/study/bloodSummary.sql
+++ b/WNPRC_EHR/resources/queries/study/bloodSummary.sql
@@ -58,8 +58,9 @@ FROM
(SELECT SUM(coalesce(draws.quantity, 0)) AS _expr
FROM study."Blood Draws" draws
WHERE draws.id=bi.id
- AND (cast(draws.date as date) >= cast(TIMESTAMPADD('SQL_TSI_DAY', 29, bi.date) as date) AND cast(draws.date as date) <= cast(bi.date as date))
- AND cast(draws.date as date) >= bi.date
+ AND draws.date <= TIMESTAMPADD('SQL_TSI_DAY', 29, bi.date)
+ AND cast(draws.date as date) > bi.date
+ --AND draws.date BETWEEN bi.date AND TIMESTAMPADD('SQL_TSI_DAY', 29, bi.date)
AND (draws.qcstate.metadata.DraftData = true OR draws.qcstate.publicdata = true)
), 0 )
) AS BloodNext30
From 9c273ab051ff9aa671d6a8ff52017ad23846c225 Mon Sep 17 00:00:00 2001
From: Chad Sebranek
Date: Wed, 11 Sep 2024 12:06:19 -0500
Subject: [PATCH 03/13] use next 30 days since it does not include today
---
WNPRC_EHR/resources/queries/study/Current Blood.sql | 2 +-
WNPRC_EHR/resources/queries/study/bloodSummary.sql | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/WNPRC_EHR/resources/queries/study/Current Blood.sql b/WNPRC_EHR/resources/queries/study/Current Blood.sql
index c99ee0b0f..1baa7d91a 100644
--- a/WNPRC_EHR/resources/queries/study/Current Blood.sql
+++ b/WNPRC_EHR/resources/queries/study/Current Blood.sql
@@ -50,7 +50,7 @@ FROM
(SELECT SUM(coalesce(draws.quantity, 0)) AS _expr
FROM study."Blood Draws" draws
WHERE draws.id=bi.id
- AND draws.date <= TIMESTAMPADD('SQL_TSI_DAY', 29, bi.date)
+ AND draws.date <= TIMESTAMPADD('SQL_TSI_DAY', 30, bi.date)
AND cast(draws.date as date) > bi.date
--AND draws.date BETWEEN bi.date AND TIMESTAMPADD('SQL_TSI_DAY', 29, bi.date)
AND (draws.qcstate.metadata.DraftData = true OR draws.qcstate.publicdata = true)
diff --git a/WNPRC_EHR/resources/queries/study/bloodSummary.sql b/WNPRC_EHR/resources/queries/study/bloodSummary.sql
index bf8e1eb85..337ff9d5f 100644
--- a/WNPRC_EHR/resources/queries/study/bloodSummary.sql
+++ b/WNPRC_EHR/resources/queries/study/bloodSummary.sql
@@ -58,7 +58,7 @@ FROM
(SELECT SUM(coalesce(draws.quantity, 0)) AS _expr
FROM study."Blood Draws" draws
WHERE draws.id=bi.id
- AND draws.date <= TIMESTAMPADD('SQL_TSI_DAY', 29, bi.date)
+ AND draws.date <= TIMESTAMPADD('SQL_TSI_DAY', 30, bi.date)
AND cast(draws.date as date) > bi.date
--AND draws.date BETWEEN bi.date AND TIMESTAMPADD('SQL_TSI_DAY', 29, bi.date)
AND (draws.qcstate.metadata.DraftData = true OR draws.qcstate.publicdata = true)
From 201d2f9f04c86cb79774d0378f0f3496f231b549 Mon Sep 17 00:00:00 2001
From: Chad Sebranek
Date: Mon, 23 Sep 2024 10:15:09 -0500
Subject: [PATCH 04/13] use ehr version
---
WNPRC_EHR/resources/web/wnprc_ehr/wnprcReports.js | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/WNPRC_EHR/resources/web/wnprc_ehr/wnprcReports.js b/WNPRC_EHR/resources/web/wnprc_ehr/wnprcReports.js
index 003e278f0..3cdaf8aad 100644
--- a/WNPRC_EHR/resources/web/wnprc_ehr/wnprcReports.js
+++ b/WNPRC_EHR/resources/web/wnprc_ehr/wnprcReports.js
@@ -1248,9 +1248,6 @@ EHR.reports['abstract'] = function(panel, tab){
};
EHR.reports.BloodSummary = function(panel, tab){
- var filterArray = panel.getFilterArray(tab);
- var title = panel.getTitleSuffix();
-
tab.add({
html: 'This report summarizes the blood available for the animals below. ' +
'
If there have been recent blood draws for the animal, a graph will show the available blood over time. On the graph, dots indicate dates when either blood was drawn or a previous blood draw fell off. The horizontal lines indicate the maximum allowable blood that can be drawn on that date.',
@@ -1262,7 +1259,7 @@ EHR.reports.BloodSummary = function(panel, tab){
if (subjects.length){
tab.add({
- xtype: 'wnprc-bloodsummarypanel',
+ xtype: 'ehr-bloodsummarypanel',
subjects: subjects
});
}
@@ -1270,7 +1267,7 @@ EHR.reports.BloodSummary = function(panel, tab){
{
panel.resolveSubjectsFromHousing(tab, function(subjects, tab){
tab.add({
- xtype: 'wnprc-bloodsummarypanel',
+ xtype: 'ehr-bloodsummarypanel',
subjects: subjects
});
}, this);
From f93b0116b6a0e772f433be5ee00335c36a6786f6 Mon Sep 17 00:00:00 2001
From: Chad Sebranek
Date: Tue, 24 Sep 2024 11:34:54 -0500
Subject: [PATCH 05/13] remove wnprc blood graph to use ehr instead
---
.../web/wnprc_ehr/panel/BloodSummaryPanel.js | 570 ------------------
.../org/labkey/wnprc_ehr/WNPRC_EHRModule.java | 1 -
2 files changed, 571 deletions(-)
delete mode 100644 WNPRC_EHR/resources/web/wnprc_ehr/panel/BloodSummaryPanel.js
diff --git a/WNPRC_EHR/resources/web/wnprc_ehr/panel/BloodSummaryPanel.js b/WNPRC_EHR/resources/web/wnprc_ehr/panel/BloodSummaryPanel.js
deleted file mode 100644
index c4c298ee8..000000000
--- a/WNPRC_EHR/resources/web/wnprc_ehr/panel/BloodSummaryPanel.js
+++ /dev/null
@@ -1,570 +0,0 @@
-/*
- * Copyright (c) 2016-2019 LabKey Corporation
- *
- * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0
- */
-/*
- * Title: BloodSummaryPanel
- * Description: This will generate the blood report plot for each subject ID passed in. Provides a hook to add
- * additional items in the report.
- * Config: {
- * subjects: Array of animal IDs,
- * getSubjectItems(optional): Function returning an array of items to add for each subject ID after the plot
- * }
- */
-
-Ext4.define('WNPRC.panel.BloodSummaryPanel', {
- extend: 'Ext.panel.Panel',
- alias: 'widget.wnprc-bloodsummarypanel',
- intervals: {},
- plotHeight: 400,
-
- bloodPerKgCol: 'species/blood_per_kg',
- bloodMaxDrawPctCol: 'species/max_draw_pct',
- bloodDrawIntervalCol: 'species/blood_draw_interval',
-
- initComponent: function(){
- Ext4.apply(this, {
- border: false,
- defaults: {
- border: false
- },
- items: [{
- html: 'Loading...'
- }]
- });
-
- this.callParent();
-
- if(!Ext4.isDefined(this.subjects) || !Ext4.isArray(this.subjects))
- console.log("Must pass in an array of animal IDs as subjects.")
- else
- this.loadData();
- },
-
- loadData: function(){
- var demoCols = 'id,species,id/MostRecentWeight/mostRecentWeight,id/MostRecentWeight/mostRecentWeightDate,Id/demographics/calculated_status,Id/demographics/calculated_status/meaning'
- + ',' + this.bloodPerKgCol + ',' + this.bloodMaxDrawPctCol + ',' + this.bloodDrawIntervalCol;
-
- LABKEY.Query.selectRows({
- schemaName: 'study',
- queryName: 'demographics',
- filterArray: [LABKEY.Filter.create('id', this.subjects.join(';'), LABKEY.Filter.Types.EQUALS_ONE_OF)],
- columns: demoCols,
- requiredVersion: 9.1,
- sort: 'id',
- scope: this,
- failure: LDK.Utils.getErrorCallback(),
- success: function(results){
- this.demographicsMap = {};
- this.intervals = {};
-
- Ext4.each(results.rows, function(row){
- var map = new LDK.SelectRowsRow(row);
- var interval = row[this.bloodDrawIntervalCol].value;
- this.demographicsMap[map.getValue('id')] = map;
-
- if(!interval) {
- interval = 42;
- }
- if( this.intervals.hasOwnProperty(interval) ) {
- this.intervals[interval].push(row.Id.value)
- } else {
- this.intervals[interval] = [row.Id.value];
- }
-
- }, this);
-
- this.loadBloodData();
- }
- });
- },
-
- loadBloodData: function() {
- var multi = new LABKEY.MultiRequest();
-
- for(var interval in this.intervals) {
- if (this.intervals.hasOwnProperty(interval)) {
-
- multi.add(LABKEY.Ajax.request, {
- url: LABKEY.ActionURL.buildURL("ehr", "bloodPlotData"),
- params: {
- ids: this.intervals[interval],
- interval: interval
- },
- method : 'POST',
- requiredVersion: 9.1,
- scope: this,
- failure: LDK.Utils.getErrorCallback(),
- success: function (response)
- {
- var results = JSON.parse(response.responseText);
- console.log(results);
-
- var meta = results.metaData.fields;
- for(var i = 0; i dDate) {
- return;
- }
- }
- //End TODO
- if (rDate && Ext4.Date.format(rDate, LABKEY.extDefaultDateFormat) == Ext4.Date.format(new Date(), LABKEY.extDefaultDateFormat)) {
- row.isToday = {value: true};
- }
- }
-
- if (!this.currentBloodMap[id])
- this.currentBloodMap[id] = [];
-
- this.currentBloodMap[id].push(row);
- }, this);
-
- if(this.bloodDrawResults) {
- this.bloodDrawResults.rows = this.bloodDrawResults.rows.concat(results.rows);
- } else {
- this.bloodDrawResults = results;
- }
- }
- });
- }
- }
-
- multi.send(this.onLoad, this);
- },
-
- onLoad: function(results){
- var toAdd = [];
- Ext4.each(this.subjects, function(subject){
- var dd = this.demographicsMap[subject];
- var bds = this.currentBloodMap[subject];
-
- var cfg = {
- xtype: 'ldk-webpartpanel',
- style: 'margin-bottom: 20px;',
- title: 'Blood Summary: ' + subject,
- defaults: {
- border: false
- },
- items: []
- };
-
- if (!dd){
- cfg.items.push({
- html: 'Either species or weight information is missing for this animal'
- });
- }
- else {
- var status = dd.getValue('Id/demographics/calculated_status/meaning') || dd.getValue('Id/demographics/calculated_status');
- cfg.items.push({
- html: 'Id: ' + dd.getValue('Id') + (status ? ' (' + status + ')' : '') + ''
- });
-
- cfg.items.push({
- html: '
'
- });
-
- if(status != null && status.toLowerCase() === "dead") {
- cfg.items.push({
- html: 'No current blood draw information for dead animal.',
- border: false
- });
- }
- else if (!bds || bds.length === 1) {
- var maxDraw = dd.getValue(this.bloodPerKgCol) * dd.getValue(this.bloodMaxDrawPctCol) * dd.getValue('id/MostRecentWeight/mostRecentWeight');
- cfg.items.push({
- html: 'There are no previous blood draws within the relevant time frame. A maximum amount of ' + Ext4.util.Format.round(maxDraw, 2) + ' mL can be drawn.',
- border: false
- });
- }
- else {
- cfg.items = cfg.items.concat(this.getGraphCfg(dd, bds));
- }
- }
-
- toAdd.push(cfg);
- }, this);
-
- this.removeAll();
- if (toAdd.length){
- this.add(toAdd);
- }
- else {
- this.add({
- html: 'No records found'
- });
- }
-
- this.addAdditionalGraphOptions();
- },
-
- addAdditionalGraphOptions: function() {
- var svgs = d3.selectAll('svg');
- var patternHeight = 8;
-
- // Add shading pattern
- var defs = svgs.selectAll('defs')
- .append('pattern')
- .attr('id', 'diag-pattern')
- .attr('patternUnits', 'userSpaceOnUse')
- .attr('x', 0)
- .attr('y', 0)
- .attr('width', 3)
- .attr('height', patternHeight)
- .attr('patternTransform', 'rotate(30)')
- .append('rect')
- .attr('x', 0)
- .attr('y', 0)
- .attr('width',.5)
- .attr('height', patternHeight)
- .attr('style', 'stroke:none;')
- .attr('fill', 'red');
-
-
- // Add under zero shading
- Ext4.each(svgs[0], function(svg) {
- var ticks = svg.getElementsByClassName('axis')[1].getElementsByClassName('tick-text')[0].getElementsByTagName('g');
- Ext4.each(ticks, function(tick) {
- if(tick.getElementsByTagName('text')[0].textContent === '0') {
- var axis = d3.select(tick.parentElement.parentElement);
- var tickText = d3.select(tick.parentElement);
- axis.append('rect')
- .attr('x', tick.getBBox().x + 16)
- .attr('y', tick.getBBox().y + 11)
- .attr('width', axis[0][0].getBBox().width - tickText[0][0].getBBox().width - 10)
- .attr('height', this.plotHeight - tick.getBBox().y - 60)
- .attr('fill-opacity',.5)
- .attr('fill', 'url(#diag-pattern)');
- }
- },this)
- },this);
-
- var points = d3.selectAll('a.point');
- var todayPoints = points.filter(function(d) {
- return (d.isToday && d.isToday == true);
- });
-
- // Add Today line and text
- todayPoints.append(function(d,i) {
-
- // Hijack the loop to setup line
- var yAxis = d3.selectAll('svg').select('g.grid-line path')[0][i];
- var path = yAxis.getAttribute('d');
- var bottom = Number(path.substring(path.indexOf(',')+1, path.indexOf('L')));
- var top = Number(path.substring(path.indexOf(',', path.indexOf(',')+1)+1, path.indexOf('Z')));
- var ht = bottom - top;
- this.getElementsByTagName('path')[0]
- .setAttribute('d', "M0 " + (ht + 68 - this.getBBox().y) + " l0 -" + (ht-1));
-
- var text = document.createElementNS(d3.ns.prefix.svg, 'text');
- text.setAttribute("x", this.getBBox().x - 18);
- text.setAttribute("y", this.getBBox().y - 3);
- text.setAttribute("style", "font-weight:bold;font-family:Arial;font-size:11px;");
- text.setAttribute("fill", "black");
- text.setAttribute("visibility", "visible");
- text.textContent = "Today";
-
- return text;
- });
- },
- getMaxBloodAvailValue: function(rows){
-
- var allowableBloodVals = [];
- for (var i = 0; i < rows.length; i++){
- allowableBloodVals.push(rows[i].allowableDisplay.value);
- }
-
- return Math.round(allowableBloodVals.reduce((a, b) => Math.max(a, b), -Infinity)) + 10;
- },
-
- getTickValues: function(rows){
- var ticks = [], msPerDay = 86400000, totalTicks = 10;
- var minDate = Date.parse(rows[0].date.value);
- var minDateGmt = Date.parse(rows[0].date.value.concat(" GMT"));
- var maxDate = Date.parse(rows[rows.length - 1].date.value);
- var diff = maxDate - minDate;
- var daysTotal = diff/msPerDay;
- var daysPerTick = Math.ceil(daysTotal/totalTicks);
- var newTotal = Math.ceil(daysTotal/daysPerTick);
-
- ticks[0] = (Math.ceil(minDate/msPerDay) * msPerDay)
- - (msPerDay - (minDate - minDateGmt)); // Offset timezone
- for(var i=1; iTotal volume of blood collected in the past ' + currentRow.blood_draw_interval.value + ' days: '
- + Ext4.util.Format.round(currentRow.bloodPrevious.value, 1) + ' mL. '
- + 'The amount of blood available if drawn today is: ' + Ext4.util.Format.round(currentRow.allowableDisplay.value, 1) + ' mL.'
- + 'The graph below shows how the amount of blood available will change over time, including when previous draws will drop off. Hover over the timepoints for more information.
',
- border: false,
- style: 'margin-bottom: 20px'
- });
- }
-
- var layerName = "Volume";
- toAdd.push({
- xtype: 'container',
- items: [{
- xtype: 'ldk-graphpanel',
- margin: '0 0 0 0',
- plotConfig: {
- results: results,
- title: 'Blood Available To Be Drawn: ' + subject,
- height: this.plotHeight,
- width: this.getWidth() - 50,
- yLabel: 'Available Blood (mL)',
- xLabel: 'Date',
- xField: 'date',
- grouping: ['seriesId'],
- scales: {
- shape: {
- scaleType: 'discrete',
- range: [LABKEY.vis.Scale.Shape()[1], LABKEY.vis.Scale.Shape()[0],
- LABKEY.vis.Scale.Shape()[4], LABKEY.vis.Scale.Shape()[0]],
- domain: ["0 " + layerName, "1 " + layerName, "2 " + layerName, "3 " + layerName]
- },
- color: {
- scaleType: 'discrete',
- range: [LABKEY.vis.Scale.ColorDiscrete()[1], LABKEY.vis.Scale.ColorDiscrete()[0], "#2fad24", "red", "black"],
- domain: ["0 " + layerName, "1 " + layerName, "2 " + layerName, "3 " + layerName]
- }
- ,
- size: {
- scaleType: 'discrete',
- range: [5, 7],
- domain: ["0 " + layerName, "1 " + layerName]
- },
- x: {
- tickValues: this.getTickValues(results.rows)
- },
- y: {
- domain: [0, this.getMaxBloodAvailValue(results.rows)],
- }
- },
- layers: [{
- y: 'allowableBlood',
- hoverText: function(row){
- var lines = [];
-
- if(row.isDeath) {
- lines.push('DEATH');
- }
- lines.push('Date: ' + Ext4.Date.format(row.date, LABKEY.extDefaultDateFormat));
- lines.push('Drawn on this Date: ' + row.quantity);
- lines.push('Volume Available on this Date: ' + LABKEY.Utils.roundNumber(row.allowableDisplay, 1) + ' mL');
-
- lines.push('Current Weight: ' + row.mostRecentWeight + ' kg (' + Ext4.Date.format(row.mostRecentWeightDate, LABKEY.extDefaultDateFormat) + ')');
-
- lines.push('Drawn in Previous ' + row.blood_draw_interval + ' days: ' + LABKEY.Utils.roundNumber(row.bloodPrevious, 1));
-
- if (new Date(row.date) < new Date() && !row.isToday)
- lines.push('Drawn in Next ' + row.blood_draw_interval + ' days: ' + LABKEY.Utils.roundNumber(row.bloodFuture, 1));
-
-
- return lines.join('\n');
- },
- name: layerName
- }]
- },
- getPlotConfig: function(){
- var cfg = LDK.panel.GraphPanel.prototype.getPlotConfig.call(this);
- cfg.legendData = [
- {
- color:'#FC8D62',
- text:'Scheduled Blood Draw Status',
- shape: LABKEY.vis.Scale.Shape()[1]
- },
- {
- color:'#66C2A5',
- text:'Non-scheduled Blood Draw Status',
- shape: LABKEY.vis.Scale.Shape()[0]
- }
- ]
- cfg.aes.color = null;
- cfg.aes.shape = null;
-
- return cfg;
- },
-
- //@Override
- appendLayer: function(plot, layerConfig){
- var meta = this.findMetadata(layerConfig.y);
- plot.addLayer(new LABKEY.vis.Layer({
- geom: new LABKEY.vis.Geom.Point({size: 5}),
- name: layerConfig.name || meta.caption,
- aes: {
- y: function(row){
- if (row.isHidden)
- return null;
-
- return row[layerConfig.y]
- },
- hoverText: layerConfig.hoverText,
- shape: function(row){
- if(row.isDeath)
- return 2;
- if(row.isToday)
- return 3;
- if(row.quantity > 0) {
- return 0;
- }
- return 1;
- },
- color: function(row){
- if(row.isToday)
- return 4;
- if(row.isDeath)
- return 4;
-
- if(row.quantity > 0) {
- return 0;
- }
-
- return 1;
- },
- size: function(row) {
- if(row.isToday)
- return 1;
- if(row.isDeath)
- return 1;
-
- return 0;
- }
- }
- }));
-
- //now add segments. this is an odd way to accomplish grouping, but
- //otherwise Vis will give each segment a different color
- Ext4.each(seriesIds, function(seriesId){
- plot.addLayer(new LABKEY.vis.Layer({
- geom: new LABKEY.vis.Geom.Path({size: 5, opacity: 2}),
- name: layerConfig.name || meta.caption,
- aes: {
- y: function(row){
- if (row.seriesId != seriesId)
- return null;
-
- return row[layerConfig.y];
- },
- group: 'none'
- }
- }));
- }, this);
- }
- }]
- });
-
- // If defined, add additional items below plot
- if(Ext4.isDefined(this.getSubjectItems) && Ext4.isFunction(this.getSubjectItems)) {
- toAdd = toAdd.concat(this.getSubjectItems(subject, dd));
- }
- else if(Ext4.isDefined(this.getSubjectItems) && !Ext4.isFunction(this.getSubjectItems)) {
- console.log("getSubjectItems must be a function returning an array of items to append after the plot")
- }
-
-
- return toAdd;
- }
-
-
-});
\ No newline at end of file
diff --git a/WNPRC_EHR/src/org/labkey/wnprc_ehr/WNPRC_EHRModule.java b/WNPRC_EHR/src/org/labkey/wnprc_ehr/WNPRC_EHRModule.java
index e9bb96249..215aac420 100644
--- a/WNPRC_EHR/src/org/labkey/wnprc_ehr/WNPRC_EHRModule.java
+++ b/WNPRC_EHR/src/org/labkey/wnprc_ehr/WNPRC_EHRModule.java
@@ -233,7 +233,6 @@ protected void doStartupAfterSpringConfig(ModuleContext moduleContext)
EHRService.get().registerClientDependency(ClientDependency.supplierFromPath("wnprc_ehr/reports/AfternoonTreatmentsReport.js"), this);
EHRService.get().registerClientDependency(ClientDependency.supplierFromPath("wnprc_ehr/reports/EveningTreatmentsReport.js"), this);
EHRService.get().registerClientDependency(ClientDependency.supplierFromPath("wnprc_ehr/reports/MasterTreatmentsReport.js"), this);
- EHRService.get().registerClientDependency(ClientDependency.supplierFromPath("wnprc_ehr/panel/BloodSummaryPanel.js"), this);
EHRService.get().registerClientDependency(ClientDependency.supplierFromPath("wnprc_ehr/Inroom.js"), this);
EHRService.get().registerReportLink(EHRService.REPORT_LINK_TYPE.housing, "List Single-housed Animals", this, DetailsURL.fromString("/query/executeQuery.view?schemaName=study&query.queryName=Demographics&query.viewName=Single%20Housed"), "Commonly Used Queries");
From 4c100ddf54d88a972169f38b69f090b191fffbba Mon Sep 17 00:00:00 2001
From: Chad Sebranek
Date: Wed, 2 Oct 2024 16:37:28 -0500
Subject: [PATCH 06/13] Consolidate blood draw reports into
currentBloodDraws.sql, adjust references
---
.../resources/queries/study/Current Blood.sql | 105 ------------
.../queries/study/Current Blood/.qview.xml | 44 -----
.../study/DailyOverDrawsWithThreshold.sql | 4 +-
.../resources/queries/study/blood.query.xml | 2 +-
.../study/blood/Blood Summary.qview.xml | 2 +-
.../queries/study/bloodDrawChanges.sql | 7 +-
.../queries/study/bloodSummary.query.xml | 39 -----
.../resources/queries/study/bloodSummary.sql | 72 ---------
....query.xml => currentBloodDraws.query.xml} | 153 +++++++++---------
.../queries/study/currentBloodDraws.sql | 55 ++++++-
.../study/currentBloodDraws/.qview.xml | 42 +++++
.../demographics/Blood Draw Info.qview.xml | 10 +-
.../study/demographicsBloodSummary.query.xml | 63 --------
.../study/demographicsBloodSummary.sql | 87 ----------
.../resources/web/wnprc_ehr/wnprcReports.js | 20 +++
.../BloodDrawReviewDailyNotification.java | 8 +-
.../notification/BloodDrawsTodayAll.java | 20 +--
.../notification/NotificationToolkit.java | 6 +-
.../wnprc_ehr/table/WNPRC_EHRCustomizer.java | 2 +-
.../test/tests/wnprc_ehr/WNPRC_EHRTest.java | 4 +-
20 files changed, 225 insertions(+), 520 deletions(-)
delete mode 100644 WNPRC_EHR/resources/queries/study/Current Blood.sql
delete mode 100644 WNPRC_EHR/resources/queries/study/Current Blood/.qview.xml
delete mode 100644 WNPRC_EHR/resources/queries/study/bloodSummary.query.xml
delete mode 100644 WNPRC_EHR/resources/queries/study/bloodSummary.sql
rename WNPRC_EHR/resources/queries/study/{Current Blood.query.xml => currentBloodDraws.query.xml} (74%)
create mode 100644 WNPRC_EHR/resources/queries/study/currentBloodDraws/.qview.xml
delete mode 100644 WNPRC_EHR/resources/queries/study/demographicsBloodSummary.query.xml
delete mode 100644 WNPRC_EHR/resources/queries/study/demographicsBloodSummary.sql
diff --git a/WNPRC_EHR/resources/queries/study/Current Blood.sql b/WNPRC_EHR/resources/queries/study/Current Blood.sql
deleted file mode 100644
index 1baa7d91a..000000000
--- a/WNPRC_EHR/resources/queries/study/Current Blood.sql
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright (c) 2010-2013 LabKey Corporation
- *
- * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0
- */
-SELECT
- bq.*,
- cast(round(bq.weight*species.max_draw_pct*species.blood_per_kg, 1) as numeric) AS MaxBlood,
- cast(round((bq.weight*species.max_draw_pct*species.blood_per_kg) - bq.BloodLast30, 1) AS numeric) AS AvailBlood,
- cast(round((bq.weight*species.max_draw_pct*species.blood_per_kg) - (bq.BloodLast30 + bq.BloodNext30), 1) AS numeric) AS BloodAvailPlusThirty
-FROM
-(
- SELECT
- b.*,
- (d.species) as species,
- (
- CONVERT (
- (SELECT AVG(w.weight) AS _expr
- FROM study.weight w
- WHERE w.id=b.id AND w.date=b.lastWeighDate
- AND w.qcstate.publicdata = true
- ), double )
- ) AS weight
- FROM
- (
- SELECT bi.*
- ,timestampadd('SQL_TSI_DAY', -29, bi.date) as minDate
- ,timestampadd('SQL_TSI_DAY', 29, bi.date) as maxDate
- ,( CONVERT(
- (SELECT MAX(w.date) as _expr
- FROM study.weight w
- WHERE w.id = bi.id
- --AND w.date <= bi.date
- AND CAST(CAST(w.date AS DATE) AS TIMESTAMP) <= bi.date
- AND w.qcstate.publicdata = true
- ), timestamp )
- ) AS lastWeighDate
- , ( COALESCE (
- (SELECT SUM(coalesce(draws.quantity, 0)) AS _expr
- FROM study."Blood Draws" draws
- WHERE draws.id=bi.id
- AND draws.date >= TIMESTAMPADD('SQL_TSI_DAY', -29, bi.date)
- AND cast(draws.date as date) <= bi.date
- AND (draws.qcstate.metadata.DraftData = true OR draws.qcstate.publicdata = true)
- --when counting backwards, dont include this date
- --AND (draws.date != bi.date and draws.qcstate.label != bi.status)
- ), 0 )
- ) AS BloodLast30
- , ( COALESCE (
- (SELECT SUM(coalesce(draws.quantity, 0)) AS _expr
- FROM study."Blood Draws" draws
- WHERE draws.id=bi.id
- AND draws.date <= TIMESTAMPADD('SQL_TSI_DAY', 30, bi.date)
- AND cast(draws.date as date) > bi.date
- --AND draws.date BETWEEN bi.date AND TIMESTAMPADD('SQL_TSI_DAY', 29, bi.date)
- AND (draws.qcstate.metadata.DraftData = true OR draws.qcstate.publicdata = true)
- --when counting forwards, dont include this date
- --AND (draws.date != bi.date and draws.qcstate.label != bi.status)
- ), 0 )
- ) AS BloodNext30
- from (
- SELECT
- b.id,
- --b.id.dataset.demographics.species as species,
- cast(b.date as date) as date,
- --b.lsid,
- --b.qcstate,
- b.qcstate.label as status,
- SUM(coalesce(b.quantity, 0)) as quantity
- FROM study.blood b
- WHERE cast(b.date as date) >= TIMESTAMPADD('SQL_TSI_DAY', -29, now())
- AND (b.qcstate.metadata.DraftData = true OR b.qcstate.publicdata = true)
- group by b.id, cast(b.date as date), b.qcstate.label
-
- UNION ALL
- SELECT
- b.id,
- --b.id.dataset.demographics.species as species,
- TIMESTAMPADD('SQL_TSI_DAY', 30, cast(cast(b.date as date) as timestamp)) as date,
- --null as lsid,
- --null as qcstate,
- null as status,
- 0 as quantity
- FROM study.blood b
- WHERE cast(b.date as date) >= TIMESTAMPADD('SQL_TSI_DAY', -29, now())
- AND (b.qcstate.metadata.DraftData = true OR b.qcstate.publicdata = true)
- GROUP BY b.id, cast(b.date as date)
-
- --add one row per animal, showing todays date
- UNION ALL
- SELECT
- b.id,
- --b.species,
- curdate() as date,
- --null as lsid,
- --null as qcstate,
- null as status,
- 0 as quantity
- FROM study.demographics b
- --WHERE b.id.status.status = 'Alive'
- ) bi
- ) b
- JOIN study.demographics d ON d.id=b.id
- ) bq
-
diff --git a/WNPRC_EHR/resources/queries/study/Current Blood/.qview.xml b/WNPRC_EHR/resources/queries/study/Current Blood/.qview.xml
deleted file mode 100644
index f75cd0a18..000000000
--- a/WNPRC_EHR/resources/queries/study/Current Blood/.qview.xml
+++ /dev/null
@@ -1,44 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/WNPRC_EHR/resources/queries/study/DailyOverDrawsWithThreshold.sql b/WNPRC_EHR/resources/queries/study/DailyOverDrawsWithThreshold.sql
index 9e0ef9abd..e87e21f4b 100644
--- a/WNPRC_EHR/resources/queries/study/DailyOverDrawsWithThreshold.sql
+++ b/WNPRC_EHR/resources/queries/study/DailyOverDrawsWithThreshold.sql
@@ -17,9 +17,9 @@ SELECT b.Id,
b.restraintTime,
b.instructions,
b.restraintDuration,
- b.BloodRemaining.AvailBlood,
+ b.BloodRemaining.allowableBlood,
b.QCState,
b.QCState.label
FROM "Blood Draws" b
LEFT JOIN ehr_lookups.species e ON e.common = b.Id.Demographics.species
-WHERE b.BloodRemaining.AvailBlood < e.blood_threshold_warning AND b.date > curdate() AND b.date < cast(TIMESTAMPADD('SQL_TSI_DAY', 1, curdate()) as date) AND b.QCState.label <> 'Request: Denied'
\ No newline at end of file
+WHERE b.BloodRemaining.allowableBlood < e.blood_threshold_warning AND b.date > curdate() AND b.date < cast(TIMESTAMPADD('SQL_TSI_DAY', 1, curdate()) as date) AND b.QCState.label <> 'Request: Denied'
\ No newline at end of file
diff --git a/WNPRC_EHR/resources/queries/study/blood.query.xml b/WNPRC_EHR/resources/queries/study/blood.query.xml
index 0d4c76bd8..ebb431ad8 100644
--- a/WNPRC_EHR/resources/queries/study/blood.query.xml
+++ b/WNPRC_EHR/resources/queries/study/blood.query.xml
@@ -106,7 +106,7 @@
true
study
- bloodSummary
+ currentBloodDraws
lsid
diff --git a/WNPRC_EHR/resources/queries/study/blood/Blood Summary.qview.xml b/WNPRC_EHR/resources/queries/study/blood/Blood Summary.qview.xml
index 04a6f204a..2e70880c8 100644
--- a/WNPRC_EHR/resources/queries/study/blood/Blood Summary.qview.xml
+++ b/WNPRC_EHR/resources/queries/study/blood/Blood Summary.qview.xml
@@ -38,7 +38,7 @@
-
+
diff --git a/WNPRC_EHR/resources/queries/study/bloodDrawChanges.sql b/WNPRC_EHR/resources/queries/study/bloodDrawChanges.sql
index d358fe95e..d58fd6410 100644
--- a/WNPRC_EHR/resources/queries/study/bloodDrawChanges.sql
+++ b/WNPRC_EHR/resources/queries/study/bloodDrawChanges.sql
@@ -15,10 +15,11 @@
*/
--this query is designed to return any dates when allowable blood draw volume changes
--this includes dates of blood draws, plus the date those draws drop off
-PARAMETERS(DATE_INTERVAL INTEGER)
+PARAMETERS(DATE_INTERVAL INTEGER DEFAULT 30)
SELECT
b2.id,
+ b2.status,
b2.dateOnly,
b2.quantity,
DATE_INTERVAL as blood_draw_interval,
@@ -29,12 +30,14 @@ FROM (
SELECT
b.id,
b.dateOnly,
+ GROUP_CONCAT(b.status,'') as status,
sum(b.quantity) as quantity
FROM (
--find all blood draws within the interval, looking backwards
SELECT
b.id,
+ b.qcstate as status,
b.dateOnly,
b.quantity,
FROM study.blood b
@@ -45,6 +48,7 @@ FROM (
--join 1 row for the current date
SELECT
d1.id,
+ null as status,
curdate() as dateOnly,
0 as quantity,
FROM study.demographics d1
@@ -55,6 +59,7 @@ FROM (
--add one row for each date when the draw drops off the record
SELECT
b.id,
+ null as status,
timestampadd('SQL_TSI_DAY', DATE_INTERVAL, b.dateOnly),
0 as quantity,
FROM study.blood b
diff --git a/WNPRC_EHR/resources/queries/study/bloodSummary.query.xml b/WNPRC_EHR/resources/queries/study/bloodSummary.query.xml
deleted file mode 100644
index 7d3c1c2a2..000000000
--- a/WNPRC_EHR/resources/queries/study/bloodSummary.query.xml
+++ /dev/null
@@ -1,39 +0,0 @@
-
-
-
-
-
-
- true
-
-
-
- Drawn in Previous 30 Days (inclusive)
- /query/executeQuery.view?schemaName=study&
- query.queryName=Blood Draws&
- query.viewName=Blood Summary&
- query.Id~eq=${Id}&
- query.Date~lte=${Date}&
- query.Date~gte=${minDate}&
- query.sort=-Date&
-
-
-
- Scheduled in Next 30 Days (inclusive)
- /query/executeQuery.view?schemaName=study&
- query.queryName=Blood Draws&
- query.viewName=Blood Summary&
- query.Id~eq=${Id}&
- query.Date~gt=${Date}&
- query.sort=-Date&
-
-
-
- /WNPRC/EHR/ehr-animalHistory.view#subjects:${Id}&inputType:singleSubject&showReport:1&activeReport:BloodSummary
-
-
- BloodLast30
-
-
-
-
diff --git a/WNPRC_EHR/resources/queries/study/bloodSummary.sql b/WNPRC_EHR/resources/queries/study/bloodSummary.sql
deleted file mode 100644
index 337ff9d5f..000000000
--- a/WNPRC_EHR/resources/queries/study/bloodSummary.sql
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (c) 2010-2013 LabKey Corporation
- *
- * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0
- */
-SELECT
- bq.lsid,
- bq.id,
- bq.date,
- bq.minDate,
--- bq.maxDate,
- bq.weight,
- bq.lastWeighDate,
- cast(bq.BloodLast30 as numeric) as BloodLast30,
- bq.BloodNext30,
- cast(round(bq.weight*species.max_draw_pct*species.blood_per_kg, 1) as numeric) AS MaxBlood,
- cast(round((bq.weight*species.max_draw_pct*species.blood_per_kg) - bq.BloodLast30, 1) AS numeric) AS AvailBlood,
- cast(round((bq.weight*species.max_draw_pct*species.blood_per_kg) - (bq.BloodLast30 + bq.BloodNext30), 1) AS numeric) AS BloodAvailNowPlusThirtyDays
-FROM
-(
- SELECT
- b.*,
- (d.species) as species,
- (
- CONVERT (
- (SELECT AVG(w.weight) AS _expr
- FROM study.weight w
- WHERE w.id=b.id AND w.date=b.lastWeighDate
- AND w.qcstate.publicdata = true
- ), double )
- ) AS weight
- FROM
- (
- SELECT bi.*
- ,timestampadd('SQL_TSI_DAY', -29, bi.date) as minDate
--- ,timestampadd('SQL_TSI_DAY', 29, bi.date) as maxDate
- , ( CONVERT(
- (SELECT MAX(w.date) as _expr
- FROM study.weight w
- WHERE w.id = bi.id
- --NOTE: we are doing this comparison such that it considers date only, not datetime
- --AND w.date <= bi.date
- AND CAST(CAST(w.date AS DATE) AS TIMESTAMP) <= bi.date
- AND w.qcstate.publicdata = true
- ), timestamp )
- ) AS lastWeighDate
- , ( COALESCE (
- (SELECT SUM(draws.quantity) AS _expr
- FROM study."Blood Draws" draws
- WHERE draws.id=bi.id
- --AND draws.date BETWEEN TIMESTAMPADD('SQL_TSI_DAY', -30, bi.date) AND bi.date
- AND (cast(draws.date as date) >= cast(TIMESTAMPADD('SQL_TSI_DAY', -29, bi.date) as date) AND cast(draws.date as date) <= cast(bi.date as date))
- AND (draws.qcstate.metadata.DraftData = true OR draws.qcstate.publicdata = true)
- --AND draws.qcstate.publicdata = true
- ), 0 )
- ) AS BloodLast30
- , ( COALESCE (
- (SELECT SUM(coalesce(draws.quantity, 0)) AS _expr
- FROM study."Blood Draws" draws
- WHERE draws.id=bi.id
- AND draws.date <= TIMESTAMPADD('SQL_TSI_DAY', 30, bi.date)
- AND cast(draws.date as date) > bi.date
- --AND draws.date BETWEEN bi.date AND TIMESTAMPADD('SQL_TSI_DAY', 29, bi.date)
- AND (draws.qcstate.metadata.DraftData = true OR draws.qcstate.publicdata = true)
- ), 0 )
- ) AS BloodNext30
- FROM study.blood bi
- --WHERE (bi.qcstate.metadata.DraftData = true OR bi.qcstate.publicdata = true)
- ) b
- JOIN study.demographics d ON d.id=b.id
- ) bq
-
diff --git a/WNPRC_EHR/resources/queries/study/Current Blood.query.xml b/WNPRC_EHR/resources/queries/study/currentBloodDraws.query.xml
similarity index 74%
rename from WNPRC_EHR/resources/queries/study/Current Blood.query.xml
rename to WNPRC_EHR/resources/queries/study/currentBloodDraws.query.xml
index 34ccca609..ec7039ef0 100644
--- a/WNPRC_EHR/resources/queries/study/Current Blood.query.xml
+++ b/WNPRC_EHR/resources/queries/study/currentBloodDraws.query.xml
@@ -1,74 +1,79 @@
-
-
-
-
-
-
- true
-
-
-
-
- study
- Animal
- Id
-
-
-
- Previous 30 Days (inclusive)
- /query/executeQuery.view?schemaName=study&
- query.queryName=Blood Draws&
- query.viewName=Blood Summary&
- query.Id~eq=${Id}&
- query.Date~datelte=${Date}&
- query.Date~dategte=${minDate}&
- query.sort=-Date&
-
-
-
- Next 30 Days (excluding today)
- /query/executeQuery.view?schemaName=study&
- query.queryName=Blood Draws&
- query.viewName=Blood Summary&
- query.Id~eq=${Id}&
- query.Date~dategte=${Date}&
- query.sort=-Date&
-
-
-
- Latest Weight (kg)
- /query/executeQuery.view?schemaName=study&
- query.queryName=Weight&
- query.Id~eq=${Id}&
- query.wDate~gt=${wDate}&
- query.sort=-Date&
-
-
-
- yyyy-MM-dd
-
-
- yyyy-MM-dd
-
-
- yyyy-MM-dd
-
-
- yyyy-MM-dd HH:mm
-
-
- 20% Volume By Weight
-
-
- Volume Remaining After Draw (mL)
-
-
- Volume Remaining Over Next 30 Days
- /WNPRC/EHR/ehr-animalHistory.view#subjects:${Id}&inputType:singleSubject&showReport:1&activeReport:BloodSummary
-
-
- BloodLast30
-
-
-
-
+
+
+
+
+
+
+ true
+
+
+
+
+ study
+ Animal
+ Id
+
+
+
+ Status
+
+ core
+ qcstate
+ rowid
+
+
+
+ Previous 30 Days (inclusive)
+ /query/executeQuery.view?schemaName=study&
+ query.queryName=Blood Draws&
+ query.viewName=Blood Summary&
+ query.Id~eq=${Id}&
+ query.Date~datelte=${Date}&
+ query.Date~dategte=${minDate}&
+ query.sort=-Date&
+
+
+
+ Next 30 Days (inclusive)
+ /query/executeQuery.view?schemaName=study&
+ query.queryName=Blood Draws&
+ query.viewName=Blood Summary&
+ query.Id~eq=${Id}&
+ query.Date~dategte=${Date}&
+ query.sort=-Date&
+
+
+
+ Latest Weight (kg)
+ /query/executeQuery.view?schemaName=study&
+ query.queryName=Weight&
+ query.Id~eq=${Id}&
+ query.wDate~gt=${wDate}&
+ query.sort=-Date&
+
+
+
+ yyyy-MM-dd
+
+
+ yyyy-MM-dd
+
+
+ yyyy-MM-dd
+
+
+ 20% Volume By Weight
+
+
+ Volume Remaining After Draw (mL)
+ /WNPRC/EHR/ehr-animalHistory.view#subjects:${Id}&inputType:singleSubject&showReport:1&activeReport:BloodSummary
+
+
+ Volume Remaining Over Next 30 Days
+ /WNPRC/EHR/ehr-animalHistory.view#subjects:${Id}&inputType:singleSubject&showReport:1&activeReport:BloodSummary
+
+
+
+
+
+
diff --git a/WNPRC_EHR/resources/queries/study/currentBloodDraws.sql b/WNPRC_EHR/resources/queries/study/currentBloodDraws.sql
index feda25ea5..cacb6129e 100644
--- a/WNPRC_EHR/resources/queries/study/currentBloodDraws.sql
+++ b/WNPRC_EHR/resources/queries/study/currentBloodDraws.sql
@@ -17,6 +17,7 @@
SELECT
t.id,
t.date,
+ t.status,
cast(t.quantity as double) as quantity,
t.species,
t.max_draw_pct,
@@ -25,7 +26,7 @@ SELECT
t.mostRecentWeight,
t.mostRecentWeightDate,
t.death,
- cast(t.allowableBlood as double) as maxAllowableBlood,
+ cast(round(t.allowableBlood,1) as numeric) as maxAllowableBlood,
cast(t.bloodPrevious as double) as bloodPrevious,
cast((t.allowableBlood - t.bloodPrevious) as double) as allowablePrevious,
@@ -34,11 +35,12 @@ SELECT
--if the draw is historic, always consider previous draws only.
--otherwise, look both forward and backwards, then take the interval with the highest volume
- cast(case
+ cast(round(case
WHEN t.date < curdate() THEN (t.allowableBlood - t.bloodPrevious)
WHEN t.bloodPrevious < t.bloodFuture THEN (t.allowableBlood - t.bloodFuture)
ELSE (t.allowableBlood - t.bloodPrevious)
- end as double) as allowableBlood,
+ end , 1) as numeric) as allowableBlood,
+ cast( round(t.allowableBlood - ((t.bloodPrevious + t.bloodFuture) - t.bloodToday), 1) as numeric) as BloodAvailPlusThirty,
t.minDate,
t.maxDate
@@ -46,17 +48,49 @@ FROM (
SELECT
bd.id,
+ bd.status,
bd.dateOnly as date,
bd.quantity,
d.species,
d.death,
+ (
+ CONVERT (
+ (SELECT AVG(w.weight) AS _expr
+ FROM study.weight w
+ WHERE w.id=bd.id AND w.date=
+ ( CONVERT(
+ (SELECT MAX(w.date) as _expr
+ FROM study.weight w
+ WHERE w.id = bd.id
+ --AND w.date <= bi.date
+ AND CAST(CAST(w.date AS DATE) AS TIMESTAMP) <= bd.dateOnly
+ AND w.qcstate.publicdata = true
+ ), timestamp )
+ )
+ AND w.qcstate.publicdata = true
+ ), double )
+ ) * d.species.max_draw_pct * d.species.blood_per_kg AS allowableBlood,
+
+ (CONVERT (
+ (SELECT AVG(w.weight) AS _expr
+ FROM study.weight w
+ WHERE w.id=bd.id AND w.date=
+ (CONVERT(
+ (SELECT MAX(w.date) as _expr
+ FROM study.weight w
+ WHERE w.id = bd.id
+ --AND w.date <= bi.date
+ AND CAST(CAST(w.date AS DATE) AS TIMESTAMP) <= bd.dateOnly
+ AND w.qcstate.publicdata = true
+ ), timestamp )
+ )
+ AND w.qcstate.publicdata = true
+ ), double ) ) as weight,
d.id.mostRecentWeight.MostRecentWeight,
d.id.mostRecentWeight.MostRecentWeightDate,
d.species.blood_per_kg,
d.species.max_draw_pct,
bd.blood_draw_interval,
-(d.id.mostRecentWeight.MostRecentWeight * d.species.blood_per_kg * d.species.max_draw_pct)
- as allowableBlood,
bd.minDate,
bd.maxDate,
COALESCE(
@@ -77,7 +111,16 @@ SELECT
AND draws.dateOnly >= bd.dateOnly
--NOTE: this has been changed to include pending/non-approved draws
AND draws.countsAgainstVolume = true
- ), 0) AS BloodFuture
+ ), 0) AS BloodFuture,
+
+COALESCE(
+ (SELECT SUM(coalesce(draws.quantity, 0)) AS _expr
+ FROM study."Blood Draws" draws
+ WHERE draws.id = bd.id AND draws.project.research = true
+ AND draws.dateOnly = curdate()
+ --NOTE: this has been changed to include pending/non-approved draws
+ AND draws.countsAgainstVolume = true
+ ), 0) AS BloodToday
FROM study.bloodDrawChanges bd
JOIN study.demographics d ON (d.id = bd.id)
diff --git a/WNPRC_EHR/resources/queries/study/currentBloodDraws/.qview.xml b/WNPRC_EHR/resources/queries/study/currentBloodDraws/.qview.xml
new file mode 100644
index 000000000..f72ca56dd
--- /dev/null
+++ b/WNPRC_EHR/resources/queries/study/currentBloodDraws/.qview.xml
@@ -0,0 +1,42 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/WNPRC_EHR/resources/queries/study/demographics/Blood Draw Info.qview.xml b/WNPRC_EHR/resources/queries/study/demographics/Blood Draw Info.qview.xml
index 7315e444b..96fe4b9e5 100644
--- a/WNPRC_EHR/resources/queries/study/demographics/Blood Draw Info.qview.xml
+++ b/WNPRC_EHR/resources/queries/study/demographics/Blood Draw Info.qview.xml
@@ -34,7 +34,7 @@
-
+
@@ -45,22 +45,22 @@
-
+
-
+
-
+
-
+
diff --git a/WNPRC_EHR/resources/queries/study/demographicsBloodSummary.query.xml b/WNPRC_EHR/resources/queries/study/demographicsBloodSummary.query.xml
deleted file mode 100644
index e680dda90..000000000
--- a/WNPRC_EHR/resources/queries/study/demographicsBloodSummary.query.xml
+++ /dev/null
@@ -1,63 +0,0 @@
-
-
-
-
-
-
- true
- true
-
-
- true
-
-
- /query/executeQuery.view?schemaName=study&
- query.queryName=Blood Draws&
- query.viewName=Blood Summary&
- query.Id~eq=${Id}&
- query.Date~lte=${Date}&
- query.sort=-Date&
-
- Blood Drawn In Previous 30 Days
-
-
- Scheduled in Next 30 Days
- /query/executeQuery.view?schemaName=study&
- query.queryName=Blood Draws&
- query.viewName=Blood Summary&
- query.Id~eq=${Id}&
- query.Date~gt=${Date}&
- query.sort=-Date&
-
-
-
- Max Blood Per 30 Days (mL)
-
-
- Available Blood (mL)
-
-
-
-
-
- FF0000
-
-
-
-
- Current Blood (mL)
-
-
-
-
-
- FBEC5D
-
-
-
-
- AvailBlood
-
-
-
-
diff --git a/WNPRC_EHR/resources/queries/study/demographicsBloodSummary.sql b/WNPRC_EHR/resources/queries/study/demographicsBloodSummary.sql
deleted file mode 100644
index dcf9fd08c..000000000
--- a/WNPRC_EHR/resources/queries/study/demographicsBloodSummary.sql
+++ /dev/null
@@ -1,87 +0,0 @@
-
-
-/*
- * Copyright (c) 2010-2014 LabKey Corporation
- *
- * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0
- */
-SELECT
- b.lsid,
- b.id,
- --b.date,
- b.wdate as MostRecentWeightDate,
- b.weight as MostRecentWeight,
- convert(BloodLast30, float) as BloodLast30,
- convert(BloodNext30, float) as BloodNext30,
- convert(CASE
- WHEN (b.species = 'Marmoset')
- THEN (b.weight*0.15*60)
- ELSE
- (b.weight*0.2*60)
- END, float) AS MaxBlood,
-
- convert(case
- when (b.species = 'Marmoset')
- THEN ((b.weight*0.15*60) - b.BloodLast30)
- else
- ((b.weight*0.2*60) - b.BloodLast30)
- end, float) as CurrentBlood,
-
- TRUNCATE(ROUND(CAST(case
- when (b.BloodLast30 > b.BloodNext30 and b.species = 'Marmoset')
- THEN ((b.weight*0.15*60) - b.BloodLast30)
- when (b.BloodLast30 > b.BloodNext30 and b.species != 'Marmoset')
- THEN ((b.weight*0.2*60) - b.BloodLast30 -b.BloodNext30)
- when (b.BloodLast30 <= b.BloodNext30 and b.species = 'Marmoset')
- THEN ((b.weight*0.15*60) - b.BloodNext30)
- else
- ((b.weight*0.2*60) - b.BloodNext30 - b.BloodLast30)
- end AS NUMERIC),2),2) as AvailBlood
-from (
-SELECT
- d.lsid,
- d.id,
- d.species,
--- d.weight,
--- d.wdate,
- lastWeight.date as wdate,
- (
- SELECT AVG(w.weight) AS _expr
- FROM study.weight w
- WHERE w.id=d.id AND w.date=lastWeight.date
- AND w.qcstate.publicdata = true
- ) AS weight,
- COALESCE ((
- SELECT
- SUM(bd.quantity) AS _expr
- FROM study."Blood Draws" bd
- WHERE bd.id=d.id AND
- bd.qcstate.publicdata = true AND
- --bd.date BETWEEN TIMESTAMPADD('SQL_TSI_DAY', -30, now()) AND now()
- (cast(bd.date as date) >= cast(TIMESTAMPADD('SQL_TSI_DAY', -30, now()) as date) AND cast(bd.date as date) <= cast(curdate() as date))
-
- ), 0) AS BloodLast30,
- COALESCE ((
- SELECT
- SUM(bd.quantity) AS _expr
- FROM study."Blood Draws" bd
- WHERE bd.id=d.id AND
- (bd.qcstate.publicdata = true OR bd.qcstate.metadata.DraftData = true) AND
- --bd.date BETWEEN now() AND TIMESTAMPADD('SQL_TSI_DAY', 30, now())
- (cast(bd.date as date) >= cast(curdate() as date) AND cast(bd.date as date) <= cast(TIMESTAMPADD('SQL_TSI_DAY', 30, now()) as date))
-
- ), 0) AS BloodNext30
-
-FROM
- study.demographics d
- LEFT OUTER JOIN
- (SELECT w.id, MAX(date) as date FROM study.weight w
- WHERE w.qcstate.publicdata = true
- GROUP BY w.id) lastWeight ON d.id = lastWeight.id
-
--- WHERE b.date >= TIMESTAMPADD('SQL_TSI_DAY', -30, now())
-WHERE
-
-d.calculated_status = 'Alive'
-
-) b
\ No newline at end of file
diff --git a/WNPRC_EHR/resources/web/wnprc_ehr/wnprcReports.js b/WNPRC_EHR/resources/web/wnprc_ehr/wnprcReports.js
index 3cdaf8aad..2bebd2370 100644
--- a/WNPRC_EHR/resources/web/wnprc_ehr/wnprcReports.js
+++ b/WNPRC_EHR/resources/web/wnprc_ehr/wnprcReports.js
@@ -661,6 +661,26 @@ EHR.reports.diagnostics = function(panel, tab){
});
};
+EHR.reports.currentBloodDraws = function(panel, tab) {
+ var filterArray = panel.getFilterArray(tab);
+ var title = panel.getTitleSuffix();
+
+ var config = panel.getQWPConfig({
+ schemaName: 'study',
+ queryName: 'currentBloodDraws',
+ title: "Current Blood " + title,
+ parameters: {'interval': '30'},
+ filters: filterArray.nonRemovable,
+ removeableFilters: filterArray.removable
+ });
+
+ tab.add({
+ xtype: 'ldk-querycmp',
+ style: 'margin-bottom:20px;',
+ queryConfig: config
+ });
+}
+
EHR.reports.bloodChemistry = function(panel, tab){
var filterArray = panel.getFilterArray(tab);
var title = panel.getTitleSuffix();
diff --git a/WNPRC_EHR/src/org/labkey/wnprc_ehr/notification/BloodDrawReviewDailyNotification.java b/WNPRC_EHR/src/org/labkey/wnprc_ehr/notification/BloodDrawReviewDailyNotification.java
index 85e38961b..ce0ca3cce 100644
--- a/WNPRC_EHR/src/org/labkey/wnprc_ehr/notification/BloodDrawReviewDailyNotification.java
+++ b/WNPRC_EHR/src/org/labkey/wnprc_ehr/notification/BloodDrawReviewDailyNotification.java
@@ -229,16 +229,16 @@ void getBloodOverdraws() {
// Creates sort.
Sort mySort = new Sort("date");
// Creates columns to retrieve.
- String[] targetColumns = new String[]{"id", "date", "BloodRemaining/AvailBlood"};
+ String[] targetColumns = new String[]{"id", "date", "BloodRemaining/allowableBlood"};
// Runs query.
ArrayList> unformattedUpcomingBloodDraws = notificationToolkit.getTableMultiRowMultiColumnWithFieldKeys(c, u, "study", "BloodSchedule", myFilter, mySort, targetColumns);
// Converts map to list (for displaying in table).
for (HashMap currentDraw : unformattedUpcomingBloodDraws) {
// Verifies there is data because some older blood draws don't list available blood.
- if (!currentDraw.get("BloodRemaining/AvailBlood").isEmpty()) {
- if (Double.valueOf(currentDraw.get("BloodRemaining/AvailBlood")) <= 0) {
- String[] currentRow = {currentDraw.get("id"), currentDraw.get("date"), currentDraw.get("BloodRemaining/AvailBlood")};
+ if (!currentDraw.get("BloodRemaining/allowableBlood").isEmpty()) {
+ if (Double.valueOf(currentDraw.get("BloodRemaining/allowableBlood")) <= 0) {
+ String[] currentRow = {currentDraw.get("id"), currentDraw.get("date"), currentDraw.get("BloodRemaining/allowableBlood")};
bloodOverdraws.add(currentRow);
}
}
diff --git a/WNPRC_EHR/src/org/labkey/wnprc_ehr/notification/BloodDrawsTodayAll.java b/WNPRC_EHR/src/org/labkey/wnprc_ehr/notification/BloodDrawsTodayAll.java
index 8030b9204..b7b7d82fa 100644
--- a/WNPRC_EHR/src/org/labkey/wnprc_ehr/notification/BloodDrawsTodayAll.java
+++ b/WNPRC_EHR/src/org/labkey/wnprc_ehr/notification/BloodDrawsTodayAll.java
@@ -123,7 +123,7 @@ public static class BloodDrawsTodayObject {
// Creates sort.
Sort mySort = new Sort("date");
// Creates columns to retrieve.
- String[] targetColumns = new String[]{"id", "qcstate/label", "projectStatus", "BloodRemaining/AvailBlood", "billedby/title", "Id/curLocation/room", "Id/curLocation/area"};
+ String[] targetColumns = new String[]{"id", "qcstate/label", "projectStatus", "BloodRemaining/allowableBlood", "billedby/title", "Id/curLocation/room", "Id/curLocation/area"};
//Runs query.
ArrayList> returnArray = notificationToolkit.getTableMultiRowMultiColumnWithFieldKeys(c, u, "study", "BloodSchedule", myFilter, mySort, targetColumns);
@@ -146,7 +146,7 @@ public static class BloodDrawsTodayObject {
// Updates id.
myCurrentRow[0] = result.get("id");
// Updates blood remaining.
- myCurrentRow[1] = result.get("BloodRemaining/AvailBlood");
+ myCurrentRow[1] = result.get("BloodRemaining/allowableBlood");
// Updates project status (this checks if animal is assigned to a project).
if (!result.get("qcstate/label").equals("Request: Denied") && !result.get("projectStatus").isEmpty()) {
myCurrentRow[2] = "UNASSIGNED";
@@ -180,25 +180,25 @@ public static class BloodDrawsTodayObject {
//Updates row colors.
myCurrentRow[8] = "white";
- if (!result.get("BloodRemaining/AvailBlood").isEmpty()) {
- Float availBlood = Float.parseFloat(result.get("BloodRemaining/AvailBlood"));
- if (availBlood <= 0) {
+ if (!result.get("BloodRemaining/allowableBlood").isEmpty()) {
+ Float allowableBlood = Float.parseFloat(result.get("BloodRemaining/allowableBlood"));
+ if (allowableBlood <= 0) {
// If blood draw is over limit, color it red.
myCurrentRow[8] = "red";
}
- else if (availBlood <= bloodThreshold) {
+ else if (allowableBlood <= bloodThreshold) {
// If blood draw is over threshold limit, color it orange.
myCurrentRow[8] = "orange";
}
}
// String currentRowColor = "white";
-// if (!result.get("BloodRemaining/AvailBlood").isEmpty()) {
-// Float availBlood = Float.parseFloat(result.get("BloodRemaining/AvailBlood"));
-// if (availBlood <= 0) {
+// if (!result.get("BloodRemaining/allowableBlood").isEmpty()) {
+// Float allowableBlood = Float.parseFloat(result.get("BloodRemaining/allowableBlood"));
+// if (allowableBlood <= 0) {
// // If blood draw is over limit, color it red.
// currentRowColor = "red";
// }
-// else if (availBlood <= bloodThreshold) {
+// else if (allowableBlood <= bloodThreshold) {
// // If blood draw is over threshold limit, color it orange.
// currentRowColor = "orange";
// }
diff --git a/WNPRC_EHR/src/org/labkey/wnprc_ehr/notification/NotificationToolkit.java b/WNPRC_EHR/src/org/labkey/wnprc_ehr/notification/NotificationToolkit.java
index 34912b9f8..66d1f1d4b 100644
--- a/WNPRC_EHR/src/org/labkey/wnprc_ehr/notification/NotificationToolkit.java
+++ b/WNPRC_EHR/src/org/labkey/wnprc_ehr/notification/NotificationToolkit.java
@@ -1035,14 +1035,14 @@ public Double checkIfBloodDrawIsOverdraw(Container c, User u, String idToCheck,
SimpleFilter myFilter = new SimpleFilter("Id", idToCheck, CompareType.EQUAL);
myFilter.addCondition("date", dateToCheck, CompareType.DATE_EQUAL);
// Runs query.
- String[] targetColumns = new String[]{"BloodRemaining/AvailBlood"};
+ String[] targetColumns = new String[]{"BloodRemaining/allowableBlood"};
ArrayList> returnArray = getTableMultiRowMultiColumnWithFieldKeys(c, u, "study", "blood", myFilter, null, targetColumns);
// Checks results.
if (!returnArray.isEmpty()) {
for (HashMap result : returnArray) {
- if (!result.get("BloodRemaining/AvailBlood").isEmpty()) {
- Double availableBlood = Double.valueOf(result.get("BloodRemaining/AvailBlood"));
+ if (!result.get("BloodRemaining/allowableBlood").isEmpty()) {
+ Double availableBlood = Double.valueOf(result.get("BloodRemaining/allowableBlood"));
if (availableBlood <=0) {
return availableBlood;
}
diff --git a/WNPRC_EHR/src/org/labkey/wnprc_ehr/table/WNPRC_EHRCustomizer.java b/WNPRC_EHR/src/org/labkey/wnprc_ehr/table/WNPRC_EHRCustomizer.java
index 606830674..d9bd8c220 100644
--- a/WNPRC_EHR/src/org/labkey/wnprc_ehr/table/WNPRC_EHRCustomizer.java
+++ b/WNPRC_EHR/src/org/labkey/wnprc_ehr/table/WNPRC_EHRCustomizer.java
@@ -364,7 +364,7 @@ private void customizeAnimalTable(AbstractTableInfo ds)
col10.setDescription("Calculates the total number of days each animal has been single housed, if applicable.");
ds.addColumn(col10);
- BaseColumnInfo bloodCol = getWrappedIdCol(us, ds, "AvailBlood", "demographicsBloodSummary");
+ BaseColumnInfo bloodCol = getWrappedIdCol(us, ds, "allowableBlood", "currentBloodDraws");
bloodCol.setLabel("Blood Remaining");
bloodCol.setDescription("Calculates the total blood draw and remaining, which is determine by weight and blood drawn in the past 30 days.");
ds.addColumn(bloodCol);
diff --git a/WNPRC_EHR/test/src/org/labkey/test/tests/wnprc_ehr/WNPRC_EHRTest.java b/WNPRC_EHR/test/src/org/labkey/test/tests/wnprc_ehr/WNPRC_EHRTest.java
index f1711acd2..a29b64ce1 100644
--- a/WNPRC_EHR/test/src/org/labkey/test/tests/wnprc_ehr/WNPRC_EHRTest.java
+++ b/WNPRC_EHR/test/src/org/labkey/test/tests/wnprc_ehr/WNPRC_EHRTest.java
@@ -4181,7 +4181,7 @@ public void insertValueIntoBloodBilledByDataset(String billingGroupRealName, Str
/**
* This function inserts data into the 'study/BloodSchedule' dataset.
- * This function creates the following fields in 'study/BloodSchedule': id, date, projectStatus, BloodRemaining/AvailBlood, billedby/title, and Id/DataSet/Demographics/calculated_status.
+ * This function creates the following fields in 'study/BloodSchedule': id, date, projectStatus, BloodRemaining/allowableBlood, billedby/title, and Id/DataSet/Demographics/calculated_status.
* This function updates the following tables: study/demographics, study/weight, study/blood.
* @param billingGroupRealName
* @param animalID
@@ -4211,7 +4211,7 @@ public void insertValueIntoBloodScheduleDataset(String billingGroupRealName, Str
HashMap demographicInfoTestData1 = new HashMap<>();
demographicInfoTestData1.put("id", animalID);
demographicInfoTestData1.put("calculated_status", livingStatus);
- // Creates weight info (this updates the bloodSchedule field: 'BloodRemaining/AvailBlood').
+ // Creates weight info (this updates the bloodSchedule field: 'BloodRemaining/allowableBlood').
HashMap weightTestData1 = new HashMap<>();
weightTestData1.put("id", animalID);
weightTestData1.put("date", new Date());
From da350df09436a137d4c2d586c2e64f7bc1711ae2 Mon Sep 17 00:00:00 2001
From: Chad Sebranek
Date: Fri, 4 Oct 2024 11:31:16 -0500
Subject: [PATCH 07/13] ignore project type
---
WNPRC_EHR/resources/queries/study/bloodDrawChanges.sql | 4 ++--
WNPRC_EHR/resources/queries/study/currentBloodDraws.sql | 6 +++---
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/WNPRC_EHR/resources/queries/study/bloodDrawChanges.sql b/WNPRC_EHR/resources/queries/study/bloodDrawChanges.sql
index d58fd6410..efb9c28f4 100644
--- a/WNPRC_EHR/resources/queries/study/bloodDrawChanges.sql
+++ b/WNPRC_EHR/resources/queries/study/bloodDrawChanges.sql
@@ -41,7 +41,7 @@ FROM (
b.dateOnly,
b.quantity,
FROM study.blood b
- WHERE b.dateOnly > timestampadd('SQL_TSI_DAY', -1 * DATE_INTERVAL, curdate()) AND b.project.research = TRUE
+ WHERE b.dateOnly > timestampadd('SQL_TSI_DAY', -1 * DATE_INTERVAL, curdate())
UNION ALL
@@ -63,7 +63,7 @@ FROM (
timestampadd('SQL_TSI_DAY', DATE_INTERVAL, b.dateOnly),
0 as quantity,
FROM study.blood b
- WHERE timestampadd('SQL_TSI_DAY', DATE_INTERVAL, b.dateOnly) >= timestampadd('SQL_TSI_DAY', -1 * DATE_INTERVAL, curdate()) AND b.project.research = TRUE
+ WHERE timestampadd('SQL_TSI_DAY', DATE_INTERVAL, b.dateOnly) >= timestampadd('SQL_TSI_DAY', -1 * DATE_INTERVAL, curdate())
) b
diff --git a/WNPRC_EHR/resources/queries/study/currentBloodDraws.sql b/WNPRC_EHR/resources/queries/study/currentBloodDraws.sql
index cacb6129e..76fcad98a 100644
--- a/WNPRC_EHR/resources/queries/study/currentBloodDraws.sql
+++ b/WNPRC_EHR/resources/queries/study/currentBloodDraws.sql
@@ -96,7 +96,7 @@ SELECT
COALESCE(
(SELECT SUM(coalesce(draws.quantity, 0)) AS _expr
FROM study."Blood Draws" draws
- WHERE draws.id = bd.id AND draws.project.research = true
+ WHERE draws.id = bd.id
AND draws.dateOnly > bd.minDate
AND draws.dateOnly <= bd.dateOnly
--NOTE: this has been changed to include pending/non-approved draws
@@ -106,7 +106,7 @@ SELECT
COALESCE(
(SELECT SUM(coalesce(draws.quantity, 0)) AS _expr
FROM study."Blood Draws" draws
- WHERE draws.id = bd.id AND draws.project.research = true
+ WHERE draws.id = bd.id
AND draws.dateOnly < bd.maxDate
AND draws.dateOnly >= bd.dateOnly
--NOTE: this has been changed to include pending/non-approved draws
@@ -116,7 +116,7 @@ SELECT
COALESCE(
(SELECT SUM(coalesce(draws.quantity, 0)) AS _expr
FROM study."Blood Draws" draws
- WHERE draws.id = bd.id AND draws.project.research = true
+ WHERE draws.id = bd.id
AND draws.dateOnly = curdate()
--NOTE: this has been changed to include pending/non-approved draws
AND draws.countsAgainstVolume = true
From cb610f31e162f8196238d7dd4ca8a9479f6638e8 Mon Sep 17 00:00:00 2001
From: Chad Sebranek
Date: Tue, 12 Nov 2024 14:40:32 -0600
Subject: [PATCH 08/13] group up the blood draws if they are done at the same
time
---
.../wnprc_billing/bloodDrawsAllTubesSPI.sql | 16 +++++++++-------
1 file changed, 9 insertions(+), 7 deletions(-)
diff --git a/wnprc_billing/resources/queries/wnprc_billing/bloodDrawsAllTubesSPI.sql b/wnprc_billing/resources/queries/wnprc_billing/bloodDrawsAllTubesSPI.sql
index fb5d7bec8..ea4fed321 100644
--- a/wnprc_billing/resources/queries/wnprc_billing/bloodDrawsAllTubesSPI.sql
+++ b/wnprc_billing/resources/queries/wnprc_billing/bloodDrawsAllTubesSPI.sql
@@ -2,15 +2,17 @@ SELECT
Id,
date,
project,
- coalesce(account, project.account.alias) AS debitedAccount,
+ coalesce(account, project.account.alias) as debitedAccount,
coalesce(a.tier_rate.tierRate, project.account.tier_rate.tierRate) as otherRate,
- objectid AS sourceRecord,
- ('Blood Draws ' || Id) AS comment,
- CAST(1 as DOUBLE) AS quantity,
- taskId,
- performedby
+ group_concat(objectid,';') as objectids,
+ ('Blood Draws ' || Id || ' x' || COUNT(*)) as comment,
+ CAST(1 AS DOUBLE) AS quantity,
+ group_concat(taskid, ';') as taskids,
+ group_concat(performedby, ';') as performedby
FROM studyLinked.BloodSchedule bloodSch
LEFT JOIN ehr_billing.aliases a ON bloodSch.account = a.alias
WHERE
billedBy.value = 'c' AND
- qcstate.publicdata = true
\ No newline at end of file
+ qcstate.publicdata = true
+
+GROUP BY id, date, project, coalesce(account, project.account.alias), coalesce(a.tier_rate.tierRate, project.account.tier_rate.tierRate);
From 4aa99c6bf1f942842a83763ebbd19e0f6ca20533 Mon Sep 17 00:00:00 2001
From: Chad Sebranek
Date: Tue, 19 Nov 2024 15:55:43 -0600
Subject: [PATCH 09/13] Revert back to original AvailBlood calculation, add new
calc for future draws in the new current blood report, fix ehr blood store so
all records in transaction are used
---
.../BloodSchedule/Blood Schedule.qview.xml | 5 --
.../study/DailyOverDrawsWithThreshold.sql | 4 +-
.../resources/queries/study/blood.query.xml | 2 +-
.../study/blood/Blood Summary.qview.xml | 2 +-
.../queries/study/bloodDrawChanges.sql | 4 +-
.../queries/study/bloodSummary.query.xml | 36 ++++++++
.../resources/queries/study/bloodSummary.sql | 76 ++++++++++++++++
.../queries/study/currentBloodDraws.query.xml | 16 ++--
.../queries/study/currentBloodDraws.sql | 86 +++++++------------
.../study/currentBloodDraws/.qview.xml | 3 +-
.../demographics/Blood Draw Info.qview.xml | 12 +--
.../study/demographicsBloodSummary.sql | 72 ++++++++++++++++
WNPRC_EHR/resources/web/ehr/ext3/ehrStore.js | 2 +-
.../BloodDrawReviewDailyNotification.java | 8 +-
.../notification/BloodDrawsTodayAll.java | 20 ++---
.../wnprc_ehr/table/WNPRC_EHRCustomizer.java | 2 +-
16 files changed, 255 insertions(+), 95 deletions(-)
create mode 100644 WNPRC_EHR/resources/queries/study/bloodSummary.query.xml
create mode 100644 WNPRC_EHR/resources/queries/study/bloodSummary.sql
create mode 100644 WNPRC_EHR/resources/queries/study/demographicsBloodSummary.sql
diff --git a/WNPRC_EHR/resources/queries/study/BloodSchedule/Blood Schedule.qview.xml b/WNPRC_EHR/resources/queries/study/BloodSchedule/Blood Schedule.qview.xml
index 3e8dccc9f..a889616dc 100644
--- a/WNPRC_EHR/resources/queries/study/BloodSchedule/Blood Schedule.qview.xml
+++ b/WNPRC_EHR/resources/queries/study/BloodSchedule/Blood Schedule.qview.xml
@@ -56,11 +56,6 @@
-
-
-
-
-
diff --git a/WNPRC_EHR/resources/queries/study/DailyOverDrawsWithThreshold.sql b/WNPRC_EHR/resources/queries/study/DailyOverDrawsWithThreshold.sql
index e87e21f4b..9e0ef9abd 100644
--- a/WNPRC_EHR/resources/queries/study/DailyOverDrawsWithThreshold.sql
+++ b/WNPRC_EHR/resources/queries/study/DailyOverDrawsWithThreshold.sql
@@ -17,9 +17,9 @@ SELECT b.Id,
b.restraintTime,
b.instructions,
b.restraintDuration,
- b.BloodRemaining.allowableBlood,
+ b.BloodRemaining.AvailBlood,
b.QCState,
b.QCState.label
FROM "Blood Draws" b
LEFT JOIN ehr_lookups.species e ON e.common = b.Id.Demographics.species
-WHERE b.BloodRemaining.allowableBlood < e.blood_threshold_warning AND b.date > curdate() AND b.date < cast(TIMESTAMPADD('SQL_TSI_DAY', 1, curdate()) as date) AND b.QCState.label <> 'Request: Denied'
\ No newline at end of file
+WHERE b.BloodRemaining.AvailBlood < e.blood_threshold_warning AND b.date > curdate() AND b.date < cast(TIMESTAMPADD('SQL_TSI_DAY', 1, curdate()) as date) AND b.QCState.label <> 'Request: Denied'
\ No newline at end of file
diff --git a/WNPRC_EHR/resources/queries/study/blood.query.xml b/WNPRC_EHR/resources/queries/study/blood.query.xml
index ebb431ad8..0d4c76bd8 100644
--- a/WNPRC_EHR/resources/queries/study/blood.query.xml
+++ b/WNPRC_EHR/resources/queries/study/blood.query.xml
@@ -106,7 +106,7 @@
true
study
- currentBloodDraws
+ bloodSummary
lsid
diff --git a/WNPRC_EHR/resources/queries/study/blood/Blood Summary.qview.xml b/WNPRC_EHR/resources/queries/study/blood/Blood Summary.qview.xml
index 2e70880c8..04a6f204a 100644
--- a/WNPRC_EHR/resources/queries/study/blood/Blood Summary.qview.xml
+++ b/WNPRC_EHR/resources/queries/study/blood/Blood Summary.qview.xml
@@ -38,7 +38,7 @@
-
+
diff --git a/WNPRC_EHR/resources/queries/study/bloodDrawChanges.sql b/WNPRC_EHR/resources/queries/study/bloodDrawChanges.sql
index efb9c28f4..f91415d21 100644
--- a/WNPRC_EHR/resources/queries/study/bloodDrawChanges.sql
+++ b/WNPRC_EHR/resources/queries/study/bloodDrawChanges.sql
@@ -30,7 +30,7 @@ FROM (
SELECT
b.id,
b.dateOnly,
- GROUP_CONCAT(b.status,'') as status,
+ b.status,
sum(b.quantity) as quantity
FROM (
@@ -67,5 +67,5 @@ FROM (
) b
- GROUP BY b.id, b.dateOnly
+ GROUP BY b.id, b.dateOnly, b.status
) b2
\ No newline at end of file
diff --git a/WNPRC_EHR/resources/queries/study/bloodSummary.query.xml b/WNPRC_EHR/resources/queries/study/bloodSummary.query.xml
new file mode 100644
index 000000000..2149003c5
--- /dev/null
+++ b/WNPRC_EHR/resources/queries/study/bloodSummary.query.xml
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+ true
+
+
+
+ Drawn in Previous 30 Days (inclusive)
+ /query/executeQuery.view?schemaName=study&
+ query.queryName=Blood Draws&
+ query.viewName=Blood Summary&
+ query.Id~eq=${Id}&
+ query.Date~lte=${Date}&
+ query.Date~gte=${minDate}&
+ query.sort=-Date&
+
+
+
+ Scheduled in Next 30 Days (inclusive)
+ /query/executeQuery.view?schemaName=study&
+ query.queryName=Blood Draws&
+ query.viewName=Blood Summary&
+ query.Id~eq=${Id}&
+ query.Date~gt=${Date}&
+ query.sort=-Date&
+
+
+
+ BloodLast30
+
+
+
+
diff --git a/WNPRC_EHR/resources/queries/study/bloodSummary.sql b/WNPRC_EHR/resources/queries/study/bloodSummary.sql
new file mode 100644
index 000000000..8661b0e72
--- /dev/null
+++ b/WNPRC_EHR/resources/queries/study/bloodSummary.sql
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2010-2013 LabKey Corporation
+ *
+ * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0
+ */
+SELECT
+ bq.lsid,
+ bq.id,
+ bq.date,
+ bq.minDate,
+-- bq.maxDate,
+ bq.weight,
+ bq.lastWeighDate,
+ cast(bq.BloodLast30 as numeric) as BloodLast30,
+ bq.BloodNext30,
+-- round(bq.weight*0.2*60, 1) AS MaxBlood,
+-- round((bq.weight*0.2*60) - bq.BloodLast30, 1) AS AvailBlood
+ cast(CASE
+ WHEN bq.species = 'Marmoset'
+ THEN round(bq.weight*0.15*60, 1)
+ ELSE
+ round(bq.weight*0.2*60, 1)
+ END as numeric) AS MaxBlood,
+ cast(CASE
+ WHEN bq.species = 'Marmoset'
+ THEN round((bq.weight*0.15*60) - bq.BloodLast30, 1)
+ ELSE
+ round((bq.weight*0.2*60) - bq.BloodLast30, 1)
+ END AS numeric) AS AvailBlood
+FROM
+(
+ SELECT
+ b.*,
+ (select species from study.demographics d where d.id = b.id) as species,
+ (
+ CONVERT (
+ (SELECT AVG(w.weight) AS _expr
+ FROM study.weight w
+ WHERE w.id=b.id AND w.date=b.lastWeighDate
+ ), double )
+ ) AS weight
+ FROM
+ (
+ SELECT bi.*
+ ,timestampadd('SQL_TSI_DAY', -30, bi.date) as minDate
+-- ,timestampadd('SQL_TSI_DAY', 29, bi.date) as maxDate
+ , ( CONVERT(
+ (SELECT MAX(w.date) as _expr
+ FROM study.weight w
+ WHERE w.id = bi.id
+ --NOTE: we are doing this comparison such that it considers date only, not datetime
+ --AND w.date <= bi.date
+ AND CAST(CAST(w.date AS DATE) AS TIMESTAMP) <= bi.date
+ ), timestamp )
+ ) AS lastWeighDate
+ , ( COALESCE (
+ (SELECT SUM(draws.quantity) AS _expr
+ FROM study."Blood Draws" draws
+ WHERE draws.id=bi.id
+ AND (cast(draws.date as date) >= cast(TIMESTAMPADD('SQL_TSI_DAY', -30, bi.date) as date) AND cast(draws.date as date) <= cast(bi.date as date))
+ --AND draws.qcstate.publicdata = true
+ ), 0 )
+ ) AS BloodLast30,
+ COALESCE ((
+ SELECT
+ SUM(draws.quantity) AS _expr
+ FROM study."Blood Draws" draws
+ WHERE draws.id=bi.id AND
+ (cast(draws.date as date) <= cast(TIMESTAMPADD('SQL_TSI_DAY', 30, bi.date) as date) AND cast(draws.date as date) > cast(bi.date as date) )
+
+ ), 0) AS BloodNext30
+ FROM study.blood bi
+ --WHERE (bi.qcstate.metadata.DraftData = true OR bi.qcstate.publicdata = true)
+ ) b
+ ) bq
+
diff --git a/WNPRC_EHR/resources/queries/study/currentBloodDraws.query.xml b/WNPRC_EHR/resources/queries/study/currentBloodDraws.query.xml
index ec7039ef0..cf0b8081c 100644
--- a/WNPRC_EHR/resources/queries/study/currentBloodDraws.query.xml
+++ b/WNPRC_EHR/resources/queries/study/currentBloodDraws.query.xml
@@ -23,7 +23,7 @@
- Previous 30 Days (inclusive)
+ Previous 30 Days (including today)
/query/executeQuery.view?schemaName=study&
query.queryName=Blood Draws&
query.viewName=Blood Summary&
@@ -32,9 +32,10 @@
query.Date~dategte=${minDate}&
query.sort=-Date&
+ This shows the amount of blood draws taken in the past, including today.
- Next 30 Days (inclusive)
+ Next 30 Days (excluding today)
/query/executeQuery.view?schemaName=study&
query.queryName=Blood Draws&
query.viewName=Blood Summary&
@@ -42,6 +43,7 @@
query.Date~dategte=${Date}&
query.sort=-Date&
+ This shows the amount of blood draws scheduled in the next 30 days after the given date.
Latest Weight (kg)
@@ -63,14 +65,16 @@
20% Volume By Weight
+ This shows the maximum blood an animal can get drawn based on their weight.
- Volume Remaining After Draw (mL)
- /WNPRC/EHR/ehr-animalHistory.view#subjects:${Id}&inputType:singleSubject&showReport:1&activeReport:BloodSummary
+ Volume Available Today (mL)
+ This shows the amount of blood remaining today. It includes blood draws that happened 30 days in the past up to today.
-
- Volume Remaining Over Next 30 Days
+
+ Volume Remaining After All Draws (mL)
/WNPRC/EHR/ehr-animalHistory.view#subjects:${Id}&inputType:singleSubject&showReport:1&activeReport:BloodSummary
+ This column shows the amount of blood remaining for the animal while considering future draws. It includes approved blood draws 30 days into the future and past blood draws 30 days in the past.
diff --git a/WNPRC_EHR/resources/queries/study/currentBloodDraws.sql b/WNPRC_EHR/resources/queries/study/currentBloodDraws.sql
index 76fcad98a..f90605794 100644
--- a/WNPRC_EHR/resources/queries/study/currentBloodDraws.sql
+++ b/WNPRC_EHR/resources/queries/study/currentBloodDraws.sql
@@ -15,41 +15,35 @@
*/
SELECT
- t.id,
- t.date,
- t.status,
- cast(t.quantity as double) as quantity,
- t.species,
- t.max_draw_pct,
- t.blood_draw_interval,
- t.blood_per_kg,
- t.mostRecentWeight,
- t.mostRecentWeightDate,
- t.death,
- cast(round(t.allowableBlood,1) as numeric) as maxAllowableBlood,
- cast(t.bloodPrevious as double) as bloodPrevious,
- cast((t.allowableBlood - t.bloodPrevious) as double) as allowablePrevious,
+ t.id,
+ t.date,
+ t.status,
+ cast(t.quantity as double) as quantity,
+ t.species,
+ t.max_draw_pct,
+ t.blood_draw_interval,
+ t.blood_per_kg,
+ t.mostRecentWeight,
+ t.mostRecentWeightDate,
+ t.death,
+ cast(round(t.allowableBlood,1) as numeric) as maxAllowableBlood,
+ cast(t.bloodPrevious as double) as bloodPrevious,
+ cast((t.allowableBlood - t.bloodPrevious) as double) as allowablePrevious,
- cast(t.bloodFuture as double) as bloodFuture,
- cast((t.allowableBlood - t.bloodFuture) as double) as allowableFuture,
+ cast(t.bloodFuture as double) as bloodFuture,
+ cast((t.allowableBlood - t.bloodFuture) as double) as allowableFuture,
- --if the draw is historic, always consider previous draws only.
- --otherwise, look both forward and backwards, then take the interval with the highest volume
- cast(round(case
- WHEN t.date < curdate() THEN (t.allowableBlood - t.bloodPrevious)
- WHEN t.bloodPrevious < t.bloodFuture THEN (t.allowableBlood - t.bloodFuture)
- ELSE (t.allowableBlood - t.bloodPrevious)
- end , 1) as numeric) as allowableBlood,
- cast( round(t.allowableBlood - ((t.bloodPrevious + t.bloodFuture) - t.bloodToday), 1) as numeric) as BloodAvailPlusThirty,
- t.minDate,
- t.maxDate
+ ROUND(CAST((t.allowableBlood - t.bloodPrevious) AS double),1) as allowableBlood,
+ ROUND(CAST((t.allowableBlood - t.bloodPrevious - t.bloodFuture) AS double),1) as allowableBloodIncludingFutureDraws,
+ t.minDate,
+ t.maxDate
FROM (
-SELECT
- bd.id,
- bd.status,
- bd.dateOnly as date,
+ SELECT
+ bd.id,
+ bd.status,
+ bd.dateOnly as date,
bd.quantity,
d.species,
d.death,
@@ -57,16 +51,7 @@ SELECT
CONVERT (
(SELECT AVG(w.weight) AS _expr
FROM study.weight w
- WHERE w.id=bd.id AND w.date=
- ( CONVERT(
- (SELECT MAX(w.date) as _expr
- FROM study.weight w
- WHERE w.id = bd.id
- --AND w.date <= bi.date
- AND CAST(CAST(w.date AS DATE) AS TIMESTAMP) <= bd.dateOnly
- AND w.qcstate.publicdata = true
- ), timestamp )
- )
+ WHERE w.id=bd.id AND w.date=d.id.mostRecentWeight.MostRecentWeightDate
AND w.qcstate.publicdata = true
), double )
) * d.species.max_draw_pct * d.species.blood_per_kg AS allowableBlood,
@@ -74,16 +59,7 @@ SELECT
(CONVERT (
(SELECT AVG(w.weight) AS _expr
FROM study.weight w
- WHERE w.id=bd.id AND w.date=
- (CONVERT(
- (SELECT MAX(w.date) as _expr
- FROM study.weight w
- WHERE w.id = bd.id
- --AND w.date <= bi.date
- AND CAST(CAST(w.date AS DATE) AS TIMESTAMP) <= bd.dateOnly
- AND w.qcstate.publicdata = true
- ), timestamp )
- )
+ WHERE w.id=bd.id AND w.date=d.id.mostRecentWeight.MostRecentWeightDate
AND w.qcstate.publicdata = true
), double ) ) as weight,
d.id.mostRecentWeight.MostRecentWeight,
@@ -108,7 +84,7 @@ SELECT
FROM study."Blood Draws" draws
WHERE draws.id = bd.id
AND draws.dateOnly < bd.maxDate
- AND draws.dateOnly >= bd.dateOnly
+ AND draws.dateOnly > bd.dateOnly
--NOTE: this has been changed to include pending/non-approved draws
AND draws.countsAgainstVolume = true
), 0) AS BloodFuture,
@@ -116,13 +92,13 @@ SELECT
COALESCE(
(SELECT SUM(coalesce(draws.quantity, 0)) AS _expr
FROM study."Blood Draws" draws
- WHERE draws.id = bd.id
+ WHERE draws.id = bd.id
AND draws.dateOnly = curdate()
--NOTE: this has been changed to include pending/non-approved draws
AND draws.countsAgainstVolume = true
), 0) AS BloodToday
-FROM study.bloodDrawChanges bd
-JOIN study.demographics d ON (d.id = bd.id)
+ FROM study.bloodDrawChanges bd
+ JOIN study.demographics d ON (d.id = bd.id)
-) t
\ No newline at end of file
+ ) t
\ No newline at end of file
diff --git a/WNPRC_EHR/resources/queries/study/currentBloodDraws/.qview.xml b/WNPRC_EHR/resources/queries/study/currentBloodDraws/.qview.xml
index f72ca56dd..22719345e 100644
--- a/WNPRC_EHR/resources/queries/study/currentBloodDraws/.qview.xml
+++ b/WNPRC_EHR/resources/queries/study/currentBloodDraws/.qview.xml
@@ -17,11 +17,12 @@
+
+
-
diff --git a/WNPRC_EHR/resources/queries/study/demographics/Blood Draw Info.qview.xml b/WNPRC_EHR/resources/queries/study/demographics/Blood Draw Info.qview.xml
index 96fe4b9e5..6b6dd23f8 100644
--- a/WNPRC_EHR/resources/queries/study/demographics/Blood Draw Info.qview.xml
+++ b/WNPRC_EHR/resources/queries/study/demographics/Blood Draw Info.qview.xml
@@ -34,7 +34,7 @@
-
+
@@ -45,24 +45,24 @@
-
+
-
+
-
+
-
+
-
+
diff --git a/WNPRC_EHR/resources/queries/study/demographicsBloodSummary.sql b/WNPRC_EHR/resources/queries/study/demographicsBloodSummary.sql
new file mode 100644
index 000000000..e07e90ead
--- /dev/null
+++ b/WNPRC_EHR/resources/queries/study/demographicsBloodSummary.sql
@@ -0,0 +1,72 @@
+
+
+/*
+ * Copyright (c) 2010-2014 LabKey Corporation
+ *
+ * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0
+ */
+SELECT
+ b.lsid,
+ b.id,
+ --b.date,
+ b.wdate as MostRecentWeightDate,
+ b.weight as MostRecentWeight,
+ convert(BloodLast30, float) as BloodLast30,
+ convert(BloodNext30, float) as BloodNext30,
+ convert(CASE
+ WHEN (b.species = 'Marmoset')
+ THEN (b.weight*0.15*60)
+ ELSE
+ (b.weight*0.2*60)
+ END, float) AS MaxBlood,
+
+ TRUNCATE(ROUND(CAST(case
+ when (b.species = 'Marmoset')
+ THEN ((b.weight*0.15*60) - b.BloodLast30)
+ else
+ ((b.weight*0.2*60) - b.BloodNext30)
+ end AS NUMERIC),2),2) as AvailBlood
+from (
+SELECT
+ d.lsid,
+ d.id,
+ d.species,
+-- d.weight,
+-- d.wdate,
+ lastWeight.date as wdate,
+ (
+ SELECT AVG(w.weight) AS _expr
+ FROM study.weight w
+ WHERE w.id=d.id AND w.date=lastWeight.date
+ ) AS weight,
+ COALESCE ((
+ SELECT
+ SUM(bd.quantity) AS _expr
+ FROM study."Blood Draws" bd
+ WHERE bd.id=d.id AND
+ --bd.date BETWEEN TIMESTAMPADD('SQL_TSI_DAY', -30, now()) AND now()
+ (cast(bd.date as date) >= cast(TIMESTAMPADD('SQL_TSI_DAY', -30, now()) as date) AND cast(bd.date as date) <= cast(curdate() as date))
+
+ ), 0) AS BloodLast30,
+ COALESCE ((
+ SELECT
+ SUM(bd.quantity) AS _expr
+ FROM study."Blood Draws" bd
+ WHERE bd.id=d.id AND
+ --bd.date BETWEEN now() AND TIMESTAMPADD('SQL_TSI_DAY', 30, now())
+ (cast(bd.date as date) >= cast(curdate() as date) AND cast(bd.date as date) <= cast(TIMESTAMPADD('SQL_TSI_DAY', 30, now()) as date))
+
+ ), 0) AS BloodNext30
+
+FROM
+ study.demographics d
+ LEFT OUTER JOIN
+ (SELECT w.id, MAX(date) as date FROM study.weight w
+ GROUP BY w.id) lastWeight ON d.id = lastWeight.id
+
+-- WHERE b.date >= TIMESTAMPADD('SQL_TSI_DAY', -30, now())
+WHERE
+
+d.calculated_status = 'Alive'
+
+) b
\ No newline at end of file
diff --git a/WNPRC_EHR/resources/web/ehr/ext3/ehrStore.js b/WNPRC_EHR/resources/web/ehr/ext3/ehrStore.js
index 4ce13bc69..708226c66 100644
--- a/WNPRC_EHR/resources/web/ehr/ext3/ehrStore.js
+++ b/WNPRC_EHR/resources/web/ehr/ext3/ehrStore.js
@@ -667,7 +667,7 @@ EHR.ext.AdvancedStore = Ext.extend(LABKEY.ext.Store, {
// top-level request, rather than only per-blood. in this instance only Blood Draws.js
// is using the data, but weights are a good example of something that might be
// globally useful.
- if (this.queryName == 'Blood Draws'){
+ if (this.queryName == 'blood'){
var bloodDrawMap = {};
var allRecords = this.getAllRecords();
for (var idx = 0; idx < allRecords.length; ++idx){
diff --git a/WNPRC_EHR/src/org/labkey/wnprc_ehr/notification/BloodDrawReviewDailyNotification.java b/WNPRC_EHR/src/org/labkey/wnprc_ehr/notification/BloodDrawReviewDailyNotification.java
index ce0ca3cce..85e38961b 100644
--- a/WNPRC_EHR/src/org/labkey/wnprc_ehr/notification/BloodDrawReviewDailyNotification.java
+++ b/WNPRC_EHR/src/org/labkey/wnprc_ehr/notification/BloodDrawReviewDailyNotification.java
@@ -229,16 +229,16 @@ void getBloodOverdraws() {
// Creates sort.
Sort mySort = new Sort("date");
// Creates columns to retrieve.
- String[] targetColumns = new String[]{"id", "date", "BloodRemaining/allowableBlood"};
+ String[] targetColumns = new String[]{"id", "date", "BloodRemaining/AvailBlood"};
// Runs query.
ArrayList> unformattedUpcomingBloodDraws = notificationToolkit.getTableMultiRowMultiColumnWithFieldKeys(c, u, "study", "BloodSchedule", myFilter, mySort, targetColumns);
// Converts map to list (for displaying in table).
for (HashMap currentDraw : unformattedUpcomingBloodDraws) {
// Verifies there is data because some older blood draws don't list available blood.
- if (!currentDraw.get("BloodRemaining/allowableBlood").isEmpty()) {
- if (Double.valueOf(currentDraw.get("BloodRemaining/allowableBlood")) <= 0) {
- String[] currentRow = {currentDraw.get("id"), currentDraw.get("date"), currentDraw.get("BloodRemaining/allowableBlood")};
+ if (!currentDraw.get("BloodRemaining/AvailBlood").isEmpty()) {
+ if (Double.valueOf(currentDraw.get("BloodRemaining/AvailBlood")) <= 0) {
+ String[] currentRow = {currentDraw.get("id"), currentDraw.get("date"), currentDraw.get("BloodRemaining/AvailBlood")};
bloodOverdraws.add(currentRow);
}
}
diff --git a/WNPRC_EHR/src/org/labkey/wnprc_ehr/notification/BloodDrawsTodayAll.java b/WNPRC_EHR/src/org/labkey/wnprc_ehr/notification/BloodDrawsTodayAll.java
index b7b7d82fa..8030b9204 100644
--- a/WNPRC_EHR/src/org/labkey/wnprc_ehr/notification/BloodDrawsTodayAll.java
+++ b/WNPRC_EHR/src/org/labkey/wnprc_ehr/notification/BloodDrawsTodayAll.java
@@ -123,7 +123,7 @@ public static class BloodDrawsTodayObject {
// Creates sort.
Sort mySort = new Sort("date");
// Creates columns to retrieve.
- String[] targetColumns = new String[]{"id", "qcstate/label", "projectStatus", "BloodRemaining/allowableBlood", "billedby/title", "Id/curLocation/room", "Id/curLocation/area"};
+ String[] targetColumns = new String[]{"id", "qcstate/label", "projectStatus", "BloodRemaining/AvailBlood", "billedby/title", "Id/curLocation/room", "Id/curLocation/area"};
//Runs query.
ArrayList> returnArray = notificationToolkit.getTableMultiRowMultiColumnWithFieldKeys(c, u, "study", "BloodSchedule", myFilter, mySort, targetColumns);
@@ -146,7 +146,7 @@ public static class BloodDrawsTodayObject {
// Updates id.
myCurrentRow[0] = result.get("id");
// Updates blood remaining.
- myCurrentRow[1] = result.get("BloodRemaining/allowableBlood");
+ myCurrentRow[1] = result.get("BloodRemaining/AvailBlood");
// Updates project status (this checks if animal is assigned to a project).
if (!result.get("qcstate/label").equals("Request: Denied") && !result.get("projectStatus").isEmpty()) {
myCurrentRow[2] = "UNASSIGNED";
@@ -180,25 +180,25 @@ public static class BloodDrawsTodayObject {
//Updates row colors.
myCurrentRow[8] = "white";
- if (!result.get("BloodRemaining/allowableBlood").isEmpty()) {
- Float allowableBlood = Float.parseFloat(result.get("BloodRemaining/allowableBlood"));
- if (allowableBlood <= 0) {
+ if (!result.get("BloodRemaining/AvailBlood").isEmpty()) {
+ Float availBlood = Float.parseFloat(result.get("BloodRemaining/AvailBlood"));
+ if (availBlood <= 0) {
// If blood draw is over limit, color it red.
myCurrentRow[8] = "red";
}
- else if (allowableBlood <= bloodThreshold) {
+ else if (availBlood <= bloodThreshold) {
// If blood draw is over threshold limit, color it orange.
myCurrentRow[8] = "orange";
}
}
// String currentRowColor = "white";
-// if (!result.get("BloodRemaining/allowableBlood").isEmpty()) {
-// Float allowableBlood = Float.parseFloat(result.get("BloodRemaining/allowableBlood"));
-// if (allowableBlood <= 0) {
+// if (!result.get("BloodRemaining/AvailBlood").isEmpty()) {
+// Float availBlood = Float.parseFloat(result.get("BloodRemaining/AvailBlood"));
+// if (availBlood <= 0) {
// // If blood draw is over limit, color it red.
// currentRowColor = "red";
// }
-// else if (allowableBlood <= bloodThreshold) {
+// else if (availBlood <= bloodThreshold) {
// // If blood draw is over threshold limit, color it orange.
// currentRowColor = "orange";
// }
diff --git a/WNPRC_EHR/src/org/labkey/wnprc_ehr/table/WNPRC_EHRCustomizer.java b/WNPRC_EHR/src/org/labkey/wnprc_ehr/table/WNPRC_EHRCustomizer.java
index d9bd8c220..606830674 100644
--- a/WNPRC_EHR/src/org/labkey/wnprc_ehr/table/WNPRC_EHRCustomizer.java
+++ b/WNPRC_EHR/src/org/labkey/wnprc_ehr/table/WNPRC_EHRCustomizer.java
@@ -364,7 +364,7 @@ private void customizeAnimalTable(AbstractTableInfo ds)
col10.setDescription("Calculates the total number of days each animal has been single housed, if applicable.");
ds.addColumn(col10);
- BaseColumnInfo bloodCol = getWrappedIdCol(us, ds, "allowableBlood", "currentBloodDraws");
+ BaseColumnInfo bloodCol = getWrappedIdCol(us, ds, "AvailBlood", "demographicsBloodSummary");
bloodCol.setLabel("Blood Remaining");
bloodCol.setDescription("Calculates the total blood draw and remaining, which is determine by weight and blood drawn in the past 30 days.");
ds.addColumn(bloodCol);
From e977c611d54911b95f736c8d18371dd98d7b299d Mon Sep 17 00:00:00 2001
From: Chad Sebranek
Date: Tue, 3 Dec 2024 10:41:29 -0600
Subject: [PATCH 10/13] update notification to revert to old blood avail name,
use species as lookups for blood queries
---
.../queries/study/bloodSummary.query.xml | 4 ++--
.../resources/queries/study/bloodSummary.sql | 19 ++++++-------------
.../study/demographicsBloodSummary.sql | 17 +++--------------
.../notification/NotificationToolkit.java | 6 +++---
4 files changed, 14 insertions(+), 32 deletions(-)
diff --git a/WNPRC_EHR/resources/queries/study/bloodSummary.query.xml b/WNPRC_EHR/resources/queries/study/bloodSummary.query.xml
index 2149003c5..c5163f487 100644
--- a/WNPRC_EHR/resources/queries/study/bloodSummary.query.xml
+++ b/WNPRC_EHR/resources/queries/study/bloodSummary.query.xml
@@ -8,7 +8,7 @@
- Drawn in Previous 30 Days (inclusive)
+ Drawn in Previous 30 Days (including today)
/query/executeQuery.view?schemaName=study&
query.queryName=Blood Draws&
query.viewName=Blood Summary&
@@ -19,7 +19,7 @@
- Scheduled in Next 30 Days (inclusive)
+ Scheduled in Next 30 Days (excluding today)
/query/executeQuery.view?schemaName=study&
query.queryName=Blood Draws&
query.viewName=Blood Summary&
diff --git a/WNPRC_EHR/resources/queries/study/bloodSummary.sql b/WNPRC_EHR/resources/queries/study/bloodSummary.sql
index 8661b0e72..1e486d444 100644
--- a/WNPRC_EHR/resources/queries/study/bloodSummary.sql
+++ b/WNPRC_EHR/resources/queries/study/bloodSummary.sql
@@ -15,23 +15,13 @@ SELECT
bq.BloodNext30,
-- round(bq.weight*0.2*60, 1) AS MaxBlood,
-- round((bq.weight*0.2*60) - bq.BloodLast30, 1) AS AvailBlood
- cast(CASE
- WHEN bq.species = 'Marmoset'
- THEN round(bq.weight*0.15*60, 1)
- ELSE
- round(bq.weight*0.2*60, 1)
- END as numeric) AS MaxBlood,
- cast(CASE
- WHEN bq.species = 'Marmoset'
- THEN round((bq.weight*0.15*60) - bq.BloodLast30, 1)
- ELSE
- round((bq.weight*0.2*60) - bq.BloodLast30, 1)
- END AS numeric) AS AvailBlood
+ cast(round((bq.weight*(species.max_draw_pct)*(species.blood_per_kg)), 1) as numeric) AS MaxBlood,
+ cast(round((bq.weight*(species.max_draw_pct)*(species.blood_per_kg)) - bq.BloodLast30, 1) AS numeric) AS AvailBlood
FROM
(
SELECT
b.*,
- (select species from study.demographics d where d.id = b.id) as species,
+ d.species as species,
(
CONVERT (
(SELECT AVG(w.weight) AS _expr
@@ -70,7 +60,10 @@ FROM
), 0) AS BloodNext30
FROM study.blood bi
+
--WHERE (bi.qcstate.metadata.DraftData = true OR bi.qcstate.publicdata = true)
) b
+
+ JOIN study.demographics d ON b.id = d.id
) bq
diff --git a/WNPRC_EHR/resources/queries/study/demographicsBloodSummary.sql b/WNPRC_EHR/resources/queries/study/demographicsBloodSummary.sql
index e07e90ead..fad214145 100644
--- a/WNPRC_EHR/resources/queries/study/demographicsBloodSummary.sql
+++ b/WNPRC_EHR/resources/queries/study/demographicsBloodSummary.sql
@@ -13,19 +13,8 @@ SELECT
b.weight as MostRecentWeight,
convert(BloodLast30, float) as BloodLast30,
convert(BloodNext30, float) as BloodNext30,
- convert(CASE
- WHEN (b.species = 'Marmoset')
- THEN (b.weight*0.15*60)
- ELSE
- (b.weight*0.2*60)
- END, float) AS MaxBlood,
-
- TRUNCATE(ROUND(CAST(case
- when (b.species = 'Marmoset')
- THEN ((b.weight*0.15*60) - b.BloodLast30)
- else
- ((b.weight*0.2*60) - b.BloodNext30)
- end AS NUMERIC),2),2) as AvailBlood
+ convert((b.weight*(b.species.max_draw_pct)*(b.species.blood_per_kg)), float) AS MaxBlood,
+ TRUNCATE(ROUND(CAST(((b.weight*(b.species.max_draw_pct)*(b.species.blood_per_kg)) - b.BloodLast30) AS NUMERIC),2),2) as AvailBlood
from (
SELECT
d.lsid,
@@ -54,7 +43,7 @@ SELECT
FROM study."Blood Draws" bd
WHERE bd.id=d.id AND
--bd.date BETWEEN now() AND TIMESTAMPADD('SQL_TSI_DAY', 30, now())
- (cast(bd.date as date) >= cast(curdate() as date) AND cast(bd.date as date) <= cast(TIMESTAMPADD('SQL_TSI_DAY', 30, now()) as date))
+ (cast(bd.date as date) > cast(curdate() as date) AND cast(bd.date as date) <= cast(TIMESTAMPADD('SQL_TSI_DAY', 30, now()) as date))
), 0) AS BloodNext30
diff --git a/WNPRC_EHR/src/org/labkey/wnprc_ehr/notification/NotificationToolkit.java b/WNPRC_EHR/src/org/labkey/wnprc_ehr/notification/NotificationToolkit.java
index 66d1f1d4b..34912b9f8 100644
--- a/WNPRC_EHR/src/org/labkey/wnprc_ehr/notification/NotificationToolkit.java
+++ b/WNPRC_EHR/src/org/labkey/wnprc_ehr/notification/NotificationToolkit.java
@@ -1035,14 +1035,14 @@ public Double checkIfBloodDrawIsOverdraw(Container c, User u, String idToCheck,
SimpleFilter myFilter = new SimpleFilter("Id", idToCheck, CompareType.EQUAL);
myFilter.addCondition("date", dateToCheck, CompareType.DATE_EQUAL);
// Runs query.
- String[] targetColumns = new String[]{"BloodRemaining/allowableBlood"};
+ String[] targetColumns = new String[]{"BloodRemaining/AvailBlood"};
ArrayList> returnArray = getTableMultiRowMultiColumnWithFieldKeys(c, u, "study", "blood", myFilter, null, targetColumns);
// Checks results.
if (!returnArray.isEmpty()) {
for (HashMap result : returnArray) {
- if (!result.get("BloodRemaining/allowableBlood").isEmpty()) {
- Double availableBlood = Double.valueOf(result.get("BloodRemaining/allowableBlood"));
+ if (!result.get("BloodRemaining/AvailBlood").isEmpty()) {
+ Double availableBlood = Double.valueOf(result.get("BloodRemaining/AvailBlood"));
if (availableBlood <=0) {
return availableBlood;
}
From bb19d3449d5ce0480cf26914cfa1f198c54255e5 Mon Sep 17 00:00:00 2001
From: Chad Sebranek
Date: Tue, 3 Dec 2024 10:51:42 -0600
Subject: [PATCH 11/13] restore demographicsBloodSummary query file
---
.../study/demographicsBloodSummary.query.xml | 52 +++++++++++++++++++
1 file changed, 52 insertions(+)
create mode 100644 WNPRC_EHR/resources/queries/study/demographicsBloodSummary.query.xml
diff --git a/WNPRC_EHR/resources/queries/study/demographicsBloodSummary.query.xml b/WNPRC_EHR/resources/queries/study/demographicsBloodSummary.query.xml
new file mode 100644
index 000000000..d90021b23
--- /dev/null
+++ b/WNPRC_EHR/resources/queries/study/demographicsBloodSummary.query.xml
@@ -0,0 +1,52 @@
+
+
+
+
+
+
+ true
+ true
+
+
+ true
+
+
+ /query/executeQuery.view?schemaName=study&
+ query.queryName=Blood Draws&
+ query.viewName=Blood Summary&
+ query.Id~eq=${Id}&
+ query.Date~lte=${Date}&
+ query.sort=-Date&
+
+ Blood Drawn In Previous 30 Days
+
+
+ Scheduled in Next 30 Days
+ /query/executeQuery.view?schemaName=study&
+ query.queryName=Blood Draws&
+ query.viewName=Blood Summary&
+ query.Id~eq=${Id}&
+ query.Date~gt=${Date}&
+ query.sort=-Date&
+
+
+
+ Max Blood Per 30 Days (mL)
+
+
+ Available Blood (mL)
+
+
+
+
+
+ FF0000
+
+
+
+
+ AvailBlood
+
+
+
+
\ No newline at end of file
From e2883c6eb59c55ac3d915ff5b7e73140c1426a8b Mon Sep 17 00:00:00 2001
From: Chad Sebranek
Date: Tue, 3 Dec 2024 10:58:50 -0600
Subject: [PATCH 12/13] update test comments
---
.../src/org/labkey/test/tests/wnprc_ehr/WNPRC_EHRTest.java | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/WNPRC_EHR/test/src/org/labkey/test/tests/wnprc_ehr/WNPRC_EHRTest.java b/WNPRC_EHR/test/src/org/labkey/test/tests/wnprc_ehr/WNPRC_EHRTest.java
index 05346477c..da85269de 100644
--- a/WNPRC_EHR/test/src/org/labkey/test/tests/wnprc_ehr/WNPRC_EHRTest.java
+++ b/WNPRC_EHR/test/src/org/labkey/test/tests/wnprc_ehr/WNPRC_EHRTest.java
@@ -4170,7 +4170,7 @@ public void insertValueIntoBloodBilledByDataset(String billingGroupRealName, Str
/**
* This function inserts data into the 'study/BloodSchedule' dataset.
- * This function creates the following fields in 'study/BloodSchedule': id, date, projectStatus, BloodRemaining/allowableBlood, billedby/title, and Id/DataSet/Demographics/calculated_status.
+ * This function creates the following fields in 'study/BloodSchedule': id, date, projectStatus, BloodRemaining/AvailBlood, billedby/title, and Id/DataSet/Demographics/calculated_status.
* This function updates the following tables: study/demographics, study/weight, study/blood.
* @param billingGroupRealName
* @param animalID
@@ -4200,7 +4200,7 @@ public void insertValueIntoBloodScheduleDataset(String billingGroupRealName, Str
HashMap demographicInfoTestData1 = new HashMap<>();
demographicInfoTestData1.put("id", animalID);
demographicInfoTestData1.put("calculated_status", livingStatus);
- // Creates weight info (this updates the bloodSchedule field: 'BloodRemaining/allowableBlood').
+ // Creates weight info (this updates the bloodSchedule field: 'BloodRemaining/AvailBlood').
HashMap weightTestData1 = new HashMap<>();
weightTestData1.put("id", animalID);
weightTestData1.put("date", new Date());
From 636721ca34af10a2357c6737f3ef1d58376e6d55 Mon Sep 17 00:00:00 2001
From: Chad Sebranek
Date: Wed, 4 Dec 2024 09:57:12 -0600
Subject: [PATCH 13/13] restore old blood draw query
---
.../wnprc_billing/bloodDrawsAllTubesSPI.sql | 16 +++++++---------
1 file changed, 7 insertions(+), 9 deletions(-)
diff --git a/wnprc_billing/resources/queries/wnprc_billing/bloodDrawsAllTubesSPI.sql b/wnprc_billing/resources/queries/wnprc_billing/bloodDrawsAllTubesSPI.sql
index ea4fed321..fb5d7bec8 100644
--- a/wnprc_billing/resources/queries/wnprc_billing/bloodDrawsAllTubesSPI.sql
+++ b/wnprc_billing/resources/queries/wnprc_billing/bloodDrawsAllTubesSPI.sql
@@ -2,17 +2,15 @@ SELECT
Id,
date,
project,
- coalesce(account, project.account.alias) as debitedAccount,
+ coalesce(account, project.account.alias) AS debitedAccount,
coalesce(a.tier_rate.tierRate, project.account.tier_rate.tierRate) as otherRate,
- group_concat(objectid,';') as objectids,
- ('Blood Draws ' || Id || ' x' || COUNT(*)) as comment,
- CAST(1 AS DOUBLE) AS quantity,
- group_concat(taskid, ';') as taskids,
- group_concat(performedby, ';') as performedby
+ objectid AS sourceRecord,
+ ('Blood Draws ' || Id) AS comment,
+ CAST(1 as DOUBLE) AS quantity,
+ taskId,
+ performedby
FROM studyLinked.BloodSchedule bloodSch
LEFT JOIN ehr_billing.aliases a ON bloodSch.account = a.alias
WHERE
billedBy.value = 'c' AND
- qcstate.publicdata = true
-
-GROUP BY id, date, project, coalesce(account, project.account.alias), coalesce(a.tier_rate.tierRate, project.account.tier_rate.tierRate);
+ qcstate.publicdata = true
\ No newline at end of file