Skip to content

Commit ea5e5fb

Browse files
Observation fixes (#674)
* Update obs schedule query used in URL formation * Sort obs in clinical history by category * Add extended timeouts to a few forms that have extra processing * Add housing validation to warn in inserting records out of order
1 parent d0672ac commit ea5e5fb

6 files changed

Lines changed: 154 additions & 15 deletions

File tree

nirc_ehr/resources/queries/study/housing.js

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,89 @@ var prevDate;
55
let triggerHelper = new org.labkey.nirc_ehr.query.NIRC_EHRTriggerHelper(LABKEY.Security.currentUser.id, LABKEY.Security.currentContainer.id);
66
let animalIds = [];
77

8+
function onInit(event, helper){
9+
helper.setScriptOptions({
10+
skipHousingCheck: true
11+
});
12+
13+
helper.decodeExtraContextProperty('housingInTransaction');
14+
15+
helper.registerRowProcessor(function(helper, row){
16+
if (!row)
17+
return;
18+
19+
if (!row.Id || !row.room){
20+
return;
21+
}
22+
23+
var housingInTransaction = helper.getProperty('housingInTransaction');
24+
housingInTransaction = housingInTransaction || {};
25+
housingInTransaction[row.Id] = housingInTransaction[row.Id] || [];
26+
27+
// this is a failsafe in case the client did not provide housing JSON. it ensures
28+
// the current row is part of housingInTransaction
29+
var shouldAdd = true;
30+
if (row.objectid){
31+
LABKEY.ExtAdapter.each(housingInTransaction[row.Id], function(r){
32+
if (r.objectid == row.objectid){
33+
shouldAdd = false;
34+
return false;
35+
}
36+
}, this);
37+
}
38+
39+
if (shouldAdd){
40+
housingInTransaction[row.Id].push({
41+
objectid: row.objectid,
42+
date: row.date,
43+
enddate: row.enddate,
44+
qcstate: row.QCState,
45+
room: row.room,
46+
cage: row.cage,
47+
divider: row.divider
48+
});
49+
}
50+
51+
helper.setProperty('housingInTransaction', housingInTransaction);
52+
});
53+
}
54+
55+
function onUpsert(helper, scriptErrors, row, oldRow){
56+
//verify we dont have 2 opened records for the same ID
57+
if (!helper.isETL() && !row.enddate && row.Id){
58+
var map = helper.getProperty('housingInTransaction');
59+
if (map && map[row.Id]){
60+
var housingRecords = map[row.Id];
61+
for (var i=0;i<housingRecords.length;i++){
62+
if (row.objectid == housingRecords[i].objectid){
63+
console.log ('same housing record');
64+
continue;
65+
}
66+
67+
if (!housingRecords[i].enddate){
68+
EHR.Server.Utils.addError(scriptErrors, 'enddate', 'Cannot enter multiple open-ended housing records for the same animal', 'WARN');
69+
}
70+
}
71+
}
72+
}
73+
74+
if (!helper.isETL() && row && row.Id && row.date && !row.enddate){
75+
var objectid = row.objectid || null;
76+
//if this record is active and public, deactivate any old housing records
77+
var map = helper.getProperty('housingInTransaction');
78+
var housingRecords = [];
79+
if (map && map[row.Id]){
80+
housingRecords = map[row.Id];
81+
}
82+
83+
//NOTE: downstream java code should handle type conversion of housingInTransaction
84+
var msg = helper.getJavaHelper().validateFutureOpenEndedHousing(row.Id, row.date, objectid, housingRecords);
85+
if (msg){
86+
EHR.Server.Utils.addError(scriptErrors, 'Id', msg, 'WARN');
87+
}
88+
}
89+
}
90+
891
EHR.Server.TriggerManager.registerHandlerForQuery(EHR.Server.TriggerManager.Events.BEFORE_INSERT, 'study', 'housing', function (helper, scriptErrors, row, oldRow) {
992

1093
if (helper.isETL()) {

nirc_ehr/resources/queries/study/observationSchedule.sql

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@ SELECT
22
g.id,
33
g.scheduledDate,
44
COUNT(g.caseid) cases,
5-
GROUP_CONCAT(g.observations, ';') AS observations,
6-
SUM(obsCount) AS obsCount,
7-
GROUP_CONCAT(g.obsOrderIds, ';') AS orderIds,
8-
GROUP_CONCAT(g.status, ';') AS status,
9-
GROUP_CONCAT(g.taskids, ';') AS taskids,
5+
o.observations,
6+
SUM(g.obsCount) AS obsCount,
7+
o.orderIds,
8+
o.status,
9+
o.taskids,
1010
MAX(g.type) AS type,
1111
MAX(g.caseid) AS caseid
1212
FROM
@@ -16,21 +16,29 @@ FROM
1616
sch.date AS scheduledDate,
1717
sch.caseid,
1818
sch.type,
19-
GROUP_CONCAT(sch.objectid, ';') AS obsOrderIds,
20-
GROUP_CONCAT(sch.category, ';') AS observations,
21-
GROUP_CONCAT(obsStatus, ';') AS status,
22-
GROUP_CONCAT(DISTINCT(sch.taskid), ';') AS taskids,
23-
COUNT(sch.category) AS obsCount,
24-
COUNT(sch.obsStatus) AS statusCount
25-
FROM (
26-
SELECT * FROM observationOrdersByDate
27-
) sch
19+
COUNT(sch.category) AS obsCount
20+
FROM observationOrdersByDate sch
2821
GROUP BY
2922
sch.animalId,
3023
sch.date,
3124
sch.caseid,
3225
sch.type
3326
) g
27+
LEFT JOIN (
28+
SELECT
29+
obs.animalId AS id,
30+
obs.date AS scheduledDate,
31+
GROUP_CONCAT(DISTINCT obs.category, ';') AS observations,
32+
GROUP_CONCAT(obs.objectid, ';') AS orderIds,
33+
GROUP_CONCAT(obs.obsStatus, ';') AS status,
34+
GROUP_CONCAT(DISTINCT(obs.taskid), ';') AS taskids
35+
FROM observationOrdersByDate obs
36+
GROUP BY obs.animalId, obs.date
37+
) o ON g.id = o.id AND g.scheduledDate = o.scheduledDate
3438
GROUP BY
3539
g.id,
36-
g.scheduledDate
40+
g.scheduledDate,
41+
o.observations,
42+
o.orderIds,
43+
o.status,
44+
o.taskids

nirc_ehr/src/org/labkey/nirc_ehr/dataentry/form/NIRCCasesFormType.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package org.labkey.nirc_ehr.dataentry.form;
22

3+
import org.json.JSONObject;
34
import org.labkey.api.ehr.dataentry.AbstractFormSection;
45
import org.labkey.api.ehr.dataentry.DataEntryFormContext;
56
import org.labkey.api.ehr.dataentry.FormSection;
@@ -117,4 +118,18 @@ protected List<String> getMoreActionButtonConfigs()
117118
configs.remove("DISCARD");
118119
return configs;
119120
}
121+
122+
@Override
123+
public JSONObject toJSON()
124+
{
125+
JSONObject ret = super.toJSON();
126+
127+
//this form involves extra work on save, so relax warning thresholds to reduce error logging
128+
ret.put("perRowWarningThreshold", 0.5);
129+
ret.put("totalTransactionWarningThrehsold", 60);
130+
ret.put("perRowValidationWarningThrehsold", 6);
131+
ret.put("totalValidationTransactionWarningThrehsold", 60);
132+
133+
return ret;
134+
}
120135
}

nirc_ehr/src/org/labkey/nirc_ehr/dataentry/form/NIRCClinicalObservationsFormType.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package org.labkey.nirc_ehr.dataentry.form;
22

3+
import org.json.JSONObject;
34
import org.labkey.api.ehr.dataentry.DataEntryFormContext;
45
import org.labkey.api.ehr.dataentry.FormSection;
56
import org.labkey.api.module.Module;
@@ -48,4 +49,18 @@ protected List<String> getButtonConfigs()
4849

4950
return ret;
5051
}
52+
53+
@Override
54+
public JSONObject toJSON()
55+
{
56+
JSONObject ret = super.toJSON();
57+
58+
//this form involves extra work on save, so relax warning thresholds to reduce error logging
59+
ret.put("perRowWarningThreshold", 0.5);
60+
ret.put("totalTransactionWarningThrehsold", 60);
61+
ret.put("perRowValidationWarningThrehsold", 6);
62+
ret.put("totalValidationTransactionWarningThrehsold", 60);
63+
64+
return ret;
65+
}
5166
}

nirc_ehr/src/org/labkey/nirc_ehr/dataentry/form/NIRCDeathNecropsyFormType.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package org.labkey.nirc_ehr.dataentry.form;
22

3+
import org.json.JSONObject;
34
import org.labkey.api.ehr.dataentry.DataEntryFormContext;
45
import org.labkey.api.ehr.dataentry.FormSection;
56
import org.labkey.api.ehr.security.EHRVeterinarianPermission;
@@ -71,4 +72,18 @@ protected List<String> getMoreActionButtonConfigs()
7172
configs.remove("DISCARD");
7273
return configs;
7374
}
75+
76+
@Override
77+
public JSONObject toJSON()
78+
{
79+
JSONObject ret = super.toJSON();
80+
81+
//this form involves extra work on save, so relax warning thresholds to reduce error logging
82+
ret.put("perRowWarningThreshold", 0.5);
83+
ret.put("totalTransactionWarningThrehsold", 60);
84+
ret.put("perRowValidationWarningThrehsold", 6);
85+
ret.put("totalValidationTransactionWarningThrehsold", 60);
86+
87+
return ret;
88+
}
7489
}

nirc_ehr/src/org/labkey/nirc_ehr/history/NIRCObservationsDataSource.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import java.util.ArrayList;
2020
import java.util.Calendar;
2121
import java.util.Collection;
22+
import java.util.Comparator;
2223
import java.util.Date;
2324
import java.util.HashMap;
2425
import java.util.List;
@@ -56,6 +57,7 @@ protected List<HistoryRow> processRows(Container c, TableSelector ts, final bool
5657
rowMap.put("taskRowId", results.getInt(FieldKey.fromString("taskId/rowid")));
5758
rowMap.put("formType", results.getString(FieldKey.fromString("taskId/formtype")));
5859
rowMap.put("objectId", results.getString(FieldKey.fromString("objectId")));
60+
rowMap.put("category", results.getString(FieldKey.fromString("category")));
5961
rowMap.put("html", html);
6062

6163
Date roundedDate = DateUtils.truncate((Date)rowMap.get("date"), Calendar.MINUTE);
@@ -73,6 +75,7 @@ protected List<HistoryRow> processRows(Container c, TableSelector ts, final bool
7375
for (String key : idMap.keySet())
7476
{
7577
List<Map<String, Object>> toAdd = idMap.get(key);
78+
toAdd.sort(Comparator.comparing(m -> String.valueOf(m.getOrDefault("category", "")), String.CASE_INSENSITIVE_ORDER));
7679

7780
Date date = null;
7881
String subjectId = null;

0 commit comments

Comments
 (0)