From 8e1d934aea2812eb9d6ce5d151c0fe99ca425cdf Mon Sep 17 00:00:00 2001 From: Lakshmi Kolli <69940873+kollil@users.noreply.github.com> Date: Mon, 1 Dec 2025 11:29:23 -0800 Subject: [PATCH 01/31] EHR data validation alert update (#1530) * Added a new alert section that displays new birth tasks created in last 7 days. * Fixed the sql error * Fixed a missed quote in the message * Added a comment * Fix duplicate columnTitle in NewBirthTasks query Removed duplicate columnTitle for 'Status'. --------- Co-authored-by: loganb --- .../queries/onprc_ehr/NewBirthTasks.query.xml | 54 +++++++++++++++++++ .../queries/onprc_ehr/NewBirthTasks.sql | 21 ++++++++ .../ColonyAlertsNotification.java | 29 +++++++++- .../DataValidationNotification.java | 3 ++ 4 files changed, 106 insertions(+), 1 deletion(-) create mode 100644 onprc_ehr/resources/queries/onprc_ehr/NewBirthTasks.query.xml create mode 100644 onprc_ehr/resources/queries/onprc_ehr/NewBirthTasks.sql diff --git a/onprc_ehr/resources/queries/onprc_ehr/NewBirthTasks.query.xml b/onprc_ehr/resources/queries/onprc_ehr/NewBirthTasks.query.xml new file mode 100644 index 000000000..d12c41f86 --- /dev/null +++ b/onprc_ehr/resources/queries/onprc_ehr/NewBirthTasks.query.xml @@ -0,0 +1,54 @@ + + + + + New Birth tasks created in last 7 days + + + Task ID + /ehr/dataEntryForm.view?formType=${formtype}&taskid=${taskid} + + + Title + + + Task Type + + + Assigned To + true + + core + PrincipalsWithoutAdmin + UserId + + + + Due Date + true + yyyy-MM-dd HH:mm + + + Created By + + core + users + userid + + + + Created + true + yyyy-MM-dd HH:mm + + + Status + false + true + 50 + + +
+
+
+
diff --git a/onprc_ehr/resources/queries/onprc_ehr/NewBirthTasks.sql b/onprc_ehr/resources/queries/onprc_ehr/NewBirthTasks.sql new file mode 100644 index 000000000..841349e66 --- /dev/null +++ b/onprc_ehr/resources/queries/onprc_ehr/NewBirthTasks.sql @@ -0,0 +1,21 @@ +/** + * Created by Kollil, 10/25 + * Get a list of tasks daily on a rolling 7 day window to review for QC. + * This will allow techs to see what new IDs were created by whom, and review for accuracy, + * housing history, group ids and flags. + * Refer tkt # 13504 + */ +SELECT + t.taskid, + t.title, + t.formType as TaskType, + t.assignedto, + t.duedate, + t.createdby, + t.created, + t.qcstate as Status +FROM ehr.tasks t +WHERE t.created >= TIMESTAMPADD('day', -7, NOW()) +And t.formtype = 'birth' + + diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/notification/ColonyAlertsNotification.java b/onprc_ehr/src/org/labkey/onprc_ehr/notification/ColonyAlertsNotification.java index 0a40e50fa..8a5363df3 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/notification/ColonyAlertsNotification.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/notification/ColonyAlertsNotification.java @@ -1551,7 +1551,7 @@ else if (rs.getString("ActiveClinicalTreatment") != null && rs.getString("Active protected void LongTermMedsAlert(final Container c, User u, final StringBuilder msg) { if (QueryService.get().getUserSchema(u, c, "onprc_ehr") == null) { - msg.append("Warning: The study schema has not been enabled in this folder, so the alert cannot run!


"); + msg.append("Warning: The onprc_ehr schema has not been enabled in this folder, so the alert cannot run!


"); return; } @@ -2333,6 +2333,33 @@ protected void duplicateFlags(Container c, User u, final StringBuilder msg) } } + /** + * Created by Kollil, 10/25 + * Get a list of tasks daily on a rolling 7 day window to review for QC. + * This will allow techs to see what new IDs were created by whom, and review for accuracy, + * housing history, group ids and flags. + * Refer tkt # 13504 + */ + protected void newBirthTasks(final Container c, User u, final StringBuilder msg) + { + if (QueryService.get().getUserSchema(u, c, "onprc_ehr") == null) { + msg.append("Warning: The onprc_ehr schema has not been enabled in this folder, so the alert cannot run!


"); + return; + } + + //Get birth tasks + TableInfo ti = QueryService.get().getUserSchema(u, c, "onprc_ehr").getTable("NewBirthTasks", ContainerFilter.Type.AllFolders.create(c, u)); + TableSelector ts = new TableSelector(ti, null, null); + long count = ts.getRowCount(); + + if (count > 0) { + msg.append("WARNING: There are " + count + " new birth(s) found in last 7 days.
"); + msg.append("

Click here to view them

\n"); + msg.append("
"); + } + + } + /** * Created by Kollil, 9/6/23 * Get the new animals found with the flag, "NHPR NOTE: BCG Vaccinated". diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/notification/DataValidationNotification.java b/onprc_ehr/src/org/labkey/onprc_ehr/notification/DataValidationNotification.java index 79b34ea4c..8268a7fc0 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/notification/DataValidationNotification.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/notification/DataValidationNotification.java @@ -112,6 +112,9 @@ public String getMessageBodyHTML(Container c, User u) birthRecordsNotMatchingHousing(c, u, msg); duplicateGroupMembership(c, u, msg); duplicateFlags(c, u, msg); + //Added by Kolli, Oct 2025 + //Tasks list alert for the new animal births, Refer to # 13504 + newBirthTasks(c, u, msg); //only send if there are alerts if (!msg.isEmpty()) From a9b0fc3afcdb334ef97b4095dbec04a43c35e58e Mon Sep 17 00:00:00 2001 From: Brent Logan Date: Wed, 3 Dec 2025 12:14:44 -0800 Subject: [PATCH 02/31] Add master problems to vet assignment main view (#1557) * Add master problems to open-case assigned vets view * Add master problems to open-case assigned vets view --- .../queries/study/demographicsAssignedVet.sql | 46 ++++++++----------- 1 file changed, 18 insertions(+), 28 deletions(-) diff --git a/onprc_ehr/resources/queries/study/demographicsAssignedVet.sql b/onprc_ehr/resources/queries/study/demographicsAssignedVet.sql index 8d4cc1842..61727ec5c 100644 --- a/onprc_ehr/resources/queries/study/demographicsAssignedVet.sql +++ b/onprc_ehr/resources/queries/study/demographicsAssignedVet.sql @@ -2,34 +2,24 @@ study.demographicsAssignedVet * Returns one or more assigned vets per animal ID -* Note to future self: don't be tempted to add more fields to this view. It will likely - result in additional rows per animal as they won't be distinct. - +* Note to future self: be very careful when adding more fields to this view. It can easily + result in additional rows per animal if they're distinct. */ --- Step 1: Find the minimum matchedRule for each ID -WITH MinMatchedRules AS ( - SELECT - VAF2.Id, - MIN(VAF2.matchedRule) AS MinRule - FROM - vetAssignment_Filter AS VAF2 - GROUP BY - VAF2.Id +SELECT + f.Id, + f.AssignedVet, + f.AssignmentType, + GROUP_CONCAT( + CASE WHEN f.matchedRule = 0 THEN f.ActiveMasterProblems ELSE NULL END, + ', ' + ) AS MasterProblems, + f.Area, + f.Room +FROM vetAssignment_filter f +WHERE f.matchedRule = ( + SELECT min(matchedRule) + FROM vetAssignment_filter sub + WHERE sub.Id = f.Id ) - --- Step 2: Join the original table with the filtered minimum matched rules -SELECT DISTINCT - VAF1.Id, - VAF1.AssignedVet, - VAF1.AssignmentType, - VAF1.Room, - VAF1.Area, - VAF1.Species - -FROM - vetAssignment_Filter AS VAF1 - INNER JOIN - MinMatchedRules AS MMR - ON VAF1.Id = MMR.Id - AND VAF1.matchedRule = MMR.MinRule \ No newline at end of file +GROUP BY f.Id, f.AssignedVet, f.AssignmentType, f.Area, f.Room \ No newline at end of file From 3888df0b4cb4c5a5a282fafe043eaec6c05d93ac Mon Sep 17 00:00:00 2001 From: Brent Logan Date: Wed, 3 Dec 2025 18:41:32 -0800 Subject: [PATCH 03/31] Add Master Problems to defined views (#1565) --- .../queries/study/demographicsAssignedVet/.qview.xml | 8 +++----- .../NHPsWithoutAnAssignedVet.qview.xml | 8 +++----- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/onprc_ehr/resources/queries/study/demographicsAssignedVet/.qview.xml b/onprc_ehr/resources/queries/study/demographicsAssignedVet/.qview.xml index 5a5a03550..9a4beb10c 100644 --- a/onprc_ehr/resources/queries/study/demographicsAssignedVet/.qview.xml +++ b/onprc_ehr/resources/queries/study/demographicsAssignedVet/.qview.xml @@ -4,11 +4,9 @@ - - - - - + + + diff --git a/onprc_ehr/resources/queries/study/demographicsAssignedVet/NHPsWithoutAnAssignedVet.qview.xml b/onprc_ehr/resources/queries/study/demographicsAssignedVet/NHPsWithoutAnAssignedVet.qview.xml index bb6014336..dc34659b9 100644 --- a/onprc_ehr/resources/queries/study/demographicsAssignedVet/NHPsWithoutAnAssignedVet.qview.xml +++ b/onprc_ehr/resources/queries/study/demographicsAssignedVet/NHPsWithoutAnAssignedVet.qview.xml @@ -4,11 +4,9 @@ - - - - - + + + From 9c3024089356408926a2aa6cb25c5929f9ff0dfc Mon Sep 17 00:00:00 2001 From: Lakshmi Kolli <69940873+kollil@users.noreply.github.com> Date: Thu, 4 Dec 2025 10:14:34 -0800 Subject: [PATCH 04/31] 25.7 New med with no end date (#1563) * New diet to bypass the enddate is added to the meds order list * Updated the headers * Changed WARN to ERROR for enddate exception validation. * Added enddate field to the test case. * Update onprc_triggers.js * Update onprc_triggers.js * Update ONPRC_EHRTest.java * Update AdminNotifications.java * Update onprc_triggers.js * Update onprc_triggers.js --------- Co-authored-by: loganb --- .../resources/queries/onprc_ehr/MedsEndDateAlert.sql | 5 ++++- .../resources/scripts/onprc_ehr/onprc_triggers.js | 12 +++++++----- .../onprc_ehr/notification/AdminNotifications.java | 11 +++++------ .../labkey/test/tests/onprc_ehr/ONPRC_EHRTest.java | 1 - 4 files changed, 16 insertions(+), 13 deletions(-) diff --git a/onprc_ehr/resources/queries/onprc_ehr/MedsEndDateAlert.sql b/onprc_ehr/resources/queries/onprc_ehr/MedsEndDateAlert.sql index 196f647b5..a6dc2db26 100644 --- a/onprc_ehr/resources/queries/onprc_ehr/MedsEndDateAlert.sql +++ b/onprc_ehr/resources/queries/onprc_ehr/MedsEndDateAlert.sql @@ -6,6 +6,9 @@ Added these two Diets to the list by Kollil on 4/15/25. Refer to tkt #12363 3. E-X0500 - Diet, L-Phyto (Low-phytoestrogen) 4. E-Y9750 - Diet, 5047 High Protein, Jumbo + + Added Diet to the list by Kollil on 5/14/25. Refer to tkt #12506 +5. E-X1380 - Diet Daily (Non-standard), 5LOP (TAD) */ SELECT Id, @@ -27,5 +30,5 @@ SELECT category, taskid.rowid as TaskId FROM study.treatment_order -WHERE code NOT IN ('E-85760', 'E-Y7735', 'E-X0500', 'E-Y9750') +WHERE code NOT IN ('E-85760', 'E-Y7735', 'E-X0500', 'E-Y9750', 'E-X1380') AND enddate is null \ No newline at end of file diff --git a/onprc_ehr/resources/scripts/onprc_ehr/onprc_triggers.js b/onprc_ehr/resources/scripts/onprc_ehr/onprc_triggers.js index d6f8da6ac..6a96e4701 100644 --- a/onprc_ehr/resources/scripts/onprc_ehr/onprc_triggers.js +++ b/onprc_ehr/resources/scripts/onprc_ehr/onprc_triggers.js @@ -1053,7 +1053,7 @@ exports.init = function(EHR){ } //Added by Kollil, 8/1/24 - /* User can bypass the enddate for these two medications, as per ticket #11016 + /* User can bypass the enddate for the following meddications, as per ticket #11016 Validation code on the Prime side to bypass the following two medications without entering the end dates. 1. E-85760 - Medroxyprogesterone injectable (150mg/ml) 2. E-Y7735 - Diet - Weekly Multivitamin @@ -1061,11 +1061,13 @@ exports.init = function(EHR){ Added these two Diets to the list by Kollil on 4/15/25. Refer to tkt #12363 3. E-X0500 - Diet, L-Phyto (Low-phytoestrogen) 4. E-Y9750 - Diet, 5047 High Protein, Jumbo + + Added Diet to the list by Kollil on 5/14/25. Refer to tkt #12506 + 5. E-X1380 - Diet Daily (Non-standard), 5LOP (TAD) */ - if (row.code != 'E-85760' && row.code != 'E-Y7735' && row.code != 'E-X0500' && row.code != 'E-Y9750'){ - if (!row.enddate) { - EHR.Server.Utils.addError(scriptErrors, 'enddate', 'Must enter enddate', 'WARN'); - } + if (row.code != 'E-85760' && row.code != 'E-Y7735' && row.code != 'E-X0500' && + row.code != 'E-Y9750' && row.code != 'E-X1380' && !row.enddate) { + EHR.Server.Utils.addError(scriptErrors, 'enddate', 'Must enter enddate', 'WARN'); } //Added by Kollil, 9/15/25 diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/notification/AdminNotifications.java b/onprc_ehr/src/org/labkey/onprc_ehr/notification/AdminNotifications.java index 427f50039..d9fc7fd8e 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/notification/AdminNotifications.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/notification/AdminNotifications.java @@ -101,19 +101,18 @@ private void MedsEndDateAlert(Container c, User u, final StringBuilder msg, fina TableSelector ts = new TableSelector(ti, null, new Sort("date")); long count = ts.getRowCount(); if (count == 0) { - //msg.append("There are no meds ordered except E-85760 (Medroxyprogesterone injectable 150mg/ml) and E-Y7735 (Diet - Weekly Multivitamin) with missing end dates!
"); - msg.append("No medication orders found with missing end date except the following approved list:" + + msg.append("No treatment orders found with missing end date except the following approved list:" + "
1. E-85760 (Medroxyprogesterone injectable 150mg/ml) " + "
2. E-Y7735 (Diet - Weekly Multivitamin)" + "
3. E-X0500 (Diet, L-Phyto (Low-phytoestrogen)) " + - "
4. E-Y9750 (Diet, 5047 High Protein, Jumbo)

"); + "
4. E-Y9750 (Diet, 5047 High Protein, Jumbo) " + + "
5. E-X1380 (Diet Daily (Non-standard), 5LOP (TAD))
"); } else if (count > 0) { //Display the report link on the notification page - msg.append("
Meds with missing end date:

"); - msg.append("" + count + " meds found with missing end dates:"); - msg.append("

Click here to view the meds/diets

\n"); + msg.append("
" + count + " treatment order(s) found with missing end dates

"); + msg.append("

Click here to view the treatments

\n"); msg.append("
"); //Display the report in the email diff --git a/onprc_ehr/test/src/org/labkey/test/tests/onprc_ehr/ONPRC_EHRTest.java b/onprc_ehr/test/src/org/labkey/test/tests/onprc_ehr/ONPRC_EHRTest.java index e1313a66f..bdf812dd0 100644 --- a/onprc_ehr/test/src/org/labkey/test/tests/onprc_ehr/ONPRC_EHRTest.java +++ b/onprc_ehr/test/src/org/labkey/test/tests/onprc_ehr/ONPRC_EHRTest.java @@ -1073,7 +1073,6 @@ public void testExamEntry() throws Exception Assert.assertEquals("mg/kg", ordersGrid.getFieldValue(3, "dosage_units")); //note: amount calculation testing handled in surgery test - //blood draws waitAndClick(Ext4Helper.Locators.ext4Tab("Blood Draws")); Ext4GridRef bloodGrid = _helper.getExt4GridForFormSection("Blood Draws"); From e8a9c42bee519726e221ee0c0e0bc0149f99775b Mon Sep 17 00:00:00 2001 From: Ohsudev <76500320+Ohsudev@users.noreply.github.com> Date: Mon, 8 Dec 2025 10:19:33 -0800 Subject: [PATCH 05/31] 25.7 fb compliance requirements view (#1560) * Modified program so that default view appears as the reporting grid instead of "Active".. * Modified Complieance Requirementd default grid reports view to show all requirements listings. * Modified Complieance Requirementd default grid reports view to show all requirements listings. --- .../queries/EHR_ComplianceDB/requirements/.qview.xml | 4 +--- .../EHR_ComplianceDB/requirements/Active.qview.xml | 8 ++++++++ 2 files changed, 9 insertions(+), 3 deletions(-) create mode 100644 ONPRC_EHR_ComplianceDB/resources/queries/EHR_ComplianceDB/requirements/Active.qview.xml diff --git a/ONPRC_EHR_ComplianceDB/resources/queries/EHR_ComplianceDB/requirements/.qview.xml b/ONPRC_EHR_ComplianceDB/resources/queries/EHR_ComplianceDB/requirements/.qview.xml index 17d0f4476..7b0d6af85 100644 --- a/ONPRC_EHR_ComplianceDB/resources/queries/EHR_ComplianceDB/requirements/.qview.xml +++ b/ONPRC_EHR_ComplianceDB/resources/queries/EHR_ComplianceDB/requirements/.qview.xml @@ -2,7 +2,5 @@ - - - + \ No newline at end of file diff --git a/ONPRC_EHR_ComplianceDB/resources/queries/EHR_ComplianceDB/requirements/Active.qview.xml b/ONPRC_EHR_ComplianceDB/resources/queries/EHR_ComplianceDB/requirements/Active.qview.xml new file mode 100644 index 000000000..8c3f3c04f --- /dev/null +++ b/ONPRC_EHR_ComplianceDB/resources/queries/EHR_ComplianceDB/requirements/Active.qview.xml @@ -0,0 +1,8 @@ + From 4a6c71e46f3b4d233ce5190bae58f5b712fc50b3 Mon Sep 17 00:00:00 2001 From: Ohsudev <76500320+Ohsudev@users.noreply.github.com> Date: Mon, 8 Dec 2025 16:15:05 -0800 Subject: [PATCH 06/31] =?UTF-8?q?Created=20a=20new=20permission=20group=20?= =?UTF-8?q?that=20prevents=20the=20NHP=20Training=20input=20f=E2=80=A6=20(?= =?UTF-8?q?#1553)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Created a new permission group that prevents the NHP Training input form from being displayed as an accessible input form when CMU groups are accessing the Pairing observation input form. * Created a new permission group that prevents the NHP Training input form from being displayed as an accessible input form when CMU groups are accessing the Pairing observation input form. * Created a new permission group that prevents the NHP Training input form from being displayed as an accessible input form when CMU groups are accessing the Pairing observation input form. * Modified BSU permission to only allow Pairing Observation access to the DCM CMU permission group and BSU Staff. * Modified BSU permission to only allow Pairing Observation access to the DCM CMU permission group and BSU Staff. * Created a new grid permission called "Form Paring Observation SF", and assigned "DCM CMU" permission group. --- .../onprc_ehr/dataentry/NHPTrainingFormType.java | 4 ++++ .../labkey/onprc_ehr/dataentry/PairingFormType.java | 12 ------------ 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/NHPTrainingFormType.java b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/NHPTrainingFormType.java index 54bd16e60..8faf1cba8 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/NHPTrainingFormType.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/NHPTrainingFormType.java @@ -21,7 +21,11 @@ import org.labkey.api.ehr.dataentry.TaskFormSection; import org.labkey.api.ehr.security.EHRBehaviorEntryPermission; import org.labkey.api.module.Module; +import org.labkey.api.security.Group; +import org.labkey.api.security.GroupManager; +import org.labkey.api.security.permissions.AdminPermission; import org.labkey.api.view.template.ClientDependency; +import org.labkey.security.xml.GroupEnumType; import java.util.Arrays; diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/PairingFormType.java b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/PairingFormType.java index 19b877428..abf1da752 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/PairingFormType.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/PairingFormType.java @@ -66,19 +66,7 @@ public PairingFormType(DataEntryFormContext ctx, Module owner) addClientDependency(ClientDependency.supplierFromPath("/onprc_ehr/form/field/PairedAdultsEntryField.js")); - - - - - } - @Override - protected boolean canInsert() - { - if (!getCtx().getContainer().hasPermission(getCtx().getUser(), EHRBehaviorEntryPermission.class)) - return false; - return super.canInsert(); - } } From ab3e1ba9867f6522e716e648f7696d8202197f6c Mon Sep 17 00:00:00 2001 From: Brent Logan Date: Wed, 10 Dec 2025 11:46:53 -0800 Subject: [PATCH 07/31] Add afternoon schedule to EHR Data Validation notification (#1570) * Add afternoon time and adjust descriptions * Finalize afternoon time and adjust descriptions --- .../notification/DataValidationNotification.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/notification/DataValidationNotification.java b/onprc_ehr/src/org/labkey/onprc_ehr/notification/DataValidationNotification.java index 8268a7fc0..6e5cda088 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/notification/DataValidationNotification.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/notification/DataValidationNotification.java @@ -48,19 +48,19 @@ public String getEmailSubject(Container c) @Override public String getCronString() { - return "0 25 6 * * ?"; + return "0 50 6/15 * * ?"; } @Override public String getScheduleDescription() { - return "every day at 6:25AM"; + return "every day at 6:50AM and 3:50PM"; } @Override public String getDescription() { - return "The report is designed to identify potential problems with the EHR data. It is similar to Colony Alerts, except it is limited to alerts that indicate a true problem in the data itself."; + return "The report identifies potential problems with the EHR data. Although similar to Colony Alerts, it is limited to problems in the data itself."; } @Override @@ -119,7 +119,7 @@ public String getMessageBodyHTML(Container c, User u) //only send if there are alerts if (!msg.isEmpty()) { - msg.insert(0, "This email contains a series of automatic alerts designed to identify problems in the EHR data. It was run on: " + getDateFormat(c).format(now) + " at " + _timeFormat.format(now) + ".

"); + msg.insert(0, "This email contains a series of automatic alerts identifying problems in the EHR data. It was run on: " + getDateFormat(c).format(now) + " at " + _timeFormat.format(now) + ".

"); } return msg.toString(); From 13664fd5c1bb7a8b1fac9ddfe69b8f7699f1754c Mon Sep 17 00:00:00 2001 From: Brent Logan Date: Mon, 15 Dec 2025 15:00:41 -0800 Subject: [PATCH 08/31] Fix schedule (#1576) --- .../onprc_ehr/notification/DataValidationNotification.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/notification/DataValidationNotification.java b/onprc_ehr/src/org/labkey/onprc_ehr/notification/DataValidationNotification.java index 6e5cda088..11080a1de 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/notification/DataValidationNotification.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/notification/DataValidationNotification.java @@ -48,7 +48,7 @@ public String getEmailSubject(Container c) @Override public String getCronString() { - return "0 50 6/15 * * ?"; + return "0 50 6,15 * * ?"; } @Override From 5f255c449b713c3bde13e0f2ba8eb4ec678551ae Mon Sep 17 00:00:00 2001 From: Ohsudev <76500320+Ohsudev@users.noreply.github.com> Date: Tue, 16 Dec 2025 11:01:45 -0800 Subject: [PATCH 09/31] Created a new Clinical permission group called "Form MedSignOff SF". (#1572) --- .../org/labkey/onprc_ehr/dataentry/MedSignoffFormType.java | 4 ++-- .../onprc_ehr/security/ONPRC_EHREnvironmentalPermission.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/MedSignoffFormType.java b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/MedSignoffFormType.java index 86312e8a4..4a221596b 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/MedSignoffFormType.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/MedSignoffFormType.java @@ -72,11 +72,11 @@ protected boolean canInsert() return super.canInsert(); } - //Modified: 12-5-2019 R.Blasa + //Modified: 12-11-2025 R.Blasa @Override public boolean isVisible() { - Group g = GroupManager.getGroup(getCtx().getContainer(), "ASB Support", GroupEnumType.SITE); + Group g = GroupManager.getGroup(getCtx().getContainer(), "Clinical Entry", GroupEnumType.SITE); if (g != null && getCtx().getUser().isInGroup(g.getUserId()) && !getCtx().getContainer().hasPermission(getCtx().getUser(), AdminPermission.class)) { return false; diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/security/ONPRC_EHREnvironmentalPermission.java b/onprc_ehr/src/org/labkey/onprc_ehr/security/ONPRC_EHREnvironmentalPermission.java index 95ca1815e..0a909fed7 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/security/ONPRC_EHREnvironmentalPermission.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/security/ONPRC_EHREnvironmentalPermission.java @@ -24,6 +24,6 @@ public class ONPRC_EHREnvironmentalPermission extends AbstractPermission { public ONPRC_EHREnvironmentalPermission() { - super("ONPRC_EHREnvironmentalPermission", "This is the base permission used to control editing of the Envioenmental Assessment"); + super("ONPRC_EHREnvironmentalPermission", "This is the base permission used to control editing of the Environmental Assessment"); } } From 764d818cabec5a612ce2189bfeb2749e6ef6a4f4 Mon Sep 17 00:00:00 2001 From: Ohsudev <76500320+Ohsudev@users.noreply.github.com> Date: Tue, 16 Dec 2025 11:02:45 -0800 Subject: [PATCH 10/31] Created a new Compliance Exception report that identifies (#1544) * Created a new Compliance Exception report that identifies employeeids that are not members of the the Employee units/categories data set. * Created a new Compliance Exception report that identifies employeeids that are not members of the the Employee units/categories data set. * Created a new Compliance Exception report that identifies employeeids that are not members of the the Employee units/categories data set. * Created a new Employee unit/category exception reports. * Created a new Employee unit/category exception reports. --- .../complianceEmployeelist_rpt.query.xml | 38 +++++++++++++++++++ .../complianceEmployeelist_rpt.sql | 23 +++++++++++ .../complianceEmployeelist_rpt/.qview.xml | 21 ++++++++++ .../resources/views/begin.html | 2 + 4 files changed, 84 insertions(+) create mode 100644 ONPRC_EHR_ComplianceDB/resources/queries/EHR_ComplianceDB/complianceEmployeelist_rpt.query.xml create mode 100644 ONPRC_EHR_ComplianceDB/resources/queries/EHR_ComplianceDB/complianceEmployeelist_rpt.sql create mode 100644 ONPRC_EHR_ComplianceDB/resources/queries/EHR_ComplianceDB/complianceEmployeelist_rpt/.qview.xml diff --git a/ONPRC_EHR_ComplianceDB/resources/queries/EHR_ComplianceDB/complianceEmployeelist_rpt.query.xml b/ONPRC_EHR_ComplianceDB/resources/queries/EHR_ComplianceDB/complianceEmployeelist_rpt.query.xml new file mode 100644 index 000000000..7c9812b7d --- /dev/null +++ b/ONPRC_EHR_ComplianceDB/resources/queries/EHR_ComplianceDB/complianceEmployeelist_rpt.query.xml @@ -0,0 +1,38 @@ + + + + + Category/Unit Comparison + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
diff --git a/ONPRC_EHR_ComplianceDB/resources/queries/EHR_ComplianceDB/complianceEmployeelist_rpt.sql b/ONPRC_EHR_ComplianceDB/resources/queries/EHR_ComplianceDB/complianceEmployeelist_rpt.sql new file mode 100644 index 000000000..65198effc --- /dev/null +++ b/ONPRC_EHR_ComplianceDB/resources/queries/EHR_ComplianceDB/complianceEmployeelist_rpt.sql @@ -0,0 +1,23 @@ +select a.employeeid, a.unit, null as category, a.enddate, a.lastName, a.firstName, a.email, a.type, a.title, a.category +from ehr_compliancedb.employees a +where a.unit not in (select unit from ehr_compliancedb.employeeperUnit j where j.EmployeeId = a.employeeid) +and a.unit is not null +and a.enddate is null + + + +group by a.employeeid, a.unit, a.enddate, a.lastName, a.firstName, a.email, a.type, a.title, a.category + + +union + +select a.employeeid, null as unit, a.category, a.enddate, a.lastName, + a.firstName, a.email, a.type, a.title, a.category +from ehr_compliancedb.employees a where + a.category not in (select category from ehr_compliancedb.employeeperUnit j where j.EmployeeId = a.employeeid) +and a.category is not null +and a.enddate is null + +group by a.employeeid, a.category, a.enddate, a.lastName, a.firstName, a.email, a.type, a.title, a.category + +order by a.employeeid \ No newline at end of file diff --git a/ONPRC_EHR_ComplianceDB/resources/queries/EHR_ComplianceDB/complianceEmployeelist_rpt/.qview.xml b/ONPRC_EHR_ComplianceDB/resources/queries/EHR_ComplianceDB/complianceEmployeelist_rpt/.qview.xml new file mode 100644 index 000000000..b52373e0b --- /dev/null +++ b/ONPRC_EHR_ComplianceDB/resources/queries/EHR_ComplianceDB/complianceEmployeelist_rpt/.qview.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/ONPRC_EHR_ComplianceDB/resources/views/begin.html b/ONPRC_EHR_ComplianceDB/resources/views/begin.html index 6712a429e..73efe6821 100644 --- a/ONPRC_EHR_ComplianceDB/resources/views/begin.html +++ b/ONPRC_EHR_ComplianceDB/resources/views/begin.html @@ -92,6 +92,8 @@ name: 'List of Unused Training Names', url: ctx['SSRSServerURL'] +'%2fPrime+Reports%2fCompliance%2fCompliance_Unassigned_requirements&rs:Command=Render' },{ name: 'List of Duplicate Completion Dates', url: ctx['SSRSServerURL'] +'%2fPrime+Reports%2fCompliance%2fCompliance_Duplicate_CompletedDates&rs:Command=Render' + },{ + name: 'Category/Unit Comparison', url: '<%=contextPath%>/query' + container + '/executeQuery.view?schemaName=ehr_compliancedb&query.queryName=complianceEmployeelist_rpt' }] },{ From e0166774f8268472308d3a5d2ed3b281aadeb218 Mon Sep 17 00:00:00 2001 From: Ohsudev <76500320+Ohsudev@users.noreply.github.com> Date: Tue, 16 Dec 2025 18:18:44 -0800 Subject: [PATCH 11/31] 25.7 fb genetic test current location (#1542) * Modified program to allow current location to be reported as part of the genetic testing report. * Modified program to allow current location to be reported as part of the genetic testing report. * Modified program to allow current location to be reported as part of the genetic testing report. * Modified program to allow current location to be reported as part of the genetic testing report. * Modified program to allow current location to be reported as part of the genetic testing report. * Modified program to allow current location to be reported as part of the genetic testing report. * Modified program to allow current location to be reported as part of the genetic testing report. * Modified program to allow current location to be reported as part of the genetic testing report. * Created a new report that includes NHP locations column as part of the Genetic Testing grid reports. * Modified Genetic Testing grid to display the default view. * Modified Genetic Testing grid to display the default view. * Modified Genetic Testing grid to display the default view. * Modified Genetic Testing default values for reporting. * Created managed view for Genetic Testing * Created managed view for Genetic Testing --- ...ypesWithSignificancewithLocation.query.xml | 36 +++++++++++++++++++ .../genotypesWithSignificancewithLocation.sql | 10 ++++++ .../.qview.xml | 11 ++++++ ...c Testing with Current Locations.qview.xml | 15 ++++++++ 4 files changed, 72 insertions(+) create mode 100644 onprc_reports/resources/queries/GeneticTests/genotypesWithSignificancewithLocation.query.xml create mode 100644 onprc_reports/resources/queries/GeneticTests/genotypesWithSignificancewithLocation.sql create mode 100644 onprc_reports/resources/queries/GeneticTests/genotypesWithSignificancewithLocation/.qview.xml create mode 100644 onprc_reports/resources/queries/GeneticTests/genotypesWithSignificancewithLocation/Genetic Testing with Current Locations.qview.xml diff --git a/onprc_reports/resources/queries/GeneticTests/genotypesWithSignificancewithLocation.query.xml b/onprc_reports/resources/queries/GeneticTests/genotypesWithSignificancewithLocation.query.xml new file mode 100644 index 000000000..15aa08c77 --- /dev/null +++ b/onprc_reports/resources/queries/GeneticTests/genotypesWithSignificancewithLocation.query.xml @@ -0,0 +1,36 @@ + + + + + Genetic Testing w/ Location + + + + Id + + + Sample Date + + + Area + + + Room + + + Room + + + Label + + + Comments + + + Status + + +
+
+
+
diff --git a/onprc_reports/resources/queries/GeneticTests/genotypesWithSignificancewithLocation.sql b/onprc_reports/resources/queries/GeneticTests/genotypesWithSignificancewithLocation.sql new file mode 100644 index 000000000..0cfa39eae --- /dev/null +++ b/onprc_reports/resources/queries/GeneticTests/genotypesWithSignificancewithLocation.sql @@ -0,0 +1,10 @@ +select a.Id, + a.date, + b.Id.curLocation.area as area, + b.Id.curLocation.room as room, + b.Id.curLocation.cage as cage, + a.label, + a.comment, + b.calculated_status as LiveStatus + +from genotypesWithSignificance a, study.demographics b where a.Id = b.Id \ No newline at end of file diff --git a/onprc_reports/resources/queries/GeneticTests/genotypesWithSignificancewithLocation/.qview.xml b/onprc_reports/resources/queries/GeneticTests/genotypesWithSignificancewithLocation/.qview.xml new file mode 100644 index 000000000..35442b9d8 --- /dev/null +++ b/onprc_reports/resources/queries/GeneticTests/genotypesWithSignificancewithLocation/.qview.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/onprc_reports/resources/queries/GeneticTests/genotypesWithSignificancewithLocation/Genetic Testing with Current Locations.qview.xml b/onprc_reports/resources/queries/GeneticTests/genotypesWithSignificancewithLocation/Genetic Testing with Current Locations.qview.xml new file mode 100644 index 000000000..0b1c76d53 --- /dev/null +++ b/onprc_reports/resources/queries/GeneticTests/genotypesWithSignificancewithLocation/Genetic Testing with Current Locations.qview.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + \ No newline at end of file From d39a04afabb245640c3c287039fe1bbbefc20138 Mon Sep 17 00:00:00 2001 From: Lakshmi Kolli <69940873+kollil@users.noreply.github.com> Date: Mon, 22 Dec 2025 18:50:53 -0800 Subject: [PATCH 12/31] Assignment updates in Behavior alert (#1547) * Added assignment dashboard updates in the behavior notification. * Added more sections to the alert * Added more sections to the alert, take #2 * Added query.xml files for the db tables * Added query.xml files for the db tables * Updated the queries and the report details * Updated the queries and the report details * Updated queries with date formatting Added sort order to the email alert grid views * Updated queries date comparison * Removed


tag * Added
tag * some cleanup --- .../AssignmentsCreatedInPast1Day.query.xml | 10 + .../study/AssignmentsCreatedInPast1Day.sql | 19 ++ .../AssignmentsReleasedInPast1Day.query.xml | 10 + .../study/AssignmentsReleasedInPast1Day.sql | 19 ++ .../AssignmentsStartedPast1to7Days.query.xml | 10 + .../study/AssignmentsStartedPast1to7Days.sql | 20 ++ ...AssignmentsStartingNext1to14Days.query.xml | 10 + .../AssignmentsStartingNext1to14Days.sql | 20 ++ .../notification/BehaviorNotification.java | 252 ++++++++++++++++-- 9 files changed, 353 insertions(+), 17 deletions(-) create mode 100644 onprc_ehr/resources/queries/study/AssignmentsCreatedInPast1Day.query.xml create mode 100644 onprc_ehr/resources/queries/study/AssignmentsCreatedInPast1Day.sql create mode 100644 onprc_ehr/resources/queries/study/AssignmentsReleasedInPast1Day.query.xml create mode 100644 onprc_ehr/resources/queries/study/AssignmentsReleasedInPast1Day.sql create mode 100644 onprc_ehr/resources/queries/study/AssignmentsStartedPast1to7Days.query.xml create mode 100644 onprc_ehr/resources/queries/study/AssignmentsStartedPast1to7Days.sql create mode 100644 onprc_ehr/resources/queries/study/AssignmentsStartingNext1to14Days.query.xml create mode 100644 onprc_ehr/resources/queries/study/AssignmentsStartingNext1to14Days.sql diff --git a/onprc_ehr/resources/queries/study/AssignmentsCreatedInPast1Day.query.xml b/onprc_ehr/resources/queries/study/AssignmentsCreatedInPast1Day.query.xml new file mode 100644 index 000000000..ba5b595d4 --- /dev/null +++ b/onprc_ehr/resources/queries/study/AssignmentsCreatedInPast1Day.query.xml @@ -0,0 +1,10 @@ + + + + + + Assignments created in past 24 hrs +
+
+
+
diff --git a/onprc_ehr/resources/queries/study/AssignmentsCreatedInPast1Day.sql b/onprc_ehr/resources/queries/study/AssignmentsCreatedInPast1Day.sql new file mode 100644 index 000000000..8a09aa654 --- /dev/null +++ b/onprc_ehr/resources/queries/study/AssignmentsCreatedInPast1Day.sql @@ -0,0 +1,19 @@ +SELECT + Id, + Id.demographics.gender as Sex, + Id.curlocation.room as Room, + Id.curlocation.cage as Cage, + project.displayname as project, + project.protocol.displayname as Protocol, + project.title as Title, + project.protocol.investigatorId.lastname as ProjectInvestigator, + CAST(date AS DATE) AS AssignDate, + CAST(enddate AS DATE) AS ReleaseDate, + CAST(projectedRelease AS DATE) AS ProjectedReleaseDate, + assignmentType, + assignCondition.meaning as AssignCondition, + projectedReleaseCondition.meaning as ProjectedReleaseCondition, + releaseCondition.meaning as ConditionAtRelease + +FROM Assignment +WHERE CAST(date AS DATE) >= TIMESTAMPADD('SQL_TSI_DAY', -1, NOW()) \ No newline at end of file diff --git a/onprc_ehr/resources/queries/study/AssignmentsReleasedInPast1Day.query.xml b/onprc_ehr/resources/queries/study/AssignmentsReleasedInPast1Day.query.xml new file mode 100644 index 000000000..bc2343418 --- /dev/null +++ b/onprc_ehr/resources/queries/study/AssignmentsReleasedInPast1Day.query.xml @@ -0,0 +1,10 @@ + + + + + + Assignments released in past 24 hrs +
+
+
+
diff --git a/onprc_ehr/resources/queries/study/AssignmentsReleasedInPast1Day.sql b/onprc_ehr/resources/queries/study/AssignmentsReleasedInPast1Day.sql new file mode 100644 index 000000000..b936474ae --- /dev/null +++ b/onprc_ehr/resources/queries/study/AssignmentsReleasedInPast1Day.sql @@ -0,0 +1,19 @@ +SELECT + Id, + Id.demographics.gender as Sex, + Id.curlocation.room as Room, + Id.curlocation.cage as Cage, + project.displayname as project, + project.protocol.displayname as Protocol, + project.title as Title, + project.protocol.investigatorId.lastname as ProjectInvestigator, + CAST(date AS DATE) AS AssignDate, + CAST(enddate AS DATE) AS ReleaseDate, + CAST(projectedRelease AS DATE) AS ProjectedReleaseDate, + assignmentType, + assignCondition.meaning as AssignCondition, + projectedReleaseCondition.meaning as ProjectedReleaseCondition, + releaseCondition.meaning as ConditionAtRelease + +FROM Assignment +WHERE CAST(enddate AS DATE) >= TIMESTAMPADD('SQL_TSI_DAY', -1, NOW()) \ No newline at end of file diff --git a/onprc_ehr/resources/queries/study/AssignmentsStartedPast1to7Days.query.xml b/onprc_ehr/resources/queries/study/AssignmentsStartedPast1to7Days.query.xml new file mode 100644 index 000000000..a65ccdd3d --- /dev/null +++ b/onprc_ehr/resources/queries/study/AssignmentsStartedPast1to7Days.query.xml @@ -0,0 +1,10 @@ + + + + + + Assignments started in past 1-7 days +
+
+
+
\ No newline at end of file diff --git a/onprc_ehr/resources/queries/study/AssignmentsStartedPast1to7Days.sql b/onprc_ehr/resources/queries/study/AssignmentsStartedPast1to7Days.sql new file mode 100644 index 000000000..020306760 --- /dev/null +++ b/onprc_ehr/resources/queries/study/AssignmentsStartedPast1to7Days.sql @@ -0,0 +1,20 @@ +SELECT + Id, + Id.demographics.gender as Sex, + Id.curlocation.room as Room, + Id.curlocation.cage as Cage, + project.displayname as project, + project.protocol.displayname as Protocol, + project.title as Title, + project.protocol.investigatorId.lastname as ProjectInvestigator, + CAST(date AS DATE) AS AssignDate, + CAST(enddate AS DATE) AS ReleaseDate, + CAST(projectedRelease AS DATE) AS ProjectedReleaseDate, + assignmentType, + assignCondition.meaning as AssignCondition, + projectedReleaseCondition.meaning as ProjectedReleaseCondition, + releaseCondition.meaning as ConditionAtRelease + +FROM Assignment +WHERE CAST(date AS DATE) >= TIMESTAMPADD('SQL_TSI_DAY', -1, NOW()) + AND CAST(date AS DATE) < TIMESTAMPADD('SQL_TSI_DAY', -7, NOW()) \ No newline at end of file diff --git a/onprc_ehr/resources/queries/study/AssignmentsStartingNext1to14Days.query.xml b/onprc_ehr/resources/queries/study/AssignmentsStartingNext1to14Days.query.xml new file mode 100644 index 000000000..165ef5863 --- /dev/null +++ b/onprc_ehr/resources/queries/study/AssignmentsStartingNext1to14Days.query.xml @@ -0,0 +1,10 @@ + + + + + + Assignments starting in next 1 to 14 days +
+
+
+
diff --git a/onprc_ehr/resources/queries/study/AssignmentsStartingNext1to14Days.sql b/onprc_ehr/resources/queries/study/AssignmentsStartingNext1to14Days.sql new file mode 100644 index 000000000..fcc73bac8 --- /dev/null +++ b/onprc_ehr/resources/queries/study/AssignmentsStartingNext1to14Days.sql @@ -0,0 +1,20 @@ +SELECT + Id, + Id.demographics.gender as Sex, + Id.curlocation.room as Room, + Id.curlocation.cage as Cage, + project.displayname as project, + project.protocol.displayname as Protocol, + project.title as Title, + project.protocol.investigatorId.lastname as ProjectInvestigator, + CAST(date AS DATE) AS AssignDate, + CAST(enddate AS DATE) AS ReleaseDate, + CAST(projectedRelease AS DATE) AS ProjectedReleaseDate, + assignmentType, + assignCondition.meaning as AssignCondition, + projectedReleaseCondition.meaning as ProjectedReleaseCondition, + releaseCondition.meaning as ConditionAtRelease + +FROM Assignment +WHERE CAST(date AS DATE) >= TIMESTAMPADD('SQL_TSI_DAY', 1, NOW()) + AND CAST(date AS DATE) < TIMESTAMPADD('SQL_TSI_DAY', 14, NOW()) \ No newline at end of file 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 03f4a35f8..958d70a3f 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/notification/BehaviorNotification.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/notification/BehaviorNotification.java @@ -17,10 +17,14 @@ import org.apache.commons.lang3.time.DateUtils; import org.json.JSONObject; +import org.labkey.api.data.ColumnInfo; import org.labkey.api.data.CompareType; import org.labkey.api.data.Container; import org.labkey.api.data.ContainerFilter; +import org.labkey.api.data.Results; +import org.labkey.api.data.ResultsImpl; import org.labkey.api.data.SQLFragment; +import org.labkey.api.data.Selector; import org.labkey.api.data.SimpleFilter; import org.labkey.api.data.Sort; import org.labkey.api.data.SqlSelector; @@ -35,14 +39,18 @@ import org.labkey.api.security.User; import org.labkey.api.util.PageFlowUtil; +import java.sql.ResultSet; +import java.sql.SQLException; import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; import java.util.Collection; import java.util.Date; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Set; /** * User: bimber @@ -107,6 +115,12 @@ public String getMessageBodyHTML(Container c, User u) NHPTraining_BehaviorAlert(c, u , msg); AlopeciaScoreAlert(c, u , msg); dcmNotesAlert(c, u , msg); + //Added by Kollil, Nov 2025 + //Refer to tkt # 13618 + assignmentsCreatedInPast1Day(c,u,msg); + assignmentsReleasedInPast1Day(c,u,msg); + assignmentsStartingNext1to14Days(c,u,msg); + assignmentsStartedPast1to7Days(c,u,msg); notesEndingToday(c, u, msg, Arrays.asList("BSU Notes"), null); saveValues(c, toSave); @@ -114,6 +128,212 @@ public String getMessageBodyHTML(Container c, User u) return msg.toString(); } + /* Added by Kollil Nov, 2025 + Priority 4: Add links to grids 3 and 4 in daily Behavior Alerts email (do not need to display full grid in email) + - for grid 3 - "There are __ assignments starting in the Next 1-14 days" with a link + Refer to tkt # 13618 + */ + private void assignmentsStartingNext1to14Days(final Container c, User u, final StringBuilder msg) + { + TableInfo ti = getStudySchema(c, u).getTable("AssignmentsStartingNext1to14Days"); + + TableSelector ts = new TableSelector(ti, null, new Sort("Id")); + long total = ts.getRowCount(); + + if (total > 0) + { + msg.append("Assignments starting in the next 1-14 days:

"); + msg.append( total + " entries found. "); + msg.append("Click here to view them\n"); + msg.append("


\n\n"); + } + else { + msg.append("WARNING: No assignments starting in the next 1-14 days!

\n"); + } + } + + /* Added by Kollil Nov, 2025 + Priority 4: Add links to grids 3 and 4 in daily Behavior Alerts email (do not need to display full grid in email) + - for grid 4 - "There were __ assignments started in the past 1-7 days" with a link + Refer to tkt # 13618 + */ + private void assignmentsStartedPast1to7Days(final Container c, User u, final StringBuilder msg) + { + TableInfo ti = getStudySchema(c, u).getTable("AssignmentsStartedPast1to7Days"); + + TableSelector ts = new TableSelector(ti, null, new Sort("Id")); + long total = ts.getRowCount(); + + if (total > 0) + { + msg.append("Assignments started in the past 1-7 days:

"); + msg.append( total + " entries found. "); + msg.append("Click here to view them\n"); + msg.append("


\n\n"); + } + else { + msg.append("WARNING: No assignments started in the past 1-7 days!

\n"); + } + } + + /* Added by Kollil Nov, 2025 + List of assignment records created by R&L in past 24hrs (this is the most important grid) + a. Replaces current grid “Assignments Modified in Past 1 Day” which captures any modifications to records in the last 24hrs + b. To clarify, not the same as records with the “assign date” within the past day + c. Include Day Leases + Refer to tkt # 13618 + */ + private void assignmentsCreatedInPast1Day(final Container c, User u, final StringBuilder msg) + { + if (QueryService.get().getUserSchema(u, c, "study") == null) { + msg.append("Warning: The study schema has not been enabled in this folder, so the alert cannot run!


"); + return; + } + //assignments query + TableInfo ti = QueryService.get().getUserSchema(u, c, "study").getTable("AssignmentsCreatedInPast1Day", ContainerFilter.Type.AllFolders.create(c, u)); + TableSelector ts = new TableSelector(ti, null, new Sort("Id")); + long count = ts.getRowCount(); + + //Get num of rows + if (count > 0) { + msg.append("Assignments created in the past 24hrs:

"); + msg.append( count + " entries found. "); + msg.append("Click here to view them in a separate window\n"); + msg.append("\n\n"); + + //Display the daily report in the email + Set columns = new HashSet<>(); + columns.add(FieldKey.fromString("Id")); + columns.add(FieldKey.fromString("Sex")); + columns.add(FieldKey.fromString("Room")); + columns.add(FieldKey.fromString("Cage")); + columns.add(FieldKey.fromString("project")); + columns.add(FieldKey.fromString("Protocol")); + columns.add(FieldKey.fromString("Title")); + columns.add(FieldKey.fromString("ProjectInvestigator")); + columns.add(FieldKey.fromString("AssignDate")); + columns.add(FieldKey.fromString("ReleaseDate")); + columns.add(FieldKey.fromString("ProjectedReleaseDate")); + columns.add(FieldKey.fromString("assignmentType")); + columns.add(FieldKey.fromString("assignCondition")); + columns.add(FieldKey.fromString("projectedReleaseCondition")); + columns.add(FieldKey.fromString("ConditionAtRelease")); + + final Map colMap = QueryService.get().getColumns(ti, columns); + TableSelector ts2 = new TableSelector(ti, colMap.values(), null, new Sort("Id")); + +// msg.append("


Assignments created in past 24hrs:

\n"); + 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(""); + 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")) + "


"); + } + else { + msg.append("WARNING: No assignments created in the past 24hrs!

\n"); + } + } + + /* Added by Kollil Nov, 2025 + Grid 2: List of records with new “Release date” added within the last 24hrs + a. Omit Day Leases + Refer to tkt # 13618 + */ + private void assignmentsReleasedInPast1Day(final Container c, User u, final StringBuilder msg) + { + if (QueryService.get().getUserSchema(u, c, "study") == null) { + msg.append("Warning: The study schema has not been enabled in this folder, so the alert cannot run!


"); + return; + } + + //assignments query + TableInfo ti = QueryService.get().getUserSchema(u, c, "study").getTable("AssignmentsReleasedInPast1Day", ContainerFilter.Type.AllFolders.create(c, u)); + TableSelector ts = new TableSelector(ti, null, new Sort("Id")); + long count = ts.getRowCount(); + + //Get num of rows + if (count > 0) { + msg.append("Assignments with new \"Release date\" added in the last 24hrs:

"); + msg.append( count + " entries found. "); + msg.append("Click here to view them in a separate window\n"); + msg.append("\n\n"); + + //Display the daily report in the email + Set columns = new HashSet<>(); + columns.add(FieldKey.fromString("Id")); + columns.add(FieldKey.fromString("Sex")); + columns.add(FieldKey.fromString("Room")); + columns.add(FieldKey.fromString("Cage")); + columns.add(FieldKey.fromString("project")); + columns.add(FieldKey.fromString("Protocol")); + columns.add(FieldKey.fromString("Title")); + columns.add(FieldKey.fromString("ProjectInvestigator")); + columns.add(FieldKey.fromString("AssignDate")); + columns.add(FieldKey.fromString("ReleaseDate")); + columns.add(FieldKey.fromString("ProjectedReleaseDate")); + columns.add(FieldKey.fromString("assignmentType")); + columns.add(FieldKey.fromString("assignCondition")); + columns.add(FieldKey.fromString("projectedReleaseCondition")); + columns.add(FieldKey.fromString("ConditionAtRelease")); + + 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(""); + + 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(""); + 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")) + "


"); + } + else { + msg.append("WARNING: No assignments released in the past 24hrs!

\n"); + } + } /* Added by Kollil 08/22/2025 New alert/notification for when an animal receives an alopecia score of 4 or 5, but does not have an open behavioral case for alopecia. @@ -128,16 +348,15 @@ private void AlopeciaScoreAlert(final Container c, User u, final StringBuilder m 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("There are " + total + " entries found. "); - msg.append("

Click here to view them

\n"); + msg.append( total + " entries found. "); + msg.append("Click here to view them\n"); msg.append("
\n\n"); } 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"); } - - } + } // Added by Kollil 11/04/2020 private void NHPTraining_BehaviorAlert(final Container c, User u, final StringBuilder msg) @@ -155,14 +374,13 @@ private void NHPTraining_BehaviorAlert(final Container c, User u, final StringBu if (total > 0) { msg.append("There are " + total + " entries found. "); - msg.append("

Click here to view them

\n"); + msg.append("Click here to view them\n"); msg.append("
\n\n"); } else { msg.append("WARNING: There are no NHP_Training entries where \"Training Result = In Progress\" for over 60 days!

\n"); } - } /* @@ -184,9 +402,9 @@ protected void dcmNotesAlert(final Container c, User u, final StringBuilder msg) long count = ts.getRowCount(); if (count > 0) { - msg.append("WARNING: There are " + count + " DCM action items.
\n"); - msg.append("

Click here to view them
\n\n"); - msg.append("



"); + msg.append("WARNING: There are " + count + " DCM action items.
\n"); + msg.append("Click here to view them
\n\n"); + msg.append("

"); } else { @@ -209,8 +427,8 @@ protected void dcmNotesAlert(final Container c, User u, final StringBuilder msg) msg.append("DCM Alerts:

"); if (count1 > 0) { msg.append("" + count1 + " DCM notes entries added yesterday where \"Category = Notes pertaining to DAR\".
\n"); - msg.append("

Click here to view them
\n\n"); - msg.append("



\n\n"); + msg.append("Click here to view them
\n\n"); + msg.append("

\n\n"); } else { @@ -228,8 +446,8 @@ New alert for DCM notes (category = notes pertaining to DAR) removed the previou if (count4 > 0) { msg.append("" + count4 + " DCM notes entries removed yesterday where \"Category = Notes pertaining to DAR\".
\n"); - msg.append("

Click here to view them
\n\n"); - msg.append("



\n\n"); + msg.append("Click here to view them
\n\n"); + msg.append("

\n\n"); } else { msg.append("WARNING: No DCM notes ended yesterday where \"Category = Notes pertaining to DAR\"!

"); @@ -243,8 +461,8 @@ New alert for DCM notes (category = notes pertaining to DAR) removed the previou if (count2 > 0) { msg.append("There are " + count2 + " flag(s) added yesterday.
\n"); - msg.append("

Click here to view them
\n\n"); - msg.append("


"); + msg.append("Click here to view them
\n\n"); + msg.append("
"); } else { @@ -258,8 +476,8 @@ New alert for DCM notes (category = notes pertaining to DAR) removed the previou long count3 = ts3.getRowCount(); if (count3 > 0) { msg.append("" + count3 + " flag(s) removed yesterday.
\n"); - msg.append("

Click here to view them
\n\n"); - msg.append("


"); + msg.append("Click here to view them
\n\n"); + msg.append("
"); } else { msg.append("WARNING: There are no flags removed yesterday!

"); From 70f673d520aa09e4af0fc6f191d1460ab60a68e1 Mon Sep 17 00:00:00 2001 From: Ohsudev <76500320+Ohsudev@users.noreply.github.com> Date: Tue, 23 Dec 2025 10:50:38 -0800 Subject: [PATCH 13/31] MOdifed flag program to include the time settings when entering starting date, and ending date. (#1580) --- .../resources/queries/study/flags.query.xml | 4 +-- .../scripts/onprc_ehr/onprc_triggers.js | 4 +-- .../onprc_ehr/model/sources/Flag_settings.js | 33 +++++++++++++++++++ .../onprc_ehr/dataentry/FlagsFormType.java | 7 ++++ 4 files changed, 44 insertions(+), 4 deletions(-) create mode 100644 onprc_ehr/resources/web/onprc_ehr/model/sources/Flag_settings.js diff --git a/onprc_ehr/resources/queries/study/flags.query.xml b/onprc_ehr/resources/queries/study/flags.query.xml index e1e38b743..6c129e173 100644 --- a/onprc_ehr/resources/queries/study/flags.query.xml +++ b/onprc_ehr/resources/queries/study/flags.query.xml @@ -11,12 +11,12 @@ Date Added - Date + DateTime Date Removed false - Date + DateTime true diff --git a/onprc_ehr/resources/scripts/onprc_ehr/onprc_triggers.js b/onprc_ehr/resources/scripts/onprc_ehr/onprc_triggers.js index 6a96e4701..1532b529a 100644 --- a/onprc_ehr/resources/scripts/onprc_ehr/onprc_triggers.js +++ b/onprc_ehr/resources/scripts/onprc_ehr/onprc_triggers.js @@ -483,8 +483,8 @@ exports.init = function(EHR){ EHR.Server.TriggerManager.registerHandlerForQuery(EHR.Server.TriggerManager.Events.INIT, 'study', 'flags', function(event, helper){ helper.setScriptOptions({ allowFutureDates: true, - removeTimeFromDate: true, - removeTimeFromEndDate: true + removeTimeFromDate: false, + removeTimeFromEndDate: false }); EHR.Server.TriggerManager.unregisterAllHandlersForQueryNameAndEvent('study', 'flags', EHR.Server.TriggerManager.Events.AFTER_INSERT); diff --git a/onprc_ehr/resources/web/onprc_ehr/model/sources/Flag_settings.js b/onprc_ehr/resources/web/onprc_ehr/model/sources/Flag_settings.js new file mode 100644 index 000000000..57d9a9d12 --- /dev/null +++ b/onprc_ehr/resources/web/onprc_ehr/model/sources/Flag_settings.js @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2014 LabKey Corporation + * + * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 + */ +EHR.model.DataModelManager.registerMetadata('Flag_Settings', { + allQueries: { + + }, + byQuery: { + 'study.flags': { + date: { + xtype: 'xdatetime', + extFormat: LABKEY.extDefaultDateTimeFormat, + editorConfig: { + dateFormat: LABKEY.extDefaultDateFormat, + timeFormat: 'H:i' + } + + }, + enddate: { + xtype: 'xdatetime', + extFormat: LABKEY.extDefaultDateTimeFormat, + editorConfig: { + dateFormat: LABKEY.extDefaultDateFormat, + timeFormat: 'H:i' + } + + } + + } + } +}); \ No newline at end of file diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/FlagsFormType.java b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/FlagsFormType.java index 43c3631c4..362f42144 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/FlagsFormType.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/FlagsFormType.java @@ -26,6 +26,7 @@ import org.labkey.api.security.GroupManager; import org.labkey.api.security.permissions.AdminPermission; import org.labkey.api.security.permissions.Permission; +import org.labkey.api.view.template.ClientDependency; import org.labkey.security.xml.GroupEnumType; import java.util.ArrayList; @@ -49,6 +50,12 @@ public FlagsFormType(DataEntryFormContext ctx, Module owner) new SimpleGridPanel("study", "flags", "Flags") )); + addClientDependency(ClientDependency.supplierFromPath("onprc_ehr/model/sources/Flag_settings.js")); + + for (FormSection s : getFormSections()) + { + s.addConfigSource("Flag_Settings"); + } } From 33811effc8475083dbc5d215ddfef2004046a292 Mon Sep 17 00:00:00 2001 From: Lakshmi Kolli <69940873+kollil@users.noreply.github.com> Date: Tue, 23 Dec 2025 18:59:15 -0800 Subject: [PATCH 14/31] BSU Assignment dashboard alert update (#1588) * Updated the queries as per Isabel's input * updated the query clauses one last time * updated the query clauses one last time --- .../study/AssignmentsCreatedInPast1Day.query.xml | 2 +- .../study/AssignmentsCreatedInPast1Day.sql | 6 +++++- .../study/AssignmentsReleasedInPast1Day.query.xml | 2 +- .../study/AssignmentsReleasedInPast1Day.sql | 12 +++++++++++- .../AssignmentsStartedPast1to7Days.query.xml | 2 +- .../study/AssignmentsStartedPast1to7Days.sql | 15 +++++++++++++-- .../AssignmentsStartingNext1to14Days.query.xml | 2 +- .../study/AssignmentsStartingNext1to14Days.sql | 10 ++++++++-- 8 files changed, 41 insertions(+), 10 deletions(-) diff --git a/onprc_ehr/resources/queries/study/AssignmentsCreatedInPast1Day.query.xml b/onprc_ehr/resources/queries/study/AssignmentsCreatedInPast1Day.query.xml index ba5b595d4..e5f63127d 100644 --- a/onprc_ehr/resources/queries/study/AssignmentsCreatedInPast1Day.query.xml +++ b/onprc_ehr/resources/queries/study/AssignmentsCreatedInPast1Day.query.xml @@ -3,7 +3,7 @@ - Assignments created in past 24 hrs + Assignments created in the past 24 hrs
diff --git a/onprc_ehr/resources/queries/study/AssignmentsCreatedInPast1Day.sql b/onprc_ehr/resources/queries/study/AssignmentsCreatedInPast1Day.sql index 8a09aa654..152a69e82 100644 --- a/onprc_ehr/resources/queries/study/AssignmentsCreatedInPast1Day.sql +++ b/onprc_ehr/resources/queries/study/AssignmentsCreatedInPast1Day.sql @@ -1,3 +1,7 @@ +/* Created by Kollil, Dec, 2025 + Tkt # 13618 + Priority 1: Add Grid 1 ("Assignments Created in the Past Day ") to daily Behavior Alerts email - display full grid in email + */ SELECT Id, Id.demographics.gender as Sex, @@ -16,4 +20,4 @@ SELECT releaseCondition.meaning as ConditionAtRelease FROM Assignment -WHERE CAST(date AS DATE) >= TIMESTAMPADD('SQL_TSI_DAY', -1, NOW()) \ No newline at end of file +WHERE CAST(created AS DATE) >= TIMESTAMPADD('SQL_TSI_DAY', -1, CAST(NOW() AS DATE)) \ No newline at end of file diff --git a/onprc_ehr/resources/queries/study/AssignmentsReleasedInPast1Day.query.xml b/onprc_ehr/resources/queries/study/AssignmentsReleasedInPast1Day.query.xml index bc2343418..40c848da0 100644 --- a/onprc_ehr/resources/queries/study/AssignmentsReleasedInPast1Day.query.xml +++ b/onprc_ehr/resources/queries/study/AssignmentsReleasedInPast1Day.query.xml @@ -3,7 +3,7 @@ - Assignments released in past 24 hrs + Assignments released in the past 24 hrs
diff --git a/onprc_ehr/resources/queries/study/AssignmentsReleasedInPast1Day.sql b/onprc_ehr/resources/queries/study/AssignmentsReleasedInPast1Day.sql index b936474ae..f476894d3 100644 --- a/onprc_ehr/resources/queries/study/AssignmentsReleasedInPast1Day.sql +++ b/onprc_ehr/resources/queries/study/AssignmentsReleasedInPast1Day.sql @@ -1,3 +1,8 @@ +/* Created by Kollil, Dec, 2025 + Tkt # 13618 + Priority 2: Create new Grid 2 (Assignments ended in the Past 1 Day): + - List of records with new “Release date” added within the last 24hrs (omitting day leases). I am not omitting day leases for now as per Isabel's request. +*/ SELECT Id, Id.demographics.gender as Sex, @@ -16,4 +21,9 @@ SELECT releaseCondition.meaning as ConditionAtRelease FROM Assignment -WHERE CAST(enddate AS DATE) >= TIMESTAMPADD('SQL_TSI_DAY', -1, NOW()) \ No newline at end of file +/* this condition: >= TIMESTAMPADD('SQL_TSI_DAY', -1, NOW()) → not older than 24 hours +and this one: <= NOW() → not in the future +Together, they produce exactly the last 24 hours, nothing more. + */ +WHERE CAST(enddate AS DATE) = TIMESTAMPADD('SQL_TSI_DAY', -1, CAST(NOW() AS DATE)) + AND CAST(enddate AS DATE) <= CAST(NOW() AS DATE) \ No newline at end of file diff --git a/onprc_ehr/resources/queries/study/AssignmentsStartedPast1to7Days.query.xml b/onprc_ehr/resources/queries/study/AssignmentsStartedPast1to7Days.query.xml index a65ccdd3d..d543e5816 100644 --- a/onprc_ehr/resources/queries/study/AssignmentsStartedPast1to7Days.query.xml +++ b/onprc_ehr/resources/queries/study/AssignmentsStartedPast1to7Days.query.xml @@ -3,7 +3,7 @@ - Assignments started in past 1-7 days + Assignments started in the past 1-7 days
diff --git a/onprc_ehr/resources/queries/study/AssignmentsStartedPast1to7Days.sql b/onprc_ehr/resources/queries/study/AssignmentsStartedPast1to7Days.sql index 020306760..1702ede9b 100644 --- a/onprc_ehr/resources/queries/study/AssignmentsStartedPast1to7Days.sql +++ b/onprc_ehr/resources/queries/study/AssignmentsStartedPast1to7Days.sql @@ -1,3 +1,9 @@ +/* Created by Kollil, Dec, 2025 + Tkt # 13618 + Priority 4: Add links to grids 3 and 4 in daily Behavior Alerts email (do not need to display full grid in email) + - for grid 3 - There were __ assignments started in the past 1-7 days" with a link, including today's date + + */ SELECT Id, Id.demographics.gender as Sex, @@ -16,5 +22,10 @@ SELECT releaseCondition.meaning as ConditionAtRelease FROM Assignment -WHERE CAST(date AS DATE) >= TIMESTAMPADD('SQL_TSI_DAY', -1, NOW()) - AND CAST(date AS DATE) < TIMESTAMPADD('SQL_TSI_DAY', -7, NOW()) \ No newline at end of file +--including today +WHERE CAST(date AS DATE) >= TIMESTAMPADD('SQL_TSI_DAY', -7, CAST(NOW() AS DATE)) + AND CAST(date AS DATE) <= CAST(NOW() AS DATE); +--excluding today +-- WHERE CAST(date AS DATE) >= TIMESTAMPADD('SQL_TSI_DAY', -1, NOW()) +-- AND CAST(date AS DATE) < TIMESTAMPADD('SQL_TSI_DAY', -7, NOW()) + diff --git a/onprc_ehr/resources/queries/study/AssignmentsStartingNext1to14Days.query.xml b/onprc_ehr/resources/queries/study/AssignmentsStartingNext1to14Days.query.xml index 165ef5863..bde8b09e6 100644 --- a/onprc_ehr/resources/queries/study/AssignmentsStartingNext1to14Days.query.xml +++ b/onprc_ehr/resources/queries/study/AssignmentsStartingNext1to14Days.query.xml @@ -3,7 +3,7 @@ - Assignments starting in next 1 to 14 days + Assignments starting in the next 1 to 14 days
diff --git a/onprc_ehr/resources/queries/study/AssignmentsStartingNext1to14Days.sql b/onprc_ehr/resources/queries/study/AssignmentsStartingNext1to14Days.sql index fcc73bac8..3dc0e61c6 100644 --- a/onprc_ehr/resources/queries/study/AssignmentsStartingNext1to14Days.sql +++ b/onprc_ehr/resources/queries/study/AssignmentsStartingNext1to14Days.sql @@ -1,3 +1,9 @@ +/* Created by Kollil, Dec, 2025 + Tkt # 13618 + Priority 4: Add links to grids 3 and 4 in daily Behavior Alerts email (do not need to display full grid in email) + - for grid 4 - There are __ assignments starting in the Next 1-14 days" with a link, including today's date +*/ + SELECT Id, Id.demographics.gender as Sex, @@ -16,5 +22,5 @@ SELECT releaseCondition.meaning as ConditionAtRelease FROM Assignment -WHERE CAST(date AS DATE) >= TIMESTAMPADD('SQL_TSI_DAY', 1, NOW()) - AND CAST(date AS DATE) < TIMESTAMPADD('SQL_TSI_DAY', 14, NOW()) \ No newline at end of file +WHERE CAST(date AS DATE) >= TIMESTAMPADD('SQL_TSI_DAY', 1, CAST(NOW() AS DATE)) + AND CAST(date AS DATE) <= TIMESTAMPADD('SQL_TSI_DAY', 14, CAST(NOW() AS DATE)) \ No newline at end of file From 077ea0d68ccfced81e20620537de476006c7af7d Mon Sep 17 00:00:00 2001 From: Lakshmi Kolli <69940873+kollil@users.noreply.github.com> Date: Tue, 30 Dec 2025 13:29:13 -0800 Subject: [PATCH 15/31] Added clause to exclude dead animals in a query (#1591) --- .../resources/queries/study/AssignmentsReleasedInPast1Day.sql | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/onprc_ehr/resources/queries/study/AssignmentsReleasedInPast1Day.sql b/onprc_ehr/resources/queries/study/AssignmentsReleasedInPast1Day.sql index f476894d3..2c530c3ef 100644 --- a/onprc_ehr/resources/queries/study/AssignmentsReleasedInPast1Day.sql +++ b/onprc_ehr/resources/queries/study/AssignmentsReleasedInPast1Day.sql @@ -26,4 +26,5 @@ and this one: <= NOW() → not in the future Together, they produce exactly the last 24 hours, nothing more. */ WHERE CAST(enddate AS DATE) = TIMESTAMPADD('SQL_TSI_DAY', -1, CAST(NOW() AS DATE)) - AND CAST(enddate AS DATE) <= CAST(NOW() AS DATE) \ No newline at end of file + AND CAST(enddate AS DATE) <= CAST(NOW() AS DATE) + AND Id.demographics.calculated_status = 'Alive' \ No newline at end of file From 86937a77e8bf312c1a004c41d806111491729c95 Mon Sep 17 00:00:00 2001 From: Ohsudev <76500320+Ohsudev@users.noreply.github.com> Date: Thu, 8 Jan 2026 14:03:19 -0800 Subject: [PATCH 16/31] =?UTF-8?q?Created=20a=20new=20reporting=20program?= =?UTF-8?q?=20called=20"Tissue=20Distribution=20by=20Animal=E2=80=A6=20(#1?= =?UTF-8?q?597)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Created a new reporting program called "Tissue Distribution by AnimalID per Calendar". * Created a new reporting program called "Tissue Distribution by AnimalID per Calendar". --- ...sueDistributionSummaryCalendarYr.query.xml | 2 +- ...utionSummarybyAnimalIDCalendarYr.query.xml | 31 +++++++++++++++++++ ...istributionSummarybyAnimalIDCalendarYr.sql | 15 +++++++++ .../.qview.xml | 6 ++++ ...ibutionSummarybyAnimalIDFiscalYr.query.xml | 31 +++++++++++++++++++ ...eDistributionSummarybyAnimalIDFiscalYr.sql | 13 ++++++++ .../.qview.xml | 6 ++++ ...tionSummarybyRecipientCalendarYr.query.xml | 2 +- .../org/labkey/onprc_ehr/ONPRC_EHRModule.java | 9 +++++- 9 files changed, 112 insertions(+), 3 deletions(-) create mode 100644 onprc_ehr/resources/queries/study/TissueDistributionSummarybyAnimalIDCalendarYr.query.xml create mode 100644 onprc_ehr/resources/queries/study/TissueDistributionSummarybyAnimalIDCalendarYr.sql create mode 100644 onprc_ehr/resources/queries/study/TissueDistributionSummarybyAnimalIDCalendarYr/.qview.xml create mode 100644 onprc_ehr/resources/queries/study/TissueDistributionSummarybyAnimalIDFiscalYr.query.xml create mode 100644 onprc_ehr/resources/queries/study/TissueDistributionSummarybyAnimalIDFiscalYr.sql create mode 100644 onprc_ehr/resources/queries/study/TissueDistributionSummarybyAnimalIDFiscalYr/.qview.xml diff --git a/onprc_ehr/resources/queries/study/TissueDistributionSummaryCalendarYr.query.xml b/onprc_ehr/resources/queries/study/TissueDistributionSummaryCalendarYr.query.xml index a33c892f9..6208d338d 100644 --- a/onprc_ehr/resources/queries/study/TissueDistributionSummaryCalendarYr.query.xml +++ b/onprc_ehr/resources/queries/study/TissueDistributionSummaryCalendarYr.query.xml @@ -2,7 +2,7 @@ - Tissue Distribution Summary + Tissue Distribution Summary By Calendar Year Total Samples diff --git a/onprc_ehr/resources/queries/study/TissueDistributionSummarybyAnimalIDCalendarYr.query.xml b/onprc_ehr/resources/queries/study/TissueDistributionSummarybyAnimalIDCalendarYr.query.xml new file mode 100644 index 000000000..db599ded7 --- /dev/null +++ b/onprc_ehr/resources/queries/study/TissueDistributionSummarybyAnimalIDCalendarYr.query.xml @@ -0,0 +1,31 @@ + + + +
+ Tissue Distribution Summary By Animal ID Per Calendar Year + + + Total Samples + /query/executeQuery.view? + schemaName=study& + query.queryName=Tissue Distributions& + query.calendarYear~eq=${calendarYear}& + query.id~eq=${id}& + query.QCState/Label~in=Completed;Request: Pending& + + + + Distinct Animal IDs + /query/executeQuery.view? + schemaName=study& + query.queryName=Tissue Distributions& + query.calendarYear~eq=${calendarYear}& + query.id~eq=${id}& + query.QCState/Label~in=Completed;Request: Pending& + + + +
+
+
+ \ No newline at end of file diff --git a/onprc_ehr/resources/queries/study/TissueDistributionSummarybyAnimalIDCalendarYr.sql b/onprc_ehr/resources/queries/study/TissueDistributionSummarybyAnimalIDCalendarYr.sql new file mode 100644 index 000000000..e834b541b --- /dev/null +++ b/onprc_ehr/resources/queries/study/TissueDistributionSummarybyAnimalIDCalendarYr.sql @@ -0,0 +1,15 @@ +-- Added: 1-2-2018 R.Blasa +SELECT + calendarYear, + t.id, +-- t.recipient.affiliation, +-- t.requestCategory, + count(t.Id) as totalSamples, + count(distinct t.Id) as distinctAnimals, + count(distinct t.recipient) as distinctRecipients + +FROM study.tissueDistributions t +Where t.taskid is not null + And t.QCState.Label in ('Request: Pending','Completed') + +GROUP BY calendarYear, t.id \ No newline at end of file diff --git a/onprc_ehr/resources/queries/study/TissueDistributionSummarybyAnimalIDCalendarYr/.qview.xml b/onprc_ehr/resources/queries/study/TissueDistributionSummarybyAnimalIDCalendarYr/.qview.xml new file mode 100644 index 000000000..4f925f9e0 --- /dev/null +++ b/onprc_ehr/resources/queries/study/TissueDistributionSummarybyAnimalIDCalendarYr/.qview.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/onprc_ehr/resources/queries/study/TissueDistributionSummarybyAnimalIDFiscalYr.query.xml b/onprc_ehr/resources/queries/study/TissueDistributionSummarybyAnimalIDFiscalYr.query.xml new file mode 100644 index 000000000..fb0a59734 --- /dev/null +++ b/onprc_ehr/resources/queries/study/TissueDistributionSummarybyAnimalIDFiscalYr.query.xml @@ -0,0 +1,31 @@ + + + + + Tissue Distribution Summary By Animal ID Per Fiscal Year + + + Total Samples + /query/executeQuery.view? + schemaName=study& + query.queryName=Tissue Distributions& + query.fiscalYear~eq=${fiscalYear}& + query.id~eq=${id}& + query.QCState/Label~in=Completed;Request: Pending& + + + + Distinct Animal IDs + /query/executeQuery.view? + schemaName=study& + query.queryName=Tissue Distributions& + query.fiscalYear~eq=${fiscalYear}& + query.id~eq=${id}& + query.QCState/Label~in=Completed;Request: Pending& + + + +
+
+
+
\ No newline at end of file diff --git a/onprc_ehr/resources/queries/study/TissueDistributionSummarybyAnimalIDFiscalYr.sql b/onprc_ehr/resources/queries/study/TissueDistributionSummarybyAnimalIDFiscalYr.sql new file mode 100644 index 000000000..875e9381e --- /dev/null +++ b/onprc_ehr/resources/queries/study/TissueDistributionSummarybyAnimalIDFiscalYr.sql @@ -0,0 +1,13 @@ +-- Added: 1-2-2018 R.Blasa +SELECT + fiscalYear, + t.id, + count(t.Id) as totalSamples, + count(distinct t.Id) as distinctAnimals, + count(distinct t.recipient) as distinctRecipients + +FROM study.tissueDistributions t +Where t.taskid is not null + And t.QCState.Label in ('Request: Pending','Completed') + +GROUP BY fiscalYear, t.id \ No newline at end of file diff --git a/onprc_ehr/resources/queries/study/TissueDistributionSummarybyAnimalIDFiscalYr/.qview.xml b/onprc_ehr/resources/queries/study/TissueDistributionSummarybyAnimalIDFiscalYr/.qview.xml new file mode 100644 index 000000000..85a4caabd --- /dev/null +++ b/onprc_ehr/resources/queries/study/TissueDistributionSummarybyAnimalIDFiscalYr/.qview.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/onprc_ehr/resources/queries/study/TissueDistributionSummarybyRecipientCalendarYr.query.xml b/onprc_ehr/resources/queries/study/TissueDistributionSummarybyRecipientCalendarYr.query.xml index 518ec01a4..34ea7529c 100644 --- a/onprc_ehr/resources/queries/study/TissueDistributionSummarybyRecipientCalendarYr.query.xml +++ b/onprc_ehr/resources/queries/study/TissueDistributionSummarybyRecipientCalendarYr.query.xml @@ -2,7 +2,7 @@ - Tissue Distribution Summary By Recipient + Tissue Distribution Summary By Recipient By Calendar Year Total Samples diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/ONPRC_EHRModule.java b/onprc_ehr/src/org/labkey/onprc_ehr/ONPRC_EHRModule.java index a8164a775..ff4a4e16c 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/ONPRC_EHRModule.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/ONPRC_EHRModule.java @@ -498,7 +498,14 @@ public String toString() // Added 1-2-2018 R.Blasa EHRService.get().registerReportLink(EHRService.REPORT_LINK_TYPE.moreReports, "View Tissue Distribution Summary, By Recipient(Calendar Year)", this, DetailsURL.fromString("/query/executeQuery.view?schemaName=study&query.queryName=tissueDistributionSummaryByRecipientCalendarYr"), "Pathology"); - //Added: 12-7-2017 R.Blasa + // Added 1-7-2026 R.Blasa + EHRService.get().registerReportLink(EHRService.REPORT_LINK_TYPE.moreReports, "View Tissue Distribution Summary, By Animal ID(Calendar Year)", this, DetailsURL.fromString("/query/executeQuery.view?schemaName=study&query.queryName=tissueDistributionSummaryByAnimalIDCalendarYr"), "Pathology"); + + // Added 1-7-2026 R.Blasa + EHRService.get().registerReportLink(EHRService.REPORT_LINK_TYPE.moreReports, "View Tissue Distribution Summary, By Animal ID(Fiscal Year)", this, DetailsURL.fromString("/query/executeQuery.view?schemaName=study&query.queryName=tissueDistributionSummaryByAnimalIDFiscalYr"), "Pathology"); + + + //Added: 12-7-2017 R.Blasa // EHRService.get().registerReportLink(EHRService.REPORT_LINK_TYPE.moreReports, "Animal Census on a Given Date Range", this, DetailsURL.fromString("/onprc_ehr/CensusGivenDateRange.view"), "Colony Management"); // Added: 2-2-2021 R.Blasa From af38dcc6e0d71b584cd4864176649e983f39dbd1 Mon Sep 17 00:00:00 2001 From: Gary Jones Date: Mon, 12 Jan 2026 11:18:18 -0700 Subject: [PATCH 17/31] Update to ChargeRate.js and active view xml to have end time at the end of the day (#1599) --- .../resources/queries/onprc_billing/chargeRates.js | 10 +++++++++- .../onprc_billing/chargeRates/Active Rates.qview.xml | 2 +- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/onprc_billing/resources/queries/onprc_billing/chargeRates.js b/onprc_billing/resources/queries/onprc_billing/chargeRates.js index 3ee20ddab..0b8f87628 100644 --- a/onprc_billing/resources/queries/onprc_billing/chargeRates.js +++ b/onprc_billing/resources/queries/onprc_billing/chargeRates.js @@ -16,10 +16,18 @@ function beforeUpdate(row, errors){ function beforeUpsert(row, errors){ if (row.startDate){ + // normalize to date-only (00:00) row.startDate = ldkUtils.removeTimeFromDate(row.startDate); } if (row.endDate){ - row.endDate = ldkUtils.removeTimeFromDate(row.endDate); + // normalize to date-only first + var cleanDate = ldkUtils.removeTimeFromDate(row.endDate); + + // create a new date object set to 23:59 + var endOfDay = new Date(cleanDate); + endOfDay.setHours(23, 59, 0, 0); + + row.endDate = endOfDay; } } \ No newline at end of file diff --git a/onprc_billing/resources/queries/onprc_billing/chargeRates/Active Rates.qview.xml b/onprc_billing/resources/queries/onprc_billing/chargeRates/Active Rates.qview.xml index 4453d5cc3..6cba0006d 100644 --- a/onprc_billing/resources/queries/onprc_billing/chargeRates/Active Rates.qview.xml +++ b/onprc_billing/resources/queries/onprc_billing/chargeRates/Active Rates.qview.xml @@ -4,6 +4,6 @@ - + \ No newline at end of file From f192fc6957228092e78290145a98d9ff9a9f2117 Mon Sep 17 00:00:00 2001 From: Brent Logan Date: Tue, 13 Jan 2026 15:10:40 -0800 Subject: [PATCH 18/31] Fix source display in invoiced Items (#1603) * Update from Original Fix by Raymond for Source display in invoiced Items * Update to Allow Reversal to show transaction number in window instead of Object ID * Restore .qview.xml to original version --------- Co-authored-by: Gary Jones --- .../queries/onprc_billing/miscCharges.query.xml | 13 ++++++++++++- onprc_billing/resources/schemas/onprc_billing.xml | 9 +++++---- .../web/onprc_billing/window/ReverseChargeWindow.js | 2 +- 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/onprc_billing/resources/queries/onprc_billing/miscCharges.query.xml b/onprc_billing/resources/queries/onprc_billing/miscCharges.query.xml index 7b284cbb5..09f09c99f 100644 --- a/onprc_billing/resources/queries/onprc_billing/miscCharges.query.xml +++ b/onprc_billing/resources/queries/onprc_billing/miscCharges.query.xml @@ -16,7 +16,7 @@ core qcstate rowid - + Charge Unit @@ -27,6 +27,17 @@ + + Source Transaction + false + + /ONPRC/Admin/Finance + onprc_billing + invoicedItems + objectid + transactionNumber + + onprc_billing diff --git a/onprc_billing/resources/schemas/onprc_billing.xml b/onprc_billing/resources/schemas/onprc_billing.xml index 2bb09f73b..596aba084 100644 --- a/onprc_billing/resources/schemas/onprc_billing.xml +++ b/onprc_billing/resources/schemas/onprc_billing.xml @@ -419,10 +419,11 @@ Source Transaction true + /ONPRC/Admin/Finance onprc_billing invoicedItems objectid - rowid + transactionNumber @@ -1152,11 +1153,11 @@ OGA Grant Number - + Agency Award Number - + Investigator @@ -1641,4 +1642,4 @@
-
\ No newline at end of file + diff --git a/onprc_billing/resources/web/onprc_billing/window/ReverseChargeWindow.js b/onprc_billing/resources/web/onprc_billing/window/ReverseChargeWindow.js index fb7058865..5691d0a26 100644 --- a/onprc_billing/resources/web/onprc_billing/window/ReverseChargeWindow.js +++ b/onprc_billing/resources/web/onprc_billing/window/ReverseChargeWindow.js @@ -681,4 +681,4 @@ Ext4.define('ONPRC_Billing.window.ReverseChargeWindow', { } }); } -}); \ No newline at end of file +}); From 1c983e38530cec1c552881d5e818b2ff017c6819 Mon Sep 17 00:00:00 2001 From: Ohsudev <76500320+Ohsudev@users.noreply.github.com> Date: Thu, 15 Jan 2026 10:31:42 -0800 Subject: [PATCH 19/31] 25.7 fb training summary report (#1605) * Modified Compliance Training/Summary report to use the same report as Overdue/Soon report version. * Modified Compliance Training/Summary report to use the same report as Overdue/Soon report version. * Modified Compliance Training/Summary report to use the same report as Overdue/Soon report version. * Modified Compliance Employee detailed reports * Modified Compliance Employee detailed reports * Modified Compliance Employee detailed reports * Modified Compliance Employee detailed reports --- .../ComplianceProcedureRecentTests.query.xml | 19 +----- .../ComplianceRecentTests.query.xml | 20 +----- .../resources/views/employeeDetails.html | 15 +++++ .../resources/views/employeeDetails.view.xml | 8 +++ .../panel/EmployeeDetailsPanel.js | 64 +++++++++++++++++++ .../ONPRC_EHR_ComplianceDBModule.java | 3 +- 6 files changed, 91 insertions(+), 38 deletions(-) create mode 100644 ONPRC_EHR_ComplianceDB/resources/views/employeeDetails.html create mode 100644 ONPRC_EHR_ComplianceDB/resources/views/employeeDetails.view.xml create mode 100644 ONPRC_EHR_ComplianceDB/resources/web/EHR_ComplianceDB/panel/EmployeeDetailsPanel.js diff --git a/ONPRC_EHR_ComplianceDB/resources/queries/EHR_ComplianceDB/ComplianceProcedureRecentTests.query.xml b/ONPRC_EHR_ComplianceDB/resources/queries/EHR_ComplianceDB/ComplianceProcedureRecentTests.query.xml index 63925bc28..75260293e 100644 --- a/ONPRC_EHR_ComplianceDB/resources/queries/EHR_ComplianceDB/ComplianceProcedureRecentTests.query.xml +++ b/ONPRC_EHR_ComplianceDB/resources/queries/EHR_ComplianceDB/ComplianceProcedureRecentTests.query.xml @@ -19,7 +19,6 @@
Requirement Name - 250 ehr_compliancedb requirements @@ -29,7 +28,6 @@ Times Completed - 50 /query/executeQuery.view?schemaName=ehr_compliancedb& query.queryName=CompletionDates& query.EmployeeId~eq=${employeeId}& @@ -38,66 +36,52 @@ Expire Period (Months) - 70 New Expire Period (Months) - 70 Email - 70 Last Name - 110 First Name - 110 Host - 110 Supervisor - 150 Unit - 210 Most Recent Date yyyy-MM-dd - 70 Comments - 70 Category - 70 Trainee Type - 70 Requirement Name Type - 180 Months Until Renewal - 60 @@ -110,12 +94,11 @@ Essential - 60 ALWAYS_OFF Snooze Until - 60 + yyyy-MM-dd ALWAYS_OFF diff --git a/ONPRC_EHR_ComplianceDB/resources/queries/EHR_ComplianceDB/ComplianceRecentTests.query.xml b/ONPRC_EHR_ComplianceDB/resources/queries/EHR_ComplianceDB/ComplianceRecentTests.query.xml index d85eb7bac..6e634ad8b 100644 --- a/ONPRC_EHR_ComplianceDB/resources/queries/EHR_ComplianceDB/ComplianceRecentTests.query.xml +++ b/ONPRC_EHR_ComplianceDB/resources/queries/EHR_ComplianceDB/ComplianceRecentTests.query.xml @@ -19,7 +19,6 @@ Requirement Name - 90 ehr_compliancedb requirements @@ -29,7 +28,6 @@ Times Completed - 50 /query/executeQuery.view?schemaName=ehr_compliancedb& query.queryName=CompletionDates& query.EmployeeId~eq=${employeeId}& @@ -38,66 +36,51 @@ Expire Period (Months) - 70 New Expire Period (Months) - 70 Email - 70 - Last Name - 110 First Name - 110 Host - 110 Supervisor - 150 Unit - 210 Most Recent Date yyyy-MM-dd - 70 Comments - 70 Category - 70 Trainee Type - 70 Requirement Name Type - 180 Months Until Renewal - 60 @@ -110,12 +93,11 @@ Essential - 60 ALWAYS_OFF Snooze Until - 60 + yyyy-MM-dd ALWAYS_OFF diff --git a/ONPRC_EHR_ComplianceDB/resources/views/employeeDetails.html b/ONPRC_EHR_ComplianceDB/resources/views/employeeDetails.html new file mode 100644 index 000000000..d5de04cf2 --- /dev/null +++ b/ONPRC_EHR_ComplianceDB/resources/views/employeeDetails.html @@ -0,0 +1,15 @@ + \ No newline at end of file diff --git a/ONPRC_EHR_ComplianceDB/resources/views/employeeDetails.view.xml b/ONPRC_EHR_ComplianceDB/resources/views/employeeDetails.view.xml new file mode 100644 index 000000000..ab66d427b --- /dev/null +++ b/ONPRC_EHR_ComplianceDB/resources/views/employeeDetails.view.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/ONPRC_EHR_ComplianceDB/resources/web/EHR_ComplianceDB/panel/EmployeeDetailsPanel.js b/ONPRC_EHR_ComplianceDB/resources/web/EHR_ComplianceDB/panel/EmployeeDetailsPanel.js new file mode 100644 index 000000000..f0ae92228 --- /dev/null +++ b/ONPRC_EHR_ComplianceDB/resources/web/EHR_ComplianceDB/panel/EmployeeDetailsPanel.js @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2013-2019 LabKey Corporation + * + * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 + */ +/** + * @cfg employeeId + * @cfg schemaName + */ +Ext4.define('EHR_ComplianceDB.panel.EmployeeDetailsPanel', { + extend: 'Ext.panel.Panel', + schemaName: 'ehr_complianceDB', + + initComponent: function(){ + var filterArray = [LABKEY.Filter.create('employeeid', this.employeeId, LABKEY.Filter.Types.EQUAL)]; + + Ext4.apply(this, { + border: false, + defaults: { + border: false, + style: 'margin-bottom: 20px;' + }, + items: [{ + xtype: 'ldk-detailspanel', + store: { + schemaName: this.schemaName, + queryName: 'employees', + filterArray: filterArray + }, + showBackBtn: false, + title: 'Employee Details' + }, { + xtype: 'ldk-querypanel', + queryConfig: { + title: 'Training / Requirement Summary', + schemaName: this.schemaName, + queryName: 'ComplianceProcedureRecentTests', //exclude employee training exemptions + filterArray: filterArray, + failure: LDK.Utils.getErrorCallback() + } + },{ + xtype: 'ldk-querypanel', + queryConfig: { + title: 'Exemptions From Training Requirements', + schemaName: this.schemaName, + queryName: 'employeerequirementexemptions', + filterArray: filterArray, + failure: LDK.Utils.getErrorCallback() + } + },{ + xtype: 'ldk-querypanel', + queryConfig: { + title: 'Training History', + schemaName: this.schemaName, + queryName: 'completionDates', + filterArray: filterArray, + failure: LDK.Utils.getErrorCallback() + } + }] + }); + + this.callParent(); + } +}); \ No newline at end of file diff --git a/ONPRC_EHR_ComplianceDB/src/org/labkey/ONPRCEHR_ComplianceDB/ONPRC_EHR_ComplianceDBModule.java b/ONPRC_EHR_ComplianceDB/src/org/labkey/ONPRCEHR_ComplianceDB/ONPRC_EHR_ComplianceDBModule.java index ffa8320d2..4ee6b9e89 100644 --- a/ONPRC_EHR_ComplianceDB/src/org/labkey/ONPRCEHR_ComplianceDB/ONPRC_EHR_ComplianceDBModule.java +++ b/ONPRC_EHR_ComplianceDB/src/org/labkey/ONPRCEHR_ComplianceDB/ONPRC_EHR_ComplianceDBModule.java @@ -110,7 +110,8 @@ protected void doStartupAfterSpringConfig(ModuleContext moduleContext) // Added: 10-24-2022 R.Blasa EHRService.get().registerMoreActionsButton(new ShowEditUIButton(this, "ehr_compliancedb", "completiondates", ONPRC_ComplianceDBEntryPermission.class), "ehr_compliancedb", "completiondates"); - + // Added 1-8-2026 + EHRService.get().registerActionOverride("employeeDetails", this, "employeeDetails.html"); } From 395e85ca706f0523ec86b5f499311294b27dc0d2 Mon Sep 17 00:00:00 2001 From: Ohsudev <76500320+Ohsudev@users.noreply.github.com> Date: Wed, 21 Jan 2026 10:25:18 -0800 Subject: [PATCH 20/31] =?UTF-8?q?Created=20a=20new=20permission=20group=20?= =?UTF-8?q?for=20accessing=20the=20Clinical=20surgical=20Ro=E2=80=A6=20(#1?= =?UTF-8?q?607)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Created a new permission group for accessing the Clinical surgical Rounds input form. * Created a new permission group for accessing the Clinical surgical Rounds input form. --- .../onprc_ehr/dataentry/BloodDrawFormType.java | 15 +++++++++++++++ .../dataentry/ClinicalRoundsFormType.java | 8 -------- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/BloodDrawFormType.java b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/BloodDrawFormType.java index c73c835b1..edbe49d39 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/BloodDrawFormType.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/BloodDrawFormType.java @@ -25,6 +25,10 @@ import org.labkey.api.ehr.dataentry.WeightFormSection; import org.labkey.api.module.Module; import org.labkey.api.view.template.ClientDependency; +import org.labkey.security.xml.GroupEnumType; +import org.labkey.api.security.GroupManager; +import org.labkey.api.security.Group; +import org.labkey.api.security.permissions.AdminPermission; import java.util.Arrays; import java.util.List; @@ -69,4 +73,15 @@ public Supplier getAddScheduledTreatmentWindowDependency() { return ClientDependency.supplierFromPath("ehr/window/AddScheduledTreatmentWindow.js"); } + //Added: 1-15-2026 R.Blasa + @Override + public boolean isVisible() + { + Group g = GroupManager.getGroup(getCtx().getContainer(), "Form Clinical Rounds SF", GroupEnumType.SITE); + if (g != null && getCtx().getUser().isInGroup(g.getUserId()) && !getCtx().getContainer().hasPermission(getCtx().getUser(), AdminPermission.class)) + { + return false; + } + return super.isVisible(); + } } diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/ClinicalRoundsFormType.java b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/ClinicalRoundsFormType.java index b0040122c..ab5d20c96 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/ClinicalRoundsFormType.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/dataentry/ClinicalRoundsFormType.java @@ -77,12 +77,4 @@ public ClinicalRoundsFormType(DataEntryFormContext ctx, Module owner) } - @Override - protected boolean canInsert() - { - if (!getCtx().getContainer().hasPermission(getCtx().getUser(), EHRClinicalEntryPermission.class)) - return false; - - return super.canInsert(); - } } From 5c7c8bfbf4ab897a31fade58fb5e59c6b322c2ee Mon Sep 17 00:00:00 2001 From: Ohsudev <76500320+Ohsudev@users.noreply.github.com> Date: Wed, 21 Jan 2026 14:49:36 -0800 Subject: [PATCH 21/31] 25.7 fb parentage reports (#1601) * Modified Parentage report on both the Clinical Snapshot, and Parentage tab * Modified Parentage reporting on the Clinical Snapshot reports. * Modified Parentage reporting process. * Modified Parentage reports to include source of data. * Modified Offspring reporting to include surrogate mom. --- .../queries/study/parentageSummary.query.xml | 12 ++++++++++++ .../queries/study/parentageSummary.sql | 19 +++++++++++++------ .../queries/study/parentageSummary/.qview.xml | 13 +++++++++++++ .../Parentage With Dates.qview.xml | 14 ++++++++++++++ 4 files changed, 52 insertions(+), 6 deletions(-) create mode 100644 onprc_ehr/resources/queries/study/parentageSummary/.qview.xml create mode 100644 onprc_ehr/resources/queries/study/parentageSummary/Parentage With Dates.qview.xml diff --git a/onprc_ehr/resources/queries/study/parentageSummary.query.xml b/onprc_ehr/resources/queries/study/parentageSummary.query.xml index 1efefbcd2..8ebcede84 100644 --- a/onprc_ehr/resources/queries/study/parentageSummary.query.xml +++ b/onprc_ehr/resources/queries/study/parentageSummary.query.xml @@ -4,6 +4,12 @@ Parentage Summary + + Id + + + Date + Parent @@ -18,6 +24,12 @@ Method + + Comments + + + Data Source +
diff --git a/onprc_ehr/resources/queries/study/parentageSummary.sql b/onprc_ehr/resources/queries/study/parentageSummary.sql index d410bee51..a457c8a91 100644 --- a/onprc_ehr/resources/queries/study/parentageSummary.sql +++ b/onprc_ehr/resources/queries/study/parentageSummary.sql @@ -18,10 +18,14 @@ SELECT p.date, p.parent, p.relationship, - p.method + p.method, + p.remark, + 'Parentage' as source FROM study.parentage p WHERE p.qcstate.publicdata = true and p.enddate is null +And p.date in (select max(t.date) from study.parentage t where p.Id = t.Id And p.parent = t.parent +And p.relationship =t.relationship And p.method = t.method And t.enddate is null and p.enddate is null and t.qcstate.publicdata = true) UNION @@ -30,20 +34,23 @@ SELECT b.date, b.dam, 'Dam' as relationship, - 'Observed' as method + 'Observed' as method, + null as remark, + 'Birth' as source FROM study.birth b WHERE b.dam is not null and b.qcstate.publicdata = true -And 'dam' not in (select k.relationship from study.parentage k where k.Id = b.Id and k.enddate is null) + UNION SELECT a.Id, - a.date, + a.date, a.sire, 'Sire' as relationship, - 'Observed' as method + 'Observed' as method, + null as remark, + 'Birth' as source FROM study.birth a WHERE a.sire is not null and a.qcstate.publicdata = true - And 'sire' not in (select k.relationship from study.parentage k where k.Id = a.Id and k.enddate is null) \ No newline at end of file diff --git a/onprc_ehr/resources/queries/study/parentageSummary/.qview.xml b/onprc_ehr/resources/queries/study/parentageSummary/.qview.xml new file mode 100644 index 000000000..e5dbb867c --- /dev/null +++ b/onprc_ehr/resources/queries/study/parentageSummary/.qview.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/onprc_ehr/resources/queries/study/parentageSummary/Parentage With Dates.qview.xml b/onprc_ehr/resources/queries/study/parentageSummary/Parentage With Dates.qview.xml new file mode 100644 index 000000000..3393258cd --- /dev/null +++ b/onprc_ehr/resources/queries/study/parentageSummary/Parentage With Dates.qview.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file From d4ae1a092848fc56848939a41a13aa0e12131e08 Mon Sep 17 00:00:00 2001 From: Ohsudev <76500320+Ohsudev@users.noreply.github.com> Date: Wed, 21 Jan 2026 15:35:44 -0800 Subject: [PATCH 22/31] =?UTF-8?q?Created=20a=20new=20program=20to=20modify?= =?UTF-8?q?=20every=20active=20compliance=20requirement=20n=E2=80=A6=20(#1?= =?UTF-8?q?598)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Created a new program to modify every active compliance requirement names onto the new set of predefined name. * Created a new reporting program called "Tissue Distribution by AnimalID per Calendar". * Created a new reporting program called "Tissue Distribution by AnimalID per Calendar". * Created a new reporting program called "Tissue Distribution by AnimalID per Calendar". * Modified Compliance Requirement names to have the names translated to its new naming conversion. * Modified Complinace Requirement name program updates. --- .../sqlserver/onprc_ehr-25.003-25.004.sql | 141 ++++++++++++++++++ onprc_ehr/resources/schemas/onprc_ehr.xml | 9 ++ .../org/labkey/onprc_ehr/ONPRC_EHRModule.java | 2 +- 3 files changed, 151 insertions(+), 1 deletion(-) create mode 100644 onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-25.003-25.004.sql diff --git a/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-25.003-25.004.sql b/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-25.003-25.004.sql new file mode 100644 index 000000000..ac8027b7d --- /dev/null +++ b/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-25.003-25.004.sql @@ -0,0 +1,141 @@ + +CREATE TABLE onprc_ehr.RequirementName_Convert( + searchid integer IDENTITY(100,1) NOT NULL, + PreviousDesignation varchar(255) NULL, + afterName varchar(255) NULL, + FileName varchar(1000) NULL + ) ON [PRIMARY] + GO + + +/* +** +** Created by Date Comment +** +** +** Blasa 1/6/2026 Convert Compliance Requirement Names to its new predefined names. +*/ + + +CREATE Procedure onprc_ehr.sp_Compliance_requirementname_Update_Process + + + + +AS + +DECLARE + + @SearchKey Int, + @TempsearchKey Int, + @Code varchar(500) +Begin + + + + ---Initial Values + set @TempSearchkey = 0 + set @Searchkey = 0 + + + +select top 1 @Searchkey= searchid from onprc_ehr.requirementname_Convert +order by searchid + + +While @TempSearchKey < @SearchKey +BEGIN + +select top 1 @Code=PreviousDesignation from onprc_ehr.requirementname_Convert + Where searchid = @Searchkey + + If @@Error <> 0 + GoTo Err_Proc + + ------Process Requirement Names + +Update ss +set ss.RequirementName = '' + trim(jj.aftername) + ' ' + trim(jj.filename) + '' + + from ehr_Compliancedb.Requirements ss, onprc_ehr.requirementname_Convert jj where ss.RequirementName like '' + trim(@code) + '%' + And jj.PreviousDesignation like '' + trim(@code) + '%' + + If @@Error <> 0 + GoTo Err_Proc + +------Process Completion Dates + +Update ss +set ss.RequirementName = '' + trim(jj.aftername) + ' ' + trim(jj.filename) + '' + + from ehr_Compliancedb.CompletionDates ss, onprc_ehr.requirementname_Convert jj where ss.RequirementName like '' + trim(@code) + '%' + And jj.PreviousDesignation like '' + trim(@code) + '%' + + If @@Error <> 0 + GoTo Err_Proc + +------Process Requirements per Employees + +Update ss +set ss.RequirementName = '' + trim(jj.aftername) + ' ' + trim(jj.filename) + '' + + from ehr_Compliancedb.RequirementsPerEmployee ss, onprc_ehr.requirementname_Convert jj where ss.RequirementName like '' + trim(@code) + '%' + And jj.PreviousDesignation like '' + trim(@code) + '%' + + If @@Error <> 0 + GoTo Err_Proc + +-----Process Requirements per Categories + +Update ss +set ss.RequirementName = '' + trim(jj.aftername) + ' ' + trim(jj.filename) + '' + + from ehr_Compliancedb.RequirementsPerCategory ss, onprc_ehr.requirementname_Convert jj where ss.RequirementName like '' + trim(@code) + '%' + And jj.PreviousDesignation like '' + trim(@code) + '%' + + If @@Error <> 0 + GoTo Err_Proc + +-----Process Employee Requirements Exemptions + +Update ss +set ss.RequirementName = '' + trim(jj.aftername) + ' ' + trim(jj.filename) + '' + + from ehr_Compliancedb.EmployeeRequirementExemptions ss, onprc_ehr.requirementname_Convert jj where ss.RequirementName like '' + trim(@code) + '%' + And jj.PreviousDesignation like '' + trim(@code) + '%' + + If @@Error <> 0 + GoTo Err_Proc + + +----- Process the next data record + +Set @TempSearchkey = @SearchKey + + +select top 1 @Searchkey= searchid from onprc_ehr.requirementname_Convert +Where searchid > @TempSearchkey +order by searchid + + If @@Error <> 0 + GoTo Err_Proc + + +END ---(While) + + + +RETURN 0 + + + Err_Proc: + + + RETURN 1 + + +END + +GO + + diff --git a/onprc_ehr/resources/schemas/onprc_ehr.xml b/onprc_ehr/resources/schemas/onprc_ehr.xml index 875814163..298c65edc 100644 --- a/onprc_ehr/resources/schemas/onprc_ehr.xml +++ b/onprc_ehr/resources/schemas/onprc_ehr.xml @@ -1471,4 +1471,13 @@ + + + + + + + +
+ diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/ONPRC_EHRModule.java b/onprc_ehr/src/org/labkey/onprc_ehr/ONPRC_EHRModule.java index ff4a4e16c..d18c157d4 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/ONPRC_EHRModule.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/ONPRC_EHRModule.java @@ -124,7 +124,7 @@ public String getName() @Override public @Nullable Double getSchemaVersion() { - return 25.003; + return 25.004; } @Override From d7683824d4aca17d77fa5fd62b4333dc781f729f Mon Sep 17 00:00:00 2001 From: Ohsudev <76500320+Ohsudev@users.noreply.github.com> Date: Wed, 21 Jan 2026 17:55:46 -0800 Subject: [PATCH 23/31] Modified Offspring reporting to include surrogate mom. (#1612) * Modified Offspring reporting to include surrogate mom. * Modified Offspring reporting to include surrogate mom. --- .../study/demographicsOffspringBSU.query.xml | 8 ++++++ .../study/demographicsOffspringBSU.sql | 3 +- .../study/demographicsOffspringBSU/.qview.xml | 1 + .../study/demographicsParents/.qview.xml | 1 + .../study/demographicsParentsBSU.query.xml | 8 ++++++ .../queries/study/demographicsParentsBSU.sql | 28 +++++++++++++++---- 6 files changed, 43 insertions(+), 6 deletions(-) diff --git a/onprc_ehr/resources/queries/study/demographicsOffspringBSU.query.xml b/onprc_ehr/resources/queries/study/demographicsOffspringBSU.query.xml index 7404ad7f6..cb64f6f1d 100644 --- a/onprc_ehr/resources/queries/study/demographicsOffspringBSU.query.xml +++ b/onprc_ehr/resources/queries/study/demographicsOffspringBSU.query.xml @@ -43,6 +43,14 @@ Foster Dam + + Surrogate Dam + + study + animal + id + + Sire diff --git a/onprc_ehr/resources/queries/study/demographicsOffspringBSU.sql b/onprc_ehr/resources/queries/study/demographicsOffspringBSU.sql index 26a72138b..47fe27b8d 100644 --- a/onprc_ehr/resources/queries/study/demographicsOffspringBSU.sql +++ b/onprc_ehr/resources/queries/study/demographicsOffspringBSU.sql @@ -17,6 +17,7 @@ d2.status, d2.geneticdam, d2.observeddam, d2.fosterMom, +d2.surrogateMom, d2.sire, d2.sireType, d.qcstate @@ -25,7 +26,7 @@ FROM study.Demographics d INNER JOIN study.demographicsParentsBSU d2 - ON ((d2.sire = d.id OR d2.geneticdam = d.id OR d2.fostermom = d.id OR d2.observeddam = d.id) AND d.id != d2.id) + ON ((d2.sire = d.id OR d2.geneticdam = d.id OR d2.fosterMom = d.id OR d2.observeddam = d.id) AND d.id != d2.id) diff --git a/onprc_ehr/resources/queries/study/demographicsOffspringBSU/.qview.xml b/onprc_ehr/resources/queries/study/demographicsOffspringBSU/.qview.xml index 4a4679a82..fd9958bee 100644 --- a/onprc_ehr/resources/queries/study/demographicsOffspringBSU/.qview.xml +++ b/onprc_ehr/resources/queries/study/demographicsOffspringBSU/.qview.xml @@ -15,6 +15,7 @@ + diff --git a/onprc_ehr/resources/queries/study/demographicsParents/.qview.xml b/onprc_ehr/resources/queries/study/demographicsParents/.qview.xml index 2ab5905b4..01e76b9af 100644 --- a/onprc_ehr/resources/queries/study/demographicsParents/.qview.xml +++ b/onprc_ehr/resources/queries/study/demographicsParents/.qview.xml @@ -6,6 +6,7 @@ + diff --git a/onprc_ehr/resources/queries/study/demographicsParentsBSU.query.xml b/onprc_ehr/resources/queries/study/demographicsParentsBSU.query.xml index 5790dc400..e947589e1 100644 --- a/onprc_ehr/resources/queries/study/demographicsParentsBSU.query.xml +++ b/onprc_ehr/resources/queries/study/demographicsParentsBSU.query.xml @@ -48,6 +48,14 @@ id + + Surrogate Dam + + study + animal + id + + Number of Parents Known diff --git a/onprc_ehr/resources/queries/study/demographicsParentsBSU.sql b/onprc_ehr/resources/queries/study/demographicsParentsBSU.sql index 76f64855f..66657396f 100644 --- a/onprc_ehr/resources/queries/study/demographicsParentsBSU.sql +++ b/onprc_ehr/resources/queries/study/demographicsParentsBSU.sql @@ -39,12 +39,23 @@ SELECT ELSE null END as sireType, - p3.parent as fosterMom, - p3.method as fosterType, - (CASE WHEN p3.parent IS NOT NULL THEN 1 ELSE 0 END + - CASE WHEN coalesce(p2.parent, b.dam) IS NOT NULL THEN 1 ELSE 0 END + - CASE WHEN coalesce(p1.parent, b.sire) IS NOT NULL THEN 1 ELSE 0 END) as numParents + coalesce(p3.parent, '') as fosterMom, + CASE + WHEN p3.parent IS NOT NULL THEN p3.method + ELSE null + END as fosterType, + + coalesce(p4.parent, '') as surrogateMom, + CASE + WHEN p4.parent IS NOT NULL THEN p4.method + ELSE null + END as surrogateType, + + (CASE WHEN p4.parent IS NOT NULL THEN 1 ELSE 0 END + + CASE WHEN p3.parent IS NOT NULL THEN 1 ELSE 0 END + + CASE WHEN coalesce(p2.parent, b.dam) IS NOT NULL THEN 1 ELSE 0 END + + CASE WHEN coalesce(p1.parent, b.sire) IS NOT NULL THEN 1 ELSE 0 END) as numParents FROM study.demographics d @@ -68,5 +79,12 @@ LEFT JOIN ( WHERE p3.relationship = 'Foster Dam' AND p3.enddate IS NULL GROUP BY p3.Id ) p3 ON (d.Id = p3.id) + +LEFT JOIN ( + select p4.id, min(p4.method) as method, max(p4.parent) as parent + FROM study.parentage p4 + WHERE p4.relationship = 'Surrogate Dam' AND p4.enddate IS NULL + GROUP BY p4.Id +) p4 ON (d.Id = p4.id) LEFT JOIN study.birth b ON (b.id = d.id) From e7f7893fc648e7dc1ee9d38d80d0e7a7fe5af1ad Mon Sep 17 00:00:00 2001 From: Ohsudev <76500320+Ohsudev@users.noreply.github.com> Date: Thu, 22 Jan 2026 16:18:30 -0800 Subject: [PATCH 24/31] Modified Compliance reports to remove subquery results errors. (#1617) --- .../onprc_ehr_compliancedb-25.000-25.001.sql | 579 ++++++++++++++++++ .../ONPRC_EHR_ComplianceDBModule.java | 2 +- 2 files changed, 580 insertions(+), 1 deletion(-) create mode 100644 ONPRC_EHR_ComplianceDB/resources/schemas/dbscripts/sqlserver/onprc_ehr_compliancedb-25.000-25.001.sql diff --git a/ONPRC_EHR_ComplianceDB/resources/schemas/dbscripts/sqlserver/onprc_ehr_compliancedb-25.000-25.001.sql b/ONPRC_EHR_ComplianceDB/resources/schemas/dbscripts/sqlserver/onprc_ehr_compliancedb-25.000-25.001.sql new file mode 100644 index 000000000..c64d1ffad --- /dev/null +++ b/ONPRC_EHR_ComplianceDB/resources/schemas/dbscripts/sqlserver/onprc_ehr_compliancedb-25.000-25.001.sql @@ -0,0 +1,579 @@ +ALTER TABLE onprc_ehr_compliancedb.ComplianceProcedureReport ALTER COLUMN expired_period varchar(50) NULL; +GO + +ALTER TABLE onprc_ehr_compliancedb.ComplianceProcedureReport ALTER COLUMN new_expired_period varchar(50) NULL; +GO + +ALTER TABLE onprc_ehr_compliancedb.ComplianceRecentReport ALTER COLUMN expired_period varchar(50) NULL; +GO + +ALTER TABLE onprc_ehr_compliancedb.ComplianceRecentReport ALTER COLUMN new_expired_period varchar(50) NULL; +GO + + + +EXEC core.fn_dropifexists 'p_ComplianceProcedureOverDueSoon_Process', 'onprc_ehr_compliancedb', 'PROCEDURE'; +GO + +-- Author: R. Blasa +-- Created: 9-20-2024 + +/* +** +** Created by +** Blasa 9-20-2024 Created a storedprocedure to create a static set of data from +** the ComplianceProcedureRecentTest.sql query +** +** 1-22-2026 Fix the issues with more than one subquery results +** +** +** +*/ + +CREATE Procedure onprc_ehr_compliancedb.p_ComplianceProcedureOverDueSoon_Process + + +AS + + + ----- Reset Reporting table + Delete onprc_ehr_compliancedb.ComplianceProcedureReport + + If @@Error <> 0 + GoTo Err_Proc + + + +BEGIN + + Insert into onprc_ehr_compliancedb.ComplianceProcedureReport + ( + requirementname, + employeeid, + unit, + category, + trackingflag, + email, + lastname, + firstname, + host, + supervisor, + trainee_type, + requirement_name_type, + times_completed, + expired_period, + new_expired_Period, + mostrecentcompleted_date, + comment, + snooze_date, + months_until_renewal + + ) + + + + + + select b.requirementname, + a.employeeid, + string_agg(a.unit,char(10)) as unit, + string_agg(a.category,char(10)) as category, + string_agg(b.trackingflag,char(10)) as trackingflag, + (select h.email from ehr_compliancedb.employees h where h.employeeid = a.employeeid) as email, + (select h.lastname from ehr_compliancedb.employees h where h.employeeid = a.employeeid) as lastname, + (select h.firstname from ehr_compliancedb.employees h where h.employeeid = a.employeeid) as firstname, + (select h.majorudds from ehr_compliancedb.employees h where h.employeeid = a.employeeid) as host, + (select h.supervisor from ehr_compliancedb.employees h where h.employeeid = a.employeeid) as supervisor, + (select h.type from ehr_compliancedb.employees h where h.employeeid = a.employeeid) as trainee_type, ----- type trainee, or trainer + (select string_agg(h.type,char(10)) from ehr_compliancedb.Requirements h where h.requirementname = b.requirementname) as requirement_type, + + (select count(zz.date) from ehr_compliancedb.completiondates zz where zz.requirementname= b.requirementname and zz.employeeid= a.employeeid ) as times_Completed, + + (select string_agg(k.expireperiod,char(10)) from ehr_compliancedb.Requirements k where k.requirementname = b.requirementname) as ExpiredPeriod, + + ( select (datediff(month,max(pq.date), tt.reviewdate) ) from ehr_compliancedb.requirements tt, ehr_compliancedb.completiondates pq where tt.requirementname = b.requirementname and pq.requirementname = tt.requirementname and pq.employeeid = a.employeeid group by tt.expireperiod, tt.reviewdate + having (COALESCE(tt.expireperiod,0)) > (datediff(month,max(pq.date), tt.reviewdate)) and (tt.reviewdate is not null) ) as NewExpirePeriod, + + (select max(zz.date) from ehr_compliancedb.completiondates zz where zz.requirementname= b.requirementname and zz.employeeid= a.employeeid ) as mostrecentcompleted_date, + + (Select distinct string_agg(yy.comment, char(10)) from ehr_compliancedb.completiondates yy where yy.date in (select max(zz.date) from ehr_compliancedb.completiondates zz where zz.requirementname= b.requirementname and zz.employeeid= a.employeeid ) + And yy.requirementname= b.requirementname and yy.employeeid= a.employeeid ) as comment, + + (Select distinct string_agg(yy.snooze_date, char(10)) from ehr_compliancedb.completiondates yy where yy.date in (select max(zz.date) from ehr_compliancedb.completiondates zz where zz.requirementname= b.requirementname and zz.employeeid= a.employeeid ) + And yy.requirementname= b.requirementname and yy.employeeid= a.employeeid ) as snooze_date, + + CAST( + CASE + + WHEN (select max(st.date) from ehr_compliancedb.completiondates st where st.requirementname = b.requirementname and st.employeeid = a.employeeid ) IS NULL then 0 + WHEN ( select (COALESCE(tt.expireperiod,0)) from ehr_compliancedb.requirements tt where tt.requirementname = b.requirementname group by tt.expireperiod ) = 0 then Null + + + WHEN ( select count(*) from ehr_compliancedb.requirements tt, ehr_compliancedb.completiondates pq where tt.requirementname = b.requirementname and pq.requirementname = tt.requirementname and pq.employeeid = a.employeeid group by tt.expireperiod, tt.reviewdate + having (tt.reviewdate) > (max(pq.date)) ) > 0 THEN + + ( select (datediff(month,max(pq.date), tt.reviewdate) - ( datediff(month,max(pq.date), getdate()) ) )from ehr_compliancedb.requirements tt, ehr_compliancedb.completiondates pq where tt.requirementname = b.requirementname and pq.requirementname = tt.requirementname and pq.employeeid = a.employeeid group by tt.expireperiod, tt.reviewdate + having (tt.reviewdate) > (max(pq.date)) ) + + + ELSE ( select (COALESCE(tt.expireperiod,0)) - ( datediff(month,max(pq.date), getdate()) ) from ehr_compliancedb.requirements tt, ehr_compliancedb.completiondates pq where tt.requirementname = b.requirementname and pq.requirementname = tt.requirementname and pq.employeeid = a.employeeid group by tt.expireperiod ) + + END AS Float) AS MonthsUntilRenewal + + + + from ehr_Compliancedb.employeeperunit a ,ehr_compliancedb.requirementspercategory b + where ( a.unit = b.unit or a.category = b.category ) + And b.requirementname not in (select distinct t.requirementname from ehr_compliancedb.employeerequirementexemptions t Where a.employeeid = t.employeeid + And b.requirementname = t.requirementname) + And a.employeeid in (select p.employeeid from ehr_compliancedb.employees p where a.employeeid = p.employeeid And p.enddate is null) + And b.requirementname in (select q.requirementname from ehr_compliancedb.Requirements q where q.requirementname = b.requirementname And q.dateDisabled is null ) + + + group by b.requirementname,a.employeeid + + union + + select a.requirementname, + a.employeeid, + null as unit, + null as category, + 'None' as trackingflag, + (select h.email from ehr_compliancedb.employees h where h.employeeid = a.employeeid) as email, + (select h.lastname from ehr_compliancedb.employees h where h.employeeid = a.employeeid) as lastname, + (select h.firstname from ehr_compliancedb.employees h where h.employeeid = a.employeeid) as firstname, + (select h.majorudds from ehr_compliancedb.employees h where h.employeeid = a.employeeid) as host, + (select h.supervisor from ehr_compliancedb.employees h where h.employeeid = a.employeeid) as supervisor, + (select h.type from ehr_compliancedb.employees h where h.employeeid = a.employeeid) as trainee_type, ----- type trainee, or trainer + (select string_agg(h.type,char(10))from ehr_compliancedb.Requirements h where h.requirementname = a.requirementname) as requirement_type, ----- type trainee, or trainer + + + (select count(zz.date) from ehr_compliancedb.completiondates zz where zz.requirementname= a.requirementname and zz.employeeid= a.employeeid ) as timesCompleted, + + (select string_agg(k.expireperiod,char(10)) from ehr_compliancedb.Requirements k where k.requirementname = a.requirementname) as ExpiredPeriod, + + ( select (datediff(month,max(pq.date), tt.reviewdate) )from ehr_compliancedb.requirements tt, ehr_compliancedb.completiondates pq where tt.requirementname = a.requirementname and pq.requirementname = tt.requirementname and pq.employeeid = a.employeeid group by tt.expireperiod, tt.reviewdate + having (COALESCE(tt.expireperiod,0)) > (datediff(month,max(pq.date), tt.reviewdate)) and (tt.reviewdate is not null) ) as NewExpirePeriod, + + (select max(zz.date) from ehr_compliancedb.completiondates zz where zz.requirementname= a.requirementname and zz.employeeid= a.employeeid ) as MostRecentDate, + + (Select distinct string_agg(yy.comment, char(10)) from ehr_compliancedb.completiondates yy where yy.date in (select max(zz.date) from ehr_compliancedb.completiondates zz where zz.requirementname= a.requirementname and zz.employeeid= a.employeeid ) + And yy.requirementname= a.requirementname and yy.employeeid= a.employeeid ) as comment, + + (Select distinct string_agg(yy.snooze_date, char(10)) from ehr_compliancedb.completiondates yy where yy.date in (select max(zz.date) from ehr_compliancedb.completiondates zz where zz.requirementname= a.requirementname and zz.employeeid= a.employeeid ) + And yy.requirementname= a.requirementname and yy.employeeid= a.employeeid ) as snooze_date, + + CAST( + CASE + WHEN (select max(st.date) from ehr_compliancedb.completiondates st where st.requirementname = a.requirementname and st.employeeid = a.employeeid ) IS NULL then 0 + WHEN ( select (COALESCE(tt.expireperiod,0)) from ehr_compliancedb.requirements tt where tt.requirementname = a.requirementname group by tt.expireperiod ) = 0 then Null + + + WHEN ( select count(*) from ehr_compliancedb.requirements tt, ehr_compliancedb.completiondates pq where tt.requirementname = a.requirementname and pq.requirementname = tt.requirementname and pq.employeeid = a.employeeid group by tt.expireperiod, tt.reviewdate + having (tt.reviewdate) > (max(pq.date)) ) > 0 THEN + + ( select (datediff(month,max(pq.date), tt.reviewdate) - ( datediff(month,max(pq.date), getdate())) ) from ehr_compliancedb.requirements tt, ehr_compliancedb.completiondates pq where tt.requirementname = a.requirementname and pq.requirementname = tt.requirementname and pq.employeeid = a.employeeid group by tt.expireperiod, tt.reviewdate + having (tt.reviewdate) > (max(pq.date)) ) + + + ELSE ( select (COALESCE(tt.expireperiod,0)) - ( datediff(month,max(pq.date), getdate())) from ehr_compliancedb.requirements tt, ehr_compliancedb.completiondates pq where tt.requirementname = a.requirementname and pq.requirementname = tt.requirementname and pq.employeeid = a.employeeid group by tt.expireperiod ) + + END AS FLOAT) AS MonthsUntilRenewal + + + from ehr_compliancedb.completiondates a + where a.requirementname not in (select distinct h.requirementname from ehr_compliancedb.employeeperunit k, ehr_compliancedb.requirementspercategory h Where (k.unit = h.unit + or k.category = h.category) And a.employeeid = k.employeeid ) + And a.requirementname not in (select distinct t.requirementname from ehr_compliancedb.employeerequirementexemptions t Where a.employeeid = t.employeeid + And a.requirementname = t.requirementname) + And a.employeeid in (select p.employeeid from ehr_compliancedb.employees p where a.employeeid = p.employeeid And p.enddate is null) + And a.requirementname in (select q.requirementname from ehr_compliancedb.Requirements q where q.requirementname = a.requirementname And q.dateDisabled is null ) + + group by a.requirementname,a.employeeid + + union + + -- Additional requirements for employees that have not completed training, but is required + select j.requirementname, + j.employeeid, + null as unit, + null as category, + string_agg(j.trackingflag,char(10)) as trackingflag, + (select h.email from ehr_compliancedb.employees h where h.employeeid = j.employeeid) as email, + (select h.lastname from ehr_compliancedb.employees h where h.employeeid = j.employeeid) as lastname, + (select h.firstname from ehr_compliancedb.employees h where h.employeeid = j.employeeid) as firstname, + (select h.majorudds from ehr_compliancedb.employees h where h.employeeid = j.employeeid) as host, + (select h.supervisor from ehr_compliancedb.employees h where h.employeeid = j.employeeid) as supervisor, + (select h.type from ehr_compliancedb.employees h where h.employeeid = j.employeeid) as trainee_type, ----- type trainee, or trainer + (select string_agg(h.type,char(10)) from ehr_compliancedb.Requirements h where h.requirementname = j.requirementname) as requirement_type, ----- type trainee, or trainer + 0 as timesCompleted, + (select string_agg(k.expireperiod,char(10)) from ehr_compliancedb.Requirements k where k.requirementname = j.requirementname) as ExpiredPeriod, + ( select (datediff(month,max(pq.date), tt.reviewdate) )from ehr_compliancedb.requirements tt, ehr_compliancedb.completiondates pq where tt.requirementname = j.requirementname and pq.requirementname = tt.requirementname and pq.employeeid = j.employeeid group by tt.expireperiod, tt.reviewdate + having (COALESCE(tt.expireperiod,0)) > (datediff(month,max(pq.date), tt.reviewdate)) and (tt.reviewdate is not null) ) as NewExpirePeriod, + null as MostRecentDate, + '' as comment, + null as snooze_date, + CAST( + CASE + + WHEN (select max(st.date) from ehr_compliancedb.completiondates st where st.requirementname = j.requirementname and st.employeeid = j.employeeid ) IS NULL then 0 + WHEN ( select (COALESCE(tt.expireperiod,0)) from ehr_compliancedb.requirements tt where tt.requirementname = j.requirementname group by tt.expireperiod ) = 0 then Null + + + WHEN ( select count(*) from ehr_compliancedb.requirements tt, ehr_compliancedb.completiondates pq where tt.requirementname = j.requirementname and pq.requirementname = tt.requirementname and pq.employeeid = j.employeeid group by tt.expireperiod, tt.reviewdate + having (tt.reviewdate) > (max(pq.date)) ) > 0 THEN + + ( select (datediff(month,max(pq.date), tt.reviewdate) - ( datediff(month,max(pq.date), getdate())) ) from ehr_compliancedb.requirements tt, ehr_compliancedb.completiondates pq where tt.requirementname = j.requirementname and pq.requirementname = tt.requirementname and pq.employeeid = j.employeeid group by tt.expireperiod, tt.reviewdate + having (tt.reviewdate) > (max(pq.date)) ) + + + ELSE ( select (COALESCE(tt.expireperiod,0)) - ( datediff(month,max(pq.date), getdate())) from ehr_compliancedb.requirements tt, ehr_compliancedb.completiondates pq where tt.requirementname = j.requirementname and pq.requirementname = tt.requirementname and pq.employeeid = j.employeeid group by tt.expireperiod ) + + END AS FLOAT) AS MonthsUntilRenewal + + + + from onprc_ehr_compliancedb.RequirementsPerEmployee j + Where j.employeeid in (select p.employeeid from ehr_compliancedb.employees p where j.employeeid = p.employeeid And p.enddate is null) + And j.requirementname in (select q.requirementname from ehr_compliancedb.Requirements q where q.requirementname = j.requirementname And q.dateDisabled is null ) + And j.requirementname not in (select distinct h.requirementname from ehr_compliancedb.employeeperunit k, ehr_compliancedb.requirementspercategory h Where (k.unit = h.unit + or k.category = h.category) And j.employeeid = k.employeeid ) + And j.requirementname not in (select distinct t.requirementname from ehr_compliancedb.employeerequirementexemptions t Where j.employeeid = t.employeeid And j.requirementname = t.requirementname) + And j.requirementname not in (select distinct k.requirementname from ehr_compliancedb.completiondates k Where k.employeeid = j.employeeid) + + group by j.requirementname,j.employeeid + + order by employeeid,requirementname, mostrecentcompleted_date desc + + + If @@Error <> 0 + GoTo Err_Proc + + + + + RETURN 0 + + +Err_Proc: + + RETURN 1 + + +END + +GO + + + + +EXEC core.fn_dropifexists 'p_ComplianceRecentOverDueSoon_Process', 'onprc_ehr_compliancedb', 'PROCEDURE'; +GO + +-- Author: R. Blasa +-- Created: 9-20-2024 + +/* +** +** Created by +** Blasa 9-20-2024 Created a storedprocedure to create a static set of data from +** the ComplianceRecentTest.sql query +** +** 1-22-2026 Fix the issues with more than one subquery results +** +** +*/ + +CREATE Procedure onprc_ehr_compliancedb.p_ComplianceRecentOverDueSoon_Process + + + AS + + + +----- Reset Reporting table +Delete onprc_ehr_compliancedb.ComplianceRecentReport + + If @@Error <> 0 + GoTo Err_Proc + + + +BEGIN + +Insert into onprc_ehr_compliancedb.ComplianceRecentReport +( + requirementname, + employeeid, + unit, + category, + trackingflag, + email, + lastname, + firstname, + host, + supervisor, + trainee_type, + requirement_name_type, + times_completed, + expired_period, + new_expired_Period, + mostrecentcompleted_date, + comment, + snooze_date, + months_until_renewal + +) + + + + +select b.requirementname, + a.employeeid, + string_agg(a.unit,char(10)) as unit, + string_agg(a.category,char(10)) as category, + string_agg(b.trackingflag,char(10)) as trackingflag, + (select h.email from ehr_compliancedb.employees h where h.employeeid = a.employeeid) as email, + (select h.lastname from ehr_compliancedb.employees h where h.employeeid = a.employeeid) as lastname, + (select h.firstname from ehr_compliancedb.employees h where h.employeeid = a.employeeid) as firstname, + (select h.majorudds from ehr_compliancedb.employees h where h.employeeid = a.employeeid) as host, + (select h.supervisor from ehr_compliancedb.employees h where h.employeeid = a.employeeid) as supervisor, + (select h.type from ehr_compliancedb.employees h where h.employeeid = a.employeeid) as trainee_type, ----- type trainee, or trainer + (select string_agg(h.type,char(10)) from ehr_compliancedb.Requirements h where h.requirementname = b.requirementname) as requirement_type, ----- type trainee, or trainer + + + (select count(zz.date) from ehr_compliancedb.completiondates zz where zz.requirementname= b.requirementname and zz.employeeid= a.employeeid ) as times_Completed, + + (select string_agg(k.expireperiod,char(10)) from ehr_compliancedb.Requirements k where k.requirementname = b.requirementname) as ExpiredPeriod, + + ( select (datediff(month,max(pq.date), tt.reviewdate) ) from ehr_compliancedb.requirements tt, ehr_compliancedb.completiondates pq where tt.requirementname = b.requirementname and pq.requirementname = tt.requirementname and pq.employeeid = a.employeeid group by tt.expireperiod, tt.reviewdate + having (COALESCE(tt.expireperiod,0)) > (datediff(month,max(pq.date), tt.reviewdate)) and (tt.reviewdate is not null) ) as NewExpirePeriod, + + (select max(zz.date) from ehr_compliancedb.completiondates zz where zz.requirementname= b.requirementname and zz.employeeid= a.employeeid ) as mostrecentcompleted_date, + + (Select distinct string_agg(yy.comment, char(10)) from ehr_compliancedb.completiondates yy where yy.date in (select max(zz.date) from ehr_compliancedb.completiondates zz where zz.requirementname= b.requirementname and zz.employeeid= a.employeeid ) + And yy.requirementname= b.requirementname and yy.employeeid= a.employeeid ) as comment, + + (Select distinct string_agg(yy.snooze_date, char(10)) from ehr_compliancedb.completiondates yy where yy.date in (select max(zz.date) from ehr_compliancedb.completiondates zz where zz.requirementname= b.requirementname and zz.employeeid= a.employeeid ) + And yy.requirementname= b.requirementname and yy.employeeid= a.employeeid ) as snooze_date, + + CAST( + CASE + + WHEN (select max(st.date) from ehr_compliancedb.completiondates st where st.requirementname = b.requirementname and st.employeeid = a.employeeid ) IS NULL then 0 + WHEN ( select (COALESCE(tt.expireperiod,0)) from ehr_compliancedb.requirements tt where tt.requirementname = b.requirementname group by tt.expireperiod ) = 0 then Null + + + WHEN ( select count(*) from ehr_compliancedb.requirements tt, ehr_compliancedb.completiondates pq where tt.requirementname = b.requirementname and pq.requirementname = tt.requirementname and pq.employeeid = a.employeeid group by tt.expireperiod, tt.reviewdate + having (tt.reviewdate) > (max(pq.date)) ) > 0 THEN + + ( select (datediff(month,max(pq.date), tt.reviewdate) - ( datediff(month,max(pq.date), getdate())) ) from ehr_compliancedb.requirements tt, ehr_compliancedb.completiondates pq where tt.requirementname = b.requirementname and pq.requirementname = tt.requirementname and pq.employeeid = a.employeeid group by tt.expireperiod, tt.reviewdate + having (tt.reviewdate) > (max(pq.date)) ) + + + + + ELSE ( select (COALESCE(tt.expireperiod,0)) - ( datediff(month,max(pq.date), getdate())) from ehr_compliancedb.requirements tt, ehr_compliancedb.completiondates pq where tt.requirementname = b.requirementname and pq.requirementname = tt.requirementname and pq.employeeid = a.employeeid group by tt.expireperiod ) + + END AS FLOAT) AS MonthsUntilRenewal + + + +from ehr_Compliancedb.employeeperunit a ,ehr_compliancedb.requirementspercategory b +where ( a.unit = b.unit or a.category = b.category ) + And b.requirementname not in (select distinct t.requirementname from ehr_compliancedb.employeerequirementexemptions t Where a.employeeid = t.employeeid + And b.requirementname = t.requirementname) + And a.employeeid in (select p.employeeid from ehr_compliancedb.employees p where a.employeeid = p.employeeid And p.enddate is null) + And b.requirementname in (select q.requirementname from ehr_compliancedb.Requirements q where q.requirementname = b.requirementname And q.dateDisabled is null ) + + +group by b.requirementname,a.employeeid + + +union + +select a.requirementname, + a.employeeid, + null as unit, + null as category, + 'None' as trackingflag, + (select h.email from ehr_compliancedb.employees h where h.employeeid = a.employeeid) as email, + (select h.lastname from ehr_compliancedb.employees h where h.employeeid = a.employeeid) as lastname, + (select h.firstname from ehr_compliancedb.employees h where h.employeeid = a.employeeid) as firstname, + (select h.majorudds from ehr_compliancedb.employees h where h.employeeid = a.employeeid) as host, + (select h.supervisor from ehr_compliancedb.employees h where h.employeeid = a.employeeid) as supervisor, + (select h.type from ehr_compliancedb.employees h where h.employeeid = a.employeeid) as trainee_type, ----- type trainee, or trainer + (select string_agg(h.type,char(10)) from ehr_compliancedb.Requirements h where h.requirementname = a.requirementname) as requirement_type, ----- type trainee, or trainer + + + (select count(zz.date) from ehr_compliancedb.completiondates zz where zz.requirementname= a.requirementname and zz.employeeid= a.employeeid ) as timesCompleted, + + (select string_agg(k.expireperiod,char(10)) from ehr_compliancedb.Requirements k where k.requirementname = a.requirementname) as ExpiredPeriod, + + ( select (datediff(month,max(pq.date), tt.reviewdate) )from ehr_compliancedb.requirements tt, ehr_compliancedb.completiondates pq where tt.requirementname = a.requirementname and pq.requirementname = tt.requirementname and pq.employeeid = a.employeeid group by tt.expireperiod, tt.reviewdate + having (COALESCE(tt.expireperiod,0)) > (datediff(month,max(pq.date), tt.reviewdate)) and (tt.reviewdate is not null) ) as NewExpirePeriod, + + (select max(zz.date) from ehr_compliancedb.completiondates zz where zz.requirementname= a.requirementname and zz.employeeid= a.employeeid ) as MostRecentDate, + + (Select distinct string_agg(yy.comment, char(10)) from ehr_compliancedb.completiondates yy where yy.date in (select max(zz.date) from ehr_compliancedb.completiondates zz where zz.requirementname= a.requirementname and zz.employeeid= a.employeeid ) + And yy.requirementname= a.requirementname and yy.employeeid= a.employeeid ) as comment, + + (Select distinct string_agg(yy.snooze_date, char(10)) from ehr_compliancedb.completiondates yy where yy.date in (select max(zz.date) from ehr_compliancedb.completiondates zz where zz.requirementname= a.requirementname and zz.employeeid= a.employeeid ) + And yy.requirementname= a.requirementname and yy.employeeid= a.employeeid ) as snooze_date, + + CAST( + CASE + WHEN (select max(st.date) from ehr_compliancedb.completiondates st where st.requirementname = a.requirementname and st.employeeid = a.employeeid ) IS NULL then 0 + WHEN ( select (COALESCE(tt.expireperiod,0)) from ehr_compliancedb.requirements tt where tt.requirementname = a.requirementname group by tt.expireperiod ) = 0 then Null + + + WHEN ( select count(*) from ehr_compliancedb.requirements tt, ehr_compliancedb.completiondates pq where tt.requirementname = a.requirementname and pq.requirementname = tt.requirementname and pq.employeeid = a.employeeid group by tt.expireperiod, tt.reviewdate + having (tt.reviewdate) > (max(pq.date)) ) > 0 THEN + + ( select (datediff(month,max(pq.date), tt.reviewdate) - ( datediff(month,max(pq.date), getdate())) ) from ehr_compliancedb.requirements tt, ehr_compliancedb.completiondates pq where tt.requirementname = a.requirementname and pq.requirementname = tt.requirementname and pq.employeeid = a.employeeid group by tt.expireperiod, tt.reviewdate + having (tt.reviewdate) > (max(pq.date)) ) + + + ELSE ( select (COALESCE(tt.expireperiod,0)) - ( datediff(month,max(pq.date), getdate())) from ehr_compliancedb.requirements tt, ehr_compliancedb.completiondates pq where tt.requirementname = a.requirementname and pq.requirementname = tt.requirementname and pq.employeeid = a.employeeid group by tt.expireperiod ) + + END AS FLOAT) AS MonthsUntilRenewal + + +from ehr_compliancedb.completiondates a +where a.requirementname not in (select distinct h.requirementname from ehr_compliancedb.employeeperunit k, ehr_compliancedb.requirementspercategory h Where (k.unit = h.unit + or k.category = h.category) And a.employeeid = k.employeeid ) + And a.requirementname not in (select distinct t.requirementname from ehr_compliancedb.employeerequirementexemptions t Where a.employeeid = t.employeeid + And a.requirementname = t.requirementname) + And a.employeeid in (select p.employeeid from ehr_compliancedb.employees p where a.employeeid = p.employeeid And p.enddate is null) + And a.requirementname in (select q.requirementname from ehr_compliancedb.Requirements q where q.requirementname = a.requirementname And q.dateDisabled is null ) + +group by a.requirementname,a.employeeid + +UNION + +--- Training that was completed by as an employee training exemptions, and at least completed one, or more times + +select a.requirementname, + a.employeeid, + null as unit, + null as category, + 'No' as trackingflag, + (select h.email from ehr_compliancedb.employees h where h.employeeid = a.employeeid) as email, + (select h.lastname from ehr_compliancedb.employees h where h.employeeid = a.employeeid) as lastname, + (select h.firstname from ehr_compliancedb.employees h where h.employeeid = a.employeeid) as firstname, + (select h.majorudds from ehr_compliancedb.employees h where h.employeeid = a.employeeid) as host, + (select h.supervisor from ehr_compliancedb.employees h where h.employeeid = a.employeeid) as supervisor, + (select h.type from ehr_compliancedb.employees h where h.employeeid = a.employeeid) as trainee_type, ----- type trainee, or trainer + (select string_agg(h.type,char(10)) from ehr_compliancedb.Requirements h where h.requirementname = a.requirementname) as requirement_type, ----- type trainee, or trainer + + + (select count(zz.date) from ehr_compliancedb.completiondates zz where zz.requirementname= a.requirementname and zz.employeeid= a.employeeid ) as timesCompleted, + + (select string_agg(k.expireperiod,char(10)) from ehr_compliancedb.Requirements k where k.requirementname = a.requirementname) as ExpiredPeriod, + + ( select (datediff(month,max(pq.date), tt.reviewdate) )from ehr_compliancedb.requirements tt, ehr_compliancedb.completiondates pq where tt.requirementname = a.requirementname and pq.requirementname = tt.requirementname and pq.employeeid = a.employeeid group by tt.expireperiod, tt.reviewdate + having (COALESCE(tt.expireperiod,0)) > (datediff(month,max(pq.date), tt.reviewdate)) and (tt.reviewdate is not null) ) as NewExpirePeriod, + + (select max(zz.date) from ehr_compliancedb.completiondates zz where zz.requirementname= a.requirementname and zz.employeeid= a.employeeid ) as MostRecentDate, + + (Select distinct string_agg(yy.comment, char(10)) from ehr_compliancedb.completiondates yy where yy.date in (select max(zz.date) from ehr_compliancedb.completiondates zz where zz.requirementname= a.requirementname and zz.employeeid= a.employeeid ) + And yy.requirementname= a.requirementname and yy.employeeid= a.employeeid ) as comment, + + (Select distinct string_agg(yy.snooze_date, char(10)) from ehr_compliancedb.completiondates yy where yy.date in (select max(zz.date) from ehr_compliancedb.completiondates zz where zz.requirementname= a.requirementname and zz.employeeid= a.employeeid ) + And yy.requirementname= a.requirementname and yy.employeeid= a.employeeid ) as snooze_date, + + CAST( + CASE + WHEN (select max(st.date) from ehr_compliancedb.completiondates st where st.requirementname = a.requirementname and st.employeeid = a.employeeid ) IS NULL then 0 + WHEN ( select (COALESCE(tt.expireperiod,0)) from ehr_compliancedb.requirements tt where tt.requirementname = a.requirementname group by tt.expireperiod ) = 0 then Null + + + WHEN ( select count(*) from ehr_compliancedb.requirements tt, ehr_compliancedb.completiondates pq where tt.requirementname = a.requirementname and pq.requirementname = tt.requirementname and pq.employeeid = a.employeeid group by tt.expireperiod, tt.reviewdate + having (tt.reviewdate) > (max(pq.date)) ) > 0 THEN + + ( select ( datediff(month,max(pq.date), tt.reviewdate) - (datediff(month,max(pq.date), getdate())) )from ehr_compliancedb.requirements tt, ehr_compliancedb.completiondates pq where tt.requirementname = a.requirementname and pq.requirementname = tt.requirementname and pq.employeeid = a.employeeid group by tt.expireperiod, tt.reviewdate + having (tt.reviewdate) > (max(pq.date)) ) + + + ELSE ( select (COALESCE(tt.expireperiod,0)) - ( datediff(month,max(pq.date), getdate())) from ehr_compliancedb.requirements tt, ehr_compliancedb.completiondates pq where tt.requirementname = a.requirementname and pq.requirementname = tt.requirementname and pq.employeeid = a.employeeid group by tt.expireperiod ) + + END AS DECIMAL) AS MonthsUntilRenewal + + +from ehr_compliancedb.employeerequirementexemptions a +Where a.employeeid in (select p.employeeid from ehr_compliancedb.employees p where a.employeeid = p.employeeid And p.enddate is null) + And a.requirementname in (select q.requirementname from ehr_compliancedb.Requirements q where q.requirementname = a.requirementname And q.dateDisabled is null ) + +group by a.requirementname,a.employeeid + +UNION + +--- Additional requirements for employees that have not completed training, but is required + +select j.requirementname, + j.employeeid, + null as unit, + null as category, + string_agg(j.trackingflag,char(10)) as trackingflag, + (select h.email from ehr_compliancedb.employees h where h.employeeid = j.employeeid) as email, + (select h.lastname from ehr_compliancedb.employees h where h.employeeid = j.employeeid) as lastname, + (select h.firstname from ehr_compliancedb.employees h where h.employeeid = j.employeeid) as firstname, + (select h.majorudds from ehr_compliancedb.employees h where h.employeeid = j.employeeid) as host, + (select h.supervisor from ehr_compliancedb.employees h where h.employeeid = j.employeeid) as supervisor, + (select h.type from ehr_compliancedb.employees h where h.employeeid = j.employeeid) as trainee_type, ----- type trainee, or trainer + (select string_agg(h.type,char(10)) from ehr_compliancedb.Requirements h where h.requirementname = j.requirementname) as requirement_type, ----- type trainee, or trainer + 0 as timesCompleted, + (select string_agg(k.expireperiod,char(10)) from ehr_compliancedb.Requirements k where k.requirementname = j.requirementname) as ExpiredPeriod, + ( select (datediff(month,max(pq.date), tt.reviewdate) )from ehr_compliancedb.requirements tt, ehr_compliancedb.completiondates pq where tt.requirementname = j.requirementname and pq.requirementname = tt.requirementname and pq.employeeid = j.employeeid group by tt.expireperiod, tt.reviewdate + having (COALESCE(tt.expireperiod,0)) > (datediff(month,max(pq.date), tt.reviewdate)) and (tt.reviewdate is not null) ) as NewExpirePeriod, + null as MostRecentDate, + '' as comment, + null as snooze_date, + CAST( + CASE + + WHEN (select max(st.date) from ehr_compliancedb.completiondates st where st.requirementname = j.requirementname and st.employeeid = j.employeeid ) IS NULL then 0 + WHEN ( select (COALESCE(tt.expireperiod,0)) from ehr_compliancedb.requirements tt where tt.requirementname = j.requirementname group by tt.expireperiod ) = 0 then Null + + WHEN ( select count(*) from ehr_compliancedb.requirements tt, ehr_compliancedb.completiondates pq where tt.requirementname = j.requirementname and pq.requirementname = tt.requirementname and pq.employeeid = j.employeeid group by tt.expireperiod, tt.reviewdate + having (tt.reviewdate) > (max(pq.date)) ) > 0 THEN + + ( select (datediff(month,max(pq.date), tt.reviewdate) - ( datediff(month,max(pq.date), getdate())) ) from ehr_compliancedb.requirements tt, ehr_compliancedb.completiondates pq where tt.requirementname = j.requirementname and pq.requirementname = tt.requirementname and pq.employeeid = j.employeeid group by tt.expireperiod, tt.reviewdate + having (tt.reviewdate) > (max(pq.date)) ) + + + ELSE ( select (COALESCE(tt.expireperiod,0)) - ( datediff(month,max(pq.date), getdate())) from ehr_compliancedb.requirements tt, ehr_compliancedb.completiondates pq where tt.requirementname = j.requirementname and pq.requirementname = tt.requirementname and pq.employeeid = j.employeeid group by tt.expireperiod ) + + END AS FLOAT) AS MonthsUntilRenewal + + +from onprc_ehr_compliancedb.RequirementsPerEmployee j +Where j.employeeid in (select p.employeeid from ehr_compliancedb.employees p where j.employeeid = p.employeeid And p.enddate is null) + And j.requirementname in (select q.requirementname from ehr_compliancedb.Requirements q where q.requirementname = j.requirementname And q.dateDisabled is null ) + And j.requirementname not in (select distinct h.requirementname from ehr_compliancedb.employeeperunit k, ehr_compliancedb.requirementspercategory h Where (k.unit = h.unit + or k.category = h.category) And j.employeeid = k.employeeid ) + And j.requirementname not in (select distinct t.requirementname from ehr_compliancedb.employeerequirementexemptions t Where j.employeeid = t.employeeid And j.requirementname = t.requirementname) + And j.requirementname not in (select distinct k.requirementname from ehr_compliancedb.completiondates k Where k.employeeid = j.employeeid) + +group by j.requirementname,j.employeeid + +order by employeeid,requirementname, mostrecentcompleted_date desc + + + If @@Error <> 0 + GoTo Err_Proc + + + + + RETURN 0 + + +Err_Proc: + + RETURN 1 + + +END + +GO \ No newline at end of file diff --git a/ONPRC_EHR_ComplianceDB/src/org/labkey/ONPRCEHR_ComplianceDB/ONPRC_EHR_ComplianceDBModule.java b/ONPRC_EHR_ComplianceDB/src/org/labkey/ONPRCEHR_ComplianceDB/ONPRC_EHR_ComplianceDBModule.java index 4ee6b9e89..e03bd4352 100644 --- a/ONPRC_EHR_ComplianceDB/src/org/labkey/ONPRCEHR_ComplianceDB/ONPRC_EHR_ComplianceDBModule.java +++ b/ONPRC_EHR_ComplianceDB/src/org/labkey/ONPRCEHR_ComplianceDB/ONPRC_EHR_ComplianceDBModule.java @@ -55,7 +55,7 @@ public String getName() @Override public Double getSchemaVersion() { - return 24.012; + return 25.001; } //Modified: 9-8-025 @Override From 8b42f94195b2d667db5dc1d174c5be21dd1f9fb4 Mon Sep 17 00:00:00 2001 From: Gary Jones Date: Wed, 28 Jan 2026 08:12:15 -0700 Subject: [PATCH 25/31] Update of dateFinalized when Status code is complete in clinPathRuns (#1618) * Update of dateFinalized when Status code is complete in clinPathRuns * Add schedule to run at 4:50 each day * Update descriptions in clinPathDateFinalized.xml Cleaned up the Description for the ETL and also for the transform statement * Update clinPathDateFinalized.xml * Fix cron expression hour format in XML --- .../resources/etls/clinPathDateFinalized.xml | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 onprc_ehr/resources/etls/clinPathDateFinalized.xml diff --git a/onprc_ehr/resources/etls/clinPathDateFinalized.xml b/onprc_ehr/resources/etls/clinPathDateFinalized.xml new file mode 100644 index 000000000..0b49d7268 --- /dev/null +++ b/onprc_ehr/resources/etls/clinPathDateFinalized.xml @@ -0,0 +1,21 @@ + + + + + clinPathRunDateFinalized + + Clin Path Runs ensure that QCState Completed generated the Date Finalized + + + Runs Stored Procedure that checks if the Date Finalized in present for finalized Charges + + + + + + + + + + + From 146277408130e6e81e2877638de501dc2b0954ba Mon Sep 17 00:00:00 2001 From: Lakshmi Kolli <69940873+kollil@users.noreply.github.com> Date: Mon, 2 Feb 2026 12:10:04 -0800 Subject: [PATCH 26/31] BSU assignment dashboard additions (#1622) * Adding new grid to BSU assignment dashboard and in the alert email. * Updated queries * Updated queries with more filters * Updated queries with final edits * Updated queries with final edits * Updated queries- Last edit --- .../study/AssignmentPoolUnderTheAge.query.xml | 10 ++ .../study/AssignmentPoolUnderTheAge.sql | 56 ++++++++++ .../study/AssignmentsUnderTheAge.query.xml | 10 ++ .../queries/study/AssignmentsUnderTheAge.sql | 101 ++++++++++++++++++ .../notification/BehaviorNotification.java | 49 +++++++++ 5 files changed, 226 insertions(+) create mode 100644 onprc_ehr/resources/queries/study/AssignmentPoolUnderTheAge.query.xml create mode 100644 onprc_ehr/resources/queries/study/AssignmentPoolUnderTheAge.sql create mode 100644 onprc_ehr/resources/queries/study/AssignmentsUnderTheAge.query.xml create mode 100644 onprc_ehr/resources/queries/study/AssignmentsUnderTheAge.sql diff --git a/onprc_ehr/resources/queries/study/AssignmentPoolUnderTheAge.query.xml b/onprc_ehr/resources/queries/study/AssignmentPoolUnderTheAge.query.xml new file mode 100644 index 000000000..ee363ecd0 --- /dev/null +++ b/onprc_ehr/resources/queries/study/AssignmentPoolUnderTheAge.query.xml @@ -0,0 +1,10 @@ + + + + + + Animals under the age of 2.5 with an assignment pool note +
+
+
+
diff --git a/onprc_ehr/resources/queries/study/AssignmentPoolUnderTheAge.sql b/onprc_ehr/resources/queries/study/AssignmentPoolUnderTheAge.sql new file mode 100644 index 000000000..bfd3899c1 --- /dev/null +++ b/onprc_ehr/resources/queries/study/AssignmentPoolUnderTheAge.sql @@ -0,0 +1,56 @@ +/* Added by Kollil, Jan 2026 + Refer to tkt # 14056 + - Extract animals under the age of 2.5 with an "Assignment pool" note in PRIMe (under general>notes) + */ + +SELECT + a.Id, + a.Id.demographics.gender AS Sex, + a.Id.Age.ageinyears, + a.Id.curlocation.room AS Room, + a.Id.curlocation.cage AS Cage, + /* Display the (active) Notes Pertaining to DAR note text */ + ( + SELECT MAX(n.value) + FROM study.Notes n + WHERE n.Id = a.Id + AND n.category = 'Notes Pertaining to DAR' + AND n.endDate IS NULL + ) AS Notes_Pertaining_to_DAR, + /* Concatenate all active cagemate IDs into one cell */ + ( + SELECT GROUP_CONCAT(DISTINCT CAST(h.roommateId AS VARCHAR), ', ') + FROM housingRoommatesDivider h + WHERE h.Id = a.Id + AND h.removalDate IS NULL + AND h.roommateEnd IS NULL + AND h.roommateId IS NOT NULL + ) AS Cagemates, + /* Concatenate all active projects & investigator into one cell */ + ( + SELECT GROUP_CONCAT(DISTINCT CAST('[' + d.project.protocol.investigatorId.lastname + ']' + d.project.displayname + '' AS VARCHAR), ', ') + FROM housingRoommatesDivider h + LEFT JOIN study.assignment d ON d.Id = h.roommateId + WHERE h.Id = a.Id + AND h.removalDate IS NULL + AND h.roommateEnd IS NULL + AND h.roommateId IS NOT NULL + AND d.enddate IS NULL + AND d.isActive = 1 + AND d.project.displayname NOT IN ('0492-02', '0492-03') + ) AS Cagemate_Assignments + +FROM Assignment a +WHERE + a.Id.Age.ageinyears <= 2.5 + AND a.project.displayname NOT IN ('0492-02', '0492-03') + AND a.Id.demographics.species = 'Rhesus Macaque' + AND EXISTS ( + SELECT 1 + FROM study.Notes n + WHERE n.Id = a.Id + AND n.value LIKE '%Assignment pool%' + AND n.endDate IS NULL + ) + + diff --git a/onprc_ehr/resources/queries/study/AssignmentsUnderTheAge.query.xml b/onprc_ehr/resources/queries/study/AssignmentsUnderTheAge.query.xml new file mode 100644 index 000000000..62259a6b4 --- /dev/null +++ b/onprc_ehr/resources/queries/study/AssignmentsUnderTheAge.query.xml @@ -0,0 +1,10 @@ + + + + + + Animals under the age of 2.5 with an active assignment +
+
+
+
diff --git a/onprc_ehr/resources/queries/study/AssignmentsUnderTheAge.sql b/onprc_ehr/resources/queries/study/AssignmentsUnderTheAge.sql new file mode 100644 index 000000000..3131b0081 --- /dev/null +++ b/onprc_ehr/resources/queries/study/AssignmentsUnderTheAge.sql @@ -0,0 +1,101 @@ +/* Added by Kollil, Jan 2026 + Refer to tkt # 14056 + - Extract animals under the age of 2.5 with an active assignment. Exclude the U42 and U42E colony maintenance assignments, i.e, center projects for these are 0492-02 and 0492-03. + */ + SELECT + a.Id, + a.Id.demographics.gender AS Sex, + a.Id.Age.ageinyears, + a.Id.curlocation.room AS Room, + a.Id.curlocation.cage AS Cage, + a.project, + a.project.protocol.displayname AS Protocol, + a.project.title AS Title, + a.project.protocol.investigatorId.lastname AS ProjectInvestigator, + CAST(a.date AS DATE) AS AssignDate, + CAST(a.enddate AS DATE) AS ReleaseDate, + CAST(a.projectedRelease AS DATE) AS ProjectedReleaseDate, + a.assignmentType, + a.projectedReleaseCondition.meaning AS ProjectedReleaseCondition, + a.releaseCondition.meaning AS ConditionAtRelease, + /* Concatenate all active cagemate IDs into one cell */ + ( + SELECT GROUP_CONCAT(DISTINCT CAST(h.roommateId AS VARCHAR), ', ') + FROM housingRoommatesDivider h + WHERE h.Id = a.Id + AND h.removalDate IS NULL + AND h.roommateEnd IS NULL + AND h.roommateId IS NOT NULL + ) AS Cagemates, + /* Concatenate all active projects & investigator into one cell */ + ( + SELECT GROUP_CONCAT(DISTINCT CAST('[' + d.project.protocol.investigatorId.lastname + ']' + d.project.displayname + '' AS VARCHAR), ', ') + FROM housingRoommatesDivider h + LEFT JOIN study.assignment d ON d.Id = h.roommateId + WHERE h.Id = a.Id + AND h.removalDate IS NULL + AND h.roommateEnd IS NULL + AND h.roommateId IS NOT NULL + AND d.enddate IS NULL + AND d.isActive = 1 + ) AS Cagemate_Assignments + +FROM Assignment a +WHERE + a.Id.Age.ageinyears <= 2.5 + AND a.Id.demographics.species = 'Rhesus Macaque' + AND a.enddate IS NULL + AND a.isActive = 1 + AND a.project.displayname NOT IN ('0492-02', '0492-03') + + + + + + + + + + + + + + + + + + + + + +-- SELECT +-- a.Id, +-- a.Id.demographics.gender AS Sex, +-- a.Id.Age.ageinyears, +-- a.Id.curlocation.room AS Room, +-- a.Id.curlocation.cage AS Cage, +-- a.project, +-- a.project.protocol.displayname AS Protocol, +-- a.project.title AS Title, +-- a.project.protocol.investigatorId.lastname AS ProjectInvestigator, +-- CAST(a.date AS DATE) AS AssignDate, +-- CAST(a.enddate AS DATE) AS ReleaseDate, +-- CAST(a.projectedRelease AS DATE) AS ProjectedReleaseDate, +-- a.assignmentType, +-- a.projectedReleaseCondition.meaning AS ProjectedReleaseCondition, +-- a.releaseCondition.meaning AS ConditionAtRelease, +-- h.roommateId AS Cagemate, +-- d.use AS Cagemate_Assignment +-- FROM Assignment a +-- LEFT JOIN housingRoommatesDivider h +-- ON h.Id = a.Id +-- AND h.removalDate IS NULL +-- AND h.roommateEnd IS NULL +-- LEFT JOIN study.demographicsUtilization d +-- ON d.Id = h.roommateId +-- WHERE +-- a.Id.Age.ageinyears <= 2.5 +-- AND a.Id.demographics.species = 'Rhesus Macaque' +-- AND a.enddate IS NULL +-- AND a.isActive = 1 +-- AND a.project.displayname NOT IN ('0492-02', '0492-03') 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 958d70a3f..4d49b7781 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/notification/BehaviorNotification.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/notification/BehaviorNotification.java @@ -122,12 +122,61 @@ public String getMessageBodyHTML(Container c, User u) assignmentsStartingNext1to14Days(c,u,msg); assignmentsStartedPast1to7Days(c,u,msg); + //Added by Kollil, Jan 2026 + //Refer to tkt # 14056 + activeAssignmentsUnderTheAge(c,u,msg); + assignmentPoolUnderTheAge(c,u,msg); + notesEndingToday(c, u, msg, Arrays.asList("BSU Notes"), null); saveValues(c, toSave); return msg.toString(); } + /* Added by Kollil, Jan 2026 + Refer to tkt # 14056 + The grid should include: + - Animals under the age of 2.5 with an active assignment. Exclude the U42 and U42E colony maintenance assignments, I believe the center projects for these are 0492-02 and 0492-03. + - Animals under the age of 2.5 with an "Assignment pool" note in PRIMe (under general>notes) + */ + private void activeAssignmentsUnderTheAge(final Container c, User u, final StringBuilder msg) + { + TableInfo ti = getStudySchema(c, u).getTable("AssignmentsUnderTheAge"); + + TableSelector ts = new TableSelector(ti, null, new Sort("Id")); + long total = ts.getRowCount(); + + if (total > 0) + { + msg.append("Animals under the age of 2.5 with an active assignment excluding the U42 & U42E assignments:

"); + msg.append( total + " entries found. "); + msg.append("Click here to view them\n"); + msg.append("


\n\n"); + } + else { + msg.append("WARNING: No animals under the age of 2.5 with an active assignment!

\n"); + } + } + + private void assignmentPoolUnderTheAge(final Container c, User u, final StringBuilder msg) + { + TableInfo ti = getStudySchema(c, u).getTable("AssignmentPoolUnderTheAge"); + + TableSelector ts = new TableSelector(ti, null, new Sort("Id")); + long total = ts.getRowCount(); + + if (total > 0) + { + msg.append("Animals under the age of 2.5 with \"Assignment pool\" notes:

"); + msg.append( total + " entries found. "); + msg.append("Click here to view them\n"); + msg.append("


\n\n"); + } + else { + msg.append("WARNING: No animals under the age of 2.5 with an \"Assignment pool\" notes!

\n"); + } + } + /* Added by Kollil Nov, 2025 Priority 4: Add links to grids 3 and 4 in daily Behavior Alerts email (do not need to display full grid in email) - for grid 3 - "There are __ assignments starting in the Next 1-14 days" with a link From 20cf8d7e0afbbeed84488b90fa9b074716242a3f Mon Sep 17 00:00:00 2001 From: Lakshmi Kolli <69940873+kollil@users.noreply.github.com> Date: Tue, 3 Feb 2026 13:58:40 -0800 Subject: [PATCH 27/31] Behavior alert assignment pool note link update (#1626) * Fixed the query link * Added a query condition --- onprc_ehr/resources/queries/study/AssignmentsUnderTheAge.sql | 1 + .../org/labkey/onprc_ehr/notification/BehaviorNotification.java | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/onprc_ehr/resources/queries/study/AssignmentsUnderTheAge.sql b/onprc_ehr/resources/queries/study/AssignmentsUnderTheAge.sql index 3131b0081..f9405ee3a 100644 --- a/onprc_ehr/resources/queries/study/AssignmentsUnderTheAge.sql +++ b/onprc_ehr/resources/queries/study/AssignmentsUnderTheAge.sql @@ -38,6 +38,7 @@ AND h.roommateId IS NOT NULL AND d.enddate IS NULL AND d.isActive = 1 + AND d.project.displayname NOT IN ('0492-02', '0492-03') ) AS Cagemate_Assignments FROM Assignment a 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 4d49b7781..b9d63e2a5 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/notification/BehaviorNotification.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/notification/BehaviorNotification.java @@ -169,7 +169,7 @@ private void assignmentPoolUnderTheAge(final Container c, User u, final StringBu { msg.append("Animals under the age of 2.5 with \"Assignment pool\" notes:

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


\n\n"); } else { From 801333ea1302153454364e76627500703187c64f Mon Sep 17 00:00:00 2001 From: Karl Lum Date: Fri, 6 Feb 2026 08:36:01 -0800 Subject: [PATCH 28/31] Suppress restricted issue exception on search (#1629) --- .../onprc_ehr/ONPRC_RestrictedIssueTest.java | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/onprc_ehr/test/src/org/labkey/test/tests/onprc_ehr/ONPRC_RestrictedIssueTest.java b/onprc_ehr/test/src/org/labkey/test/tests/onprc_ehr/ONPRC_RestrictedIssueTest.java index 7e54dae2c..5d0abf4a0 100644 --- a/onprc_ehr/test/src/org/labkey/test/tests/onprc_ehr/ONPRC_RestrictedIssueTest.java +++ b/onprc_ehr/test/src/org/labkey/test/tests/onprc_ehr/ONPRC_RestrictedIssueTest.java @@ -1,5 +1,6 @@ package org.labkey.test.tests.onprc_ehr; +import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; import org.junit.experimental.categories.Category; @@ -11,7 +12,9 @@ import org.labkey.test.pages.issues.DetailsPage; import org.labkey.test.pages.issues.InsertPage; import org.labkey.test.pages.issues.UpdatePage; +import org.labkey.test.pages.search.SearchResultsPage; import org.labkey.test.util.IssuesHelper; +import org.labkey.test.util.SearchHelper; import org.labkey.test.util.SqlserverOnlyTest; import org.labkey.test.util.TestUser; @@ -265,4 +268,37 @@ private Locator getIssueLinkLocator(String issueID) { return Locator.tagWithAttributeContaining("a", "href", String.format("issues-details.view?issueId=%s", issueID)); } + + @Test + public void restrictedIssueSearchTest() + { + goToProjectHome(); + + // create a few issues in the restricted list + clickAndWait(Locator.linkContainingText(RESTRICTED_ISSUES_LIST)); + DetailsPage detailsPage = _issuesHelper.addIssue("Restricted issue search test #1", USER1.getUserDisplayName()); + final String ISSUE_1 = detailsPage.getIssueId(); + InsertPage insertPage = detailsPage.clickCreateNewIssue(); + insertPage.title().set("Restricted issue search test #2"); + insertPage.assignedTo().set(USER2.getUserDisplayName()); + detailsPage = insertPage.save(); + final String ISSUE_2 = detailsPage.getIssueId(); + + SearchHelper searchHelper = new SearchHelper(this); + SearchResultsPage resultsPage = searchHelper.searchFor("Restricted issue search test"); + + // verify that we can return links even if the user doesn't have permission to view a restricted issue + Assert.assertTrue("Number of search results not expected", resultsPage.getResults().size() == 2); + + // verify assigned to users will see both results but shouldn't be able to see details of issues not assigned to them + impersonate(USER1.getEmail()); + verifyIssueAccess(ISSUE_1, true); + verifyIssueAccess(ISSUE_2, false); + stopImpersonating(false); + + impersonate(USER2.getEmail()); + verifyIssueAccess(ISSUE_1, false); + verifyIssueAccess(ISSUE_2, true); + stopImpersonating(); + } } From 3c3bb640f39a3d92741dd0cb4476275db2b15287 Mon Sep 17 00:00:00 2001 From: Lakshmi Kolli <69940873+kollil@users.noreply.github.com> Date: Wed, 11 Feb 2026 14:37:02 -0800 Subject: [PATCH 29/31] Changed the animal age to under 3 instead 2.5 years (#1635) --- .../queries/study/AssignmentPoolUnderTheAge.query.xml | 2 +- .../queries/study/AssignmentPoolUnderTheAge.sql | 2 +- .../queries/study/AssignmentsUnderTheAge.query.xml | 2 +- .../resources/queries/study/AssignmentsUnderTheAge.sql | 2 +- .../onprc_ehr/notification/BehaviorNotification.java | 9 +++++---- 5 files changed, 9 insertions(+), 8 deletions(-) diff --git a/onprc_ehr/resources/queries/study/AssignmentPoolUnderTheAge.query.xml b/onprc_ehr/resources/queries/study/AssignmentPoolUnderTheAge.query.xml index ee363ecd0..2d839c69e 100644 --- a/onprc_ehr/resources/queries/study/AssignmentPoolUnderTheAge.query.xml +++ b/onprc_ehr/resources/queries/study/AssignmentPoolUnderTheAge.query.xml @@ -3,7 +3,7 @@ - Animals under the age of 2.5 with an assignment pool note + Animals under the age of 3 with an assignment pool note
diff --git a/onprc_ehr/resources/queries/study/AssignmentPoolUnderTheAge.sql b/onprc_ehr/resources/queries/study/AssignmentPoolUnderTheAge.sql index bfd3899c1..da5ff511a 100644 --- a/onprc_ehr/resources/queries/study/AssignmentPoolUnderTheAge.sql +++ b/onprc_ehr/resources/queries/study/AssignmentPoolUnderTheAge.sql @@ -42,7 +42,7 @@ SELECT FROM Assignment a WHERE - a.Id.Age.ageinyears <= 2.5 + a.Id.Age.ageinyears <= 3 AND a.project.displayname NOT IN ('0492-02', '0492-03') AND a.Id.demographics.species = 'Rhesus Macaque' AND EXISTS ( diff --git a/onprc_ehr/resources/queries/study/AssignmentsUnderTheAge.query.xml b/onprc_ehr/resources/queries/study/AssignmentsUnderTheAge.query.xml index 62259a6b4..9636deb96 100644 --- a/onprc_ehr/resources/queries/study/AssignmentsUnderTheAge.query.xml +++ b/onprc_ehr/resources/queries/study/AssignmentsUnderTheAge.query.xml @@ -3,7 +3,7 @@ - Animals under the age of 2.5 with an active assignment + Animals under the age of 3 with an active assignment
diff --git a/onprc_ehr/resources/queries/study/AssignmentsUnderTheAge.sql b/onprc_ehr/resources/queries/study/AssignmentsUnderTheAge.sql index f9405ee3a..2f5234fdb 100644 --- a/onprc_ehr/resources/queries/study/AssignmentsUnderTheAge.sql +++ b/onprc_ehr/resources/queries/study/AssignmentsUnderTheAge.sql @@ -43,7 +43,7 @@ FROM Assignment a WHERE - a.Id.Age.ageinyears <= 2.5 + a.Id.Age.ageinyears <= 3 AND a.Id.demographics.species = 'Rhesus Macaque' AND a.enddate IS NULL AND a.isActive = 1 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 b9d63e2a5..e2829e445 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/notification/BehaviorNotification.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/notification/BehaviorNotification.java @@ -138,6 +138,7 @@ public String getMessageBodyHTML(Container c, User u) The grid should include: - Animals under the age of 2.5 with an active assignment. Exclude the U42 and U42E colony maintenance assignments, I believe the center projects for these are 0492-02 and 0492-03. - Animals under the age of 2.5 with an "Assignment pool" note in PRIMe (under general>notes) + - 2/11/26 - change the age animals under 3 years old */ private void activeAssignmentsUnderTheAge(final Container c, User u, final StringBuilder msg) { @@ -148,13 +149,13 @@ private void activeAssignmentsUnderTheAge(final Container c, User u, final Strin if (total > 0) { - msg.append("Animals under the age of 2.5 with an active assignment excluding the U42 & U42E assignments:

"); + msg.append("Animals under the age of 3 with an active assignment excluding the U42 & U42E assignments:

"); msg.append( total + " entries found. "); msg.append("Click here to view them\n"); msg.append("


\n\n"); } else { - msg.append("WARNING: No animals under the age of 2.5 with an active assignment!

\n"); + msg.append("WARNING: No animals under the age of 3 with an active assignment!

\n"); } } @@ -167,13 +168,13 @@ private void assignmentPoolUnderTheAge(final Container c, User u, final StringBu if (total > 0) { - msg.append("Animals under the age of 2.5 with \"Assignment pool\" notes:

"); + msg.append("Animals under the age of 3 with \"Assignment pool\" notes:

"); msg.append( total + " entries found. "); msg.append("Click here to view them\n"); msg.append("


\n\n"); } else { - msg.append("WARNING: No animals under the age of 2.5 with an \"Assignment pool\" notes!

\n"); + msg.append("WARNING: No animals under the age of 3 with an \"Assignment pool\" notes!

\n"); } } From 65b720aacb71950fb8ba4ee5d333784b54652630 Mon Sep 17 00:00:00 2001 From: Gary Jones Date: Thu, 12 Feb 2026 10:18:53 -0700 Subject: [PATCH 30/31] Made change to Billing Customizer to format total cost as a decimal (#1630) Review and approved will deploy Tonight --- .../table/ONPRC_BillingCustomizer.java | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/onprc_billing/src/org/labkey/onprc_billing/table/ONPRC_BillingCustomizer.java b/onprc_billing/src/org/labkey/onprc_billing/table/ONPRC_BillingCustomizer.java index 3c678ea9d..804757c78 100644 --- a/onprc_billing/src/org/labkey/onprc_billing/table/ONPRC_BillingCustomizer.java +++ b/onprc_billing/src/org/labkey/onprc_billing/table/ONPRC_BillingCustomizer.java @@ -180,8 +180,17 @@ private void addTotalCost(AbstractTableInfo ti) if (ti.getColumn("totalCost") == null && unitCost != null && ti.getColumn("quantity") != null) { - SQLFragment sql = new SQLFragment("(" + ExprColumn.STR_TABLE_ALIAS + ".unitCost * " + ExprColumn.STR_TABLE_ALIAS + ".quantity)"); - ExprColumn totalCost = new ExprColumn(ti, "totalCost", sql, JdbcType.DOUBLE, ti.getColumn("unitCost"), ti.getColumn("quantity")); + SQLFragment sql = new SQLFragment( + "CAST(ROUND((" + ExprColumn.STR_TABLE_ALIAS + ".unitCost * " + + ExprColumn.STR_TABLE_ALIAS + ".quantity), 2) AS DECIMAL(18,2))"); + ExprColumn totalCost = new ExprColumn( + ti, + "totalCost", + sql, + JdbcType.DECIMAL, + ti.getColumn("unitCost"), + ti.getColumn("quantity") + ); totalCost.setLabel("Total Cost"); totalCost.setFormat("$###,##0.00"); ti.addColumn(totalCost); From e104040456564832fc4189330ba1a3ec029f97da Mon Sep 17 00:00:00 2001 From: Lakshmi Kolli <69940873+kollil@users.noreply.github.com> Date: Tue, 24 Feb 2026 17:51:46 -0800 Subject: [PATCH 31/31] Parentage dam mismatch in Colony alert (#1643) * Added a new report in the Colony alert: Parentage Dam mismatch records * Fixed a few comments and typos --- .../study/ParentageDamMismatch.query.xml | 9 +++ .../queries/study/ParentageDamMismatch.sql | 61 ++++++++++++++++++ .../ColonyAlertsNotification.java | 64 +++++++++++++++++++ .../notification/ColonyMgmtNotification.java | 4 ++ 4 files changed, 138 insertions(+) create mode 100644 onprc_ehr/resources/queries/study/ParentageDamMismatch.query.xml create mode 100644 onprc_ehr/resources/queries/study/ParentageDamMismatch.sql diff --git a/onprc_ehr/resources/queries/study/ParentageDamMismatch.query.xml b/onprc_ehr/resources/queries/study/ParentageDamMismatch.query.xml new file mode 100644 index 000000000..5a237c10e --- /dev/null +++ b/onprc_ehr/resources/queries/study/ParentageDamMismatch.query.xml @@ -0,0 +1,9 @@ + + + + + Mismatched Genetic and Observed Dams +
+
+
+
\ No newline at end of file diff --git a/onprc_ehr/resources/queries/study/ParentageDamMismatch.sql b/onprc_ehr/resources/queries/study/ParentageDamMismatch.sql new file mode 100644 index 000000000..f9e07f467 --- /dev/null +++ b/onprc_ehr/resources/queries/study/ParentageDamMismatch.sql @@ -0,0 +1,61 @@ +/* + Added by Kolli, Feb 2026 + Refer tkt# 14114 for details + Display 4 columns: Animal Id, Area, Genetic dam, Observed dam + + Get genetic and observed dam mismatch data. + Use the following criteria, + * 1. One genetic dam per animal + * 2. Included Alive + Dead animals + * 3. Excludes animals that have a foster dam + * 4. Excludes rows where observedDam or geneticDam IS BLANK + * 5. Keeps only mismatches between observed and genetic dams + * 6. Excludes old parentage entries, enddate IS BLANK +*/ + +SELECT + d.Id, + d.Id.curLocation.area AS Area, + coalesce(p2.parent, '') as geneticDam, + coalesce(b.dam, '') as observedDam +FROM study.demographics d + + LEFT JOIN ( + SELECT + p2.Id, + MAX(p2.parent) AS parent + FROM study.parentage p2 + WHERE (p2.method = 'Genetic' OR p2.method = 'Provisional Genetic') + AND p2.relationship = 'Dam' + AND p2.enddate IS NULL + GROUP BY p2.Id +) p2 ON d.Id = p2.Id + + LEFT JOIN ( + SELECT + p3.Id, + MAX(p3.parent) AS parent + FROM study.parentage p3 + WHERE p3.relationship = 'Foster Dam' + AND p3.enddate IS NULL + GROUP BY p3.Id +) p3 ON d.Id = p3.Id + + LEFT JOIN study.birth b + ON b.Id = d.Id + +WHERE d.calculated_status.code IN ('Alive', 'Dead') AND d.qcstate = 18 + /* exclude foster-dam cases (NULL or blank only) */ + AND COALESCE(RTRIM(LTRIM(CAST(p3.parent AS VARCHAR(50)))), '') = '' + + /* exclude blank observed dam */ + AND COALESCE(RTRIM(LTRIM(CAST(b.dam AS VARCHAR(50)))), '') <> '' + + /* exclude blank genetic dam */ + AND COALESCE(RTRIM(LTRIM(CAST(p2.parent AS VARCHAR(50)))), '') <> '' + + /* mismatch observed vs genetic */ + AND COALESCE(RTRIM(LTRIM(CAST(b.dam AS VARCHAR(50)))), '') <> + COALESCE(RTRIM(LTRIM(CAST(p2.parent AS VARCHAR(50)))), '') + + diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/notification/ColonyAlertsNotification.java b/onprc_ehr/src/org/labkey/onprc_ehr/notification/ColonyAlertsNotification.java index 8a5363df3..3b62bd188 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/notification/ColonyAlertsNotification.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/notification/ColonyAlertsNotification.java @@ -312,6 +312,70 @@ protected void roomsReportingNegativeCagesAvailable(final Container c, User u, f } } + /** + * Kollil, Jan, 2026 : + * Refer tkt# 14114 for more details + * Alert title: WARNING: There are [x total] mismatches of observed and genetic dam data requiring review + * Format: Table + * 4 columns: Animal Id, Area, Genetic dam, Observed dam + * Alert criteria: + * 1. One genetic dam per animal + * 2. Included Alive + Dead animals + * 3. Excludes animals that have a foster dam + * 4. Excludes rows where observedDam or geneticDam IS BLANK + * 5. Keeps only mismatches between observed and genetic dams + * 6. Excludes old parentage entries, enddate IS BLANK + */ + protected void mismatchedObservedAndGeneticDam(final Container c, User u, final StringBuilder msg) + { + if (QueryService.get().getUserSchema(u, c, "study") == null) { + msg.append("Warning: The study schema has not been enabled in this folder, so the alert cannot run.


"); + return; + } + + //Dam mismatch query + TableInfo ti = QueryService.get().getUserSchema(u, c, "study").getTable("ParentageDamMismatch", ContainerFilter.Type.AllFolders.create(c, u)); + TableSelector ts = new TableSelector(ti, null, null); + long count = ts.getRowCount(); + + //Get num of rows + if (count > 0) { + msg.append(" WARNING: There are " + count + " mismatches of observed and genetic dam data requiring review."); + msg.append(" Click here to view them in a grid\n"); + + //Display the report in the email + Set columns = new HashSet<>(); + columns.add(FieldKey.fromString("Id")); + columns.add(FieldKey.fromString("area")); + columns.add(FieldKey.fromString("geneticdam")); + columns.add(FieldKey.fromString("observeddam")); + + final Map colMap = QueryService.get().getColumns(ti, columns); + TableSelector ts2 = new TableSelector(ti, colMap.values(), null, null); + + msg.append("

\n"); + msg.append(""); + msg.append(""); + msg.append(""); + + ts2.forEach(object -> { + Results rs = new ResultsImpl(object, colMap); + String url = getParticipantURL(c, rs.getString("Id")); + msg.append("\n"); + msg.append(""); + msg.append(""); + msg.append(""); + msg.append(""); + }); + } + else { + msg.append(" There are NO mismatches of observed and genetic dam data. "); + } + msg.append("
Id Area Genetic Dam Observed Dam
" + PageFlowUtil.filter(rs.getString("Id")) + " " + PageFlowUtil.filter(rs.getString("area")) + "" + PageFlowUtil.filter(rs.getString("geneticdam")) + "" + PageFlowUtil.filter(rs.getString("observeddam")) + "
"); + msg.append("
\n"); + } + //End of Dam mismatch report + /** * Finds all rooms with animals of mixed viral status * Modified by Kollil, 2/17/2023 diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/notification/ColonyMgmtNotification.java b/onprc_ehr/src/org/labkey/onprc_ehr/notification/ColonyMgmtNotification.java index c7d35ab92..1ca060cad 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/notification/ColonyMgmtNotification.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/notification/ColonyMgmtNotification.java @@ -74,6 +74,10 @@ public String getMessageBodyHTML(Container c, User u) doHousingChecks(c, u, msg); transfersYesterday(c, u, msg); roomsWithMixedViralStatus(c, u, msg); + /*Added by kollil, Jan, 2026 + Refer to tkt # 14114 + */ + mismatchedObservedAndGeneticDam(c, u, msg); livingAnimalsWithoutWeight(c, u, msg); hospitalAnimalsWithoutCase(c, u, msg);