Click here to view the meds/diets
\n"); + msg.append("Click here to view the treatments
\n"); msg.append(""); + msg.append( total + " entries found. "); + msg.append("Click here to view them\n"); + msg.append("
"); + msg.append( total + " entries found. "); + msg.append("Click here to view them\n"); + msg.append("
"); + msg.append( total + " entries found. "); + msg.append("Click here to view them\n"); + msg.append("
"); + msg.append( total + " entries found. "); + msg.append("Click here to view them\n"); + msg.append("
");
+ 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 ");
+ 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 ");
if (total > 0)
{
- msg.append("There are " + total + " entries found. ");
- msg.append(" Click here to view them Click here to view them Click here to view them Click here to view them Click here to view them ");
+ 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();
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");
}
}
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");
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();
+ }
}
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 @@
+
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("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 ");
+ msg.append(" ");
+ });
+ msg.append(" " + PageFlowUtil.filter(rs.getString("Id")) + " \n");
+ msg.append("" + PageFlowUtil.filter(rs.getString("Sex")) + " ");
+ msg.append("" + PageFlowUtil.filter(rs.getString("Room")) + " ");
+ msg.append("" + PageFlowUtil.filter(rs.getString("Cage")) + " ");
+ msg.append("" + PageFlowUtil.filter(rs.getString("project")) + " ");
+ msg.append("" + PageFlowUtil.filter(rs.getString("Protocol")) + " ");
+ msg.append("" + PageFlowUtil.filter(rs.getString("Title")) + " ");
+ msg.append("" + PageFlowUtil.filter(rs.getString("ProjectInvestigator")) + " ");
+ msg.append("" + PageFlowUtil.filter(rs.getString("AssignDate")) + " ");
+ msg.append("" + PageFlowUtil.filter(rs.getString("ReleaseDate")) + " ");
+ msg.append("" + PageFlowUtil.filter(rs.getString("ProjectedReleaseDate")) + " ");
+ msg.append("" + PageFlowUtil.filter(rs.getString("assignmentType")) + " ");
+ msg.append("" + PageFlowUtil.filter(rs.getString("assignCondition")) + " ");
+ msg.append("" + PageFlowUtil.filter(rs.getString("projectedReleaseCondition")) + " ");
+ msg.append("" + PageFlowUtil.filter(rs.getString("ConditionAtRelease")) + " ");
+ msg.append("
");
+ }
+ 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:
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("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 ");
+ msg.append(" ");
+ });
+ msg.append(" " + PageFlowUtil.filter(rs.getString("Id")) + " \n");
+ msg.append("" + PageFlowUtil.filter(rs.getString("Sex")) + " ");
+ msg.append("" + PageFlowUtil.filter(rs.getString("Room")) + " ");
+ msg.append("" + PageFlowUtil.filter(rs.getString("Cage")) + " ");
+ msg.append("" + PageFlowUtil.filter(rs.getString("project")) + " ");
+ msg.append("" + PageFlowUtil.filter(rs.getString("Protocol")) + " ");
+ msg.append("" + PageFlowUtil.filter(rs.getString("Title")) + " ");
+ msg.append("" + PageFlowUtil.filter(rs.getString("ProjectInvestigator")) + " ");
+ msg.append("" + PageFlowUtil.filter(rs.getString("AssignDate")) + " ");
+ msg.append("" + PageFlowUtil.filter(rs.getString("ReleaseDate")) + " ");
+ msg.append("" + PageFlowUtil.filter(rs.getString("ProjectedReleaseDate")) + " ");
+ msg.append("" + PageFlowUtil.filter(rs.getString("assignmentType")) + " ");
+ msg.append("" + PageFlowUtil.filter(rs.getString("assignCondition")) + " ");
+ msg.append("" + PageFlowUtil.filter(rs.getString("projectedReleaseCondition")) + " ");
+ msg.append("" + PageFlowUtil.filter(rs.getString("ConditionAtRelease")) + " ");
+ msg.append("
");
+ }
+ 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 +398,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:
\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 +424,13 @@ private void NHPTraining_BehaviorAlert(final Container c, User u, final StringBu
if (total > 0)
{
msg.append("There are " + total + " entries found. ");
- msg.append("\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 +452,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("
\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 +477,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("
\n\n");
- msg.append("
\n\n");
+ msg.append("Click here to view them
\n\n");
+ msg.append("
\n\n");
}
else
{
@@ -228,8 +496,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("
\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 +511,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("
\n\n");
- msg.append("
");
+ msg.append("Click here to view them
\n\n");
+ msg.append("
");
}
else
{
@@ -258,8 +526,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("
\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!
");
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..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
\n");
+ msg.append("");
+ msg.append("
");
+ msg.append("");
+ msg.append(" ");
+
+ ts2.forEach(object -> {
+ Results rs = new ResultsImpl(object, colMap);
+ String url = getParticipantURL(c, rs.getString("Id"));
+ msg.append("Id Area Genetic Dam Observed Dam ");
+ });
+ }
+ else {
+ msg.append(" There are NO mismatches of observed and genetic dam data. ");
+ }
+ msg.append(" " + PageFlowUtil.filter(rs.getString("Id")) + " \n");
+ msg.append("" + PageFlowUtil.filter(rs.getString("area")) + " ");
+ msg.append("" + PageFlowUtil.filter(rs.getString("geneticdam")) + " ");
+ msg.append("" + 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
@@ -1551,7 +1615,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 +2397,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("\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/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);
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..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,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
@@ -112,11 +112,14 @@ 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())
{
- 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) + ".
+
+