From b1a0d61791457c78a72fae2c6c28a2967e5d490c Mon Sep 17 00:00:00 2001 From: Lakshmi Kolli <69940873+kollil@users.noreply.github.com> Date: Mon, 20 Jul 2026 15:16:41 -0700 Subject: [PATCH 1/2] Behavior alert - alopecia email update (#1797) Added email report to alopecia section --- ...lopeciaScoreMissingBehaviorCases.query.xml | 10 ++ .../AlopeciaScoreMissingBehaviorCases.sql | 15 ++- .../notification/BehaviorNotification.java | 100 +++++++++++++----- 3 files changed, 92 insertions(+), 33 deletions(-) create mode 100644 onprc_ehr/resources/queries/study/AlopeciaScoreMissingBehaviorCases.query.xml diff --git a/onprc_ehr/resources/queries/study/AlopeciaScoreMissingBehaviorCases.query.xml b/onprc_ehr/resources/queries/study/AlopeciaScoreMissingBehaviorCases.query.xml new file mode 100644 index 000000000..a7f5d6805 --- /dev/null +++ b/onprc_ehr/resources/queries/study/AlopeciaScoreMissingBehaviorCases.query.xml @@ -0,0 +1,10 @@ + + + + + + Animals with alopecia score 4 or 5 with missing behavior cases +
+
+
+
diff --git a/onprc_ehr/resources/queries/study/AlopeciaScoreMissingBehaviorCases.sql b/onprc_ehr/resources/queries/study/AlopeciaScoreMissingBehaviorCases.sql index 0096f2725..dc670937a 100644 --- a/onprc_ehr/resources/queries/study/AlopeciaScoreMissingBehaviorCases.sql +++ b/onprc_ehr/resources/queries/study/AlopeciaScoreMissingBehaviorCases.sql @@ -5,11 +5,18 @@ Show 1 year data. Modified by Kollil 09/15/2025 Added date comparison to check only dates and ignore time + +Modified by Kollil July 2026 +Showing only 1 month data, Refer to tkt # 14974 */ SELECT mr.Id, d.species, - d.gender, + CASE + WHEN LOWER(d.gender) = 'f' THEN 'Female' + WHEN LOWER(d.gender) = 'm' THEN 'Male' + ELSE d.gender + END AS gender, d.Id.age.ageinYearsRounded, d.Id.curLocation.area, d.Id.curLocation.room, @@ -22,14 +29,14 @@ FROM ( FROM study.clinical_observations AS co WHERE co.category = 'Alopecia Score' - AND co.created >= TIMESTAMPADD(SQL_TSI_YEAR, -1, NOW()) + AND co.created >= TIMESTAMPADD(SQL_TSI_MONTH, -1, NOW()) AND co.created = ( SELECT MAX(co2.created) FROM study.clinical_observations AS co2 WHERE co2.Id = co.Id AND co2.category = 'Alopecia Score' - AND co2.created >= TIMESTAMPADD(SQL_TSI_YEAR, -1, NOW()) + AND co2.created >= TIMESTAMPADD(SQL_TSI_MONTH, -1, NOW()) ) ) AS mr INNER JOIN study.demographics AS d ON mr.Id = d.Id @@ -43,8 +50,6 @@ WHERE c.Id = mr.Id AND c.category = 'Behavior' AND c.allProblemCategories = 'Behavioral: Alopecia' --- AND c.date <= mr.date --- AND (c.enddate IS NULL OR c.enddate > mr.date) AND CAST(c.date AS DATE) <= CAST(mr.date AS DATE) AND (c.enddate IS NULL OR CAST(c.enddate AS DATE) >= CAST(mr.date AS DATE)) ) diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/notification/BehaviorNotification.java b/onprc_ehr/src/org/labkey/onprc_ehr/notification/BehaviorNotification.java index e2829e445..aaed5fe1b 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/notification/BehaviorNotification.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/notification/BehaviorNotification.java @@ -351,8 +351,7 @@ private void assignmentsReleasedInPast1Day(final Container c, User u, final Stri final Map colMap = QueryService.get().getColumns(ti, columns); TableSelector ts2 = new TableSelector(ti, colMap.values(), null, new Sort("Id")); -// msg.append("
Assignments with new \"Release date\" added within the last 24hrs:

\n"); - msg.append(""); + msg.append("
"); msg.append(""); msg.append(""); @@ -360,22 +359,22 @@ private void assignmentsReleasedInPast1Day(final Container c, User u, final Stri Results rs = new ResultsImpl(object, colMap); String url = getParticipantURL(c, rs.getString("Id")); - msg.append(""); - msg.append("\n"); - msg.append(""); - msg.append(""); - msg.append(""); - msg.append(""); - msg.append(""); - msg.append(""); - msg.append(""); - msg.append(""); - msg.append(""); - msg.append(""); - msg.append(""); - msg.append(""); - msg.append(""); - msg.append(""); + msg.append(""); + msg.append("\n"); + msg.append(""); + msg.append(""); + msg.append(""); + msg.append(""); + msg.append(""); + msg.append(""); + msg.append(""); + msg.append(""); + msg.append(""); + msg.append(""); + msg.append(""); + msg.append(""); + msg.append(""); + msg.append(""); msg.append(""); }); msg.append("
Id Sex Room Cage Project Protocol Title Project Investigator Assign Date Release Date Projected Release Date Assignment Type Assign Condition Projected Release Condition Condition At Release
" + PageFlowUtil.filter(rs.getString("Id")) + " " + PageFlowUtil.filter(rs.getString("Sex")) + "" + PageFlowUtil.filter(rs.getString("Room")) + "" + PageFlowUtil.filter(rs.getString("Cage")) + "" + PageFlowUtil.filter(rs.getString("project")) + "" + PageFlowUtil.filter(rs.getString("Protocol")) + "" + PageFlowUtil.filter(rs.getString("Title")) + "" + PageFlowUtil.filter(rs.getString("ProjectInvestigator")) + "" + PageFlowUtil.filter(rs.getString("AssignDate")) + "" + PageFlowUtil.filter(rs.getString("ReleaseDate")) + "" + PageFlowUtil.filter(rs.getString("ProjectedReleaseDate")) + "" + PageFlowUtil.filter(rs.getString("assignmentType")) + "" + PageFlowUtil.filter(rs.getString("assignCondition")) + "" + PageFlowUtil.filter(rs.getString("projectedReleaseCondition")) + "" + PageFlowUtil.filter(rs.getString("ConditionAtRelease")) + "
" + PageFlowUtil.filter(rs.getString("Id")) + " " + PageFlowUtil.filter(rs.getString("Sex")) + "" + PageFlowUtil.filter(rs.getString("Room")) + "" + PageFlowUtil.filter(rs.getString("Cage")) + "" + PageFlowUtil.filter(rs.getString("project")) + "" + PageFlowUtil.filter(rs.getString("Protocol")) + "" + PageFlowUtil.filter(rs.getString("Title")) + "" + PageFlowUtil.filter(rs.getString("ProjectInvestigator")) + "" + PageFlowUtil.filter(rs.getString("AssignDate")) + "" + PageFlowUtil.filter(rs.getString("ReleaseDate")) + "" + PageFlowUtil.filter(rs.getString("ProjectedReleaseDate")) + "" + PageFlowUtil.filter(rs.getString("assignmentType")) + "" + PageFlowUtil.filter(rs.getString("assignCondition")) + "" + PageFlowUtil.filter(rs.getString("projectedReleaseCondition")) + "" + PageFlowUtil.filter(rs.getString("ConditionAtRelease")) + "


"); @@ -394,17 +393,62 @@ private void AlopeciaScoreAlert(final Container c, User u, final StringBuilder m TableInfo ti = getStudySchema(c, u).getTable("AlopeciaScoreMissingBehaviorCases"); TableSelector ts = new TableSelector(ti, null, null); - long total = ts.getRowCount(); - msg.append("Animals with alopecia score of 4 or 5, but does not have an open behavioral case for alopecia:

"); - if (total > 0) - { - msg.append( total + " entries found. "); - msg.append("Click here to view them\n"); - msg.append("


\n\n"); + long count = ts.getRowCount(); + + //Get num of rows + if (count > 0) { + msg.append("Animals with alopecia score of 4 or 5, but does not have an open behavioral case for alopecia:

"); + msg.append( count + " entries found. "); + msg.append("Click here to view them in a separate window\n"); + msg.append("\n\n"); + + //Changes made byKolli, July 2026, Refer to tkt # 14974 + //Display the daily report in the email + Set columns = new HashSet<>(); + columns.add(FieldKey.fromString("Id")); + columns.add(FieldKey.fromString("species")); + columns.add(FieldKey.fromString("gender")); + columns.add(FieldKey.fromString("ageinYearsRounded")); + columns.add(FieldKey.fromString("area")); + columns.add(FieldKey.fromString("room")); + columns.add(FieldKey.fromString("cage")); + columns.add(FieldKey.fromString("MostRecentAlopeciaScore")); + columns.add(FieldKey.fromString("date")); + columns.add(FieldKey.fromString("performedby")); + + final Map colMap = QueryService.get().getColumns(ti, columns); + TableSelector ts2 = new TableSelector(ti, colMap.values(), null, new Sort("Id")); + + msg.append(""); + msg.append(""); + msg.append(""); + + ts2.forEach(object -> { + Results rs = new ResultsImpl(object, colMap); + String url = getParticipantURL(c, rs.getString("Id")); + + msg.append(""); + msg.append("\n"); + msg.append(""); + msg.append(""); + msg.append(""); + msg.append(""); + msg.append(""); + msg.append(""); + msg.append(""); + java.sql.Date date = rs.getDate("date"); + msg.append(""); + msg.append(""); + msg.append(""); + }); + msg.append("
Id Species Sex Age(Years, Rounded) Area Room Cage Most Recent Alopecia Score Date Performed By
" + PageFlowUtil.filter(rs.getString("Id")) + " " + PageFlowUtil.filter(rs.getString("Species")) + "" + PageFlowUtil.filter(rs.getString("gender")) + "" + PageFlowUtil.filter(rs.getString("ageinYearsRounded")) + "" + PageFlowUtil.filter(rs.getString("area")) + "" + PageFlowUtil.filter(rs.getString("room")) + "" + PageFlowUtil.filter(rs.getString("cage")) + "" + PageFlowUtil.filter(rs.getString("MostRecentAlopeciaScore")) + "") + .append(PageFlowUtil.filter( + date == null ? "" : new java.text.SimpleDateFormat("MM/dd/yyyy").format(date) + )) + .append("" + PageFlowUtil.filter(rs.getString("performedby")) + "


"); } - else - { - msg.append("WARNING: No animals found with alopecia score of 4 or 5, but does not have an open behavioral case for alopecia!

\n"); + else { + msg.append("WARNING: No animals found with alopecia score of 4 or 5, there fore no open behavioral case(s) for alopecia!

\n"); } } From 2456f0485e4ad532a127b3f1043b222e9a1586e4 Mon Sep 17 00:00:00 2001 From: Ohsudev <76500320+Ohsudev@users.noreply.github.com> Date: Tue, 21 Jul 2026 13:54:58 -0700 Subject: [PATCH 2/2] 26.3 fb bsu rounds rewrite (#1807) Modified the BSU Rounds template process to prevent auto generating of an "Alopecia Regrowth" when there are existing Alopecia Regrowth defined to the same case id. --- .../window/AddBehaviorCasesWindow.js | 30 ++++++++++++++----- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/onprc_ehr/resources/web/onprc_ehr/window/AddBehaviorCasesWindow.js b/onprc_ehr/resources/web/onprc_ehr/window/AddBehaviorCasesWindow.js index f8082a0ba..c88f57e97 100644 --- a/onprc_ehr/resources/web/onprc_ehr/window/AddBehaviorCasesWindow.js +++ b/onprc_ehr/resources/web/onprc_ehr/window/AddBehaviorCasesWindow.js @@ -50,7 +50,7 @@ Ext4.define('ONPRC_EHR.window.AddBehaviorCasesWindow', { requiredVersion: 9.1, schemaName: 'study', queryName: 'cases', - sort: 'Id/curLocation/room,Id/curLocation/cage,Id,remark,allProblemCategories', + sort: 'Id/curLocation/room,Id/curLocation/cage,Id,category,remark,allProblemCategories', columns: 'Id,objectid,remark,allProblemCategories', filterArray: casesFilterArray, scope: this, @@ -86,17 +86,31 @@ Ext4.define('ONPRC_EHR.window.AddBehaviorCasesWindow', { } var previousObsMap = {}; + var newobservation = ''; + var tempcaseid = ''; + if (this.obsResults && this.obsResults.rows && this.obsResults.rows.length){ Ext4.Array.forEach(this.obsResults.rows, function(sr){ //reset variable - var newobservation = ''; - var newremark = ''; + var row = new LDK.SelectRowsRow(sr); - newobservation = row.getValue('category'); - newremark = row.getValue('remark'); + //note: this has been changed to ensure 1 row per case var key = row.getValue('caseid'); + // if ( row.getValue('category') == 'Alopecia Regrowth' || (tempcaseid != key || tempcaseid == '') ) { + if ( (tempcaseid != key || tempcaseid == '') ) { + if (row.getValue('category') != 'Alopecia Regrowth') { + newobservation = ''; + tempcaseid = ''; + } + else + { + newobservation = row.getValue('category'); //load Alopecia Regrowth + tempcaseid = row.getValue('caseid'); + } + + } if (!previousObsMap[key]) previousObsMap[key] = []; @@ -110,7 +124,8 @@ Ext4.define('ONPRC_EHR.window.AddBehaviorCasesWindow', { allProblemCategories:row.getValue('allProblemCategories'), remark: row.getValue('remark') }); - if (newobservation == 'Alopecia Score' && (newremark == null || newremark == '')) { + + if (row.getValue('category') == 'Alopecia Score' && (newobservation == '') && tempcaseid == '' && (row.getValue('remark') == null || row.getValue('remark') == '')) { previousObsMap[key].push({ Id: row.getValue('Id'), date: this.recordData.date, @@ -121,7 +136,8 @@ Ext4.define('ONPRC_EHR.window.AddBehaviorCasesWindow', { allProblemCategories:row.getValue('allProblemCategories') }); - + newobservation = ''; + tempcaseid = ''; } }, this); }