diff --git a/onprc_ehr/resources/etls/SLAWeaning.xml b/onprc_ehr/resources/etls/SLAWeaning.xml index b03f7a8c5..b1301e787 100644 --- a/onprc_ehr/resources/etls/SLAWeaning.xml +++ b/onprc_ehr/resources/etls/SLAWeaning.xml @@ -20,9 +20,11 @@ - - - + + + + + \ No newline at end of file diff --git a/onprc_ehr/resources/etls/TB_Test_Historical_Process.xml b/onprc_ehr/resources/etls/TB_Test_Historical_Process.xml new file mode 100644 index 000000000..04c400b0c --- /dev/null +++ b/onprc_ehr/resources/etls/TB_Test_Historical_Process.xml @@ -0,0 +1,38 @@ + + + + + TB_Test_Historical_Record_Updates + + Transfer Tb Test temp tables into study Clinical Observation values + + + + + + + Transfer to EHR Tasks + + + + + + + + + + Transfer temp table data to study clinical observation + + + + + + + + + + + + + + diff --git a/onprc_ehr/resources/queries/study/DVMAlertForAlopeciaCases.sql b/onprc_ehr/resources/queries/study/DVMAlertForAlopeciaCases.sql new file mode 100644 index 000000000..f248fc189 --- /dev/null +++ b/onprc_ehr/resources/queries/study/DVMAlertForAlopeciaCases.sql @@ -0,0 +1,69 @@ +/* Added by Kollil 09/22/2025 + When BSU creates a case AND scores the alopecia at either 4 or 5 (only those scores) + THEN the vet assigned to that animal should receive an alert. + Show open cases in last 7 days +Refer to old tkt # 12523, new ticket # 15401 +*/ +SELECT + co.Id, + co.date AS AlertObservationDate, + co.observation AS AlopeciaScore, + co.performedby, + CASE + WHEN co.enteredSincevetReview = 1 THEN 'true' + WHEN co.enteredSincevetReview = 0 THEN 'false' + ELSE NULL + END AS enteredSincevetReview, + co.Id.assignedVet.AssignedVet AS AssignedVet, + c.BehaviorCaseOpenDate, + TIMESTAMPADD(SQL_TSI_DAY, 7, c.BehaviorCaseOpenDate) AS VetReviewDueDate +FROM study.clinical_observations co + INNER JOIN study.demographics d + ON d.Id = co.Id + INNER JOIN ( + SELECT + x.Id, + MAX(x.date) AS BehaviorCaseOpenDate + FROM study.Cases x + WHERE x.category = 'Behavior' + AND x.allProblemCategories = 'Behavioral: Alopecia' + AND x.enddate IS NULL + AND x.date >= TIMESTAMPADD(SQL_TSI_DAY, -7, NOW()) + GROUP BY x.Id + ) c + ON c.Id = co.Id +WHERE co.category = 'Alopecia Score' + AND co.observation IN ('4', '5') + AND d.calculated_status = 'Alive' + + /* Only the first 4/5 in a streak */ + AND NOT EXISTS ( + SELECT 1 + FROM study.clinical_observations prev + WHERE prev.Id = co.Id + AND prev.category = 'Alopecia Score' + AND prev.observation IN ('4', '5') + AND prev.date < co.date + AND prev.date > + COALESCE( + ( + SELECT MAX(reset.date) + FROM study.clinical_observations reset + WHERE reset.Id = co.Id + AND reset.category = 'Alopecia Score' + AND reset.observation IN ('0', '1', '2', '3') + AND reset.date < co.date + ), + {ts '1900-01-01 00:00:00'} + ) +) + /* Remove old streaks that later returned to 0-3 */ + AND NOT EXISTS ( + SELECT 1 + FROM study.clinical_observations laterReset + WHERE laterReset.Id = co.Id + AND laterReset.category = 'Alopecia Score' + AND laterReset.observation IN ('0', '1', '2', '3') + AND laterReset.date > co.date +) +ORDER BY co.Id ASC \ No newline at end of file diff --git a/onprc_ehr/resources/queries/study/DVMAlertforAlopeciaCases.query.xml b/onprc_ehr/resources/queries/study/DVMAlertforAlopeciaCases.query.xml new file mode 100644 index 000000000..92a6ffd2f --- /dev/null +++ b/onprc_ehr/resources/queries/study/DVMAlertforAlopeciaCases.query.xml @@ -0,0 +1,41 @@ + + + + + New severe alopecia cases with a score of 4 or 5 requires Vet review + + + false + + study + animal + id + + + + false + Alert Observation Date + + + Alopecia Score + + + Performed By + + + Entered Since Last Vet Review? + + + Assigned Vet + + + Behavior Case Open Date + + + Vet Review Due Date + + +
+
+
+
\ No newline at end of file diff --git a/onprc_ehr/resources/schemas/dbscripts/postgresql/onprc_ehr-26.005-26.006.sql b/onprc_ehr/resources/schemas/dbscripts/postgresql/onprc_ehr-26.005-26.006.sql new file mode 100644 index 000000000..7874237c6 --- /dev/null +++ b/onprc_ehr/resources/schemas/dbscripts/postgresql/onprc_ehr-26.005-26.006.sql @@ -0,0 +1,237 @@ +CREATE TABLE onprc_ehr.TB_TestTemp_Historical ( + rowid integer GENERATED BY DEFAULT AS IDENTITY (START WITH 100 INCREMENT BY 1) NOT NULL, + animalid varchar(200) NULL, + date timestamp NULL, + objectid ENTITYID NOT NULL, + created timestamp NULL, + createdby integer NULL, + performedby varchar(200) NULL, + modifiedby integer NULL, + date_posted timestamp(0) NULL, + CONSTRAINT PK_TB_TestTemp_Historical PRIMARY KEY (rowid) +); + +CREATE TABLE onprc_ehr.Temp_Clinical_Observations_Historical ( + rowid integer GENERATED BY DEFAULT AS IDENTITY (START WITH 100 INCREMENT BY 1) NOT NULL, + Id varchar(200) NULL, + date timestamp(0) NULL, + category varchar(500) NULL, + area varchar(500) NULL, + observation varchar(500) NULL, + createdby integer NULL, + performedby varchar(500) NULL, + taskid varchar(4000) NULL, + qcstate integer NULL, + modifiedby integer NULL, + CONSTRAINT PK_Temp_Clinical_Observations_Historical PRIMARY KEY (rowid) +); + +CREATE TABLE onprc_ehr.Temp_Clinical_Observations_Historical_Master ( + rowid integer GENERATED BY DEFAULT AS IDENTITY (START WITH 100 INCREMENT BY 1) NOT NULL, + searchid integer NULL, + Id varchar(200) NULL, + date timestamp(0) NULL, + category varchar(500) NULL, + area varchar(500) NULL, + observation varchar(500) NULL, + createdby integer NULL, + performedby varchar(500) NULL, + taskid varchar(4000) NULL, + qcstate smallint NULL, + modifiedby integer NULL, -- smalldatetime on SQL Server is clearly wrong + Posted_date timestamp(0) NULL, + CONSTRAINT PK_Temp_Clinical_Observations_Historical_Master PRIMARY KEY (rowid) +); + +CREATE TABLE onprc_ehr.Observation_Historical_EHRTasks ( + rowid integer GENERATED BY DEFAULT AS IDENTITY (START WITH 100 INCREMENT BY 1) NOT NULL, + taskid varchar(4000) NULL, + description varchar(500) NULL, + title varchar(500) NULL, + qcstate smallint NULL, + formtype varchar(500) NULL, + category varchar(500) NULL, + assignedto smallint NULL, + createdby smallint NULL, + modifiedby smallint NULL, + CONSTRAINT PK_Observation_Historical_EHRTasks PRIMARY KEY (rowid) +); + +/* +** +** Created by +** R. Blasa 7-31-2026 A Program Process that reviews all TB Test Encounter entries on a current date, and creates a +** new TB Test Clinical Observation record based on +** having the same monkey id, date, and then to be assigned to a Data Admin for reviews. +** +*/ + +CREATE OR REPLACE FUNCTION onprc_ehr.p_Create_TB_Observation_Historical_records( + Start_Date TIMESTAMP, + End_Date TIMESTAMP +) +RETURNS integer +LANGUAGE plpgsql +AS $$ +DECLARE + v_SearchKey integer; + v_TempSearchKey integer; + v_TaskId varchar(4000); + v_AnimalID varchar(100); + v_date timestamp(0); + v_performedby varchar(500); + v_FirstFlag integer; +BEGIN + -- Reset temp tables + TRUNCATE TABLE onprc_ehr.TB_TestTemp_Historical RESTART IDENTITY; + TRUNCATE TABLE onprc_ehr.Temp_Clinical_Observations_Historical RESTART IDENTITY; + TRUNCATE TABLE onprc_ehr.Observation_Historical_EHRTasks RESTART IDENTITY; + + -- Generate a list of TB test monkeys + INSERT INTO onprc_ehr.TB_TestTemp_Historical (animalid, date, objectid, created, createdby, performedby, modifiedby, date_posted) + SELECT + a.participantid, + a.date::date, + a.objectid, + a.created, + a.createdBy, + a.performedby, + a.modifiedby, + CURRENT_TIMESTAMP + FROM studydataset.c6d214_encounters a + WHERE lower(a.type) IN (lower('Procedure'), lower('Surgery')) + AND a.qcstate = 18 + AND a.procedureid = 802 -----'TB Test Intradermal' + AND a.date >= Start_Date + AND a.date < End_Date + INTERVAL '1 day' + AND a.participantid NOT IN ( + SELECT j.participantid + FROM studydataset.c6d171_clinical_observations j + WHERE j.participantid = a.participantid + AND j.date::date = a.date::date + 3 + AND lower(j.category) = lower('TB TST Score (72 hr)') + AND j.qcstate = 18 + ) + ORDER BY a.participantid, a.date DESC; + + IF NOT EXISTS (SELECT 1 FROM onprc_ehr.TB_TestTemp_Historical) THEN + RETURN 0; + END IF; + + v_TempSearchKey := 0; + v_TaskId := NULL; + v_FirstFlag := 0; + + SELECT rowid INTO v_SearchKey + FROM onprc_ehr.TB_TestTemp_Historical + ORDER BY rowid + LIMIT 1; + + -- Create a single task for each process run + WHILE v_TempSearchKey < v_SearchKey LOOP + + SELECT animalid, date, performedby + INTO v_AnimalID, v_date, v_performedby + FROM onprc_ehr.TB_TestTemp_Historical + WHERE rowid = v_SearchKey; + + IF NOT EXISTS ( + SELECT 1 FROM studydataset.c6d171_clinical_observations j + WHERE j.participantid = v_AnimalID + AND j.date::date = v_date::date + 3 + AND lower(j.category) = lower('TB TST Score (72 hr)') + ) THEN + + IF v_FirstFlag != 1 THEN + v_TaskId := gen_random_uuid()::text; + + INSERT INTO onprc_ehr.Observation_Historical_EHRTasks ( + taskid, + description, + title, + qcstate, + formtype, + category, + assignedto, + createdby, + modifiedby + ) VALUES ( + v_TaskId, + 'TB TST Scores ' || COALESCE(v_date::text, ''), + 'TB TST Scores', + 20, --- Qc State (In Progress) + 'TB TST Scores', + 'task', + 1822, ------- Assigned To Data Admins + 1042, -------- Created By IS + 1042 ----- Modified by IS + ); + + v_FirstFlag := 1; + END IF; + + -- Add three days from TB Test date + v_date := v_date + INTERVAL '3 days'; + + INSERT INTO onprc_ehr.Temp_Clinical_Observations_Historical ( + Id, + date, + category, + area, + observation, + createdby, + performedby, + taskid, + qcstate, + modifiedby + ) VALUES ( + v_AnimalID, + v_date, + 'TB TST Score (72 hr)', + 'Right Eyelid', + 'Grade: Negative', + 1042, + v_performedby, + v_TaskId, + 20, + 1042 + ); + + END IF; + + v_TempSearchKey := v_SearchKey; + + SELECT rowid INTO v_SearchKey + FROM onprc_ehr.TB_TestTemp_Historical + WHERE rowid > v_TempSearchKey + ORDER BY rowid + LIMIT 1; + + IF NOT FOUND OR v_SearchKey IS NULL THEN + EXIT; + END IF; + + END LOOP; + + -- Create a master copy of the completed transaction + INSERT INTO onprc_ehr.Temp_Clinical_Observations_Historical_Master ( + searchid, Id, date, category, area, observation, createdby, performedby, taskid, qcstate, modifiedby, Posted_date + ) + SELECT + rowid, + Id, + date, + category, + area, + observation, + createdby, + performedby, + taskid, + qcstate, + modifiedby, + CURRENT_TIMESTAMP + FROM onprc_ehr.Temp_Clinical_Observations_Historical; + + RETURN 0; +END; +$$; diff --git a/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-26.004-26.005.sql b/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-26.004-26.005.sql new file mode 100644 index 000000000..ae836ff71 --- /dev/null +++ b/onprc_ehr/resources/schemas/dbscripts/sqlserver/onprc_ehr-26.004-26.005.sql @@ -0,0 +1,329 @@ +CREATE TABLE [onprc_ehr].[TB_TestTemp_Historical]( + rowid [int] IDENTITY(100,1) NOT NULL, + animalid varchar(200) NULL, + date datetime NULL, + objectid ENTITYID NOT NULL, + created datetime NULL, + createdby integer NULL, + performedby varchar(200) NULL, + modifiedby integer NULL, + date_posted smalldatetime + ) + GO + + +CREATE TABLE [onprc_ehr].[Temp_Clinical_Observations_Historical]( + rowid [int] IDENTITY(100,1) NOT NULL, + Id varchar(200) NULL, + date smalldatetime NULL, + category varchar(500) NULL, + area varchar(500) NULL, + observation varchar(500) NULL, + createdby integer NULL, + performedby varchar(500) NULL, + taskid varchar(4000) NULL, + qcstate integer NULL, + modifiedby integer NULL + + ) + GO + +CREATE TABLE [onprc_ehr].[Temp_Clinical_Observations_Historical_Master]( + rowid [int] IDENTITY(100,1) NOT NULL, + searchid integer NULL, + Id varchar(200) NULL, + date smalldatetime NULL, + category varchar(500) NULL, + area varchar(500) NULL, + observation varchar(500) NULL, + createdby integer NULL, + performedby varchar(500) NULL, + taskid varchar(4000) NULL, + qcstate smallint NULL, + modifiedby smalldatetime NULL, + Posted_date smalldatetime + + ) + GO + +CREATE TABLE [onprc_ehr].[Observation_Historical_EHRTasks]( + rowid [int] IDENTITY(100,1) NOT NULL, + taskid varchar(4000) NULL, + description varchar(500)NULL, + title varchar(500)NULL, + qcstate smallint NULL, + formtype varchar(500) NULL, + category varchar(500) NULL, + assignedto smallint NULL, + createdby smallint NULL, + modifiedby smallint NULL + + ) + GO + + + EXEC core.fn_dropifexists 'p_Create_TB_Observation_Historical_records', 'onprc_ehr', 'PROCEDURE', NULL; +GO + + +/* +** +** Created by +** R. Blasa 7-31-2026 A Program Process that reviews all TB Test Encounter entries on a current date, and creates a +** new TB Test Clinical Observation record based on +** having the same monkey id, date, and then to be assigned to a Data Admin for reviews. +** + +** +** +*/ + +CREATE Procedure onprc_ehr.p_Create_TB_Observation_Historical_records + @Start_Date smalldatetime, + @End_Date smalldatetime + + + +AS + + + +DECLARE +@SearchKey Int, + @TempsearchKey Int, + @TaskId varchar(4000), + @AnimalID varchar(100), + @date smalldatetime, + @createdby integer, + @performedby varchar(500), + @modifiedby integer, + @RunID varchar(4000), + @FirstFlag integer, + @TestDate smalldatetime + + + + +BEGIN + + + ---- Reset temp table + +Truncate table onprc_ehr.TB_TestTemp_Historical + + If @@Error <> 0 + GoTo Err_Proc + + Truncate table [onprc_ehr].[Temp_Clinical_Observations_Historical] + + If @@Error <> 0 + GoTo Err_Proc + + Truncate table [onprc_ehr].[Observation_Historical_EHRTasks] + + If @@Error <> 0 + GoTo Err_Proc + + --- Generate a list TB test monkeys ) + + Insert into onprc_ehr.TB_TestTemp_Historical + +select + a.participantid, + cast(a.date as date), + a.objectid, + a.created, + a.createdBy, + a.performedby, + a.modifiedby, + getdate() -----date processed + + +from studydataset.c6d214_encounters a +Where a.type in ('Procedure','Surgery') + And a.qcstate = 18 + And a.procedureid = 802 -----'TB Test Intradermal' + And (a.date >= @Start_Date And a.date < dateadd(day, 1, @End_Date) ) + AND a.participantid not in (select j.participantid from studydataset.c6d171_clinical_observations j + Where j.participantid = a.participantid + And cast(j.date as date) = dateadd(day,3,cast(a.date as date) ) + And j.category = 'TB TST Score (72 hr)' + And j.qcstate = 18 ) + +order by a.participantid, a.date desc + + + If @@Error <> 0 + GoTo Err_Proc + + ---- When there are no records to process, exit immediately from the program. + + If (Select count(*) from onprc_ehr.TB_TestTemp_Historical) = 0 + BEGIN + GOTO No_Records + END + + + ---- Reset temp variables + + Set @SearchKey = 0 + Set @TempSearchKey = 0 + Set @Date = NULL + Set @modifiedby = NULL + Set @createdby =NULL + Set @performedby = NULL + Set @TaskID = NULL + Set @Animalid = Null + Set @RunID = Null + Set @FirstFlag = 0 + + + + ----- extract initial row id + +Select Top 1 @Searchkey = rowid from onprc_ehr.TB_TestTemp_Historical +Order by rowid + + + + ----Create a single task for each daily process + + + While @TempSearchKey < @SearchKey +BEGIN + + -----Begin entry Tb observation process + +Select @Animalid =animalid, @date = date, @modifiedby=modifiedby, @createdby =createdby,@performedby= performedby +from onprc_ehr.TB_TestTemp_Historical Where rowid = @Searchkey + + + + + If not exists (select * from studydataset.c6d171_clinical_observations j Where j.participantid = @AnimalID + And cast(j.date as date) = dateadd(day,3,@date) + And j.category = 'TB TST Score (72 hr)' ) + + +BEGIN + + If @FirstFlag != 1 + BEGIN + ---- created a new task id + Set @TaskID = NEWID() + + ---- Create Clinical Observation entries + Insert into onprc_ehr.Observation_Historical_EHRTasks + ( + taskid, + description, + title, + qcstate, + formType, + category, + assignedto, + createdby, + modifiedby + + ) + + Values ( + + @TaskID, + 'TB TST Scores ' + cast(@Date as varchar(50)) , ------ Title consist of animal id and Clinical procedure date + 'TB TST Scores', + 20, --- Qc State (In Progress) + 'TB TST Scores', ------ FormType + 'task', ----- category, + 1822, ------- Assigned To Data Admins + 1042, -------- Created By IS + 1042 ----- Modified by IS + + ) + + If @@Error <> 0 + GoTo Err_Proc + + ---Set Task insert process only once per single process + Set @FirstFlag = 1 + + END ---(@FirstFlag) + + + ----- Initialize data entries + Set @date = dateadd(day, 3,@date) ----- Add three days from TB Test date + + + + --- Create a Clinical Observation Record + + Insert into Temp_Clinical_Observations_Historical + ( + Id, + date, + category, + area, + observation, + createdby, + performedby, + taskid, + qcstate, + modifiedby + + + ) + values ( + @animalid, + @date, + 'TB TST Score (72 hr)', + 'Right Eyelid', + 'Grade: Negative', + 1042, -----created by IS + @performedby, + @TaskID, + 20 , ---- In Progress QCState + 1042 -----modified by IS + + + ) + + If @@Error <> 0 + GoTo Err_Proc + + +END --(If not exist) + + ----- Proceed and fetch the next record + + Set @TempSearchKey = @SearchKey + + Select Top 1 @SearchKey = rowid from onprc_ehr.TB_TestTemp_Historical + Where rowid > @TempSearchKey + Order by rowid + + +END ---- While @TempSearchKey + + + ----- Create a master copy of the completed transaction + +Insert into onprc_ehr.Temp_Clinical_Observations_Master +Select *, getdate() +from onprc_ehr.Temp_Clinical_Observations_Historical + + If @@Error <> 0 + GoTo Err_Proc + + + + No_Records: + + RETURN 0 + + + Err_Proc: + -------Error Generated, program processed stopped + RETURN 1 + + +END diff --git a/onprc_ehr/resources/schemas/onprc_ehr.xml b/onprc_ehr/resources/schemas/onprc_ehr.xml index 26e225c6f..a1c94dffe 100644 --- a/onprc_ehr/resources/schemas/onprc_ehr.xml +++ b/onprc_ehr/resources/schemas/onprc_ehr.xml @@ -1517,4 +1517,67 @@ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + +
+ 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 0188d8b75..4873624de 100644 --- a/onprc_ehr/resources/web/onprc_ehr/data/sources/ONPRCDefaults.js +++ b/onprc_ehr/resources/web/onprc_ehr/data/sources/ONPRCDefaults.js @@ -273,13 +273,17 @@ EHR.model.DataModelManager.registerMetadata('Default', { } }, //Modified: 9-10-2026 R. Blasa - 'study.housing': { + 'study.Housing': { room: { - editorConfig: { - plugins: [Ext4.create('LDK.plugin.UserEditableCombo', { - allowChooseOther: false - })] - } + xtype: 'onprc_ehr.roomfieldsingle', + allowBlank: false, + } + }, + + 'study.Birth': { + room: { + xtype: 'onprc_ehr.roomfieldsingle', + allowBlank: false } }, diff --git a/onprc_ehr/resources/web/onprc_ehr/form/field/RoomFieldSingle.js b/onprc_ehr/resources/web/onprc_ehr/form/field/RoomFieldSingle.js new file mode 100644 index 000000000..82a60bba7 --- /dev/null +++ b/onprc_ehr/resources/web/onprc_ehr/form/field/RoomFieldSingle.js @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2013-2019 LabKey Corporation + * + * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 + */ +Ext4.define('EHR.form.field.RoomFieldSingle', { + extend: 'Ext.form.field.ComboBox', + alias: 'widget.onprc_ehr-roomfieldsingle', + + caseSensitive: false, + anyMatch: true, + displayField: 'room', + forceSelection: true, + columns: 'room,area', + + initComponent: function(){ + var ctx = EHR.Utils.getEHRContext(); + + Ext4.apply(this, { + valueField: 'room', + queryMode: 'local', + store: { + type: 'labkey-store', + containerPath: ctx ? ctx['EHRStudyContainer'] : null, + schemaName: 'ehr_lookups', + queryName: 'rooms', + columns: this.columns, + sort: 'room_sortValue', + filterArray: [LABKEY.Filter.create('datedisabled', null, LABKEY.Filter.Types.ISBLANK)], + autoLoad: true + }, + }); + + this.callParent(arguments); + } +}); \ No newline at end of file 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 aeeeb29b8..d7642d5a4 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 26.004; + return 26.006; } @Override @@ -327,6 +327,8 @@ private void registerEHRResources() //Added: 10-12-2023 R.Blasa EHRService.get().registerClientDependency(ClientDependency.supplierFromPath("onprc_ehr/form/field/EnvironmentalField.js"), this); + //Added: 9-14-2026 R.Blasa + EHRService.get().registerClientDependency(ClientDependency.supplierFromPath("onprc_ehr/form/field/RoomFieldSingle.js"), this); EHRService.get().registerReportLink(EHRService.REPORT_LINK_TYPE.housing, "List Single Housed Animals", this, DetailsURL.fromString("/query/executeQuery.view?schemaName=study&query.queryName=demographicsPaired&query.viewName=Single Housed"), "Commonly Used Queries"); EHRService.get().registerReportLink(EHRService.REPORT_LINK_TYPE.housing, "Find Animals Housed In A Given Room/Cage At A Specific Time", this, DetailsURL.fromString("/ehr/housingOverlaps.view?groupById=1"), "Commonly Used Queries"); diff --git a/onprc_ehr/src/org/labkey/onprc_ehr/notification/VetReviewNotification.java b/onprc_ehr/src/org/labkey/onprc_ehr/notification/VetReviewNotification.java index c84b4d07a..e6f0d23c8 100644 --- a/onprc_ehr/src/org/labkey/onprc_ehr/notification/VetReviewNotification.java +++ b/onprc_ehr/src/org/labkey/onprc_ehr/notification/VetReviewNotification.java @@ -37,8 +37,10 @@ import java.sql.SQLException; import java.util.ArrayList; import java.util.Date; +import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Set; /** * Created by bimber on 9/18/2014. @@ -85,13 +87,76 @@ public String getMessageBodyHTML(Container c, User u) { StringBuilder msg = new StringBuilder(); - /* remarksWithoutAssignedVet(c, u, msg);*/ + /* remarksWithoutAssignedVet(c, u, msg);*/ + DVMAlopeciaAlert(c,u,msg); //Added by Kolli, March 2026 vetRecordsUnderReview(c, u, msg); animalsWithoutAssignedVet(c, u, msg); + return msg.toString(); } + /* Added by Kollil 09/22/2025 + When BSU creates a case AND scores the alopecia at either 4 or 5 (only those scores) + THEN the vet assigned to that animal should receive an alert. Show open cases in last 7 days + Refer to old tkt # 12523, new tkt # 15401 + */ + private void DVMAlopeciaAlert(final Container c, User u, final StringBuilder msg) + { + TableInfo ti = getStudySchema(c, u).getTable("DVMAlertforAlopeciaCases"); + + TableSelector ts = new TableSelector(ti, null, null); + long total = ts.getRowCount(); + + if (total > 0) + { + msg.append("
ALERT: " + total + " animals found with alopecia score of 4 or 5 with open behavioral case for alopecia in the last 7 days. "); + msg.append("Click here to view the data in a grid view\n"); + msg.append("
"); + + //Display the report in the email + Set columns = new HashSet<>(); + columns.add(FieldKey.fromString("Id")); + columns.add(FieldKey.fromString("AlertObservationDate")); + columns.add(FieldKey.fromString("AlopeciaScore")); + columns.add(FieldKey.fromString("performedby")); + columns.add(FieldKey.fromString("enteredSincevetReview")); + columns.add(FieldKey.fromString("AssignedVet")); + columns.add(FieldKey.fromString("BehaviorCaseOpenDate")); + columns.add(FieldKey.fromString("VetReviewDueDate")); + + final Map colMap = QueryService.get().getColumns(ti, columns); + TableSelector ts2 = new TableSelector(ti, colMap.values(), null, new Sort("date")); + + // Table header + 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(""); + msg.append(""); + msg.append(""); + msg.append(""); + msg.append(""); + }); + msg.append("
Id Alert Observation Date Alopecia Score Performed by Entered Since Vet Review Assigned Vet Behavior Case Open Date Vet Review Due Date
" + PageFlowUtil.filter(rs.getString("Id")) + " " + PageFlowUtil.filter(rs.getString("AlertObservationDate")) + "" + PageFlowUtil.filter(rs.getString("AlopeciaScore")) + "" + PageFlowUtil.filter(rs.getString("performedby")) + "" + PageFlowUtil.filter(rs.getString("enteredSincevetReview")) + "" + PageFlowUtil.filter(rs.getString("AssignedVet")) + "" + PageFlowUtil.filter(rs.getString("BehaviorCaseOpenDate")) + "" + PageFlowUtil.filter(rs.getString("VetReviewDueDate")) + "


"); + } + else + { + msg.append("WARNING: No animals found with alopecia score of 4 or 5 with open behavioral case for alopecia in last 7 days!

\n"); + } + + + } + public void vetRecordsUnderReview(Container c, User u, final StringBuilder msg) { int duration = 7; @@ -171,4 +236,4 @@ protected void animalsWithoutAssignedVet(final Container c, User u, final String msg.append("
\n"); } } -} +} \ No newline at end of file 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 efff00392..fc3e44bf2 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,15 +390,6 @@ 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 (isPublic) { //we expect demographics record to be present @@ -412,19 +403,7 @@ private void testBirthRecordStatus(String offspringId, boolean birthWasChanged) org.junit.Assert.assertEquals(INDIAN, demographicsRow.get("geographic_origin")); } - //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")); + 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()); diff --git a/sla/resources/queries/sla_public/PurchaseOrderDetailsAdmin.query.xml b/sla/resources/queries/sla_public/PurchaseOrderDetailsAdmin.query.xml index d018c1309..f9c30eabb 100644 --- a/sla/resources/queries/sla_public/PurchaseOrderDetailsAdmin.query.xml +++ b/sla/resources/queries/sla_public/PurchaseOrderDetailsAdmin.query.xml @@ -4,6 +4,7 @@ Purchase Order Details + diff --git a/sla/resources/queries/sla_public/PurchaseOrderDetailsAdmin.sql b/sla/resources/queries/sla_public/PurchaseOrderDetailsAdmin.sql index c75219c35..26ff7288d 100644 --- a/sla/resources/queries/sla_public/PurchaseOrderDetailsAdmin.sql +++ b/sla/resources/queries/sla_public/PurchaseOrderDetailsAdmin.sql @@ -36,4 +36,4 @@ pd.cancelledby FROM PublicPurchase p, PublicPurchaseDetails pd WHERE p.objectid = pd.purchaseid - +ORDER BY requestdate DESC diff --git a/sla/resources/queries/sla_public/PurchaseOrdersByRequestor.query.xml b/sla/resources/queries/sla_public/PurchaseOrdersByRequestor.query.xml index f5873a642..98c3945f9 100644 --- a/sla/resources/queries/sla_public/PurchaseOrdersByRequestor.query.xml +++ b/sla/resources/queries/sla_public/PurchaseOrdersByRequestor.query.xml @@ -3,7 +3,7 @@
- Check Purchase Orders By Requestor + Purchase Orders By Requestor true diff --git a/sla/resources/queries/sla_public/PurchaseOrdersByRequestor.sql b/sla/resources/queries/sla_public/PurchaseOrdersByRequestor.sql index ebde278b2..81d38afd2 100644 --- a/sla/resources/queries/sla_public/PurchaseOrdersByRequestor.sql +++ b/sla/resources/queries/sla_public/PurchaseOrdersByRequestor.sql @@ -3,9 +3,22 @@ * * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 */ -SELECT requestorid, -requestor, -SUM(CASE WHEN confirmationnum IS NULL AND datecancelled IS NULL THEN 1 ELSE 0 END) AS pendingorders, -COUNT(rowid) AS numberoforders +-- Modified by Kollil in Sep, 2026 - Removed any empty requestor data +SELECT + requestorid, + requestorid.lastName AS RequestorLastname, + SUM( + CASE + WHEN confirmationnum IS NULL + AND datecancelled IS NULL + THEN 1 + ELSE 0 + END + ) AS pendingorders, + COUNT(rowid) AS numberoforders FROM PurchaseOrderDetails -GROUP By requestorid, requestor \ No newline at end of file +WHERE requestor IS NOT NULL + AND requestor <> '' +GROUP BY + requestorid, + requestorid.lastName \ No newline at end of file