diff --git a/onprc_ehr/resources/queries/onprc_ehr/vet_assignment_invalidRule.query.xml b/onprc_ehr/resources/queries/onprc_ehr/vet_assignment_invalidRule.query.xml
new file mode 100644
index 000000000..10b47c56c
--- /dev/null
+++ b/onprc_ehr/resources/queries/onprc_ehr/vet_assignment_invalidRule.query.xml
@@ -0,0 +1,9 @@
+
+
+
+
+ Invalid Vet Assignment Rules
+
+
+
+
diff --git a/onprc_ehr/resources/queries/onprc_ehr/vet_assignment_invalidRule.sql b/onprc_ehr/resources/queries/onprc_ehr/vet_assignment_invalidRule.sql
new file mode 100644
index 000000000..0ad9d717d
--- /dev/null
+++ b/onprc_ehr/resources/queries/onprc_ehr/vet_assignment_invalidRule.sql
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2014-2026 LabKey Corporation
+ *
+ * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0
+ */
+
+WITH ruleData AS (
+ SELECT
+ rowid,
+ CASE
+ WHEN (userId IS NOT NULL AND Room IS NOT NULL AND Area IS NULL AND Project IS NULL AND Protocol IS NULL AND Priority = true) THEN 1
+ WHEN (userId IS NOT NULL AND Area IS NOT NULL AND Room IS NULL AND Project IS NULL AND Protocol IS NULL AND Priority = true) THEN 1
+ WHEN (userId IS NOT NULL AND Project IS NOT NULL AND Room IS NOT NULL AND Area IS NULL AND Protocol IS NULL AND Priority = true) THEN 1
+ WHEN (userId IS NOT NULL AND Project IS NOT NULL AND Room IS NOT NULL AND Area IS NULL AND Protocol IS NULL AND Priority = false) THEN 1
+ WHEN (userId IS NOT NULL AND Project IS NOT NULL AND Area IS NOT NULL AND Room IS NULL AND Protocol IS NULL AND Priority = true) THEN 1
+ WHEN (userId IS NOT NULL AND Project IS NOT NULL AND Area IS NOT NULL AND Room IS NULL AND Protocol IS NULL AND Priority = false) THEN 1
+ WHEN (userId IS NOT NULL AND Project IS NOT NULL AND Area IS NULL AND Room IS NULL AND Protocol IS NULL AND Priority = true) THEN 1
+ WHEN (userId IS NOT NULL AND Project IS NOT NULL AND Area IS NULL AND Room IS NULL AND Protocol IS NULL AND Priority = false) THEN 1
+ WHEN (userId IS NOT NULL AND Protocol.DisplayName IS NOT NULL AND Room IS NOT NULL AND Area IS NULL AND Project IS NULL AND Priority = true) THEN 1
+ WHEN (userId IS NOT NULL AND Protocol.DisplayName IS NOT NULL AND Area IS NOT NULL AND Room IS NULL AND Project IS NULL AND Priority = true) THEN 1
+ WHEN (userId IS NOT NULL AND Protocol.DisplayName IS NOT NULL AND Room IS NOT NULL AND Area IS NULL AND Project IS NULL AND Priority = false) THEN 1
+ WHEN (userId IS NOT NULL AND Protocol.DisplayName IS NOT NULL AND Area IS NOT NULL AND Room IS NULL AND Project IS NULL AND Priority = false) THEN 1
+ WHEN (userId IS NOT NULL AND Protocol.DisplayName IS NOT NULL AND Area IS NULL AND Room IS NULL AND Project IS NULL AND Priority = true) THEN 1
+ WHEN (userId IS NOT NULL AND Protocol.DisplayName IS NOT NULL AND Area IS NULL AND Room IS NULL AND Project IS NULL AND Priority = false) THEN 1
+ WHEN (userId IS NOT NULL AND Room IS NOT NULL AND Area IS NULL AND Protocol IS NULL AND Project IS NULL AND Priority = false) THEN 1
+ WHEN (userId IS NOT NULL AND Area IS NOT NULL AND Room IS NULL AND Protocol IS NULL AND Project IS NULL AND Priority = false) THEN 1
+ ELSE 0
+ END AS valid
+ FROM onprc_ehr.vet_assignment
+)
+SELECT
+ userId,
+ project,
+ protocol,
+ area,
+ room,
+ priority
+FROM onprc_ehr.vet_assignment
+WHERE rowid IN (SELECT rowid FROM ruleData WHERE valid = 0)
diff --git a/onprc_ehr/resources/queries/study/observationsLinkedToAnotherAnimalsCase.query.xml b/onprc_ehr/resources/queries/study/observationsLinkedToAnotherAnimalsCase.query.xml
new file mode 100644
index 000000000..8e8ed7a63
--- /dev/null
+++ b/onprc_ehr/resources/queries/study/observationsLinkedToAnotherAnimalsCase.query.xml
@@ -0,0 +1,9 @@
+
+
+
+
+ Observations Linked to Another Animal's Case
+
+
+
+
diff --git a/onprc_ehr/resources/queries/study/observationsLinkedToAnotherAnimalsCase.sql b/onprc_ehr/resources/queries/study/observationsLinkedToAnotherAnimalsCase.sql
new file mode 100644
index 000000000..8ae269fc6
--- /dev/null
+++ b/onprc_ehr/resources/queries/study/observationsLinkedToAnotherAnimalsCase.sql
@@ -0,0 +1,113 @@
+WITH Observations AS (
+ SELECT
+ o.Id,
+ o.caseid,
+ o.caseid.id.id AS linkid,
+ o.caseid.caseNo AS linkCaseNo,
+ o.caseid._key AS linkCaseKey,
+ o.caseid.date AS linkCaseDate,
+ o.taskid,
+ o.performedby,
+ o.date,
+ o.created,
+
+ NULLIF(o.category, 'Observations') AS category,
+ NULLIF(o.area, 'N/A') AS area,
+
+ CASE
+ WHEN o.category IS NULL AND o.observation IS NOT NULL
+ THEN o.observation
+ WHEN o.category IS NOT NULL AND o.observation IS NULL
+ THEN o.category
+ WHEN o.category IS NOT NULL AND o.area IS NULL
+ THEN (o.category || ': ' || o.observation)
+ WHEN o.category IS NOT NULL AND o.area IS NOT NULL
+ THEN (o.category || ': ' || o.area || ', ' || o.observation)
+ ELSE NULL
+ END
+ ||
+ COALESCE(
+ CASE
+ WHEN o.remark IS NOT NULL AND o.observation IS NOT NULL
+ THEN ('. ' || o.remark)
+ ELSE o.remark
+ END,
+ ''
+ ) AS observation_string
+ FROM study.clinical_observations o
+ WHERE
+ o.caseid IS NOT NULL
+ AND o.category NOT IN ('Vet Review', 'Reviewed')
+ AND o.id <> o.caseid.id.id -- MUCH faster than NOT LIKE
+),
+
+ AggregatedObservations AS (
+ SELECT
+ Id,
+ caseid,
+ linkid,
+ linkCaseNo,
+ linkCaseKey,
+ linkCaseDate,
+ taskid,
+ performedby,
+ date,
+ MIN(created) AS created,
+ GROUP_CONCAT(
+ CAST(observation_string AS VARCHAR(1000)),
+ '; '
+ ) AS observations
+FROM Observations
+GROUP BY
+ Id,
+ caseid,
+ linkid,
+ linkCaseNo,
+ linkCaseKey,
+ linkCaseDate,
+ taskid,
+ performedby,
+ date
+ ),
+
+ AnimalCases AS (
+SELECT
+ ao.*,
+ c.category,
+ c.caseNo,
+ c.objectId AS key
+FROM AggregatedObservations ao
+ LEFT JOIN study.cases c
+ON c.Id = ao.Id
+ AND ao.created >= c.date
+ AND (ao.created <= c.enddate OR c.enddate IS NULL)
+ )
+
+SELECT
+ Id AS ObsAnimalId,
+ date,
+ created,
+ observations,
+ taskid,
+ performedby,
+ linkid AS LinkedCaseAnimalId,
+ caseid AS linkedCaseCategory,
+ linkCaseNo,
+ linkCaseKey,
+ linkCaseDate,
+ GROUP_CONCAT(category, ', ') AS openCasesAtObsCreation,
+ GROUP_CONCAT(caseNo, ', ') AS openCaseNosAtObsCreation,
+ GROUP_CONCAT(key, ', ') AS openCaseKeysAtObsCreation
+FROM AnimalCases
+GROUP BY
+ Id,
+ date,
+ created,
+ observations,
+ taskid,
+ performedby,
+ linkid,
+ caseid,
+ linkCaseNo,
+ linkCaseKey,
+ linkCaseDate
\ No newline at end of file
diff --git a/onprc_ehr/resources/queries/study/vetAssignment_multipleVets.query.xml b/onprc_ehr/resources/queries/study/vetAssignment_multipleVets.query.xml
new file mode 100644
index 000000000..98750be9e
--- /dev/null
+++ b/onprc_ehr/resources/queries/study/vetAssignment_multipleVets.query.xml
@@ -0,0 +1,9 @@
+
+
+
+
+ NHPs With Multiple Assigned Vets
+
+
+
+
diff --git a/onprc_ehr/resources/queries/study/vetAssignment_multipleVets.sql b/onprc_ehr/resources/queries/study/vetAssignment_multipleVets.sql
new file mode 100644
index 000000000..2bbeed3f7
--- /dev/null
+++ b/onprc_ehr/resources/queries/study/vetAssignment_multipleVets.sql
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2014-2026 LabKey Corporation
+ *
+ * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0
+ */
+
+WITH assignmentData AS (
+ SELECT DISTINCT
+ Id,
+ Area,
+ Room,
+ CASE
+ WHEN AssignmentType = 'Open Case' THEN (AssignedVet || ', Open Case: ' || COALESCE(MasterProblems, ''))
+ ELSE (AssignedVet || ', ' || AssignmentType)
+ END AS assignment
+ FROM demographicsAssignedVet
+)
+SELECT
+ Id,
+ Area,
+ Room,
+ GROUP_CONCAT(assignment, chr(10)) AS Vets
+FROM assignmentData
+GROUP BY Id, Area, Room
+HAVING COUNT(*) > 1
diff --git a/onprc_ehr/resources/queries/study/vetassignment_filter.sql b/onprc_ehr/resources/queries/study/vetassignment_filter.sql
index 82371bd07..7969f717a 100644
--- a/onprc_ehr/resources/queries/study/vetassignment_filter.sql
+++ b/onprc_ehr/resources/queries/study/vetassignment_filter.sql
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2023-2026 LabKey Corporation
+ * Copyright (c) 2014-2026 LabKey Corporation
*
* Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0
*/
diff --git a/onprc_ehr/resources/scripts/onprc_ehr/onprc_triggers.js b/onprc_ehr/resources/scripts/onprc_ehr/onprc_triggers.js
index c5103d51b..355baf14c 100644
--- a/onprc_ehr/resources/scripts/onprc_ehr/onprc_triggers.js
+++ b/onprc_ehr/resources/scripts/onprc_ehr/onprc_triggers.js
@@ -27,7 +27,11 @@ exports.init = function(EHR){
Id: row.Id,
birth: row.date,
date: row.date,
- calculated_status: 'Fetus'
+ calculated_status: 'Fetus',
+ species: row.species,
+ geographic_origin: row.geographic_origin,
+ gender: row.gender
+
};
@@ -692,16 +696,6 @@ exports.init = function(EHR){
hasUpdates = true;
}
- //update death date in demographics if born dead
- if (row.Id && row.date && !data.death && !triggerHelper.isBirthAlive(row.birth_condition || null)){
- obj.death = row.date;
- hasUpdates = true;
-
- //if this is the first time a birth condition was entered, treat this the same as when a death is entered
- if (oldRow && !oldRow.birth_condition){
- helper.onDeathDeparture(row.Id, row.date);
- }
- }
if (hasUpdates){
obj.Id = row.Id;
diff --git a/onprc_ehr/resources/web/onprc_ehr/data/sources/ONPRCDefaults.js b/onprc_ehr/resources/web/onprc_ehr/data/sources/ONPRCDefaults.js
index 3a848ba30..0188d8b75 100644
--- a/onprc_ehr/resources/web/onprc_ehr/data/sources/ONPRCDefaults.js
+++ b/onprc_ehr/resources/web/onprc_ehr/data/sources/ONPRCDefaults.js
@@ -44,7 +44,52 @@ EHR.model.DataModelManager.registerMetadata('Default', {
ret.setHours(8);
return ret;
}
+ },
+ route: {
+ editorConfig: {
+ plugins: [Ext4.create('LDK.plugin.UserEditableCombo', {
+ allowChooseOther: false
+ })]
+ }
+ },
+ vol_units: {
+ editorConfig: {
+ plugins: [Ext4.create('LDK.plugin.UserEditableCombo', {
+ allowChooseOther: false
+ })]
+ }
+ },
+ amount_units: {
+ editorConfig: {
+ plugins: [Ext4.create('LDK.plugin.UserEditableCombo', {
+ allowChooseOther: false
+ })]
+ }
}
+ },
+ 'study.drug': {
+ route: {
+ editorConfig: {
+ plugins: [Ext4.create('LDK.plugin.UserEditableCombo', {
+ allowChooseOther: false
+ })]
+ }
+ },
+ vol_units: {
+ editorConfig: {
+ plugins: [Ext4.create('LDK.plugin.UserEditableCombo', {
+ allowChooseOther: false
+ })]
+ }
+ },
+ amount_units: {
+ editorConfig: {
+ plugins: [Ext4.create('LDK.plugin.UserEditableCombo', {
+ allowChooseOther: false
+ })]
+ }
+ }
+
},
'study.blood' : {
@@ -96,6 +141,13 @@ EHR.model.DataModelManager.registerMetadata('Default', {
width: 150
}
},
+ source: {
+ editorConfig: {
+ plugins: [Ext4.create('LDK.plugin.UserEditableCombo', {
+ allowChooseOther: false
+ })]
+ }
+ },
//Added: 5-3-2018 R.Blasa
acquisitionType: {
hidden: false,
@@ -210,7 +262,37 @@ EHR.model.DataModelManager.registerMetadata('Default', {
height: 52
}
},
+ //Modified: 9-10-2026 R. Blasa affects both Necropsy and Surgery
+ 'ehr.encounter_participants': {
+ username: {
+ editorConfig: {
+ plugins: [Ext4.create('LDK.plugin.UserEditableCombo', {
+ allowChooseOther: false
+ })]
+ }
+ }
+ },
+ //Modified: 9-10-2026 R. Blasa
+ 'study.housing': {
+ room: {
+ editorConfig: {
+ plugins: [Ext4.create('LDK.plugin.UserEditableCombo', {
+ allowChooseOther: false
+ })]
+ }
+ }
+ },
+ //Modified: 9-10-2026 R. Blasa
+ 'study.Departure': {
+ destination: {
+ editorConfig: {
+ plugins: [Ext4.create('LDK.plugin.UserEditableCombo', {
+ allowChooseOther: false
+ })]
+ }
+ }
+ },
//Added: 12-27-2017 R.blasa
'study.flags': {
diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/query/ONPRC_EHRTriggerHelper.java b/onprc_ehr/src/org/labkey/onprc_ehr/query/ONPRC_EHRTriggerHelper.java
index 2cca6fe75..b17420f64 100644
--- a/onprc_ehr/src/org/labkey/onprc_ehr/query/ONPRC_EHRTriggerHelper.java
+++ b/onprc_ehr/src/org/labkey/onprc_ehr/query/ONPRC_EHRTriggerHelper.java
@@ -1244,8 +1244,8 @@ public void createBirthRecord_ONPRC(String id, Map props) throws
// Added: 6-27-2017 F.Blasa Process when transitioning from Prenatal - Fetus to Live
public void doBirthConditionAfterPrenatal(String id, Date date, String dam, Date Arrival_Date, String birthCondition, boolean isBecomingPublic) throws Exception
{
- //is the infant is dead, terminate the assignments
- Date enddate = isBirthAlive(birthCondition) ? null : date;
+
+ Date enddate = null ;
String nonRestrictedFlag = getFlag("Condition", NONRESTRICTED, null, true);
if (nonRestrictedFlag != null)
@@ -1273,16 +1273,9 @@ public void doBirthConditionAfterPrenatal(String id, Date date, String dam, Date
//Modified: 10-13-2016 R.Blasa to include assign Arrival date
public void doBirthTriggers(String id, Date date, String dam, Date Arrival_Date, String birthCondition, String species, boolean isBecomingPublic) throws Exception
{
- //is the infant is dead, terminate the assignments
- Date enddate = isBirthAlive(birthCondition) ? null : date;
+ Date enddate = null ;
- //also check for a pre-existing death record:
- Date deathDate = new TableSelector(getTableInfo("study", "deaths"), Collections.singleton("date"), new SimpleFilter(FieldKey.fromString("Id"), id), null).getObject(Date.class);
- if (deathDate != null)
- {
- enddate = deathDate;
- }
//note: we only want this to run the first time this record becomes public, not on subsequent updates
if (isBecomingPublic)
diff --git a/onprc_ehr/test/src/org/labkey/test/tests/onprc_ehr/ONPRC_EHRTest2.java b/onprc_ehr/test/src/org/labkey/test/tests/onprc_ehr/ONPRC_EHRTest2.java
index 608df4bd7..efff00392 100644
--- a/onprc_ehr/test/src/org/labkey/test/tests/onprc_ehr/ONPRC_EHRTest2.java
+++ b/onprc_ehr/test/src/org/labkey/test/tests/onprc_ehr/ONPRC_EHRTest2.java
@@ -390,14 +390,14 @@ private void testBirthRecordStatus(String offspringId, boolean birthWasChanged)
SelectRowsCommand weightSelect = new SelectRowsCommand("study", "weight");
weightSelect.addFilter(new Filter("Id", offspringId, Filter.Operator.EQUAL));
- if (!isAlive)
- {
- //if the animal was born dead, we expect these flags to be endded automatically
- groupSelect.addFilter(new Filter("enddate", null, Filter.Operator.NONBLANK));
- spfFlagSelect.addFilter(new Filter("enddate", null, Filter.Operator.NONBLANK));
- conditionSelect.addFilter(new Filter("enddate", null, Filter.Operator.NONBLANK));
- housingSelect.addFilter(new Filter("enddate", null, Filter.Operator.NONBLANK));
- }
+// if (!isAlive)
+// {
+// //if the animal was born dead, we expect these flags to be endded automatically
+// groupSelect.addFilter(new Filter("enddate", null, Filter.Operator.NONBLANK));
+// spfFlagSelect.addFilter(new Filter("enddate", null, Filter.Operator.NONBLANK));
+// conditionSelect.addFilter(new Filter("enddate", null, Filter.Operator.NONBLANK));
+// housingSelect.addFilter(new Filter("enddate", null, Filter.Operator.NONBLANK));
+// }
if (isPublic)
{
@@ -413,18 +413,18 @@ private void testBirthRecordStatus(String offspringId, boolean birthWasChanged)
}
//expect death date
- if (!isAlive)
- {
- //in our test scenario, death date always matches birth
- org.junit.Assert.assertEquals("demographics death date should match birth", birthDate, demographicsRow.get("death"));
- }
- else
- {
- //in our test scenario, death date always matches birth
- Assert.assertNull("demographics death date should be null", demographicsRow.get("death"));
- }
-
- org.junit.Assert.assertEquals("demographics birth date not set properly", birthDate, demographicsRow.get("birth"));
+// if (!isAlive)
+// {
+// //in our test scenario, death date always matches birth
+// org.junit.Assert.assertEquals("demographics death date should match birth", birthDate, demographicsRow.get("death"));
+// }
+// else
+// {
+// //in our test scenario, death date always matches birth
+// Assert.assertNull("demographics death date should be null", demographicsRow.get("death"));
+// }
+
+// org.junit.Assert.assertEquals("demographics birth date not set properly", birthDate, demographicsRow.get("birth"));
//always expect condition = Nonrestricted
org.junit.Assert.assertEquals(1, conditionSelect.execute(getApiHelper().getConnection(), getContainerPath()).getRowCount().intValue());